using 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+bdd81da9536ca25c514abdb7bcf9c070d75a9d24")] [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 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 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.16")] [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.16"; public static ManualLogSource Log; public static ConfigSync ConfigSync = new ConfigSync("expand_world_spawns") { DisplayName = "Expand World Spawns", CurrentVersion = "1.16", 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 Data = new Dictionary(); public static Dictionary> Objects = new Dictionary>(); 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(Data[val], val2); } else { Data.Add(val, val2); } } if (data.objects != null) { Dictionary> objects = Objects; List list = new List(); list.AddRange(data.objects.Select((string s) => Parse.Split(s, true, ',')).Select((Func)((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)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 value)) { return; } foreach (BlueprintObject item in value) { if (!(item.Chance < 1f) || !(Random.value > item.Chance)) { Spawn.BPO(item, spawnPoint, Quaternion.identity, Vector3.one, (Func)DataOverride, (Func)PrefabOverride, (List)null); } } } } public class LoaderFields { private static readonly int HashFaction = StringExtensionMethods.GetStableHashCode("faction"); private static readonly int HashDamage = StringExtensionMethods.GetStableHashCode("damage"); private static readonly HashSet KnownFloats = new HashSet { ZDOVars.s_randomSkillFactor, HashDamage, ZDOVars.s_health, ZDOVars.s_maxHealth, ZDOVars.s_noise }; private static readonly HashSet KnownInts = new HashSet { ZDOVars.s_level, ZDOVars.s_seed, ZDOVars.s_lovePoints }; private static readonly HashSet KnownLongs = new HashSet { ZDOVars.s_spawnTime, ZDOVars.s_worldTimeHash, ZDOVars.s_pregnant }; private static readonly HashSet KnownBools = new HashSet { StringExtensionMethods.GetStableHashCode("bosscount"), ZDOVars.s_isBlockingHash, ZDOVars.s_tamed, ZDOVars.s_aggravated, ZDOVars.s_alert, ZDOVars.s_shownAlertMessage, ZDOVars.s_huntPlayer, ZDOVars.s_patrol, ZDOVars.s_despawnInDay, ZDOVars.s_eventCreature, ZDOVars.s_sleeping, ZDOVars.s_haveSaddleHash }; private static readonly HashSet KnownVecs = new HashSet { ZDOVars.s_bodyVelocity, ZDOVars.s_spawnPoint, ZDOVars.s_patrolPoint }; private static readonly HashSet KnownStrings = new HashSet { ZDOVars.s_tamedName, ZDOVars.s_tamedNameAuthor }; 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(); } val.Strings[HashFaction] = DataValue.Simple(data.faction); } if (data.fields != null) { if (val == null) { val = new DataEntry(); } Dictionary dictionary = new Dictionary(); Dictionary> dictionary2 = new Dictionary>(); foreach (KeyValuePair 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(); } if (num == HashDamage) { num = ZDOVars.s_randomSkillFactor; } val.Floats[num] = DataValue.Float(field.Value); continue; } if (KnownInts.Contains(num)) { DataEntry val2 = val; if (val2.Ints == null) { val2.Ints = new Dictionary(); } val.Ints[num] = DataValue.Int(field.Value); continue; } if (KnownLongs.Contains(num)) { DataEntry val2 = val; if (val2.Longs == null) { val2.Longs = new Dictionary(); } val.Longs[num] = DataValue.Long(field.Value); continue; } if (KnownBools.Contains(num)) { DataEntry val2 = val; if (val2.Bools == null) { val2.Bools = new Dictionary(); } val.Bools[num] = DataValue.Bool(field.Value); continue; } if (KnownVecs.Contains(num)) { DataEntry val2 = val; if (val2.Vecs == null) { val2.Vecs = new Dictionary(); } val.Vecs[num] = DataValue.Vector3(field.Value); continue; } if (KnownStrings.Contains(num)) { DataEntry val2 = val; if (val2.Strings == null) { val2.Strings = new Dictionary(); } val.Strings[num] = DataValue.String(field.Value); continue; } string[] array = field.Key.Split(new char[1] { '.' }); if (array.Length > 1) { string text = array[0]; switch (text) { case "int": { DataEntry val2 = val; if (val2.Ints == null) { val2.Ints = new Dictionary(); } val.Ints[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Int(field.Value); break; } case "float": { DataEntry val2 = val; if (val2.Floats == null) { val2.Floats = new Dictionary(); } val.Floats[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Float(field.Value); break; } case "bool": { DataEntry val2 = val; if (val2.Bools == null) { val2.Bools = new Dictionary(); } val.Bools[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Bool(field.Value); break; } case "vec": { DataEntry val2 = val; if (val2.Vecs == null) { val2.Vecs = new Dictionary(); } val.Vecs[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Vector3(field.Value); break; } case "quat": { DataEntry val2 = val; if (val2.Quats == null) { val2.Quats = new Dictionary(); } val.Quats[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Quaternion(field.Value); break; } case "string": { DataEntry val2 = val; if (val2.Strings == null) { val2.Strings = new Dictionary(); } val.Strings[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Simple(field.Value); break; } default: if (!dictionary2.ContainsKey(text)) { dictionary2[text] = new Dictionary(); } dictionary2[text][array[1]] = field.Value; break; } } 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> componentFields, Dictionary otherFields) { spawn.m_prefab.GetComponentsInChildren(ZNetView.m_tempComponents); foreach (MonoBehaviour tempComponent in ZNetView.m_tempComponents) { Type type = ((object)tempComponent).GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public); foreach (FieldInfo fieldInfo in fields) { if (componentFields.TryGetValue(type.Name, out Dictionary 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) { int stableHashCode = StringExtensionMethods.GetStableHashCode(((object)component).GetType().Name + "." + info.Name); DataEntry val = customData; if (val.Ints == null) { val.Ints = new Dictionary(); } 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(); } customData.Ints[stableHashCode] = DataValue.Int(value); } else if (info.FieldType == typeof(float)) { val = customData; if (val.Floats == null) { val.Floats = new Dictionary(); } customData.Floats[stableHashCode] = DataValue.Float(value); } else if (info.FieldType == typeof(bool)) { val = customData; if (val.Bools == null) { val.Bools = new Dictionary(); } customData.Bools[stableHashCode] = DataValue.Bool(value); } else if (info.FieldType == typeof(Vector3)) { val = customData; if (val.Vecs == null) { val.Vecs = new Dictionary(); } customData.Vecs[stableHashCode] = DataValue.Vector3(value); } else if (info.FieldType == typeof(Quaternion)) { val = customData; if (val.Quats == null) { val.Quats = new Dictionary(); } customData.Quats[stableHashCode] = DataValue.Quaternion(value); } else { val = customData; if (val.Strings == null) { val.Strings = new Dictionary(); } 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 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(Pattern, (Func)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 list = (from d in Yaml.Deserialize(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? 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? fields; } }