diff --git a/ZedSpawner/Classes/Spawn.uc b/ZedSpawner/Classes/Spawn.uc index 583e152..64f982e 100644 --- a/ZedSpawner/Classes/Spawn.uc +++ b/ZedSpawner/Classes/Spawn.uc @@ -11,6 +11,7 @@ var public config float SingleSpawnLimitMultiplier; var public config float SingleSpawnLimitPlayerMultiplier; var public config float SingleSpawnLimitCycleMultiplier; var public config int AliveSpawnLimit; +var public config bool bSmoothSpawn; public static function InitConfig(int Version, int LatestVersion) { @@ -19,6 +20,9 @@ public static function InitConfig(int Version, int LatestVersion) case `NO_CONFIG: ApplyDefault(); + case 3: + default.bSmoothSpawn = false; + default: break; } @@ -32,6 +36,7 @@ private static function ApplyDefault() { default.bCyclicalSpawn = true; default.bShadowSpawn = true; + default.bSmoothSpawn = true; default.ZedTotalMultiplier = 1.0; default.SpawnTotalPlayerMultiplier = 0.75; default.SpawnTotalCycleMultiplier = 0.75; diff --git a/ZedSpawner/Classes/ZedSpawner.uc b/ZedSpawner/Classes/ZedSpawner.uc index de9633e..8929b4f 100644 --- a/ZedSpawner/Classes/ZedSpawner.uc +++ b/ZedSpawner/Classes/ZedSpawner.uc @@ -1,7 +1,7 @@ class ZedSpawner extends Info config(ZedSpawner); -const LatestVersion = 3; +const LatestVersion = 4; const CfgSpawn = class'Spawn'; const CfgSpawnAtPlayerStart = class'SpawnAtPlayerStart'; @@ -26,6 +26,7 @@ struct S_SpawnEntry var int PawnsTotal; var bool ForceSpawn; var String ZedNameFiller; + var int SmoothPawnPool; }; var private config int Version; @@ -118,6 +119,7 @@ private function InitConfig() Tickrate = 1.0f; case 2: + case 3: case MaxInt: `Log_Info("Config updated to version"@LatestVersion); @@ -514,6 +516,7 @@ private function SpawnEntry(out Array SpawnList, int Index) SE = SpawnList[Index]; SpawnList[Index].Delay = float(SE.DelayDefault); + if (FRand() <= SE.Probability || SE.ForceSpawn) { if (SE.SingleSpawnLimit == 0 || SE.PawnsLeft < SE.SingleSpawnLimit) @@ -525,6 +528,15 @@ private function SpawnEntry(out Array SpawnList, int Index) PawnCount = SE.SingleSpawnLimit; } + if (CfgSpawn.default.bSmoothSpawn) + { + if (SE.SmoothPawnPool <= 0) + { + SpawnList[Index].SmoothPawnPool = PawnCount; + } + PawnCount = 1; + } + if (CfgSpawn.default.bShadowSpawn && !KFGIS.MyKFGRI.IsBossWave()) { FreeSpawnSlots = KFGIS.MyKFGRI.AIRemaining - KFGIS.AIAliveCount; @@ -558,9 +570,26 @@ private function SpawnEntry(out Array SpawnList, int Index) } else { - SpawnList[Index].ForceSpawn = false; Action = "Spawned"; Comment = "x" $ Spawned; + if (CfgSpawn.default.bSmoothSpawn) + { + SpawnList[Index].SmoothPawnPool -= Spawned; + if (SpawnList[Index].SmoothPawnPool > 0) + { + SpawnList[Index].Delay = 1.0f; + SpawnList[Index].ForceSpawn = true; + } + else + { + SpawnList[Index].Delay = float(SE.DelayDefault); + SpawnList[Index].ForceSpawn = false; + } + } + else + { + SpawnList[Index].ForceSpawn = false; + } } } else @@ -573,7 +602,14 @@ private function SpawnEntry(out Array SpawnList, int Index) SpawnList[Index].PawnsLeft -= Spawned; if (SpawnList[Index].PawnsLeft > 0) { - NextSpawn = "next after" @ SE.DelayDefault $ "sec," @ "pawns left:" @ SpawnList[Index].PawnsLeft; + if (CfgSpawn.default.bSmoothSpawn && SpawnList[Index].SmoothPawnPool > 0) + { + NextSpawn = "next after" @ Round(SpawnList[Index].Delay) $ "sec," @ "pawns left:" @ SpawnList[Index].SmoothPawnPool @ "(" $ SpawnList[Index].PawnsLeft $ ")"; + } + else + { + NextSpawn = "next after" @ SE.DelayDefault $ "sec," @ "pawns left:" @ SpawnList[Index].PawnsLeft; + } } SpawnLog(SE, Action, Comment, NextSpawn); } @@ -715,7 +751,7 @@ private function int SpawnZed(class ZedClass, int PawnCount, opt public function NotifyLogin(Controller C) { `Log_Trace(`Location); - `Log_Info(`Location); + CreateRepLink(C); } diff --git a/ZedSpawner/Classes/ZedSpawnerRepLink.uc b/ZedSpawner/Classes/ZedSpawnerRepLink.uc index e9caee0..5f59a12 100644 --- a/ZedSpawner/Classes/ZedSpawnerRepLink.uc +++ b/ZedSpawner/Classes/ZedSpawnerRepLink.uc @@ -13,7 +13,6 @@ replication public simulated function bool SafeDestroy() { - `Log_Debug(`Location @ "bPendingDelete:" @ bPendingDelete @ "bDeleteMe" @ bDeleteMe); return (bPendingDelete || bDeleteMe || Destroy()); }