add custom spawn manager
This commit is contained in:
parent
e5e2b711f0
commit
e7e141d379
350
ZedSpawner/Classes/AISpawnManager.uc
Normal file
350
ZedSpawner/Classes/AISpawnManager.uc
Normal file
@ -0,0 +1,350 @@
|
|||||||
|
class AISpawnManager extends KFAISpawnManager
|
||||||
|
abstract;
|
||||||
|
|
||||||
|
const class<Config_SpawnManager> Config;
|
||||||
|
|
||||||
|
struct S_DifficultyWaveInfo
|
||||||
|
{
|
||||||
|
var Array<AIWaveInfo> Waves;
|
||||||
|
};
|
||||||
|
|
||||||
|
var protected ZedSpawner ZS;
|
||||||
|
|
||||||
|
var protected Array<S_DifficultyWaveInfo> V_DifficultyWaveSettings;
|
||||||
|
var protected S_DifficultyWaveInfo V_WaveSettings;
|
||||||
|
var protected Array<AISpawnSquad> V_AvailableSquads;
|
||||||
|
|
||||||
|
var public E_LogLevel LogLevel;
|
||||||
|
|
||||||
|
private function CopySpawnSquadArray(Array<KFAISpawnSquad> From, out Array<AISpawnSquad> To)
|
||||||
|
{
|
||||||
|
local KFAISpawnSquad SS;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
To.Length = 0;
|
||||||
|
foreach From(SS)
|
||||||
|
To.AddItem(class'AISpawnSquad'.static.CreateFrom(SS));
|
||||||
|
}
|
||||||
|
|
||||||
|
private function ZedSpawner GetZedSpawner()
|
||||||
|
{
|
||||||
|
foreach WorldInfo.DynamicActors(class'ZedSpawner', ZS)
|
||||||
|
return ZS;
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Initialize()
|
||||||
|
{
|
||||||
|
ZS = GetZedSpawner();
|
||||||
|
if (ZS != None)
|
||||||
|
{
|
||||||
|
LogLevel = ZS.LogLevel;
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
`ZS_Log("FATAL: no ZedSpawner found! Destroy" @ Self.class);
|
||||||
|
`ZS_Log("FATAL:" @ `Location);
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
|
||||||
|
Super.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetWaveSettings(out DifficultyWaveInfo WaveInfo)
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (DifficultyWaveSettings.Length > 0)
|
||||||
|
WaveInfo = DifficultyWaveSettings[Clamp(GameDifficulty, 0, DifficultyWaveSettings.Length - 1)];
|
||||||
|
|
||||||
|
V_GetWaveSettings(V_WaveSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function V_GetWaveSettings(out S_DifficultyWaveInfo WaveInfo)
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (V_DifficultyWaveSettings.Length > 0)
|
||||||
|
WaveInfo = V_DifficultyWaveSettings[Clamp(GameDifficulty, 0, V_DifficultyWaveSettings.Length - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SetupNextWave(byte NextWaveIndex, int TimeToNextWaveBuffer = 0)
|
||||||
|
{
|
||||||
|
local KFGameReplicationInfo KFGRI;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (OutbreakEvent.ActiveEvent.bBossRushMode)
|
||||||
|
{
|
||||||
|
NextWaveIndex = MyKFGRI.WaveMax - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NextWaveIndex < V_WaveSettings.Waves.Length)
|
||||||
|
{
|
||||||
|
if (GameDifficulty < RecycleSpecialSquad.Length)
|
||||||
|
{
|
||||||
|
bRecycleSpecialSquad = RecycleSpecialSquad[GameDifficulty];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bRecycleSpecialSquad = RecycleSpecialSquad[RecycleSpecialSquad.Length - 1];
|
||||||
|
}
|
||||||
|
|
||||||
|
LeftoverSpawnSquad.Length = 0;
|
||||||
|
NumSpawnListCycles = 1;
|
||||||
|
NumSpecialSquadRecycles = 0;
|
||||||
|
|
||||||
|
if (MyKFGRI.IsBossWave() || OutbreakEvent.ActiveEvent.bBossRushMode)
|
||||||
|
{
|
||||||
|
WaveTotalAI = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (V_WaveSettings.Waves[NextWaveIndex].bRecycleWave)
|
||||||
|
{
|
||||||
|
WaveTotalAI = V_WaveSettings.Waves[NextWaveIndex].MaxAI *
|
||||||
|
DifficultyInfo.GetPlayerNumMaxAIModifier(GetNumHumanTeamPlayers()) *
|
||||||
|
DifficultyInfo.GetDifficultyMaxAIModifier();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WaveTotalAI = V_WaveSettings.Waves[NextWaveIndex].MaxAI;
|
||||||
|
}
|
||||||
|
WaveTotalAI *= GetTotalWaveCountScale();
|
||||||
|
WaveTotalAI = Max(1, WaveTotalAI);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetAvailableSquads(NextWaveIndex, true);
|
||||||
|
|
||||||
|
WaveStartTime = WorldInfo.TimeSeconds;
|
||||||
|
TimeUntilNextSpawn = 5.f + TimeToNextWaveBuffer;
|
||||||
|
|
||||||
|
if (NextWaveIndex == 0)
|
||||||
|
{
|
||||||
|
TotalWavesActiveTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
KFGRI = KFGameReplicationInfo(WorldInfo.GRI);
|
||||||
|
if (KFGRI != None && (KFGRI.bDebugSpawnManager || KFGRI.bGameConductorGraphingEnabled))
|
||||||
|
{
|
||||||
|
KFGRI.CurrentSineMod = GetSineMod();
|
||||||
|
KFGRI.CurrentNextSpawnTime = TimeUntilNextSpawn;
|
||||||
|
KFGRI.CurrentSineWavFreq = GetSineWaveFreq();
|
||||||
|
KFGRI.CurrentNextSpawnTimeMod = GetNextSpawnTimeMod();
|
||||||
|
KFGRI.CurrentTotalWavesActiveTime = TotalWavesActiveTime;
|
||||||
|
KFGRI.CurrentMaxMonsters = GetMaxMonsters();
|
||||||
|
KFGRI.CurrentTimeTilNextSpawn = TimeUntilNextSpawn;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
LastAISpawnVolume = None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAvailableSquads(byte MyWaveIndex, optional bool bNeedsSpecialSquad=false)
|
||||||
|
{
|
||||||
|
local int i, j, TotalZedsInSquads;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (V_WaveSettings.Waves[MyWaveIndex] != None)
|
||||||
|
{
|
||||||
|
NumSpawnListCycles++;
|
||||||
|
|
||||||
|
V_WaveSettings.Waves[MyWaveIndex].GetNewSquadList(V_AvailableSquads);
|
||||||
|
|
||||||
|
if (bNeedsSpecialSquad)
|
||||||
|
{
|
||||||
|
V_WaveSettings.Waves[MyWaveIndex].GetSpecialSquad(V_AvailableSquads);
|
||||||
|
|
||||||
|
for (i = 0; i < V_AvailableSquads.Length; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < V_AvailableSquads[i].MonsterList.Length; j++)
|
||||||
|
{
|
||||||
|
TotalZedsInSquads += V_AvailableSquads[i].MonsterList[j].Num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (WaveTotalAI < TotalZedsInSquads)
|
||||||
|
{
|
||||||
|
bForceRequiredSquad = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function V_GetSpawnListFromSquad(byte SquadIdx, out Array<AISpawnSquad> SquadsList, out Array<class<KFPawn_Monster> > AISpawnList)
|
||||||
|
{
|
||||||
|
local AISpawnSquad Squad;
|
||||||
|
local EAIType AIType;
|
||||||
|
local int i, j, RandNum;
|
||||||
|
local ESquadType LargestMonsterSquadType;
|
||||||
|
local Array<class<KFPawn_Monster> > TempSpawnList;
|
||||||
|
local int RandBossIndex;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
Squad = SquadsList[SquadIdx];
|
||||||
|
|
||||||
|
LargestMonsterSquadType = EST_Crawler;
|
||||||
|
|
||||||
|
for (i = 0; i < Squad.MonsterList.Length; i++)
|
||||||
|
{
|
||||||
|
for (j = 0; j < Squad.MonsterList[i].Num; j++)
|
||||||
|
{
|
||||||
|
if (Squad.MonsterList[i].CustomClass != None)
|
||||||
|
{
|
||||||
|
TempSpawnList.AddItem(Squad.MonsterList[i].CustomClass);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AIType = Squad.MonsterList[i].Type;
|
||||||
|
if (AIType == AT_BossRandom)
|
||||||
|
{
|
||||||
|
if (OutbreakEvent.ActiveEvent.bBossRushMode)
|
||||||
|
{
|
||||||
|
RandBossIndex = Rand(BossRushEnemies.length);
|
||||||
|
TempSpawnList.AddItem( default.AIBossClassList[BossRushEnemies[RandBossIndex]]);
|
||||||
|
BossRushEnemies.Remove(RandBossIndex, 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TempSpawnList.AddItem(GetBossAISpawnType());
|
||||||
|
}
|
||||||
|
|
||||||
|
LargestMonsterSquadType = EST_Boss;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
TempSpawnList.AddItem(GetAISpawnType(AIType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TempSpawnList[TempSpawnList.Length - 1].default.MinSpawnSquadSizeType < LargestMonsterSquadType)
|
||||||
|
{
|
||||||
|
LargestMonsterSquadType = TempSpawnList[TempSpawnList.Length - 1].default.MinSpawnSquadSizeType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (TempSpawnList.Length > 0)
|
||||||
|
{
|
||||||
|
while (TempSpawnList.Length > 0)
|
||||||
|
{
|
||||||
|
RandNum = Rand( TempSpawnList.Length);
|
||||||
|
AISpawnList.AddItem( TempSpawnList[RandNum]);
|
||||||
|
TempSpawnList.Remove( RandNum, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
DesiredSquadType = Squad.MinVolumeType;
|
||||||
|
|
||||||
|
if (LargestMonsterSquadType < DesiredSquadType)
|
||||||
|
{
|
||||||
|
DesiredSquadType = LargestMonsterSquadType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function Array<class<KFPawn_Monster> > GetNextSpawnList()
|
||||||
|
{
|
||||||
|
local Array<class<KFPawn_Monster> > NewSquad, RequiredSquad;
|
||||||
|
local int RandNum, AINeeded;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (LeftoverSpawnSquad.Length > 0)
|
||||||
|
{
|
||||||
|
NewSquad = LeftoverSpawnSquad;
|
||||||
|
SetDesiredSquadTypeForZedList(NewSquad);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!IsAISquadAvailable())
|
||||||
|
{
|
||||||
|
if (!bSummoningBossMinions)
|
||||||
|
{
|
||||||
|
if (bRecycleSpecialSquad && NumSpawnListCycles % 2 == 1 && (MaxSpecialSquadRecycles == -1 || NumSpecialSquadRecycles < MaxSpecialSquadRecycles))
|
||||||
|
{
|
||||||
|
GetAvailableSquads(MyKFGRI.WaveNum - 1, true);
|
||||||
|
++NumSpecialSquadRecycles;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GetAvailableSquads(MyKFGRI.WaveNum - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CopySpawnSquadArray(BossMinionsSpawnSquads, V_AvailableSquads);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RandNum = Rand(V_AvailableSquads.Length);
|
||||||
|
|
||||||
|
if (bForceRequiredSquad && RandNum == (V_AvailableSquads.Length - 1))
|
||||||
|
{
|
||||||
|
bForceRequiredSquad=false;
|
||||||
|
}
|
||||||
|
|
||||||
|
V_GetSpawnListFromSquad(RandNum, V_AvailableSquads, NewSquad);
|
||||||
|
|
||||||
|
if (bForceRequiredSquad)
|
||||||
|
{
|
||||||
|
V_GetSpawnListFromSquad((V_AvailableSquads.Length - 1), V_AvailableSquads, RequiredSquad);
|
||||||
|
|
||||||
|
if ((NumAISpawnsQueued + NewSquad.Length + RequiredSquad.Length) > WaveTotalAI)
|
||||||
|
{
|
||||||
|
NewSquad = RequiredSquad;
|
||||||
|
RandNum = (V_AvailableSquads.Length - 1);
|
||||||
|
bForceRequiredSquad=false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V_AvailableSquads.Remove(RandNum, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
AINeeded = GetNumAINeeded();
|
||||||
|
if (AINeeded < NewSquad.Length)
|
||||||
|
{
|
||||||
|
LeftoverSpawnSquad = NewSquad;
|
||||||
|
LeftoverSpawnSquad.Remove(0, AINeeded);
|
||||||
|
NewSquad.Length = AINeeded;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LeftoverSpawnSquad.Length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewSquad;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bool IsAISquadAvailable()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
return (V_AvailableSquads.Length > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function SummonBossMinions(Array<KFAISpawnSquad> NewMinionSquad, int NewMaxBossMinions, optional bool bUseLivingPlayerScale = true)
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
CopySpawnSquadArray(NewMinionSquad, V_AvailableSquads);
|
||||||
|
Super.SummonBossMinions(NewMinionSquad, NewMaxBossMinions, bUseLivingPlayerScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function StopSummoningBossMinions()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
V_AvailableSquads.Length = 0;
|
||||||
|
Super.StopSummoningBossMinions();
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
Config = class'Config_SpawnManager'
|
||||||
|
}
|
118
ZedSpawner/Classes/AISpawnManager_Endless.uc
Normal file
118
ZedSpawner/Classes/AISpawnManager_Endless.uc
Normal file
@ -0,0 +1,118 @@
|
|||||||
|
class AISpawnManager_Endless extends AISpawnManager
|
||||||
|
within KFGameInfo_Endless;
|
||||||
|
|
||||||
|
struct S_MacroDifficultyWaveInfo
|
||||||
|
{
|
||||||
|
var Array<S_DifficultyWaveInfo> MacroDifficultyWaveSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct MacroDifficultyWaveInfo
|
||||||
|
{
|
||||||
|
var Array<DifficultyWaveInfo> MacroDifficultyWaveSettings;
|
||||||
|
};
|
||||||
|
|
||||||
|
var protected Array<MacroDifficultyWaveInfo> DifficultyWaves;
|
||||||
|
var protected Array<S_MacroDifficultyWaveInfo> V_DifficultyWaves;
|
||||||
|
|
||||||
|
public function SetupNextWave(byte NextWaveIndex, int TimeToNextWaveBuffer = 0)
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
Super.SetupNextWave(NextWaveIndex % WaveSettings.Waves.length, TimeToNextWaveBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetAvailableSquads(byte MyWaveIndex, optional bool bNeedsSpecialSquad = false)
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
Super.GetAvailableSquads(MyWaveIndex % WaveSettings.Waves.length, bNeedsSpecialSquad);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetWaveSettings(out DifficultyWaveInfo WaveInfo)
|
||||||
|
{
|
||||||
|
local int AdGD; // AdjustedGameDifficulty
|
||||||
|
local int AvAdGD; // AvailableAdjustedGameDifficulty
|
||||||
|
local int AvGD; // AvailableGameDifficulty
|
||||||
|
local int DWL; // DifficultyWavesLength
|
||||||
|
local int MDWSL; // MacroDifficultyWaveSettingsLength
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
DWL = DifficultyWaves.Length;
|
||||||
|
if (DWL > 0)
|
||||||
|
{
|
||||||
|
AvGD = Clamp(GameDifficulty, 0, DWL - 1);
|
||||||
|
MDWSL = DifficultyWaves[AvGD].MacroDifficultyWaveSettings.Length;
|
||||||
|
if (MDWSL > 0)
|
||||||
|
{
|
||||||
|
AdGD = EndlessDifficulty.GetCurrentDifficultyIndex();
|
||||||
|
AvAdGD = Clamp(AdGD, 0, MDWSL - 1);
|
||||||
|
WaveInfo = DifficultyWaves[AvGD].MacroDifficultyWaveSettings[AvAdGD];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
V_GetWaveSettings(V_WaveSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function V_GetWaveSettings(out S_DifficultyWaveInfo WaveInfo)
|
||||||
|
{
|
||||||
|
local int AdGD; // AdjustedGameDifficulty
|
||||||
|
local int AvAdGD; // AvailableAdjustedGameDifficulty
|
||||||
|
local int AvGD; // AvailableGameDifficulty
|
||||||
|
local int VDWL; // V_DifficultyWavesLength
|
||||||
|
local int MDWSL; // MacroDifficultyWaveSettingsLength
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
VDWL = V_DifficultyWaves.Length;
|
||||||
|
if (VDWL > 0)
|
||||||
|
{
|
||||||
|
AvGD = Clamp(GameDifficulty, 0, VDWL - 1);
|
||||||
|
MDWSL = V_DifficultyWaves[AvGD].MacroDifficultyWaveSettings.Length;
|
||||||
|
if (MDWSL > 0)
|
||||||
|
{
|
||||||
|
AdGD = EndlessDifficulty.GetCurrentDifficultyIndex();
|
||||||
|
AvAdGD = Clamp(AdGD, 0, MDWSL - 1);
|
||||||
|
WaveInfo = V_DifficultyWaves[AvGD].MacroDifficultyWaveSettings[AvAdGD];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function OnDifficultyUpdated()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
GetWaveSettings(WaveSettings);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function OnBossDied()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
BossMinionsSpawnSquads.length = 0;
|
||||||
|
AvailableSquads.length = 0;
|
||||||
|
V_AvailableSquads.length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function float GetNextSpawnTimeMod()
|
||||||
|
{
|
||||||
|
local float SpawnTimeMod, SpawnTimeModMin;
|
||||||
|
local int TempModIdx;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
SpawnTimeMod = super.GetNextSpawnTimeMod();
|
||||||
|
|
||||||
|
if (MyKFGRI.IsSpecialWave(TempModIdx))
|
||||||
|
{
|
||||||
|
SpawnTimeModMin = EndlessDifficulty.GetSpecialWaveSpawnTimeModMin(SpecialWaveType);
|
||||||
|
SpawnTimeMod = Max(SpawnTimeMod, SpawnTimeModMin);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SpawnTimeMod;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
Config = class'Config_SpawnManager_Endless'
|
||||||
|
}
|
6
ZedSpawner/Classes/AISpawnManager_Long.uc
Normal file
6
ZedSpawner/Classes/AISpawnManager_Long.uc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class AISpawnManager_Long extends AISpawnManager;
|
||||||
|
|
||||||
|
DefaultProperties
|
||||||
|
{
|
||||||
|
Config = class'Config_SpawnManager_Long'
|
||||||
|
}
|
6
ZedSpawner/Classes/AISpawnManager_Normal.uc
Normal file
6
ZedSpawner/Classes/AISpawnManager_Normal.uc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class AISpawnManager_Normal extends AISpawnManager;
|
||||||
|
|
||||||
|
DefaultProperties
|
||||||
|
{
|
||||||
|
Config = class'Config_SpawnManager_Normal'
|
||||||
|
}
|
6
ZedSpawner/Classes/AISpawnManager_Short.uc
Normal file
6
ZedSpawner/Classes/AISpawnManager_Short.uc
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
class AISpawnManager_Short extends AISpawnManager;
|
||||||
|
|
||||||
|
DefaultProperties
|
||||||
|
{
|
||||||
|
Config = class'Config_SpawnManager_Short'
|
||||||
|
}
|
61
ZedSpawner/Classes/AISpawnSquad.uc
Normal file
61
ZedSpawner/Classes/AISpawnSquad.uc
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
class AISpawnSquad extends Object
|
||||||
|
hidecategories(Object);
|
||||||
|
|
||||||
|
struct S_AISquadElement
|
||||||
|
{
|
||||||
|
var() EAIType Type;
|
||||||
|
var() byte Num <ClampMin=1 | ClampMax=6>;
|
||||||
|
|
||||||
|
var class<KFPawn_Monster> CustomClass;
|
||||||
|
|
||||||
|
structdefaultproperties
|
||||||
|
{
|
||||||
|
Num = 1
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var() ESquadType MinVolumeType;
|
||||||
|
var() array<S_AISquadElement> MonsterList;
|
||||||
|
|
||||||
|
public function AISpawnSquad InitFrom(KFAISpawnSquad SpawnSquad)
|
||||||
|
{
|
||||||
|
local AISquadElement SE;
|
||||||
|
local S_AISquadElement SSE;
|
||||||
|
|
||||||
|
MinVolumeType = SpawnSquad.MinVolumeType;
|
||||||
|
|
||||||
|
foreach SpawnSquad.MonsterList(SE)
|
||||||
|
{
|
||||||
|
SSE.Type = SE.Type;
|
||||||
|
SSE.Num = SE.Num;
|
||||||
|
SSE.CustomClass = SE.CustomClass;
|
||||||
|
MonsterList.AddItem(SSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Self;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function AISpawnSquad CreateFrom(KFAISpawnSquad SpawnSquad)
|
||||||
|
{
|
||||||
|
local AISquadElement SE;
|
||||||
|
local S_AISquadElement SSE;
|
||||||
|
local AISpawnSquad NewSpawnSquad;
|
||||||
|
|
||||||
|
NewSpawnSquad = new class'AISpawnSquad';
|
||||||
|
NewSpawnSquad.MinVolumeType = SpawnSquad.MinVolumeType;
|
||||||
|
|
||||||
|
foreach SpawnSquad.MonsterList(SE)
|
||||||
|
{
|
||||||
|
SSE.Type = SE.Type;
|
||||||
|
SSE.Num = SE.Num;
|
||||||
|
SSE.CustomClass = SE.CustomClass;
|
||||||
|
NewSpawnSquad.MonsterList.AddItem(SSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NewSpawnSquad;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
MinVolumeType = EST_Medium
|
||||||
|
}
|
71
ZedSpawner/Classes/AIWaveInfo.uc
Normal file
71
ZedSpawner/Classes/AIWaveInfo.uc
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
class AIWaveInfo extends Object
|
||||||
|
dependson(AISpawnSquad)
|
||||||
|
hidecategories(Object);
|
||||||
|
|
||||||
|
var() bool bRecycleWave;
|
||||||
|
var() Array<AISpawnSquad> Squads;
|
||||||
|
var() Array<AISpawnSquad> SpecialSquads;
|
||||||
|
var() int MaxAI<ClampMin=1|ClampMax=200|DisplayName=TotalAIBase>;
|
||||||
|
var() Array<AISpawnSquad> EventSquads;
|
||||||
|
|
||||||
|
public function GetNewSquadList(out Array<AISpawnSquad> out_SquadList)
|
||||||
|
{
|
||||||
|
local AISpawnSquad SS;
|
||||||
|
|
||||||
|
out_SquadList.Length = 0;
|
||||||
|
foreach Squads(SS)
|
||||||
|
if (SS != None)
|
||||||
|
out_SquadList.AddItem(SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetSpecialSquad(out Array<AISpawnSquad> out_SquadList)
|
||||||
|
{
|
||||||
|
if (SpecialSquads.Length > 0)
|
||||||
|
out_SquadList.AddItem(SpecialSquads[Rand(SpecialSquads.Length)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function GetEventSquadList(out Array<AISpawnSquad> out_SquadList)
|
||||||
|
{
|
||||||
|
local AISpawnSquad SS;
|
||||||
|
|
||||||
|
out_SquadList.Length = 0;
|
||||||
|
foreach EventSquads(SS)
|
||||||
|
if (SS != None)
|
||||||
|
out_SquadList.AddItem(SS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function InitFrom(KFAIWaveInfo WaveInfo)
|
||||||
|
{
|
||||||
|
local KFAISpawnSquad KFSS;
|
||||||
|
|
||||||
|
bRecycleWave = WaveInfo.bRecycleWave;
|
||||||
|
MaxAI = WaveInfo.MaxAI;
|
||||||
|
|
||||||
|
Squads.Length = 0;
|
||||||
|
foreach WaveInfo.Squads(KFSS)
|
||||||
|
Squads.AddItem(class'AISpawnSquad'.static.CreateFrom(KFSS));
|
||||||
|
|
||||||
|
SpecialSquads.Length = 0;
|
||||||
|
foreach WaveInfo.SpecialSquads(KFSS)
|
||||||
|
SpecialSquads.AddItem(class'AISpawnSquad'.static.CreateFrom(KFSS));
|
||||||
|
|
||||||
|
EventSquads.Length = 0;
|
||||||
|
foreach WaveInfo.EventSquads(KFSS)
|
||||||
|
EventSquads.AddItem(class'AISpawnSquad'.static.CreateFrom(KFSS));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function AIWaveInfo CreateFrom(KFAIWaveInfo WaveInfo)
|
||||||
|
{
|
||||||
|
local AIWaveInfo AIWI;
|
||||||
|
|
||||||
|
AIWI = new class'AIWaveInfo';
|
||||||
|
AIWI.InitFrom(WaveInfo);
|
||||||
|
|
||||||
|
return AIWI;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
bRecycleWave = true
|
||||||
|
MaxAI = 32
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
class SpawnListBossWaves extends Object
|
class Config_SpawnListBossWaves extends Object
|
||||||
dependson(ZedSpawner)
|
dependson(ZedSpawner)
|
||||||
config(ZedSpawner);
|
config(ZedSpawner);
|
||||||
|
|
||||||
@ -25,7 +25,7 @@ public static function InitConfig()
|
|||||||
default.Spawn.Length = 0;
|
default.Spawn.Length = 0;
|
||||||
|
|
||||||
SpawnEntry.BossClass = "KFGameContent.KFPawn_ZedFleshpoundKing";
|
SpawnEntry.BossClass = "KFGameContent.KFPawn_ZedFleshpoundKing";
|
||||||
SpawnEntry.ZedClass = "SomePackage.SomeFleshpoundClass";
|
SpawnEntry.ZedClass = "SomePackage.SomeClass";
|
||||||
SpawnEntry.SpawnCountBase = 2;
|
SpawnEntry.SpawnCountBase = 2;
|
||||||
SpawnEntry.SingleSpawnLimit = 1;
|
SpawnEntry.SingleSpawnLimit = 1;
|
||||||
SpawnEntry.Delay = 60;
|
SpawnEntry.Delay = 60;
|
||||||
@ -33,6 +33,10 @@ public static function InitConfig()
|
|||||||
SpawnEntry.bSpawnAtPlayerStart = false;
|
SpawnEntry.bSpawnAtPlayerStart = false;
|
||||||
default.Spawn.AddItem(SpawnEntry);
|
default.Spawn.AddItem(SpawnEntry);
|
||||||
|
|
||||||
|
// TODO:
|
||||||
|
//SpawnEntry.BossClass = "KFGameContent.KFPawn_ZedFleshpoundKing";
|
||||||
|
//default.Spawn.AddItem(SpawnEntry);
|
||||||
|
|
||||||
StaticSaveConfig();
|
StaticSaveConfig();
|
||||||
}
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
class SpawnListRegular extends Object
|
class Config_SpawnListRegular extends Object
|
||||||
dependson(ZedSpawner)
|
dependson(ZedSpawner)
|
||||||
config(ZedSpawner);
|
config(ZedSpawner);
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
class SpawnListSpecialWaves extends Object
|
class Config_SpawnListSpecialWaves extends Object
|
||||||
dependson(ZedSpawner)
|
dependson(ZedSpawner)
|
||||||
config(ZedSpawner);
|
config(ZedSpawner);
|
||||||
|
|
37
ZedSpawner/Classes/Config_SpawnManager.uc
Normal file
37
ZedSpawner/Classes/Config_SpawnManager.uc
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
class Config_SpawnManager extends Object
|
||||||
|
config(ZedSpawner);
|
||||||
|
|
||||||
|
var const class<KFAISpawnManager> DefSpawnManager;
|
||||||
|
|
||||||
|
public static function InitConfig()
|
||||||
|
{
|
||||||
|
local DifficultyWaveInfo DWI;
|
||||||
|
local KFAIWaveInfo KFAIWI;
|
||||||
|
local AIWaveInfo AIWI;
|
||||||
|
local int Diff, Wave;
|
||||||
|
|
||||||
|
`ZS_Log("InitConfig:" @ default.DefSpawnManager);
|
||||||
|
foreach default.DefSpawnManager.default.DifficultyWaveSettings(DWI, Diff)
|
||||||
|
{
|
||||||
|
`ZS_Log(" Diff:" @ Diff);
|
||||||
|
foreach DWI.Waves(KFAIWI, Wave)
|
||||||
|
{
|
||||||
|
`ZS_Log(" Wave:" @ Wave);
|
||||||
|
AIWI = class'AIWaveInfo'.static.CreateFrom(KFAIWI);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//StaticSaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function bool Load(E_LogLevel LogLevel)
|
||||||
|
{
|
||||||
|
local bool Errors;
|
||||||
|
Errors = false;
|
||||||
|
return !Errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
DefSpawnManager = class'KFAISpawnManager'
|
||||||
|
}
|
14
ZedSpawner/Classes/Config_SpawnManager_Endless.uc
Normal file
14
ZedSpawner/Classes/Config_SpawnManager_Endless.uc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Config_SpawnManager_Endless extends Config_SpawnManager
|
||||||
|
config(ZedSpawner);
|
||||||
|
|
||||||
|
public static function bool Load(E_LogLevel LogLevel)
|
||||||
|
{
|
||||||
|
local bool Errors;
|
||||||
|
Errors = false;
|
||||||
|
return !Errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
DefSpawnManager = class'KFAISpawnManager_Endless'
|
||||||
|
}
|
14
ZedSpawner/Classes/Config_SpawnManager_Long.uc
Normal file
14
ZedSpawner/Classes/Config_SpawnManager_Long.uc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Config_SpawnManager_Long extends Config_SpawnManager
|
||||||
|
config(ZedSpawner);
|
||||||
|
|
||||||
|
public static function bool Load(E_LogLevel LogLevel)
|
||||||
|
{
|
||||||
|
local bool Errors;
|
||||||
|
Errors = false;
|
||||||
|
return !Errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
DefSpawnManager = class'KFAISpawnManager_Long'
|
||||||
|
}
|
14
ZedSpawner/Classes/Config_SpawnManager_Normal.uc
Normal file
14
ZedSpawner/Classes/Config_SpawnManager_Normal.uc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Config_SpawnManager_Normal extends Config_SpawnManager
|
||||||
|
config(ZedSpawner);
|
||||||
|
|
||||||
|
public static function bool Load(E_LogLevel LogLevel)
|
||||||
|
{
|
||||||
|
local bool Errors;
|
||||||
|
Errors = false;
|
||||||
|
return !Errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
DefSpawnManager = class'KFAISpawnManager_Normal'
|
||||||
|
}
|
14
ZedSpawner/Classes/Config_SpawnManager_Short.uc
Normal file
14
ZedSpawner/Classes/Config_SpawnManager_Short.uc
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
class Config_SpawnManager_Short extends Config_SpawnManager
|
||||||
|
config(ZedSpawner);
|
||||||
|
|
||||||
|
public static function bool Load(E_LogLevel LogLevel)
|
||||||
|
{
|
||||||
|
local bool Errors;
|
||||||
|
Errors = false;
|
||||||
|
return !Errors;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
DefSpawnManager = class'KFAISpawnManager_Short'
|
||||||
|
}
|
184
ZedSpawner/Classes/Config_SpawnManager_WaveInfo.uc
Normal file
184
ZedSpawner/Classes/Config_SpawnManager_WaveInfo.uc
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
class Config_SpawnManager_WaveInfo extends Object
|
||||||
|
abstract
|
||||||
|
config(ZedSpawnManager);
|
||||||
|
|
||||||
|
var const class<KFAISpawnManager> DefSpawnManager;
|
||||||
|
var const byte Difficulty;
|
||||||
|
var const byte Wave;
|
||||||
|
|
||||||
|
struct Unit
|
||||||
|
{
|
||||||
|
var int Num;
|
||||||
|
var String ZedClass;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Squad
|
||||||
|
{
|
||||||
|
var ESquadType MinVolumeType;
|
||||||
|
var Array<Unit> Units;
|
||||||
|
};
|
||||||
|
|
||||||
|
var config bool bRecycleWave;
|
||||||
|
var config int MaxAI;
|
||||||
|
var config Array<Squad> Squads;
|
||||||
|
var config Array<Squad> SquadsSpecial;
|
||||||
|
var config Array<Squad> SquadsEvent;
|
||||||
|
|
||||||
|
public static function InitConfig(KFGI_Access KFGIA)
|
||||||
|
{
|
||||||
|
local KFAIWaveInfo KFAIWI;
|
||||||
|
local KFAISpawnSquad KFAISS;
|
||||||
|
local AISquadElement AISE;
|
||||||
|
local Squad S;
|
||||||
|
local Unit U;
|
||||||
|
|
||||||
|
KFAIWI = default.DefSpawnManager.default.DifficultyWaveSettings[default.Difficulty].Waves[default.Wave];
|
||||||
|
|
||||||
|
default.bRecycleWave = KFAIWI.bRecycleWave;
|
||||||
|
default.MaxAI = KFAIWI.MaxAI;
|
||||||
|
|
||||||
|
default.Squads.Length = 0;
|
||||||
|
foreach KFAIWI.Squads(KFAISS)
|
||||||
|
{
|
||||||
|
S.MinVolumeType = KFAISS.MinVolumeType;
|
||||||
|
foreach KFAISS.MonsterList(AISE)
|
||||||
|
{
|
||||||
|
U.ZedClass = GetPawnClassString(KFGIA, AISE);
|
||||||
|
U.Num = AISE.Num;
|
||||||
|
S.Units.AddItem(U);
|
||||||
|
}
|
||||||
|
default.Squads.AddItem(S);
|
||||||
|
}
|
||||||
|
|
||||||
|
default.SquadsSpecial.Length = 0;
|
||||||
|
foreach KFAIWI.SpecialSquads(KFAISS)
|
||||||
|
{
|
||||||
|
S.MinVolumeType = KFAISS.MinVolumeType;
|
||||||
|
foreach KFAISS.MonsterList(AISE)
|
||||||
|
{
|
||||||
|
U.ZedClass = GetPawnClassString(KFGIA, AISE);
|
||||||
|
U.Num = AISE.Num;
|
||||||
|
S.Units.AddItem(U);
|
||||||
|
}
|
||||||
|
default.SquadsSpecial.AddItem(S);
|
||||||
|
}
|
||||||
|
|
||||||
|
default.SquadsEvent.Length = 0;
|
||||||
|
foreach KFAIWI.EventSquads(KFAISS)
|
||||||
|
{
|
||||||
|
S.MinVolumeType = KFAISS.MinVolumeType;
|
||||||
|
foreach KFAISS.MonsterList(AISE)
|
||||||
|
{
|
||||||
|
U.ZedClass = GetPawnClassString(KFGIA, AISE);
|
||||||
|
U.Num = AISE.Num;
|
||||||
|
S.Units.AddItem(U);
|
||||||
|
}
|
||||||
|
default.SquadsEvent.AddItem(S);
|
||||||
|
}
|
||||||
|
|
||||||
|
StaticSaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function String GetPawnClassString(KFGI_Access KFGIA, AISquadElement AISE)
|
||||||
|
{
|
||||||
|
local class<KFPawn_Monster> KFPMC;
|
||||||
|
|
||||||
|
KFPMC = KFGIA.AITypePawn(AISE.Type);
|
||||||
|
if (KFPMC == None)
|
||||||
|
KFPMC = AISE.CustomClass;
|
||||||
|
|
||||||
|
return "KFGameContent." $ String(KFPMC);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function AIWaveInfo Load(E_LogLevel LogLevel, KFGI_Access KFGIA)
|
||||||
|
{
|
||||||
|
local class<KFPawn_Monster> KFPMC;
|
||||||
|
local AIWaveInfo AIWI;
|
||||||
|
local AISpawnSquad AISS;
|
||||||
|
local S_AISquadElement AISE;
|
||||||
|
local Squad S;
|
||||||
|
local Unit U;
|
||||||
|
|
||||||
|
AIWI = new class'AIWaveInfo';
|
||||||
|
|
||||||
|
AIWI.bRecycleWave = default.bRecycleWave;
|
||||||
|
AIWI.MaxAI = default.MaxAI;
|
||||||
|
|
||||||
|
foreach default.Squads(S)
|
||||||
|
{
|
||||||
|
AISS = new class'AISpawnSquad';
|
||||||
|
AISS.MinVolumeType = S.MinVolumeType;
|
||||||
|
foreach S.Units(U)
|
||||||
|
{
|
||||||
|
KFPMC = class<KFPawn_Monster>(DynamicLoadObject(U.ZedClass, class'Class'));
|
||||||
|
if (KFPMC == None)
|
||||||
|
{
|
||||||
|
`ZS_Warn("Can't load zed class:" @ U.ZedClass);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!KFGIA.IsOriginalAI(KFPMC, AISE.Type))
|
||||||
|
AISE.CustomClass = KFPMC;
|
||||||
|
|
||||||
|
AISE.Num = AISE.Num;
|
||||||
|
|
||||||
|
AISS.MonsterList.AddItem(AISE);
|
||||||
|
}
|
||||||
|
AIWI.Squads.AddItem(AISS);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach default.SquadsSpecial(S)
|
||||||
|
{
|
||||||
|
AISS = new class'AISpawnSquad';
|
||||||
|
AISS.MinVolumeType = S.MinVolumeType;
|
||||||
|
foreach S.Units(U)
|
||||||
|
{
|
||||||
|
KFPMC = class<KFPawn_Monster>(DynamicLoadObject(U.ZedClass, class'Class'));
|
||||||
|
if (KFPMC == None)
|
||||||
|
{
|
||||||
|
`ZS_Warn("Can't load zed class:" @ U.ZedClass);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!KFGIA.IsOriginalAI(KFPMC, AISE.Type))
|
||||||
|
AISE.CustomClass = KFPMC;
|
||||||
|
|
||||||
|
AISE.Num = AISE.Num;
|
||||||
|
|
||||||
|
AISS.MonsterList.AddItem(AISE);
|
||||||
|
}
|
||||||
|
AIWI.SpecialSquads.AddItem(AISS);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach default.SquadsEvent(S)
|
||||||
|
{
|
||||||
|
AISS = new class'AISpawnSquad';
|
||||||
|
AISS.MinVolumeType = S.MinVolumeType;
|
||||||
|
foreach S.Units(U)
|
||||||
|
{
|
||||||
|
KFPMC = class<KFPawn_Monster>(DynamicLoadObject(U.ZedClass, class'Class'));
|
||||||
|
if (KFPMC == None)
|
||||||
|
{
|
||||||
|
`ZS_Warn("Can't load zed class:" @ U.ZedClass);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!KFGIA.IsOriginalAI(KFPMC, AISE.Type))
|
||||||
|
AISE.CustomClass = KFPMC;
|
||||||
|
|
||||||
|
AISE.Num = AISE.Num;
|
||||||
|
|
||||||
|
AISS.MonsterList.AddItem(AISE);
|
||||||
|
}
|
||||||
|
AIWI.EventSquads.AddItem(AISS);
|
||||||
|
}
|
||||||
|
|
||||||
|
return AIWI;
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
DefSpawnManager = class'KFAISpawnManager'
|
||||||
|
Difficulty = 255
|
||||||
|
Wave = 255
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
class Spawn extends Object
|
class Config_Spawner extends Object
|
||||||
dependson(ZedSpawner)
|
dependson(ZedSpawner)
|
||||||
config(ZedSpawner);
|
config(ZedSpawner);
|
||||||
|
|
@ -1,9 +1,7 @@
|
|||||||
class KFGI_Access extends Object
|
class KFGI_Access extends Object
|
||||||
within KFGameInfo_Survival;
|
within KFGameInfo;
|
||||||
|
|
||||||
// Bypass protected modifier for these lists
|
public function bool IsCustomZed(class<KFPawn_Monster> KFPM)
|
||||||
|
|
||||||
function bool IsCustomZed(class<KFPawn_Monster> KFPM)
|
|
||||||
{
|
{
|
||||||
if (AIClassList.Find(KFPM) != INDEX_NONE) return false;
|
if (AIClassList.Find(KFPM) != INDEX_NONE) return false;
|
||||||
if (NonSpawnAIClassList.Find(KFPM) != INDEX_NONE) return false;
|
if (NonSpawnAIClassList.Find(KFPM) != INDEX_NONE) return false;
|
||||||
@ -11,6 +9,51 @@ function bool IsCustomZed(class<KFPawn_Monster> KFPM)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WARN: <optional out> - can it work? need check
|
||||||
|
public function bool IsOriginalAI(class<KFPawn_Monster> KFPM, optional out EAIType AIType)
|
||||||
|
{
|
||||||
|
local int Type;
|
||||||
|
|
||||||
|
Type = AIClassList.Find(KFPM);
|
||||||
|
if (Type != INDEX_NONE)
|
||||||
|
{
|
||||||
|
AIType = EAIType(Type);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function bool IsOriginalAIBoss(class<KFPawn_Monster> KFPM, optional out EBossAIType AIType)
|
||||||
|
{
|
||||||
|
local int Type;
|
||||||
|
|
||||||
|
Type = AIBossClassList.Find(KFPM);
|
||||||
|
if (Type != INDEX_NONE)
|
||||||
|
{
|
||||||
|
AIType = EBossAIType(Type);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function class<KFPawn_Monster> AITypePawn(EAIType AIType)
|
||||||
|
{
|
||||||
|
if (AIType < AIClassList.Length)
|
||||||
|
return AIClassList[AIType];
|
||||||
|
else
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function class<KFPawn_Monster> BossAITypePawn(EBossAIType AIType)
|
||||||
|
{
|
||||||
|
if (AIType < AIBossClassList.Length)
|
||||||
|
return AIBossClassList[AIType];
|
||||||
|
else
|
||||||
|
return None;
|
||||||
|
}
|
||||||
|
|
||||||
defaultproperties
|
defaultproperties
|
||||||
{
|
{
|
||||||
|
|
||||||
|
@ -3,22 +3,19 @@ class ZedSpawner extends Info
|
|||||||
|
|
||||||
const dt = 1;
|
const dt = 1;
|
||||||
|
|
||||||
const CfgSpawn = class'Spawn';
|
const CfgSpawn = class'Config_Spawner';
|
||||||
const CfgSpawnListR = class'SpawnListRegular';
|
const CfgSpawnListR = class'Config_SpawnListRegular';
|
||||||
const CfgSpawnListBW = class'SpawnListBossWaves';
|
const CfgSpawnListBW = class'Config_SpawnListBossWaves';
|
||||||
const CfgSpawnListSW = class'SpawnListSpecialWaves';
|
const CfgSpawnListSW = class'Config_SpawnListSpecialWaves';
|
||||||
|
const CfgSpawnManagerE = class'Config_SpawnManager_Endless';
|
||||||
|
const CfgSpawnManagerS = class'Config_SpawnManager_Short';
|
||||||
|
const CfgSpawnManagerN = class'Config_SpawnManager_Normal';
|
||||||
|
const CfgSpawnManagerL = class'Config_SpawnManager_Long';
|
||||||
|
|
||||||
enum E_LogLevel
|
const SpawnManagerS = class'AISpawnManager_Short';
|
||||||
{
|
const SpawnManagerN = class'AISpawnManager_Normal';
|
||||||
LL_WrongLevel,
|
const SpawnManagerL = class'AISpawnManager_Long';
|
||||||
LL_Fatal,
|
const SpawnManagerE = class'AISpawnManager_Endless';
|
||||||
LL_Error,
|
|
||||||
LL_Warning,
|
|
||||||
LL_Info,
|
|
||||||
LL_Debug,
|
|
||||||
LL_Trace,
|
|
||||||
LL_All
|
|
||||||
};
|
|
||||||
|
|
||||||
struct S_SpawnEntry
|
struct S_SpawnEntry
|
||||||
{
|
{
|
||||||
@ -66,6 +63,192 @@ var private Array<class<KFPawn_Monster> > CustomZeds;
|
|||||||
|
|
||||||
delegate bool WaveCondition(S_SpawnEntry SE);
|
delegate bool WaveCondition(S_SpawnEntry SE);
|
||||||
|
|
||||||
|
event PreBeginPlay()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
Super.PreBeginPlay();
|
||||||
|
|
||||||
|
PreInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
event PostBeginPlay()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (bPendingDelete) return;
|
||||||
|
|
||||||
|
Super.PostBeginPlay();
|
||||||
|
|
||||||
|
PostInit();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function PreInit()
|
||||||
|
{
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
if (WorldInfo.NetMode == NM_Client)
|
||||||
|
{
|
||||||
|
`ZS_Fatal("NetMode == NM_Client, Destroy...");
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!bConfigInitialized)
|
||||||
|
{
|
||||||
|
bConfigInitialized = true;
|
||||||
|
LogLevel = LL_Info;
|
||||||
|
SaveConfig();
|
||||||
|
CfgSpawn.static.InitConfig();
|
||||||
|
CfgSpawnListR.static.InitConfig();
|
||||||
|
CfgSpawnListBW.static.InitConfig();
|
||||||
|
CfgSpawnListSW.static.InitConfig();
|
||||||
|
CfgSpawnManagerS.static.InitConfig();
|
||||||
|
CfgSpawnManagerN.static.InitConfig();
|
||||||
|
CfgSpawnManagerL.static.InitConfig();
|
||||||
|
CfgSpawnManagerE.static.InitConfig();
|
||||||
|
`ZS_Info("Config initialized.");
|
||||||
|
}
|
||||||
|
|
||||||
|
CfgSpawnManagerS.static.InitConfig();
|
||||||
|
CfgSpawnManagerN.static.InitConfig();
|
||||||
|
CfgSpawnManagerL.static.InitConfig();
|
||||||
|
CfgSpawnManagerE.static.InitConfig();
|
||||||
|
|
||||||
|
if (LogLevel == LL_WrongLevel)
|
||||||
|
{
|
||||||
|
LogLevel = LL_Info;
|
||||||
|
`ZS_Warn("Wrong 'LogLevel', return to default value");
|
||||||
|
SaveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
`ZS_Log("LogLevel:" @ LogLevel);
|
||||||
|
|
||||||
|
if (!CfgSpawn.static.Load(LogLevel))
|
||||||
|
{
|
||||||
|
`ZS_Fatal("Wrong settings, Destroy...");
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function PostInit()
|
||||||
|
{
|
||||||
|
local S_SpawnEntry SE;
|
||||||
|
local bool NeedInitSM;
|
||||||
|
|
||||||
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
|
CurrentWave = INDEX_NONE;
|
||||||
|
KFGIS = KFGameInfo_Survival(WorldInfo.Game);
|
||||||
|
if (KFGIS == None)
|
||||||
|
{
|
||||||
|
`ZS_Fatal("Incompatible gamemode:" @ WorldInfo.Game $ ". Destroy...");
|
||||||
|
Destroy();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
KFGIA = new(KFGIS) class'KFGI_Access';
|
||||||
|
KFGIE = KFGameInfo_Endless(KFGIS);
|
||||||
|
|
||||||
|
SpawnListR = CfgSpawnListR.static.Load(LogLevel);
|
||||||
|
SpawnListBW = CfgSpawnListBW.static.Load(LogLevel);
|
||||||
|
SpawnListSW = CfgSpawnListSW.static.Load(KFGIE, LogLevel);
|
||||||
|
|
||||||
|
CfgSpawnManagerE.static.Load(LogLevel);
|
||||||
|
CfgSpawnManagerS.static.Load(LogLevel);
|
||||||
|
CfgSpawnManagerN.static.Load(LogLevel);
|
||||||
|
CfgSpawnManagerL.static.Load(LogLevel);
|
||||||
|
|
||||||
|
SpecialWave = INDEX_NONE;
|
||||||
|
CurrentCycle = 1;
|
||||||
|
CycleWaveSize = 0;
|
||||||
|
CycleWaveShift = MaxInt;
|
||||||
|
foreach SpawnListR(SE)
|
||||||
|
{
|
||||||
|
CycleWaveShift = Min(CycleWaveShift, SE.Wave);
|
||||||
|
CycleWaveSize = Max(CycleWaveSize, SE.Wave);
|
||||||
|
}
|
||||||
|
CycleWaveSize = CycleWaveSize - CycleWaveShift + 1;
|
||||||
|
|
||||||
|
foreach SpawnListBW(SE)
|
||||||
|
if (BossClassCache.Find(SE.BossClass) == INDEX_NONE)
|
||||||
|
BossClassCache.AddItem(SE.BossClass);
|
||||||
|
|
||||||
|
if (true)
|
||||||
|
{
|
||||||
|
NeedInitSM = (KFGIS.SpawnManager != None);
|
||||||
|
KFGIS.SpawnManagerClasses.Length = 0;
|
||||||
|
if (KFGIE != None)
|
||||||
|
{
|
||||||
|
KFGIE.SpawnManagerClasses.AddItem(SpawnManagerE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
KFGIS.SpawnManagerClasses.AddItem(SpawnManagerS);
|
||||||
|
KFGIS.SpawnManagerClasses.AddItem(SpawnManagerN);
|
||||||
|
KFGIS.SpawnManagerClasses.AddItem(SpawnManagerL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NeedInitSM)
|
||||||
|
{
|
||||||
|
KFGIS.InitSpawnManager();
|
||||||
|
}
|
||||||
|
|
||||||
|
`ZS_Info("SpawnManager replaced");
|
||||||
|
}
|
||||||
|
|
||||||
|
PreparePreloadContent();
|
||||||
|
|
||||||
|
if (SpawnListSW.Length > 0 || SpawnListBW.Length > 0 || SpawnListR.Length > 0)
|
||||||
|
{
|
||||||
|
SetTimer(float(dt), true, nameof(SpawnTimer));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
`ZS_Info("Spawn timer disabled (no spawn lists)", LogLevel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function PreparePreloadContent()
|
||||||
|
{
|
||||||
|
local class<KFPawn_Monster> PawnClass;
|
||||||
|
|
||||||
|
ExtractCustomZedsFromSpawnList(SpawnListR, CustomZeds);
|
||||||
|
ExtractCustomZedsFromSpawnList(SpawnListBW, CustomZeds);
|
||||||
|
ExtractCustomZedsFromSpawnList(SpawnListSW, CustomZeds);
|
||||||
|
ExtractCustomZedsFromSpawnManager(AISpawnManager(KFGIS.SpawnManager), CustomZeds);
|
||||||
|
|
||||||
|
foreach CustomZeds(PawnClass)
|
||||||
|
PawnClass.static.PreloadContent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private function ExtractCustomZedsFromSpawnList(Array<S_SpawnEntry> SpawnList, out Array<class<KFPawn_Monster> > Out)
|
||||||
|
{
|
||||||
|
local S_SpawnEntry SE;
|
||||||
|
|
||||||
|
foreach SpawnList(SE)
|
||||||
|
{
|
||||||
|
if (Out.Find(SE.ZedClass) == INDEX_NONE
|
||||||
|
&& KFGIA.IsCustomZed(SE.ZedClass))
|
||||||
|
{
|
||||||
|
`ZS_Debug("Add custom zed:" @ SE.ZedClass);
|
||||||
|
Out.AddItem(SE.ZedClass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private function ExtractCustomZedsFromSpawnManager(AISpawnManager SpawnManager, out Array<class<KFPawn_Monster> > Out)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
private function PreloadContent(Array<class<KFPawn_Monster> > Pawns)
|
||||||
|
{
|
||||||
|
local class<KFPawn_Monster> KFPM;
|
||||||
|
foreach Pawns(KFPM) KFPM.static.PreloadContent();
|
||||||
|
}
|
||||||
|
|
||||||
public function bool WaveConditionRegular(S_SpawnEntry SE)
|
public function bool WaveConditionRegular(S_SpawnEntry SE)
|
||||||
{
|
{
|
||||||
`ZS_Trace(`Location);
|
`ZS_Trace(`Location);
|
||||||
@ -108,119 +291,6 @@ public function bool WaveConditionSpecial(S_SpawnEntry SE)
|
|||||||
return (SE.Wave == SpecialWave);
|
return (SE.Wave == SpecialWave);
|
||||||
}
|
}
|
||||||
|
|
||||||
event PostBeginPlay()
|
|
||||||
{
|
|
||||||
`ZS_Trace(`Location);
|
|
||||||
|
|
||||||
Super.PostBeginPlay();
|
|
||||||
|
|
||||||
if (WorldInfo.NetMode == NM_Client)
|
|
||||||
{
|
|
||||||
Destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
Init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private function Init()
|
|
||||||
{
|
|
||||||
local S_SpawnEntry SE;
|
|
||||||
|
|
||||||
`ZS_Trace(`Location);
|
|
||||||
|
|
||||||
if (!bConfigInitialized)
|
|
||||||
{
|
|
||||||
bConfigInitialized = true;
|
|
||||||
LogLevel = LL_Info;
|
|
||||||
SaveConfig();
|
|
||||||
CfgSpawn.static.InitConfig();
|
|
||||||
CfgSpawnListR.static.InitConfig();
|
|
||||||
CfgSpawnListBW.static.InitConfig();
|
|
||||||
CfgSpawnListSW.static.InitConfig();
|
|
||||||
`ZS_Info("Config initialized.");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (LogLevel == LL_WrongLevel)
|
|
||||||
{
|
|
||||||
LogLevel = LL_Info;
|
|
||||||
`ZS_Warn("Wrong 'LogLevel', return to default value");
|
|
||||||
SaveConfig();
|
|
||||||
}
|
|
||||||
|
|
||||||
`ZS_Log("LogLevel:" @ LogLevel);
|
|
||||||
|
|
||||||
if (!CfgSpawn.static.Load(LogLevel))
|
|
||||||
{
|
|
||||||
`ZS_Fatal("Wrong settings, Destroy...");
|
|
||||||
Destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
CurrentWave = INDEX_NONE;
|
|
||||||
KFGIS = KFGameInfo_Survival(WorldInfo.Game);
|
|
||||||
if (KFGIS == None)
|
|
||||||
{
|
|
||||||
`ZS_Fatal("Incompatible gamemode:" @ WorldInfo.Game $ ". Destroy...");
|
|
||||||
Destroy();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
KFGIA = new(KFGIS) class'KFGI_Access';
|
|
||||||
|
|
||||||
KFGIE = KFGameInfo_Endless(KFGIS);
|
|
||||||
|
|
||||||
SpawnListR = CfgSpawnListR.static.Load(LogLevel);
|
|
||||||
SpawnListBW = CfgSpawnListBW.static.Load(LogLevel);
|
|
||||||
SpawnListSW = CfgSpawnListSW.static.Load(KFGIE, LogLevel);
|
|
||||||
|
|
||||||
SpecialWave = INDEX_NONE;
|
|
||||||
CurrentCycle = 1;
|
|
||||||
CycleWaveSize = 0;
|
|
||||||
CycleWaveShift = MaxInt;
|
|
||||||
foreach SpawnListR(SE)
|
|
||||||
{
|
|
||||||
if (CustomZeds.Find(SE.ZedClass) == INDEX_NONE
|
|
||||||
&& KFGIA.IsCustomZed(SE.ZedClass))
|
|
||||||
{
|
|
||||||
`ZS_Debug("Add custom zed:" @ SE.ZedClass);
|
|
||||||
CustomZeds.AddItem(SE.ZedClass);
|
|
||||||
SE.ZedClass.static.PreloadContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
CycleWaveShift = Min(CycleWaveShift, SE.Wave);
|
|
||||||
CycleWaveSize = Max(CycleWaveSize, SE.Wave);
|
|
||||||
}
|
|
||||||
CycleWaveSize = CycleWaveSize - CycleWaveShift + 1;
|
|
||||||
|
|
||||||
foreach SpawnListBW(SE)
|
|
||||||
{
|
|
||||||
if (CustomZeds.Find(SE.ZedClass) == INDEX_NONE
|
|
||||||
&& KFGIA.IsCustomZed(SE.ZedClass))
|
|
||||||
{
|
|
||||||
`ZS_Debug("Add custom zed:" @ SE.ZedClass);
|
|
||||||
CustomZeds.AddItem(SE.ZedClass);
|
|
||||||
SE.ZedClass.static.PreloadContent();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (BossClassCache.Find(SE.BossClass) == INDEX_NONE)
|
|
||||||
BossClassCache.AddItem(SE.BossClass);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach SpawnListSW(SE)
|
|
||||||
{
|
|
||||||
if (CustomZeds.Find(SE.ZedClass) == INDEX_NONE
|
|
||||||
&& KFGIA.IsCustomZed(SE.ZedClass))
|
|
||||||
{
|
|
||||||
`ZS_Debug("Add custom zed:" @ SE.ZedClass);
|
|
||||||
CustomZeds.AddItem(SE.ZedClass);
|
|
||||||
SE.ZedClass.static.PreloadContent();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
SetTimer(float(dt), true, nameof(SpawnTimer));
|
|
||||||
}
|
|
||||||
|
|
||||||
private function SpawnTimer()
|
private function SpawnTimer()
|
||||||
{
|
{
|
||||||
`ZS_Trace(`Location);
|
`ZS_Trace(`Location);
|
||||||
|
@ -10,6 +10,8 @@ replication
|
|||||||
LogLevel;
|
LogLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public simulated function bool SafeDestroy() { if (!bPendingDelete) return Destroy(); else return true; }
|
||||||
|
|
||||||
public reliable client function ClientSync(class<KFPawn_Monster> CustomZed)
|
public reliable client function ClientSync(class<KFPawn_Monster> CustomZed)
|
||||||
{
|
{
|
||||||
`ZS_Trace(`Location);
|
`ZS_Trace(`Location);
|
||||||
@ -31,18 +33,18 @@ public reliable client function SyncFinished()
|
|||||||
CustomZed.static.PreloadContent();
|
CustomZed.static.PreloadContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
Destroy();
|
SafeDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
public reliable server function ServerSync()
|
public reliable server function ServerSync()
|
||||||
{
|
{
|
||||||
`ZS_Trace(`Location);
|
`ZS_Trace(`Location);
|
||||||
|
|
||||||
if (CustomZeds.Length == Recieved)
|
if (CustomZeds.Length == Recieved || WorldInfo.NetMode == NM_StandAlone)
|
||||||
{
|
{
|
||||||
`ZS_Debug("Sync finished");
|
`ZS_Debug("Sync finished");
|
||||||
SyncFinished();
|
SyncFinished();
|
||||||
Destroy();
|
SafeDestroy();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
18
ZedSpawner/Classes/_CommonTypes.uc
Normal file
18
ZedSpawner/Classes/_CommonTypes.uc
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
class _CommonTypes extends Object;
|
||||||
|
|
||||||
|
enum E_LogLevel
|
||||||
|
{
|
||||||
|
LL_WrongLevel,
|
||||||
|
LL_Fatal,
|
||||||
|
LL_Error,
|
||||||
|
LL_Warning,
|
||||||
|
LL_Info,
|
||||||
|
LL_Debug,
|
||||||
|
LL_Trace,
|
||||||
|
LL_All
|
||||||
|
};
|
||||||
|
|
||||||
|
defaultproperties
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user