remake mod structure into my template

This commit is contained in:
GenZmeY 2023-05-20 21:10:14 +03:00
parent 7b5669febf
commit 5f4b2abfe5
3 changed files with 320 additions and 153 deletions

View File

@ -0,0 +1,77 @@
class OptionsParser extends Object;
const GameInfo = class'GameInfo';
/**
*** @brief Gets a int from the launch command if available.
***
*** @param Options - options passed in via the launch command
*** @param ParseString - the variable we are looking for
*** @param CurrentValue - the current value of the variable
*** @return int value of the option we are looking for
***/
static function int GetIntOption( string Options, string ParseString, int CurrentValue)
{
return GameInfo.static.GetIntOption(Options, ParseString, CurrentValue);
}
/**
*** @brief Gets a bool from the launch command if available.
***
*** @param Options - options passed in via the launch command
*** @param ParseString - the variable we are looking for
*** @param CurrentValue - the current value of the variable
*** @return bool value of the option we are looking for
***/
static public function bool GetBoolOption(string Options, string ParseString, bool CurrentValue)
{
local string InOpt;
//Find the value associated with this variable in the launch command.
InOpt = GameInfo.static.ParseOption(Options, ParseString);
if(InOpt != "")
{
return bool(InOpt);
}
//If a value for this variable was not specified in the launch command, return the original value.
return CurrentValue;
}
/**
*** @brief Gets a string from the launch command if available.
***
*** @param Options - options passed in via the launch command
*** @param ParseString - the variable we are looking for
*** @param CurrentValue - the current value of the variable
*** @return string value of the option we are looking for
***/
static public function string GetStringOption(string Options, string ParseString, string CurrentValue)
{
local string InOpt;
//Find the value associated with this variable in the launch command.
InOpt = GameInfo.static.ParseOption(Options, ParseString);
if(InOpt != "")
{
return InOpt;
}
//If a value for this variable was not specified in the launch command, return the original value.
return CurrentValue;
}
/**
*** @brief Gets a LogLevel from the launch command if available.
***
*** @param Options - options passed in via the launch command
*** @param ParseString - the variable we are looking for
*** @param CurrentValue - the current value of the variable
*** @return E_LogLevel value of the option we are looking for
***/
static public function E_LogLevel GetLogLevelOption(string Options, string ParseString, E_LogLevel CurrentValue)
{
return CurrentValue; // TODO: impl
}

View File

