Запрет на поднятие чужих пушек

Тема в разделе "Общего назначения", создана пользователем Flame, 20 окт 2016.

Метки:
  1. RaideN111

    RaideN111 Игровая Администрация

    Флейм, подправил. Так правильно?

    Код:
    simulated function PostBeginPlay()
    {
        local bool bCustomView;
        if(Role<Role_Authority)
        {
            bCustomView=bool(class'SRMySettings'.static.Get("bCustomView"));
            SendSettingsToServer("bEnhancedShoulderView",string(int(bCustomView)));
            bEnhancedShoulderView=bCustomView;
        }
    }
       
    simulated function PostNetBeginPlay()
    {
        if(Role<Role_Authority)
        {
            bAllowPickup=bool(class'SRMySettings'.static.Get("bAllowPickup"));
            SendSettingsToServer("bAllowPickup",string(int(bAllowPickup)));
        }
        Super.PostNetBeginPlay();
    }
    
     
  2. Flame

    Flame -Заслуженый кодер форума-

    Почему ты bCustomView оставил в PostBeginPlay? ))
    Убери PostBeginPlay, если он не используется для чего-то ещё
    Код:
    simulated function PostNetBeginPlay()
    {
        local bool bCustomView;
        if(Role<Role_Authority)
        {
            bAllowPickup=bool(class'SRMySettings'.static.Get("bAllowPickup"));
            SendSettingsToServer("bAllowPickup",string(int(bAllowPickup)));
    
            bCustomView=bool(class'SRMySettings'.static.Get("bCustomView"));
            SendSettingsToServer("bEnhancedShoulderView",string(int(bCustomView)));
            bEnhancedShoulderView=bCustomView;
        }
        Super.PostNetBeginPlay();
    }
    
    И ещё я не понял почему так не написать
    Код:
    simulated function PostNetBeginPlay()
    {
        if(Role<Role_Authority)
        {
            bAllowPickup=bool(class'SRMySettings'.static.Get("bAllowPickup"));
            SendSettingsToServer("bAllowPickup",string(int(bAllowPickup)));
    
            bEnhancedShoulderView=bool(class'SRMySettings'.static.Get("bCustomView"));
            SendSettingsToServer("bEnhancedShoulderView",string(int(bEnhancedShoulderView)));
        }
        Super.PostNetBeginPlay();
    }
    
    А самое главное что я не понял - зачем тебе переменная bEnhancedShoulderView на сервере?
    Она ж вроде используется только на клиенте
    В общем попробовал бы ты такой вариант:
    Код:
    simulated function PostNetBeginPlay()
    {
    	if(Role<Role_Authority)
    	{
    		bAllowPickup=bool(class'SRMySettings'.static.Get("bAllowPickup"));
    		SendSettingsToServer("bAllowPickup",string(int(bAllowPickup)));
    		bEnhancedShoulderView=bool(class'SRMySettings'.static.Get("bCustomView"));
    	}
    	Super.PostNetBeginPlay();
    }
    
     
  3. Krasi

    Krasi Новенький

    Привет, я не знаю в чем дело, но эта настройка не работает как надо, даже если галочка стоит во флажке, никто не может подобрать чье-либо оружие
     
  4. Flame

    Flame -Заслуженый кодер форума-

    Попросили меня сделать вариацию на тему
    Игрок может поднять только оружие "своего" перка

    Код:
    Код:
    class OnlyMyPerkPickupsMut extends Mutator;
    
    var array<WeaponPickup> PendingPickups;
    var OnlyMyPerkPickupsRules Rules;
    
    function PostBeginPlay()
    {
        if(Rules==None)
            Rules=Spawn(Class'OnlyMyPerkPickupsRules');
    }
    
    defaultproperties
    {
        GroupName="KF-OnlyMyPerkPickups"
        FriendlyName="OnlyMyPerkPickupsMut"
        Description="OnlyMyPerkPickupsMut"
    }
    
    Код:
    class OnlyMyPerkPickupsRules extends GameRules;
    
    function PostBeginPlay()
    {
        if(Level.Game.GameRulesModifiers == none)
            Level.Game.GameRulesModifiers = self;
        else
            Level.Game.GameRulesModifiers.AddGameRules(self);
    }
    
    function AddGameRules(GameRules GR)
    {
        if(GR != self)
            super.AddGameRules(GR);
    }
    
    function bool OverridePickupQuery(Pawn Other, Pickup Item, out byte bAllowPickup)
    {
        if(WeaponPickup(Item)!=None && Other.Controller!=None )
        {
            if(!HasSameVeterancyClass(Other,Item))
            {
                bAllowPickup = 0;
                return true;
            }
        }
        if(NextGameRules!=None)
            return NextGameRules.OverridePickupQuery(Other, Item, bAllowPickup);
        return false;
    }
    
    function bool HasSameVeterancyClass(Pawn P, Pickup Item)
    {
        local KFPlayerReplicationInfo KFPRI;
        local KFWeaponPickup KFWP;
        if(P==none)
            return false;
        KFPRI=KFPlayerReplicationInfo(P.PlayerReplicationInfo);
        KFWP=KFWeaponPickup(Item);
        if(KFWP.default.CorrespondingPerkIndex==KFPRI.ClientVeteranSkill.default.PerkIndex)
            return true;
        return false;
    }
    

    Ссылка
    OnlyMyPerkPickupsMut.OnlyMyPerkPickupsMut
     
  5. Flame

    Flame -Заслуженый кодер форума-

    Код кидай свой - поглядим
     
  6. Krasi

    Krasi Новенький

    Class SRInvasionLoginMenu extends UT2K4PlayerLoginMenu;

    var() noexport bool bNetGame;
    var bool bOldSpectator;

    var automated GUIButton b_Settings, b_Browser, b_Quit, b_Favs,
    b_Leave, b_MapVote, b_KickVote, b_MatchSetup, b_Spec, b_Profile;
    var GUIStyles PlayerStyle;
    var array<SRMenuAddition> AddOnList;
    var int CurTabOrder;
    var localized string UserSPName;

    simulated final function GUIButton AddControlButton( string Cap, optional string Hint )
    {
    local GUIButton G;

    G = GUIButton(AddComponent(string(Class'GUIButton')));
    G.Caption = Cap;
    G.Hint = Hint;
    G.StyleName = "SquareButton";
    G.OnKeyEvent = G.InternalOnKeyEvent;
    G.WinLeft = 0.725;
    G.WinTop = 0.89;
    G.WinWidth = 0.2;
    G.WinHeight = 0.05;
    G.bAutoSize = True;
    G.TabOrder = CurTabOrder++;
    return G;
    }

    function InitComponent(GUIController MyController, GUIComponent MyOwner)
    {
    local int i;
    local string s;
    local eFontScale FS;
    local SRMenuAddition M;

    // Setup panel classes.
    Panels[0].ClassName = string(Class'SRTab_ServerNews');
    Panels[1].ClassName = string(Class'SRTab_MidGamePerks');
    Panels[2].ClassName = string(Class'SRTab_MidGameVoiceChat');
    Panels[3].ClassName = string(Class'SRTab_MidGameHelp');
    Panels[4].ClassName = string(Class'SRTab_MidGameStats');
    Panels[5].ClassName = string(Class'SRSettingsTab');

    // Setup localization.
    Panels[1].Caption = Class'KFInvasionLoginMenu'.Default.Panels[1].Caption;
    Panels[2].Caption = Class'KFInvasionLoginMenu'.Default.Panels[2].Caption;
    Panels[3].Caption = Class'KFInvasionLoginMenu'.Default.Panels[3].Caption;
    Panels[1].Hint = Class'KFInvasionLoginMenu'.Default.Panels[1].Hint;
    Panels[2].Hint = Class'KFInvasionLoginMenu'.Default.Panels[2].Hint;
    Panels[3].Hint = Class'KFInvasionLoginMenu'.Default.Panels[3].Hint;
    b_Spec.Caption=class'KFTab_MidGamePerks'.default.b_Spec.Caption;
    b_MatchSetup.Caption=class'KFTab_MidGamePerks'.default.b_MatchSetup.Caption;
    b_KickVote.Caption=class'KFTab_MidGamePerks'.default.b_KickVote.Caption;
    b_MapVote.Caption=class'KFTab_MidGamePerks'.default.b_MapVote.Caption;
    b_Quit.Caption=class'KFTab_MidGamePerks'.default.b_Quit.Caption;
    b_Favs.Caption=class'KFTab_MidGamePerks'.default.b_Favs.Caption;
    b_Favs.Hint=class'KFTab_MidGamePerks'.default.b_Favs.Hint;
    b_Settings.Caption=class'KFTab_MidGamePerks'.default.b_Settings.Caption;
    b_Browser.Caption=class'KFTab_MidGamePerks'.default.b_Browser.Caption;

    Super.InitComponent(MyController, MyOwner);

    //c_Main.AddTab(UserSPName, "ServerPerks.SRTab_UserSettings",,"User Settings");
    c_Main.AddTab(UserSPName, "ServerPerks.SRSettingsTab",,"User Settings");

    // Mod menus
    foreach MyController.ViewportOwner.Actor.DynamicActors(class'SRMenuAddition',M)
    if( M.bHasInit )
    {
    AddOnList[AddOnList.Length] = M;
    M.NotifyMenuOpen(Self,MyController);
    }

    s = GetSizingCaption();

    for ( i = 0; i < Controls.Length; i++ )
    {
    if ( GUIButton(Controls) != None )
    {
    GUIButton(Controls).bAutoSize = true;
    GUIButton(Controls).SizingCaption = s;
    GUIButton(Controls).AutoSizePadding.HorzPerc = 0.04;
    GUIButton(Controls).AutoSizePadding.VertPerc = 0.5;
    }
    }
    s = class'KFTab_MidGamePerks'.default.PlayerStyleName;
    PlayerStyle = MyController.GetStyle(s, fs);
    //KFPCServ(PlayerOwner()).ServerManualPickup(KFPCServ(PlayerOwner()).bManualPickup);
    InitGRI();
    }

    function Opened(GUIComponent Sender)
    {
    local int i;

    Super.Opened(Sender);
    for( i=0; i<AddOnList.Length; ++i )
    AddOnList.NotifyMenuShown();
    }
    event Closed(GUIComponent Sender, bool bCancelled)
    {
    local int i;

    Super.Closed(Sender,bCancelled);
    for( i=0; i<AddOnList.Length; ++i )
    AddOnList.NotifyMenuClosed();
    }

    function string GetSizingCaption()
    {
    local int i;
    local string s;

    for ( i = 0; i < Controls.Length; i++ )
    {
    if ( GUIButton(Controls) != none )
    {
    if ( s == "" || Len(GUIButton(Controls).Caption) > Len(s) )
    {
    s = GUIButton(Controls).Caption;
    }
    }
    }

    return s;
    }
    function GameReplicationInfo GetGRI()
    {
    return PlayerOwner().GameReplicationInfo;
    }

    function InitGRI()
    {
    local PlayerController PC;
    local GameReplicationInfo GRI;

    GRI = GetGRI();
    PC = PlayerOwner();

    if ( PC == none || PC.PlayerReplicationInfo == none || GRI == none )
    return;

    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();
    }
    function float ItemHeight(Canvas C)
    {
    local float XL, YL, H;
    local eFontScale f;

    f=FNS_Medium;

    PlayerStyle.TextSize(C, MSAT_Blurry, "Wqz, ", XL, H, F);

    if ( C.ClipX > 640 && bNetGame )
    PlayerStyle.TextSize(C, MSAT_Blurry, "Wqz, ", XL, YL, FNS_Small);

    H += YL;
    H += (H * 0.2);

    return h;
    }

    function SetupGroups()
    {
    local PlayerController PC;

    PC = PlayerOwner();

    if ( PC.Level.NetMode != NM_Client )
    {
    RemoveComponent(b_Favs);
    RemoveComponent(b_Browser);
    }
    else if ( CurrentServerIsInFavorites() )
    {
    DisableComponent(b_Favs);
    }

    if ( PC.Level.NetMode == NM_StandAlone )
    {
    RemoveComponent(b_MapVote, True);
    RemoveComponent(b_MatchSetup, True);
    RemoveComponent(b_KickVote, True);
    }
    else if ( PC.VoteReplicationInfo != None )
    {
    if ( !PC.VoteReplicationInfo.MapVoteEnabled() )
    {
    RemoveComponent(b_MapVote,True);
    }

    if ( !PC.VoteReplicationInfo.KickVoteEnabled() )
    {
    RemoveComponent(b_KickVote);
    }

    if ( !PC.VoteReplicationInfo.MatchSetupEnabled() )
    {
    RemoveComponent(b_MatchSetup);
    }
    }
    else
    {
    RemoveComponent(b_MapVote);
    RemoveComponent(b_KickVote);
    RemoveComponent(b_MatchSetup);
    }

    RemapComponents();
    }

    function SetButtonPositions(Canvas C)
    {
    local int i, j, ButtonsPerRow, ButtonsLeftInRow, NumButtons;
    local float Width, Height, Center, X, Y, YL, ButtonSpacing;

    Width = b_Settings.ActualWidth();
    Height = b_Settings.ActualHeight();
    Center = ActualLeft() + (ActualWidth() / 2.0);

    ButtonSpacing = Width * 0.05;
    YL = Height * 1.2;
    Y = b_Settings.ActualTop();

    ButtonsPerRow = ActualWidth() / (Width + ButtonSpacing);
    ButtonsLeftInRow = ButtonsPerRow;

    for ( i = 0; i < Components.Length; i++)
    {
    if ( Components.bVisible && GUIButton(Components) != none )
    {
    NumButtons++;
    }
    }

    if ( NumButtons < ButtonsPerRow )
    {
    X = Center - (((Width * float(NumButtons)) + (ButtonSpacing * float(NumButtons - 1))) * 0.5);
    }
    else if ( ButtonsPerRow > 1 )
    {
    X = Center - (((Width * float(ButtonsPerRow)) + (ButtonSpacing * float(ButtonsPerRow - 1))) * 0.5);
    }
    else
    {
    X = Center - Width / 2.0;
    }

    for ( i = 0; i < Components.Length; i++)
    {
    if ( !Components.bVisible || GUIButton(Components) == none )
    {
    continue;
    }

    Components.SetPosition( X, Y, Width, Height, true );

    if ( --ButtonsLeftInRow > 0 )
    {
    X += Width + ButtonSpacing;
    }
    else
    {
    Y += YL;

    for ( j = i + 1; j < Components.Length && ButtonsLeftInRow < ButtonsPerRow; j++)
    {
    if ( Components.bVisible && GUIButton(Components) != none )
    {
    ButtonsLeftInRow++;
    }
    }

    if ( ButtonsLeftInRow > 1 )
    {
    X = Center - (((Width * float(ButtonsLeftInRow)) + (ButtonSpacing * float(ButtonsLeftInRow - 1))) * 0.5);
    }
    else
    {
    X = Center - Width / 2.0;
    }
    }
    }
    }

    // See if we already have this server in our favorites
    function bool CurrentServerIsInFavorites()
    {
    local ExtendedConsole.ServerFavorite Fav;
    local string address,portString;

    // Get current network address
    if ( PlayerOwner() == None )
    return true;

    address = PlayerOwner().GetServerNetworkAddress();

    if( address == "" )
    return true; // slightly hacky - dont want to add "none"!

    // Parse text to find IP and possibly port number
    if ( Divide(address, ":", Fav.IP, portstring) )
    Fav.Port = int(portString);
    else Fav.IP = address;

    return class'KFConsole'.static.InFavorites(Fav);
    }
    function bool ButtonClicked(GUIComponent Sender)
    {
    local PlayerController PC;

    PC = PlayerOwner();

    if ( Sender == b_Settings )
    {
    // Settings
    Controller.OpenMenu(Controller.GetSettingsPage());
    }
    else if ( Sender == b_Browser )
    {
    // Server browser
    Controller.OpenMenu("KFGUI.KFServerBrowser");
    }
    else if ( Sender == b_Leave )
    {
    // Forfeit/Disconnect
    PC.ConsoleCommand("DISCONNECT");
    KFGUIController(Controller).ReturnToMainMenu();
    }
    else if ( Sender == b_Favs )
    {
    // Add this server to favorites
    PC.ConsoleCommand( "ADDCURRENTTOFAVORITES" );
    b_Favs.MenuStateChange(MSAT_Disabled);
    }
    else if ( Sender == b_Quit )
    {
    // Quit game
    Controller.OpenMenu(Controller.GetQuitPage());
    }
    else if ( Sender == b_MapVote )
    {
    // Map voting
    Controller.OpenMenu(Controller.MapVotingMenu);
    }
    else if ( Sender == b_KickVote )
    {
    // Kick voting
    Controller.OpenMenu(Controller.KickVotingMenu);
    }
    else if ( Sender == b_MatchSetup )
    {
    // Match setup
    Controller.OpenMenu(Controller.MatchSetupMenu);
    }
    else if ( Sender == b_Spec )
    {
    Controller.CloseMenu();

    // Spectate/rejoin
    if ( PC.PlayerReplicationInfo.bOnlySpectator )
    PC.BecomeActivePlayer();
    else PC.BecomeSpectator();
    }
    else if( Sender==b_Profile )
    {
    // Profile
    Controller.OpenMenu(string(Class'SRProfilePage'));
    }

    return true;
    }

    function bool InternalOnPreDraw(Canvas C)
    {
    local GameReplicationInfo GRI;
    local PlayerController PC;

    GRI = GetGRI();

    if ( GRI != none )
    {
    if ( bInit )
    InitGRI();

    SetButtonPositions(C);

    PC = PlayerOwner();
    if ( (PC.myHUD == None || !PC.myHUD.IsInCinematic()) && GRI != none && GRI.bMatchHasBegun && !PC.IsInState('GameEnded') )
    EnableComponent(b_Spec);
    else DisableComponent(b_Spec);

    if( PC.PlayerReplicationInfo!=None && bOldSpectator!=PC.PlayerReplicationInfo.bOnlySpectator )
    {
    bOldSpectator = !bOldSpectator;
    if ( bOldSpectator )
    b_Spec.Caption = class'KFTab_MidGamePerks'.default.JoinGameButtonText;
    else b_Spec.Caption = class'KFTab_MidGamePerks'.default.SpectateButtonText;
    }
    }
    return false;
    }
    function RemoveMultiplayerTabs(GameInfo Game);

    defaultproperties
    {
    Begin Object Class=GUIButton Name=SettingsButton
    WinTop=0.900000
    WinLeft=0.194420
    WinWidth=0.147268
    WinHeight=0.035000
    TabOrder=0
    bBoundToParent=True
    bScaleToParent=True
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=SettingsButton.InternalOnKeyEvent
    End Object
    b_Settings=GUIButton'ServerPerks.SRInvasionLoginMenu.SettingsButton'

    Begin Object Class=GUIButton Name=BrowserButton
    bAutoSize=True
    WinTop=0.850000
    WinLeft=0.375000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=1
    bBoundToParent=True
    bScaleToParent=True
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=BrowserButton.InternalOnKeyEvent
    End Object
    b_Browser=GUIButton'ServerPerks.SRInvasionLoginMenu.BrowserButton'

    Begin Object Class=GUIButton Name=QuitGameButton
    bAutoSize=True
    WinTop=0.870000
    WinLeft=0.725000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=50
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=QuitGameButton.InternalOnKeyEvent
    End Object
    b_Quit=GUIButton'ServerPerks.SRInvasionLoginMenu.QuitGameButton'

    Begin Object Class=GUIButton Name=FavoritesButton
    bAutoSize=True
    WinTop=0.870000
    WinLeft=0.025000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=2
    bBoundToParent=True
    bScaleToParent=True
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=FavoritesButton.InternalOnKeyEvent
    End Object
    b_Favs=GUIButton'ServerPerks.SRInvasionLoginMenu.FavoritesButton'

    Begin Object Class=GUIButton Name=LeaveMatchButton
    bAutoSize=True
    WinTop=0.870000
    WinLeft=0.725000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=49
    bBoundToParent=True
    bScaleToParent=True
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=LeaveMatchButton.InternalOnKeyEvent
    End Object
    b_Leave=GUIButton'ServerPerks.SRInvasionLoginMenu.LeaveMatchButton'

    Begin Object Class=GUIButton Name=MapVotingButton
    bAutoSize=True
    WinTop=0.890000
    WinLeft=0.025000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=3
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=MapVotingButton.InternalOnKeyEvent
    End Object
    b_MapVote=GUIButton'ServerPerks.SRInvasionLoginMenu.MapVotingButton'

    Begin Object Class=GUIButton Name=KickVotingButton
    bAutoSize=True
    WinTop=0.890000
    WinLeft=0.375000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=4
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=KickVotingButton.InternalOnKeyEvent
    End Object
    b_KickVote=GUIButton'ServerPerks.SRInvasionLoginMenu.KickVotingButton'

    Begin Object Class=GUIButton Name=MatchSetupButton
    bAutoSize=True
    WinTop=0.890000
    WinLeft=0.725000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=5
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=MatchSetupButton.InternalOnKeyEvent
    End Object
    b_MatchSetup=GUIButton'ServerPerks.SRInvasionLoginMenu.MatchSetupButton'

    Begin Object Class=GUIButton Name=SpectateButton
    bAutoSize=True
    WinTop=0.890000
    WinLeft=0.725000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=6
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=SpectateButton.InternalOnKeyEvent
    End Object
    b_Spec=GUIButton'ServerPerks.SRInvasionLoginMenu.SpectateButton'

    Begin Object Class=GUIButton Name=ProfileButton
    Caption="Profile"
    bAutoSize=True
    WinTop=0.890000
    WinLeft=0.725000
    WinWidth=0.200000
    WinHeight=0.050000
    TabOrder=7
    OnClick=SRInvasionLoginMenu.ButtonClicked
    OnKeyEvent=ProfileButton.InternalOnKeyEvent
    End Object
    b_Profile=GUIButton'ServerPerks.SRInvasionLoginMenu.ProfileButton'

    CurTabOrder=8
    Panels(0)=(Caption="News",Hint="View server news")
    Panels(4)=(Caption="Stats",Hint="View your current stats of this server")
    Panels(5)=(Caption="Settings",Hint="Set your server preferences")
    OnPreDraw=SRInvasionLoginMenu.InternalOnPreDraw
    UserSPName="User settings"
    }

    Class SRMySettings extends Object
    PerObjectConfig
    Config(MySettings);

    var private transient SRMySettings Ref;

    var config bool bAllowPickup;

    static final function SRMySettings GetSettings()
    {
    if( Default.Ref==None )
    Default.Ref = New(None,"Settings")Class'SRMySettings';
    return Default.Ref;
    }

    static final function string Get(string Setting)
    {
    local SRMySettings S;
    S = GetSettings();
    return S.GetPropertyText(Setting);
    }

    static final function Set(string Setting, string V)
    {
    local SRMySettings S;
    S = GetSettings();
    S.SetPropertyText(Setting,V);
    S.SaveConfig();
    }
    class SRPlayerReplicationInfo extends KFPlayerReplicationInfo;

    var string PlayerLocalTime;
    var float ExpMult, DamMult;
    var bool bCH, bDP, CanGrabWeapon;
    var Pickup LastItem;

    //Разрешаем поднимать пушки
    var bool bAllowPickup;
    //

    replication
    {
    reliable if ( bNetDirty && (Role == Role_Authority) )
    ExpMult, DamMult, bCH, bDP, CanGrabWeapon, LastItem;

    //Добавляем репликацию функции с клиента на сервер
    reliable if(Role < Role_Authority)
    SendSettingsToServer;
    }

    //Инициализация значения bAllowPickup из MySettings.ini файла клиента и отсылка значения на сервер.
    simulated function PostNetBeginPlay()
    {
    if(Role<Role_Authority)
    {
    bAllowPickup=bool(class'SRMySettings'.static.Get("bAllowPickup"));
    SendSettingsToServer("bAllowPickup",string(int(bAllowPickup)));
    }
    Super.PostNetBeginPlay();
    }

    simulated function PostBeginPlay()
    {
    SetTimer(1.0,true);
    Super.PostBeginPlay();
    }

    //Здесь я тоже сделал универсальную функцию, которая принимает 2 строки и использует SetPropertyText для изменения
    //значения переменной с названием Variable на значение заданное строкой bValue
    function SendSettingsToServer(string Variable, string bValue)
    {
    if(bNetOwner)
    SetPropertyText(Variable,bValue);
    }

    simulated function Timer()
    {
    local Controller C;

    if(((Owner != none) && Controller(Owner).Pawn != none) && LastItem != none)
    {
    if(Abs(Controller(Owner).Pawn.Location.X - LastItem.Location.X) > 5)
    {
    LastItem = none;
    }
    }
    CanGrabWeapon = false;
    UpdatePlayerLocation();
    C = Controller(Owner);
    if(C == none)
    {
    return;
    }
    if(C.Pawn == none)
    {
    PlayerHealth = 0;
    }
    else
    {
    PlayerHealth = C.Pawn.Health;
    }
    CanGrabWeapon = false;
    if(Role < ROLE_Authority)
    PlayerLocalTime=GetLocalTimeString();
    Super.Timer();
    }

    simulated function string GetLocalTimeString()
    {
    local string Hour,Minute,Second,result;
    Hour=string(Level.Hour);
    if(Level.Hour<10) Hour=0$Hour;
    Minute=string(Level.Minute);
    if(Level.Minute<10) Minute=0$Minute;
    Second=string(Level.Second);
    if(Level.Second<10) Second=0$Second;
    result=Hour$":"$Minute$":"$Second;
    return result;
    }
    class SRSettingsTab extends MidGamePanel;

    var automated automated moCheckBox checkBoxAllowPickup;

    var automated GUISectionBackground i_BG;


    function InitComponent(GUIController MyController, GUIComponent MyOwner)
    {
    Super.InitComponent(MyController, MyOwner);
    checkBoxAllowPickup.bChecked=bool(class'SRMySettings'.static.Get("bAllowPickup"));
    SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).SendSettingsToServer("bAllowPickup",string(int(checkBoxAllowPickup.bChecked)));
    SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bAllowPickup=checkBoxAllowPickup.bChecked;
    }

    function InternalOnChange( GUIComponent C )
    {
    if(C == checkBoxAllowPickup)
    {
    class'SRMySettings'.static.Set("bAllowPickup",string(int(checkBoxAllowPickup.bChecked)));
    SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).SendSettingsToServer("bAllowPickup",string(int(checkBoxAllowPickup.bChecked)));
    SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bAllowPickup=checkBoxAllowPickup.bChecked;
    }
    }

    defaultproperties
    {
    Begin Object Class=GUISectionBackground Name=BGSec
    bFillClient=True
    Caption="Settings"
    WinTop=0.015000
    WinLeft=0.250000
    WinWidth=0.500000
    WinHeight=0.410000
    RenderWeight=0.100100
    OnPreDraw=BGSec.InternalPreDraw
    End Object
    i_BG=BGSec

    Begin Object Class=moCheckBox Name=ManualPickupSteal
    CaptionWidth=0.955000
    Caption="Disable weapon stealing"
    OnCreateComponent=ManualPickupSteal.InternalOnCreateComponent
    IniOption="@Internal"
    Hint="Check this to disable players to pickup your weapons"
    WinTop=0.075000
    WinLeft=0.300000
    WinWidth=0.400000
    TabOrder=0
    OnChange=SRSettingsTab.InternalOnChange
    //OnLoadINI=SRSettingsTab.InternalOnLoadINI
    End Object
    checkBoxAllowPickup=ManualPickupSteal
    }
    ...
    function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
    {
    if( Controller(Other) !=None ) {
    Controller(Other).PlayerReplicationInfoClass=Class'SRPlayerReplicationInfo';
    }
    if( PlayerController(Other)!=None )
    {
    PendingPlayers[PendingPlayers.Length] = PlayerController(Other);
    SetTimer(0.1,false);
    PlayerController(Other).PlayerReplicationInfoClass=Class'SRPlayerReplicationInfo';
    }
    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;

    }
    ...
     
  7. Flame

    Flame -Заслуженый кодер форума-

    Во-первых поправь
    SRSettingsTab.InitComponent
    Код:
    function InitComponent(GUIController MyController, GUIComponent MyOwner)
    {
        Super.InitComponent(MyController, MyOwner);
        checkBoxAllowPickup.bChecked=SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bAllowPickup;
    }
    
    Я в шапке тоже поправлю - данный код более адекватный
    Но самое главное ты не кинул - сам мутатор OwnWeaponsMut
    А так вроде все нормально и успешно работает минимум на 3х серваках )
    Если с мутатором OwnWeaponsMut всё нормально будет и я не найду таки косяк - напишу куда добавить логи и сразу будет всё ясно
     
  8. Krasi

    Krasi Новенький

    Я не изменял OwnWeaponsMut и поэтому я его тут не постил
    Я начну над этим работать и дам знать в чем проблема, спасибо за помощь!
     
  9. Krasi

    Krasi Новенький

    Проблема в том, что если у поставлю маркер на Allow weapon pickup, то INI файл в System не изменяется на true. Еще, я как будто использую OwnWeaponsMut только без ServerPerks, так что никто не может подобрать иое оружие, не знаю почему.

    Код:
    class OwnWeaponsMut extends Mutator;
    
    var array<WeaponPickup> PendingPickups;
    var OwnWeaponsRules Rules;
    
    function PostBeginPlay()
    {
        if(Rules==None)
            Rules=Spawn(Class'OwnWeaponsRules');
    }
    
    //Отлавливаем новые WeaponPickup, даём 0.1 секунду на инициализацию необходимых нам переменных и зовём Rules.AddPickup в таймере
    //Если WeaponPickup являются теми, что изначально валяются на карте - они не будут добавлены в массив. У них нет владельца
    function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
    {
        if(WeaponPickup(Other)!=None)
        {
            PendingPickups[PendingPickups.Length] = WeaponPickup(Other);
            SetTimer(0.1,false);
        }
        return true;
    }
    function Timer()
    {
        local int i;
        for(i=0;i<PendingPickups.Length;i++)
        {
            if(PendingPickups[i]!=None)
                Rules.AddPickup(PendingPickups[i]);
        }
        PendingPickups.Length = 0;
    }
    
    defaultproperties
    {
        GroupName="KF-OwnWeapons"
        FriendlyName="OwnWeaponsMut"
        Description="OwnWeaponsMut"
    }
    Код:
    class OwnWeaponsRules extends GameRules;
    
    struct PickupInfo
    {
        var string ID;
        var string PlayerName;
        var WeaponPickup P;
    };
    var array<PickupInfo> OwnedPickups;
    //Нельзя на кириллице писать в коде. Только в defaultproperties. Поэтому если хотим написать что по-русски делаем переменную.
    var string rusMessage;
    
    //Стандартные функции GameRules
    function PostBeginPlay()
    {
        if(Level.Game.GameRulesModifiers == none)
            Level.Game.GameRulesModifiers = self;
        else
            Level.Game.GameRulesModifiers.AddGameRules(self);
    }
    function AddGameRules(GameRules GR)
    {
        if(GR != self)
            super.AddGameRules(GR);
    }
    //
    
    //Flame. Здесь мы отслеживаем смерть игрока и ставим свойство bIsTier2Weapon=false его текущей пушке
    //Тут некоторый финт получается. Если bIsTier2Weapon=false, то у KFWeaponPickup класса заполняется свойство
    //DroppedBy при выкидывании - функция KFWeaponPickup.InitDroppedPickupFor.
    //А это поможет нам получить контроллер владельца после смерти владельца. Pawn.Controller то уже None и обычный способ не катит.
    //В принципе можно было бы всем пушкам сразу ставить это свойство (в CheckReplacement, например)
    //Оно относится к стим ачивкам и в общем то нам безразлично. Всё равно мутатор не белый и никаких стим ачивок небось не ожидается
    //Тогда можно было бы работать в едином стиле с KFWeaponPickup объектами и отслеживать только DroppedBy
    //Ну почему-то хочется мне пока сделать так как сделано. Вроде как с минимальными вмешательствами
    function bool PreventDeath(Pawn Killed, Controller Killer, class<DamageType> damageType, vector HitLocation)
    {
        if    (
                Killed.IsA('KFHumanPawn')
                &&    Killed.Controller!=none
                &&    Killed.Controller.IsA('PlayerController')
            )
        {
            KFWeapon(Killed.Weapon).bIsTier2Weapon=false;
        }
        if(NextGameRules!=None)
            return NextGameRules.PreventDeath(Killed,Killer, damageType,HitLocation);
        return false;
    }
    
    //Flame. В общем то базовая функция на которой держится мутатор. Если out переменная bAllowPickup=0 и
    //функция возвращается true - значит мы переопределяем процесс поднятия пушки и запрещаем поднятие.
    //Если функция возвращает false - нам пофиг на значение переменной bAllowPickup, функция как будто бы и не вызывалась
    //То есть мы проверяем что поднимаем пушку, проверяем можем ли мы её поднимать. Если да, то false и функции как будто бы и не было.
    //Если true, то глядим на bAllowPickup. Оно тут 0, значит запрещаем поднимать.
    function bool OverridePickupQuery(Pawn Other, Pickup Item, out byte bAllowPickup)
    {
        if(WeaponPickup(Item)!=None && Other.Controller!=None)
        {
            bAllowPickup = 0;
            if(CanTakeItem(Other.Controller,Item))
            {
                if(NextGameRules!=None)
                    return NextGameRules.OverridePickupQuery(Other, Item, bAllowPickup);
                return false;
            }
            return true;
        }
        if(NextGameRules!=None)
            return NextGameRules.OverridePickupQuery(Other, Item, bAllowPickup);
        return false;
    }
    //Flame. Функция проверяет принадлежит ли кому-то пушка и если да, то принадлежит ли она нам
    function bool CanTakeItem(Controller C, Pickup WP)
    {
        local int i;
        local PlayerController PC;
        PC=PlayerController(C);
        if(PC==none)
            return false;
        for(i=0;i<OwnedPickups.Length;i++)
        {
            if(OwnedPickups[i].P==WP)
            {
                if(OwnedPickups[i].ID==PC.GetPlayerIDHash() || WeaponPickupIsAllowed(OwnedPickups[i].ID))
                    return true;
                PC.ClientMessage("This weapon is owned by /"@rusMessage@OwnedPickups[i].PlayerName);
                return false;
            }
        }
        return true;
    }
    
    //Flame. Проверяем - не разрешил ли владелец поднимать пушки
    function bool WeaponPickupIsAllowed(string Hash)
    {
        local Controller C;
        for( C = Level.ControllerList; C != None; C = C.nextController )
        {
            if(C.IsA('PlayerController') && C.PlayerReplicationInfo.PlayerID>0)
            {
                if    (
                        PlayerController(C).GetPlayerIDHash()~=Hash
                        &&    bool(C.PlayerReplicationInfo.GetPropertyText("bAllowPickup"))
                    )
                {
                    return true;
                }
            }
        }
        return false;
    }
    
    //Flame. Функция вызывается, когда на карте появляется новый WeaponPickup объект. Если у неё есть владелец - она заносится в массив.
    //WeaponPickup добавляется в массив либо если Instigator.Controller пушки не None (при обычном выкидывании)
    //Либо если DroppedBy не None, при посмертном выкидывании пушки
    //По-хорошему надо бы чистить этот массив. В том же таймере пробегать по всем WeaponPickup и глядеть каких уже нет в OwnedPickups
    //Но у меня не было целью сделать оптимизированный код, акцент был на простоте и лаконичности). Так что сами можете это поправить.
    function AddPickup(WeaponPickup WP)
    {
        local PlayerController PC;
        local PickupInfo pi;
        if(WP==none || WP.Instigator==none)
            return;
        PC=PlayerController(WP.Instigator.Controller);
        //Отслеживаем пушку выпавшую из рук трупа
        if(PC==None)
            PC=KFWeaponPickup(WP).DroppedBy;
        //
        if(PC==None)
            return;
        pi.P=WP;
        pi.ID=PC.GetPlayerIDHash();
        pi.PlayerName=PC.PlayerReplicationInfo.PlayerName;
        OwnedPickups[OwnedPickups.Length] = pi;
    }
    
    defaultproperties
    {
        rusMessage=""
    }
    Код:
    Class SRInvasionLoginMenu extends UT2K4PlayerLoginMenu;
    
    var() noexport  bool                    bNetGame;
    var bool bOldSpectator;
    
    var automated   GUIButton               b_Settings, b_Browser, b_Quit, b_Favs,
                                            b_Leave, b_MapVote, b_KickVote, b_MatchSetup, b_Spec, b_Profile;
    var             GUIStyles               PlayerStyle;
    var array<SRMenuAddition>                AddOnList;
    var int                                    CurTabOrder;
    var localized string UserSPName;
    
    simulated final function GUIButton AddControlButton( string Cap, optional string Hint )
    {
        local GUIButton G;
      
        G = GUIButton(AddComponent(string(Class'GUIButton')));
        G.Caption = Cap;
        G.Hint = Hint;
        G.StyleName = "SquareButton";
        G.OnKeyEvent = G.InternalOnKeyEvent;
        G.WinLeft = 0.725;
        G.WinTop = 0.89;
        G.WinWidth = 0.2;
        G.WinHeight = 0.05;
        G.bAutoSize = True;
        G.TabOrder = CurTabOrder++;
        return G;
    }
    
    function InitComponent(GUIController MyController, GUIComponent MyOwner)
    {
        local int i;
        local string s;
        local eFontScale FS;
        local SRMenuAddition M;
    
        // Setup panel classes.
        Panels[0].ClassName = string(Class'SRTab_ServerNews');
        Panels[1].ClassName = string(Class'SRTab_MidGamePerks');
        Panels[2].ClassName = string(Class'SRTab_MidGameVoiceChat');
        Panels[3].ClassName = string(Class'SRTab_MidGameHelp');
        Panels[4].ClassName = string(Class'SRTab_MidGameStats');
        Panels[5].ClassName = string(Class'SRSettingsTab');
    
        // Setup localization.
        Panels[1].Caption = Class'KFInvasionLoginMenu'.Default.Panels[1].Caption;
        Panels[2].Caption = Class'KFInvasionLoginMenu'.Default.Panels[2].Caption;
        Panels[3].Caption = Class'KFInvasionLoginMenu'.Default.Panels[3].Caption;
        Panels[1].Hint = Class'KFInvasionLoginMenu'.Default.Panels[1].Hint;
        Panels[2].Hint = Class'KFInvasionLoginMenu'.Default.Panels[2].Hint;
        Panels[3].Hint = Class'KFInvasionLoginMenu'.Default.Panels[3].Hint;
        b_Spec.Caption=class'KFTab_MidGamePerks'.default.b_Spec.Caption;
        b_MatchSetup.Caption=class'KFTab_MidGamePerks'.default.b_MatchSetup.Caption;
        b_KickVote.Caption=class'KFTab_MidGamePerks'.default.b_KickVote.Caption;
        b_MapVote.Caption=class'KFTab_MidGamePerks'.default.b_MapVote.Caption;
        b_Quit.Caption=class'KFTab_MidGamePerks'.default.b_Quit.Caption;
        b_Favs.Caption=class'KFTab_MidGamePerks'.default.b_Favs.Caption;
        b_Favs.Hint=class'KFTab_MidGamePerks'.default.b_Favs.Hint;
        b_Settings.Caption=class'KFTab_MidGamePerks'.default.b_Settings.Caption;
        b_Browser.Caption=class'KFTab_MidGamePerks'.default.b_Browser.Caption;
    
         Super.InitComponent(MyController, MyOwner);
      
        //c_Main.AddTab(UserSPName, "ServerPerks.SRTab_UserSettings",,"User Settings");
    c_Main.AddTab(UserSPName, "ServerPerks.SRSettingsTab",,"User Settings");
    
        // Mod menus
        foreach MyController.ViewportOwner.Actor.DynamicActors(class'SRMenuAddition',M)
            if( M.bHasInit )
            {
                AddOnList[AddOnList.Length] = M;
                M.NotifyMenuOpen(Self,MyController);
            }
    
           s = GetSizingCaption();
    
        for ( i = 0; i < Controls.Length; i++ )
        {
            if ( GUIButton(Controls[i]) != None )
            {
                GUIButton(Controls[i]).bAutoSize = true;
                GUIButton(Controls[i]).SizingCaption = s;
                GUIButton(Controls[i]).AutoSizePadding.HorzPerc = 0.04;
                GUIButton(Controls[i]).AutoSizePadding.VertPerc = 0.5;
            }
        }
        s = class'KFTab_MidGamePerks'.default.PlayerStyleName;
        PlayerStyle = MyController.GetStyle(s, fs);
        //KFPCServ(PlayerOwner()).ServerManualPickup(KFPCServ(PlayerOwner()).bManualPickup);
        InitGRI();
    }
    
    function Opened(GUIComponent Sender)
    {
        local int i;
    
        Super.Opened(Sender);
        for( i=0; i<AddOnList.Length; ++i )
            AddOnList[i].NotifyMenuShown();
    }
    event Closed(GUIComponent Sender, bool bCancelled)
    {
        local int i;
    
        Super.Closed(Sender,bCancelled);
        for( i=0; i<AddOnList.Length; ++i )
            AddOnList[i].NotifyMenuClosed();
    }
    
    function string GetSizingCaption()
    {
        local int i;
        local string s;
    
        for ( i = 0; i < Controls.Length; i++ )
        {
            if ( GUIButton(Controls[i]) != none )
            {
                if ( s == "" || Len(GUIButton(Controls[i]).Caption) > Len(s) )
                {
                    s = GUIButton(Controls[i]).Caption;
                }
            }
        }
    
        return s;
    }
    function GameReplicationInfo GetGRI()
    {
        return PlayerOwner().GameReplicationInfo;
    }
    
    function InitGRI()
    {
        local PlayerController PC;
        local GameReplicationInfo GRI;
    
        GRI = GetGRI();
        PC = PlayerOwner();
    
        if ( PC == none || PC.PlayerReplicationInfo == none || GRI == none )
            return;
    
        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();
    }
    function float ItemHeight(Canvas C)
    {
        local float XL, YL, H;
        local eFontScale f;
    
        f=FNS_Medium;
    
        PlayerStyle.TextSize(C, MSAT_Blurry, "Wqz, ", XL, H, F);
    
        if ( C.ClipX > 640 && bNetGame )
            PlayerStyle.TextSize(C, MSAT_Blurry, "Wqz, ", XL, YL, FNS_Small);
    
        H += YL;
        H += (H * 0.2);
    
        return h;
    }
    
    function SetupGroups()
    {
        local PlayerController PC;
    
        PC = PlayerOwner();
    
        if ( PC.Level.NetMode != NM_Client )
        {
            RemoveComponent(b_Favs);
            RemoveComponent(b_Browser);
        }
        else if ( CurrentServerIsInFavorites() )
        {
            DisableComponent(b_Favs);
        }
    
        if ( PC.Level.NetMode == NM_StandAlone )
        {
            RemoveComponent(b_MapVote, True);
            RemoveComponent(b_MatchSetup, True);
            RemoveComponent(b_KickVote, True);
        }
        else if ( PC.VoteReplicationInfo != None )
        {
            if ( !PC.VoteReplicationInfo.MapVoteEnabled() )
            {
                RemoveComponent(b_MapVote,True);
            }
    
            if ( !PC.VoteReplicationInfo.KickVoteEnabled() )
            {
                RemoveComponent(b_KickVote);
            }
    
            if ( !PC.VoteReplicationInfo.MatchSetupEnabled() )
            {
                RemoveComponent(b_MatchSetup);
            }
        }
        else
        {
            RemoveComponent(b_MapVote);
            RemoveComponent(b_KickVote);
            RemoveComponent(b_MatchSetup);
        }
    
        RemapComponents();
    }
    
    function SetButtonPositions(Canvas C)
    {
        local int i, j, ButtonsPerRow, ButtonsLeftInRow, NumButtons;
        local float Width, Height, Center, X, Y, YL, ButtonSpacing;
    
        Width = b_Settings.ActualWidth();
        Height = b_Settings.ActualHeight();
        Center = ActualLeft() + (ActualWidth() / 2.0);
    
        ButtonSpacing = Width * 0.05;
        YL = Height * 1.2;
        Y = b_Settings.ActualTop();
    
        ButtonsPerRow = ActualWidth() / (Width + ButtonSpacing);
        ButtonsLeftInRow = ButtonsPerRow;
    
        for ( i = 0; i < Components.Length; i++)
        {
            if ( Components[i].bVisible && GUIButton(Components[i]) != none )
            {
                NumButtons++;
            }
        }
    
        if ( NumButtons < ButtonsPerRow )
        {
            X = Center - (((Width * float(NumButtons)) + (ButtonSpacing * float(NumButtons - 1))) * 0.5);
        }
        else if ( ButtonsPerRow > 1 )
        {
            X = Center - (((Width * float(ButtonsPerRow)) + (ButtonSpacing * float(ButtonsPerRow - 1))) * 0.5);
        }
        else
        {
            X = Center - Width / 2.0;
        }
    
        for ( i = 0; i < Components.Length; i++)
        {
            if ( !Components[i].bVisible || GUIButton(Components[i]) == none )
            {
                continue;
            }
    
            Components[i].SetPosition( X, Y, Width, Height, true );
    
            if ( --ButtonsLeftInRow > 0 )
            {
                X += Width + ButtonSpacing;
            }
            else
            {
                Y += YL;
    
                for ( j = i + 1; j < Components.Length && ButtonsLeftInRow < ButtonsPerRow; j++)
                {
                    if ( Components[i].bVisible && GUIButton(Components[i]) != none )
                    {
                        ButtonsLeftInRow++;
                    }
                }
    
                if ( ButtonsLeftInRow > 1 )
                {
                    X = Center - (((Width * float(ButtonsLeftInRow)) + (ButtonSpacing * float(ButtonsLeftInRow - 1))) * 0.5);
                }
                else
                {
                    X = Center - Width / 2.0;
                }
            }
        }
    }
    
    // See if we already have this server in our favorites
    function bool CurrentServerIsInFavorites()
    {
        local ExtendedConsole.ServerFavorite Fav;
        local string address,portString;
    
        // Get current network address
        if ( PlayerOwner() == None )
            return true;
    
        address = PlayerOwner().GetServerNetworkAddress();
    
        if( address == "" )
            return true; // slightly hacky - dont want to add "none"!
    
        // Parse text to find IP and possibly port number
        if ( Divide(address, ":", Fav.IP, portstring) )
            Fav.Port = int(portString);
        else Fav.IP = address;
    
        return class'KFConsole'.static.InFavorites(Fav);
    }
    function bool ButtonClicked(GUIComponent Sender)
    {
        local PlayerController PC;
        PC = PlayerOwner();
    
        if ( Sender == b_Settings )
        {
            // Settings
            Controller.OpenMenu(Controller.GetSettingsPage());
        }
        else if ( Sender == b_Browser )
        {
            // Server browser
            Controller.OpenMenu("KFGUI.KFServerBrowser");
        }
        else if ( Sender == b_Leave )
        {
            // Forfeit/Disconnect
            PC.ConsoleCommand("DISCONNECT");
            KFGUIController(Controller).ReturnToMainMenu();
        }
        else if ( Sender == b_Favs )
        {
            // Add this server to favorites
            PC.ConsoleCommand( "ADDCURRENTTOFAVORITES" );
            b_Favs.MenuStateChange(MSAT_Disabled);
        }
        else if ( Sender == b_Quit )
        {
            // Quit game
            Controller.OpenMenu(Controller.GetQuitPage());
        }
        else if ( Sender == b_MapVote )
        {
            // Map voting
            Controller.OpenMenu(Controller.MapVotingMenu);
        }
        else if ( Sender == b_KickVote )
        {
            // Kick voting
            Controller.OpenMenu(Controller.KickVotingMenu);
        }
        else if ( Sender == b_MatchSetup )
        {
            // Match setup
            Controller.OpenMenu(Controller.MatchSetupMenu);
        }
        else if ( Sender == b_Spec )
        {
            Controller.CloseMenu();
    
            // Spectate/rejoin
            if ( PC.PlayerReplicationInfo.bOnlySpectator )
                PC.BecomeActivePlayer();
            else PC.BecomeSpectator();
        }
        else if( Sender==b_Profile )
        {
            // Profile
            Controller.OpenMenu(string(Class'SRProfilePage'));
        }
      
        return true;
    }
    
    function bool InternalOnPreDraw(Canvas C)
    {
        local GameReplicationInfo GRI;
        local PlayerController PC;
    
        GRI = GetGRI();
    
        if ( GRI != none )
        {
            if ( bInit )
                InitGRI();
    
            SetButtonPositions(C);
    
            PC = PlayerOwner();
            if ( (PC.myHUD == None || !PC.myHUD.IsInCinematic()) && GRI != none && GRI.bMatchHasBegun && !PC.IsInState('GameEnded') )
                EnableComponent(b_Spec);
            else DisableComponent(b_Spec);
          
            if( PC.PlayerReplicationInfo!=None && bOldSpectator!=PC.PlayerReplicationInfo.bOnlySpectator )
            {
                bOldSpectator = !bOldSpectator;
                if ( bOldSpectator )
                    b_Spec.Caption = class'KFTab_MidGamePerks'.default.JoinGameButtonText;
                else b_Spec.Caption = class'KFTab_MidGamePerks'.default.SpectateButtonText;
            }
        }
        return false;
    }
    function RemoveMultiplayerTabs(GameInfo Game);
    
    defaultproperties
    {
         Begin Object Class=GUIButton Name=SettingsButton
             WinTop=0.900000
             WinLeft=0.194420
             WinWidth=0.147268
             WinHeight=0.035000
             TabOrder=0
             bBoundToParent=True
             bScaleToParent=True
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=SettingsButton.InternalOnKeyEvent
         End Object
         b_Settings=GUIButton'ServerPerks.SRInvasionLoginMenu.SettingsButton'
    
         Begin Object Class=GUIButton Name=BrowserButton
             bAutoSize=True
             WinTop=0.850000
             WinLeft=0.375000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=1
             bBoundToParent=True
             bScaleToParent=True
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=BrowserButton.InternalOnKeyEvent
         End Object
         b_Browser=GUIButton'ServerPerks.SRInvasionLoginMenu.BrowserButton'
    
         Begin Object Class=GUIButton Name=QuitGameButton
             bAutoSize=True
             WinTop=0.870000
             WinLeft=0.725000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=50
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=QuitGameButton.InternalOnKeyEvent
         End Object
         b_Quit=GUIButton'ServerPerks.SRInvasionLoginMenu.QuitGameButton'
    
         Begin Object Class=GUIButton Name=FavoritesButton
             bAutoSize=True
             WinTop=0.870000
             WinLeft=0.025000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=2
             bBoundToParent=True
             bScaleToParent=True
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=FavoritesButton.InternalOnKeyEvent
         End Object
         b_Favs=GUIButton'ServerPerks.SRInvasionLoginMenu.FavoritesButton'
    
         Begin Object Class=GUIButton Name=LeaveMatchButton
             bAutoSize=True
             WinTop=0.870000
             WinLeft=0.725000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=49
             bBoundToParent=True
             bScaleToParent=True
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=LeaveMatchButton.InternalOnKeyEvent
         End Object
         b_Leave=GUIButton'ServerPerks.SRInvasionLoginMenu.LeaveMatchButton'
    
         Begin Object Class=GUIButton Name=MapVotingButton
             bAutoSize=True
             WinTop=0.890000
             WinLeft=0.025000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=3
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=MapVotingButton.InternalOnKeyEvent
         End Object
         b_MapVote=GUIButton'ServerPerks.SRInvasionLoginMenu.MapVotingButton'
    
         Begin Object Class=GUIButton Name=KickVotingButton
             bAutoSize=True
             WinTop=0.890000
             WinLeft=0.375000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=4
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=KickVotingButton.InternalOnKeyEvent
         End Object
         b_KickVote=GUIButton'ServerPerks.SRInvasionLoginMenu.KickVotingButton'
    
         Begin Object Class=GUIButton Name=MatchSetupButton
             bAutoSize=True
             WinTop=0.890000
             WinLeft=0.725000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=5
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=MatchSetupButton.InternalOnKeyEvent
         End Object
         b_MatchSetup=GUIButton'ServerPerks.SRInvasionLoginMenu.MatchSetupButton'
    
         Begin Object Class=GUIButton Name=SpectateButton
             bAutoSize=True
             WinTop=0.890000
             WinLeft=0.725000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=6
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=SpectateButton.InternalOnKeyEvent
         End Object
         b_Spec=GUIButton'ServerPerks.SRInvasionLoginMenu.SpectateButton'
    
         Begin Object Class=GUIButton Name=ProfileButton
             Caption="Profile"
             bAutoSize=True
             WinTop=0.890000
             WinLeft=0.725000
             WinWidth=0.200000
             WinHeight=0.050000
             TabOrder=7
             OnClick=SRInvasionLoginMenu.ButtonClicked
             OnKeyEvent=ProfileButton.InternalOnKeyEvent
         End Object
         b_Profile=GUIButton'ServerPerks.SRInvasionLoginMenu.ProfileButton'
    
         CurTabOrder=8
         Panels(0)=(Caption="News",Hint="View server news")
         Panels(4)=(Caption="Stats",Hint="View your current stats of this server")
    Panels(5)=(Caption="Settings",Hint="Set your server preferences")
         OnPreDraw=SRInvasionLoginMenu.InternalOnPreDraw    
    UserSPName="User settings"
    }
    
    Код:
    Class SRMySettings extends Object
        PerObjectConfig
        Config(MySettings);
    
    var private transient SRMySettings Ref;
    
    var config bool bAllowPickup;
    
    static final function SRMySettings GetSettings()
    {
        if( Default.Ref==None )
            Default.Ref = New(None,"Settings")Class'SRMySettings';
        return Default.Ref;
    }
    
    static final function string Get(string Setting)
    {
        local SRMySettings S;
        S = GetSettings();
        return S.GetPropertyText(Setting);
    }
    
    static final function Set(string Setting, string V)
    {
        local SRMySettings S;
        S = GetSettings();
        S.SetPropertyText(Setting,V);
        S.SaveConfig();
    }
    Код:
    class SRPlayerReplicationInfo extends KFPlayerReplicationInfo;
    
    var string PlayerLocalTime;
    var float ExpMult, DamMult;
    var bool bCH, bDP, CanGrabWeapon;
    var Pickup LastItem;
    
    //Разрешаем поднимать пушки
    var bool bAllowPickup;
    //
    
    replication
    {
        reliable if ( bNetDirty && (Role == Role_Authority) )
            ExpMult, DamMult, bCH, bDP, CanGrabWeapon, LastItem;
    
        //Добавляем репликацию функции с клиента на сервер
        reliable if(Role < Role_Authority)
            SendSettingsToServer;
    }
    
    //Инициализация значения bAllowPickup из MySettings.ini файла клиента и отсылка значения на сервер.
    simulated function PostNetBeginPlay()
    {
        if(Role<Role_Authority)
        {
            bAllowPickup=bool(class'SRMySettings'.static.Get("bAllowPickup"));
            SendSettingsToServer("bAllowPickup",string(int(bAllowPickup)));
        }
        Super.PostNetBeginPlay();
    }
    
    simulated function PostBeginPlay()
    {
        SetTimer(1.0,true);
        Super.PostBeginPlay();
    }
    
    //Здесь я тоже сделал универсальную функцию, которая принимает 2 строки и использует SetPropertyText для изменения
    //значения переменной с названием Variable на значение заданное строкой bValue
    function SendSettingsToServer(string Variable, string bValue)
    {
        if(bNetOwner)
            SetPropertyText(Variable,bValue);
    }
    
    simulated function Timer()
    {
        local Controller C;
    
        if(((Owner != none) && Controller(Owner).Pawn != none) && LastItem != none)
        {
            if(Abs(Controller(Owner).Pawn.Location.X - LastItem.Location.X) > 5)
            {
                LastItem = none;
            }
        }
        CanGrabWeapon = false;
        UpdatePlayerLocation();
        C = Controller(Owner);
        if(C == none)
        {
            return;
        }
        if(C.Pawn == none)
        {
            PlayerHealth = 0;
        }
        else
        {
            PlayerHealth = C.Pawn.Health;
        }
        CanGrabWeapon = false;
        if(Role < ROLE_Authority)
            PlayerLocalTime=GetLocalTimeString();
        Super.Timer();
    }
    
    simulated function string GetLocalTimeString()
    {
        local string Hour,Minute,Second,result;
        Hour=string(Level.Hour);
        if(Level.Hour<10) Hour=0$Hour;
        Minute=string(Level.Minute);
        if(Level.Minute<10) Minute=0$Minute;
        Second=string(Level.Second);
        if(Level.Second<10) Second=0$Second;
        result=Hour$":"$Minute$":"$Second;
        return result;
    }
    Код:
    class SRSettingsTab extends MidGamePanel;
    
    var automated automated moCheckBox checkBoxAllowPickup;
    
    var automated GUISectionBackground i_BG;
    
    function InitComponent(GUIController MyController, GUIComponent MyOwner)
    {
        Super.InitComponent(MyController, MyOwner);
        checkBoxAllowPickup.bChecked=SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bAllowPickup;
    }
    
    /* Old
    function InitComponent(GUIController MyController, GUIComponent MyOwner)
    {
        Super.InitComponent(MyController, MyOwner);
        checkBoxAllowPickup.bChecked=bool(class'SRMySettings'.static.Get("bAllowPickup"));
        SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).SendSettingsToServer("bAllowPickup",string(int(checkBoxAllowPickup.bChecked)));
        SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bAllowPickup=checkBoxAllowPickup.bChecked;
    }
    */
    
    function InternalOnChange( GUIComponent C )
    {
        if(C == checkBoxAllowPickup)
        {
            class'SRMySettings'.static.Set("bAllowPickup",string(int(checkBoxAllowPickup.bChecked)));
            SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).SendSettingsToServer("bAllowPickup",string(int(checkBoxAllowPickup.bChecked)));
            SRPlayerReplicationInfo(PlayerOwner().PlayerReplicationInfo).bAllowPickup=checkBoxAllowPickup.bChecked;
        }
    }
    
    defaultproperties
    {
        Begin Object Class=GUISectionBackground Name=BGSec
             bFillClient=True
             Caption="Settings"
             WinTop=0.015000
             WinLeft=0.250000
             WinWidth=0.500000
             WinHeight=0.410000
             RenderWeight=0.100100
             OnPreDraw=BGSec.InternalPreDraw
        End Object
        i_BG=BGSec
      
        Begin Object Class=moCheckBox Name=ManualPickupSteal
             CaptionWidth=0.955000
             Caption="Disable weapon stealing"
             OnCreateComponent=ManualPickupSteal.InternalOnCreateComponent
             IniOption="@Internal"
             Hint="Check this to disable players to pickup your weapons"
             WinTop=0.075000
             WinLeft=0.300000
             WinWidth=0.400000
             TabOrder=0
             OnChange=SRSettingsTab.InternalOnChange
             //OnLoadINI=SRSettingsTab.InternalOnLoadINI
         End Object
         checkBoxAllowPickup=ManualPickupSteal
    }
    
    Код:
    ServerPerksMut.uc
    
    ...
    function bool CheckReplacement(Actor Other, out byte bSuperRelevant)
    {
        if( Controller(Other) !=None ) {
            Controller(Other).PlayerReplicationInfoClass=Class'SRPlayerReplicationInfo';
        }
        if( PlayerController(Other)!=None )
        {
            PendingPlayers[PendingPlayers.Length] = PlayerController(Other);
            SetTimer(0.1,false);
            PlayerController(Other).PlayerReplicationInfoClass=Class'SRPlayerReplicationInfo';
        }
        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;
    }
    ...
     
    Последнее редактирование: 4 фев 2017
  10. Flame

    Flame -Заслуженый кодер форума-

    Да ты то может и не изменял, но в теме используется несколько мутаторов, может ты по ошибке скачал не ту версию)
    Именно это я и хотел глянуть
    Дак о том и речь) Ты точно используешь SP версию?
    Ну я могу создать чистый сервак с SP и этим мутатором и ты убедишься, что он работает
    А потом можешь поискать в чём разница между реализациями, как ещё тебе помочь я не знаю)