Please disclose if your mod was created primarily 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 LevelingSystem Fixed v0.5.19
plugins/Cozyheim_CoreAPI.dll
Decompiled 10 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("CoreAPI")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("CoreAPI")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("82567395-190E-4D2E-B63A-E651911C76E4")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] namespace Cozyheim.DifficultyScaler; public class DifficultyScalerBase : MonoBehaviour { private readonly Dictionary<DifficultyScalerMultiplier, float> _multipliers = new Dictionary<DifficultyScalerMultiplier, float>(); public float StartHealth { get; private set; } public int Level { get; private set; } private void Awake() { Character component = ((Component)this).GetComponent<Character>(); if (!((Object)(object)component == (Object)null)) { StartHealth = component.m_health; } } private void Start() { Setup(); } private void Setup() { Character component = ((Component)this).GetComponent<Character>(); ZNetView val = default(ZNetView); if ((Object)(object)component == (Object)null || !((Component)this).TryGetComponent<ZNetView>(ref val)) { return; } ZDO zDO = val.GetZDO(); if (zDO == null) { return; } Level = zDO.GetInt(ZDOVars.s_level, 1); float @float = zDO.GetFloat(ZDOVars.s_maxHealth, StartHealth); if (!Mathf.Approximately(@float, StartHealth) && !Mathf.Approximately(@float, StartHealth * (float)Level)) { return; } StartHealth *= Level; float num = 1f + GetTotalHealthMultiplier(); component.SetMaxHealth(StartHealth * num); foreach (KeyValuePair<DifficultyScalerMultiplier, float> multiplier in _multipliers) { GetMultiplier(multiplier.Key); } } public void SetMultiplier(DifficultyScalerMultiplier multiplierType, float multiplierValue) { if (_multipliers.ContainsKey(multiplierType)) { _multipliers[multiplierType] = multiplierValue; } else { _multipliers.Add(multiplierType, multiplierValue); } } public float GetMultiplier(DifficultyScalerMultiplier multiplierType) { if (!_multipliers.TryGetValue(multiplierType, out var value)) { return 0f; } if (!IsMultiplierBasedOnLevel(multiplierType)) { return value; } return (float)(Level - 1) * value; } public float GetSumOfMultipliers(IEnumerable<DifficultyScalerMultiplier> multiplierTypes) { return multiplierTypes.Sum((Func<DifficultyScalerMultiplier, float>)GetMultiplier); } public float GetTotalDamageMultiplier() { return _multipliers.Sum((KeyValuePair<DifficultyScalerMultiplier, float> keyValuePair) => (keyValuePair.Key != DifficultyScalerMultiplier.HealthMultiplier) ? GetMultiplier(keyValuePair.Key) : 0f); } public float GetTotalHealthMultiplier() { return _multipliers.Sum((KeyValuePair<DifficultyScalerMultiplier, float> keyValuePair) => (keyValuePair.Key != 0) ? GetMultiplier(keyValuePair.Key) : 0f); } public bool IsMultiplierBasedOnLevel(DifficultyScalerMultiplier multiplierType) { return multiplierType == DifficultyScalerMultiplier.StarMultiplier; } } public enum DifficultyScalerMultiplier { DamageMultiplier, HealthMultiplier, NightMultiplier, BossKillMultiplier, StarMultiplier, BiomeMultiplier }
plugins/Cozyheim_LevelingSystem.dll
Decompiled 10 months 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.Globalization; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using System.Security; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using Cozyheim.DifficultyScaler; using HarmonyLib; using Jotunn; using Jotunn.Entities; using Jotunn.Managers; using Jotunn.Utils; using MonoMod.Utils; using SimpleJson; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("LevelingSystem")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("LevelingSystem")] [assembly: AssemblyCopyright("Copyright © 2023")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("4d2a4a69-cbcf-4527-b504-7c1d1d3b3696")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: TargetFramework(".NETFramework,Version=v4.8", FrameworkDisplayName = ".NET Framework 4.8")] [assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)] [assembly: AssemblyVersion("1.0.0.0")] [module: UnverifiableCode] public enum SkillCategory { Offensive, Defensive, Core, Utility } public enum XPType { Regular, MonsterLevel, Rested } namespace Cozyheim.LevelingSystem; public class CritTextAnim : MonoBehaviour { [CompilerGenerated] private sealed class <Start>d__6 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public CritTextAnim <>4__this; private Vector3 <startSize>5__2; private float <f>5__3; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Start>d__6(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0021: Unknown result type (might be due to invalid IL or missing references) //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0027: 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) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_004e: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Unknown result type (might be due to invalid IL or missing references) //IL_0054: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Unknown result type (might be due to invalid IL or missing references) //IL_0074: Unknown result type (might be due to invalid IL or missing references) //IL_0079: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_0086: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Unknown result type (might be due to invalid IL or missing references) //IL_00b2: Unknown result type (might be due to invalid IL or missing references) //IL_00b7: Unknown result type (might be due to invalid IL or missing references) //IL_00d2: Unknown result type (might be due to invalid IL or missing references) //IL_00d7: Unknown result type (might be due to invalid IL or missing references) //IL_00f2: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_0132: Unknown result type (might be due to invalid IL or missing references) //IL_0137: Unknown result type (might be due to invalid IL or missing references) //IL_013f: Unknown result type (might be due to invalid IL or missing references) //IL_0149: Expected O, but got Unknown //IL_0150: Unknown result type (might be due to invalid IL or missing references) //IL_0155: 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_0188: Unknown result type (might be due to invalid IL or missing references) //IL_019a: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; CritTextAnim critTextAnim = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; Vector3 zero = Vector3.zero; zero += Random.Range(0f - critTextAnim.spread, critTextAnim.spread) * ((Component)Camera.main).transform.right; zero += Random.Range(0f, critTextAnim.spread) * ((Component)Camera.main).transform.up; Transform transform = ((Component)critTextAnim).transform; transform.position += zero; Keyframe[] array = (Keyframe[])(object)new Keyframe[5] { new Keyframe(0f, 0f, 0f, 1f), new Keyframe(0.08f, 1.2f, 0f, 2f), new Keyframe(0.15f, 1f, -2f, 0f), new Keyframe(0.75f, 1f, 0f, -0.5f), new Keyframe(1f, 0f, 0f, 0f) }; critTextAnim.animCurve = new AnimationCurve(array); <startSize>5__2 = ((Component)critTextAnim).transform.localScale; <f>5__3 = 0f; break; } case 1: <>1__state = -1; <f>5__3 += Time.deltaTime; break; } if (<f>5__3 < critTextAnim.fullAnimTime) { float num2 = <f>5__3 / critTextAnim.fullAnimTime; ((Component)critTextAnim).transform.localScale = <startSize>5__2 * critTextAnim.damageSizeScale * critTextAnim.animCurve.Evaluate(num2); <>2__current = null; <>1__state = 1; return true; } Object.Destroy((Object)(object)((Component)critTextAnim).gameObject); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } private AnimationCurve animCurve; private float fullAnimTime = 3f; private float maxCritSize = 1f; private float damageSizeScale = 1f; private float spread = 0.5f; private void Update() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.eulerAngles = ((Component)Camera.main).transform.eulerAngles; } [IteratorStateMachine(typeof(<Start>d__6))] private IEnumerator Start() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Start>d__6(0) { <>4__this = this }; } private void SetColorAndScale(float damage) { //IL_00bc: Unknown result type (might be due to invalid IL or missing references) Text componentInChildren = ((Component)this).GetComponentInChildren<Text>(); Color color = default(Color); ((Color)(ref color))..ctor(0.8f, 0.6f, 0.15f, 1f); if (damage < 30f) { damageSizeScale = 1f; color.g = 0.6f; } else if (damage < 100f) { damageSizeScale = 1.2f; color.g = 0.45f; } else if (damage < 200f) { damageSizeScale = 1.4f; color.g = 0.3f; } else if (damage < 300f) { damageSizeScale = 1.6f; color.g = 0.15f; } else { damageSizeScale = 1.8f; color.g = 0f; } ((Graphic)componentInChildren).color = color; } public void SetText(string value) { ((Component)this).GetComponentInChildren<Text>().text = value.ToString(CultureInfo.GetCultureInfo("en-US")); } public void SetText(float value, int decimals = 0) { decimals = Mathf.Max(0, decimals); string text = "N" + decimals; SetText(value.ToString(text)); SetColorAndScale(value); } public void SetText(int value) { SetText(value.ToString()); } } [HarmonyPatch] internal class LevelingDummy_Patch { [HarmonyPrefix] [HarmonyPatch(typeof(CraftingStation), "Interact")] private static bool CraftingStation_Interact_Prefix(CraftingStation __instance) { if ((Object)(object)((Component)__instance).transform.parent != (Object)null && ((Object)((Component)__instance).transform.parent).name.StartsWith("LevelingDummy") && !UIManager.Instance.skillsUIVisible) { UIManager.Instance.ToggleSkillsUI(value: true); return false; } return true; } } internal class RPC_LevelUpVFX { [CompilerGenerated] private sealed class <LevelUpVFX_Server>d__3 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <LevelUpVFX_Server>d__3(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Expected O, but got Unknown if (<>1__state != 0) { return false; } <>1__state = -1; ConsoleLog.Print("LevelUpVFX RPC"); if (!NetworkHandler.IsServer() || package == null) { return false; } ConsoleLog.Print("LevelUpVFX RPC Server"); long num = package.ReadLong(); Player player = Player.GetPlayer(num); if (!Object.op_Implicit((Object)(object)player)) { ConsoleLog.Print($"Couldn't find a player with id '{num}'. Cancelling level up vfx.", LogType.Error); return false; } ZPackage val = new ZPackage(); val.Write(num); spawnVFX.SendPackage(ZRoutedRpc.Everybody, val); ConsoleLog.Print("Player with ID " + num + " (" + player.GetPlayerName() + ") leveled up!"); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <SpawnVFX>d__4 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <SpawnVFX>d__4(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; ConsoleLog.Print("SpawnVFX"); if ((Object)(object)UIManager.Instance != (Object)null) { ConsoleLog.Print("SpawnVFX !UIManager"); UIManager.rpc_LevelUpEffect.SendPackage(ZRoutedRpc.Everybody, package); } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public static CustomRPC levelUpVFX; public static CustomRPC spawnVFX; public static void SetupRPC() { //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 //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0053: Expected O, but got Unknown levelUpVFX = NetworkManager.Instance.AddRPC("LevelUpVFX_Server", new CoroutineHandler(LevelUpVFX_Server), new CoroutineHandler(LevelUpVFX_Server)); spawnVFX = NetworkManager.Instance.AddRPC("SpawnVFX_Server", new CoroutineHandler(SpawnVFX), new CoroutineHandler(SpawnVFX)); } [IteratorStateMachine(typeof(<LevelUpVFX_Server>d__3))] private static IEnumerator LevelUpVFX_Server(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <LevelUpVFX_Server>d__3(0) { package = package }; } [IteratorStateMachine(typeof(<SpawnVFX>d__4))] private static IEnumerator SpawnVFX(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <SpawnVFX>d__4(0) { package = package }; } } internal class NetworkHandler { public static void Init() { RPC_LevelUpVFX.SetupRPC(); } public static void LevelUpVFX() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown ConsoleLog.Print("LevelUpVFX"); ZPackage val = new ZPackage(); val.Write(GetLocalPlayerID()); RPC_LevelUpVFX.levelUpVFX.SendPackage(ZRoutedRpc.Everybody, val); } public static bool IsServer() { return ZNet.instance.IsServer(); } public static bool IsAdmin() { if (!SynchronizationManager.Instance.PlayerIsAdmin) { return false; } return true; } private static long GetLocalPlayerID() { return Player.m_localPlayer.GetPlayerID(); } } internal class SkillCriticalHitDamage : SkillBase { public static SkillCriticalHitDamage Instance; public SkillCriticalHitDamage(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.CriticalDamage; Instance = this; } } internal class SkillResistanceSpirit : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_spirit *= num; } } } public static SkillResistanceSpirit Instance; public SkillResistanceSpirit(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistanceSpirit; Instance = this; } } internal class SkillResistancePoison : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "AddPoisonDamage")] private static void Character_ElementalResistance_Prefix(Character __instance, ref float damage) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; damage *= num; } } } public static SkillResistancePoison Instance; public SkillResistancePoison(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistancePoison; Instance = this; } } internal class SkillResistanceFrost : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_frost *= num; } } } public static SkillResistanceFrost Instance; public SkillResistanceFrost(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistanceFrost; Instance = this; } } internal class SkillResistanceLightning : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_lightning *= num; } } } public static SkillResistanceLightning Instance; public SkillResistanceLightning(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistanceLightning; Instance = this; } } internal class SkillResistanceFire : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "AddFireDamage")] private static void Character_ElementalResistance_Prefix(Character __instance, ref float damage) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; damage *= num; } } } public static SkillResistanceFire Instance; public SkillResistanceFire(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistanceFire; Instance = this; } } internal class SkillResistancePierce : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_pierce *= num; } } } public static SkillResistancePierce Instance; public SkillResistancePierce(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistancePierce; Instance = this; } } internal class SkillResistanceBlunt : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_blunt *= num; } } } public static SkillResistanceBlunt Instance; public SkillResistanceBlunt(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistanceBlunt; Instance = this; } } internal class SkillResistanceSlash : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_slash *= num; } } } public static SkillResistanceSlash Instance; public SkillResistanceSlash(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ResistanceSlash; Instance = this; } } internal class SkillConfig { public static List<SkillSettings> skillSettings = new List<SkillSettings> { new SkillSettings { skillType = SkillType.HP, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Core, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.Stamina, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Core, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.Eitr, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Core, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.HPRegen, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Core, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.StaminaRegen, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Core, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.EitrRegen, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Core, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.CarryWeight, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 7.5f, category = SkillCategory.Utility, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.Woodcutting, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1.5f, category = SkillCategory.Utility, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.Mining, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1.5f, category = SkillCategory.Utility, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.PhysicalDamage, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1.5f, category = SkillCategory.Offensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ElementalDamage, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1.5f, category = SkillCategory.Offensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.PhysicalResistance, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1.5f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistanceBlunt, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistanceSlash, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistancePierce, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ElementalResistance, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1.5f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistanceFire, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistanceFrost, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistanceLightning, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistancePoison, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.ResistanceSpirit, enabled = true, defaultMaxLevel = 30, defaultBonusValue = 3f, category = SkillCategory.Defensive, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.MovementSpeed, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 1f, category = SkillCategory.Utility, defaultBaseValue = 0f }, new SkillSettings { skillType = SkillType.CriticalChance, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 0.5f, category = SkillCategory.Offensive, defaultBaseValue = 1f }, new SkillSettings { skillType = SkillType.CriticalDamage, enabled = true, defaultMaxLevel = 20, defaultBonusValue = 5f, category = SkillCategory.Offensive, defaultBaseValue = 10f } }; public static void Init() { foreach (SkillSettings skillSetting in skillSettings) { skillSetting.CreateConfigEntries(); } } public static SkillSettings GetSkill(SkillType skillType) { foreach (SkillSettings skillSetting in skillSettings) { if (skillSetting.skillType == skillType) { return skillSetting; } } return null; } } internal class SkillSettings { public SkillCategory category; private ConfigEntry<string> configSettings; public float defaultBaseValue; public float defaultBonusValue; public int defaultMaxLevel; public bool enabled; public SkillType skillType; public void CreateConfigEntries() { string value = enabled + ":" + defaultMaxLevel + ":" + defaultBonusValue + ":" + defaultBaseValue; configSettings = Main.CreateConfigEntry("Skills", skillType.ToString(), value, "Settings for " + skillType.ToString() + ". Must follow the following format 'bool:int:float:float' (enabled:maxLevel:bonusValue:baseValue)", synchronizedSetting: true, requiresAdminToChange: true); } public bool GetEnabled() { return bool.Parse(configSettings.Value.Split(new char[1] { ':' })[0]); } public int GetMaxLevel() { int.TryParse(configSettings.Value.Split(new char[1] { ':' })[1], out var result); return result; } public float GetBonusValue() { string obj = configSettings.Value.Split(new char[1] { ':' })[2]; float result; bool flag = float.TryParse(obj, out result); float result2; bool flag2 = float.TryParse(obj.Replace(',', '.'), out result2); float result3; bool flag3 = float.TryParse(obj.Replace('.', ','), out result3); float result4 = 0f; if (flag && flag2 && flag3) { result4 = Mathf.Min(Mathf.Min(result, result2), result3); } else if (flag && flag2) { result4 = Mathf.Min(result, result2); } else if (flag && flag3) { result4 = Mathf.Min(result, result3); } else if (flag2 && flag3) { result4 = Mathf.Min(result2, result3); } else if (flag) { result4 = result; } else if (flag2) { result4 = result2; } else if (flag3) { result4 = result3; } return result4; } public float GetBaseValue() { string[] array = configSettings.Value.Split(new char[1] { ':' }); string text = ((array.Length >= 4) ? array[3] : defaultBaseValue.ToString()); float result; bool flag = float.TryParse(text, out result); float result2; bool flag2 = float.TryParse(text.Replace(',', '.'), out result2); float result3; bool flag3 = float.TryParse(text.Replace('.', ','), out result3); float result4 = 0f; if (flag && flag2 && flag3) { result4 = Mathf.Min(Mathf.Min(result, result2), result3); } else if (flag && flag2) { result4 = Mathf.Min(result, result2); } else if (flag && flag3) { result4 = Mathf.Min(result, result3); } else if (flag2 && flag3) { result4 = Mathf.Min(result2, result3); } else if (flag) { result4 = result; } else if (flag2) { result4 = result2; } else if (flag3) { result4 = result3; } return result4; } } internal class SkillCriticalHitChance : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] [HarmonyPriority(0)] private static void Character_ApplyDamage_Prefix(Character __instance, ref HitData hit, ref bool showDamageText) { //IL_001b: Unknown result type (might be due to invalid IL or missing references) //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && SkillCriticalHitDamage.Instance != null && hit.HaveAttacker() && (int)__instance.m_faction != 0 && (int)hit.GetAttacker().m_faction == 0 && Random.Range(0f, 100f) < Instance.GetBonus()) { float num = 1f + SkillCriticalHitDamage.Instance.GetBonus() / 100f; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; hit.m_damage.m_chop *= num; hit.m_damage.m_pickaxe *= num; hit.m_damage.m_fire *= num; hit.m_damage.m_frost *= num; hit.m_damage.m_lightning *= num; hit.m_damage.m_poison *= num; hit.m_damage.m_spirit *= num; SkillManager.Instance.SpawnCriticalHitVFX(hit.m_point, hit.GetTotalDamage()); showDamageText = false; } } } public static SkillCriticalHitChance Instance; public SkillCriticalHitChance(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.CriticalChance; Instance = this; } } internal class SkillEitrRegen : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(SEMan), "ModifyEitrRegen")] private static void SEMan_ModifyEitrRegen_Postfix(Character ___m_character, ref float eitrMultiplier) { if (Instance != null && ___m_character.IsPlayer()) { eitrMultiplier += (float)Instance.level * Instance.bonusPerLevel / 100f / 2f; } } } public static SkillEitrRegen Instance; public SkillEitrRegen(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.EitrRegen; Instance = this; } } internal class SkillStaminaRegen : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(SEMan), "ModifyStaminaRegen")] private static void SEMan_ModifyStaminaRegen_Postfix(ref float staminaMultiplier) { if (Instance != null) { staminaMultiplier += (float)Instance.level * Instance.bonusPerLevel / 100f; } } } public static SkillStaminaRegen Instance; public SkillStaminaRegen(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.StaminaRegen; Instance = this; } } internal class SkillHPRegen : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(SEMan), "ModifyHealthRegen")] private static void SEMan_ModifyHealthRegen_Postfix(ref float regenMultiplier) { if (Instance != null) { regenMultiplier += (float)Instance.level * Instance.bonusPerLevel / 100f; } } } public static SkillHPRegen Instance; public SkillHPRegen(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.HPRegen; Instance = this; } } internal class SkillMovementSpeed : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "GetJogSpeedFactor")] private static void Player_GetJogSpeedFactor_Postfix(Player __instance, ref float __result) { if (Instance != null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { float num = (float)Instance.level * Instance.bonusPerLevel / 100f; __result += num; } } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "GetRunSpeedFactor")] private static void Player_GetRunSpeedFactor_Postfix(Player __instance, ref float __result) { if (Instance != null && (Object)(object)__instance == (Object)(object)Player.m_localPlayer) { float num = (float)Instance.level * Instance.bonusPerLevel / 100f; float num2 = num * 0.25f; float num3 = __result + num * 0.25f; float num4 = 1f + ((Character)__instance).GetEquipmentMovementModifier() + num; __result = ((num3 > num4 + num2) ? num3 : (num3 + num2)); } } } public static SkillMovementSpeed Instance; public SkillMovementSpeed(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.MovementSpeed; Instance = this; } } internal class SkillElementalResistance : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_ElementalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_lightning *= num; hit.m_damage.m_frost *= num; hit.m_damage.m_spirit *= num; } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "AddFireDamage")] private static void Character_FireResistance_Prefix(Character __instance, ref float damage) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; damage *= num; } } [HarmonyPrefix] [HarmonyPatch(typeof(Character), "AddPoisonDamage")] private static void Character_PoisonResistance_Prefix(Character __instance, ref float damage) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && !(damage <= 0f) && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; damage *= num; } } } public static SkillElementalResistance Instance; public SkillElementalResistance(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ElementalResistance; Instance = this; } } internal class SkillElementalDamage : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_ElementalDamage_Prefix(Character __instance, ref HitData hit) { //IL_0015: 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) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction != 0 && (int)hit.GetAttacker().m_faction == 0) { float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_fire *= num; hit.m_damage.m_lightning *= num; hit.m_damage.m_frost *= num; hit.m_damage.m_poison *= num; hit.m_damage.m_spirit *= num; } } } public static SkillElementalDamage Instance; public SkillElementalDamage(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.ElementalDamage; Instance = this; } } internal class SkillPhysicalResistance : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_PhysicalResistance_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction == 0) { float num = 1f - (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; } } } public static SkillPhysicalResistance Instance; public SkillPhysicalResistance(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.PhysicalResistance; Instance = this; } } internal class SkillPhysicalDamage : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Character), "ApplyDamage")] private static void Character_PhysicalDamage_Prefix(Character __instance, ref HitData hit) { //IL_0012: Unknown result type (might be due to invalid IL or missing references) //IL_0020: Unknown result type (might be due to invalid IL or missing references) if (Instance != null && hit.HaveAttacker() && (int)__instance.m_faction != 0 && (int)hit.GetAttacker().m_faction == 0) { float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f; hit.m_damage.m_blunt *= num; hit.m_damage.m_slash *= num; hit.m_damage.m_pierce *= num; } } } public static SkillPhysicalDamage Instance; public SkillPhysicalDamage(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.PhysicalDamage; Instance = this; } } internal class SkillOption : MonoBehaviour { public Button addPointButton; public Button removePointButton; public Button resetPointButton; private CanvasGroup addPointButtonGroup; private Text bonusText; private Text bonusTextShadow; private Text description; private Image iconImage; private Image levelFillBar; private Text levelText; private Text levelTextShadow; private Text maxLevelText; private Text nameText; private Text nameTextShadow; private CanvasGroup removePointButtonGroup; private CanvasGroup resetPointButtonGroup; private GameObject resetTextGO; public void Setup() { nameText = ((Component)((Component)this).transform.Find("Skill Name")).GetComponent<Text>(); nameTextShadow = ((Component)((Component)this).transform.Find("Skill Name/Skill Name Shadow")).GetComponent<Text>(); bonusText = ((Component)((Component)this).transform.Find("Bonus Text")).GetComponent<Text>(); bonusTextShadow = ((Component)((Component)this).transform.Find("Bonus Text/Bonus Text Shadow")).GetComponent<Text>(); levelText = ((Component)((Component)this).transform.Find("Skill Level")).GetComponent<Text>(); levelTextShadow = ((Component)((Component)this).transform.Find("Skill Level/Skill Level Shadow")).GetComponent<Text>(); maxLevelText = ((Component)((Component)this).transform.Find("Skill Level Ring/Skill Level Max")).GetComponent<Text>(); description = ((Component)((Component)this).transform.Find("Description")).GetComponent<Text>(); iconImage = ((Component)((Component)this).transform.Find("Skill Icon")).GetComponent<Image>(); levelFillBar = ((Component)((Component)this).transform.Find("Skill Level Ring/Skill Level Fill Slider")).GetComponent<Image>(); addPointButton = ((Component)((Component)this).transform.Find("Add Skill Point (Mask)/Add Skill Point")).GetComponent<Button>(); addPointButtonGroup = ((Component)((Component)this).transform.Find("Add Skill Point (Mask)/Add Skill Point")).GetComponent<CanvasGroup>(); removePointButton = ((Component)((Component)this).transform.Find("Remove Skill Point (Mask)/Remove Skill Point")).GetComponent<Button>(); removePointButtonGroup = ((Component)((Component)this).transform.Find("Remove Skill Point (Mask)/Remove Skill Point")).GetComponent<CanvasGroup>(); resetPointButton = ((Component)((Component)this).transform.Find("Reset Skill Point (Mask)/Reset Skill Point")).GetComponent<Button>(); resetPointButtonGroup = ((Component)((Component)this).transform.Find("Reset Skill Point (Mask)/Reset Skill Point")).GetComponent<CanvasGroup>(); resetTextGO = ((Component)((Component)this).transform.Find("Reset Skill Point (Mask)/Reset Text")).gameObject; } private void ToggleButtonVisibility(CanvasGroup cnvGroup, bool value) { cnvGroup.alpha = (value ? 1f : 0f); cnvGroup.interactable = value; } public void UpdateAllButtonVisibility(SkillBase skillInfo) { ToggleButtonVisibility(addPointButtonGroup, !skillInfo.IsLevelMax()); ToggleButtonVisibility(removePointButtonGroup, !skillInfo.IsLevelZero()); ToggleButtonVisibility(resetPointButtonGroup, !skillInfo.IsLevelZero()); resetTextGO.SetActive(!skillInfo.IsLevelZero()); } public void UpdateInformation(SkillBase skillInfo) { UpdateAllButtonVisibility(skillInfo); nameText.text = skillInfo.GetName(); nameTextShadow.text = skillInfo.GetName(); bonusText.text = "+" + skillInfo.GetBonus() + skillInfo.bonusUnit; bonusTextShadow.text = "+" + skillInfo.GetBonus() + skillInfo.bonusUnit; levelText.text = skillInfo.GetLevel().ToString(); levelTextShadow.text = skillInfo.GetLevel().ToString(); maxLevelText.text = skillInfo.GetMaxLevel().ToString(); iconImage.sprite = Main.assetBundle.LoadAsset<Sprite>(Main.assetsPath + "Sprites/Skill Icons/" + skillInfo.iconName + ".png"); description.text = "+" + skillInfo.bonusPerLevel + skillInfo.bonusUnit + " / Level"; float num = 0.1245f; float num2 = (float)skillInfo.GetLevel() / (float)skillInfo.GetMaxLevel() * 0.75f; levelFillBar.fillAmount = num + num2; } } internal class SkillStamina : SkillBase { [HarmonyPatch] private class SkillStamina_Patch { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] private static void Player_GetTotalFoodValue_Postfix(ref float stamina) { if (Instance != null) { float num = (float)Instance.level * Instance.bonusPerLevel; stamina += num; } } } public static SkillStamina Instance; public SkillStamina(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.Stamina; Instance = this; } } internal class SkillEitr : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] private static void Player_GetTotalFoodValue_Postfix(ref float eitr) { if (Instance != null) { eitr += (float)Instance.level * Instance.bonusPerLevel; } } } public static SkillEitr Instance; public SkillEitr(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.Eitr; Instance = this; } } internal class SkillWoodcutting : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(ItemData), "GetDamage", new Type[] { typeof(int), typeof(float) })] private static void ItemData_GetDamage_Woodcutting_Postfix(ItemData __instance, ref DamageTypes __result) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0014: Invalid comparison between Unknown and I4 if (Instance != null && (int)__instance.m_shared.m_skillType == 7) { float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f; __result.m_chop *= num; } } } public static SkillWoodcutting Instance; public SkillWoodcutting(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.Woodcutting; Instance = this; } } internal class SkillHunting : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Player), "Awake")] private static void Player_Awake_Prefix() { _ = Instance; } } public static SkillHunting Instance; public SkillHunting(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.Hunting; Instance = this; } } internal class SkillFarming : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Player), "Awake")] private static void Player_Awake_Prefix() { _ = Instance; } } public static SkillFarming Instance; public SkillFarming(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.Farming; Instance = this; } } internal class SkillMining : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(ItemData), "GetDamage", new Type[] { typeof(int), typeof(float) })] private static void ItemData_GetDamage_Mining_Postfix(ItemData __instance, ref DamageTypes __result) { //IL_000e: Unknown result type (might be due to invalid IL or missing references) //IL_0015: Invalid comparison between Unknown and I4 if (Instance != null && (int)__instance.m_shared.m_skillType == 12) { float num = 1f + (float)Instance.level * Instance.bonusPerLevel / 100f; __result.m_pickaxe *= num; } } } public static SkillMining Instance; public SkillMining(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.Mining; Instance = this; } } internal class SkillHP : SkillBase { [HarmonyPatch] private class PatchClass { [HarmonyPostfix] [HarmonyPatch(typeof(Player), "GetBaseFoodHP")] public static void Player_GetBaseFoodHP_Postfix(ref float __result) { if (Instance != null) { __result += (float)Instance.level * Instance.bonusPerLevel; } } [HarmonyPostfix] [HarmonyPatch(typeof(Player), "GetTotalFoodValue")] public static void Player_GetTotalFoodValue_Postfix(ref float hp) { if (Instance != null && !Main.modJewelcraftingLoaded) { hp += (float)Instance.level * Instance.bonusPerLevel; } } } public static SkillHP Instance; public SkillHP(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.HP; Instance = this; } } internal class SkillCarryWeight : SkillBase { [HarmonyPatch] private class SkillCarryWeight_Patch { [HarmonyPostfix] [HarmonyPatch(typeof(SEMan), "ModifyMaxCarryWeight")] private static void Player_ModifyMaxCarryWeight_Postfix(SEMan __instance, Character ___m_character, ref float limit) { if (Instance != null && ___m_character.IsPlayer()) { limit += (float)Instance.level * Instance.bonusPerLevel; } } } public static SkillCarryWeight Instance; public SkillCarryWeight(int maxLevel, float bonusPerLevel, string iconName, string displayName, string unit = "", float baseBonus = 0f) : base(maxLevel, bonusPerLevel, iconName, displayName, unit, baseBonus) { skillType = SkillType.CarryWeight; Instance = this; } } internal enum SkillType { HP, HPRegen, Stamina, StaminaRegen, Eitr, EitrRegen, CarryWeight, MovementSpeed, Woodcutting, Mining, PhysicalDamage, ElementalDamage, PhysicalResistance, ElementalResistance, CriticalChance, CriticalDamage, Hunting, Farming, ResistanceSlash, ResistanceBlunt, ResistancePierce, ResistanceFire, ResistanceFrost, ResistanceLightning, ResistancePoison, ResistanceSpirit, EndOfEnum } internal class SkillBase { private int _level; protected SkillOption uiSettings; protected SkillType skillType; protected int maxLevel; public string displayName; public float bonusPerLevel; public string bonusUnit; public string iconName; public float baseBonus; protected int level { get { return _level; } set { _level = value; } } public SkillBase(int maxLevel, float bonusPerLevel, string iconName, string displayName, string bonusUnit = "", float baseBonus = 0f) { level = 0; this.maxLevel = maxLevel; this.bonusPerLevel = bonusPerLevel; this.bonusUnit = bonusUnit; this.displayName = displayName; this.iconName = iconName; this.baseBonus = baseBonus; } public void SetSkillUI(SkillOption uiSettings) { //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_0053: Expected O, but got Unknown //IL_0065: Unknown result type (might be due to invalid IL or missing references) //IL_006f: Expected O, but got Unknown //IL_0081: Unknown result type (might be due to invalid IL or missing references) //IL_008b: Expected O, but got Unknown ((UnityEventBase)uiSettings.addPointButton.onClick).RemoveAllListeners(); ((UnityEventBase)uiSettings.removePointButton.onClick).RemoveAllListeners(); ((UnityEventBase)uiSettings.resetPointButton.onClick).RemoveAllListeners(); this.uiSettings = uiSettings; ((UnityEvent)uiSettings.addPointButton.onClick).AddListener((UnityAction)delegate { SkillManager.Instance.SkillLevelUp(skillType); }); ((UnityEvent)uiSettings.removePointButton.onClick).AddListener((UnityAction)delegate { SkillManager.Instance.SkillLevelDown(skillType); }); ((UnityEvent)uiSettings.resetPointButton.onClick).AddListener((UnityAction)delegate { SkillManager.Instance.SkillReset(skillType); }); } public int ResetLevel() { int result = level; level = 0; return result; } public void SetLevel(int level) { if (level > GetMaxLevel()) { level = GetMaxLevel(); } if (level < 0) { level = 0; } this.level = level; } public bool AddLevel() { if (IsLevelMax()) { return false; } level++; return true; } public bool RemoveLevel() { if (level <= 0) { return false; } level--; return true; } public bool IsLevelMax() { return level == maxLevel; } public bool IsLevelZero() { return level == 0; } public float GetBonus() { return bonusPerLevel * (float)level + baseBonus; } public string GetName() { return displayName; } public int GetLevel() { return level; } public int GetMaxLevel() { return maxLevel; } public void UpdateSkillInformation() { if ((Object)(object)uiSettings != (Object)null) { uiSettings.UpdateAllButtonVisibility(this); uiSettings.UpdateInformation(this); } } } internal class SkillManager : MonoBehaviour { public int unspendPoints; public static SkillManager Instance; private GameObject criticalHitVFX; private GameObject criticalHitText; private float critTextOffsetY = 1f; private float critTextOffsetTowardsCam = 0.75f; internal static Dictionary<SkillType, SkillBase> skills; public static void InitSkills() { skills = new Dictionary<SkillType, SkillBase>(); foreach (SkillSettings skillSetting in SkillConfig.skillSettings) { if (skillSetting.GetEnabled()) { switch (skillSetting.skillType) { case SkillType.HP: skills.Add(skillSetting.skillType, new SkillHP(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "HP", "Health", string.Empty, skillSetting.GetBaseValue())); break; case SkillType.Stamina: skills.Add(skillSetting.skillType, new SkillStamina(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Stamina", "Stamina", string.Empty, skillSetting.GetBaseValue())); break; case SkillType.Eitr: skills.Add(skillSetting.skillType, new SkillEitr(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Eitr", "Eitr", string.Empty, skillSetting.GetBaseValue())); break; case SkillType.HPRegen: skills.Add(skillSetting.skillType, new SkillHPRegen(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "HPRegen", "Health Regen", "%", skillSetting.GetBaseValue())); break; case SkillType.StaminaRegen: skills.Add(skillSetting.skillType, new SkillStaminaRegen(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "StaminaRegen", "Stamina Regen", "%", skillSetting.GetBaseValue())); break; case SkillType.EitrRegen: skills.Add(skillSetting.skillType, new SkillEitrRegen(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "EitrRegen", "Eitr Regen", "%", skillSetting.GetBaseValue())); break; case SkillType.CarryWeight: skills.Add(skillSetting.skillType, new SkillCarryWeight(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "CarryWeight", "Carry Weight", string.Empty, skillSetting.GetBaseValue())); break; case SkillType.Woodcutting: skills.Add(skillSetting.skillType, new SkillWoodcutting(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Woodcutting", "Woodcutting", "% damage", skillSetting.GetBaseValue())); break; case SkillType.Mining: skills.Add(skillSetting.skillType, new SkillMining(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "Mining", "Mining", "% damage", skillSetting.GetBaseValue())); break; case SkillType.PhysicalDamage: skills.Add(skillSetting.skillType, new SkillPhysicalDamage(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalDamage", "Physical Damage", "%", skillSetting.GetBaseValue())); break; case SkillType.ElementalDamage: skills.Add(skillSetting.skillType, new SkillElementalDamage(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalDamage", "Elemental Damage", "%", skillSetting.GetBaseValue())); break; case SkillType.PhysicalResistance: skills.Add(skillSetting.skillType, new SkillPhysicalResistance(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Physical Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistanceSlash: skills.Add(skillSetting.skillType, new SkillResistanceSlash(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Slash Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistancePierce: skills.Add(skillSetting.skillType, new SkillResistancePierce(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Pierce Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistanceBlunt: skills.Add(skillSetting.skillType, new SkillResistanceBlunt(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "PhysicalResistance", "Blunt Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ElementalResistance: skills.Add(skillSetting.skillType, new SkillElementalResistance(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Elemental Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistanceFire: skills.Add(skillSetting.skillType, new SkillResistanceFire(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Fire Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistanceFrost: skills.Add(skillSetting.skillType, new SkillResistanceFrost(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Frost Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistanceLightning: skills.Add(skillSetting.skillType, new SkillResistanceLightning(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Lightning Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistancePoison: skills.Add(skillSetting.skillType, new SkillResistancePoison(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Poison Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.ResistanceSpirit: skills.Add(skillSetting.skillType, new SkillResistanceSpirit(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "ElementalResistance", "Spirit Resistance", "%", skillSetting.GetBaseValue())); break; case SkillType.MovementSpeed: skills.Add(skillSetting.skillType, new SkillMovementSpeed(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "MovementSpeed", "Movement Speed", "%", skillSetting.GetBaseValue())); break; case SkillType.CriticalChance: skills.Add(skillSetting.skillType, new SkillCriticalHitChance(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "CriticalHitChance", "Critical Hit Chance", "%", skillSetting.GetBaseValue())); break; case SkillType.CriticalDamage: skills.Add(skillSetting.skillType, new SkillCriticalHitDamage(skillSetting.GetMaxLevel(), skillSetting.GetBonusValue(), "CriticalHitDamage", "Critical Hit Damage", "%", skillSetting.GetBaseValue())); break; } } } } public void SpawnCriticalHitVFX(Vector3 position, float damage) { //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) //IL_0052: Unknown result type (might be due to invalid IL or missing references) //IL_0057: Unknown result type (might be due to invalid IL or missing references) //IL_005a: 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_0060: Unknown result type (might be due to invalid IL or missing references) //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006c: Unknown result type (might be due to invalid IL or missing references) //IL_0071: Unknown result type (might be due to invalid IL or missing references) //IL_0076: Unknown result type (might be due to invalid IL or missing references) //IL_007d: Unknown result type (might be due to invalid IL or missing references) //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_0087: Unknown result type (might be due to invalid IL or missing references) //IL_008e: Unknown result type (might be due to invalid IL or missing references) //IL_008f: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ac: Unknown result type (might be due to invalid IL or missing references) //IL_0028: Unknown result type (might be due to invalid IL or missing references) if (Main.criticalHitVFX.Value) { if (Main.criticalHitShake.Value) { GameCamera.instance.AddShake(((Component)Player.m_localPlayer).transform.position, 10f, Main.criticalHitShakeIntensity.Value, false); } Vector3 val = ((Component)GameCamera.instance).transform.position - position; Vector3 normalized = ((Vector3)(ref val)).normalized; Vector3 val2 = position + Vector3.up * critTextOffsetY + normalized * critTextOffsetTowardsCam; Object.Instantiate<GameObject>(criticalHitText, val2, Quaternion.identity).GetComponent<CritTextAnim>().SetText(damage, 1); Object.Destroy((Object)(object)Object.Instantiate<GameObject>(criticalHitVFX, position, Quaternion.identity), 4f); } } public void UpdateAllSkillInformation() { foreach (KeyValuePair<SkillType, SkillBase> skill in skills) { skill.Value.UpdateSkillInformation(); } } public void SkillSetLevel(SkillType skillType, int level) { SkillBase skillByType = GetSkillByType(skillType); if (skillByType != null) { ConsoleLog.Print("Set skill " + skillType.ToString() + " to level " + level); skillByType.SetLevel(level); UpdateUnspendPoints(); } } public int GetTotalSkillsCount() { return skills.Count; } public SkillBase GetSkillByIndex(int index) { if (skills.ContainsKey((SkillType)index)) { return skills[(SkillType)index]; } return null; } public SkillBase GetSkillByType(SkillType type) { if (!skills.TryGetValue(type, out var value)) { return null; } return value; } public void SkillLevelUp(SkillType skillType) { //IL_001c: Unknown result type (might be due to invalid IL or missing references) //IL_0043: Unknown result type (might be due to invalid IL or missing references) SkillBase skillByType = GetSkillByType(skillType); if (skillByType == null || !HasUnspendPoints()) { return; } int num = 1; if (Input.GetKey(Main.addMultiplePointsKey.Value)) { num = Mathf.Min(Main.addMultiplePointsAmount.Value, unspendPoints); } if (Input.GetKey(Main.addMaxPointsKey.Value)) { num = unspendPoints; } for (int i = 0; i < num; i++) { if (!skillByType.AddLevel()) { break; } } UpdateUnspendPoints(); } public void SkillLevelDown(SkillType skillType) { //IL_0013: 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) SkillBase skillByType = GetSkillByType(skillType); if (skillByType == null) { return; } int num = 1; if (Input.GetKey(Main.addMultiplePointsKey.Value)) { num = Main.addMultiplePointsAmount.Value; } if (Input.GetKey(Main.addMaxPointsKey.Value)) { SkillReset(skillType); return; } for (int i = 0; i < num; i++) { if (!skillByType.RemoveLevel()) { break; } } UpdateUnspendPoints(); } public int SkillReset(SkillType skillType) { SkillBase skillByType = GetSkillByType(skillType); if (skillByType == null) { return 0; } int result = skillByType.ResetLevel(); UpdateUnspendPoints(); return result; } public void SkillResetAll() { foreach (KeyValuePair<SkillType, SkillBase> skill in skills) { skill.Value.ResetLevel(); } UpdateUnspendPoints(); } public bool IsSkillMaxLevel(SkillType skillType) { return GetSkillByType(skillType)?.IsLevelMax() ?? false; } public bool HasUnspendPoints() { return unspendPoints > 0; } public int GetSkillPointSpendOnCategory(SkillCategory category) { int num = 0; foreach (SkillSettings skillSetting in SkillConfig.skillSettings) { if (skillSetting.GetEnabled() && skillSetting.category == category) { num += GetSkillByType(skillSetting.skillType).GetLevel(); } } return num; } private void Awake() { Instance = this; } private void Start() { InitSkills(); LoadSkills(); criticalHitVFX = PrefabManager.Instance.GetPrefab("CriticalHitEffect"); criticalHitText = PrefabManager.Instance.GetPrefab("CritDamageText"); } public void UpdateUnspendPoints() { if ((Object)(object)XPManager.Instance != (Object)null && skills != null) { RecalculateUnspendPoints(); UIManager.Instance.remainingPoints.text = "Remaining points: " + unspendPoints; UIManager.Instance.UpdateCategoryPoints(); SaveSkills(); UpdateAllSkillInformation(); } } public void RecalculateUnspendPoints() { int num = Mathf.FloorToInt((float)XPManager.Instance.GetPlayerLevel() * Main.pointsPerLevel.Value); foreach (KeyValuePair<SkillType, SkillBase> skill in skills) { num -= skill.Value.GetLevel(); } unspendPoints = num; } private void LoadSkills() { foreach (KeyValuePair<SkillType, SkillBase> skill in skills) { string key = "LevelingSystem_" + skill.Key; if (Player.m_localPlayer.m_customData.ContainsKey(key) && int.TryParse(Player.m_localPlayer.m_customData[key], out var result)) { skill.Value.SetLevel(result); } } UpdateUnspendPoints(); } private void SaveSkills() { foreach (KeyValuePair<SkillType, SkillBase> skill in skills) { string key = "LevelingSystem_" + skill.Key; Player.m_localPlayer.m_customData[key] = skill.Value.GetLevel().ToString(); } } public void DestroySelf() { SaveSkills(); Object.Destroy((Object)(object)((Component)this).gameObject); } public void ReloadAllSkills() { InitSkills(); LoadSkills(); UIManager.Instance.UpdateUI(instantUpdate: true); } } internal class PatchXP_Woodcutting : MonoBehaviour { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(TreeBase), "Damage")] private static void TreeBase_Damage_Prefix(TreeBase __instance, HitData hit, ZNetView ___m_nview) { if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier) { WoodcuttingXP(((Object)__instance).name, hit); } } [HarmonyPrefix] [HarmonyPatch(typeof(TreeLog), "Damage")] private static void TreeLog_Damage_Prefix(TreeLog __instance, HitData hit, ZNetView ___m_nview) { if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier) { WoodcuttingXP(((Object)__instance).name, hit); } } [HarmonyPrefix] [HarmonyPatch(typeof(Destructible), "Damage")] private static void Destructible_Damage_Prefix(Destructible __instance, HitData hit, ZNetView ___m_nview, bool ___m_firstFrame) { if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && !(!___m_nview.IsValid() || ___m_firstFrame) && hit.m_toolTier >= __instance.m_minToolTier) { WoodcuttingXP(((Object)__instance).name, hit); } } private static void WoodcuttingXP(string name, HitData hit) { if (Main.woodcuttingXpEnabled.Value && !((Object)(object)hit.GetAttacker() == (Object)null)) { Player component = ((Component)hit.GetAttacker()).GetComponent<Player>(); if (!((Object)(object)component == (Object)null) && !(hit.m_damage.m_chop <= 0f) && !(hit.GetTotalDamage() <= 0f)) { long playerID = component.GetPlayerID(); XPManager.Instance.GetXPFromServer(playerID, name, "Woodcutting"); } } } } } internal class PatchXP_Mining : MonoBehaviour { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(MineRock5), "Awake")] private static void MineRock5_Start_Prefix(MineRock5 __instance, ref object[] __state) { if (!((Object)(object)__instance == (Object)null)) { __state = new object[1] { ((Object)__instance).name }; } } [HarmonyPostfix] [HarmonyPatch(typeof(MineRock5), "Awake")] private static void MineRock5_Start_Postfix(MineRock5 __instance, object[] __state) { if (!((Object)(object)__instance == (Object)null) && __state.Length != 0) { ((Object)__instance).name = (string)__state[0]; } } [HarmonyPrefix] [HarmonyPatch(typeof(MineRock5), "Damage")] private static void MineRock5_Damage_Prefix(MineRock5 __instance, HitData hit, ZNetView ___m_nview) { if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier) { MiningXP(((Object)__instance).name, hit); } } [HarmonyPrefix] [HarmonyPatch(typeof(MineRock), "Damage")] private static void MineRock_Damage_Prefix(MineRock __instance, HitData hit, ZNetView ___m_nview) { if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && ___m_nview.IsValid() && hit.m_toolTier >= __instance.m_minToolTier) { MiningXP(((Object)__instance).name, hit); } } [HarmonyPrefix] [HarmonyPatch(typeof(Destructible), "Damage")] private static void Destructible_Damage_Prefix(Destructible __instance, HitData hit, ZNetView ___m_nview, bool ___m_firstFrame) { if (!((Object)(object)__instance == (Object)null) && hit != null && !((Object)(object)___m_nview == (Object)null) && !(!___m_nview.IsValid() || ___m_firstFrame) && hit.m_toolTier >= __instance.m_minToolTier) { MiningXP(((Object)__instance).name, hit); } } private static void MiningXP(string name, HitData hit) { if (Main.miningXpEnabled.Value && !(hit.m_damage.m_pickaxe <= 0f) && !((Object)(object)hit.GetAttacker() == (Object)null)) { Player component = ((Component)hit.GetAttacker()).GetComponent<Player>(); if (!((Object)(object)component == (Object)null) && !(hit.GetTotalDamage() <= 0f)) { long playerID = component.GetPlayerID(); XPManager.Instance.GetXPFromServer(playerID, name, "Mining"); } } } } } internal class PatchXP_Pickable : MonoBehaviour { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Beehive), "Interact")] private static void Beehive_Interact_Prefix(Beehive __instance, Humanoid character, ZNetView ___m_nview) { if ((Object)(object)__instance == (Object)null || (Object)(object)character == (Object)null || (Object)(object)___m_nview == (Object)null || !Main.pickableXpEnabled.Value) { return; } int @int = ___m_nview.GetZDO().GetInt("level", 0); if (@int > 0) { Player component = ((Component)character).GetComponent<Player>(); if (!((Object)(object)component == (Object)null)) { long playerID = component.GetPlayerID(); XPManager.Instance.GetXPFromServer(playerID, ((Object)__instance).name, "Pickable", @int); } } } [HarmonyPrefix] [HarmonyPatch(typeof(Pickable), "RPC_SetPicked")] private static void Pickable_RPCSetPicked_Prefix(Pickable __instance, long sender, bool picked, bool ___m_picked) { //IL_003a: Unknown result type (might be due to invalid IL or missing references) //IL_003f: Unknown result type (might be due to invalid IL or missing references) //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_001f: Unknown result type (might be due to invalid IL or missing references) Player localPlayer = Player.m_localPlayer; if ((Object)(object)localPlayer == (Object)null) { return; } ZDOID zDOID; if (!((Object)(object)__instance == (Object)null)) { zDOID = ((Character)localPlayer).GetZDOID(); if (((ZDOID)(ref zDOID)).UserID == sender) { if (picked == ___m_picked || !picked) { ConsoleLog.Print("Already picked!", LogType.Error); return; } long playerID = localPlayer.GetPlayerID(); XPManager.Instance.GetXPFromServer(playerID, ((Object)__instance).name, "Pickable"); return; } } object arg = sender; zDOID = ((Character)Player.m_localPlayer).GetZDOID(); ConsoleLog.Print($"Sender id ({arg}) doesn't match with nview uid ({((ZDOID)(ref zDOID)).UserID})", LogType.Error); } } } [HarmonyPatch] internal class XPBarFade_Patch { [HarmonyPrefix] [HarmonyPatch(typeof(Hud), "UpdateBlackScreen")] private static void Player_SetSleeping_Prefix(Player player) { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)ZNetScene.instance == (Object)null) { return; } float fadeTime = 1f; if ((Object)(object)player != (Object)null) { if (((Character)player).IsDead()) { fadeTime = 9.5f; } if (player.IsSleeping()) { fadeTime = 3f; } } if ((Object)(object)player == (Object)null || ((Character)player).IsDead() || ((Character)player).IsTeleporting() || Game.instance.IsShuttingDown() || player.IsSleeping()) { if ((Object)(object)UIManager.Instance == (Object)null) { ConsoleLog.Print("UIManager is missing! Can't fade out XPBar", LogType.Error); } else { UIManager.Instance.FadeOutXPBar(fadeTime); } } else if ((Object)(object)UIManager.Instance == (Object)null) { ConsoleLog.Print("UIManager is missing! Can't fade out XPBar", LogType.Error); } else { UIManager.Instance.FadeInXPBar(fadeTime); } } } public class XPText : MonoBehaviour { [CompilerGenerated] private sealed class <Start>d__7 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public XPText <>4__this; private CanvasGroup <canvasGroup>5__2; private float <startSize>5__3; private Vector3 <startPosition>5__4; private Vector3 <deltaPosition>5__5; private float <fullAnimTime>5__6; private float <f>5__7; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <Start>d__7(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <canvasGroup>5__2 = null; <>1__state = -2; } private bool MoveNext() { //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_005a: Unknown result type (might be due to invalid IL or missing references) //IL_0070: Unknown result type (might be due to invalid IL or missing references) //IL_0075: Unknown result type (might be due to invalid IL or missing references) //IL_007b: 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_008b: Unknown result type (might be due to invalid IL or missing references) //IL_00cf: Unknown result type (might be due to invalid IL or missing references) //IL_00d5: 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_00e0: Unknown result type (might be due to invalid IL or missing references) //IL_0100: Unknown result type (might be due to invalid IL or missing references) //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_014e: Unknown result type (might be due to invalid IL or missing references) //IL_0153: Unknown result type (might be due to invalid IL or missing references) //IL_015e: Unknown result type (might be due to invalid IL or missing references) //IL_01bc: 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_01cc: Unknown result type (might be due to invalid IL or missing references) int num = <>1__state; XPText xPText = <>4__this; switch (num) { default: return false; case 0: { <>1__state = -1; Transform transform = ((Component)xPText).transform; transform.localScale *= Main.xpFontSize.Value / 100f; <canvasGroup>5__2 = ((Component)xPText).GetComponentInChildren<CanvasGroup>(); <startSize>5__3 = ((Component)xPText).transform.localScale.x; <startPosition>5__4 = ((Component)xPText).transform.position; <deltaPosition>5__5 = Vector3.up * xPText.moveDistance; <fullAnimTime>5__6 = xPText.fadeInTime + xPText.visibleTime + xPText.fadeOutTime; <f>5__7 = 0f; break; } case 1: <>1__state = -1; <f>5__7 += Time.deltaTime; break; } if (<f>5__7 < <fullAnimTime>5__6) { float num2 = <f>5__7 / <fullAnimTime>5__6; ((Component)xPText).transform.position = <startPosition>5__4 + <deltaPosition>5__5 * num2; <canvasGroup>5__2.alpha = 1f; ((Component)xPText).transform.localScale = Vector3.one * <startSize>5__3; if (<f>5__7 < xPText.fadeInTime) { <canvasGroup>5__2.alpha = <f>5__7 / xPText.fadeInTime; ((Component)xPText).transform.localScale = <f>5__7 / xPText.fadeInTime * Vector3.one * <startSize>5__3; } float num3 = xPText.fadeInTime + xPText.visibleTime; if (<f>5__7 > num3) { float num4 = <fullAnimTime>5__6 - num3; <canvasGroup>5__2.alpha = 1f - (<f>5__7 - num3) / num4; ((Component)xPText).transform.localScale = (1f - (<f>5__7 - num3) / num4) * Vector3.one * <startSize>5__3; } <>2__current = null; <>1__state = 1; return true; } Object.Destroy((Object)(object)((Component)xPText).gameObject); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public int xpGained; private float fadeInTime = 0.5f; private float visibleTime = 1.5f; private float fadeOutTime = 1f; private float moveDistance = 0.5f; public void XPGained(int xp) { ((Component)this).GetComponentInChildren<Text>().text = "+" + xp + " xp"; } private void Update() { //IL_0010: Unknown result type (might be due to invalid IL or missing references) ((Component)this).transform.eulerAngles = ((Component)Camera.main).transform.eulerAngles; } [IteratorStateMachine(typeof(<Start>d__7))] private IEnumerator Start() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <Start>d__7(0) { <>4__this = this }; } } internal class ChatCommands : MonoBehaviour { [HarmonyPatch] private class PatchClass { [HarmonyPrefix] [HarmonyPatch(typeof(Chat), "SendText")] private static bool Chat_SendText_Prefix(string text) { string[] array = text.Split(new char[1] { ' ' }); if (array.Length >= 2 && array[0].ToLower().Equals("-" + "LevelingSystem".ToLower())) { string value = array[1].ToLower(); foreach (KeyValuePair<string, Action> command in commands) { if (command.Key.ToLower().Equals(value)) { chatArgs = array.ToList(); chatArgs.RemoveAt(0); chatArgs.RemoveAt(0); command.Value(); return false; } } } return true; } } private static List<string> chatArgs = new List<string>(); private static Dictionary<string, Action> commands = new Dictionary<string, Action> { { "Reload", Reload } }; private static void Reload() { ConsoleLog.ReloadConfig(); } } internal class XPTable { public enum XPTableType { Monster, Pickable, Mining, Woodcutting, Player } public static Dictionary<string, string> miningXPMappingTable = new Dictionary<string, string> { { "rock4_coast", "Stone" }, { "rock4_coast_frac", "Stone" }, { "HeathRockPillar", "Stone" }, { "HeathRockPillar_frac", "Stone" }, { "highstone", "Stone" }, { "highstone_frac", "Stone" }, { "Rock_3", "Stone" }, { "Rock_3_frac", "Stone" }, { "Rock_4", "Stone" }, { "Rock_4_frac", "Stone" }, { "rock2_heath", "Stone" }, { "rock2_heath_frac", "Stone" }, { "rock4_forest_", "Stone" }, { "rock4_forest_frac", "Stone" }, { "rock4_heath", "Stone" }, { "rock4_heath_frac", "Stone" }, { "RockFinger", "Stone" }, { "RockFinger_frac", "Stone" }, { "RockFingerBroken", "Stone" }, { "RockFingerBroken_frac", "Stone" }, { "RockThumb", "Stone" }, { "RockThumb_frac", "Stone" }, { "widestone", "Stone" }, { "widestone_frac", "Stone" }, { "rock1_mountain", "Stone" }, { "rock1_mountain_frac", "Stone" }, { "rock2_mountain", "Stone" }, { "rock2_mountain_frac", "Stone" }, { "rock3_mountain_", "Stone" }, { "rock3_mountain_frac", "Stone" }, { "tarlump1", "Stone" }, { "tarlump1_frac", "Stone" }, { "rock_mistlands1", "Stone" }, { "rock_mistlands1_frac", "Stone" }, { "cliff_mistlands1_creep", "Stone" }, { "cliff_mistlands1_creep_frac", "Stone" }, { "cliff_mistlands1", "Stone" }, { "cliff_mistlands1_frac", "Stone" }, { "MineRock_Stone", "Stone" }, { "MineRock_Tin", "Tin" }, { "MineRock_Copper", "Copper" }, { "rock4_copper", "Copper" }, { "rock4_copper_frac", "Copper" }, { "MineRock_Iron", "Iron" }, { "mudpile_old", "Iron" }, { "mudpile", "Iron" }, { "mudpile_frac", "Iron" }, { "mudpile2", "Iron" }, { "mudpile2_frac", "Iron" }, { "giant_helmet1", "Iron" }, { "giant_helmet1_destruction", "Iron" }, { "giant_helmet2", "Iron" }, { "giant_helmet2_destruction", "Iron" }, { "giant_sword1", "Iron" }, { "giant_sword1_destruction", "Iron" }, { "giant_sword2", "Iron" }, { "giant_sword2_destruction", "Iron" }, { "MineRock_Obsidian", "Obsidian" }, { "Leviathan", "Chitin" }, { "rock3_silver", "Silver" }, { "rock3_silver_frac", "Silver" }, { "silvervein", "Silver" }, { "silvervein_frac", "Silver" }, { "MineRock_Meteorite", "Flametal" }, { "giant_brain", "SoftTissue" }, { "giant_brain_frac", "SoftTissue" }, { "giant_ribs", "BlackMarble" }, { "giant_ribs_frac", "BlackMarble" }, { "giant_skull", "BlackMarble" }, { "giant_skull_frac", "BlackMarble" } }; public static Dictionary<string, string> woodcuttingXPMappingTable = new Dictionary<string, string> { { "beech_log", "Beech" }, { "beech_log_half", "Beech" }, { "Beech_Stub", "Beech" }, { "Beech1", "Beech" }, { "FirTree_log", "Fir" }, { "FirTree_log_half", "Fir" }, { "FirTree", "Fir" }, { "FirTree_Stub", "Fir" }, { "PineTree_log", "Pine" }, { "PineTree_log_half", "Pine" }, { "PineTree_log_halfOLD", "Pine" }, { "PineTree_logOLD", "Pine" }, { "PineTree", "Pine" }, { "Pinetree_01", "Pine" }, { "Pinetree_01_Stub", "Pine" }, { "Birch_log", "Birch" }, { "Birch_log_half", "Birch" }, { "Birch1", "Birch" }, { "Birch1_aut", "Birch" }, { "Birch2", "Birch" }, { "Birch2_aut", "Birch" }, { "BirchStub", "Birch" }, { "Oak_log", "Oak" }, { "Oak_log_half", "Oak" }, { "Oak1", "Oak" }, { "OakStub", "Oak" }, { "SwampTree1_log", "Ancient" }, { "SwampTree1", "Ancient" }, { "SwampTree1_Stub", "Ancient" }, { "yggashoot_log", "Yggdrasil" }, { "yggashoot_log_half", "Yggdrasil" }, { "YggaShoot1", "Yggdrasil" }, { "YggaShoot2", "Yggdrasil" }, { "YggaShoot3", "Yggdrasil" } }; public static Dictionary<string, int> miningXPTable = new Dictionary<string, int> { { "Stone", 3 }, { "Copper", 6 }, { "Tin", 6 }, { "Iron", 9 }, { "Obsidian", 12 }, { "Chitin", 12 }, { "Silver", 15 }, { "Flametal", 15 }, { "BlackMarble", 18 }, { "SoftTissue", 18 } }; public static Dictionary<string, int> woodcuttingXPTable = new Dictionary<string, int> { { "Beech", 6 }, { "Fir", 12 }, { "Pine", 18 }, { "Birch", 24 }, { "Ancient", 30 }, { "Oak", 40 }, { "Yggdrasil", 100 } }; public static Dictionary<string, int> pickableXPTable = new Dictionary<string, int> { { "Pickable_Branch", 2 }, { "Pickable_Stone", 2 }, { "Pickable_Dandelion", 2 }, { "Pickable_Mushroom", 2 }, { "RaspberryBush", 3 }, { "BlueberryBush", 6 }, { "Pickable_Carrot", 4 }, { "Pickable_SeedCarrot", 4 }, { "Pickable_Flint", 4 }, { "Pickable_ForestCryptRemains01", 8 }, { "Pickable_ForestCryptRemains02", 8 }, { "Pickable_ForestCryptRemains03", 8 }, { "Pickable_ForestCryptRemains04", 8 }, { "Pickable_ForestCryptRandom", 8 }, { "Pickable_Mushroom_yellow", 4 }, { "Pickable_Thistle", 4 }, { "Pickable_Tin", 4 }, { "Pickable_SurtlingCoreStand", 30 }, { "Pickable_BogIronOre", 6 }, { "Pickable_Turnip", 6 }, { "Pickable_SeedTurnip", 6 }, { "Pickable_SunkenCryptRandom", 12 }, { "Pickable_Obsidian", 8 }, { "Pickable_Onion", 8 }, { "Pickable_SeedOnion", 8 }, { "hanging_hairstrands", 16 }, { "Pickable_Hairstrands01", 16 }, { "Pickable_Hairstrands02", 16 }, { "Pickable_MeatPile", 16 }, { "Pickable_MountainCaveCrystal", 16 }, { "Pickable_MountainCaveObsidian", 16 }, { "Pickable_MountainCaveRandom", 16 }, { "Pickable_MountainRemains01_buried", 16 }, { "Pickable_DragonEgg", 1200 }, { "CloudberryBush", 10 }, { "Pickable_Barley", 10 }, { "Pickable_Barley_Wild", 10 }, { "Pickable_Flax", 10 }, { "Pickable_Flax_Wild", 10 }, { "Pickable_Tar", 10 }, { "Pickable_TarBig", 20 }, { "goblin_totempole", 3000 }, { "Pickable_Mushroom_JotunPuffs", 12 }, { "Pickable_Mushroom_Magecap", 12 }, { "Pickable_RoyalJelly", 12 }, { "Pickable_DvergrMineTreasure", 24 }, { "Pickable_BlackCoreStand", 6000 }, { "Pickable_Item", 10 }, { "Pickable_DolmenTreasure", 10 }, { "Pickable_Meteorite", 10 }, { "LuredWisp", 100 }, { "piece_beehive", 10 } }; public static Dictionary<string, int> monsterXPTable = new Dictionary<string, int> { { "Deer", 5 }, { "Neck", 5 }, { "Boar", 8 }, { "Greyling", 8 }, { "Eikthyr", 96 }, { "Greydwarf", 22 }, { "Skeleton", 30 }, { "Ghost", 36 }, { "Greydwarf_Shaman", 40 }, { "Skeleton_Poison", 53 }, { "Greydwarf_Elite", 69 }, { "Troll", 243 }, { "gd_king", 833 }, { "Surtling", 85 }, { "Blob", 99 }, { "Leech", 120 }, { "Draugr", 139 }, { "Wraith", 156 }, { "BlobElite", 187 }, { "Draugr_Elite", 224 }, { "Abomination", 783 }, { "Bonemass", 2685 }, { "Bat", 109 }, { "Ulv", 457 }, { "Wolf", 479 }, { "Hatchling", 609 }, { "Cultist", 762 }, { "Fenring", 1067 }, { "Serpent", 3200 }, { "StoneGolem", 1600 }, { "Dragon", 12800 }, { "Deathsquito", 620 }, { "BlobTar", 782 }, { "GoblinShaman", 980 }, { "Goblin", 1126 }, { "GoblinBrute", 1904 }, { "Lox", 2264 }, { "GoblinKing", 24693 }, { "Hare", 34 }, { "SeekerBrood", 483 }, { "Tick", 504 }, { "DvergerMageSupport", 1207 }, { "Seeker", 1517 }, { "DvergerMageFire", 1897 }, { "Dverger", 1966 }, { "DvergerMage", 1966 }, { "DvergerMageIce", 2586 }, { "SeekerBrute", 6001 }, { "Gjall", 18002 }, { "SeekerQueen", 72008 }, { "FallenValkyrie", 7500 }, { "Charred_Melee", 1750 }, { "Charred_Archer", 1250 }, { "Charred_Mage", 1500 }, { "Charred_Twitcher", 650 }, { "Charred_Melee_Fader", 1250 }, { "Morgen", 8000 }, { "BonemawSerpent", 5500 }, { "Asksvin", 2500 }, { "Volture", 1250 }, { "BlobLava", 2500 }, { "DvergerAshlands", 1750 }, { "Charred_Melee_Dyrnwyn", 27450 }, { "Fader", 100000 } }; public static int[] playerXPTable; public static void GenerateDefaultPlayerXPTable() { int num = 90; float num2 = 80f; float num3 = 80f; float num4 = 0.09f; float num5 = 0.00033f; int num6 = 0; List<int> list = new List<int>(); for (int i = 1; i <= num; i++) { int num7 = (int)(num2 + num3 * (float)(i - 1)); num2 *= 1f + num4; num4 += num5; list.Add(num7); num6 += num7; _ = i % 10; } playerXPTable = list.ToArray(); } public static void UpdatePickableXPTable() { ConsoleLog.Print("Level System: Creating Pickable XP Table", LogType.Message); string text = "PickableXP"; string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json"); Array.Sort(files); CreateListsFromJSON(files, XPTableType.Pickable); } public static void UpdateWoodcuttingXPTable() { ConsoleLog.Print("Level System: Creating Woodcutting XP Table", LogType.Message); string text = "WoodcuttingXP"; string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json"); Array.Sort(files); CreateListsFromJSON(files, XPTableType.Woodcutting); } public static void UpdateMiningXPTable() { ConsoleLog.Print("Level System: Creating Mining XP Table", LogType.Message); string text = "MiningXP"; string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json"); Array.Sort(files); CreateListsFromJSON(files, XPTableType.Mining); } public static void UpdateMonsterXPTable() { ConsoleLog.Print("Level System: Creating Monster XP Table", LogType.Message); string text = "MonsterXP"; string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json"); Array.Sort(files); CreateListsFromJSON(files, XPTableType.Monster); } public static void UpdatePlayerXPTable() { ConsoleLog.Print("Level System: Creating Player XP Table", LogType.Message); string text = "PlayerXP"; string[] files = Directory.GetFiles(Paths.ConfigPath + "/LevelingSystem/" + text + "/", "*.json"); Array.Sort(files); int[] array = Array.Empty<int>(); string[] array2 = files; foreach (string path in array2) { string text2 = File.ReadAllText(path); Dictionary<string, int> dictionary; try { dictionary = SimpleJson.DeserializeObject<Dictionary<string, int>>(text2); } catch (Exception ex) { ConsoleLog.Print("Could not read player xp table file: '" + Path.GetFileName(path) + "'. Please make sure the json is valid and doesn't contain comments\n\nError Message: '" + ex.Message + "'", LogType.Warning); continue; } array = dictionary.Values.ToArray(); ConsoleLog.Print("Reading file: " + Path.GetFileName(path) + " (" + dictionary.Count + " values)", LogType.Message); if (array.Length != 0) { break; } } if (array.Length == 0) { throw new IOException("Could not find a valid player xp table. Please check for any errors further up, that might've occurred during the loading of the xp tables."); } playerXPTable = array.ToArray(); } public static int GetMonsterXP(string name) { name = name.Replace("(Clone)", ""); ConsoleLog.Print("Monster XP Table -> Looking for " + name + " -> Found: " + monsterXPTable.ContainsKey(name)); if (!monsterXPTable.ContainsKey(name)) { return 0; } return monsterXPTable[name]; } public static int GetPickableXP(string name) { name = name.Replace("(Clone)", ""); if (!pickableXPTable.ContainsKey(name)) { return 0; } return pickableXPTable[name]; } public static int GetMiningXP(string name) { name = name.Replace("(Clone)", ""); string text = (miningXPMappingTable.ContainsKey(name) ? miningXPMappingTable[name] : ""); if (string.IsNullOrEmpty(text)) { if (!miningXPTable.ContainsKey(name)) { return 0; } return miningXPTable[name]; } if (!miningXPTable.ContainsKey(text)) { return 0; } return miningXPTable[text]; } public static int GetWoodcuttingXP(string name) { name = name.Replace("(Clone)", ""); string key = (woodcuttingXPMappingTable.ContainsKey(name) ? woodcuttingXPMappingTable[name] : ""); if (!woodcuttingXPTable.ContainsKey(key)) { return 0; } return woodcuttingXPTable[key]; } private static void CreateListsFromJSON(string[] jsonFiles, XPTableType xpTableType) { switch (xpTableType) { case XPTableType.Monster: monsterXPTable.Clear(); break; case XPTableType.Pickable: pickableXPTable.Clear(); break; case XPTableType.Woodcutting: woodcuttingXPTable.Clear(); break; case XPTableType.Mining: miningXPTable.Clear(); break; } foreach (string path in jsonFiles) { string text = File.ReadAllText(path); Dictionary<string, int> dictionary; try { dictionary = SimpleJson.DeserializeObject<Dictionary<string, int>>(text); } catch (Exception ex) { ConsoleLog.Print("Could not read xp table file: '" + Path.GetFileName(path) + "'. Please make sure the json is valid and doesn't contain comments\n\nError Message: '" + ex.Message + "'", LogType.Warning); continue; } ConsoleLog.Print("Reading file: " + Path.GetFileName(path) + " (" + dictionary.Count + " values)", LogType.Message); Extensions.AddRange<string, int>(xpTableType switch { XPTableType.Monster => monsterXPTable, XPTableType.Pickable => pickableXPTable, XPTableType.Woodcutting => woodcuttingXPTable, XPTableType.Mining => miningXPTable, _ => new Dictionary<string, int>(), }, dictionary); } switch (xpTableType) { case XPTableType.Monster: ValidateXpTable("Monster", monsterXPTable); break; case XPTableType.Pickable: ValidateXpTable("Pickable", pickableXPTable); break; case XPTableType.Woodcutting: ValidateXpTable("Woodcutting", woodcuttingXPTable); break; case XPTableType.Mining: ValidateXpTable("Mining", miningXPTable); break; } static void ValidateXpTable(string name, IReadOnlyDictionary<string, int> xpTable) { if (xpTable.Count > 0) { return; } throw new IOException("No xp table was found for '" + name + "'. Please make sure that you have at least one valid .json file that represents an xp table for '" + name + "'."); } } } internal class MonsterXP { public uint monsterID; public List<PlayerDamage> playerDamages; public MonsterXP(uint monsterID) { this.monsterID = monsterID; playerDamages = new List<PlayerDamage>(); } public void AddDamage(long playerID, float damage, string playerName = "") { foreach (PlayerDamage playerDamage in playerDamages) { if (playerDamage.playerID == playerID) { playerDamage.playerTotalDamage += damage; return; } } playerDamages.Add(new PlayerDamage { playerID = playerID, playerTotalDamage = damage, playerName = playerName }); } public float GetTotalDamageDealt() { float num = 0f; foreach (PlayerDamage playerDamage in playerDamages) { num += playerDamage.playerTotalDamage; } return num; } } internal class PlayerDamage { public string playerName; public long playerID; public float playerTotalDamage; } internal class XPManager : MonoBehaviour { [CompilerGenerated] private sealed class <RPC_AddMonsterDamage>d__10 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RPC_AddMonsterDamage>d__10(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: { <>1__state = -1; if (!ZNet.instance.IsServer()) { ConsoleLog.Print("Expected server instance but got a non-server instance. Rejecting RPC", LogType.Error); return false; } uint monsterID = package.ReadUInt(); long playerID = package.ReadLong(); float damage = package.ReadSingle(); string playerName = package.ReadString(); MonsterXP monsterXP = Instance.GetMonsterXP(monsterID); if (monsterXP != null) { ConsoleLog.Print("Updated monster damage (Server)"); monsterXP.AddDamage(playerID, damage, playerName); } else { ConsoleLog.Print("Created new monster damage (Server)"); Instance.CreateNewMonsterXP(monsterID).AddDamage(playerID, damage, playerName); } <>2__current = null; <>1__state = 1; return true; } case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RPC_GetXPFromServer>d__14 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; public long sender; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RPC_GetXPFromServer>d__14(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { if (<>1__state != 0) { return false; } <>1__state = -1; if (!ZNet.instance.IsServer()) { ConsoleLog.Print("Expected server instance but got a non-server instance. Rejecting RPC", LogType.Error); return false; } long playerId = package.ReadLong(); string text = package.ReadString(); string text2 = package.ReadString(); int num = package.ReadInt(); ConsoleLog.Print("Server: Recieved GetXP Call (" + text + " - " + text2 + " - " + num + ")"); int num2; switch (text2) { case "Woodcutting": num2 = XPTable.GetWoodcuttingXP(text); break; case "Mining": num2 = XPTable.GetMiningXP(text); break; case "Pickable": num2 = XPTable.GetPickableXP(text); break; default: return false; } if (num2 <= 0) { return false; } ConsoleLog.Print("Server: Found XP = " + num2); RewardXP(sender, playerId, num2 * num, text2); return false; } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <RPC_RewardXPMonsters>d__16 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public ZPackage package; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <RPC_RewardXPMonsters>d__16(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <>1__state = -2; } private bool MoveNext() { //IL_0119: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Expected O, but got Unknown if (<>1__state != 0) { return false; } <>1__state = -1; if (!ZNet.instance.IsServer()) { return false; } uint monsterID = package.ReadUInt(); uint num = package.ReadUInt(); string text = package.ReadString(); ConsoleLog.Print("Monster died (Server) - " + text); MonsterXP monsterXP = Instance.GetMonsterXP(monsterID); if (monsterXP != null) { float totalDamageDealt = monsterXP.GetTotalDamageDealt(); float num2 = 0f; float num3 = 0f; float num4 = 0f; float num5 = 0f; float num6 = 0f; float num7 = 0f; bool flag = package.ReadBool(); if (flag) { num2 = package.ReadSingle(); num3 = package.ReadSingle(); num4 = package.ReadSingle(); num5 = package.ReadSingle(); num6 = package.ReadSingle(); num7 = package.ReadSingle(); } foreach (PlayerDamage playerDamage in monsterXP.playerDamages) { ZPackage val = new ZPackage(); float num8 = playerDamage.playerTotalDamage / totalDamageDealt; float num9 = Mathf.Min(1f - Main.baseXpSpreadMin.Value / 100f, 1f); float num10 = Mathf.Max(1f + Main.baseXpSpreadMax.Value / 100f, 1f); float num11 = Mathf.Max(0f, Main.monsterLvlXPMultiplier.Value / 100f); float num12 = Mathf.Max(0f, Main.allXPMultiplier.Value / 100f); float num13 = Mathf.Max(0f, Main.restedXPMultiplier.Value / 100f); float num14 = (float)XPTable.GetMonsterXP(text) * num8 * Random.Range(num9, num10) * num12; if (flag && Main.modDifficultyScalerLoaded && Main.enableDifficultyScalerXP.Value) { float num15 = num2 * Main.difficultyScalerOverallHealthRatio.Value; float num16 = num3 * Main.difficultyScalerOverallDamageRatio.Value; float num17 = num4 * Main.difficultyScalerBiomeRatio.Value; float num18 = num5 * Main.difficultyScalerBossRatio.Value; float num19 = num6 * Main.difficultyScalerBossRatio.Value; float num20 = num7 * Main.difficultyScalerStarRatio.Value; float num21 = 0f; ConsoleLog.Print("XP before scaling: " + num14); if (Main.difficultyScalerOverallHealth.Value) { num21 += num15; } if (Main.difficultyScalerOverallDamage.Value) { num21 += num16; } if (Main.difficultyScalerBiome.Value) { num21 += num17; } if (Main.difficultyScalerNight.Value) { num21 += num18; } if (Main.difficultyScalerBo