@ -1,6 +1,14 @@
class StartWave extends KFMutator class StartWave extends Info
config(StartWave); config(StartWave);
const OptionsParser = class'OptionsParser';
var private KFGameInfo KFGI;
var private KFGameInfo_Survival KFGIS;
var private KFGameInfo_Endless KFGIE;
var private KFGameReplicationInfo KFGRI;
/********************************************************************************************************* /*********************************************************************************************************
* Config properties * Config properties
*********************************************************************************************************/ *********************************************************************************************************/
@ -37,29 +45,71 @@ var bool bOverridenDifficultySettings;
/** Whether the trader duration has been overriden. */ /** Whether the trader duration has been overriden. */
var bool bOverridenTraderDuration; var bool bOverridenTraderDuration;
function InitMutator(string Options, out string ErrorMessage) public simulated function bool SafeDestroy()
{ {
//This needs to be called first since KFMutator.InitMutator sets the MyKFGI reference. `Log_Trace();
Super.InitMutator(Options, ErrorMessage);
return (bPendingDelete || bDeleteMe || Destroy());
}
public event PreBeginPlay()
{
`Log_Trace();
if (WorldInfo.NetMode == NM_Client)
{
`Log_Fatal("Wrong NetMode:" @ WorldInfo.NetMode);
SafeDestroy();
return;
}
Super.PreBeginPlay();
PreInit();
}
public event PostBeginPlay()
{
`Log_Trace();
if (bPendingDelete || bDeleteMe) return;
Super.PostBeginPlay();
PostInit();
}
private function PreInit()
{
local String Options;
`Log_Trace();
Options = WorldInfo.GetLocalURL();
//Parse options entered via the launch command. //Parse options entered via the launch command.
//We further restrict StartWave later when we know the maximum wave number for the selected game length. //We further restrict StartWave later when we know the maximum wave number for the selected game length.
StartWave = Max(class'GameInfo'.static.GetIntOption(Options, "StartWave", StartWave), 1); StartWave = OptionsParser.static.GetIntOption (Options, "StartWave", StartWave);
InitialTraderTime = Max(class'GameInfo'.static.GetIntOption(Options, "InitialTraderTime", InitialTraderTime = OptionsParser.static.GetIntOption (Options, "InitialTraderTime", InitialTraderTime);
InitialTraderTime), 1); TraderTime = OptionsParser.static.GetIntOption (Options, "TraderTime", TraderTime);
TraderTime = Max(class'GameInfo'.static.GetIntOption(Options, "TraderTime", TraderTime), 1); Dosh = OptionsParser.static.GetIntOption (Options, "Dosh", Dosh);
Dosh = Max(class'GameInfo'.static.GetIntOption(Options, "Dosh", Dosh), 0); Boss = OptionsParser.static.GetIntOption (Options, "Boss", Boss);
Boss = class'GameInfo'.static.GetIntOption(Options, "Boss", Boss); bStartWithTrader = OptionsParser.static.GetBoolOption (Options, "bStartWithTrader", bStartWithTrader);
bStartWithTrader = GetBoolOption(Options, "bStartWithTrader", bStartWithTrader); LogLevel = OptionsParser.static.GetLogLevelOption(Options, "LogLevel", LogLevel);
LogLevel = E_LogLevel(class'GameInfo'.static.GetIntOption(Options, "LogLevel", LogLevel));
// Adjust values if needed
StartWave = Max(StartWave, 1);
InitialTraderTime = Max(InitialTraderTime, 1);
TraderTime = Max(TraderTime, 1);
Dosh = Max(Dosh, 0);
//DEBUG //DEBUG
`Log_Debug("StartWave: " $ StartWave); `Log_Debug("StartWave:" @ StartWave);
`Log_Debug("InitialTraderTime: " $ InitialTraderTime); `Log_Debug("InitialTraderTime:" @ InitialTraderTime);
`Log_Debug("TraderTime: " $ TraderTime); `Log_Debug("TraderTime:" @ TraderTime);
`Log_Debug("Dosh: " $ Dosh); `Log_Debug("Dosh:" @ Dosh);
`Log_Debug("Boss: " $ Boss); `Log_Debug("Boss:" @ Boss);
`Log_Debug("bStartWithTrader: " $ bStartWithTrader); `Log_Debug("bStartWithTrader:" @ bStartWithTrader);
bOverridenDifficultySettings = false; bOverridenDifficultySettings = false;
bOverridenTraderDuration = false; bOverridenTraderDuration = false;
@ -67,7 +117,7 @@ function InitMutator(string Options, out string ErrorMessage)
SetTimer(0.1, false, nameof(OverrideTimer)); SetTimer(0.1, false, nameof(OverrideTimer));
//Override the boss with the boss corresponding to the specified boss index. -1 signifies random. //Override the boss with the boss corresponding to the specified boss index. -1 signifies random.
if(Boss != -1) if (Boss != -1)
{ {
SetTimer(0.1, false, nameof(OverrideBoss)); SetTimer(0.1, false, nameof(OverrideBoss));
} }
@ -78,26 +128,50 @@ function InitMutator(string Options, out string ErrorMessage)
bInitialTrader = bStartWithTrader; bInitialTrader = bStartWithTrader;
//If we want to start with the trader active or alter the starting wave number. //If we want to start with the trader active or alter the starting wave number.
if(bStartWithTrader || StartWave > 1) if (bStartWithTrader || StartWave > 1)
{ {
`Log_Debug("Calling StartWaveTimer() to alter the start wave or activate the trader initially."); `Log_Debug("Calling StartWaveTimer() to alter the start wave or activate the trader initially.");
SetTimer(0.2, false, nameof(StartWaveTimer)); SetTimer(0.2, false, nameof(StartWaveTimer));
} }
//If we will need to alter TimeBetweenWaves for later activations of the trader. //If we will need to alter TimeBetweenWaves for later activations of the trader.
if(bStartWithTrader && InitialTraderTime != TraderTime) if (bStartWithTrader && InitialTraderTime != TraderTime)
{ {
`Log_Debug("Calling UpdateTraderDurationTimer() to alter the trader duration later."); `Log_Debug("Calling UpdateTraderDurationTimer() to alter the trader duration later.");
SetTimer(1, true, nameof(UpdateTraderDurationTimer)); SetTimer(1, true, nameof(UpdateTraderDurationTimer));
} }
} }
private function PostInit()
{
`Log_Trace();
KFGI = KFGameInfo(WorldInfo.Game);
if (KFGIS == None)
{
`Log_Fatal("Incompatible gamemode:" @ WorldInfo.Game $ ". Destroy...");
SafeDestroy();
return;
}
KFGIS = KFGameInfo_Survival(KFGI);
if (KFGIS == None)
{
`Log_Warn("The game mode does not extend KFGameInfo_Survival. Most features of this mutator are not compatible with non-wave-based game modes.");
}
KFGIE = KFGameInfo_Endless(KFGIS);
KFGRI = KFGI.MyKFGRI;
}
/** Allows for handling player input in the console by the mutator. */ /** Allows for handling player input in the console by the mutator. */
function Mutate(string MutateString, PlayerController Sender) public function Mutate(string MutateString, PlayerController Sender)
{ {
local array<string> CommandBreakdown; local array<string> CommandBreakdown;
if(MutateString == "") `Log_Trace();
if (MutateString == "")
{ {
return; return;
} }
@ -106,13 +180,15 @@ function Mutate(string MutateString, PlayerController Sender)
ParseStringIntoArray(MutateString, CommandBreakdown, " ", true); ParseStringIntoArray(MutateString, CommandBreakdown, " ", true);
//The CheatManager check is equivalent to checking if cheats are enabled for that player. //The CheatManager check is equivalent to checking if cheats are enabled for that player.
if(CommandBreakdown.Length > 1 && CommandBreakdown[0] == "setwave" && Sender.CheatManager != None && if (CommandBreakdown.Length > 1&&
MyKFGI.GetLivingPlayerCount() > 0) CommandBreakdown[0] == "setwave" &&
Sender.CheatManager != None &&
KFGI.GetLivingPlayerCount() > 0)
{ {
//The setwave command should be: mutate setwave WaveNum bSkipTraderTime //The setwave command should be: mutate setwave WaveNum bSkipTraderTime
//where WaveNum is an integer (or byte) and bSkipTraderTime is a bool. //where WaveNum is an integer (or byte) and bSkipTraderTime is a bool.
if(CommandBreakdown.Length == 2) if (CommandBreakdown.Length == 2)
{ {
SetWave(int(CommandBreakdown[1]), Sender); SetWave(int(CommandBreakdown[1]), Sender);
} }
@ -121,23 +197,23 @@ function Mutate(string MutateString, PlayerController Sender)
SetWave(int(CommandBreakdown[1]), Sender, bool(CommandBreakdown[2])); SetWave(int(CommandBreakdown[1]), Sender, bool(CommandBreakdown[2]));
} }
} }
Super.Mutate(MutateString, Sender);
} }
/** Jumps to the specified wave, NewWaveNum, with trader time iff bSkipTraderTime is false. */ /** Jumps to the specified wave, NewWaveNum, with trader time iff bSkipTraderTime is false. */
function SetWave(int NewWaveNum, PlayerController PC, optional bool bSkipTraderTime) private function SetWave(int NewWaveNum, PlayerController PC, optional bool bSkipTraderTime)
{ {
if(NewWaveNum < 1) `Log_Trace();
if (NewWaveNum < 1)
{ {
`Log_Error("SetWave: new wave num must be > 0."); `Log_Error("SetWave: new wave num must be > 0.");
return; return;
} }
if(KFGameInfo_Endless(MyKFGI) != None) if (KFGIE != None)
{ {
//Jump straight to the final wave if the specified wave number is higher than wave max. //Jump straight to the final wave if the specified wave number is higher than wave max.
if(NewWaveNum > 254) if (NewWaveNum > 254)
{ {
NewWaveNum = 254; NewWaveNum = 254;
} }
@ -145,83 +221,87 @@ function SetWave(int NewWaveNum, PlayerController PC, optional bool bSkipTraderT
else else
{ {
//Jump straight to the boss wave if the specified wave number is higher than wave max. //Jump straight to the boss wave if the specified wave number is higher than wave max.
if(NewWaveNum > KFGameInfo_Survival(MyKFGI).WaveMax) if (NewWaveNum > KFGameInfo_Survival(KFGI).WaveMax)
{ {
NewWaveNum = KFGameInfo_Survival(MyKFGI).WaveMax+1; NewWaveNum = KFGameInfo_Survival(KFGI).WaveMax+1;
} }
} }
KFGameInfo_Survival(MyKFGI).WaveNum = NewWaveNum - 1; if (KFGIS != None)
{
KFGIS.WaveNum = NewWaveNum - 1;
}
//Kill all zeds currently alive. //Kill all zeds currently alive.
PC.ConsoleCommand("KillZeds"); PC.ConsoleCommand("KillZeds");
//Clear any current objectives. //Clear any current objectives.
MyKFGI.MyKFGRI.DeactivateObjective(); KFGRI.DeactivateObjective();
if(bSkipTraderTime) if (bSkipTraderTime)
{ {
//Go to some unused state so that PlayingWave.BeginState is called when we go to PlayingWave. //Go to some unused state so that PlayingWave.BeginState is called when we go to PlayingWave.
MyKFGI.GotoState('TravelTheWorld'); KFGI.GotoState('TravelTheWorld');
UpdateEndlessDifficulty(); UpdateEndlessDifficulty();
//Go to PlayingWave to start the new wave. //Go to PlayingWave to start the new wave.
MyKFGI.GotoState('PlayingWave'); KFGI.GotoState('PlayingWave');
} }
else else
{ {
//Go to trader time before starting the new wave. //Go to trader time before starting the new wave.
MyKFGI.GotoState('TraderOpen'); KFGI.GotoState('TraderOpen');
UpdateEndlessDifficulty(); UpdateEndlessDifficulty();
} }
MyKFGI.ResetAllPickups(); KFGI.ResetAllPickups();
} }
/** /**
*** Since the difficulty in Endless scales with the wave number, we need to update the difficulty when *** Since the difficulty in Endless scales with the wave number, we need to update the difficulty when
*** jumping between wave numbers to match the expected difficulty. *** jumping between wave numbers to match the expected difficulty.
***/ ***/
function UpdateEndlessDifficulty() private function UpdateEndlessDifficulty()
{ {
local KFGameInfo_Endless Endless;
local int i; local int i;
Endless = KFGameInfo_Endless(MyKFGI); `Log_Trace();
if(Endless == None) if (KFGIE == None)
{ {
return; return;
} }
//Reflects the difficulty update in KFGameInfo_Endless.SetWave. //Reflects the difficulty update in KFGameInfo_Endless.SetWave.
Endless.bIsInHoePlus = false; KFGIE.bIsInHoePlus = false;
Endless.ResetDifficulty(); KFGIE.ResetDifficulty();
Endless.SpawnManager.GetWaveSettings(Endless.SpawnManager.WaveSettings); KFGIE.SpawnManager.GetWaveSettings(KFGIE.SpawnManager.WaveSettings);
Endless.UpdateGameSettings(); KFGIE.UpdateGameSettings();
//Don't bother iterating for i=0-4, no difficulty increment can occur. //Don't bother iterating for i=0-4, no difficulty increment can occur.
for(i = 5; i < Endless.WaveNum; ++i) for (i = 5; i < KFGIE.WaveNum; ++i)
{ {
//Simulate the death of a boss. The difficulty is incremented after each boss round. //Simulate the death of a boss. The difficulty is incremented after each boss round.
if(i % 5 == 0) if (i % 5 == 0)
{ {
Endless.IncrementDifficulty(); KFGIE.IncrementDifficulty();
} }
//This should happen at the end of each wave (if we're in HoE+). The check is handled internally. //This should happen at the end of each wave (if we're in HoE+). The check is handled internally.
//We do this after the simulation of a boss death so that bIsInHoePlus can be set first. //We do this after the simulation of a boss death so that bIsInHoePlus can be set first.
Endless.HellOnEarthPlusRoundIncrement(); KFGIE.HellOnEarthPlusRoundIncrement();
} }
} }
/** Checks whether we should force the initial trader, regardless of the config/command value. */ /** Checks whether we should force the initial trader, regardless of the config/command value. */
function CheckForceInitialTrader() private function CheckForceInitialTrader()
{ {
`Log_Trace();
//Force the initial trader for compatibility with holdout maps. Otherwise, zeds spawn in the wrong room. //Force the initial trader for compatibility with holdout maps. Otherwise, zeds spawn in the wrong room.
if(!bStartWithTrader && StartWave > 1) if (!bStartWithTrader && StartWave > 1)
{ {
bStartWithTrader = true; bStartWithTrader = true;
InitialTraderTime = 1.0; InitialTraderTime = 1.0;
@ -229,13 +309,15 @@ function CheckForceInitialTrader()
} }
/** Overrides the boss to spawn if a valid boss index has been specified. */ /** Overrides the boss to spawn if a valid boss index has been specified. */
function OverrideBoss() private function OverrideBoss()
{ {
local bool bHalt; local bool bHalt;
local byte MaxIters, i, MaxSameIters, PrevIndex, SameIters; local byte MaxIters, i, MaxSameIters, PrevIndex, SameIters;
`Log_Trace();
//We need a valid KFGRI reference as we use its public BossIndex field. //We need a valid KFGRI reference as we use its public BossIndex field.
if(MyKFGI.MyKFGRI == None) if (KFGRI == None)
{ {
SetTimer(0.2, false, nameof(OverrideBoss)); SetTimer(0.2, false, nameof(OverrideBoss));
return; return;
@ -254,33 +336,33 @@ function OverrideBoss()
//while we assume the index is forced, in which case we can't do anything about it. //while we assume the index is forced, in which case we can't do anything about it.
SameIters = 0; SameIters = 0;
MaxSameIters = 10; MaxSameIters = 10;
PrevIndex = MyKFGI.MyKFGRI.BossIndex; PrevIndex = KFGRI.BossIndex;
bHalt = Boss < 0 || MyKFGI.MyKFGRI.BossIndex == Boss; bHalt = Boss < 0 || KFGRI.BossIndex == Boss;
while(!bHalt) while (!bHalt)
{ {
++i; ++i;
//Randomly select a new boss. //Randomly select a new boss.
MyKFGI.SetBossIndex(); KFGI.SetBossIndex();
//Track whether the boss index is changing. //Track whether the boss index is changing.
if(MyKFGI.MyKFGRI.BossIndex == PrevIndex) if (KFGRI.BossIndex == PrevIndex)
{ {
++SameIters; ++SameIters;
} }
else else
{ {
SameIters = 0; SameIters = 0;
PrevIndex = MyKFGI.MyKFGRI.BossIndex; PrevIndex = KFGRI.BossIndex;
} }
//Halt if we have the desired index or we have tried enough times. //Halt if we have the desired index or we have tried enough times.
bHalt = MyKFGI.MyKFGRI.BossIndex == Boss || SameIters >= MaxSameIters || i >= MaxIters; bHalt = KFGRI.BossIndex == Boss || SameIters >= MaxSameIters || i >= MaxIters;
} }
if(MyKFGI.MyKFGRI.BossIndex == Boss) if (KFGRI.BossIndex == Boss)
{ {
`Log_Debug("Successfully overrode boss index to" @ Boss @ "after" @ i @ "attempts."); `Log_Debug("Successfully overrode boss index to" @ Boss @ "after" @ i @ "attempts.");
} }
@ -291,41 +373,40 @@ function OverrideBoss()
} }
/** Overrides difficulty settings and trader duration when possible. */ /** Overrides difficulty settings and trader duration when possible. */
function OverrideTimer() private function OverrideTimer()
{ {
local KFGameInfo_Survival KFGI_Surv; local KFGameDifficulty_Endless KFGDE;
local KFGameInfo_Endless KFGI_Endl;
local KFGameDifficulty_Endless KFGD_Endl;
local int i; local int i;
`Log_Trace();
//If we've overriden what we need to, don't call this timer again. //If we've overriden what we need to, don't call this timer again.
if(bOverridenDifficultySettings && bOverridenTraderDuration) if (bOverridenDifficultySettings && bOverridenTraderDuration)
{ {
`Log_Debug("All settings have been overriden."); `Log_Debug("All settings have been overriden.");
return; return;
} }
if(!bOverridenDifficultySettings && MyKFGI.DifficultyInfo != None) if (!bOverridenDifficultySettings && KFGI.DifficultyInfo != None)
{ {
`Log_Debug("Overriding difficulty settings..."); `Log_Debug("Overriding difficulty settings...");
bOverridenDifficultySettings = true; bOverridenDifficultySettings = true;
//Override starting dosh. //Override starting dosh.
MyKFGI.DifficultyInfo.Normal.StartingDosh = Dosh; KFGI.DifficultyInfo.Normal.StartingDosh = Dosh;
MyKFGI.DifficultyInfo.Hard.StartingDosh = Dosh; KFGI.DifficultyInfo.Hard.StartingDosh = Dosh;
MyKFGI.DifficultyInfo.Suicidal.StartingDosh = Dosh; KFGI.DifficultyInfo.Suicidal.StartingDosh = Dosh;
MyKFGI.DifficultyInfo.HellOnEarth.StartingDosh = Dosh; KFGI.DifficultyInfo.HellOnEarth.StartingDosh = Dosh;
KFGI_Endl = KFGameInfo_Endless(MyKFGI); if (KFGIE != None)
if (KFGI_Endl != None)
{ {
KFGD_Endl = KFGameDifficulty_Endless(KFGI_Endl.DifficultyInfo); KFGDE = KFGameDifficulty_Endless(KFGIE.DifficultyInfo);
if (KFGD_Endl != None) if (KFGDE != None)
{ {
for (i = 0; i < KFGD_Endl.CurrentDifficultyScaling.Difficulties.length; ++i) for (i = 0; i < KFGDE.CurrentDifficultyScaling.Difficulties.length; ++i)
{ {
KFGD_Endl.CurrentDifficultyScaling.Difficulties[i].StartingDosh = Dosh; KFGDE.CurrentDifficultyScaling.Difficulties[i].StartingDosh = Dosh;
} }
} }
} }
@ -334,19 +415,17 @@ function OverrideTimer()
//We need to set the difficulty settings again - normally done in KFGameInfo.InitGame - to apply //We need to set the difficulty settings again - normally done in KFGameInfo.InitGame - to apply
//these changes, since this happens after InitGame is executed. //these changes, since this happens after InitGame is executed.
MyKFGI.DifficultyInfo.SetDifficultySettings(MyKFGI.GameDifficulty); KFGI.DifficultyInfo.SetDifficultySettings(KFGI.GameDifficulty);
} }
//Set the starting wave number. //Set the starting wave number.
if(!bOverridenTraderDuration) if (!bOverridenTraderDuration)
{ {
KFGI_Surv = KFGameInfo_Survival(MyKFGI); if (KFGIS != None)
if(KFGI_Surv != None)
{ {
//We require the SpawnManager to be set, because this signifies that InitSpawnManager has been //We require the SpawnManager to be set, because this signifies that InitSpawnManager has been
//executed, which sets WaveMax. //executed, which sets WaveMax.
if(MyKFGI.SpawnManager != None) if (KFGI.SpawnManager != None)
{ {
`Log_Debug("Overriding trader duration..."); `Log_Debug("Overriding trader duration...");
@ -355,13 +434,13 @@ function OverrideTimer()
//Since InitSpawnManager has been executed, then PreBeginPlay must have been executed. This //Since InitSpawnManager has been executed, then PreBeginPlay must have been executed. This
//means that PostBeginPlay will have been executed as well since it happens straight after. //means that PostBeginPlay will have been executed as well since it happens straight after.
//Now we can override TimeBetweenWaves. //Now we can override TimeBetweenWaves.
KFGI_Surv.TimeBetweenWaves = bInitialTrader ? InitialTraderTime : TraderTime; KFGIS.TimeBetweenWaves = bInitialTrader ? InitialTraderTime : TraderTime;
`Log_Debug("Trader duration has been set to:" @ KFGI_Surv.TimeBetweenWaves @ "seconds."); `Log_Debug("Trader duration has been set to:" @ KFGIS.TimeBetweenWaves @ "seconds.");
} }
else else
{ {
`Log_Debug("MyKFGI.SpawnManager hasn't been set yet. Calling StartWaveTimer again."); `Log_Debug("KFGI.SpawnManager hasn't been set yet. Calling StartWaveTimer again.");
//We don't know WaveMax yet, so we need to wait longer. //We don't know WaveMax yet, so we need to wait longer.
SetTimer(0.1, false, nameof(StartWaveTimer)); SetTimer(0.1, false, nameof(StartWaveTimer));
@ -378,22 +457,21 @@ function OverrideTimer()
SetTimer(0.1, false, nameof(OverrideTimer)); SetTimer(0.1, false, nameof(OverrideTimer));
} }
function StartWaveTimer() private function StartWaveTimer()
{ {
local KFGameInfo_Survival KFGI_Surv;
local PlayerController PC; local PlayerController PC;
`Log_Trace();
//We need to wait for the wave to be active, as this will signify that StartMatch has been executed. //We need to wait for the wave to be active, as this will signify that StartMatch has been executed.
if(!MyKFGI.IsWaveActive()) if (!KFGI.IsWaveActive())
{ {
//If the wave isn't active yet (probably still in lobby), wait. //If the wave isn't active yet (probably still in lobby), wait.
SetTimer(0.1, false, nameof(StartWaveTimer)); SetTimer(0.1, false, nameof(StartWaveTimer));
return; return;
} }
KFGI_Surv = KFGameInfo_Survival(MyKFGI); if (KFGIS == None)
if(KFGI_Surv == None)
{ {
return; return;
} }
@ -412,50 +490,52 @@ function StartWaveTimer()
//Set the starting wave number. //Set the starting wave number.
//Keep the assignments separated so that we can used the restricted StartWave later if we want. //Keep the assignments separated so that we can used the restricted StartWave later if we want.
StartWave = Min(StartWave, KFGI_Surv.WaveMax); StartWave = Min(StartWave, KFGIS.WaveMax);
//We need to subtract 1 because when the state is eventually reset to PlayingWave, this will be //We need to subtract 1 because when the state is eventually reset to PlayingWave, this will be
//incremented by 1. //incremented by 1.
KFGI_Surv.WaveNum = StartWave - 1; KFGIS.WaveNum = StartWave - 1;
`Log_Debug("WaveNum set to:" @ KFGI_Surv.WaveNum); `Log_Debug("WaveNum set to:" @ KFGIS.WaveNum);
if(bStartWithTrader) if (bStartWithTrader)
{ {
`Log_Debug("Switching to state: TraderOpen."); `Log_Debug("Switching to state: TraderOpen.");
//We need to update GRI's WaveNum and update the HUD element that shows the last wave. //We need to update GRI's WaveNum and update the HUD element that shows the last wave.
MyKFGI.MyKFGRI.WaveNum = KFGI_Surv.WaveNum; KFGRI.WaveNum = KFGIS.WaveNum;
MyKFGI.MyKFGRI.UpdateHUDWaveCount(); KFGRI.UpdateHUDWaveCount();
//Start with the trader active. //Start with the trader active.
MyKFGI.GotoState('TraderOpen', 'Begin'); KFGI.GotoState('TraderOpen', 'Begin');
} }
else else
{ {
`Log_Debug("Switching to state: PlayingWave."); `Log_Debug("Switching to state: PlayingWave.");
//Start with a wave as usual - but our StartWave number will be used. //Start with a wave as usual - but our StartWave number will be used.
MyKFGI.GotoState('PlayingWave'); KFGI.GotoState('PlayingWave');
} }
//Since we've updated the wave number, we need to update the game settings (which includes the //Since we've updated the wave number, we need to update the game settings (which includes the
//current wave number). //current wave number).
MyKFGI.UpdateGameSettings(); KFGI.UpdateGameSettings();
bInitialTrader = false; bInitialTrader = false;
} }
/** Updates the trader duration. Waits until the initial trader has closed. */ /** Updates the trader duration. Waits until the initial trader has closed. */
function UpdateTraderDurationTimer() private function UpdateTraderDurationTimer()
{ {
`Log_Trace();
//If the initial trader has already been opened, and the wave is now active. //If the initial trader has already been opened, and the wave is now active.
if(!bInitialTrader && MyKFGI.IsWaveActive()) if (!bInitialTrader && KFGI.IsWaveActive())
{ {
if(KFGameInfo_Survival(MyKFGI) != None) if (KFGameInfo_Survival(KFGI) != None)
{ {
`Log_Debug("Updating trader duration to" @ TraderTime @ "seconds."); `Log_Debug("Updating trader duration to" @ TraderTime @ "seconds.");
//We can update TimeBetweenWaves to be the TraderTime we specified in the launch command. //We can update TimeBetweenWaves to be the TraderTime we specified in the launch command.
KFGameInfo_Survival(MyKFGI).TimeBetweenWaves = TraderTime; KFGameInfo_Survival(KFGI).TimeBetweenWaves = TraderTime;
} }
else else
{ {
@ -467,50 +547,7 @@ function UpdateTraderDurationTimer()
} }
} }
/** defaultproperties
*** @brief Gets a bool from the launch command if available.
***
*** @param Options - options passed in via the launch command
*** @param ParseString - the variable we are looking for
*** @param CurrentValue - the current value of the variable
*** @return bool value of the option we are looking for
***/
static function bool GetBoolOption(string Options, string ParseString, bool CurrentValue)
{ {
local string InOpt;
//Find the value associated with this variable in the launch command.
InOpt = class'GameInfo'.static.ParseOption(Options, ParseString);
if(InOpt != "")
{
return bool(InOpt);
}
//If a value for this variable was not specified in the launch command, return the original value.
return CurrentValue;
}
/**
*** @brief Gets a string from the launch command if available.
***
*** @param Options - options passed in via the launch command
*** @param ParseString - the variable we are looking for
*** @param CurrentValue - the current value of the variable
*** @return string value of the option we are looking for
***/
static function string GetStringOption(string Options, string ParseString, string CurrentValue)
{
local string InOpt;
//Find the value associated with this variable in the launch command.
InOpt = class'GameInfo'.static.ParseOption(Options, ParseString);
if(InOpt != "")
{
return InOpt;
}
//If a value for this variable was not specified in the launch command, return the original value.
return CurrentValue;
} }

View File

@ -0,0 +1,53 @@
class StartWaveMut extends KFMutator;
var private StartWave StartWave;
public simulated function bool SafeDestroy()
{
return (bPendingDelete || bDeleteMe || Destroy());
}
public event PreBeginPlay()
{
Super.PreBeginPlay();
if (WorldInfo.NetMode == NM_Client) return;
foreach WorldInfo.DynamicActors(class'StartWave', StartWave)
{
break;
}
if (StartWave == None)
{
StartWave = WorldInfo.Spawn(class'StartWave');
}
if (StartWave == None)
{
`Log_Base("FATAL: Can't Spawn 'StartWave'");
SafeDestroy();
}
}
public function AddMutator(Mutator Mut)
{
if (Mut == Self || bPendingDelete || bDeleteMe) return;
if (Mut.Class == Class)
StartWaveMut(Mut).SafeDestroy();
else
Super.AddMutator(Mut);
}
public function Mutate(String MutateString, PlayerController Sender)
{
StartWave.Mutate(MutateString, Sender);
Super.Mutate(MutateString, Sender);
}
defaultproperties
{
}