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