class ScrnBalanceVoting extends ScrnVotingOptions; var ScrnBalance Mut; const VOTE_PERKLOCK = 0; const VOTE_PERKUNLOCK = 1; const VOTE_PAUSE = 2; const VOTE_ENDTRADE = 3; const VOTE_BLAME = 4; const VOTE_KICK = 5; const VOTE_BORING = 6; const VOTE_SPAWN = 7; const VOTE_ENDWAVE = 8; const VOTE_SPEC = 9; const VOTE_READY = 10; const VOTE_UNREADY = 11; const VOTE_TEAMLOCK = 12; const VOTE_TEAMUNLOCK = 13; const VOTE_INVITE = 14; const VOTE_FF = 15; const VOTE_MAPRESTART = 16; const VOTE_FAKEDPLAYERS = 17; const VOTE_FAKEDCOUNT = 18; const VOTE_FAKEDHEALTH = 19; const VOTE_DIFF = 20; const VOTE_RKILL = 100; var localized string strCantEndTrade; var localized string strTooLate; var localized string strGamePaused, strSecondsLeft, strGameUnPaused, strPauseTraderOnly; var localized string viResume, viEndTrade, viDifficulty; var localized string strZedSpawnsDoubled; var localized string strSquadNotFound, strCantSpawnSquadNow, strSquadList; var localized string strNotInStoryMode, strNotInTSC; var localized string strCantEndWaveNow, strEndWavePenalty; var localized string strRCommands; //variables for GamePaused state var int PauseTime; var transient bool bPauseable; var transient string msgPause; var string Reason; // reason why voting was started (e.g. kick player for being noob) var transient float LastBlameVoteTime; function class FindPerkByName(PlayerController Sender, string VeterancyNameOrIndex) { local int i; local ClientPerkRepLink L; local class Perk; local string s1, s2; // log("FindPerkByName("$Sender$", "$VeterancyNameOrIndex$")", 'ScrnBalance'); if ( Sender == none || VeterancyNameOrIndex == "" || SRStatsBase(Sender.SteamStatsAndAchievements) == none ) return none; L = SRStatsBase(Sender.SteamStatsAndAchievements).Rep; if ( L == none ) return none; i = int(VeterancyNameOrIndex); if ( i > 0 && i <= L.CachePerks.Length ) return class(L.CachePerks[i-1].PerkClass); // log("CachePerks.Length="$L.CachePerks.Length, 'ScrnBalance'); for ( i = 0; i < L.CachePerks.Length; ++i ) { Perk = class(L.CachePerks[i].PerkClass); if ( Perk != none ) { // log(GetItemName(String(Perk.class)) @ Perk.default.VeterancyNameOrIndex, 'ScrnBalance'); if ( GetItemName(String(Perk.class)) ~= VeterancyNameOrIndex || Perk.default.VeterancyName ~= VeterancyNameOrIndex || (Divide(Perk.default.VeterancyName, " ", s1, s2) && (VeterancyNameOrIndex ~= s1 || VeterancyNameOrIndex ~= s2)) ) return Perk; } } return none; } function SendSquadList(PlayerController Sender) { local int i; local string s; if ( Mut.Squads.Length == 0 ) { Sender.ClientMessage(strOptionDisabled); return; } s = strSquadList @ Mut.Squads[0].SquadName; for ( i=1; i Perk; if ( Key == "LOCKPERK" ) { if ( !Mut.bAllowLockPerkVote ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } Perk = FindPerkByName(Sender, Value); if ( Perk == none ) return VOTE_ILLEGAL; if ( Perk.default.bLocked ) return VOTE_NOEFECT; result = VOTE_PERKLOCK; Value = Perk.default.VeterancyName; } else if ( Key == "UNLOCKPERK" ) { Perk = FindPerkByName(Sender, Value); if ( Perk == none ) return VOTE_ILLEGAL; if ( !Perk.default.bLocked ) return VOTE_NOEFECT; result = VOTE_PERKUNLOCK; Value = Perk.default.VeterancyName; } else if ( Key == "PAUSE" || (Level.Pauser != none && Key == "RESUME") ) { if ( !Mut.bAllowPauseVote ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } if ( Mut.bPauseTraderOnly && !Mut.KF.bTradingDoorsOpen && Mut.KF.IsInState('MatchInProgress') ) { Sender.ClientMessage(strPauseTraderOnly); return VOTE_NOEFECT; } result = VOTE_PAUSE; if ( Value == "" ) Value = "60"; else { v = int(Value); if ( v <= 0 ) v = 60; Value = string(v); } if ( Level.Pauser != none ) VoteInfo = viResume; } else if ( Key == "ENDTRADE" || (Key == "END" && Value == "TRADE") ) { if ( Mut.bStoryMode ) { Sender.ClientMessage(strNotInStoryMode); return VOTE_NOEFECT; } if ( Mut.KF.bWaveInProgress|| Mut.KF.WaveCountDown < 10 || Mut.SkippedTradeTimeMult < 0 ) { Sender.ClientMessage(strCantEndTrade); return VOTE_NOEFECT; } result = VOTE_ENDTRADE; Value = ""; VoteInfo = viEndTrade; } else if ( Key == "BLAME" ) { if ( !Mut.bAllowBlameVote ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } if ( Level.TimeSeconds - LastBlameVoteTime < Mut.BlameVoteCoolDown ) { Sender.ClientMessage(strNotAvaliableATM); return VOTE_LOCAL; } if ( Value == "" ) { SendPlayerList(Sender); return VOTE_LOCAL; } Reason = ""; if ( Left(Value, 1) == "\"" ) { // don't look for player in quoted string - just blame it :) VotingHandler.VotedPlayer = none; Value = Mid(Value, 1); Divide(Value, "\"", Value, Reason); VotingHandler.VotedPlayer = none; } else { Divide(Value, " ", Value, Reason); if ( Value ~= "ALL" || Value ~= "TEAM" ) { Value = "TEAM"; VoteInfo = "Blame Team"; VotingHandler.VotedPlayer = none; } else { if ( Value ~= "ME" ) VotingHandler.VotedPlayer = Sender; else VotingHandler.VotedPlayer = FindPlayer(Value); if ( VotingHandler.VotedPlayer == none ) { Sender.ClientMessage(strPlayerNotFound); SendPlayerList(Sender); return VOTE_ILLEGAL; } Value = Mut.ColoredPlayerName(VotingHandler.VotedPlayer.PlayerReplicationInfo); VoteInfo = "Blame " $ Value; } } LastBlameVoteTime = Level.TimeSeconds; result = VOTE_BLAME; } else if ( Key == "SPEC" ) { if ( Level.Game.AccessControl == none || Level.Game.NumSpectators > Level.Game.MaxSpectators || (!Mut.bAllowKickVote && !Sender.PlayerReplicationInfo.bAdmin) ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } if ( Value == "" ) { SendPlayerList(Sender); return VOTE_LOCAL; } Reason = ""; Divide(Value, " ", Value, Reason); VotingHandler.VotedPlayer = FindPlayer(Value); if ( VotingHandler.VotedPlayer == none ) { Sender.ClientMessage(strPlayerNotFound); SendPlayerList(Sender); return VOTE_ILLEGAL; } Value = Mut.ColoredPlayerName(VotingHandler.VotedPlayer.PlayerReplicationInfo); VoteInfo = "Spectate " $ Value; result = VOTE_SPEC; } else if ( Key == "KICK" ) { if ( Level.Game.AccessControl == none || (!Mut.bAllowKickVote && !Sender.PlayerReplicationInfo.bAdmin) ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } if ( Value == "" ) { SendPlayerList(Sender); return VOTE_LOCAL; } Reason = ""; Divide(Value, " ", Value, Reason); VotingHandler.VotedPlayer = FindPlayer(Value); if ( VotingHandler.VotedPlayer == none ) { Sender.ClientMessage(strPlayerNotFound); SendPlayerList(Sender); return VOTE_ILLEGAL; } Value = Mut.ColoredPlayerName(VotingHandler.VotedPlayer.PlayerReplicationInfo); VoteInfo = "Kick " $ Value; result = VOTE_KICK; } else if ( Key == "INVITE" ) { if ( !Mut.CheckScrnGT(Sender) ) return VOTE_LOCAL; if ( Value == "" ) { SendPlayerList(Sender); return VOTE_LOCAL; } Reason = ""; Divide(Value, " ", Value, Reason); VotingHandler.VotedPlayer = FindPlayer(Value); if ( VotingHandler.VotedPlayer == none ) { Sender.ClientMessage(strPlayerNotFound); SendPlayerList(Sender); return VOTE_ILLEGAL; } else if ( Mut.ScrnGT.IsInvited(VotingHandler.VotedPlayer) ) { VotingHandler.VotedPlayer = none; return VOTE_NOEFECT; } Value = Mut.ColoredPlayerName(VotingHandler.VotedPlayer.PlayerReplicationInfo); VoteInfo = "Invite " $ Value; result = VOTE_INVITE; } else if ( Key == "BORING" ) { if ( Mut.bStoryMode ) { Sender.ClientMessage(strNotInStoryMode); return VOTE_LOCAL; } else if ( !Mut.bAllowBoringVote && !Sender.PlayerReplicationInfo.bAdmin ) { Sender.ClientMessage(strOptionDisabled); return VOTE_LOCAL; } else if ( Mut.KF.bTradingDoorsOpen || Mut.KF.KFLRules.WaveSpawnPeriod < 0.5 ) { Sender.ClientMessage(strNotAvaliableATM); return VOTE_LOCAL; } Value = ""; VoteInfo = "Game is BORING"; result = VOTE_BORING; } else if ( Key == "SPAWN" ) { if ( Mut.bStoryMode && !Mut.bBeta ) { Sender.ClientMessage(strNotInStoryMode); return VOTE_NOEFECT; } if ( Mut.Squads.Length == 0 ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } if ( Value == "" ) { SendSquadList(Sender); return VOTE_LOCAL; } if ( Mut.FindSquad(Value) == -1 ) { Sender.ClientMessage(strSquadNotFound); return VOTE_ILLEGAL; } if ( Mut.KF.TotalMaxMonsters < 10 ) { Sender.ClientMessage(strCantSpawnSquadNow); return VOTE_NOEFECT; } result = VOTE_SPAWN; } else if ( Key == "ENDWAVE" || (Key == "END" && Value == "WAVE") ) { VotingHandler.VotedTeam = Sender.PlayerReplicationInfo.Team; if ( VotingHandler.VotedTeam == none ) return VOTE_ILLEGAL; if ( Mut.KF.NumMonsters == 0 ) return VOTE_NOEFECT; if ( Mut.MaxVoteKillMonsters == 0 ) { Sender.ClientMessage(strOptionDisabled); return VOTE_NOEFECT; } if ( Mut.KF.TotalMaxMonsters > 0 || Mut.KF.NumMonsters > Mut.MaxVoteKillMonsters || Mut.GameRules.bFinalWave || !CanEndWave() ) { Sender.ClientMessage(strCantEndWaveNow); return VOTE_NOEFECT; } return VOTE_ENDWAVE; } else if ( Key == "READY" ) { if ( !Level.Game.bWaitingToStartMatch ) return VOTE_NOEFECT; return VOTE_READY; } else if ( Key == "UNREADY" ) { if ( !Level.Game.bWaitingToStartMatch ) return VOTE_NOEFECT; return VOTE_UNREADY; } else if ( Key == "LOCKTEAM" || Key == "LOCKTEAMS" ) { if ( !Mut.CheckScrnGT(Sender) ) return VOTE_LOCAL; else if ( Mut.bTeamsLocked ) return VOTE_NOEFECT; else if ( !Sender.PlayerReplicationInfo.bAdmin && (Mut.ScrnGT.WaveNum+1) < Mut.ScrnGT.RelativeWaveNum(Mut.LockTeamMinWave) ) { Sender.ClientMessage(strNotAvaliableATM); return VOTE_LOCAL; } return VOTE_TEAMLOCK; } else if ( Key == "UNLOCKTEAM" || Key == "UNLOCKTEAMS" ) { if ( !Mut.CheckScrnGT(Sender) ) return VOTE_LOCAL; else if ( !Mut.bTeamsLocked ) return VOTE_NOEFECT; return VOTE_TEAMUNLOCK; } else if ( Key == "FF" ) { if ( Mut.bTSCGame ) { Sender.ClientMessage(strNotInTSC); return VOTE_NOEFECT; } if ( Level.GRI.bMatchHasBegun ) { Sender.ClientMessage(strNotAvaliableATM); return VOTE_LOCAL; } if ( right(Value, 1) == "%" ) Value = left(Value, len(Value)-1); if ( !TryStrToInt(Value, v) || v < Mut.MinVoteFF || v > Mut.MaxVoteFF ) return VOTE_ILLEGAL; if ( v == int(Mut.KF.FriendlyFireScale*100) ) return VOTE_NOEFECT; if ( v == 0 ) VoteInfo = "Friendly Fire OFF"; else VoteInfo = "Friendly Fire "$v$"%"; return VOTE_FF; } else if ( Key == "MAP" && Value == "RESTART" ) { result = VOTE_MAPRESTART; } else if ( Key == "FAKED" || Key == "FAKEDPLAYERS" ) { if ( !Mut.CheckScrnGT(Sender) ) return VOTE_LOCAL; if ( !TryStrToInt(Value, v) || v < 0 || v > 32 ) return VOTE_ILLEGAL; if ( Mut.ScrnGT.ScrnGRI.FakedPlayers == v && Mut.ScrnGT.ScrnGRI.FakedAlivePlayers == v ) return VOTE_NOEFECT; if ( v <= 1 ) VoteInfo = "Faked Players OFF"; else VoteInfo = v $ " Faked Players"; return VOTE_FAKEDPLAYERS; } else if ( Key == "FAKEDCOUNT" ) { if ( !Mut.CheckScrnGT(Sender) ) return VOTE_LOCAL; if ( !TryStrToInt(Value, v) || v < 0 || v > 32 ) return VOTE_ILLEGAL; if ( Mut.ScrnGT.ScrnGRI.FakedPlayers == v ) return VOTE_NOEFECT; if ( v <= 1 ) VoteInfo = "Faked Zed Count OFF"; else VoteInfo = v $ "p Faked Zed Count"; return VOTE_FAKEDCOUNT; } else if ( Key == "FAKEDHEALTH" ) { if ( !Mut.CheckScrnGT(Sender) ) return VOTE_LOCAL; if ( !TryStrToInt(Value, v) || v < 0 || v > 32 ) return VOTE_ILLEGAL; if ( Mut.ScrnGT.ScrnGRI.FakedAlivePlayers == v ) return VOTE_NOEFECT; if ( v <= 1 ) VoteInfo = "Faked Zed Health OFF"; else VoteInfo = v $ "p Faked Zed Health"; return VOTE_FAKEDHEALTH; } else if ( Key == "DIFF" || Key == "DIFFICULTY" ) { if ( Value == "" ) { Sender.ClientMessage("Usage: MVOTE DIFF DEFAULT|NORMAL|HARD|SUI|SUI+|HOE|HOE+"); return VOTE_LOCAL; } v = GetDifficulty(Value); if ( v != 0 && v < Mut.MinVoteDifficulty || v > 8 ) return VOTE_ILLEGAL; if ( v == Mut.Persistence.Difficulty ) return VOTE_NOEFECT; VoteInfo = Value @ viDifficulty; Value = string(v); return VOTE_DIFF; } else if ( Key == "R_KILL" ) { if ( !Sender.PlayerReplicationInfo.bAdmin || Mut.SrvTourneyMode == 0 ) { Sender.ClientMessage(strRCommands); return VOTE_LOCAL; } if ( Value == "" ) { SendPlayerList(Sender); return VOTE_LOCAL; } Reason = ""; Divide(Value, " ", Value, Reason); VotingHandler.VotedPlayer = FindPlayer(Value); if ( VotingHandler.VotedPlayer == none ) { Sender.ClientMessage(strPlayerNotFound); SendPlayerList(Sender); return VOTE_ILLEGAL; } Value = Mut.ColoredPlayerName(VotingHandler.VotedPlayer.PlayerReplicationInfo); VoteInfo = "Referee KILL " $ Value; result = VOTE_RKILL; } else return VOTE_UNKNOWN; return result; } function ApplyVoteValue(int VoteIndex, string VoteValue) { local class Perk; local ScrnCustomPRI ScrnPRI; switch ( VoteIndex ) { case VOTE_PERKLOCK: case VOTE_PERKUNLOCK: Perk = FindPerkByName(VotingHandler.VoteInitiator, VoteValue); if ( Perk != none ) { Mut.LockPerk(Perk, VoteIndex == VOTE_PERKLOCK); } break; case VOTE_PAUSE: if (Level.Pauser == none ) { //pause game if ( Mut.bPauseTraderOnly && !Mut.KF.bTradingDoorsOpen && Mut.KF.IsInState('MatchInProgress') ) { VotingHandler.BroadcastMessage(strPauseTraderOnly); return; } PauseTime = int(VoteValue); if ( PauseTime <= 0 ) PauseTime = 60; GotoState('GamePaused', 'Begin'); //Enable('Tick'); } else { //resume game Level.Pauser = none; VotingHandler.BroadcastMessage(strGameUnpaused); //Disable('Tick'); } break; case VOTE_ENDTRADE: if ( Mut.KF.bWaveInProgress || Mut.KF.WaveCountDown < 6 ) { VotingHandler.BroadcastMessage(strTooLate); return; } Mut.TradeTimeAddSeconds = max(float(Mut.KF.WaveCountDown - 5) * Mut.SkippedTradeTimeMult, 0); Mut.KF.WaveCountDown = 6; // need to left at least 6 to execute kfgametype.timer() events break; case VOTE_BLAME: if ( VotingHandler.VotedPlayer != none ) VoteValue = Mut.ColoredPlayerName(VotingHandler.VotedPlayer.PlayerReplicationInfo); LastBlameVoteTime = Level.TimeSeconds; if ( Reason == "" ) VotingHandler.BroadcastMessage(VoteValue $ " blamed"); else VotingHandler.BroadcastMessage(VoteValue $ " blamed for " $Reason); //achievement if ( IsGoodReason(Reason) && VotingHandler.VoteInitiator != none && SRStatsBase(VotingHandler.VoteInitiator.SteamStatsAndAchievements) != none ) { class'ScrnBalanceSrv.ScrnAchievements'.static.ProgressAchievementByID( SRStatsBase(VotingHandler.VoteInitiator.SteamStatsAndAchievements).Rep, 'Blame55p', 1); if ( VotingHandler.VotedPlayer == VotingHandler.VoteInitiator ) class'ScrnBalanceSrv.ScrnAchievements'.static.ProgressAchievementByID( SRStatsBase(VotingHandler.VoteInitiator.SteamStatsAndAchievements).Rep, 'BlameMe', 1); else if ( ScrnPlayerController(VotingHandler.VotedPlayer) != none && ScrnPlayerController(VotingHandler.VotedPlayer).BeggingForMoney >= 3 ) { class'ScrnBalanceSrv.ScrnAchievements'.static.ProgressAchievementByID( SRStatsBase(VotingHandler.VoteInitiator.SteamStatsAndAchievements).Rep, 'SellCrap', 1); VotingHandler.VotedPlayer.ReceiveLocalizedMessage(class'ScrnBalanceSrv.ScrnFakedAchMsg', 1); ScrnPlayerController(VotingHandler.VotedPlayer).BeggingForMoney = 0; } } if ( VotingHandler.VotedPlayer != none ) { ScrnPRI = class'ScrnCustomPRI'.static.FindMe(VotingHandler.VotedPlayer.PlayerReplicationInfo); if ( ScrnPRI != none ) { VotingHandler.VotedPlayer.ReceiveLocalizedMessage(class'ScrnBalanceSrv.ScrnBlamedMsg', ScrnPRI.BlameCounter++); // more blame = bigger shit //achievement if ( ScrnPRI.BlameCounter == 5 && SRStatsBase(VotingHandler.VotedPlayer.SteamStatsAndAchievements) != none ) class'ScrnBalanceSrv.ScrnAchievements'.static.ProgressAchievementByID( SRStatsBase(VotingHandler.VotedPlayer.SteamStatsAndAchievements).Rep, 'MaxBlame', 1); } else VotingHandler.VotedPlayer.ReceiveLocalizedMessage(class'ScrnBalanceSrv.ScrnBlamedMsg'); } if ( VoteValue ~= "TEAM" || VoteValue ~= "ALL" ) { BlameAll(); //achievement if ( IsGoodReason(Reason) && VotingHandler.VoteInitiator != none && SRStatsBase(VotingHandler.VoteInitiator.SteamStatsAndAchievements) != none ) class'ScrnBalanceSrv.ScrnAchievements'.static.ProgressAchievementByID( SRStatsBase(VotingHandler.VoteInitiator.SteamStatsAndAchievements).Rep, 'BlameTeam', 1); } else if ( VoteValue ~= "Baron" || (VotingHandler.VotedPlayer != none && VotingHandler.VotedPlayer.GetPlayerIDHash() == "76561198006289592") ) { Mut.BroadcastFakedAchievement(0); // blame Baron :) // blame the one who blamed baron if ( VotingHandler.VoteInitiator != none && VotingHandler.VotedPlayer != VotingHandler.VoteInitiator ) { VotingHandler.VotedPlayer = VotingHandler.VoteInitiator; Reason = "Blaming Baron"; ApplyVoteValue(VoteIndex, VoteValue); } } else if ( VoteValue ~= "TWI" || VoteValue ~= "Tripwire" ) { Mut.BroadcastFakedAchievement(3); // blame Tripwire :) } else BlameMonster(VoteValue); break; case VOTE_SPEC: if ( VotingHandler.VotedPlayer != none && !VotingHandler.VotedPlayer.PlayerReplicationInfo.bAdmin ) { if ( Mut.ScrnGT != none ) Mut.ScrnGT.UninvitePlayer(VotingHandler.VotedPlayer); VotingHandler.VotedPlayer.BecomeSpectator(); } break; case VOTE_KICK: if ( VotingHandler.VotedPlayer != none && !VotingHandler.VotedPlayer.PlayerReplicationInfo.bAdmin && NetConnection(VotingHandler.VotedPlayer.Player)!=None ) { if ( Mut.ScrnGT != none ) Mut.ScrnGT.UninvitePlayer(VotingHandler.VotedPlayer); if ( Reason == "" ) { VotingHandler.BroadcastMessage(VoteValue $ " kicked"); VotingHandler.VotedPlayer.ClientNetworkMessage("AC_Kicked", "Team Vote"); } else { VotingHandler.BroadcastMessage(VoteValue $ " kicked for " $Reason); VotingHandler.VotedPlayer.ClientNetworkMessage("AC_Kicked", Reason); } if (VotingHandler.VotedPlayer.Pawn != none && Vehicle(VotingHandler.VotedPlayer.Pawn) == none) VotingHandler.VotedPlayer.Pawn.Destroy(); if (VotingHandler.VotedPlayer != None) VotingHandler.VotedPlayer.Destroy(); } break; case VOTE_BORING: Mut.KF.KFLRules.WaveSpawnPeriod *= 0.5; VotingHandler.BroadcastMessage(strZedSpawnsDoubled $ " ("$Mut.KF.KFLRules.WaveSpawnPeriod$")"); break; case VOTE_SPAWN: Mut.SpawnSquad(VoteValue); break; case VOTE_ENDWAVE: if ( Mut.KF.TotalMaxMonsters > 0 || Mut.KF.NumMonsters > Mut.MaxVoteKillMonsters || Mut.GameRules.bFinalWave ) { return; } DoEndWave(); break; case VOTE_READY: SetReady(VotingHandler.VotedTeam.TeamIndex, true); break; case VOTE_UNREADY: SetReady(VotingHandler.VotedTeam.TeamIndex, false); break; case VOTE_TEAMLOCK: Mut.ScrnGT.LockTeams(); break; case VOTE_TEAMUNLOCK: Mut.ScrnGT.UnlockTeams(); break; case VOTE_INVITE: Mut.ScrnGT.InvitePlayer(VotingHandler.VotedPlayer); break; case VOTE_FF: Mut.KF.FriendlyFireScale = float(VoteValue)/100.0; if ( TSCGame(Mut.KF) != none ) TSCGame(Mut.KF).HdmgScale = Mut.KF.FriendlyFireScale; break; case VOTE_MAPRESTART: Level.ServerTravel("?restart",false); break; case VOTE_FAKEDPLAYERS: Mut.ScrnGT.ScrnGRI.FakedPlayers = byte(VoteValue); Mut.ScrnGT.ScrnGRI.FakedAlivePlayers = byte(VoteValue); break; case VOTE_FAKEDCOUNT: Mut.ScrnGT.ScrnGRI.FakedPlayers = byte(VoteValue); break; case VOTE_FAKEDHEALTH: Mut.ScrnGT.ScrnGRI.FakedAlivePlayers = byte(VoteValue); break; case VOTE_DIFF: Mut.Persistence.Difficulty = byte(VoteValue); Mut.Persistence.SaveConfig(); break; case VOTE_RKILL: if ( VotingHandler.VotedPlayer != none && VotingHandler.VotedPlayer.Pawn != none ) { VotingHandler.VotedPlayer.Pawn.Suicide(); if ( Reason == "" ) { VotingHandler.BroadcastMessage(VoteValue $ " killed by referee"); } else { VotingHandler.BroadcastMessage(VoteValue $ " killed by referee for " $Reason); } } break; } } function SetReady(byte TeamIndex, bool bReady) { local Controller C; for ( C = Level.ControllerList; C != None; C = C.NextController ) { if ( C.PlayerReplicationInfo != none && C.bIsPlayer && PlayerController(C) != none && C.PlayerReplicationInfo.Team != none && C.PlayerReplicationInfo.bWaitingPlayer && !C.PlayerReplicationInfo.bOnlySpectator ) { C.PlayerReplicationInfo.bReadyToPlay = bReady; } } } function class Str2Monster(string MonsterName) { MonsterName = caps(MonsterName); if ( MonsterName == "CLOT" ) return class'ZombieClot'; if ( MonsterName == "CRAWLER" ) return class'ZombieCrawler'; if ( MonsterName == "STALKER" ) return class'ZombieStalker'; if ( MonsterName == "BLOAT" ) return class'ZombieBloat'; if ( MonsterName == "GOREFAST" ) return class'ZombieGorefast'; if ( MonsterName == "SIREN" ) return class'ZombieSiren'; if ( MonsterName == "HUSK" ) return class'ZombieHusk'; if ( MonsterName == "SCRAKE" || MonsterName == "SC" ) return class'ZombieScrake'; if ( MonsterName == "FLESHPOUND" || MonsterName == "FP" ) return class'ZombieFleshpound'; if ( MonsterName == "PAT" || MonsterName == "PATRIARCH" || MonsterName == "BOSS" ) return class'ZombieBoss'; return none; } function BlameAll() { local Controller P; local ScrnPlayerController Player; local ScrnCustomPRI ScrnPRI; for ( P = Level.ControllerList; P != none; P = P.nextController ) { Player = ScrnPlayerController(P); if ( Player != none ) { ScrnPRI = class'ScrnCustomPRI'.static.FindMe(Player.PlayerReplicationInfo); if ( ScrnPRI != none ) { Player.ReceiveLocalizedMessage(class'ScrnBalanceSrv.ScrnBlamedMsg', ScrnPRI.BlameCounter++); // more blame = bigger shit if ( Player.PlayerReplicationInfo != none && Player.PlayerReplicationInfo.PlayerName ~= "Baron" ) Mut.BroadcastFakedAchievement(0); // blame Baron :) } } } } // returns false if monster not found or can't be blamed function bool BlameMonster(String MonsterName) { local class MC; local Controller P; local ScrnPlayerController Player; MC = Str2Monster(MonsterName); // don't blame Stalkers and Patriarch, because shit on their head could reveal // their positions if ( MC == none || MC == class'ZombieStalker' || MC == class'ZombieBoss' ) return false; for ( P = Level.ControllerList; P != none; P = P.nextController ) { Player = ScrnPlayerController(P); if ( Player != none ) { Player.ClientMonsterBlamed(MC); } } return true; } static function bool IsGoodReason(string Reason) { local string a, b; // good reason contains from at least 2 words, one of them is at least 6 character long // "n00b" and "screw you" aren't good reasons :) return Divide(Reason, " ", a, b) && ( len(a) >= 6 || len(b) >= 6); } function bool CanEndWave() { local Controller C; local MonsterController MC; local Monster M; local KFHumanPawn P; local int TotalHP; for ( C = Level.ControllerList; C != None; C = C.NextController ) { MC = MonsterController(C); M = Monster(C.Pawn); if ( MC==none || M == none ) continue; TotalHP += M.default.Health; if ( Mut.bVoteKillCheckVisibility ) { foreach VisibleCollidingActors(class'KFHumanPawn', P, 1000) { if ( P.Health > 0 && P.Controller != none && P.Controller.bIsPlayer && KF_StoryNPC(P) == none && MC.CanSee(P) ) return false; } } } return TotalHP <= Mut.MaxVoteKillHP; } function DoEndWave() { local Monster M; local int Penalty, TotalPenalty; foreach DynamicActors(class'Monster', M) { Penalty = max(M.ScoringValue * Mut.VoteKillPenaltyMult, 0); VotingHandler.VotedTeam.Score -= Penalty; TotalPenalty += Penalty; M.KilledBy(M); } if ( TotalPenalty > 0 ) VotingHandler.BroadcastMessage(strEndWavePenalty $ TotalPenalty); } function byte GetDifficulty(out string DiffStr) { if ( DiffStr == "0" || DiffStr == "DEFAULT" || DiffStr == "OFF" ) { DiffStr = "Default"; return 2; } else if ( DiffStr == "2" || DiffStr == "NORMAL" ) { DiffStr = "Normal"; return 2; } else if ( DiffStr == "4" || DiffStr == "HARD" ) { DiffStr = "Hard"; return 4; } else if ( DiffStr == "5" || DiffStr == "SUICIDAL" || DiffStr == "SUI" ) { DiffStr = "Suicidal"; return 5; } else if ( DiffStr == "6" || DiffStr == "SUICIDAL+" || DiffStr == "SUI+" ) { DiffStr = "Suicidal+"; return 6; } else if ( DiffStr == "7" || DiffStr == "HELLONEARTH" || DiffStr == "HOE" ) { DiffStr = "HoE"; return 7; } else if ( DiffStr == "8" || DiffStr == "HELLONEARTH+" || DiffStr == "HOE+" ) { DiffStr = "HoE+"; return 8; } return 255; } state GamePaused { Begin: Level.Pauser = VotingHandler.VoteInitiator.PlayerReplicationInfo; if ( Level.Pauser != none ) { // tell players that game is paused msgPause = strGamePaused; ReplaceText(msgPause, "%s", string(PauseTime)); VotingHandler.BroadcastMessage(msgPause); // wait for pause time ends or game resumes by other source (e.g. admin) while ( PauseTime > 0 && Level.Pauser != none ) { if ( PauseTime <= 5 ) VotingHandler.BroadcastMessage(String(PauseTime)); else if ( (PauseTime%30 == 0) || (PauseTime < 30 && PauseTime%10 == 0) ) VotingHandler.BroadcastMessage(PauseTime @ strSecondsLeft); //log(Level.TimeSeconds @ "Sleep", 'ScrnBalance'); sleep(1.0); PauseTime--; } // resume game after pause time ends if ( Level.Pauser != none ) { Level.Pauser = none; VotingHandler.BroadcastMessage(strGameUnpaused); } } GotoState(''); } defaultproperties { strCantEndTrade="Can not end trade time at the current moment" strTooLate="Too late" strGamePaused="Game paused for %s seconds" strSecondsLeft="seconds left" strGameUnPaused="Game resumed" strPauseTraderOnly="Game can be paused only during trader time!" viResume="RESUME GAME" viEndTrade="END TRADER TIME" viDifficulty="Difficulty" strZedSpawnsDoubled="ZED spawn rate doubled!" strSquadNotFound="Monster squad with a given name not found" strCantSpawnSquadNow="Can not spawn monsters at this moment" strSquadList="Avaliable Squads:" strNotInStoryMode="Not avaliable in Story Mode" strNotInTSC="Not avaliable in TSC" strCantEndWaveNow="Can't end the wave now" strEndWavePenalty="Team charged for premature wave end with $" strRCommands="R_* commands can be executed only by Referee (Admin rights + Tourney Mode)" HelpInfo(0)="%gLOCKPERK%w|%gUNLOCKPERK %y %w Disables/Enables perk at the end of the wave" HelpInfo(1)="%gLOCKTEAM%w|%gUNLOCKTEAM %w Locks/Unlocks teams. Only invited players may join locked team." HelpInfo(2)="%gPAUSE %yX %w Pause the game for X seconds" HelpInfo(3)="%gEND TRADE %w Immediately end current trader time and start next wave" HelpInfo(4)="%gEND WAVE %w Kills last stuck zeds to end the wave" HelpInfo(5)="%gBLAME %y %b[] %w Blame player [for the ]" HelpInfo(6)="%gSPEC %y %b[] %w Move player to spectators" HelpInfo(7)="%gKICK %y %b[] %w Kick player [for the ]" HelpInfo(8)="%gINVITE %y %w Invite player to join locked team." HelpInfo(9)="%gBORING %w Doubles ZED spawn rate" HelpInfo(10)="%gSPAWN %y %w Spawns zed squad" HelpInfo(11)="%gREADY%w|%gUNREADY %w Makes everybody ready/unready to play" HelpInfo(12)="%gFF %yX %w Set Friendly Fire to X%" HelpInfo(13)="%gMAP RESTART %w Restarts current map" HelpInfo(14)="%gFAKED %yX %w Set Faked Players to X (FAKEDCOUNT+FAKEDHEALTH)" HelpInfo(15)="%gFAKEDCOUNT %yX %w Set Faked Players for zed count calculation" HelpInfo(16)="%gFAKEDHEALTH %yX %w Set Faked Players for zed health calculation" HelpInfo(17)="%gDIFF %yX %w Changes map difficulty (2-8) for the next map" bAlwaysTick=True }