Decompiled source of OctoPack Camping Kit v0.1.19

plugins/OctoPack_addon_Camping/OctoPack_addon_Camping.dll

Decompiled 3 days ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using OctoPack;
using TMPro;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.UI;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: AssemblyTitle("OctoPack Camping Kit")]
[assembly: AssemblyFileVersion("0.1.19.0")]
[assembly: AssemblyDescription("Camping Kit 0.1.19 - safe camp cleanup during player shutdown; developed with OpenAI Codex assistance")]
[assembly: AssemblyVersion("0.1.19.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace OctoPack_addon_Camping
{
	internal sealed class CampBedDrape : MonoBehaviour
	{
		private sealed class Surface
		{
			internal Mesh Mesh;

			internal Vector3[] Rest;

			internal Vector3[] Air;

			internal Vector3[] Working;
		}

		private readonly List<Surface> surfaces = new List<Surface>();

		private float age;

		private float nextStep;

		private static readonly RaycastHit[] hits = (RaycastHit[])(object)new RaycastHit[64];

		internal static void Create(Transform root)
		{
			((Component)root).gameObject.AddComponent<CampBedDrape>().Prepare();
		}

		internal static float Ground(Vector3 point, float reference)
		{
			//IL_0000: 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_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_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: 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_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			int num = Physics.RaycastNonAlloc(new Vector3(point.x, reference + 0.6f, point.z), Vector3.down, hits, 1.2f, LayerMask.GetMask(new string[4] { "Default", "static_solid", "piece", "terrain" }), (QueryTriggerInteraction)1);
			float num2 = float.NegativeInfinity;
			for (int i = 0; i < num; i++)
			{
				RaycastHit val = hits[i];
				if (Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).collider) && CampDrapeRules.GroundAllowed((Object)(object)((Component)((RaycastHit)(ref val)).collider).GetComponentInParent<Character>() != (Object)null, Object.op_Implicit((Object)(object)((RaycastHit)(ref val)).rigidbody) && !((RaycastHit)(ref val)).rigidbody.isKinematic, ((RaycastHit)(ref val)).normal.y, ((RaycastHit)(ref val)).point.y - reference))
				{
					num2 = Mathf.Max(num2, ((RaycastHit)(ref val)).point.y);
				}
			}
			if (Object.op_Implicit((Object)(object)ZoneSystem.instance))
			{
				float groundHeight = ZoneSystem.instance.GetGroundHeight(point);
				if (Mathf.Abs(groundHeight - reference) <= 0.35f)
				{
					num2 = Mathf.Max(num2, groundHeight);
				}
			}
			if (!float.IsInfinity(num2))
			{
				return num2;
			}
			return reference;
		}

		private void Prepare()
		{
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0044: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ab: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: 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_01ba: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01fa: Unknown result type (might be due to invalid IL or missing references)
			//IL_0220: Unknown result type (might be due to invalid IL or missing references)
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			MeshFilter[] componentsInChildren = ((Component)this).GetComponentsInChildren<MeshFilter>();
			float num = float.PositiveInfinity;
			MeshFilter[] array = componentsInChildren;
			foreach (MeshFilter val in array)
			{
				Vector3[] vertices = val.sharedMesh.vertices;
				foreach (Vector3 val2 in vertices)
				{
					num = Mathf.Min(num, ((Component)val).transform.TransformPoint(val2).y);
				}
			}
			Dictionary<Vector2, float> dictionary = new Dictionary<Vector2, float>();
			float y = ((Component)this).transform.parent.position.y;
			float num2 = float.NegativeInfinity;
			array = componentsInChildren;
			Vector2 key = default(Vector2);
			foreach (MeshFilter val3 in array)
			{
				Vector3[] vertices = val3.sharedMesh.vertices;
				foreach (Vector3 val4 in vertices)
				{
					Vector3 val5 = ((Component)val3).transform.TransformPoint(val4);
					((Vector2)(ref key))..ctor(val5.x, val5.z);
					if (!dictionary.TryGetValue(key, out var value))
					{
						value = Ground(val5, y);
						dictionary.Add(key, value);
						num2 = Mathf.Max(num2, value);
					}
				}
			}
			array = componentsInChildren;
			foreach (MeshFilter val6 in array)
			{
				Mesh val7 = Object.Instantiate<Mesh>(val6.sharedMesh);
				((Object)val7).name = ((Object)val6.sharedMesh).name + "_GroundDrape";
				val7.MarkDynamic();
				val6.sharedMesh = val7;
				Vector3[] vertices2 = val7.vertices;
				Vector3[] array2 = (Vector3[])(object)new Vector3[vertices2.Length];
				for (int k = 0; k < vertices2.Length; k++)
				{
					Vector3 val8 = ((Component)val6).transform.TransformPoint(vertices2[k]);
					float ground = dictionary[new Vector2(val8.x, val8.z)];
					float originalHeightAboveBottom = val8.y - num;
					val8.y = CampDrapeRules.RestHeight(ground, originalHeightAboveBottom);
					vertices2[k] = ((Component)val6).transform.InverseTransformPoint(val8);
					val8.y = CampDrapeRules.RestHeight(num2, originalHeightAboveBottom) + 0.075f;
					array2[k] = ((Component)val6).transform.InverseTransformPoint(val8);
				}
				Vector3[] working = (val7.vertices = (Vector3[])array2.Clone());
				val7.RecalculateBounds();
				surfaces.Add(new Surface
				{
					Mesh = val7,
					Rest = vertices2,
					Air = array2,
					Working = working
				});
			}
		}

		private void Update()
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			//IL_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			age += Time.deltaTime;
			if (age < nextStep)
			{
				return;
			}
			nextStep = age + 0.033f;
			float num = CampDrapeRules.Blend(age);
			foreach (Surface surface in surfaces)
			{
				for (int i = 0; i < surface.Working.Length; i++)
				{
					surface.Working[i] = Vector3.Lerp(surface.Air[i], surface.Rest[i], num);
				}
				surface.Mesh.vertices = surface.Working;
				surface.Mesh.RecalculateBounds();
			}
			if (!(age >= 0.85f))
			{
				return;
			}
			foreach (Surface surface2 in surfaces)
			{
				surface2.Mesh.vertices = surface2.Rest;
				surface2.Mesh.RecalculateNormals();
				surface2.Mesh.RecalculateBounds();
			}
			((Behaviour)this).enabled = false;
		}

		private void OnDestroy()
		{
			foreach (Surface surface in surfaces)
			{
				if (Object.op_Implicit((Object)(object)surface.Mesh))
				{
					Object.Destroy((Object)(object)surface.Mesh);
				}
			}
			surfaces.Clear();
		}
	}
	internal static class CampContactAllowance
	{
		internal static bool Clear(float depth, float restingDepth)
		{
			return depth <= restingDepth + 0.002f;
		}
	}
	[DefaultExecutionOrder(3400)]
	internal sealed class CampController : MonoBehaviour
	{
		internal CampFood Food;

		internal bool MenuOpen;

		internal List<CampFood.Choice> Choices;

		internal int Selected;

		internal string Status = "";

		private Player player;

		private ItemData kit;

		private GameObject scene;

		private CampTerrain terrain;

		private Transform groundPot;

		private Transform bedAnchor;

		private Vector3 origin;

		private Quaternion facing;

		private float entered;

		private readonly CampSeatGuard seat = new CampSeatGuard();

		private bool sleeping;

		private CampStir stir;

		private readonly List<Renderer> hidden = new List<Renderer>();

		internal const string ActiveKey = "OctoPack.Camping.Active";

		internal const string HostKey = "OctoPack.Camping.Host";

		internal const string SessionKey = "OctoPack.Camping.Session";

		internal const string SlotKey = "OctoPack.Camping.Slot";

		internal const string OriginKey = "OctoPack.Camping.Origin";

		internal const string FacingKey = "OctoPack.Camping.Facing";

		private const string JoinRpc = "OctoPack.Camp.Join.v1";

		private const string ReplyRpc = "OctoPack.Camp.Reply.v1";

		private const string LeaveRpc = "OctoPack.Camp.Leave.v1";

		private readonly CampGuestSlots<ZDOID> guests = new CampGuestSlots<ZDOID>();

		private ZNetView groupView;

		private Player host;

		private Player pendingHost;

		private int session;

		private int slot;

		private int pendingSession;

		private int request;

		private float pendingUntil;

		internal bool Active { get; private set; }

		internal bool Guest => slot > 0;

		private void Awake()
		{
			player = ((Component)this).GetComponent<Player>();
			SetNetwork(camp: false, stir: false);
		}

		internal static bool Unsafe(Player p)
		{
			if (p.IsTargeted())
			{
				return true;
			}
			foreach (BaseAI allInstance in BaseAI.GetAllInstances())
			{
				if (Object.op_Implicit((Object)(object)allInstance) && (Object)(object)allInstance.GetTargetCreature() == (Object)(object)p)
				{
					return true;
				}
			}
			return false;
		}

		private static bool Busy()
		{
			if (!Console.IsVisible() && (!Object.op_Implicit((Object)(object)Chat.instance) || !Chat.instance.HasFocus()) && !TextInput.IsVisible() && !Menu.IsVisible() && !InventoryGui.IsVisible())
			{
				return Minimap.IsOpen();
			}
			return true;
		}

		private void Update()
		{
			try
			{
				Tick();
			}
			catch (Exception e)
			{
				End(threat: false);
				if (Object.op_Implicit((Object)(object)Plugin.Instance))
				{
					Plugin.Instance.Warn(e);
				}
			}
		}

		private void Tick()
		{
			//IL_0222: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_018c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f6: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)Plugin.Instance) || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			GroupTick();
			RepairTracking.Observe(player);
			if (Active)
			{
				if (!Plugin.Instance.Enabled.Value || ((Character)player).IsDead() || ((Character)player).IsTeleporting() || ((Character)player).IsSwimming() || (Guest ? (!HostAlive()) : (!CampItem.EquippedFor(player))))
				{
					End(threat: false);
					return;
				}
				if (Unsafe(player))
				{
					End(threat: true);
					return;
				}
				if (CampInput.Down(Plugin.Instance.CampKey.Value) && !Console.IsVisible() && !TextInput.IsVisible())
				{
					End(threat: false);
					return;
				}
				if (sleeping)
				{
					if (!((Character)player).IsAttached())
					{
						End(threat: false);
					}
					return;
				}
				if (seat.LeftPose(((Character)player).IsSitting(), ((Character)player).InEmote(), Time.time - entered))
				{
					End(threat: false);
					return;
				}
				CampNativeUI.Tick();
				if (!Guest)
				{
					Food.Tick(Time.deltaTime);
					SetNetwork(camp: true, Food.Timer.Phase == FoodPhase.Cooking);
				}
				if (Busy())
				{
					return;
				}
				KeyboardShortcut value;
				if (!Guest)
				{
					value = Plugin.Instance.CookKey.Value;
					if (((KeyboardShortcut)(ref value)).IsDown())
					{
						CampNativeUI.Open(player);
					}
				}
				value = Plugin.Instance.RepairKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Say("Camp repaired " + RepairTracking.Repair(player) + " item(s).");
				}
				value = Plugin.Instance.SleepKey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Sleep();
				}
			}
			else if (Plugin.Instance.Enabled.Value && CampInput.Down(Plugin.Instance.CampKey.Value) && !Busy())
			{
				if (Object.op_Implicit((Object)(object)pendingHost))
				{
					CancelPending();
					Say("Cancelled joining camp.");
				}
				else if (!TryJoin())
				{
					Begin();
				}
			}
		}

		private void Begin()
		{
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0153: Unknown result type (might be due to invalid IL or missing references)
			//IL_0159: Unknown result type (might be due to invalid IL or missing references)
			//IL_017b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0185: Expected O, but got Unknown
			//IL_019d: 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_01c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_0203: Unknown result type (might be due to invalid IL or missing references)
			if (!CampItem.EquippedFor(player))
			{
				Say("Equip the camping kit in a backpack slot first.");
				return;
			}
			if (Unsafe(player))
			{
				Say("It's not safe to camp right now.");
				return;
			}
			if (((Character)player).IsSwimming() || !((Character)player).IsOnGround() || ((Character)player).IsTeleporting() || ((Character)player).IsAttached() || ((Character)player).IsDead())
			{
				Say("Find dry, stable ground before camping.");
				return;
			}
			Transform packRoot = BackpackPlugin.GetPackRoot(player);
			if (!Object.op_Implicit((Object)(object)packRoot))
			{
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (CampItem.Is(allItem) && allItem.m_equipped)
				{
					kit = allItem;
					break;
				}
			}
			if (kit == null)
			{
				return;
			}
			try
			{
				session = Random.Range(1, int.MaxValue);
				slot = 0;
				host = null;
				Food = new CampFood(player, kit);
				CampModel.Ensure(packRoot);
				origin = ((Component)player).transform.position;
				facing = ((Component)player).transform.rotation;
				if (!CampTerrain.CanFlatten(origin))
				{
					Say("The camp needs continuous ground beneath the bedrolls.");
					return;
				}
				scene = new GameObject("OctoPack_Campsite");
				scene.SetActive(false);
				scene.transform.position = origin;
				scene.transform.rotation = facing;
				terrain = CampTerrain.Attach(scene, origin);
				groundPot = CampModel.Build(scene.transform, ladle: false, ((Component)player).gameObject.layer, open: true);
				CampLayout.PlacePot(groundPot, CampScene.CookingScale(packRoot));
				CampScene.Build(scene.transform, packRoot, ((Component)player).gameObject.layer, out bedAnchor);
				CampSoup.Create(groundPot, ((Component)player).gameObject.layer);
				stir = new CampStir(player, groundPot, scene.transform);
				HideBedroll(packRoot);
				scene.SetActive(true);
				scene.AddComponent<CampFade>();
				if (!StartSitting())
				{
					End(threat: false);
					Say("Could not sit down right now.");
					return;
				}
				SetNetwork(camp: true, stir: false);
				MenuOpen = false;
				Choices = CampFood.Choices(player);
				Selected = 0;
				Say("K: cook   J: repair   L: sleep   Shift+P: leave camp");
			}
			catch (Exception e)
			{
				End(threat: false);
				Plugin.Instance.Warn(e);
				Say("Could not set up camp; see the log.");
			}
		}

		private void Sleep()
		{
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			if (!EnvMan.CanSleep())
			{
				Say("You can't sleep right now.");
				return;
			}
			CampNativeUI.Close();
			MenuOpen = false;
			AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null).Invoke(player, null);
			((Character)player).AttachStart(bedAnchor, scene, true, true, false, "attach_bed", new Vector3(0f, 0.5f, 0f), (Transform)null);
			sleeping = true;
			SetNetwork(camp: true, stir: false);
		}

		internal void End(bool threat, bool destroying = false)
		{
			CampNativeUI.Close(!destroying);
			bool active = Active;
			if (!destroying)
			{
				SetNetwork(camp: false, stir: false);
				LeaveGroup();
			}
			else
			{
				pendingHost = null;
				pendingSession = 0;
				host = null;
				slot = (session = 0);
				guests.Clear();
			}
			Active = false;
			MenuOpen = false;
			Food?.Flush();
			kit = null;
			Food = null;
			if (!destroying && Object.op_Implicit((Object)(object)player) && active)
			{
				if (sleeping && ((Character)player).IsAttached())
				{
					((Character)player).AttachStop();
				}
				AccessTools.Method(typeof(Player), "StopEmote", (Type[])null, (Type[])null).Invoke(player, null);
			}
			sleeping = false;
			stir?.Release();
			stir = null;
			foreach (Renderer item in hidden)
			{
				if (Object.op_Implicit((Object)(object)item))
				{
					item.enabled = true;
				}
			}
			hidden.Clear();
			terrain?.Release();
			terrain = null;
			if (Object.op_Implicit((Object)(object)scene))
			{
				Object.Destroy((Object)(object)scene);
			}
			scene = null;
			groundPot = (bedAnchor = null);
			if (threat && !destroying)
			{
				Say("It's not safe to camp right now.");
			}
		}

		private void SetNetwork(bool camp, bool stir)
		{
			//IL_006b: Unknown result type (might be due to invalid IL or missing references)
			ZNetView val = (Object.op_Implicit((Object)(object)player) ? ((Component)player).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsOwner() && val.GetZDO() != null)
			{
				ZDO zDO = val.GetZDO();
				if (camp && zDO.GetInt("OctoPack.Camping.Session", 0) != session)
				{
					PublishGroup(zDO);
				}
				if (!camp)
				{
					zDO.Set("OctoPack.Camping.Host", ZDOID.None);
					zDO.Set("OctoPack.Camping.Session", 0);
					zDO.Set("OctoPack.Camping.Slot", 0);
				}
				if (zDO.GetBool("OctoPack.Camping.Active", false) != camp)
				{
					zDO.Set("OctoPack.Camping.Active", camp);
				}
				if (zDO.GetBool("OctoPack.Camping.Stirring", false) != stir)
				{
					zDO.Set("OctoPack.Camping.Stirring", stir);
				}
			}
		}

		internal void Say(string text)
		{
			Status = text;
			if (Object.op_Implicit((Object)(object)player))
			{
				((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false);
			}
		}

		private void LateUpdate()
		{
			if (Active && !Guest && !sleeping)
			{
				stir?.Step(Food != null && Food.Timer.Phase == FoodPhase.Cooking);
			}
		}

		private void OnDestroy()
		{
			End(threat: false, destroying: true);
			if (Object.op_Implicit((Object)(object)groupView) && Object.op_Implicit((Object)(object)player) && (Object)(object)Player.m_localPlayer == (Object)(object)player)
			{
				groupView.Unregister("OctoPack.Camp.Join.v1");
				groupView.Unregister("OctoPack.Camp.Reply.v1");
				groupView.Unregister("OctoPack.Camp.Leave.v1");
			}
		}

		internal static ZDO Data(Player p)
		{
			ZNetView val = (Object.op_Implicit((Object)(object)p) ? ((Component)p).GetComponent<ZNetView>() : null);
			if (!Object.op_Implicit((Object)(object)val))
			{
				return null;
			}
			return val.GetZDO();
		}

		internal static Player Find(ZDOID id)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			if (((ZDOID)(ref id)).IsNone())
			{
				return null;
			}
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if (Object.op_Implicit((Object)(object)allPlayer) && ((Character)allPlayer).GetZDOID() == id)
				{
					return allPlayer;
				}
			}
			return null;
		}

		internal static bool Hosting(Player p)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			ZDO val = Data(p);
			if (Object.op_Implicit((Object)(object)p) && !((Character)p).IsDead() && val != null && val.GetBool("OctoPack.Camping.Active", false))
			{
				ZDOID zDOID = val.GetZDOID("OctoPack.Camping.Host");
				if (((ZDOID)(ref zDOID)).IsNone())
				{
					return val.GetInt("OctoPack.Camping.Session", 0) > 0;
				}
			}
			return false;
		}

		private void GroupTick()
		{
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.IsOwner() && component.GetZDO() != null && (Object)(object)groupView != (Object)(object)component)
			{
				groupView = component;
				component.Register<ZDOID, int, int>("OctoPack.Camp.Join.v1", (Action<long, ZDOID, int, int>)JoinRequest);
				component.Register<ZDOID, int, int>("OctoPack.Camp.Reply.v1", (Action<long, ZDOID, int, int>)JoinReply);
				component.Register<ZDOID, int>("OctoPack.Camp.Leave.v1", (Action<long, ZDOID, int>)LeaveRequest);
				ZDO zDO = component.GetZDO();
				zDO.Set("OctoPack.Camping.Active", false);
				zDO.Set("OctoPack.Camping.Host", ZDOID.None);
				zDO.Set("OctoPack.Camping.Session", 0);
				zDO.Set("OctoPack.Camping.Slot", 0);
			}
			if (Object.op_Implicit((Object)(object)pendingHost) && Time.realtimeSinceStartup >= pendingUntil)
			{
				CancelPending();
				Say("The camp did not respond. Try again.");
			}
			if (Active && !Guest)
			{
				guests.Prune(Time.realtimeSinceStartup, (ZDOID id, int s) => ValidGuest(Find(id), s));
			}
		}

		private bool ValidGuest(Player p, int seatSlot)
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_006e: 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_0079: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			ZDO val = Data(p);
			if (Object.op_Implicit((Object)(object)p) && !((Character)p).IsDead() && val != null && val.GetBool("OctoPack.Camping.Active", false) && val.GetZDOID("OctoPack.Camping.Host") == ((Character)player).GetZDOID() && val.GetInt("OctoPack.Camping.Session", 0) == session && val.GetInt("OctoPack.Camping.Slot", 0) == seatSlot)
			{
				Vector3 val2 = ((Component)p).transform.position - origin;
				return ((Vector3)(ref val2)).sqrMagnitude < 36f;
			}
			return false;
		}

		private bool HostAlive()
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)host) && Hosting(host) && Data(host).GetInt("OctoPack.Camping.Session", 0) == session)
			{
				Vector3 val = ((Component)host).transform.position - origin;
				return ((Vector3)(ref val)).sqrMagnitude < 16f;
			}
			return false;
		}

		private bool TryJoin()
		{
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0052: Unknown result type (might be due to invalid IL or missing references)
			//IL_0057: Unknown result type (might be due to invalid IL or missing references)
			//IL_013e: Unknown result type (might be due to invalid IL or missing references)
			Player val = null;
			float num = 16.0001f;
			foreach (Player allPlayer in Player.GetAllPlayers())
			{
				if ((Object)(object)allPlayer != (Object)(object)player && Hosting(allPlayer))
				{
					Vector3 val2 = ((Component)allPlayer).transform.position - ((Component)player).transform.position;
					float sqrMagnitude = ((Vector3)(ref val2)).sqrMagnitude;
					if (CampGroupRules.InRange(sqrMagnitude) && sqrMagnitude < num)
					{
						val = allPlayer;
						num = sqrMagnitude;
					}
				}
			}
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if (!CanSit())
			{
				Say("Find safe, dry ground before joining camp.");
				return true;
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if (!Object.op_Implicit((Object)(object)groupView) || !Object.op_Implicit((Object)(object)component))
			{
				return true;
			}
			pendingHost = val;
			pendingSession = Data(val).GetInt("OctoPack.Camping.Session", 0);
			request = ((request == int.MaxValue) ? 1 : (request + 1));
			pendingUntil = Time.realtimeSinceStartup + 6f;
			Say("Joining the nearby camp...");
			component.InvokeRPC(((Character)val).GetOwner(), "OctoPack.Camp.Join.v1", new object[3]
			{
				((Character)player).GetZDOID(),
				pendingSession,
				request
			});
			return true;
		}

		private bool CanSit()
		{
			if (Object.op_Implicit((Object)(object)Plugin.Instance) && Plugin.Instance.Enabled.Value && !Unsafe(player) && !((Character)player).IsSwimming() && ((Character)player).IsOnGround() && !((Character)player).IsTeleporting() && !((Character)player).IsAttached())
			{
				return !((Character)player).IsDead();
			}
			return false;
		}

		private void JoinRequest(long sender, ZDOID guestId, int epoch, int token)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: 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)
			//IL_0090: 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)
			Player val = Find(guestId);
			if (!Object.op_Implicit((Object)(object)val) || (Object)(object)val == (Object)(object)player || ((Character)val).GetOwner() != sender)
			{
				return;
			}
			int num = -1;
			if (Active && !Guest && epoch == session && !Unsafe(player) && !((Character)val).IsDead() && !((Character)val).IsTeleporting() && !((Character)val).IsSwimming())
			{
				Vector3 val2 = ((Component)val).transform.position - ((Component)player).transform.position;
				if (CampGroupRules.InRange(((Vector3)(ref val2)).sqrMagnitude))
				{
					guests.Prune(Time.realtimeSinceStartup, (ZDOID id, int s) => ValidGuest(Find(id), s));
					num = guests.Reserve(guestId, Time.realtimeSinceStartup);
				}
			}
			ZNetView component = ((Component)val).GetComponent<ZNetView>();
			if (component != null)
			{
				component.InvokeRPC(sender, "OctoPack.Camp.Reply.v1", new object[3]
				{
					((Character)player).GetZDOID(),
					token,
					num
				});
			}
		}

		private void JoinReply(long sender, ZDOID hostId, int token, int assigned)
		{
			//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_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00af: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0112: Unknown result type (might be due to invalid IL or missing references)
			//IL_0133: Unknown result type (might be due to invalid IL or missing references)
			//IL_0138: Unknown result type (might be due to invalid IL or missing references)
			//IL_013d: Unknown result type (might be due to invalid IL or missing references)
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0175: Expected O, but got Unknown
			//IL_018d: 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_01a5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0227: Unknown result type (might be due to invalid IL or missing references)
			//IL_0230: Unknown result type (might be due to invalid IL or missing references)
			//IL_0236: Unknown result type (might be due to invalid IL or missing references)
			//IL_028a: Unknown result type (might be due to invalid IL or missing references)
			//IL_028f: Unknown result type (might be due to invalid IL or missing references)
			//IL_029c: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_02b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_02c9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02cb: Unknown result type (might be due to invalid IL or missing references)
			if (!Object.op_Implicit((Object)(object)pendingHost) || ((Character)pendingHost).GetZDOID() != hostId || ((Character)pendingHost).GetOwner() != sender || token != request)
			{
				return;
			}
			Player val = pendingHost;
			if (assigned < 1 || assigned > 2)
			{
				CancelPending();
				Say((assigned == 0) ? "That camp already has two guests." : "That camp is no longer available.");
				return;
			}
			if (Hosting(val) && Data(val).GetInt("OctoPack.Camping.Session", 0) == pendingSession && CanSit())
			{
				Vector3 val2 = ((Component)val).transform.position - ((Component)player).transform.position;
				if (CampGroupRules.InRange(((Vector3)(ref val2)).sqrMagnitude))
				{
					try
					{
						host = val;
						session = pendingSession;
						slot = assigned;
						origin = Data(host).GetVec3("OctoPack.Camping.Origin", ((Component)host).transform.position);
						facing = Data(host).GetQuaternion("OctoPack.Camping.Facing", ((Component)host).transform.rotation);
						Transform packRoot = BackpackPlugin.GetPackRoot(host);
						if (!Object.op_Implicit((Object)(object)packRoot))
						{
							throw new InvalidOperationException("Host camp models are not ready.");
						}
						CampModel.Ensure(packRoot);
						scene = new GameObject("OctoPack_GuestCamp");
						scene.SetActive(false);
						scene.transform.SetPositionAndRotation(origin, facing);
						terrain = CampTerrain.Attach(scene, origin);
						Vector3 val3 = origin + facing * CampLayout.Seat(slot);
						float num = (Object.op_Implicit((Object)(object)ZoneSystem.instance) ? ZoneSystem.instance.GetGroundHeight(val3) : origin.y);
						if (Mathf.Abs(num - origin.y) > 0.2f)
						{
							throw new InvalidOperationException("The guest seat needs flatter ground.");
						}
						val3.y = num;
						if (!CampScene.SeatClear(val3) || !CampScene.BedGroundClear(origin, facing, slot))
						{
							throw new InvalidOperationException("The guest spot is obstructed or too steep.");
						}
						CampScene.BuildBed(scene.transform, ((Component)player).gameObject.layer, slot, out bedAnchor);
						Vector3 position = ((Component)player).transform.position;
						Quaternion rotation = ((Component)player).transform.rotation;
						MoveToSeat(val3, facing * CampLayout.Facing(slot));
						if (!StartSitting())
						{
							MoveToSeat(position, rotation);
							throw new InvalidOperationException("Could not sit at the guest seat.");
						}
						HideBedroll(BackpackPlugin.GetPackRoot(player));
						scene.SetActive(true);
						scene.AddComponent<CampFade>();
						pendingHost = null;
						pendingSession = 0;
						SetNetwork(camp: true, stir: false);
						Say("Joined camp. J: repair   L: sleep   Shift+P: leave camp");
						return;
					}
					catch (Exception e)
					{
						End(threat: false);
						Plugin.Instance.Warn(e);
						Say("Could not join camp; find clear, flat ground.");
						return;
					}
				}
			}
			CancelPending();
			Say("Could not join that camp.");
		}

		private void MoveToSeat(Vector3 position, Quaternion rotation)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0072: Unknown result type (might be due to invalid IL or missing references)
			//IL_0031: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_009e: Unknown result type (might be due to invalid IL or missing references)
			((Character)player).SetMoveDir(Vector3.zero);
			((Character)player).SetRun(false);
			Rigidbody component = ((Component)player).GetComponent<Rigidbody>();
			if (Object.op_Implicit((Object)(object)component))
			{
				component.linearVelocity = Vector3.zero;
				component.angularVelocity = Vector3.zero;
				component.position = position;
				component.rotation = rotation;
			}
			((Component)player).transform.SetPositionAndRotation(position, rotation);
			((Character)player).SetLookDir(rotation * Vector3.forward, 0f);
			ZDO obj = Data(player);
			if (obj != null)
			{
				obj.SetPosition(position);
			}
			if (obj != null)
			{
				obj.SetRotation(rotation);
			}
		}

		private void LeaveRequest(long sender, ZDOID guestId, int epoch)
		{
			//IL_0000: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			Player val = Find(guestId);
			if (Object.op_Implicit((Object)(object)val) && ((Character)val).GetOwner() == sender && epoch == session)
			{
				guests.Release(guestId);
			}
		}

		private void CancelPending()
		{
			//IL_0040: Unknown result type (might be due to invalid IL or missing references)
			if (Object.op_Implicit((Object)(object)pendingHost))
			{
				ZNetView component = ((Component)pendingHost).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.InvokeRPC(((Character)pendingHost).GetOwner(), "OctoPack.Camp.Leave.v1", new object[2]
					{
						((Character)player).GetZDOID(),
						pendingSession
					});
				}
			}
			pendingHost = null;
			pendingSession = 0;
		}

		private void LeaveGroup()
		{
			//IL_0046: Unknown result type (might be due to invalid IL or missing references)
			CancelPending();
			if (Object.op_Implicit((Object)(object)host))
			{
				ZNetView component = ((Component)host).GetComponent<ZNetView>();
				if (Object.op_Implicit((Object)(object)component))
				{
					component.InvokeRPC(((Character)host).GetOwner(), "OctoPack.Camp.Leave.v1", new object[2]
					{
						((Character)player).GetZDOID(),
						session
					});
				}
			}
			host = null;
			slot = (session = 0);
			guests.Clear();
		}

		private void PublishGroup(ZDO z)
		{
			//IL_0020: Unknown result type (might be due to invalid IL or missing references)
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			//IL_0053: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: Unknown result type (might be due to invalid IL or missing references)
			z.Set("OctoPack.Camping.Host", Object.op_Implicit((Object)(object)host) ? ((Character)host).GetZDOID() : ZDOID.None);
			z.Set("OctoPack.Camping.Session", session);
			z.Set("OctoPack.Camping.Slot", slot);
			z.Set("OctoPack.Camping.Origin", origin);
			z.Set("OctoPack.Camping.Facing", facing);
		}

		private bool StartSitting()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			((Character)player).SetMoveDir(Vector3.zero);
			((Character)player).SetRun(false);
			((Humanoid)player).HideHandItems(false, false);
			if (!player.StartEmote("sit", false))
			{
				return false;
			}
			Active = true;
			entered = Time.time;
			seat.Reset();
			return true;
		}

		private void HideBedroll(Transform root)
		{
			if (!Object.op_Implicit((Object)(object)root))
			{
				return;
			}
			Renderer[] componentsInChildren = ((Component)root).GetComponentsInChildren<Renderer>(true);
			foreach (Renderer val in componentsInChildren)
			{
				if (val.enabled && ((Object)val).name.IndexOf("Bedroll", StringComparison.OrdinalIgnoreCase) >= 0)
				{
					hidden.Add(val);
					val.enabled = false;
				}
			}
		}
	}
	internal sealed class CampFood
	{
		internal sealed class Choice
		{
			internal Recipe Recipe;

			internal ItemConversion Conversion;

			internal CookingStation Station;

			internal string Name;
		}

		private const string Key = "OctoPack.CampFood.v1";

		private readonly ItemData kit;

		private readonly Player player;

		internal readonly CookTimer Timer = new CookTimer();

		internal string Output;

		internal string Burnt;

		internal string Title;

		internal int Amount;

		private float sinceSave;

		internal List<KeyValuePair<string, int>> Costs = new List<KeyValuePair<string, int>>();

		internal CampFood(Player p, ItemData item)
		{
			player = p;
			kit = item;
			if (!kit.m_customData.TryGetValue("OctoPack.CampFood.v1", out var value))
			{
				return;
			}
			try
			{
				string[] array = value.Split('|');
				Output = array[0];
				Burnt = array[1];
				Amount = int.Parse(array[2]);
				Title = array[3];
				if (Amount < 1 || Amount > 10000 || !Object.op_Implicit((Object)(object)ObjectDB.instance.GetItemPrefab(Output)))
				{
					throw new FormatException();
				}
				Timer.Start(double.Parse(array[4], CultureInfo.InvariantCulture), array[5] == "1");
				Timer.Step(double.Parse(array[6], CultureInfo.InvariantCulture));
			}
			catch
			{
				Timer.Clear();
				throw new InvalidOperationException("Camping food state could not be read. Existing saved entry was retained.");
			}
		}

		private static string Localize(string text)
		{
			Type type = AccessTools.TypeByName("Localization");
			object obj = AccessTools.Property(type, "instance")?.GetValue(null) ?? AccessTools.Field(type, "instance")?.GetValue(null);
			if (obj != null)
			{
				return (string)AccessTools.Method(type, "Localize", new Type[1] { typeof(string) }, (Type[])null).Invoke(obj, new object[1] { text });
			}
			return text;
		}

		internal static List<Choice> Choices(Player p)
		{
			List<Choice> list = new List<Choice>();
			ObjectDB instance = ObjectDB.instance;
			if (!Object.op_Implicit((Object)(object)instance))
			{
				return list;
			}
			foreach (Recipe recipe in instance.m_recipes)
			{
				if (Object.op_Implicit((Object)(object)recipe) && recipe.m_enabled && !recipe.m_noCraftOnlyUpgrade && Object.op_Implicit((Object)(object)recipe.m_item) && Object.op_Implicit((Object)(object)recipe.m_craftingStation) && recipe.m_craftingStation.m_name == "$piece_cauldron" && p.IsRecipeKnown(recipe.m_item.m_itemData.m_shared.m_name))
				{
					list.Add(new Choice
					{
						Recipe = recipe,
						Name = Localize(recipe.m_item.m_itemData.m_shared.m_name)
					});
				}
			}
			HashSet<string> hashSet = new HashSet<string>();
			if (Object.op_Implicit((Object)(object)ZNetScene.instance))
			{
				foreach (GameObject prefab in ZNetScene.instance.m_prefabs)
				{
					if (!Object.op_Implicit((Object)(object)prefab))
					{
						continue;
					}
					CookingStation component = prefab.GetComponent<CookingStation>();
					if (!Object.op_Implicit((Object)(object)component))
					{
						continue;
					}
					foreach (ItemConversion item in component.m_conversion)
					{
						if (Object.op_Implicit((Object)(object)item.m_from) && Object.op_Implicit((Object)(object)item.m_to) && item.m_to.m_itemData.m_shared.m_food > 0f && p.IsMaterialKnown(item.m_from.m_itemData.m_shared.m_name) && hashSet.Add(((Object)item.m_from).name))
						{
							list.Add(new Choice
							{
								Conversion = item,
								Station = component,
								Name = Localize(item.m_to.m_itemData.m_shared.m_name)
							});
						}
					}
				}
			}
			return list.OrderBy((Choice x) => x.Name).ToList();
		}

		internal string Requirements(Choice c)
		{
			if (Object.op_Implicit((Object)(object)c.Recipe))
			{
				return string.Join(", ", from r in c.Recipe.m_resources
					where Object.op_Implicit((Object)(object)r.m_resItem) && r.GetAmount(1) > 0
					select r.GetAmount(1) + " " + Localize(r.m_resItem.m_itemData.m_shared.m_name)) + ((c.Recipe.m_minStationLevel > 1) ? ("; cauldron level " + c.Recipe.m_minStationLevel) : "");
			}
			return "1 " + Localize(c.Conversion.m_from.m_itemData.m_shared.m_name);
		}

		internal string Start(Choice c)
		{
			//IL_0062: Unknown result type (might be due to invalid IL or missing references)
			if (Timer.Phase != FoodPhase.Empty)
			{
				return "Finish the current food first.";
			}
			Costs.Clear();
			Inventory inventory = ((Humanoid)player).GetInventory();
			int num = -1;
			if (Object.op_Implicit((Object)(object)c.Recipe))
			{
				Recipe recipe = c.Recipe;
				if (recipe.m_minStationLevel > 1)
				{
					CraftingStation val = CraftingStation.FindClosestStationInRange(recipe.m_craftingStation.m_name, ((Component)player).transform.position, 20f);
					if (!Object.op_Implicit((Object)(object)val) || val.GetLevel(false) < recipe.m_minStationLevel)
					{
						return "This recipe requires an upgraded cauldron nearby.";
					}
				}
				Requirement[] resources = recipe.m_resources;
				foreach (Requirement val2 in resources)
				{
					if (Object.op_Implicit((Object)(object)val2.m_resItem) && val2.GetAmount(1) > 0)
					{
						Costs.Add(new KeyValuePair<string, int>(((Object)val2.m_resItem).name, val2.GetAmount(1)));
					}
				}
				Output = ((Object)recipe.m_item).name;
				Amount = recipe.m_amount;
				Burnt = "";
				if (recipe.m_requireOnlyOneIngredient)
				{
					Costs.Clear();
					int value = default(int);
					ItemData val3 = default(ItemData);
					try
					{
						Amount = recipe.GetAmount(1, ref value, ref val3, 1);
					}
					catch
					{
						return "Missing ingredients.";
					}
					if (val3 == null)
					{
						return "Missing ingredients.";
					}
					Costs.Add(new KeyValuePair<string, int>(((Object)val3.m_dropPrefab).name, value));
					num = val3.m_quality;
				}
			}
			else
			{
				Costs.Add(new KeyValuePair<string, int>(((Object)c.Conversion.m_from).name, 1));
				Output = ((Object)c.Conversion.m_to).name;
				Amount = 1;
				Burnt = ((c.Station.m_canOvercookItems && Object.op_Implicit((Object)(object)c.Station.m_overCookedItem)) ? ((Object)c.Station.m_overCookedItem).name : "");
			}
			foreach (KeyValuePair<string, int> cost in Costs)
			{
				GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(cost.Key);
				if (!Object.op_Implicit((Object)(object)itemPrefab) || inventory.CountItems(itemPrefab.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, -1, true) < cost.Value)
				{
					return "Missing ingredients.";
				}
			}
			foreach (KeyValuePair<string, int> cost2 in Costs)
			{
				GameObject itemPrefab2 = ObjectDB.instance.GetItemPrefab(cost2.Key);
				inventory.RemoveItem(itemPrefab2.GetComponent<ItemDrop>().m_itemData.m_shared.m_name, cost2.Value, num, true);
			}
			Title = c.Name;
			Timer.Start((c.Conversion != null) ? c.Conversion.m_cookTime : 2f, Burnt.Length > 0);
			Save();
			return "";
		}

		internal void Tick(float dt)
		{
			if (Timer.Phase != FoodPhase.Empty)
			{
				FoodPhase phase = Timer.Phase;
				Timer.Step(dt);
				sinceSave += dt;
				if (phase != Timer.Phase || sinceSave >= 1f)
				{
					Save();
					sinceSave = 0f;
				}
			}
		}

		internal void Flush()
		{
			if (Timer.Phase != FoodPhase.Empty)
			{
				Save();
			}
		}

		private void Save()
		{
			kit.m_customData["OctoPack.CampFood.v1"] = string.Join("|", Output, Burnt, Amount.ToString(), Title, Timer.Duration.ToString("R", CultureInfo.InvariantCulture), Timer.CanBurn ? "1" : "0", Timer.Elapsed.ToString("R", CultureInfo.InvariantCulture));
		}

		internal string Collect()
		{
			if (Timer.Phase != FoodPhase.Ready && Timer.Phase != FoodPhase.Burnt)
			{
				return "Food is still cooking.";
			}
			string text = ((Timer.Phase == FoodPhase.Burnt) ? Burnt : Output);
			int num = ((Timer.Phase == FoodPhase.Burnt) ? 1 : Amount);
			GameObject itemPrefab = ObjectDB.instance.GetItemPrefab(text);
			if (!Object.op_Implicit((Object)(object)itemPrefab))
			{
				return "Food prefab is unavailable; the food remains saved in the kit.";
			}
			if (!((Humanoid)player).GetInventory().CanAddItem(itemPrefab, num))
			{
				return "Make room in your inventory first.";
			}
			if (!(bool)AccessTools.Method(typeof(Inventory), "AddItem", new Type[2]
			{
				typeof(GameObject),
				typeof(int)
			}, (Type[])null).Invoke(((Humanoid)player).GetInventory(), new object[2] { itemPrefab, num }))
			{
				return "Could not collect food; it remains saved in the kit.";
			}
			Timer.Collect();
			kit.m_customData.Remove("OctoPack.CampFood.v1");
			return "";
		}
	}
	internal static class CampDrapeRules
	{
		internal const float Clearance = 0.018f;

		internal const float Duration = 0.85f;

		internal static bool GroundAllowed(bool character, bool moving, float upwardNormal, float difference)
		{
			if (!character && !moving && upwardNormal >= 0.55f)
			{
				return Math.Abs(difference) <= 0.35f;
			}
			return false;
		}

		internal static float RestHeight(float ground, float originalHeightAboveBottom)
		{
			return ground + 0.018f + originalHeightAboveBottom;
		}

		internal static float Blend(float age)
		{
			float num = Math.Max(0f, Math.Min(1f, age / 0.85f));
			return num * num * (3f - 2f * num);
		}
	}
	internal static class CampEffects
	{
		private static bool warnedSteam;

		private static bool warnedFire;

		internal static void Fire(Transform fire, int layer)
		{
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: 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_00f6: Unknown result type (might be due to invalid IL or missing references)
			//IL_0102: Unknown result type (might be due to invalid IL or missing references)
			//IL_0107: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0121: Unknown result type (might be due to invalid IL or missing references)
			//IL_0132: Unknown result type (might be due to invalid IL or missing references)
			//IL_0143: Unknown result type (might be due to invalid IL or missing references)
			//IL_015c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0161: Unknown result type (might be due to invalid IL or missing references)
			//IL_018d: 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_01df: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01f1: Expected O, but got Unknown
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("piece_groundtorch") : null);
			int num = 0;
			if (Object.op_Implicit((Object)(object)val))
			{
				foreach (ParticleSystem item in Roots(val, steam: false))
				{
					GameObject val2 = Clone(item, fire, "Camping_Flames", layer);
					ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem val3 in componentsInChildren)
					{
						if (((Object)val3).name.IndexOf("flare", StringComparison.OrdinalIgnoreCase) >= 0)
						{
							Object.DestroyImmediate((Object)(object)((Component)val3).gameObject);
						}
					}
					componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem val4 in componentsInChildren)
					{
						Reset(val4);
						MainModule main = val4.main;
						((MainModule)(ref main)).startSize = new MinMaxCurve(0.045f, 0.085f);
						((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.07f, 0.17f);
						((MainModule)(ref main)).startLifetime = new MinMaxCurve(0.45f, 0.85f);
						((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(Color.white);
						((MainModule)(ref main)).maxParticles = 64;
						EmissionModule emission = val4.emission;
						((EmissionModule)(ref emission)).enabled = true;
						((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(46f);
						((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(0f);
						((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[0]);
						ShapeModule shape = val4.shape;
						((ShapeModule)(ref shape)).enabled = true;
						((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
						((ShapeModule)(ref shape)).radius = 0.13f;
						((ShapeModule)(ref shape)).angle = 12f;
						((ShapeModule)(ref shape)).position = Vector3.zero;
						((ShapeModule)(ref shape)).rotation = new Vector3(-90f, 0f, 0f);
						ParticleSystemRenderer component = ((Component)val4).GetComponent<ParticleSystemRenderer>();
						if (Object.op_Implicit((Object)(object)component) && Object.op_Implicit((Object)(object)((Renderer)component).sharedMaterial))
						{
							Material val5 = new Material(((Renderer)component).sharedMaterial)
							{
								name = "Camping_FlameMaterial"
							};
							if (val5.HasProperty("_SoftParticles"))
							{
								val5.SetFloat("_SoftParticles", 0f);
							}
							if (val5.HasProperty("_SoftParticlesEnabled"))
							{
								val5.SetFloat("_SoftParticlesEnabled", 0f);
							}
							val5.DisableKeyword("SOFTPARTICLES_ON");
							val5.DisableKeyword("_SOFTPARTICLES_ON");
							((Renderer)component).sharedMaterial = val5;
							((Component)val4).gameObject.AddComponent<OwnMaterial>().Material = val5;
						}
					}
					Play(val2);
					num++;
				}
			}
			if (num == 0 && !warnedFire)
			{
				warnedFire = true;
				Plugin.Instance?.Warn(new InvalidOperationException("Camp fire: native ground-torch flame particles are unavailable."));
			}
		}

		internal static void Steam(Transform soup, int layer)
		{
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: 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_00ed: 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_0106: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_012d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0145: Unknown result type (might be due to invalid IL or missing references)
			//IL_014a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0176: Unknown result type (might be due to invalid IL or missing references)
			//IL_0191: Unknown result type (might be due to invalid IL or missing references)
			//IL_019b: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("piece_cauldron") : null);
			int num = 0;
			if (Object.op_Implicit((Object)(object)val))
			{
				foreach (ParticleSystem item in Roots(val, steam: true))
				{
					GameObject val2 = Clone(item, soup, "Camping_CauldronSteam", layer);
					val2.transform.localPosition = new Vector3(0f, -0.166f, 0f);
					ParticleSystem[] componentsInChildren = val2.GetComponentsInChildren<ParticleSystem>(true);
					foreach (ParticleSystem obj in componentsInChildren)
					{
						Reset(obj);
						MainModule main = obj.main;
						((MainModule)(ref main)).startSize = new MinMaxCurve(0.055f, 0.11f);
						((MainModule)(ref main)).startSpeed = new MinMaxCurve(0.13f, 0.24f);
						((MainModule)(ref main)).startLifetime = new MinMaxCurve(1.4f, 2.2f);
						((MainModule)(ref main)).startColor = MinMaxGradient.op_Implicit(new Color(0.88f, 0.9f, 0.9f, 0.38f));
						((MainModule)(ref main)).maxParticles = 32;
						EmissionModule emission = obj.emission;
						((EmissionModule)(ref emission)).enabled = true;
						((EmissionModule)(ref emission)).rateOverTime = MinMaxCurve.op_Implicit(9f);
						((EmissionModule)(ref emission)).rateOverDistance = MinMaxCurve.op_Implicit(0f);
						((EmissionModule)(ref emission)).SetBursts((Burst[])(object)new Burst[0]);
						ShapeModule shape = obj.shape;
						((ShapeModule)(ref shape)).enabled = true;
						((ShapeModule)(ref shape)).shapeType = (ParticleSystemShapeType)4;
						((ShapeModule)(ref shape)).radius = 0.065f;
						((ShapeModule)(ref shape)).angle = 5f;
						((ShapeModule)(ref shape)).position = Vector3.zero;
						((ShapeModule)(ref shape)).rotation = new Vector3(-90f, 0f, 0f);
						SizeOverLifetimeModule sizeOverLifetime = obj.sizeOverLifetime;
						((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = true;
						((SizeOverLifetimeModule)(ref sizeOverLifetime)).size = new MinMaxCurve(1f, AnimationCurve.Linear(0f, 0.45f, 1f, 1.8f));
					}
					Play(val2);
					num++;
				}
			}
			if (num == 0 && !warnedSteam)
			{
				warnedSteam = true;
				Plugin.Instance?.Warn(new InvalidOperationException("Camp soup: piece_cauldron has no loaded steam/smoke particle renderer. Broth remains available."));
			}
		}

		private static List<ParticleSystem> Roots(GameObject prefab, bool steam)
		{
			List<ParticleSystem> list = new List<ParticleSystem>();
			ParticleSystem[] componentsInChildren = prefab.GetComponentsInChildren<ParticleSystem>(true);
			foreach (ParticleSystem val in componentsInChildren)
			{
				string text = ((Object)val).name.ToLowerInvariant();
				bool flag = text.Contains("steam") || text.Contains("smoke");
				bool num;
				if (!steam)
				{
					if (flag || text.Contains("spark"))
					{
						continue;
					}
					num = text.Contains("ember");
				}
				else
				{
					num = !flag;
				}
				if (num)
				{
					continue;
				}
				bool flag2 = false;
				foreach (ParticleSystem item in list)
				{
					if (((Component)val).transform.IsChildOf(((Component)item).transform))
					{
						flag2 = true;
						break;
					}
				}
				if (!flag2)
				{
					list.Add(val);
				}
				if (list.Count >= (steam ? 1 : 3))
				{
					break;
				}
			}
			return list;
		}

		private static GameObject Clone(ParticleSystem source, Transform parent, string name, int layer)
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_004b: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject(name);
			val.SetActive(false);
			val.layer = layer;
			val.transform.SetParent(parent, false);
			GameObject val2 = Object.Instantiate<GameObject>(((Component)source).gameObject, val.transform, false);
			val2.transform.localPosition = Vector3.zero;
			val2.transform.localRotation = Quaternion.identity;
			val2.transform.localScale = Vector3.one;
			MonoBehaviour[] componentsInChildren = val2.GetComponentsInChildren<MonoBehaviour>(true);
			for (int i = 0; i < componentsInChildren.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren[i]);
			}
			Collider[] componentsInChildren2 = val2.GetComponentsInChildren<Collider>(true);
			for (int i = 0; i < componentsInChildren2.Length; i++)
			{
				Object.DestroyImmediate((Object)(object)componentsInChildren2[i]);
			}
			Light[] componentsInChildren3 = val2.GetComponentsInChildren<Light>(true);
			for (int i = 0; i < componentsInChildren3.Length; i++)
			{
				((Behaviour)componentsInChildren3[i]).enabled = false;
			}
			Transform[] componentsInChildren4 = val2.GetComponentsInChildren<Transform>(true);
			foreach (Transform obj in componentsInChildren4)
			{
				((Component)obj).gameObject.layer = layer;
				((Component)obj).gameObject.SetActive(true);
			}
			return val;
		}

		private static void Reset(ParticleSystem ps)
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Unknown result type (might be due to invalid IL or missing references)
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00df: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ef: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			ps.Stop(false, (ParticleSystemStopBehavior)0);
			((Component)ps).transform.localPosition = Vector3.zero;
			((Component)ps).transform.localRotation = Quaternion.identity;
			((Component)ps).transform.localScale = Vector3.one;
			MainModule main = ps.main;
			((MainModule)(ref main)).scalingMode = (ParticleSystemScalingMode)0;
			((MainModule)(ref main)).simulationSpace = (ParticleSystemSimulationSpace)0;
			((MainModule)(ref main)).startSize3D = false;
			((MainModule)(ref main)).prewarm = false;
			((MainModule)(ref main)).loop = true;
			((MainModule)(ref main)).playOnAwake = false;
			((MainModule)(ref main)).startDelay = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).gravityModifier = MinMaxCurve.op_Implicit(0f);
			((MainModule)(ref main)).stopAction = (ParticleSystemStopAction)0;
			((MainModule)(ref main)).cullingMode = (ParticleSystemCullingMode)3;
			VelocityOverLifetimeModule velocityOverLifetime = ps.velocityOverLifetime;
			((VelocityOverLifetimeModule)(ref velocityOverLifetime)).enabled = false;
			ForceOverLifetimeModule forceOverLifetime = ps.forceOverLifetime;
			((ForceOverLifetimeModule)(ref forceOverLifetime)).enabled = false;
			NoiseModule noise = ps.noise;
			((NoiseModule)(ref noise)).enabled = false;
			CollisionModule collision = ps.collision;
			((CollisionModule)(ref collision)).enabled = false;
			SubEmittersModule subEmitters = ps.subEmitters;
			((SubEmittersModule)(ref subEmitters)).enabled = false;
			LightsModule lights = ps.lights;
			((LightsModule)(ref lights)).enabled = false;
			SizeOverLifetimeModule sizeOverLifetime = ps.sizeOverLifetime;
			((SizeOverLifetimeModule)(ref sizeOverLifetime)).enabled = false;
			ParticleSystemRenderer component = ((Component)ps).GetComponent<ParticleSystemRenderer>();
			if (Object.op_Implicit((Object)(object)component))
			{
				((Renderer)component).enabled = true;
				component.renderMode = (ParticleSystemRenderMode)0;
				((Renderer)component).shadowCastingMode = (ShadowCastingMode)0;
				((Renderer)component).receiveShadows = false;
			}
		}

		private static void Play(GameObject holder)
		{
			holder.AddComponent<CampParticleStart>();
			holder.SetActive(true);
		}
	}
	internal static class CampItem
	{
		private const string Marker = "OctoPack_addon_Camping.Item.v1";

		private const string Wanted = "OctoPack_addon_Camping.Equipped.v1";

		private const string Net = "OctoPack_addon_Camping.Equipped.v1";

		private static Recipe recipe;

		private static ObjectDB database;

		private static GameObject cache;

		private static float next;

		private static Sprite icon;

		private static Texture2D texture;

		private static void Toggle(Player player, ItemData item)
		{
			if (!Object.op_Implicit((Object)(object)player) || (Object)(object)player != (Object)(object)Player.m_localPlayer)
			{
				return;
			}
			if (Selected(item))
			{
				item.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "0";
				item.m_equipped = false;
				Tick();
				return;
			}
			if (!InPack(player, item))
			{
				((Character)player).Message((MessageType)2, "Move the camping kit into a backpack slot first.", 0, (Sprite)null, false);
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					allItem.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "0";
				}
			}
			item.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "1";
			Tick();
		}

		internal static bool Use(Humanoid __instance, ItemData item)
		{
			if (!Is(item))
			{
				return true;
			}
			Toggle((Player)(object)((__instance is Player) ? __instance : null), item);
			return false;
		}

		internal static bool Equip(Humanoid __instance, ItemData item, ref bool __result)
		{
			if (!Is(item))
			{
				return true;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			__result = false;
			if (!Object.op_Implicit((Object)(object)val))
			{
				return false;
			}
			if (Selected(item))
			{
				__result = InPack(val, item);
				return false;
			}
			if ((Object)(object)val != (Object)(object)Player.m_localPlayer || (bool)AccessTools.Field(typeof(Player), "m_isLoading").GetValue(val))
			{
				return false;
			}
			if (!InPack(val, item))
			{
				((Character)val).Message((MessageType)2, "Move the camping kit into a backpack slot first.", 0, (Sprite)null, false);
				return false;
			}
			foreach (ItemData allItem in ((Humanoid)val).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					allItem.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "0";
				}
			}
			item.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "1";
			Tick();
			__result = true;
			return false;
		}

		internal static bool Unequip(Humanoid __instance, ItemData item)
		{
			if (!Is(item))
			{
				return true;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!Object.op_Implicit((Object)(object)val) || (bool)AccessTools.Field(typeof(Player), "m_isLoading").GetValue(val))
			{
				item.m_equipped = false;
				return false;
			}
			item.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "0";
			item.m_equipped = false;
			Tick();
			return false;
		}

		internal static void IsEquipped(Humanoid __instance, ItemData item, ref bool __result)
		{
			if (Is(item))
			{
				__result = Selected(item) && InPack((Player)(object)((__instance is Player) ? __instance : null), item);
			}
		}

		internal static bool Is(ItemData item)
		{
			return CampSelection.Is(item);
		}

		internal static bool Selected(ItemData item)
		{
			return CampSelection.Selected(item);
		}

		private static bool InPack(Player player, ItemData item)
		{
			return BackpackPlugin.IsBackpackSlot(player, item);
		}

		internal static bool EquippedFor(Player player)
		{
			if (!Object.op_Implicit((Object)(object)player))
			{
				return false;
			}
			if ((Object)(object)player == (Object)(object)Player.m_localPlayer)
			{
				if (!Object.op_Implicit((Object)(object)Plugin.Instance) || !Plugin.Instance.Enabled.Value || ((Character)player).IsDead())
				{
					return false;
				}
				foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
				{
					if (Selected(allItem) && InPack(player, allItem))
					{
						return true;
					}
				}
				return false;
			}
			ZNetView component = ((Component)player).GetComponent<ZNetView>();
			if (Object.op_Implicit((Object)(object)component) && component.GetZDO() != null)
			{
				return component.GetZDO().GetBool("OctoPack_addon_Camping.Equipped.v1", false);
			}
			return false;
		}

		private static Sprite Icon()
		{
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Expected O, but got Unknown
			//IL_00e3: 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)
			if (Object.op_Implicit((Object)(object)icon))
			{
				return icon;
			}
			using Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Camping.Icon");
			byte[] array = new byte[65536];
			int i;
			int num;
			for (i = 0; i < array.Length; i += num)
			{
				if ((num = stream.Read(array, i, array.Length - i)) <= 0)
				{
					break;
				}
			}
			if (i != array.Length)
			{
				throw new InvalidDataException("Camping icon");
			}
			byte[] array2 = new byte[array.Length];
			for (int j = 0; j < 128; j++)
			{
				Array.Copy(array, j * 512, array2, (127 - j) * 512, 512);
			}
			texture = new Texture2D(128, 128, (TextureFormat)4, false);
			texture.LoadRawTextureData(array2);
			texture.Apply(false, true);
			icon = Sprite.Create(texture, new Rect(0f, 0f, 128f, 128f), new Vector2(0.5f, 0.5f), 128f);
			return icon;
		}

		internal static void Install(Harmony h)
		{
			//IL_007d: Unknown result type (might be due to invalid IL or missing references)
			//IL_008b: Expected O, but got Unknown
			//IL_00be: Unknown result type (might be due to invalid IL or missing references)
			//IL_00cb: Expected O, but got Unknown
			//IL_00f3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0101: Expected O, but got Unknown
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_0156: Expected O, but got Unknown
			//IL_017e: 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_01a0: Expected O, but got Unknown
			//IL_01a0: Expected O, but got Unknown
			string[][] array = new string[3][]
			{
				new string[2] { "UseItem", "Use" },
				new string[2] { "EquipItem", "Equip" },
				new string[2] { "UnequipItem", "Unequip" }
			};
			foreach (string[] array2 in array)
			{
				h.Patch((MethodBase)AccessTools.Method(typeof(Humanoid), array2[0], (Type[])null, (Type[])null), new HarmonyMethod(typeof(CampItem), array2[1], (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			}
			h.Patch((MethodBase)AccessTools.Method(typeof(Humanoid), "IsItemEquiped", (Type[])null, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CampItem), "IsEquipped", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			h.Patch((MethodBase)AccessTools.Method(typeof(Player), "CreateTombStone", (Type[])null, (Type[])null), new HarmonyMethod(typeof(CampItem), "BeforeDeath", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			h.Patch((MethodBase)AccessTools.Method(typeof(Inventory), "Load", new Type[2]
			{
				typeof(ZPackage),
				typeof(bool)
			}, (Type[])null), (HarmonyMethod)null, new HarmonyMethod(typeof(CampItem), "Loaded", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
			h.Patch((MethodBase)AccessTools.Method(typeof(InventoryGui), "DoCrafting", (Type[])null, (Type[])null), new HarmonyMethod(typeof(CampItem), "BeforeCraft", (Type[])null), new HarmonyMethod(typeof(CampItem), "AfterCraft", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null);
		}

		private static void Mark(ItemData item)
		{
			item.m_customData["OctoPack_addon_Camping.Item.v1"] = "1";
			if (!item.m_customData.ContainsKey("OctoPack_addon_Camping.Equipped.v1"))
			{
				item.m_customData["OctoPack_addon_Camping.Equipped.v1"] = "0";
			}
			Decorate(item);
		}

		internal static void Decorate(ItemData item)
		{
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			if (Is(item) && !(item.m_shared.m_name == "OctoPack Camping Kit"))
			{
				item.m_shared = (SharedData)typeof(object).GetMethod("MemberwiseClone", BindingFlags.Instance | BindingFlags.NonPublic).Invoke(item.m_shared, null);
				item.m_shared.m_name = "OctoPack Camping Kit";
				item.m_shared.m_description = "Equip in a backpack slot. Shift+P camps; K cooks, J repairs, L sleeps. Pot and copper ladle hang independently.\nMade from 2 copper, 2 iron, and 2 deer hide.";
				item.m_shared.m_icons = (Sprite[])(object)new Sprite[1] { Icon() };
				item.m_shared.m_itemType = (ItemType)1;
				item.m_shared.m_questItem = false;
				item.m_shared.m_equipStatusEffect = null;
				item.m_shared.m_useDurability = false;
				item.m_shared.m_maxStackSize = 1;
				item.m_shared.m_maxQuality = 1;
				item.m_shared.m_weight = 2f;
			}
		}

		internal static void Loaded(Inventory __instance)
		{
			foreach (ItemData allItem in __instance.GetAllItems())
			{
				Decorate(allItem);
			}
		}

		internal static void Tick()
		{
			Player localPlayer = Player.m_localPlayer;
			if (Time.realtimeSinceStartup >= next)
			{
				next = Time.realtimeSinceStartup + 2f;
				EnsureRecipe();
				if (Object.op_Implicit((Object)(object)localPlayer) && Object.op_Implicit((Object)(object)recipe))
				{
					AccessTools.Method(typeof(Player), "UpdateKnownRecipesList", (Type[])null, (Type[])null).Invoke(localPlayer, null);
				}
			}
			if (!Object.op_Implicit((Object)(object)localPlayer))
			{
				return;
			}
			bool flag = false;
			foreach (ItemData allItem in ((Humanoid)localPlayer).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					Decorate(allItem);
					if (allItem.m_equipped = !flag && Selected(allItem) && InPack(localPlayer, allItem) && Plugin.Instance.Enabled.Value && !((Character)localPlayer).IsDead())
					{
						flag = true;
					}
				}
			}
			ZNetView component = ((Component)localPlayer).GetComponent<ZNetView>();
			ZDO val = (Object.op_Implicit((Object)(object)component) ? component.GetZDO() : null);
			if (Object.op_Implicit((Object)(object)component) && component.IsOwner() && val != null && val.GetBool("OctoPack_addon_Camping.Equipped.v1", false) != flag)
			{
				val.Set("OctoPack_addon_Camping.Equipped.v1", flag);
			}
		}

		internal static void BeforeDeath(Player __instance)
		{
			foreach (ItemData allItem in ((Humanoid)__instance).GetInventory().GetAllItems())
			{
				if (Is(allItem))
				{
					allItem.m_equipped = false;
				}
			}
		}

		private static Requirement Cost(GameObject go, int amount)
		{
			//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_0011: 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_0020: Expected O, but got Unknown
			return new Requirement
			{
				m_resItem = go.GetComponent<ItemDrop>(),
				m_amount = amount,
				m_amountPerLevel = 0
			};
		}

		private static void EnsureRecipe()
		{
			//IL_00db: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e5: Expected O, but got Unknown
			//IL_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0104: Unknown result type (might be due to invalid IL or missing references)
			//IL_010b: Unknown result type (might be due to invalid IL or missing references)
			ObjectDB instance = ObjectDB.instance;
			if (Object.op_Implicit((Object)(object)instance) && (!((Object)(object)database == (Object)(object)instance) || !Object.op_Implicit((Object)(object)recipe) || !instance.m_recipes.Contains(recipe)))
			{
				GameObject itemPrefab = instance.GetItemPrefab("Wishbone");
				GameObject itemPrefab2 = instance.GetItemPrefab("Copper");
				GameObject itemPrefab3 = instance.GetItemPrefab("Iron");
				GameObject itemPrefab4 = instance.GetItemPrefab("DeerHide");
				GameObject val = (Object.op_Implicit((Object)(object)ZNetScene.instance) ? ZNetScene.instance.GetPrefab("forge") : null);
				CraftingStation val2 = (Object.op_Implicit((Object)(object)val) ? val.GetComponent<CraftingStation>() : null);
				if (Object.op_Implicit((Object)(object)itemPrefab) && Object.op_Implicit((Object)(object)itemPrefab2) && Object.op_Implicit((Object)(object)itemPrefab3) && Object.op_Implicit((Object)(object)itemPrefab4) && Object.op_Implicit((Object)(object)val2))
				{
					DisposeRecipe();
					database = instance;
					cache = new GameObject("OctoPack_LanternArmRecipe");
					cache.SetActive(false);
					Object.DontDestroyOnLoad((Object)(object)cache);
					GameObject val3 = new GameObject("Wishbone");
					val3.SetActive(false);
					val3.transform.SetParent(cache.transform, false);
					ItemDrop val4 = val3.AddComponent<ItemDrop>();
					val4.m_itemData = itemPrefab.GetComponent<ItemDrop>().m_itemData.Clone();
					val4.m_itemData.m_dropPrefab = itemPrefab;
					val4.m_itemData.m_customData = new Dictionary<string, string>();
					Mark(val4.m_itemData);
					recipe = ScriptableObject.CreateInstance<Recipe>();
					((Object)recipe).name = "Recipe_OctoPack_addon_Camping";
					recipe.m_item = val4;
					recipe.m_amount = 1;
					recipe.m_enabled = true;
					recipe.m_craftingStation = (recipe.m_repairStation = val2);
					recipe.m_minStationLevel = 1;
					recipe.m_resources = (Requirement[])(object)new Requirement[3]
					{
						Cost(itemPrefab2, 2),
						Cost(itemPrefab3, 2),
						Cost(itemPrefab4, 2)
					};
					instance.m_recipes.Add(recipe);
				}
			}
		}

		internal static void BeforeCraft(InventoryGui __instance, Player player, out HashSet<ItemData> __state)
		{
			__state = ((Object.op_Implicit((Object)(object)recipe) && AccessTools.Field(typeof(InventoryGui), "m_craftRecipe").GetValue(__instance) == recipe && Object.op_Implicit((Object)(object)player)) ? new HashSet<ItemData>(((Humanoid)player).GetInventory().GetAllItems()) : null);
		}

		internal static void AfterCraft(Player player, HashSet<ItemData> __state)
		{
			if (!Object.op_Implicit((Object)(object)player) || __state == null)
			{
				return;
			}
			foreach (ItemData allItem in ((Humanoid)player).GetInventory().GetAllItems())
			{
				if (!__state.Contains(allItem) && Object.op_Implicit((Object)(object)allItem.m_dropPrefab) && ((Object)allItem.m_dropPrefab).name == "Wishbone")
				{
					Mark(allItem);
				}
			}
		}

		private static void DisposeRecipe()
		{
			if (Object.op_Implicit((Object)(object)database) && Object.op_Implicit((Object)(object)recipe))
			{
				database.m_recipes.Remove(recipe);
			}
			if (Object.op_Implicit((Object)(object)recipe))
			{
				Object.Destroy((Object)(object)recipe);
			}
			if (Object.op_Implicit((Object)(object)cache))
			{
				Object.Destroy((Object)(object)cache);
			}
			recipe = null;
			cache = null;
			database = null;
		}

		internal static void Dispose()
		{
			Player localPlayer = Player.m_localPlayer;
			ZNetView val = (Object.op_Implicit((Object)(object)localPlayer) ? ((Component)localPlayer).GetComponent<ZNetView>() : null);
			if (Object.op_Implicit((Object)(object)val) && val.IsOwner() && val.GetZDO() != null)
			{
				val.GetZDO().Set("OctoPack_addon_Camping.Equipped.v1", false);
			}
			DisposeRecipe();
			if (Object.op_Implicit((Object)(object)icon))
			{
				Object.Destroy((Object)(object)icon);
			}
			if (Object.op_Implicit((Object)(object)texture))
			{
				Object.Destroy((Object)(object)texture);
			}
			icon = null;
			texture = null;
		}
	}
	[DefaultExecutionOrder(3500)]
	internal sealed class CampFlameLimit : MonoBehaviour
	{
		internal float Ceiling;

		internal float Radius;

		private ParticleSystem[] systems;

		private Particle[][] particles;

		private void Start()
		{
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			systems = ((Component)this).GetComponentsInChildren<ParticleSystem>(true);
			particles = new Particle[systems.Length][];
			for (int i = 0; i < systems.Length; i++)
			{
				Particle[][] array = particles;
				int num = i;
				MainModule main = systems[i].main;
				array[num] = (Particle[])(object)new Particle[((MainModule)(ref main)).maxParticles];
			}
		}

		private void LateUpdate()
		{
			//IL_0025: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Invalid comparison between Unknown and I4
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0070: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Invalid comparison between Unknown and I4
			//IL_008a: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0081: Unknown result type (might be due to invalid IL or missing references)
			//IL_008f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0093: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: 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_00ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Unknown result type (might be due to invalid IL or missing references)
			//IL_011c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0180: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ee: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			if (systems == null)
			{
				return;
			}
			Vector3 val5 = default(Vector3);
			for (int i = 0; i < systems.Length; i++)
			{
				ParticleSystem val = systems[i];
				if (!Object.op_Implicit((Object)(object)val))
				{
					continue;
				}
				MainModule main = val.main;
				int num = val.GetParticles(particles[i]);
				Transform val2 = (((int)((MainModule)(ref main)).simulationSpace == 2) ? ((MainModule)(ref main)).customSimulationSpace : ((Component)val).transform);
				for (int j = 0; j < num; j++)
				{
					Particle val3 = particles[i][j];
					Vector3 val4 = (((int)((MainModule)(ref main)).simulationSpace == 1) ? ((Particle)(ref val3)).position : val2.TransformPoint(((Particle)(ref val3)).position));
					float num2 = (((int)((MainModule)(ref main)).scalingMode == 0) ? Mathf.Max(((Component)val).transform.lossyScale.x, Mathf.Max(((Component)val).transform.lossyScale.y, ((Component)val).transform.lossyScale.z)) : 1f);
					float num3 = ((Particle)(ref val3)).GetCurrentSize(val) * num2 * 0.87f;
					((Vector3)(ref val5))..ctor(val4.x - ((Component)this).transform.position.x, 0f, val4.z - ((Component)this).transform.position.z);
					float num4 = Radius - ((Vector3)(ref val5)).magnitude;
					if (num4 <= 0f)
					{
						((Particle)(ref val3)).remainingLifetime = 0f;
					}
					else if (num3 > num4)
					{
						((Particle)(ref val3)).startSize = ((Particle)(ref val3)).startSize * Mathf.Min(1f, num4 / Mathf.Max(1E-06f, num3));
					}
					if (val4.y >= Ceiling)
					{
						((Particle)(ref val3)).remainingLifetime = 0f;
					}
					else if (val4.y + num3 >= Ceiling)
					{
						((Particle)(ref val3)).startSize = ((Particle)(ref val3)).startSize * Mathf.Min(1f, (Ceiling - val4.y) / Mathf.Max(1E-06f, num3));
					}
					particles[i][j] = val3;
				}
				val.SetParticles(particles[i], num);
			}
		}
	}
	internal sealed class CampGuestSlots<T>
	{
		private readonly T[] guests = new T[2];

		private readonly double[] deadlines = new double[2];

		private readonly bool[] occupied = new bool[2];

		internal int Reserve(T guest, double now)
		{
			for (int i = 0; i < 2; i++)
			{
				if (occupied[i] && object.Equals(guests[i], guest))
				{
					return i + 1;
				}
			}
			for (int j = 0; j < 2; j++)
			{
				if (!occupied[j])
				{
					occupied[j] = true;
					guests[j] = guest;
					deadlines[j] = now + 8.0;
					return j + 1;
				}
			}
			return 0;
		}

		internal bool Contains(int slot, T guest)
		{
			if (slot >= 1 && slot <= 2 && occupied[slot - 1])
			{
				return object.Equals(guests[slot - 1], guest);
			}
			return false;
		}

		internal void Release(T guest)
		{
			for (int i = 0; i < 2; i++)
			{
				if (occupied[i] && object.Equals(guests[i], guest))
				{
					occupied[i] = false;
				}
			}
		}

		internal void Prune(double now, Func<T, int, bool> valid)
		{
			for (int i = 0; i < 2; i++)
			{
				if (occupied[i])
				{
					if (valid(guests[i], i + 1))
					{
						deadlines[i] = now + 8.0;
					}
					else if (now >= deadlines[i])
					{
						occupied[i] = false;
					}
				}
			}
		}

		internal void Clear()
		{
			Array.Clear(occupied, 0, 2);
		}
	}
	internal static class CampGroupRules
	{
		internal const float JoinRange = 4f;

		internal static bool InRange(float squaredDistance)
		{
			if (!float.IsNaN(squaredDistance) && squaredDistance >= 0f)
			{
				return squaredDistance <= 16f;
			}
			return false;
		}

		internal static bool ShiftEquivalent(bool requiredLeft, bool requiredRight, bool left, bool right)
		{
			return !(requiredLeft || requiredRight) || left || right;
		}

		internal static void Seat(int slot, out float x, out float z, out float yaw)
		{
			switch (slot)
			{
			case 0:
				x = (z = (yaw = 0f));
				break;
			default:
				throw new ArgumentOutOfRangeException("slot");
			case 1:
			case 2:
				yaw = ((slot == 1) ? 120 : 240);
				x = ((slot == 1) ? (-0.8660254f) : 0.8660254f);
				z = 1.05f;
				break;
			}
		}

		internal static float PotPivot(float scale, float lowestVertex)
		{
			return 0.012f - lowestVertex * scale;
		}
	}
	internal static class CampHinge
	{
		internal static double Angle(double downY, double downZ, double limit)
		{
			double val = Math.Atan2(0.0 - downZ, 0.0 - downY) * 180.0 / Math.PI;
			return Math.Max(0.0 - limit, Math.Min(limit, val));
		}
	}
	internal sealed class CampHingeMotion
	{
		private double angle;

		private double speed;

		internal double Angle => angle * 180.0 / Math.PI;

		internal double AngularSpeed => speed;

		internal void Reset()
		{
			angle = (speed = 0.0);
		}

		internal void Step(double fy, double fz, double length, double mass, double drag, double dt, double limit)
		{
			if (!Finite(fy) || !Finite(fz) || !Finite(dt) || dt <= 0.0)
			{
				return;
			}
			if (dt > 0.25)
			{
				Reset();
				return;
			}
			length = Math.Max(0.025, Math.Min(0.5, length));
			mass = Math.Max(0.025, Math.Min(2.0, mass));
			drag = Math.Max(0.0, Math.Min(4.0, drag));
			double num = Math.Max(Math.Max(0.0, limit) * Math.PI / 180.0, Math.Abs(angle));
			int num2 = (int)Math.Ceiling(dt * 240.0);
			double num3 = dt / (double)num2;
			for (int i = 0; i < num2; i++)
			{
				speed += ((0.0 - Math.Cos(angle)) * fz + Math.Sin(angle) * fy) / length * num3;
				speed *= Math.Exp((0.0 - drag) / mass * num3);
				angle += speed * num3;
				if (angle > num)
				{
					angle = num;
					if (speed > 0.0)
					{
						speed = 0.0;
					}
				}
				if (angle < 0.0 - num)
				{
					angle = 0.0 - num;
					if (speed < 0.0)
					{
						speed = 0.0;
					}
				}
			}
		}

		internal void Contact(double degrees)
		{
			double num = degrees * Math.PI / 180.0;
			double num2 = num - angle;
			if ((num2 > 0.0 && speed < 0.0) || (num2 < 0.0 && speed > 0.0))
			{
				speed = 0.0;
			}
			angle = num;
		}

		private static bool Finite(double value)
		{
			if (!double.IsNaN(value))
			{
				return !double.IsInfinity(value);
			}
			return false;
		}
	}
	internal static class CampContactSearch
	{
		internal static bool Find(Func<double, bool> clear, double max, out double angle)
		{
			angle = 0.0;
			if (clear(0.0))
			{
				return true;
			}
			double num = 0.0;
			for (double num2 = Math.Min(2.0, max); num2 <= max; num2 = Math.Min(max, num2 + 2.0))
			{
				if (clear(num2))
				{
					double num3 = num2;
					for (int i = 0; i < 14; i++)
					{
						double num4 = (num + num3) * 0.5;
						if (clear(num4))
						{
							num3 = num4;
						}
						else
						{
							num = num4;
						}
					}
					angle = num3;
					return true;
				}
				if (num2 == max)
				{
					break;
				}
				num = num2;
			}
			return false;
		}
	}
	internal static class CampInput
	{
		internal static bool Down(KeyboardShortcut key)
		{
			//IL_0002: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Invalid comparison between Unknown and I4
			//IL_0036: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Invalid comparison between Unknown and I4
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if (!Input.GetKeyDown(((KeyboardShortcut)(ref key)).MainKey))
			{
				return false;
			}
			bool requiredLeft = false;
			bool requiredRight = false;
			foreach (KeyCode modifier in ((KeyboardShortcut)(ref key)).Modifiers)
			{
				if ((int)modifier == 304)
				{
					requiredLeft = true;
				}
				else if ((int)modifier == 303)
				{
					requiredRight = true;
				}
				else if (!Input.GetKey(modifier))
				{
					return false;
				}
			}
			return CampGroupRules.ShiftEquivalent(requiredLeft, requiredRight, Input.GetKey((KeyCode)304), Input.GetKey((KeyCode)303));
		}
	}
	internal sealed class CampLadlePlacement
	{
		internal static readonly Vector3 BowlCenter = new Vector3(0f, -0.274f, -0.016f);

		internal static readonly Quaternion Rotation = Quaternion.Euler(0f, 0f, -24f);

		internal const float Clearance = 0.0015f;

		internal const float StirRadius = 0.025f;

		private const int Samples = 64;

		private readonly float[] heights = new float[64];

		private readonly float idle;

		private readonly Vector3[] floor;

		private readonly Vector3[] bowl;

		internal CampLadlePlacement(Vector3[] pot, Vector3[] ladle)
		{
			//IL_001f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0024: Unknown result type (might be due to invalid IL or missing references)
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			//IL_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)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0049: Unknown result type (might be due to invalid IL or missing references)
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0066: Unknown result type (might be due to invalid IL or missing references)
			//IL_006d: Unknown result type (might be due to invalid IL or missing references)
			//IL_007e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d5: Unknown result type (might be due to invalid IL or missing references)
			//IL_00da: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e6: Unknown result type (might be due to invalid IL or missing references)
			List<Vector3> list = new List<Vector3>();
			for (int i = 0; i < pot.Length; i += 3)
			{
				Vector3 val = pot[i];
				Vector3 val2 = pot[i + 1];
				Vector3 val3 = pot[i + 2];
				if ((val2.z - val.z) * (val3.x - val.x) - (val2.x - val.x) * (val3.z - val.z) > 1E-09f)
				{
					list.Add(val);
					list.Add(val2);
					list.Add(val3);
				}
			}
			floor = list.ToArray();
			List<Vector3> list2 = new List<Vector3>();
			foreach (Vector3 val4 in ladle)
			{
				if (val4.y < -0.22f)
				{
					list2.Add(Rotation * (val4 - BowlCenter));
				}
			}
			bowl = list2.ToArray();
			if (floor.Length == 0 || bowl.Length == 0)
			{
				throw new InvalidOperationException("Camping pot/ladle contact geometry is missing.");
			}
			idle = Support(-0.022f, 0f);
			for (int k = 0; k < 64; k++)
			{
				float num = (float)k * (MathF.PI / 32f);
				heights[k] = Support(Mathf.Sin(num) * 0.025f, Mathf.Cos(num) * 0.025f);
			}
		}

		internal Vector3 Position(float phase, bool cooking)
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0080: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			float num = -0.022f;
			float num2 = 0f;
			float num3 = idle;
			if (cooking)
			{
				num = Mathf.Sin(phase) * 0.025f;
				num2 = Mathf.Cos(phase) * 0.025f;
				float num4 = Mathf.Repeat(phase / (MathF.PI * 2f), 1f) * 64f;
				int num5 = (int)num4;
				num3 = Mathf.Lerp(heights[num5], heights[(num5 + 1) % 64], num4 - (float)num5);
			}
			return new Vector3(num, num3, num2) - Rotation * BowlCenter;
		}

		private float Support(float x, float z)
		{
			//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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0043: Unknown result type (might be due to invalid IL or missing references)
			float num = float.NegativeInfinity;
			Vector3[] array = bowl;
			foreach (Vector3 val in array)
			{
				float num2 = Floor(x + val.x, z + val.z);
				if (!float.IsInfinity(num2))
				{
					num = Mathf.Max(num, num2 + 0.0015f - val.y);
				}
			}
			if (float.IsInfinity(num))
			{
				throw new InvalidOperationException("Ladle bowl is outside the pot's interior support surface.");
			}
			return num;
		}

		private float Floor(float x, float z)
		{
			//IL_0014: 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_0023: Unknown result type (might be due to invalid IL or missing references)
			//IL_0028: Unknown result type (might be due to invalid IL or missing references)
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_0037: Unknown result type (might be due to invalid IL or missing references)
			//IL_0039: Unknown result type (might be due to invalid IL or missing references)
			//IL_003f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0056: Unknown result type (might be due to invalid IL or missing references)
			//IL_005d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0064: 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_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0085: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b3: 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_00c4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
			//IL_0103: Unknown result type (might be due to invalid IL or missing references)
			//IL_010c: Unknown result type (might be due to invalid IL or missing references)
			//IL_011f: Unknown result type (might be due to invalid IL or missing references)
			float num = float.NegativeInfinity;
			for (int i = 0; i < floor.Length; i += 3)
			{
				Vector3 val = floor[i];
				Vector3 val2 = floor[i + 1];
				Vector3 val3 = floor[i + 2];
				float num2 = (val2.z - val3.z) * (val.x - val3.x) + (val3.x - val2.x) * (val.z - val3.z);
				float num3 = ((val2.z - val3.z) * (x - val3.x) + (val3.x - val2.x) * (z - val3.z)) / num2;
				float num4 = ((val3.z - val.z) * (x - val3.x) + (val.x - val3.x) * (z - val3.z)) / num2;
				if (!(num3 < -1E-05f) && !(num4 < -1E-05f) && !(num3 + num4 > 1.00001f))
				{
					num = Mathf.Max(num, num3 * val.y + num4 * val2.y + (1f - num3 - num4) * val3.y);
				}
			}
			return num;
		}
	}
	internal static class CampLayout
	{
		internal static readonly Vector3 Fire = new Vector3(0f, 0f, 0.55f);

		internal static Vector3 Seat(int slot)
		{
			//IL_0013: Unknown result type (might be due to invalid IL or missing references)
			CampGroupRules.Seat(slot, out var x, out var z, out var _);
			return new Vector3(x, 0f, z);
		}

		internal static Quaternion Facing(int slot)
		{
			//IL_0017: Unknown result type (might be due to invalid IL or missing references)
			CampGroupRules.Seat(slot, out var _, out var _, out var yaw);
			return Quaternion.Euler(0f, yaw, 0f);
		}

		internal static Vector3 Bed(int slot)
		{
			//IL_0001: 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_001b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: 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)
			return