337 lines
9.4 KiB
Ucode
337 lines
9.4 KiB
Ucode
class KF_StoryCheckPointVolumeSE extends KF_StoryCheckPointVolume;
|
|
|
|
var array<PlayerStart> ForeignPSList;
|
|
var transient bool bPSListInit;
|
|
|
|
simulated function PostBeginPlay()
|
|
{
|
|
local KF_DialogueSpot DlgSpot;
|
|
|
|
if( Level.NetMode==NM_Client )
|
|
return;
|
|
|
|
/* No KFO Gametype, no Initialization */
|
|
StoryGI = KFStoryGameInfo(Level.Game);
|
|
if(StoryGI == none)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if(RestartFromCheckPoint != "" &&
|
|
RestartFromCheckPoint != CheckPointName &&
|
|
StoryGI != none )
|
|
{
|
|
ForcedRestartCheckPoint = StoryGI.FindCheckPointNamed(RestartFromCheckPoint);
|
|
}
|
|
|
|
// cache all the DialogueSpots in the map - we'll need this to store the states for each one
|
|
foreach DynamicActors(class 'KF_DialogueSpot', DlgSpot)
|
|
{
|
|
SavedDialogue.length = SavedDialogue.length + 1;
|
|
SavedDialogue[SavedDialogue.length-1].DialogueActor = DlgSpot;
|
|
SavedDialogue[SavedDialogue.length-1].DialogueTriggerStates.length = DlgSpot.Dialogues.length ;
|
|
}
|
|
}
|
|
|
|
// copy-pasted from KFStoryGameInfo to allow use in non-story games
|
|
function int GetTotalActivePlayers()
|
|
{
|
|
local int LivingCount;
|
|
local Controller C;
|
|
|
|
for ( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
if ((C.PlayerReplicationInfo != None) &&
|
|
C.bIsPlayer && !C.PlayerReplicationInfo.bOutOfLives &&
|
|
!C.PlayerReplicationInfo.bOnlySpectator )
|
|
{
|
|
LivingCount ++ ;
|
|
}
|
|
}
|
|
|
|
// log("TOTAL PLAYERS : "@LivingCount);
|
|
|
|
return LivingCount ;
|
|
}
|
|
|
|
// bIncludeBots now can be enabled without bRespawnPlayers
|
|
function CheckPointActivated( Pawn CheckPointInstigator, bool bForceActivate, optional bool bShowMessage)
|
|
{
|
|
local KF_StoryCheckPointVolume OldCheckpoint;
|
|
local Controller C;
|
|
|
|
/* Check for a human controlled pawn */
|
|
if( CheckPointInstigator != none && CheckPointInstigator.Controller != none ) {
|
|
ActivatingPlayer = CheckPointInstigator.Controller;
|
|
if(ActivatingPlayer != none && PlayerController(ActivatingPlayer) != none &&
|
|
ActivatingPlayer.Pawn != none )
|
|
Instigator = ActivatingPlayer.Pawn ;
|
|
}
|
|
|
|
if( !bForceActivate && bRequiresWholeTeam && GetNumPlayersInVolume() < GetTotalActivePlayers())
|
|
return;
|
|
|
|
if(!bIsActive || bForceActivate || !bSingleActivationOnly)
|
|
{
|
|
// log("===============================================",'Story_Debug');
|
|
// log("CheckPointActivated! - "@CheckPointName,'Story_Debug');
|
|
|
|
bIsActive = true;
|
|
|
|
if(!bPendingFullRestart) {
|
|
TriggerActivationEvents();
|
|
|
|
if(bRespawnOnWipe)
|
|
SaveStoryState();
|
|
}
|
|
|
|
if(StoryGI != none)
|
|
{
|
|
OldCheckPoint = StoryGI.CurrentCheckPoint ;
|
|
StoryGI.CurrentCheckPoint = self ;
|
|
|
|
for ( C=Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
if(KFPlayerController_Story(C) != none)
|
|
{
|
|
KFPlayerController_Story(C).CurrentCheckPoint = self;
|
|
}
|
|
}
|
|
|
|
if(bShowMessage)
|
|
{
|
|
BroadcastLocalizedMessage( StoryGI.default.CheckPointMessageClass , 0, ActivatingPlayer.PlayerReplicationinfo, None, self );
|
|
}
|
|
}
|
|
|
|
UpdateSpawnAvailability();
|
|
ResetPlayerCheckpointStats();
|
|
|
|
if( bRespawnPlayers || bIncludeBots )
|
|
{
|
|
if ( RespawnDelay > 0 )
|
|
DelayedRespawnDeadPlayers();
|
|
else
|
|
RespawnTimerPop();
|
|
}
|
|
|
|
if( bTeleportstragglers)
|
|
{
|
|
TeleportLivingPlayers();
|
|
}
|
|
|
|
// if(Instigator == none)
|
|
// {
|
|
// log("Warning - No human instigator found when Activating "@self@". Some actors require a human instigator to trigger successfully . (Movers) ");
|
|
// }
|
|
|
|
if(bDebugCheckPoint)
|
|
{
|
|
PrintDebugText(ActivatingPlayer.PlayerReplicationInfo.PlayerName@"activated"@CheckPointName);
|
|
}
|
|
}
|
|
}
|
|
|
|
function InitPlayerStarts()
|
|
{
|
|
local NavigationPoint N;
|
|
local PlayerStart PS;
|
|
|
|
for( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) {
|
|
PS = PlayerStart(N);
|
|
if( PS!=None ) {
|
|
if(Encompasses(PS) )
|
|
PSList[PSList.Length] = PS;
|
|
else
|
|
ForeignPSList[ForeignPSList.Length] = PS;
|
|
}
|
|
}
|
|
bPSListInit = true;
|
|
}
|
|
|
|
function DebugPlayerStarts()
|
|
{
|
|
local NavigationPoint N;
|
|
local PlayerStart PS;
|
|
|
|
ClearStayingDebugLines();
|
|
for( N=Level.NavigationPointList; N!=None; N=N.NextNavigationPoint ) {
|
|
PS = PlayerStart(N);
|
|
if( PS!=None ) {
|
|
if(PS.bEnabled)
|
|
{
|
|
DrawStayingDebugLine(N.Location, N.Location + (100 * vect(0,0,1)), 0,255,0);
|
|
}
|
|
else
|
|
{
|
|
DrawStayingDebugLine(N.Location, N.Location + (100 * vect(0,0,1)), 255,0,0);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
function UpdateSpawnAvailability()
|
|
{
|
|
local int i;
|
|
|
|
if ( !bPSListInit )
|
|
InitPlayerStarts();
|
|
|
|
if( PSList.Length>0 ) {
|
|
for ( i=0; i<PSList.Length; ++i )
|
|
PSList[i].bEnabled = true;
|
|
for ( i=0; i<ForeignPSList.Length; ++i )
|
|
ForeignPSList[i].bEnabled = false;
|
|
// debug
|
|
//DebugPlayerStarts();
|
|
}
|
|
else {
|
|
for ( i=0; i<ForeignPSList.Length; ++i )
|
|
ForeignPSList[i].bEnabled = true;
|
|
log("Warning - No Playerstarts associated with "@self@": Respawns may fail.");
|
|
}
|
|
}
|
|
|
|
|
|
// allows respawning bots only (excluding players)
|
|
function RespawnDeadPlayers()
|
|
{
|
|
local int i;
|
|
local Controller C;
|
|
local KFPlayerController KFPC;
|
|
local PlayerController PC;
|
|
local KFPlayerReplicationInfo KFPRI;
|
|
local bool bWaveInProgress, bBalanceTeams;
|
|
|
|
bPendingRespawn = false;
|
|
bWaveInProgress = KFGameType(Level.Game).bWaveInProgress;
|
|
bBalanceTeams = KFGameType(Level.Game).bBalanceTeams;
|
|
KFGameType(Level.Game).bWaveInProgress = false;
|
|
KFGameType(Level.Game).bBalanceTeams = false;
|
|
|
|
For ( C= Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
if ( C.PlayerReplicationInfo != none )
|
|
{
|
|
/* I'm guessing we are still using Perks in Story mode ? ... will leave this in for now */
|
|
KFPC = KFPlayerController(C);
|
|
if ( KFPC != none )
|
|
{
|
|
KFPRI = KFPlayerReplicationInfo(C.PlayerReplicationinfo);
|
|
if ( KFPRI != none )
|
|
{
|
|
KFPC.bChangedVeterancyThisWave = false;
|
|
|
|
if ( KFPRI.ClientVeteranSkill != KFPC.SelectedVeterancy )
|
|
{
|
|
KFPC.SendSelectedVeterancyToServer();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( C.PlayerReplicationInfo.bOnlySpectator || !C.PlayerReplicationInfo.bOutOfLives )
|
|
continue;
|
|
|
|
if ( C.PlayerReplicationInfo.bBot ) {
|
|
if ( !bIncludeBots )
|
|
continue;
|
|
}
|
|
else if ( !bRespawnPlayers )
|
|
continue;
|
|
|
|
C.PlayerReplicationInfo.bOutOfLives = false;
|
|
C.PlayerReplicationInfo.NumLives = 0;
|
|
|
|
PC = PlayerController(C);
|
|
if( PC != none )
|
|
{
|
|
PC.GotoState('PlayerWaiting');
|
|
PC.SetViewTarget(C);
|
|
PC.ClientSetBehindView(false);
|
|
PC.bBehindView = False;
|
|
}
|
|
|
|
if(KFPlayerController_Story(C) != none)
|
|
{
|
|
KFPLayerController_Story(C).NumCheckPointRespawns ++ ;
|
|
}
|
|
|
|
LastRespawnedPlayer = C;
|
|
|
|
// Make sure the dude we're respawning hast at least some cash.
|
|
C.PlayerReplicationInfo.Score = Max(KFGameType(Level.Game).MinRespawnCash, int(C.PlayerReplicationInfo.Score));
|
|
C.ServerReStartPlayer();
|
|
|
|
if ( C.Pawn != none ) {
|
|
if ( bTeleportStragglers ) {
|
|
for ( i=0; i<PSList.Length; ++i )
|
|
if ( PSList[i].Accept(C.Pawn, none) )
|
|
break;
|
|
}
|
|
|
|
if( PC != none )
|
|
PC.ClientSetViewTarget(PC.Pawn);
|
|
}
|
|
}
|
|
}
|
|
|
|
KFGameType(Level.Game).bWaveInProgress = bWaveInProgress;
|
|
KFGameType(Level.Game).bBalanceTeams = bBalanceTeams;
|
|
|
|
LastRespawnedPlayer = none;
|
|
|
|
/* Full Checkpoint restart (everyone was wiped out) */
|
|
if(bPendingFullRestart && StoryGI != none)
|
|
{
|
|
bPendingFullRestart = false;
|
|
StoryGI.NotifyTeamRestarted();
|
|
}
|
|
}
|
|
|
|
function TeleportLivingPlayers()
|
|
{
|
|
local Controller C;
|
|
local bool bTeleportMe;
|
|
local int i;
|
|
|
|
For ( C= Level.ControllerList; C!=None; C=C.NextController )
|
|
{
|
|
bTeleportMe = false;
|
|
|
|
if ( C.PlayerReplicationInfo != none )
|
|
{
|
|
if(C.bIsPlayer
|
|
&& !C.PlayerReplicationInfo.bOutOfLives
|
|
&& !C.PlayerReplicationInfo.bOnlySpectator
|
|
&& C.Pawn != none && C.Pawn.Health > 0
|
|
&& C.Pawn.PhysicsVolume != self
|
|
&& ((C.PlayerReplicationInfo.bBot && bIncludeBots) || (!C.PlayerReplicationInfo.bBot && bRespawnPlayers)) )
|
|
{
|
|
if(TeleportExclusionVolume != none)
|
|
bTeleportMe = !TeleportExclusionVolume.Encompasses(C.Pawn);
|
|
else
|
|
bTeleportMe = TeleportStragglerDist == 0 || VSize(C.Pawn.Location - Location) >= TeleportStragglerDist;
|
|
|
|
if(bTeleportMe){
|
|
for ( i=0; i<PSList.Length; ++i )
|
|
if ( PSList[i].Accept(C.Pawn, none) )
|
|
break;
|
|
if ( i == PSList.Length )
|
|
log("Unable to teleport " $ C.Pawn $ " to " $ self, 'StoryCheckPoint');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function SaveStoryState()
|
|
{
|
|
if ( StoryGI != none )
|
|
super.SaveStoryState();
|
|
}
|
|
|
|
defaultproperties
|
|
{
|
|
}
|