optimize spawn cycle (improved performance on large spawn lists)

This commit is contained in:
GenZmeY 2022-05-31 06:36:42 +03:00
parent 62c3f79c5e
commit b5355d9fb5

View File

@ -6,7 +6,7 @@ const LatestVersion = 1;
const dt = 1; const dt = 1;
const CfgSpawn = class'Spawn'; const CfgSpawn = class'Spawn';
const CfgSpawnListR = class'SpawnListRegular'; const CfgSpawnListRW = class'SpawnListRegular';
const CfgSpawnListBW = class'SpawnListBossWaves'; const CfgSpawnListBW = class'SpawnListBossWaves';
const CfgSpawnListSW = class'SpawnListSpecialWaves'; const CfgSpawnListSW = class'SpawnListSpecialWaves';
@ -43,9 +43,10 @@ struct S_SpawnEntry
var private config int Version; var private config int Version;
var private config E_LogLevel LogLevel; var private config E_LogLevel LogLevel;
var private Array<S_SpawnEntry> SpawnListR; var private Array<S_SpawnEntry> SpawnListRW;
var private Array<S_SpawnEntry> SpawnListBW; var private Array<S_SpawnEntry> SpawnListBW;
var private Array<S_SpawnEntry> SpawnListSW; var private Array<S_SpawnEntry> SpawnListSW;
var private Array<S_SpawnEntry> SpawnListCurrent;
var private bool NoFreeSpawnSlots; var private bool NoFreeSpawnSlots;
var private bool UseRegularSpawnList; var private bool UseRegularSpawnList;
@ -106,7 +107,7 @@ private function InitConfig()
} }
CfgSpawn.static.InitConfig(Version, LatestVersion); CfgSpawn.static.InitConfig(Version, LatestVersion);
CfgSpawnListR.static.InitConfig(Version, LatestVersion, KFGIA); CfgSpawnListRW.static.InitConfig(Version, LatestVersion, KFGIA);
CfgSpawnListBW.static.InitConfig(Version, LatestVersion, KFGIA); CfgSpawnListBW.static.InitConfig(Version, LatestVersion, KFGIA);
CfgSpawnListSW.static.InitConfig(Version, LatestVersion); CfgSpawnListSW.static.InitConfig(Version, LatestVersion);
@ -171,7 +172,7 @@ private function Init()
return; return;
} }
SpawnListR = CfgSpawnListR.static.Load(LogLevel); SpawnListRW = CfgSpawnListRW.static.Load(LogLevel);
SpawnListBW = CfgSpawnListBW.static.Load(LogLevel); SpawnListBW = CfgSpawnListBW.static.Load(LogLevel);
SpawnListSW = CfgSpawnListSW.static.Load(KFGIE, LogLevel); SpawnListSW = CfgSpawnListSW.static.Load(KFGIE, LogLevel);
@ -183,7 +184,7 @@ private function Init()
{ {
CycleWaveSize = 0; CycleWaveSize = 0;
CycleWaveShift = MaxInt; CycleWaveShift = MaxInt;
foreach SpawnListR(SE) foreach SpawnListRW(SE)
{ {
CycleWaveShift = Min(CycleWaveShift, SE.Wave); CycleWaveShift = Min(CycleWaveShift, SE.Wave);
CycleWaveSize = Max(CycleWaveSize, SE.Wave); CycleWaveSize = Max(CycleWaveSize, SE.Wave);
@ -210,7 +211,7 @@ private function PreloadContent()
{ {
local class<KFPawn_Monster> PawnClass; local class<KFPawn_Monster> PawnClass;
ExtractCustomZedsFromSpawnList(SpawnListR, CustomZeds); ExtractCustomZedsFromSpawnList(SpawnListRW, CustomZeds);
ExtractCustomZedsFromSpawnList(SpawnListBW, CustomZeds); ExtractCustomZedsFromSpawnList(SpawnListBW, CustomZeds);
ExtractCustomZedsFromSpawnList(SpawnListSW, CustomZeds); ExtractCustomZedsFromSpawnList(SpawnListSW, CustomZeds);
@ -237,15 +238,11 @@ private function ExtractCustomZedsFromSpawnList(Array<S_SpawnEntry> SpawnList, o
public function bool WaveConditionRegular(S_SpawnEntry SE) public function bool WaveConditionRegular(S_SpawnEntry SE)
{ {
`ZS_Trace(`Location);
return (SE.Wave == KFGIS.WaveNum - CycleWaveSize * (CurrentCycle - 1)); return (SE.Wave == KFGIS.WaveNum - CycleWaveSize * (CurrentCycle - 1));
} }
public function bool WaveConditionBoss(S_SpawnEntry SE) public function bool WaveConditionBoss(S_SpawnEntry SE)
{ {
`ZS_Trace(`Location);
if (CurrentBossClass == None) if (CurrentBossClass == None)
return false; return false;
else else
@ -254,13 +251,15 @@ public function bool WaveConditionBoss(S_SpawnEntry SE)
public function bool WaveConditionSpecial(S_SpawnEntry SE) public function bool WaveConditionSpecial(S_SpawnEntry SE)
{ {
`ZS_Trace(`Location);
return (SE.Wave == SpecialWave); return (SE.Wave == SpecialWave);
} }
private function SpawnTimer() private function SpawnTimer()
{ {
local S_SpawnEntry SE;
local int Index;
`ZS_Trace(`Location); `ZS_Trace(`Location);
if (KFGIS.WaveNum != 0 && CurrentWave < KFGIS.WaveNum) if (KFGIS.WaveNum != 0 && CurrentWave < KFGIS.WaveNum)
@ -292,9 +291,24 @@ private function SpawnTimer()
SpawnTimerLogger(false, SpawnListsComment); SpawnTimerLogger(false, SpawnListsComment);
if (UseRegularSpawnList) SpawnZeds(SpawnListR, WaveConditionRegular); foreach SpawnListCurrent(SE, Index)
if (UseSpecialSpawnList) SpawnZeds(SpawnListSW, WaveConditionSpecial); {
if (UseBossSpawnList) SpawnZeds(SpawnListBW, WaveConditionBoss); if (!ReadyToStart(SE))
{
continue;
}
if (SE.Delay > 0)
{
SpawnListCurrent[Index].Delay -= dt;
continue;
}
if (SE.SpawnsLeft > 0)
{
SpawnEntry(SpawnListCurrent, Index);
}
}
} }
private function SetupWave() private function SetupWave()
@ -350,21 +364,34 @@ private function SetupWave()
CurrentBossClass = None; CurrentBossClass = None;
} }
ResetSpawnList(SpawnListR);
ResetSpawnList(SpawnListSW);
ResetSpawnList(SpawnListBW);
NoFreeSpawnSlots = false; NoFreeSpawnSlots = false;
UseBossSpawnList = KFGIS.MyKFGRI.IsBossWave(); UseBossSpawnList = KFGIS.MyKFGRI.IsBossWave();
UseSpecialSpawnList = (SpecialWave != INDEX_NONE); UseSpecialSpawnList = (SpecialWave != INDEX_NONE);
UseRegularSpawnList = ((!UseSpecialSpawnList && !UseBossSpawnList) UseRegularSpawnList = ((!UseSpecialSpawnList && !UseBossSpawnList)
|| (UseSpecialSpawnList && !CfgSpawnListSW.default.bStopRegularSpawn) || (UseSpecialSpawnList && !CfgSpawnListSW.default.bStopRegularSpawn)
|| (UseBossSpawnList && !CfgSpawnListBW.default.bStopRegularSpawn)); || (UseBossSpawnList && !CfgSpawnListBW.default.bStopRegularSpawn));
SpawnListCurrent.Length = 0;
if (UseRegularSpawnList)
{
SpawnListNames.AddItem("regular");
FillCurrentSpawnList(SpawnListRW, WaveConditionRegular);
}
if (UseSpecialSpawnList)
{
SpawnListNames.AddItem("special");
FillCurrentSpawnList(SpawnListSW, WaveConditionSpecial);
}
if (UseBossSpawnList)
{
SpawnListNames.AddItem("boss");
FillCurrentSpawnList(SpawnListBW, WaveConditionBoss);
}
if (UseRegularSpawnList) SpawnListNames.AddItem("regular");
if (UseSpecialSpawnList) SpawnListNames.AddItem("special");
if (UseBossSpawnList) SpawnListNames.AddItem("boss");
JoinArray(SpawnListNames, SpawnListsComment, ", "); JoinArray(SpawnListNames, SpawnListsComment, ", ");
ResetSpawnList(SpawnListCurrent);
if (WaveTypeInfo != "") if (WaveTypeInfo != "")
{ {
@ -374,6 +401,17 @@ private function SetupWave()
`ZS_Info("Wave" @ CurrentWave @ WaveTypeInfo); `ZS_Info("Wave" @ CurrentWave @ WaveTypeInfo);
} }
private function FillCurrentSpawnList(Array<S_SpawnEntry> SpawnList, delegate<WaveCondition> Condition)
{
local S_SpawnEntry SE;
`ZS_Trace(`Location);
foreach SpawnList(SE)
if (Condition(SE))
SpawnListCurrent.AddItem(SE);
}
private function ResetSpawnList(out Array<S_SpawnEntry> List) private function ResetSpawnList(out Array<S_SpawnEntry> List)
{ {
local S_SpawnEntry SE; local S_SpawnEntry SE;
@ -405,7 +443,7 @@ private function ResetSpawnList(out Array<S_SpawnEntry> List)
else else
{ {
List[Index].RelativeStart = SE.RelativeStartDefault; List[Index].RelativeStart = SE.RelativeStartDefault;
if (SE.RelativeStart == 0.f) if (List[Index].RelativeStart == 0.f)
List[Index].Delay = SE.DelayDefault; List[Index].Delay = SE.DelayDefault;
else else
List[Index].Delay = 0; List[Index].Delay = 0;
@ -439,36 +477,6 @@ private function SpawnTimerLogger(bool Stop, optional String Comment)
} }
} }
private function SpawnZeds(out Array<S_SpawnEntry> SpawnList, delegate<WaveCondition> Condition)
{
local S_SpawnEntry SE;
local int Index;
`ZS_Trace(`Location);
foreach SpawnList(SE, Index)
{
if (Condition(SE))
{
if (!ReadyToStart(SE))
{
continue;
}
if (SE.Delay > 0)
{
SpawnList[Index].Delay -= dt;
continue;
}
if (SE.SpawnsLeft > 0)
{
SpawnEntry(SpawnList, Index);
}
}
}
}
private function bool ReadyToStart(S_SpawnEntry SE) private function bool ReadyToStart(S_SpawnEntry SE)
{ {
`ZS_Trace(`Location); `ZS_Trace(`Location);