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 JGRPG v0.1.61
BepInEx/plugins/JGRPG.dll
Decompiled 5 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.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Configuration; using HarmonyLib; using Jotunn; using Jotunn.Configs; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using TMPro; using UnityEngine; using UnityEngine.EventSystems; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("JGRPG")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("JGRPG")] [assembly: AssemblyCopyright("Copyright © 2021")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("e3243d22-4307-4008-ba36-9f326008cde5")] [assembly: AssemblyFileVersion("0.1.61")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("0.1.61.0")] namespace JGRPG; internal static class AbilityBuffStatusEffects { private static bool _registered; private static StatusEffect _huntersMark; private static StatusEffect _explosiveShot; private static StatusEffect _rangersRally; private static StatusEffect _ullrsQuiver; private static StatusEffect _rage; private static StatusEffect _fury; private static StatusEffect _vorpal; private static StatusEffect _thorsHammer; private static StatusEffect _fortify; private static StatusEffect _guardiansRally; private static StatusEffect _retaliation; public static void Register() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0059: 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_00b3: Unknown result type (might be due to invalid IL or missing references) //IL_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_010d: Unknown result type (might be due to invalid IL or missing references) //IL_013a: Unknown result type (might be due to invalid IL or missing references) //IL_0167: Unknown result type (might be due to invalid IL or missing references) //IL_0194: Unknown result type (might be due to invalid IL or missing references) //IL_01c1: Unknown result type (might be due to invalid IL or missing references) //IL_01ee: Unknown result type (might be due to invalid IL or missing references) if (!_registered) { _registered = true; _huntersMark = CreateStatusEffect("JGRPG_HuntersMarkDisplay", "Hunter's Mark", new Color(0.65f, 0.2f, 0.2f, 1f)); _explosiveShot = CreateStatusEffect("JGRPG_ExplosiveShotDisplay", "Explosive Shot", new Color(0.85f, 0.4f, 0.12f, 1f)); _rangersRally = CreateStatusEffect("JGRPG_RangersRallyDisplay", "Ranger's Rally", new Color(0.2f, 0.6f, 0.25f, 1f)); _ullrsQuiver = CreateStatusEffect("JGRPG_UllrsQuiverDisplay", "Ullr's Quiver", new Color(0.2f, 0.45f, 0.75f, 1f)); _rage = CreateStatusEffect("JGRPG_RageDisplay", "Rage", new Color(0.75f, 0.12f, 0.08f, 1f)); _fury = CreateStatusEffect("JGRPG_FuryDisplay", "Fury", new Color(0.85f, 0.3f, 0.08f, 1f)); _vorpal = CreateStatusEffect("JGRPG_VorpalDisplay", "Vorpal", new Color(0.55f, 0.1f, 0.65f, 1f)); _thorsHammer = CreateStatusEffect("JGRPG_ThorsHammerDisplay", "Thor's Hammer", new Color(0.25f, 0.55f, 0.9f, 1f)); _fortify = CreateStatusEffect("JGRPG_FortifyDisplay", "Fortify", new Color(0.3f, 0.45f, 0.65f, 1f)); _guardiansRally = CreateStatusEffect("JGRPG_GuardiansRallyDisplay", "Guardian's Rally", new Color(0.45f, 0.6f, 0.8f, 1f)); _retaliation = CreateStatusEffect("JGRPG_RetaliationDisplay", "Retaliation", new Color(0.7f, 0.25f, 0.2f, 1f)); RegisterEffect(_huntersMark); RegisterEffect(_explosiveShot); RegisterEffect(_rangersRally); RegisterEffect(_ullrsQuiver); RegisterEffect(_rage); RegisterEffect(_fury); RegisterEffect(_vorpal); RegisterEffect(_thorsHammer); RegisterEffect(_fortify); RegisterEffect(_guardiansRally); RegisterEffect(_retaliation); } } public static void ShowHuntersMark(float duration) { ShowOnLocalPlayer(_huntersMark, duration); } public static void ShowExplosiveShot(float duration) { ShowOnLocalPlayer(_explosiveShot, duration); } public static void ShowUllrsQuiver(float duration) { ShowOnLocalPlayer(_ullrsQuiver, duration); } public static void ShowRage(float duration) { ShowOnLocalPlayer(_rage, duration); } public static void ShowFury(float duration) { ShowOnLocalPlayer(_fury, duration); } public static void ShowVorpal(float duration) { ShowOnLocalPlayer(_vorpal, duration); } public static void ShowThorsHammer(float duration) { ShowOnLocalPlayer(_thorsHammer, duration); } public static void ShowFortify(float duration) { ShowOnLocalPlayer(_fortify, duration); } public static void ShowRetaliation(float duration) { ShowOnLocalPlayer(_retaliation, duration); } public static void ShowGuardiansRally(float duration, float radius) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } List<Player> list = new List<Player>(); Player.GetPlayersInRange(((Component)localPlayer).transform.position, radius, list); foreach (Player item in list) { if (TankGuardianRally.Affects(item)) { ShowOnPlayer(item, _guardiansRally, duration); } } } public static void ShowForActivatedAbility(int slot) { if (CharacterProgression.Class == CharacterClass.Tank) { switch (slot) { case 2: ShowFortify(TankAbilities.GetFortifyDuration()); break; case 4: ShowGuardiansRally(TankGuardianRally.GetDuration(), TankGuardianRally.GetRadius()); break; case 1: case 3: case 5: break; } } else if (CharacterProgression.Class == CharacterClass.Berserker) { switch (slot) { case 1: ShowRage(BerserkerAbilities.GetRageDuration()); break; case 3: ShowFury(BerserkerAbilities.GetFuryDuration()); break; case 4: ShowVorpal(BerserkerAbilities.GetVorpalDuration()); break; case 5: ShowThorsHammer(BerserkerAbilities.GetThorsHammerDuration()); break; case 2: break; } } else if (CharacterProgression.Class == CharacterClass.Ranger) { switch (slot) { case 1: ShowHuntersMark(10f); break; case 2: ShowExplosiveShot(10f); break; case 4: ShowRangersRally(10f + (float)CharacterProgression.GetTalentRank("Ranger_ExtendedRally"), 20f); break; case 5: ShowUllrsQuiver(10f); break; case 3: break; } } } public static void ShowRangersRally(float duration, float radius) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } List<Player> list = new List<Player>(); Player.GetPlayersInRange(((Component)localPlayer).transform.position, radius, list); foreach (Player item in list) { ShowOnPlayer(item, _rangersRally, duration); } } private static void ShowOnLocalPlayer(StatusEffect effect, float duration) { ShowOnPlayer(Player.m_localPlayer, effect, duration); } private static void ShowOnPlayer(Player player, StatusEffect effect, float duration) { if (!((Object)(object)player == (Object)null) && !((Object)(object)effect == (Object)null) && !(duration <= 0f)) { StatusEffect val = ((Character)player).GetSEMan().AddStatusEffect(effect, true, 0, 0f, (short)(-1)); if (!((Object)(object)val == (Object)null)) { val.m_ttl = duration; val.ResetTime(); } } } private static void RegisterEffect(StatusEffect effect) { //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Expected O, but got Unknown ItemManager.Instance.AddStatusEffect(new CustomStatusEffect(effect, false)); } private static StatusEffect CreateStatusEffect(string internalName, string displayName, Color iconColor) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) StatusEffect obj = ScriptableObject.CreateInstance<StatusEffect>(); ((Object)obj).name = internalName; obj.m_name = displayName; obj.m_icon = CreateIcon(iconColor); obj.m_ttl = 10f; return obj; } private static Sprite CreateIcon(Color fillColor) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00ae: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) Texture2D val = new Texture2D(32, 32, (TextureFormat)4, false); ((Object)val).name = "JGRPG_AbilityStatusIcon"; ((Texture)val).filterMode = (FilterMode)0; ((Texture)val).wrapMode = (TextureWrapMode)1; Color val2 = default(Color); ((Color)(ref val2))..ctor(0.05f, 0.05f, 0.05f, 1f); for (int i = 0; i < 32; i++) { for (int j = 0; j < 32; j++) { bool flag = j < 3 || i < 3 || j >= 29 || i >= 29; val.SetPixel(j, i, flag ? val2 : fillColor); } } val.Apply(); return Sprite.Create(val, new Rect(0f, 0f, 32f, 32f), new Vector2(0.5f, 0.5f), 100f); } } [HarmonyPatch(typeof(ClassAbilityCooldowns), "StartCooldown")] internal static class AbilityDisplayCooldownPatch { [HarmonyPostfix] private static void Postfix(object[] __args) { if (__args != null && __args.Length >= 1 && __args[0] != null) { int slot; try { slot = Convert.ToInt32(__args[0]); } catch { return; } AbilityBuffStatusEffects.ShowForActivatedAbility(slot); AbilityHUD.Refresh(); } } } [HarmonyPatch(typeof(ClassAbilityManager), "TryActivate")] internal static class ClassAbilityUnlockPatch { [HarmonyPrefix] private static bool Prefix(object[] __args) { if (__args == null || __args.Length < 1 || __args[0] == null) { return true; } if (CharacterProgression.Class == CharacterClass.None) { return true; } int slot; try { slot = Convert.ToInt32(__args[0]); } catch { return true; } return ClassAbilityUnlocks.IsUnlocked(slot); } } [HarmonyPatch(typeof(Player), "UseHotbarItem")] internal static class AbilityHotbarPatch { [HarmonyPrefix] private static bool Prefix(Player __instance, int __0) { //IL_004a: Unknown result type (might be due to invalid IL or missing references) //IL_004f: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) //IL_006c: 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_0089: Unknown result type (might be due to invalid IL or missing references) //IL_00a1: Unknown result type (might be due to invalid IL or missing references) //IL_00a6: 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) if ((Object)(object)__instance != (Object)(object)Player.m_localPlayer) { return true; } if (CharacterProgression.Class == CharacterClass.None) { return true; } KeyboardShortcut value; switch (__0) { case 1: if (JGRPG.Ability1KeyConfig != null) { value = JGRPG.Ability1KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return false; } } break; case 2: if (JGRPG.Ability2KeyConfig != null) { value = JGRPG.Ability2KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return false; } } break; case 3: if (JGRPG.Ability3KeyConfig != null) { value = JGRPG.Ability3KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return false; } } break; case 4: if (JGRPG.Ability4KeyConfig != null) { value = JGRPG.Ability4KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return false; } } break; case 5: if (JGRPG.Ability5KeyConfig != null) { value = JGRPG.Ability5KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { return false; } } break; } return true; } } internal static class AbilityHUD { private sealed class SlotView { public GameObject Root; public Image Background; public Text NameText; public Text CooldownText; } private static readonly SlotView[] Slots = new SlotView[6]; private static GameObject _root; private static bool _registered; private static readonly Color ReadyColor = new Color(0.08f, 0.08f, 0.08f, 0.82f); private static readonly Color CooldownColor = new Color(0.28f, 0.28f, 0.28f, 0.88f); public static void Register() { if (!_registered) { _registered = true; GUIManager.OnCustomGUIAvailable += Build; } } private static void Build() { //IL_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Expected O, but got Unknown //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00a4: Unknown result type (might be due to invalid IL or missing references) //IL_00b9: Unknown result type (might be due to invalid IL or missing references) //IL_00ce: Unknown result type (might be due to invalid IL or missing references) //IL_00e2: Unknown result type (might be due to invalid IL or missing references) if (GUIManager.IsHeadless()) { return; } if (Object.op_Implicit((Object)(object)_root)) { Object.Destroy((Object)(object)_root); } if (!((Object)(object)GUIManager.CustomGUIFront == (Object)null) && GUIManager.Instance != null) { _root = new GameObject("JGRPG_AbilityHUD", new Type[1] { typeof(RectTransform) }); _root.layer = 5; _root.transform.SetParent(GUIManager.CustomGUIFront.transform, false); RectTransform component = _root.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0f); component.anchorMax = new Vector2(0.5f, 0f); component.pivot = new Vector2(0.5f, 0f); component.anchoredPosition = new Vector2(0f, 135f); component.sizeDelta = new Vector2(900f, 70f); _root.AddComponent<AbilityHUDUpdater>(); for (int i = 1; i <= 5; i++) { CreateSlot(i); } Refresh(); } } private static void CreateSlot(int slot) { //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Expected O, but got Unknown //IL_0071: 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_009b: 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_00c9: Unknown result type (might be due to invalid IL or missing references) //IL_00db: 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_010e: Unknown result type (might be due to invalid IL or missing references) //IL_011d: 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_0134: Unknown result type (might be due to invalid IL or missing references) //IL_0170: Unknown result type (might be due to invalid IL or missing references) //IL_017f: 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_019f: Unknown result type (might be due to invalid IL or missing references) //IL_01a5: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject($"JGRPG_Ability_{slot}", new Type[3] { typeof(RectTransform), typeof(CanvasRenderer), typeof(Image) }); val.layer = 5; val.transform.SetParent(_root.transform, false); RectTransform component = val.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.5f, 0.5f); component.anchorMax = new Vector2(0.5f, 0.5f); component.pivot = new Vector2(0.5f, 0.5f); component.sizeDelta = new Vector2(166f, 58f); component.anchoredPosition = new Vector2((float)(slot - 3) * 174f, 0f); Image component2 = val.GetComponent<Image>(); ((Graphic)component2).color = ReadyColor; Text component3 = GUIManager.Instance.CreateText("", val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 10f), GUIManager.Instance.AveriaSerifBold, 15, Color.white, true, Color.black, 158f, 28f, false).GetComponent<Text>(); component3.alignment = (TextAnchor)4; Text component4 = GUIManager.Instance.CreateText("", val.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, -14f), GUIManager.Instance.AveriaSerifBold, 19, Color.white, true, Color.black, 158f, 28f, false).GetComponent<Text>(); component4.alignment = (TextAnchor)4; Slots[slot] = new SlotView { Root = val, Background = component2, NameText = component3, CooldownText = component4 }; } public static void Refresh() { //IL_00dd: Unknown result type (might be due to invalid IL or missing references) //IL_00d6: Unknown result type (might be due to invalid IL or missing references) //IL_010c: 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) if (!Object.op_Implicit((Object)(object)_root)) { return; } if ((Object)(object)Player.m_localPlayer == (Object)null || CharacterProgression.Class == CharacterClass.None) { for (int i = 1; i <= 5; i++) { SlotView slotView = Slots[i]; if (slotView != null && Object.op_Implicit((Object)(object)slotView.Root)) { slotView.Root.SetActive(false); } } return; } for (int j = 1; j <= 5; j++) { SlotView slotView2 = Slots[j]; if (slotView2 != null && Object.op_Implicit((Object)(object)slotView2.Root)) { string abilityName = GetAbilityName(CharacterProgression.Class, j); bool flag = !string.IsNullOrEmpty(abilityName) && ClassAbilityUnlocks.IsUnlocked(j); slotView2.Root.SetActive(flag); if (flag) { slotView2.NameText.text = abilityName; float remaining = ClassAbilityCooldowns.GetRemaining(j); bool flag2 = remaining > 0f; ((Graphic)slotView2.Background).color = (flag2 ? CooldownColor : ReadyColor); ((Graphic)slotView2.NameText).color = (Color)(flag2 ? new Color(0.72f, 0.72f, 0.72f, 1f) : Color.white); slotView2.CooldownText.text = (flag2 ? $"{remaining:0.0}s" : ""); } } } } private static string GetAbilityName(CharacterClass characterClass, int slot) { if (characterClass == CharacterClass.Ranger) { switch (slot) { case 1: return "Hunter's Mark"; case 2: return "Explosive Shot"; case 3: return "Rapid Shot"; case 4: return "Ranger's Rally"; case 5: return "Ullr's Quiver"; } } if (characterClass == CharacterClass.Tank) { switch (slot) { case 1: return "Provoke"; case 2: return "Fortify"; case 3: return "Thunderclap"; case 4: return "Guardian's Rally"; case 5: return "Odin's Glare"; } } if (characterClass == CharacterClass.Berserker) { switch (slot) { case 1: return "Rage"; case 2: return "Whirlwind"; case 3: return "Fury"; case 4: return "Vorpal"; case 5: return "Thor's Hammer"; } } return null; } } internal sealed class AbilityHUDUpdater : MonoBehaviour { private float _nextUpdate; private void Update() { if (!(Time.unscaledTime < _nextUpdate)) { _nextUpdate = Time.unscaledTime + 0.05f; AbilityHUD.Refresh(); } } } [HarmonyPatch(typeof(Player), "OnDestroy")] internal static class AbilityCooldownLogoutResetPatch { [HarmonyPrefix] private static void Prefix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ClassAbilityCooldowns.ClearAll(); Logger.LogInfo((object)"JGRPG ability cooldowns cleared because the local player was destroyed."); } } } internal static class BerserkerAbilities { private static float _rageEndTime; private static Player _ragePlayer; private static float _furyEndTime; private static Player _furyPlayer; private static float _vorpalEndTime; private static Player _vorpalPlayer; private static float _thorsHammerEndTime; private static Player _thorsHammerPlayer; public static void TryActivate(int abilitySlot) { switch (abilitySlot) { case 1: TryActivateRage(); break; case 2: TryActivateWhirlwind(); break; case 3: TryActivateFury(); break; case 4: TryActivateVorpal(); break; case 5: TryActivateThorsHammer(); break; default: Logger.LogInfo((object)("JGRPG Berserker ability " + $"{abilitySlot} not implemented yet.")); break; } } private static void TryActivateRage() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(1)) { float rageDuration = GetRageDuration(); float rageCooldown = GetRageCooldown(); _ragePlayer = localPlayer; _rageEndTime = Time.time + rageDuration; ClassAbilityCooldowns.StartCooldown(1, rageCooldown); Logger.LogInfo((object)("JGRPG Rage activated. " + $"Duration: {rageDuration:0.0}s. " + "Melee Damage: +10%. Incoming Damage: " + $"+{GetRageIncomingDamageBonus() * 100f:0}%. " + $"Cooldown: {rageCooldown:0.0}s.")); } } private static void TryActivateWhirlwind() { //IL_0031: 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_0080: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e1: Expected O, but got Unknown //IL_00e4: Unknown result type (might be due to invalid IL or missing references) //IL_00e9: Unknown result type (might be due to invalid IL or missing references) //IL_0121: Unknown result type (might be due to invalid IL or missing references) //IL_0178: Unknown result type (might be due to invalid IL or missing references) //IL_017d: Unknown result type (might be due to invalid IL or missing references) //IL_0186: 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_0197: Unknown result type (might be due to invalid IL or missing references) //IL_01a2: Unknown result type (might be due to invalid IL or missing references) //IL_01a7: 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_01d7: Unknown result type (might be due to invalid IL or missing references) //IL_01dc: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Unknown result type (might be due to invalid IL or missing references) //IL_01e2: Unknown result type (might be due to invalid IL or missing references) //IL_01f2: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null || CharacterProgression.Class != CharacterClass.Berserker || !ClassAbilityCooldowns.IsReady(2)) { return; } ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon(); if (currentWeapon == null || !BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType) || !((Character)localPlayer).HaveStamina(30f)) { return; } float whirlwindRadius = GetWhirlwindRadius(); float whirlwindCooldown = GetWhirlwindCooldown(); float randomSkillFactor = ((Character)localPlayer).GetRandomSkillFactor(currentWeapon.m_shared.m_skillType); float totalMeleeDamageMultiplier = BerserkerPassiveBonuses.GetTotalMeleeDamageMultiplier(localPlayer); List<Character> list = new List<Character>(); Character.GetCharactersInRange(((Component)localPlayer).transform.position, whirlwindRadius, list); int num = 0; foreach (Character item in list) { if (!((Object)(object)item == (Object)null) && !((Object)(object)item == (Object)(object)localPlayer) && !item.IsDead() && BaseAI.IsEnemy((Character)(object)localPlayer, item)) { HitData val = new HitData(); val.m_damage = currentWeapon.GetDamage(); ((DamageTypes)(ref val.m_damage)).Modify(0.75f * randomSkillFactor * totalMeleeDamageMultiplier); val.m_toolTier = (short)currentWeapon.m_shared.m_toolTier; val.m_skillLevel = ((Character)localPlayer).GetSkillLevel(currentWeapon.m_shared.m_skillType); val.m_itemLevel = (short)currentWeapon.m_quality; val.m_itemWorldLevel = (byte)currentWeapon.m_worldLevel; val.m_blockable = currentWeapon.m_shared.m_blockable; val.m_dodgeable = currentWeapon.m_shared.m_dodgeable; val.m_skill = currentWeapon.m_shared.m_skillType; val.m_point = item.GetCenterPoint(); Vector3 dir = ((Component)item).transform.position - ((Component)localPlayer).transform.position; dir.y = 0f; if (((Vector3)(ref dir)).sqrMagnitude > 0.001f) { ((Vector3)(ref dir)).Normalize(); } else { dir = ((Component)localPlayer).transform.forward; } val.m_dir = dir; val.SetAttacker((Character)(object)localPlayer); val.m_hitType = (HitType)2; item.Damage(val); num++; } } ((Character)localPlayer).UseStamina(30f); ClassAbilityCooldowns.StartCooldown(2, whirlwindCooldown); Logger.LogInfo((object)("JGRPG Whirlwind activated. " + $"Radius: {whirlwindRadius:0.0}m. " + "Damage: 75% weapon damage. " + $"Targets hit: {num}. " + $"Stamina: {30f:0}. " + $"Cooldown: {whirlwindCooldown:0.0}s.")); } private static void TryActivateFury() { Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(3) && ((Character)localPlayer).HaveStamina(40f)) { float furyHealthFraction = GetFuryHealthFraction(); float num = ((Character)localPlayer).GetMaxHealth() * furyHealthFraction; if (((Character)localPlayer).GetHealth() > num) { ((Character)localPlayer).SetHealth(num); } _furyPlayer = localPlayer; _furyEndTime = Time.time + GetFuryDuration(); localPlayer.m_foodRegenTimer = 0f; ((Character)localPlayer).UseStamina(40f); float furyCooldown = GetFuryCooldown(); ClassAbilityCooldowns.StartCooldown(3, furyCooldown); Logger.LogInfo((object)("JGRPG Fury activated. Health floor: " + $"{furyHealthFraction * 100f:0}% max HP. " + $"Duration: {GetFuryDuration():0.0}s. " + "Health Regen: 0. " + $"Stamina: {40f:0}. " + $"Cooldown: {furyCooldown:0.0}s.")); } } private static void TryActivateVorpal() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(4)) { ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon(); if (currentWeapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType) && ((Character)localPlayer).HaveStamina(30f)) { float vorpalDuration = GetVorpalDuration(); float vorpalCooldown = GetVorpalCooldown(); _vorpalPlayer = localPlayer; _vorpalEndTime = Time.time + vorpalDuration; ((Character)localPlayer).UseStamina(30f); ClassAbilityCooldowns.StartCooldown(4, vorpalCooldown); Logger.LogInfo((object)("JGRPG Vorpal activated. " + $"Duration: {vorpalDuration:0.0}s. " + "Execute threshold: 30% HP. Damage: +50%. " + $"Stamina: {30f:0}. " + $"Cooldown: {vorpalCooldown:0.0}s.")); } } } private static void TryActivateThorsHammer() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if (!((Object)(object)localPlayer == (Object)null) && CharacterProgression.Class == CharacterClass.Berserker && ClassAbilityCooldowns.IsReady(5)) { ItemData currentWeapon = ((Humanoid)localPlayer).GetCurrentWeapon(); if (currentWeapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType) && ((Character)localPlayer).HaveStamina(50f)) { float thorsHammerDuration = GetThorsHammerDuration(); float thorsHammerCooldown = GetThorsHammerCooldown(); _thorsHammerPlayer = localPlayer; _thorsHammerEndTime = Time.time + thorsHammerDuration; ((Character)localPlayer).UseStamina(50f); ClassAbilityCooldowns.StartCooldown(5, thorsHammerCooldown); Logger.LogInfo((object)("JGRPG Thor's Hammer activated. " + $"Duration: {thorsHammerDuration:0.0}s. " + "Melee Damage: +20%. Physical Damage: converted to Lightning. " + $"Stamina: {50f:0}. " + $"Cooldown: {thorsHammerCooldown:0.0}s.")); } } } public static bool IsRageActive() { return IsRageActive(Player.m_localPlayer); } public static bool IsRageActive(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)_ragePlayer == (Object)null || (Object)(object)player != (Object)(object)_ragePlayer || CharacterProgression.Class != CharacterClass.Berserker) { return false; } if (((Character)player).IsDead()) { ClearActiveEffects(); return false; } if (Time.time >= _rageEndTime) { ClearActiveEffects(); return false; } return true; } public static float GetRageDuration() { if (CharacterProgression.GetTalentRank("Berserker_EndlessRage") <= 0) { return 10f; } return 60f; } public static float GetRageCooldown() { int talentRank = CharacterProgression.GetTalentRank("Berserker_QuickenedRage"); return Mathf.Max(0f, 20f - (float)talentRank); } public static float GetRageIncomingDamageBonus() { int talentRank = CharacterProgression.GetTalentRank("Berserker_PainResistant"); return Mathf.Max(0f, 0.1f - (float)talentRank * 0.01f); } public static float GetWhirlwindRadius() { int talentRank = CharacterProgression.GetTalentRank("Berserker_OdinsRage"); return 5f + (float)talentRank * 2.5f; } public static float GetWhirlwindCooldown() { int talentRank = CharacterProgression.GetTalentRank("Berserker_OdinsPresence"); return Mathf.Max(0f, 30f - (float)talentRank); } public static bool IsFuryActive() { return IsFuryActive(Player.m_localPlayer); } public static bool IsFuryActive(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)_furyPlayer == (Object)null || (Object)(object)player != (Object)(object)_furyPlayer || CharacterProgression.Class != CharacterClass.Berserker) { return false; } if (((Character)player).IsDead()) { ClearFury(); return false; } if (Time.time >= _furyEndTime) { ClearFury(); return false; } return true; } public static float GetFuryDuration() { return 10f; } public static float GetFuryHealthFraction() { int talentRank = CharacterProgression.GetTalentRank("Berserker_ReasonedFury"); return 0.3f + (float)talentRank * 0.05f; } public static float GetFuryCooldown() { int talentRank = CharacterProgression.GetTalentRank("Berserker_QuickFury"); return Mathf.Max(0f, 30f - (float)talentRank * 2f); } private static void ClearFury() { _furyEndTime = 0f; _furyPlayer = null; } public static bool IsVorpalActive() { return IsVorpalActive(Player.m_localPlayer); } public static bool IsVorpalActive(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)_vorpalPlayer == (Object)null || (Object)(object)player != (Object)(object)_vorpalPlayer || CharacterProgression.Class != CharacterClass.Berserker) { return false; } if (((Character)player).IsDead()) { ClearVorpal(); return false; } if (Time.time >= _vorpalEndTime) { ClearVorpal(); return false; } return true; } public static float GetVorpalDuration() { return 10f; } public static float GetVorpalCooldown() { int talentRank = CharacterProgression.GetTalentRank("Berserker_Slayer"); return Mathf.Max(0f, 30f - (float)talentRank); } private static void ClearVorpal() { _vorpalEndTime = 0f; _vorpalPlayer = null; } public static bool IsThorsHammerActive() { return IsThorsHammerActive(Player.m_localPlayer); } public static bool IsThorsHammerActive(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)_thorsHammerPlayer == (Object)null || (Object)(object)player != (Object)(object)_thorsHammerPlayer || CharacterProgression.Class != CharacterClass.Berserker) { return false; } if (((Character)player).IsDead()) { ClearThorsHammer(); return false; } if (Time.time >= _thorsHammerEndTime) { ClearThorsHammer(); return false; } return true; } public static float GetThorsHammerDuration() { return 10f; } public static float GetThorsHammerCooldown() { int talentRank = CharacterProgression.GetTalentRank("Berserker_ThorsMight"); return Mathf.Max(0f, 60f - (float)talentRank * 5f); } private static void ClearThorsHammer() { _thorsHammerEndTime = 0f; _thorsHammerPlayer = null; } public static void ClearActiveEffects() { _rageEndTime = 0f; _ragePlayer = null; ClearFury(); ClearVorpal(); ClearThorsHammer(); } } [HarmonyPatch(typeof(Player), "OnDeath")] internal static class BerserkerRageDeathPatch { [HarmonyPrefix] private static void Prefix(Player __instance) { if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { BerserkerAbilities.ClearActiveEffects(); ClassAbilityCooldowns.ClearAll(); AbilityHUD.Refresh(); } } } [HarmonyPatch(typeof(Player), "PlayerAttackInput")] internal static class BerserkerAttackSpeedPatch { private static Animator _animator; private static float _baseAnimatorSpeed = 1f; private static float _lastAppliedSpeed = 1f; private static bool _applied; [HarmonyPostfix] private static void Postfix(Player __instance) { if (!((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { Animator animator = ((Character)__instance).m_animator; if ((Object)(object)animator == (Object)null) { ClearState(); return; } if (!ShouldBoostAttack(__instance)) { RestoreAnimator(animator); return; } float attackSpeedMultiplier = GetAttackSpeedMultiplier(); ApplyMultiplier(animator, attackSpeedMultiplier); } } private static bool ShouldBoostAttack(Player player) { //IL_0026: Unknown result type (might be due to invalid IL or missing references) if (CharacterProgression.Class != CharacterClass.Berserker) { return false; } if (GetTotalAttackSpeedRanks() <= 0) { return false; } ItemData currentWeapon = ((Humanoid)player).GetCurrentWeapon(); if (currentWeapon == null) { return false; } if (!BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType)) { return false; } return ((Character)player).InAttack(); } private static int GetTotalAttackSpeedRanks() { return CharacterProgression.GetTalentRank("Berserker_AttackSpeed1") + CharacterProgression.GetTalentRank("Berserker_AttackSpeed2") + CharacterProgression.GetTalentRank("Berserker_AttackSpeed3"); } private static float GetAttackSpeedMultiplier() { int totalAttackSpeedRanks = GetTotalAttackSpeedRanks(); return 1f + (float)totalAttackSpeedRanks * 0.025f; } private static void ApplyMultiplier(Animator animator, float multiplier) { float speed = animator.speed; if (!_applied || (Object)(object)_animator != (Object)(object)animator) { _animator = animator; _baseAnimatorSpeed = speed; } else if (Mathf.Abs(speed - _lastAppliedSpeed) > 0.0001f) { _baseAnimatorSpeed = speed; } float lastAppliedSpeed = (animator.speed = _baseAnimatorSpeed * multiplier); _lastAppliedSpeed = lastAppliedSpeed; _applied = true; } private static void RestoreAnimator(Animator animator) { if (_applied) { if ((Object)(object)_animator == (Object)(object)animator && Mathf.Abs(animator.speed - _lastAppliedSpeed) <= 0.0001f) { animator.speed = _baseAnimatorSpeed; } ClearState(); } } private static void ClearState() { _animator = null; _baseAnimatorSpeed = 1f; _lastAppliedSpeed = 1f; _applied = false; } } [HarmonyPatch(typeof(Player), "UpdateFood")] internal static class BerserkerFuryHealthRegenPatch { [HarmonyPrefix] private static void Prefix(Player __instance, bool forceUpdate) { if (!((Object)(object)__instance == (Object)null || (Object)(object)__instance != (Object)(object)Player.m_localPlayer || forceUpdate) && BerserkerAbilities.IsFuryActive(__instance)) { __instance.m_foodRegenTimer = 0f; } } } internal static class BerserkerPassiveBonuses { public static float GetMeleeDamageBonus() { return (float)(CharacterProgression.GetTalentRank("Berserker_MeleeDamage1") + CharacterProgression.GetTalentRank("Berserker_MeleeDamage2") + CharacterProgression.GetTalentRank("Berserker_MeleeDamage3")) * 0.03f; } public static float GetDesperationDamageBonus() { return (float)(CharacterProgression.GetTalentRank("Berserker_Desperation1") + CharacterProgression.GetTalentRank("Berserker_Desperation2") + CharacterProgression.GetTalentRank("Berserker_Desperation3")) * 0.05f; } public static float GetTotalMeleeDamageMultiplier(Player player) { float num = GetMeleeDamageBonus(); if ((Object)(object)player != (Object)null && ((Character)player).GetHealth() < ((Character)player).GetMaxHealth() * 0.5f) { num += GetDesperationDamageBonus(); } if (BerserkerAbilities.IsRageActive(player)) { num += 0.1f; } if (BerserkerAbilities.IsThorsHammerActive(player)) { num += 0.2f; } return 1f + num; } public static float GetStaminaRegenMultiplier() { int num = CharacterProgression.GetTalentRank("Berserker_StaminaRegeneration1") + CharacterProgression.GetTalentRank("Berserker_StaminaRegeneration2"); return 1f + (float)num * 0.05f; } public static float GetArmorBonus() { return (float)CharacterProgression.GetTalentRank("Berserker_Armored") * 5f; } public static float GetMaxStaminaBonus() { return (float)(CharacterProgression.GetTalentRank("Berserker_Endurance1") + CharacterProgression.GetTalentRank("Berserker_Endurance2")) * 5f; } public static float GetMovementSpeedMultiplier() { int num = CharacterProgression.GetTalentRank("Berserker_RelentlessPursuit1") + CharacterProgression.GetTalentRank("Berserker_RelentlessPursuit2"); return 1f + (float)num * 0.05f; } public static float GetMaxHealthBonus() { return (float)CharacterProgression.GetTalentRank("Berserker_Vitality1") * 5f; } public static float GetSprintStaminaReduction() { return Mathf.Clamp((float)CharacterProgression.GetTalentRank("Berserker_Tireless") * 0.05f, 0f, 0.95f); } public static float GetEndlessThirstStaminaFraction() { return Mathf.Clamp01((float)CharacterProgression.GetTalentRank("Berserker_EndlessThirst") * 0.04f); } public static float GetOdinsStrengthReduction() { return Mathf.Clamp((float)CharacterProgression.GetTalentRank("Berserker_OdinsStrength") * 0.025f, 0f, 0.95f); } public static float GetTooAngryToDieReduction() { return Mathf.Clamp((float)CharacterProgression.GetTalentRank("Berserker_TooAngryToDie") * 0.05f, 0f, 0.95f); } public static float GetIncomingDamageMultiplier(Player player) { if ((Object)(object)player == (Object)null) { return 1f; } float num = 0f; if (((Character)player).GetHealth() < ((Character)player).GetMaxHealth() * 0.5f) { num -= GetTooAngryToDieReduction(); } if (BerserkerAbilities.IsRageActive()) { num += BerserkerAbilities.GetRageIncomingDamageBonus(); } return 1f + num; } public static bool IsMeleeWeaponSkill(SkillType skillType) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0002: Invalid comparison between Unknown and I4 //IL_0004: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Invalid comparison between Unknown and I4 //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_000a: Invalid comparison between Unknown and I4 //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_000e: Invalid comparison between Unknown and I4 //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Invalid comparison between Unknown and I4 //IL_0014: Unknown result type (might be due to invalid IL or missing references) //IL_0016: Invalid comparison between Unknown and I4 if ((int)skillType != 7 && (int)skillType != 3 && (int)skillType != 2 && (int)skillType != 4 && (int)skillType != 5) { return (int)skillType == 1; } return true; } } [HarmonyPatch(typeof(Attack), "ModifyDamage")] internal static class BerserkerMeleeDamagePatch { [HarmonyPostfix] private static void Postfix(Attack __instance, HitData hitData) { //IL_0042: Unknown result type (might be due to invalid IL or missing references) if (CharacterProgression.Class == CharacterClass.Berserker && __instance != null && hitData != null && !((Object)(object)__instance.m_character == (Object)null) && !((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && __instance.m_weapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(__instance.m_weapon.m_shared.m_skillType)) { float totalMeleeDamageMultiplier = BerserkerPassiveBonuses.GetTotalMeleeDamageMultiplier(Player.m_localPlayer); if (totalMeleeDamageMultiplier != 1f) { ((DamageTypes)(ref hitData.m_damage)).Modify(totalMeleeDamageMultiplier); } } } } [HarmonyPatch(typeof(Player), "UpdateStats", new Type[] { typeof(float) })] internal static class BerserkerStaminaRegenPatch { [HarmonyPrefix] private static void Prefix(Player __instance, out float __state) { __state = -1f; if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { float staminaRegenMultiplier = BerserkerPassiveBonuses.GetStaminaRegenMultiplier(); if (staminaRegenMultiplier != 1f) { __state = __instance.m_staminaRegen; __instance.m_staminaRegen *= staminaRegenMultiplier; } } } [HarmonyPostfix] private static void Postfix(Player __instance, float __state) { if (!((Object)(object)__instance == (Object)null) && !(__state < 0f)) { __instance.m_staminaRegen = __state; } } } [HarmonyPatch(typeof(Player), "GetBodyArmor")] internal static class BerserkerArmoredPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float __result) { if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __result += BerserkerPassiveBonuses.GetArmorBonus(); } } } [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] internal static class BerserkerMaxStatsPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float hp, ref float stamina) { if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { hp += BerserkerPassiveBonuses.GetMaxHealthBonus(); stamina += BerserkerPassiveBonuses.GetMaxStaminaBonus(); } } } [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] internal static class BerserkerRelentlessPursuitJogPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float __result) { if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __result *= BerserkerPassiveBonuses.GetMovementSpeedMultiplier(); } } } [HarmonyPatch(typeof(Player), "GetRunSpeedFactor")] internal static class BerserkerRelentlessPursuitRunPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float __result) { if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __result *= BerserkerPassiveBonuses.GetMovementSpeedMultiplier(); } } } [HarmonyPatch(typeof(Player), "GetEquipmentRunStaminaModifier")] internal static class BerserkerTirelessPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float __result) { if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { __result -= BerserkerPassiveBonuses.GetSprintStaminaReduction(); } } } [HarmonyPatch(typeof(Player), "GetEquipmentAttackStaminaModifier")] internal static class BerserkerOdinsStrengthPatch { [HarmonyPostfix] private static void Postfix(Player __instance, ref float __result) { //IL_002f: Unknown result type (might be due to invalid IL or missing references) if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { ItemData currentWeapon = ((Humanoid)__instance).GetCurrentWeapon(); if (currentWeapon != null && BerserkerPassiveBonuses.IsMeleeWeaponSkill(currentWeapon.m_shared.m_skillType)) { __result -= BerserkerPassiveBonuses.GetOdinsStrengthReduction(); } } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class BerserkerTooAngryToDiePatch { [HarmonyPrefix] private static void Prefix(Character __instance, HitData hit) { if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)__instance != (Object)(object)Player.m_localPlayer)) { float incomingDamageMultiplier = BerserkerPassiveBonuses.GetIncomingDamageMultiplier(Player.m_localPlayer); if (incomingDamageMultiplier != 1f) { ((DamageTypes)(ref hit.m_damage)).Modify(incomingDamageMultiplier); } } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class BerserkerEndlessThirstPatch { [HarmonyPrefix] private static void Prefix(Character __instance, HitData hit, out bool __state) { __state = false; if (CharacterProgression.Class == CharacterClass.Berserker && !((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)Player.m_localPlayer == (Object)null)) { Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if (!((Object)(object)val == (Object)null) && !((Object)(object)val != (Object)(object)Player.m_localPlayer) && !__instance.IsDead() && !(__instance.GetHealth() <= 0f) && BaseAI.IsEnemy((Character)(object)val, __instance)) { __state = true; } } } [HarmonyPostfix] private static void Postfix(Character __instance, bool __state) { if (__state && !((Object)(object)__instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null) && (__instance.IsDead() || !(__instance.GetHealth() > 0f))) { float endlessThirstStaminaFraction = BerserkerPassiveBonuses.GetEndlessThirstStaminaFraction(); if (!(endlessThirstStaminaFraction <= 0f)) { Player localPlayer = Player.m_localPlayer; ((Character)localPlayer).AddStamina(((Character)localPlayer).GetMaxStamina() * endlessThirstStaminaFraction); } } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class BerserkerCombatAbilityDamagePatch { [HarmonyPrefix] private static void Prefix(Character __instance, HitData hit) { //IL_0046: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || hit == null || (Object)(object)Player.m_localPlayer == (Object)null || CharacterProgression.Class != CharacterClass.Berserker) { return; } Character attacker = hit.GetAttacker(); Player val = (Player)(object)((attacker is Player) ? attacker : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || !BerserkerPassiveBonuses.IsMeleeWeaponSkill(hit.m_skill) || hit.m_ranged) { return; } bool flag = BerserkerAbilities.IsVorpalActive(val); bool flag2 = BerserkerAbilities.IsThorsHammerActive(val); if (!flag && !flag2) { return; } if (flag) { float maxHealth = __instance.GetMaxHealth(); if (maxHealth > 0f && __instance.GetHealth() / maxHealth <= 0.3f) { float totalMeleeDamageMultiplier = BerserkerPassiveBonuses.GetTotalMeleeDamageMultiplier(val); if (totalMeleeDamageMultiplier > 0f) { float num = (totalMeleeDamageMultiplier + 0.5f) / totalMeleeDamageMultiplier; ((DamageTypes)(ref hit.m_damage)).Modify(num); } } } if (flag2) { float blunt = hit.m_damage.m_blunt; float slash = hit.m_damage.m_slash; float pierce = hit.m_damage.m_pierce; float num2 = blunt + slash + pierce; hit.m_damage.m_blunt = 0f; hit.m_damage.m_slash = 0f; hit.m_damage.m_pierce = 0f; hit.m_damage.m_lightning += num2; } } } internal static class BossProgression { public static int GetWorldLevelCap() { if ((Object)(object)ZoneSystem.instance == (Object)null) { return 10; } if (ZoneSystem.instance.GetGlobalKey("defeated_fader")) { return 90; } if (ZoneSystem.instance.GetGlobalKey("defeated_queen")) { return 70; } if (ZoneSystem.instance.GetGlobalKey("defeated_goblinking")) { return 60; } if (ZoneSystem.instance.GetGlobalKey("defeated_dragon")) { return 50; } if (ZoneSystem.instance.GetGlobalKey("defeated_bonemass")) { return 40; } if (ZoneSystem.instance.GetGlobalKey("defeated_gdking")) { return 30; } if (ZoneSystem.instance.GetGlobalKey("defeated_eikthyr")) { return 20; } return 10; } public static bool TryGetBossInfo(Character character, out string globalKey, out int newLevelCap) { globalKey = null; newLevelCap = 0; if ((Object)(object)character == (Object)null) { return false; } return TryGetBossInfo(((Object)character).name, out globalKey, out newLevelCap); } public static bool TryGetBossInfo(string prefabName, out string globalKey, out int newLevelCap) { globalKey = null; newLevelCap = 0; if (string.IsNullOrEmpty(prefabName)) { return false; } prefabName = prefabName.Replace("(Clone)", ""); switch (prefabName) { case "Eikthyr": globalKey = "defeated_eikthyr"; newLevelCap = 20; return true; case "gd_king": globalKey = "defeated_gdking"; newLevelCap = 30; return true; case "Bonemass": globalKey = "defeated_bonemass"; newLevelCap = 40; return true; case "Dragon": globalKey = "defeated_dragon"; newLevelCap = 50; return true; case "GoblinKing": globalKey = "defeated_goblinking"; newLevelCap = 60; return true; case "SeekerQueen": globalKey = "defeated_queen"; newLevelCap = 70; return true; case "Fader": globalKey = "defeated_fader"; newLevelCap = 90; return true; default: return false; } } } internal enum CharacterClass { None, Tank, Berserker, Ranger } internal static class CharacterProgression { public static CharacterClass Class { get; private set; } = CharacterClass.None; public static int AvailableTalentPoints { get { int num = WorldProgression.Level - SpentTalentPoints; if (num >= 0) { return num; } return 0; } } public static int SpentTalentPoints { get; private set; } = 0; public static Dictionary<string, int> TalentRanks { get; private set; } = new Dictionary<string, int>(); public static void SetClass(CharacterClass characterClass) { Class = characterClass; } public static void ChangeClass(CharacterClass characterClass) { Class = characterClass; SpentTalentPoints = 0; TalentRanks.Clear(); } public static void RestoreTalentRank(string talentId, int rank) { if (!string.IsNullOrWhiteSpace(talentId) && rank > 0) { if (TalentRanks.TryGetValue(talentId, out var value)) { SpentTalentPoints -= value; } TalentRanks[talentId] = rank; SpentTalentPoints += rank; } } public static int GetTalentRank(string talentId) { if (string.IsNullOrWhiteSpace(talentId)) { return 0; } if (TalentRanks.TryGetValue(talentId, out var value)) { return value; } return 0; } public static bool TryPurchaseTalentRank(string talentId) { if (string.IsNullOrWhiteSpace(talentId) || AvailableTalentPoints <= 0) { return false; } if (!TalentCatalog.Talents.TryGetValue(talentId, out var value)) { return false; } if (value.Class != Class) { return false; } if (WorldProgression.Level < value.MinimumLevel) { return false; } int value2 = 0; TalentRanks.TryGetValue(talentId, out value2); if (value2 >= value.MaxRank) { return false; } value2++; TalentRanks[talentId] = value2; SpentTalentPoints++; return true; } public static bool ResetTalents() { if (SpentTalentPoints <= 0 && TalentRanks.Count <= 0) { return false; } TalentRanks.Clear(); SpentTalentPoints = 0; return true; } public static void Reset() { Class = CharacterClass.None; TalentRanks.Clear(); SpentTalentPoints = 0; } } internal static class CharacterProgressionSave { private static string GetSavePath(Player player) { long worldUID = ZNet.instance.GetWorldUID(); long playerID = player.GetPlayerID(); string text = Path.Combine(Paths.ConfigPath, "JGRPG", "Characters"); Directory.CreateDirectory(text); return Path.Combine(text, $"character_{playerID}_world_{worldUID}.txt"); } public static void Save(Player player) { if ((Object)(object)player == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return; } string savePath = GetSavePath(player); List<string> list = new List<string> { $"Class={CharacterProgression.Class}" }; foreach (KeyValuePair<string, int> talentRank in CharacterProgression.TalentRanks) { list.Add($"Talent.{talentRank.Key}={talentRank.Value}"); } File.WriteAllLines(savePath, list); Logger.LogInfo((object)("JGRPG character progression saved: " + $"Class {CharacterProgression.Class}")); } public static void Load(Player player) { CharacterProgression.Reset(); if ((Object)(object)player == (Object)null || (Object)(object)ZNet.instance == (Object)null) { return; } string savePath = GetSavePath(player); if (!File.Exists(savePath)) { Logger.LogInfo((object)"JGRPG character progression: no save found"); return; } string[] array = File.ReadAllLines(savePath); foreach (string text in array) { if (text.StartsWith("Class=")) { if (Enum.TryParse<CharacterClass>(text.Substring("Class=".Length), out var result)) { CharacterProgression.SetClass(result); } } else { if (!text.StartsWith("Talent.")) { continue; } int num = text.IndexOf('='); if (num > "Talent.".Length) { string talentId = text.Substring("Talent.".Length, num - "Talent.".Length); if (int.TryParse(text.Substring(num + 1), out var result2)) { CharacterProgression.RestoreTalentRank(talentId, result2); } } } } Logger.LogInfo((object)("JGRPG character progression loaded: " + $"Class {CharacterProgression.Class}")); } } internal static class ClassAbilityCooldowns { private static readonly float[] ReadyTimes = new float[6]; public static bool IsReady(int abilitySlot) { if (abilitySlot < 1 || abilitySlot > 5) { return false; } return Time.time >= ReadyTimes[abilitySlot]; } public static float GetRemaining(int abilitySlot) { if (abilitySlot < 1 || abilitySlot > 5) { return 0f; } float num = ReadyTimes[abilitySlot] - Time.time; return Mathf.Max(0f, num); } public static void StartCooldown(int abilitySlot, float duration) { if (abilitySlot >= 1 && abilitySlot <= 5) { if (duration < 0f) { duration = 0f; } ReadyTimes[abilitySlot] = Time.time + duration; } } public static void ClearAll() { for (int i = 1; i <= 5; i++) { ReadyTimes[i] = 0f; } } } internal static class ClassAbilityManager { public static void TryActivate(int abilitySlot) { if (abilitySlot >= 1 && abilitySlot <= 5 && CharacterProgression.Class != CharacterClass.None) { switch (CharacterProgression.Class) { case CharacterClass.Ranger: RangerAbilities.TryActivate(abilitySlot); break; case CharacterClass.Tank: TankAbilities.TryActivate(abilitySlot); break; case CharacterClass.Berserker: BerserkerAbilities.TryActivate(abilitySlot); break; } } } } internal static class ClassAbilityUnlocks { public static int GetRequiredLevel(int slot) { return slot switch { 1 => 1, 2 => 21, 3 => 41, 4 => 61, 5 => 81, _ => int.MaxValue, }; } public static bool IsUnlocked(int slot) { return WorldProgression.Level >= GetRequiredLevel(slot); } } [HarmonyPatch(typeof(Character), "Awake")] internal static class EnemySpawnBiomePatch { private const string SpawnBiomeKey = "JGRPG_SpawnBiome"; [HarmonyPostfix] private static void Postfix(Character __instance) { //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_0066: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_0078: Expected I4, but got Unknown if (!((Object)(object)__instance == (Object)null) && !__instance.IsPlayer() && !((Object)(object)__instance.m_nview == (Object)null) && __instance.m_nview.IsValid() && __instance.m_nview.IsOwner()) { ZDO zDO = __instance.m_nview.GetZDO(); if (zDO != null && zDO.GetInt("JGRPG_SpawnBiome", -1) == -1) { Biome val = Heightmap.FindBiome(((Component)__instance).transform.position); zDO.Set("JGRPG_SpawnBiome", (int)val); } } } public static Biome GetSpawnBiome(Character character) { //IL_004c: Unknown result type (might be due to invalid IL or missing references) //IL_0051: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)character != (Object)null && (Object)(object)character.m_nview != (Object)null && character.m_nview.IsValid()) { ZDO zDO = character.m_nview.GetZDO(); if (zDO != null) { int num = zDO.GetInt("JGRPG_SpawnBiome", -1); if (num != -1) { return (Biome)num; } } } return Heightmap.FindBiome(((Component)character).transform.position); } } internal static class EnemyXP { public static double GetStarMultiplier(int stars) { if (stars < 0) { stars = 0; } return 1.0 + (double)stars * 0.5; } private static int GetCurrentBiomeTier() { if (WorldProgression.Level <= 10) { return 0; } if (WorldProgression.Level <= 20) { return 1; } if (WorldProgression.Level <= 30) { return 2; } if (WorldProgression.Level <= 40) { return 3; } if (WorldProgression.Level <= 50) { return 4; } if (WorldProgression.Level <= 60) { return 5; } if (WorldProgression.Level <= 70) { return 6; } return 7; } private static int GetBiomeTier(Biome biome) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0003: Invalid comparison between Unknown and I4 //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Invalid comparison between Unknown and I4 //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_0007: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Expected I4, but got Unknown //IL_0039: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Invalid comparison between Unknown and I4 //IL_002d: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Invalid comparison between Unknown and I4 //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Invalid comparison between Unknown and I4 //IL_0041: Unknown result type (might be due to invalid IL or missing references) //IL_0047: Invalid comparison between Unknown and I4 //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0035: Invalid comparison between Unknown and I4 //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0024: Invalid comparison between Unknown and I4 if ((int)biome <= 16) { switch (biome - 1) { case 0: return 0; case 1: return 2; case 3: goto IL_0051; case 2: goto IL_005b; } if ((int)biome == 8) { return 1; } if ((int)biome == 16) { return 4; } } else if ((int)biome <= 64) { if ((int)biome == 32) { return 6; } if ((int)biome == 64) { return 7; } } else { if ((int)biome == 256) { goto IL_0051; } if ((int)biome == 512) { return 5; } } goto IL_005b; IL_0051: return 3; IL_005b: return int.MaxValue; } public static double GetBiomeMultiplier(Biome biome) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) int currentBiomeTier = GetCurrentBiomeTier(); int biomeTier = GetBiomeTier(biome); if (biomeTier >= currentBiomeTier) { return 1.0; } return (currentBiomeTier - biomeTier) switch { 1 => 0.5, 2 => 0.25, _ => 0.0, }; } public static long CalculateBaseXP(float baseMaxHealth, int stars) { if (baseMaxHealth <= 0f) { return 0L; } return (long)Math.Round((double)baseMaxHealth * GetStarMultiplier(stars)); } public static long CalculateXP(float baseMaxHealth, int stars, Biome biome) { //IL_0010: Unknown result type (might be due to invalid IL or missing references) long num = CalculateBaseXP(baseMaxHealth, stars); if (num <= 0) { return 0L; } double biomeMultiplier = GetBiomeMultiplier(biome); return (long)Math.Round((double)num * biomeMultiplier); } } [HarmonyPatch] internal static class ExplosiveShotAttackPatch { [HarmonyPatch(typeof(Attack), "Start")] [HarmonyPostfix] private static void AttackStartPostfix(Attack __instance, bool __result) { //IL_0018: Unknown result type (might be due to invalid IL or missing references) //IL_001e: Invalid comparison between Unknown and I4 //IL_0035: Unknown result type (might be due to invalid IL or missing references) //IL_003a: 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_003d: Invalid comparison between Unknown and I4 //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_0042: Invalid comparison between Unknown and I4 if (__result && !((Object)(object)__instance.m_character != (Object)(object)Player.m_localPlayer) && (int)__instance.m_attackType == 2 && __instance.m_weapon != null) { SkillType skillType = __instance.m_weapon.m_shared.m_skillType; if (((int)skillType == 8 || (int)skillType == 14) && ExplosiveShotSystem.IsActive()) { ExplosiveShotAttackTracker.StartAttack(__instance); } } } [HarmonyPatch(typeof(Attack), "FireProjectileBurst")] [HarmonyPrefix] private static void FireProjectileBurstPrefix(Attack __instance) { ExplosiveShotAttackTracker.BeginProjectileBurst(__instance); } [HarmonyPatch(typeof(Attack), "FireProjectileBurst")] [HarmonyPostfix] private static void FireProjectileBurstPostfix() { ExplosiveShotAttackTracker.EndProjectileBurst(); } [HarmonyPatch(typeof(Projectile), "Setup")] [HarmonyPostfix] private static void ProjectileSetupPostfix(Projectile __instance) { ExplosiveShotAttackTracker.RegisterProjectile(__instance); } [HarmonyPatch(typeof(Attack), "Stop")] [HarmonyPostfix] private static void AttackStopPostfix(Attack __instance) { ExplosiveShotAttackTracker.EndAttack(__instance); } } internal static class ExplosiveShotAttackTracker { private static int _nextAttackId = 1; private static int _currentAttackId; private static readonly Dictionary<Attack, int> AttackIds = new Dictionary<Attack, int>(); private static readonly Dictionary<int, int> ProjectileAttackIds = new Dictionary<int, int>(); private static readonly HashSet<int> ExplodedAttackIds = new HashSet<int>(); private static readonly HashSet<int> ExplodedProjectileIds = new HashSet<int>(); public static int CreateAttackGroup() { int nextAttackId = _nextAttackId; _nextAttackId++; return nextAttackId; } public static void RegisterAttackToGroup(Attack attack, int attackId) { if (attack != null && attackId > 0) { AttackIds[attack] = attackId; } } public static void StartAttack(Attack attack) { if (attack != null) { AttackIds[attack] = CreateAttackGroup(); } } public static void BeginProjectileBurst(Attack attack) { _currentAttackId = 0; if (attack != null && AttackIds.TryGetValue(attack, out var value)) { _currentAttackId = value; } } public static void EndProjectileBurst() { _currentAttackId = 0; } public static void RegisterProjectile(Projectile projectile) { if (!((Object)(object)projectile == (Object)null) && _currentAttackId != 0) { ProjectileAttackIds[((Object)projectile).GetInstanceID()] = _currentAttackId; } } public static bool TryClaimExplosion(Projectile projectile) { if ((Object)(object)projectile == (Object)null) { return false; } int instanceID = ((Object)projectile).GetInstanceID(); if (!ProjectileAttackIds.TryGetValue(instanceID, out var value)) { return false; } if (UllrsQuiverProjectileTracker.IsUllrProjectile(projectile)) { return ExplodedProjectileIds.Add(instanceID); } return ExplodedAttackIds.Add(value); } public static void EndAttack(Attack attack) { if (attack != null) { AttackIds.Remove(attack); } } public static void Clear() { AttackIds.Clear(); ProjectileAttackIds.Clear(); ExplodedAttackIds.Clear(); ExplodedProjectileIds.Clear(); _currentAttackId = 0; _nextAttackId = 1; } } [HarmonyPatch(typeof(Projectile), "OnHit")] internal static class ExplosiveShotDamagePatch { [HarmonyPostfix] private static void Postfix(Projectile __instance, Collider collider, Vector3 hitPoint) { //IL_00c0: Unknown result type (might be due to invalid IL or missing references) //IL_00c8: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)__instance == (Object)null || (Object)(object)collider == (Object)null) { return; } Character owner = __instance.m_owner; Player val = (Player)(object)((owner is Player) ? owner : null); if ((Object)(object)val == (Object)null || (Object)(object)val != (Object)(object)Player.m_localPlayer || __instance.m_originalHitData == null) { return; } GameObject val2 = Projectile.FindHitObject(collider); if ((Object)(object)val2 == (Object)null) { return; } Character component = val2.GetComponent<Character>(); if ((Object)(object)component == (Object)null || component.IsTamed() || !BaseAI.IsEnemy((Character)(object)val, component) || !ExplosiveShotAttackTracker.TryClaimExplosion(__instance)) { return; } float explosionRadius = ExplosiveShotSystem.GetExplosionRadius(); foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)val) && !allCharacter.IsTamed() && BaseAI.IsEnemy((Character)(object)val, allCharacter) && !(Vector3.Distance(hitPoint, ((Component)allCharacter).transform.position) > explosionRadius)) { ExplosiveShotSystem.ApplyExplosionDamage(allCharacter, val, __instance.m_originalHitData); } } } } internal static class ExplosiveShotSystem { private const float Duration = 10f; private const float BaseCooldown = 30f; private const float BaseRadius = 5f; public const float ExplosionDamageMultiplier = 0.5f; public const float StaminaCost = 30f; private static float _endTime; public static DamageTypes GetExplosionDamage(HitData originalHit) { //IL_0001: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_0013: Unknown result type (might be due to invalid IL or missing references) DamageTypes damage = originalHit.m_damage; ((DamageTypes)(ref damage)).Modify(0.5f); return damage; } public static void ApplyExplosionDamage(Character target, Player attacker, HitData originalHit) { //IL_0016: Unknown result type (might be due to invalid IL or missing references) //IL_001c: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Unknown result type (might be due to invalid IL or missing references) //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: 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_004b: Unknown result type (might be due to invalid IL or missing references) //IL_0050: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_0058: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Unknown result type (might be due to invalid IL or missing references) //IL_0064: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)target == (Object)null) && !((Object)(object)attacker == (Object)null) && originalHit != null) { HitData val = new HitData(); val.m_damage = GetExplosionDamage(originalHit); val.m_point = ((Component)target).transform.position; Vector3 val2 = ((Component)target).transform.position - ((Component)attacker).transform.position; val.m_dir = ((Vector3)(ref val2)).normalized; val.m_attacker = ((Character)attacker).GetZDOID(); val.m_ranged = false; target.Damage(val); } } public static float GetCooldownDuration() { int talentRank = CharacterProgression.GetTalentRank("Ranger_AlchemistTrained"); return Mathf.Max(0f, 30f - (float)talentRank); } public static float GetExplosionRadius() { int talentRank = CharacterProgression.GetTalentRank("Ranger_Volatile"); return 5f + (float)talentRank * 2.5f; } public static void Activate() { ExplosiveShotAttackTracker.Clear(); _endTime = Time.time + 10f; } public static bool IsActive() { return Time.time < _endTime; } public static float GetRemainingDuration() { return Mathf.Max(0f, _endTime - Time.time); } public static void Clear() { _endTime = 0f; ExplosiveShotAttackTracker.Clear(); } } [HarmonyPatch(typeof(ZoneSystem), "SetGlobalKey", new Type[] { typeof(string) })] internal static class GlobalKeyPatch { [HarmonyPostfix] private static void Postfix(string name) { if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer()) { int levelCap = WorldProgression.LevelCap; WorldProgression.SetLevelCap(BossProgression.GetWorldLevelCap()); if (WorldProgression.LevelCap > levelCap) { Logger.LogInfo((object)("JGRPG level cap increased: " + $"{levelCap} -> {WorldProgression.LevelCap} " + "after global key '" + name + "'")); WorldProgressionNetwork.Broadcast(); } } } } [HarmonyPatch(typeof(Character), "Damage")] internal static class HuntersMarkDamagePatch { [HarmonyPrefix] private static void Prefix(Character __instance, HitData hit) { if ((Object)(object)__instance == (Object)null || hit == null) { return; } float damageBonus = HuntersMarkSystem.GetDamageBonus(__instance); if (!(damageBonus <= 0f)) { Character attacker = hit.GetAttacker(); if (!((Object)(object)attacker == (Object)null) && attacker.IsPlayer()) { ((DamageTypes)(ref hit.m_damage)).Modify(1f + damageBonus); } } } } internal static class HuntersMarkNetwork { public static CustomRPC MarkRPC { get; private set; } public static void Register() { //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_001d: Unknown result type (might be due to invalid IL or missing references) //IL_0027: Expected O, but got Unknown //IL_0027: Expected O, but got Unknown MarkRPC = NetworkManager.Instance.AddRPC("HuntersMark", new CoroutineHandler(ServerReceive), new CoroutineHandler(ClientReceive)); } public static void SendMark(Character target) { //IL_001f: 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_0025: 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_0045: Unknown result type (might be due to invalid IL or missing references) //IL_0055: Unknown result type (might be due to invalid IL or missing references) //IL_005b: Expected O, but got Unknown //IL_005c: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null || (Object)(object)ZNet.instance == (Object)null || MarkRPC == null) { return; } ZDOID zDOID = target.GetZDOID(); if (!(zDOID == ZDOID.None)) { float damageBonus = HuntersMarkSystem.GetDamageBonus(); if (ZNet.instance.IsServer()) { BroadcastMark(zDOID, damageBonus); } else if (ZRoutedRpc.instance != null) { ZPackage val = new ZPackage(); val.Write(zDOID); val.Write(damageBonus); MarkRPC.SendPackage(ZRoutedRpc.instance.GetServerPeerID(), val); } } } private static void BroadcastMark(ZDOID targetID, float damageBonus) { //IL_0038: Unknown result type (might be due to invalid IL or missing references) //IL_003e: Expected O, but got Unknown //IL_003f: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNet.instance == (Object)null) && ZNet.instance.IsServer() && MarkRPC != null) { List<ZNetPeer> peers = ZNet.instance.GetPeers(); if (peers != null && peers.Count != 0) { ZPackage val = new ZPackage(); val.Write(targetID); val.Write(damageBonus); MarkRPC.SendPackage(peers, val); } } } private static Character FindCharacter(ZDOID targetID) { //IL_0014: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNetScene.instance == (Object)null) { return null; } GameObject val = ZNetScene.instance.FindInstance(targetID); if ((Object)(object)val == (Object)null) { return null; } return val.GetComponent<Character>(); } private static IEnumerator ServerReceive(long sender, ZPackage package) { ZDOID targetID = package.ReadZDOID(); float damageBonus = package.ReadSingle(); Character val = FindCharacter(targetID); if (!((Object)(object)val == (Object)null)) { HuntersMarkSystem.ApplyMark(val, damageBonus); BroadcastMark(targetID, damageBonus); yield return null; } } private static IEnumerator ClientReceive(long sender, ZPackage package) { ZDOID targetID = package.ReadZDOID(); float damageBonus = package.ReadSingle(); Character val = FindCharacter(targetID); if ((Object)(object)val != (Object)null) { HuntersMarkSystem.ApplyMark(val, damageBonus); } yield return null; } } internal static class HuntersMarkSystem { private class MarkData { public float EndTime; public float DamageBonus; } private const float MarkDuration = 10f; private const float BaseCooldown = 20f; private static readonly Dictionary<ZDOID, MarkData> Marks = new Dictionary<ZDOID, MarkData>(); public static float GetCooldownDuration() { int talentRank = CharacterProgression.GetTalentRank("Ranger_HuntersInsight"); return Mathf.Max(0f, 20f - (float)talentRank); } public static float GetDamageBonus() { float num = 0.1f; if (CharacterProgression.GetTalentRank("Ranger_MarkedWeakness") > 0) { num += 0.05f; } int talentRank = CharacterProgression.GetTalentRank("Ranger_PackHunter"); return num + (float)talentRank * 0.025f; } public static bool HasGroupHunt() { return CharacterProgression.GetTalentRank("Ranger_GroupHunt") > 0; } public static List<Character> GetTargets(Player player, Character primaryTarget) { //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Unknown result type (might be due to invalid IL or missing references) //IL_0081: 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) List<Character> list = new List<Character>(); if ((Object)(object)player == (Object)null || (Object)(object)primaryTarget == (Object)null) { return list; } list.Add(primaryTarget); if (!HasGroupHunt()) { return list; } foreach (Character allCharacter in Character.GetAllCharacters()) { if (!((Object)(object)allCharacter == (Object)null) && !((Object)(object)allCharacter == (Object)(object)primaryTarget) && !((Object)(object)allCharacter == (Object)(object)player) && !allCharacter.IsTamed() && BaseAI.IsEnemy((Character)(object)player, allCharacter)) { Vector3 val = ((Component)allCharacter).transform.position - ((Component)primaryTarget).transform.position; if (!(((Vector3)(ref val)).sqrMagnitude > 100f)) { list.Add(allCharacter); } } } return list; } public static void ApplyMark(Character target) { ApplyMark(target, GetDamageBonus()); } public static void ApplyMark(Character target, float damageBonus) { //IL_000b: Unknown result type (might be due to invalid IL or missing references) //IL_0010: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: 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) if (!((Object)(object)target == (Object)null)) { ZDOID zDOID = target.GetZDOID(); if (!(zDOID == ZDOID.None)) { Marks[zDOID] = new MarkData { EndTime = Time.time + 10f, DamageBonus = damageBonus }; } } } public static bool IsMarked(Character target) { return GetMarkData(target) != null; } public static float GetDamageBonus(Character target) { return GetMarkData(target)?.DamageBonus ?? 0f; } public static float GetRemainingDuration(Character target) { MarkData markData = GetMarkData(target); if (markData == null) { return 0f; } return Mathf.Max(0f, markData.EndTime - Time.time); } private static MarkData GetMarkData(Character target) { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0011: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0013: 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_0044: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)target == (Object)null) { return null; } ZDOID zDOID = target.GetZDOID(); if (zDOID == ZDOID.None) { return null; } if (!Marks.TryGetValue(zDOID, out var value)) { return null; } if (Time.time >= value.EndTime) { Marks.Remove(zDOID); return null; } return value; } public static void Clear() { Marks.Clear(); } } [BepInPlugin("com.jongr.jgrpg", "JGRPG", "0.1.61")] [BepInDependency(/*Could not decode attribute arguments.*/)] [NetworkCompatibility(/*Could not decode attribute arguments.*/)] internal class JGRPG : BaseUnityPlugin { public const string PluginGUID = "com.jongr.jgrpg"; public const string PluginName = "JGRPG"; public const string PluginVersion = "0.1.61"; private Harmony _harmony; internal static ConfigEntry<CharacterClass> SelectedClassConfig; internal static ConfigEntry<KeyboardShortcut> TalentMenuKeyConfig; internal static ConfigEntry<KeyboardShortcut> Ability1KeyConfig; internal static ConfigEntry<KeyboardShortcut> Ability2KeyConfig; internal static ConfigEntry<KeyboardShortcut> Ability3KeyConfig; internal static ConfigEntry<KeyboardShortcut> Ability4KeyConfig; internal static ConfigEntry<KeyboardShortcut> Ability5KeyConfig; internal static ConfigEntry<GamepadButton> Ability1GamepadConfig; internal static ConfigEntry<GamepadButton> Ability2GamepadConfig; internal static ConfigEntry<GamepadButton> Ability3GamepadConfig; internal static ConfigEntry<GamepadButton> Ability4GamepadConfig; internal static ConfigEntry<GamepadButton> Ability5GamepadConfig; internal static ConfigEntry<GamepadButton> AbilityGamepadModifierConfig; internal static ConfigEntry<GamepadButton> TalentMenuGamepadConfig; internal static ConfigEntry<GamepadButton> TalentNavUpGamepadConfig; internal static ConfigEntry<GamepadButton> TalentNavRightGamepadConfig; internal static ConfigEntry<GamepadButton> TalentNavDownGamepadConfig; internal static ConfigEntry<GamepadButton> TalentNavLeftGamepadConfig; private ButtonConfig _ability1Button; private ButtonConfig _ability2Button; private ButtonConfig _ability3Button; private ButtonConfig _ability4Button; private ButtonConfig _ability5Button; internal static ButtonConfig _abilityGamepadModifierButton; private ButtonConfig _talentMenuGamepadButton; private ButtonConfig _talentNavUpButton; private ButtonConfig _talentNavRightButton; private ButtonConfig _talentNavDownButton; private ButtonConfig _talentNavLeftButton; public static CustomLocalization Localization = LocalizationManager.Instance.GetLocalization(); private static bool IsTextInputActive() { if (((Object)(object)Chat.instance != (Object)null && Chat.instance.HasFocus()) || Console.IsVisible() || TextInput.IsVisible()) { return true; } if ((Object)(object)EventSystem.current != (Object)null) { GameObject currentSelectedGameObject = EventSystem.current.currentSelectedGameObject; if ((Object)(object)currentSelectedGameObject != (Object)null) { TMP_InputField val = currentSelectedGameObject.GetComponent<TMP_InputField>(); if ((Object)(object)val == (Object)null) { val = currentSelectedGameObject.GetComponentInParent<TMP_InputField>(); } if ((Object)(object)val != (Object)null && val.isFocused) { return true; } } } return false; } private void Awake() { //IL_0037: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_009f: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) //IL_0107: 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) //IL_02b1: Unknown result type (might be due to invalid IL or missing references) //IL_02b6: Unknown result type (might be due to invalid IL or missing references) //IL_02c1: Unknown result type (might be due to invalid IL or missing references) //IL_02cc: 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_02df: Expected O, but got Unknown //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_02fa: Unknown result type (might be due to invalid IL or missing references) //IL_0305: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0317: Unknown result type (might be due to invalid IL or missing references) //IL_0323: Expected O, but got Unknown //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_033e: Unknown result type (might be due to invalid IL or missing references) //IL_0349: Unknown result type (might be due to invalid IL or missing references) //IL_0354: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_0367: Expected O, but got Unknown //IL_037d: 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_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Unknown result type (might be due to invalid IL or missing references) //IL_039f: Unknown result type (might be due to invalid IL or missing references) //IL_03ab: Expected O, but got Unknown //IL_03c0: Unknown result type (might be due to invalid IL or missing references) //IL_03c5: Unknown result type (might be due to invalid IL or missing references) //IL_03d0: Unknown result type (might be due to invalid IL or missing references) //IL_03db: Unknown result type (might be due to invalid IL or missing references) //IL_03e7: Expected O, but got Unknown //IL_03fc: Unknown result type (might be due to invalid IL or missing references) //IL_0401: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Unknown result type (might be due to invalid IL or missing references) //IL_041e: Unknown result type (might be due to invalid IL or missing references) //IL_042a: Expected O, but got Unknown //IL_0440: Unknown result type (might be due to invalid IL or missing references) //IL_0445: Unknown result type (might be due to invalid IL or missing references) //IL_0450: Unknown result type (might be due to invalid IL or missing references) //IL_045b: Unknown result type (might be due to invalid IL or missing references) //IL_0467: Expected O, but got Unknown //IL_047d: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_048d: Unknown result type (might be due to invalid IL or missing references) //IL_0498: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Expected O, but got Unknown //IL_04ba: Unknown result type (might be due to invalid IL or missing references) //IL_04bf: Unknown result type (might be due to invalid IL or missing references) //IL_04ca: Unknown result type (might be due to invalid IL or missing references) //IL_04d5: Unknown result type (might be due to invalid IL or missing references) //IL_04e1: Expected O, but got Unknown //IL_04f7: Unknown result type (might be due to invalid IL or missing references) //IL_04fc: Unknown result type (might be due to invalid IL or missing references) //IL_0507: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_051e: Expected O, but got Unknown //IL_0534: Unknown result type (might be due to invalid IL or missing references) //IL_0539: Unknown result type (might be due to invalid IL or missing references) //IL_0544: Unknown result type (might be due to invalid IL or missing references) //IL_054f: Unknown result type (might be due to invalid IL or missing references) //IL_055b: Expected O, but got Unknown //IL_058a: Unknown result type (might be due to invalid IL or missing references) //IL_0594: Expected O, but got Unknown SelectedClassConfig = ((BaseUnityPlugin)this).Config.Bind<CharacterClass>("Character", "SelectedClass", CharacterClass.None, "Class to select for the current character when no class has been chosen yet."); TalentMenuKeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "TalentMenu", new KeyboardShortcut((KeyCode)117, Array.Empty<KeyCode>()), "Key used to open and close the JGRPG talent tree."); Ability1KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability1", new KeyboardShortcut((KeyCode)49, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 1."); Ability2KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability2", new KeyboardShortcut((KeyCode)50, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 2."); Ability3KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability3", new KeyboardShortcut((KeyCode)51, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 3."); Ability4KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability4", new KeyboardShortcut((KeyCode)52, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 4."); Ability5KeyConfig = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("Hotkeys", "Ability5", new KeyboardShortcut((KeyCode)53, (KeyCode[])(object)new KeyCode[1] { (KeyCode)304 }), "Key used to activate class ability 5."); Ability1GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability1Gamepad", (GamepadButton)1, "Gamepad button used for class ability 1."); Ability2GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability2Gamepad", (GamepadButton)4, "Gamepad button used for class ability 2."); Ability3GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability3Gamepad", (GamepadButton)2, "Gamepad button used for class ability 3."); Ability4GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability4Gamepad", (GamepadButton)3, "Gamepad button used for class ability 4."); Ability5GamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "Ability5Gamepad", (GamepadButton)5, "Gamepad button used for class ability 5."); AbilityGamepadModifierConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "AbilityGamepadModifier", (GamepadButton)9, "Gamepad modifier held while pressing a class ability button."); TalentMenuGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentMenuGamepad", (GamepadButton)8, "Gamepad button used with the gamepad modifier to open and close the JGRPG talent tree."); TalentNavUpGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavUpGamepad", (GamepadButton)1, "Gamepad button used to navigate up in the JGRPG talent tree."); TalentNavRightGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavRightGamepad", (GamepadButton)4, "Gamepad button used to navigate right in the JGRPG talent tree."); TalentNavDownGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavDownGamepad", (GamepadButton)2, "Gamepad button used to navigate down in the JGRPG talent tree."); TalentNavLeftGamepadConfig = ((BaseUnityPlugin)this).Config.Bind<GamepadButton>("Hotkeys", "TalentNavLeftGamepad", (GamepadButton)3, "Gamepad button used to navigate left in the JGRPG talent tree."); _talentNavUpButton = new ButtonConfig { Name = "JGRPG_TalentNavUp", GamepadConfig = TalentNavUpGamepadConfig, BlockOtherInputs = true, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavUpButton); _talentNavRightButton = new ButtonConfig { Name = "JGRPG_TalentNavRight", GamepadConfig = TalentNavRightGamepadConfig, BlockOtherInputs = true, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavRightButton); _talentNavDownButton = new ButtonConfig { Name = "JGRPG_TalentNavDown", GamepadConfig = TalentNavDownGamepadConfig, BlockOtherInputs = true, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavDownButton); _talentNavLeftButton = new ButtonConfig { Name = "JGRPG_TalentNavLeft", GamepadConfig = TalentNavLeftGamepadConfig, BlockOtherInputs = true, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _talentNavLeftButton); _abilityGamepadModifierButton = new ButtonConfig { Name = "JGRPG_AbilityModifier", GamepadConfig = AbilityGamepadModifierConfig, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _abilityGamepadModifierButton); _talentMenuGamepadButton = new ButtonConfig { Name = "JGRPG_TalentMenu", GamepadConfig = TalentMenuGamepadConfig, BlockOtherInputs = true, ActiveInCustomGUI = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _talentMenuGamepadButton); _ability1Button = new ButtonConfig { Name = "JGRPG_Ability1", GamepadConfig = Ability1GamepadConfig, BlockOtherInputs = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _ability1Button); _ability2Button = new ButtonConfig { Name = "JGRPG_Ability2", GamepadConfig = Ability2GamepadConfig, BlockOtherInputs = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _ability2Button); _ability3Button = new ButtonConfig { Name = "JGRPG_Ability3", GamepadConfig = Ability3GamepadConfig, BlockOtherInputs = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _ability3Button); _ability4Button = new ButtonConfig { Name = "JGRPG_Ability4", GamepadConfig = Ability4GamepadConfig, BlockOtherInputs = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _ability4Button); _ability5Button = new ButtonConfig { Name = "JGRPG_Ability5", GamepadConfig = Ability5GamepadConfig, BlockOtherInputs = true }; InputManager.Instance.AddButton("com.jongr.jgrpg", _ability5Button); WorldProgressionNetwork.Register(); TalentUI.Register(); AbilityHUD.Register(); AbilityBuffStatusEffects.Register(); _harmony = new Harmony("com.jongr.jgrpg"); _harmony.PatchAll(); Logger.LogInfo((object)"JGRPG has loaded"); } private void Update() { //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_0148: Unknown result type (might be due to invalid IL or missing references) //IL_0164: Unknown result type (might be due to invalid IL or missing references) //IL_0169: 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_01a6: 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) if (TalentUI.IsOpen && Input.GetKeyDown((KeyCode)27)) { TalentUI.Toggle(); } else { if (IsTextInputActive() && !TalentUI.IsOpen) { return; } KeyboardShortcut value; if (TalentMenuKeyConfig != null) { value = TalentMenuKeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { TalentUI.Toggle(); } } if (ZInput.instance != null && _abilityGamepadModifierButton != null && _talentMenuGamepadButton != null && ZInput.GetButton(_abilityGamepadModifierButton.Name) && ZInput.GetButtonDown(_talentMenuGamepadButton.Name)) { TalentUI.Toggle(); return; } if (TalentUI.IsOpen) { if (_talentNavUpButton != null && ZInput.GetButtonDown(_talentNavUpButton.Name)) { TalentUI.NavigateSelection(0, 1); } else if (_talentNavRightButton != null && ZInput.GetButtonDown(_talentNavRightButton.Name)) { TalentUI.NavigateSelection(1, 0); } else if (_talentNavDownButton != null && ZInput.GetButtonDown(_talentNavDownButton.Name)) { TalentUI.NavigateSelection(0, -1); } else if (_talentNavLeftButton != null && ZInput.GetButtonDown(_talentNavLeftButton.Name)) { TalentUI.NavigateSelection(-1, 0); } return; } if (Ability1KeyConfig != null) { value = Ability1KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ClassAbilityManager.TryActivate(1); } } if (Ability2KeyConfig != null) { value = Ability2KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ClassAbilityManager.TryActivate(2); } } if (Ability3KeyConfig != null) { value = Ability3KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ClassAbilityManager.TryActivate(3); } } if (Ability4KeyConfig != null) { value = Ability4KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ClassAbilityManager.TryActivate(4); } } if (Ability5KeyConfig != null) { value = Ability5KeyConfig.Value; if (((KeyboardShortcut)(ref value)).IsDown()) { ClassAbilityManager.TryActivate(5); } } if (ZInput.instance != null && _abilityGamepadModifierButton != null && ZInput.GetButton(_abilityGamepadModifierButton.Name)) { if (_ability1Button != null && ZInput.GetButtonDown(_ability1Button.Name)) { ClassAbilityManager.TryActivate(1); } if (_ability2Button != null && ZInput.GetButtonDown(_ability2Button.Name)) { ClassAbilityManager.TryActivate(2); } if (_ability3Button != null && ZInput.GetButtonDown(_ability3Button.Name)) { ClassAbilityManager.TryActivate(3); } if (_ability4Button != null && ZInput.GetButtonDown(_ability4Button.Name)) { ClassAbilityManager.TryActivate(4); } if (_ability5Button != null && ZInput.GetButtonDown(_ability5Button.Name)) { ClassAbilityManager.TryActivate(5); } } } } } internal static class LevelRequirements { public static readonly int[] XPToNextLevel = new int[91] { 0, 80, 87, 95, 103, 111, 119, 127, 135, 143, 500, 1587, 1746, 1905, 2064, 2222, 2381, 2540, 2698, 2857, 2500, 2381, 2619, 2857, 3095, 3333, 3571, 3810, 4048, 4286, 5000, 1984, 2183, 2381, 2579, 2778, 2976, 3175, 3373, 3571, 7500, 3968, 4365, 4762, 5159, 5556, 5952, 6349, 6746, 7143, 40000, 6349, 6984, 7619, 8254, 8889, 9524, 10159, 10794, 11428, 12500, 7937, 8730, 9524, 10317, 11111, 11905, 12698, 13492, 14286, 25000, 4155, 4571, 4986, 5402, 5817, 6233, 6648, 7064, 7479, 7895, 8310, 8726, 9141, 9557, 9972, 10388, 10803, 11219, 11634, 0 }; } [HarmonyPatch(typeof(Character), "RPC_Damage")] internal static class PlayerKillPatch { [HarmonyPrefix] private static void Prefix(Character __instance, ref bool __state) { __state = (Object)(object)__instance != (Object)null && __instance.GetHealth() > 0f; } [HarmonyPostfix] private static void Postfix(Character __instance, HitData hit, bool __state) { //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_010c: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)ZNet.instance == (Object)null || (Object)(object)__instance == (Object)null || (Object)(object)__instance.m_nview == (Object)null || !__instance.m_nview.IsValid() || !__instance.m_nview.IsOwner() || !__state || __insta