using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Photon.Pun;
using UnityEngine;
using UnityEngine.SceneManagement;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Zombies Anywhere")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Zombies Anywhere")]
[assembly: AssemblyCopyright("Copyright © 2025")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("887df093-284b-4d21-b615-1096ecf89525")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
namespace Zombies_Anywhere;
[BepInPlugin("tony4twenty.PEAK_Zombies", "PEAK Zombies", "1.0.0")]
public class ZombiesAnywhereMod : BaseUnityPlugin
{
[HarmonyPatch(typeof(MushroomZombieSpawner), "Start")]
private static class MushroomZombieSpawnerStartPatch
{
private static bool Prefix(MushroomZombieSpawner __instance)
{
ZombiesAnywhereMod instance = Instance;
if ((Object)(object)instance == (Object)null)
{
return true;
}
if (instance.disableZombies.Value)
{
if ((Object)(object)__instance != (Object)null && (Object)(object)((Component)__instance).gameObject != (Object)null)
{
Object.Destroy((Object)(object)((Component)__instance).gameObject);
}
ManualLogSource logger = ZombiesAnywhereMod.logger;
if (logger != null)
{
logger.LogInfo((object)"Destroyed zombie spawner because zombies are globally disabled.");
}
return false;
}
if (Ascents.currentAscent == -1 && instance.allowTenderfootZombies.Value)
{
if (__instance.cullRandomly && Random.Range(0f, 1f) > 0.333f)
{
ManualLogSource logger2 = ZombiesAnywhereMod.logger;
if (logger2 != null)
{
logger2.LogInfo((object)"Tenderfoot zombie spawner culled by random chance.");
}
Object.Destroy((Object)(object)((Component)__instance).gameObject);
return false;
}
if (!ZombieManager.Instance.spawners.Contains(__instance))
{
ZombieManager.Instance.spawners.Add(__instance);
}
ManualLogSource logger3 = ZombiesAnywhereMod.logger;
if (logger3 != null)
{
logger3.LogInfo((object)"Registered Tenderfoot zombie spawner (AllowTenderfootZombies=true).");
}
return false;
}
if (Ascents.currentAscent == -1 && !instance.allowTenderfootZombies.Value)
{
ManualLogSource logger4 = ZombiesAnywhereMod.logger;
if (logger4 != null)
{
logger4.LogInfo((object)"Tenderfoot zombie spawner destroyed (AllowTenderfootZombies=false).");
}
}
return true;
}
}
[CompilerGenerated]
private sealed class <AutoSpawnCoroutine>d__59 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public float intervalSeconds;
public float spawnRadius;
public ZombiesAnywhereMod <>4__this;
private Vector3 <spawnCenter>5__1;
private int <spawnCount>5__2;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <AutoSpawnCoroutine>d__59(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0042: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00ba: Unknown result type (might be due to invalid IL or missing references)
//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
if (<>4__this.disableZombies.Value)
{
break;
}
if (!PhotonNetwork.IsMasterClient)
{
<>2__current = null;
<>1__state = 2;
return true;
}
<spawnCenter>5__1 = (((Object)(object)_instance != (Object)null) ? _instance.GetSpawnCenter() : Vector3.zero);
if (<spawnCenter>5__1 != Vector3.zero)
{
<spawnCount>5__2 = ((!((Object)(object)_instance != (Object)null)) ? 1 : _instance.zombiesPerSpawn.Value);
SpawnZombiesAround(<spawnCenter>5__1, spawnRadius, <spawnCount>5__2);
if (logger != null)
{
logger.LogInfo((object)$"Auto-spawned {<spawnCount>5__2} zombie(s). Total active zombies: {(((Object)(object)ZombieManager.Instance != (Object)null) ? ZombieManager.Instance.zombies.Count : 0)}");
}
}
else
{
logger.LogWarning((object)"No valid spawn center found, skipping auto-spawn");
}
break;
case 2:
<>1__state = -1;
break;
}
<>2__current = (object)new WaitForSeconds(intervalSeconds);
<>1__state = 1;
return true;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <DelayedInitialization>d__48 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public ZombiesAnywhereMod <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <DelayedInitialization>d__48(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Expected O, but got Unknown
//IL_007f: Unknown result type (might be due to invalid IL or missing references)
//IL_0089: Expected O, but got Unknown
//IL_00af: Unknown result type (might be due to invalid IL or missing references)
//IL_00b9: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(<>4__this.initialSpawnDelay.Value);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (<>4__this.disableZombies.Value)
{
return false;
}
goto IL_009a;
case 2:
<>1__state = -1;
goto IL_009a;
case 3:
{
<>1__state = -1;
break;
}
IL_009a:
if (!PhotonNetwork.IsConnected)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
}
break;
}
if (!PhotonNetwork.InRoom)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 3;
return true;
}
if (<>4__this.disableZombies.Value)
{
return false;
}
logger.LogInfo((object)"Game ready! Starting zombie spawning...");
if (PhotonNetwork.IsMasterClient)
{
<>4__this.SpawnInitialZombies();
}
if (<>4__this.autoSpawnInterval.Value > 0f)
{
StartAutoSpawning(<>4__this.autoSpawnInterval.Value, <>4__this.autoSpawnRadius.Value);
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static ManualLogSource logger;
private static ZombiesAnywhereMod _instance;
private ConfigEntry<bool> autoSpawnEnabled;
private ConfigEntry<float> autoSpawnInterval;
private ConfigEntry<float> autoSpawnRadius;
private ConfigEntry<int> initialSpawnCount;
private ConfigEntry<int> zombiesPerSpawn;
private ConfigEntry<float> initialSpawnDelay;
private ConfigEntry<bool> bypassMaxZombieLimit;
private ConfigEntry<int> customMaxZombies;
private ConfigEntry<bool> removeZombieLifetime;
private ConfigEntry<float> zombieLifetimeOverride;
private ConfigEntry<bool> hideMushroomVisuals;
private ConfigEntry<bool> enableMushroomGrowth;
private ConfigEntry<bool> disableZombies;
private ConfigEntry<bool> allowTenderfootZombies;
private ConfigEntry<float> reachForce;
private ConfigEntry<float> distanceBeforeWakeup;
private ConfigEntry<float> lookAngleBeforeWakeup;
private ConfigEntry<float> initialWakeUpTime;
private ConfigEntry<float> distanceBeforeChase;
private ConfigEntry<float> zombieSprintDistance;
private ConfigEntry<float> chaseTimeBeforeSprint;
private ConfigEntry<float> zombieLungeDistance;
private ConfigEntry<float> lungeTime;
private ConfigEntry<float> lungeRecoveryTime;
private ConfigEntry<float> biteStunTime;
private ConfigEntry<float> biteInitialInjury;
private ConfigEntry<float> biteInitialSpores;
private ConfigEntry<float> biteDelayBeforeSpores;
private ConfigEntry<float> biteSporesPerSecond;
private ConfigEntry<float> totalBiteSporesTime;
private ConfigEntry<float> distanceToEnable;
private ConfigEntry<float> zombieGruntWaitMin;
private ConfigEntry<float> zombieGruntWaitMax;
private ConfigEntry<float> mushroomGrowTimeMin;
private ConfigEntry<float> mushroomGrowTimeMax;
private ConfigEntry<float> attackHeightDelta;
private static readonly FieldInfo MushroomsGrowingField = typeof(MushroomZombie).GetField("mushroomsGrowing", BindingFlags.Instance | BindingFlags.NonPublic);
private static readonly FieldInfo MushroomGrowTimesField = typeof(MushroomZombie).GetField("mushroomGrowTimes", BindingFlags.Instance | BindingFlags.NonPublic);
private Harmony harmony;
private Coroutine autoSpawnCoroutine;
internal static ZombiesAnywhereMod Instance => _instance;
private void Awake()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0029: Expected O, but got Unknown
_instance = this;
logger = ((BaseUnityPlugin)this).Logger;
LoadConfiguration();
harmony = new Harmony("tony4twenty.ZombiesAnywhere.Patches");
harmony.PatchAll(typeof(ZombiesAnywhereMod).Assembly);
SceneManager.sceneLoaded += OnSceneLoaded;
logger.LogInfo((object)"PEAK Zombies mod loaded!");
logger.LogInfo((object)("Global zombies: " + (disableZombies.Value ? "DISABLED" : "ENABLED")));
logger.LogInfo((object)("Tenderfoot zombies: " + (allowTenderfootZombies.Value ? "ALLOWED" : "BLOCKED")));
ZombieManager instance = ZombieManager.Instance;
if ((Object)(object)instance != (Object)null)
{
logger.LogInfo((object)$"Game's max active zombies: {instance.maxActiveZombies}");
if (bypassMaxZombieLimit.Value)
{
logger.LogInfo((object)"Max zombie limit bypass: ENABLED (unlimited zombies)");
}
else if (customMaxZombies.Value > 0)
{
logger.LogInfo((object)$"Custom max zombies: {customMaxZombies.Value}");
}
}
if (removeZombieLifetime.Value)
{
logger.LogInfo((object)"Zombie lifetime: REMOVED (zombies live forever)");
}
else if (zombieLifetimeOverride.Value > 0f)
{
logger.LogInfo((object)$"Zombie lifetime: {zombieLifetimeOverride.Value} seconds");
}
else
{
logger.LogInfo((object)"Zombie lifetime: Using game default (120 seconds)");
}
logger.LogInfo((object)$"Auto-spawn settings: {zombiesPerSpawn.Value} zombie(s) every {autoSpawnInterval.Value} seconds");
logger.LogInfo((object)("Mushroom visuals: " + (hideMushroomVisuals.Value ? "HIDDEN" : "VISIBLE")));
logger.LogInfo((object)("Mushroom growth: " + (enableMushroomGrowth.Value ? "ENABLED" : "DISABLED (instant full size)")));
}
private void LoadConfiguration()
{
disableZombies = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "DisableZombies", false, "Master toggle. Set true to prevent any zombies from spawning or registering");
allowTenderfootZombies = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AllowTenderfootZombies", true, "If true, prevents Tenderfoot ascent from destroying zombie spawners");
autoSpawnEnabled = ((BaseUnityPlugin)this).Config.Bind<bool>("General", "AutoSpawnEnabled", true, "Enable automatic zombie spawning");
autoSpawnInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AutoSpawnInterval", 10f, "How often to spawn zombies (in seconds)");
autoSpawnRadius = ((BaseUnityPlugin)this).Config.Bind<float>("General", "AutoSpawnRadius", 50f, "Radius around players to spawn zombies within");
initialSpawnCount = ((BaseUnityPlugin)this).Config.Bind<int>("General", "InitialSpawnCount", 3, "Number of zombies to spawn when game starts");
zombiesPerSpawn = ((BaseUnityPlugin)this).Config.Bind<int>("General", "ZombiesPerSpawn", 2, "Number of zombies to spawn each auto-spawn cycle");
initialSpawnDelay = ((BaseUnityPlugin)this).Config.Bind<float>("General", "InitialSpawnDelay", 15f, "Delay in seconds before first spawn after scene load");
bypassMaxZombieLimit = ((BaseUnityPlugin)this).Config.Bind<bool>("Zombie Limits", "BypassMaxZombieLimit", true, "If true, ignore the game's maxActiveZombies limit (unlimited zombies)");
customMaxZombies = ((BaseUnityPlugin)this).Config.Bind<int>("Zombie Limits", "CustomMaxZombies", -1, "Custom max zombie limit. Set to -1 to use game default, or > 0 to set your own limit");
removeZombieLifetime = ((BaseUnityPlugin)this).Config.Bind<bool>("Zombie Behavior", "RemoveZombieLifetime", true, "If true, zombies won't die from old age (they'll live forever)");
zombieLifetimeOverride = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Behavior", "ZombieLifetimeOverride", -1f, "Override zombie lifetime in seconds. Set to -1 to use game default, or > 0 to set custom lifetime");
hideMushroomVisuals = ((BaseUnityPlugin)this).Config.Bind<bool>("Zombie Behavior", "HideMushroomVisuals", false, "If true, hides the mushroom visuals on zombies");
enableMushroomGrowth = ((BaseUnityPlugin)this).Config.Bind<bool>("Zombie Behavior", "EnableMushroomGrowth", true, "If false, mushrooms start fully grown and do not animate");
reachForce = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "ReachForce", -1f, "Override reach force when lunging/reaching (set to -1 to keep prefab value)");
distanceBeforeWakeup = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "DistanceBeforeWakeup", 30f, "Distance at which a sleeping zombie wakes up");
lookAngleBeforeWakeup = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "LookAngleBeforeWakeup", 30f, "Look angle threshold required to wake a sleeping zombie");
initialWakeUpTime = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "InitialWakeUpTime", 5f, "Time a zombie spends waking up before becoming active");
distanceBeforeChase = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "DistanceBeforeChase", 30f, "Distance at which a zombie starts chasing its target");
zombieSprintDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "ZombieSprintDistance", 20f, "Distance within which zombies start sprinting");
chaseTimeBeforeSprint = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "ChaseTimeBeforeSprint", 3f, "Time spent chasing before zombies start sprinting");
zombieLungeDistance = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "ZombieLungeDistance", 10f, "Distance within which zombies lunge");
lungeTime = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "LungeTime", 1.5f, "Duration of the lunge attack");
lungeRecoveryTime = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "LungeRecoveryTime", 5f, "Recovery time after a lunge");
biteStunTime = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "BiteStunTime", 3f, "Time a target is stunned after being bitten");
biteInitialInjury = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "BiteInitialInjury", -1f, "Override initial injury applied when bitten (set to -1 to keep prefab value)");
biteInitialSpores = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "BiteInitialSpores", -1f, "Override initial spores applied when bitten (set to -1 to keep prefab value)");
biteDelayBeforeSpores = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "BiteDelayBeforeSpores", -1f, "Override delay before spores begin applying after a bite (set to -1 to keep prefab value)");
biteSporesPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "BiteSporesPerSecond", -1f, "Override spores applied per second after a bite (set to -1 to keep prefab value)");
totalBiteSporesTime = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "TotalBiteSporesTime", -1f, "Override total duration spores are applied after a bite (set to -1 to keep prefab value)");
distanceToEnable = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "DistanceToEnable", -1f, "Override enable distance for NPC zombies (set to -1 to keep prefab value)");
zombieGruntWaitMin = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "ZombieGruntWaitMin", 10f, "Minimum seconds between zombie grunts");
zombieGruntWaitMax = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "ZombieGruntWaitMax", 20f, "Maximum seconds between zombie grunts");
mushroomGrowTimeMin = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "MushroomGrowTimeMin", -1f, "Override minimum mushroom grow time (set to -1 to keep prefab value)");
mushroomGrowTimeMax = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "MushroomGrowTimeMax", -1f, "Override maximum mushroom grow time (set to -1 to keep prefab value)");
attackHeightDelta = ((BaseUnityPlugin)this).Config.Bind<float>("Zombie Stats", "AttackHeightDelta", 100f, "Vertical offset used when aiming attacks");
}
private void OnDestroy()
{
SceneManager.sceneLoaded -= OnSceneLoaded;
StopAutoSpawning();
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
}
private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
{
logger.LogInfo((object)("Scene loaded: " + ((Scene)(ref scene)).name));
if (disableZombies.Value)
{
logger.LogInfo((object)"Global zombies disabled – skipping auto spawn setup.");
}
else if (autoSpawnEnabled.Value)
{
((MonoBehaviour)this).StartCoroutine(DelayedInitialization());
}
}
[IteratorStateMachine(typeof(<DelayedInitialization>d__48))]
private IEnumerator DelayedInitialization()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <DelayedInitialization>d__48(0)
{
<>4__this = this
};
}
private void SpawnInitialZombies()
{
//IL_0014: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
if (!disableZombies.Value)
{
Vector3 spawnCenter = GetSpawnCenter();
if (spawnCenter != Vector3.zero)
{
logger.LogInfo((object)$"Spawning {initialSpawnCount.Value} initial zombies...");
SpawnZombiesAround(spawnCenter, autoSpawnRadius.Value, initialSpawnCount.Value);
}
}
}
private Vector3 GetSpawnCenter()
{
//IL_0092: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0022: Unknown result type (might be due to invalid IL or missing references)
//IL_009b: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Unknown result type (might be due to invalid IL or missing references)
//IL_004f: Unknown result type (might be due to invalid IL or missing references)
//IL_0054: Unknown result type (might be due to invalid IL or missing references)
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Unknown result type (might be due to invalid IL or missing references)
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
if (Character.AllCharacters != null && Character.AllCharacters.Count > 0)
{
Vector3 val = Vector3.zero;
int num = 0;
foreach (Character allCharacter in Character.AllCharacters)
{
if ((Object)(object)allCharacter != (Object)null)
{
val += allCharacter.Center;
num++;
}
}
if (num > 0)
{
return val / (float)num;
}
}
return Vector3.zero;
}
public static MushroomZombie SpawnZombieAt(Vector3 position, Quaternion rotation = default(Quaternion), MushroomZombie zombiePrefab = null)
{
//IL_01c7: Unknown result type (might be due to invalid IL or missing references)
//IL_01c8: Unknown result type (might be due to invalid IL or missing references)
//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
//IL_01d1: Unknown result type (might be due to invalid IL or missing references)
//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
//IL_01dd: Unknown result type (might be due to invalid IL or missing references)
//IL_01da: Unknown result type (might be due to invalid IL or missing references)
//IL_0499: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)_instance != (Object)null && _instance.disableZombies.Value)
{
if (logger != null)
{
logger.LogWarning((object)"Attempted to spawn zombie while global zombies are disabled.");
}
return null;
}
if (!PhotonNetwork.IsMasterClient)
{
if (logger != null)
{
logger.LogWarning((object)"Only master client can spawn zombies!");
}
return null;
}
if ((Object)(object)zombiePrefab == (Object)null)
{
zombiePrefab = GetZombiePrefab();
if ((Object)(object)zombiePrefab == (Object)null)
{
if (logger != null)
{
logger.LogError((object)"Could not find MushroomZombie prefab! Make sure spawners exist in the scene.");
}
return null;
}
}
ZombieManager instance = ZombieManager.Instance;
if ((Object)(object)_instance != (Object)null && !_instance.bypassMaxZombieLimit.Value && (Object)(object)instance != (Object)null)
{
int num = ((_instance.customMaxZombies.Value > 0) ? _instance.customMaxZombies.Value : instance.maxActiveZombies);
if (instance.zombies.Count >= num)
{
if (logger != null)
{
logger.LogWarning((object)$"Max active zombies reached ({num}). Cannot spawn more. (Current: {instance.zombies.Count})");
}
return null;
}
}
if (logger != null)
{
logger.LogInfo((object)$"Spawning zombie at position: {position}");
}
GameObject val = PhotonNetwork.Instantiate(((Object)((Component)zombiePrefab).gameObject).name, position, (rotation == default(Quaternion)) ? Quaternion.identity : rotation, (byte)0, (object[])null);
if ((Object)(object)val == (Object)null)
{
if (logger != null)
{
logger.LogError((object)"Failed to instantiate zombie!");
}
return null;
}
MushroomZombie component = val.GetComponent<MushroomZombie>();
if ((Object)(object)component == (Object)null)
{
if (logger != null)
{
logger.LogError((object)"Spawned object doesn't have MushroomZombie component!");
}
PhotonNetwork.Destroy(val);
return null;
}
if (component.isNPCZombie && (Object)(object)instance != (Object)null)
{
instance.RegisterZombie(component);
}
if ((Object)(object)_instance != (Object)null && _instance.removeZombieLifetime.Value)
{
component.lifetime = 3.1536E+09f;
if (logger != null)
{
logger.LogInfo((object)"Removed lifetime for zombie (set to infinite)");
}
}
else if ((Object)(object)_instance != (Object)null && _instance.zombieLifetimeOverride.Value > 0f)
{
component.lifetime = _instance.zombieLifetimeOverride.Value;
if (logger != null)
{
logger.LogInfo((object)$"Set zombie lifetime to {_instance.zombieLifetimeOverride.Value} seconds");
}
}
if ((Object)(object)_instance != (Object)null && _instance.hideMushroomVisuals.Value)
{
if (component.mushroomVisuals != null && component.mushroomVisuals.Count > 0)
{
foreach (GameObject mushroomVisual in component.mushroomVisuals)
{
if ((Object)(object)mushroomVisual != (Object)null)
{
mushroomVisual.SetActive(false);
}
}
if (logger != null)
{
logger.LogInfo((object)$"Hid {component.mushroomVisuals.Count} mushroom visual(s) on zombie");
}
}
}
else if ((Object)(object)_instance != (Object)null && !_instance.enableMushroomGrowth.Value && component.mushroomVisuals != null)
{
foreach (GameObject mushroomVisual2 in component.mushroomVisuals)
{
if ((Object)(object)mushroomVisual2 != (Object)null)
{
mushroomVisual2.SetActive(true);
mushroomVisual2.transform.localScale = Vector3.one;
}
}
if (MushroomsGrowingField != null)
{
MushroomsGrowingField.SetValue(component, false);
}
if (MushroomGrowTimesField != null && MushroomGrowTimesField.GetValue(component) is List<float> list)
{
for (int i = 0; i < list.Count; i++)
{
list[i] = 0f;
}
}
if (logger != null)
{
logger.LogInfo((object)"Disabled mushroom growth (instant full size)");
}
}
if ((Object)(object)_instance != (Object)null)
{
_instance.ApplyZombieTuning(component);
}
return component;
}
private void ApplyZombieTuning(MushroomZombie zombie)
{
//IL_0213: Unknown result type (might be due to invalid IL or missing references)
//IL_0218: Unknown result type (might be due to invalid IL or missing references)
//IL_02a7: Unknown result type (might be due to invalid IL or missing references)
//IL_02ac: Unknown result type (might be due to invalid IL or missing references)
//IL_02f9: Unknown result type (might be due to invalid IL or missing references)
//IL_02fe: Unknown result type (might be due to invalid IL or missing references)
if (!((Object)(object)zombie == (Object)null))
{
if (reachForce.Value >= 0f)
{
zombie.reachForce = reachForce.Value;
}
zombie.distanceBeforeWakeup = distanceBeforeWakeup.Value;
zombie.lookAngleBeforeWakeup = lookAngleBeforeWakeup.Value;
zombie.initialWakeUpTime = initialWakeUpTime.Value;
zombie.distanceBeforeChase = distanceBeforeChase.Value;
zombie.zombieSprintDistance = zombieSprintDistance.Value;
zombie.chaseTimeBeforeSprint = chaseTimeBeforeSprint.Value;
zombie.zombieLungeDistance = zombieLungeDistance.Value;
zombie.lungeTime = lungeTime.Value;
zombie.lungeRecoveryTime = lungeRecoveryTime.Value;
zombie.biteStunTime = biteStunTime.Value;
if (biteInitialInjury.Value >= 0f)
{
zombie.biteInitialInjury = biteInitialInjury.Value;
}
if (biteInitialSpores.Value >= 0f)
{
zombie.biteInitialSpores = biteInitialSpores.Value;
}
if (biteDelayBeforeSpores.Value >= 0f)
{
zombie.biteDelayBeforeSpores = biteDelayBeforeSpores.Value;
}
if (biteSporesPerSecond.Value >= 0f)
{
zombie.biteSporesPerSecond = biteSporesPerSecond.Value;
}
if (totalBiteSporesTime.Value >= 0f)
{
zombie.totalBiteSporesTime = totalBiteSporesTime.Value;
}
if (distanceToEnable.Value >= 0f)
{
zombie.distanceToEnable = distanceToEnable.Value;
}
zombie.zombieGruntWaitTimeMinMax = new Vector2(zombieGruntWaitMin.Value, zombieGruntWaitMax.Value);
float num = ((mushroomGrowTimeMin.Value >= 0f) ? mushroomGrowTimeMin.Value : zombie.minMaxMushroomGrowTime.x);
float num2 = ((mushroomGrowTimeMax.Value >= 0f) ? mushroomGrowTimeMax.Value : zombie.minMaxMushroomGrowTime.y);
if (mushroomGrowTimeMin.Value >= 0f || mushroomGrowTimeMax.Value >= 0f)
{
zombie.minMaxMushroomGrowTime = new Vector2(num, num2);
}
zombie.attackHeightDelta = attackHeightDelta.Value;
if (zombie.zombieGruntWaitTimeMinMax.x > zombie.zombieGruntWaitTimeMinMax.y)
{
zombie.zombieGruntWaitTimeMinMax = new Vector2(zombie.zombieGruntWaitTimeMinMax.y, zombie.zombieGruntWaitTimeMinMax.x);
}
}
}
public static MushroomZombie SpawnZombieNearCharacter(Character character, Vector3 offset = default(Vector3))
{
//IL_002f: Unknown result type (might be due to invalid IL or missing references)
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_0069: Unknown result type (might be due to invalid IL or missing references)
//IL_006e: Unknown result type (might be due to invalid IL or missing references)
//IL_006f: Unknown result type (might be due to invalid IL or missing references)
//IL_0074: Unknown result type (might be due to invalid IL or missing references)
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_0078: Unknown result type (might be due to invalid IL or missing references)
//IL_007e: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
//IL_0060: Unknown result type (might be due to invalid IL or missing references)
//IL_0065: Unknown result type (might be due to invalid IL or missing references)
if ((Object)(object)character == (Object)null)
{
if (logger != null)
{
logger.LogError((object)"Character is null!");
}
return null;
}
if (offset == default(Vector3))
{
offset = ((Component)character.refs.head).transform.forward * 5f;
}
Vector3 position = character.Center + offset;
return SpawnZombieAt(position);
}
public static List<MushroomZombie> SpawnZombiesAround(Vector3 center, float radius, int count)
{
//IL_00cb: Unknown result type (might be due to invalid IL or missing references)
//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
//IL_00d7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d8: Unknown result type (might be due to invalid IL or missing references)
//IL_00e3: Unknown result type (might be due to invalid IL or missing references)
//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
//IL_00f5: Unknown result type (might be due to invalid IL or missing references)
//IL_00f7: Unknown result type (might be due to invalid IL or missing references)
//IL_00fc: Unknown result type (might be due to invalid IL or missing references)
//IL_00fe: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Unknown result type (might be due to invalid IL or missing references)
//IL_0108: Unknown result type (might be due to invalid IL or missing references)
List<MushroomZombie> list = new List<MushroomZombie>();
ZombieManager instance = ZombieManager.Instance;
for (int i = 0; i < count; i++)
{
if ((Object)(object)_instance != (Object)null && !_instance.bypassMaxZombieLimit.Value && (Object)(object)instance != (Object)null)
{
int num = ((_instance.customMaxZombies.Value > 0) ? _instance.customMaxZombies.Value : instance.maxActiveZombies);
if (instance.zombies.Count >= num)
{
if (logger != null)
{
logger.LogWarning((object)$"Max active zombies reached ({num}). Only spawned {list.Count} out of {count} requested.");
}
break;
}
}
Vector2 val = Random.insideUnitCircle * radius;
Vector3 position = center + new Vector3(val.x, 0f, val.y);
position = FindGroundPosition(position);
MushroomZombie val2 = SpawnZombieAt(position);
if ((Object)(object)val2 != (Object)null)
{
list.Add(val2);
}
}
return list;
}
private static MushroomZombie GetZombiePrefab()
{
ZombieManager instance = ZombieManager.Instance;
if ((Object)(object)instance != (Object)null && instance.spawners.Count > 0)
{
foreach (MushroomZombieSpawner spawner in instance.spawners)
{
if ((Object)(object)spawner != (Object)null && (Object)(object)spawner.mushroomZombiePrefab != (Object)null)
{
return spawner.mushroomZombiePrefab;
}
}
}
MushroomZombieSpawner[] array = Object.FindObjectsByType<MushroomZombieSpawner>((FindObjectsSortMode)0);
MushroomZombieSpawner[] array2 = array;
foreach (MushroomZombieSpawner val in array2)
{
if ((Object)(object)val != (Object)null && (Object)(object)val.mushroomZombiePrefab != (Object)null)
{
return val.mushroomZombiePrefab;
}
}
return null;
}
private static Vector3 FindGroundPosition(Vector3 position)
{
//IL_0001: Unknown result type (might be due to invalid IL or missing references)
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_000c: Unknown result type (might be due to invalid IL or missing references)
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0016: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0037: Unknown result type (might be due to invalid IL or missing references)
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0033: Unknown result type (might be due to invalid IL or missing references)
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
RaycastHit val = default(RaycastHit);
if (Physics.Raycast(position + Vector3.up * 10f, Vector3.down, ref val, 100f))
{
return ((RaycastHit)(ref val)).point;
}
return position;
}
public static void StartAutoSpawning(float intervalSeconds, float spawnRadius = 50f)
{
if ((Object)(object)_instance != (Object)null && !_instance.disableZombies.Value && _instance.autoSpawnCoroutine == null)
{
_instance.autoSpawnCoroutine = ((MonoBehaviour)_instance).StartCoroutine(_instance.AutoSpawnCoroutine(intervalSeconds, spawnRadius));
logger.LogInfo((object)$"Auto-spawning started: {intervalSeconds}s interval, {spawnRadius} unit radius");
}
}
public void StopAutoSpawning()
{
if (autoSpawnCoroutine != null)
{
((MonoBehaviour)this).StopCoroutine(autoSpawnCoroutine);
autoSpawnCoroutine = null;
logger.LogInfo((object)"Auto-spawning stopped");
}
}
[IteratorStateMachine(typeof(<AutoSpawnCoroutine>d__59))]
private IEnumerator AutoSpawnCoroutine(float intervalSeconds, float spawnRadius)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <AutoSpawnCoroutine>d__59(0)
{
<>4__this = this,
intervalSeconds = intervalSeconds,
spawnRadius = spawnRadius
};
}
}