Decompiled source of Campfire Building Fix v1.0.0

Campfire_Building_Fix.dll

Decompiled 3 days ago
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 <SpawnFirewoodAfterSceneLoad>d__6 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public CampfireBuildingPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnFirewoodAfterSceneLoad>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 <WaitForRunStart>d__4 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			public CampfireBuildingPlugin <>4__this;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <WaitForRunStart>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(<WaitForRunStart>d__4))]
		private IEnumerator WaitForRunStart()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <WaitForRunStart>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(<SpawnFirewoodAfterSceneLoad>d__6))]
		private IEnumerator SpawnFirewoodAfterSceneLoad()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnFirewoodAfterSceneLoad>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<GameObject>((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<Item>((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<Item>();
					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 <SpawnFirewoodInNewSegment>d__2 : IEnumerator<object>, IDisposable, IEnumerator
		{
			private int <>1__state;

			private object <>2__current;

			object IEnumerator<object>.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			object IEnumerator.Current
			{
				[DebuggerHidden]
				get
				{
					return <>2__current;
				}
			}

			[DebuggerHidden]
			public <SpawnFirewoodInNewSegment>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(<SpawnFirewoodInNewSegment>d__2))]
		private static IEnumerator SpawnFirewoodInNewSegment()
		{
			//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
			return new <SpawnFirewoodInNewSegment>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<Campfire, int> firewoodCounts = new Dictionary<Campfire, int>();

		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<PhotonView>();
					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;
		}
	}
}