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 RandomSpawnPointBruh v2.1.5
plugins/RandomSpawnPointBruh.dll
Decompiled 2 weeks ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Concurrent; using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics; using System.Globalization; using System.IO; using System.Linq; using System.Net.Http; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.RegularExpressions; using System.Threading; using System.Threading.Tasks; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using HarmonyLib; using JetBrains.Annotations; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using Microsoft.CodeAnalysis; using RandomSpawnPointBruh.Components; using RandomSpawnPointBruh.Configuration; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Controls; using UnityEngine.Networking; using UnityEngine.UI; using Valheim.SettingsGui; using Vapok.Common.Abstractions; using Vapok.Common.Managers; using Vapok.Common.Managers.Configuration; using Vapok.Common.Managers.Creature; using Vapok.Common.Managers.LocalizationManager; using Vapok.Common.Managers.Location; using Vapok.Common.Managers.PieceManager; using Vapok.Common.Managers.Skill; using Vapok.Common.Managers.Splash; using Vapok.Common.Managers.StatusEffects; using Vapok.Common.Managers.Telemetry; using Vapok.Common.Shared; using Vapok.Common.Tools; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("RandomSpawnPointBruh")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("RandomSpawnPointBruh")] [assembly: AssemblyCopyright("Copyright © Vapok Modding 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("997CB563-FCC7-44B7-8F71-069747D27CC5")] [assembly: AssemblyFileVersion("2.1.5.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("2.1.5.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [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 RandomSpawnPointBruh { [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInPlugin("vapok.mods.RandomSpawnPointBruh", "RandomSpawnPointBruh", "2.1.5")] [SynchronizationMode(/*Could not decode attribute arguments.*/)] public class RandomSpawnPointBruh : BaseUnityPlugin, IPluginInfo { private const string _pluginId = "vapok.mods.RandomSpawnPointBruh"; private const string _displayName = "RandomSpawnPointBruh"; private const string _version = "2.1.5"; public static bool ValheimAwake; public static Waiting Waiter; public bool HasCompetingMods; private static RandomSpawnPointBruh _instance; private static ConfigSyncBase _config; private static ILogIt _log; private Harmony _harmony; public string PluginId => "vapok.mods.RandomSpawnPointBruh"; public string DisplayName => "RandomSpawnPointBruh"; public string Version => "2.1.5"; public BaseUnityPlugin Instance => (BaseUnityPlugin)(object)_instance; public static RandomSpawnPointBruh Main => _instance; public static ILogIt Log => _log; [UsedImplicitly] private void Awake() { //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Expected O, but got Unknown _instance = this; HasCompetingMods = Chainloader.PluginInfos.ContainsKey("org.bepinex.plugins.servercharacters") || Chainloader.PluginInfos.ContainsKey("com.orianaventure.mod.MultiplayerTweaks"); Waiter = new Waiting(); CustomLocalization localization = LocalizationManager.Instance.GetLocalization(); LogManager.Init(PluginId, out _log); Initializer.LoadManagers(localization); _config = new ConfigRegistry(_instance); ModSplashManager.Register(new ModSplashDossier(_instance) { Tagline = "Randomized and static player respawn and initial spawn point mechanics.", ShowOnStartup = ConfigSyncBase.ShowSplashOnStartup }); Log.Debug($"HasCompetingMods: {HasCompetingMods}"); Localizer.Waiter.StatusChanged += InitializeModule; _harmony = new Harmony(((BaseUnityPlugin)this).Info.Metadata.GUID); _harmony.PatchAll(Assembly.GetExecutingAssembly()); } private void Update() { if (Object.op_Implicit((Object)(object)Player.m_localPlayer)) { Object.op_Implicit((Object)(object)ZNetScene.instance); } } public void InitializeModule(object send, EventArgs args) { if (!ValheimAwake) { ConfigRegistry.Waiter.ConfigurationComplete(configDone: true); ValheimAwake = true; } } private void OnDestroy() { SpawnPointGenerator.Reset(); StartingKitManager.Reset(); _instance = null; } } } namespace RandomSpawnPointBruh.Patches { public static class GamePatches { [HarmonyPatch] private static class GameFindSpawnPointPatch { [UsedImplicitly] private static IEnumerable<MethodInfo> TargetMethods() { return GetMethods(); } private static IEnumerable<MethodInfo> GetMethods() { return new List<MethodInfo> { AccessTools.DeclaredMethod(typeof(Game), "FindSpawnPoint", (Type[])null, (Type[])null) }; } [UsedImplicitly] public static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions) { bool patchedSuccess = false; bool patchedSuccess2 = false; List<CodeInstruction> instrs = instructions.ToList(); int counter = 0; MethodInfo zoneSystemInstance = AccessTools.DeclaredPropertyGetter(typeof(ZoneSystem), "instance"); MethodInfo getLocationMethod = AccessTools.DeclaredMethod(typeof(ZoneSystem), "GetLocationIcon", (Type[])null, (Type[])null); FieldInfo startLocationField = AccessTools.DeclaredField(typeof(Game), "m_StartLocation"); int i = 0; while (i < instrs.Count) { if (!RandomSpawnPointBruh.Main.HasCompetingMods && i > 5 && instrs[i].opcode == OpCodes.Callvirt && instrs[i].operand.Equals(getLocationMethod) && instrs[i - 2].opcode == OpCodes.Ldfld && instrs[i - 2].operand.Equals(startLocationField)) { yield return LogMessage(new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(SpawnPointGenerator), "GetSpawnPoint", (Type[])null, (Type[])null))); counter++; patchedSuccess = true; } else if (RandomSpawnPointBruh.Main.HasCompetingMods && i > 5 && instrs[i].opcode == OpCodes.Callvirt && instrs[i - 2].opcode == OpCodes.Ldfld && instrs[i - 2].operand.Equals(startLocationField)) { yield return LogMessage(new CodeInstruction(OpCodes.Call, (object)AccessTools.DeclaredMethod(typeof(SpawnPointGenerator), "GetSpawnPoint", (Type[])null, (Type[])null))); counter++; patchedSuccess = true; } else if (!RandomSpawnPointBruh.Main.HasCompetingMods && i > 5 && instrs[i].opcode == OpCodes.Call && instrs[i].operand.Equals(zoneSystemInstance) && instrs[i + 4].opcode == OpCodes.Callvirt && instrs[i + 4].operand.Equals(getLocationMethod) && instrs[i + 2].opcode == OpCodes.Ldfld && instrs[i + 2].operand.Equals(startLocationField)) { if (instrs[i].labels.Count > 0) { CodeInstructionExtensions.MoveLabelsTo(instrs[i], instrs[i + 1]); } patchedSuccess2 = true; } else if (RandomSpawnPointBruh.Main.HasCompetingMods && i > 5 && instrs[i].opcode == OpCodes.Call && instrs[i].operand.Equals(zoneSystemInstance) && instrs[i + 4].opcode == OpCodes.Callvirt && instrs[i + 2].opcode == OpCodes.Ldfld && instrs[i + 2].operand.Equals(startLocationField)) { if (instrs[i].labels.Count > 0) { CodeInstructionExtensions.MoveLabelsTo(instrs[i], instrs[i + 1]); } patchedSuccess2 = true; } else { yield return LogMessage(instrs[i]); counter++; } int num = i + 1; i = num; } if (!patchedSuccess || !patchedSuccess2) { RandomSpawnPointBruh.Log.Error("Game.FindSpawnPoint Transpiler Failed To Patch"); RandomSpawnPointBruh.Log.Warning($"Patch1: {patchedSuccess} - Patch 2: {patchedSuccess2}"); Thread.Sleep(15000); } CodeInstruction LogMessage(CodeInstruction instruction) { RandomSpawnPointBruh.Log.Debug($"IL_{counter}: Opcode: {instruction.opcode} Operand: {instruction.operand}"); return instruction; } } } [HarmonyPatch(typeof(Game), "SpawnPlayer")] internal static class GameSpawnPlayerPatch { [HarmonyPrefix] private static void Prefix(Game __instance, bool spawnValkyrie) { if (!GUIManager.IsHeadless() && ((__instance.m_playerProfile != null && __instance.m_playerProfile.m_firstSpawn) || spawnValkyrie)) { StartingKitManager.QueueKitAward(); } } [HarmonyPostfix] private static void Postfix(Player __result) { if (!GUIManager.IsHeadless() && (Object)(object)__result != (Object)null && StartingKitManager.HasPendingKit) { StartingKitManager.StartAwardCoroutine(); } } } [HarmonyPatch(typeof(Terminal), "InitTerminal")] internal static class TerminalInitTerminalPatch { [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) { if ((Object)(object)Player.m_localPlayer != (Object)null) { StartingKitManager.ResetKitQueue(); args.Context.AddString("RSPB: Starting kit queued for local player."); } else { args.Context.AddString("RSPB: No active local player."); } } } [HarmonyPostfix] private static void Postfix() { //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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: Expected O, but got Unknown if (GUIManager.IsHeadless()) { return; } object obj = <>c.<>9__0_0; if (obj == null) { ConsoleEvent val = delegate(ConsoleEventArgs args) { if ((Object)(object)Player.m_localPlayer != (Object)null) { StartingKitManager.ResetKitQueue(); args.Context.AddString("RSPB: Starting kit queued for local player."); } else { args.Context.AddString("RSPB: No active local player."); } }; <>c.<>9__0_0 = val; obj = (object)val; } new ConsoleCommand("rspb_resetkit", "Queues starting kit to re-award on local player (Requires devcommands)", (ConsoleEvent)obj, true, false, false, false, false, false, (ConsoleOptionsFetcher)null, false, false, false); } } [HarmonyPatch(typeof(Humanoid), "GiveDefaultItem")] internal static class HumanoidGiveDefaultItemPatch { private static readonly HashSet<string> VanillaStartingItems = new HashSet<string> { "ArmorRagsLegs", "ArmorRagsChest", "Torch" }; [HarmonyPrefix] private static bool Prefix(Humanoid __instance, GameObject prefab) { if (GUIManager.IsHeadless()) { return true; } if (__instance is Player && ConfigRegistry.EnableStartingKits.Value && ConfigRegistry.ClearVanillaStartingItems.Value && (Object)(object)prefab != (Object)null) { string item = ((Object)prefab).name.Replace("(Clone)", "").Trim(); if (VanillaStartingItems.Contains(item)) { return false; } } return true; } } } [HarmonyPatch(typeof(Minimap), "UpdateExplore")] internal static class MinimapUpdateExplorePatch { private static bool _suppressionActive; [HarmonyPrefix] private static bool Prefix(Player player) { if (GUIManager.IsHeadless()) { return true; } if ((Object)(object)player != (Object)null && ((Character)player).InIntro()) { if (!_suppressionActive) { _suppressionActive = true; RandomSpawnPointBruh.Log.Debug("Minimap: Sensor active - Suppressing fog-of-war exploration during Valkyrie flight."); } return false; } if (_suppressionActive) { _suppressionActive = false; RandomSpawnPointBruh.Log.Debug("Minimap: Valkyrie flight complete - Fog-of-war exploration resumed."); } return true; } } } namespace RandomSpawnPointBruh.Configuration { public class BiomeStartingKit { public ConfigEntry<bool> Enabled; public ConfigEntry<string> KitItems; public Biome Biome { get; } public string SectionName { get; } public BiomeStartingKit(Biome biome, string sectionName) { //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) Biome = biome; SectionName = sectionName; } public void Register(ConfigRegistry registry, string defaultItems) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_002a: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown //IL_0048: Unknown result type (might be due to invalid IL or missing references) //IL_0059: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_00a2: Expected O, but got Unknown ConfigSyncBase.SyncedConfig(SectionName, "Enabled", value: true, new ConfigDescription($"Enables the starting kit for {Biome}. If false, vanilla starting items are kept.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = SectionName, Order = 2 } }), ref Enabled); ConfigSyncBase.SyncedConfig(SectionName, "Kit Items", defaultItems, new ConfigDescription("Items awarded on first spawn. Format: PrefabName:Count[:Quality], separated by commas.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = SectionName, Order = 1 } }), ref KitItems); } public bool TryGiveKit(Player player) { //IL_03b8: Unknown result type (might be due to invalid IL or missing references) //IL_012c: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_0192: Invalid comparison between Unknown and I4 //IL_0165: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_0269: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || !Enabled.Value || (Object)(object)ObjectDB.instance == (Object)null) { return false; } if (ConfigRegistry.ClearVanillaStartingItems.Value) { RemoveVanillaStartingItem(player, "ArmorRagsChest"); RemoveVanillaStartingItem(player, "ArmorRagsLegs"); RemoveVanillaStartingItem(player, "Torch"); } List<string> list = new List<string>(); string value = KitItems.Value; if (!string.IsNullOrEmpty(value)) { string[] array = value.Split(new char[2] { ',', ';' }, StringSplitOptions.RemoveEmptyEntries); for (int i = 0; i < array.Length; i++) { string text = array[i].Trim(); if (string.IsNullOrEmpty(text)) { continue; } string[] array2 = text.Split(new char[1] { ':' }); string text2 = array2[0].Trim(); int result = 1; int result2 = 1; if (array2.Length > 1 && !int.TryParse(array2[1].Trim(), out result)) { result = 1; } if (array2.Length > 2 && !int.TryParse(array2[2].Trim(), out result2)) { result2 = 1; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text2); if ((Object)(object)itemPrefab == (Object)null) { RandomSpawnPointBruh.Log.Warning($"Starting Kit ({Biome}): Item prefab '{text2}' not found in ObjectDB!"); continue; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { RandomSpawnPointBruh.Log.Warning($"Starting Kit ({Biome}): Prefab '{text2}' does not have an ItemDrop component!"); continue; } if ((int)component.m_itemData.m_shared.m_itemType == 2 && !list.Contains(text2)) { list.Add(text2); } int num = result; while (num > 0) { int num2 = Mathf.Min(num, component.m_itemData.m_shared.m_maxStackSize); ItemData val = component.m_itemData.Clone(); val.m_stack = num2; val.m_quality = Mathf.Clamp(result2, 1, val.m_shared.m_maxQuality); val.m_durability = val.GetMaxDurability(); if (((Humanoid)player).GetInventory().AddItem(val)) { ItemData item = ((Humanoid)player).GetInventory().GetItem(text2, val.m_quality, true); if (item != null) { player.AddKnownItem(item); if (ConfigRegistry.AutoEquipGear.Value && IsEquippable(item)) { ((Humanoid)player).EquipItem(item, false); } } num -= num2; continue; } RandomSpawnPointBruh.Log.Warning($"Starting Kit ({Biome}): Inventory full, could not add '{text2}'!"); break; } } } if (ConfigRegistry.AutoConsumeConsumables.Value && !GUIManager.IsHeadless()) { for (int j = 0; j < list.Count; j++) { string text3 = list[j]; ItemData item2 = ((Humanoid)player).GetInventory().GetItem(text3, -1, true); if (item2 == null) { continue; } if (!((Humanoid)player).ConsumeItem(((Humanoid)player).GetInventory(), item2, false)) { if (item2.m_shared.m_food > 0f) { if (player.EatFood(item2)) { ((Humanoid)player).GetInventory().RemoveOneItem(item2); RandomSpawnPointBruh.Log.Debug($"Starting Kit ({Biome}): Auto-consumed 1x food '{text3}'."); } } else if ((Object)(object)item2.m_shared.m_consumeStatusEffect != (Object)null) { ((Character)player).GetSEMan().AddStatusEffect(item2.m_shared.m_consumeStatusEffect, true, 0, 0f, (short)(-1)); ((Humanoid)player).GetInventory().RemoveOneItem(item2); RandomSpawnPointBruh.Log.Debug($"Starting Kit ({Biome}): Applied status effect and deducted 1x '{text3}'."); } } else { RandomSpawnPointBruh.Log.Debug($"Starting Kit ({Biome}): Auto-consumed 1x '{text3}'."); } } } return true; } private static bool IsEquippable(ItemData itemData) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Invalid comparison between Unknown and I4 //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Invalid comparison between Unknown and I4 //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0021: Invalid comparison between Unknown and I4 //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Invalid comparison between Unknown and I4 //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Invalid comparison between Unknown and I4 if (itemData.IsWeapon()) { return true; } ItemType itemType = itemData.m_shared.m_itemType; if ((int)itemType != 6 && (int)itemType != 7 && (int)itemType != 11 && (int)itemType != 17 && (int)itemType != 5) { return (int)itemType == 18; } return true; } private static void RemoveVanillaStartingItem(Player player, string prefabName) { ItemData item = ((Humanoid)player).GetInventory().GetItem(prefabName, -1, true); if (item != null) { if (((Humanoid)player).IsItemEquiped(item)) { ((Humanoid)player).UnequipItem(item, false); } ((Humanoid)player).GetInventory().RemoveItem(item); } } } public class ConfigRegistry : ConfigSyncBase { internal static ConfigEntry<bool> Enabled; internal static ConfigEntry<SpawnFunction> SpawnMethod; internal static ConfigEntry<UseableBiomes> SpawnBiome; internal static ConfigEntry<float> MinSearchRange; internal static ConfigEntry<float> BiomePaddingDistance; internal static ConfigEntry<float> MinAltitudeAboveWater; internal static ConfigEntry<float> PlayerSeparationDistance; internal static ConfigEntry<float> SpecialPoiBufferDistance; internal static ConfigEntry<int> MaxSearchAttempts; internal static ConfigEntry<Vector3> CustomSpawnPoint; internal static ConfigEntry<bool> EnableStartingKits; internal static ConfigEntry<bool> ClearVanillaStartingItems; internal static ConfigEntry<bool> AutoEquipGear; internal static ConfigEntry<bool> AutoConsumeConsumables; internal static ConfigEntry<bool> UseBiomeSpecificStartingKit; internal static ConfigEntry<UseableBiomes> DefaultStarterKit; private static readonly Dictionary<Biome, BiomeStartingKit> _kits = new Dictionary<Biome, BiomeStartingKit>(); public static Waiting Waiter; public ConfigRegistry(IPluginInfo mod) : base(mod) { Waiter = new Waiting(); InitializeConfigurationSettings(); } public sealed override void InitializeConfigurationSettings() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: 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) //IL_003e: Expected O, but got Unknown //IL_003e: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Expected O, but got Unknown //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_009e: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Expected O, but got Unknown //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Expected O, but got Unknown //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0107: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0124: Expected O, but got Unknown //IL_014f: Unknown result type (might be due to invalid IL or missing references) //IL_0154: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Expected O, but got Unknown //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_017c: Expected O, but got Unknown //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01c4: Expected O, but got Unknown //IL_01c4: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Expected O, but got Unknown //IL_01ff: Unknown result type (might be due to invalid IL or missing references) //IL_0204: Unknown result type (might be due to invalid IL or missing references) //IL_020f: Unknown result type (might be due to invalid IL or missing references) //IL_021c: Expected O, but got Unknown //IL_021c: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Expected O, but got Unknown //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Expected O, but got Unknown //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Expected O, but got Unknown //IL_02af: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02bf: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: Expected O, but got Unknown //IL_02cc: Unknown result type (might be due to invalid IL or missing references) //IL_02dc: Expected O, but got Unknown //IL_0304: Unknown result type (might be due to invalid IL or missing references) //IL_0309: Unknown result type (might be due to invalid IL or missing references) //IL_0314: Unknown result type (might be due to invalid IL or missing references) //IL_0321: Expected O, but got Unknown //IL_0321: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Expected O, but got Unknown //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_035a: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Expected O, but got Unknown //IL_0367: Unknown result type (might be due to invalid IL or missing references) //IL_0377: Expected O, but got Unknown //IL_0390: Unknown result type (might be due to invalid IL or missing references) //IL_0395: Unknown result type (might be due to invalid IL or missing references) //IL_03a0: Unknown result type (might be due to invalid IL or missing references) //IL_03ad: Expected O, but got Unknown //IL_03ad: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Expected O, but got Unknown //IL_03d6: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e6: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Expected O, but got Unknown //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_0403: Expected O, but got Unknown //IL_041c: Unknown result type (might be due to invalid IL or missing references) //IL_0421: Unknown result type (might be due to invalid IL or missing references) //IL_042c: Unknown result type (might be due to invalid IL or missing references) //IL_0439: Expected O, but got Unknown //IL_0439: Unknown result type (might be due to invalid IL or missing references) //IL_0449: Expected O, but got Unknown //IL_0462: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_047f: Expected O, but got Unknown //IL_047f: Unknown result type (might be due to invalid IL or missing references) //IL_048f: Expected O, but got Unknown //IL_04a8: Unknown result type (might be due to invalid IL or missing references) //IL_04ad: Unknown result type (might be due to invalid IL or missing references) //IL_04b8: Unknown result type (might be due to invalid IL or missing references) //IL_04c5: Expected O, but got Unknown //IL_04c5: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Expected O, but got Unknown if (ConfigSyncBase._config != null) { ConfigSyncBase.SyncedConfig("General Settings (Synced)", "Enable Random Spawn Bruh!", value: true, new ConfigDescription("If true, will randomize new player spawn points within the area parameters. Requires Game Restart.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "General Settings (Synced)", Order = 1 } }), ref Enabled); ConfigSyncBase.SyncedConfig("General Settings (Synced)", "Spawn Point Method", SpawnFunction.RandomSpawnPoint, new ConfigDescription("Spawn method to use. Only affects NEW players who join the world.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "General Settings (Synced)", Order = 2 } }), ref SpawnMethod); ConfigSyncBase.SyncedConfig("Static Spawn Settings (Synced)", "Spawn Point", Vector3.zero, new ConfigDescription("Vector Coordinates to use for all players spawns.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Static Spawn Settings (Synced)", Order = 1 } }), ref CustomSpawnPoint); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Biome for Spawn Points", UseableBiomes.Meadows, new ConfigDescription("Defines which biome to look for spawn points.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 1 } }), ref SpawnBiome); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Min Search Range", 500f, new ConfigDescription("Inner most distance from center point to begin looking for a spawn point.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 9000f), new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 2 } }), ref MinSearchRange); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Biome Padding Distance", 100f, new ConfigDescription("Minimum distance in meters to keep between spawn points and any other biome.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 500f), new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 3 } }), ref BiomePaddingDistance); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Min Altitude Above Water", 4f, new ConfigDescription("Minimum height in meters above sea level to place spawn points. Prevents spawning on soggy beaches, waterlines, or submerged ground.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(1f, 50f), new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 4 } }), ref MinAltitudeAboveWater); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Player Separation Distance", 200f, new ConfigDescription("Minimum distance in meters to keep between new spawn points and existing players, player bases, or wards.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(0f, 2000f), new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 5 } }), ref PlayerSeparationDistance); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Special POI Buffer Distance", 100f, new ConfigDescription("Buffer distance in meters beyond the POI reveal radius and Valkyrie flight path to prevent new spawns from revealing traders or unique locations.", (AcceptableValueBase)(object)new AcceptableValueRange<float>(50f, 500f), new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 6 } }), ref SpecialPoiBufferDistance); ConfigSyncBase.SyncedConfig("Random Spawn Settings (Synced)", "Max Search Attempts", 250, new ConfigDescription("Maximum number of random candidate points to test before falling back to the original start temple.", (AcceptableValueBase)(object)new AcceptableValueRange<int>(10, 1000), new object[1] { (object)new ConfigurationManagerAttributes { Category = "Random Spawn Settings (Synced)", Order = 7 } }), ref MaxSearchAttempts); ConfigSyncBase.SyncedConfig("Starting Kits (Synced)", "Enable Starting Kits", value: false, new ConfigDescription("If enabled, awards starting equipment and survival seeds tailored to the player's initial landing biome. Defaults to false to preserve vanilla behavior for existing installs.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Starting Kits (Synced)", Order = 5 } }), ref EnableStartingKits); ConfigSyncBase.SyncedConfig("Starting Kits (Synced)", "Clear Vanilla Starting Items", value: true, new ConfigDescription("If true, removes default rag clothes and torch before awarding the biome starting kit.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Starting Kits (Synced)", Order = 4 } }), ref ClearVanillaStartingItems); ConfigSyncBase.SyncedConfig("Starting Kits (Synced)", "Auto-Equip Gear", value: true, new ConfigDescription("If true, automatically equips weapons, shields, utility belts, and armor from the kit upon landing.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Starting Kits (Synced)", Order = 3 } }), ref AutoEquipGear); ConfigSyncBase.SyncedConfig("Starting Kits (Synced)", "Auto-Consume Foods and Meads", value: true, new ConfigDescription("If true, automatically consumes one of each food and mead item included in the starting kit upon landing.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Starting Kits (Synced)", Order = 2 } }), ref AutoConsumeConsumables); ConfigSyncBase.SyncedConfig("Starting Kits (Synced)", "Use Biome Specific Starter Kit", value: true, new ConfigDescription("When enabled, awards the starting kit configured for the biome where the player lands. When disabled, awards the Default Starter Kit regardless of landing location.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Starting Kits (Synced)", Order = 1 } }), ref UseBiomeSpecificStartingKit); ConfigSyncBase.SyncedConfig("Starting Kits (Synced)", "Default Starter Kit", UseableBiomes.Meadows, new ConfigDescription("Selects the default biome starting kit to award when biome-specific kits are disabled or when landing in a biome without a dedicated kit.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes { Category = "Starting Kits (Synced)", Order = 0 } }), ref DefaultStarterKit); RegisterStartingKits(); } } private void RegisterStartingKits() { _kits.Clear(); RegisterKit((Biome)1, "Starting Kits: Meadows (Synced)", "ArmorRagsChest:1, ArmorRagsLegs:1, Club:1, Torch:1, Wood:10, Stone:6, Raspberry:5, CookedMeat:3"); RegisterKit((Biome)8, "Starting Kits: Black Forest (Synced)", "ArmorLeatherChest:1, ArmorLeatherLegs:1, HelmetLeather:1, CapeDeerHide:1, Club:1, ShieldWood:1, Torch:1, HardAntler:1, Wood:10, Stone:6, CookedDeerMeat:3, Blueberries:5"); RegisterKit((Biome)2, "Starting Kits: Swamp (Synced)", "ArmorTrollLeatherChest:1, ArmorTrollLeatherLegs:1, HelmetTrollLeather:1, CapeTrollHide:1, MaceBronze:1:1, ShieldBronzeBuckler:1:1, PickaxeAntler:1, AxeFlint:1, Hoe:1, Hammer:1, MeadPoisonResist:4, CarrotSoup:3, CookedDeerMeat:3, QueensJam:3"); RegisterKit((Biome)4, "Starting Kits: Mountain (Synced)", "ArmorIronChest:1:1, ArmorIronLegs:1:1, HelmetIron:1:1, MaceIron:1:1, ShieldBanded:1:1, BowHuntsman:1:1, ArrowFire:30, PickaxeAntler:1, AxeBronze:1:1, Hammer:1, MeadFrostResist:4, Sausages:3, TurnipStew:3, CookedDeerMeat:3"); RegisterKit((Biome)16, "Starting Kits: Plains (Synced)", "ArmorWolfChest:1:1, ArmorWolfLegs:1:1, HelmetDrake:1:1, CapeWolf:1:1, MaceBronze:1:4, ShieldBronzeBuckler:1:4, BowDraugrFang:1:1, ArrowObsidian:30, PickaxeAntler:1, AxeBronze:1:1, Hammer:1, WolfMeatSkewer:3, Eyescream:3, Sausages:3"); RegisterKit((Biome)512, "Starting Kits: Mistlands (Synced)", "ArmorPaddedCuirass:1:1, ArmorPaddedGreaves:1:1, HelmetPadded:1:1, CapeLox:1:1, Demister:1, MaceSilver:1:1, ShieldBlackmetal:1:1, PickaxeAntler:1, AxeBlackMetal:1:1, Hammer:1, FineWood:30, DeerHide:10, Resin:20, BronzeNails:80, BarleyWine:4, LoxPie:3, BloodPudding:3, Bread:3"); RegisterKit((Biome)32, "Starting Kits: Ashlands (Synced)", "ArmorCarapaceChest:1:1, ArmorCarapaceLegs:1:1, HelmetCarapace:1:1, CapeLox:1:1, BeltStrength:1, SwordMistwalker:1:1, ShieldCarapace:1:1, PickaxeAntler:1, AxeBlackMetal:1:1, Hammer:1, BlackMarble:10, BlackCore:5, CeramicPlate:30, IronNails:100, FineWood:50, YggdrasilWood:35, BarleyWine:4, MisthareSupreme:3, MeatPlatter:3, Salad:3"); RegisterKit((Biome)64, "Starting Kits: Deep North (Synced)", "ArmorFlametalChest:1:1, ArmorFlametalLegs:1:1, HelmetFlametal:1:1, CapeLox:1:1, BowAshlands:1:1, ShieldFlametal:1:1, SwordMistwalker:1:1, ArrowFire:40, PickaxeAntler:1, AxeBlackMetal:1:1, Hammer:1, Wood:20, FineWood:30, DeerHide:10, Resin:20, BronzeNails:80, MeatPlatter:3, MisthareSupreme:3, Salad:3"); } private void RegisterKit(Biome biome, string sectionName, string defaultItems) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Unknown result type (might be due to invalid IL or missing references) BiomeStartingKit biomeStartingKit = new BiomeStartingKit(biome, sectionName); biomeStartingKit.Register(this, defaultItems); _kits[biome] = biomeStartingKit; } public static BiomeStartingKit GetKit(Biome biome) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) if (_kits.TryGetValue(biome, out var value)) { return value; } return null; } } public class Waiting { public event EventHandler StatusChanged; public void ConfigurationComplete(bool configDone) { if (configDone) { this.StatusChanged?.Invoke(this, EventArgs.Empty); } } } } namespace RandomSpawnPointBruh.Components { public enum SpawnFunction { RandomSpawnPoint, StaticSpawnPoint, VanillaSpawnPoint } public enum UseableBiomes { Meadows, BlackForest, Swamp, Mountains, Plains, Mistlands, Ashlands, DeepNorth, Ocean } public static class SpawnPointGenerator { private struct SpecialPoiData { public Vector3 Position; public string Name; } private const float SolidHeightTolerance = 1.5f; private const float PoiClearanceMargin = 40f; private const float ValkyrieFlightRadius = 500f; private const float BasePoiRevealRadius = 500f; private static List<SpecialPoiData> _cachedSpecialPois; private static ZoneSystem _cachedZoneSystem; private static readonly Vector2[] PaddingDirections = (Vector2[])(object)new Vector2[8] { new Vector2(1f, 0f), new Vector2(-1f, 0f), new Vector2(0f, 1f), new Vector2(0f, -1f), new Vector2(0.7071f, 0.7071f), new Vector2(-0.7071f, 0.7071f), new Vector2(0.7071f, -0.7071f), new Vector2(-0.7071f, -0.7071f) }; private static Vector3 _pendingSpawnPoint = Vector3.zero; public static bool GetSpawnPoint(string startLocation, out Vector3 pos) { //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008e: 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_007c: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: Unknown result type (might be due to invalid IL or missing references) //IL_00bf: Unknown result type (might be due to invalid IL or missing references) //IL_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01b7: Unknown result type (might be due to invalid IL or missing references) //IL_01bd: Unknown result type (might be due to invalid IL or missing references) //IL_01c2: Unknown result type (might be due to invalid IL or missing references) //IL_015a: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_0174: Unknown result type (might be due to invalid IL or missing references) //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: 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_0144: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null || !ZoneSystem.instance.LocationsGenerated) { RandomSpawnPointBruh.Log.Debug("Waiting for world locations to generate before selecting spawn point..."); pos = Vector3.zero; return false; } Vector3 val = default(Vector3); bool locationIcon = ZoneSystem.instance.GetLocationIcon(startLocation, ref val); if (!ConfigRegistry.Enabled.Value) { pos = val; RandomSpawnPointBruh.Log.Debug("Random Spawn Point Bruh! - Disabled"); return locationIcon; } switch (ConfigRegistry.SpawnMethod.Value) { case SpawnFunction.VanillaSpawnPoint: pos = val; return locationIcon; case SpawnFunction.StaticSpawnPoint: pos = ConfigRegistry.CustomSpawnPoint.Value; return true; default: { if ((Object)(object)Game.instance != (Object)null && Game.instance.m_playerProfile != null) { Vector3 homePoint = Game.instance.m_playerProfile.GetHomePoint(); if (homePoint != Vector3.zero) { RandomSpawnPointBruh.Log.Debug($"Player home point already set: {homePoint}"); pos = homePoint; return true; } } if (_pendingSpawnPoint != Vector3.zero) { if (!((Object)(object)ZNetScene.instance != (Object)null) || !ZNetScene.instance.IsAreaReady(_pendingSpawnPoint)) { RandomSpawnPointBruh.Log.Debug($"Waiting for sector around {_pendingSpawnPoint} to load..."); pos = _pendingSpawnPoint; return true; } if (ValidateLoadedArea(ref _pendingSpawnPoint)) { pos = _pendingSpawnPoint; _pendingSpawnPoint = Vector3.zero; return true; } _pendingSpawnPoint = Vector3.zero; } RandomSpawnPointBruh.Log.Debug($"Spawn Method: {ConfigRegistry.SpawnMethod.Value}"); if (GetRandomPointInBiome(GetBiome(ConfigRegistry.SpawnBiome.Value), out var customSpawnPoint)) { _pendingSpawnPoint = customSpawnPoint; pos = _pendingSpawnPoint; return true; } pos = val; return locationIcon; } } } private static bool ValidateLoadedArea(ref Vector3 candidate) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ad: Unknown result type (might be due to invalid IL or missing references) //IL_00b3: Invalid comparison between Unknown and I4 //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_012a: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0315: Invalid comparison between Unknown and I4 //IL_0201: Unknown result type (might be due to invalid IL or missing references) //IL_0257: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0330: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Invalid comparison between Unknown and I4 //IL_0395: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null) { return true; } Stopwatch stopwatch = Stopwatch.StartNew(); RandomSpawnPointBruh.Log.Debug($"Validating loaded sector for candidate {candidate}..."); Vector3 val = default(Vector3); Biome val2 = default(Biome); BiomeArea val3 = default(BiomeArea); Heightmap val4 = default(Heightmap); ZoneSystem.instance.GetGroundData(ref candidate, ref val, ref val2, ref val3, ref val4); if ((Object)(object)val4 != (Object)null && val4.IsLava(candidate, 0.6f)) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: inside lava ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } float solidHeight = ZoneSystem.instance.GetSolidHeight(candidate); if ((int)val2 != 256) { float num = Math.Abs(solidHeight - candidate.y); if (num > 1.5f) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: solid height offset ({num:F1}m) exceeds tolerance ({1.5f:F1}m) ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } candidate.y = solidHeight; } else { candidate.y = ZoneSystem.instance.m_waterLevel; } if ((Object)(object)Location.GetLocation(candidate, false) != (Object)null) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: inside active POI location ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } float value = ConfigRegistry.SpecialPoiBufferDistance.Value; if (IsNearSpecialPoi(candidate, value, out var closestPoiName, out var closestPoiDistance, out var requiredSafeDistance)) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: TRIPPED SPECIAL POI BARRIER in loaded area! Distance: {closestPoiDistance:F0}m to {closestPoiName} (Required safe barrier: {requiredSafeDistance:F0}m) ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } float separationDistance = ConfigRegistry.PlayerSeparationDistance.Value; if (separationDistance > 0f) { if ((Object)(object)EffectArea.IsPointInsideArea(candidate, (Type)4, separationDistance) != (Object)null) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: within {separationDistance:F0}m of a player base ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } Vector3 checkPoint = candidate; if (PrivateArea.m_allAreas.Any((PrivateArea x) => (Object)(object)x != (Object)null && x.IsInside(checkPoint, separationDistance))) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: within {separationDistance:F0}m of a player ward ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } if (Player.GetAllPlayers().Any((Player p) => (Object)(object)p != (Object)null && Vector3.Distance(((Component)p).transform.position, checkPoint) < separationDistance)) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: within {separationDistance:F0}m of an active player ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } } float waterLevel = ZoneSystem.instance.m_waterLevel; float num2 = (((int)val2 == 2) ? (waterLevel + 0.5f) : (waterLevel + ConfigRegistry.MinAltitudeAboveWater.Value)); if ((int)val2 != 256 && candidate.y < num2) { stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Spawn Point rejected: altitude {candidate.y:F1}m below dry elevation threshold {num2:F1}m ({stopwatch.Elapsed.TotalMilliseconds:F2}ms)"); return false; } stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Random Spawn Point Verified at {candidate} in {stopwatch.Elapsed.TotalMilliseconds:F2}ms (SolidHeight={solidHeight:F1})"); return true; } private static bool GetRandomPointInBiome(Biome biome, out Vector3 customSpawnPoint) { //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0063: Unknown result type (might be due to invalid IL or missing references) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Invalid comparison between Unknown and I4 //IL_051e: Unknown result type (might be due to invalid IL or missing references) //IL_0523: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Invalid comparison between Unknown and I4 //IL_0131: Unknown result type (might be due to invalid IL or missing references) //IL_0154: 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_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0169: Unknown result type (might be due to invalid IL or missing references) //IL_0184: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Unknown result type (might be due to invalid IL or missing references) //IL_019f: 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_01ea: Unknown result type (might be due to invalid IL or missing references) //IL_01ec: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f8: Unknown result type (might be due to invalid IL or missing references) //IL_01fa: Unknown result type (might be due to invalid IL or missing references) //IL_01ff: 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_0204: Invalid comparison between Unknown and I4 //IL_01b6: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0210: Unknown result type (might be due to invalid IL or missing references) //IL_021e: Unknown result type (might be due to invalid IL or missing references) //IL_023c: Unknown result type (might be due to invalid IL or missing references) //IL_023e: Unknown result type (might be due to invalid IL or missing references) //IL_0329: Unknown result type (might be due to invalid IL or missing references) //IL_028e: Unknown result type (might be due to invalid IL or missing references) //IL_0251: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Unknown result type (might be due to invalid IL or missing references) //IL_029e: Unknown result type (might be due to invalid IL or missing references) //IL_02a0: Unknown result type (might be due to invalid IL or missing references) //IL_02ac: Unknown result type (might be due to invalid IL or missing references) //IL_02bc: Unknown result type (might be due to invalid IL or missing references) //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c2: Invalid comparison between Unknown and I4 //IL_02e8: Unknown result type (might be due to invalid IL or missing references) //IL_03d4: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Invalid comparison between Unknown and I4 //IL_0435: Unknown result type (might be due to invalid IL or missing references) //IL_043b: Invalid comparison between Unknown and I4 //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_044f: Unknown result type (might be due to invalid IL or missing references) //IL_0478: Unknown result type (might be due to invalid IL or missing references) //IL_04d0: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) int value = ConfigRegistry.MaxSearchAttempts.Value; float value2 = ConfigRegistry.MinSearchRange.Value; float value3 = ConfigRegistry.BiomePaddingDistance.Value; float value4 = ConfigRegistry.MinAltitudeAboveWater.Value; GetBiomeRangeBounds(biome, out var naturalMin, out var naturalMax); float num = Mathf.Max(value2, naturalMin); float num2 = naturalMax; if (num >= num2) { num = naturalMin; } Stopwatch stopwatch = Stopwatch.StartNew(); RandomSpawnPointBruh.Log.Debug($"Initiating random spawn search: Biome={biome}, EffectiveRange=[{num:F0}m - {num2:F0}m], MinAltitude=+{value4:F1}m, Padding={value3:F0}m, MaxAttempts={value}"); Random random = new Random(Guid.NewGuid().GetHashCode()); Vector3 val3 = default(Vector3); for (int i = 1; i <= value; i++) { double num3 = (((int)biome == 32) ? (Math.PI + random.NextDouble() * Math.PI) : (((int)biome != 64) ? (random.NextDouble() * Math.PI * 2.0) : (random.NextDouble() * Math.PI))); Vector2 val = new Vector2((float)Math.Cos(num3), (float)Math.Sin(num3)); float num4 = (float)Math.Sqrt(random.NextDouble()); float num5 = Mathf.Lerp(num, num2, num4); Vector2 val2 = val * num5; ((Vector3)(ref val3))..ctor(val2.x, 0f, val2.y); if (WorldGenerator.instance == null) { continue; } Biome biome2 = WorldGenerator.instance.GetBiome(val3.x, val3.z, 0.02f, false); if (biome2 != biome) { RandomSpawnPointBruh.Log.Debug($"Point {val3} (attempt {i}): Biome {biome2} != {biome}"); continue; } Vector2s zone = ZoneSystem.GetZone(val3); BiomeArea biomeArea = WorldGenerator.instance.GetBiomeArea(zone); if ((int)biomeArea != 2) { RandomSpawnPointBruh.Log.Debug($"Point {val3} (attempt {i}): BiomeArea {biomeArea} != Median"); continue; } if (value3 > 0f && !IsBiomePadded(val3, biome, value3)) { RandomSpawnPointBruh.Log.Debug($"Point {val3} (attempt {i}): Encroaches on neighboring biome within {value3:F0}m padding"); continue; } if ((Object)(object)ZoneSystem.instance != (Object)null && ZoneSystem.instance.m_locationInstances.TryGetValue(zone, out var value5)) { float num6 = Vector3.Distance(val3, value5.m_position); float num7 = ((value5.m_location != null) ? value5.m_location.m_interiorRadius : 30f) + 40f; if (num6 < num7) { RandomSpawnPointBruh.Log.Debug($"Point {val3} (attempt {i}): Near POI (dist={num6:F0}m, safeRadius={num7:F0}m)"); continue; } } float value6 = ConfigRegistry.SpecialPoiBufferDistance.Value; if (IsNearSpecialPoi(val3, value6, out var closestPoiName, out var closestPoiDistance, out var requiredSafeDistance)) { RandomSpawnPointBruh.Log.Debug($"Point {val3} (attempt {i}): TRIPPED SPECIAL POI BARRIER! Distance: {closestPoiDistance:F0}m to {closestPoiName} (Required safe barrier: {requiredSafeDistance:F0}m). Rejecting candidate."); continue; } float height = WorldGenerator.instance.GetHeight(val3.x, val3.z); float num8 = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f); float num9 = (((int)biome == 2) ? (num8 + 0.5f) : (num8 + value4)); if ((int)biome != 256 && height < num9) { RandomSpawnPointBruh.Log.Debug($"Point {val3} (attempt {i}): Elevation {height:F1}m below dry threshold {num9:F1}m (waterLevel={num8:F1})"); continue; } val3.y = (((int)biome == 256) ? num8 : height); stopwatch.Stop(); IsNearSpecialPoi(val3, value6, out var closestPoiName2, out var closestPoiDistance2, out var requiredSafeDistance2); float num10 = closestPoiDistance2 - requiredSafeDistance2; RandomSpawnPointBruh.Log.Debug($"Random Spawn Point candidate selected: {val3} in {stopwatch.Elapsed.TotalMilliseconds:F2}ms (Evaluated {i} points). Closest special POI: {closestPoiName2} at {closestPoiDistance2:F0}m (Safe barrier: {requiredSafeDistance2:F0}m, Clearance: +{num10:F0}m - Sensor PASS)"); customSpawnPoint = val3; return true; } stopwatch.Stop(); RandomSpawnPointBruh.Log.Debug($"Random point search exhausted after {value} evaluations in {stopwatch.Elapsed.TotalMilliseconds:F2}ms without finding a candidate"); customSpawnPoint = Vector3.zero; return false; } private static void GetBiomeRangeBounds(Biome biome, out float naturalMin, out float naturalMax) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected I4, but got Unknown //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Invalid comparison between Unknown and I4 //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((int)biome <= 16) { switch (biome - 1) { default: if ((int)biome != 8) { if ((int)biome != 16) { break; } naturalMin = 3000f; naturalMax = 8500f; return; } naturalMin = 600f; naturalMax = 6000f; return; case 0: naturalMin = 0f; naturalMax = 5000f; return; case 1: naturalMin = 2000f; naturalMax = 8000f; return; case 3: naturalMin = 1500f; naturalMax = 8500f; return; case 2: break; } } else if ((int)biome <= 64) { if ((int)biome == 32) { naturalMin = 7500f; naturalMax = 10000f; return; } if ((int)biome == 64) { naturalMin = 7500f; naturalMax = 10000f; return; } } else { if ((int)biome == 256) { naturalMin = 1000f; naturalMax = 9000f; return; } if ((int)biome == 512) { naturalMin = 5500f; naturalMax = 9500f; return; } } naturalMin = 0f; naturalMax = 10000f; } private static List<SpecialPoiData> GetSpecialPois() { //IL_007b: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a3: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00d1: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZoneSystem.instance == (Object)null || !ZoneSystem.instance.LocationsGenerated || ZoneSystem.instance.m_locationInstances == null) { return null; } if ((Object)(object)_cachedZoneSystem == (Object)(object)ZoneSystem.instance && _cachedSpecialPois != null && _cachedSpecialPois.Count > 0) { return _cachedSpecialPois; } _cachedZoneSystem = ZoneSystem.instance; List<SpecialPoiData> list = new List<SpecialPoiData>(); foreach (LocationInstance value in ZoneSystem.instance.m_locationInstances.Values) { if (value.m_location != null && (value.m_location.m_iconPlaced || value.m_location.m_unique)) { _ = value.m_location.m_prefab; string name = value.m_location.m_prefab.Name; list.Add(new SpecialPoiData { Position = value.m_position, Name = name }); } } if (list.Count > 0) { _cachedSpecialPois = list; RandomSpawnPointBruh.Log.Debug($"Discovered and cached {_cachedSpecialPois.Count} special POI positions for spawn protection"); } return list; } private static bool IsNearSpecialPoi(Vector3 candidatePoint, float bufferDistance, out string closestPoiName, out float closestPoiDistance, out float requiredSafeDistance) { //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_0096: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a9: Unknown result type (might be due to invalid IL or missing references) closestPoiName = string.Empty; closestPoiDistance = float.MaxValue; requiredSafeDistance = 0f; List<SpecialPoiData> specialPois = GetSpecialPois(); if (specialPois == null || specialPois.Count == 0) { return false; } float num = ((((SimulationDistance)(ref ZoneSystem.instance.m_simulationDistance)).TotalSimulationDistance > 0) ? Mathf.Max(500f, (float)((SimulationDistance)(ref ZoneSystem.instance.m_simulationDistance)).TotalSimulationDistance * 64f + 51.2f) : 500f); requiredSafeDistance = num + 500f + bufferDistance; float num2 = requiredSafeDistance * requiredSafeDistance; bool result = false; for (int i = 0; i < specialPois.Count; i++) { SpecialPoiData specialPoiData = specialPois[i]; float num3 = candidatePoint.x - specialPoiData.Position.x; float num4 = candidatePoint.z - specialPoiData.Position.z; float num5 = num3 * num3 + num4 * num4; if (num5 < num2) { result = true; } float num6 = Mathf.Sqrt(num5); if (num6 < closestPoiDistance) { closestPoiDistance = num6; closestPoiName = specialPoiData.Name; } } return result; } private static bool IsBiomePadded(Vector3 point, Biome targetBiome, float padding) { //IL_0004: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) for (int i = 0; i < PaddingDirections.Length; i++) { float num = point.x + PaddingDirections[i].x * padding; float num2 = point.z + PaddingDirections[i].y * padding; if (WorldGenerator.instance.GetBiome(num, num2, 0.02f, false) != targetBiome) { return false; } } return true; } public static Biome GetBiome(UseableBiomes biome) { return (Biome)(biome switch { UseableBiomes.BlackForest => 8, UseableBiomes.Swamp => 2, UseableBiomes.Mountains => 4, UseableBiomes.Plains => 16, UseableBiomes.Mistlands => 512, UseableBiomes.Ashlands => 32, UseableBiomes.DeepNorth => 64, UseableBiomes.Ocean => 256, _ => 1, }); } public static void Reset() { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) _pendingSpawnPoint = Vector3.zero; _cachedSpecialPois = null; _cachedZoneSystem = null; } } public static class StartingKitManager { private const float MaxGroundedWaitSeconds = 5f; private static Coroutine _activeCoroutine; private static bool _hasPendingKit; public static bool HasPendingKit => _hasPendingKit; public static void QueueKitAward() { if (!GUIManager.IsHeadless()) { _hasPendingKit = true; RandomSpawnPointBruh.Log.Debug("Starting kit queued for award on touchdown."); } } public static void StartAwardCoroutine() { if (!GUIManager.IsHeadless() && _hasPendingKit && !((Object)(object)RandomSpawnPointBruh.Main == (Object)null)) { if (_activeCoroutine != null) { ((MonoBehaviour)RandomSpawnPointBruh.Main).StopCoroutine(_activeCoroutine); _activeCoroutine = null; } RandomSpawnPointBruh.Log.Debug("Starting touchdown coroutine for kit award."); _activeCoroutine = ((MonoBehaviour)RandomSpawnPointBruh.Main).StartCoroutine(AwardKitWhenReadyCoroutine()); } } private static IEnumerator AwardKitWhenReadyCoroutine() { if (GUIManager.IsHeadless()) { _activeCoroutine = null; yield break; } while (true) { if (!_hasPendingKit) { _activeCoroutine = null; yield break; } if ((Object)(object)Game.instance == (Object)null || Game.instance.IsShuttingDown()) { _activeCoroutine = null; yield break; } Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || ((Character)localPlayer).IsDead()) { yield return null; continue; } if (Game.instance.WaitingForRespawn()) { yield return null; continue; } if (((Character)localPlayer).InIntro() || ((Character)localPlayer).InCutscene() || ((Character)localPlayer).IsTeleporting()) { yield return null; continue; } if ((Object)(object)Hud.instance == (Object)null || (Object)(object)Hud.instance.m_loadingScreen == (Object)null) { yield return null; continue; } if (((Component)Hud.instance.m_loadingScreen).gameObject.activeInHierarchy && Hud.instance.m_loadingScreen.alpha > 0.05f) { yield return null; continue; } if (WorldGenerator.instance != null) { break; } yield return null; } float groundedTimer = 0f; while (groundedTimer < 5f) { Player localPlayer2 = Player.m_localPlayer; if ((Object)(object)localPlayer2 == (Object)null || ((Character)localPlayer2).IsDead()) { _activeCoroutine = null; yield break; } if (((Character)localPlayer2).IsOnGround() || ((Character)localPlayer2).InWater() || ((Character)localPlayer2).IsSwimming()) { break; } groundedTimer += Time.deltaTime; yield return null; } yield return (object)new WaitForSeconds(0.5f); if (_hasPendingKit) { Player localPlayer3 = Player.m_localPlayer; if ((Object)(object)localPlayer3 != (Object)null && !((Character)localPlayer3).IsDead()) { AwardKit(localPlayer3); _hasPendingKit = false; } } _activeCoroutine = null; } private static void AwardKit(Player player) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_001f: 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_0030: 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) //IL_0037: Invalid comparison between Unknown and I4 //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Invalid comparison between Unknown and I4 //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Invalid comparison between Unknown and I4 //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) if (WorldGenerator.instance == null) { return; } Vector3 position = ((Component)player).transform.position; Biome biome = WorldGenerator.instance.GetBiome(position.x, position.z, 0.02f, false); if ((int)biome == 256 || ((Character)player).InWater() || ((Character)player).IsSwimming()) { SpawnOceanKarve(player); } if (!ConfigRegistry.EnableStartingKits.Value) { return; } Biome val; if (ConfigRegistry.UseBiomeSpecificStartingKit.Value && (int)biome != 256) { val = biome; } else { val = SpawnPointGenerator.GetBiome(ConfigRegistry.DefaultStarterKit.Value); if ((int)val == 256) { val = (Biome)1; } } BiomeStartingKit kit = ConfigRegistry.GetKit(val); bool flag = false; if (kit != null) { flag = kit.TryGiveKit(player); if (flag) { RandomSpawnPointBruh.Log.Debug($"Awarded {val} Starting Kit to '{player.GetPlayerName()}'."); } } if (!flag) { if (ConfigRegistry.ClearVanillaStartingItems.Value) { GiveEmergencyItem(player, "ArmorRagsChest", 1); GiveEmergencyItem(player, "ArmorRagsLegs", 1); } GiveEmergencyItem(player, "Bread", 2); } } private static void SpawnOceanKarve(Player player) { //IL_004d: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Unknown result type (might be due to invalid IL or missing references) //IL_0085: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //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_009e: 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_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00a7: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return; } GameObject prefab = ZNetScene.instance.GetPrefab("Karve"); if (!((Object)(object)prefab == (Object)null)) { float y = (((Object)(object)ZoneSystem.instance != (Object)null) ? ZoneSystem.instance.m_waterLevel : 30f); Vector3 forward = ((Component)player).transform.forward; forward.y = 0f; if (((Vector3)(ref forward)).sqrMagnitude < 0.01f) { forward = Vector3.forward; } ((Vector3)(ref forward)).Normalize(); Vector3 val = ((Component)player).transform.position + forward * 6f; val.y = y; Quaternion val2 = Quaternion.LookRotation(forward); Object.Instantiate<GameObject>(prefab, val, val2); RandomSpawnPointBruh.Log.Debug($"Ocean Easter Egg: Spawned Karve at {val} for '{player.GetPlayerName()}'."); } } private static void GiveEmergencyItem(Player player, string prefabName, int count) { //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Invalid comparison between Unknown and I4 //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Invalid comparison between Unknown and I4 if ((Object)(object)ObjectDB.instance == (Object)null) { return; } GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(prefabName); if ((Object)(object)itemPrefab == (Object)null) { return; } ItemDrop component = itemPrefab.GetComponent<ItemDrop>(); if ((Object)(object)component == (Object)null) { return; } ItemData val = component.m_itemData.Clone(); val.m_stack = count; if (!((Humanoid)player).GetInventory().AddItem(val)) { return; } ItemData item = ((Humanoid)player).GetInventory().GetItem(prefabName, val.m_quality, true); if (item != null) { player.AddKnownItem(item); if ((int)item.m_shared.m_itemType == 7 || (int)item.m_shared.m_itemType == 11) { ((Humanoid)player).EquipItem(item, false); } } } public static void ResetKitQueue() { if (!GUIManager.IsHeadless()) { QueueKitAward(); StartAwardCoroutine(); RandomSpawnPointBruh.Log.Debug("Queued starting kit for local player via console reset."); } } public static void Reset() { _hasPendingKit = false; if (_activeCoroutine != null && (Object)(object)RandomSpawnPointBruh.Main != (Object)null) { ((MonoBehaviour)RandomSpawnPointBruh.Main).StopCoroutine(_activeCoroutine); } _activeCoroutine = null; } } } 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; } } } namespace ItemManager { [PublicAPI] internal enum CraftingTable { Disabled, Inventory, [InternalName("piece_workbench")] Workbench, [InternalName("piece_cauldron")] Cauldron, [InternalName("forge")] Forge, [InternalName("piece_artisanstation")] ArtisanTable, [InternalName("piece_stonecutter")] StoneCutter, [InternalName("piece_magetable")] MageTable, [InternalName("blackforge")] BlackForge, [InternalName("piece_preptable")] FoodPreparationTable, [InternalName("piece_MeadCauldron")] MeadKetill, Custom } [PublicAPI] internal enum ConversionPiece { Disabled, [InternalName("smelter")] Smelter, [InternalName("charcoal_kiln")] CharcoalKiln, [InternalName("blastfurnace")] BlastFurnace, [InternalName("windmill")] Windmill, [InternalName("piece_spinningwheel")] SpinningWheel, [InternalName("eitrrefinery")] EitrRefinery, Custom } internal class InternalName : Attribute { public readonly string internalName; public InternalName(string internalName) { this.internalName = internalName; } } [PublicAPI] internal class RequiredResourceList { public readonly List<Requirement> Requirements = new List<Requirement>(); public bool Free; public void Add(string itemName, int amount, int quality = 0) { Requirements.Add(new Requirement { itemName = itemName, amount = amount, quality = quality }); } public void Add(string itemName, ConfigEntry<int> amountConfig, int quality = 0) { Requirements.Add(new Requirement { itemName = itemName, amountConfig = amountConfig, quality = quality }); } } [PublicAPI] internal class CraftingStationList { public readonly List<CraftingStationConfig> Stations = new List<CraftingStationConfig>(); public void Add(CraftingTable table, int level) { Stations.Add(new CraftingStationConfig { Table = table, level = level }); } public void Add(string customTable, int level) { Stations.Add(new CraftingStationConfig { Table = CraftingTable.Custom, level = level, custom = customTable }); } } [PublicAPI] internal class ItemRecipe { public readonly RequiredResourceList RequiredItems = new RequiredResourceList(); public readonly RequiredResourceList RequiredUpgradeItems = new RequiredResourceList(); public readonly CraftingStationList Crafting = new CraftingStationList(); public int CraftAmount = 1; public bool RequireOnlyOneIngredient; public float QualityResultAmountMultiplier = 1f; public ConfigEntryBase? RecipeIsActive; } [PublicAPI] internal class Trade { public Trader Trader; public uint Price; public uint Stack = 1u; public string? RequiredGlobalKey; } [PublicAPI] [Flags] internal enum Trader { None = 0, Haldor = 1, Hildir = 2 } internal struct Requirement { public string itemName; public int amount; public ConfigEntry<int>? amountConfig; [Description("Set to a non-zero value to apply the requirement only for a specific quality")] public int quality; } internal struct CraftingStationConfig { public CraftingTable Table; public int level; public string? custom; } [Flags] internal enum Configurability { Disabled = 0, Recipe = 1, Stats = 2, Drop = 4, Trader = 8, Full = 0xF } [PublicAPI] internal class DropTargets { public readonly List<DropTarget> Drops = new List<DropTarget>(); public void Add(string creatureName, float chance, int min = 1, int? max = null, bool levelMultiplier = true, bool dontScale = false) { Drops.Add(new DropTarget { creature = creatureName, chance = chance, min = min, max = (max ?? min), levelMultiplier = levelMultiplier, dontScale = dontScale }); } } internal struct DropTarget { public string creature; public int min; public int max; public float chance; public bool levelMultiplier; public bool dontScale; } internal enum Toggle { On = 1, Off = 0 } [PublicAPI] internal class Item { private class ItemConfig { public ConfigEntry<string>? craft; public ConfigEntry<string>? upgrade; public ConfigEntry<CraftingTable> table; public ConfigEntry<int> tableLevel; public ConfigEntry<string> customTable; public ConfigEntry<int>? maximumTableLevel; public ConfigEntry<Toggle> requireOneIngredient; public ConfigEntry<float> qualityResultAmountMultiplier; } private class TraderConfig { public ConfigEntry<Trader> trader; public ConfigEntry<uint> price; public ConfigEntry<uint> stack; public ConfigEntry<string> requiredGlobalKey; } private class RequirementQuality { public int quality; } private class ConfigurationManagerAttributes { [UsedImplicitly] public int? Order; [UsedImplicitly] public bool? Browsable; [UsedImplicitly] public string? Category; [UsedImplicitly] public Action<ConfigEntryBase>? CustomDrawer; [UsedImplicitly] public Action<IUguiDrawerScope>? CustomUguiDrawer; public Func<bool>? browsability; } [PublicAPI] public enum DamageModifier { Normal, Resistant, Weak, Immune, Ignore, VeryResistant, VeryWeak, None } private delegate void setDmgFunc(ref DamageTypes dmg, float value); private class SerializedRequirements { public readonly List<Requirement> Reqs; public SerializedRequirements(List<Requirement> reqs) { Reqs = reqs; } public SerializedRequirements(string reqs) : this(reqs.Split(new char[1] { ',' }).Select(delegate(string r) { string[] array = r.Split(new char[1] { ':' }); int result; int result2; return new Requirement { itemName = array[0], amount = ((array.Length <= 1 || !int.TryParse(array[1], out result)) ? 1 : result), quality = ((array.Length > 2 && int.TryParse(array[2], out result2)) ? result2 : 0) }; }).ToList()) { } public override string ToString() { return string.Join(",", Reqs.Select((Requirement r) => $"{r.itemName}:{r.amount}")); } public static ItemDrop? fetchByName(ObjectDB objectDB, string name) { GameObject itemPrefab = objectDB.GetItemPrefab(name); ItemDrop obj = (((Object)(object)itemPrefab != (Object)null) ? itemPrefab.GetComponent<ItemDrop>() : null); if ((Object)(object)obj == (Object)null) { LogManager.Log.Warning("The required item '" + name + "' does not exist."); } return obj; } public static Requirement[] toPieceReqs(ObjectDB objectDB, SerializedRequirements craft, SerializedRequirements upgrade) { //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f5: Unknown result type (might be due to invalid IL or missing references) //IL_00fd: Unknown result type (might be due to invalid IL or missing references) //IL_0178: 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_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018c: Unknown result type (might be due to invalid IL or missing references) //IL_018f: Expected O, but got Unknown //IL_0194: Expected O, but got Unknown //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown Dictionary<string, Requirement> dictionary = craft.Reqs.Where((Requirement r) => r.itemName != "").ToDictionary((Func<Requirement, string>)((Requirement r) => r.itemName), (Func<Requirement, Requirement>)delegate(Requirement r) { //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_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown ItemDrop val6 = ResItem(r); return (val6 != null) ? new Requirement { m_amount = (r.amountConfig?.Value ?? r.amount), m_resItem = val6, m_amountPerLevel = 0 } : ((Requirement)null); }); List<Requirement> list = dictionary.Values.Where((Requirement v) => v != null).ToList(); foreach (Requirement item in upgrade.Reqs.Where((Requirement r) => r.itemName != "")) { if (item.quality > 0) { ItemDrop val = ResItem(item); if (val != null) { Requirement val2 = new Requirement { m_resItem = val, m_amountPerLevel = (item.amountConfig?.Value ?? item.amount), m_amount = 0 }; list.Add(val2); requirementQuality.Add(val2, new RequirementQuality { quality = item.quality }); } continue; } if (!dictionary.TryGetValue(item.itemName, out var value) || value == null) { ItemDrop val3 = ResItem(item); if (val3 != null) { string itemName = item.itemName; Requirement val4 = new Requirement { m_resItem = val3, m_amount = 0 }; Requirement val5 = val4; dictionary[itemName] = val4; value = val5; list.Add(value); } } if (value != null) { value.m_amountPerLevel = item.amountConfig?.Value ?? item.amount; } } return list.ToArray(); ItemDrop? ResItem(Requirement r) { return fetchByName(objectDB, r.itemName); } } } private class SerializedDrop { public readonly List<DropTarget> Drops; public SerializedDrop(List<DropTarget> drops) { Drops = drops; } public SerializedDrop(string drops) { Drops = ((drops == "") ? ((IEnumerable<string>)Array.Empty<string>()) : ((IEnumerable<string>)drops.Split(new char[1] { ',' }))).Select(delegate(string r) { string[] array = r.Split(new char[1] { ':' }); if (array.Length <= 2 || !int.TryParse(array[2], out var result)) { result = 1; } if (array.Length <= 3 || !int.TryParse(array[3], out var result2)) { result2 = result; } bool levelMultiplier = array.Length <= 4 || array[4] != "0"; float result3; return new DropTarget { creature = array[0], chance = ((array.Length > 1 && float.TryParse(array[1], out result3)) ? result3 : 1f), min = result, max = result2, levelMultiplier = levelMultiplier }; }).ToList(); } public override string ToString() { return string.Join(",", Drops.Select((DropTarget r) => $"{r.creature}:{r.chance.ToString(CultureInfo.InvariantCulture)}:{r.min}:" + ((r.min == r.max) ? "" : $"{r.max}") + (r.levelMultiplier ? "" : ":0"))); } private static Character? fetchByName(ZNetScene netScene, string name) { GameObject prefab = netScene.GetPrefab(name); Character obj = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<Character>() : null); if ((Object)(object)obj == (Object)null) { LogManager.Log.Debug("The drop target character '" + name + "' does not exist."); } return obj; } public Dictionary<Character, Drop> toCharacterDrops(ZNetScene netScene, GameObject item, bool adjustLevel = false, bool adjustScaling = false) { //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_0033: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_005e: 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_0075: Expected O, but got Unknown Dictionary<Character, Drop> dictionary = new Dictionary<Character, Drop>(); foreach (DropTarget drop in Drops) { Character val = fetchByName(netScene, drop.creature); if (val != null) { dictionary[val] = new Drop { m_prefab = item, m_amountMin = drop.min, m_amountMax = drop.max, m_chance = drop.chance, m_levelMultiplier = adjustLevel, m_dontScale = !adjustScaling }; } } return dictionary; } } private static bool _initialized; private static readonly MethodBase? _itemTarget; private static readonly List<Item> registeredItems; private static readonly Dictionary<ItemDrop, Item> itemDropMap; private static Dictionary<Item, Dictionary<string, List<Recipe>>> activeRecipes; private static Dictionary<Recipe, ConfigEntryBase?> hiddenCraftRecipes; private static Dictionary<Recipe, ConfigEntryBase?> hiddenUpgradeRecipes; private static Dictionary<Item, Dictionary<string, ItemConfig>> itemCraftConfigs; private static Dictionary<Item, ConfigEntry<string>> itemDropConfigs; private static Dictionary<Item, ConfigEntry<bool>> itemDropEnabledConfig; private static Dictionary<Item, ConfigEntry<bool>> itemDropScalingConfig; private static Dictionary<Item, ConfigEntry<bool>> itemDropLevelingConfig; private Dictionary<CharacterDrop, Drop> characterDrops = new Dictionary<CharacterDrop, Drop>(); private readonly Dictionary<ConfigEntryBase, Action> statsConfigs = new Dictionary<ConfigEntryBase, Action>(); private static readonly ConditionalWeakTable<Requirement, RequirementQuality> requirementQuality; public string SectionName = string.Empty; public static Configurability DefaultConfigurability; public Configurability? Configurable; private Configurability configurationVisible = Configurability.Full; private TraderConfig? traderConfig; public readonly GameObject Prefab; [Description("Specifies the maximum required crafting station level to upgrade and repair the item.\nDefault is calculated from crafting station level and maximum quality.")] public int MaximumRequiredStationLevel = int.MaxValue; [Description("Assigns the item as a drop item to a creature.\nUses a creature name, a drop chance and a minimum and maximum amount.")] public readonly DropTargets DropsFrom = new DropTargets(); [Description("Configures whether the item can be bought at the trader.\nDon't forget to set cost to something above 0 or the item will be sold for free.")] public readonly Trade Trade = new Trade(); internal List<Conversion> Conversions = new List<Conversion>(); internal List<ItemConversion> conversions = new List<ItemConversion>(); public Dictionary<string, ItemRecipe> Recipes = new Dictionary<string, ItemRecipe>(); private static object? configManager; private static BaseUnityPlugin? _plugin; private Configurability configurability => Configurable ?? DefaultConfigurability; [Description("Specifies the resources needed to craft the item.\nUse .Add to add resources with their internal ID and an amount.\nUse one .Add for each resource type the item should need.")] public RequiredResourceList RequiredItems => this[""].RequiredItems; [Description("Specifies the resources needed to upgrade the item.\nUse .Add to add resources with their internal ID and an amount. This amount will be multipled by the item quality level.\nUse one .Add for each resource type the upgrade should need.")] public RequiredResourceList RequiredUpgradeItems => this[""].RequiredUpgradeItems; [Description("Specifies the crafting station needed to craft the item.\nUse .Add to add a crafting station, using the CraftingTable enum and a minimum level for the crafting station.\nUse one .Add for each crafting station.")] public CraftingStationList Crafting => this[""].Crafting; [Description("Specifies a config entry which toggles whether a recipe is active.")] public ConfigEntryBase? RecipeIsActive { get { return this[""].RecipeIsActive; } set { this[""].RecipeIsActive = value; } } [Description("Specifies the number of items that should be given to the player with a single craft of the item.\nDefaults to 1.")] public int CraftAmount { get { return this[""].CraftAmount; } set { this[""].CraftAmount = value; } } public bool RequireOnlyOneIngredient { get { return this[""].RequireOnlyOneIngredient; } set { this[""].RequireOnlyOneIngredient = value; } } public float QualityResultAmountMultiplier { get { return this[""].QualityResultAmountMultiplier; } set { this[""].QualityResultAmountMultiplier = value; } } public ItemRecipe this[string name] { get { if (Recipes.TryGetValue(name, out ItemRecipe value)) { return value; } return Recipes[name] = new ItemRecipe(); } } private static BaseUnityPlugin plugin { get { //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Expected O, but got Unknown if ((Object)(object)_plugin == (Object)null) { IEnumerable<TypeInfo> source; try { source = Assembly.GetExecutingAssembly().DefinedTypes.ToList(); } catch (ReflectionTypeLoadException ex) { source = from t in ex.Types where t != null select t.GetTypeInfo(); } _plugin = (BaseUnityPlugin)Chainloader.ManagerObject.GetComponent((Type)source.First((TypeInfo t) => t.IsClass && typeof(BaseUnityPlugin).IsAssignableFrom(t))); } return _plugin; } } static Item() { _initialized = false; _itemTarget = AccessTools.DeclaredMethod(typeof(Item), "Patch_FejdStartup", (Type[])null, (Type[])null); registeredItems = new List<Item>(); itemDropMap = new Dictionary<ItemDrop, Item>(); activeRecipes = new Dictionary<Item, Dictionary<string, List<Recipe>>>(); hiddenCraftRecipes = new Dictionary<Recipe, ConfigEntryBase>(); hiddenUpgradeRecipes = new Dictionary<Recipe, ConfigEntryBase>(); itemCraftConfigs = new Dictionary<Item, Dictionary<string, ItemConfig>>(); itemDropConfigs = new Dictionary<Item, ConfigEntry<string>>(); itemDropEnabledConfig = new Dictionary<Item, ConfigEntry<bool>>(); itemDropScalingConfig = new Dictionary<Item, ConfigEntry<bool>>(); itemDropLevelingConfig = new Dictionary<Item, ConfigEntry<bool>>(); requirementQuality = new ConditionalWeakTable<Requirement, RequirementQuality>(); DefaultConfigurability = Configurability.Full; if (_itemTarget != null) { DynamicPatches.Register(_itemTarget, 848123570u, "Ei8+Ngs6LzgzPik="); } } public static void Init() { if (!_initialized) { _initialized = true; } } public Item(string assetBundleFileName, string prefabName, string folderName = "assets") : this(PrefabManager.RegisterAssetBundle(assetBundleFileName, folderName), prefabName) { } public Item(AssetBundle bundle, string prefabName) : this(PrefabManager.RegisterPrefab(bundle, prefabName, addToObjectDb: true), skipRegistering: true) { } public Item(GameObject prefab, bool skipRegistering = false) { if ((Object)(object)prefab == (Object)null) { LogManager.Log?.Warning("Attempted to initialize Item with a null prefab."); Prefab = null; return; } if (!skipRegistering) { PrefabManager.RegisterPrefab(prefab, addToObjectDb: true); } Prefab = prefab; registeredItems.Add(this); ItemDrop component = Prefab.GetComponent<ItemDrop>(); if ((Object)(object)component != (Object)null) { itemDropMap[component] = this; if (component.m_itemData != null) { component.m_itemData.m_dropPrefab = Prefab; } } } public void ToggleConfigurationVisibility(Configurability visible) { configurationVisible = visible; if (itemDropConfigs.TryGetValue(this, out ConfigEntry<string> value)) { Toggle((ConfigEntryBase)(object)value, Configurability.Drop); } if (itemCraftConfigs.TryGetValue(this, out Dictionary<string, ItemConfig> value2)) { foreach (ItemConfig value4 in value2.Values) { ToggleObj(value4, Configurability.Recipe); } } foreach (Conversion conversion in Conversions) { if (conversion.config != null) { ToggleObj(conversion.config, Configurability.Recipe); } } foreach (KeyValuePair<ConfigEntryBase, Action> statsConfig in statsConfigs) { Toggle(statsConfig.Key, Configurability.Stats); if ((visible & Configurability.Stats) != Configurability.Disabled) { statsConfig.Value(); } } reloadConfigDisplay(); void Toggle(ConfigEntryBase cfg, Configurability check) { object[] tags = cfg.Description.Tags; for (int i = 0; i < tags.Length; i++) { if (tags[i] is ConfigurationManagerAttributes configurationManagerAttributes) { configurationManagerAttributes.Browsable = (visible & check) != Configurability.Disabled && (configurationManagerAttributes.browsability == null || configurationManagerAttributes.browsability()); } } } void ToggleObj(object obj, Configurability check) { FieldInfo[] fields = obj.GetType().GetFields(); for (int i = 0; i < fields.Length; i++) { object? value3 = fields[i].GetValue(obj); ConfigEntryBase val = (ConfigEntryBase)((value3 is ConfigEntryBase) ? value3 : null); if (val != null) { Toggle(val, check); } } } } internal static void reloadConfigDisplay() { object obj = configManager?.GetType().GetProperty("DisplayingWindow").GetValue(configManager); if (obj is bool && (bool)obj) { configManager.GetType().GetMethod("BuildSettingList").Invoke(configManager, Array.Empty<object>()); } } private void UpdateItemTableConfig(string recipeKey, CraftingTable table, string customTableValue) { if (activeRecipes.ContainsKey(this) && activeRecipes[this].TryGetValue(recipeKey, out List<Recipe> value)) { value.First().m_enabled = table != CraftingTable.Disabled; if ((uint)table <= 1u) { value.First().m_craftingStation = null; } else if (table == CraftingTable.Custom) { GameObject prefab = ZNetScene.instance.GetPrefab(customTableValue); value.First().m_craftingStation = (((Object)(object)prefab != (Object)null) ? prefab.GetComponent<CraftingStation>() : null); } else { GameObject prefab2 = ZNetScene.instance.GetPrefab(getInternalName(table)); value.First().m_craftingStation = (((Object)(object)prefab2 != (Object)null) ? prefab2.GetComponent<CraftingStation>() : null); } } } private void UpdateCraftConfig(string recipeKey, SerializedRequirements craftRequirements, SerializedRequirements upgradeRequirements) { if (!Object.op_Implicit((Object)(object)ObjectDB.instance) || !activeRecipes.ContainsKey(this) || !activeRecipes[this].TryGetValue(recipeKey, out List<Recipe> value)) { return; } foreach (Recipe item in value) { item.m_resources = SerializedReq