Decompiled source of FatalsCutsAndBruises v0.0.1

plugins/FatalsCutsAndBruises.dll

Decompiled 4 months ago
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using FatalsCutsAndBruises.Effects;
using HarmonyLib;
using Jotunn;
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.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("FatalsCutsandBruises")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FatalsCutsandBruises")]
[assembly: AssemblyCopyright("Copyright ©  2021")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
namespace FatalsCutsAndBruises
{
	public class CoroutineHost : MonoBehaviour
	{
		private static CoroutineHost _instance;

		public static CoroutineHost Instance
		{
			get
			{
				//IL_0016: Unknown result type (might be due to invalid IL or missing references)
				//IL_001c: Expected O, but got Unknown
				if ((Object)(object)_instance == (Object)null)
				{
					GameObject val = new GameObject("CutsAndBruises_CoroutineHost");
					_instance = val.AddComponent<CoroutineHost>();
					Object.DontDestroyOnLoad((Object)(object)val);
				}
				return _instance;
			}
		}
	}
	[BepInPlugin("jotunn.fatal.cutsandbruises", "Fatals Cuts and Bruises", "1.0.0")]
	public class CutsAndBruises : BaseUnityPlugin
	{
		public class RemoveInfectionEffect : StatusEffect
		{
			public override void Setup(Character character)
			{
				((StatusEffect)this).Setup(character);
				if ((Object)(object)base.m_character != (Object)null)
				{
					base.m_character.m_seman.RemoveStatusEffect(InfectionEffectHash, true);
				}
			}
		}

		public const string PluginGUID = "jotunn.fatal.cutsandbruises";

		public const string PluginName = "Fatals Cuts and Bruises";

		public const string PluginVersion = "1.0.0";

		public static ConfigEntry<float> CutChance;

		public static ConfigEntry<float> CutDuration;

		public static ConfigEntry<float> BruiseChance;

		public static ConfigEntry<float> BruiseDuration;

		public static ConfigEntry<float> BruiseTickInterval;

		public static ConfigEntry<float> BruiseStaminaReduction;

		public static ConfigEntry<float> InfectionChance;

		public static ConfigEntry<float> InfectionDamagePerTick;

		public static ConfigEntry<float> InfectionTickInterval;

		public static ConfigEntry<float> InfectionDuration;

		public static Sprite CutSprite;

		public static Sprite InfectedSprite;

		public static Sprite BruiseSprite;

		public static Sprite AntibioticSprite;

		public static StatusEffect CutEffectPrefab;

		public static StatusEffect BruiseEffectPrefab;

		public static StatusEffect InfectionEffectPrefab;

		public static int CutEffectHash;

		public static int BruiseEffectHash;

		public static int InfectionEffectHash;

		private Harmony harmony;

		private void Awake()
		{
			//IL_0012: Unknown result type (might be due to invalid IL or missing references)
			//IL_001c: Expected O, but got Unknown
			Logger.LogInfo((object)"CutsAndBruises mod initializing...");
			harmony = new Harmony("com.fatal.cutsandbruises");
			harmony.PatchAll();
			CreateConfig();
			LoadIcons();
			PrefabManager.OnVanillaPrefabsAvailable += RegisterStatusEffects;
			PrefabManager.OnVanillaPrefabsAvailable += CreateAntibioticItem;
			AddLocalizations();
		}

		private void CreateConfig()
		{
			CutChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Cut Chance", 0.1f, (ConfigDescription)null);
			CutDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Cut Duration", 30f, (ConfigDescription)null);
			BruiseChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Bruise Chance", 0.2f, (ConfigDescription)null);
			BruiseDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Bruise Duration", 45f, (ConfigDescription)null);
			BruiseTickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Bruise Tick Interval", 2f, (ConfigDescription)null);
			BruiseStaminaReduction = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Bruise Stamina Reduction", 10f, (ConfigDescription)null);
			InfectionChance = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Infection Chance", 0.01f, (ConfigDescription)null);
			InfectionDamagePerTick = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Infection Damage", 2f, (ConfigDescription)null);
			InfectionTickInterval = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Infection Tick Interval", 4f, (ConfigDescription)null);
			InfectionDuration = ((BaseUnityPlugin)this).Config.Bind<float>("General", "Infection Duration", 2000f, (ConfigDescription)null);
		}

		private void AddLocalizations()
		{
			CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
			string text = "English";
			localization.AddTranslation(ref text, new Dictionary<string, string>
			{
				{ "status_cut", "Cut" },
				{ "status_infected", "Infected" },
				{ "status_bruise", "Bruise" },
				{ "item_antibiotic", "Antibiotic" },
				{ "item_antibiotic_description", "A dose of antibiotics. Removes infection." }
			});
			LocalizationManager.Instance.AddLocalization(localization);
		}

		private void RegisterStatusEffects()
		{
			PrefabManager.OnVanillaPrefabsAvailable -= RegisterStatusEffects;
			CutEffect cutEffect = ScriptableObject.CreateInstance<CutEffect>();
			((Object)cutEffect).name = "Cut";
			((StatusEffect)cutEffect).m_name = "$status_cut";
			((StatusEffect)cutEffect).m_icon = CutSprite;
			((StatusEffect)cutEffect).m_tooltip = "You're bleeding from a wound.";
			((StatusEffect)cutEffect).m_ttl = CutDuration.Value;
			CutEffectPrefab = (StatusEffect)(object)cutEffect;
			CutEffectHash = StringExtensionMethods.GetStableHashCode(((Object)cutEffect).name);
			BruiseEffect bruiseEffect = ScriptableObject.CreateInstance<BruiseEffect>();
			((Object)bruiseEffect).name = "Bruise";
			((StatusEffect)bruiseEffect).m_name = "$status_bruise";
			((StatusEffect)bruiseEffect).m_icon = BruiseSprite;
			((StatusEffect)bruiseEffect).m_tooltip = "You have a bruise that reduces your stamina.";
			((StatusEffect)bruiseEffect).m_ttl = BruiseDuration.Value;
			BruiseEffectPrefab = (StatusEffect)(object)bruiseEffect;
			BruiseEffectHash = StringExtensionMethods.GetStableHashCode(((Object)bruiseEffect).name);
			InfectionEffect infectionEffect = ScriptableObject.CreateInstance<InfectionEffect>();
			((Object)infectionEffect).name = "Infected";
			((StatusEffect)infectionEffect).m_name = "$status_infected";
			((StatusEffect)infectionEffect).m_icon = InfectedSprite;
			((StatusEffect)infectionEffect).m_tooltip = "The wound is infected and draining your strength.";
			((StatusEffect)infectionEffect).m_ttl = InfectionDuration.Value;
			InfectionEffectPrefab = (StatusEffect)(object)infectionEffect;
			InfectionEffectHash = StringExtensionMethods.GetStableHashCode(((Object)infectionEffect).name);
			Logger.LogInfo((object)$"CutEffect m_icon is null: {(Object)(object)((StatusEffect)cutEffect).m_icon == (Object)null}");
			Logger.LogInfo((object)$"InfectionEffect m_icon is null: {(Object)(object)((StatusEffect)infectionEffect).m_icon == (Object)null}");
			ObjectDB.instance.m_StatusEffects.Add(CutEffectPrefab);
			ObjectDB.instance.m_StatusEffects.Add(InfectionEffectPrefab);
			Logger.LogInfo((object)"Custom status effects registered using SE_Stats clone.");
		}

		private void LoadIcons()
		{
			Logger.LogInfo((object)"LoadIcons() called");
			AssetBundle val = AssetUtils.LoadAssetBundleFromResources("cut", typeof(CutsAndBruises).Assembly);
			if ((Object)(object)val == (Object)null)
			{
				Logger.LogError((object)"Failed to load Cut asset bundle");
				return;
			}
			CutSprite = val.LoadAsset<Sprite>("cut");
			Logger.LogInfo((object)$"CutSprite loaded: {(Object)(object)CutSprite != (Object)null}");
			AssetBundle val2 = AssetUtils.LoadAssetBundleFromResources("infected", typeof(CutsAndBruises).Assembly);
			if ((Object)(object)val2 == (Object)null)
			{
				Logger.LogError((object)"Failed to load Infected asset bundle");
				return;
			}
			InfectedSprite = val2.LoadAsset<Sprite>("infected");
			Logger.LogInfo((object)$"InfectedSprite loaded: {(Object)(object)InfectedSprite != (Object)null}");
			AssetBundle val3 = AssetUtils.LoadAssetBundleFromResources("antibiotic", typeof(CutsAndBruises).Assembly);
			if ((Object)(object)val3 == (Object)null)
			{
				Logger.LogError((object)"Failed to load Antibiotic asset bundle");
				return;
			}
			AntibioticSprite = val3.LoadAsset<Sprite>("antibiotic");
			Logger.LogInfo((object)$"AntibioticSprite loaded: {(Object)(object)AntibioticSprite != (Object)null}");
			AssetBundle val4 = AssetUtils.LoadAssetBundleFromResources("bruise", typeof(CutsAndBruises).Assembly);
			if ((Object)(object)val4 == (Object)null)
			{
				Logger.LogError((object)"Failed to load Bruise asset bundle");
				return;
			}
			BruiseSprite = val4.LoadAsset<Sprite>("bruise");
			Logger.LogInfo((object)$"BruiseSprite loaded: {(Object)(object)BruiseSprite != (Object)null}");
		}

		private void CreateAntibioticItem()
		{
			//IL_0001: Unknown result type (might be due to invalid IL or missing references)
			//IL_0007: Expected O, but got Unknown
			//IL_0048: Unknown result type (might be due to invalid IL or missing references)
			//IL_004e: Expected O, but got Unknown
			//IL_0058: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Expected O, but got Unknown
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			ItemConfig val = new ItemConfig();
			val.Name = "$item_antibiotic";
			val.Description = "$item_antibiotic_description";
			val.CraftingStation = "Workbench";
			val.Icon = AntibioticSprite;
			val.Requirements = (RequirementConfig[])(object)new RequirementConfig[2]
			{
				new RequirementConfig("Mushroom", 1, 0, true),
				new RequirementConfig("Dandelion", 2, 0, true)
			};
			ItemConfig val2 = val;
			CustomItem val3 = new CustomItem("antibioticPrefab", "Mushroom", val2);
			val3.ItemDrop.m_itemData.m_shared.m_consumeStatusEffect = (StatusEffect)(object)ScriptableObject.CreateInstance<RemoveInfectionEffect>();
			ItemManager.Instance.AddItem(val3);
			PrefabManager.OnVanillaPrefabsAvailable -= CreateAntibioticItem;
		}
	}
}
namespace FatalsCutsAndBruises.Patches
{
	[HarmonyPatch(typeof(Character), "Damage")]
	public static class DamageHook
	{
		[HarmonyPrefix]
		private static void Prefix(Character __instance, HitData hit)
		{
			if ((Object)(object)__instance == (Object)null || !__instance.IsPlayer() || !__instance.IsOwner())
			{
				return;
			}
			Player val = (Player)(object)((__instance is Player) ? __instance : null);
			if (!((Object)(object)val == (Object)null))
			{
				SEMan sEMan = ((Character)val).GetSEMan();
				if (!sEMan.HaveStatusEffect(CutsAndBruises.CutEffectHash) && Random.value < CutsAndBruises.CutChance.Value)
				{
					sEMan.AddStatusEffect(CutsAndBruises.CutEffectPrefab, false, 0, 0f);
					Logger.LogInfo((object)"Cut status effect applied");
				}
				if (!sEMan.HaveStatusEffect(CutsAndBruises.BruiseEffectHash) && Random.value < CutsAndBruises.BruiseChance.Value)
				{
					sEMan.AddStatusEffect(CutsAndBruises.BruiseEffectPrefab, false, 0, 0f);
					Logger.LogInfo((object)"Bruise status effect applied");
				}
			}
		}
	}
}
namespace FatalsCutsAndBruises.Effects
{
	public class BruiseEffect : SE_Stats
	{
		private float damageTimer = 0f;

		public override void Setup(Character character)
		{
			((SE_Stats)this).Setup(character);
			((StatusEffect)this).m_ttl = CutsAndBruises.BruiseDuration.Value;
			Logger.LogInfo((object)"BruiseEffect Setup() called");
		}

		public override void UpdateStatusEffect(float dt)
		{
			((SE_Stats)this).UpdateStatusEffect(dt);
			damageTimer += dt;
			if (damageTimer >= CutsAndBruises.BruiseTickInterval.Value)
			{
				damageTimer = 0f;
				Logger.LogInfo((object)"BruiseEffect reducing stamina");
				Character character = ((StatusEffect)this).m_character;
				Player val = (Player)(object)((character is Player) ? character : null);
				if (val != null)
				{
					float value = CutsAndBruises.BruiseStaminaReduction.Value;
					((Character)val).UseStamina(value);
				}
			}
		}
	}
	public class CutEffect : SE_Stats
	{
		private float infectionCheckTimer = 0f;

		public override void Setup(Character character)
		{
			((SE_Stats)this).Setup(character);
			Logger.LogInfo((object)"CutEffect Setup() called");
		}

		private bool PlayerHasAntibioticInFoodBar(Player player)
		{
			return player.m_foods.Any((Food fd) => fd.m_item != null && fd.m_item.m_shared != null && fd.m_item.m_shared.m_name == "$item_antibiotic");
		}

		public override void UpdateStatusEffect(float dt)
		{
			((SE_Stats)this).UpdateStatusEffect(dt);
			infectionCheckTimer += dt;
			if (!(infectionCheckTimer >= 1f))
			{
				return;
			}
			infectionCheckTimer = 0f;
			Character character = ((StatusEffect)this).m_character;
			Player val = (Player)(object)((character is Player) ? character : null);
			if (!((Object)(object)val == (Object)null))
			{
				Logger.LogInfo((object)"CutEffect UpdateStatusEffect() tick");
				SEMan sEMan = ((StatusEffect)this).m_character.GetSEMan();
				bool flag = PlayerHasAntibioticInFoodBar(val);
				if (!flag && !sEMan.HaveStatusEffect(CutsAndBruises.InfectionEffectHash) && Random.value < CutsAndBruises.InfectionChance.Value)
				{
					Logger.LogInfo((object)"Applying InfectionEffect from CutEffect");
					sEMan.AddStatusEffect(CutsAndBruises.InfectionEffectPrefab, false, 0, 0f);
				}
				else if (flag)
				{
					Logger.LogInfo((object)"Player has antibiotic in food bar, skipping infection");
				}
			}
		}
	}
	public class InfectionEffect : SE_Stats
	{
		private float damageTimer = 0f;

		public override void Setup(Character character)
		{
			((SE_Stats)this).Setup(character);
			((StatusEffect)this).m_ttl = CutsAndBruises.InfectionDuration.Value;
			Logger.LogInfo((object)"InfectionEffect Setup() called");
		}

		public override void UpdateStatusEffect(float dt)
		{
			//IL_0047: Unknown result type (might be due to invalid IL or missing references)
			//IL_004d: Expected O, but got Unknown
			((SE_Stats)this).UpdateStatusEffect(dt);
			damageTimer += dt;
			if (damageTimer >= CutsAndBruises.InfectionTickInterval.Value)
			{
				damageTimer = 0f;
				Logger.LogInfo((object)"InfectionEffect dealing damage");
				HitData val = new HitData();
				val.m_damage.m_damage = CutsAndBruises.InfectionDamagePerTick.Value;
				((StatusEffect)this).m_character.Damage(val);
			}
		}
	}
}