rott/kf_sources/ServerPerksMut/Classes/ServerStStats.uc
2026-07-14 20:27:09 +07:00

682 lines
18 KiB
Ucode

// Written by .:..: (2009)
Class ServerStStats extends SRStatsBase;
var StatsObject MyStatsObject;
var ServerPerksMut MutatorOwner;
var byte SelectingIndex;
var bool bHasChanged,bStatsChecking,bStHasInit,bHadSwitchedVet,bSwitchIsOKNow;
var class<SRVeterancyTypes> SelectingPerk;
function int GetID()
{
return MyStatsObject.ID;
}
function SetID( int ID )
{
MyStatsObject.ID = ID;
}
function PreBeginPlay()
{
local LinkedReplicationInfo L;
PlayerOwner = KFPlayerController(Owner);
if( Rep==None )
{
Rep = Spawn(Class'ClientPerkRepLink',Owner);
Rep.StatObject = Self;
if( PlayerOwner.PlayerReplicationInfo.CustomReplicationInfo==None )
PlayerOwner.PlayerReplicationInfo.CustomReplicationInfo = Rep;
else
{
for( L=PlayerOwner.PlayerReplicationInfo.CustomReplicationInfo; L!=None; L=L.NextReplicationInfo )
if( L.NextReplicationInfo==None )
{
L.NextReplicationInfo = Rep;
break;
}
}
}
Super.PreBeginPlay();
}
function PostBeginPlay()
{
if( Rep!=None )
Rep.SpawnCustomLinks();
bStatsReadyNow = MutatorOwner.bNoSavingProgress || !MutatorOwner.bUseRemoteDatabase;
MyStatsObject = MutatorOwner.GetStatsForPlayer(PlayerOwner);
if( MyStatsObject!=None && MyStatsObject.bStatsChanged )
bStatsReadyNow = true; // Server has already the most fresh stats for this client.
KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill = None;
if( !bStatsReadyNow )
{
Timer();
SetTimer(1+FRand(),true);
return;
}
bSwitchIsOKNow = true;
if( MyStatsObject!=None )
{
// Apply selected character.
if( MyStatsObject.SelectedChar!="" )
ApplyCharacter(MyStatsObject.SelectedChar);
else if( Rep.bNoStandardChars && Rep.CustomChars.Length>0 )
{
MyStatsObject.SelectedChar = Rep.PickRandomCustomChar();
ApplyCharacter(MyStatsObject.SelectedChar);
}
RepCopyStats();
bHasChanged = true;
CheckPerks(true);
SelectingIndex = MyStatsObject.PerkIndex;
if( MutatorOwner.bNoPerkChanges && MyStatsObject.ChosenPerk!=None )
ServerSelectPerk(MyStatsObject.ChosenPerk);
else ServerSelectPerkName(MyStatsObject.GetSelectedPerk());
SelectingIndex = 255;
}
else CheckPerks(true);
if( MutatorOwner.bForceGivePerk && KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==None )
ServerSelectPerk(Rep.PickRandomPerk());
bSwitchIsOKNow = false;
bHadSwitchedVet = false;
SetTimer(0.1,false);
}
function ApplyCharacter( string CN )
{
PlayerOwner.PawnSetupRecord = class'xUtil'.static.FindPlayerRecord(CN);
if( PlayerOwner.PawnSetupRecord.VoiceClassName!="" )
PlayerOwner.PlayerReplicationInfo.SetCharacterVoice(PlayerOwner.PawnSetupRecord.VoiceClassName);
PlayerOwner.PlayerReplicationInfo.SetCharacterName(CN);
}
function ChangeCharacter( string CN )
{
local bool bCustom;
bCustom = Rep.IsCustomCharacter(CN);
if( !bCustom )
{
if( Rep.bNoStandardChars && Rep.CustomChars.Length>0 ) // Prevent from switching to a standard character.
{
CN = Rep.PickRandomCustomChar();
bCustom = true;
}
else CN = Class'KFGameType'.Static.GetValidCharacter(CN); // Make sure client doesn't chose some invalid character.
}
ApplyCharacter(CN);
if( !bCustom ) // Was not a custom character, don't save client char on server.
CN = "";
if( MyStatsObject!=None )
MyStatsObject.SetSelectedChar(CN);
}
function GetData( string D )
{
bStatsReadyNow = true;
MyStatsObject.SetSaveData(D);
RepCopyStats();
bHasChanged = true;
bSwitchIsOKNow = true;
// Apply selected character.
if( MyStatsObject.SelectedChar!="" )
ApplyCharacter(MyStatsObject.SelectedChar);
else if( Rep.bNoStandardChars && Rep.CustomChars.Length>0 )
{
MyStatsObject.SelectedChar = Rep.PickRandomCustomChar();
ApplyCharacter(MyStatsObject.SelectedChar);
}
CheckPerks(true);
SelectingIndex = MyStatsObject.PerkIndex;
ServerSelectPerkName(MyStatsObject.GetSelectedPerk());
SelectingIndex = 255;
Rep.SendClientPerks();
if( MutatorOwner.bForceGivePerk && KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==None )
ServerSelectPerk(Rep.PickRandomPerk());
bHadSwitchedVet = false;
bSwitchIsOKNow = false;
SetTimer(0.1,false);
}
function Timer()
{
if( !bStatsReadyNow )
{
MutatorOwner.RequestStats(Self);
return;
}
if( !bStHasInit )
{
if( PlayerOwner.SteamStatsAndAchievements!=None && PlayerOwner.SteamStatsAndAchievements!=Self )
PlayerOwner.SteamStatsAndAchievements.Destroy();
PlayerOwner.SteamStatsAndAchievements = Self;
PlayerOwner.PlayerReplicationInfo.SteamStatsAndAchievements = Self;
bStHasInit = true;
Rep.SendClientPerks();
}
if( bStatsChecking )
{
bStatsChecking = false;
CheckPerks(false);
}
}
function RepCopyStats()
{
// Copy all stats from data object for client replication
Rep.RDamageHealedStat = MyStatsObject.DamageHealedStat;
Rep.RWeldingPointsStat = MyStatsObject.WeldingPointsStat;
Rep.RShotgunDamageStat = MyStatsObject.ShotgunDamageStat;
Rep.RHeadshotKillsStat = MyStatsObject.HeadshotKillsStat;
Rep.RStalkerKillsStat = MyStatsObject.StalkerKillsStat;
Rep.RBullpupDamageStat = MyStatsObject.BullpupDamageStat;
Rep.RMeleeDamageStat = MyStatsObject.MeleeDamageStat;
Rep.RFlameThrowerDamageStat = MyStatsObject.FlameThrowerDamageStat;
Rep.RSelfHealsStat = MyStatsObject.SelfHealsStat;
Rep.RSoleSurvivorWavesStat = MyStatsObject.SoleSurvivorWavesStat;
Rep.RCashDonatedStat = MyStatsObject.CashDonatedStat;
Rep.RFeedingKillsStat = MyStatsObject.FeedingKillsStat;
Rep.RBurningCrossbowKillsStat = MyStatsObject.BurningCrossbowKillsStat;
Rep.RGibbedFleshpoundsStat = MyStatsObject.GibbedFleshpoundsStat;
Rep.RStalkersKilledWithExplosivesStat = MyStatsObject.StalkersKilledWithExplosivesStat;
Rep.RGibbedEnemiesStat = MyStatsObject.GibbedEnemiesStat;
Rep.RBloatKillsStat = MyStatsObject.BloatKillsStat;
Rep.RTotalZedTimeStat = MyStatsObject.TotalZedTimeStat;
Rep.RSirenKillsStat = MyStatsObject.SirenKillsStat;
Rep.RKillsStat = MyStatsObject.KillsStat;
Rep.RExplosivesDamageStat = MyStatsObject.ExplosivesDamageStat;
Rep.TotalPlayTime = MyStatsObject.TotalPlayTime;
Rep.WinsCount = MyStatsObject.WinsCount;
Rep.LostsCount = MyStatsObject.LostsCount;
MyStatsObject.GetCustomValues(Rep.CustomLink);
}
final function ForcePerkChange( Class<SRVeterancyTypes> VetType )
{
bSwitchIsOKNow = true;
ServerSelectPerk(VetType);
bSwitchIsOKNow = false;
}
function ServerSelectPerkName( name N )
{
local byte i,Index;
if( N=='' )
return;
Index = 255;
for( i=0; i<Rep.CachePerks.Length; i++ )
{
if( Rep.CachePerks[i].PerkClass.Name==N )
{
ServerSelectPerk(Rep.CachePerks[i].PerkClass);
return;
}
else if( Rep.CachePerks[i].PerkClass.Default.PerkIndex==SelectingIndex )
Index = i;
}
if( Index!=255 )
ServerSelectPerk(Rep.CachePerks[Index].PerkClass); // Fallback to using saved index.
}
function ServerSelectPerk( Class<SRVeterancyTypes> VetType )
{
local byte i;
if( !bStatsReadyNow )
return;
if( VetType==None || !SelectionOK(VetType) )
{
if( !bSwitchIsOKNow )
PlayerOwner.ClientMessage("Your desired perk is unavailable.");
return;
}
else if( KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==VetType )
{
if( SelectingPerk!=None )
{
SelectingPerk = None;
PlayerOwner.ClientMessage("You will remain the same perk now.");
}
return;
}
if( MyStatsObject!=None )
{
MyStatsObject.ChosenPerk = VetType;
MyStatsObject.SetSelectedPerk(VetType.Name);
MyStatsObject.PerkIndex = VetType.Default.PerkIndex;
}
if( !Level.Game.bWaitingToStartMatch && !bSwitchIsOKNow && !MutatorOwner.bAllowAlwaysPerkChanges )
{
if( MutatorOwner.bNoPerkChanges && KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill!=None )
{
PlayerOwner.ClientMessage("You are not allowed to change perk during game.");
return;
}
if( PlayerOwner.Pawn!=None )
{
if( KFGameReplicationInfo(Level.GRI).bWaveInProgress || bHadSwitchedVet )
i = 1;
else
{
bHadSwitchedVet = true;
i = 0;
}
if( i==1 )
{
PlayerOwner.ClientMessage(Repl(PlayerOwner.YouWillBecomePerkString, "%Perk%", VetType.Default.VeterancyName));
SelectingPerk = VetType;
PlayerOwner.SelectedVeterancy = VetType; // Force KFGameType update this.
return;
}
}
}
SelectingPerk = None;
for( i=0; i<Rep.CachePerks.Length; i++ )
{
if( Rep.CachePerks[i].PerkClass==VetType )
{
if( Rep.CachePerks[i].CurrentLevel==0 )
return;
PlayerOwner.SelectedVeterancy = VetType;
KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill = VetType;
KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkillLevel = Rep.CachePerks[i].CurrentLevel-1;
if( KFHumanPawn(PlayerOwner.Pawn)!=None )
{
KFHumanPawn(PlayerOwner.Pawn).VeterancyChanged();
DropToCarryLimit(KFHumanPawn(PlayerOwner.Pawn));
}
}
}
}
function DropToCarryLimit( KFHumanPawn P )
{
local byte c;
local Inventory I;
while( P.CurrentWeight>P.MaxCarryWeight && ++c<6 )
{
for ( I = P.Inventory; I != none; I = I.Inventory )
{
if ( KFWeapon(I) != none && !KFWeapon(I).bKFNeverThrow )
{
I.Velocity = P.Velocity;
I.DropFrom(P.Location + VRand() * 10);
break; // Drop weapons until player is capable of carrying them all.
}
}
}
}
function bool SelectionOK( Class<SRVeterancyTypes> VetType )
{
local byte i;
for( i=0; i<Rep.CachePerks.Length; i++ )
{
if( Rep.CachePerks[i].PerkClass==VetType )
return (Rep.CachePerks[i].CurrentLevel>0);
}
return false;
}
function CheckPerks( bool bInit )
{
local byte i,NewLevel;
if( !bStatsReadyNow )
return;
if( bInit )
{
for( i=0; i<Rep.CachePerks.Length; i++ )
Rep.CachePerks[i].CurrentLevel = Rep.CachePerks[i].PerkClass.Static.PerkIsAvailable(Rep);
return;
}
for( i=0; i<Rep.CachePerks.Length; i++ )
{
NewLevel = Rep.CachePerks[i].CurrentLevel;
while( NewLevel<Rep.MaximumLevel && Rep.CachePerks[i].PerkClass.Static.LevelIsFinished(Rep,NewLevel) )
++NewLevel;
if( NewLevel>Rep.CachePerks[i].CurrentLevel )
{
if( KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkill==Rep.CachePerks[i].PerkClass )
KFPlayerReplicationInfo(PlayerOwner.PlayerReplicationInfo).ClientVeteranSkillLevel = NewLevel-1;
Rep.CachePerks[i].CurrentLevel = NewLevel;
Rep.ClientPerkLevel(i,NewLevel);
if( MutatorOwner.bMessageAnyPlayerLevelUp )
BroadcastLocalizedMessage(Class'KFVetEarnedMessagePL',(NewLevel-1),PlayerOwner.PlayerReplicationInfo,,Rep.CachePerks[i].PerkClass);
}
}
}
final function DelayedStatCheck()
{
if( MyStatsObject!=None )
MyStatsObject.bStatsChanged = true;
if( bStatsChecking || !bStatsReadyNow )
return;
bStatsChecking = true;
SetTimer(1,false);
}
function NotifyStatChanged()
{
bHasChanged = true;
DelayedStatCheck();
}
function MatchEnded()
{
}
function AddDamageHealed(int Amount, optional bool bMP7MHeal, optional bool bMP5MHeal)
{
bHasChanged = true;
Rep.RDamageHealedStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.DamageHealedStat+=Amount;
DelayedStatCheck();
}
function AddWeldingPoints(int Amount)
{
bHasChanged = true;
Rep.RWeldingPointsStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.WeldingPointsStat+=Amount;
DelayedStatCheck();
}
function AddShotgunDamage(int Amount)
{
bHasChanged = true;
Rep.RShotgunDamageStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.ShotgunDamageStat+=Amount;
DelayedStatCheck();
}
function AddHeadshotKill(bool bLaserSightedEBRHeadshot)
{
bHasChanged = true;
Rep.RHeadshotKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.HeadshotKillsStat++;
DelayedStatCheck();
}
function AddStalkerKill()
{
bHasChanged = true;
Rep.RStalkerKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.StalkerKillsStat++;
DelayedStatCheck();
}
function AddBullpupDamage(int Amount)
{
bHasChanged = true;
Rep.RBullpupDamageStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.BullpupDamageStat+=Amount;
DelayedStatCheck();
}
function AddMeleeDamage(int Amount)
{
bHasChanged = true;
Rep.RMeleeDamageStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.MeleeDamageStat+=Amount;
DelayedStatCheck();
}
function AddFlameThrowerDamage(int Amount)
{
bHasChanged = true;
Rep.RFlameThrowerDamageStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.FlameThrowerDamageStat+=Amount;
DelayedStatCheck();
}
function WaveEnded()
{
if( SelectingPerk!=None )
{
bSwitchIsOKNow = true;
ServerSelectPerk(SelectingPerk);
bSwitchIsOKNow = false;
bHadSwitchedVet = true;
}
else bHadSwitchedVet = false;
}
function MatchStarting()
{
bHadSwitchedVet = false;
}
function AddKill(bool bLaserSightedEBRM14Headshotted, bool bMeleeKill, bool bZEDTimeActive, bool bM4Kill, bool bBenelliKill, bool bRevolverKill, bool bMK23Kill, bool bFNFalKill, bool bBullpupKill, string MapName)
{
bHasChanged = true;
Rep.RKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.KillsStat++;
DelayedStatCheck();
}
function AddBloatKill(bool bWithBullpup)
{
bHasChanged = true;
Rep.RBloatKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.BloatKillsStat++;
DelayedStatCheck();
}
function AddSirenKill(bool bLawRocketImpact)
{
bHasChanged = true;
Rep.RSirenKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.SirenKillsStat++;
DelayedStatCheck();
}
function AddStalkerKillWithExplosives()
{
bHasChanged = true;
Rep.RStalkersKilledWithExplosivesStat++;
if( MyStatsObject!=None )
MyStatsObject.StalkersKilledWithExplosivesStat++;
DelayedStatCheck();
}
function AddFireAxeKill();
function AddChainsawScrakeKill();
function AddBurningCrossbowKill()
{
bHasChanged = true;
Rep.RBurningCrossbowKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.BurningCrossbowKillsStat++;
DelayedStatCheck();
}
function AddFeedingKill()
{
bHasChanged = true;
Rep.RFeedingKillsStat++;
if( MyStatsObject!=None )
MyStatsObject.FeedingKillsStat++;
DelayedStatCheck();
}
function OnGrenadeExploded();
function AddGrenadeKill();
function OnShotHuntingShotgun();
function AddHuntingShotgunKill();
function KilledEnemyWithBloatAcid();
function KilledFleshpound(bool bWithMeleeAttack, bool bWithAA12, bool bWithKnife, bool bWithClaymore);
function AddMedicKnifeKill();
function AddGibKill(bool bWithM79)
{
bHasChanged = true;
Rep.RGibbedEnemiesStat++;
if( MyStatsObject!=None )
MyStatsObject.GibbedEnemiesStat++;
DelayedStatCheck();
}
function AddFleshpoundGibKill()
{
bHasChanged = true;
Rep.RGibbedFleshpoundsStat++;
if( MyStatsObject!=None )
MyStatsObject.GibbedFleshpoundsStat++;
DelayedStatCheck();
}
function AddSelfHeal()
{
bHasChanged = true;
Rep.RSelfHealsStat++;
if( MyStatsObject!=None )
MyStatsObject.SelfHealsStat++;
DelayedStatCheck();
}
function AddOnlySurvivorOfWave()
{
bHasChanged = true;
Rep.RSoleSurvivorWavesStat++;
if( MyStatsObject!=None )
MyStatsObject.SoleSurvivorWavesStat++;
DelayedStatCheck();
}
function AddDonatedCash(int Amount)
{
bHasChanged = true;
Rep.RCashDonatedStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.CashDonatedStat+=Amount;
DelayedStatCheck();
}
function AddZedTime(float Amount)
{
bHasChanged = true;
Rep.RTotalZedTimeStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.TotalZedTimeStat+=Amount;
}
function AddExplosivesDamage(int Amount)
{
bHasChanged = true;
Rep.RExplosivesDamageStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.ExplosivesDamageStat+=Amount;
}
function AddHeadshotKills(int Amount)
{
bHasChanged = true;
Rep.RHeadshotKillsStat+= Amount;
if( MyStatsObject!=None )
MyStatsObject.HeadshotKillsStat+= Amount;
DelayedStatCheck();
}
function AddStalkerKills(int Amount)
{
bHasChanged = true;
Rep.RStalkerKillsStat+=Amount;
if( MyStatsObject!=None )
MyStatsObject.StalkerKillsStat+= Amount;
DelayedStatCheck();
}
function WonLostGame( bool bDidWin )
{
if( bDidWin )
{
++Rep.WinsCount;
if( MyStatsObject!=None )
++MyStatsObject.WinsCount;
}
else
{
++Rep.LostsCount;
if( MyStatsObject!=None )
++MyStatsObject.LostsCount;
}
bHasChanged = true;
DelayedStatCheck();
GoToState('');
}
// Allow no default functionality with the stats.
function OnStatsAndAchievementsReady();
function PostNetBeginPlay();
function InitializeSteamStatInt(int Index, int Value);
function SetSteamAchievementCompleted(int Index);
event SetLocalAchievementCompleted(int Index);
function ServerSteamStatsAndAchievementsInitialized();
function UpdateAchievementProgress();
function int GetAchievementCompletedCount();
event OnPerkAvailable();
function WonLongGame(string MapName, float Difficulty);
function AddDemolitionsPipebombKill();
function AddSCARKill();
function AddCrawlerKilledInMidair();
function Killed8ZedsWithGrenade();
function Killed10ZedsWithPipebomb();
function KilledHusk(bool bDamagedFriendly);
function AddMac10BurnDamage(int Amount);
function AddGorefastBackstab();
function ScrakeKilledByFire();
function KilledCrawlerWithCrossbow();
function OnLARReloaded();
function AddStalkerKillWithLAR();
function KilledHuskWithPistol();
function AddDroppedTier3Weapon();
function Survived10SecondsAfterVomit();
function CheckChristmasAchievementsCompleted();
function PlayerDied();
function KilledPatriarch(bool bPatriarchHealed, bool bKilledWithLAW, bool bSuicidalDifficulty, bool bOnlyUsedCrossbows, bool bClaymore, string MapName);
function WonGame(string MapName, float Difficulty, bool bLong);
function Destroyed()
{
if( Rep!=None )
{
if( MyStatsObject!=None )
MyStatsObject.SetCustomValues(Rep.CustomLink);
Rep.Destroy();
Rep = None;
}
if( PlayerOwner!=None && !PlayerOwner.bDeleteMe )
{
// Was destroyed mid-game for random reason, respawn.
MutatorOwner.PendingPlayers[MutatorOwner.PendingPlayers.Length] = PlayerOwner;
MutatorOwner.SetTimer(0.1,false);
}
Super.Destroyed();
}
Auto state PlaytimeTimer
{
Begin:
while( true )
{
Sleep(1.f);
if( bStatsReadyNow && !PlayerOwner.PlayerReplicationInfo.bOnlySpectator )
{
++Rep.TotalPlayTime;
if( MyStatsObject!=None )
++MyStatsObject.TotalPlayTime;
}
}
}
defaultproperties
{
SelectingIndex=255
}