Decompiled source of ExtraItems v1.0.0

BepInEx/plugins/ExtraItems.dll

Decompiled 6 months ago
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Logging;
using ExtraItems.items;
using HarmonyLib;
using Microsoft.CodeAnalysis;
using Photon.Pun;
using Sirenix.Utilities;
using UnityEngine;
using UnityEngine.SceneManagement;
using Zorro.Core;
using Zorro.Core.Serizalization;

[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: TargetFramework(".NETFramework,Version=v4.7.1", FrameworkDisplayName = ".NET Framework 4.7.1")]
[assembly: AssemblyCompany("ExtraItems")]
[assembly: AssemblyConfiguration("Release")]
[assembly: AssemblyDescription("Adds several new items to Content Warning")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("ExtraItems")]
[assembly: AssemblyTitle("ExtraItems")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[Microsoft.CodeAnalysis.Embedded]
	[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
	internal sealed class RefSafetyRulesAttribute : Attribute
	{
		public readonly int Version;

		public RefSafetyRulesAttribute(int P_0)
		{
			Version = P_0;
		}
	}
}
namespace ExtraItems
{
	public class SingleUseItemEntry : ItemDataEntry, IHaveUIData
	{
		private bool _wasUsed;

		public bool wasUsed
		{
			get
			{
				return _wasUsed;
			}
			set
			{
				_wasUsed = value;
				((ItemDataEntry)this).SetDirty();
			}
		}

		public override void Deserialize(BinaryDeserializer binaryDeserializer)
		{
			_wasUsed = binaryDeserializer.ReadBool();
		}

		public override void Serialize(BinarySerializer binarySerializer)
		{
			binarySerializer.WriteBool(_wasUsed);
		}

		public string GetString()
		{
			if (!_wasUsed)
			{
				return "Unused";
			}
			return "Already used";
		}
	}
	public abstract class CustomItem<T> : ItemInstanceBehaviour where T : CustomItem<T>, new()
	{
		public abstract string ItemName { get; }

		public virtual int Price => 100;

		public virtual ShopItemCategory ShopCategory => (ShopItemCategory)3;

		public virtual GameObject BaseObject => null;

		public sealed override void ConfigItem(ItemInstanceData data, PhotonView playerView)
		{
			//IL_0034: Unknown result type (might be due to invalid IL or missing references)
			ExtraItemsPlugin.Logger.LogInfo((object)("Configuring custom item '" + base.itemInstance.item.displayName + "'"));
			((Component)base.itemInstance).transform.localScale = Vector3.one;
			ConfigCustomItem(data, playerView);
		}

		public static Item AddItemToGame()
		{
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_003a: Unknown result type (might be due to invalid IL or missing references)
			T val = new T();
			if ((Object)(object)val.BaseObject == (Object)null)
			{
				return CustomItemManager.Instance.CreateNewItem<T>(val.ItemName, val.Price, val.ShopCategory);
			}
			return CustomItemManager.Instance.CreateNewItem<T>(val.ItemName, val.BaseObject, val.Price, val.ShopCategory);
		}

		protected abstract void ConfigCustomItem(ItemInstanceData data, PhotonView playerView);
	}
	public class CustomItemManager
	{
		private static CustomItemManager _instance = new CustomItemManager();

		private int _newItemID;

		public static CustomItemManager Instance => _instance;

		public Shader NiceShader { get; private set; }

		private CustomItemManager()
		{
			_newItemID = 0;
			Item[] objects = ((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects;
			foreach (Item val in objects)
			{
				if (val.id > _newItemID)
				{
					_newItemID = val.id;
				}
			}
			_newItemID++;
			NiceShader = Resources.FindObjectsOfTypeAll<Shader>().First((Shader shader) => ((Object)shader).name == "NiceShader");
		}

		public GameObject SetupBaseObject(GameObject @object)
		{
			//IL_001a: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(@object);
			Object.DontDestroyOnLoad((Object)(object)val);
			val.AddComponent<ItemInstance>();
			val.transform.localScale = Vector3.zero;
			((Component)val.transform.GetChild(0)).gameObject.AddComponent<HandGizmo>();
			Material[] materials = ((Renderer)val.GetComponentInChildren<MeshRenderer>()).materials;
			for (int i = 0; i < materials.Length; i++)
			{
				materials[i].shader = NiceShader;
			}
			return val;
		}

		public Item CreateNewItem<T>(string itemName, int price = 100, ShopItemCategory shopCategory = 3) where T : ItemInstanceBehaviour
		{
			//IL_000d: Unknown result type (might be due to invalid IL or missing references)
			return CreateNewItem(itemName, typeof(T), price, shopCategory);
		}

		public Item CreateNewItem(string itemName, Type instanceBehaviour, int price = 100, ShopItemCategory shopCategory = 3)
		{
			//IL_0092: 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_00ae: Unknown result type (might be due to invalid IL or missing references)
			//IL_0067: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = Object.Instantiate<GameObject>(((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects.First((Item item) => item.id == 7).itemObject);
			((Object)val).name = "_TEMPLATE_" + itemName;
			if (TypeExtensions.InheritsFrom(instanceBehaviour, typeof(CustomItem<>).GetGenericTypeDefinition()))
			{
				val.transform.localScale = Vector3.zero;
			}
			Object.DontDestroyOnLoad((Object)(object)val);
			Object.Destroy((Object)(object)val.GetComponent<Flare>());
			Object.Destroy((Object)(object)val.GetComponent<SFX_PlayOneShot>());
			Item obj = CreateNewItem(itemName, instanceBehaviour, val, price, shopCategory);
			obj.alternativeHoldRot = new Vector3(-10f, -10f, 5f);
			obj.useAlternativeHoldingRot = true;
			if ((Object)(object)obj == (Object)null)
			{
				Object.Destroy((Object)(object)val);
			}
			return obj;
		}

		public Item CreateNewItem<T>(string itemName, GameObject baseItem, int price = 100, ShopItemCategory shopCategory = 3) where T : ItemInstanceBehaviour
		{
			//IL_000e: Unknown result type (might be due to invalid IL or missing references)
			return CreateNewItem(itemName, typeof(T), baseItem, price, shopCategory);
		}

		public Item CreateNewItem(string itemName, Type instanceBehaviour, GameObject baseItem, int price = 100, ShopItemCategory shopCategory = 3)
		{
			//IL_0095: Unknown result type (might be due to invalid IL or missing references)
			//IL_009b: 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)
			if (_newItemID > 255)
			{
				ExtraItemsPlugin.Logger.LogError((object)"Cannot add another custom object. Object limit (256 Objects) reached");
			}
			else if (!TypeExtensions.InheritsFrom<ItemInstanceBehaviour>(instanceBehaviour))
			{
				ExtraItemsPlugin.Logger.LogError((object)("Custom item '" + itemName + "' behaviour class '" + instanceBehaviour.Name + "' doesn't inherit from ItemInstanceBehaviour!"));
				return null;
			}
			Item obj = ScriptableObject.CreateInstance<Item>();
			obj.price = price;
			obj.displayName = itemName;
			((Object)obj).name = itemName;
			obj.purchasable = true;
			obj.budgetCost = price;
			obj.itemObject = baseItem;
			obj.itemType = (ItemType)1;
			obj.Category = shopCategory;
			obj.quantity = 0;
			obj.id = (byte)_newItemID;
			_newItemID++;
			obj.itemObject.AddComponent(instanceBehaviour);
			RegisterItem(obj);
			return obj;
		}

		public static void RegisterItem(Item item)
		{
			((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects = CollectionExtensions.AddItem<Item>((IEnumerable<Item>)((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects, item).ToArray();
			ExtraItemsPlugin.Logger.LogInfo((object)$"Custom item '{item.displayName}' was registered with ID {item.id}");
		}

		public static bool IsSubclassOfRawGeneric(Type generic, Type toCheck)
		{
			while (toCheck != null && toCheck != typeof(object))
			{
				Type type = (toCheck.IsGenericType ? toCheck.GetGenericTypeDefinition() : toCheck);
				if (generic == type)
				{
					return true;
				}
				toCheck = toCheck.BaseType;
			}
			return false;
		}
	}
	[BepInPlugin("ExtraItems", "ExtraItems", "1.0.0")]
	[BepInProcess("Content Warning.exe")]
	public class ExtraItemsPlugin : BaseUnityPlugin
	{
		internal static ManualLogSource Logger;

		private Harmony _harmony;

		private bool _isInitialized;

		public static DivingBell DivingBell { get; private set; }

		private void Awake()
		{
			_isInitialized = false;
			Logger = ((BaseUnityPlugin)this).Logger;
			Logger.LogInfo((object)"Plugin ExtraItems is loaded!");
			SceneManager.sceneLoaded += OnSceneLoaded;
			_harmony = Harmony.CreateAndPatchAll(Assembly.GetExecutingAssembly(), "Toedtmanns.ExtraItems");
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			//IL_004e: Unknown result type (might be due to invalid IL or missing references)
			if (_isInitialized)
			{
				return;
			}
			_ = PackageLoader.Instance;
			_isInitialized = true;
			DivingBell = Object.FindObjectOfType<DivingBell>();
			Item[] objects = ((DatabaseAsset<ItemDatabase, Item>)(object)SingletonAsset<ItemDatabase>.Instance).Objects;
			foreach (Item val in objects)
			{
				if (val.displayName == "Camera")
				{
					val.purchasable = true;
					val.Category = (ShopItemCategory)3;
					break;
				}
			}
			CustomItem<OxygenTankItem>.AddItemToGame();
			CustomItem<EnergyDrinkItem>.AddItemToGame();
		}
	}
	[HarmonyPatch(typeof(ItemInstanceData), "GetEntryIdentifier")]
	internal static class EntryIdentifierPatch
	{
		private static Exception Finalizer(Exception __exception, ref byte __result, object[] __args)
		{
			if ((Type)__args[0] == typeof(SingleUseItemEntry))
			{
				__result = 9;
				return null;
			}
			return __exception;
		}
	}
	[HarmonyPatch(typeof(ItemInstanceData), "GetEntryType")]
	internal static class EntryTypePatch
	{
		private static Exception Finalizer(Exception __exception, ref ItemDataEntry __result, object[] __args)
		{
			if ((byte)__args[0] == 9)
			{
				__result = (ItemDataEntry)(object)new SingleUseItemEntry();
				return null;
			}
			return __exception;
		}
	}
	public class PackageLoader
	{
		private static PackageLoader _instance = new PackageLoader();

		public static PackageLoader Instance => _instance;

		public string PackagePath { get; private set; }

		public AssetBundle ExtraItemsBundle { get; private set; }

		public GameObject GetPrefab(string name)
		{
			if (!ExtraItemsBundle.Contains(name))
			{
				ExtraItemsPlugin.Logger.LogInfo((object)("Could not find prefab '" + name + "'"));
				return null;
			}
			return ExtraItemsBundle.LoadAsset<GameObject>(name);
		}

		private PackageLoader()
		{
			PackagePath = Paths.PluginPath;
			LoadMainPackage();
		}

		private void LoadMainPackage()
		{
			ExtraItemsBundle = AssetBundle.LoadFromFile(Utility.CombinePaths(new string[2] { PackagePath, "extraitemsbundle" }));
		}
	}
	public static class MyPluginInfo
	{
		public const string PLUGIN_GUID = "ExtraItems";

		public const string PLUGIN_NAME = "ExtraItems";

		public const string PLUGIN_VERSION = "1.0.0";
	}
}
namespace ExtraItems.items
{
	public class EnergyDrinkItem : CustomItem<EnergyDrinkItem>
	{
		private GameObject _baseObject;

		public const float DrinkDuration = 8f;

		public const float DrinkEffectiveness = 2f;

		private SingleUseItemEntry _itemState;

		private StashAbleEntry _stashable;

		public override string ItemName => "Energy Drink";

		public override int Price => 30;

		public override ShopItemCategory ShopCategory => (ShopItemCategory)2;

		public override GameObject BaseObject
		{
			get
			{
				if ((Object)(object)_baseObject == (Object)null)
				{
					GameObject prefab = PackageLoader.Instance.GetPrefab("EnergyDrink");
					_baseObject = CustomItemManager.Instance.SetupBaseObject(prefab);
				}
				return _baseObject;
			}
		}

		protected override void ConfigCustomItem(ItemInstanceData data, PhotonView playerView)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			if (!data.TryGetEntry<StashAbleEntry>(ref _stashable))
			{
				_stashable = new StashAbleEntry
				{
					isStashAble = true
				};
				data.AddDataEntry((ItemDataEntry)(object)_stashable);
			}
			if (data.TryGetEntry<SingleUseItemEntry>(ref _itemState))
			{
				ExtraItemsPlugin.Logger.LogInfo((object)("Single use entry found with state: " + _itemState.GetString()));
			}
			else
			{
				_itemState = new SingleUseItemEntry
				{
					wasUsed = false
				};
				data.AddDataEntry((ItemDataEntry)(object)_itemState);
			}
			((Component)((ItemInstanceBehaviour)this).itemInstance).transform.localScale = Vector3.one;
		}

		private void Update()
		{
			if (((ItemInstanceBehaviour)this).isHeldByMe && !_itemState.wasUsed && Player.localPlayer.input.clickWasPressed && !Player.localPlayer.HasLockedInput())
			{
				((MonoBehaviour)Player.localPlayer).StartCoroutine(ReEnergize());
				_itemState.wasUsed = true;
				ExtraItemsPlugin.Logger.LogInfo((object)$"Player '{((Object)Player.localPlayer).name}' drank an energy drink with {Player.localPlayer.data.currentStamina} stamina");
			}
		}

		private IEnumerator ReEnergize()
		{
			Player.localPlayer.data.staminaDepleated = false;
			float maxStam = Player.localPlayer.refs.controller.maxStamina;
			for (float remainingDuration = 8f; remainingDuration >= 0f; remainingDuration -= Time.deltaTime)
			{
				Player.localPlayer.data.currentStamina = Mathf.MoveTowards(Player.localPlayer.data.currentStamina, maxStam, 2f * Time.deltaTime);
				yield return null;
			}
		}
	}
	public class OxygenTankItem : CustomItem<OxygenTankItem>
	{
		private StashAbleEntry _stashableEntry;

		private SingleUseItemEntry _itemState;

		private GameObject _baseObject;

		public override string ItemName => "Oxygen Tank";

		public override int Price => 50;

		public override ShopItemCategory ShopCategory => (ShopItemCategory)2;

		public override GameObject BaseObject
		{
			get
			{
				if ((Object)(object)_baseObject == (Object)null)
				{
					_baseObject = CustomItemManager.Instance.SetupBaseObject(PackageLoader.Instance.GetPrefab("OxygenTank"));
				}
				return _baseObject;
			}
		}

		protected override void ConfigCustomItem(ItemInstanceData data, PhotonView playerView)
		{
			//IL_000f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0014: Unknown result type (might be due to invalid IL or missing references)
			//IL_0020: Expected O, but got Unknown
			if (!data.TryGetEntry<StashAbleEntry>(ref _stashableEntry))
			{
				_stashableEntry = new StashAbleEntry
				{
					isStashAble = true
				};
				data.AddDataEntry((ItemDataEntry)(object)_stashableEntry);
			}
			if (data.TryGetEntry<SingleUseItemEntry>(ref _itemState))
			{
				ExtraItemsPlugin.Logger.LogInfo((object)("Single use entry found with state: " + _itemState.GetString()));
				return;
			}
			_itemState = new SingleUseItemEntry
			{
				wasUsed = false
			};
			data.AddDataEntry((ItemDataEntry)(object)_itemState);
		}

		private void Update()
		{
			if (((ItemInstanceBehaviour)this).isHeldByMe && !_itemState.wasUsed && Player.localPlayer.input.clickWasPressed && !Player.localPlayer.HasLockedInput() && Player.localPlayer.data.usingOxygen)
			{
				ExtraItemsPlugin.Logger.LogInfo((object)("Player '" + ((Object)Player.localPlayer).name + "' refreshed their oxygen with a tank"));
				((MonoBehaviour)Player.localPlayer).StartCoroutine(ReOxidize());
				_itemState.wasUsed = true;
			}
		}

		private IEnumerator ReOxidize()
		{
			float maxOxygen = Player.localPlayer.data.maxOxygen;
			Player.localPlayer.data.usingOxygen = false;
			while (Player.localPlayer.data.remainingOxygen < maxOxygen)
			{
				Player.localPlayer.data.remainingOxygen = Mathf.MoveTowards(Player.localPlayer.data.remainingOxygen, maxOxygen, 50f * Time.deltaTime);
				yield return null;
			}
			Player.localPlayer.data.usingOxygen = true;
			ExtraItemsPlugin.Logger.LogInfo((object)"Oxygen refilled");
		}
	}
}