Decompiled source of CampOut v1.0.0

plugins\CampOut.dll

Decompiled 2 months ago
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Configuration;
using HarmonyLib;
using Jotunn.Configs;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using UnityEngine;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.6.2", FrameworkDisplayName = ".NET Framework 4.6.2")]
[assembly: AssemblyCompany("CampOut")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("CampOut")]
[assembly: AssemblyTitle("CampOut")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace CampOut;

[BepInPlugin("com.jimmy.valheim.campout", "Camp Out", "1.0.0")]
[BepInDependency(/*Could not decode attribute arguments.*/)]
[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
public sealed class CampOutPlugin : BaseUnityPlugin
{
	[HarmonyPatch(typeof(Humanoid), "UseItem")]
	private static class UseCampKitPatch
	{
		private static bool Prefix(Humanoid __instance, ItemData item)
		{
			//IL_0083: 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_0098: 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_00a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a9: Unknown result type (might be due to invalid IL or missing references)
			//IL_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_00f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_00fe: 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_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_0109: Unknown result type (might be due to invalid IL or missing references)
			//IL_010e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0113: Unknown result type (might be due to invalid IL or missing references)
			//IL_0115: Unknown result type (might be due to invalid IL or missing references)
			//IL_0117: 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_013d: 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)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_0149: Unknown result type (might be due to invalid IL or missing references)
			//IL_014e: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_01af: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c2: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c3: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ca: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cf: Unknown result type (might be due to invalid IL or missing references)
			//IL_01d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01da: 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_0166: Unknown result type (might be due to invalid IL or missing references)
			//IL_0167: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: 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_017b: 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)
			if ((Object)(object)item?.m_dropPrefab == (Object)null || ((Object)item.m_dropPrefab).name != "CampOutKit")
			{
				return true;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer)
			{
				return false;
			}
			long playerID = val.GetPlayerID();
			if (HasActiveCamp(playerID))
			{
				Message(val, "You already have an active camp. Pack it before placing another.");
				return false;
			}
			if (((Character)val).InInterior())
			{
				Message(val, "Camp Out cannot be placed inside a dungeon.");
				return false;
			}
			Vector3 val2 = ((Component)val).transform.position + ((Component)val).transform.forward * 2.5f;
			if (Physics.CheckSphere(val2 + Vector3.up, Mathf.Max(1f, ClearRadius.Value), LayerMask.GetMask(new string[1] { "piece" })))
			{
				Message(val, "Find a little more open ground for the camp.");
				return false;
			}
			Vector3 val3 = Vector3.ProjectOnPlane(((Component)val).transform.forward, Vector3.up);
			Vector3 normalized = ((Vector3)(ref val3)).normalized;
			Quaternion val4 = Quaternion.LookRotation(normalized, Vector3.up);
			Vector3 val5 = val4 * Vector3.right;
			string campId = Guid.NewGuid().ToString("N");
			GameObject val6 = SpawnPiece("piece_tent", val2 + normalized * 0.5f, val4);
			if ((Object)(object)val6 == (Object)null)
			{
				val6 = SpawnPiece("piece_roof_26", val2 + Vector3.up * 1.7f, val4 * Quaternion.Euler(0f, 0f, 25f));
			}
			GameObject val7 = SpawnPiece("bed", val2 - val5 * 0.65f, val4);
			GameObject val8 = SpawnPiece("fire_pit", val2 + val5 * 1.8f + normalized * 0.4f, val4);
			if ((Object)(object)val7 == (Object)null || (Object)(object)val8 == (Object)null || (Object)(object)val6 == (Object)null)
			{
				if ((Object)(object)val6 != (Object)null)
				{
					ZNetScene.instance.Destroy(val6);
				}
				if ((Object)(object)val7 != (Object)null)
				{
					ZNetScene.instance.Destroy(val7);
				}
				if ((Object)(object)val8 != (Object)null)
				{
					ZNetScene.instance.Destroy(val8);
				}
				Message(val, "The camp could not be placed here.");
				return false;
			}
			Tag(val6, campId, playerID);
			Tag(val7, campId, playerID, isBed: true);
			Tag(val8, campId, playerID);
			((Humanoid)val).GetInventory().RemoveItem(item, 1);
			Message(val, "Camp set up. Light the fire, then use the bedroll at night.");
			return false;
		}
	}

	[HarmonyPatch(typeof(Bed), "GetHoverText")]
	private static class CampBedHoverPatch
	{
		private static void Postfix(Bed __instance, ref string __result)
		{
			if (IsCampBed(__instance))
			{
				__result += "\n[<color=yellow>Crouch + $KEY_Use</color>] Pack camp";
			}
		}
	}

	[HarmonyPatch(typeof(Bed), "Interact")]
	private static class CampBedInteractPatch
	{
		private struct SpawnState
		{
			public bool Active;

			public bool HadSpawn;

			public Vector3 Spawn;
		}

		private static bool Prefix(Bed __instance, Humanoid user, bool hold, ref SpawnState __state)
		{
			//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a3: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a8: Unknown result type (might be due to invalid IL or missing references)
			Player val = (Player)(object)((user is Player) ? user : null);
			if ((Object)(object)val == (Object)null || hold || !IsCampBed(__instance))
			{
				return true;
			}
			ZNetView component = ((Component)__instance).GetComponent<ZNetView>();
			string campId = component.GetZDO().GetString("CampOut.Id", "");
			long num = component.GetZDO().GetLong("CampOut.Owner", 0L);
			if (((Character)val).IsCrouching())
			{
				if (val.GetPlayerID() != num)
				{
					Message(val, "Only the camp owner can pack this camp.");
					return false;
				}
				PackCamp(val, campId);
				return false;
			}
			Game instance = Game.instance;
			PlayerProfile val2 = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val2 != null)
			{
				__state.Active = true;
				__state.HadSpawn = val2.HaveCustomSpawnPoint();
				if (__state.HadSpawn)
				{
					__state.Spawn = val2.GetCustomSpawnPoint();
				}
				val2.SetCustomSpawnPoint(((Component)__instance).transform.position);
			}
			return true;
		}

		private static void Postfix(ref SpawnState __state)
		{
			//IL_0029: Unknown result type (might be due to invalid IL or missing references)
			if (!__state.Active)
			{
				return;
			}
			Game instance = Game.instance;
			PlayerProfile val = ((instance != null) ? instance.GetPlayerProfile() : null);
			if (val != null)
			{
				if (__state.HadSpawn)
				{
					val.SetCustomSpawnPoint(__state.Spawn);
				}
				else
				{
					val.ClearCustomSpawnPoint();
				}
			}
		}
	}

	public const string PluginGuid = "com.jimmy.valheim.campout";

	public const string PluginName = "Camp Out";

	public const string PluginVersion = "1.0.0";

	internal const string KitPrefabName = "CampOutKit";

	internal const string KitDisplayName = "Camp Out Kit";

	internal const string CampTag = "CampOut.Id";

	internal const string OwnerTag = "CampOut.Owner";

	internal const string BedTag = "CampOut.Bed";

	internal static ConfigEntry<int> WoodCost;

	internal static ConfigEntry<int> StoneCost;

	internal static ConfigEntry<int> DeerHideCost;

	internal static ConfigEntry<int> LeatherScrapsCost;

	internal static ConfigEntry<float> ClearRadius;

	private Harmony harmony;

	private void Awake()
	{
		//IL_00bd: Unknown result type (might be due to invalid IL or missing references)
		//IL_00c7: Expected O, but got Unknown
		WoodCost = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "Wood", 50, "Wood required to craft the reusable kit.");
		StoneCost = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "Stone", 20, "Stone required to craft the reusable kit.");
		DeerHideCost = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "DeerHide", 3, "Deer hide required to craft the reusable kit.");
		LeatherScrapsCost = ((BaseUnityPlugin)this).Config.Bind<int>("Recipe", "LeatherScraps", 6, "Leather scraps required to craft the reusable kit.");
		ClearRadius = ((BaseUnityPlugin)this).Config.Bind<float>("Camp", "PlacementClearRadius", 3.5f, "Open ground required around the player when placing camp.");
		PrefabManager.OnVanillaPrefabsAvailable += RegisterKit;
		harmony = new Harmony("com.jimmy.valheim.campout");
		harmony.PatchAll();
	}

	private void OnDestroy()
	{
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterKit;
		Harmony obj = harmony;
		if (obj != null)
		{
			obj.UnpatchSelf();
		}
	}

	private void RegisterKit()
	{
		//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_0010: 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_0026: Unknown result type (might be due to invalid IL or missing references)
		//IL_002d: Unknown result type (might be due to invalid IL or missing references)
		//IL_0034: 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: Expected O, but got Unknown
		//IL_00a6: Unknown result type (might be due to invalid IL or missing references)
		//IL_00ac: Expected O, but got Unknown
		ItemConfig val = new ItemConfig
		{
			Name = "Camp Out Kit",
			Description = "A reusable shelter, bedroll, and campfire. Right-click to set up camp.",
			CraftingStation = "piece_workbench",
			MinStationLevel = 1,
			Amount = 1,
			Weight = 5f,
			StackSize = 1
		};
		AddRequirement(val, "Wood", WoodCost.Value);
		AddRequirement(val, "Stone", StoneCost.Value);
		AddRequirement(val, "DeerHide", DeerHideCost.Value);
		AddRequirement(val, "LeatherScraps", LeatherScrapsCost.Value);
		CustomItem val2 = new CustomItem("CampOutKit", "Hammer", val);
		ItemManager.Instance.AddItem(val2);
		PrefabManager.OnVanillaPrefabsAvailable -= RegisterKit;
	}

	private static void AddRequirement(ItemConfig config, string item, int amount)
	{
		//IL_0009: Unknown result type (might be due to invalid IL or missing references)
		//IL_0013: Expected O, but got Unknown
		if (amount > 0)
		{
			config.AddRequirement(new RequirementConfig(item, amount, 0, true));
		}
	}

	internal static void Message(Player player, string text)
	{
		((Character)player).Message((MessageType)2, text, 0, (Sprite)null, false);
	}

	internal static bool IsCampBed(Bed bed)
	{
		ZNetView val = ((bed != null) ? ((Component)bed).GetComponent<ZNetView>() : null);
		if ((Object)(object)val != (Object)null && val.IsValid())
		{
			return val.GetZDO().GetBool("CampOut.Bed", false);
		}
		return false;
	}

	internal static bool HasActiveCamp(long ownerId)
	{
		ZNetView[] array = Object.FindObjectsOfType<ZNetView>();
		foreach (ZNetView val in array)
		{
			if (val.IsValid() && val.GetZDO().GetLong("CampOut.Owner", 0L) == ownerId && !string.IsNullOrEmpty(val.GetZDO().GetString("CampOut.Id", "")))
			{
				return true;
			}
		}
		return false;
	}

	internal static void Tag(GameObject obj, string campId, long ownerId, bool isBed = false)
	{
		ZNetView val = ((obj != null) ? obj.GetComponent<ZNetView>() : null);
		if (!((Object)(object)val == (Object)null) && val.IsValid())
		{
			val.GetZDO().Set("CampOut.Id", campId);
			val.GetZDO().Set("CampOut.Owner", ownerId);
			if (isBed)
			{
				val.GetZDO().Set("CampOut.Bed", true);
			}
		}
	}

	internal static GameObject SpawnPiece(string prefabName, Vector3 position, Quaternion rotation)
	{
		//IL_001d: 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)
		ZNetScene instance = ZNetScene.instance;
		GameObject val = ((instance != null) ? instance.GetPrefab(prefabName) : null);
		if (!((Object)(object)val == (Object)null))
		{
			return Object.Instantiate<GameObject>(val, position, rotation);
		}
		return null;
	}

	internal static void PackCamp(Player player, string campId)
	{
		//IL_010b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0116: Unknown result type (might be due to invalid IL or missing references)
		//IL_011b: Unknown result type (might be due to invalid IL or missing references)
		//IL_0120: Unknown result type (might be due to invalid IL or missing references)
		//IL_0125: Unknown result type (might be due to invalid IL or missing references)
		//IL_012a: Unknown result type (might be due to invalid IL or missing references)
		List<ZNetView> list = new List<ZNetView>();
		ZNetView[] array = Object.FindObjectsOfType<ZNetView>();
		foreach (ZNetView val in array)
		{
			if (val.IsValid() && val.GetZDO().GetString("CampOut.Id", "") == campId)
			{
				list.Add(val);
			}
		}
		foreach (ZNetView item in list)
		{
			if ((Object)(object)item != (Object)null && item.IsValid())
			{
				item.ClaimOwnership();
				ZNetScene.instance.Destroy(((Component)item).gameObject);
			}
		}
		ObjectDB instance = ObjectDB.instance;
		GameObject val2 = ((instance != null) ? instance.GetItemPrefab("CampOutKit") : null);
		ItemDrop val3 = ((val2 != null) ? val2.GetComponent<ItemDrop>() : null);
		if ((Object)(object)val3 != (Object)null && ((Humanoid)player).GetInventory().AddItem(val3.m_itemData.Clone()))
		{
			Message(player, "Camp packed. The Camp Out Kit is back in your inventory.");
		}
		else if ((Object)(object)val2 != (Object)null)
		{
			Object.Instantiate<GameObject>(val2, ((Component)player).transform.position + ((Component)player).transform.forward + Vector3.up, Quaternion.identity);
			Message(player, "Inventory full—the Camp Out Kit was dropped beside you.");
		}
	}
}