Please disclose if your mod was created primarily using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Expand World Spawns v1.15.0
ExpandWorldSpawns.dll
Decompiled 2 months agousing System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using Data; using ExpandWorld.Spawn; using ExpandWorldData; using HarmonyLib; using Microsoft.CodeAnalysis; using ServerSync; using Service; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: AssemblyCompany("ExpandWorldSpawns")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d833c13f50c1246b93bd8962c57e59db3c9ff212")] [assembly: AssemblyProduct("ExpandWorldSpawns")] [assembly: AssemblyTitle("ExpandWorldSpawns")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace ExpandWorld { public class Configuration { public static CustomSyncedValue<string> valueSpawnData; public static void Init(ConfigWrapper wrapper) { valueSpawnData = wrapper.AddValue("spawn_data"); ((CustomSyncedValueBase)valueSpawnData).ValueChanged += delegate { Manager.FromSetting(valueSpawnData.Value); }; } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] public class SetCommands { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; internal void <Postfix>b__0_0(ConsoleEventArgs args) { Manager.Save(); } } private static void Postfix() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate { Manager.Save(); }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("ew_spawns", "Forces spawn file creation.", (ConsoleEvent)obj, true, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } [BepInPlugin("expand_world_spawns", "Expand World Spawns", "1.15")] [BepInDependency("expand_world_data", "1.52")] public class EWS : BaseUnityPlugin { public const string GUID = "expand_world_spawns"; public const string NAME = "Expand World Spawns"; public const string VERSION = "1.15"; public static ManualLogSource Log; public static ConfigSync ConfigSync = new ConfigSync("expand_world_spawns") { DisplayName = "Expand World Spawns", CurrentVersion = "1.15", ModRequired = true, IsLocked = true }; public static void LogWarning(string message) { Log.LogWarning((object)message); } public static void LogError(string message) { Log.LogError((object)message); } public static void LogInfo(string message) { Log.LogInfo((object)message); } public void Awake() { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0044: Expected O, but got Unknown //IL_0049: Unknown result type (might be due to invalid IL or missing references) Log = ((BaseUnityPlugin)this).Logger; Configuration.Init(new ConfigWrapper("expand_spawns_config", ((BaseUnityPlugin)this).Config, ConfigSync, (Action)delegate { })); new Harmony("expand_world_spawns").PatchAll(); try { if (Configuration.DataReload) { Manager.SetupWatcher(); } } catch (Exception ex) { Log.LogError((object)ex); } } } } namespace ExpandWorld.Spawn { public class Loader { public static Dictionary<SpawnData, DataEntry?> Data = new Dictionary<SpawnData, DataEntry>(); public static Dictionary<SpawnData, List<BlueprintObject>> Objects = new Dictionary<SpawnData, List<BlueprintObject>>(); public static SpawnData FromData(Data data, string fileName) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0058: 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) //IL_006a: 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_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Unknown result type (might be due to invalid IL or missing references) //IL_0141: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0171: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a1: Unknown result type (might be due to invalid IL or missing references) //IL_01ad: Unknown result type (might be due to invalid IL or missing references) //IL_01b9: Unknown result type (might be due to invalid IL or missing references) //IL_01c5: 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_01dd: Unknown result type (might be due to invalid IL or missing references) //IL_01e9: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Unknown result type (might be due to invalid IL or missing references) //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_020e: Expected O, but got Unknown string fileName2 = fileName; SpawnData val = new SpawnData { m_prefab = DataManager.ToPrefab(data.prefab, fileName2), m_name = data.name, m_enabled = data.enabled, m_biome = DataManager.ToBiomes(data.biome, fileName2), m_biomeArea = DataManager.ToBiomeAreas(data.biomeArea, fileName2), m_maxSpawned = data.maxSpawned, m_spawnInterval = data.spawnInterval, m_spawnChance = data.spawnChance, m_spawnDistance = data.spawnDistance, m_spawnRadiusMin = data.spawnRadiusMin, m_spawnRadiusMax = data.spawnRadiusMax, m_requiredGlobalKey = data.requiredGlobalKey, m_requiredEnvironments = DataManager.ToList(data.requiredEnvironments, true), m_groupSizeMin = data.groupSizeMin, m_groupSizeMax = data.groupSizeMax, m_spawnAtDay = data.spawnAtDay, m_spawnAtNight = data.spawnAtNight, m_groupRadius = data.groupRadius, m_minAltitude = data.minAltitude, m_maxAltitude = data.maxAltitude, m_minTilt = data.minTilt, m_maxTilt = data.maxTilt, m_inForest = data.inForest, m_outsideForest = data.outsideForest, m_minOceanDepth = data.minOceanDepth, m_maxOceanDepth = data.maxOceanDepth, m_huntPlayer = data.huntPlayer, m_groundOffset = data.groundOffset, m_maxLevel = data.maxLevel, m_minLevel = data.minLevel, m_levelUpMinCenterDistance = data.levelUpMinCenterDistance, m_overrideLevelupChance = data.overrideLevelupChance, m_inLava = data.inLava, m_outsideLava = data.outsideLava, m_canSpawnCloseToPlayer = data.canSpawnCloseToPlayer, m_insidePlayerBase = data.insidePlayerBase, m_groundOffsetRandom = data.groundOffsetRandom, m_minDistanceFromCenter = data.minDistance, m_maxDistanceFromCenter = data.maxDistance }; if (val.m_minAltitude == -10000f) { val.m_minAltitude = ((val.m_maxAltitude > 0f) ? 0f : (-1000f)); } if (data.data != null) { Data[val] = DataHelper.Get(data.data, fileName2); } DataEntry val2 = LoaderFields.HandleCustomData(data, val); if (val2 != null) { if (Data.ContainsKey(val)) { Data[val] = DataHelper.Merge((DataEntry[])(object)new DataEntry[2] { Data[val], val2 }); } else { Data.Add(val, val2); } } if (data.objects != null) { Dictionary<SpawnData, List<BlueprintObject>> objects = Objects; List<BlueprintObject> list = new List<BlueprintObject>(); list.AddRange(data.objects.Select((string s) => Parse.Split(s, true, ',')).Select((Func<string[], BlueprintObject>)((string[] split) => new BlueprintObject(split[0], Parse.VectorXZY(split, 1), Quaternion.identity, Vector3.one, DataHelper.Get((split.Length > 5) ? split[5] : "", fileName2), Parse.Float(split, 4, 1f), false)))); objects[val] = list; } return val; } public static Data ToData(SpawnData spawn) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0041: Unknown result type (might be due to invalid IL or missing references) return new Data { prefab = ((Object)spawn.m_prefab).name, name = spawn.m_name, enabled = spawn.m_enabled, biome = DataManager.FromBiomes(spawn.m_biome), biomeArea = DataManager.FromBiomeAreas(spawn.m_biomeArea), maxSpawned = spawn.m_maxSpawned, spawnInterval = spawn.m_spawnInterval, spawnChance = spawn.m_spawnChance, spawnDistance = spawn.m_spawnDistance, spawnRadiusMin = spawn.m_spawnRadiusMin, spawnRadiusMax = spawn.m_spawnRadiusMax, requiredGlobalKey = spawn.m_requiredGlobalKey, requiredEnvironments = DataManager.FromList((IEnumerable<string>)spawn.m_requiredEnvironments), spawnAtDay = spawn.m_spawnAtDay, spawnAtNight = spawn.m_spawnAtNight, groupSizeMin = spawn.m_groupSizeMin, groupSizeMax = spawn.m_groupSizeMax, groupRadius = spawn.m_groupRadius, minAltitude = spawn.m_minAltitude, maxAltitude = spawn.m_maxAltitude, minTilt = spawn.m_minTilt, maxTilt = spawn.m_maxTilt, inForest = spawn.m_inForest, outsideForest = spawn.m_outsideForest, minOceanDepth = spawn.m_minOceanDepth, maxOceanDepth = spawn.m_maxOceanDepth, huntPlayer = spawn.m_huntPlayer, groundOffset = spawn.m_groundOffset, maxLevel = spawn.m_maxLevel, minLevel = spawn.m_minLevel, levelUpMinCenterDistance = spawn.m_levelUpMinCenterDistance, overrideLevelupChance = spawn.m_overrideLevelupChance, inLava = spawn.m_inLava, outsideLava = spawn.m_outsideLava, canSpawnCloseToPlayer = spawn.m_canSpawnCloseToPlayer, insidePlayerBase = spawn.m_insidePlayerBase, groundOffsetRandom = spawn.m_groundOffsetRandom, minDistance = spawn.m_minDistanceFromCenter, maxDistance = spawn.m_maxDistanceFromCenter }; } } [HarmonyPatch(typeof(SpawnSystem), "Spawn")] public class SpawnZDO { private static void Prefix(SpawnData critter, Vector3 spawnPoint) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0017: Unknown result type (might be due to invalid IL or missing references) if (Loader.Data.TryGetValue(critter, out DataEntry value)) { DataHelper.Init(critter.m_prefab, spawnPoint, Quaternion.identity, (Vector3?)null, value); } } private static string PrefabOverride(string prefab) { return prefab; } private static DataEntry? DataOverride(DataEntry? data, string prefab) { return data; } private static void Postfix(SpawnData critter, Vector3 spawnPoint) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (!Loader.Objects.TryGetValue(critter, out List<BlueprintObject> value)) { return; } foreach (BlueprintObject item in value) { if (!(item.Chance < 1f) || !(Random.value > item.Chance)) { Spawn.BPO(item, spawnPoint, Quaternion.identity, Vector3.one, (Func<DataEntry, string, DataEntry>)DataOverride, (Func<string, string>)PrefabOverride, (List<GameObject>)null); } } } } public class LoaderFields { private static readonly int HashFaction = StringExtensionMethods.GetStableHashCode("faction"); private static readonly int HashDamage = StringExtensionMethods.GetStableHashCode("damage"); private static readonly HashSet<int> KnownFloats = new HashSet<int> { ZDOVars.s_randomSkillFactor, HashDamage }; public static DataEntry? HandleCustomData(Data data, SpawnData spawn) { //IL_000d: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Expected O, but got Unknown //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown DataEntry val = null; if (data.faction != null) { if (val == null) { val = new DataEntry(); } DataEntry val2 = val; if (val2.Strings == null) { val2.Strings = new Dictionary<int, IStringValue>(); } val.Strings[HashFaction] = DataValue.Simple(data.faction); } if (data.fields != null) { if (val == null) { val = new DataEntry(); } Dictionary<string, string> dictionary = new Dictionary<string, string>(); Dictionary<string, Dictionary<string, string>> dictionary2 = new Dictionary<string, Dictionary<string, string>>(); foreach (KeyValuePair<string, string> field in data.fields) { int num = StringExtensionMethods.GetStableHashCode(field.Key); if (KnownFloats.Contains(num)) { DataEntry val2 = val; if (val2.Floats == null) { val2.Floats = new Dictionary<int, IFloatValue>(); } if (num == HashDamage) { num = ZDOVars.s_randomSkillFactor; } val.Floats[num] = DataValue.Simple(Parse.Float(field.Value, 0f)); continue; } string[] array = field.Key.Split(new char[1] { '.' }); if (array.Length > 1) { Dictionary<string, Dictionary<string, string>> dictionary3 = dictionary2; string key = array[0]; if (dictionary3[key] == null) { Dictionary<string, string> dictionary5 = (dictionary3[key] = new Dictionary<string, string>()); } dictionary2[array[0]][array[1]] = field.Value; dictionary2[array[0]]["m_" + array[1]] = field.Value; } else { dictionary[field.Key] = field.Value; dictionary["m_" + field.Key] = field.Value; } } HandleFields(spawn, val, dictionary2, dictionary); } return val; } private static void HandleFields(SpawnData spawn, DataEntry customData, Dictionary<string, Dictionary<string, string>> componentFields, Dictionary<string, string> otherFields) { spawn.m_prefab.GetComponentsInChildren<MonoBehaviour>(ZNetView.m_tempComponents); foreach (MonoBehaviour tempComponent in ZNetView.m_tempComponents) { FieldInfo[] fields = ((object)tempComponent).GetType().GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (componentFields.TryGetValue(fieldInfo.Name, out Dictionary<string, string> value) && value.TryGetValue(fieldInfo.Name, out var value2)) { InsertData(customData, (Component)(object)tempComponent, fieldInfo, value2); } if (otherFields.TryGetValue(fieldInfo.Name, out string value3)) { InsertData(customData, (Component)(object)tempComponent, fieldInfo, value3); } } } ZNetView.m_tempComponents.Clear(); } private static void InsertData(DataEntry customData, Component component, FieldInfo info, string value) { //IL_019c: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) int stableHashCode = StringExtensionMethods.GetStableHashCode(((object)component).GetType().Name + "." + info.Name); DataEntry val = customData; if (val.Ints == null) { val.Ints = new Dictionary<int, IIntValue>(); } customData.Ints[StringExtensionMethods.GetStableHashCode("HasFields")] = DataValue.Simple(1); customData.Ints[StringExtensionMethods.GetStableHashCode("HasFields" + ((object)component).GetType().Name)] = DataValue.Simple(1); if (info.FieldType == typeof(int)) { val = customData; if (val.Ints == null) { val.Ints = new Dictionary<int, IIntValue>(); } customData.Ints[stableHashCode] = DataValue.Simple(Parse.Int(value, 0)); } else if (info.FieldType == typeof(float)) { val = customData; if (val.Floats == null) { val.Floats = new Dictionary<int, IFloatValue>(); } customData.Floats[stableHashCode] = DataValue.Simple(Parse.Float(value, 0f)); } else if (info.FieldType == typeof(bool)) { val = customData; if (val.Ints == null) { val.Ints = new Dictionary<int, IIntValue>(); } bool flag = value == "1" || value == "true"; customData.Ints[stableHashCode] = DataValue.Simple(flag ? 1 : 0); } else if (info.FieldType == typeof(Vector3)) { val = customData; if (val.Vecs == null) { val.Vecs = new Dictionary<int, IVector3Value>(); } customData.Vecs[stableHashCode] = DataValue.Simple(Parse.VectorXZY(value)); } else if (info.FieldType == typeof(Quaternion)) { val = customData; if (val.Quats == null) { val.Quats = new Dictionary<int, IQuaternionValue>(); } customData.Quats[stableHashCode] = DataValue.Simple(Parse.AngleYXZ(value)); } else { val = customData; if (val.Strings == null) { val.Strings = new Dictionary<int, IStringValue>(); } customData.Strings[stableHashCode] = DataValue.Simple(value); } } } public class Manager { public static string FileName = "expand_spawns.yaml"; public static string FilePath = Path.Combine(Yaml.Directory, FileName); public static string Pattern = "expand_spawns*.yaml"; public static bool IsValid(SpawnData spawn) { return Object.op_Implicit((Object)(object)spawn.m_prefab); } public static string Save() { SpawnSystem val = SpawnSystem.m_instances.FirstOrDefault(); if ((Object)(object)val == (Object)null) { return ""; } IEnumerable<SpawnData> source = val.m_spawnLists.SelectMany((SpawnSystemList s) => s.m_spawners); string text = Yaml.Serializer().Serialize((object)source.Select(Loader.ToData).ToList()); File.WriteAllText(FilePath, text); return text; } public static void ToFile() { if (!Helper.IsClient() && !File.Exists(FilePath)) { string value = Save(); Configuration.valueSpawnData.Value = value; } } public static void FromFile() { if (!Helper.IsClient()) { string text = DataManager.Read<Data, SpawnData>(Pattern, (Func<Data, string, SpawnData>)Loader.FromData); Configuration.valueSpawnData.Value = text; Set(text); } } public static void FromSetting(string yaml) { if (HandleSpawnData.Override != null && Helper.IsClient()) { Set(yaml); } } public static void Set(string yaml) { HandleSpawnData.Override = null; Loader.Data.Clear(); Loader.Objects.Clear(); if (yaml == "") { return; } try { List<SpawnData> list = (from d in Yaml.Deserialize<Data>(yaml, "Spawns") select Loader.FromData(d, "Spawns")).Where(IsValid).ToList(); if (list.Count == 0) { EWS.LogWarning("Failed to load any spawn data."); return; } EWS.LogInfo($"Reloading spawn data ({list.Count} entries)."); HandleSpawnData.Override = list; SpawnSystem.m_instances.ForEach(HandleSpawnData.Set); } catch (Exception ex) { EWS.LogError(ex.Message); EWS.LogError(ex.StackTrace); } } public static void SetupWatcher() { Yaml.SetupWatcher(Pattern, (Action)FromFile); } } [HarmonyPatch(typeof(ZoneSystem), "Start")] [HarmonyPriority(100)] public class InitializeContent { private static void Postfix() { HandleSpawnData.Override = null; if (Helper.IsServer()) { Manager.FromFile(); } } } [HarmonyPatch(typeof(SpawnSystem), "Awake")] public class HandleSpawnData { public static List<SpawnData>? Override; private static void Postfix(SpawnSystem __instance) { if (Override == null) { if (Helper.IsClient() && Configuration.valueSpawnData.Value != "") { Manager.Set(Configuration.valueSpawnData.Value); } if (Helper.IsServer()) { Manager.ToFile(); } } Set(__instance); } public static void Set(SpawnSystem system) { if (Override != null) { while (system.m_spawnLists.Count > 1) { system.m_spawnLists.RemoveAt(system.m_spawnLists.Count - 1); } system.m_spawnLists[0].m_spawners = Override; } } } [HarmonyPatch(typeof(ZoneSystem), "RPC_SetGlobalKey")] public class RPC_SetGlobalKey { private static void Prefix(ZoneSystem __instance, ref string name) { string text = default(string); GlobalKeys val = default(GlobalKeys); string keyValue = ZoneSystem.GetKeyValue(name.ToLower(), ref text, ref val); int result3; if (text.StartsWith("--", StringComparison.OrdinalIgnoreCase)) { if (int.TryParse(text.Substring(2), out var result)) { string s = default(string); if (__instance.GetGlobalKey(keyValue, ref s) && int.TryParse(s, out var result2)) { name = $"{keyValue} {result2 - result}"; } else { name = $"{keyValue} -{result}"; } } } else if (text.StartsWith("++", StringComparison.OrdinalIgnoreCase) && int.TryParse(text.Substring(2), out result3)) { string s2 = default(string); if (__instance.GetGlobalKey(keyValue, ref s2) && int.TryParse(s2, out var result4)) { name = $"{keyValue} {result4 + result3}"; } else { name = $"{keyValue} {result3}"; } } } } [HarmonyPatch(typeof(ZoneSystem), "GetGlobalKey", new Type[] { typeof(string) })] public class GetGlobalKey { private static bool Prefix(ZoneSystem __instance, string name, ref bool __result) { string[] array = name.Trim().Split(new char[1] { ' ' }); if (array.Length < 2) { return true; } if (!int.TryParse(array[1], out var result)) { return true; } __result = HasKey(__instance, array[0].ToLower(), result); return false; } private static bool HasKey(ZoneSystem zs, string requiredKey, int requiredValue) { if (!zs.m_globalKeysValues.TryGetValue(requiredKey, out var value)) { return false; } if (!int.TryParse(value, out var result)) { return false; } return result >= requiredValue; } } [HarmonyPatch(typeof(SpawnSystem), "Spawn")] public class Spawn { private static void Postfix(SpawnData critter) { if (!string.IsNullOrEmpty(critter.m_requiredGlobalKey)) { string[] array = critter.m_requiredGlobalKey.Trim().Split(new char[1] { ' ' }); if (array.Length >= 2 && int.TryParse(array[1], out var result)) { ZoneSystem.instance.SetGlobalKey($"{array[0]} --{result}"); } } } } public class Data { public string prefab = ""; public bool enabled = true; [DefaultValue("")] public string name = ""; [DefaultValue("")] public string biome = ""; [DefaultValue("")] public string biomeArea = ""; [DefaultValue(100f)] public float spawnChance = 100f; public int maxSpawned = 1; public float spawnInterval; [DefaultValue(1)] public int maxLevel = 1; [DefaultValue(1)] public int minLevel = 1; [DefaultValue(-10000f)] public float minAltitude = -10000f; [DefaultValue(10000f)] public float maxAltitude = 10000f; [DefaultValue(true)] public bool spawnAtDay = true; [DefaultValue(true)] public bool spawnAtNight = true; [DefaultValue("")] public string requiredGlobalKey = ""; [DefaultValue("")] public string requiredEnvironments = ""; public float spawnDistance = 10f; [DefaultValue(0f)] public float spawnRadiusMin; [DefaultValue(0f)] public float spawnRadiusMax; [DefaultValue(1)] public int groupSizeMin = 1; [DefaultValue(1)] public int groupSizeMax = 1; [DefaultValue(0f)] public float groupRadius; [DefaultValue(0f)] public float minTilt; [DefaultValue(35f)] public float maxTilt = 35f; [DefaultValue(true)] public bool inForest = true; [DefaultValue(true)] public bool outsideForest = true; [DefaultValue(false)] public bool canSpawnCloseToPlayer; [DefaultValue(false)] public bool insidePlayerBase; [DefaultValue(false)] public bool inLava; [DefaultValue(true)] public bool outsideLava = true; [DefaultValue(0f)] public float minOceanDepth; [DefaultValue(0f)] public float maxOceanDepth; [DefaultValue(false)] public bool huntPlayer; [DefaultValue(0.5f)] public float groundOffset = 0.5f; [DefaultValue(0f)] public float groundOffsetRandom; [DefaultValue(0f)] public float levelUpMinCenterDistance; [DefaultValue(-1f)] public float overrideLevelupChance = -1f; [DefaultValue(0f)] public float minDistance; [DefaultValue(0f)] public float maxDistance; [DefaultValue(null)] public string[]? objects; [DefaultValue(null)] public string? data; [DefaultValue(null)] public string? faction; [DefaultValue(null)] public Dictionary<string, string>? fields; } }