using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Runtime.Versioning;
using BepInEx;
using BepInEx.Logging;
using HarmonyLib;
using Peak.Afflictions;
using Photon.Pun;
using Photon.Realtime;
using UnityEngine;
using UnityEngine.UI;
using Zorro.Core;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: AssemblyTitle("Mod_Peak_2026")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Mod_Peak_2026")]
[assembly: AssemblyCopyright("Copyright © 2026")]
[assembly: AssemblyTrademark("")]
[assembly: ComVisible(false)]
[assembly: Guid("6f7cd0cf-eafa-4617-93d2-7739adc5a0a0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: AssemblyVersion("1.0.0.0")]
namespace PeakClassMod;
public static class ClassBalance
{
public const string BLOWGUN = "HealingDart Variant";
public const float GOBELIN_SIZE = 0.5f;
public const float GOBELIN_CURSE_PER_SHOT = 0.05f;
public const float ASTRONAUT_JUMP_IMPULSE = 1200f;
public const float ASTRONAUT_SPRINT_MULT = 1.7f;
public const float ASTRONAUT_HUNGER_MULT = 1.3f;
public const float ASTRONAUT_MAX_WALK_SPEED = 1.6f;
public const float ASTRONAUT_LOW_GRAV_DURATION = 3f;
public const float GENERAL_CURSE_MIN = 0.35f;
public const float GENERAL_HUNGER_MULT = 2f;
public const float GENERAL_WEIGHT_MULT = 2f;
public const float MEDIC_CURSE = 0.15f;
public const int MEDIC_MAX_HEALS = 10;
public const float MEDIC_HEAL_AMOUNT = 0.1f;
public const float MEDIC_HEAL_COOLDOWN = 1f;
public const float SCOUT_STAMINA_MULT = 0.8f;
public const float SCOUT_HUNGER_MULT = 1.7f;
public const float SCOUT_WEIGHT_MULT = 0.5f;
public const float ROGUE_STAMINA_MULT = 1.7f;
public const int ROGUE_EXTRA_JUMPS = 2;
public const float GREATEPEE_SLEEP_MIN = 30f;
public const float GREATEPEE_SLEEP_MAX = 60f;
public const float GREATEPEE_EFFECT_DURATION = 99999f;
public const float MUSHROOM_STAMINA_COOLDOWN = 10f;
public const float MUSHROOM_CURSE_AMOUNT = 0.02f;
public const float ITEM_REQUEST_DELAY = 0.3f;
public const float ITEM_GIVE_COOLDOWN = 2f;
public const float ITEM_CACHE_DURATION = 300f;
public const float SIZE_CHECK_INTERVAL = 0.5f;
}
[BepInPlugin("com.peakmod.classmod", "PEAK Class Mod", "5.1.0")]
public class PeakClassModPlugin : BaseUnityPlugin
{
public static PeakClassModPlugin Instance;
internal static ManualLogSource Log;
private static Harmony harmony;
public static bool scoutActive = false;
public static bool medicActive = false;
public static bool techPriestActive = false;
public static bool mushroomancerActive = false;
public static bool greatEpeeActive = false;
public static bool rogueActive = false;
public static bool generalActive = false;
public static bool astronautActive = false;
public static bool gobelinActive = false;
public static string currentClass = "None";
private GameObject _callbacksGO;
private static readonly string[] StartBerries = new string[5] { "Shroomberry_Red", "Shroomberry_Yellow", "Shroomberry_Purple", "Shroomberry_Blue", "Shroomberry_Green" };
private void Awake()
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0021: Expected O, but got Unknown
//IL_0032: Unknown result type (might be due to invalid IL or missing references)
//IL_003c: Expected O, but got Unknown
Instance = this;
Log = ((BaseUnityPlugin)this).Logger;
harmony = new Harmony("com.peakmod.classmod");
harmony.PatchAll();
_callbacksGO = new GameObject("PeakClassModCallbacks");
Object.DontDestroyOnLoad((Object)(object)_callbacksGO);
_callbacksGO.AddComponent<PeakClassModCallbacks>();
ManualLogSource log = Log;
if (log != null)
{
log.LogInfo((object)"[ClassMod] Ready. Version 5.1.0 loaded (Infinite Fix).");
}
}
private void OnDestroy()
{
try
{
Harmony obj = harmony;
if (obj != null)
{
obj.UnpatchSelf();
}
}
catch
{
}
if ((Object)(object)_callbacksGO != (Object)null)
{
Object.Destroy((Object)(object)_callbacksGO);
}
}
public void EnsureComponent<T>(GameObject go) where T : Component
{
if ((Object)(object)go != (Object)null && (Object)(object)go.GetComponent<T>() == (Object)null)
{
go.AddComponent<T>();
}
}
public static List<string> BuildStartItemsByHatName(string hatName)
{
List<string> list = new List<string>();
if (string.IsNullOrEmpty(hatName))
{
return list;
}
switch (hatName)
{
case "Hat_Mushroom":
{
for (int i = 0; i < 3; i++)
{
list.Add(StartBerries[Random.Range(0, StartBerries.Length)]);
}
break;
}
case "Hat_Medic":
list.Add("FirstAidKit");
list.Add("Cure-All");
break;
case "Hat_Crab":
list.Add("ChainShooter");
list.Add("ChainShooter");
break;
case "Hat_NinjaHeadband":
list.Add("RopeSpool");
list.Add("RopeSpool");
break;
case "Hat_Astronaut":
list.Add("BalloonBunch");
break;
case "Hat_Midsummer":
list.Add("HealingDart Variant");
list.Add("MagicBean");
break;
}
return list;
}
}
internal static class GobelinDiet
{
public static bool IsPackagedFood(Item item)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Invalid comparison between Unknown and I4
if ((Object)(object)item == (Object)null)
{
return false;
}
return (item.itemTags & 2) > 0;
}
}
[HarmonyPatch(typeof(Item), "Consume")]
public class GobelinInfiniteConsumePatch
{
private static bool Prefix(Item __instance)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.holderCharacter == (Object)null)
{
return true;
}
if (ClassCheckUtil.IsGobelin(__instance.holderCharacter) && ((Object)__instance).name.IndexOf("HealingDart Variant", StringComparison.OrdinalIgnoreCase) >= 0)
{
__instance.holderCharacter.data.lastConsumedItem = Time.time;
if (__instance.holderCharacter.refs != null && (Object)(object)__instance.holderCharacter.refs.animator != (Object)null)
{
__instance.holderCharacter.refs.animator.SetBool("Consumed Item", true);
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Item), "FinishCastPrimary")]
public class GobelinCurseOnShootPatch
{
private static void Postfix(Item __instance)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.holderCharacter == (Object)null || !__instance.holderCharacter.IsLocal || !ClassCheckUtil.IsGobelin(__instance.holderCharacter) || ((Object)__instance).name.IndexOf("HealingDart Variant", StringComparison.OrdinalIgnoreCase) < 0)
{
return;
}
CharacterRefs refs = __instance.holderCharacter.refs;
if (refs != null)
{
CharacterAfflictions afflictions = refs.afflictions;
if (afflictions != null)
{
afflictions.AddStatus((STATUSTYPE)5, 0.05f, false, true, true);
}
}
}
}
[HarmonyPatch(typeof(Item), "Update")]
public class GobelinBlowgunEnforcer
{
private static void Postfix(Item __instance)
{
if ((Object)(object)__instance == (Object)null || ((Object)__instance).name.IndexOf("HealingDart Variant", StringComparison.OrdinalIgnoreCase) < 0)
{
return;
}
Character holderCharacter = __instance.holderCharacter;
if ((Object)(object)holderCharacter != (Object)null && ClassCheckUtil.IsGobelin(holderCharacter))
{
if (holderCharacter.IsLocal)
{
Traverse val = Traverse.Create((object)__instance);
Traverse val2 = val.Field("destroyOnUse");
if (val2.FieldExists() && val2.GetValue<bool>())
{
val2.SetValue((object)false);
}
try
{
if (__instance.data != null && __instance.HasData((DataEntryKey)2))
{
OptionableIntItemData data = __instance.GetData<OptionableIntItemData>((DataEntryKey)2);
if (data != null && data.Value != -1)
{
data.Value = -1;
}
}
}
catch
{
}
}
if (__instance.UIData != null)
{
__instance.UIData.canDrop = false;
__instance.UIData.canBackpack = false;
__instance.UIData.canThrow = false;
__instance.UIData.canPocket = true;
}
return;
}
if (__instance.UIData != null)
{
__instance.UIData.canDrop = true;
__instance.UIData.canBackpack = true;
__instance.UIData.canThrow = true;
__instance.UIData.canPocket = true;
}
Traverse val3 = Traverse.Create((object)__instance);
Traverse val4 = val3.Field("destroyOnUse");
if (val4.FieldExists())
{
val4.SetValue((object)true);
}
try
{
if (__instance.data != null && __instance.HasData((DataEntryKey)2))
{
OptionableIntItemData data2 = __instance.GetData<OptionableIntItemData>((DataEntryKey)2);
if (data2 != null && data2.Value == -1)
{
data2.Value = 1;
}
}
}
catch
{
}
}
}
[HarmonyPatch(typeof(Item), "StartUsePrimary")]
[HarmonyPriority(600)]
public class GobelinFoodBlockerPrimary
{
private static bool Prefix(Item __instance)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.holderCharacter == (Object)null)
{
return true;
}
if (ClassCheckUtil.IsGobelin(__instance.holderCharacter) && (Object)(object)((Component)__instance).GetComponent<Action_RestoreHunger>() != (Object)null && GobelinDiet.IsPackagedFood(__instance))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Item), "StartUseSecondary")]
[HarmonyPriority(600)]
public class GobelinFoodBlockerSecondary
{
private static bool Prefix(Item __instance)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.holderCharacter == (Object)null)
{
return true;
}
if (ClassCheckUtil.IsGobelin(__instance.holderCharacter) && (Object)(object)((Component)__instance).GetComponent<Action_RestoreHunger>() != (Object)null && GobelinDiet.IsPackagedFood(__instance))
{
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Item), "StartUseSecondary")]
public class GobelinAntiFeedPatch
{
private static bool Prefix(Item __instance)
{
if ((Object)(object)__instance == (Object)null)
{
return true;
}
if ((Object)(object)((Component)__instance).GetComponent<Action_RestoreHunger>() != (Object)null && GobelinDiet.IsPackagedFood(__instance))
{
Interaction instance = Interaction.instance;
if ((Object)(object)instance == (Object)null)
{
return true;
}
MonoBehaviour value = Traverse.Create((object)instance).Field("bestCharacter").GetValue<MonoBehaviour>();
if ((Object)(object)value != (Object)null)
{
Character value2 = Traverse.Create((object)value).Field("character").GetValue<Character>();
if ((Object)(object)value2 != (Object)null && ClassCheckUtil.IsGobelin(value2))
{
return false;
}
}
}
return true;
}
}
public class GobelinSizeHandler : MonoBehaviour
{
private Character _character;
private float _lastCheckTime = 0f;
private void Start()
{
_character = ((Component)this).GetComponent<Character>();
}
private void Update()
{
//IL_0075: Unknown result type (might be due to invalid IL or missing references)
//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
if (Time.time - _lastCheckTime < 0.2f)
{
return;
}
_lastCheckTime = Time.time;
if (!((Object)(object)_character == (Object)null))
{
bool flag = false;
flag = ((!_character.IsLocal) ? ClassCheckUtil.IsGobelin(_character) : ClassManager.IsGobelinActive());
float x = ((Component)_character).transform.localScale.x;
float num = (flag ? 0.5f : 1f);
if (Mathf.Abs(x - num) > 0.05f)
{
((Component)_character).transform.localScale = Vector3.one * num;
}
}
}
}
public class ClassModNetwork : MonoBehaviourPun
{
[CompilerGenerated]
private sealed class <HostGiveItemsRoutine>d__10 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public string hatName;
public Player requestor;
public ClassModNetwork <>4__this;
private List<string> <itemsToGive>5__1;
private Character <targetChar>5__2;
private int <actorNumber>5__3;
private Character <cachedChar>5__4;
private List<Character>.Enumerator <>s__5;
private Character <ch>5__6;
private List<string>.Enumerator <>s__7;
private string <itemName>5__8;
private Item <item>5__9;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <HostGiveItemsRoutine>d__10(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
int num = <>1__state;
if (num == -3 || num == 1)
{
try
{
}
finally
{
<>m__Finally1();
}
}
<itemsToGive>5__1 = null;
<targetChar>5__2 = null;
<cachedChar>5__4 = null;
<>s__5 = default(List<Character>.Enumerator);
<ch>5__6 = null;
<>s__7 = default(List<string>.Enumerator);
<itemName>5__8 = null;
<item>5__9 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_020f: Unknown result type (might be due to invalid IL or missing references)
//IL_0219: Expected O, but got Unknown
try
{
switch (<>1__state)
{
default:
return false;
case 0:
{
<>1__state = -1;
<itemsToGive>5__1 = PeakClassModPlugin.BuildStartItemsByHatName(hatName);
if (<itemsToGive>5__1.Count == 0)
{
return false;
}
<targetChar>5__2 = null;
<actorNumber>5__3 = requestor.ActorNumber;
if (_characterCache.TryGetValue(<actorNumber>5__3, out <cachedChar>5__4) && (Object)(object)<cachedChar>5__4 != (Object)null)
{
<targetChar>5__2 = <cachedChar>5__4;
}
else
{
<>s__5 = Character.AllCharacters.GetEnumerator();
try
{
while (<>s__5.MoveNext())
{
<ch>5__6 = <>s__5.Current;
Character obj = <ch>5__6;
object obj2;
if (obj == null)
{
obj2 = null;
}
else
{
PhotonView photonView = ((MonoBehaviourPun)obj).photonView;
obj2 = ((photonView != null) ? photonView.Owner : null);
}
if (obj2 == requestor)
{
<targetChar>5__2 = <ch>5__6;
_characterCache[<actorNumber>5__3] = <ch>5__6;
break;
}
<ch>5__6 = null;
}
}
finally
{
((IDisposable)<>s__5).Dispose();
}
<>s__5 = default(List<Character>.Enumerator);
}
Character obj3 = <targetChar>5__2;
if ((Object)(object)((obj3 != null) ? obj3.player : null) == (Object)null)
{
return false;
}
<>s__7 = <itemsToGive>5__1.GetEnumerator();
<>1__state = -3;
break;
}
case 1:
<>1__state = -3;
<item>5__9 = null;
<itemName>5__8 = null;
break;
}
if (<>s__7.MoveNext())
{
<itemName>5__8 = <>s__7.Current;
<item>5__9 = ItemCache.Get(<itemName>5__8);
if ((Object)(object)<item>5__9 != (Object)null && <targetChar>5__2.player.HasEmptySlot(<item>5__9.itemID))
{
ItemSlot val = default(ItemSlot);
<targetChar>5__2.player.AddItem(<item>5__9.itemID, (ItemInstanceData)null, ref val);
}
<>2__current = (object)new WaitForSeconds(0.02f);
<>1__state = 1;
return true;
}
<>m__Finally1();
<>s__7 = default(List<string>.Enumerator);
return false;
}
catch
{
//try-fault
((IDisposable)this).Dispose();
throw;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
private void <>m__Finally1()
{
<>1__state = -1;
((IDisposable)<>s__7).Dispose();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <RequestItemsRoutine>d__8 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public ClassModNetwork <>4__this;
private float <timeout>5__1;
private bool <inventoryReady>5__2;
private string <myHatName>5__3;
private string <d>5__4;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <RequestItemsRoutine>d__8(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<myHatName>5__3 = null;
<d>5__4 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_0141: Unknown result type (might be due to invalid IL or missing references)
//IL_014b: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(0.3f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
goto IL_006d;
case 2:
<>1__state = -1;
goto IL_006d;
case 3:
{
<>1__state = -1;
break;
}
IL_006d:
if (!PhotonNetwork.InRoom)
{
<>2__current = null;
<>1__state = 2;
return true;
}
if ((Object)(object)<>4__this._character == (Object)null)
{
<>4__this._character = ((Component)<>4__this).GetComponent<Character>();
}
<timeout>5__1 = 5f;
<inventoryReady>5__2 = false;
break;
}
if (<timeout>5__1 > 0f)
{
Character character = <>4__this._character;
if (((character == null) ? null : character.player?.itemSlots) == null || <>4__this._character.player.itemSlots.Length == 0 || <>4__this._character.player.itemSlots[0].IsEmpty())
{
<timeout>5__1 -= 0.1f;
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 3;
return true;
}
<inventoryReady>5__2 = true;
}
<myHatName>5__3 = "None";
if (HatUtils.TryGetHatName(<>4__this._character, out <d>5__4))
{
<myHatName>5__3 = <d>5__4;
}
if (<inventoryReady>5__2 || <timeout>5__1 <= 0f)
{
((MonoBehaviourPun)<>4__this).photonView.RPC("RPC_HostGiveItems", (RpcTarget)2, new object[1] { <myHatName>5__3 });
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private Character _character;
private bool _hasRequestedItems = false;
private static Dictionary<int, float> _hostGiveCooldown = new Dictionary<int, float>();
private static Dictionary<int, Character> _characterCache = new Dictionary<int, Character>();
private void Awake()
{
ClassModNetwork[] components = ((Component)this).GetComponents<ClassModNetwork>();
if (components.Length > 1)
{
Object.Destroy((Object)(object)this);
}
else
{
_character = ((Component)this).GetComponent<Character>();
}
}
private void Start()
{
if ((Object)(object)((MonoBehaviourPun)this).photonView != (Object)null && ((MonoBehaviourPun)this).photonView.IsMine && !_hasRequestedItems)
{
_hasRequestedItems = true;
((MonoBehaviour)this).StartCoroutine(RequestItemsRoutine());
}
}
private void OnDestroy()
{
Character character = _character;
object obj;
if (character == null)
{
obj = null;
}
else
{
PhotonView photonView = ((MonoBehaviourPun)character).photonView;
obj = ((photonView != null) ? photonView.Owner : null);
}
if (obj != null)
{
_characterCache.Remove(((MonoBehaviourPun)_character).photonView.Owner.ActorNumber);
}
}
public static void ClearPlayerCache(int actorNumber)
{
_characterCache.Remove(actorNumber);
_hostGiveCooldown.Remove(actorNumber);
}
[IteratorStateMachine(typeof(<RequestItemsRoutine>d__8))]
private IEnumerator RequestItemsRoutine()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <RequestItemsRoutine>d__8(0)
{
<>4__this = this
};
}
[PunRPC]
public void RPC_HostGiveItems(string clientHatName, PhotonMessageInfo info)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0056: Unknown result type (might be due to invalid IL or missing references)
if (PhotonNetwork.IsMasterClient)
{
int actorNumber = info.Sender.ActorNumber;
if (!_hostGiveCooldown.TryGetValue(actorNumber, out var value) || !(Time.time - value < 2f))
{
_hostGiveCooldown[actorNumber] = Time.time;
((MonoBehaviour)this).StartCoroutine(HostGiveItemsRoutine(clientHatName, info.Sender));
}
}
}
[IteratorStateMachine(typeof(<HostGiveItemsRoutine>d__10))]
private IEnumerator HostGiveItemsRoutine(string hatName, Player requestor)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <HostGiveItemsRoutine>d__10(0)
{
<>4__this = this,
hatName = hatName,
requestor = requestor
};
}
[PunRPC]
public void ShowMedicHealEffectRPC(int remainingHeals)
{
ManualLogSource log = PeakClassModPlugin.Log;
if (log != null)
{
log.LogInfo((object)$"[ClassMod] Medic heal: {remainingHeals}");
}
}
[PunRPC]
public void RPC_SyncClassActivation(string className, int actorNumber)
{
ManualLogSource log = PeakClassModPlugin.Log;
if (log != null)
{
log.LogInfo((object)$"[ClassMod] Player {actorNumber} class: {className}");
}
}
}
public class PeakClassModCallbacks : MonoBehaviourPunCallbacks
{
public override void OnPlayerLeftRoom(Player otherPlayer)
{
ClassModNetwork.ClearPlayerCache(otherPlayer.ActorNumber);
}
}
internal static class HatUtils
{
private static string _lastLocalHatName;
internal static void SetLastLocalHatName(string hatName)
{
if (!string.IsNullOrEmpty(hatName))
{
_lastLocalHatName = hatName;
}
}
public static bool TryGetHatName(Character ch, out string hatName)
{
hatName = null;
if ((Object)(object)ch == (Object)null)
{
return false;
}
PersistentPlayerDataService service = GameHandler.GetService<PersistentPlayerDataService>();
PersistentPlayerData val = null;
PhotonView photonView = ((MonoBehaviourPun)ch).photonView;
if (((photonView != null) ? photonView.Owner : null) != null)
{
val = ((service != null) ? service.GetPlayerData(((MonoBehaviourPun)ch).photonView.Owner) : null);
}
if (val == null && ch.IsLocal && PhotonNetwork.LocalPlayer != null)
{
val = ((service != null) ? service.GetPlayerData(PhotonNetwork.LocalPlayer) : null);
}
if (val != null)
{
CustomizationOption[] array = Singleton<Customization>.Instance?.hats;
int currentHat = val.customizationData.currentHat;
if (array != null && currentHat >= 0 && currentHat < array.Length && (Object)(object)array[currentHat] != (Object)null)
{
hatName = ((Object)array[currentHat]).name;
}
}
if (string.IsNullOrEmpty(hatName) && ch.IsLocal)
{
hatName = _lastLocalHatName;
}
return !string.IsNullOrEmpty(hatName);
}
public static bool HasAnyHat(Character ch, params string[] names)
{
if (!TryGetHatName(ch, out var hatName))
{
return false;
}
return names.Contains<string>(hatName, StringComparer.OrdinalIgnoreCase);
}
public static bool HasHat(Character ch, string expected)
{
string hatName;
return TryGetHatName(ch, out hatName) && string.Equals(hatName, expected, StringComparison.OrdinalIgnoreCase);
}
}
internal static class ClassCheckUtil
{
public static bool IsGeneral(Character ch)
{
return HatUtils.HasAnyHat(ch, "Hat_Bandana", "Hat_Captain");
}
public static bool IsTechPriest(Character ch)
{
return HatUtils.HasHat(ch, "Hat_Crab");
}
public static bool IsMedicHat(Character ch)
{
return HatUtils.HasAnyHat(ch, "Hat_Medic", "MedicHelmet");
}
public static bool IsMushroom(Character ch)
{
return HatUtils.HasHat(ch, "Hat_Mushroom");
}
public static bool IsRogueHat(Character ch)
{
return HatUtils.HasHat(ch, "Hat_NinjaHeadband");
}
public static bool IsGreatEpeeHat(Character ch)
{
return HatUtils.HasHat(ch, "Hat_Propeller");
}
public static bool IsAstronaut(Character ch)
{
return HatUtils.HasHat(ch, "Hat_Astronaut");
}
public static bool IsGobelin(Character ch)
{
return HatUtils.HasAnyHat(ch, "Hat_Midsummer");
}
public static bool IsScout(Character ch)
{
return HatUtils.HasHat(ch, "Hat_Scoutmaster");
}
}
internal static class ItemCache
{
private static Dictionary<string, Item> _byName;
private static float _lastRefreshTime;
public static Item Get(string name)
{
if (_byName == null || Time.time - _lastRefreshTime > 300f)
{
_byName = new Dictionary<string, Item>(StringComparer.OrdinalIgnoreCase);
Item[] array = Resources.FindObjectsOfTypeAll<Item>();
foreach (Item val in array)
{
if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name) && !_byName.ContainsKey(((Object)val).name))
{
_byName[((Object)val).name] = val;
}
}
_lastRefreshTime = Time.time;
}
Item value;
return _byName.TryGetValue(name, out value) ? value : null;
}
}
[HarmonyPatch(typeof(Character), "Start")]
public class Character_Start_AddNetComp_Patch
{
private static void Postfix(Character __instance)
{
if ((Object)(object)__instance != (Object)null)
{
PeakClassModPlugin instance = PeakClassModPlugin.Instance;
instance.EnsureComponent<ClassModNetwork>(((Component)__instance).gameObject);
instance.EnsureComponent<AstronautStatHandler>(((Component)__instance).gameObject);
instance.EnsureComponent<MedicStatHandler>(((Component)__instance).gameObject);
instance.EnsureComponent<TechPriestWeightEnforcer>(((Component)__instance).gameObject);
instance.EnsureComponent<GobelinSizeHandler>(((Component)__instance).gameObject);
}
}
}
public static class ClassManager
{
[CompilerGenerated]
private sealed class <GreatEpeePermanentEffects>d__29 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Character character;
private bool <hasFaster>5__1;
private List<Affliction> <list>5__2;
private int <i>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GreatEpeePermanentEffects>d__29(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<list>5__2 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0109: Unknown result type (might be due to invalid IL or missing references)
//IL_0113: Expected O, but got Unknown
//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
//IL_00f1: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
<list>5__2 = null;
break;
}
if (PeakClassModPlugin.greatEpeeActive && (Object)(object)character != (Object)null && character.IsLocal)
{
<hasFaster>5__1 = false;
<list>5__2 = character.refs?.afflictions?.afflictionList;
if (<list>5__2 != null)
{
<i>5__3 = 0;
while (<i>5__3 < <list>5__2.Count)
{
if (((object)<list>5__2[<i>5__3]).GetType().Name.Contains("FasterBoi"))
{
<hasFaster>5__1 = true;
break;
}
<i>5__3++;
}
}
if (!<hasFaster>5__1)
{
character.refs.afflictions.AddAffliction((Affliction)new Affliction_FasterBoi
{
totalTime = 99999f
}, false);
}
<>2__current = (object)new WaitForSeconds(2f);
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <GreatEpeeStaminaRoutine>d__30 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Character character;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <GreatEpeeStaminaRoutine>d__30(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_003a: Unknown result type (might be due to invalid IL or missing references)
//IL_0044: Expected O, but got Unknown
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
//IL_006d: Expected O, but got Unknown
//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
//IL_0102: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
goto IL_018e;
case 2:
<>1__state = -1;
if (!PeakClassModPlugin.greatEpeeActive)
{
return false;
}
goto IL_008c;
case 3:
{
<>1__state = -1;
if ((Object)(object)character?.refs?.afflictions == (Object)null || !PeakClassModPlugin.greatEpeeActive)
{
return false;
}
if (character.refs.afflictions.GetCurrentStatus((STATUSTYPE)6) < 0.1f)
{
character.refs.afflictions.AddStatus((STATUSTYPE)6, 1f, false, true, true);
}
goto IL_018e;
}
IL_008c:
if ((Object)(object)character?.refs?.afflictions != (Object)null && character.refs.afflictions.GetCurrentStatus((STATUSTYPE)6) > 0.05f)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
}
if ((Object)(object)character == (Object)null)
{
return false;
}
<>2__current = (object)new WaitForSeconds(Random.Range(30f, 60f));
<>1__state = 3;
return true;
IL_018e:
if (!PeakClassModPlugin.greatEpeeActive || !((Object)(object)character != (Object)null) || !character.IsLocal)
{
break;
}
goto IL_008c;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
[CompilerGenerated]
private sealed class <MushroomancerLocalStaminaWatch>d__27 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public Character character;
private bool <isKnockedOut>5__1;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <MushroomancerLocalStaminaWatch>d__27(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_00c8: Unknown result type (might be due to invalid IL or missing references)
//IL_00d2: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
break;
case 1:
<>1__state = -1;
break;
}
if ((Object)(object)character != (Object)null && PeakClassModPlugin.mushroomancerActive && character.IsLocal)
{
<isKnockedOut>5__1 = false;
if ((Object)(object)character.data != (Object)null && (character.data.passedOut || character.data.fullyPassedOut || character.data.dead))
{
<isKnockedOut>5__1 = true;
}
if (!<isKnockedOut>5__1 && character.data.currentStamina <= 0.02f)
{
TryActivateStaminaZeroMechanic(character);
}
<>2__current = (object)new WaitForSeconds(0.1f);
<>1__state = 1;
return true;
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static readonly Dictionary<int, float> lastStaminaZeroTime = new Dictionary<int, float>();
private static Coroutine _mushroomCoroutine;
private static Coroutine _greatEpeeEffectsCoroutine;
private static Coroutine _greatEpeeStaminaCoroutine;
private static readonly string[] ZeroStaminaFungi = new string[3] { "ShelfShroom", "BounceShroom", "CloudFungus" };
public static void ResetAllFlags()
{
//IL_0063: Unknown result type (might be due to invalid IL or missing references)
Character localCharacter = Character.localCharacter;
if ((Object)(object)localCharacter != (Object)null)
{
if (_mushroomCoroutine != null)
{
((MonoBehaviour)localCharacter).StopCoroutine(_mushroomCoroutine);
}
if (_greatEpeeEffectsCoroutine != null)
{
((MonoBehaviour)localCharacter).StopCoroutine(_greatEpeeEffectsCoroutine);
}
if (_greatEpeeStaminaCoroutine != null)
{
((MonoBehaviour)localCharacter).StopCoroutine(_greatEpeeStaminaCoroutine);
}
((Component)localCharacter).transform.localScale = Vector3.one;
}
PeakClassModPlugin.scoutActive = false;
PeakClassModPlugin.medicActive = false;
PeakClassModPlugin.techPriestActive = false;
PeakClassModPlugin.mushroomancerActive = false;
PeakClassModPlugin.greatEpeeActive = false;
PeakClassModPlugin.rogueActive = false;
PeakClassModPlugin.generalActive = false;
PeakClassModPlugin.astronautActive = false;
PeakClassModPlugin.gobelinActive = false;
PeakClassModPlugin.currentClass = "None";
}
public static void ActivateScoutClass()
{
ResetAllFlags();
PeakClassModPlugin.scoutActive = true;
PeakClassModPlugin.currentClass = "Scout";
}
public static void ActivateMedicClass()
{
ResetAllFlags();
PeakClassModPlugin.medicActive = true;
PeakClassModPlugin.currentClass = "Medic";
}
public static void ActivateTechPriestClass()
{
ResetAllFlags();
PeakClassModPlugin.techPriestActive = true;
PeakClassModPlugin.currentClass = "Tech-Priest";
}
public static void ActivateMushroomancerClass()
{
ResetAllFlags();
PeakClassModPlugin.mushroomancerActive = true;
PeakClassModPlugin.currentClass = "Mushroomancer";
}
public static void ActivateGreatEpeeClass()
{
ResetAllFlags();
PeakClassModPlugin.greatEpeeActive = true;
PeakClassModPlugin.currentClass = "GreatEpee";
}
public static void ActivateRogueClass()
{
ResetAllFlags();
PeakClassModPlugin.rogueActive = true;
PeakClassModPlugin.currentClass = "Rogue";
if ((Object)(object)Character.localCharacter != (Object)null)
{
Character.localCharacter.data.jumpsRemaining = 2;
}
}
public static void ActivateGeneralClass()
{
ResetAllFlags();
PeakClassModPlugin.generalActive = true;
PeakClassModPlugin.currentClass = "General";
}
public static void ActivateAstronautClass()
{
ResetAllFlags();
PeakClassModPlugin.astronautActive = true;
PeakClassModPlugin.currentClass = "Astronaut";
}
public static void ActivateGobelinClass()
{
ResetAllFlags();
PeakClassModPlugin.gobelinActive = true;
PeakClassModPlugin.currentClass = "Gobelin";
}
public static void DeactivateAllClasses()
{
ResetAllFlags();
if ((Object)(object)Character.localCharacter != (Object)null)
{
Character.localCharacter.data.jumpsRemaining = 1;
}
}
public static bool IsScoutActive()
{
return PeakClassModPlugin.scoutActive;
}
public static bool IsMedicActive()
{
return PeakClassModPlugin.medicActive;
}
public static bool IsTechPriestActive()
{
return PeakClassModPlugin.techPriestActive;
}
public static bool IsMushroomancerActive()
{
return PeakClassModPlugin.mushroomancerActive;
}
public static bool IsGreatEpeeActive()
{
return PeakClassModPlugin.greatEpeeActive;
}
public static bool IsRogueActive()
{
return PeakClassModPlugin.rogueActive;
}
public static bool IsGeneralActive()
{
return PeakClassModPlugin.generalActive;
}
public static bool IsAstronautActive()
{
return PeakClassModPlugin.astronautActive;
}
public static bool IsGobelinActive()
{
return PeakClassModPlugin.gobelinActive;
}
public static void StartMushroomancerWatch(Character character)
{
if ((Object)(object)character != (Object)null)
{
_mushroomCoroutine = ((MonoBehaviour)character).StartCoroutine(MushroomancerLocalStaminaWatch(character));
}
}
public static void StartGreatEpeeRoutines(Character character)
{
if ((Object)(object)character != (Object)null)
{
_greatEpeeEffectsCoroutine = ((MonoBehaviour)character).StartCoroutine(GreatEpeePermanentEffects(character));
_greatEpeeStaminaCoroutine = ((MonoBehaviour)character).StartCoroutine(GreatEpeeStaminaRoutine(character));
}
}
[IteratorStateMachine(typeof(<MushroomancerLocalStaminaWatch>d__27))]
public static IEnumerator MushroomancerLocalStaminaWatch(Character character)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <MushroomancerLocalStaminaWatch>d__27(0)
{
character = character
};
}
public static void TryActivateStaminaZeroMechanic(Character character)
{
object obj;
if (character == null)
{
obj = null;
}
else
{
PhotonView photonView = ((MonoBehaviourPun)character).photonView;
obj = ((photonView != null) ? photonView.Owner : null);
}
if (obj == null)
{
return;
}
int actorNumber = ((MonoBehaviourPun)character).photonView.Owner.ActorNumber;
if (lastStaminaZeroTime.TryGetValue(actorNumber, out var value) && Time.time - value < 10f)
{
return;
}
lastStaminaZeroTime[actorNumber] = Time.time;
CharacterRefs refs = character.refs;
if (refs != null)
{
CharacterAfflictions afflictions = refs.afflictions;
if (afflictions != null)
{
afflictions.AddStatus((STATUSTYPE)5, 0.02f, false, true, true);
}
}
string name = ZeroStaminaFungi[Random.Range(0, ZeroStaminaFungi.Length)];
Item val = ItemCache.Get(name);
if (!((Object)(object)val == (Object)null))
{
ushort itemID = val.itemID;
if ((Object)(object)character.player != (Object)null && character.player.HasEmptySlot(itemID))
{
ItemSlot val2 = default(ItemSlot);
character.player.AddItem(itemID, (ItemInstanceData)null, ref val2);
}
}
}
[IteratorStateMachine(typeof(<GreatEpeePermanentEffects>d__29))]
public static IEnumerator GreatEpeePermanentEffects(Character character)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <GreatEpeePermanentEffects>d__29(0)
{
character = character
};
}
[IteratorStateMachine(typeof(<GreatEpeeStaminaRoutine>d__30))]
public static IEnumerator GreatEpeeStaminaRoutine(Character character)
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <GreatEpeeStaminaRoutine>d__30(0)
{
character = character
};
}
}
public class TechPriestWeightEnforcer : MonoBehaviour
{
private Character _character;
private CharacterAfflictions _afflictions;
private bool _isActive;
private int _weightIndex;
private float _lastCheck = 0f;
private void Start()
{
_character = ((Component)this).GetComponent<Character>();
_weightIndex = 7;
RefreshState();
}
private void RefreshState()
{
_isActive = (Object)(object)_character != (Object)null && ClassCheckUtil.IsTechPriest(_character);
if (_isActive)
{
_afflictions = _character.refs.afflictions;
}
}
private void LateUpdate()
{
if (!_isActive || !ClassManager.IsTechPriestActive())
{
if (Time.time - _lastCheck > 2f)
{
_lastCheck = Time.time;
RefreshState();
}
}
else if ((Object)(object)_afflictions != (Object)null && _afflictions.currentStatuses[_weightIndex] > 0f)
{
_afflictions.currentStatuses[_weightIndex] = 0f;
}
}
}
public class AstronautStatHandler : MonoBehaviour
{
[CompilerGenerated]
private sealed class <ApplyWindWalkDelayed>d__14 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
public AstronautStatHandler <>4__this;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <ApplyWindWalkDelayed>d__14(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0026: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
if (ClassManager.IsAstronautActive() && (Object)(object)<>4__this._character != (Object)null && !<>4__this._character.data.isGrounded)
{
<>4__this.TriggerWindWalk();
}
return false;
}
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private Character _character;
private CharacterMovement _movement;
private Traverse _travMove;
private float _defJump = 400f;
private float _defSprintMult = 2f;
private bool _defaultsCaptured = false;
private bool _isModified = false;
private Traverse _jumpImpulseField;
private Traverse _sprintMultiplierField;
private Traverse _velocityField;
private bool _fieldsInitialized = false;
private void Start()
{
_character = ((Component)this).GetComponent<Character>();
_movement = ((Component)this).GetComponent<CharacterMovement>();
if ((Object)(object)_movement != (Object)null)
{
_travMove = Traverse.Create((object)_movement);
InitializeFields();
}
}
private void InitializeFields()
{
if (!_fieldsInitialized && _travMove != null)
{
_jumpImpulseField = _travMove.Field("jumpImpulse");
_sprintMultiplierField = _travMove.Field("sprintMultiplier");
_velocityField = _travMove.Field("velocity");
_fieldsInitialized = true;
}
}
private void Update()
{
if (!((Object)(object)_character == (Object)null) && _character.IsLocal && ClassManager.IsAstronautActive() && _character.input.jumpWasPressed && _character.data.isGrounded)
{
((MonoBehaviour)this).StopAllCoroutines();
((MonoBehaviour)this).StartCoroutine(ApplyWindWalkDelayed());
}
}
[IteratorStateMachine(typeof(<ApplyWindWalkDelayed>d__14))]
private IEnumerator ApplyWindWalkDelayed()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <ApplyWindWalkDelayed>d__14(0)
{
<>4__this = this
};
}
private void TriggerWindWalk()
{
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_002f: Expected O, but got Unknown
try
{
CharacterRefs refs = _character.refs;
if (refs != null)
{
CharacterAfflictions afflictions = refs.afflictions;
if (afflictions != null)
{
afflictions.AddAffliction((Affliction)new Affliction_LowGravity(3, 3f), true);
}
}
}
catch
{
}
}
private void FixedUpdate()
{
if ((Object)(object)_character == (Object)null || !_character.IsLocal || !_fieldsInitialized)
{
return;
}
if (ClassManager.IsAstronautActive())
{
if (!_defaultsCaptured && !_isModified)
{
CaptureDefaults();
}
ApplyAstronautStats();
_isModified = true;
}
else if (_isModified)
{
RestoreDefaults();
}
}
private void CaptureDefaults()
{
Traverse jumpImpulseField = _jumpImpulseField;
float? num = ((jumpImpulseField != null) ? new float?(jumpImpulseField.GetValue<float>()) : null);
if (num.HasValue && num.Value > 0f)
{
_defJump = num.Value;
}
Traverse sprintMultiplierField = _sprintMultiplierField;
float? num2 = ((sprintMultiplierField != null) ? new float?(sprintMultiplierField.GetValue<float>()) : null);
if (num2.HasValue)
{
_defSprintMult = num2.Value;
}
_defaultsCaptured = true;
}
private void ApplyAstronautStats()
{
//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_00ff: Unknown result type (might be due to invalid IL or missing references)
//IL_010b: 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_0138: Unknown result type (might be due to invalid IL or missing references)
//IL_013d: 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_014c: Unknown result type (might be due to invalid IL or missing references)
//IL_0153: Unknown result type (might be due to invalid IL or missing references)
//IL_015a: Unknown result type (might be due to invalid IL or missing references)
Traverse jumpImpulseField = _jumpImpulseField;
if (jumpImpulseField != null)
{
jumpImpulseField.SetValue((object)1200f);
}
Traverse sprintMultiplierField = _sprintMultiplierField;
if (sprintMultiplierField != null)
{
sprintMultiplierField.SetValue((object)1.7f);
}
if (_character.data.isGrounded)
{
List<Affliction> list = _character.refs?.afflictions?.afflictionList;
if (list != null)
{
for (int num = list.Count - 1; num >= 0; num--)
{
if (list[num] is Affliction_LowGravity)
{
_character.refs.afflictions.RemoveAffliction(list[num], false, true);
}
}
}
}
if (!_character.data.isSprinting && _velocityField != null)
{
Vector3 value = _velocityField.GetValue<Vector3>();
Vector3 val = default(Vector3);
((Vector3)(ref val))..ctor(value.x, 0f, value.z);
if (((Vector3)(ref val)).magnitude > 1.6f)
{
Vector3 val2 = ((Vector3)(ref val)).normalized * 1.6f;
_velocityField.SetValue((object)new Vector3(val2.x, value.y, val2.z));
}
}
}
private void RestoreDefaults()
{
Traverse jumpImpulseField = _jumpImpulseField;
if (jumpImpulseField != null)
{
jumpImpulseField.SetValue((object)_defJump);
}
Traverse sprintMultiplierField = _sprintMultiplierField;
if (sprintMultiplierField != null)
{
sprintMultiplierField.SetValue((object)_defSprintMult);
}
_isModified = false;
_defaultsCaptured = false;
}
}
public class MedicStatHandler : MonoBehaviour
{
private Character _character;
private ClassModNetwork _network;
private CharacterAfflictions _afflictions;
private int _healsRemaining = 10;
private float _lastHealTime = 0f;
private void Start()
{
_character = ((Component)this).GetComponent<Character>();
_network = ((Component)this).GetComponent<ClassModNetwork>();
if (_character?.refs != null)
{
_afflictions = _character.refs.afflictions;
}
}
private void Update()
{
if ((Object)(object)_character == (Object)null || !_character.IsLocal)
{
return;
}
if (ClassManager.IsMedicActive())
{
if (Input.GetKeyDown((KeyCode)104) && Time.time - _lastHealTime > 1f)
{
TrySelfHeal();
}
}
else if (_healsRemaining < 10)
{
_healsRemaining = 10;
}
}
private void TrySelfHeal()
{
if (_healsRemaining <= 0)
{
return;
}
if ((Object)(object)_afflictions == (Object)null && _character?.refs != null)
{
_afflictions = _character.refs.afflictions;
}
if ((Object)(object)_afflictions != (Object)null && _afflictions.GetCurrentStatus((STATUSTYPE)0) > 0f)
{
_healsRemaining--;
_lastHealTime = Time.time;
_afflictions.SubtractStatus((STATUSTYPE)0, 0.1f, false, false);
ClassModNetwork network = _network;
if ((Object)(object)((network != null) ? ((MonoBehaviourPun)network).photonView : null) != (Object)null)
{
((MonoBehaviourPun)_network).photonView.RPC("ShowMedicHealEffectRPC", (RpcTarget)0, new object[1] { _healsRemaining });
}
}
}
}
[HarmonyPatch(typeof(CharacterCustomization), "SetCharacterHat")]
public class SetHat_Patch
{
private static void Postfix(int index)
{
CustomizationOption[] array = Singleton<Customization>.Instance?.hats;
object obj;
if (array == null || index < 0 || index >= array.Length)
{
obj = "Unknown";
}
else
{
CustomizationOption obj2 = array[index];
obj = ((obj2 != null) ? ((Object)obj2).name : null);
}
string text = (string)obj;
HatUtils.SetLastLocalHatName(text);
switch (text)
{
case "Hat_Scoutmaster":
ClassManager.ActivateScoutClass();
break;
case "Hat_Medic":
case "MedicHelmet":
ClassManager.ActivateMedicClass();
break;
case "Hat_Crab":
ClassManager.ActivateTechPriestClass();
break;
case "Hat_Mushroom":
ClassManager.ActivateMushroomancerClass();
break;
case "Hat_Propeller":
ClassManager.ActivateGreatEpeeClass();
break;
case "Hat_NinjaHeadband":
ClassManager.ActivateRogueClass();
break;
case "Hat_Bandana":
case "Hat_Captain":
ClassManager.ActivateGeneralClass();
break;
case "Hat_Astronaut":
ClassManager.ActivateAstronautClass();
break;
case "Hat_Midsummer":
ClassManager.ActivateGobelinClass();
break;
default:
ClassManager.DeactivateAllClasses();
break;
}
if ((Object)(object)Character.localCharacter != (Object)null && (Object)(object)GUIManager.instance?.bar != (Object)null)
{
GUIManager.instance.bar.ChangeBar();
}
}
}
[HarmonyPatch(typeof(RunManager), "StartRun")]
public class RunManager_StartRun_Patch
{
[CompilerGenerated]
private sealed class <AddEffectsDelayed>d__1 : IEnumerator<object>, IDisposable, IEnumerator
{
private int <>1__state;
private object <>2__current;
private Character <lc>5__1;
private float <c>5__2;
private float <c>5__3;
object IEnumerator<object>.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
object IEnumerator.Current
{
[DebuggerHidden]
get
{
return <>2__current;
}
}
[DebuggerHidden]
public <AddEffectsDelayed>d__1(int <>1__state)
{
this.<>1__state = <>1__state;
}
[DebuggerHidden]
void IDisposable.Dispose()
{
<lc>5__1 = null;
<>1__state = -2;
}
private bool MoveNext()
{
//IL_0031: Unknown result type (might be due to invalid IL or missing references)
//IL_003b: Expected O, but got Unknown
//IL_006d: Unknown result type (might be due to invalid IL or missing references)
//IL_0077: Expected O, but got Unknown
switch (<>1__state)
{
default:
return false;
case 0:
<>1__state = -1;
<>2__current = (object)new WaitForSeconds(1.5f);
<>1__state = 1;
return true;
case 1:
<>1__state = -1;
<lc>5__1 = Character.localCharacter;
if ((Object)(object)<lc>5__1 == (Object)null)
{
<>2__current = (object)new WaitForSeconds(1f);
<>1__state = 2;
return true;
}
break;
case 2:
<>1__state = -1;
<lc>5__1 = Character.localCharacter;
if ((Object)(object)<lc>5__1 == (Object)null)
{
return false;
}
break;
}
if (ClassCheckUtil.IsMushroom(<lc>5__1))
{
ClassManager.ActivateMushroomancerClass();
ClassManager.StartMushroomancerWatch(<lc>5__1);
}
else if (ClassCheckUtil.IsGeneral(<lc>5__1))
{
ClassManager.ActivateGeneralClass();
CharacterRefs refs = <lc>5__1.refs;
float? obj;
if (refs == null)
{
obj = null;
}
else
{
CharacterAfflictions afflictions = refs.afflictions;
obj = ((afflictions != null) ? new float?(afflictions.GetCurrentStatus((STATUSTYPE)5)) : null);
}
float? num = obj;
<c>5__2 = num.GetValueOrDefault();
if (<c>5__2 < 0.35f)
{
CharacterRefs refs2 = <lc>5__1.refs;
if (refs2 != null)
{
CharacterAfflictions afflictions2 = refs2.afflictions;
if (afflictions2 != null)
{
afflictions2.SetStatus((STATUSTYPE)5, 0.35f, true);
}
}
}
}
else if (ClassCheckUtil.IsGreatEpeeHat(<lc>5__1))
{
ClassManager.ActivateGreatEpeeClass();
ClassManager.StartGreatEpeeRoutines(<lc>5__1);
}
else if (ClassCheckUtil.IsMedicHat(<lc>5__1))
{
ClassManager.ActivateMedicClass();
CharacterRefs refs3 = <lc>5__1.refs;
float? obj2;
if (refs3 == null)
{
obj2 = null;
}
else
{
CharacterAfflictions afflictions3 = refs3.afflictions;
obj2 = ((afflictions3 != null) ? new float?(afflictions3.GetCurrentStatus((STATUSTYPE)5)) : null);
}
float? num = obj2;
<c>5__3 = num.GetValueOrDefault();
if (<c>5__3 < 0.15f)
{
CharacterRefs refs4 = <lc>5__1.refs;
if (refs4 != null)
{
CharacterAfflictions afflictions4 = refs4.afflictions;
if (afflictions4 != null)
{
afflictions4.SetStatus((STATUSTYPE)5, 0.15f, true);
}
}
}
}
else if (ClassCheckUtil.IsAstronaut(<lc>5__1))
{
ClassManager.ActivateAstronautClass();
}
else if (ClassCheckUtil.IsTechPriest(<lc>5__1))
{
ClassManager.ActivateTechPriestClass();
}
else if (ClassCheckUtil.IsRogueHat(<lc>5__1))
{
ClassManager.ActivateRogueClass();
}
else if (ClassCheckUtil.IsGobelin(<lc>5__1))
{
ClassManager.ActivateGobelinClass();
}
else if (ClassCheckUtil.IsScout(<lc>5__1))
{
ClassManager.ActivateScoutClass();
}
return false;
}
bool IEnumerator.MoveNext()
{
//ILSpy generated this explicit interface implementation from .override directive in MoveNext
return this.MoveNext();
}
[DebuggerHidden]
void IEnumerator.Reset()
{
throw new NotSupportedException();
}
}
private static void Postfix()
{
PeakClassModPlugin instance = PeakClassModPlugin.Instance;
if (instance != null)
{
((MonoBehaviour)instance).StartCoroutine(AddEffectsDelayed());
}
}
[IteratorStateMachine(typeof(<AddEffectsDelayed>d__1))]
public static IEnumerator AddEffectsDelayed()
{
//yield-return decompiler failed: Unexpected instruction in Iterator.Dispose()
return new <AddEffectsDelayed>d__1(0);
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddStatus")]
public class General_AddStatus_Patch
{
private static bool Prefix(CharacterAfflictions __instance, STATUSTYPE statusType, ref float amount)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002a: Invalid comparison between Unknown and I4
//IL_0085: Unknown result type (might be due to invalid IL or missing references)
//IL_0088: Invalid comparison between Unknown and I4
//IL_00de: Unknown result type (might be due to invalid IL or missing references)
//IL_00e0: Invalid comparison between Unknown and I4
//IL_00b4: Unknown result type (might be due to invalid IL or missing references)
//IL_00b6: Invalid comparison between Unknown and I4
//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
//IL_00c9: Invalid comparison between Unknown and I4
Character val = __instance?.character;
if ((Object)(object)val == (Object)null)
{
return true;
}
if (val.IsLocal && (int)statusType == 1)
{
if (ClassManager.IsAstronautActive())
{
amount *= 1.3f;
}
else if (ClassManager.IsScoutActive())
{
amount *= 1.7f;
}
else if (ClassManager.IsGeneralActive())
{
amount *= 2f;
}
}
if (ClassCheckUtil.IsGobelin(val) && (int)statusType == 10)
{
amount = 0f;
return false;
}
if (ClassCheckUtil.IsTechPriest(val) && ClassManager.IsTechPriestActive())
{
if ((int)statusType == 1)
{
amount = 0f;
}
else if ((int)statusType == 7)
{
amount = 0f;
return false;
}
}
if ((int)statusType == 3 && ClassCheckUtil.IsMushroom(val))
{
amount = 0f;
}
return true;
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "AddAffliction")]
public class GobelinSporeAfflictionPatch
{
private static bool Prefix(CharacterAfflictions __instance, Affliction affliction)
{
if ((Object)(object)__instance == (Object)null || (Object)(object)__instance.character == (Object)null || affliction == null)
{
return true;
}
if (ClassCheckUtil.IsGobelin(__instance.character))
{
string name = ((object)affliction).GetType().Name;
if (name.Contains("Confus") || name.Contains("Spore"))
{
return false;
}
}
return true;
}
}
[HarmonyPatch(typeof(BarAffliction), "ChangeAffliction")]
public class BarAffliction_Patch
{
private static void Postfix(BarAffliction __instance)
{
//IL_000f: Unknown result type (might be due to invalid IL or missing references)
//IL_0015: Invalid comparison between Unknown and I4
if ((Object)(object)Character.localCharacter == (Object)null || (int)__instance.afflictionType != 7)
{
return;
}
if (ClassManager.IsScoutActive())
{
__instance.size *= 0.5f;
}
else if (ClassManager.IsGeneralActive())
{
__instance.size *= 2f;
}
else if (ClassManager.IsTechPriestActive() && ClassCheckUtil.IsTechPriest(Character.localCharacter))
{
__instance.size = 0f;
Image component = ((Component)__instance).GetComponent<Image>();
if ((Object)(object)component != (Object)null)
{
((Behaviour)component).enabled = false;
}
}
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "get_statusSum")]
public class StatusSum_Patch
{
private static void Postfix(CharacterAfflictions __instance, ref float __result)
{
if (!((Object)(object)__instance?.character == (Object)null) && __instance.character.IsLocal)
{
float currentStatus = __instance.GetCurrentStatus((STATUSTYPE)7);
if (ClassManager.IsScoutActive())
{
__result = __result - currentStatus + currentStatus * 0.5f;
}
else if (ClassManager.IsGeneralActive())
{
__result = __result - currentStatus + currentStatus * 2f;
}
else if (ClassManager.IsTechPriestActive() && ClassCheckUtil.IsTechPriest(__instance.character))
{
__result -= currentStatus;
}
}
}
}
[HarmonyPatch(typeof(CharacterAfflictions), "UpdateNormalStatuses")]
public class UpdateStatus_TechPriest_Patch
{
private static void Postfix(CharacterAfflictions __instance)
{
if ((Object)(object)__instance?.character != (Object)null && ClassCheckUtil.IsTechPriest(__instance.character) && ClassManager.IsTechPriestActive())
{
__instance.currentStatuses[1] = 0f;
__instance.currentStatuses[7] = 0f;
}
}
}
[HarmonyPatch(typeof(Affliction_PoisonOverTime), "OnApplied")]
public class PoisonPatch
{
private static bool Prefix(Affliction_PoisonOverTime __instance)
{
return (Object)(object)((Affliction)(__instance?)).character == (Object)null || !ClassCheckUtil.IsMushroom(((Affliction)__instance).character);
}
}
[HarmonyPatch(typeof(CharacterMovement), "EvaluateGroundChecks")]
public class RogueJumpPatch
{
private static void Postfix(CharacterMovement __instance)
{
Character val = ((__instance != null) ? ((Component)__instance).GetComponent<Character>() : null);
if ((Object)(object)val != (Object)null && val.IsLocal && PeakClassModPlugin.rogueActive)
{
val.data.jumpsRemaining = 2;
}
}
}
[HarmonyPatch(typeof(CharacterMovement), "TryToJump")]
public class RogueJumpRPCPatch
{
private static bool Prefix(CharacterMovement __instance)
{
Character val = ((__instance != null) ? ((Component)__instance).GetComponent<Character>() : null);
if ((Object)(object)val != (Object)null && val.IsLocal && PeakClassModPlugin.rogueActive && val.data.jumpsRemaining > 0 && val.data.currentStamina > 0.005f)
{
CharacterData data = val.data;
data.jumpsRemaining--;
val.data.chargingJump = true;
CharacterRefs refs = val.refs;
if (refs != null)
{
PhotonView view = refs.view;
if (view != null)
{
view.RPC("JumpRpc", (RpcTarget)0, new object[1] { false });
}
}
return false;
}
return true;
}
}
[HarmonyPatch(typeof(Character), "UseStamina")]
public class Character_UseStamina_Patch
{
private static void Prefix(Character __instance, ref float usage)
{
if (!((Object)(object)__instance == (Object)null) && __instance.IsLocal)
{
if (ClassManager.IsScoutActive())
{
usage *= 0.8f;
}
else if (ClassManager.IsRogueActive())
{
usage *= 1.7f;
}
}
}
}
internal static class TechPriestBlocker
{
private static readonly HashSet<string> BlockedTypeNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "heal", "cure", "medicine", "restorehealth" };
private static readonly HashSet<string> BlockedItemNames = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "bandage", "firstaid", "medkit", "cure", "marshmallow" };
private static Dictionary<int, bool> _blockCache = new Dictionary<int, bool>();
public static bool ShouldBlockItem(Item item)
{
if ((Object)(object)item == (Object)null)
{
return false;
}
int instanceID = ((Object)item).GetInstanceID();
if (_blockCache.TryGetValue(instanceID, out var value))
{
return value;
}
bool flag = false;
if ((Object)(object)((Component)item).GetComponent<Action_RestoreHunger>() != (Object)null || (Object)(object)((Component)item).GetComponent<Action_GiveExtraStamina>() != (Object)null)
{
flag = true;
}
if (!flag)
{
string text = ((Object)item).name?.Replace("(Clone)", "").Trim() ?? "";
foreach (string blockedItemName in BlockedItemNames)
{
if (text.IndexOf(blockedItemName, StringComparison.OrdinalIgnoreCase) >= 0)
{
flag = true;
break;
}
}
}
if (!flag)
{
MonoBehaviour[] components = ((Component)item).GetComponents<MonoBehaviour>();
foreach (MonoBehaviour val in components)
{
if ((Object)(object)val == (Object)null)
{
continue;
}
string name = ((object)val).GetType().Name;
foreach (string blockedTypeName in BlockedTypeNames)
{
if (name.IndexOf(blockedTypeName, StringComparison.OrdinalIgnoreCase) >= 0)
{
flag = true;
break;
}
}
if (flag)
{
break;
}
}
}
_blockCache[instanceID] = flag;
return flag;
}
public static void ClearCache()
{
_blockCache.Clear();
}
}
internal static class TechPriestItemChecker
{
public static bool ShouldBlockUse(Item item)
{
if ((Object)(object)item == (Object)null || (Object)(object)item.holderCharacter == (Object)null || !ClassCheckUtil.IsTechPriest(item.holderCharacter))
{
return false;
}
if (TechPriestBlocker.ShouldBlockItem(item))
{
return true;
}
Action_ApplyAffliction component = ((Component)item).GetComponent<Action_ApplyAffliction>();
return component?.affliction != null && ((object)component.affliction).GetType().Name.Contains("FasterBoi");
}
}
[HarmonyPatch(typeof(Item), "StartUsePrimary")]
[HarmonyPriority(400)]
public class TechPriestConsumablePatch1
{
private static bool Prefix(Item __instance)
{
return !TechPriestItemChecker.ShouldBlockUse(__instance);
}
}
[HarmonyPatch(typeof(Item), "StartUseSecondary")]
[HarmonyPriority(400)]
public class TechPriestConsumablePatch2
{
private static bool Prefix(Item __instance)
{
return !TechPriestItemChecker.ShouldBlockUse(__instance);
}
}
[HarmonyPatch(typeof(Affliction_FasterBoi), "OnApplied")]
public class TechPriestFasterBoiBlock
{
private static bool Prefix(Affliction_FasterBoi __instance)
{
return (Object)(object)((Affliction)(__instance?)).character == (Object)null || !ClassCheckUtil.IsTechPriest(((Affliction)__instance).character);
}
}
[HarmonyPatch(typeof(Character), "AddExtraStamina")]
public class TechPriestStaminaPatch1
{
private static bool Prefix(Character __instance)
{
return (Object)(object)__instance == (Object)null || !ClassCheckUtil.IsTechPriest(__instance);
}
}
[HarmonyPatch(typeof(Affliction_InfiniteStamina), "OnApplied")]
public class TechPriestStaminaPatch2
{
private static bool Prefix(Affliction_InfiniteStamina __instance)
{
return (Object)(object)((Affliction)(__instance?)).character == (Object)null || !ClassCheckUtil.IsTechPriest(((Affliction)__instance).character);
}
}
[HarmonyPatch(typeof(Affliction_InfiniteStamina), "UpdateEffect")]
public class TechPriestStaminaPatch2_Update
{
private static bool Prefix(Affliction_InfiniteStamina __instance)
{
return (Object)(object)((Affliction)(__instance?)).character == (Object)null || !ClassCheckUtil.IsTechPriest(((Affliction)__instance).character);
}
}