//============================================================================= // KFGameReplicationInfoVersus //============================================================================= // //============================================================================= // Killing Floor 2 // Copyright (C) 2016 Tripwire Interactive LLC // - John "Ramm-Jaeger" Gibson //============================================================================= class KFGameReplicationInfoVersus extends KFGameReplicationInfo; struct sPlayerZedSpawnWaitTimeData { var byte SpawnWaitTime; var bool bTakeOverActive; var byte DirtyFlag; }; var bool bTeamBalanceEnabled; var byte TeamBalanceDelta; var float TimeToLockSwitchTeam; /** Current round of play */ var byte CurrentRound; /** Current wait time until next spawn */ var repnotify sPlayerZedSpawnWaitTimeData PlayerZedSpawnWaitTimeData; var byte TimeUntilNextSpawn; replication { if ( bNetInitial ) bTeamBalanceEnabled; if( bNetDirty ) CurrentRound, PlayerZedSpawnWaitTimeData; } simulated event ReplicatedEvent( name VarName ) { local KFPlayerController KFPC; if( VarName == nameOf(PlayerZedSpawnWaitTimeData) ) { TimeUntilNextSpawn = PlayerZedSpawnWaitTimeData.SpawnWaitTime; if( TimeUntilNextSpawn != 255 ) { SetTimer( 1.f, true, nameOf(Timer_TickDownSpawnTimer) ); } else { ClearTimer( nameOf(Timer_TickDownSpawnTimer) ); } } else if( VarName == nameOf(CurrentRound) ) { if( CurrentRound > 0 ) { OnRoundIncremented(); } } else if( VarName == nameOf(bRoundIsOver) ) { KFPC = KFPlayerController(GetALocalPlayerController()); if( KFPC != none ) { if( KFPC.MyGFxManager != none ) { KFPC.MyGFxManager.OnRoundOver(); } } } else { super.ReplicatedEvent( VarName ); } } function SetPlayerZedSpawnTime( byte NewSpawnTime, bool bTakeOverActive ) { PlayerZedSpawnWaitTimeData.SpawnWaitTime = NewSpawnTime; PlayerZedSpawnWaitTimeData.DirtyFlag++; PlayerZedSpawnWaitTimeData.bTakeOverActive = bTakeOverActive; bNetDirty = true; bForceNetUpdate = true; if( WorldInfo.NetMode != NM_DedicatedServer ) { TimeUntilNextSpawn = PlayerZedSpawnWaitTimeData.SpawnWaitTime; if( TimeUntilNextSpawn != 255 ) { SetTimer( 1.f, true, nameOf(Timer_TickDownSpawnTimer) ); } else { ClearTimer( nameOf(Timer_TickDownSpawnTimer) ); } } } simulated function Timer_TickDownSpawnTimer() { if( TimeUntilNextSpawn < 255 ) { --TimeUntilNextSpawn; if( TimeUntilNextSpawn == 0 ) { ClearTimer( nameOf(Timer_TickDownSpawnTimer) ); } } } simulated function SetTeam( int Index, TeamInfo TI ) { if(Index == 255) { // No!!! Index = 1; } Super.SetTeam(Index, TI); } // Called once a second simulated event Timer() { local KFGameInfo_VersusSurvival MyKFGameInfo; super.Timer(); if(Role == ROLE_Authority) { MyKFGameInfo = KFGameInfo_VersusSurvival(WorldInfo.Game); bAllowSwitchTeam = !IsFinalWave() && !( (MyKFGameInfo.MajorityPlayersReady() && RemainingTime <= TimeToLockSwitchTeam || MyKFGameInfo.CheckAllPlayersReady()) && !bMatchHasBegun); if(bAllowSwitchTeam) { return; } else { if(bMatchHasBegun) { //do not attempt to auto balance when match has begun return; } if(MyKFGameInfo != none && AreTeamsOutOfBalanced()) { MyKFGameInfo.BalanceTeams(); } } } } simulated function bool AreTeamsOutOfBalanced() { local int ZedTeamSize, HumanTeamSize, i; if(!bTeamBalanceEnabled) { return false; } for ( i = 0; i < PRIArray.Length; i++) { if ( PRIArray[i] != None && !PRIArray[i].bOnlySpectator) { if(PRIArray[i].Team != none) { if(PRIArray[i].GetTeamNum() == 255) { ZedTeamSize++; } else { HumanTeamSize++; } } } } if( ZedTeamSize > `KF_MAX_PLAYERS || HumanTeamSize > `KF_MAX_PLAYERS) { return true; } if( abs(ZedTeamSize - HumanTeamSize) > TeamBalanceDelta) { return true; } return false; } simulated function int GetCurrentRoundNumber() { return CurrentRound; } /** Overridden to allow perk changes during round over period */ simulated event bool CanChangePerks() { return super.CanChangePerks() || bRoundIsOver; } function ServerStartVoteKick(PlayerReplicationInfo PRI_Kickee, PlayerReplicationInfo PRI_Kicker) { local KFPawn_Monster KFPM; local PlayerController C; if (PRI_Kickee.GetTeamNum() != PRI_Kicker.GetTeamNum()) { return; } C = PlayerController(PRI_Kickee.Owner); if (C != none) { KFPM = KFPawn_Monster(C.Pawn); if (KFPM != none && KFPM.IsABoss()) { return; } } super.ServerStartVoteKick(PRI_Kickee, PRI_Kicker); } reliable server function RecieveVoteKick(PlayerReplicationInfo PRI, bool bKick) { if (VoteCollector != none && VoteCollector.bIsKickVoteInProgress && VoteCollector.CurrentKickVote.PlayerPRI.GetTeamNum() != PRI.GetTeamNum()) { return; } super.RecieveVoteKick(PRI, bKick); } /** Performs client-specific resets */ simulated function OnRoundIncremented(); /** Resets the GRI */ function Reset() { WaveNum = 0; super.Reset(); } DefaultProperties { TeamBalanceDelta=1 TimeToLockSwitchTeam=3.0f bAllowSwitchTeam=true }