Decompiled source of Wizards Luggage Items from Another World v1.0.0
plugins/OvrSlepr_Wizard’sLuggageItemsfromAnotherWorld.dll
Decompiled a week 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.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Configuration; using ExitGames.Client.Photon; using HarmonyLib; using Microsoft.CodeAnalysis; using PEAKLib.Core; using Peak.Afflictions; using Photon.Pun; using Photon.Realtime; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.UI; using Zorro.Core; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("OvrSlepr_Wizard’sLuggageItemsfromAnotherWorld")] [assembly: AssemblyConfiguration("Debug")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("OvrSlepr_Wizard’sLuggageItemsfromAnotherWorld")] [assembly: AssemblyTitle("OvrSlepr_Wizard’sLuggageItemsfromAnotherWorld")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } namespace WizardsLuggage { public class AntiPetrificationPotionSoundAction : ItemAction { public override void RunAction() { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Character character = ((ItemActionBase)this).character; if (!((Object)(object)character == (Object)null)) { PotionSoundNetwork.Play(PotionSoundType.AntiPetrification, ((Component)character).transform.position); } } } public class AntiPetrificationSoundNetwork : MonoBehaviour { public static AudioClip? AntiPetrificationClip; [PunRPC] public void PlayAntiPetrificationSound(Vector3 position) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)AntiPetrificationClip == (Object)null)) { GameObject val = new GameObject("AntiPetrificationSound"); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.clip = AntiPetrificationClip; val2.volume = 0.5f; val2.pitch = 1f; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 5f; val2.maxDistance = 500f; val2.Play(); Object.Destroy((Object)(object)val, AntiPetrificationClip.length + 0.5f); } } } [HarmonyPatch(typeof(Character), "Awake")] public static class CharacterNetworkPatch { [HarmonyPostfix] private static void Postfix(Character __instance) { if (!((Object)(object)__instance == (Object)null)) { if ((Object)(object)((Component)__instance).GetComponent<FrostbiteSoundNetwork>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<FrostbiteSoundNetwork>(); } if ((Object)(object)((Component)__instance).GetComponent<HeartOfEternitySoundNetwork>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<HeartOfEternitySoundNetwork>(); } if ((Object)(object)((Component)__instance).GetComponent<MoonShineSoundNetwork>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<MoonShineSoundNetwork>(); } if ((Object)(object)((Component)__instance).GetComponent<AntiPetrificationSoundNetwork>() == (Object)null) { ((Component)__instance).gameObject.AddComponent<AntiPetrificationSoundNetwork>(); } } } } public class ElixirAmbientSounds : MonoBehaviour { [Header("Ambient Sounds")] [SerializeField] private AudioSource? audioSource; [SerializeField] private AudioClip?[] sounds = (AudioClip?[])(object)new AudioClip[3]; [Header("Random Interval")] [SerializeField] private float minInterval = 8f; [SerializeField] private float maxInterval = 20f; private Item? item; private Coroutine? soundRoutine; private int lastSoundIndex = -1; private void Awake() { item = ((Component)this).GetComponent<Item>(); if ((Object)(object)audioSource == (Object)null) { audioSource = ((Component)this).GetComponent<AudioSource>(); } if ((Object)(object)item == (Object)null) { Debug.LogError((object)"[Moon Shine Elixir] Item component not found!", (Object)(object)this); ((Behaviour)this).enabled = false; } else if ((Object)(object)audioSource == (Object)null) { Debug.LogError((object)"[Moon Shine Elixir] AudioSource not found!", (Object)(object)this); ((Behaviour)this).enabled = false; } else { audioSource.playOnAwake = false; audioSource.loop = false; audioSource.spatialBlend = 1f; } } private void OnEnable() { if (!((Object)(object)item == (Object)null)) { Item? obj = item; obj.OnStateChange = (Action<ItemState>)Delegate.Combine(obj.OnStateChange, new Action<ItemState>(HandleStateChange)); CheckItemState(); } } private void Start() { CheckItemState(); } private void OnDisable() { if ((Object)(object)item != (Object)null) { Item? obj = item; obj.OnStateChange = (Action<ItemState>)Delegate.Remove(obj.OnStateChange, new Action<ItemState>(HandleStateChange)); } StopSoundRoutine(); } private void HandleStateChange(ItemState state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)state == 1) { StartSoundRoutine(); } else { StopSoundRoutine(); } } private void CheckItemState() { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Invalid comparison between Unknown and I4 if ((Object)(object)item != (Object)null && (int)item.itemState == 1) { StartSoundRoutine(); } else { StopSoundRoutine(); } } private void StartSoundRoutine() { if (soundRoutine == null) { soundRoutine = ((MonoBehaviour)this).StartCoroutine(PlayRandomSounds()); } } private void StopSoundRoutine() { if (soundRoutine != null) { ((MonoBehaviour)this).StopCoroutine(soundRoutine); soundRoutine = null; } if ((Object)(object)audioSource != (Object)null) { audioSource.Stop(); } } private IEnumerator PlayRandomSounds() { while ((Object)(object)item != (Object)null && (int)item.itemState == 1) { float delay = Random.Range(minInterval, Mathf.Max(minInterval, maxInterval)); yield return (object)new WaitForSeconds(delay); if ((Object)(object)item == (Object)null || (int)item.itemState != 1) { break; } int soundIndex = GetRandomSoundIndex(); if (soundIndex >= 0 && !((Object)(object)audioSource == (Object)null)) { AudioClip clip = sounds[soundIndex]; if ((Object)(object)clip != (Object)null) { audioSource.PlayOneShot(clip); } } } soundRoutine = null; } private int GetRandomSoundIndex() { if (sounds == null || sounds.Length == 0) { return -1; } int num = 0; for (int i = 0; i < sounds.Length; i++) { if ((Object)(object)sounds[i] != (Object)null) { num++; } } switch (num) { case 0: return -1; case 1: { for (int j = 0; j < sounds.Length; j++) { if ((Object)(object)sounds[j] != (Object)null) { return j; } } break; } } int num2; do { num2 = Random.Range(0, sounds.Length); } while ((Object)(object)sounds[num2] == (Object)null || num2 == lastSoundIndex); lastSoundIndex = num2; return num2; } } public class FrostbitePotionAction : ItemAction { public override void RunAction() { //IL_0040: 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_0056: Expected O, but got Unknown //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Expected O, but got Unknown //IL_0070: Unknown result type (might be due to invalid IL or missing references) Character character = ((ItemActionBase)this).character; if (!((Object)(object)character == (Object)null)) { CharacterAfflictions afflictions = character.refs.afflictions; float num = Random.Range(0.02f, 0.55f); afflictions.AddStatus((STATUSTYPE)2, num, false, true, true, false, false); afflictions.AddAffliction((Affliction)new Affliction_Blind { totalTime = 10f }, false); afflictions.AddAffliction((Affliction)new Affliction_Sunscreen(150.001f), false); PotionSoundNetwork.Play(PotionSoundType.Frostbite, ((Component)character).transform.position); } } } public class FrostbiteSoundNetwork : MonoBehaviour { public static AudioClip? FrostbiteClip; [PunRPC] public void PlayFrostbiteSound(Vector3 position) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)FrostbiteClip == (Object)null)) { GameObject val = new GameObject("FrostbiteSound"); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.clip = FrostbiteClip; val2.volume = 0.5f; val2.pitch = 1f; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 5f; val2.maxDistance = 500f; val2.Play(); Object.Destroy((Object)(object)val, FrostbiteClip.length + 0.5f); } } } [HarmonyPatch(typeof(Affliction_Sunscreen), "Stack")] public static class FrostbiteSunscreenStackPatch { private static void Postfix(Affliction_Sunscreen __instance, Affliction incomingAffliction) { if (incomingAffliction != null && Mathf.Abs(incomingAffliction.totalTime - 150.001f) < 0.0001f) { ((Affliction)__instance).totalTime = 150.001f; } } } [HarmonyPatch(typeof(Affliction_Sunscreen), "UpdateEffectNetworked")] public static class FrostbiteSunscreenColorPatch { private static bool Prefix(Affliction_Sunscreen __instance) { //IL_0080: Unknown result type (might be due to invalid IL or missing references) if (Mathf.Abs(((Affliction)__instance).totalTime - 150.001f) >= 0.0001f) { return true; } object? obj = AccessTools.Field(typeof(Affliction), "character")?.GetValue(__instance); Character val = (Character)((obj is Character) ? obj : null); if ((Object)(object)val == (Object)null) { return false; } Color val2 = default(Color); ((Color)(ref val2))..ctor(0.2f, 0.55f, 1f); val.refs.customization.PulseStatus(val2, 1f); return false; } } [HarmonyPatch(typeof(StaminaBar), "Update")] public static class HeartOfEternityBarEffect { private class BarColors { public Color Stamina; public Color Backing; public Color Outline; public Color OutlineCap; } private static readonly Dictionary<StaminaBar, BarColors> OriginalColors = new Dictionary<StaminaBar, BarColors>(); private static readonly Color DeepRed = new Color(0.55f, 0.015f, 0.035f, 1f); private static readonly Color BrightRed = new Color(0.85f, 0.015f, 0.045f, 1f); private static readonly Color DeepBacking = new Color(0.12f, 0.005f, 0.015f, 1f); private static readonly Color BrightBacking = new Color(0.28f, 0.008f, 0.025f, 1f); private static readonly Color DeepOutline = new Color(0.35f, 0.015f, 0.035f, 1f); private static readonly Color BrightOutline = new Color(1f, 0.12f, 0.18f, 1f); [HarmonyPostfix] private static void Postfix(StaminaBar __instance) { //IL_00f8: 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_0109: Unknown result type (might be due to invalid IL or missing references) //IL_010e: 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_011a: 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_012a: 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_0252: 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_025e: Unknown result type (might be due to invalid IL or missing references) //IL_026f: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_027b: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028b: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_0297: Unknown result type (might be due to invalid IL or missing references) //IL_029a: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01a8: 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_02b3: Unknown result type (might be due to invalid IL or missing references) //IL_01d3: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.staminaBar == (Object)null) { return; } Image val = ((Component)__instance.staminaBar).GetComponent<Image>(); if ((Object)(object)val == (Object)null) { val = ((Component)__instance.staminaBar).GetComponentInChildren<Image>(true); } if ((Object)(object)val == (Object)null || (Object)(object)__instance.backing == (Object)null) { return; } Transform val2 = ((Component)__instance).transform.Find("OutlineMask/Outline/OutlineImage"); if ((Object)(object)val2 == (Object)null) { return; } Image component = ((Component)val2).GetComponent<Image>(); if ((Object)(object)component == (Object)null) { return; } Transform val3 = ((Component)__instance).transform.Find("OutlineMask/Outline/OutlineCap"); Image val4 = null; if ((Object)(object)val3 != (Object)null) { val4 = ((Component)val3).GetComponent<Image>(); } if (!OriginalColors.ContainsKey(__instance)) { OriginalColors.Add(__instance, new BarColors { Stamina = ((Graphic)val).color, Backing = ((Graphic)__instance.backing).color, Outline = ((Graphic)component).color, OutlineCap = (((Object)(object)val4 != (Object)null) ? ((Graphic)val4).color : Color.white) }); } BarColors barColors = OriginalColors[__instance]; Character observedCharacter = Character.observedCharacter; HeartOfEternityProtection heartOfEternityProtection = null; if ((Object)(object)observedCharacter != (Object)null) { heartOfEternityProtection = ((Component)observedCharacter).GetComponent<HeartOfEternityProtection>(); } if ((Object)(object)heartOfEternityProtection == (Object)null || !heartOfEternityProtection.IsActive) { ((Graphic)val).color = barColors.Stamina; ((Graphic)__instance.backing).color = barColors.Backing; ((Graphic)component).color = barColors.Outline; if ((Object)(object)val4 != (Object)null) { ((Graphic)val4).color = barColors.OutlineCap; } return; } float num = Time.time % 1.25f; float num2 = Mathf.Exp(0f - Mathf.Pow((num - 0.1f) / 0.075f, 2f)); float num3 = Mathf.Exp(0f - Mathf.Pow((num - 0.32f) / 0.09f, 2f)); float num4 = Mathf.Max(num2, num3 * 0.8f); float num5 = 0.35f + num4 * 0.65f; ((Graphic)val).color = Color.Lerp(DeepRed, BrightRed, num5); ((Graphic)__instance.backing).color = Color.Lerp(DeepBacking, BrightBacking, num5); Color color = (((Graphic)component).color = Color.Lerp(DeepOutline, BrightOutline, num5)); if ((Object)(object)val4 != (Object)null) { ((Graphic)val4).color = color; } } } public class HeartOfEternityElixirAction : ItemAction { public override void RunAction() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) Character character = ((ItemActionBase)this).character; if ((Object)(object)character == (Object)null) { Debug.LogError((object)"[Heart of Eternity] Character is null!"); return; } CharacterAfflictions afflictions = character.refs.afflictions; afflictions.SetStatus((STATUSTYPE)0, 0f, true); HeartOfEternityProtection heartOfEternityProtection = ((Component)character).GetComponent<HeartOfEternityProtection>(); if ((Object)(object)heartOfEternityProtection == (Object)null) { heartOfEternityProtection = ((Component)character).gameObject.AddComponent<HeartOfEternityProtection>(); } heartOfEternityProtection.Activate(60f); PotionSoundNetwork.Play(PotionSoundType.HeartOfEternity, ((Component)character).transform.position); } } [HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")] public static class HeartOfEternityPatch { [HarmonyPrefix] public static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)statusType > 0) { return true; } if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.character == (Object)null) { return true; } HeartOfEternityProtection component = ((Component)__instance.character).GetComponent<HeartOfEternityProtection>(); if ((Object)(object)component == (Object)null || !component.IsActive) { return true; } if (__instance.character.data.isSkeleton) { amount = 0f; return false; } if (Ascents.currentAscent >= 1) { amount *= 0.15f; return true; } amount *= 0.25f; return true; } } [HarmonyPatch(typeof(CharacterClimbing), "CheckFallDamage")] public static class HeartOfEternityClimbingFallPatch { [ThreadStatic] private static bool isClimbingFallDamage; public static bool IsClimbingFallDamage => isClimbingFallDamage; [HarmonyPrefix] private static void Prefix(out bool __state) { __state = isClimbingFallDamage; isClimbingFallDamage = true; } [HarmonyFinalizer] private static Exception Finalizer(Exception __exception, bool __state) { isClimbingFallDamage = __state; return __exception; } } [HarmonyPatch(typeof(Character), "HandleLife")] public static class HeartOfEternitySkeletonLifePatch { [HarmonyPrefix] private static bool Prefix(Character __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.data == (Object)null) { return true; } if (!__instance.data.isSkeleton) { return true; } HeartOfEternityProtection component = ((Component)__instance).GetComponent<HeartOfEternityProtection>(); if ((Object)(object)component == (Object)null || !component.IsActive) { return true; } return false; } } [HarmonyPatch(typeof(Character), "RPCA_Die")] public static class HeartOfEternitySkeletonDeathPatch { [HarmonyPrefix] private static bool Prefix(Character __instance) { if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.data == (Object)null) { return true; } if (!__instance.data.isSkeleton) { return true; } HeartOfEternityProtection component = ((Component)__instance).GetComponent<HeartOfEternityProtection>(); if ((Object)(object)component == (Object)null || !component.IsActive) { return true; } return false; } } public class HeartOfEternityProtection : MonoBehaviour { public float ProtectionTime { get; private set; } public bool IsActive => ProtectionTime > 0f; public void Activate(float duration) { ProtectionTime = duration; } private void Update() { if (ProtectionTime > 0f) { ProtectionTime -= Time.deltaTime; if (ProtectionTime < 0f) { ProtectionTime = 0f; } } } } public class HeartOfEternitySoundNetwork : MonoBehaviour { public static AudioClip? HeartOfEternityClip; [PunRPC] public void PlayHeartOfEternitySound(Vector3 position) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)HeartOfEternityClip == (Object)null)) { GameObject val = new GameObject("HeartOfEternitySound"); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.clip = HeartOfEternityClip; val2.volume = 0.5f; val2.pitch = 1f; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 5f; val2.maxDistance = 500f; val2.Play(); Object.Destroy((Object)(object)val, HeartOfEternityClip.length + 0.5f); } } } public class MoonShineElixirAction : ItemAction { public override void RunAction() { //IL_006e: 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) //IL_00a3: 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_00b9: Expected O, but got Unknown //IL_00c1: Unknown result type (might be due to invalid IL or missing references) Character character = ((ItemActionBase)this).character; if ((Object)(object)character == (Object)null) { Debug.LogError((object)"[Moon Shine] Character is null!"); return; } if (MoonShineShieldCheck.HasAnyShield(character)) { Debug.Log((object)"[Moon Shine] Cannot use: target already has an active shield!"); return; } CharacterAfflictions afflictions = character.refs.afflictions; STATUSTYPE[] array = new STATUSTYPE[12]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); STATUSTYPE[] array2 = (STATUSTYPE[])(object)array; STATUSTYPE[] array3 = array2; foreach (STATUSTYPE val in array3) { afflictions.SubtractStatus(val, 2f, false, false); } afflictions.AddStatus((STATUSTYPE)6, 2f, false, true, true, false, false); afflictions.AddAffliction((Affliction)new Affliction_BingBongShield { totalTime = 78f }, false); PotionSoundNetwork.Play(PotionSoundType.MoonShine, ((Component)character).transform.position); Debug.Log((object)"[Moon Shine] Negative effects cleansed. 200 sleep and 78s shield applied."); } } public class MoonShineHeldSound : MonoBehaviour { public static AudioClip? HeldClip; private Item? item; private AudioSource? audioSource; private void Awake() { item = ((Component)this).GetComponent<Item>(); audioSource = ((Component)this).gameObject.AddComponent<AudioSource>(); audioSource.clip = HeldClip; audioSource.loop = true; audioSource.playOnAwake = false; audioSource.volume = 0.5f; audioSource.spatialBlend = 0f; } private void OnEnable() { //IL_005c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)item == (Object)null) { item = ((Component)this).GetComponent<Item>(); } if ((Object)(object)item != (Object)null) { Item? obj = item; obj.OnStateChange = (Action<ItemState>)Delegate.Combine(obj.OnStateChange, new Action<ItemState>(OnItemStateChanged)); OnItemStateChanged(item.itemState); } } private void OnDisable() { if ((Object)(object)item != (Object)null) { Item? obj = item; obj.OnStateChange = (Action<ItemState>)Delegate.Remove(obj.OnStateChange, new Action<ItemState>(OnItemStateChanged)); } StopHeldSound(); } private void OnItemStateChanged(ItemState state) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 if ((int)state == 1) { StartHeldSound(); } else { StopHeldSound(); } } private void StartHeldSound() { if (!((Object)(object)HeldClip == (Object)null) && !((Object)(object)audioSource == (Object)null) && !audioSource.isPlaying) { audioSource.clip = HeldClip; audioSource.loop = true; audioSource.Play(); } } private void StopHeldSound() { if ((Object)(object)audioSource != (Object)null && audioSource.isPlaying) { audioSource.Stop(); } } private void OnDestroy() { StopHeldSound(); } } public static class MoonShineShieldCheck { public static bool HasAnyShield(Character character) { if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null) { return false; } Affliction val = default(Affliction); if (character.refs.afflictions.HasAfflictionType((AfflictionType)14, ref val)) { return true; } if (character.refs.afflictions.HasAfflictionType((AfflictionType)16, ref val)) { return true; } return false; } } public class MoonShineSoundNetwork : MonoBehaviour { public static AudioClip? MoonShineClip; [PunRPC] public void PlayMoonShineSound(Vector3 position) { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Expected O, but got Unknown //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)MoonShineClip == (Object)null)) { GameObject val = new GameObject("MoonShineSound"); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.clip = MoonShineClip; val2.volume = 0.5f; val2.pitch = 1f; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 5f; val2.maxDistance = 500f; val2.Play(); Object.Destroy((Object)(object)val, MoonShineClip.length + 0.5f); } } } public static class MoonShineTargetFinder { public static Character? GetTarget() { Interaction instance = Interaction.instance; if ((Object)(object)instance == (Object)null || !instance.hasValidTargetCharacter) { return null; } try { Type type = ((object)instance).GetType(); object memberValue = GetMemberValue(type, instance, "bestCharacter"); if (memberValue == null) { return null; } object memberValue2 = GetMemberValue(memberValue.GetType(), memberValue, "character"); return (Character?)((memberValue2 is Character) ? memberValue2 : null); } catch (Exception ex) { Debug.LogError((object)("[Moon Shine] Failed to find target: " + ex)); return null; } } private static object? GetMemberValue(Type type, object instance, string name) { FieldInfo field = type.GetField(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (field != null) { return field.GetValue(instance); } PropertyInfo property = type.GetProperty(name, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (property != null) { return property.GetValue(instance, null); } return null; } } public static class MoonShineItemCheck { public static bool IsMoonShine(Item? item) { if ((Object)(object)item == (Object)null || (Object)(object)((Component)item).gameObject == (Object)null) { return false; } return ((Object)((Component)item).gameObject).name.Replace("(Clone)", "").Trim().Contains("MoonShineElixir"); } } [HarmonyPatch(typeof(Item), "CanUsePrimary")] public static class MoonShineCanUsePrimaryPatch { [HarmonyPostfix] private static void Postfix(Item __instance, ref bool __result) { if (!__result || !MoonShineItemCheck.IsMoonShine(__instance)) { return; } Character holderCharacter = __instance.holderCharacter; if (!((Object)(object)holderCharacter == (Object)null)) { if ((Object)(object)holderCharacter.data != (Object)null && holderCharacter.data.isSkeleton) { __result = false; } else if (MoonShineShieldCheck.HasAnyShield(holderCharacter)) { __result = false; } } } } [HarmonyPatch(typeof(Item), "CanUseSecondary")] public static class MoonShineCanUseSecondaryPatch { [HarmonyPostfix] private static void Postfix(Item __instance, ref bool __result) { if (!__result || !MoonShineItemCheck.IsMoonShine(__instance)) { return; } Character target = MoonShineTargetFinder.GetTarget(); if (!((Object)(object)target == (Object)null)) { if ((Object)(object)target.data != (Object)null && target.data.isSkeleton) { __result = false; } else if (MoonShineShieldCheck.HasAnyShield(target)) { __result = false; } } } } [HarmonyPatch(typeof(Item), "FinishCastSecondary")] public static class MoonShineFinishCastSecondaryPatch { [HarmonyPrefix] private static bool Prefix(Item __instance) { if (!MoonShineItemCheck.IsMoonShine(__instance)) { return true; } Character target = MoonShineTargetFinder.GetTarget(); if ((Object)(object)target == (Object)null) { return true; } bool flag = (Object)(object)target.data != (Object)null && target.data.isSkeleton; bool flag2 = MoonShineShieldCheck.HasAnyShield(target); if (!flag && !flag2) { return true; } Debug.Log((object)"[Moon Shine] Feeding cancelled: target is skeleton or already has a shield."); __instance.CancelUseSecondary(); return false; } } [BepInPlugin("OvrSlepr.WizardsLuggage", "Wizard's Luggage: Items from Another World", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BaseUnityPlugin { public static Plugin Instance { get; private set; } = null; public static ConfigEntry<bool> EnableF8DebugSpawn { get; private set; } = null; public static string PoisonCloudPrefabId { get; private set; } = ""; public static string SporeCloudPrefabId { get; private set; } = ""; public static string MushroomExplosionPrefabId { get; private set; } = ""; public static string DrowsyCloudPrefabId { get; private set; } = ""; public void LogInfo(string message) { ((BaseUnityPlugin)this).Logger.LogInfo((object)message); } public void LogError(string message) { ((BaseUnityPlugin)this).Logger.LogError((object)message); } private void Awake() { //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005e: Expected O, but got Unknown Instance = this; if ((Object)(object)((Component)this).GetComponent<PotionSoundNetwork>() == (Object)null) { ((Component)this).gameObject.AddComponent<PotionSoundNetwork>(); } WizardLuggageConfig.Bind(((BaseUnityPlugin)this).Config); EnableF8DebugSpawn = ((BaseUnityPlugin)this).Config.Bind<bool>("Experimental", "EnableF8DebugSpawn", false, "Enables spawning Wizard's Luggage using F8 for testing purposes."); Harmony val = new Harmony("OvrSlepr.WizardsLuggage"); val.PatchAll(); WizardLuggageLocalization.Apply(); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Wizard's Luggage: Items from Another World loaded!"); BundleLoader.LoadBundleWithName((BaseUnityPlugin)(object)this, "wizardsluggage_itemsfromanotherworld.peakbundle", (Action<PeakBundle>)delegate(PeakBundle peakBundle) { peakBundle.Mod.RegisterContent(); string[] allAssetNames = peakBundle.GetAllAssetNames(); GameObject val2 = null; GameObject val3 = null; GameObject val4 = null; GameObject val5 = null; string[] array = allAssetNames; foreach (string text in array) { if (text.EndsWith("/wizard_vfx_poisonexplo.prefab", StringComparison.OrdinalIgnoreCase)) { val2 = peakBundle.LoadAsset<GameObject>(text); } if (text.EndsWith("/wizard_vfx_sporeexplo.prefab", StringComparison.OrdinalIgnoreCase)) { val3 = peakBundle.LoadAsset<GameObject>(text); } if (text.EndsWith("/wizard_vfx_sporeexploexplo.prefab", StringComparison.OrdinalIgnoreCase)) { val4 = peakBundle.LoadAsset<GameObject>(text); } if (text.EndsWith("/wizard_vfx_drowsyexplo.prefab", StringComparison.OrdinalIgnoreCase)) { val5 = peakBundle.LoadAsset<GameObject>(text); } } if ((Object)(object)val2 != (Object)null) { if ((Object)(object)val2.GetComponent<PhotonView>() == (Object)null) { val2.AddComponent<PhotonView>(); } NetworkPrefabManager.RegisterNetworkPrefab(peakBundle.Mod, val2); PoisonCloudPrefabId = "OvrSlepr.WizardsLuggage:Wizard_VFX_PoisonExplo"; if (NetworkPrefabManager.HasNetworkPrefab(PoisonCloudPrefabId)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Poison cloud registered!"); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Poison cloud network registration failed!"); } } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Custom Wizard_VFX_PoisonExplo prefab not found in bundle!"); } if ((Object)(object)val3 != (Object)null) { if ((Object)(object)val3.GetComponent<PhotonView>() == (Object)null) { val3.AddComponent<PhotonView>(); } NetworkPrefabManager.RegisterNetworkPrefab(peakBundle.Mod, val3); SporeCloudPrefabId = "OvrSlepr.WizardsLuggage:Wizard_VFX_SporeExplo"; if (NetworkPrefabManager.HasNetworkPrefab(SporeCloudPrefabId)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Spore cloud registered!"); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Spore cloud network registration failed!"); } } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Custom Wizard_VFX_SporeExplo prefab not found in bundle!"); } if ((Object)(object)val4 != (Object)null) { if ((Object)(object)val4.GetComponent<PhotonView>() == (Object)null) { val4.AddComponent<PhotonView>(); } NetworkPrefabManager.RegisterNetworkPrefab(peakBundle.Mod, val4); MushroomExplosionPrefabId = "OvrSlepr.WizardsLuggage:Wizard_VFX_SporeExploExplo"; if (NetworkPrefabManager.HasNetworkPrefab(MushroomExplosionPrefabId)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Mushroom explosion registered!"); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Mushroom explosion network registration failed!"); } } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Custom Wizard_VFX_SporeExploExplo prefab not found in bundle!"); } if ((Object)(object)val5 != (Object)null) { if ((Object)(object)val5.GetComponent<PhotonView>() == (Object)null) { val5.AddComponent<PhotonView>(); } NetworkPrefabManager.RegisterNetworkPrefab(peakBundle.Mod, val5); DrowsyCloudPrefabId = "OvrSlepr.WizardsLuggage:Wizard_VFX_DrowsyExplo"; if (NetworkPrefabManager.HasNetworkPrefab(DrowsyCloudPrefabId)) { ((BaseUnityPlugin)this).Logger.LogInfo((object)"Drowsy cloud registered!"); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Drowsy cloud network registration failed!"); } } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Custom Wizard_VFX_DrowsyExplo prefab not found in bundle!"); } FrostbiteSoundNetwork.FrostbiteClip = LoadAudioClip(peakBundle, "frostbitesound"); HeartOfEternitySoundNetwork.HeartOfEternityClip = LoadAudioClip(peakBundle, "heartofeternity_sound"); MoonShineSoundNetwork.MoonShineClip = LoadAudioClip(peakBundle, "moonshine_sound"); AntiPetrificationSoundNetwork.AntiPetrificationClip = LoadAudioClip(peakBundle, "anti-petrificationpotion_sound"); MoonShineHeldSound.HeldClip = LoadAudioClip(peakBundle, "took_moonshine_elixir"); string[] array2 = new string[5] { "OvrSlepr.WizardsLuggage:MoonShineElixir", "OvrSlepr.WizardsLuggage:HeartofEternityElixir", "OvrSlepr.WizardsLuggage:FrostbitePotion", "OvrSlepr.WizardsLuggage:Anti-PetrificationPotion", "Cure-All" }; List<GameObject> list = new List<GameObject>(); string[] array3 = array2; Item val6 = default(Item); foreach (string text2 in array3) { if (ItemDatabase.TryGetItem(text2, ref val6)) { if (text2 == "OvrSlepr.WizardsLuggage:MoonShineElixir") { MoonShineElixirAction moonShineElixirAction = ((Component)val6).gameObject.GetComponent<MoonShineElixirAction>(); if ((Object)(object)moonShineElixirAction == (Object)null) { moonShineElixirAction = ((Component)val6).gameObject.AddComponent<MoonShineElixirAction>(); } ((ItemAction)moonShineElixirAction).OnConsumed = false; ((ItemAction)moonShineElixirAction).OnPressed = false; ((ItemAction)moonShineElixirAction).OnCastFinished = true; MoonShineHeldSound component = ((Component)val6).gameObject.GetComponent<MoonShineHeldSound>(); if ((Object)(object)component == (Object)null) { ((Component)val6).gameObject.AddComponent<MoonShineHeldSound>(); } } if (text2 == "OvrSlepr.WizardsLuggage:FrostbitePotion") { FrostbitePotionAction frostbitePotionAction = ((Component)val6).gameObject.GetComponent<FrostbitePotionAction>(); if ((Object)(object)frostbitePotionAction == (Object)null) { frostbitePotionAction = ((Component)val6).gameObject.AddComponent<FrostbitePotionAction>(); } ((ItemAction)frostbitePotionAction).OnConsumed = false; ((ItemAction)frostbitePotionAction).OnPressed = false; ((ItemAction)frostbitePotionAction).OnCastFinished = true; } if (text2 == "OvrSlepr.WizardsLuggage:HeartofEternityElixir") { HeartOfEternityElixirAction heartOfEternityElixirAction = ((Component)val6).gameObject.GetComponent<HeartOfEternityElixirAction>(); if ((Object)(object)heartOfEternityElixirAction == (Object)null) { heartOfEternityElixirAction = ((Component)val6).gameObject.AddComponent<HeartOfEternityElixirAction>(); } ((ItemAction)heartOfEternityElixirAction).OnConsumed = false; ((ItemAction)heartOfEternityElixirAction).OnPressed = false; ((ItemAction)heartOfEternityElixirAction).OnCastFinished = true; } if (text2 == "OvrSlepr.WizardsLuggage:Anti-PetrificationPotion") { AntiPetrificationPotionSoundAction antiPetrificationPotionSoundAction = ((Component)val6).gameObject.GetComponent<AntiPetrificationPotionSoundAction>(); if ((Object)(object)antiPetrificationPotionSoundAction == (Object)null) { antiPetrificationPotionSoundAction = ((Component)val6).gameObject.AddComponent<AntiPetrificationPotionSoundAction>(); } ((ItemAction)antiPetrificationPotionSoundAction).OnConsumed = false; ((ItemAction)antiPetrificationPotionSoundAction).OnPressed = false; ((ItemAction)antiPetrificationPotionSoundAction).OnCastFinished = true; } if (!list.Contains(((Component)val6).gameObject)) { list.Add(((Component)val6).gameObject); } } else { ((BaseUnityPlugin)this).Logger.LogError((object)("Potion item not found: " + text2)); } } ushort[] array4 = new ushort[16] { 115, 25, 110, 173, 67, 175, 74, 43, 58, 183, 47, 192, 180, 182, 179, 170 }; ushort[] array5 = array4; Item val7 = default(Item); for (int k = 0; k < array5.Length; k++) { ushort num = array5[k]; if (ItemDatabase.TryGetItem(num, ref val7)) { if (!list.Contains(((Component)val7).gameObject)) { list.Add(((Component)val7).gameObject); } } else { ((BaseUnityPlugin)this).Logger.LogWarning((object)("Additional item not found, ID: " + num)); } } WizardLuggage.SetPotionPool(list); ((BaseUnityPlugin)this).Logger.LogInfo((object)("Wizard's Luggage item pool size: " + list.Count)); GameObject val8 = peakBundle.LoadAsset<GameObject>("assets/_МОД/БАГАЖ/wizard's luggage.prefab"); if ((Object)(object)val8 == (Object)null) { ((BaseUnityPlugin)this).Logger.LogError((object)"Wizard's Luggage prefab not found in bundle!"); } else { ((Object)val8).name = "OvrSlepr_WizardLuggage"; WizardLuggageSounds component2 = val8.GetComponent<WizardLuggageSounds>(); if ((Object)(object)component2 == (Object)null) { val8.AddComponent<WizardLuggageSounds>(); } NetworkPrefabManager.RegisterNetworkPrefab(peakBundle.Mod, val8); if (NetworkPrefabManager.HasNetworkPrefab(((Object)val8).name)) { if ((Object)(object)((Component)this).GetComponent<WizardLuggageDebug>() == (Object)null) { ((Component)this).gameObject.AddComponent<WizardLuggageDebug>(); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Wizard's Luggage registered!"); ((BaseUnityPlugin)this).Logger.LogInfo((object)("F8 Debug Spawn: " + (EnableF8DebugSpawn.Value ? "Enabled" : "Disabled"))); } else { ((BaseUnityPlugin)this).Logger.LogError((object)"Wizard's Luggage network registration failed!"); } ((BaseUnityPlugin)this).Logger.LogInfo((object)"Wizard's Luggage: bundle content registered!"); } }); } private AudioClip? LoadAudioClip(PeakBundle peakBundle, string assetNamePart) { string[] allAssetNames = peakBundle.GetAllAssetNames(); foreach (string text in allAssetNames) { if (text.IndexOf(assetNamePart, StringComparison.OrdinalIgnoreCase) >= 0) { AudioClip val = peakBundle.LoadAsset<AudioClip>(text); if ((Object)(object)val != (Object)null) { return val; } } } ((BaseUnityPlugin)this).Logger.LogError((object)("Sound not found: " + assetNamePart)); return null; } } public enum PotionSoundType : byte { AntiPetrification = 1, Frostbite, HeartOfEternity, MoonShine } public class PotionSoundNetwork : MonoBehaviour, IOnEventCallback { private const byte SoundEventCode = 199; private static PotionSoundNetwork? instance; private void OnEnable() { instance = this; PhotonNetwork.AddCallbackTarget((object)this); Debug.Log((object)"[Potion Sound] Network listener registered."); } private void OnDisable() { PhotonNetwork.RemoveCallbackTarget((object)this); if ((Object)(object)instance == (Object)(object)this) { instance = null; } } private void OnDestroy() { if ((Object)(object)instance == (Object)(object)this) { instance = null; } } public static void Play(PotionSoundType soundType, Vector3 position) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_005c: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_0093: Expected O, but got Unknown //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)instance == (Object)null) { Debug.LogError((object)"[Potion Sound] Network listener is not initialized!"); return; } if (!PhotonNetwork.InRoom) { instance.PlayLocal(soundType, position); return; } object[] array = new object[4] { (byte)soundType, position.x, position.y, position.z }; if (!PhotonNetwork.RaiseEvent((byte)199, (object)array, new RaiseEventOptions { Receivers = (ReceiverGroup)1 }, SendOptions.SendReliable)) { Debug.LogWarning((object)"[Potion Sound] Network event failed. Playing locally."); instance.PlayLocal(soundType, position); } } public void OnEvent(EventData photonEvent) { //IL_00ea: Unknown result type (might be due to invalid IL or missing references) if (photonEvent.Code != 199) { return; } if (!(photonEvent.CustomData is object[] array) || array.Length < 4) { Debug.LogWarning((object)"[Potion Sound] Invalid event data."); return; } if (array[0] is byte b && array[1] is float num && array[2] is float num2) { object obj = array[3]; float num3 = default(float); int num4; if (obj is float) { num3 = (float)obj; num4 = 1; } else { num4 = 0; } if (num4 != 0) { PotionSoundType soundType = (PotionSoundType)b; Vector3 position = default(Vector3); ((Vector3)(ref position))..ctor(num, num2, num3); if (!((Object)(object)instance == (Object)null)) { instance.PlayLocal(soundType, position); } return; } } Debug.LogWarning((object)"[Potion Sound] Incorrect event data types."); } private void PlayLocal(PotionSoundType soundType, Vector3 position) { //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Expected O, but got Unknown //IL_005a: Unknown result type (might be due to invalid IL or missing references) AudioClip clip = GetClip(soundType); if ((Object)(object)clip == (Object)null) { Debug.LogError((object)("[Potion Sound] AudioClip is missing: " + soundType)); return; } GameObject val = new GameObject("PotionSound_" + soundType); val.transform.position = position; AudioSource val2 = val.AddComponent<AudioSource>(); val2.clip = clip; val2.volume = 0.5f; val2.pitch = 1f; val2.spatialBlend = 1f; val2.rolloffMode = (AudioRolloffMode)1; val2.minDistance = 5f; val2.maxDistance = 500f; val2.dopplerLevel = 0f; val2.Play(); Object.Destroy((Object)(object)val, clip.length + 0.5f); Debug.Log((object)("[Potion Sound] Playing: " + soundType)); } private AudioClip? GetClip(PotionSoundType soundType) { return (AudioClip?)(soundType switch { PotionSoundType.AntiPetrification => AntiPetrificationSoundNetwork.AntiPetrificationClip, PotionSoundType.Frostbite => FrostbiteSoundNetwork.FrostbiteClip, PotionSoundType.HeartOfEternity => HeartOfEternitySoundNetwork.HeartOfEternityClip, PotionSoundType.MoonShine => MoonShineSoundNetwork.MoonShineClip, _ => null, }); } } public class WizardLuggage : Luggage { private class WeightedItem { public GameObject Prefab; public Item ItemComponent; public float Weight; public WeightedItem(GameObject prefab, Item itemComponent, float weight) { Prefab = prefab; ItemComponent = itemComponent; Weight = weight; } } private static readonly List<WeightedItem> PotionPool = new List<WeightedItem>(); private static readonly Dictionary<ushort, float> ItemWeights = new Dictionary<ushort, float> { { 74, 15f }, { 183, 0.1f }, { 173, 20f }, { 110, 20f }, { 43, 32f }, { 115, 35f }, { 47, 1f }, { 175, 21f }, { 67, 10f }, { 25, 18.5f }, { 192, 15f }, { 58, 15f }, { 180, 1f }, { 182, 1f }, { 179, 1f }, { 170, 1f } }; private static readonly Dictionary<string, float> PotionWeights = new Dictionary<string, float>(StringComparer.OrdinalIgnoreCase) { { "Cure-All", 35f }, { "MoonShineElixir", 20f }, { "HeartofEternityElixir", 13f }, { "FrostbitePotion", 25f }, { "Anti-PetrificationPotion", 40f } }; private const float DefaultWeight = 100f; private static float GetItemWeight(Item item) { if ((Object)(object)item == (Object)null) { return 0f; } if (ItemWeights.TryGetValue(item.itemID, out var value)) { return Mathf.Max(0f, value); } string name = ((Object)((Component)item).gameObject).name; name = name.Replace("(Clone)", "").Trim(); if (PotionWeights.TryGetValue(name, out var value2)) { return Mathf.Max(0f, value2); } return 100f; } public static void SetPotionPool(List<GameObject> potions) { PotionPool.Clear(); if (potions == null) { return; } foreach (GameObject potion in potions) { if ((Object)(object)potion == (Object)null) { continue; } Item component = potion.GetComponent<Item>(); if ((Object)(object)component == (Object)null) { Plugin.Instance.LogInfo("[Wizard Luggage] Item component missing: " + ((Object)potion).name); continue; } float itemWeight = GetItemWeight(component); if (itemWeight <= 0f) { Plugin.Instance.LogInfo("[Wizard Luggage] Item disabled by weight: " + ((Object)potion).name); } else { PotionPool.Add(new WeightedItem(potion, component, itemWeight)); } } Plugin.Instance.LogInfo("[Wizard Luggage] Weighted item pool size: " + PotionPool.Count); } private static bool IsItemValid(WeightedItem entry) { if (entry == null || (Object)(object)entry.ItemComponent == (Object)null || (Object)(object)entry.Prefab == (Object)null) { return false; } try { return entry.ItemComponent.IsValidToSpawn(); } catch (Exception ex) { Plugin.Instance.LogError("[Wizard Luggage] IsValidToSpawn failed for " + ((Object)entry.Prefab).name + ": " + ex.Message); return false; } } public static List<GameObject> GetRandomPotions(int spawnCount, bool canRepeat = false) { List<GameObject> list = new List<GameObject>(); if (PotionPool.Count == 0 || spawnCount <= 0) { return list; } List<WeightedItem> list2 = new List<WeightedItem>(); foreach (WeightedItem item in PotionPool) { if (IsItemValid(item)) { list2.Add(item); } } if (list2.Count == 0) { Plugin.Instance.LogInfo("[Wizard Luggage] No valid items available!"); return list; } int num = (canRepeat ? spawnCount : Mathf.Min(spawnCount, list2.Count)); for (int i = 0; i < num; i++) { float num2 = 0f; foreach (WeightedItem item2 in list2) { num2 += item2.Weight; } if (num2 <= 0f) { break; } float num3 = Random.Range(0f, num2); float num4 = 0f; WeightedItem weightedItem = list2[list2.Count - 1]; foreach (WeightedItem item3 in list2) { num4 += item3.Weight; if (num3 < num4) { weightedItem = item3; break; } } list.Add(weightedItem.Prefab); Plugin.Instance.LogInfo("[Wizard Luggage] Selected item: " + ((Object)weightedItem.Prefab).name + " | Weight: " + weightedItem.Weight); if (!canRepeat) { list2.Remove(weightedItem); } } return list; } protected override List<GameObject> GetObjectsToSpawn(int spawnCount, bool canRepeat = false) { return GetRandomPotions(spawnCount, canRepeat); } } [HarmonyPatch(typeof(MapHandler), "JumpToSegmentLogic")] internal static class WizardLuggageBiomeDebug { private unsafe static void Postfix(Segment newSegment) { //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0086: 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) if (!PhotonNetwork.IsMasterClient) { return; } MapHandler instance = Singleton<MapHandler>.Instance; if ((Object)(object)instance == (Object)null) { Debug.Log((object)"[Wizard Luggage BIOME DEBUG] MapHandler is NULL!"); return; } MapSegment currentMapSegment = MapHandler.CurrentMapSegment; Debug.Log((object)("[Wizard Luggage BIOME DEBUG] Segment: " + ((object)(*(Segment*)(&newSegment))/*cast due to .constrained prefix*/).ToString() + " | Current segment index: " + ((object)MapHandler.CurrentSegmentNumber/*cast due to .constrained prefix*/).ToString() + " | Selected biome: " + ((object)currentMapSegment.biome/*cast due to .constrained prefix*/).ToString())); GameObject segmentParent = currentMapSegment.segmentParent; if ((Object)(object)segmentParent == (Object)null) { Debug.Log((object)"[Wizard Luggage BIOME DEBUG] Segment parent is NULL!"); return; } Biome[] componentsInChildren = segmentParent.GetComponentsInChildren<Biome>(true); Biome[] array = componentsInChildren; foreach (Biome val in array) { Debug.Log((object)("[Wizard Luggage BIOME DEBUG] Biome object: " + ((Object)((Component)val).gameObject).name + " | BiomeType: " + ((object)Unsafe.As<BiomeType, BiomeType>(ref val.biomeType)/*cast due to .constrained prefix*/).ToString() + " | Active: " + ((Component)val).gameObject.activeInHierarchy)); } } } internal static class WizardLuggageConfig { public static ConfigEntry<bool> Enabled; public static ConfigEntry<float> SpawnChance; public static ConfigEntry<int> MinAmount; public static ConfigEntry<int> MaxAmount; public static ConfigEntry<float> MushroomChance; public static ConfigEntry<float> SporeChance; public static ConfigEntry<float> PoisonChance; public static ConfigEntry<float> DrowsyChance; public static ConfigEntry<float> NoSurpriseChance; public static void Bind(ConfigFile config) { Enabled = config.Bind<bool>("Wizard Luggage", "Enabled", true, "Enable or disable Wizard's Luggage spawning."); SpawnChance = config.Bind<float>("Wizard Luggage", "SpawnChance", 85f, "Individual chance for each Wizard's Luggage to spawn (0-100%)."); MinAmount = config.Bind<int>("Wizard Luggage", "MinAmount", 1, "Minimum number of potential Wizard's Luggage spawns (1-6)."); MaxAmount = config.Bind<int>("Wizard Luggage", "MaxAmount", 6, "Maximum number of potential Wizard's Luggage spawns (1-6)."); MushroomChance = config.Bind<float>("Surprise Chances", "MushroomExplosion", 33f, "Relative chance of Mushroom Explosion."); SporeChance = config.Bind<float>("Surprise Chances", "SporeCloud", 40f, "Relative chance of Spore Cloud."); PoisonChance = config.Bind<float>("Surprise Chances", "PoisonCloud", 30f, "Relative chance of Poison Cloud."); DrowsyChance = config.Bind<float>("Surprise Chances", "DrowsyCloud", 50f, "Relative chance of Drowsy Cloud."); NoSurpriseChance = config.Bind<float>("Surprise Chances", "NoSurprise", 100f, "Relative chance of opening luggage without a surprise."); } } internal class WizardLuggageDebug : MonoBehaviour { private void Update() { //IL_00b6: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) //IL_00c2: Unknown result type (might be due to invalid IL or missing references) //IL_00c7: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00d8: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Unknown result type (might be due to invalid IL or missing references) //IL_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00e6: Unknown result type (might be due to invalid IL or missing references) //IL_0113: Unknown result type (might be due to invalid IL or missing references) //IL_0118: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) //IL_01f6: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) if (Plugin.EnableF8DebugSpawn == null || !Plugin.EnableF8DebugSpawn.Value || !Input.GetKeyDown((KeyCode)289)) { return; } Debug.Log((object)"[Wizard Luggage] F8 PRESSED!"); if (!PhotonNetwork.IsMasterClient) { Debug.LogWarning((object)"[Wizard Luggage] Only host can spawn luggage!"); return; } if ((Object)(object)Player.localPlayer == (Object)null) { Debug.LogWarning((object)"[Wizard Luggage] Local player not found!"); return; } Character character = Player.localPlayer.character; if ((Object)(object)character == (Object)null) { Debug.LogWarning((object)"[Wizard Luggage] Character not found!"); return; } Vector3 forward = ((Component)character).transform.forward; Vector3 val = ((Component)character).transform.position + forward * 2f; Quaternion val2 = Quaternion.LookRotation(forward); try { GameObject val3 = NetworkPrefabManager.SpawnNetworkPrefab("OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage", val, val2, (byte)0, (object[])null); Debug.Log((object)("[Wizard Luggage] SPAWNED: " + ((Object)val3).name)); Debug.Log((object)("[Wizard Luggage] Position: " + ((object)val3.transform.position/*cast due to .constrained prefix*/).ToString())); Debug.Log((object)("[Wizard Luggage] Active: " + val3.activeInHierarchy)); Renderer[] componentsInChildren = val3.GetComponentsInChildren<Renderer>(true); Debug.Log((object)("[Wizard Luggage] Renderer count: " + componentsInChildren.Length)); Renderer[] array = componentsInChildren; foreach (Renderer val4 in array) { string[] obj = new string[8] { "[Wizard Luggage] Renderer: ", ((Object)val4).name, " | Enabled: ", val4.enabled.ToString(), " | Active: ", ((Component)val4).gameObject.activeInHierarchy.ToString(), " | Bounds center: ", null }; Bounds bounds = val4.bounds; obj[7] = ((object)((Bounds)(ref bounds)).center/*cast due to .constrained prefix*/).ToString(); Debug.Log((object)string.Concat(obj)); } } catch (Exception ex) { Debug.LogError((object)("[Wizard Luggage] Spawn failed: " + ex)); } } } public static class WizardLuggageLocalization { public static void Apply() { Dictionary<string, List<string>> mainTable = LocalizedText.mainTable; mainTable["NAME_MOON SHINE ELIXIR"] = new List<string> { "MOON SHINE ELIXIR", "ÉLIXIR DE LUMIÈRE LUNAIRE", "ELISIRIO DEL CHIARO DI LUNA", "MONDSCHEIN-ELIXIER", "ELIXIR DE LUZ DE LUNA", "ELIXIR DE LUZ DE LUNA", "ELIXIR DO LUAR", "ЭЛИКСИР ЛУННОГО СВЕТА", "ЕЛІКСИР МІСЯЧНОГО СЯЙВА", "月光灵药", "月光靈藥", "月光のエリクサー", "달빛 영약", "ELIXIR KSIĘŻYCOWEGO BLASKU", "AY IŞIĞI İKSİRİ" }; mainTable["NAME_HEART OF ETERNITY ELIXIR"] = new List<string> { "HEART OF ETERNITY ELIXIR", "ÉLIXIR DU CŒUR ÉTERNEL", "ELISIR DEL CUORE ETERNO", "ELIXIER DES EWIGEN HERZENS", "ELIXIR DEL CORAZÓN ETERNO", "ELIXIR DEL CORAZÓN ETERNO", "ELIXIR DO CORAÇÃO ETERNO", "ЭЛИКСИР СЕРДЦА ВЕЧНОСТИ", "ЕЛІКСИР СЕРЦЯ ВІЧНОСТІ", "永恒之心灵药", "永恆之心靈藥", "永遠の心のエリクサー", "영원의 심장 영약", "ELIXIR WIECZNEGO SERCA", "EBEDİYET KALBİ İKSİRİ" }; mainTable["NAME_FROSTBITE POTION"] = new List<string> { "FROSTBITE POTION", "POTION DE GELURE", "POZIONE DEL CONGELAMENTO", "ERFRIERUNGSTRANK", "POCIÓN DE CONGELACIÓN", "POCIÓN DE CONGELACIÓN", "POÇÃO DE CONGELAMENTO", "ЗЕЛЬЕ ОБМОРОЖЕНИЯ", "ЗІЛЛЯ ОБМОРОЖЕННЯ", "冻伤药水", "凍傷藥水", "凍傷のポーション", "동상 물약", "MIKSTURA ODMROŻEŃ", "DONMA İKSİRİ" }; mainTable["NAME_ANTI-PETRIFICATION POTION"] = new List<string> { "ANTI-PETRIFICATION", "ANTI-PÉTRIFICATION", "ANTIPETRIFICAZIONE", "ENTPETRIFIZIERUNG", "ANTIPETRIFICACIÓN", "ANTIPETRIFICACIÓN", "ANTIPETRIFICAÇÃO", "ПРОТИВООКАМЕНЕНИЕ", "ПРОТИВОКАМ'ЯНІННЯ", "反石化", "反石化", "石化解除", "석화 방지", "ANTYPETRYFIKACJA", "TAŞLAŞMA ÖNLEYİCİ" }; mainTable["NAME_WIZARD'S LUGGAGE"] = new List<string> { "WIZARD'S LUGGAGE", "BAGAGE DU SORCIER", "BAGAGLIO DEL MAGO", "ZAUBERER-GEPÄCK", "EQUIPAJE DEL MAGO", "EQUIPAJE DEL MAGO", "BAGAGEM DO MAGO", "БАГАЖ ВОЛШЕБНИКА", "БАГАЖ ЧАРІВНИКА", "巫师的行李", "巫師的行李", "魔法使いの荷物", "마법사의 짐", "BAGAŻ CZARODZIEJA", "BÜYÜCÜNÜN BAGAJI" }; mainTable["WIZARD'S LUGGAGE"] = new List<string> { "WIZARD'S LUGGAGE", "BAGAGE DU SORCIER", "BAGAGLIO DEL MAGO", "ZAUBERER-GEPÄCK", "EQUIPAJE DEL MAGO", "EQUIPAJE DEL MAGO", "BAGAGEM DO MAGO", "БАГАЖ ВОЛШЕБНИКА", "БАГАЖ ЧАРІВНИКА", "巫师的行李", "巫師的行李", "魔法使いの荷物", "마법사의 짐", "BAGAŻ CZARODZIEJA", "BÜYÜCÜNÜN BAGAJI" }; } } [HarmonyPatch(typeof(LocalizedText), "LoadMainTable")] public static class WizardLuggageLocalizationPatch { [HarmonyPostfix] public static void Postfix() { WizardLuggageLocalization.Apply(); } } [HarmonyPatch(typeof(Spawner), "GetObjectsToSpawn")] internal static class WizardLuggagePatch { private static bool Prefix(Spawner __instance, int spawnCount, bool canRepeat, ref List<GameObject> __result) { if ((Object)(object)__instance == (Object)null) { return true; } Debug.Log((object)("[Wizard Luggage DEBUG] GetObjectsToSpawn called! | Name: " + ((Object)__instance).name + " | Type: " + ((object)__instance).GetType().FullName + " | Count: " + spawnCount)); if (!((Object)__instance).name.Contains("OvrSlepr_WizardLuggage")) { Debug.Log((object)"[Wizard Luggage DEBUG] Not our luggage. Original method used."); return true; } Debug.Log((object)"[Wizard Luggage DEBUG] OUR LUGGAGE DETECTED!"); __result = WizardLuggage.GetRandomPotions(spawnCount, canRepeat); Debug.Log((object)("[Wizard Luggage] Custom potion selection: " + __result.Count)); return false; } } public class WizardLuggageRenderer : MonoBehaviour { private void Awake() { ApplyRendering(); } private void Start() { ApplyRendering(); } public void ApplyRendering() { MeshRenderer[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshRenderer>(true); MeshRenderer[] array = componentsInChildren; foreach (MeshRenderer val in array) { if ((Object)(object)val == (Object)null) { continue; } ((Renderer)val).enabled = true; ((Renderer)val).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val).receiveShadows = true; ((Renderer)val).forceRenderingOff = false; Material[] sharedMaterials = ((Renderer)val).sharedMaterials; Material[] array2 = sharedMaterials; foreach (Material val2 in array2) { if (!((Object)(object)val2 == (Object)null)) { Debug.Log((object)("[Wizard Luggage Renderer] " + ((Object)val).name + " | Material: " + ((Object)val2).name + " | Shader: " + (((Object)(object)val2.shader != (Object)null) ? ((Object)val2.shader).name : "NULL") + " | Queue: " + val2.renderQueue)); } } } SkinnedMeshRenderer[] componentsInChildren2 = ((Component)this).GetComponentsInChildren<SkinnedMeshRenderer>(true); SkinnedMeshRenderer[] array3 = componentsInChildren2; foreach (SkinnedMeshRenderer val3 in array3) { if (!((Object)(object)val3 == (Object)null)) { ((Renderer)val3).enabled = true; ((Renderer)val3).shadowCastingMode = (ShadowCastingMode)1; ((Renderer)val3).receiveShadows = true; ((Renderer)val3).forceRenderingOff = false; } } Debug.Log((object)"[Wizard Luggage Renderer] Rendering settings applied."); } } internal static class WizardLuggageSpawnManager { private const string PrefabKey = "OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage"; private const float PollInterval = 0.5f; private const int AttemptsPerItem = 50; private const float RayHeight = 5f; private const float MinimumGroundNormal = 0.55f; private const int VerticalSamples = 5; private static float nextPollTime; private static int lastLoggedSegment = int.MinValue; private static readonly HashSet<int> ProcessedSegments = new HashSet<int>(); private static readonly Dictionary<int, int> PendingSpawns = new Dictionary<int, int>(); private static readonly RaycastHit[] RaycastBuffer = (RaycastHit[])(object)new RaycastHit[256]; private static readonly Collider[] OverlapBuffer = (Collider[])(object)new Collider[128]; private static readonly HashSet<Collider> SegmentColliders = new HashSet<Collider>(); public static void ResetRun() { ProcessedSegments.Clear(); PendingSpawns.Clear(); nextPollTime = 0f; lastLoggedSegment = int.MinValue; Debug.Log((object)"[Wizard Luggage] New run: spawn history reset."); } public static void Tick() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected I4, but got Unknown //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0080: Invalid comparison between Unknown and I4 //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Invalid comparison between Unknown and I4 if (!PhotonNetwork.IsMasterClient || !PhotonNetwork.InRoom || !WizardLuggageConfig.Enabled.Value || !MapHandler.ExistsAndInitialized || Time.unscaledTime < nextPollTime) { return; } nextPollTime = Time.unscaledTime + 0.5f; int num = (int)MapHandler.CurrentSegmentNumber; if (num >= 0 && (int)MapHandler.CurrentSegmentNumber != 5 && (int)MapHandler.CurrentSegmentNumber != 6) { if (num != lastLoggedSegment) { lastLoggedSegment = num; Debug.Log((object)("[Wizard Luggage] Random surface spawn: segment " + num)); } TrySpawnForSegment(num); } } private static bool TryGetSegmentBounds(GameObject segmentParent, GameObject segmentCampfire, out Bounds bounds) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) bounds = default(Bounds); bool initialized = false; if ((Object)(object)segmentParent == (Object)null) { return false; } SegmentColliders.Clear(); AddBoundsFromRoot(segmentParent, ref bounds, ref initialized, collectColliders: true); if ((Object)(object)segmentCampfire != (Object)null) { AddBoundsFromRoot(segmentCampfire, ref bounds, ref initialized, collectColliders: false); } return initialized; } private static void AddBoundsFromRoot(GameObject root, ref Bounds bounds, ref bool initialized, bool collectColliders) { //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0106: 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) Collider[] componentsInChildren = root.GetComponentsInChildren<Collider>(true); Collider[] array = componentsInChildren; foreach (Collider val in array) { if (!((Object)(object)val == (Object)null) && val.enabled && ((Component)val).gameObject.activeInHierarchy && !val.isTrigger) { if (collectColliders) { SegmentColliders.Add(val); } if (!initialized) { bounds = val.bounds; initialized = true; } else { ((Bounds)(ref bounds)).Encapsulate(val.bounds); } } } Renderer[] componentsInChildren2 = root.GetComponentsInChildren<Renderer>(true); Renderer[] array2 = componentsInChildren2; foreach (Renderer val2 in array2) { if (!((Object)(object)val2 == (Object)null) && val2.enabled && ((Component)val2).gameObject.activeInHierarchy) { if (!initialized) { bounds = val2.bounds; initialized = true; } else { ((Bounds)(ref bounds)).Encapsulate(val2.bounds); } } } } private static bool HasClearance(Vector3 position, Collider groundCollider) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_002d: 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_0034: Unknown result type (might be due to invalid IL or missing references) Vector3 val = position + Vector3.up * 0.6f; Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0.35f, 0.55f, 0.35f); int num = Physics.OverlapBoxNonAlloc(val, val2, OverlapBuffer, Quaternion.identity, -5, (QueryTriggerInteraction)1); if (num >= OverlapBuffer.Length) { return false; } for (int i = 0; i < num; i++) { Collider val3 = OverlapBuffer[i]; if (!((Object)(object)val3 == (Object)null) && !((Object)(object)val3 == (Object)(object)groundCollider)) { return false; } } return true; } private static bool TryFindRandomSurface(Bounds bounds, out Vector3 position, out Quaternion rotation) { //IL_0002: 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_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_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00cc: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: 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_0116: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_0208: 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_0219: 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_0223: Unknown result type (might be due to invalid IL or missing references) //IL_0225: Unknown result type (might be due to invalid IL or missing references) //IL_0240: Unknown result type (might be due to invalid IL or missing references) //IL_0242: Unknown result type (might be due to invalid IL or missing references) //IL_0247: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0253: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_026c: Unknown result type (might be due to invalid IL or missing references) //IL_027a: Unknown result type (might be due to invalid IL or missing references) //IL_027f: Unknown result type (might be due to invalid IL or missing references) //IL_0284: Unknown result type (might be due to invalid IL or missing references) //IL_016c: Unknown result type (might be due to invalid IL or missing references) //IL_0187: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_01d9: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) position = Vector3.zero; rotation = Quaternion.identity; float num = Random.Range(((Bounds)(ref bounds)).min.x, ((Bounds)(ref bounds)).max.x); float num2 = Random.Range(((Bounds)(ref bounds)).min.z, ((Bounds)(ref bounds)).max.z); Vector3 val = default(Vector3); for (int i = 0; i < 5; i++) { float num3 = ((i != 0) ? Random.Range(((Bounds)(ref bounds)).min.y + 0.5f, ((Bounds)(ref bounds)).max.y) : (((Bounds)(ref bounds)).max.y + 5f)); ((Vector3)(ref val))..ctor(num, num3, num2); float num4 = Mathf.Max(1f, num3 - ((Bounds)(ref bounds)).min.y + 5f); int num5 = Physics.RaycastNonAlloc(val, Vector3.down, RaycastBuffer, num4, -5, (QueryTriggerInteraction)1); if (num5 == 0) { continue; } float num6 = float.MaxValue; RaycastHit val2 = default(RaycastHit); bool flag = false; for (int j = 0; j < num5; j++) { RaycastHit val3 = RaycastBuffer[j]; if (!((Object)(object)((RaycastHit)(ref val3)).collider == (Object)null) && SegmentColliders.Contains(((RaycastHit)(ref val3)).collider) && !(((RaycastHit)(ref val3)).distance >= num6) && !(((RaycastHit)(ref val3)).normal.y < 0.55f) && !(((RaycastHit)(ref val3)).point.y < ((Bounds)(ref bounds)).min.y - 2f) && !(((RaycastHit)(ref val3)).point.y > ((Bounds)(ref bounds)).max.y + 2f)) { num6 = ((RaycastHit)(ref val3)).distance; val2 = val3; flag = true; } } if (flag) { Vector3 val4 = ((RaycastHit)(ref val2)).point + ((RaycastHit)(ref val2)).normal * 0.05f; if (HasClearance(val4, ((RaycastHit)(ref val2)).collider)) { position = val4; Quaternion val5 = Quaternion.FromToRotation(Vector3.up, ((RaycastHit)(ref val2)).normal); float num7 = Random.Range(0f, 360f); rotation = val5 * Quaternion.Euler(0f, num7, 0f); return true; } } } return false; } private static int CalculateSuccessfulSpawnChecks(int segmentIndex) { int num = Mathf.Clamp(WizardLuggageConfig.MinAmount.Value, 1, 6); int num2 = Mathf.Clamp(WizardLuggageConfig.MaxAmount.Value, num, 6); int num3 = Random.Range(num, num2 + 1); float num4 = Mathf.Clamp(WizardLuggageConfig.SpawnChance.Value, 0f, 100f); int num5 = 0; Debug.Log((object)("[Wizard Luggage] Starting individual spawn checks. | Segment: " + segmentIndex + " | Potential luggage: " + num3 + " | Individual chance: " + num4 + "%")); for (int i = 0; i < num3; i++) { float num6 = Random.Range(0f, 100f); bool flag = num6 < num4; Debug.Log((object)("[Wizard Luggage] Chance check " + (i + 1) + "/" + num3 + " | Roll: " + num6.ToString("F2") + " | Chance: " + num4 + " | Result: " + (flag ? "PASSED" : "FAILED"))); if (flag) { num5++; } } Debug.Log((object)("[Wizard Luggage] Segment " + segmentIndex + " | Potential: " + num3 + " | Passed: " + num5)); return num5; } public unsafe static void TrySpawnForSegment(int segmentIndex) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Invalid comparison between Unknown and I4 //IL_0045: Unknown result type (might be due to invalid IL or missing references) //IL_004b: Invalid comparison between Unknown and I4 //IL_01cb: Unknown result type (might be due to invalid IL or missing references) //IL_01d1: Invalid comparison between Unknown and I4 //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01e5: Unknown result type (might be due to invalid IL or missing references) //IL_0205: Unknown result type (might be due to invalid IL or missing references) //IL_0207: 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_0241: Unknown result type (might be due to invalid IL or missing references) if (ProcessedSegments.Contains(segmentIndex) || !PhotonNetwork.IsMasterClient || !MapHandler.ExistsAndInitialized || (int)MapHandler.CurrentSegmentNumber == 5 || (int)MapHandler.CurrentSegmentNumber == 6) { return; } MapSegment currentMapSegment = MapHandler.CurrentMapSegment; if (currentMapSegment == null || (Object)(object)currentMapSegment.segmentParent == (Object)null) { return; } GameObject segmentParent = currentMapSegment.segmentParent; GameObject segmentCampfire = currentMapSegment.segmentCampfire; if (!TryGetSegmentBounds(segmentParent, segmentCampfire, out var bounds)) { Debug.LogWarning((object)"[Wizard Luggage] Could not get segment bounds."); return; } if (!PendingSpawns.ContainsKey(segmentIndex)) { int num = CalculateSuccessfulSpawnChecks(segmentIndex); PendingSpawns[segmentIndex] = num; if (num <= 0) { PendingSpawns.Remove(segmentIndex); ProcessedSegments.Add(segmentIndex); Debug.Log((object)("[Wizard Luggage] Segment " + segmentIndex + ": no luggage passed individual spawn checks.")); return; } } int num2 = PendingSpawns[segmentIndex]; int num3 = 0; int num4 = num2 * 50; Debug.Log((object)("[Wizard Luggage] Searching surfaces. | Segment: " + segmentIndex + " | Biome: " + ((object)currentMapSegment.biome/*cast due to .constrained prefix*/).ToString() + " | Requested: " + num2 + " | Attempts: " + num4 + " | Bounds: " + ((object)(*(Bounds*)(&bounds))/*cast due to .constrained prefix*/).ToString())); for (int i = 0; i < num4; i++) { if (num3 >= num2) { break; } if (!MapHandler.ExistsAndInitialized || (int)MapHandler.CurrentSegmentNumber != segmentIndex) { return; } if (!TryFindRandomSurface(bounds, out var position, out var rotation)) { continue; } try { GameObject val = NetworkPrefabManager.SpawnNetworkPrefab("OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage", position, rotation, (byte)0, (object[])null); if (!((Object)(object)val == (Object)null)) { num3++; Debug.Log((object)("[Wizard Luggage] RANDOM SPAWNED | Biome: " + ((object)currentMapSegment.biome/*cast due to .constrained prefix*/).ToString() + " | Segment: " + segmentIndex + " | Position: " + ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString())); } } catch (Exception ex) { Debug.LogError((object)("[Wizard Luggage] Spawn failed: " + ex)); } } if (num3 > 0) { int num5 = Mathf.Max(0, PendingSpawns[segmentIndex] - num3); if (num5 == 0) { PendingSpawns.Remove(segmentIndex); ProcessedSegments.Add(segmentIndex); } else { PendingSpawns[segmentIndex] = num5; } Debug.Log((object)("[Wizard Luggage] Segment " + segmentIndex + ": spawned " + num3 + " | Remaining: " + num5)); } else { Debug.LogWarning((object)"[Wizard Luggage] No valid random surface found. Will retry without rerolling individual chances."); } } } [HarmonyPatch(typeof(MapHandler), "InitializeMap")] internal static class WizardLuggageInitializePatch { [HarmonyPostfix] private static void Postfix() { if (PhotonNetwork.IsMasterClient) { WizardLuggageSpawnManager.ResetRun(); } } } [HarmonyPatch(typeof(MapHandler), "Update")] internal static class WizardLuggageAutomaticSpawnPatch { [HarmonyPostfix] private static void Postfix() { WizardLuggageSpawnManager.Tick(); } } internal class WizardLuggageScanner : MonoBehaviour { private const string WizardLuggagePrefab = "OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage"; private readonly HashSet<int> processedLocations = new HashSet<int>(); private float scanTimer; private float debugTimer; private const float ScanInterval = 5f; private void Awake() { Debug.Log((object)"[Wizard Luggage] SCANNER AWAKE!"); } private void Update() { //IL_00db: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: 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_01bc: 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_01bf: Invalid comparison between Unknown and I4 //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01c3: Invalid comparison between Unknown and I4 //IL_0250: Unknown result type (might be due to invalid IL or missing references) debugTimer += Time.deltaTime; if (debugTimer >= 5f) { debugTimer = 0f; Debug.Log((object)("[Wizard Luggage] SCANNER STATUS | Master: " + PhotonNetwork.IsMasterClient + " | InRoom: " + PhotonNetwork.InRoom + " | Map: " + MapHandler.ExistsAndInitialized + " | Enabled: " + WizardLuggageConfig.Enabled.Value)); if (MapHandler.ExistsAndInitialized) { GameObject segmentParent = MapHandler.CurrentMapSegment.segmentParent; Debug.Log((object)("[Wizard Luggage] SEGMENT CHECK | Segment: " + ((object)MapHandler.CurrentSegmentNumber/*cast due to .constrained prefix*/).ToString() + " | Parent exists: " + ((Object)(object)segmentParent != (Object)null) + " | Parent name: " + (((Object)(object)segmentParent != (Object)null) ? ((Object)segmentParent).name : "NULL") + " | Processed: " + ((Object)(object)segmentParent != (Object)null && processedLocations.Contains(((Object)segmentParent).GetInstanceID())))); } } if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || !WizardLuggageConfig.Enabled.Value || !MapHandler.ExistsAndInitialized) { return; } Segment currentSegmentNumber = MapHandler.CurrentSegmentNumber; if ((int)currentSegmentNumber == 5 || (int)currentSegmentNumber == 6) { return; } GameObject segmentParent2 = MapHandler.CurrentMapSegment.segmentParent; if ((Object)(object)segmentParent2 == (Object)null) { return; } int instanceID = ((Object)segmentParent2).GetInstanceID(); if (processedLocations.Contains(instanceID)) { return; } scanTimer += Time.deltaTime; if (!(scanTimer < 5f)) { scanTimer = 0f; if (NetworkPrefabManager.HasNetworkPrefab("OvrSlepr_WizardLuggage")) { ProcessCurrentSegment(currentSegmentNumber, segmentParent2, instanceID); } } } private unsafe void ProcessCurrentSegment(Segment segment, GameObject segmentParent, int locationID) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_03d8: Unknown result type (might be due to invalid IL or missing references) //IL_03dd: 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_03eb: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f5: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)segmentParent == (Object)null || MapHandler.CurrentSegmentNumber != segment || (Object)(object)MapHandler.CurrentMapSegment.segmentParent != (Object)(object)segmentParent) { return; } Luggage[] componentsInChildren = segmentParent.GetComponentsInChildren<Luggage>(true); List<Luggage> list = new List<Luggage>(); Luggage[] array = componentsInChildren; foreach (Luggage val in array) { if (!((Object)(object)val == (Object)null)) { PhotonView component = ((Component)val).GetComponent<PhotonView>(); Debug.Log((object)("[Wizard Luggage] BAG FOUND | Name: " + ((Object)val).name + " | Type: " + ((object)val).GetType().FullName + " | Active: " + ((Component)val).gameObject.activeInHierarchy + " | IsOpen: " + val.IsOpen + " | PhotonView: " + ((Object)(object)component != (Object)null) + " | ViewID: " + (((Object)(object)component != (Object)null) ? component.ViewID : 0) + " | IsRoomView: " + ((Object)(object)component != (Object)null && component.IsRoomView) + " | IsMine: " + ((Object)(object)component != (Object)null && component.IsMine))); if (((Component)val).gameObject.activeInHierarchy && !val.IsOpen && !((Object)val).name.Contains("OvrSlepr_WizardLuggage") && !((Object)(object)component == (Object)null) && component.ViewID != 0 && component.IsRoomView && component.IsMine) { list.Add(val); } } } Debug.Log((object)("[Wizard Luggage] LOCATION SCAN | Segment: " + ((object)(*(Segment*)(&segment))/*cast due to .constrained prefix*/).ToString() + " | Found: " + componentsInChildren.Length + " | Candidates: " + list.Count)); if (list.Count == 0) { Debug.Log((object)"[Wizard Luggage] No suitable luggage found. Retrying."); return; } float num = Mathf.Clamp(WizardLuggageConfig.SpawnChance.Value, 0f, 100f); if (Random.Range(0f, 100f) >= num) { processedLocations.Add(locationID); Debug.Log((object)"[Wizard Luggage] Spawn chance failed."); return; } int num2 = Mathf.Max(0, WizardLuggageConfig.MinAmount.Value); int num3 = Mathf.Max(0, WizardLuggageConfig.MaxAmount.Value); if (num2 > num3) { int num4 = num2; num2 = num3; num3 = num4; } int num5 = Random.Range(num2, num3 + 1); num5 = Mathf.Min(num5, list.Count); Debug.Log((object)("[Wizard Luggage] Selected replacements: " + num5)); for (int num6 = list.Count - 1; num6 > 0; num6--) { int index = Random.Range(0, num6 + 1); Luggage value = list[num6]; list[num6] = list[index]; list[index] = value; } int num7 = 0; for (int j = 0; j < num5; j++) { Luggage val2 = list[j]; if ((Object)(object)val2 == (Object)null) { continue; } Vector3 position = ((Component)val2).transform.position; Quaternion rotation = ((Component)val2).transform.rotation; try { GameObject val3 = NetworkPrefabManager.SpawnNetworkPrefab("OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage", position, rotation, (byte)0, (object[])null); if ((Object)(object)val3 == (Object)null) { Debug.LogError((object)"[Wizard Luggage] Spawn returned NULL!"); continue; } PhotonView component2 = val3.GetComponent<PhotonView>(); if ((Object)(object)component2 == (Object)null || component2.ViewID == 0) { Debug.LogError((object)"[Wizard Luggage] New bag has no valid PhotonView!"); continue; } string name = ((Object)val2).name; PhotonNetwork.Destroy(((Component)val2).gameObject); num7++; Debug.Log((object)("[Wizard Luggage] REPLACED | Original: " + name + " | New: " + ((Object)val3).name + " | Position: " + ((object)(*(Vector3*)(&position))/*cast due to .constrained prefix*/).ToString() + " | ViewID: " + component2.ViewID)); } catch (Exception ex) { Debug.LogError((object)("[Wizard Luggage] Replacement error: " + ex)); } } processedLocations.Add(locationID); Debug.Log((object)("[Wizard Luggage] FINISHED | Replaced: " + num7 + " | Selected: " + num5)); } } [HarmonyPatch(typeof(MapHandler), "JumpToSegmentLogic")] internal static class WizardLuggageSegmentPatch { private const string WizardLuggagePrefab = "OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage"; private const string WizardLuggageName = "OvrSlepr_WizardLuggage"; private static readonly HashSet<int> ProcessedSegments = new HashSet<int>(); private unsafe static void Postfix(Segment newSegment) { //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Invalid comparison between Unknown and I4 //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Invalid comparison between Unknown and I4 //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Expected I4, but got Unknown //IL_03f4: Unknown result type (might be due to invalid IL or missing references) //IL_03f9: Unknown result type (might be due to invalid IL or missing references) //IL_0402: Unknown result type (might be due to invalid IL or missing references) //IL_0407: Unknown result type (might be due to invalid IL or missing references) //IL_040f: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.InRoom || !PhotonNetwork.IsMasterClient || !WizardLuggageConfig.Enabled.Value || (int)newSegment == 5 || (int)newSegment == 6) { return; } if (!NetworkPrefabManager.HasNetworkPrefab("OvrSlepr_WizardLuggage")) { Debug.LogError((object)"[Wizard Luggage] Network prefab is not registered!"); return; } int item = (int)newSegment; if (ProcessedSegments.Contains(item)) { return; } ProcessedSegments.Add(item); MapSegment currentMapSegment = MapHandler.CurrentMapSegment; HashSet<Luggage> hashSet = new HashSet<Luggage>(); if ((Object)(object)currentMapSegment.segmentParent != (Object)null) { Luggage[] componentsInChildren = currentMapSegment.segmentParent.GetComponentsInChildren<Luggage>(true); Luggage[] array = componentsInChildren; foreach (Luggage val in array) { if ((Object)(object)val != (Object)null) { hashSet.Add(val); } } } if ((Object)(object)currentMapSegment.segmentCampfire != (Object)null) { Luggage[] componentsInChildren2 = currentMapSegment.segmentCampfire.GetComponentsInChildren<Luggage>(true); Luggage[] array2 = componentsInChildren2; foreach (Luggage val2 in array2) { if ((Object)(object)val2 != (Object)null) { hashSet.Add(val2); } } } List<Luggage> list = new List<Luggage>(); HashSet<int> hashSet2 = new HashSet<int>(); foreach (Luggage item2 in hashSet) { if (!((Object)(object)item2 == (Object)null) && !item2.IsOpen) { PhotonView val3 = ((Component)item2).GetComponent<PhotonView>(); if ((Object)(object)val3 == (Object)null) { val3 = ((Component)item2).GetComponentInParent<PhotonView>(); } if (!((Object)(object)val3 == (Object)null) && val3.ViewID != 0 && hashSet2.Add(val3.ViewID) && !((Object)((Component)val3).gameObject).name.Contains("OvrSlepr_WizardLuggage")) { list.Add(item2); } } } Debug.Log((object)("[Wizard Luggage] Segment: " + ((object)(*(Segment*)(&newSegment))/*cast due to .constrained prefix*/).ToString() + " | Found luggage: " + list.Count)); if (list.Count == 0) { return; } float num = Mathf.Clamp(WizardLuggageConfig.SpawnChance.Value, 0f, 100f); if (Random.Range(0f, 100f) >= num) { Debug.Log((object)"[Wizard Luggage] Segment spawn chance failed."); return; } int num2 = Mathf.Max(0, WizardLuggageConfig.MinAmount.Value); int num3 = Mathf.Max(0, WizardLuggageConfig.MaxAmount.Value); if (num2 > num3) { int num4 = num2; num2 = num3; num3 = num4; } int num5 = Random.Range(num2, num3 + 1); num5 = Mathf.Min(num5, list.Count); for (int num6 = list.Count - 1; num6 > 0; num6--) { int index = Random.Range(0, num6 + 1); Luggage value = list[num6]; list[num6] = list[index]; list[index] = value; } int num7 = 0; for (int k = 0; k < num5; k++) { Luggage val4 = list[k]; if ((Object)(object)val4 == (Object)null) { continue; } PhotonView val5 = ((Component)val4).GetComponent<PhotonView>(); if ((Object)(object)val5 == (Object)null) { val5 = ((Component)val4).GetComponentInParent<PhotonView>(); } if ((Object)(object)val5 == (Object)null || val5.ViewID == 0 || !val5.IsMine) { continue; } Vector3 position = ((Component)val5).transform.position; Quaternion rotation = ((Component)val5).transform.rotation; try { GameObject val6 = NetworkPrefabManager.SpawnNetworkPrefab("OvrSlepr.WizardsLuggage:OvrSlepr_WizardLuggage", position, rotation, (byte)0, (object[])null); if (!((Object)(object)val6 == (Object)null)) { PhotonView component = val6.GetComponent<PhotonView>(); if ((Object)(object)component == (Object)null || component.ViewID == 0) { Debug.LogError((object)"[Wizard Luggage] Invalid PhotonView on new luggage!"); continue; } string name = ((Object)((Component)val5).gameObject).name; PhotonNetwork.Destroy(((Component)val5).gameObject); num7++; Debug.Log((object)("[Wizard Luggage] REPLACED! | Segment: " + ((object)(*(Segment*)(&newSegment))/*cast due to .constrained prefix*/).ToString() + " | Original: " + name + " | New: " + ((Object)val6).name + " | ViewID: " + component.ViewID)); } } catch (Exception ex) { Debug.LogError((object)("[Wizard Luggage] Replacement error: " + ex)); } } Debug.Log((object)("[Wizard Luggage] SEGMENT COMPLETE: " + ((object)(*(Segment*)(&newSegment))/*cast due to .constrained prefix*/).ToString() + " | Replaced: " + num7 + "/" + num5)); } } public class WizardLuggageSounds : MonoBehaviour { private SFX_PlayOneShot? latch1; private SFX_PlayOneShot? latch2; private SFX_PlayOneShot? opened; private void Awake() { latch1 = FindSound("SFX Latch 1"); latch2 = FindSound("SFX Latch 2"); opened = FindSound("SFX Opened"); Debug.Log((object)"[Wizard Luggage] Sound components initialized."); } private SFX_PlayOneShot? FindSound(string objectName) { Transform val = ((Component)this).transform.Find("SFX/" + objectName); if ((Object)(object)val == (Object)null) { Debug.LogWarning((object)("[Wizard Luggage] Sound object not found: " + objectName)); return null; } return ((Component)val).GetComponent<SFX_PlayOneShot>(); } public void PlayLatch1() { SFX_PlayOneShot? obj = latch1; if (obj != null) { obj.Play(); } } public void PlayLatch2() { SFX_PlayOneShot? obj = latch2; if (obj != null) { obj.Play(); } } public void PlayOpened() { SFX_PlayOneShot? obj = opened; if (obj != null) { obj.Play(); } } } [HarmonyPatch(typeof(Luggage), "OpenLuggageRPC")] public static class WizardLuggageOpenPatch { private const string WizardLuggageName = "OvrSlepr_WizardLuggage"; private static readonly HashSet<Luggage> TriggeredLuggage = new HashSet<Luggage>(); private static void Postfix(Luggage __instance, bool spawnItems) { if (!((Object)(object)__instance == (Object)null) && spawnItems && ((Object)__instance).name.Contains("OvrSlepr_WizardLuggage") && PhotonNetwork.IsMasterClient && !TriggeredLuggage.Contains(__instance)) { TriggeredLuggage.Add(__instance); Plugin.Instance.LogInfo("[Wizard Surprise] Wizard luggage detected!"); ((MonoBehaviour)Plugin.Instance).StartCoroutine(SpawnSurprise(__instance)); } } private static IEnumerator SpawnSurprise(Luggage luggage) { Plugin.Instance.LogInfo("[Wizard Surprise] Random selection started!"); yield return (object)new WaitForSeconds(2.3f); if ((Object)(object)luggage == (Object)null || !PhotonNetwork.IsMasterClient) { yield break; } float mushroomChance = Mathf.Max(0f, WizardLuggageConfig.MushroomChance.Value); float sporeChance = Mathf.Max(0f, WizardLuggageConfig.SporeChance.Value); float poisonChance = Mathf.Max(0f, WizardLuggageConfig.PoisonChance.Value); float drowsyChance = Mathf.Max(0f, WizardLuggageConfig.DrowsyChance.Value); float noSurpriseChance = Mathf.Max(0f, WizardLuggageConfig.NoSurpriseChance.Value); float totalChance = mushroomChance + sporeChance + poisonChance + drowsyChance + noSurpriseChance; float rollRange = Mathf.Max(100f, totalChance); Plugin.Instance.LogInfo("[Wizard Surprise] Config chances: Mushroom=" + mushroomChance + "%, Spore=" + sporeChance + "%, Poison=" + poisonChance + "%, Drowsy=" + drowsyChance + "%, NoSurprise=" + noSurpriseChance + "%"); Plugin.Instance.LogInfo("[Wizard Surprise] Total: " + totalChance.ToString("F2") + "% | Roll range: " + rollRange.ToString("F2")); if (totalChance <= 0f) { Plugin.Instance.LogInfo("[Wizard Surprise] All chances are zero. Normal opening."); yield break; } float roll = Random.Range(0f, rollRange); string prefabId = ""; string surpriseName = ""; float currentLimit = 0f; currentLimit += mushroomChance; if (roll < currentLimit) { prefabId = Plugin.MushroomExplosionPrefabId; surpriseName = "Mushroom Explosion"; } else { currentLimit += sporeChance; if (roll < currentLimit) { prefabId = Plugin.SporeCloudPrefabId; surpriseName = "Spore Cloud"; } else { currentLimit += poisonChance; if (roll < currentLimit) { prefabId = Plugin.PoisonCloudPrefabId; surpriseName = "Poison Cloud"; } else { currentLimit += drowsyChance; if (roll < currentLimit) { prefabId = Plugin.DrowsyCloudPrefabId; surpriseName = "Drowsy Cloud"; } else { currentLimit += noSurpriseChance; if (roll < currentLimit) { surpriseName = "No Surprise"; } } } } } Plugin.Instance.LogInfo("[Wizard Surprise] Roll: " + roll.ToString("F2") + " / " + rollRange.ToString("F2") + " | Selected: " + (string.IsNullOrEmpty(surpriseName) ? "No Surprise" : surpriseName)); if (string.IsNullOrEmpty(prefabId)) { Plugin.Instance.LogInfo("[Wizard Surprise] Normal opening. No surprise."); yield break; } if (string.IsNullOrEmpty(prefabId)) { Plugin.Instance.LogError("[Wizard Surprise] Prefab ID is empty: " + surpriseName); yield break; } if (!NetworkPrefabManager.HasNetworkPrefab(prefabId)) { Plugin.Instance.LogError("[Wizard Surprise] Prefab not registered: " + prefabId); yield break; } GameObject spawnedEffect; try { spawnedEffect = PhotonNetwork.Instantiate(prefabId, ((Component)luggage).transform.position, Quaternion.identity, (byte)0, (object[])null); } catch (Exception ex) { Plugin.Instance.LogError("[Wizard Surprise] Spawn exception: " + ex); yield break; } if ((Object)(object)spawnedEffect != (Object)null) { Plugin.Instance.LogInfo("[Wizard Surprise] " + surpriseName + " spawned successfully!"); } else { Plugin.Instance.LogError("[Wizard Surprise] Instantiate returned NULL: " + surpriseName); } } } [Har