Decompiled source of CreatureDiscomforts v1.0.0
CreatureDiscomforts.dll
Decompiled a day ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using System.Text; using System.Text.Json; using BepInEx; using BepInEx.Configuration; using BepInEx.Core.Logging.Interpolation; using BepInEx.Logging; using BepInEx.Unity.IL2CPP; using CreatureDiscomforts.Effects; using CreatureDiscomforts.Model; using CreatureDiscomforts.Survey; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.Attributes; using Il2CppInterop.Runtime.Injection; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppSystem.Collections.Generic; using Microsoft.CodeAnalysis; using SOD.Common; using SOD.Common.Helpers; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")] [assembly: AssemblyCompany("CreatureDiscomforts")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0")] [assembly: AssemblyProduct("CreatureDiscomforts")] [assembly: AssemblyTitle("CreatureDiscomforts")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] [module: RefSafetyRules(11)] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } [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 CreatureDiscomforts { [BepInPlugin("ekem.creaturediscomforts", "Creature Discomforts", "1.0.0")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class Plugin : BasePlugin { private Harmony? _harmony; public static ManualLogSource Log { get; private set; } public static Settings Cfg { get; private set; } public override void Load() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Expected O, but got Unknown //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Expected O, but got Unknown Log = ((BasePlugin)this).Log; Cfg = new Settings(((BasePlugin)this).Config); _harmony = new Harmony("ekem.creaturediscomforts"); _harmony.PatchAll(); InstallHotkeys(); Illness.Install(); ManualLogSource log = Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("Creature Discomforts"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("1.0.0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" loaded."); } log.LogInfo(val); } private static void InstallHotkeys() { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_000f: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Expected O, but got Unknown //IL_0015: Unknown result type (might be due to invalid IL or missing references) ClassInjector.RegisterTypeInIl2Cpp<Heartbeat>(); GameObject val = new GameObject("Creature DiscomfortsHotkeys"); Object.DontDestroyOnLoad((Object)val); ((Object)val).hideFlags = (HideFlags)61; val.AddComponent<Heartbeat>(); } } public class Settings { public readonly ConfigEntry<float> ThirstToHunger; public readonly ConfigEntry<bool> Starving; public readonly ConfigEntry<float> StarvingBelow; public readonly ConfigEntry<float> StarvingDamage; public readonly ConfigEntry<bool> Parched; public readonly ConfigEntry<float> ParchedBelow; public readonly ConfigEntry<float> ParchedDamage; public readonly ConfigEntry<float> HealthFloor; public readonly ConfigEntry<float> StumbleChance; public readonly ConfigEntry<float> ThirstHeadachePerHour; public readonly ConfigEntry<bool> CatchingColds; public readonly ConfigEntry<float> ColdThreshold; public readonly ConfigEntry<float> CatchFromCold; public readonly ConfigEntry<float> CatchFromWet; public readonly ConfigEntry<float> CatchFromBoth; public readonly ConfigEntry<float> RecoveryPerHour; public readonly ConfigEntry<float> RecoverAboveHeat; public readonly ConfigEntry<float> SleepRecovery; public readonly ConfigEntry<bool> Immunity; public readonly ConfigEntry<float> ImmunityLossPerHour; public readonly ConfigEntry<float> ImmunityLossStarving; public readonly ConfigEntry<float> ImmunityGainPerHour; public readonly ConfigEntry<float> ImmunityBaseGain; public readonly ConfigEntry<float> LowImmunityCatch; public readonly ConfigEntry<float> LowImmunityRecovery; public readonly ConfigEntry<float> AlcoholHeatLoss; public readonly ConfigEntry<bool> RealisticDrinks; public readonly ConfigEntry<float> StrongDrinkThirst; public readonly ConfigEntry<float> StrongDrinkTiring; public readonly ConfigEntry<float> NauseaFromDrunk; public readonly ConfigEntry<float> DrunkNauseaPerHour; public readonly ConfigEntry<float> OverdrinkNausea; public readonly ConfigEntry<float> RetchAbove; public readonly ConfigEntry<float> RetchPerHour; public readonly ConfigEntry<float> VomitSobers; public readonly ConfigEntry<float> VomitTiring; public readonly ConfigEntry<bool> DebugLogging; public readonly ConfigEntry<KeyCode> SurveyKey; public readonly ConfigEntry<KeyCode> OverlayKey; public readonly ConfigEntry<KeyCode> ShopKey; public readonly ConfigEntry<KeyCode> IllnessKey; public readonly ConfigEntry<KeyCode> MoneyKey; public Settings(ConfigFile config) { ThirstToHunger = config.Bind<float>("Needs", "ThirstToHunger", 1.5f, "How fast thirst drains compared to hunger. 1.5 means you get thirsty 1.5 times as fast as you get hungry. 0 keeps the game's own rate."); Starving = config.Bind<bool>("Needs", "Starving", true, "Running out of food entirely makes you Starving: no health recovery, unsteady on your feet, and slowly losing health. Never down to a hospital visit, see HealthFloor."); StarvingBelow = config.Bind<float>("Needs", "StarvingBelow", 0.02f, "At or below this nourishment (0..1) you are starving. The game's own Hungry starts at 0.2."); StarvingDamage = config.Bind<float>("Needs", "StarvingDamage", 0.1f, "How much health you lose per game hour while starving, as a share of your maximum health. 0 turns the damage off."); Parched = config.Bind<bool>("Needs", "Parched", true, "Running out of water entirely makes you Parched: the same as Starving, a little harsher."); ParchedBelow = config.Bind<float>("Needs", "ParchedBelow", 0.02f, "At or below this hydration (0..1) you are parched. The game's own Thirsty starts at 0.2."); ParchedDamage = config.Bind<float>("Needs", "ParchedDamage", 0.15f, "How much health you lose per game hour while parched, as a share of your maximum health. 0 turns the damage off."); HealthFloor = config.Bind<float>("Needs", "HealthFloor", 0.25f, "Starving and parched never take your health below this share of the maximum, and neither do stumbles while you are starving or parched."); StumbleChance = config.Bind<float>("Needs", "StumbleChance", 0.25f, "How often you stumble and fall while starving or parched, compared to being as drunk as you can get (1 = just as often, about one step in fifty). Both at once add up. 0 turns this off. Takes effect after restarting the game."); ThirstHeadachePerHour = config.Bind<float>("Needs", "ThirstHeadachePerHour", 0.8f, "While you are Thirsty, a headache builds up this much per game hour. The game eases a headache by about 0.5-0.75 per hour, so it creeps in slowly. Painkillers stop it for a while. 0 turns this off."); CatchingColds = config.Bind<bool>("Illness", "CatchingColds", true, "Being out in the cold or soaking wet can give you a cold, with a stuffy nose, a headache, fever and chills."); ColdThreshold = config.Bind<float>("Illness", "ColdThreshold", 0.25f, "Below this body heat (0..1) you count as freezing."); CatchFromCold = config.Bind<float>("Illness", "CatchFromCold", 0.1f, "How much of a cold you pick up per game hour when completely frozen but dry."); CatchFromWet = config.Bind<float>("Illness", "CatchFromWet", 0.05f, "How much of a cold you pick up per game hour when soaked but warm."); CatchFromBoth = config.Bind<float>("Illness", "CatchFromBoth", 0.1f, "Extra per game hour on top of the two above when you are frozen AND soaked. With the defaults that makes 0.25: fever in about two hours."); RecoveryPerHour = config.Bind<float>("Illness", "RecoveryPerHour", 0.03f, "How fast a cold wears off per game hour while you are warm and dry and awake. At 0.03 a bad cold takes about a day to pass."); RecoverAboveHeat = config.Bind<float>("Illness", "RecoverAboveHeat", 0.5f, "A cold only wears off when your body heat is at least this. Between this and ColdThreshold it neither gets worse nor better."); SleepRecovery = config.Bind<float>("Illness", "SleepRecovery", 3f, "How many times faster a cold wears off while you sleep in a bed."); Immunity = config.Bind<bool>("Illness", "Immunity", true, "Going hungry, thirsty or without sleep wears down your resistance, and eating, drinking and sleeping well build it back up. It is never shown: you only notice it in how easily you catch a cold and how long it takes to pass."); ImmunityLossPerHour = config.Bind<float>("Illness", "ImmunityLossPerHour", 0.01f, "How much resistance (0..1) you lose per game hour for each of Hungry, Thirsty and Tired."); ImmunityLossStarving = config.Bind<float>("Illness", "ImmunityLossStarving", 0.01f, "Extra resistance lost per game hour for each of Starving and Parched. With the defaults, a whole day without food or water takes it from full to about 0.4."); ImmunityGainPerHour = config.Bind<float>("Illness", "ImmunityGainPerHour", 0.05f, "Resistance regained per game hour for each of Energized, Hydrated and Well Rested."); ImmunityBaseGain = config.Bind<float>("Illness", "ImmunityBaseGain", 0.015f, "Resistance regained per game hour while you are neither hungry, thirsty nor tired."); LowImmunityCatch = config.Bind<float>("Illness", "LowImmunityCatch", 2f, "How many times faster you catch a cold with no resistance left. In between it scales evenly; 1 means resistance doesn't affect catching a cold."); LowImmunityRecovery = config.Bind<float>("Illness", "LowImmunityRecovery", 0.5f, "How fast a cold wears off with no resistance left, compared to full resistance (0.5 = half as fast). 1 means resistance doesn't affect getting better."); AlcoholHeatLoss = config.Bind<float>("Alcohol", "AlcoholHeatLoss", 0.5f, "While drunk you lose body heat this much faster (0.5 = one and a half times), and you don't feel the cold: no shivering, no chills. 0 turns this off. Takes effect after restarting the game."); RealisticDrinks = config.Bind<bool>("Alcohol", "RealisticDrinks", true, "Spirits dry you out instead of quenching thirst, and coffee or tea no longer sober you up or cancel painkillers. Takes effect after restarting the game."); StrongDrinkThirst = config.Bind<float>("Alcohol", "StrongDrinkThirst", 0.3f, "How much thirst a glass of spirits (bourbon, vodka) costs instead of quenching it. Beer, cider and wine are unchanged. Takes effect after restarting the game."); StrongDrinkTiring = config.Bind<float>("Alcohol", "StrongDrinkTiring", 0.15f, "How much energy a glass of spirits costs. Takes effect after restarting the game."); NauseaFromDrunk = config.Bind<float>("Alcohol", "NauseaFromDrunk", 0.7f, "Above this drunkenness (0..1) you start feeling sick. 0 turns this off."); DrunkNauseaPerHour = config.Bind<float>("Alcohol", "DrunkNauseaPerHour", 1.5f, "How fast nausea builds per game hour when completely drunk. The game eases nausea on its own, so a little over the line passes and a lot does not."); OverdrinkNausea = config.Bind<float>("Alcohol", "OverdrinkNausea", 0.5f, "Once you are as drunk as you can get, whatever more you drink turns into nausea instead: this much per unit of drunkenness that doesn't fit. A second bottle of vodka will come back up. 0 turns this off."); RetchAbove = config.Bind<float>("Needs", "RetchAbove", 0.8f, "Above this nausea (0..1) you may throw up wherever you are, not just over a toilet."); RetchPerHour = config.Bind<float>("Needs", "RetchPerHour", 12f, "How likely that is per game hour at full nausea (12 = usually within five minutes). Less likely when only just past RetchAbove. 0 turns this off."); VomitSobers = config.Bind<float>("Alcohol", "VomitSobers", 0.6f, "How much a full throw-up sobers you. 0 turns this off."); VomitTiring = config.Bind<float>("Needs", "VomitTiring", 0.15f, "How much energy throwing up costs. 0 turns this off."); DebugLogging = config.Bind<bool>("Debug", "DebugLogging", false, "Logs every change to your own condition, and what the game has switched on."); SurveyKey = config.Bind<KeyCode>("Debug", "SurveyKey", (KeyCode)288, "Logs which survival statuses the game has enabled and how you are doing right now."); OverlayKey = config.Bind<KeyCode>("Debug", "OverlayKey", (KeyCode)289, "Toggles an on-screen panel with your current needs and how fast they change per game hour."); ShopKey = config.Bind<KeyCode>("Debug", "ShopKey", (KeyCode)290, "Logs every item sold in shops and what it does to your needs, and writes the same as a table to BepInEx/CreatureDiscomforts-shop.tsv."); IllnessKey = config.Bind<KeyCode>("Debug", "IllnessKey", (KeyCode)0, "Makes your cold 0.2 worse each press; past the worst it cures you. For testing; unbound by default (F10 is handy)."); MoneyKey = config.Bind<KeyCode>("Debug", "MoneyKey", (KeyCode)0, "Gives you 10000 money. For testing; unbound by default (F11 is handy)."); } } public static class PluginInfo { public const string Guid = "ekem.creaturediscomforts"; public const string Name = "Creature Discomforts"; public const string Version = "1.0.0"; } } namespace CreatureDiscomforts.Survey { public static class IconDump { public static void Run() { //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0091: Expected O, but got Unknown //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown string text = Path.Combine(Paths.BepInExRootPath, "CreatureDiscomforts-icons"); Directory.CreateDirectory(text); int num = 0; bool flag = default(bool); foreach (Object item in (Il2CppArrayBase<Object>)(object)Resources.FindObjectsOfTypeAll(Il2CppType.Of<StatusPreset>())) { StatusPreset val = ((Il2CppObjectBase)item).TryCast<StatusPreset>(); if ((Object)(object)((val != null) ? val.icon : null) == (Object)null) { continue; } try { File.WriteAllBytes(Path.Combine(text, ((Object)val).name + ".png"), Encode(val.icon)); num++; } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(16, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[status] icon "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)val).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); } } ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(34, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[status] "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" status icons written to "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(text); } log2.LogInfo(val3); } private static byte[] Encode(Sprite sprite) { //IL_0008: 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_0047: Unknown result type (might be due to invalid IL or missing references) //IL_004c: 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_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0060: Expected O, but got Unknown Texture2D texture = sprite.texture; Rect textureRect = sprite.textureRect; RenderTexture temporary = RenderTexture.GetTemporary(((Texture)texture).width, ((Texture)texture).height, 0, (RenderTextureFormat)0); RenderTexture active = RenderTexture.active; try { Graphics.Blit((Texture)(object)texture, temporary); RenderTexture.active = temporary; Texture2D val = new Texture2D((int)((Rect)(ref textureRect)).width, (int)((Rect)(ref textureRect)).height, (TextureFormat)4, false); val.ReadPixels(textureRect, 0, 0); val.Apply(); return Il2CppArrayBase<byte>.op_Implicit((Il2CppArrayBase<byte>)(object)ImageConversion.EncodeToPNG(val)); } finally { RenderTexture.active = active; RenderTexture.ReleaseTemporary(temporary); } } } public static class SelfSurvey { public static void Run() { //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_019d: Expected O, but got Unknown //IL_01ee: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Expected O, but got Unknown //IL_0270: Unknown result type (might be due to invalid IL or missing references) //IL_0276: Expected O, but got Unknown //IL_034b: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Expected O, but got Unknown Game instance = Game.Instance; if ((Object)(object)instance == (Object)null) { Plugin.Log.LogWarning((object)"[me] no game instance"); return; } List<string> on = new List<string>(); List<string> off = new List<string>(); Check("cold", instance.coldStatusEnabled); Check("smelly", instance.smellyStatusEnabled); Check("headache", instance.headacheStatusEnabled); Check("injury", instance.injuryStatusEnabled); Check("tired", instance.tiredStatusEnabled); Check("hunger", instance.hungerStatusEnabled); Check("hydration", instance.hydrationStatusEnabled); Check("numb", instance.numbStatusEnabled); Check("bleeding", instance.bleedingStatusEnabled); Check("wet", instance.wetStatusEnabled); Check("sick", instance.sickStatusEnabled); Check("drunk", instance.drunkStatusEnabled); Check("starch addiction", instance.starchAddictionEnabled); Check("poison", instance.poisonStatusEnabled); Check("blinded", instance.blindedStatusEnabled); Check("energized", instance.energizedStatusEnabled); Check("hydrated", instance.hydratedStatusEnabled); Check("focused", instance.focusedStatusEnabled); Check("well rested", instance.wellRestedStatusEnabled); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] statuses ON ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(on.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", on)); } log.LogInfo(val); ManualLogSource log2 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(22, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] statuses OFF ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(off.Count); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", off)); } log2.LogInfo(val); Player instance2 = Player.Instance; Human val2 = ((instance2 != null) ? ((Il2CppObjectBase)instance2).TryCast<Human>() : null); if ((Object)(object)val2 == (Object)null) { Plugin.Log.LogInfo((object)"[me] no player to read"); return; } ManualLogSource log3 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(52, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] food "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.nourishment, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", water "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.hydration, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("energy "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.energy, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", alert "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.alertness, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("hygiene "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.hygiene, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", heat "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.heat, "F2"); } log3.LogInfo(val); ManualLogSource log4 = Plugin.Log; val = new BepInExInfoLogInterpolatedStringHandler(44, 5, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] sick "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.sick, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", wet "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.wet, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", drunk "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.drunk, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("headache "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(val2.headache, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", health "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Actor)val2).currentHealth, "F2"); } log4.LogInfo(val); StatusEffects(); IconDump.Run(); void Check(string name, bool enabled) { (enabled ? on : off).Add(name); } } private static void StatusEffects() { //IL_0283: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Expected O, but got Unknown StatusController instance = StatusController.Instance; HashSet<StatusPreset> val = ((instance != null) ? instance.activeStatuses : null); bool flag2 = default(bool); foreach (StatusPreset item in from o in (IEnumerable<Object>)Resources.FindObjectsOfTypeAll(Il2CppType.Of<StatusPreset>()) select ((Il2CppObjectBase)o).TryCast<StatusPreset>() into p where (SoCustomComparison)(object)p != (SoCustomComparison)null orderby ((Object)p).name select p) { List<string> parts = new List<string>(); Flag("stopsRecovery", item.stopsRecovery); Flag("stopsSprint", item.stopsSprint); Flag("stopsJump", item.stopsJump); Num("recovery", item.recoveryRatePlusMP); Num("maxHealth", item.maxHealthPlusMP); Num("speed", item.movementSpeedPlusMP); Num("tempGain", item.temperatureGainPlusMP); Num("dmgIn", item.damageIncomingPlusMP); Num("dmgOut", item.damageOutgoingPlusMP); Num("drunkControls", item.drunkControls); Num("tripWet", item.tripChanceWet); Num("tripDrunk", item.tripChanceDrunk); Num("drunkVision", item.drunkVision); Num("shiver", item.shiverVision); Num("headacheVision", item.headacheVision); Num("lens", item.drunkLensDistort); Num("headBob", item.affectHeadBob); Num("bloom", item.bloomIntensityPlusMP); Num("blur", item.motionBlurPlusMP); Num("chromatic", item.chromaticAbberationAmount); Num("vignette", item.vignetteAmount); Num("exposure", item.expsosure); Flag("channelMixer", item.useChannelMixer); bool flag = val?.Contains(item) ?? false; string text = ((parts.Count == 0) ? "(nothing)" : string.Join(", ", parts)); ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(11, 3, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[status] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag ? "*" : " "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)item).name.PadRight(22)); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); } log.LogInfo(val2); void Flag(string name, bool on) { if (on) { parts.Add(name); } } void Num(string name, float v) { if (v != 0f) { parts.Add($"{name} {v:+0.##;-0.##}"); } } } } } public static class ShopSurvey { private static readonly (string Name, Func<RetailItemPreset, float> Read)[] Effects = new(string, Func<RetailItemPreset, float>)[24] { ("nourishment", (RetailItemPreset r) => r.nourishment), ("hydration", (RetailItemPreset r) => r.hydration), ("alertness", (RetailItemPreset r) => r.alertness), ("energy", (RetailItemPreset r) => r.energy), ("wellRested", (RetailItemPreset r) => r.wellRested), ("excitement", (RetailItemPreset r) => r.excitement), ("chores", (RetailItemPreset r) => r.chores), ("hygiene", (RetailItemPreset r) => r.hygiene), ("bladder", (RetailItemPreset r) => r.bladder), ("heat", (RetailItemPreset r) => r.heat), ("wet", (RetailItemPreset r) => r.wet), ("drunk", (RetailItemPreset r) => r.drunk), ("sick", (RetailItemPreset r) => r.sick), ("headache", (RetailItemPreset r) => r.headache), ("starchAddiction", (RetailItemPreset r) => r.starchAddiction), ("poisoned", (RetailItemPreset r) => r.poisoned), ("numb", (RetailItemPreset r) => r.numb), ("bleeding", (RetailItemPreset r) => r.bleeding), ("bruised", (RetailItemPreset r) => r.bruised), ("blackEye", (RetailItemPreset r) => r.blackEye), ("brokenLeg", (RetailItemPreset r) => r.brokenLeg), ("blackedOut", (RetailItemPreset r) => r.blackedOut), ("breath", (RetailItemPreset r) => r.breath), ("health", (RetailItemPreset r) => r.health) }; private const int ShownSellers = 5; private static Dictionary<string, List<string>> Sellers() { Dictionary<string, List<string>> dictionary = new Dictionary<string, List<string>>(); CityData instance = CityData.Instance; List<Company> val = ((instance != null) ? instance.companyDirectory : null); if (val == null) { return dictionary; } Enumerator<Company> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { Company current = enumerator.Current; if (((current != null) ? current.prices : null) == null) { continue; } NewAddress address = current.address; string text = ((address != null) ? ((Object)address).name : null); string value = ((text != null && text.Length > 0 && text != current.name) ? (current.name + " (" + text + ")") : current.name); Enumerator<InteractablePreset, int> enumerator2 = current.prices.GetEnumerator(); while (enumerator2.MoveNext()) { KeyValuePair<InteractablePreset, int> current2 = enumerator2.Current; InteractablePreset key = current2.Key; string key2 = ((key != null) ? ((SoCustomComparison)key).presetName : null) ?? ""; if (!dictionary.TryGetValue(key2, out var value2)) { value2 = (dictionary[key2] = new List<string>()); } value2.Add($"{value} cr{current2.Value}"); } } return dictionary; } public static void Run() { //IL_00c7: 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_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00eb: Unknown result type (might be due to invalid IL or missing references) //IL_0152: 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_0128: Unknown result type (might be due to invalid IL or missing references) //IL_0477: Unknown result type (might be due to invalid IL or missing references) //IL_047e: Expected O, but got Unknown //IL_05a4: Unknown result type (might be due to invalid IL or missing references) //IL_05ab: Expected O, but got Unknown //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0351: Unknown result type (might be due to invalid IL or missing references) //IL_0369: Unknown result type (might be due to invalid IL or missing references) //IL_036e: Unknown result type (might be due to invalid IL or missing references) Toolbox instance = Toolbox.Instance; Dictionary<string, InteractablePreset> val = ((instance != null) ? instance.objectPresetDictionary : null); if (val == null) { Plugin.Log.LogWarning((object)"[shop] no preset dictionary yet"); return; } Dictionary<string, List<string>> dictionary = Sellers(); List<(string, string, string, string)> list = new List<(string, string, string, string)>(); Enumerator<string, InteractablePreset> enumerator = val.GetEnumerator(); bool isConsumable = default(bool); while (enumerator.MoveNext()) { KeyValuePair<string, InteractablePreset> current = enumerator.Current; InteractablePreset value = current.Value; RetailItemPreset retail = ((value != null) ? value.retailItem : null); if (!((SoCustomComparison)(object)retail == (SoCustomComparison)null)) { List<(string, float)> list2 = (from e in Effects select (Name: e.Name, Value: e.Read(retail)) into e where e.Value != 0f select e).ToList(); string text = ((object)retail.menuCategory/*cast due to .constrained prefix*/).ToString(); string value2 = ((value.value.x == value.value.y) ? $"{value.value.x:0}" : $"{value.value.x:0}-{value.value.y:0}"); string value3 = (string.IsNullOrEmpty(retail.brandName) ? "" : (" [" + retail.brandName + "]")); string value4 = ((list2.Count == 0) ? "(no effect)" : string.Join(", ", list2.Select<(string, float), string>(((string Name, float Value) e) => $"{e.Name} {e.Value:+0.##;-0.##}"))); dictionary.TryGetValue(((SoCustomComparison)value).presetName ?? "", out var value5); if (value5 == null) { value5 = new List<string>(); } string value6 = ((value5.Count == 0) ? "not sold" : ($"{value5.Count} shops: " + string.Join("; ", value5.Take(5)) + ((value5.Count > 5) ? "; ..." : ""))); string key = current.Key; string item = $"[shop] {text,-10} {current.Key}{value3} cr{value2} {value4}\n[shop] at {value6}"; string[] obj = new string[9] { text, current.Key, retail.brandName ?? "", value.value.x.ToString("0"), value.value.y.ToString("0"), null, null, null, null }; isConsumable = retail.isConsumable; obj[5] = isConsumable.ToString(); obj[6] = value.consumableAmount.ToString("0.##"); obj[7] = value5.Count.ToString(); obj[8] = string.Join("; ", value5); list.Add((text, key, item, string.Join("\t", obj.Concat(Effects.Select(((string Name, Func<RetailItemPreset, float> Read) e) => e.Read(retail).ToString("0.###")))))); } } list.Sort(delegate((string Category, string Name, string Line, string Tsv) a, (string Category, string Name, string Line, string Tsv) b) { int num = string.CompareOrdinal(a.Category, b.Category); return (num == 0) ? string.CompareOrdinal(a.Name, b.Name) : num; }); foreach (var item2 in list) { Plugin.Log.LogInfo((object)item2.Item3); } ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref isConsumable); if (isConsumable) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[shop] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<int>(list.Count); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" retail items"); } log.LogInfo(val2); StringBuilder stringBuilder = new StringBuilder(); stringBuilder.AppendLine(string.Join("\t", new string[9] { "category", "preset", "brand", "priceMin", "priceMax", "consumable", "amount", "shops", "soldAt" }.Concat(Effects.Select(((string Name, Func<RetailItemPreset, float> Read) e) => e.Name)))); foreach (var item3 in list) { stringBuilder.AppendLine(item3.Item4); } string text2 = Path.Combine(Paths.BepInExRootPath, "CreatureDiscomforts-shop.tsv"); File.WriteAllText(text2, stringBuilder.ToString()); ManualLogSource log2 = Plugin.Log; val2 = new BepInExInfoLogInterpolatedStringHandler(16, 1, ref isConsumable); if (isConsumable) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[shop] table -> "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text2); } log2.LogInfo(val2); } } } namespace CreatureDiscomforts.Model { public static class Illness { private sealed class Saved { public float Illness { get; set; } public float? Immunity { get; set; } public Dictionary<string, float>? Relieved { get; set; } public Dictionary<string, List<float>>? Doses { get; set; } } private const string FileName = "creaturediscomforts.json"; private const float MaxStep = 1f; private static float _lastGameTime = float.NaN; private static float _nextReport = float.NaN; public static float Level { get; private set; } public static void Install() { Lib.SaveGame.OnBeforeSave += OnBeforeSave; Lib.SaveGame.OnAfterLoad += OnAfterLoad; Lib.SaveGame.OnBeforeNewGame += delegate { Reset(0f); Remedies.Load(null, null); }; Lib.SaveGame.OnBeforeDelete += OnBeforeDelete; } public static float Coldness(Human player) { float value = Plugin.Cfg.ColdThreshold.Value; if (!(value <= 0f)) { return Mathf.Clamp01(1f - player.heat / value); } return 0f; } private static bool Asleep() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Invalid comparison between Unknown and I4 InteractionController instance = InteractionController.Instance; Interactable val = ((instance != null) ? instance.lockedInInteraction : null); if ((SoCustomComparison)(object)((val != null) ? val.preset : null) != (SoCustomComparison)null) { return (int)val.preset.specialCaseFlag == 1; } return false; } public static void Tick() { SessionData instance = SessionData.Instance; Player instance2 = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null) { _lastGameTime = float.NaN; return; } float gameTime = instance.gameTime; float num = (float.IsNaN(_lastGameTime) ? 0f : (gameTime - _lastGameTime)); _lastGameTime = gameTime; if (num < 0f || num > 1f) { num = 0f; } Starvation.Apply(instance2, num); Immunity.Tick(instance2, num); if (!Plugin.Cfg.CatchingColds.Value) { Level = 0f; } else if (num > 0f) { float num2 = Coldness((Human)(object)instance2); float num3 = Mathf.Clamp01(((Human)instance2).wet); float num4 = Plugin.Cfg.CatchFromCold.Value * num2 + Plugin.Cfg.CatchFromWet.Value * num3 + Plugin.Cfg.CatchFromBoth.Value * num2 * num3; num4 *= Immunity.CatchMultiplier; if (num4 > 0f) { Level = Mathf.Clamp01(Level + num4 * num); } else if (((Human)instance2).heat >= Plugin.Cfg.RecoverAboveHeat.Value) { Level = Mathf.Clamp01(Level - Plugin.Cfg.RecoveryPerHour.Value * num * (Asleep() ? Plugin.Cfg.SleepRecovery.Value : 1f) * Immunity.RecoveryMultiplier); } } Symptoms.Apply(instance2, Level, num); Hourly(instance2, gameTime); } private static void Hourly(Player player, float now) { if (Plugin.Cfg.DebugLogging.Value && (float.IsNaN(_nextReport) || !(now < _nextReport) || !(now > _nextReport - 2f))) { _nextReport = Mathf.Floor(now) + 1f; StatusController instance = StatusController.Instance; Plugin.Log.LogInfo((object)($"[me] hourly {now:F1}h: illness {Level:F2}, immunity {Immunity.Level:F2}, heat {((Human)player).heat:F2}, wet {((Human)player).wet:F2}, health {((Actor)player).currentHealth:F2}/{((Actor)player).maximumHealth:F2}, drunk {((Human)player).drunk:F2}, food {((Human)player).nourishment:F2}, water {((Human)player).hydration:F2}, energy {((Human)player).energy:F2}, sick {((Human)player).sick:F2}, heat loss x{((instance != null) ? instance.temperatureGainMultiplier : 1f):F2}, recovery {(((Object)(object)instance != (Object)null && instance.disabledRecovery) ? "off" : "on")}" + (Asleep() ? ", asleep" : ""))); } } public static void DebugBump() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0038: Expected O, but got Unknown Level = ((Level >= 0.99f) ? 0f : Mathf.Clamp01(Level + 0.2f)); ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(20, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] illness set to "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Level, "F2"); } log.LogInfo(val); } private static void Reset(float level) { Level = level; _lastGameTime = float.NaN; Immunity.Reset(1f); } private static string PathFor(SaveGameArgs args) { return Lib.SaveGame.GetSaveGameDataPath(args, "creaturediscomforts.json"); } private static void OnBeforeSave(object? sender, SaveGameArgs e) { //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Expected O, but got Unknown try { File.WriteAllText(PathFor(e), JsonSerializer.Serialize(new Saved { Illness = Level, Immunity = Immunity.Level, Relieved = Remedies.SaveRelief(), Doses = Remedies.SaveDoses() })); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] failed to save: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogError(val); } } private static void OnAfterLoad(object? sender, SaveGameArgs e) { //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Expected O, but got Unknown Reset(0f); Remedies.Load(null, null); string path = PathFor(e); if (!File.Exists(path)) { return; } bool flag = default(bool); try { Saved saved = JsonSerializer.Deserialize<Saved>(File.ReadAllText(path)); Reset(Mathf.Clamp01(saved?.Illness ?? 0f)); Immunity.Reset(saved?.Immunity ?? 1f); Remedies.Load(saved?.Relieved, saved?.Doses); ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(31, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] loaded illness "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Level, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", immunity "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Immunity.Level, "F2"); } log.LogInfo(val); } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] unreadable save data, starting healthy: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log2.LogError(val2); } } private static void OnBeforeDelete(object? sender, SaveGameArgs e) { string path = PathFor(e); if (File.Exists(path)) { File.Delete(path); } } } public static class Immunity { private const float Low = 0.2f; private const float High = 0.9f; public static float Level { get; private set; } = 1f; public static float CatchMultiplier { get { if (!Plugin.Cfg.Immunity.Value) { return 1f; } return Mathf.Lerp(Mathf.Max(1f, Plugin.Cfg.LowImmunityCatch.Value), 1f, Level); } } public static float RecoveryMultiplier { get { if (!Plugin.Cfg.Immunity.Value) { return 1f; } return Mathf.Lerp(Mathf.Clamp01(Plugin.Cfg.LowImmunityRecovery.Value), 1f, Level); } } public static void Reset(float level) { Level = Mathf.Clamp01(level); } public static void Tick(Player player, float dt) { Settings cfg = Plugin.Cfg; if (!cfg.Immunity.Value) { Level = 1f; } else { if (dt <= 0f || ((Actor)player).isDead || player.playerKOInProgress) { return; } Game instance = Game.Instance; if (!((Object)(object)instance == (Object)null)) { int num = ((instance.hungerStatusEnabled && ((Human)player).nourishment <= 0.2f) ? 1 : 0) + ((instance.hydrationStatusEnabled && ((Human)player).hydration <= 0.2f) ? 1 : 0) + ((instance.tiredStatusEnabled && ((Human)player).energy <= 0.2f) ? 1 : 0); int num2 = (Starvation.IsStarving ? 1 : 0) + (Starvation.IsParched ? 1 : 0); float num3 = (float)(((instance.energizedStatusEnabled && ((Human)player).nourishment >= 0.9f) ? 1 : 0) + ((instance.hydratedStatusEnabled && ((Human)player).hydration >= 0.9f) ? 1 : 0) + ((instance.wellRestedStatusEnabled && ((Human)player).wellRested > 0f) ? 1 : 0)) * cfg.ImmunityGainPerHour.Value - (float)num * cfg.ImmunityLossPerHour.Value - (float)num2 * cfg.ImmunityLossStarving.Value; if (num == 0) { num3 += cfg.ImmunityBaseGain.Value; } Level = Mathf.Clamp01(Level + num3 * dt); } } } } } namespace CreatureDiscomforts.Effects { public static class Booze { private static StatusPreset? _drunk; private static StatusPreset? _cold; private static float _coldShiver; private static bool _ready; public static bool NumbToCold { get; private set; } public static void Tick() { //IL_00a9: Unknown result type (might be due to invalid IL or missing references) //IL_00af: Expected O, but got Unknown float value = Plugin.Cfg.AlcoholHeatLoss.Value; if (value <= 0f || (!_ready && !Setup(value))) { return; } StatusController instance = StatusController.Instance; HashSet<StatusPreset> val = ((instance != null) ? instance.activeStatuses : null); bool flag = val != null && (SoCustomComparison)(object)_drunk != (SoCustomComparison)null && val.Contains(_drunk); if (flag != NumbToCold) { NumbToCold = flag; if ((SoCustomComparison)(object)_cold != (SoCustomComparison)null) { _cold.shiverVision = (flag ? 0f : _coldShiver); } StatusController instance2 = StatusController.Instance; if (instance2 != null) { instance2.ForceStatusCheck(); } ManualLogSource log = Plugin.Log; bool flag2 = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(18, 2, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(flag ? "drunk: cold numbed" : "sober: feel the cold again"); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("heat loss x"); StatusController instance3 = StatusController.Instance; ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<float>((instance3 != null) ? instance3.temperatureGainMultiplier : 1f, "F2"); } log.LogInfo(val2); } } private static bool Setup(float heatLoss) { //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Expected O, but got Unknown //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Expected O, but got Unknown Toolbox instance = Toolbox.Instance; List<StatusPreset> val = ((instance != null) ? instance.allStatuses : null); if (val == null) { return false; } Enumerator<StatusPreset> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { StatusPreset current = enumerator.Current; if (!((SoCustomComparison)(object)current == (SoCustomComparison)null)) { if (((Object)current).name == "Drunk") { _drunk = current; } else if (((Object)current).name == "Cold") { _cold = current; } } } if ((SoCustomComparison)(object)_drunk == (SoCustomComparison)null) { Plugin.Log.LogWarning((object)"[me] no Drunk status, alcohol will not affect the cold"); _ready = true; return false; } StatusPreset? drunk = _drunk; drunk.temperatureGainPlusMP += heatLoss; if ((SoCustomComparison)(object)_cold != (SoCustomComparison)null) { _coldShiver = _cold.shiverVision; } bool flag = default(bool); try { string text = Lib.DdsStrings.Get("ui.states", "drunk_description") ?? ""; Lib.DdsStrings.AddOrUpdate("ui.states", "drunk_description", text.TrimEnd() + " You won't feel the cold, but you lose body heat faster."); } catch (Exception ex) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(45, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] could not extend the drunk description: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); } ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(37, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[me] alcohol: heat loss +"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<float>(heatLoss); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" while drunk"); } log2.LogInfo(val3); _ready = true; return true; } } public class Heartbeat : MonoBehaviour { public Heartbeat(IntPtr pointer) : base(pointer) { } [HideFromIl2Cpp] private static bool Pressed(ConfigEntry<KeyCode> key) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0009: Unknown result type (might be due to invalid IL or missing references) if ((int)key.Value != 0) { return Input.GetKeyDown(key.Value); } return false; } private void Update() { if (Pressed(Plugin.Cfg.SurveyKey)) { Plugin.Log.LogInfo((object)"[hotkey] self survey"); SelfSurvey.Run(); } if (Pressed(Plugin.Cfg.ShopKey)) { Plugin.Log.LogInfo((object)"[hotkey] shop survey"); ShopSurvey.Run(); } if (Pressed(Plugin.Cfg.IllnessKey)) { Illness.DebugBump(); } if (Pressed(Plugin.Cfg.MoneyKey) && (Object)(object)GameplayController.Instance != (Object)null) { GameplayController.Instance.AddMoney(10000, true, "debug"); Plugin.Log.LogInfo((object)"[hotkey] +10000 money"); } if (Pressed(Plugin.Cfg.OverlayKey)) { NeedsOverlay.Toggle(); } NeedsOverlay.Tick(); Thirst.Apply(); Shelf.Apply(); Stomach.Tick(); Booze.Tick(); Illness.Tick(); } private void OnGUI() { NeedsOverlay.Draw(); } } public static class NeedsOverlay { private sealed class Row { public readonly string Name; public readonly Func<Human, float> Read; public float Last = float.NaN; public float Drift; public float Hours; public float Rate { get { if (!(Hours > 0f)) { return 0f; } return Drift / Hours; } } public Row(string name, Func<Human, float> read) { Name = name; Read = read; } } public static bool Visible; private const float SampleEvery = 1f; private const float Jump = 0.05f; private const float MaxStep = 0.1f; private const int KeepEvents = 4; private static readonly List<Row> Rows = new List<Row> { new Row("food", (Human h) => h.nourishment), new Row("water", (Human h) => h.hydration), new Row("energy", (Human h) => h.energy), new Row("alert", (Human h) => h.alertness), new Row("rested", (Human h) => h.wellRested), new Row("hygiene", (Human h) => h.hygiene), new Row("heat", (Human h) => h.heat), new Row("bladder", (Human h) => h.bladder), new Row("wet", (Human h) => h.wet), new Row("illness", (Human _) => Illness.Level), new Row("sick", (Human h) => h.sick), new Row("drunk", (Human h) => h.drunk), new Row("headache", (Human h) => h.headache), new Row("starch", (Human h) => h.starchAddiction), new Row("numb", (Human h) => h.numb), new Row("poisoned", (Human h) => h.poisoned), new Row("blinded", (Human h) => h.blinded), new Row("bleeding", (Human h) => h.bleeding), new Row("bruised", (Human h) => h.bruised), new Row("black eye", (Human h) => h.blackEye), new Row("broken leg", (Human h) => h.brokenLeg), new Row("health", (Human h) => ((Actor)h).currentHealth) }; private static float _nextSample; private static float _lastGameTime = float.NaN; private static string _text = ""; private static readonly List<string> Events = new List<string>(); private static GUIStyle? _style; public static void Tick() { if (!Visible || Time.unscaledTime < _nextSample) { return; } _nextSample = Time.unscaledTime + 1f; Player instance = Player.Instance; Human val = ((instance != null) ? ((Il2CppObjectBase)instance).TryCast<Human>() : null); SessionData instance2 = SessionData.Instance; if ((Object)(object)val == (Object)null || (Object)(object)instance2 == (Object)null) { _text = "no player"; return; } float gameTime = instance2.gameTime; float num = (float.IsNaN(_lastGameTime) ? 0f : (gameTime - _lastGameTime)); _lastGameTime = gameTime; StringBuilder stringBuilder = new StringBuilder(); StringBuilder stringBuilder2 = stringBuilder; StringBuilder stringBuilder3 = stringBuilder2; StringBuilder.AppendInterpolatedStringHandler handler = new StringBuilder.AppendInterpolatedStringHandler(19, 2, stringBuilder2); handler.AppendLiteral("<b>me</b> game "); handler.AppendFormatted(gameTime, "F2"); handler.AppendLiteral(" h"); handler.AppendFormatted((num <= 0f) ? " (paused)" : ""); stringBuilder3.AppendLine(ref handler); stringBuilder.AppendLine(" now /h"); foreach (Row row in Rows) { float num2 = row.Read(val); if (num > 0f && num < 0.1f && !float.IsNaN(row.Last)) { float num3 = num2 - row.Last; if (Mathf.Abs(num3) > 0.05f) { Events.Add($"{gameTime:F2}h {row.Name} {num3:+0.00;-0.00} -> {num2:F2}"); if (Events.Count > 4) { Events.RemoveAt(0); } } else { row.Drift += num3; row.Hours += num; } } row.Last = num2; string value = ((Mathf.Abs(row.Rate) < 0.0005f) ? "" : row.Rate.ToString("+0.000;-0.000")); string text = $"{row.Name,-11}{num2,7:F3} {value,7}"; stringBuilder.AppendLine((num2 != 0f && IsEventful(row.Name)) ? ("<color=#ffcc66>" + text + "</color>") : text); } if (Events.Count > 0) { stringBuilder.AppendLine(); foreach (string @event in Events) { stringBuilder2 = stringBuilder; StringBuilder stringBuilder4 = stringBuilder2; handler = new StringBuilder.AppendInterpolatedStringHandler(23, 1, stringBuilder2); handler.AppendLiteral("<color=#aaaaaa>"); handler.AppendFormatted(@event); handler.AppendLiteral("</color>"); stringBuilder4.AppendLine(ref handler); } } _text = stringBuilder.ToString(); } private static bool IsEventful(string name) { switch (name) { case "blinded": case "illness": case "bruised": case "numb": case "sick": case "bleeding": case "headache": case "poisoned": case "wet": case "drunk": case "starch": case "black eye": case "broken leg": return true; default: return false; } } public static void Draw() { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown //IL_00d9: 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_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0021: 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_0035: Expected O, but got Unknown if (!Visible) { return; } if (_style == null) { _style = new GUIStyle(GUI.skin.label) { fontSize = 14, richText = true }; try { _style.font = Font.CreateDynamicFontFromOSFont(Il2CppStringArray.op_Implicit(new string[4] { "Consolas", "DejaVu Sans Mono", "Liberation Mono", "Courier New" }), 14); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(34, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] overlay: no monospace font ("); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(")"); } log.LogWarning(val); } } Rect val2 = default(Rect); ((Rect)(ref val2))..ctor((float)Screen.width - 280f - 10f, 10f, 280f, 500f); GUI.Box(val2, ""); GUI.Label(new Rect(((Rect)(ref val2)).x + 8f, ((Rect)(ref val2)).y + 6f, 264f, 488f), _text, _style); } public static void Toggle() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0088: Expected O, but got Unknown Visible = !Visible; _nextSample = 0f; _lastGameTime = float.NaN; Events.Clear(); foreach (Row row in Rows) { row.Last = float.NaN; row.Drift = 0f; row.Hours = 0f; } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] overlay "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(Visible ? "on" : "off"); } log.LogInfo(val); } } public static class Remedies { private sealed record Remedy(string Preset, float Hours, float Energy, params string[] Relieves); [HarmonyPatch(typeof(FirstPersonItemController), "SetConsuming")] public static class StartedConsuming { [HarmonyPrefix] public static void Prefix(FirstPersonItemController __instance, out bool __state) { __state = __instance.isConsuming; } [HarmonyPostfix] public static void Postfix(FirstPersonItemController __instance, bool __state) { //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00a5: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Expected O, but got Unknown if (__state || !__instance.isConsuming) { return; } bool flag = default(bool); try { BioScreenController instance = BioScreenController.Instance; object obj; if (instance == null) { obj = null; } else { InventorySlot selectedSlot = instance.selectedSlot; obj = ((selectedSlot != null) ? selectedSlot.GetInteractable() : null); } object obj2; if (obj == null) { obj2 = null; } else { InteractablePreset preset = ((Interactable)obj).preset; obj2 = ((preset != null) ? ((SoCustomComparison)preset).presetName : null); } string text = (string)obj2; if (Plugin.Cfg.DebugLogging.Value) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] consuming "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(text ?? "(unknown)"); } log.LogInfo(val); } if (text != null) { Took(text); } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExErrorLogInterpolatedStringHandler val2 = new BepInExErrorLogInterpolatedStringHandler(35, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] could not tell what you took: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log2.LogError(val2); } } } private static readonly Remedy[] All = new Remedy[3] { new Remedy("Painkillers", 4f, 0f, "Headache"), new Remedy("CoughMedicine", 6f, -0.3f, "Fever", "StuffyNose"), new Remedy("HeatPack", 2f, 0f, "Chills") }; private const float ToleranceWindow = 24f; private const float TolerancePerDose = 0.67f; private const float MinEffect = 0.25f; private static Dictionary<string, float> _until = new Dictionary<string, float>(); private static Dictionary<string, List<float>> _doses = new Dictionary<string, List<float>>(); public static bool Relieved(string symptom) { SessionData instance = SessionData.Instance; if ((Object)(object)instance != (Object)null && _until.TryGetValue(symptom, out var value)) { return instance.gameTime < value; } return false; } public static Dictionary<string, float> SaveRelief() { return new Dictionary<string, float>(_until); } public static Dictionary<string, List<float>> SaveDoses() { return _doses.ToDictionary<KeyValuePair<string, List<float>>, string, List<float>>((KeyValuePair<string, List<float>> p) => p.Key, (KeyValuePair<string, List<float>> p) => p.Value.ToList()); } public static void Load(Dictionary<string, float>? relief, Dictionary<string, List<float>>? doses) { _until = relief ?? new Dictionary<string, float>(); _doses = doses ?? new Dictionary<string, List<float>>(); } private static void Took(string presetName) { //IL_0128: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Expected O, but got Unknown Remedy remedy = All.FirstOrDefault((Remedy r) => r.Preset == presetName); SessionData instance = SessionData.Instance; if (remedy == null || (Object)(object)instance == (Object)null) { return; } float now = instance.gameTime; if (!_doses.TryGetValue(presetName, out List<float> value)) { value = (_doses[presetName] = new List<float>()); } value.RemoveAll((float t) => t < now - 24f || t > now); int count = value.Count; value.Add(now); float num = remedy.Hours * Math.Max(0.25f, (float)Math.Pow(0.6700000166893005, count)); float num2 = now + num; string[] relieves = remedy.Relieves; foreach (string key in relieves) { _until[key] = num2; } if (remedy.Energy != 0f) { Player instance2 = Player.Instance; if (instance2 != null) { ((Human)instance2).AddEnergy(remedy.Energy); } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(49, 6, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] took "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(presetName); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (dose "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(count + 1); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" in "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(24f, "0"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h): "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(string.Join(", ", remedy.Relieves)); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" relieved for "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F1"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h, until "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num2, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("h"); } log.LogInfo(val); } } public static class SelfProbe { [HarmonyPatch(typeof(Player), "AddNourishment")] public static class Food { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { Note("food", addVal, ((Human)__instance).nourishment); } } [HarmonyPatch(typeof(Player), "AddHydration")] public static class Water { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { Note("water", addVal, ((Human)__instance).hydration); } } [HarmonyPatch(typeof(Player), "AddEnergy")] public static class Rest { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { Note("energy", addVal, ((Human)__instance).energy); } } [HarmonyPatch(typeof(Player), "AddAlertness")] public static class Alert { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { Note("alertness", addVal, ((Human)__instance).alertness); } } [HarmonyPatch(typeof(Player), "AddHygiene")] public static class Clean { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { Note("hygiene", addVal, ((Human)__instance).hygiene); } } [HarmonyPatch(typeof(Player), "AddHeat")] public static class Warmth { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { Note("heat", addVal, ((Human)__instance).heat); } } [HarmonyPatch(typeof(Player), "AddSick")] public static class Illness { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (addVal != 0f && Plugin.Cfg.DebugLogging.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(14, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] SICK "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).sick, "F2"); } log.LogInfo(val); } } } [HarmonyPatch(typeof(Player), "AddWet")] public static class Rain { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (addVal != 0f && Plugin.Cfg.DebugLogging.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] WET "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).wet, "F2"); } log.LogInfo(val); } } } [HarmonyPatch(typeof(Player), "AddHeadache")] public static class Ache { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (addVal != 0f && Plugin.Cfg.DebugLogging.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] HEADACHE "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).headache, "F2"); } log.LogInfo(val); } } } [HarmonyPatch(typeof(Player), "AddDrunk")] public static class Booze { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (addVal != 0f && Plugin.Cfg.DebugLogging.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(15, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] DRUNK "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)__instance).drunk, "F2"); } log.LogInfo(val); } } } [HarmonyPatch(typeof(Player), "AddStarchAddiction")] public static class Kola { [HarmonyPostfix] public static void Postfix(float addVal) { //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Expected O, but got Unknown if (addVal != 0f && Plugin.Cfg.DebugLogging.Value) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(22, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] STARCH ADDICTION "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(addVal, "+0.000;-0.000"); } log.LogInfo(val); } } } private const float Noticeable = 0.01f; private static void Note(string field, float delta, float now) { //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown if (Plugin.Cfg.DebugLogging.Value && !(Math.Abs(delta) < 0.01f)) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(field); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(delta, "+0.00;-0.00"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(now, "F2"); } log.LogInfo(val); } } } public static class Shelf { private const float StrongDrink = 1f; private static bool _done; public static void Apply() { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0135: Expected O, but got Unknown if (_done) { return; } Toolbox instance = Toolbox.Instance; Dictionary<string, InteractablePreset> val = ((instance != null) ? instance.objectPresetDictionary : null); if (val == null || val.Count == 0) { return; } _done = true; if (!Plugin.Cfg.RealisticDrinks.Value) { Plugin.Log.LogInfo((object)"[me] shelf: vanilla drinks kept"); return; } float value = Plugin.Cfg.StrongDrinkThirst.Value; float value2 = Plugin.Cfg.StrongDrinkTiring.Value; int num = 0; int num2 = 0; int num3 = 0; Enumerator<string, InteractablePreset> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { InteractablePreset value3 = enumerator.Current.Value; RetailItemPreset val2 = ((value3 != null) ? value3.retailItem : null); if (!((SoCustomComparison)(object)val2 == (SoCustomComparison)null)) { if (val2.drunk >= 1f) { val2.hydration = 0f - value; val2.energy = 0f - value2; num++; } if (val2.drunk < 0f) { val2.drunk = 0f; num2++; } if (val2.numb < 0f && val2.hydration > 0f) { val2.numb = 0f; num3++; } } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val3 = new BepInExInfoLogInterpolatedStringHandler(96, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[me] shelf: "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" strong drinks now dehydrate, "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num2); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" no longer sober you up, "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<int>(num3); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" no longer cancel painkillers"); } log.LogInfo(val3); } } public static class Starvation { private sealed class Need { public readonly string Name; public readonly string Title; public readonly string Description; public readonly string Source; public StatusPreset? Preset; public bool Active; public StatusCount? Count; public bool JustShown; public Need(string name, string title, string description, string source) { Name = name; Title = title; Description = description; Source = source; } } [HarmonyPatch(typeof(StatusController), "ForceStatusCheck", new Type[] { typeof(bool) })] public static class StatusCheck { [HarmonyPrefix] public static void Prefix(StatusController __instance) { //IL_0013: Unknown result type (might be due to invalid IL or missing references) //IL_0019: Expected O, but got Unknown try { Sync(__instance); } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(24, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] needs sync failed: "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<Exception>(ex); } log.LogError(val); } } } [HarmonyPatch(typeof(Player), "Trip")] public static class NoFatalTrip { [HarmonyPrefix] public static void Prefix(Player __instance, ref float damage) { //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009d: Expected O, but got Unknown //IL_0040: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Expected O, but got Unknown if (!Starving.Active && !Parched.Active) { return; } float num = Mathf.Max(0f, ((Actor)__instance).currentHealth - Floor(__instance)); bool flag = default(bool); if (damage > num) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(36, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] trip damage "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(damage, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" -> "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(num, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" (health floor)"); } log.LogInfo(val); damage = num; } else { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(21, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] tripped: damage "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(damage, "F2"); } log2.LogInfo(val); } } } private const float ThirstyLevel = 0.2f; private static readonly Need Starving = new Need("Starving", "Starving", "You haven't eaten in far too long. Health recovery is inactive, you are unsteady on your feet and slowly losing health. Eat something.", "Hungry"); private static readonly Need Parched = new Need("Parched", "Parched", "You are badly dehydrated. Health recovery is inactive, you are dizzy, unsteady on your feet and slowly losing health. Drink something.", "Thirsty"); private static readonly Need[] All = new Need[2] { Starving, Parched }; private static bool _created; private static float _damage; private static float _headache; public static bool IsStarving => Starving.Active; public static bool IsParched => Parched.Active; public static void Apply(Player player, float dt) { if (!_created) { _created = Create(); } Game instance = Game.Instance; Settings cfg = Plugin.Cfg; bool active = cfg.Starving.Value && (Object)(object)instance != (Object)null && instance.hungerStatusEnabled && ((Human)player).nourishment <= cfg.StarvingBelow.Value; bool active2 = cfg.Parched.Value && (Object)(object)instance != (Object)null && instance.hydrationStatusEnabled && ((Human)player).hydration <= cfg.ParchedBelow.Value; if (Set(Starving, active, ((Human)player).nourishment) | Set(Parched, active2, ((Human)player).hydration)) { StatusController instance2 = StatusController.Instance; if (instance2 != null) { instance2.ForceStatusCheck(); } } if (!(dt <= 0f) && !((Actor)player).isDead && !player.playerKOInProgress) { Hurt(player, dt); ThirstHeadache(player, instance, dt); } } private static bool Set(Need n, bool active, float value) { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown active &= (SoCustomComparison)(object)n.Preset != (SoCustomComparison)null; if (active == n.Active) { return false; } n.Active = active; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(10, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(n.Name); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(active ? "on" : "off"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" at "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(value, "F2"); } log.LogInfo(val); return true; } private static void Hurt(Player player, float dt) { float num = (Starving.Active ? Plugin.Cfg.StarvingDamage.Value : 0f) + (Parched.Active ? Plugin.Cfg.ParchedDamage.Value : 0f); if (num <= 0f) { _damage = 0f; return; } _damage += num * ((Actor)player).maximumHealth * dt; if (!(_damage < 0.01f)) { float num2 = ((Actor)player).currentHealth - Floor(player); float num3 = Mathf.Min(_damage, num2); _damage = 0f; if (num3 > 0f) { ((Actor)player).AddHealth(0f - num3, false, false); } } } private static float Floor(Player player) { return Mathf.Clamp01(Plugin.Cfg.HealthFloor.Value) * ((Actor)player).maximumHealth; } private static void ThirstHeadache(Player player, Game? game, float dt) { float value = Plugin.Cfg.ThirstHeadachePerHour.Value; if (value <= 0f || (Object)(object)game == (Object)null || !game.hydrationStatusEnabled || ((Human)player).hydration > 0.2f || Remedies.Relieved("Headache")) { _headache = 0f; return; } _headache += value * dt; if (!(_headache < 0.02f)) { ((Human)player).AddHeadache(_headache); _headache = 0f; } } private static bool Create() { //IL_01c5: Unknown result type (might be due to invalid IL or missing references) //IL_01cc: Expected O, but got Unknown //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Expected O, but got Unknown Toolbox instance = Toolbox.Instance; List<StatusPreset> val = ((instance != null) ? instance.allStatuses : null); if (val == null) { return false; } Need[] all = All; bool flag = default(bool); foreach (Need need in all) { StatusPreset val2 = null; Enumerator<StatusPreset> enumerator = val.GetEnumerator(); while (enumerator.MoveNext()) { StatusPreset current = enumerator.Current; if ((SoCustomComparison)(object)current != (SoCustomComparison)null && ((Object)current).name == need.Source) { val2 = current; } } if ((SoCustomComparison)(object)val2 == (SoCustomComparison)null) { ManualLogSource log = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val3 = new BepInExWarningLogInterpolatedStringHandler(29, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("[me] no '"); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(need.Source); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral("' status to base "); ((BepInExLogInterpolatedStringHandler)val3).AppendFormatted<string>(need.Name); ((BepInExLogInterpolatedStringHandler)val3).AppendLiteral(" on"); } log.LogWarning(val3); } else { StatusPreset val4 = Object.Instantiate<StatusPreset>(val2); ((Object)val4).name = need.Name; ((SoCustomComparison)val4).presetName = need.Name; ((Object)val4).hideFlags = (HideFlags)32; ClearEffects(val4); val4.stopsRecovery = true; val4.tripChanceDrunk = Mathf.Max(0f, Plugin.Cfg.StumbleChance.Value); StatusIcons.Apply(val4, need.Name, val2); need.Preset = val4; string text = need.Name.ToLowerInvariant(); Lib.DdsStrings.AddOrUpdate("ui.states", text, need.Title); Lib.DdsStrings.AddOrUpdate("ui.states", text + "_description", need.Description); } } if (Plugin.Cfg.ThirstHeadachePerHour.Value > 0f) { AppendHint("thirsty_description", "Going thirsty for long gives you a headache."); } ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val5 = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val5).AppendLiteral("[me] needs ready: "); ((BepInExLogInterpolatedStringHandler)val5).AppendFormatted<string>(string.Join(", ", from n in All where (SoCustomComparison)(object)n.Preset != (SoCustomComparison)null select n.Name)); } log2.LogInfo(val5); return true; } private static void AppendHint(string key, string hint) { //IL_0051: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Expected O, but got Unknown try { string text = Lib.DdsStrings.Get("ui.states", key) ?? ""; if (!text.Contains(hint)) { Lib.DdsStrings.AddOrUpdate("ui.states", key, text.TrimEnd() + " " + hint); } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val = new BepInExWarningLogInterpolatedStringHandler(24, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] could not extend "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(key); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(": "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message); } log.LogWarning(val); } } private static void ClearEffects(StatusPreset p) { bool flag = (p.stopsJump = false); bool stopsRecovery = (p.stopsSprint = flag); p.stopsRecovery = stopsRecovery; float num = (p.movementSpeedPlusMP = 0f); float recoveryRatePlusMP = (p.maxHealthPlusMP = num); p.recoveryRatePlusMP = recoveryRatePlusMP; num = (p.damageOutgoingPlusMP = 0f); recoveryRatePlusMP = (p.damageIncomingPlusMP = num); p.temperatureGainPlusMP = recoveryRatePlusMP; float num6 = (p.affectHeadBob = 0f); num = (p.tripChanceDrunk = num6); recoveryRatePlusMP = (p.tripChanceWet = num); p.drunkControls = recoveryRatePlusMP; num6 = (p.drunkLensDistort = 0f); num = (p.headacheVision = num6); recoveryRatePlusMP = (p.shiverVision = num); p.drunkVision = recoveryRatePlusMP; num = (p.chromaticAbberationAmount = 0f); recoveryRatePlusMP = (p.motionBlurPlusMP = num); p.bloomIntensityPlusMP = recoveryRatePlusMP; recoveryRatePlusMP = (p.expsosure = 0f); p.vignetteAmount = recoveryRatePlusMP; p.useChannelMixer = false; } private static void Sync(StatusController controller) { //IL_00ec: Unknown result type (might be due to invalid IL or missing references) //IL_00f3: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Expected O, but got Unknown //IL_00ae: 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_00c1: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00d9: Expected O, but got Unknown HashSet<StatusPreset> activeStatuses = controller.activeStatuses; if (activeStatuses == null) { return; } Need[] all = All; bool flag2 = default(bool); foreach (Need need in all) { if ((SoCustomComparison)(object)need.Preset == (SoCustomComparison)null) { continue; } if (need.Count != null && !activeStatuses.Contains(need.Preset) && !need.JustShown) { need.Count = null; } need.JustShown = false; bool flag = need.Count != null; if (need.Active == flag) { continue; } if (need.Active) { ManualLogSource log = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] showing "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(need.Name); } log.LogInfo(val); StatusInstance val2 = new StatusInstance { preset = need.Preset }; need.Count = new StatusCount(val2) { amount = 1f }; need.JustShown = true; } else { ManualLogSource log2 = Plugin.Log; BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(12, 1, ref flag2); if (flag2) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] hiding "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(need.Name); } log2.LogInfo(val); need.Count.Remove(); activeStatuses.Remove(need.Preset); need.Count = null; } } } } public static class StatusIcons { public static void Apply(StatusPreset preset, string name, StatusPreset source) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown try { Sprite val = Load(name, source.icon); if (!((Object)(object)val == (Object)null)) { preset.icon = val; if ((Object)(object)source.alternateIcon != (Object)null) { preset.alternateIcon = val; } } } catch (Exception ex) { ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExWarningLogInterpolatedStringHandler val2 = new BepInExWarningLogInterpolatedStringHandler(31, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] no icon for "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(", keeping "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)source).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("'s: "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(ex.Message); } log.LogWarning(val2); } } private static Sprite? Load(string name, Sprite? like) { //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Expected O, but got Unknown //IL_00a8: 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) using Stream stream = typeof(StatusIcons).Assembly.GetManifestResourceStream("CreatureDiscomforts.assets.status." + name + ".png"); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); Texture2D val = new Texture2D(2, 2, (TextureFormat)4, false); if (!ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(memoryStream.ToArray()))) { return null; } ((Texture)val).filterMode = (FilterMode)1; ((Texture)val).wrapMode = (TextureWrapMode)1; ((Object)val).hideFlags = (HideFlags)32; float num = (((Object)(object)like != (Object)null) ? like.pixelsPerUnit : 100f); Sprite obj = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), num); ((Object)obj).name = name; ((Object)obj).hideFlags = (HideFlags)32; return obj; } } public static class Stomach { [HarmonyPatch(typeof(Player), "AddDrunk")] public static class Overdrink { [HarmonyPrefix] public static void Prefix(Player __instance, float addVal) { if (addVal <= 0f) { return; } float value = Plugin.Cfg.OverdrinkNausea.Value; if (!(value <= 0f)) { float num = ((Human)__instance).drunk + addVal - 1f; if (num > 0f) { ((Human)__instance).AddSick(value * Mathf.Min(num, addVal)); } } } } [HarmonyPatch(typeof(Player), "AddSick")] public static class VomitProgress { [HarmonyPostfix] public static void Postfix(Player __instance, float addVal) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) //IL_0048: Expected O, but got Unknown if (addVal >= 0f) { return; } InteractionController instance = InteractionController.Instance; if ((Object)(object)instance == (Object)null || instance.interactionActionName != "Vomiting") { return; } if (!_reportedVomit) { _reportedVomit = true; ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(51, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] throwing up: sobers "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Plugin.Cfg.VomitSobers.Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", "); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("tires "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(Plugin.Cfg.VomitTiring.Value); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" per full throw-up"); } log.LogInfo(val); } Aftermath(__instance, 0f - addVal); } } private const string Vomiting = "Vomiting"; private const float MaxStep = 1f; private static float _lastGameTime = float.NaN; private static SpatterPatternPreset? _vomit; private static readonly Color Bile = new Color(0.62f, 0.55f, 0.22f, 1f); private static readonly string[] ColorProps = new string[4] { "_BaseColor", "_Color", "_TintColor", "_MainColor" }; private const float DrunkCap = 1f; private static bool _reportedVomit; public static void Tick() { SessionData instance = SessionData.Instance; Player instance2 = Player.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)instance2 == (Object)null) { _lastGameTime = float.NaN; return; } float gameTime = instance.gameTime; float num = (float.IsNaN(_lastGameTime) ? 0f : (gameTime - _lastGameTime)); _lastGameTime = gameTime; if (!(num <= 0f) && !(num > 1f)) { float value = Plugin.Cfg.NauseaFromDrunk.Value; if (value > 0f && value < 1f && ((Human)instance2).drunk > value) { float num2 = Mathf.Clamp01((((Human)instance2).drunk - value) / (1f - value)); ((Human)instance2).AddSick(Plugin.Cfg.DrunkNauseaPerHour.Value * num2 * num); } MaybeRetch(instance2, num); } } private static void MaybeRetch(Player player, float dt) { //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Invalid comparison between Unknown and I4 float value = Plugin.Cfg.RetchAbove.Value; float value2 = Plugin.Cfg.RetchPerHour.Value; if (value2 <= 0f || value >= 1f || ((Human)player).sick <= value) { return; } InteractionController instance = InteractionController.Instance; if ((Object)(object)instance == (Object)null || instance.activeInteractionAction) { return; } Interactable lockedInInteraction = instance.lockedInInteraction; InteractablePreset val = ((lockedInInteraction != null) ? lockedInInteraction.preset : null); if (!((SoCustomComparison)(object)val != (SoCustomComparison)null) || (int)val.specialCaseFlag != 1) { float num = Mathf.Clamp01((((Human)player).sick - value) / (1f - value)); float num2 = 1f - Mathf.Exp((0f - value2) * num * dt); if (!(Random.value >= num2)) { Retch(player); } } } private static void Retch(Player player) { //IL_000a: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Expected O, but got Unknown //IL_0172: Unknown result type (might be due to invalid IL or missing references) //IL_0179: Expected O, but got Unknown //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_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_00b4: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Unknown result type (might be due to invalid IL or missing references) //IL_00bd: 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_00c1: Unknown result type (might be due to invalid IL or missing references) //IL_00c3: 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_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_00de: Unknown result type (might be due to invalid IL or missing references) //IL_00e3: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(44, 2, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val).AppendLiteral("[me] retching where you stand: sick "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)player).sick, "F2"); ((BepInExLogInterpolatedStringHandler)val).AppendLiteral(", drunk "); ((BepInExLogInterpolatedStringHandler)val).AppendFormatted<float>(((Human)player).drunk, "F2"); } log.LogInfo(val); ((Human)player).AddSick(-1f); ((Human)player).AddHygiene(-0.5f); Aftermath(player, 1f); try { SpatterPatternPreset val2 = VomitSpatter(); Camera main = Camera.main; Transform val3 = ((main != null) ? ((Component)main).transform : null); if ((SoCustomComparison)(object)val2 != (SoCustomComparison)null && (Object)(object)val3 != (Object)null) { Vector3 position = val3.position; Vector3 val4 = Vector3.ProjectOnPlane(val3.forward, Vector3.up); Vector3 normalized = ((Vector3)(ref val4)).normalized; SpatterSimulation val5 = new SpatterSimulation(position, position + normalized * 0.6f + Vector3.down * 1.6f, val2, (EraseMode)4, 1f, true); if (!val5.isExecuted) { val5.Execute(); } } } catch (Exception ex) { ManualLogSource log2 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(28, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[me] no vomit on the floor: "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex.Message); } log2.LogWarning(val6); } try { Lib.GameMessage.Broadcast("You throw up.", (GameMessageType)0, (Icon)37, (Color?)null, 0f); } catch (Exception ex2) { ManualLogSource log3 = Plugin.Log; BepInExWarningLogInterpolatedStringHandler val6 = new BepInExWarningLogInterpolatedStringHandler(42, 1, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val6).AppendLiteral("[me] could not show the retching message: "); ((BepInExLogInterpolatedStringHandler)val6).AppendFormatted<string>(ex2.Message); } log3.LogWarning(val6); } } private static SpatterPatternPreset? VomitSpatter() { if ((SoCustomComparison)(object)_vomit != (SoCustomComparison)null) { return _vomit; } CitizenControls instance = CitizenControls.Instance; SpatterPatternPreset val = ((instance != null) ? instance.vomitSpatter : null); if ((SoCustomComparison)(object)val == (SoCustomComparison)null) { return null; } SpatterPatternPreset obj = Object.Instantiate<SpatterPatternPreset>(val); obj.heavyMaterial = Tint(val.heavyMaterial); obj.mediumMaterial = Tint(val.mediumMaterial); obj.lightMaterial = Tint(val.lightMaterial); _vomit = obj; return obj; } private static Material? Tint(Material? vanilla) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown //IL_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Expected O, but got Unknown //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_005c: Unknown result type (might be due to invalid IL or missing references) //IL_0063: 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) if ((Object)(object)vanilla == (Object)null) { return null; } Material val = new Material(vanilla); string text = "none"; string[] colorProps = ColorProps; foreach (string text2 in colorProps) { if (val.HasProperty(text2)) { Color color = val.GetColor(text2); val.SetColor(text2, new Color(Bile.r, Bile.g, Bile.b, color.a)); text = $"{text2} was {color}"; } } ManualLogSource log = Plugin.Log; bool flag = default(bool); BepInExInfoLogInterpolatedStringHandler val2 = new BepInExInfoLogInterpolatedStringHandler(25, 3, ref flag); if (flag) { ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("[me] vomit material "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(((Object)vanilla).name); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral(" ("); Shader shader = vanilla.shader; ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>((shader != null) ? ((Object)shader).name : null); ((BepInExLogInterpolatedStringHandler)val2).AppendLiteral("): "); ((BepInExLogInterpolatedStringHandler)val2).AppendFormatted<string>(text); } log.LogInfo(val2); return val; } private static void Aftermath(Player player, float part) { float value = Plugin.Cfg.VomitSobers.Value; float value2 = Plugin.Cfg.VomitTiring.Value; if (value > 0f && ((Human)player).drunk > 0f) { ((Human)player).AddDrunk((0f - value) * part); } if (value2 > 0f) { ((Human)player).AddEnergy((0f - value2) * part); } } } public static class Symptoms { private sealed class Symptom { public readonly string Name; public readonly string Title; public readonly string Description; public readonly string Source; public readonly float Threshold; public readonly float ExtraThirst; public readonly float ExtraTiredness; public float HygienePerHour; public float HeadachePerHour;