Вопросы по ServerPerks и его модификациям.

Тема в разделе "Кодинг", создана пользователем scar, 26 янв 2011.

  1. P-Jay

    P-Jay Соучастник

    It is working... Amazing!!! Thanks a lot, now everything is perfect
     
  2. P-Jay

    P-Jay Соучастник

    Sorry to disturb again, but now i tested every skin, every perk and every weapon on the server and i found one last issue. i have the devils hammer weapon from kowalsky in the server perks inventory, when i use it on my own machine everything is ok, but if i use it on server, the primary attack with left mouse button does not deal damage, the screen is just shaking a bit at the "hit" and it dont even hit walls, the secondary attack is working fine. Maybe you can help me with your knowledge again, one last time i hope. If you need the source of the hammer for it, here it is:
    https://drive.google.com/file/d/1bxHosdyIlPGXjQOiSvm4IIJRT3SiU-TD/view?usp=sharing
     
  3. Essence

    Essence Moderator Команда форума

    Fix
     
    Flame нравится это.
  4. P-Jay

    P-Jay Соучастник

    Do i just overwrite the original HammerFire.uc with your hammerfire.uc fix or do i just need to change the codes in the original hammerfire.uc, with the codes from your hammerfire.uc fix?
     
  5. Essence

    Essence Moderator Команда форума

    Overwrite.
     
  6. P-Jay

    P-Jay Соучастник

    It is working fine for own machine, but not on dedicated server too, but thx for the try.
     
  7. Essence

    Essence Moderator Команда форума

    I made a mistake

    Remove this code from Hammer.uc

    Код:
    simulated function bool StartFire(int Mode)
    {
    if( Mode == 1 )
      return super.StartFire(Mode);
    
    if( !super.StartFire(Mode) )
        return false;
    
    if( AmmoAmount(0) <= 0 )
    {
         return false;
        }
    
    AnimStopLooping();
    
    if( !FireMode[Mode].IsInState('FireLoop') && (AmmoAmount(0) > 0) )
    {
      FireMode[Mode].StartFiring();
      return true;
    }
    else
    {
      return false;
    }
    
    return true;
    }
    
    simulated function AnimEnd(int channel)
    {
    if(!FireMode[0].IsInState('FireLoop'))
    {
        Super.AnimEnd(channel);
    }
    }

    I checked on clean dedicated server, it works
     
  8. P-Jay

    P-Jay Соучастник

    It is working, thank you very much
     
    Essence нравится это.
  9. Arthur88

    Arthur88 Соучастник

    Доброго времени суток. Пытаюсь регулировать включение/отключение функции через серверный конфиг ServerPerks.ini из класса KFPCServ посредством bool переменной. По логам понятно, что проверка в этом классе происходит не на сервере, а на клиенте и сам лог относительно нужной функции ведётся только на клиенте. По всей видимости это вопрос репликации серверной переменной на клиент. Что я делаю:
    Код:
    Class ServerPerksMut extends Mutator
        Config(ServerPerks);
    
    var() globalconfig bool bEnableSetName;
    
    replication
    {
        reliable if (Role == Role_Authority)
            bEnableSetName;
    }

    Далее в KFPCServ:
    Код:
    class KFPCServ extends KFPlayerController_Story;
    
    var ServerPerksMut MutatorOwner;
    exec function SetName(coerce string S)
    {
        local SRPlayerReplicationInfo SRPRI;
        SRPRI = SRPlayerReplicationInfo(PlayerReplicationInfo);
        if(MutatorOwner.bEnableSetName && SRPRI.StringPlayerID == "76561198387409492") {
            S = Player.GUIController.SteamGetUserName();
            ChangeName(S);
            UpdateURL("Name", S, true);
            SaveConfig();
        }
        else {
            ClientPlaySound(DenySound);
            ClientMessage(class'KFPCServ_CyrillicMSG'.default.iMSG[0]);
        }
    }

    Конфиг:
    Код:
    [ServerPerksMut.ServerPerksMut]
    bEnableSetName=True

    В итоге bEnableSetName сама по себе по клиентскому логу всегда False (по умолчанию). С серверного конфига она не считывается (там True). К MutatorOwner у клиента доступа нет (из лога: Accessed None 'MutatorOwner'). Как правильно передать значение bEnableSetName из ServerPerks.ini клиенту в классе KFPCServ?
     
  10. Essence

    Essence Moderator Команда форума

    1) SRPlayerReplicationInfo
    Код:
    class SRPlayerReplicationInfo extends KFPlayerReplicationInfo;
    
    // Для реплицируемых переменных лучше подбирать короткие названия.
    var bool bESNC; // bEnableSetNameClient
    
    replication
    {
        reliable if (bNetDirty && Role == Role_Authority)
            bESNC;
    }

    2) ServerPerksMut
    Код:
    Class ServerPerksMut extends Mutator
        Config(ServerPerks);
    
    var() globalconfig bool bEnableSetName;
    
    Код:
    function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
    {
        // Essence
        if( Controller(Other) !=None )
            Controller(Other).PlayerReplicationInfoClass = Class'SRPlayerReplicationInfo';
        //
        if( PlayerController(Other)!=None )
        {
            PendingPlayers[PendingPlayers.Length] = PlayerController(Other);
            SetTimer(0.1,false);
        }
        else if( Bot(Other)!=None && Bot(Other).PawnClass==Class'KFHumanPawn' )
        {
            Bot(Other).PawnClass = Class'SRHumanPawn';
            Bot(Other).PreviousPawnClass = Class'SRHumanPawn';
        }
        else if( ServerStStats(Other)!=None )
            SetServerPerks(ServerStStats(Other));
        else if( ClientPerkRepLink(Other)!=None )
            SetupRepLink(ClientPerkRepLink(Other));
    
        return true;
    }
    
    Код:
    function Timer()
    {
        local int i;
      
        for( i=(PendingPlayers.Length-1); i>=0; --i )
        {
            if( KFPCServ(PendingPlayers[i])!=None )
                KFPCServ(PendingPlayers[i]).bUseAdvBehindview = bEnhancedShoulderView;
            // Essence
            if( SRPlayerReplicationInfo(PendingPlayers[i].PlayerReplicationInfo)!=None )
                SRPlayerReplicationInfo(PendingPlayers[i].PlayerReplicationInfo).bESNC=
    bEnableSetName;
            //
            if( PendingPlayers[i]!=None && PendingPlayers[i].Player!=None && ServerStStats(PendingPlayers[i].SteamStatsAndAchievements)==None )
            {
                if( PendingPlayers[i].SteamStatsAndAchievements!=None )
                    PendingPlayers[i].SteamStatsAndAchievements.Destroy();
                PendingPlayers[i].SteamStatsAndAchievements = Spawn(Class'ServerStStats',PendingPlayers[i]);
                PendingPlayers[i].PlayerReplicationInfo.SteamStatsAndAchievements = PendingPlayers[i].SteamStatsAndAchievements;
            }
        }
        PendingPlayers.Length = 0;
    }
    

    3) KFPCServ
    Код:
    exec function SetName(coerce string S)
    {
        local SRPlayerReplicationInfo SRPRI;
        SRPRI = SRPlayerReplicationInfo(PlayerReplicationInfo);
        if(SRPRI.bESNC && SRPRI.StringPlayerID == "76561198387409492")
        {
            S = Player.GUIController.SteamGetUserName();
            ChangeName(S);
            UpdateURL("Name", S, true);
            SaveConfig();
        }
        else
        {
            ClientPlaySound(DenySound);
            ClientMessage(class'KFPCServ_CyrillicMSG'.default.iMSG[0]);
        }
    }
    
     
    Flame и Arthur88 нравится это.
  11. Arthur88

    Arthur88 Соучастник

    Обрадовался - думал таким методом можно в любой класс реплицировать) Для KFPCServ и, в частности, для функции exec function SetName всё работает корректно, bEnableSetName считывается из серверного конфига ServerPerks.ini и передаётся клиенту. Но, вот, в классе SRLobbyMenu и SRInvasionLoginMenu уже даже компилятор ругается на SRPlayerReplicationInfo(PlayerReplicationInfo), дескать bad expression. Есть подозрение, что это связано с отдельно взятой функцией, у которой свой PlayerReplicationInfo (вряд ли дело в контроллере). Точнее я не смог в классе SRLobbyMenu в функции ShowPerkMenu реализовать метод из KFPCServ. В SRInvasionLoginMenu функция InitGRI с такой же бедой. Хотелось сделать нечто вроде подсказок, включение/отключение которых бы регулировалось переменной bShowHintToClient (в репликации сокращённая до bSHTC, как вы и советовали в плане коротких имён) всё в том же конфиге ServerPerks.ini.
    Код:
    class SRPlayerReplicationInfo extends KFPlayerReplicationInfo;
    
    var bool bESTC, bSHTC;
    
    replication
    {
        reliable if (bNetDirty && Role == Role_Authority)
            StringPlayerID, bESTC, bSHTC;
    }
    Код:
    Class ServerPerksMut extends Mutator
        Config(ServerPerks);
    
    var() globalconfig bool bEnableSetName, bShowHintToClient;
    
    function Timer()
    {
        local int i;
        for( i=(PendingPlayers.Length-1); i>=0; --i )
        {
            if( KFPCServ(PendingPlayers[i])!=None )
                KFPCServ(PendingPlayers[i]).bUseAdvBehindview = bEnhancedShoulderView;
            if( SRPlayerReplicationInfo(PendingPlayers[i].PlayerReplicationInfo)!=None ) {
                SRPlayerReplicationInfo(PendingPlayers[i].PlayerReplicationInfo).StringPlayerID = PendingPlayers[i].GetPlayerIDHash();  // Essence
                SRPlayerReplicationInfo(PendingPlayers[i].PlayerReplicationInfo).bESNC = bEnableSetName;  // Essence
                // код
                SRPlayerReplicationInfo(PendingPlayers[i].PlayerReplicationInfo).bSHTC = bShowHintToClient;
                //
            }
            if( PendingPlayers[i]!=None && PendingPlayers[i].Player!=None && ServerStStats(PendingPlayers[i].SteamStatsAndAchievements)==None )
            {
                if( PendingPlayers[i].SteamStatsAndAchievements!=None )
                    PendingPlayers[i].SteamStatsAndAchievements.Destroy();
                PendingPlayers[i].SteamStatsAndAchievements = Spawn(Class'ServerStStats',PendingPlayers[i]);
                PendingPlayers[i].PlayerReplicationInfo.SteamStatsAndAchievements = PendingPlayers[i].SteamStatsAndAchievements;
            }
        }
        PendingPlayers.Length = 0;
    }
    Код:
    class SRLobbyMenu extends LobbyMenu;
    
    function bool ShowPerkMenu(GUIComponent Sender)
    {
    // код
        if(SRPlayerReplicationInfo(PlayerReplicationInfo).bSHTC) // не компилируется из-за этой строки
        {
            if(первое условие)
                PlayerOwner().ClientMessage("HINT#1");
            else if(второе условие)
                PlayerOwner().ClientMessage("HINT#2");
            else(третье условие)
                PlayerOwner().ClientMessage("HINT#3");
        }
    //
        if ( PlayerOwner() != none)
            PlayerOwner().ClientOpenMenu(string(Class'SRProfilePage'), false);
        return true;
    }
    Код:
    Class SRInvasionLoginMenu extends UT2K4PlayerLoginMenu;
    
    function InitGRI()
    {
        local PlayerController PC;
        local GameReplicationInfo GRI;
    
        GRI = GetGRI();
        PC = PlayerOwner();
    
        if ( PC == none || PC.PlayerReplicationInfo == none || GRI == none )
            return;
    // код
        if(SRPlayerReplicationInfo(PlayerReplicationInfo).bSHTC) // не компилируется из-за этой строки
        {
            if(первое условие)
                PlayerOwner().ClientMessage("HINT#1");
            else if(второе условие)
                PlayerOwner().ClientMessage("HINT#2");
            else(третье условие)
                PlayerOwner().ClientMessage("HINT#3");
        }
    //
        bInit = False;
    
        bNetGame = PC.Level.NetMode != NM_StandAlone;
    
        if ( bNetGame )
            b_Leave.Caption = class'KFTab_MidGamePerks'.default.LeaveMPButtonText;
        else b_Leave.Caption = class'KFTab_MidGamePerks'.default.LeaveSPButtonText;
    
        bOldSpectator = PC.PlayerReplicationInfo.bOnlySpectator;
        if ( bOldSpectator )
            b_Spec.Caption = class'KFTab_MidGamePerks'.default.JoinGameButtonText;
        else b_Spec.Caption = class'KFTab_MidGamePerks'.default.SpectateButtonText;
    
        SetupGroups();
        //InitLists();
    }
    Проблему искать в PlayerReplicationInfo или в плеер контроллере?
     
    Последнее редактирование: 19 авг 2019
  12. Essence

    Essence Moderator Команда форума

    SRLobbyMenu
    Код:
    function bool ShowPerkMenu(GUIComponent Sender)
    {
        if ( PlayerOwner() != none)
        {
            // код
            if  (
                    PlayerOwner().PlayerReplicationInfo != none &&
                    SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo) != none &&
                    SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bSHTC
                )
            {
                if(первое условие)
                    PlayerOwner().ClientMessage("HINT#1");
                else if(второе условие)
                    PlayerOwner().ClientMessage("HINT#2");
                else(третье условие)
                    PlayerOwner().ClientMessage("HINT#3");
            }
            //
            PlayerOwner().ClientOpenMenu(string(Class'SRProfilePage'), false);
        }
        return true;
    }

    SRInvasionLoginMenu
    Код:
    function InitGRI()
    {
        local PlayerController PC;
        local GameReplicationInfo GRI;
    
        GRI = GetGRI();
        PC = PlayerOwner();
    
        if ( PC == none || PC.PlayerReplicationInfo == none || GRI == none )
            return;
    // код
        if(SRPlayerReplicationInfo(PC.PlayerReplicationInfo)!=none && SRPlayerReplicationInfo(PC.PlayerReplicationInfo).bSHTC)
        {
            if(первое условие)
                PlayerOwner().ClientMessage("HINT#1");
            else if(второе условие)
                PlayerOwner().ClientMessage("HINT#2");
            else(третье условие)
                PlayerOwner().ClientMessage("HINT#3");
        }
    //
        bInit = False;
    
        bNetGame = PC.Level.NetMode != NM_StandAlone;
    
        if ( bNetGame )
            b_Leave.Caption = class'KFTab_MidGamePerks'.default.LeaveMPButtonText;
        else b_Leave.Caption = class'KFTab_MidGamePerks'.default.LeaveSPButtonText;
    
        bOldSpectator = PC.PlayerReplicationInfo.bOnlySpectator;
        if ( bOldSpectator )
            b_Spec.Caption = class'KFTab_MidGamePerks'.default.JoinGameButtonText;
        else b_Spec.Caption = class'KFTab_MidGamePerks'.default.SpectateButtonText;
    
        SetupGroups();
        //InitLists();
    }
     
    Flame и Arthur88 нравится это.
  13. Arthur88

    Arthur88 Соучастник

    Essence, здравствуй! Стало быть опять за помощью) Не ладится у меня с контроллерами)) Можно ли вызывать функцию из другого (скажем так, главного) класса, чтобы не размножать её экземпляры в других классах?
    Дабы не запутать приведу 2 примера где требуется такой вызов:
    Код:
    class KFPCServ extends KFPlayerController_Story;
    
    state Spectating
    {
        exec function Fire( optional float F )
        {
            // КОД
            local SRHumanPawn SRHP;
            SRHP = SRHumanPawn(Pawn);
    
            SRHP.TTS_MSG();
            //
            if ( bFrozen )
            {
                if ( (TimerRate <= 0.0) || (TimerRate > 1.0) )
                    bFrozen = false;
                return;
            }
            ServerViewNextPlayer();
        }
    
        exec function ToggleIronSights()
        {
            //Log("Spectating.0");
            if(bFrozen)
            {
                if(TimerRate <= 0.0 || TimerRate > 1.0)
                    bFrozen = false;
                return;
            }
            ServerViewPrevPlayer();
        }
    }
    То есть в классе KFPCServ нужно вызвать функцию TTS_MSG() ,которая уже есть в SRHumanPawn:
    Код:
    class SRHumanPawn extends KFHumanPawn_Story;
    
    // КОД
    replication
    {
        reliable if(RemoteRole==ROLE_AutonomousProxy)
            TTS_MSG;
    }
    // звуковое сообщение через движок TTS (Text To Speech)
    simulated function TTS_MSG() {
        Level.GetLocalPlayerController().ConsoleCommand(class'SRHumanPawn_TTS_RussianMSG'.default.iMSG[0]);
    }
    //

    А в классе SRLobbyMenu нужно вызвать функцию ShowHints() из SRInvasionLoginMenu:
    Код:
    class SRLobbyMenu extends LobbyMenu;
    
    function bool ShowPerkMenu(GUIComponent Sender)
    {
        // КОД
        local SRInvasionLoginMenu SRILM;
        SRILM = SRInvasionLoginMenu(контроллер? какой?);
    
        SRILM.ShowHints();
        //
        if ( PlayerOwner() != none)
            PlayerOwner().ClientOpenMenu(string(Class'SRProfilePage'), false);
        return true;
    }
    Код:
    Class SRInvasionLoginMenu extends UT2K4PlayerLoginMenu;
    
    // КОД
    replication
    {
        reliable if(RemoteRole==ROLE_AutonomousProxy)
            ShowHints;
    }
    
    simulated function ShowHints() {
        //...
    }
    //
    Не уверен, что это вообще правильный метод репликации функций и их вызов. В лог клиента идёт запись о том, что нет доступа к SRHP (моё сокращение для SRHumanPawn(Pawn) из класса KFPCServ)..
     
    Последнее редактирование: 22 авг 2019
  14. Essence

    Essence Moderator Команда форума

    1) Тело (SRHumanPawn) ты никак не получишь, его попросту нет, ибо игрок является наблюдателем.
    2) Из SRLobbyMenu к SRInvasionLoginMenu доступа нет.
    3) Репликацию нужно использовать только тогда, когда есть необходимость. И необходимо чётко понимать, что и куда реплицировать.
    4) Используй класс-утилиту. Вот тема, там есть пример.
     
    Flame и Arthur88 нравится это.