using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Logging; using HarmonyLib; using Microsoft.CodeAnalysis; using Photon.Pun; using UnityEngine; using UnityEngine.SceneManagement; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("mycampfirebuilding")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("mycampfirebuilding")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("BD480A63-2F10-4ADD-A5A3-F2E3F6BD8B6F")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("1.0.0.0")] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)] internal sealed class RefSafetyRulesAttribute : Attribute { public readonly int Version; public RefSafetyRulesAttribute(int P_0) { Version = P_0; } } } namespace Campfire_Building_Fix { [BepInPlugin("HnskNoah.Campfire_Building_Fix", "Campfire Building Fix", "1.0.0")] public class CampfireBuildingPlugin : BaseUnityPlugin { [CompilerGenerated] private sealed class d__6 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CampfireBuildingPlugin <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0024: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Expected O, but got Unknown int num = <>1__state; CampfireBuildingPlugin campfireBuildingPlugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(2f); <>1__state = 1; return true; case 1: <>1__state = -1; campfireBuildingPlugin.SpawnFirewoodNearNaturalObjects(); return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class d__4 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CampfireBuildingPlugin <>4__this; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Expected O, but got Unknown int num = <>1__state; CampfireBuildingPlugin campfireBuildingPlugin = <>4__this; switch (num) { default: return false; case 0: <>1__state = -1; goto IL_004b; case 1: <>1__state = -1; goto IL_004b; case 2: { <>1__state = -1; campfireBuildingPlugin.SpawnFirewoodNearNaturalObjects(); return false; } IL_004b: if (!PhotonNetwork.InRoom || !Object.op_Implicit((Object)(object)Character.localCharacter) || LoadingScreenHandler.loading) { <>2__current = (object)new WaitForSeconds(1f); <>1__state = 1; return true; } <>2__current = (object)new WaitForSeconds(3f); <>1__state = 2; return true; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static CampfireBuildingPlugin instance; private readonly Harmony harmony = new Harmony("HnskNoah.Campfire_Building_Fix"); public static ManualLogSource logger; private void Awake() { instance = this; logger = ((BaseUnityPlugin)this).Logger; logger.LogInfo((object)"Plugin Campfire Building is loaded!"); harmony.PatchAll(); SceneManager.activeSceneChanged += OnSceneChanged; ((MonoBehaviour)this).StartCoroutine(WaitForRunStart()); } [IteratorStateMachine(typeof(d__4))] private IEnumerator WaitForRunStart() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__4(0) { <>4__this = this }; } private void OnSceneChanged(Scene oldScene, Scene newScene) { if (((Scene)(ref newScene)).name != "Airport" && ((Scene)(ref newScene)).name != ((Scene)(ref oldScene)).name) { ((MonoBehaviour)this).StartCoroutine(SpawnFirewoodAfterSceneLoad()); } } [IteratorStateMachine(typeof(d__6))] private IEnumerator SpawnFirewoodAfterSceneLoad() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__6(0) { <>4__this = this }; } public void SpawnFirewoodNearNaturalObjects() { //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_015b: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) if (!PhotonNetwork.IsMasterClient) { logger.LogInfo((object)"Not master client, skipping firewood spawning"); return; } try { GameObject[] array = Object.FindObjectsByType((FindObjectsSortMode)0); int num = 0; int currentAscent = Ascents.currentAscent; logger.LogInfo((object)$"Current ascent level: {currentAscent}"); GameObject[] array2 = array; foreach (GameObject val in array2) { string text = ((Object)val).name.ToLower(); float num2 = 0f; int num3 = 1; if (text.Contains("tree") || text.Contains("pine")) { num2 = ((currentAscent >= 6) ? 0.01f : ((currentAscent < 3) ? 0.03f : 0.02f)); } else if (text.Contains("bush")) { num2 = 0.01f; } else if (text.Contains("nest")) { num2 = 1f; num3 = ((currentAscent >= 3) ? 1 : 2); } else if (text.Contains("tumbleweed")) { num2 = 1f; num3 = ((currentAscent >= 3) ? 1 : 2); } if (num2 > 0f && Random.Range(0f, 1f) < num2) { for (int j = 0; j < num3; j++) { Vector3 position = val.transform.position + new Vector3(Random.Range(-5f, 5f), Random.Range(0f, 2f), Random.Range(-5f, 5f)); SpawnFirewoodAtPosition(position); num++; } } } if (num > 0) { logger.LogInfo((object)$"Spawned {num} firewood items near natural objects"); } } catch { } } public void CleanupOldFirewood() { if (!PhotonNetwork.IsMasterClient) { logger.LogInfo((object)"Not master client, skipping firewood cleanup"); return; } try { Item[] array = Object.FindObjectsByType((FindObjectsSortMode)0); int num = 0; Item[] array2 = array; foreach (Item val in array2) { if (val.itemID == 28 && (Object)(object)((Component)val).gameObject != (Object)null) { PhotonNetwork.Destroy(((Component)val).gameObject); num++; } } if (num > 0) { logger.LogInfo((object)$"Cleaned up {num} old firewood items"); } } catch { } } private void SpawnFirewoodAtPosition(Vector3 position) { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) try { GameObject val = PhotonNetwork.Instantiate("0_Items/FireWood", position, Random.rotation, (byte)0, (object[])null); if ((Object)(object)val != (Object)null) { Item component = val.GetComponent(); if ((Object)(object)component != (Object)null) { component.itemID = 28; } } } catch { } } private void OnDestroy() { harmony.UnpatchSelf(); SceneManager.activeSceneChanged -= OnSceneChanged; } } [HarmonyPatch] public static class CampfirePatches { [CompilerGenerated] private sealed class d__2 : IEnumerator, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public d__2(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if ((Object)(object)CampfireBuildingPlugin.instance != (Object)null) { CampfireBuildingPlugin.instance.CleanupOldFirewood(); } <>2__current = (object)new WaitForSeconds(10f); <>1__state = 1; return true; case 1: <>1__state = -1; if ((Object)(object)CampfireBuildingPlugin.instance != (Object)null) { CampfireBuildingPlugin.instance.SpawnFirewoodNearNaturalObjects(); } return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [HarmonyPatch(typeof(Campfire), "Awake")] [HarmonyPostfix] public static void Awake_Postfix(Campfire __instance) { EnhancedCampfireSystem.SetFireWoodCount(__instance, 0); } [HarmonyPatch(typeof(MapHandler), "GoToSegment")] [HarmonyPostfix] public static void GoToSegment_Postfix(MapHandler __instance, Segment s) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) ((MonoBehaviour)__instance).StartCoroutine(SpawnFirewoodInNewSegment()); } [IteratorStateMachine(typeof(d__2))] private static IEnumerator SpawnFirewoodInNewSegment() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new d__2(0); } [HarmonyPatch(typeof(Campfire), "SetFireWoodCount")] [HarmonyPrefix] public static bool SetFireWoodCount_Prefix(Campfire __instance, int count) { EnhancedCampfireSystem.SetFireWoodCount(__instance, count); return false; } [HarmonyPatch(typeof(Campfire), "GetInteractionText")] [HarmonyPrefix] public static bool GetInteractionText_Prefix(Campfire __instance, ref string __result) { __result = EnhancedCampfireSystem.GetInteractionText(__instance); return false; } [HarmonyPatch(typeof(Campfire), "Interact")] [HarmonyPrefix] public static bool Interact_Prefix(Campfire __instance, Character interactor) { return EnhancedCampfireSystem.Interact(__instance, interactor); } [HarmonyPatch(typeof(Campfire), "Interact_CastFinished")] [HarmonyPrefix] public static bool Interact_CastFinished_Prefix(Campfire __instance, Character interactor) { return EnhancedCampfireSystem.Interact_CastFinished(__instance, interactor); } } public static class EnhancedCampfireSystem { private static Dictionary firewoodCounts = new Dictionary(); private static int GetRequiredFirewood() { if (PhotonNetwork.CurrentRoom == null) { return 3; } if (PhotonNetwork.CurrentRoom.PlayerCount <= 4) { return 3; } return 6; } private static int GetFirewoodCount(Campfire campfire) { if (firewoodCounts.ContainsKey(campfire)) { return firewoodCounts[campfire]; } return 0; } private static void SetFirewoodCount(Campfire campfire, int count) { firewoodCounts[campfire] = count; } public static void SetFireWoodCount(Campfire campfire, int count) { SetFirewoodCount(campfire, count); int requiredFirewood = GetRequiredFirewood(); CampfireBuildingPlugin.logger.LogInfo((object)$" SetFireWoodCount called with count: {count}, required: {requiredFirewood}, players: {PhotonNetwork.CurrentRoom.PlayerCount}"); Transform val = FindLogsObject(campfire); if ((Object)(object)val != (Object)null) { CampfireBuildingPlugin.logger.LogInfo((object)$" logRoot found! Name: {((Object)val).name}, Child count: {val.childCount}"); for (int i = 0; i < val.childCount; i++) { ((Component)val.GetChild(i)).gameObject.SetActive(false); } if (requiredFirewood == 3) { if (count >= 1) { SetLogActive(val, 0, active: true); SetLogActive(val, 5, active: true); SetLogActive(val, 6, active: true); SetLogActive(val, 7, active: true); } if (count >= 2) { SetLogActive(val, 2, active: true); SetLogActive(val, 3, active: true); } if (count >= 3) { SetLogActive(val, 1, active: true); SetLogActive(val, 4, active: true); } return; } if (count >= 1) { SetLogActive(val, 0, active: true); } if (count >= 2) { SetLogActive(val, 5, active: true); } if (count >= 3) { SetLogActive(val, 2, active: true); } if (count >= 4) { SetLogActive(val, 3, active: true); } if (count >= 5) { SetLogActive(val, 1, active: true); } if (count >= 6) { SetLogActive(val, 4, active: true); } } else { CampfireBuildingPlugin.logger.LogError((object)" Could not find Logs object!"); } } private static Transform FindLogsObject(Campfire campfire) { if ((Object)(object)campfire.logRoot != (Object)null) { CampfireBuildingPlugin.logger.LogInfo((object)(" Found logRoot via field: " + ((Object)campfire.logRoot).name)); return campfire.logRoot; } return FindLogsRecursive(((Component)campfire).transform, 0); } private static Transform FindLogsRecursive(Transform parent, int depth) { if (depth > 3) { return null; } for (int i = 0; i < parent.childCount; i++) { Transform child = parent.GetChild(i); if (((Object)child).name.Contains("Logs")) { CampfireBuildingPlugin.logger.LogInfo((object)$" Found logRoot at depth {depth}: {((Object)child).name}"); return child; } Transform val = FindLogsRecursive(child, depth + 1); if ((Object)(object)val != (Object)null) { return val; } } return null; } private static void SetLogActive(Transform logRoot, int index, bool active) { if (index < logRoot.childCount) { Transform child = logRoot.GetChild(index); if ((Object)(object)child != (Object)null) { ((Component)child).gameObject.SetActive(active); CampfireBuildingPlugin.logger.LogInfo((object)string.Format(" Log {0}: {1} -> {2}", index, ((Object)child).name, active ? "ON" : "OFF")); } } } public static string GetInteractionText(Campfire campfire) { if (!campfire.Lit) { int firewoodCount = GetFirewoodCount(campfire); int requiredFirewood = GetRequiredFirewood(); string text = default(string); if (!campfire.EveryoneInRange(ref text, 15f)) { if (firewoodCount >= requiredFirewood) { return text; } return GetLocalizedAddFirewoodText(firewoodCount, requiredFirewood) + text; } if (firewoodCount >= requiredFirewood) { return LocalizedText.GetText("LIGHT", true); } return GetLocalizedAddFirewoodText(firewoodCount, requiredFirewood); } return LocalizedText.GetText("COOK", true); } private static string GetLocalizedAddFirewoodText(int current, int required) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected I4, but got Unknown Language cURRENT_LANGUAGE = LocalizedText.CURRENT_LANGUAGE; switch ((int)cURRENT_LANGUAGE) { case 0: return $"ADD FIREWOOD ({current}/{required})"; case 1: return $"AJOUTER DU BOIS ({current}/{required})"; case 2: return $"AGGIUNGI LEGNA ({current}/{required})"; case 3: return $"HOLZ HINZUFÜGEN ({current}/{required})"; case 4: case 5: return $"AÑADIR LEÑA ({current}/{required})"; case 6: return $"ADICIONAR MADEIRA ({current}/{required})"; case 7: return $"ДОБАВИТЬ ДРОВА ({current}/{required})"; case 8: return $"ДОДАТИ ДРОВА ({current}/{required})"; case 9: case 10: return $"添加木柴 ({current}/{required})"; case 11: return $"薪を追加 ({current}/{required})"; case 12: return $"장작 추가 ({current}/{required})"; case 13: return $"DODAJ DRZEWO ({current}/{required})"; case 14: return $"DODAJ ODUN ({current}/{required})"; default: return $"ADD FIREWOOD ({current}/{required})"; } } public static bool Interact(Campfire campfire, Character interactor) { CampfireBuildingPlugin.logger.LogInfo((object)string.Format(" Interact called - Fire lit: {0}, Current item: {1}", campfire.Lit, ((Object)(object)interactor.data.currentItem != (Object)null) ? ((Object)interactor.data.currentItem).name : "null")); if (campfire.Lit && (Object)(object)interactor.data.currentItem != (Object)null && interactor.data.currentItem.cooking.canBeCooked) { CampfireBuildingPlugin.logger.LogInfo((object)" Allowing cooking interaction"); return true; } if (!campfire.Lit) { int firewoodCount = GetFirewoodCount(campfire); int requiredFirewood = GetRequiredFirewood(); CampfireBuildingPlugin.logger.LogInfo((object)$" Fire not lit, current firewood count: {firewoodCount}, required: {requiredFirewood}, players: {PhotonNetwork.CurrentRoom.PlayerCount}"); if (firewoodCount >= requiredFirewood) { CampfireBuildingPlugin.logger.LogInfo((object)" Enough firewood, allowing lighting"); return true; } if (firewoodCount < requiredFirewood && (Object)(object)interactor.data.currentItem != (Object)null && IsFirewoodItem(interactor.data.currentItem)) { CampfireBuildingPlugin.logger.LogInfo((object)$" Adding firewood! Current: {firewoodCount}, Adding 1"); int num = firewoodCount + 1; SetFireWoodCount(campfire, num); PhotonView component = ((Component)campfire).GetComponent(); if ((Object)(object)component != (Object)null && component.IsMine) { component.RPC("SetFireWoodCount", (RpcTarget)1, new object[1] { num }); } int num2 = -1; if ((Object)(object)((MonoBehaviourPun)interactor).photonView != (Object)null) { num2 = ((MonoBehaviourPun)interactor).photonView.ViewID; } interactor.data.currentItem.Consume(num2); CampfireBuildingPlugin.logger.LogInfo((object)" Firewood consumed, skipping original method"); return false; } CampfireBuildingPlugin.logger.LogInfo((object)" Not enough firewood and no firewood item, preventing interaction"); return false; } return true; } public static bool Interact_CastFinished(Campfire campfire, Character interactor) { if (campfire.Lit) { if ((Object)(object)interactor.data.currentItem != (Object)null && interactor.data.currentItem.cooking.canBeCooked) { return true; } return false; } string text = default(string); if (!campfire.EveryoneInRange(ref text, 15f)) { CampfireBuildingPlugin.logger.LogInfo((object)(" Cannot light - players out of range: " + text)); return false; } int firewoodCount = GetFirewoodCount(campfire); int requiredFirewood = GetRequiredFirewood(); if (firewoodCount >= requiredFirewood) { return true; } return false; } private static bool IsFirewoodItem(Item item) { if ((Object)(object)item != (Object)null) { return item.itemID == 28; } return false; } } }