Upload from upload_mods.ps1

This commit is contained in:
Nathaniel Cosford
2025-06-04 16:44:53 +09:30
commit f1fbbe67bb
1722 changed files with 165268 additions and 0 deletions

View File

@@ -0,0 +1,568 @@
using System.Collections.Generic;
using System.Diagnostics;
namespace Harmony.AIWanderingHordeSpawnerPatches
{
[HarmonyPatch(typeof(AIDirectorWanderingHordeComponent))]
[HarmonyPatch("StartSpawning")]
public class StartSpawningPatch
{
public static bool Prefix(AIDirectorWanderingHordeComponent __instance, AIWanderingHordeSpawner.SpawnType _spawnType)
{
RebirthVariables.isWHSpawned = false;
RebirthVariables.stopWHSpawns = false;
RebirthVariables.herdStartTime = Time.time;
float optionWanderingHordeHerdProb = float.Parse(RebirthVariables.customWanderingHordeHerdProb);
//Log.Out("AIWanderingHordeSpawnerPatches-StartSpawning optionWanderingHordeHerdProb: " + optionWanderingHordeHerdProb);
int random = UnityEngine.Random.Range(1, 100);
//Log.Out("AIWanderingHordeSpawnerPatches-StartSpawning random: " + random);
RebirthVariables.isHerd = random <= optionWanderingHordeHerdProb;
if (RebirthVariables.forceHerd)
{
RebirthVariables.isHerd = true;
RebirthVariables.forceHerd = false;
}
int optionWanderingHordeHerdDur = RebirthVariables.customWanderingHordeHerdDur;
RebirthVariables.herdDuration = UnityEngine.Random.Range((optionWanderingHordeHerdDur * 60) - 30, (optionWanderingHordeHerdDur * 60) + 30);
// START OF VANILLA CODE
AIDirector.LogAI("Wandering StartSpawning {0}", (object)_spawnType);
__instance.CleanupType(_spawnType);
bool flag = false;
DictionaryList<int, AIDirectorPlayerState> trackedPlayers = __instance.Director.GetComponent<AIDirectorPlayerManagementComponent>().trackedPlayers;
for (int index = 0; index < trackedPlayers.list.Count; ++index)
{
if (!trackedPlayers.list[index].Dead)
{
flag = true;
break;
}
}
if (!flag)
{
AIDirector.LogAI("Spawn {0}, no living players, wait 4 hours", (object)_spawnType);
__instance.SetNextTime(_spawnType, __instance.Director.World.worldTime + 4000UL);
}
else
{
List<AIDirectorPlayerState> directorPlayerStateList = new List<AIDirectorPlayerState>();
Vector3 startPos;
Vector3 pitStop;
Vector3 endPos;
uint targets = __instance.FindTargets(out startPos, out pitStop, out endPos, directorPlayerStateList);
if (targets > 0U)
{
AIDirector.LogAI("Spawn {0}, find targets, wait {1} hours", (object)_spawnType, (object)targets);
__instance.SetNextTime(_spawnType, __instance.Director.World.worldTime + (ulong)(1000U * targets));
}
else
{
int searchDistance = 150;
List<Entity> entitiesInBounds = GameManager.Instance.World.GetEntitiesInBounds(typeof(EntityZombieScreamerRebirth), BoundsUtils.BoundsForMinMax(startPos.x - searchDistance, startPos.y - 50, startPos.z - searchDistance, startPos.x + searchDistance, startPos.y + 50, startPos.z + searchDistance), new List<Entity>());
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn NUM Screamers: " + entitiesInBounds.Count);
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn RebirthVariables.customScreamerMax: " + RebirthVariables.customScreamerMax);
int numActiveScreamers = 0;
if (entitiesInBounds.Count >= 1)
{
for (int index = 0; index < entitiesInBounds.Count; ++index)
{
EntityZombieScreamerRebirth screamer = (EntityZombieScreamerRebirth)entitiesInBounds[index];
if (!screamer.IsDead())
{
numActiveScreamers++;
}
}
}
if (numActiveScreamers > 0 && RebirthVariables.isHerd)
{
Log.Out("AIDirectorChunkEventComponentPatches-SpawnScouts CAN'T START AN OUTBREAK WHILE SCREAMERS ARE STILL ACTIVE");
RebirthVariables.isHerd = false;
RebirthVariables.stopWHSpawns = true;
RebirthVariables.herdDuration = 0f;
}
else
{
__instance.ChooseNextTime(_spawnType);
__instance.spawners.Add(new AIWanderingHordeSpawner(__instance.Director, _spawnType, (AIWanderingHordeSpawner.HordeArrivedDelegate)null, directorPlayerStateList, __instance.Director.World.worldTime + 12000UL, startPos, pitStop, endPos));
}
}
}
return false;
}
}
[HarmonyPatch(typeof(GameStageDefinition))]
[HarmonyPatch("GetStage")]
public class GetStagePatch
{
public static bool Prefix(GameStageDefinition __instance, ref GameStageDefinition.Stage __result, int stage)
{
if (new StackTrace().FrameCount > 5)
{
MethodBase caller = new StackTrace().GetFrame(5).GetMethod();
string callerClassName = caller.ReflectedType.Name;
if (callerClassName != "AIWanderingHordeSpawner")
{
return true;
}
//Log.Out("AIDirectorGameStagePartySpawnerPatches-GetStage stage: " + stage);
//Log.Out("AIDirectorGameStagePartySpawnerPatches-GetStage callerClassName: " + callerClassName);
if (__instance.stages.Count < 1)
{
//Log.Out("AIDirectorGameStagePartySpawnerPatches-GetStage NO STAGES");
__result = (GameStageDefinition.Stage)null;
return false;
}
}
//Log.Out("AIDirectorGameStagePartySpawnerPatches-GetStage __instance.stages[0].stageNum: " + __instance.stages[0].stageNum);
// Set the result to the same value to keep the spawning consistent
__result = __instance.stages[0];
return false;
}
}
[HarmonyPatch(typeof(AIDirectorGameStagePartySpawner))]
[HarmonyPatch("Tick")]
public class TickPatch
{
public static bool Prefix(AIDirectorGameStagePartySpawner __instance, ref bool __result, double _deltaTime
)
{
if (__instance.spawnGroup != null)
{
bool flag = true;
if (__instance.spawnCount >= __instance.numToSpawn)
{
__instance.interval -= _deltaTime;
flag = __instance.interval <= 0.0;
}
if (flag)
{
//Log.Out("AIDirectorGameStagePartySpawner-Tick: " + __instance.ToString());
__instance.SetupGroup();
}
}
__result = __instance.spawnGroup != null;
return false;
}
}
[HarmonyPatch(typeof(AIWanderingHordeSpawner))]
[HarmonyPatch("UpdateHorde")]
public class UpdateHordePatch
{
public static bool Prefix(AIWanderingHordeSpawner __instance, float dt)
{
int index = 0;
while (index < __instance.commandList.Count)
{
AIWanderingHordeSpawner.ZombieCommand command = __instance.commandList[index];
bool hasAttackTaget = false; // command.Enemy.GetAttackTarget() != null;
bool hasOther = false;
bool flag = command.Enemy.IsDead() || hasAttackTaget;
if (!flag)
{
if (command.Command == AIWanderingHordeSpawner.ECommand.PitStop || command.Command == AIWanderingHordeSpawner.ECommand.EndPos)
{
if (command.Enemy.HasInvestigatePosition)
{
/*if (command.Enemy.InvestigatePosition != command.TargetPos)
{
flag = true;
AIDirector.LogAIExtra("Wandering horde zombie '" + command.Enemy?.ToString() + "' removed from horde control. Was killed or investigating");
}
else*/
{
command.Enemy.SetInvestigatePosition(command.TargetPos, 6000, false);
}
}
else if (command.Command == AIWanderingHordeSpawner.ECommand.PitStop)
{
AIDirector.LogAIExtra("Wandering horde zombie '" + command.Enemy?.ToString() + "' reached pitstop. Wander around for awhile");
command.WanderTime = (float)(90.0 + (double)__instance.director.random.RandomFloat * 4.0);
command.Command = AIWanderingHordeSpawner.ECommand.Wander;
}
else
{
//command.Enemy.SetInvestigatePosition(command.TargetPos, 6000, false);
/*Log.Out("AIWanderingHordeSpawner-UpdateHorde command.Command: " + command.Command + " / " + command.Enemy?.ToString());
hasOther = true;
flag = true;*/
}
}
else
{
command.WanderTime -= dt;
command.Enemy.ResetDespawnTime();
if ((double)command.WanderTime <= 0.0 && command.Enemy.GetAttackTarget() == null)
{
AIDirector.LogAIExtra("Wandering horde zombie '" + command.Enemy?.ToString() + "' wandered long enough. Going to endstop");
command.Command = AIWanderingHordeSpawner.ECommand.EndPos;
command.TargetPos = AIWanderingHordeSpawner.RandomPos(__instance.director, __instance.endPos, 6f);
command.Enemy.SetInvestigatePosition(command.TargetPos, 6000, false);
command.Enemy.IsHordeZombie = false;
}
}
}
if (flag)
{
string additionalInfo = "";
if (hasOther)
{
additionalInfo = " / HAS OTHER";
}
if (hasAttackTaget)
{
additionalInfo = " / HAS ATTACK TARGET";
}
AIDirector.LogAIExtra("Wandering horde zombie '" + command.Enemy?.ToString() + "' removed from control" + additionalInfo);
command.Enemy.IsHordeZombie = false;
command.Enemy.bIsChunkObserver = false;
__instance.commandList.RemoveAt(index);
}
else
++index;
}
return false;
}
}
[HarmonyPatch(typeof(AIWanderingHordeSpawner))]
[HarmonyPatch("Update")]
public class UpdatePatch
{
public static bool Prefix(AIWanderingHordeSpawner __instance, ref bool __result, World world, float _deltaTime)
{
if (world.GetPlayers().Count == 0)
{
//Log.Out("AIWanderingHordeSpawnerPatches-Update NO PLAYERS");
__result = true;
return false;
}
if (world.worldTime >= __instance.endTime)
{
if (__instance.arrivedCallback != null)
__instance.arrivedCallback();
//Log.Out("AIWanderingHordeSpawnerPatches-Update OVER END TIME: " + __instance.endTime);
__result = true;
return false;
}
bool flag = __instance.UpdateSpawn(world, _deltaTime);
//Log.Out("AIWanderingHordeSpawnerPatches-Update Wandering Horde size: " + __instance.commandList.Count);
//Log.Out("AIWanderingHordeSpawnerPatches-Update Wandering Horde Total Size: " + RebirthVariables.wanderingHordeCount);
if (flag)
{
//Log.Out("AIWanderingHordeSpawnerPatches-Update CANNOT SPAWN");
if (!RebirthVariables.isHerd)
{
if (__instance.commandList.Count == 0 || __instance.commandList.Count == RebirthVariables.wanderingHordeCount)
{
if (__instance.arrivedCallback != null)
__instance.arrivedCallback();
//Log.Out("AIWanderingHordeSpawnerPatches-Update __instance.commandList.Count: " + __instance.commandList.Count);
__result = true;
return false;
}
}
}
else
{
//Log.Out("AIWanderingHordeSpawnerPatches-Update CAN SPAWN");
}
if (!flag)
{
AstarManager.Instance.AddLocationLine(__instance.startPos, __instance.endPos, 64);
}
else
{
Vector3 zero = Vector3.zero;
int num = 0;
for (int index = 0; index < __instance.commandList.Count; ++index)
{
Entity enemy = (Entity)__instance.commandList[index].Enemy;
if (!enemy.IsDead())
{
zero += enemy.position;
++num;
}
}
if (num > 0)
{
Vector3 pos3d = zero * (1f / (float)num);
AstarManager.Instance.AddLocation(pos3d, 64);
}
}
__instance.UpdateHorde(_deltaTime);
__result = false;
return false;
}
}
[HarmonyPatch(typeof(AIWanderingHordeSpawner))]
[HarmonyPatch("UpdateSpawn")]
public class UpdateSpawnPatch
{
public static bool Prefix(AIWanderingHordeSpawner __instance, ref bool __result, World _world, float _deltaTime)
{
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn RebirthVariables.isWHSpawned: " + RebirthVariables.isWHSpawned);
EntityPlayer closestPlayer = _world.GetClosestPlayer(__instance.startPos, 100, false);
if (closestPlayer != null)
{
int searchDistance = 150;
List<Entity> entitiesInBounds = GameManager.Instance.World.GetEntitiesInBounds(typeof(EntityZombieScreamerRebirth), BoundsUtils.BoundsForMinMax(closestPlayer.position.x - searchDistance, closestPlayer.position.y - 50, closestPlayer.position.z - searchDistance, closestPlayer.position.x + searchDistance, closestPlayer.position.y + 50, closestPlayer.position.z + searchDistance), new List<Entity>());
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn NUM Screamers: " + entitiesInBounds.Count);
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn RebirthVariables.customScreamerMax: " + RebirthVariables.customScreamerMax);
if (entitiesInBounds.Count >= 1)
{
int numActiveScreamers = 0;
for (int index = 0; index < entitiesInBounds.Count; ++index)
{
EntityZombieScreamerRebirth screamer = (EntityZombieScreamerRebirth)entitiesInBounds[index];
if (!screamer.IsDead())
{
numActiveScreamers++;
}
}
if (numActiveScreamers >= RebirthVariables.customScreamerMax)
{
Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn STOPPING WANDERING HORDE, TOO MANY SCREAMERS FOUND");
RebirthVariables.isHerd = false;
RebirthVariables.stopWHSpawns = true;
RebirthVariables.herdDuration = 0f;
__instance.Cleanup();
AIDirectorWanderingHordeComponent director = GameManager.Instance.World.aiDirector.GetComponent<AIDirectorWanderingHordeComponent>();
if (director != null && director.spawners.Count > 0)
{
AIWanderingHordeSpawner spawner = director.spawners[director.spawners.Count - 1];
if (spawner != null)
{
director.spawners.RemoveAt(director.spawners.Count - 1);
}
}
}
}
}
if (!RebirthVariables.isWHSpawned)
{
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn ATTEMPTING TO FIND A PLAYER");
if (closestPlayer != null)
{
RebirthVariables.wanderingHordeGameStage = closestPlayer.gameStage;
string optionWanderingHordeHerdRestriction = RebirthVariables.customWanderingHordeHerdRestriction;
if (optionWanderingHordeHerdRestriction == "low")
{
if (RebirthVariables.wanderingHordeGameStage >= RebirthVariables.spawnThresholdFeral)
{
RebirthVariables.wanderingHordeGameStage = RebirthVariables.spawnThresholdFeral;
}
}
else if (optionWanderingHordeHerdRestriction == "medium")
{
if (RebirthVariables.wanderingHordeGameStage >= RebirthVariables.spawnThresholdRadiated)
{
RebirthVariables.wanderingHordeGameStage = RebirthVariables.spawnThresholdRadiated;
}
}
else if (optionWanderingHordeHerdRestriction == "high")
{
if (RebirthVariables.wanderingHordeGameStage >= RebirthVariables.spawnThresholdTainted)
{
RebirthVariables.wanderingHordeGameStage = RebirthVariables.spawnThresholdTainted;
}
}
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn FOUND CLOSE MEMBER: " + closestPlayer.EntityName + " / gamestage: " + closestPlayer.gameStage);
}
RebirthVariables.stopWHSpawns = false;
RebirthVariables.isWHSpawned = true;
}
else
{
if (RebirthVariables.isHerd)
{
float diff = Time.time - RebirthVariables.herdStartTime;
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn diff: " + diff + " / " + RebirthVariables.herdDuration);
if (diff >= RebirthVariables.herdDuration || RebirthUtilities.IsHordeNight()) // 1 in-game hour (170)
{
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn OVER TIME LIMIT");
RebirthVariables.isHerd = false;
RebirthVariables.stopWHSpawns = true;
RebirthVariables.herdDuration = 0f;
__instance.Cleanup();
AIDirectorWanderingHordeComponent director = GameManager.Instance.World.aiDirector.GetComponent<AIDirectorWanderingHordeComponent>();
if (director != null && director.spawners.Count > 0)
{
AIWanderingHordeSpawner spawner = director.spawners[director.spawners.Count - 1];
if (spawner != null)
{
director.spawners.RemoveAt(director.spawners.Count - 1);
}
}
}
}
}
bool canSpawnDirector = GameStats.GetInt(EnumGameStats.EnemyCount) < GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedZombies);
int whSizeMultiplier = RebirthVariables.wanderingHordeMultiplier;
if (canSpawnDirector)
{
if (__instance.commandList.Count >= whSizeMultiplier * RebirthVariables.wanderingHordeSize)
{
canSpawnDirector = false;
}
}
if (!canSpawnDirector && !RebirthVariables.stopWHSpawns)
{
if (!RebirthVariables.isHerd)
{
//Log.Out("Reached wandering horde size: " + __instance.commandList.Count);
RebirthVariables.stopWHSpawns = true;
}
}
bool tick = __instance.spawner.Tick((double)_deltaTime);
if (!canSpawnDirector || !tick || RebirthVariables.stopWHSpawns)
{
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn CANNOT SPAWN canSpawnDirector: " + canSpawnDirector + " / tick: " + tick);
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn GameStats.GetInt(EnumGameStats.EnemyCount): " + GameStats.GetInt(EnumGameStats.EnemyCount));
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedZombies): " + (double)GamePrefs.GetInt(EnumGamePrefs.MaxSpawnedZombies));
//Log.Out("AIWanderingHordeSpawnerPatches-UpdateSpawn RebirthVariables.stopWHSpawns: " + RebirthVariables.stopWHSpawns);
__result = true;
return false;
}
__instance.spawnDelay -= _deltaTime;
if ((double)__instance.spawnDelay >= 0.0)
{
__result = false;
return false;
}
__instance.spawnDelay = 1f;
Vector3 _position;
bool canSpawn = __instance.spawner.canSpawn;
bool spawnPosition = _world.GetMobRandomSpawnPosWithWater(__instance.startPos, 1, 6, 15, true, out _position);
if (!canSpawn || !spawnPosition)
{
__result = false;
return false;
}
RebirthVariables.wanderingHordeCount = whSizeMultiplier * RebirthVariables.wanderingHordeSize;
if (__instance.commandList.Count >= whSizeMultiplier * RebirthVariables.wanderingHordeSize)
{
if (!RebirthVariables.isHerd)
{
RebirthVariables.stopWHSpawns = true;
}
__result = true;
return false;
}
if (RebirthUtilities.ScenarioSkip())
{
string biomeName = RebirthUtilities.GetBiomeName(__instance.startPos);
if (biomeName == "desert")
{
biomeName = "pine_forest";
}
RebirthUtilities.SetHiveSpawnGroup(biomeName);
}
EntityEnemy entity = (EntityEnemy)EntityFactory.CreateEntity(EntityGroups.GetRandomFromGroup(__instance.spawner.spawnGroupName, ref __instance.lastClassId), _position);
if (entity is EntityZombieSDX zombie)
{
zombie.wanderingHorde = 1;
}
if (RebirthVariables.isHerd)
{
entity.Buffs.SetCustomVar("$herdEntity", 1f);
}
_world.SpawnEntityInWorld((Entity)entity);
entity.SetSpawnerSource(EnumSpawnerSource.Dynamic);
entity.IsHordeZombie = true;
entity.bIsChunkObserver = true;
entity.IsHordeZombie = true;
entity.bIsChunkObserver = true;
if (++__instance.bonusLootSpawnCount >= GameStageDefinition.LootWanderingBonusEvery)
{
__instance.bonusLootSpawnCount = 0;
entity.lootDropProb *= GameStageDefinition.LootWanderingBonusScale;
}
AIWanderingHordeSpawner.ZombieCommand zombieCommand = new AIWanderingHordeSpawner.ZombieCommand();
zombieCommand.Enemy = entity;
zombieCommand.TargetPos = AIWanderingHordeSpawner.RandomPos(__instance.director, __instance.endPos, 6f);
zombieCommand.Command = AIWanderingHordeSpawner.ECommand.EndPos;
__instance.commandList.Add(zombieCommand);
entity.SetInvestigatePosition(zombieCommand.TargetPos, 6000, false);
AIDirector.LogAI("Spawned wandering horde (group {0}, zombie {1})", (object)__instance.spawner.spawnGroupName, (object)entity);
__instance.spawner.IncSpawnCount();
__result = false;
return false;
}
}
}