Please disclose if any significant portion of your mod was created 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.18.0
ExpandWorldSpawns.dll
Decompiled 3 days agousing System; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Logging; using Data; using ExpandWorld.Drops; 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+4ae2dacd0ae6e515265ce2a571b07aa18d476619")] [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] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [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] [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] [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 CustomSyncedValue<string> valueDropData; public static void Init(ConfigWrapper wrapper) { valueSpawnData = wrapper.AddValue("spawn_data"); ((CustomSyncedValueBase)valueSpawnData).ValueChanged += delegate { ExpandWorld.Spawn.Manager.FromSetting(valueSpawnData.Value); }; valueDropData = wrapper.AddValue("drop_data"); ((CustomSyncedValueBase)valueDropData).ValueChanged += delegate { ExpandWorld.Drops.Loader.Set(valueDropData.Value); }; } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] public class SetCommands { [CompilerGenerated] private static class <>O { public static ConsoleOptionsFetcher <0>__GetSpawnNames; } [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static ConsoleEvent <>9__0_0; public static ConsoleEvent <>9__0_1; public static ConsoleEvent <>9__0_2; public static ConsoleEvent <>9__0_3; internal void <Postfix>b__0_0(ConsoleEventArgs args) { ExpandWorld.Spawn.Manager.Save(); } internal void <Postfix>b__0_1(ConsoleEventArgs args) { ReferenceFileGenerator.Save(); } internal void <Postfix>b__0_2(ConsoleEventArgs args) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) SpawnSystem closestSpawnSystem = GetClosestSpawnSystem(args.Context); if (Object.op_Implicit((Object)(object)closestSpawnSystem)) { closestSpawnSystem.m_nview.ClaimOwnership(); SpawnData val = FindSpawn(args.Context, closestSpawnSystem, args.ArgsAll); if (val != null) { closestSpawnSystem.Spawn(val, ((Component)Player.m_localPlayer).transform.position, false); } } } internal void <Postfix>b__0_3(ConsoleEventArgs args) { SpawnSystem closestSpawnSystem = GetClosestSpawnSystem(args.Context); if (Object.op_Implicit((Object)(object)closestSpawnSystem)) { closestSpawnSystem.m_nview.ClaimOwnership(); SpawnData val = FindSpawn(args.Context, closestSpawnSystem, args.ArgsAll); if (val != null) { originalSpawnData.canSpawnCloseToPlayer = val.m_canSpawnCloseToPlayer; originalSpawnData.spawnRadiusMin = val.m_spawnRadiusMin; originalSpawnData.spawnRadiusMax = val.m_spawnRadiusMax; originalSpawnData.spawnInterval = val.m_spawnInterval; val.m_canSpawnCloseToPlayer = true; val.m_spawnRadiusMin = 0.01f; val.m_spawnRadiusMax = 0.01f; val.m_spawnInterval = 0.01f; closestSpawnSystem.UpdateSpawning(); val.m_canSpawnCloseToPlayer = originalSpawnData.canSpawnCloseToPlayer; val.m_spawnRadiusMin = originalSpawnData.spawnRadiusMin; val.m_spawnRadiusMax = originalSpawnData.spawnRadiusMax; val.m_spawnInterval = originalSpawnData.spawnInterval; } } } } private static OriginalSpawnData originalSpawnData; private static void Postfix() { //IL_0033: 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 //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0062: Expected O, but got Unknown //IL_0090: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009b: Expected O, but got Unknown //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00b1: Unknown result type (might be due to invalid IL or missing references) //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bc: Expected O, but got Unknown //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00e8: Unknown result type (might be due to invalid IL or missing references) //IL_00ee: Expected O, but got Unknown //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0104: Unknown result type (might be due to invalid IL or missing references) //IL_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate { ExpandWorld.Spawn.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, false, (ConsoleOptionsFetcher)null, false, false, false); object obj2 = <>c.<>9__0_1; if (obj2 == null) { ConsoleEvent val2 = delegate { ReferenceFileGenerator.Save(); }; <>c.<>9__0_1 = val2; obj2 = (object)val2; } new ConsoleCommand("ew_drops", "Forces drop file creation.", (ConsoleEvent)obj2, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); object obj3 = <>c.<>9__0_2; if (obj3 == null) { ConsoleEvent val3 = delegate(ConsoleEventArgs args) { //IL_0043: Unknown result type (might be due to invalid IL or missing references) SpawnSystem closestSpawnSystem = GetClosestSpawnSystem(args.Context); if (Object.op_Implicit((Object)(object)closestSpawnSystem)) { closestSpawnSystem.m_nview.ClaimOwnership(); SpawnData val7 = FindSpawn(args.Context, closestSpawnSystem, args.ArgsAll); if (val7 != null) { closestSpawnSystem.Spawn(val7, ((Component)Player.m_localPlayer).transform.position, false); } } }; <>c.<>9__0_2 = val3; obj3 = (object)val3; } object obj4 = <>O.<0>__GetSpawnNames; if (obj4 == null) { ConsoleOptionsFetcher val4 = GetSpawnNames; <>O.<0>__GetSpawnNames = val4; obj4 = (object)val4; } new ConsoleCommand("ew_test_spawn", "Spawns a creature from spawn system by entry name.", (ConsoleEvent)obj3, true, false, false, false, false, false, (ConsoleOptionsFetcher)obj4, false, false, false); object obj5 = <>c.<>9__0_3; if (obj5 == null) { ConsoleEvent val5 = delegate(ConsoleEventArgs args) { SpawnSystem closestSpawnSystem = GetClosestSpawnSystem(args.Context); if (Object.op_Implicit((Object)(object)closestSpawnSystem)) { closestSpawnSystem.m_nview.ClaimOwnership(); SpawnData val7 = FindSpawn(args.Context, closestSpawnSystem, args.ArgsAll); if (val7 != null) { originalSpawnData.canSpawnCloseToPlayer = val7.m_canSpawnCloseToPlayer; originalSpawnData.spawnRadiusMin = val7.m_spawnRadiusMin; originalSpawnData.spawnRadiusMax = val7.m_spawnRadiusMax; originalSpawnData.spawnInterval = val7.m_spawnInterval; val7.m_canSpawnCloseToPlayer = true; val7.m_spawnRadiusMin = 0.01f; val7.m_spawnRadiusMax = 0.01f; val7.m_spawnInterval = 0.01f; closestSpawnSystem.UpdateSpawning(); val7.m_canSpawnCloseToPlayer = originalSpawnData.canSpawnCloseToPlayer; val7.m_spawnRadiusMin = originalSpawnData.spawnRadiusMin; val7.m_spawnRadiusMax = originalSpawnData.spawnRadiusMax; val7.m_spawnInterval = originalSpawnData.spawnInterval; } } }; <>c.<>9__0_3 = val5; obj5 = (object)val5; } object obj6 = <>O.<0>__GetSpawnNames; if (obj6 == null) { ConsoleOptionsFetcher val6 = GetSpawnNames; <>O.<0>__GetSpawnNames = val6; obj6 = (object)val6; } new ConsoleCommand("ew_try_spawn", "Attempts to spawn a creature from spawn system by entry name.", (ConsoleEvent)obj5, true, false, false, false, false, false, (ConsoleOptionsFetcher)obj6, false, false, false); } private static List<string> GetSpawnNames() { SpawnSystem closestSpawnSystem = GetClosestSpawnSystem(); if (!Object.op_Implicit((Object)(object)closestSpawnSystem)) { return new List<string>(); } List<string> list = new List<string>(); foreach (SpawnSystemList spawnList in closestSpawnSystem.m_spawnLists) { foreach (SpawnData spawner in spawnList.m_spawners) { list.Add(spawner.m_name); } } return list; } private static SpawnSystem? GetClosestSpawnSystem(Terminal? context = null) { //IL_002d: 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) if (!Object.op_Implicit((Object)(object)Player.m_localPlayer)) { if (context != null) { context.AddString("Player not found."); } return null; } Vector3 pos = ((Component)Player.m_localPlayer).transform.position; SpawnSystem val = SpawnSystem.m_instances.OrderBy((SpawnSystem s) => Vector3.Distance(((Component)s).transform.position, pos)).FirstOrDefault(); if (!Object.op_Implicit((Object)(object)val)) { if (context != null) { context.AddString("No spawn system found nearby."); } return null; } return val; } private static SpawnData? FindSpawn(Terminal context, SpawnSystem ss, string name) { foreach (SpawnSystemList spawnList in ss.m_spawnLists) { foreach (SpawnData spawner in spawnList.m_spawners) { if (spawner.m_name.Equals(name, StringComparison.OrdinalIgnoreCase)) { return spawner; } } } context.AddString("Spawn '" + name + "' not found in closest spawn system."); return null; } } public struct OriginalSpawnData { public bool canSpawnCloseToPlayer; public float spawnRadiusMin; public float spawnRadiusMax; public float spawnInterval; } [BepInPlugin("expand_world_spawns", "Expand World Spawns", "1.18")] [BepInDependency("expand_world_data", "1.71")] public class EWS : BaseUnityPlugin { public const string GUID = "expand_world_spawns"; public const string NAME = "Expand World Spawns"; public const string VERSION = "1.18"; public static ManualLogSource Log; public static ConfigSync ConfigSync = new ConfigSync("expand_world_spawns") { DisplayName = "Expand World Spawns", CurrentVersion = "1.18", 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) { ExpandWorld.Spawn.Manager.SetupWatcher(); ExpandWorld.Drops.Loader.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 SpawnData val = new SpawnData { m_prefab = DataManager.ToPrefab(data.prefab, fileName), m_name = data.name, m_enabled = data.enabled, m_biome = DataManager.ToBiomes(data.biome, fileName), m_biomeArea = DataManager.ToBiomeAreas(data.biomeArea, fileName), 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, fileName); } 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<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] : "", fileName), 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, ZDOVars.s_health, ZDOVars.s_maxHealth, ZDOVars.s_noise, ZDOVars.s_scaleScalarHash }; private static readonly HashSet<int> KnownInts = new HashSet<int> { ZDOVars.s_level, ZDOVars.s_seed, ZDOVars.s_lovePoints }; private static readonly HashSet<int> KnownLongs = new HashSet<int> { ZDOVars.s_spawnTime, ZDOVars.s_worldTimeHash, ZDOVars.s_pregnant }; private static readonly HashSet<int> KnownBools = new HashSet<int> { 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<int> KnownVecs = new HashSet<int> { ZDOVars.s_bodyVelocity, ZDOVars.s_spawnPoint, ZDOVars.s_patrolPoint, ZDOVars.s_scaleHash }; private static readonly HashSet<int> KnownStrings = new HashSet<int> { 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_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0098: 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.drops != null) { if (val == null) { val = new DataEntry(); } DataEntry val2 = val; if (val2.Hashes == null) { val2.Hashes = new Dictionary<int, IHashValue>(); } val.Hashes[ExpandWorld.Drops.Manager.HashDrop] = DataValue.Hash(data.drops); } 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.Float(field.Value); continue; } if (KnownInts.Contains(num)) { DataEntry val2 = val; if (val2.Ints == null) { val2.Ints = new Dictionary<int, IIntValue>(); } val.Ints[num] = DataValue.Int(field.Value); continue; } if (KnownLongs.Contains(num)) { DataEntry val2 = val; if (val2.Longs == null) { val2.Longs = new Dictionary<int, ILongValue>(); } val.Longs[num] = DataValue.Long(field.Value); continue; } if (KnownBools.Contains(num)) { DataEntry val2 = val; if (val2.Bools == null) { val2.Bools = new Dictionary<int, IBoolValue>(); } val.Bools[num] = DataValue.Bool(field.Value); continue; } if (KnownVecs.Contains(num)) { DataEntry val2 = val; if (val2.Vecs == null) { val2.Vecs = new Dictionary<int, IVector3Value>(); } val.Vecs[num] = DataValue.Vector3(field.Value); continue; } if (KnownStrings.Contains(num)) { DataEntry val2 = val; if (val2.Strings == null) { val2.Strings = new Dictionary<int, IStringValue>(); } 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<int, IIntValue>(); } val.Ints[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Int(field.Value); break; } case "float": { DataEntry val2 = val; if (val2.Floats == null) { val2.Floats = new Dictionary<int, IFloatValue>(); } val.Floats[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Float(field.Value); break; } case "bool": { DataEntry val2 = val; if (val2.Bools == null) { val2.Bools = new Dictionary<int, IBoolValue>(); } val.Bools[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Bool(field.Value); break; } case "vec": { DataEntry val2 = val; if (val2.Vecs == null) { val2.Vecs = new Dictionary<int, IVector3Value>(); } val.Vecs[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Vector3(field.Value); break; } case "quat": { DataEntry val2 = val; if (val2.Quats == null) { val2.Quats = new Dictionary<int, IQuaternionValue>(); } val.Quats[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Quaternion(field.Value); break; } case "string": { DataEntry val2 = val; if (val2.Strings == null) { val2.Strings = new Dictionary<int, IStringValue>(); } val.Strings[StringExtensionMethods.GetStableHashCode(array[1])] = DataValue.Simple(field.Value); break; } default: if (!dictionary2.ContainsKey(text)) { dictionary2[text] = new Dictionary<string, string>(); } 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<string, Dictionary<string, string>> componentFields, Dictionary<string, string> otherFields) { spawn.m_prefab.GetComponentsInChildren<MonoBehaviour>(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<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) { 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.Int(value); } else if (info.FieldType == typeof(float)) { val = customData; if (val.Floats == null) { val.Floats = new Dictionary<int, IFloatValue>(); } customData.Floats[stableHashCode] = DataValue.Float(value); } else if (info.FieldType == typeof(bool)) { val = customData; if (val.Bools == null) { val.Bools = new Dictionary<int, IBoolValue>(); } customData.Bools[stableHashCode] = DataValue.Bool(value); } else if (info.FieldType == typeof(Vector3)) { val = customData; if (val.Vecs == null) { val.Vecs = new Dictionary<int, IVector3Value>(); } customData.Vecs[stableHashCode] = DataValue.Vector3(value); } else if (info.FieldType == typeof(Quaternion)) { val = customData; if (val.Quats == null) { val.Quats = new Dictionary<int, IQuaternionValue>(); } customData.Quats[stableHashCode] = DataValue.Quaternion(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 drops = ""; [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; } } namespace ExpandWorld.Drops { public class Data { public string name = ""; [DefaultValue(1)] public int minAmount = 1; [DefaultValue(1)] public int maxAmount = 1; [DefaultValue(1f)] public float chance = 1f; [DefaultValue(false)] public bool oneOfEach; [DefaultValue("")] public string biome = ""; [DefaultValue("")] public string biomeArea = ""; [DefaultValue("")] public string log = ""; [DefaultValue("")] public string stump = ""; internal Biome biomes; internal BiomeArea biomeAreas; internal GameObject? logObj; internal GameObject? stumpObj; internal bool logNone; internal bool stumpNone; public DropEntry[] drops = Array.Empty<DropEntry>(); } public class DropEntry { public string prefab = ""; internal GameObject? obj; internal ItemDrop? item; [DefaultValue(1)] public int minAmount = 1; [DefaultValue(1)] public int maxAmount = 1; [DefaultValue(1f)] public float chance = 1f; [DefaultValue(false)] public bool onePerPlayer; [DefaultValue(false)] public bool levelMultiplier; [DefaultValue(1)] public int minStack = 1; [DefaultValue(1)] public int maxStack = 1; [DefaultValue(1f)] public float weight = 1f; [DefaultValue(1)] public int amount = 1; [DefaultValue(true)] public bool recover = true; [DefaultValue(false)] public bool dontScale; [DefaultValue("")] public string biome = ""; [DefaultValue("")] public string biomeArea = ""; internal Biome biomes; internal BiomeArea biomeAreas; } public class Loader { public static string ReferenceFileName = "ref_expand_drops.yaml"; public static string ReferenceFilePath = Path.Combine(Yaml.Directory, ReferenceFileName); public static string FileName = "expand_drops.yaml"; public static string FilePath = Path.Combine(Yaml.Directory, FileName); public static string Pattern = "expand_drops*.yaml"; public static void Initialize() { ToReferenceFile(); ToFile(); FromFile(); } public static void ToReferenceFile() { if (!Helper.IsClient() && !File.Exists(ReferenceFilePath)) { ReferenceFileGenerator.Save(); } } public static void ToFile() { if (!Helper.IsClient() && !File.Exists(FilePath)) { string contents = "# Drop data. See reference file for examples."; File.WriteAllText(FilePath, contents); } } public static void FromFile() { if (!Helper.IsClient()) { string value = DataManager.Read<Data, Data>(Pattern, (Func<Data, string, Data>)FromData); Configuration.valueDropData.Value = value; } } public static Data FromData(Data data, string fileName) { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000d: 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_001f: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: 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) data.biomes = DataManager.ToBiomes(data.biome, fileName); data.biomeAreas = DataManager.ToBiomeAreas(data.biomeArea, fileName); if (data.log.Equals("none", StringComparison.OrdinalIgnoreCase)) { data.logNone = true; } else if (data.log != "") { data.logObj = DataManager.ToPrefab(data.log, fileName); } if (data.stump.Equals("none", StringComparison.OrdinalIgnoreCase)) { data.stumpNone = true; } else if (data.stump != "") { data.stumpObj = DataManager.ToPrefab(data.stump, fileName); } DropEntry[] drops = data.drops; foreach (DropEntry dropEntry in drops) { dropEntry.obj = DataManager.ToPrefab(dropEntry.prefab, fileName); if (Object.op_Implicit((Object)(object)dropEntry.obj)) { dropEntry.item = dropEntry.obj.GetComponent<ItemDrop>(); } dropEntry.biomes = DataManager.ToBiomes(dropEntry.biome, fileName); dropEntry.biomeAreas = DataManager.ToBiomeAreas(dropEntry.biomeArea, fileName); } return data; } public static bool IsValid(Data data) { if (data.drops.All((DropEntry d) => (Object)(object)d.obj != (Object)null) && (data.log == "" || data.logNone || (Object)(object)data.logObj != (Object)null)) { if (!(data.stump == "") && !data.stumpNone) { return (Object)(object)data.stumpObj != (Object)null; } return true; } return false; } public static void Set(string yaml) { Manager.DataByHash.Clear(); Manager.DataByName.Clear(); if (yaml == "") { return; } try { List<Data> list = (from d in Yaml.Deserialize<Data>(yaml, "Drops") select FromData(d, "Drops")).Where(IsValid).ToList(); if (list.Count == 0) { return; } foreach (Data item in list) { Manager.Add(item); } EWS.LogInfo($"Reloading drop data ({list.Count} entries)."); } 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() { Loader.Initialize(); } } [HarmonyPatch] public class Manager { public static readonly int HashDrop = StringExtensionMethods.GetStableHashCode("ews_drops"); public static Dictionary<int, Data> DataByHash = new Dictionary<int, Data>(); public static Dictionary<string, Data> DataByName = new Dictionary<string, Data>(); public static bool Matches(Biome biomes, BiomeArea areas, Vector3 pos) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: 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_0012: 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) //IL_0018: 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_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) Biome biome = WorldGenerator.instance.GetBiome(pos); BiomeArea biomeArea = WorldGenerator.instance.GetBiomeArea(pos); if (((Enum)biomes).HasFlag((Enum)(object)biome)) { return ((Enum)areas).HasFlag((Enum)(object)biomeArea); } return false; } public static void Add(Data data) { int stableHashCode = StringExtensionMethods.GetStableHashCode(data.name); DataByHash[stableHashCode] = data; DataByName[data.name] = data; } public static bool TryGetData(ZNetView view, out Data data) { if (!Object.op_Implicit((Object)(object)view)) { data = null; return false; } ZDO zDO = view.GetZDO(); if (zDO == null) { data = null; return false; } return TryGetData(zDO, out data); } public static bool TryGetData(ZDO zDO, out Data data) { data = null; if (zDO == null) { return false; } int num = zDO.GetInt(HashDrop, 0); if (num != 0) { return DataByHash.TryGetValue(num, out data); } string text = zDO.GetString(HashDrop, ""); if (text != "") { return DataByName.TryGetValue(text, out data); } return false; } } [HarmonyPatch] public static class CharacterDropPatches { [HarmonyPatch(typeof(CharacterDrop), "GenerateDropList")] [HarmonyPrefix] private static void CharacterDropGenerateDropList(CharacterDrop __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_character.m_nview, out Data data)) { Apply(__instance, data, ((Component)__instance).transform.position); } } private static void Apply(CharacterDrop drop, Data data, Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) if (Manager.Matches(data.biomes, data.biomeAreas, pos)) { List<Drop> list = new List<Drop>(); list.AddRange(data.drops.Where((DropEntry d) => Manager.Matches(d.biomes, d.biomeAreas, pos)).Select((Func<DropEntry, Drop>)((DropEntry d) => new Drop { m_prefab = d.obj, m_chance = d.chance, m_amountMax = d.maxAmount, m_amountMin = d.minAmount, m_dontScale = d.dontScale, m_onePerPlayer = d.onePerPlayer, m_levelMultiplier = d.levelMultiplier }))); drop.m_drops = list; } } } [HarmonyPatch] public static class PieceRequirementPatches { [HarmonyPatch(typeof(Piece), "DropResources")] [HarmonyPrefix] private static void PieceDropResources(Piece __instance) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance, data, ((Component)__instance).transform.position); } } private static void Apply(Piece piece, Data data, Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) if (Manager.Matches(data.biomes, data.biomeAreas, pos)) { List<Requirement> list = new List<Requirement>(); list.AddRange(data.drops.Where((DropEntry d) => (Object)(object)d.item != (Object)null && Manager.Matches(d.biomes, d.biomeAreas, pos)).Select((Func<DropEntry, Requirement>)((DropEntry d) => new Requirement { m_amount = Random.Range(d.minAmount, d.maxAmount + 1), m_resItem = d.item, m_amountPerLevel = 0, m_recover = true, m_extraAmountOnlyOneIngredient = 0 }))); piece.m_resources = list.ToArray(); } } } [HarmonyPatch] public static class DropTablePatches { [HarmonyPatch(typeof(Container), "AddDefaultItems")] [HarmonyPrefix] private static void ContainerAddDefaultItems(Container __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance.m_defaultItems, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(FishingFloat), "Catch")] [HarmonyPrefix] private static void FishingFloatCatch(Fish fish) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(fish.m_nview, out Data data)) { Apply(fish.m_extraDrops, data, ((Component)fish).transform.position); } } [HarmonyPatch(typeof(Pickable), "RPC_Pick")] [HarmonyPrefix] private static void PickableRPC_Pick(Pickable __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance.m_extraDrops, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(DropOnDestroyed), "OnDestroyed")] [HarmonyPrefix] private static void DropOnDestroyedOnDestroyed(DropOnDestroyed __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(((Component)__instance).GetComponent<ZNetView>(), out Data data)) { Apply(__instance.m_dropWhenDestroyed, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(LootSpawner), "UpdateSpawner")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> LootSpawnerUpdateSpawner(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(LootSpawner), "m_items"), (string)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DropTablePatches), "ApplyDrops", new Type[1] { typeof(LootSpawner) }, (Type[])null)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InstructionEnumeration(); } private static void ApplyDrops(LootSpawner __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance.m_items, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(MineRock), "RPC_Hit")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> MineRockRPC_Hit(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(MineRock), "m_dropItems"), (string)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DropTablePatches), "ApplyDrops", new Type[1] { typeof(MineRock) }, (Type[])null)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InstructionEnumeration(); } private static void ApplyDrops(MineRock __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance.m_dropItems, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(MineRock5), "DamageArea")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> MineRock5DamageArea(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(MineRock5), "m_dropItems"), (string)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DropTablePatches), "ApplyDrops", new Type[1] { typeof(MineRock5) }, (Type[])null)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InstructionEnumeration(); } private static void ApplyDrops(MineRock5 __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance.m_dropItems, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(TreeBase), "RPC_Damage")] [HarmonyTranspiler] private static IEnumerable<CodeInstruction> TreeBaseRPC_Damage(IEnumerable<CodeInstruction> instructions) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Expected O, but got Unknown //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Expected O, but got Unknown return new CodeMatcher(instructions, (ILGenerator)null).MatchForward(false, (CodeMatch[])(object)new CodeMatch[1] { new CodeMatch((OpCode?)OpCodes.Ldfld, (object)AccessTools.Field(typeof(TreeBase), "m_dropWhenDestroyed"), (string)null) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Call, (object)AccessTools.Method(typeof(DropTablePatches), "ApplyDrops", new Type[1] { typeof(TreeBase) }, (Type[])null)) }).InsertAndAdvance((CodeInstruction[])(object)new CodeInstruction[1] { new CodeInstruction(OpCodes.Ldarg_0, (object)null) }) .InstructionEnumeration(); } private static void ApplyDrops(TreeBase __instance) { //IL_001d: Unknown result type (might be due to invalid IL or missing references) if (Manager.TryGetData(__instance.m_nview, out Data data)) { Apply(__instance.m_dropWhenDestroyed, data, ((Component)__instance).transform.position); } } [HarmonyPatch(typeof(TreeBase), "SpawnLog")] [HarmonyPrefix] private static bool TreeBaseSpawnLog(TreeBase __instance) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0018: 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) if (!Manager.TryGetData(__instance.m_nview, out Data data)) { return true; } if (!Manager.Matches(data.biomes, data.biomeAreas, ((Component)__instance).transform.position)) { return true; } if (data.logNone) { return false; } if ((Object)(object)data.logObj != (Object)null) { __instance.m_logPrefab = data.logObj; } if (data.stumpNone) { __instance.m_stubPrefab = null; } else if ((Object)(object)data.stumpObj != (Object)null) { __instance.m_stubPrefab = data.stumpObj; } return true; } [HarmonyPatch(typeof(TreeLog), "Destroy")] [HarmonyPrefix] private static void TreeLogDestroy(TreeLog __instance) { //IL_0011: 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) //IL_0022: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) if (!Manager.TryGetData(__instance.m_nview, out Data data)) { return; } if (Manager.Matches(data.biomes, data.biomeAreas, ((Component)__instance).transform.position)) { if (data.logNone) { __instance.m_subLogPrefab = null; } else if ((Object)(object)data.logObj != (Object)null) { __instance.m_subLogPrefab = data.logObj; } } Apply(__instance.m_dropWhenDestroyed, data, ((Component)__instance).transform.position); } private static void Apply(DropTable dropTable, Data data, Vector3 pos) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: 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) if (Manager.Matches(data.biomes, data.biomeAreas, pos)) { dropTable.m_dropChance = data.chance; dropTable.m_oneOfEach = data.oneOfEach; dropTable.m_dropMax = data.maxAmount; dropTable.m_dropMin = data.minAmount; List<DropData> list = new List<DropData>(); list.AddRange(data.drops.Where((DropEntry d) => Manager.Matches(d.biomes, d.biomeAreas, pos)).Select((Func<DropEntry, DropData>)((DropEntry d) => new DropData { m_dontScale = d.dontScale, m_item = d.obj, m_stackMax = d.maxStack, m_stackMin = d.minStack, m_weight = d.weight }))); dropTable.m_drops = list; } } } public static class ReferenceFileGenerator { public static string Save() { ZNetScene instance = ZNetScene.instance; if ((Object)(object)instance == (Object)null) { EWS.LogWarning("Failed to create drop reference data: ZNetScene not initialized."); return ""; } List<Data> list = (from entry in instance.m_namedPrefabs.Values.Where((GameObject prefab) => (Object)(object)prefab != (Object)null).Select(ToData) where entry != null select (entry) into entry orderby entry.name select entry).ToList(); string text = Yaml.Serializer().Serialize((object)list); File.WriteAllText(Loader.ReferenceFilePath, text); EWS.LogInfo($"Regenerated drop reference file ({list.Count} entries)."); return text; } private static Data? ToData(GameObject prefab) { CharacterDrop component = prefab.GetComponent<CharacterDrop>(); if ((Object)(object)component != (Object)null) { return ToCharacterDropData(((Object)prefab).name, component); } Piece component2 = prefab.GetComponent<Piece>(); if ((Object)(object)component2 != (Object)null) { return ToPieceData(((Object)prefab).name, component2); } TreeBase component3 = prefab.GetComponent<TreeBase>(); if ((Object)(object)component3 != (Object)null) { return ToTreeBaseData(((Object)prefab).name, component3); } TreeLog component4 = prefab.GetComponent<TreeLog>(); if ((Object)(object)component4 != (Object)null) { return ToTreeLogData(((Object)prefab).name, component4); } if (TryGetDropTable(prefab, out DropTable table)) { return ToDropTableData(((Object)prefab).name, table); } return null; } private static bool TryGetDropTable(GameObject prefab, out DropTable table) { Container component = prefab.GetComponent<Container>(); if ((Object)(object)component != (Object)null && component.m_defaultItems != null) { table = component.m_defaultItems; return true; } Fish component2 = prefab.GetComponent<Fish>(); if ((Object)(object)component2 != (Object)null && component2.m_extraDrops != null) { table = component2.m_extraDrops; return true; } Pickable component3 = prefab.GetComponent<Pickable>(); if ((Object)(object)component3 != (Object)null && component3.m_extraDrops != null) { table = component3.m_extraDrops; return true; } DropOnDestroyed component4 = prefab.GetComponent<DropOnDestroyed>(); if ((Object)(object)component4 != (Object)null && component4.m_dropWhenDestroyed != null) { table = component4.m_dropWhenDestroyed; return true; } LootSpawner component5 = prefab.GetComponent<LootSpawner>(); if ((Object)(object)component5 != (Object)null && component5.m_items != null) { table = component5.m_items; return true; } MineRock component6 = prefab.GetComponent<MineRock>(); if ((Object)(object)component6 != (Object)null && component6.m_dropItems != null) { table = component6.m_dropItems; return true; } MineRock5 component7 = prefab.GetComponent<MineRock5>(); if ((Object)(object)component7 != (Object)null && component7.m_dropItems != null) { table = component7.m_dropItems; return true; } table = null; return false; } private static Data ToCharacterDropData(string name, CharacterDrop characterDrop) { Data obj = new Data { name = name }; List<DropEntry> list = new List<DropEntry>(); list.AddRange(from drop in characterDrop.m_drops where (Object)(object)drop?.m_prefab != (Object)null select new DropEntry { prefab = ((Object)drop.m_prefab).name, chance = drop.m_chance, minAmount = drop.m_amountMin, maxAmount = drop.m_amountMax, dontScale = drop.m_dontScale, onePerPlayer = drop.m_onePerPlayer, levelMultiplier = drop.m_levelMultiplier }); obj.drops = list.ToArray(); return obj; } private static Data ToPieceData(string name, Piece piece) { Data obj = new Data { name = name }; List<DropEntry> list = new List<DropEntry>(); list.AddRange(from requirement in piece.m_resources where (Object)(object)requirement?.m_resItem != (Object)null select new DropEntry { prefab = ((Object)requirement.m_resItem).name, minAmount = requirement.m_amount, maxAmount = requirement.m_amount, recover = requirement.m_recover }); obj.drops = list.ToArray(); return obj; } private static Data ToDropTableData(string name, DropTable? table) { if (table == null) { return new Data { name = name }; } Data obj = new Data { name = name, chance = table.m_dropChance, oneOfEach = table.m_oneOfEach, minAmount = table.m_dropMin, maxAmount = table.m_dropMax }; List<DropEntry> list = new List<DropEntry>(); list.AddRange(from drop in table.m_drops where (Object)(object)drop.m_item != (Object)null select new DropEntry { prefab = ((Object)drop.m_item).name, dontScale = drop.m_dontScale, minStack = drop.m_stackMin, maxStack = drop.m_stackMax, weight = drop.m_weight }); obj.drops = list.ToArray(); return obj; } private static Data ToTreeBaseData(string name, TreeBase treeBase) { Data data = ToDropTableData(name, treeBase.m_dropWhenDestroyed); data.log = (((Object)(object)treeBase.m_logPrefab != (Object)null) ? ((Object)treeBase.m_logPrefab).name : "none"); data.stump = (((Object)(object)treeBase.m_stubPrefab != (Object)null) ? ((Object)treeBase.m_stubPrefab).name : "none"); return data; } private static Data ToTreeLogData(string name, TreeLog treeLog) { Data data = ToDropTableData(name, treeLog.m_dropWhenDestroyed); data.log = (((Object)(object)treeLog.m_subLogPrefab != (Object)null) ? ((Object)treeLog.m_subLogPrefab).name : "none"); return data; } } }