class AutoRespawn extends KFGameInfo_Survival;
var array<Controller> PendingSpawners;
var bool bBossDied;
var array<Controller> FakedPlayers;
function Killed(Controller Killer, Controller KilledPlayer, Pawn KilledPawn, class<DamageType> damageType)
{
Super.Killed(Killer, KilledPlayer, KilledPawn, damageType);
if(KFPlayerController(KilledPlayer)!= None )
{
KilledPlayer.PlayerReplicationInfo.bForceNetUpdate = true;
if( PendingSpawners.Find(KilledPlayer) < 0 )
PendingSpawners.AddItem(KilledPlayer);
//Respawn player after 3 secs
SetTimer(3, false, 'RestartPlayer');
}
}
function RespawnPlayers()
{
local int i;
local Controller PC;
local bool bSpawned;
for( i=0; i < PendingSpawners.Length; i++ )
{
PC = PendingSpawners;
PC.PlayerReplicationInfo.bForceNetUpdate = true;
if( !bSpawned ) // Spawn only one player at a time
{
bSpawned = true;
RestartPlayer(PC);
PC.PlayerReplicationInfo.bForceNetUpdate = true;
PendingSpawners.Remove(i,1);
}
}
}
/* Spawn the Player */
function RestartPlayer(Controller NewPlayer)
{
// Super.RestartPlayer(NewPlayer);
if( NewPlayer.PlayerReplicationInfo != None )
{
WorldInfo.Game.Broadcast(NewPlayer,NewPlayer.PlayerReplicationInfo.GetHumanReadableName()@" has been revived ");
}
}
/*
function RespawnSpectators()
{
if( KFGameInfo(WorldInfo.Game) != none )
{
KFGameInfo(WorldInfo.Game).StartHumans();
}
}
*/
function BossDied(Controller Killer, optional bool bCheckWaveEnded )
{
bBossDied = true;
}
function Logout( Controller Exiting )
{
// Clean PendingSpawners on Logout
if( PendingSpawners.Find(Exiting) != -1 )
PendingSpawners.RemoveItem(Exiting);
Super.Logout( Exiting );
}
function StartMatch()
{
Super.StartMatch();
AddFakedPlayer();
}
function EndOfMatch(bool bVictory)
{
if(bBossDied == true)
{
Super.EndOfMatch(bVictory);
RemoveFakedPlayer();
}
}
function bool AddFakedPlayer()
{
local KFGameInfo KFGI;
local KFPlayerReplicationInfo KFPRI;
local int NumCurrentPlayers;
local KFAIController KFBot;
Local KFPawn_Human KFPH;
local Vector SpawnLocation;
NumCurrentPlayers = GetNumPlayers() + FakedPlayers.Length;
//Don't add faked players if the Max Players Allowed is reached
if(NumCurrentPlayers == MaxPlayersAllowed )
return false;
//replace with self?
KFGI = KFGameInfo(WorldInfo.Game);
/* Begin Copy Paste from KFCheatManager.SpawnHumanPawn */
KFPH = Spawn(class'KFPawn_Human', , , SpawnLocation);
KFPH.SetPhysics(PHYS_Falling);
// Create a new Controller for this Bot
KFBot = Spawn(class'KFAIController');
// Set Bot name
WorldInfo.Game.ChangeName(KFBot, "Faked Player", false);
// Add Bot to a team and set other stuff
KFGI.SetTeam(KFBot, KFGI.Teams[0]);
KFBot.Possess(KFPH, false);
KFBot.bGodMode = true;
KFPRI = KFPlayerReplicationInfo(KFBot.PlayerReplicationInfo);
// Set the same Character used by the current player and other perk stuff
//KFPRI.SetCharacter(KFPRI.StoredCharIndex);
KFPRI.CurrentPerkClass = Class'KFPlayerController'.default.PerkList[1].PerkClass;
KFPRI.NetPerkIndex = 1;
if( KFPRI != none )
{
KFPRI.PLayerHealthPercent = FloatToByte( float(KFPH.Health) / float(KFPH.HealthMax) );
KFPRI.PLayerHealth = KFPH.Health;
}
KFPH.AddDefaultInventory();
/* End Copy Paste from KFCheatManager.SpawnHumanPawn */
FakedPlayers.AddItem(KFBot);
// Show Message
// BroadcastLocalizedMessage( class'STMLocalMessage_Game', GMT_AddedFakedPlayer, Sender.PlayerReplicationInfo);
return true;
}
/* Remove a Faked Player */
function bool RemoveFakedPlayer()
{
local Controller KFBot;
local int LastBotIndex;
// Exit if there are no faked players to remove
if(FakedPlayers.Length == 0)
return false;
LastBotIndex = FakedPlayers.Length-1;
KFBot = FakedPlayers[LastBotIndex];
KFBot.Pawn.KilledBy(KFBot.Pawn);
KFBot.Destroy();
FakedPlayers.Remove(LastBotIndex,1);
// Show Message
// BroadcastLocalizedMessage(class'STMLocalMessage_Game', GMT_RemovedFakedPlayer, Sender.PlayerReplicationInfo);
return true;
}
//-----------End----------------------
Above is my AutoRespawn Code,
because I don't really know how to properly respawn players,
so I copied some code from https://steamcommunity.com/sharedfiles/filedetails/?id=643313659
and there comes many problems..
First,only the player who died at the end of match respawned,other players won't respawn after they died.
Second, because I naively thought that if I added some faked player, then the match won't end because there were faked player alive,but it totally gone wrong,the match still end with faked player alive and real player all dead.
So I'm here to seek you guys' opinions,hope to improve my code here..
Much thanks
var array<Controller> PendingSpawners;
var bool bBossDied;
var array<Controller> FakedPlayers;
function Killed(Controller Killer, Controller KilledPlayer, Pawn KilledPawn, class<DamageType> damageType)
{
Super.Killed(Killer, KilledPlayer, KilledPawn, damageType);
if(KFPlayerController(KilledPlayer)!= None )
{
KilledPlayer.PlayerReplicationInfo.bForceNetUpdate = true;
if( PendingSpawners.Find(KilledPlayer) < 0 )
PendingSpawners.AddItem(KilledPlayer);
//Respawn player after 3 secs
SetTimer(3, false, 'RestartPlayer');
}
}
function RespawnPlayers()
{
local int i;
local Controller PC;
local bool bSpawned;
for( i=0; i < PendingSpawners.Length; i++ )
{
PC = PendingSpawners;
PC.PlayerReplicationInfo.bForceNetUpdate = true;
if( !bSpawned ) // Spawn only one player at a time
{
bSpawned = true;
RestartPlayer(PC);
PC.PlayerReplicationInfo.bForceNetUpdate = true;
PendingSpawners.Remove(i,1);
}
}
}
/* Spawn the Player */
function RestartPlayer(Controller NewPlayer)
{
// Super.RestartPlayer(NewPlayer);
if( NewPlayer.PlayerReplicationInfo != None )
{
WorldInfo.Game.Broadcast(NewPlayer,NewPlayer.PlayerReplicationInfo.GetHumanReadableName()@" has been revived ");
}
}
/*
function RespawnSpectators()
{
if( KFGameInfo(WorldInfo.Game) != none )
{
KFGameInfo(WorldInfo.Game).StartHumans();
}
}
*/
function BossDied(Controller Killer, optional bool bCheckWaveEnded )
{
bBossDied = true;
}
function Logout( Controller Exiting )
{
// Clean PendingSpawners on Logout
if( PendingSpawners.Find(Exiting) != -1 )
PendingSpawners.RemoveItem(Exiting);
Super.Logout( Exiting );
}
function StartMatch()
{
Super.StartMatch();
AddFakedPlayer();
}
function EndOfMatch(bool bVictory)
{
if(bBossDied == true)
{
Super.EndOfMatch(bVictory);
RemoveFakedPlayer();
}
}
function bool AddFakedPlayer()
{
local KFGameInfo KFGI;
local KFPlayerReplicationInfo KFPRI;
local int NumCurrentPlayers;
local KFAIController KFBot;
Local KFPawn_Human KFPH;
local Vector SpawnLocation;
NumCurrentPlayers = GetNumPlayers() + FakedPlayers.Length;
//Don't add faked players if the Max Players Allowed is reached
if(NumCurrentPlayers == MaxPlayersAllowed )
return false;
//replace with self?
KFGI = KFGameInfo(WorldInfo.Game);
/* Begin Copy Paste from KFCheatManager.SpawnHumanPawn */
KFPH = Spawn(class'KFPawn_Human', , , SpawnLocation);
KFPH.SetPhysics(PHYS_Falling);
// Create a new Controller for this Bot
KFBot = Spawn(class'KFAIController');
// Set Bot name
WorldInfo.Game.ChangeName(KFBot, "Faked Player", false);
// Add Bot to a team and set other stuff
KFGI.SetTeam(KFBot, KFGI.Teams[0]);
KFBot.Possess(KFPH, false);
KFBot.bGodMode = true;
KFPRI = KFPlayerReplicationInfo(KFBot.PlayerReplicationInfo);
// Set the same Character used by the current player and other perk stuff
//KFPRI.SetCharacter(KFPRI.StoredCharIndex);
KFPRI.CurrentPerkClass = Class'KFPlayerController'.default.PerkList[1].PerkClass;
KFPRI.NetPerkIndex = 1;
if( KFPRI != none )
{
KFPRI.PLayerHealthPercent = FloatToByte( float(KFPH.Health) / float(KFPH.HealthMax) );
KFPRI.PLayerHealth = KFPH.Health;
}
KFPH.AddDefaultInventory();
/* End Copy Paste from KFCheatManager.SpawnHumanPawn */
FakedPlayers.AddItem(KFBot);
// Show Message
// BroadcastLocalizedMessage( class'STMLocalMessage_Game', GMT_AddedFakedPlayer, Sender.PlayerReplicationInfo);
return true;
}
/* Remove a Faked Player */
function bool RemoveFakedPlayer()
{
local Controller KFBot;
local int LastBotIndex;
// Exit if there are no faked players to remove
if(FakedPlayers.Length == 0)
return false;
LastBotIndex = FakedPlayers.Length-1;
KFBot = FakedPlayers[LastBotIndex];
KFBot.Pawn.KilledBy(KFBot.Pawn);
KFBot.Destroy();
FakedPlayers.Remove(LastBotIndex,1);
// Show Message
// BroadcastLocalizedMessage(class'STMLocalMessage_Game', GMT_RemovedFakedPlayer, Sender.PlayerReplicationInfo);
return true;
}
//-----------End----------------------
Above is my AutoRespawn Code,
because I don't really know how to properly respawn players,
so I copied some code from https://steamcommunity.com/sharedfiles/filedetails/?id=643313659
and there comes many problems..
First,only the player who died at the end of match respawned,other players won't respawn after they died.
Second, because I naively thought that if I added some faked player, then the match won't end because there were faked player alive,but it totally gone wrong,the match still end with faked player alive and real player all dead.
So I'm here to seek you guys' opinions,hope to improve my code here..
Much thanks