//----------------------------------------------------------- // //----------------------------------------------------------- class utvMutator extends Mutator; var string origcontroller; var class origcclass; var array utvId; //C is the owner function CreateInitialUtvReplication(Controller c) { local utvReplicationInfo uri; local Controller p; foreach dynamicactors(class'Controller', p) { if (p != c) { //Log("Initially spawning utvReplicationInfo for player " $ p.PlayerReplicationInfo.PlayerName $ " owner " $ c.PlayerReplicationInfo.PlayerName); uri = Spawn(class'utvReplicationInfo', c); uri.OwnerCtrl = p; } } } //C is the possible new player function CreateUtvReplication(Controller c) { local utvReplicationInfo uri; local PlayerController pc; local bool found; foreach dynamicactors(class'PlayerController', pc) { //Only spawn these for controllers that are utv in seeall mode if (!pc.bAllActorsRelevant) continue; found = false; foreach dynamicactors(class'utvReplicationInfo', uri) { if ((uri.OwnerPlayer == c.PlayerReplicationInfo) && (uri.Owner == pc)) { found = true; break; } } if (!found) { //Log("Spawning utvReplicationInfo for player " $ c.PlayerReplicationInfo.PlayerName $ " owner " $ pc.PlayerReplicationInfo.PlayerName); uri = Spawn(class'utvReplicationInfo', pc); uri.OwnerCtrl = c; } } } function Tick(float deltaTime) { local PlayerController pc; local int i; super.Tick(deltaTime); if (utvId.Length > 0) { foreach dynamicactors(class'PlayerController', pc) { for (i = 0; i < utvId.Length; ++i) { if (pc.PlayerReplicationInfo.PlayerID == utvId[i]) { CreateInitialUtvReplication(pc); Log(FriendlyName $ ": Found new ROTV player: " $ pc.PlayerReplicationInfo.PlayerName); utvId.Remove(i, 1); i--; } } } } } //Returns a suitable UTV-spectator class. Knows about UTComp and TTM function string GetNewController() { local string cur; local string newc; cur = Level.Game.PlayerControllerClassName; //Utcomp? if (InStr(cur, "BS_") > 0) { newc = Repl(cur, "BS_", "UTV_BS_", false); Log(FriendlyName $ ": UTComp detected, using class " $ newc); } else if (InStr(cur, "TTM_PlayerController") > 0) { newc = Repl(cur, "TTM_PlayerController", "TTM_UTV_Spectator", false); Log(FriendlyName $ ": TTM detected, using class " $ newc); } else { newc = FriendlyName $ ".utvSpectator"; Log(FriendlyName $ ": Using class " $ newc); } return newc; } function ModifyLogin(out string Portal, out string Options) { local bool bSeeAll; local bool bSpectator; super.ModifyLogin (Portal, Options); if (Level.game == none) { Log (FriendlyName $ ": Level.game is none?"); return; } //If we replaced the controller last time round, make sure to restore it if (origcontroller != "") { Level.Game.PlayerControllerClassName = origcontroller; Level.Game.PlayerControllerClass = origcclass; origcontroller = ""; } bSpectator = ( Level.Game.ParseOption( Options, "SpectatorOnly" ) ~= "1" ); bSeeAll = ( Level.Game.ParseOption( Options, "UTVSeeAll" ) ~= "1" ); if (bSeeAll && bSpectator) { Log(FriendlyName $ ": Player with id " $ Level.Game.CurrentID $ " is requesting SeeAll"); utvId[utvId.Length] = Level.Game.CurrentID; origcontroller = Level.Game.PlayerControllerClassName; origcclass = Level.Game.PlayerControllerClass; Level.Game.PlayerControllerClassName = GetNewController(); Level.Game.PlayerControllerClass = none; } } function ModifyPlayer(Pawn Other) { super.ModifyPlayer(Other); CreateUtvReplication(Other.Controller); } function NotifyLogout(Controller Exiting) { local utvReplicationInfo uri; local PlayerController pc; super.NotifyLogout(Exiting); //Log if seeall players leave pc = PlayerController(Exiting); if ((pc != none) && (pc.bAllActorsRelevant)) { Log(FriendlyName $ ": SeeAll enabled player " $ Exiting.PlayerReplicationInfo.PlayerName $ " (" $ Exiting.PlayerReplicationInfo.PlayerID $ ") leaving"); } //Remove all utvReplicationInfos associated with the leaving player foreach dynamicactors(class'utvReplicationInfo', uri) { if ((uri.OwnerCtrl == Exiting) || (uri.Owner == Exiting)) { //Log("Removing utvReplication for pawn " $ Exiting $ " player " $ uri.Owner); uri.Destroy(); } } } defaultproperties { bAddToServerPackages=true IconMaterialName="MutatorArt.nosym" ConfigMenuClassName="" GroupName="" FriendlyName="UTV2004S" Description="Required to support ROTV SeeAll mode" bAlwaysTick=true }