using System;
using System.Collections;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using BepInEx;
using BepInEx.Configuration;
using BepInEx.Logging;
using ExitGames.Client.Photon;
using HarmonyLib;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)]
[assembly: IgnoresAccessChecksTo("Assembly-CSharp")]
[assembly: AssemblyTitle("Vasodilation")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Vasodilation")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("15fa7750-965f-4249-837f-3d54157b5401")]
[assembly: AssemblyFileVersion("2.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("2.0.0.0")]
[module: UnverifiableCode]
namespace System.Runtime.CompilerServices
{
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
internal sealed class IgnoresAccessChecksToAttribute : Attribute
{
public IgnoresAccessChecksToAttribute(string assemblyName)
{
}
}
}
namespace VasodilationMod
{
internal enum WarmthSource
{
None,
Sprint,
Jump,
SprintJump,
ClimbJump,
WallClimb,
RopeClimb,
VineClimb
}
[BepInPlugin("tony4twentys.Vasodilation", "Vasodilation", "2.0.0")]
[BepInProcess("PEAK.exe")]
public class VasodilationPlugin : BaseUnityPlugin
{
public const string PluginGuid = "tony4twentys.Vasodilation";
public const string PluginName = "Vasodilation";
public const string PluginVersion = "2.0.0";
internal const byte EventCode = 162;
internal const int ProtocolVersion = 3;
internal const string EventMagic = "tony4twentys.Vasodilation";
internal const int ConfigPayloadLength = 13;
internal static ConfigEntry<float> SprintRatio;
internal static ConfigEntry<float> JumpRatio;
internal static ConfigEntry<float> SprintJumpRatio;
internal static ConfigEntry<float> ClimbJumpRatio;
internal static ConfigEntry<float> WallClimbRatio;
internal static ConfigEntry<float> RopeClimbRatio;
internal static ConfigEntry<float> VineClimbRatio;
internal static ConfigEntry<float> EmoteColdPerSecond;
internal static ConfigEntry<float> GateOn;
internal static ConfigEntry<float> GateOff;
internal static ConfigEntry<bool> VerboseLogs;
internal static float syncedSprintRatio = 0.5f;
internal static float syncedJumpRatio = 0.25f;
internal static float syncedSprintJumpRatio = 0.25f;
internal static float syncedClimbJumpRatio = 0.25f;
internal static float syncedWallClimbRatio = 0.5f;
internal static float syncedRopeClimbRatio = 1f;
internal static float syncedVineClimbRatio = 0.75f;
internal static float syncedEmoteColdPerSecond = 0.01f;
internal static float syncedGateOn = 0.025f;
internal static float syncedGateOff = 0f;
internal static bool isHandshakeValid = true;
private Harmony _harmony;
private bool _warmingActive;
private bool _loggedTickError;
private bool _loggedStaminaError;
private float _nextEmoteLog;
private static readonly float[] NextSourceLog = new float[8];
private static float _alpineCachedAt = -999f;
private static bool _alpineCached;
internal static VasodilationPlugin Instance { get; private set; }
internal static ManualLogSource Log { get; private set; }
internal static bool IsGameplayEnabled
{
get
{
try
{
if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
{
return true;
}
}
catch
{
return isHandshakeValid;
}
return isHandshakeValid;
}
}
internal static bool DebugLogs
{
get
{
if (VerboseLogs != null)
{
return VerboseLogs.Value;
}
return false;
}
}
private void Awake()
{
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
BindConfig();
ApplyLocalConfig();
if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
{
isHandshakeValid = true;
}
_harmony = new Harmony("tony4twentys.Vasodilation");
PatchAllSafe();
VasoNet.Ensure();
((BaseUnityPlugin)this).Config.SettingChanged += OnSettingChanged;
Log.LogInfo((object)string.Format("{0} v{1} loaded. Photon {2}.", "Vasodilation", "2.0.0", (byte)162));
}
private void Update()
{
try
{
TickEmoteWarmth(Time.deltaTime);
}
catch (Exception ex)
{
LogOnce(ref _loggedTickError, "[Vasodilation] Emote warmth tick failed.", ex);
}
}
private void BindConfig()
{
if ((0u | (DropOldConfig("General", "ColdPerSecond") ? 1u : 0u) | (DropOldConfig("General", "TickSeconds") ? 1u : 0u) | (DropOldConfig("General", "StaminaToColdRatio") ? 1u : 0u) | (DropOldConfig("General", "EmoteColdPerSecond") ? 1u : 0u)) != 0)
{
((BaseUnityPlugin)this).Config.Save();
}
SprintRatio = BindWarmthRatio("Sprint", 0.5f, "Grounded sprint.");
JumpRatio = BindWarmthRatio("Jump", 0.25f, "Standing jump.");
SprintJumpRatio = BindWarmthRatio("SprintJump", 0.25f, "Jump while sprinting.");
ClimbJumpRatio = BindWarmthRatio("ClimbJump", 0.25f, "Wall sprint-boost. Alpine walls are ignored.");
WallClimbRatio = BindWarmthRatio("WallClimb", 0.5f, "Wall hang, move, or re-grab. Alpine walls are ignored.");
RopeClimbRatio = BindWarmthRatio("RopeClimb", 1f, "Climbing up a rope. Hang and climb-down are ignored.");
VineClimbRatio = BindWarmthRatio("VineClimb", 0.75f, "Climbing a vine. Hang, slide, and grab are ignored.");
EmoteColdPerSecond = ((BaseUnityPlugin)this).Config.Bind<float>("Warmth", "EmoteColdPerSecond", 0.01f, "Host only. Cold removed per second during Dance, Crashout, Shimmy, Backflip, Wave, or Bully. Emotes do not use stamina. Host value is synced to the room.");
GateOn = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ColdGateOn", 0.025f, "Host only. Start warming once Cold is above this. Host value is synced to the room.");
GateOff = ((BaseUnityPlugin)this).Config.Bind<float>("General", "ColdGateOff", 0f, "Host only. Stop warming once Cold is at or below this. Host value is synced to the room.");
VerboseLogs = ((BaseUnityPlugin)this).Config.Bind<bool>("Debug", "VerboseLogs", false, "Local only. Log warmth about once per second per move. Not host-synced.");
}
private ConfigEntry<float> BindWarmthRatio(string key, float defaultValue, string what)
{
return ((BaseUnityPlugin)this).Config.Bind<float>("Warmth", key, defaultValue, "Host only. Cold removed per stamina spent: " + what + " 0.5 = half, 1 = 1:1. Host value is synced to the room.");
}
private bool DropOldConfig(string section, string key)
{
//IL_0002: Unknown result type (might be due to invalid IL or missing references)
//IL_0008: Expected O, but got Unknown
ConfigDefinition val = new ConfigDefinition(section, key);
if (!((BaseUnityPlugin)this).Config.ContainsKey(val))
{
return false;
}
((BaseUnityPlugin)this).Config.Remove(val);
return true;
}
private void OnSettingChanged(object sender, SettingChangedEventArgs args)
{
if (args == null || (object)args.ChangedSetting != VerboseLogs)
{
VasoNet.OnLocalSettingChanged();
}
}
internal static void ApplyLocalConfig()
{
ApplySyncedValues(GateOn.Value, GateOff.Value, EmoteColdPerSecond.Value, SprintRatio.Value, JumpRatio.Value, SprintJumpRatio.Value, ClimbJumpRatio.Value, WallClimbRatio.Value, RopeClimbRatio.Value, VineClimbRatio.Value);
}
internal static object[] BuildConfigPayload(byte sub)
{
return new object[13]
{
"tony4twentys.Vasodilation", 3, sub, GateOn.Value, GateOff.Value, EmoteColdPerSecond.Value, SprintRatio.Value, JumpRatio.Value, SprintJumpRatio.Value, ClimbJumpRatio.Value,
WallClimbRatio.Value, RopeClimbRatio.Value, VineClimbRatio.Value
};
}
internal static void ApplyRemoteConfig(object[] arr)
{
if (arr == null || arr.Length < 13)
{
throw new InvalidOperationException("Vasodilation config payload too short.");
}
ApplySyncedValues(Convert.ToSingle(arr[3]), Convert.ToSingle(arr[4]), Convert.ToSingle(arr[5]), Convert.ToSingle(arr[6]), Convert.ToSingle(arr[7]), Convert.ToSingle(arr[8]), Convert.ToSingle(arr[9]), Convert.ToSingle(arr[10]), Convert.ToSingle(arr[11]), Convert.ToSingle(arr[12]));
}
private static void ApplySyncedValues(float gateOn, float gateOff, float emote, float sprint, float jump, float sprintJump, float climbJump, float wall, float rope, float vine)
{
syncedGateOn = Mathf.Max(0f, gateOn);
syncedGateOff = Mathf.Max(0f, gateOff);
syncedEmoteColdPerSecond = Mathf.Max(0f, emote);
syncedSprintRatio = Mathf.Max(0f, sprint);
syncedJumpRatio = Mathf.Max(0f, jump);
syncedSprintJumpRatio = Mathf.Max(0f, sprintJump);
syncedClimbJumpRatio = Mathf.Max(0f, climbJump);
syncedWallClimbRatio = Mathf.Max(0f, wall);
syncedRopeClimbRatio = Mathf.Max(0f, rope);
syncedVineClimbRatio = Mathf.Max(0f, vine);
if (syncedGateOff > syncedGateOn)
{
syncedGateOff = syncedGateOn;
}
}
internal static void DebugLog(string message)
{
if (DebugLogs)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)message);
}
}
}
internal static void LogOnce(ref bool flag, string message, Exception ex)
{
if (flag)
{
return;
}
flag = true;
if (ex != null)
{
ManualLogSource log = Log;
if (log != null)
{
log.LogError((object)(message + " " + ex));
}
}
else
{
ManualLogSource log2 = Log;
if (log2 != null)
{
log2.LogError((object)message);
}
}
}
internal static void OnStaminaSpent(Character character, float spent)
{
VasodilationPlugin instance = Instance;
if ((Object)(object)instance == (Object)null)
{
return;
}
try
{
instance.TryWarmFromStamina(character, spent);
}
catch (Exception ex)
{
LogOnce(ref instance._loggedStaminaError, "[Vasodilation] Stamina warmth failed.", ex);
}
}
private void TryWarmFromStamina(Character character, float spent)
{
if (spent <= 1E-05f || !IsGameplayEnabled || !CanWarm(character))
{
return;
}
WarmthSource warmthSource = GetWarmthSource(character);
if (warmthSource != WarmthSource.None && UpdateWarmingGate(character))
{
float num = spent * GetSyncedRatio(warmthSource);
if (!(num <= 0f))
{
character.refs.afflictions.SubtractStatus((STATUSTYPE)2, num, false, false);
MaybeLogWarmth(warmthSource, spent, num);
}
}
}
private void TickEmoteWarmth(float deltaTime)
{
if (deltaTime <= 0f || syncedEmoteColdPerSecond <= 0f || !IsGameplayEnabled)
{
return;
}
Character localCharacter = Character.localCharacter;
if (!EmoteWarmth.IsWarming(localCharacter) || !CanWarm(localCharacter) || !UpdateWarmingGate(localCharacter))
{
return;
}
float num = syncedEmoteColdPerSecond * deltaTime;
if (!(num <= 0f))
{
localCharacter.refs.afflictions.SubtractStatus((STATUSTYPE)2, num, false, false);
if (DebugLogs && Time.unscaledTime >= _nextEmoteLog)
{
_nextEmoteLog = Time.unscaledTime + 1f;
DebugLog("[Vasodilation] emote coldDelta=" + num.ToString("0.####"));
}
}
}
private bool CanWarm(Character character)
{
if ((Object)(object)character == (Object)null || !character.IsLocal)
{
return false;
}
if ((Object)(object)character.data == (Object)null || character.refs == null || (Object)(object)character.refs.afflictions == (Object)null)
{
return false;
}
if (character.data.dead)
{
return false;
}
return true;
}
private bool UpdateWarmingGate(Character character)
{
float currentStatus = character.refs.afflictions.GetCurrentStatus((STATUSTYPE)2);
if (currentStatus <= syncedGateOff)
{
_warmingActive = false;
}
else if (currentStatus > syncedGateOn)
{
_warmingActive = true;
}
return _warmingActive;
}
internal static WarmthSource GetWarmthSource(Character character)
{
if ((Object)(object)character == (Object)null || (Object)(object)character.data == (Object)null)
{
return WarmthSource.None;
}
CharacterData data = character.data;
if (WarmthSpendMark.Ignore)
{
return WarmthSource.None;
}
if (WarmthSpendMark.ClimbJump)
{
if (!IsAlpine())
{
return WarmthSource.ClimbJump;
}
return WarmthSource.None;
}
if (data.isJumping)
{
if (!data.isSprinting)
{
return WarmthSource.Jump;
}
return WarmthSource.SprintJump;
}
if (data.isRopeClimbing)
{
if (!IsClimbingRopeUp(character))
{
return WarmthSource.None;
}
return WarmthSource.RopeClimb;
}
if (data.isVineClimbing)
{
if (!IsClimbingVine(character))
{
return WarmthSource.None;
}
return WarmthSource.VineClimb;
}
if (data.isClimbing)
{
if (!IsAlpine())
{
return WarmthSource.WallClimb;
}
return WarmthSource.None;
}
if (data.isSprinting)
{
return WarmthSource.Sprint;
}
return WarmthSource.None;
}
internal static float GetSyncedRatio(WarmthSource source)
{
return source switch
{
WarmthSource.Sprint => syncedSprintRatio,
WarmthSource.Jump => syncedJumpRatio,
WarmthSource.SprintJump => syncedSprintJumpRatio,
WarmthSource.ClimbJump => syncedClimbJumpRatio,
WarmthSource.WallClimb => syncedWallClimbRatio,
WarmthSource.RopeClimb => syncedRopeClimbRatio,
WarmthSource.VineClimb => syncedVineClimbRatio,
_ => 0f,
};
}
private static bool IsClimbingRopeUp(Character character)
{
if ((Object)(object)character == (Object)null || (Object)(object)character.input == (Object)null)
{
return false;
}
return character.input.movementInput.y > 0.01f;
}
private static bool IsClimbingVine(Character character)
{
if ((Object)(object)character == (Object)null || (Object)(object)character.input == (Object)null)
{
return false;
}
if (character.refs != null && (Object)(object)character.refs.vineClimbing != (Object)null && character.refs.vineClimbing.Sliding())
{
return false;
}
return Mathf.Abs(character.input.movementInput.y) >= 0.01f;
}
private void MaybeLogWarmth(WarmthSource source, float spent, float amount)
{
if (!DebugLogs)
{
return;
}
if (source >= WarmthSource.None && (int)source < NextSourceLog.Length)
{
float unscaledTime = Time.unscaledTime;
if (!(spent < 0.02f) || !(unscaledTime < NextSourceLog[(int)source]))
{
NextSourceLog[(int)source] = unscaledTime + 1f;
DebugLog($"[Vasodilation] stam={spent:0.####} coldDelta={amount:0.####} source={source}");
}
}
}
internal static bool IsAlpine()
{
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Invalid comparison between Unknown and I4
float unscaledTime = Time.unscaledTime;
if (unscaledTime - _alpineCachedAt < 0.5f)
{
return _alpineCached;
}
_alpineCachedAt = unscaledTime;
try
{
MapHandler instance = Singleton<MapHandler>.Instance;
_alpineCached = (Object)(object)instance != (Object)null && (int)instance.GetCurrentBiome() == 2;
}
catch
{
_alpineCached = false;
}
return _alpineCached;
}
private void PatchAllSafe()
{
Type[] types = typeof(VasodilationPlugin).Assembly.GetTypes();
foreach (Type type in types)
{
if (!(type == null) && type.GetCustomAttributes(typeof(HarmonyPatch), inherit: false).Length != 0)
{
try
{
_harmony.CreateClassProcessor(type).Patch();
}
catch (Exception ex)
{
Log.LogError((object)("[Vasodilation] Patch failed on " + type.Name + ": " + ex.Message));
}
}
}
}
}
internal sealed class VasoNet : MonoBehaviourPunCallbacks, IOnEventCallback
{
private const byte SubConfig = 1;
private const byte SubConfigRequest = 2;
private const float HostSyncTimeoutSeconds = 12f;
private const float HostSyncRetrySeconds = 2f;
internal static bool HostModConfirmed;
private Coroutine _debounce;
private Coroutine _hostSyncWatch;
private bool _syncingFromNet;
internal static VasoNet Instance { get; private set; }
internal static void Ensure()
{
//IL_0013: Unknown result type (might be due to invalid IL or missing references)
//IL_0018: Unknown result type (might be due to invalid IL or missing references)
//IL_001e: Expected O, but got Unknown
if ((Object)(object)Instance != (Object)null)
{
return;
}
GameObject val = new GameObject("Vasodilation_Net");
Object.DontDestroyOnLoad((Object)val);
Instance = val.AddComponent<VasoNet>();
try
{
if (PhotonNetwork.InRoom)
{
Instance.HandleJoinedRoom();
}
}
catch
{
}
}
private void Awake()
{
Instance = this;
}
public override void OnEnable()
{
((MonoBehaviourPunCallbacks)this).OnEnable();
PhotonNetwork.AddCallbackTarget((object)this);
}
public override void OnDisable()
{
PhotonNetwork.RemoveCallbackTarget((object)this);
((MonoBehaviourPunCallbacks)this).OnDisable();
}
public override void OnJoinedRoom()
{
HandleJoinedRoom();
}
public override void OnLeftRoom()
{
StopHostSyncWatch();
HostModConfirmed = false;
VasodilationPlugin.isHandshakeValid = true;
VasodilationPlugin.ApplyLocalConfig();
}
public override void OnMasterClientSwitched(Player newMasterClient)
{
if (PhotonNetwork.IsMasterClient)
{
HostModConfirmed = true;
VasodilationPlugin.isHandshakeValid = true;
VasodilationPlugin.ApplyLocalConfig();
BroadcastNow();
StopHostSyncWatch();
}
else
{
HostModConfirmed = false;
VasodilationPlugin.isHandshakeValid = false;
RequestHostSync();
RestartHostSyncWatch();
}
}
public override void OnPlayerEnteredRoom(Player newPlayer)
{
if (PhotonNetwork.IsMasterClient)
{
((MonoBehaviour)this).StartCoroutine(BroadcastAfterDelay(0.5f));
}
}
public void OnEvent(EventData photonEvent)
{
if (photonEvent == null || photonEvent.Code != 162 || !(photonEvent.CustomData is object[] array) || array.Length < 3 || !(array[0] is string text) || text != "tony4twentys.Vasodilation" || ToInt(array[1]) != 3)
{
return;
}
byte b = ToByte(array[2]);
if (b == 2 && PhotonNetwork.IsMasterClient)
{
BroadcastNow();
}
else
{
if (b != 1 || PhotonNetwork.IsMasterClient)
{
return;
}
try
{
_syncingFromNet = true;
VasodilationPlugin.ApplyRemoteConfig(array);
StopHostSyncWatch();
HostModConfirmed = true;
VasodilationPlugin.isHandshakeValid = true;
VasodilationPlugin.Log.LogInfo((object)"[Vasodilation] Host config sync applied.");
}
catch (Exception ex)
{
VasodilationPlugin.Log.LogError((object)("[Vasodilation] Config sync failed: " + ex.Message));
}
finally
{
_syncingFromNet = false;
}
}
}
internal static void OnLocalSettingChanged()
{
if (!((Object)(object)Instance != (Object)null) || !Instance._syncingFromNet)
{
if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient)
{
VasodilationPlugin.ApplyLocalConfig();
}
ScheduleBroadcast();
}
}
internal static void ScheduleBroadcast()
{
if (!((Object)(object)Instance == (Object)null) && PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
{
if (Instance._debounce != null)
{
((MonoBehaviour)Instance).StopCoroutine(Instance._debounce);
}
Instance._debounce = ((MonoBehaviour)Instance).StartCoroutine(Instance.DebounceBroadcast());
}
}
private void HandleJoinedRoom()
{
if (PhotonNetwork.IsMasterClient)
{
HostModConfirmed = true;
VasodilationPlugin.isHandshakeValid = true;
VasodilationPlugin.ApplyLocalConfig();
BroadcastNow();
StopHostSyncWatch();
}
else
{
HostModConfirmed = false;
VasodilationPlugin.isHandshakeValid = false;
RequestHostSync();
RestartHostSyncWatch();
}
}
private static void RequestHostSync()
{
//IL_0034: Unknown result type (might be due to invalid IL or missing references)
//IL_0039: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Unknown result type (might be due to invalid IL or missing references)
//IL_0040: Unknown result type (might be due to invalid IL or missing references)
//IL_004a: Expected O, but got Unknown
if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
{
PhotonNetwork.RaiseEvent((byte)162, (object)new object[3]
{
"tony4twentys.Vasodilation",
3,
(byte)2
}, new RaiseEventOptions
{
Receivers = (ReceiverGroup)2
}, SendOptions.SendReliable);
}
}
private void RestartHostSyncWatch()
{
StopHostSyncWatch();
if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient)
{
_hostSyncWatch = ((MonoBehaviour)this).StartCoroutine(WatchForHostSync());
}
}
private void StopHostSyncWatch()
{
if (_hostSyncWatch != null)
{
((MonoBehaviour)this).StopCoroutine(_hostSyncWatch);
_hostSyncWatch = null;
}
}
private IEnumerator WatchForHostSync()
{
float elapsed = 0f;
float nextRetry = 2f;
while (elapsed < 12f)
{
if (!PhotonNetwork.InRoom || PhotonNetwork.IsMasterClient || HostModConfirmed)
{
yield break;
}
elapsed += Time.unscaledDeltaTime;
if (elapsed >= nextRetry)
{
RequestHostSync();
nextRetry += 2f;
}
yield return null;
}
if (PhotonNetwork.InRoom && !PhotonNetwork.IsMasterClient && !HostModConfirmed)
{
VasodilationPlugin.isHandshakeValid = false;
VasodilationPlugin.Log.LogWarning((object)"[Vasodilation] Host does not appear to have Vasodilation — warmth disabled.");
}
_hostSyncWatch = null;
}
private IEnumerator DebounceBroadcast()
{
yield return (object)new WaitForSeconds(0.25f);
BroadcastNow();
_debounce = null;
}
private IEnumerator BroadcastAfterDelay(float seconds)
{
yield return (object)new WaitForSeconds(seconds);
BroadcastNow();
}
private static void BroadcastNow()
{
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Unknown result type (might be due to invalid IL or missing references)
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
if (PhotonNetwork.InRoom && PhotonNetwork.IsMasterClient)
{
PhotonNetwork.RaiseEvent((byte)162, (object)VasodilationPlugin.BuildConfigPayload(1), new RaiseEventOptions
{
Receivers = (ReceiverGroup)0
}, SendOptions.SendReliable);
}
}
private static int ToInt(object value)
{
return Convert.ToInt32(value);
}
private static byte ToByte(object value)
{
return Convert.ToByte(value);
}
}
internal static class EmoteWarmth
{
internal static bool LastIsWarming;
private static readonly string[] WarmTokens = new string[6] { "dance", "crashout", "shimmy", "backflip", "wave", "bully" };
internal static bool IsWarmingName(string emoteName)
{
if (string.IsNullOrEmpty(emoteName))
{
return false;
}
string text = emoteName.ToLowerInvariant();
for (int i = 0; i < WarmTokens.Length; i++)
{
if (text.IndexOf(WarmTokens[i], StringComparison.Ordinal) >= 0)
{
return true;
}
}
return false;
}
internal static bool IsWarming(Character character)
{
if (!LastIsWarming)
{
return false;
}
if ((Object)(object)character == (Object)null || character.refs == null || (Object)(object)character.refs.animations == (Object)null)
{
return false;
}
return character.refs.animations.emoting;
}
internal static void Remember(CharacterAnimations animations, string emoteName)
{
if (!((Object)(object)animations == (Object)null) && !string.IsNullOrEmpty(emoteName))
{
Character character = animations.character;
if (!((Object)(object)character == (Object)null) && character.IsLocal)
{
LastIsWarming = IsWarmingName(emoteName);
}
}
}
}
internal static class WarmthSpendMark
{
internal static bool Ignore;
internal static bool ClimbJump;
}
[HarmonyPatch(typeof(CharacterVineClimbing), "GrabVineRpc")]
internal static class VineGrabSkipPatch
{
private static void Prefix()
{
WarmthSpendMark.Ignore = true;
}
private static Exception Finalizer(Exception __exception)
{
WarmthSpendMark.Ignore = false;
return __exception;
}
}
[HarmonyPatch(typeof(CharacterGrabbing), "KickCast")]
internal static class KickSkipPatch
{
private static void Prefix()
{
WarmthSpendMark.Ignore = true;
}
private static Exception Finalizer(Exception __exception)
{
WarmthSpendMark.Ignore = false;
return __exception;
}
}
[HarmonyPatch(typeof(CharacterClimbing), "RPCA_ClimbJump")]
internal static class ClimbJumpMarkPatch
{
private static void Prefix()
{
WarmthSpendMark.ClimbJump = true;
}
private static Exception Finalizer(Exception __exception)
{
WarmthSpendMark.ClimbJump = false;
return __exception;
}
}
[HarmonyPatch(typeof(Character), "UseStamina")]
internal static class UseStaminaWarmthPatch
{
private static bool _logged;
private static void Prefix(Character __instance, out float __state)
{
__state = -1f;
try
{
if (!((Object)(object)__instance == (Object)null) && __instance.IsLocal)
{
__state = __instance.GetTotalStamina();
}
}
catch (Exception ex)
{
VasodilationPlugin.LogOnce(ref _logged, "[Vasodilation] UseStamina prefix failed.", ex);
}
}
private static void Postfix(Character __instance, float __state)
{
if (__state < 0f || (Object)(object)__instance == (Object)null)
{
return;
}
try
{
float num = __state - __instance.GetTotalStamina();
if (num > 1E-05f)
{
VasodilationPlugin.OnStaminaSpent(__instance, num);
}
}
catch (Exception ex)
{
VasodilationPlugin.LogOnce(ref _logged, "[Vasodilation] UseStamina postfix failed.", ex);
}
}
}
[HarmonyPatch(typeof(CharacterAnimations), "RPCA_PlayRemove")]
internal static class EmotePlayPatch
{
private static bool _logged;
private static void Postfix(CharacterAnimations __instance, string emoteName)
{
try
{
EmoteWarmth.Remember(__instance, emoteName);
}
catch (Exception ex)
{
VasodilationPlugin.LogOnce(ref _logged, "[Vasodilation] Emote postfix failed.", ex);
}
}
}
[HarmonyPatch(typeof(CharacterAnimations), "PlayEmote")]
internal static class EmoteLocalPlayPatch
{
private static bool _logged;
private static void Postfix(CharacterAnimations __instance, string emoteName)
{
try
{
EmoteWarmth.Remember(__instance, emoteName);
}
catch (Exception ex)
{
VasodilationPlugin.LogOnce(ref _logged, "[Vasodilation] PlayEmote postfix failed.", ex);
}
}
}
}