Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of Drinkable v1.1.0
Drinkable.dll
Decompiled 2 hours ago
The result has been truncated due to the large size, download it to view full contents!
using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Reflection.Emit; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Cryptography; using System.Text; using System.Text.RegularExpressions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using BepInEx.Logging; using CSync.Extensions; using CSync.Lib; using Frailty; using Frailty.Manager; using GameNetcodeStuff; using HarmonyLib; using LethalLib.Modules; using Microsoft.CodeAnalysis; using TMPro; using Unity.Collections; using Unity.Netcode; using UnityEngine; using UnityEngine.Events; using UnityEngine.Rendering; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("Drinkable")] [assembly: AssemblyConfiguration("Release")] [assembly: AssemblyFileVersion("1.1.0.0")] [assembly: AssemblyInformationalVersion("1.1.0")] [assembly: AssemblyProduct("Drinkable")] [assembly: AssemblyTitle("Drinkable")] [assembly: AssemblyVersion("1.1.0.0")] [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 DrinkableSoda { internal static class Assets { private static readonly Dictionary<string, Sprite> sprites = new Dictionary<string, Sprite>(); private static readonly Dictionary<string, AudioClip> clips = new Dictionary<string, AudioClip>(); private static readonly Dictionary<string, Texture2D> cans = new Dictionary<string, Texture2D>(); internal static byte[] Read(string name) { using Stream stream = typeof(Assets).Assembly.GetManifestResourceStream("DrinkableSoda." + name); if (stream == null) { return null; } using MemoryStream memoryStream = new MemoryStream(); stream.CopyTo(memoryStream); return memoryStream.ToArray(); } internal static Sprite Icon(string name) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown //IL_005e: Unknown result type (might be due to invalid IL or missing references) //IL_006d: Unknown result type (might be due to invalid IL or missing references) if (sprites.TryGetValue(name, out var value)) { return value; } value = null; try { byte[] array = Read("Icons." + name + ".png"); if (array != null) { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); ImageConversion.LoadImage(val, array); ((Texture)val).wrapMode = (TextureWrapMode)1; value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)value).name = name; } else { Plugin.Log.LogWarning((object)("Missing icon " + name)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Icon " + name + ": " + ex.Message)); } sprites[name] = value; return value; } internal static Texture2D CanTexture(string key) { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Expected O, but got Unknown if (cans.TryGetValue(key, out var value)) { return value; } value = null; try { byte[] array = Read("Cans." + key + ".png"); if (array != null) { value = new Texture2D(2, 2, (TextureFormat)4, true); ImageConversion.LoadImage(value, array, false); ((Object)value).name = "DrinkableSoda_" + key; ((Texture)value).wrapMode = (TextureWrapMode)1; ((Texture)value).filterMode = (FilterMode)1; ((Texture)value).anisoLevel = 4; value.Apply(true, true); } else { Plugin.Log.LogWarning((object)("Missing can texture " + key)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Can " + key + ": " + ex.Message)); } cans[key] = value; return value; } internal static Texture2D MachineTexture(string name) { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Expected O, but got Unknown string text = "Machine." + name; if (cans.TryGetValue(text, out var value)) { return value; } value = null; try { byte[] array = Read(text + ".png"); if (array != null) { value = new Texture2D(2, 2, (TextureFormat)4, true); ImageConversion.LoadImage(value, array, false); ((Object)value).name = "SodaMachine_" + name; ((Texture)value).wrapMode = (TextureWrapMode)1; ((Texture)value).anisoLevel = 4; value.Apply(true, true); } else { Plugin.Log.LogWarning((object)("Missing machine texture " + name)); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Machine texture " + name + ": " + ex.Message)); } cans[text] = value; return value; } internal static Sprite CanIcon(string key) { //IL_003c: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Expected O, but got Unknown //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) string text = key + "_icon"; if (sprites.TryGetValue(text, out var value)) { return value; } value = null; try { byte[] array = Read("Cans." + text + ".png"); if (array != null) { Texture2D val = new Texture2D(2, 2, (TextureFormat)4, true); ImageConversion.LoadImage(val, array); ((Texture)val).wrapMode = (TextureWrapMode)1; value = Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f), 100f); ((Object)value).name = text; } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Icon " + text + ": " + ex.Message)); } sprites[text] = value; return value; } internal static AudioClip Sound(string name) { if (clips.TryGetValue(name, out var value)) { return value; } value = null; try { byte[] array = Read("Sounds." + name + ".wav"); if (array != null) { value = LoadWav(name, array); } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Sound " + name + ": " + ex.Message)); } clips[name] = value; return value; } private static AudioClip LoadWav(string name, byte[] d) { int num = 1; int num2 = 44100; int num3 = 16; int num4 = -1; int num5 = 0; int num6; for (int i = 12; i + 8 <= d.Length; i += 8 + num6 + (num6 & 1)) { string text = Encoding.ASCII.GetString(d, i, 4); num6 = BitConverter.ToInt32(d, i + 4); if (text == "fmt ") { num = BitConverter.ToInt16(d, i + 10); num2 = BitConverter.ToInt32(d, i + 12); num3 = BitConverter.ToInt16(d, i + 22); } else if (text == "data") { num4 = i + 8; num5 = Math.Min(num6, d.Length - num4); break; } } if (num4 < 0 || num3 != 16) { throw new Exception("unsupported wav"); } int num7 = num5 / 2; float[] array = new float[num7]; for (int j = 0; j < num7; j++) { array[j] = (float)BitConverter.ToInt16(d, num4 + j * 2) / 32768f; } AudioClip obj = AudioClip.Create(name, num7 / num, num, num2, false); obj.SetData(array, 0); return obj; } } internal static class BuffInfo { internal static readonly Color Gold = new Color(1f, 0.72f, 0.11f); internal static readonly Color Cyan = new Color(0f, 0.86f, 1f); internal static readonly Color Green = new Color(0.35f, 1f, 0.45f); internal static readonly Color Pink = new Color(1f, 0.55f, 0.75f); internal static readonly Color Purple = new Color(0.75f, 0.5f, 1f); internal static readonly Color Red = new Color(1f, 0f, 0.216f); internal static readonly Color Ice = new Color(0.6f, 0.78f, 1f); internal static string Title(BuffKind k) { return k switch { BuffKind.SugarRush => "Sugar Rush", BuffKind.WebRush => "Sugar Rush+", BuffKind.SugarCrash => "Sugar Crash", BuffKind.Hydration => "Hydration", BuffKind.Dehydration => "Dehydration", BuffKind.Regeneration => "Regeneration", BuffKind.SugarMend => "Sugar Mend", BuffKind.Brawn => "Brawn", BuffKind.Swift => "Swift", BuffKind.Spring => "Spring", BuffKind.SecondWind => "Second Wind", BuffKind.Endurance => "Endurance", BuffKind.Hyponatremia => "Hyponatremia", BuffKind.Equilibrium => "Equilibrium", BuffKind.BorrowedTime => "Borrowed Time", BuffKind.Equivalence => "Equivalence", BuffKind.SharpSight => "Sharp Sight", BuffKind.Exquisite => "Exquisite", BuffKind.CheeseSense => "Cheese Sense", BuffKind.Grounded => "Grounded", BuffKind.Numb => "Numb", _ => k.ToString(), }; } internal static string Description(BuffKind k) { switch (k) { case BuffKind.SugarRush: return "You move a bit faster and jump a bit higher. A Sugar Crash may follow."; case BuffKind.WebRush: return "A stronger, longer Sugar Rush: faster and higher jumps. A longer Sugar Crash may follow."; case BuffKind.SugarCrash: return "Your stamina refills slower."; case BuffKind.Hydration: return "While you drink, your stamina refills much faster."; case BuffKind.Dehydration: return "Salty! While you drink, your stamina drains."; case BuffKind.Regeneration: return "You slowly heal over time."; case BuffKind.SugarMend: return "You slowly heal over time and your stamina refills faster."; case BuffKind.Brawn: return "Carried weight slows you down and tires you less. Melee hits deal much more damage."; case BuffKind.Swift: return "You walk and run faster."; case BuffKind.Spring: return "You jump higher."; case BuffKind.SecondWind: return "Your stamina refills faster."; case BuffKind.Endurance: return "Sprinting drains less stamina."; case BuffKind.Hyponatremia: return "Too much Mystery Soda. You run slower, jump lower and sprinting costs more stamina."; case BuffKind.Equilibrium: if (!FrailtyBridge.Installed) { return "You take less damage. Getting hit can give Borrowed Time."; } return "You take less damage and new injuries last shorter. Getting hit can give Borrowed Time and Equivalence."; case BuffKind.BorrowedTime: return "You were hit: you run faster and sprinting costs no stamina for a moment."; case BuffKind.Equivalence: return "For a moment your injuries and debuffs do nothing. Their time still runs out."; case BuffKind.SharpSight: return "You see wider, and dark places are easier to see in."; case BuffKind.Exquisite: return "You move faster, jump higher, climb faster and your stamina refills faster."; case BuffKind.CheeseSense: return "Inside the facility, arrows at the top of your screen point to the nearest scrap and the nearest exit."; case BuffKind.Grounded: return "You don't sink in quicksand and lightning doesn't hit you."; case BuffKind.Numb: return "The pills dull the pain: you take less damage."; default: return ""; } } internal static Color Color(BuffKind k) { //IL_0056: 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_0062: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) //IL_0068: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_006e: Unknown result type (might be due to invalid IL or missing references) switch (k) { case BuffKind.SugarCrash: case BuffKind.Dehydration: case BuffKind.Hyponatremia: return Red; case BuffKind.Hydration: case BuffKind.Equilibrium: case BuffKind.Equivalence: return Cyan; case BuffKind.Regeneration: case BuffKind.SugarMend: return Green; case BuffKind.SharpSight: return Pink; case BuffKind.Numb: return Ice; case BuffKind.Exquisite: case BuffKind.CheeseSense: return Purple; default: return Gold; } } } [HarmonyPatch(typeof(PlayerControllerB))] internal static class BuffPatches { private static bool applied; private static float savedSpeed; private static float newSpeed; private static float savedJump; private static float newJump; private static float savedClimb; private static float newClimb; private static float savedCarry; private static float newCarry; private static float staminaBefore = -1f; private static float lateCarrySaved; private static float lateCarryNew; private static bool lateCarry; private static float fovApplied; private static readonly HashSet<string> logged = new HashSet<string>(); [HarmonyPatch("Update")] [HarmonyPrefix] [HarmonyPriority(200)] private static void UpdatePrefix(PlayerControllerB __instance) { applied = false; if (!Local.Is(__instance) || SodaConfig.Instance == null) { return; } try { Buffs.Tick(__instance); if (fovApplied != 0f && (Object)(object)__instance.gameplayCamera != (Object)null) { Camera gameplayCamera = __instance.gameplayCamera; gameplayCamera.fieldOfView -= fovApplied; } float num = Buffs.SpeedMul(); float num2 = Buffs.JumpMul(); float num3 = Buffs.ClimbMul(); float num4 = Buffs.CarryReduce(); if (num != 1f || num2 != 1f || num3 != 1f || num4 != 0f) { savedSpeed = __instance.movementSpeed; newSpeed = savedSpeed * num; __instance.movementSpeed = newSpeed; savedJump = __instance.jumpForce; newJump = savedJump * Mathf.Sqrt(Mathf.Max(0.01f, num2)); __instance.jumpForce = newJump; if (num2 < 1f && __instance.fallValueUncapped > newJump) { __instance.fallValueUncapped = newJump; } savedClimb = __instance.climbSpeed; newClimb = savedClimb * num3; __instance.climbSpeed = newClimb; savedCarry = __instance.carryWeight; newCarry = 1f + Mathf.Max(0f, savedCarry - 1f) * (1f - num4); __instance.carryWeight = newCarry; applied = true; } } catch (Exception e) { Once("update", e); } } [HarmonyPatch("Update")] [HarmonyFinalizer] private static void UpdateFinalizer(PlayerControllerB __instance) { if (!Local.Is(__instance)) { return; } if (applied) { applied = false; __instance.movementSpeed = Restore(__instance.movementSpeed, savedSpeed, newSpeed); __instance.jumpForce = Restore(__instance.jumpForce, savedJump, newJump); __instance.climbSpeed = Restore(__instance.climbSpeed, savedClimb, newClimb); __instance.carryWeight = Restore(__instance.carryWeight, savedCarry, newCarry); } try { float num = Buffs.FovAdd(); fovApplied = Mathf.MoveTowards(fovApplied, num, 30f * Time.deltaTime); if (fovApplied != 0f && (Object)(object)__instance.gameplayCamera != (Object)null) { Camera gameplayCamera = __instance.gameplayCamera; gameplayCamera.fieldOfView += fovApplied; } Visuals.Update(__instance); } catch (Exception e) { Once("visuals", e); } } private static float Restore(float now, float saved, float changed) { if (!Mathf.Approximately(now, changed)) { return now + (saved - changed); } return saved; } [HarmonyPatch("LateUpdate")] [HarmonyPrefix] [HarmonyPriority(200)] private static void LatePrefix(PlayerControllerB __instance) { staminaBefore = -1f; lateCarry = false; if (Local.Is(__instance) && SodaConfig.Instance != null && Buffs.All != null) { staminaBefore = __instance.sprintMeter; float num = Buffs.CarryReduce(); if (num > 0f) { lateCarrySaved = __instance.carryWeight; lateCarryNew = 1f + Mathf.Max(0f, lateCarrySaved - 1f) * (1f - num); __instance.carryWeight = lateCarryNew; lateCarry = true; } } } [HarmonyPatch("LateUpdate")] [HarmonyPostfix] [HarmonyPriority(600)] private static void LatePostfix(PlayerControllerB __instance) { if (lateCarry) { __instance.carryWeight = Restore(__instance.carryWeight, lateCarrySaved, lateCarryNew); lateCarry = false; } if (staminaBefore < 0f) { return; } try { float num = __instance.sprintMeter - staminaBefore; if (num > 0f) { __instance.sprintMeter = Mathf.Clamp01(staminaBefore + num * Buffs.RefillMul()); } else if (num < 0f) { __instance.sprintMeter = Mathf.Clamp01(staminaBefore + num * Buffs.DrainMul()); } if (Buffs.Has(BuffKind.Dehydration)) { __instance.sprintMeter = Mathf.Clamp01(__instance.sprintMeter - SodaConfig.Instance.DehydrationDrain.Value * Time.deltaTime); } } catch (Exception e) { Once("stamina", e); } staminaBefore = -1f; } [HarmonyPatch("DamagePlayer")] [HarmonyPrefix] [HarmonyPriority(600)] private static bool Damage(PlayerControllerB __instance, ref int damageNumber, bool fallDamage) { if (!Local.Is(__instance) || SodaConfig.Instance == null) { return true; } if (Lightning.Striking && Buffs.Has(BuffKind.Grounded)) { return false; } float num = Buffs.DamageMul(); if (num < 1f && damageNumber > 0) { damageNumber = Mathf.Max(1, Mathf.RoundToInt((float)damageNumber * num)); } if (!FrailtyBridge.Installed && damageNumber > 0 && !fallDamage && Buffs.Has(BuffKind.Equilibrium) && SodaConfig.Instance.BorrowedTime.Value > 0f && !__instance.isPlayerDead && __instance.AllowPlayerDeath()) { Buffs.Add(BuffKind.BorrowedTime, SodaConfig.Instance.BorrowedTime.Value); } return true; } [HarmonyPatch("KillPlayer")] [HarmonyPrefix] [HarmonyPriority(600)] private static bool Kill(PlayerControllerB __instance) { if (Local.Is(__instance) && Lightning.Striking) { return !Buffs.Has(BuffKind.Grounded); } return true; } [HarmonyPatch("CheckConditionsForSinkingInQuicksand")] [HarmonyPostfix] private static void Quicksand(PlayerControllerB __instance, ref bool __result) { if (__result && Local.Is(__instance) && Buffs.Has(BuffKind.Grounded)) { __result = false; } } internal static void Once(string key, Exception e) { if (logged.Add(key)) { Plugin.Log.LogError((object)(key + ": " + e)); } } } [HarmonyPatch(typeof(StormyWeather), "LightningStrike")] internal static class Lightning { internal static bool Striking; [HarmonyPrefix] private static void Prefix() { Striking = true; } [HarmonyFinalizer] private static void Finalizer() { Striking = false; } } [HarmonyPatch] internal static class MeleePatches { private static readonly FieldRef<Shovel, PlayerControllerB> shovelHolder = AccessTools.FieldRefAccess<Shovel, PlayerControllerB>("previousPlayerHeldBy"); [HarmonyPatch(typeof(Shovel), "HitShovel")] [HarmonyPrefix] private static void ShovelPrefix(Shovel __instance, out int __state) { __state = int.MinValue; PlayerControllerB p = shovelHolder.Invoke(__instance) ?? ((GrabbableObject)__instance).playerHeldBy; float num = Buffs.MeleeMul(); if (num > 1f && Local.Is(p)) { __state = __instance.shovelHitForce; __instance.shovelHitForce = Mathf.Max(1, Mathf.RoundToInt((float)__state * num)); } } [HarmonyPatch(typeof(Shovel), "HitShovel")] [HarmonyFinalizer] private static void ShovelFinalizer(Shovel __instance, int __state) { if (__state != int.MinValue) { __instance.shovelHitForce = __state; } } [HarmonyPatch(typeof(KnifeItem), "HitKnife")] [HarmonyPrefix] private static void KnifePrefix(KnifeItem __instance, out int __state) { __state = int.MinValue; PlayerControllerB p = __instance.previousPlayerHeldBy ?? ((GrabbableObject)__instance).playerHeldBy; float num = Buffs.MeleeMul(); if (num > 1f && Local.Is(p)) { __state = __instance.knifeHitForce; __instance.knifeHitForce = Mathf.Max(1, Mathf.RoundToInt((float)__state * num)); } } [HarmonyPatch(typeof(KnifeItem), "HitKnife")] [HarmonyFinalizer] private static void KnifeFinalizer(KnifeItem __instance, int __state) { if (__state != int.MinValue) { __instance.knifeHitForce = __state; } } } public enum BuffKind { SugarRush, WebRush, SugarCrash, Hydration, Dehydration, Regeneration, SugarMend, Brawn, Swift, Spring, SecondWind, Endurance, Hyponatremia, Equilibrium, BorrowedTime, Equivalence, SharpSight, Exquisite, CheeseSense, Grounded, Numb } public class Buff { public BuffKind kind; public float end; public float length; public float healLeft; public float healPending; public float crashAfter; public float Left => Mathf.Max(0f, end - Time.time); } public static class Buffs { private static readonly Dictionary<BuffKind, Buff> active = new Dictionary<BuffKind, Buff>(); private static readonly List<Buff> expired = new List<Buff>(); private static int healedSinceSync; public static IEnumerable<Buff> All => active.Values; private static SodaConfig C => SodaConfig.Instance; public static bool Has(BuffKind k) { return active.ContainsKey(k); } public static Buff Get(BuffKind k) { if (!active.TryGetValue(k, out var value)) { return null; } return value; } public static Buff Add(BuffKind k, float seconds) { if (seconds <= 0f) { return null; } if ((k == BuffKind.SugarCrash || k == BuffKind.Hyponatremia) && Has(BuffKind.Equilibrium) && FrailtyBridge.Installed) { seconds *= Mathf.Clamp01(C.EquiDebuffTime.Value / 100f); } if (!active.TryGetValue(k, out var value)) { value = new Buff { kind = k, end = Time.time + seconds, length = seconds }; active[k] = value; } else if (value.Left < seconds) { value.end = Time.time + seconds; value.length = seconds; } return value; } public static void Remove(BuffKind k) { active.Remove(k); } public static void Clear() { active.Clear(); } public static bool IsDebuff(BuffKind k) { if (k != BuffKind.SugarCrash && k != BuffKind.Hyponatremia) { return k == BuffKind.Dehydration; } return true; } public static void ClearDebuffs() { Remove(BuffKind.SugarCrash); Remove(BuffKind.Hyponatremia); Remove(BuffKind.Dehydration); } internal static void Tick(PlayerControllerB player) { if (active.Count == 0) { return; } if (player.isPlayerDead) { Clear(); return; } float deltaTime = Time.deltaTime; expired.Clear(); foreach (Buff value in active.Values) { if (value.healLeft > 0f) { Heal(player, value, deltaTime); } if (Time.time >= value.end) { expired.Add(value); } } foreach (Buff item in expired) { active.Remove(item.kind); if ((item.kind == BuffKind.SugarRush || item.kind == BuffKind.WebRush) && item.crashAfter > 0f && C.SugarCrash.Value && !Has(BuffKind.SugarRush) && !Has(BuffKind.WebRush)) { Add(BuffKind.SugarCrash, item.crashAfter); } } } private static void Heal(PlayerControllerB player, Buff b, float dt) { float num = b.healLeft / Mathf.Max(0.05f, b.Left); float num2 = Mathf.Min(b.healLeft, num * dt); b.healLeft -= num2; b.healPending += num2; if (b.healPending < 1f) { return; } int num3 = Mathf.FloorToInt(b.healPending); b.healPending -= num3; if (player.health >= 100) { return; } player.health = Mathf.Min(100, player.health + num3); HUDManager.Instance.UpdateHealthUI(player.health, false); if (player.health >= 20 && player.criticallyInjured) { player.MakeCriticallyInjured(false); } healedSinceSync += num3; if (healedSinceSync >= 5 || player.health >= 100 || b.healLeft < 1f) { healedSinceSync = 0; if (FrailtyBridge.Installed) { FrailtyBridge.SyncHealth(player); } } } public static float SpeedMul() { float num = 1f; if (Has(BuffKind.SugarRush)) { num *= 1f + C.RushSpeed.Value / 100f; } if (Has(BuffKind.WebRush)) { num *= 1f + C.WebSpeed.Value / 100f; } if (Has(BuffKind.Swift)) { num *= 1f + C.GenericSpeed.Value / 100f; } if (Has(BuffKind.Exquisite)) { num *= 1f + C.ExqSpeed.Value / 100f; } if (Has(BuffKind.BorrowedTime)) { num *= 1f + C.BorrowedSpeed.Value / 100f; } if (Has(BuffKind.Hyponatremia)) { num *= 1f - C.HypoSlow.Value / 100f; } return num; } public static float JumpMul() { float num = 1f; if (Has(BuffKind.SugarRush)) { num *= 1f + C.RushJump.Value / 100f; } if (Has(BuffKind.WebRush)) { num *= 1f + C.WebJump.Value / 100f; } if (Has(BuffKind.Spring)) { num *= 1f + C.GenericJump.Value / 100f; } if (Has(BuffKind.Exquisite)) { num *= 1f + C.ExqJump.Value / 100f; } if (Has(BuffKind.Hyponatremia)) { num *= 1f - C.HypoSlow.Value / 100f; } return num; } public static float ClimbMul() { if (!Has(BuffKind.Exquisite)) { return 1f; } return 1f + C.ExqClimb.Value / 100f; } public static float RefillMul() { float num = 1f; if (Has(BuffKind.Hydration)) { num *= C.HydrationRefill.Value; } if (Has(BuffKind.SugarMend)) { num *= 1f + C.MendRefill.Value / 100f; } if (Has(BuffKind.SecondWind)) { num *= 1f + C.GenericRefill.Value / 100f; } if (Has(BuffKind.Exquisite)) { num *= 1f + C.ExqRefill.Value / 100f; } if (Has(BuffKind.SugarCrash)) { num *= 1f - C.CrashRefill.Value / 100f; } return num; } public static float DrainMul() { if (Has(BuffKind.BorrowedTime)) { return 0f; } float num = 1f; if (Has(BuffKind.Endurance)) { num *= 1f - C.GenericEndurance.Value / 100f; } if (Has(BuffKind.Hyponatremia)) { num *= 1f + C.HypoDrain.Value / 100f; } return num; } public static float CarryReduce() { if (!Has(BuffKind.Brawn)) { return 0f; } return Mathf.Clamp01(C.BrawnCarry.Value / 100f); } public static float DamageMul() { float num = 1f; if (Has(BuffKind.Equilibrium)) { num *= 1f - Mathf.Clamp01(C.EquiReduction.Value / 100f); } if (Has(BuffKind.Numb)) { num *= 1f - Mathf.Clamp01(C.NumbReduction.Value / 100f); } return num; } public static float MeleeMul() { if (!Has(BuffKind.Brawn)) { return 1f; } return C.BrawnMelee.Value; } public static float FovAdd() { if (!Has(BuffKind.SharpSight)) { return 0f; } return C.SharpFov.Value; } } [HarmonyPatch] internal static class CustomDrinks { private static readonly Dictionary<DrinkId, Item> items = new Dictionary<DrinkId, Item>(); private static GameObject holder; private static bool made; private static readonly FieldInfo hashField = typeof(NetworkObject).GetField("GlobalObjectIdHash", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); internal static Material BaseMaterial; private static int baseMin = -1; private static int baseMax = -1; internal static IEnumerable<Item> All => items.Values; internal static Item ItemFor(DrinkDef def) { if (def == null || !items.TryGetValue(def.id, out var value)) { return null; } return value; } [HarmonyPatch(typeof(GameNetworkManager), "Start")] [HarmonyPostfix] private static void Make() { //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Expected O, but got Unknown //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_0336: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Expected O, but got Unknown if (made) { return; } made = true; try { NetworkManager singleton = NetworkManager.Singleton; if ((Object)(object)singleton == (Object)null || singleton.NetworkConfig == null || singleton.NetworkConfig.Prefabs == null) { Plugin.Log.LogError((object)"Our drinks: no network manager yet."); return; } GameObject val = null; foreach (NetworkPrefab prefab in singleton.NetworkConfig.Prefabs.Prefabs) { GrabbableObject val2 = (((Object)(object)prefab?.Prefab != (Object)null) ? prefab.Prefab.GetComponent<GrabbableObject>() : null); if ((Object)(object)val2 != (Object)null && (Object)(object)val2.itemProperties != (Object)null && val2.itemProperties.itemName == "Red soda") { val = prefab.Prefab; break; } } if ((Object)(object)val == (Object)null) { Plugin.Log.LogError((object)"Our drinks: the Red soda wasn't found, so Bolt Cola and the others can't be made."); return; } Item itemProperties = val.GetComponent<GrabbableObject>().itemProperties; baseMin = itemProperties.minValue; baseMax = itemProperties.maxValue; Sprite val3 = Assets.CanIcon("RedSoda"); if ((Object)(object)val3 != (Object)null) { itemProperties.itemIcon = val3; } Renderer componentInChildren = val.GetComponentInChildren<Renderer>(true); if ((Object)(object)componentInChildren != (Object)null && (Object)(object)componentInChildren.sharedMaterial != (Object)null) { BaseMaterial = componentInChildren.sharedMaterial; } holder = new GameObject("DrinkableSodaPrefabs"); holder.SetActive(false); ((Object)holder).hideFlags = (HideFlags)61; Object.DontDestroyOnLoad((Object)(object)holder); foreach (DrinkDef item in DrinkDefs.All.Where((DrinkDef d) => d.Custom)) { GameObject val4 = Object.Instantiate<GameObject>(val, holder.transform); ((Object)val4).name = "DrinkableSoda_" + item.key; ((Object)val4).hideFlags = (HideFlags)61; hashField?.SetValue(val4.GetComponent<NetworkObject>(), Hash("DrinkableSoda." + item.key)); Item val5 = Object.Instantiate<Item>(itemProperties); ((Object)val5).name = "DrinkableSoda_" + item.key; val5.itemName = item.itemName; val5.spawnPrefab = val4; val5.isScrap = true; Sprite val6 = Assets.CanIcon(item.key); if ((Object)(object)val6 != (Object)null) { val5.itemIcon = val6; } val4.GetComponent<GrabbableObject>().itemProperties = val5; ScanNodeProperties[] componentsInChildren = val4.GetComponentsInChildren<ScanNodeProperties>(true); for (int num = 0; num < componentsInChildren.Length; num++) { componentsInChildren[num].headerText = item.itemName; } Texture2D val7 = Assets.CanTexture(item.key); if ((Object)(object)val7 != (Object)null) { Renderer[] componentsInChildren2 = val4.GetComponentsInChildren<Renderer>(true); foreach (Renderer val8 in componentsInChildren2) { Material[] sharedMaterials = val8.sharedMaterials; bool flag = false; for (int num2 = 0; num2 < sharedMaterials.Length; num2++) { if (!((Object)(object)sharedMaterials[num2] == (Object)null)) { Material val9 = new Material(sharedMaterials[num2]) { name = "DrinkableSoda_" + item.key }; if (val9.HasProperty("_BaseColorMap")) { val9.SetTexture("_BaseColorMap", (Texture)(object)val7); } if (val9.HasProperty("_MainTex")) { val9.SetTexture("_MainTex", (Texture)(object)val7); } sharedMaterials[num2] = val9; flag = true; } } if (flag) { val8.sharedMaterials = sharedMaterials; } } } singleton.AddNetworkPrefab(val4); items[item.id] = val5; } Plugin.Log.LogInfo((object)string.Format("Made {0} drinks: {1}.", items.Count, string.Join(", ", items.Values.Select((Item i) => i.itemName)))); } catch (Exception ex) { Plugin.Log.LogError((object)("Our drinks: " + ex)); } } private static uint Hash(string s) { using MD5 mD = MD5.Create(); return BitConverter.ToUInt32(mD.ComputeHash(Encoding.UTF8.GetBytes(s)), 0); } [HarmonyPatch(typeof(StartOfRound), "Awake")] [HarmonyPrefix] [HarmonyPriority(600)] private static void AddToItemList(StartOfRound __instance) { try { List<Item> list = __instance.allItemsList?.itemsList; if (list == null) { return; } foreach (DrinkDef item in DrinkDefs.All.Where((DrinkDef d) => d.Custom)) { Item val = ItemFor(item); if ((Object)(object)val != (Object)null && !list.Contains(val)) { list.Add(val); } } } catch (Exception ex) { Plugin.Log.LogError((object)("Our drinks (item list): " + ex)); } } internal static float ScrapWeight(DrinkDef def) { return Mathf.Sqrt(30f / (float)Mathf.Max(10, def.price())); } [HarmonyPatch(typeof(RoundManager), "SpawnScrapInLevel")] [HarmonyPrefix] private static void AddToScrap(RoundManager __instance) { //IL_0156: Unknown result type (might be due to invalid IL or missing references) //IL_0160: Expected O, but got Unknown try { SelectableLevel currentLevel = __instance.currentLevel; if ((Object)(object)currentLevel == (Object)null || currentLevel.spawnableScrap == null) { return; } SodaConfig instance = SodaConfig.Instance; currentLevel.spawnableScrap.RemoveAll((SpawnableItemWithRarity s) => s != null && (Object)(object)s.spawnableItem != (Object)null && items.ContainsValue(s.spawnableItem)); if (!instance.ScrapSpawn.Value || currentLevel.levelID == 3) { return; } foreach (DrinkDef item in DrinkDefs.All.Where((DrinkDef d) => d.Custom && d.enabled())) { Item val = ItemFor(item); if (!((Object)(object)val == (Object)null)) { int num = Mathf.Max(0, Mathf.RoundToInt((float)instance.ScrapRarity.Value * ScrapWeight(item))); float num2 = Mathf.Sqrt((float)Mathf.Max(10, item.price()) / 30f); if (baseMin > 0 && baseMax > 0) { val.minValue = Mathf.Max(1, Mathf.RoundToInt((float)baseMin * num2)); val.maxValue = Mathf.Max(val.minValue + 1, Mathf.RoundToInt((float)baseMax * num2)); } if (num > 0) { currentLevel.spawnableScrap.Add(new SpawnableItemWithRarity(val, num)); } } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("Our drinks (scrap): " + ex.Message)); } } } internal static class Diagnostics { private static readonly HashSet<string> seen = new HashSet<string>(); private static int scanFrame = -1; private static int scanCount; internal static void TryPatch(Harmony harmony) { //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) //IL_0077: Expected O, but got Unknown //IL_0077: Expected O, but got Unknown //IL_00aa: Unknown result type (might be due to invalid IL or missing references) //IL_00b8: Expected O, but got Unknown if (SodaConfig.Instance == null || !SodaConfig.Instance.LogTypeSearches.Value) { return; } try { MethodInfo methodInfo = AccessTools.Method(typeof(AccessTools), "TypeByName", new Type[1] { typeof(string) }, (Type[])null); harmony.Patch((MethodBase)methodInfo, new HarmonyMethod(typeof(Diagnostics), "Prefix", (Type[])null), new HarmonyMethod(typeof(Diagnostics), "Postfix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); MethodInfo methodInfo2 = AccessTools.Method(typeof(AccessTools), "GetTypesFromAssembly", (Type[])null, (Type[])null); if (methodInfo2 != null) { harmony.Patch((MethodBase)methodInfo2, new HarmonyMethod(typeof(Diagnostics), "ScanPrefix", (Type[])null), (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); } Plugin.Log.LogWarning((object)"Debug: logging slow type searches (turn off in config when done)."); } catch (Exception ex) { Plugin.Log.LogWarning((object)("Type search logging: " + ex.Message)); } } private static void Prefix(out float __state) { __state = Time.realtimeSinceStartup; } private static void Postfix(string name, Type __result, float __state) { float num = (Time.realtimeSinceStartup - __state) * 1000f; if (name != null && (!(__result != null) || !(num < 15f)) && seen.Add(name)) { Plugin.Log.LogWarning((object)string.Format("Slow type search: \"{0}\" {1} ({2:0} ms). Asked by:\n{3}", name, (__result == null) ? "not found" : "found", num, Environment.StackTrace)); } } private static void ScanPrefix() { int frameCount = Time.frameCount; if (frameCount != scanFrame) { scanFrame = frameCount; scanCount = 0; } if (++scanCount == 40) { string stackTrace = Environment.StackTrace; if (seen.Add("scan:" + stackTrace.GetHashCode())) { Plugin.Log.LogWarning((object)("Slow type search: a mod is reading every type of every mod. Asked by:\n" + stackTrace)); } } } } public enum DrinkId { RedSoda, Pills, Alt, Generic, Web, Jim, Sakura, Morv, Cheese, Harvest, Vanilla } public class DrinkDef { public DrinkId id; public string itemName; public bool pill; public string key; public Func<bool> enabled; public Func<int> price; public Func<int> machineBase; public bool special; public bool Custom => key != null; public int MaxUses { get { if (!pill) { return 1; } return Mathf.Max(1, SodaConfig.Instance.PillUses.Value); } } public string Tip(int usesLeft) { if (!pill) { return "Drink : [LMB]"; } return $"Take a pill ({usesLeft} left) : [LMB]"; } } internal static class DrinkDefs { internal static readonly List<DrinkDef> All = new List<DrinkDef>(); private static SodaConfig C => SodaConfig.Instance; internal static void Init() { All.Clear(); Add(DrinkId.RedSoda, "Red soda", pill: false, null, () => C.OnRedSoda.Value, () => C.PriceRedSoda.Value); Add(DrinkId.Pills, "Pill bottle", pill: true, null, () => C.OnPills.Value && !FrailtyBridge.MedicalInstalled, () => C.PricePills.Value); Add(DrinkId.Alt, "Peach Soda", pill: false, "PeachSoda", () => C.OnAlt.Value, () => C.PriceAlt.Value); Add(DrinkId.Generic, "Mystery Soda", pill: false, "MysterySoda", () => C.OnGeneric.Value, () => C.PriceGeneric.Value); Add(DrinkId.Web, "Bolt Cola", pill: false, "BoltCola", () => C.OnWeb.Value, () => C.PriceWeb.Value); Add(DrinkId.Jim, "Sparkle Soda", pill: false, "SparkleSoda", () => C.OnJim.Value, () => C.PriceJim.Value); Add(DrinkId.Sakura, "ACE Soda", pill: false, "AceSoda", () => C.OnSakura.Value, () => C.PriceSakura.Value); Add(DrinkId.Morv, "Climate Soda", pill: false, "ClimateSoda", () => C.OnMorv.Value, () => C.PriceMorv.Value); Add(DrinkId.Cheese, "Cheesy Soda", pill: false, "CheesySoda", () => C.OnCheese.Value, () => C.PriceCheese.Value); Add(DrinkId.Harvest, "Kosher Soda", pill: false, "KosherSoda", () => C.OnHarvest.Value, () => C.PriceHarvest.Value); Add(DrinkId.Vanilla, "Vanilla Soda", pill: false, "VanillaSoda", () => C.OnVanilla.Value, () => C.PriceVanilla.Value); Special(DrinkId.Morv, () => C.MachineBaseMorv.Value); Special(DrinkId.Cheese, () => C.MachineBaseCheese.Value); Special(DrinkId.Harvest, () => C.MachineBaseHarvest.Value); } private static void Add(DrinkId id, string name, bool pill, string key, Func<bool> on, Func<int> price) { All.Add(new DrinkDef { id = id, itemName = name, pill = pill, key = key, enabled = on, price = price }); } private static void Special(DrinkId id, Func<int> machineBase) { DrinkDef drinkDef = Get(id); drinkDef.special = true; drinkDef.machineBase = machineBase; } internal static DrinkDef Get(DrinkId id) { return All.Find((DrinkDef d) => d.id == id); } internal static DrinkDef Find(Item item) { if ((Object)(object)item == (Object)null || string.IsNullOrEmpty(item.itemName)) { return null; } string b = item.itemName.Trim(); foreach (DrinkDef item2 in All) { if (string.Equals(item2.itemName, b, StringComparison.OrdinalIgnoreCase)) { return item2; } } return null; } } public class Drinkable : MonoBehaviour { public DrinkDef def; public GrabbableObject item; public int used; private ScanNodeProperties scan; private string scanHeader; private int scanNodeType = -1; private string scanSub; public bool Empty => used >= def.MaxUses; public int UsesLeft => Mathf.Max(0, def.MaxUses - used); public bool FromStore { get { if ((Object)(object)item != (Object)null) { return item.scrapValue <= 0; } return false; } } internal static Drinkable For(GrabbableObject g) { if ((Object)(object)g == (Object)null) { return null; } Drinkable component = ((Component)g).GetComponent<Drinkable>(); if ((Object)(object)component != (Object)null) { return component; } DrinkDef drinkDef = DrinkDefs.Find(g.itemProperties); if (drinkDef == null) { return null; } component = ((Component)g).gameObject.AddComponent<Drinkable>(); component.def = drinkDef; component.item = g; component.scan = ((Component)g).GetComponentInChildren<ScanNodeProperties>(true); if ((Object)(object)component.scan != (Object)null) { if (component.scan.headerText != null && component.scan.headerText.Contains("???")) { component.scan.headerText = "Cheese soda"; } component.scanHeader = component.scan.headerText; } Net.ApplyPending(component); component.RefreshScan(); return component; } internal void SetUsed(int value) { used = Mathf.Max(0, value); RefreshScan(); if ((Object)(object)item != (Object)null && (Object)(object)item.playerHeldBy != (Object)null && (Object)(object)item.playerHeldBy == (Object)(object)GameNetworkManager.Instance?.localPlayerController && (Object)(object)item.playerHeldBy.currentlyHeldObjectServer == (Object)(object)item) { Drinking.SetTips(this); } } internal void RefreshScan() { if ((Object)(object)scan == (Object)null) { return; } if (scanNodeType < 0) { scanNodeType = scan.nodeType; } if (FromStore) { if (scan.nodeType != 0) { scan.nodeType = 0; scanSub = scan.subText; } scan.subText = ""; } else if (scan.nodeType != scanNodeType) { scan.nodeType = scanNodeType; if (scanSub != null && string.IsNullOrEmpty(scan.subText)) { scan.subText = scanSub; } } string text = scanHeader ?? def.itemName; if (Empty) { scan.headerText = "Empty " + text; } else if (def.pill) { scan.headerText = text + " (" + UsesLeft + ((UsesLeft == 1) ? " use left)" : " uses left)"); } else { scan.headerText = text; } } } internal static class Drinking { internal static bool Busy; private static SodaConfig C => SodaConfig.Instance; internal static float DrinkTime(DrinkDef d) { if (!d.pill) { return 3.2f; } return 1.6f; } internal static void SetTips(Drinkable d) { try { string[] array = ((!d.def.enabled() || d.Empty) ? new string[0] : new string[1] { d.def.Tip(d.UsesLeft) }); HUDManager.Instance.ChangeControlTipMultiple(array, true, d.item.itemProperties); } catch { } } internal static bool TryUse(GrabbableObject item) { Drinkable drinkable = Drinkable.For(item); if ((Object)(object)drinkable == (Object)null || !drinkable.def.enabled()) { return false; } if (Busy || drinkable.Empty) { return true; } PlayerControllerB playerHeldBy = item.playerHeldBy; if ((Object)(object)playerHeldBy == (Object)null || (Object)(object)playerHeldBy != (Object)(object)GameNetworkManager.Instance.localPlayerController || playerHeldBy.isPlayerDead) { return true; } ((MonoBehaviour)Plugin.Instance).StartCoroutine(Drink(playerHeldBy, drinkable)); return true; } private static IEnumerator Drink(PlayerControllerB player, Drinkable d) { Busy = true; GrabbableObject item = d.item; float time = DrinkTime(d.def); player.activatingItem = true; player.playerBodyAnimator.SetBool("useTZPItem", true); Sfx.Play(player, d.def.pill); Net.SendDrink(item, d.def.pill); if (C.NoiseRange.Value > 0f) { RoundManager.Instance.PlayAudibleNoise(((Component)item).transform.position, C.NoiseRange.Value, 0.5f, 0, item.isInElevator && StartOfRound.Instance.hangarDoorsClosed, 0); } BuffKind? during = (d.def.pill ? ((BuffKind?)null) : new BuffKind?((d.def.id == DrinkId.Harvest) ? BuffKind.Dehydration : BuffKind.Hydration)); if (during.HasValue) { Buffs.Add(during.Value, time); } bool cancelled = false; float t = 0f; while (t < time) { yield return null; t += Time.deltaTime; if ((Object)(object)player == (Object)null || player.isPlayerDead || (Object)(object)item == (Object)null || (Object)(object)item.playerHeldBy != (Object)(object)player || item.isPocketed || (Object)(object)player.currentlyHeldObjectServer != (Object)(object)item) { cancelled = true; break; } } if ((Object)(object)player != (Object)null) { player.playerBodyAnimator.SetBool("useTZPItem", false); player.activatingItem = false; } if (during.HasValue) { Buffs.Remove(during.Value); } Busy = false; if (cancelled || (Object)(object)player == (Object)null || player.isPlayerDead) { Sfx.Stop(player); yield break; } try { Effects.Apply(player, d.def); } catch (Exception ex) { Plugin.Log.LogError((object)("Drink effects: " + ex)); } Consume(player, d); } private static void Consume(PlayerControllerB player, Drinkable d) { int num = d.used + 1; if (num >= d.def.MaxUses && d.FromStore) { player.DespawnHeldObject(); return; } int value = d.item.scrapValue; if (num >= d.def.MaxUses && !d.FromStore) { value = Mathf.Max(1, Mathf.RoundToInt((float)d.item.scrapValue * Mathf.Clamp01(C.EmptyValuePercent.Value / 100f))); } Net.SendState(d.item, num, value); } } internal static class Sfx { internal static void Play(PlayerControllerB player, bool pill) { if (!((Object)(object)player == (Object)null) && !((Object)(object)player.itemAudio == (Object)null)) { AudioClip val = Assets.Sound(pill ? "Pill_Shake" : "Soda_Drink_tight"); if (!((Object)(object)val == (Object)null)) { player.itemAudio.PlayOneShot(val, 1f); WalkieTalkie.TransmitOneShotAudio(player.itemAudio, val, 1f); } } } internal static void Stop(PlayerControllerB player) { } } internal static class Effects { private static SodaConfig C => SodaConfig.Instance; internal static void Apply(PlayerControllerB player, DrinkDef d) { switch (d.id) { case DrinkId.RedSoda: Buffs.Add(BuffKind.SugarRush, C.RushTime.Value).crashAfter = C.CrashTime.Value; Buffs.Remove(BuffKind.SugarCrash); break; case DrinkId.Web: Buffs.Add(BuffKind.WebRush, C.WebTime.Value).crashAfter = C.WebCrashTime.Value; Buffs.Remove(BuffKind.SugarCrash); break; case DrinkId.Pills: if (FrailtyBridge.Installed) { FrailtyBridge.CurePillInjuries(); } CureVanillaTzp(player); Buffs.Add(BuffKind.Numb, C.NumbTime.Value); if (C.PillHeal.Value > 0f) { Heal(BuffKind.Regeneration, C.PillHeal.Value, C.PillHealTime.Value); } break; case DrinkId.Alt: Heal(BuffKind.SugarMend, C.MendHeal.Value, C.MendTime.Value); break; case DrinkId.Generic: { if (Buffs.Has(BuffKind.Swift) || Buffs.Has(BuffKind.Spring) || Buffs.Has(BuffKind.SecondWind) || Buffs.Has(BuffKind.Endurance)) { Buffs.Add(BuffKind.Hyponatremia, C.HypoTime.Value); } float value = Random.value; float num = Mathf.Clamp01(C.GenericCureChance.Value); if (value < num) { CureAll(player); break; } Buffs.Add(Mathf.Clamp((int)((value - num) / Mathf.Max(0.0001f, 1f - num) * 4f), 0, 3) switch { 2 => BuffKind.SecondWind, 1 => BuffKind.Spring, 0 => BuffKind.Swift, _ => BuffKind.Endurance, }, C.GenericTime.Value); break; } case DrinkId.Jim: Buffs.Add(BuffKind.Brawn, C.BrawnTime.Value); break; case DrinkId.Sakura: Buffs.Add(BuffKind.SharpSight, C.SharpTime.Value); break; case DrinkId.Vanilla: Buffs.Add(BuffKind.Exquisite, C.ExqTime.Value); break; case DrinkId.Cheese: Buffs.Add(BuffKind.CheeseSense, C.CheeseTime.Value); break; case DrinkId.Morv: Buffs.Add(BuffKind.Grounded, C.GroundedTime.Value); break; case DrinkId.Harvest: Buffs.Add(BuffKind.Equilibrium, C.EquiTime.Value); break; } } private static void Heal(BuffKind kind, float hp, float seconds) { float num = Buffs.Get(kind)?.healLeft ?? 0f; Buff buff = Buffs.Add(kind, seconds); if (buff != null) { buff.healLeft = num + hp; } } internal static void CureAll(PlayerControllerB player) { if (FrailtyBridge.Installed) { FrailtyBridge.CureAll(); } Buffs.ClearDebuffs(); CureVanillaTzp(player); } internal static void CureVanillaTzp(PlayerControllerB player) { player.drunkness = 0f; player.drunknessInertia = 0f; } } internal static class EladsTint { private const string EladsGuid = "me.eladnlg.customhud"; private static FieldInfo healthBar; private static FieldInfo healthGroup; private static FieldInfo staminaBar; private static FieldInfo warnColor; private static FieldInfo colorLerp; private static bool tzpPlus; private static object lastHud; private static Color originalHealth; private static float staminaAmount; private static float healthAmount; private static Color staminaColor = BuffInfo.Gold; private static readonly BuffKind[] staminaBuffs = new BuffKind[10] { BuffKind.Exquisite, BuffKind.BorrowedTime, BuffKind.Hydration, BuffKind.SecondWind, BuffKind.Endurance, BuffKind.Swift, BuffKind.WebRush, BuffKind.SugarRush, BuffKind.SugarMend, BuffKind.Brawn }; internal static void TryPatch(Harmony harmony) { //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0102: Expected O, but got Unknown try { if (!Chainloader.PluginInfos.TryGetValue("me.eladnlg.customhud", out var value) || (Object)(object)value.Instance == (Object)null) { return; } Type type = ((object)value.Instance).GetType().Assembly.GetType("CustomHUD_Mono"); if (!(type == null)) { healthBar = AccessTools.Field(type, "healthBar"); healthGroup = AccessTools.Field(type, "healthGroup"); staminaBar = AccessTools.Field(type, "staminaBar"); warnColor = AccessTools.Field(type, "staminaWarnColor"); colorLerp = AccessTools.Field(type, "colorLerp"); MethodInfo methodInfo = AccessTools.Method(type, "UpdateFromPlayer", (Type[])null, (Type[])null); if (!(methodInfo == null) && !(healthBar == null) && !(staminaBar == null)) { tzpPlus = Chainloader.PluginInfos.ContainsKey("Miles.TZPPlus"); HarmonyMethod val = new HarmonyMethod(typeof(EladsTint), "Postfix", (Type[])null); val.priority = 400; val.after = new string[1] { "Miles.TZPPlus" }; harmony.Patch((MethodBase)methodInfo, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); Plugin.Log.LogInfo((object)"EladsHUD+ found: its bars change color with drink buffs."); } } } catch (Exception ex) { Plugin.Log.LogWarning((object)("EladsHUD+ bar colors: " + ex.Message)); } } private static void Postfix(object __instance) { //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007f: Unknown result type (might be due to invalid IL or missing references) //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_018a: Unknown result type (might be due to invalid IL or missing references) //IL_00ff: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: 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_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0138: Unknown result type (might be due to invalid IL or missing references) //IL_013c: Unknown result type (might be due to invalid IL or missing references) //IL_0146: Unknown result type (might be due to invalid IL or missing references) //IL_01e8: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) //IL_01ed: Unknown result type (might be due to invalid IL or missing references) //IL_01f1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fd: Unknown result type (might be due to invalid IL or missing references) try { SodaConfig instance = SodaConfig.Instance; if (instance == null) { return; } float deltaTime = Time.deltaTime; BuffKind? buffKind = null; if (instance.TintStamina.Value) { BuffKind[] array = staminaBuffs; foreach (BuffKind buffKind2 in array) { if (Buffs.Has(buffKind2)) { buffKind = buffKind2; break; } } } if (buffKind.HasValue) { staminaColor = Color.Lerp(staminaColor, BuffInfo.Color(buffKind.Value), 4f * deltaTime); } staminaAmount = Mathf.MoveTowards(staminaAmount, buffKind.HasValue ? 1f : 0f, 2f * deltaTime); if (staminaAmount > 0f) { object? value = staminaBar.GetValue(__instance); Image val = (Image)((value is Image) ? value : null); if (val != null && (Object)(object)val != (Object)null) { Color val2 = (Color)((warnColor != null) ? ((Color)warnColor.GetValue(__instance)) : Color.red); float num = ((colorLerp != null) ? Convert.ToSingle(colorLerp.GetValue(__instance)) : 0f); ((Graphic)val).color = Color.Lerp(((Graphic)val).color, Color.Lerp(staminaColor, val2, num), staminaAmount); } } object? value2 = healthBar.GetValue(__instance); Image val3 = (Image)((value2 is Image) ? value2 : null); if (val3 == null || (Object)(object)val3 == (Object)null) { return; } if (__instance != lastHud) { lastHud = __instance; originalHealth = ((Graphic)val3).color; } bool flag = instance.TintHealth.Value && (Buffs.Has(BuffKind.Regeneration) || Buffs.Has(BuffKind.SugarMend)); healthAmount = Mathf.MoveTowards(healthAmount, flag ? 1f : 0f, 2f * deltaTime); Color val4 = (tzpPlus ? ((Graphic)val3).color : originalHealth); ((Graphic)val3).color = Color.Lerp(val4, BuffInfo.Green, healthAmount); if (healthAmount > 0f && healthGroup != null) { object? value3 = healthGroup.GetValue(__instance); CanvasGroup val5 = (CanvasGroup)((value3 is CanvasGroup) ? value3 : null); if (val5 != null && (Object)(object)val5 != (Object)null) { val5.alpha = Mathf.Max(val5.alpha, healthAmount); } } } catch { } } } internal static class FrailtyBridge { private static bool? installed; private static Transform conditionRow; private static bool rowSearched; internal static bool Installed { get { bool? flag = installed; if (!flag.HasValue) { bool? flag2 = (installed = Chainloader.PluginInfos.ContainsKey("Chaos.Frailty")); return flag2.Value; } return flag == true; } } internal static bool MedicalInstalled => Chainloader.PluginInfos.ContainsKey("Miles.FrailtyMedical"); [MethodImpl(MethodImplOptions.NoInlining)] internal static void Hook() { SodaConfig C = SodaConfig.Instance; FrailtyApi.NewDebuffTimeScale.Add(() => (!Buffs.Has(BuffKind.Equilibrium)) ? 1f : Mathf.Clamp01(C.EquiDebuffTime.Value / 100f)); FrailtyApi.SuppressEffects.Add(() => Buffs.Has(BuffKind.Equivalence)); FrailtyApi.LocalPlayerHurt += delegate(PlayerControllerB player, int taken, CauseOfDeath cause, bool fall) { if (Buffs.Has(BuffKind.Equilibrium)) { if (!fall && C.BorrowedTime.Value > 0f) { Buffs.Add(BuffKind.BorrowedTime, C.BorrowedTime.Value); } if (C.EquivalenceTime.Value > 0f && Random.value < C.EquivalenceChance.Value) { Buffs.Add(BuffKind.Equivalence, C.EquivalenceTime.Value); } } }; Plugin.Log.LogInfo((object)"FrailtyPlus found: Equilibrium and Cure All work with its injuries."); } internal static int VisibleConditionIcons() { try { if ((Object)(object)conditionRow == (Object)null && !rowSearched) { rowSearched = true; PluginInfo value; object? obj = (((Chainloader.PluginInfos.TryGetValue("Chaos.Frailty", out value) && (Object)(object)value.Instance != (Object)null) ? ((object)value.Instance).GetType().Assembly.GetType("Frailty.Patches.HUDPatch") : null)?.GetField("conditionHud", BindingFlags.Static | BindingFlags.Public))?.GetValue(null); GameObject val = (GameObject)((obj is GameObject) ? obj : null); conditionRow = (((Object)(object)val != (Object)null) ? val.transform : null); } if ((Object)(object)conditionRow == (Object)null) { rowSearched = false; return 0; } int num = 0; for (int i = 0; i < conditionRow.childCount; i++) { if (((Component)conditionRow.GetChild(i)).gameObject.activeSelf) { num++; } } return num; } catch { return 0; } } [MethodImpl(MethodImplOptions.NoInlining)] internal static void CureAll() { FrailtyApi.CureAll(); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void CurePillInjuries() { ConditionType[] array = new ConditionType[5]; RuntimeHelpers.InitializeArray(array, (RuntimeFieldHandle)/*OpCode not supported: LdMemberToken*/); FrailtyApi.Cure((ConditionType[])(object)array); } [MethodImpl(MethodImplOptions.NoInlining)] internal static void SyncHealth(PlayerControllerB player) { HealthSync.Send(player); } } public class SodaMachine : MonoBehaviour { internal enum Status { Free, Buy, NoMoney, NotSold, SoldOut, OutOfStock } internal static readonly List<SodaMachine> All = new List<SodaMachine>(); internal const int ButtonCount = 10; private NetworkObject netObj; private PlaceableShipObject placeable; private AutoParentToShip parent; private readonly InteractTrigger[] buttons = (InteractTrigger[])(object)new InteractTrigger[10]; private AudioSource audioSource; private Transform dispensePoint; private MachineModel model; private float busyUntil; private int selected = -1; private float selectedUntil; private const float SelectTime = 8f; private int litButton = -1; private float litUntil; private bool litGreen; private readonly Material[] lampShown = (Material[])(object)new Material[10]; private string shownText; private float nextTips; private static Sprite hoverIcon; private static AudioClip placeSfx; private static readonly Color DisplayGreen = new Color(0.49f, 1f, 0.54f); private static readonly Color DisplayRed = new Color(1f, 0.33f, 0.28f); private AudioSource motor; private const float FlapOpen = 70f; private bool Busy => Time.time < busyUntil; private bool Picked { get { if (selected >= 0) { return Time.time < selectedUntil; } return false; } } private static PlayerControllerB Me { get { if (!((Object)(object)GameNetworkManager.Instance != (Object)null)) { return null; } return GameNetworkManager.Instance.localPlayerController; } } internal ulong Id { get { if (!((Object)(object)netObj != (Object)null)) { return 0uL; } return netObj.NetworkObjectId; } } internal IEnumerable<Collider> OwnColliders => ((Component)this).GetComponentsInChildren<Collider>(true); internal static void BuildPrefab(GameObject root) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0024: 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_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0046: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f8: Expected O, but got Unknown //IL_0115: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_0136: Unknown result type (might be due to invalid IL or missing references) //IL_0158: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_016f: Unknown result type (might be due to invalid IL or missing references) //IL_017a: Unknown result type (might be due to invalid IL or missing references) //IL_018b: Unknown result type (might be due to invalid IL or missing references) //IL_0195: Unknown result type (might be due to invalid IL or missing references) //IL_01ab: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_01f3: Unknown result type (might be due to invalid IL or missing references) //IL_01fe: Unknown result type (might be due to invalid IL or missing references) //IL_021a: Unknown result type (might be due to invalid IL or missing references) //IL_028d: Unknown result type (might be due to invalid IL or missing references) Vector3 size = MachineModel.Size; root.AddComponent<AutoParentToShip>(); SetupAudio(root.AddComponent<AudioSource>()); root.AddComponent<SodaMachine>(); GameObject val = new GameObject("Placement"); val.transform.SetParent(root.transform, false); val.transform.localPosition = new Vector3(0f, size.y * 0.5f, 0f); val.layer = Layer("PlaceableShipObjects", 26); val.tag = "PlaceableObject"; BoxCollider val2 = val.AddComponent<BoxCollider>(); val2.size = size; SetupAudio(val.AddComponent<AudioSource>()); PlaceableShipObject obj = val.AddComponent<PlaceableShipObject>(); obj.parentObject = root.GetComponent<AutoParentToShip>(); obj.placeObjectCollider = (Collider)(object)val2; obj.yOffset = size.y * 0.5f; obj.AllowPlacementOnCounters = false; obj.AllowPlacementOnWalls = false; obj.unlockableID = -1; GameObject obj2 = GameObject.CreatePrimitive((PrimitiveType)3); Mesh sharedMesh = obj2.GetComponent<MeshFilter>().sharedMesh; Object.DestroyImmediate((Object)(object)obj2); GameObject val3 = new GameObject("Shape"); val3.transform.SetParent(root.transform, false); val3.transform.localPosition = new Vector3(0f, size.y * 0.5f, 0f); val3.transform.localScale = size; val3.AddComponent<MeshFilter>().sharedMesh = sharedMesh; obj.mainMesh = val3.GetComponent<MeshFilter>(); GameObject val4 = new GameObject("Body"); val4.transform.SetParent(root.transform, false); val4.transform.localPosition = new Vector3(0f, size.y * 0.5f, 0f); val4.layer = Layer("Room", 8); val4.AddComponent<BoxCollider>().size = size; for (int i = 0; i < 10; i++) { GameObject val5 = new GameObject("Button" + i); val5.transform.SetParent(root.transform, false); val5.layer = Layer("InteractableObject", 9); val5.tag = "InteractTrigger"; BoxCollider obj3 = val5.AddComponent<BoxCollider>(); ((Collider)obj3).isTrigger = true; obj3.size = new Vector3(0.26f, 0.1f, 0.2f); InteractTrigger obj4 = val5.AddComponent<InteractTrigger>(); obj4.hoverTip = "Pick : [E]"; obj4.disabledHoverTip = ""; obj4.interactable = true; obj4.oneHandedItemAllowed = true; obj4.twoHandedItemAllowed = true; obj4.holdInteraction = false; obj4.interactCooldown = true; obj4.cooldownTime = 0.3f; obj4.disableTriggerMesh = false; InitEvents(obj4); } new GameObject("Dispense").transform.SetParent(root.transform, false); } private static int Layer(string name, int fallback) { int num = LayerMask.NameToLayer(name); if (num < 0) { return fallback; } return num; } private static void SetupAudio(AudioSource a) { a.playOnAwake = false; a.spatialBlend = 1f; a.rolloffMode = (AudioRolloffMode)1; a.minDistance = 2f; a.maxDistance = 18f; } private static void InitEvents(InteractTrigger it) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) it.onInteract = (InteractEvent)(((object)it.onInteract) ?? ((object)new InteractEvent())); it.onInteractEarly = (InteractEvent)(((object)it.onInteractEarly) ?? ((object)new InteractEvent())); it.onInteractEarlyOtherClients = (InteractEvent)(((object)it.onInteractEarlyOtherClients) ?? ((object)new InteractEvent())); it.onStopInteract = (InteractEvent)(((object)it.onStopInteract) ?? ((object)new InteractEvent())); it.onCancelAnimation = (InteractEvent)(((object)it.onCancelAnimation) ?? ((object)new InteractEvent())); it.holdingInteractEvent = (InteractEventFloat)(((object)it.holdingInteractEvent) ?? ((object)new InteractEventFloat())); } private void Awake() { //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_0133: Unknown result type (might be due to invalid IL or missing references) //IL_0145: Unknown result type (might be due to invalid IL or missing references) //IL_0151: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_0182: Unknown result type (might be due to invalid IL or missing references) //IL_0198: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01df: Unknown result type (might be due to invalid IL or missing references) netObj = ((Component)this).GetComponent<NetworkObject>(); parent = ((Component)this).GetComponent<AutoParentToShip>(); audioSource = ((Component)this).GetComponent<AudioSource>(); placeable = ((Component)this).GetComponentInChildren<PlaceableShipObject>(true); dispensePoint = ((Component)this).transform.Find("Dispense"); for (int i = 0; i < 10; i++) { Transform val = ((Component)this).transform.Find("Button" + i); buttons[i] = (((Object)(object)val != (Object)null) ? ((Component)val).GetComponent<InteractTrigger>() : null); if (!((Object)(object)buttons[i] == (Object)null)) { InitEvents(buttons[i]); int index = i; ((UnityEvent<PlayerControllerB>)(object)buttons[i].onInteract).AddListener((UnityAction<PlayerControllerB>)delegate(PlayerControllerB p) { OnButton(index, p); }); } } try { model = MachineModel.Build(((Component)this).transform); Plugin.Log.LogInfo((object)"Soda Machine spawned."); float num = 0.5f; for (int num2 = 0; num2 < 10; num2++) { if (!((Object)(object)buttons[num2] == (Object)null)) { Bounds val2 = model.ButtonRect(num2, 10); ((Component)buttons[num2]).transform.localPosition = new Vector3(((Bounds)(ref val2)).center.x, ((Bounds)(ref val2)).center.y, num + 0.06f); ((Component)buttons[num2]).GetComponent<BoxCollider>().size = new Vector3(Mathf.Max(0.15f, ((Bounds)(ref val2)).size.x), Mathf.Max(0.05f, ((Bounds)(ref val2)).size.y), 0.2f); } } if ((Object)(object)dispensePoint != (Object)null) { dispensePoint.localPosition = model.dispense; } } catch (Exception ex) { Plugin.Log.LogError((object)("Soda Machine model: " + ex)); } int id = MachineSetup.Id; if (id >= 0) { if ((Object)(object)placeable != (Object)null && placeable.unlockableID < 0) { placeable.unlockableID = id; } if ((Object)(object)parent != (Object)null && parent.unlockableID < 0) { parent.unlockableID = id; } } } private void Start() { All.Add(this); BorrowVanillaBits(); if ((Object)(object)NetworkManager.Singleton != (Object)null && NetworkManager.Singleton.IsServer) { ((MonoBehaviour)this).StartCoroutine(PlaceIfNew()); } } private void OnDestroy() { All.Remove(this); } private void BorrowVanillaBits() { try { InteractTrigger[] array; if ((Object)(object)hoverIcon == (Object)null) { array = Object.FindObjectsOfType<InteractTrigger>(); foreach (InteractTrigger val in array) { if ((Object)(object)val != (Object)null && !buttons.Contains(val) && (Object)(object)val.hoverIcon != (Object)null) { hoverIcon = val.hoverIcon; break; } } } if ((Object)(object)placeSfx == (Object)null) { PlaceableShipObject[] array2 = Object.FindObjectsOfType<PlaceableShipObject>(); foreach (PlaceableShipObject val2 in array2) { if ((Object)(object)val2 != (Object)null && (Object)(object)val2 != (Object)(object)placeable && (Object)(object)val2.placeObjectSFX != (Object)null && ((Object)val2.placeObjectSFX).name == "MoveShipObjectBig") { placeSfx = val2.placeObjectSFX; break; } } } if ((Object)(object)placeSfx == (Object)null) { placeSfx = MachineSounds.Get("MoveShipObjectBig"); } if ((Object)(object)placeSfx == (Object)null) { PlaceableShipObject[] array2 = Object.FindObjectsOfType<PlaceableShipObject>(); foreach (PlaceableShipObject val3 in array2) { if ((Object)(object)val3 != (Object)null && (Object)(object)val3 != (Object)(object)placeable && (Object)(object)val3.placeObjectSFX != (Object)null) { placeSfx = val3.placeObjectSFX; break; } } } array = buttons; foreach (InteractTrigger val4 in array) { if ((Object)(object)val4 != (Object)null) { val4.hoverIcon = hoverIcon; } } if ((Object)(object)placeable != (Object)null) { placeable.placeObjectSFX = placeSfx; } } catch (Exception ex) { Plugin.Log.LogDebug((object)("Soda Machine: " + ex.Message)); } } internal static Status StatusOf(int button, PlayerControllerB me) { if ((Object)(object)me != (Object)null && MachineNet.LeftToday(me) > 0) { return Status.Free; } DrinkDef drinkDef = MachineNet.DefAt(button); Item val = MachineNet.ItemAt(button); if (drinkDef == null || (Object)(object)val == (Object)null || (Object)(object)val.spawnPrefab == (Object)null || !drinkDef.enabled()) { return Status.SoldOut; } if (!SodaConfig.Instance.MachineSells.Value) { return Status.NotSold; } if (MachineNet.StockLeft(button) <= 0) { return Status.OutOfStock; } Terminal term = MachineNet.Term; if (!((Object)(object)term != (Object)null) || term.groupCredits < MachineNet.PriceOf(drinkDef)) { return Status.NoMoney; } return Status.Buy; } private void Update() { PlayerControllerB me = Me; if (!((Object)(object)me == (Object)null)) { if (!Picked) { selected = -1; } Status st = (Picked ? StatusOf(selected, me) : Status.SoldOut); UpdateLamps(st); UpdateDisplay(me, st); if (Time.time >= nextTips) { nextTips = Time.time + 0.2f; UpdateTips(me); } } } private void UpdateLamps(Status st) { if (model == null || model.leds.Count == 0) { return; } bool flag = Mathf.Repeat(Time.time * 4f, 1f) < 0.55f; bool flag2 = st == Status.Free || st == Status.Buy; for (int i = 0; i < 10 && i < model.leds.Count; i++) { Material val = model.ledOff; if (i == litButton && Time.time < litUntil) { val = (litGreen ? model.ledOn : model.ledRed); } else if (i == selected && flag) { val = (flag2 ? model.ledOn : model.ledRed); } if ((Object)(object)val != (Object)null && (Object)(object)lampShown[i] != (Object)(object)val && (Object)(object)model.leds[i] != (Object)null) { model.leds[i].sharedMaterial = val; lampShown[i] = val; } } } private void UpdateDisplay(PlayerControllerB me, Status st) { //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) TextMeshPro val = ((model != null) ? model.display : null); if ((Object)(object)val == (Object)null) { return; } bool flag = false; string text; if (Busy) { text = "ENJOY!"; } else if (Picked) { DrinkDef drinkDef = MachineNet.DefAt(selected); string text2 = ((st == Status.Free) ? "RANDOM DRINK" : ((drinkDef != null) ? drinkDef.itemName.ToUpperInvariant() : "")); string text3; switch (st) { case Status.Free: text3 = "FREE"; break; case Status.Buy: text3 = "$" + MachineNet.PriceOf(drinkDef); break; case Status.NoMoney: text3 = "$" + MachineNet.PriceOf(drinkDef); flag = true; break; case Status.NotSold: text3 = "TOMORROW"; flag = true; break; default: text3 = "SOLD OUT"; flag = true; break; } text = "<size=45%>" + text2 + "</size>\n" + text3; } else { text = ((MachineNet.LeftToday(me) > 0) ? "FREE" : ""); } text += (flag ? "#r" : "#g"); if (!(text == shownText)) { shownText = text; ((Graphic)val).color = (flag ? DisplayRed : DisplayGreen); ((TMP_Text)val).text = text.Substring(0, text.Length - 2); } } private void UpdateTips(PlayerControllerB me) { for (int i = 0; i < 10; i++) { InteractTrigger val = buttons[i]; if ((Object)(object)val == (Object)null) { continue; } if (Busy) { val.interactable = false; val.disabledHoverTip = "Dispensing..."; continue; } val.interactable = true; DrinkDef drinkDef = MachineNet.DefAt(i); string text = ((drinkDef != null) ? drinkDef.itemName : "Soda"); Status status = StatusOf(i, me); int num = ((drinkDef != null) ? MachineNet.PriceOf(drinkDef) : 0); int num2 = MachineNet.StockLeft(i); string arg = ((num2 < 100 && SodaConfig.Instance.MachineShowStock.Value) ? $", {num2} left" : ""); if (i == selected) { switch (status) { case Status.Free: val.hoverTip = "Get your free random drink : [E]"; break; case Status.Buy: val.hoverTip = $"Buy {text} (${num}{arg}) : [E]"; break; case Status.NoMoney: val.hoverTip = $"{text} ${num}: not enough credits"; break; case Status.NotSold: val.hoverTip = "Free drink used: come back tomorrow"; break; case Status.OutOfStock: val.hoverTip = text + " is sold out for today"; break; default: val.hoverTip = text + " is turned off"; break; } } else { switch (status) { case Status.Free: val.hoverTip = "Free random drink : [E]"; break; case Status.Buy: case Status.NoMoney: val.hoverTip = $"{text} (${num}{arg}) : [E]"; break; case Status.NotSold: val.hoverTip = text + " (come back tomorrow) : [E]"; break; case Status.OutOfStock: val.hoverTip = text + " (sold out) : [E]"; break; default: val.hoverTip = text + " (turned off) : [E]"; break; } } } } private void OnButton(int index, PlayerControllerB player) { if ((Object)(object)player == (Object)null || (Object)(object)player != (Object)(object)Me || (Object)(object)netObj == (Object)null || !netObj.IsSpawned || Busy) { return; } if (index == selected && Picked) { Status status = StatusOf(index, player); if (status == Status.Free || status == Status.Buy) { selected = -1; MachineNet.SendUse(this, player, index, status == Status.Free); return; } selectedUntil = Time.time + 8f; Click(0.5f); Deny(); DrinkDef drinkDef = MachineNet.DefAt(index); string text = status switch { Status.OutOfStock => (drinkDef?.itemName ?? "That drink") + " is sold out for today. More tomorrow!", Status.NotSold => "You had your free drink today. Come back tomorrow!", Status.NoMoney => $"Not enough credits: {drinkDef?.itemName} costs ${MachineNet.PriceOf(drinkDef)}.", _ => (drinkDef?.itemName ?? "That drink") + " is turned off in the config.", }; HUDManager instance = HUDManager.Instance; if (instance != null) { instance.DisplayTip("Soda Machine", text, true, false, "LC_Tip1"); } nextTips = 0f; } else { selected = index; selectedUntil = Time.time + 8f; nextTips = 0f; Click(0.6f); } } private void Play(AudioClip clip, float volume, float pitch = 1f) { if (!((Object)(object)clip == (Object)null) && !((Object)(object)audioSource == (Object)null)) { if (Mathf.Approximately(pitch, 1f)) { audioSource.PlayOneShot(clip, volume); return; } AudioSource obj = Motor(); obj.pitch = pitch; obj.PlayOneShot(clip, volume); } } private AudioSource Motor() { if ((Object)(object)motor == (Object)null) { motor = ((Component)this).gameObject.AddComponent<AudioSource>(); SetupAudio(motor); if ((Object)(object)audioSource != (Object)null) { motor.outputAudioMixerGroup = audioSource.outputAudioMixerGroup; } } return motor; } private void Click(float volume) { Play(MachineSounds.Button(), volume); } private void Deny() { Play(MachineSounds.Deny(), 0.7f); } internal void PlayPress(int button, bool dispensing, bool paid) { busyUntil = (dispensing ? (Time.time + 3f) : 0f); litButton = button; litGreen = dispensing; litUntil = Time.time + (dispensing ? 1.6f : 0.8f); nextTips = 0f; try { Click(0.9f); if (!dispensing) { Deny(); return; } if (paid) { Play(MachineSounds.Get("PurchaseSFX"), 0.8f); } ((MonoBehaviour)this).StopCoroutine("Vend"); ((MonoBehaviour)this).StartCoroutine("Vend"); } catch (Exception ex) { Plugin.Log.LogDebug((object)("Soda Machine press: " + ex.Message)); } } private IEnumerator Vend() { yield return (object)new WaitForSeconds(0.1f); AudioSource m = Motor(); AudioClip val = MachineSounds.Get("MicrowaveWhir"); if ((Object)(object)val != (Object)null) { m.clip = val; m.pitch = 1.35f; m.volume = 0.55f; m.time = Mathf.Min(0.4f, val.length * 0.2f); m.Play(); } yield return (object)new WaitForSeconds(0.5f); Play(MachineSounds.Get("DropCan", "DropMetalObject3"), 0.9f); yield return (object)new WaitForSeconds(0.15f); if (m.isPlaying) { m.Stop(); } m.pitch = 1f; Play(MachineSounds.Get("MetalHatchOpen", "CupboardOpen"), 0.6f); yield return Swing(0f, 70f, 0.15f); yield return (object)new WaitForSeconds(1.05f); yield return Swing(70f, 0f, 0.3f); Play(MachineSounds.Get("ExtensionLadderLidOpen", "DoorClose", "CupboardOpen"), 0.6f, 1.1f); } private IEnumerator Swing(float from, float to, float time) { Transform hinge = ((model != null) ? model.flap : null); if (!((Object)(object)hinge == (Object)null)) { for (float t = 0f; t < time; t += Time.deltaTime) { float num = Mathf.SmoothStep(0f, 1f, t / time); hinge.localRotation = Quaternion.Euler(Mathf.Lerp(from, to, num), 0f, 0f); yield return null; } hinge.localRotation = Quaternion.Euler(to, 0f, 0f); } } internal void SetBusy(bool value) { busyUntil = (value ? (Time.time + 3f) : 0f); } internal void ServerDispense(Item item) { ((MonoBehaviour)this).StartCoroutine(DispenseLater(item)); } private IEnumerator DispenseLater(Item item) { busyUntil = Time.time + 3f; yield return (object)new WaitForSeconds(1f); try { StartOfRound instance = StartOfRound.Instance; Vector3 val = (((Object)(object)dispensePoint != (Object)null) ? dispensePoint.position : (((Component)this).transform.position + ((Component)this).transform.forward + Vector3.up * 0.4f)); GrabbableObject component = Object.Instantiate<GameObject>(item.spawnPrefab, val, Quaternion.identity, instance.elevatorTransform).GetComponent<GrabbableObject>(); component.fallTime = 0f; component.scrapValue = 0; component.isInElevator = true; component.isInShipRoom = true; ((NetworkBehaviour)component).NetworkObject.Spawn(false); MachineNet.SendDispensed(this, ((NetworkBehaviour)component).NetworkObjectId); } catch (Exception ex) { Plugin.Log.LogError((object)("Soda Machine: couldn't dispense " + item?.itemName + ": " + ex)); } busyUntil = 0f; } private IEnumerator PlaceIfNew() { yield return null; yield return null; StartOfRound instance = StartOfRound.Instance; if ((Object)(object)instance == (Object)null || (Object)(object)placeable == (Object)null || placeable.unlockableID < 0) { yield break; } UnlockableItem val = instance.unlockablesList.unlockables[placeable.unlockableID]; if (val.inStorage || (MachineNet.AutoPlacedBefore() && (val.hasBeenMoved || val.placedPosition != Vector3.zero))) { yield break; } if (MachinePlacement.TryFind(this, out var placement, out var yaw)) { Vector3 val2 = default(Vector3); ((Vector3)(ref val2))..ctor(0f, yaw, 0f); ShipBuildModeManager instance2 = ShipBuildModeManager.Instance; if ((Object)(object)instance2 != (Object)null) { instance2.PlaceShipObjectClientRpc(placement, val2, NetworkObjectReference.op_Implicit(netObj), -1); } MachineNet.MarkAutoPlaced(); Plugin.Log.LogInfo((object)$"Soda Machine placed at {placement} (facing {yaw:0})."); } else { Plugin.Log.LogInfo((object)"Soda Machine: no free spot found, it stays where it spawned (press B to move it)."); } } } internal static class MachinePlacement { private const int WallMask = 2305; private const int BlockMask = 134220033; private static readonly Vector2[] Spots = (Vector2[])(object)new Vector2[3] { new Vector2(3.3f, 1f), new Vector2(3.3f, -1f), new Vector2(-0.8f, 1f) }; private const float RoomMidZ = -6.67f; private const float ChestY = 1f; internal static bool TryFind(SodaMachine machine, out Vector3 placement, out float yaw) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Unknown result type (might be due to invalid IL or missing references) //IL_0097: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Unknown result type (might be due to invalid IL or missing references) //IL_00be: 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_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00dc: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_00ea: Unknown result type (might be due to invalid IL or missing references) //IL_00ed: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_0103: Unknown result type (might be due to invalid IL or missing references) //IL_0114: Unknown result type (might be due to invalid IL or missing references) //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_011e: Unknown result type (might be due to invalid IL or missing references) //IL_012f: Unknown result type (might be due to invalid IL or missing references) //IL_0140: Unknown result type (might be due to invalid IL or missing references) //IL_0382: Unknown result type (might be due to invalid IL or missing references) //IL_0384: Unknown result type (might be due to invalid IL or missing references) //IL_020d: Unknown result type (might be due to invalid IL or missing references) //IL_01f4: Unknown result type (might be due to invalid IL or missing references) //IL_0183: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Unknown result type (might be due to invalid IL or missing references) //IL_0189: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) //IL_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a4: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Unknown result type (might be due to invalid IL or missing references) //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0236: Unknown result type (might be due to invalid IL or missing references) //IL_0244: Unknown result type (might be due to invalid IL or missing references) //IL_0249: Unknown result type (might be due to invalid IL or missing references) //IL_024e: Unknown result type (might be due to invalid IL or missing references) //IL_0258: Unknown result type (might be due to invalid IL or missing references) //IL_025d: Unknown result type (might be due to invalid IL or missing references) //IL_0262: Unknown result type (might be due to invalid IL or missing references) //IL_0280: Unknown result type (might be due to invalid IL or missing references) //IL_0285: Unknown result type (might be due to invalid IL or missing references) //IL_028a: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) //IL_02a2: Unknown result type (might be due to invalid IL or missing references) //IL_02a7: Unknown result type (might be due to invalid IL or missing references) //IL_02a9: Unknown result type (might be due to invalid IL or missing references) //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b0: Unknown result type (might be due to invalid IL or missing references) //IL_02b5: Unknown result type (might be due to invalid IL or missing references) //IL_02ba: Unknown result type (might be due to invalid IL or missing references) //IL_02be: Unknown result type (might be due to invalid IL or missing references) //IL_02d9: Unknown result type (might be due to invalid IL or missing references) //IL_02db: Unknown result type (might be due to invalid IL or missing references) //IL_02e2: Unknown result type (might be due to invalid IL or missing references) //IL_02ec: Unknown result type (might be due to invalid IL or missing references) //IL_02fd: Unknown result type (might be due to invalid IL or missing references) //IL_02d1: Unknown result type (might be due to invalid IL or missing references) //IL_02d3: Unknown result type (might be due to invalid IL or missing references) //IL_032d: Unknown result type (might be due to invalid IL or missing references) //IL_032f: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034a: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Unknown result type (might be due to invalid IL or missing references) placement = default(Vector3); yaw = 0f; StartOfRound instance = StartOfRound.Instance; Transform val = (((Object)(object)instance != (Object)null) ? instance.elevatorTransform : null); if ((Object)(object)val == (Object)null) { return false; } List<Collider> list = machine.OwnColliders.Where((Collider c) => c.enabled).ToList(); foreach (Collider item in list) { item.enabled = false; } try { Vector3 size = MachineModel.Size; bool flag = false; Vector3 val2 = default(Vector3); float num = 0f; Vector2[] spots = Spots; RaycastHit val6 = default(RaycastHit); RaycastHit val7 = default(RaycastHit); foreach (Vector2 val3 in spots) { Vector3 val4 = val.TransformDirection(new Vector3(0f, 0f, val3.y)); Vector3 normalized = ((Vector3)(ref val4)).normalized; val4 = val.TransformDirection(Vector3.right); Vector3 normalized2 = ((Vector3)(ref val4)).normalized; Vector3 val5 = val.TransformPoint(new Vector3(val3.x, 1f, -6.67f)); float num3 = float.MaxValue; float[] array = new float[3] { (0f - size.x) * 0.5f, 0f, size.x * 0.5f }; foreach (float num5 in array) { float[] array2 = new float[2] { -0.5f, 0.6f }; foreach (float num7 in array2) { if (Physics.Raycast(val5 + normalized2 * num5 + Vector3.up * num7, normalized, ref val6, 6f, 2305, (QueryTriggerInteraction)1)) { num3 = Mathf.Min(num3, ((RaycastHit)(ref val6)).distance); } } } if (num3 == float.MaxValue || num3 < size.z + 0.6f) { Plugin.Log.LogInfo((object)$"Soda Machine: spot {val3} has no room (wall at {num3:0.00} m)."); } else if (Physics.Raycast(val5 + normalized * (num3 - 0.04f - size.z * 0.5f) + Vector3.up * 0.5f, Vector3.down, ref val7, 3f, 2305, (QueryTriggerInteraction)1)) { Vector3 val8 = ((RaycastHit)(ref val7)).point + Vector3.up * (size.y * 0.5f + 0.02f); Quaternion val9 = Quaternion.LookRotation(-normalized, Vector3.up); float y = ((Quaternion)(ref val9)).eulerAngles.y; if (!flag) { flag = true; val2 = val8; num = y; } if (!Physics.CheckBox(val8, size * 0.5f * 0.9f, Quaternion.Euler(0f, y, 0f), 134220033, (QueryTriggerInteraction)1)) { placement = val8; yaw = y; Plugin.Log.LogInfo((object)$"Soda Machine: spot {val3} (ship {val.InverseTransformPoint(val8)}), wall {num3:0.00} m away."); return true; } Plugin.Log.LogInfo((object)$"Soda Machine: spot {val3} is taken."); } } if (flag) { placement = val2; yaw = num; Plugin.Log.LogInfo((object)"Soda Machine: every spot looked taken, using the first one."); return true; } return false; } finally { foreach (Collider item2 in list) { if ((Object)(object)item2 != (Object)null) { item2.enabled = true; } } } } } internal static class MachineNet { internal enum Result { Free, Bought, NoMoney, NoFree, SoldOut, NotSold, OutOfStock } [CompilerGenerated] private static class <>O { public static HandleNamedMessageDelegate <0>__OnUse; public static HandleNamedMessageDelegate <1>__OnPress; public static HandleNamedMessageDelegate <2>__OnItem; public static HandleNamedMessageDelegate <3>__OnClaims; public static HandleNamedMessageDelegate <4>__OnClaimRequest; } private const string UseMsg = "Miles.DrinkableSoda.MachineUse"; private const string PressMsg = "Miles.DrinkableSoda.MachinePress"; private const string ItemMsg = "Miles.DrinkableSoda.MachineItem"; private const string ClaimsMsg = "Miles.DrinkableSoda.MachineClaims"; private const string ClaimReqMsg = "Miles.DrinkableSoda.MachineClaimReq"; private const string SaveKey = "Miles.DrinkableSoda.MachineClaims"; private static NetworkManager registeredOn; private static readonly Dictionary<string, int> claims = new Dictionary<string, int>(); private static int claimsDay = -1; private static string claimsFile; private static int stockDay = -2; private const string StockKey = "Miles.DrinkableSoda.MachineStock"; private static readonly int[] stock = new int[10]; private static bool stockReady; private const string PlacedKey = "Miles.DrinkableSoda.MachinePlaced"; private const int PlacedVersion = 2; private static readonly DrinkId[] ButtonOrder = new DrinkId[10] { DrinkId.RedSoda, DrinkId.Web, DrinkId.Alt, DrinkId.Jim, DrinkId.Sakura, DrinkId.Vanilla, DrinkId.Cheese, DrinkId.Morv, DrinkId.Harvest, DrinkId.Generic }; private static Terminal term; private static NetworkManager NM => NetworkManager.Singleton; internal static bool Limited { get { if (SodaConfig.Instance != null) { return SodaConfig.Instance.MachineStock.Value; } return false; } } internal static Terminal Term { get { if ((Object)(object)term == (Object)null) { term = (((Object)(object)Shop.Current != (Object)null) ? Shop.Current : Object.FindObjectOfType<Terminal>()); } return term; } } internal static int StockLeft(int button) { if (!Limited) { return int.MaxValue; } if ((Object)(object)NM != (Object)null && NM.IsServer) { EnsureDay(); } if (button < 0 || button >= stock.Length) { return 0; } return stock[button]; } private static int SpecialStock(int max, float odds) { max = Mathf.Max(0, max); odds = Mathf.Clamp(odds, 0.01f, 1f); float num = 0f; float num2 = 1f; int num3 = 0; while (num3 <= max) { num += num2; num3++; num2 *= odds; } float num4 = Random.value * num; num2 = 1f; int num5 = 0; while (num5 <= max) { num4 -= num2; if (num4 <= 0f) { return num5; } num5++; num2 *= odds; } return max; } private static void Restock() { SodaConfig instance = SodaConfig.Instance; int num = Mathf.Max(0, Mathf.Min(instance.MachineStockMin.Value, instance.MachineStockMax.Value)); int num2 = Mathf.Max(num, Mathf.Max(instance.MachineStockMin.Value, instance.MachineStockMax.Value)); for (int i = 0; i < stock.Length; i++) { DrinkDef drinkDef = DefAt(i); if (drinkDef != null && drinkDef.special) { stock[i] = SpecialStock(instance.MachineRareStock.Value, instance.MachineRareChance.Value); } else { stock[i] = Random.Range(num, num2 + 1); } } stockReady = true; Plugin.Log.LogInfo((object)("Soda Machine restocked: " + string.Join(", ", stock))); } internal unsafe static void Register() { //IL_005e: 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_0069: Expected O, but got Unknown //IL_0084: Unknown result type (might be due to invalid IL or missing references) //IL_0089: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Expected O, but got Unknown //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_00b5: Expected O, but got Unknown //IL_00d0: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: Unknown result type (might be due to invalid IL or missing references) //IL_00db: Expected O, but got Unknown //IL_00f6: Unknown result type (might be due to invalid IL or missing references) //IL_00fb: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Expected O, but got Unknown //IL_0120: Unknown result type (might be due to invalid IL or missing references) NetworkManager nM = NM; if ((Object)(object)nM == (Object)null || nM.CustomMessagingManager == null || (Object)(object)registeredOn == (Object)(object)nM) { return; } registeredOn = nM; claims.Clear(); claimsDay = -1; claimsFile = null; CustomMessagingManager customMessagingManager = nM.CustomMessagingManager; object obj = <>O.<0>__OnUse; if (obj == null) { HandleNamedMessageDelegate val = OnUse; <>O.<0>__OnUse = val; obj = (object)val; } customMessagingManager.RegisterNamedMessageHandler("Miles.DrinkableSoda.MachineUse", (HandleNamedMessageDelegate)obj); object obj2 = <>O.<1>__OnPress; if (obj2 == null) { HandleNamedMessageDelegate val2 = OnPress; <>O.<1>__OnPress = val2; obj2 = (object)val2; } customMessagingManager.RegisterNamedMessageHandler("Miles.DrinkableSoda.MachinePress", (HandleNamedMessageDelegate)obj2); object obj3 = <>O.<2>__OnItem; if (obj3 == null) { HandleNamedMessageDelegate val3 = OnItem; <>O.<2>__OnItem = val3; obj3 = (object)val3; } customMessagingManager.RegisterNamedMessageHandler("Miles.DrinkableSoda.MachineItem", (HandleNamedMessageDelegate)obj3); object obj4 = <>O.<3>__OnClaims; if (obj4 == null) { HandleNamedMessageDelegate val4 = OnClaims; <>O.<3>__OnClaims = val4; obj4 = (object)val4; } customMessagingManager.RegisterNamedMessageHandler("Miles.DrinkableSoda.MachineClaims", (HandleNamedMessageDelegate)obj4); object obj5 = <>O.<4>__OnClaimRequest; if (obj5 == null) { HandleNamedMessageDelegate val5 = OnClaimRequest; <>O.<4>__OnClaimRequest = val5; obj5 = (object)val5; } customMessagingManager.RegisterNamedMessageHandler("Miles.DrinkableSoda.MachineClaimReq", (HandleNamedMessageDelegate)obj5); if (nM.IsServer)