Class ClientPerkRepLink extends LinkedReplicationInfo DependsOn(SRHUDKillingFloor); var int RDamageHealedStat, RWeldingPointsStat, RShotgunDamageStat, RHeadshotKillsStat, RChainsawKills, RStalkerKillsStat, RBullpupDamageStat, RMeleeDamageStat, RFlameThrowerDamageStat,RTotalZedTimeStat, RSelfHealsStat, RSoleSurvivorWavesStat, RCashDonatedStat, RFeedingKillsStat,RHuntingShotgunKills, RBurningCrossbowKillsStat, RGibbedFleshpoundsStat, RStalkersKilledWithExplosivesStat, RGibbedEnemiesStat, RBloatKillsStat, RSirenKillsStat, RKillsStat, RMedicKnifeKills, RExplosivesDamageStat, TotalPlayTime, WinsCount, LostsCount; var byte MinimumLevel,MaximumLevel; var float NextRepTime,RequirementScaling; var int ClientAccknowledged[2],SendIndex,ClientAckSkinNum; struct FPerksListType { var class PerkClass; var byte CurrentLevel; }; var array CachePerks; var SRStatsBase StatObject; struct FShopItemIndex { var class PC; var byte CatNum,bDLCLocked; }; struct FShopCategoryIndex { var string Name; var byte PerkIndex; }; var array ShopInventory; var array ShopPerkIcons; var array ShopCategories; var array CustomChars; var array AllocatedObjects; var array SmileyTags; var int CurrentPerkProgress; var KFPlayerReplicationInfo OwnerPRI; var SRCustomProgress CustomLink; var string ServerWebSite,UserID; var bool bMinimalRequirements,bBWZEDTime,bNoStandardChars,bReceivedURL,bRepCompleted; replication { reliable if( Role==ROLE_Authority && bNetOwner ) RDamageHealedStat, RWeldingPointsStat, RShotgunDamageStat, RHeadshotKillsStat, RChainsawKills, RStalkerKillsStat, RBullpupDamageStat, RMeleeDamageStat, RFlameThrowerDamageStat, RSelfHealsStat, RSoleSurvivorWavesStat, RCashDonatedStat, RFeedingKillsStat, RHuntingShotgunKills, RBurningCrossbowKillsStat, RGibbedFleshpoundsStat, RStalkersKilledWithExplosivesStat, RExplosivesDamageStat, RGibbedEnemiesStat, RBloatKillsStat, RTotalZedTimeStat, RSirenKillsStat, RKillsStat, RMedicKnifeKills, TotalPlayTime, WinsCount, LostsCount, bBWZEDTime, bNoStandardChars, MinimumLevel, RequirementScaling, MaximumLevel, bMinimalRequirements,CustomLink; // Functions server can call. reliable if( Role == ROLE_Authority ) ClientReceivePerk,ClientPerkLevel,ClientReceiveWeapon,ClientSendAcknowledge,ClientReceiveCategory, ClientReceiveChar,ClientReceiveTag,ClientAllReceived,ClientReceiveURL; reliable if( Role < ROLE_Authority ) ServerSelectPerk,ServerRequestPerks,ServerAcnowledge,ServerSetCharacter,ServerAckSkin; } function Destroyed() { local SRCustomProgress S,NS; for( S=CustomLink; S!=None; S=NS ) { NS = S.NextLink; S.Destroy(); } Super.Destroyed(); } simulated final function string GetCustomValue( class C ) { local SRCustomProgress S; for( S=CustomLink; S!=None; S=S.NextLink ) if( S.Class.Name==C.Name ) return S.GetProgress(); return ""; } simulated final function int GetCustomValueInt( class C ) { local SRCustomProgress S; for( S=CustomLink; S!=None; S=S.NextLink ) if( S.Class.Name==C.Name ) return S.GetProgressInt(); return 0; } final function SRCustomProgress AddCustomValue( class C ) { local SRCustomProgress S,Last; for( S=CustomLink; S!=None; S=S.NextLink ) { Last = S; if( S.Class.Name==C.Name ) return S; } S = Spawn(C,Owner); S.RepLink = Self; // Add new one in the end of the chain. if( Last!=None ) Last.NextLink = S; else CustomLink = S; return S; } final function ProgressCustomValue( class C, int Count ) { local SRCustomProgress S; for( S=CustomLink; S!=None; S=S.NextLink ) { if( S.Class.Name==C.Name ) { S.IncrementProgress(Count); break; } } } final function SpawnCustomLinks() { local int i; for( i=0; i PickRandomPerk() { local array< class > CA; local int i; for( i=0; i0 ) CA[CA.Length] = CachePerks[i].PerkClass; } if( CA.Length==0 ) return None; return CA[Rand(CA.Length)]; } final function ServerSelectPerk( Class VetType ) { StatObject.ServerSelectPerk(VetType); } final function ServerRequestPerks() { if( NextRepTime V, byte Level ) { // Setup correct icon for trader. if( V.Default.PerkIndex<255 && V.Default.OnHUDIcon!=None ) { if( ShopPerkIcons.Length<=V.Default.PerkIndex ) ShopPerkIcons.Length = V.Default.PerkIndex+1; ShopPerkIcons[V.Default.PerkIndex] = V.Default.OnHUDIcon; } if( CachePerks.Length<=Index ) CachePerks.Length = (Index+1); CachePerks[Index].PerkClass = V; CachePerks[Index].CurrentLevel = Level; } simulated function ClientPerkLevel( int Index, byte CurLevel ) { Level.GetLocalPlayerController().ReceiveLocalizedMessage(Class'KFVetEarnedMessageSR',(CurLevel-1),,,CachePerks[Index].PerkClass); CachePerks[Index].CurrentLevel = CurLevel; } simulated function ClientReceiveWeapon( int Index, class P, byte Categ ) { ShopInventory.Length = Max(ShopInventory.Length,Index+1); if( ShopInventory[Index].PC==None ) { ShopInventory[Index].PC = P; ShopInventory[Index].CatNum = Categ; if( class(P.Default.InventoryType)!=none && (class(P.Default.InventoryType).Default.AppID>0 || class(P.Default.InventoryType).Default.UnlockedByAchievement!=-1) ) ShopInventory[Index].bDLCLocked = 1; ++ClientAccknowledged[0]; } } simulated function ClientReceiveCategory( byte Index, FShopCategoryIndex S ) { ShopCategories.Length = Max(ShopCategories.Length,Index+1); if( ShopCategories[Index].Name=="" ) { ShopCategories[Index] = S; ++ClientAccknowledged[1]; } } simulated function ClientReceiveURL( string S, string ID ) { ServerWebSite = S; UserID = ID; bReceivedURL = true; } simulated function ClientSendAcknowledge() { ServerAcnowledge(ClientAccknowledged[0],ClientAccknowledged[1]); } function ServerAcnowledge( int A, int B ) { ClientAccknowledged[0] = A; ClientAccknowledged[1] = B; } simulated function ClientReceiveChar( string CharName, int Num ) { CustomChars.Length = Num+1; CustomChars[Num] = CharName; ServerAckSkin(Num+1); } simulated function ClientReceiveTag( Texture T, string Tag, bool bInCaps ) { local int i; i = SmileyTags.Length; SmileyTags.Length = i+1; SmileyTags[i].SmileyTex = T; SmileyTags[i].SmileyTag = Tag; SmileyTags[i].bInCAPS = bInCaps; } simulated function ClientAllReceived() { local PlayerController PC; local int i; bRepCompleted = true; PC = Level.GetLocalPlayerController(); if( (PC!=None && PC==Owner) || Level.NetMode==NM_Client ) { // Check if a DLC check is required. for( i=(ShopInventory.Length-1); i>=0; --i ) if( ShopInventory[i].bDLCLocked!=0 ) { Spawn(Class'SRSteamStatsGet',Owner).Link = Self; break; } } if( SmileyTags.Length==0 ) return; if( PC!=None && SRHUDKillingFloor(PC.MyHUD)!=None ) SRHUDKillingFloor(PC.MyHUD).SmileyMsgs = SmileyTags; } function ServerAckSkin( int Index ) { ClientAckSkinNum = Index; } simulated final function string PickRandomCustomChar() { local string S; local int i; if( CustomChars.Length==0 ) return ""; S = CustomChars[Rand(CustomChars.Length)]; i = InStr(S,":"); if( i>=0 ) S = Mid(S,i+1); return S; } simulated final function bool IsCustomCharacter( string CN ) { local int i; for( i=0; i0 ) // Denied. return; Level.GetLocalPlayerController().UpdateURL("Character", CN, True); } ServerSetCharacter(CN); } function ServerSetCharacter( string CN ) { if( xPlayer(Owner)!=None ) StatObject.ChangeCharacter(CN); } final function bool CanBuyPickup( class WC ) { local int i; local KFPlayerReplicationInfo K; for( i=(ShopInventory.Length-1); i>=0; --i ) if( ShopInventory[i].PC==WC ) { K = KFPlayerReplicationInfo(StatObject.PlayerOwner.PlayerReplicationInfo); for( i=(CachePerks.Length-1); i>=0; --i ) if( !CachePerks[i].PerkClass.Static.AllowWeaponInTrader(WC,K,CachePerks[i].CurrentLevel) ) return false; return true; } return false; } Auto state RepSetup { final function InitDLCCheck() { local int i; for( i=(ShopInventory.Length-1); i>=0; --i ) { if( class(ShopInventory[i].PC.Default.InventoryType)!=none && (class(ShopInventory[i].PC.Default.InventoryType).Default.AppID>0 || class(ShopInventory[i].PC.Default.InventoryType).Default.UnlockedByAchievement!=-1) ) ShopInventory[i].bDLCLocked = 1; } } Begin: if( Level.NetMode==NM_Client ) Stop; Sleep(1.f); NetUpdateFrequency = 0.5f; if( NetConnection(StatObject.PlayerOwner.Player)!=None ) // Network client. { ClientReceiveURL(ServerWebSite,StatObject.PlayerOwner.GetPlayerIDHash()); // Now MAKE SURE client receives the full inventory list. while( ClientAccknowledged[0] SV; local byte Lv; local float V; SV = Class(OwnerPRI.ClientVeteranSkill); Lv = OwnerPRI.ClientVeteranSkillLevel+1; if( Lv