Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of WeaponCrafting v0.1.0
plugins/JotunnModStub.dll
Decompiled 6 months agousing System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.Versioning; using System.Security.Permissions; using BepInEx; using BepInEx.Bootstrap; using HarmonyLib; using Newtonsoft.Json; using UnityEngine; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints)] [assembly: AssemblyTitle("WeaponCraftingMod")] [assembly: AssemblyDescription("Valheim mod adding SES/Perk Tiers with Smithing skill")] [assembly: AssemblyCompany("proflupin")] [assembly: AssemblyProduct("WeaponCraftingMod")] [assembly: AssemblyFileVersion("1.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")] [BepInPlugin("proflupin.weaponcrafting", "WeaponCrafting", "1.0.0")] public class WeaponCraftingMod : BaseUnityPlugin { private const string DataFileName = "weaponcrafting_smithing.json"; private SmithingDataStore _store; private string DataFilePath => Path.Combine(Paths.ConfigPath, "weaponcrafting_smithing.json"); private void Awake() { //IL_0005: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Expected O, but got Unknown Harmony val = new Harmony("proflupin.weaponcrafting"); val.PatchAll(); LoadData(); try { Type typeFromHandle = typeof(ZRoutedRpc); ZRoutedRpc instance = ZRoutedRpc.instance; if (instance != null) { MethodInfo[] methods = typeFromHandle.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { if (methodInfo.Name != "Register") { continue; } ParameterInfo[] parameters = methodInfo.GetParameters(); if (parameters.Length == 2 && !(parameters[0].ParameterType != typeof(string))) { Type parameterType = parameters[1].ParameterType; bool flag = false; try { MethodInfo method = ((object)this).GetType().GetMethod("OnMasterForgeRpc_Long", BindingFlags.Instance | BindingFlags.NonPublic); Delegate @delegate = Delegate.CreateDelegate(parameterType, this, method); methodInfo.Invoke(instance, new object[2] { "WeaponCrafting_MasterForge", @delegate }); flag = true; } catch { } if (flag) { break; } try { MethodInfo method2 = ((object)this).GetType().GetMethod("OnMasterForgeRpc_ZRpc", BindingFlags.Instance | BindingFlags.NonPublic); Delegate delegate2 = Delegate.CreateDelegate(parameterType, this, method2); methodInfo.Invoke(instance, new object[2] { "WeaponCrafting_MasterForge", delegate2 }); flag = true; } catch { } if (flag) { break; } } } } } catch { } try { SetupUpgradePatches(val); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"WeaponCrafting: failed to setup upgrade patches: {arg}"); } } private void OnDestroy() { SaveData(); } private void LoadData() { try { if (File.Exists(DataFilePath)) { string text = File.ReadAllText(DataFilePath); _store = JsonConvert.DeserializeObject<SmithingDataStore>(text) ?? new SmithingDataStore(); } else { _store = new SmithingDataStore(); } } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"WeaponCrafting: failed to load data: {arg}"); _store = new SmithingDataStore(); } } private void SaveData() { try { string directoryName = Path.GetDirectoryName(DataFilePath); if (!Directory.Exists(directoryName)) { Directory.CreateDirectory(directoryName); } string contents = JsonConvert.SerializeObject((object)_store, (Formatting)1); File.WriteAllText(DataFilePath, contents); } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"WeaponCrafting: failed to save data: {arg}"); } } private void OnMasterForgeRpc_Long(long sender, ZPackage pkg) { try { if (pkg != null) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); string text4 = ((Random.Range(0, 100) >= 50) ? ("The " + text2 + " of " + text + " shall be revered throughout the ages") : ("Odin smiles upon " + text + "'s " + text2 + ", bestowing his great power upon it")); if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text4, 0, (Sprite)null, false); } Debug.Log((object)("[WeaponCrafting] Master-forge broadcast: " + text + " -> " + text2 + " (boon: " + text3 + ")")); } } catch { } } private void OnMasterForgeRpc_ZRpc(ZRpc rpc, ZPackage pkg) { try { if (pkg != null) { string text = pkg.ReadString(); string text2 = pkg.ReadString(); string text3 = pkg.ReadString(); string text4 = ((Random.Range(0, 100) >= 50) ? ("The " + text2 + " of " + text + " shall be revered throughout the ages") : ("Odin smiles upon " + text + "'s " + text2 + ", bestowing his great power upon it")); if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text4, 0, (Sprite)null, false); } Debug.Log((object)("[WeaponCrafting] Master-forge broadcast: " + text + " -> " + text2 + " (boon: " + text3 + ")")); } } catch { } } public void AddSmithingXP(string playerName, int xp) { if (!string.IsNullOrEmpty(playerName) && xp > 0) { SmithingEntry orCreate = _store.GetOrCreate(playerName); orCreate.XP += xp; orCreate.Level = ComputeLevelFromXP(orCreate.XP); SaveData(); } } private int ComputeLevelFromXP(int xp) { int i = 1; int num = xp; for (; i < 100; i++) { int num2 = (int)Math.Floor(80.0 * Math.Pow(1.05, i - 1)); if (num < num2) { break; } num -= num2; } if (i < 1) { i = 1; } if (i > 100) { i = 100; } return i; } public SmithingEntry GetSmithingFor(string playerName) { return _store.GetOrCreate(playerName); } private void SetupUpgradePatches(Harmony harmony) { //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Expected O, but got Unknown try { Assembly assembly = typeof(Player).Assembly; List<MethodInfo> list = new List<MethodInfo>(); Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (type.IsGenericType || type.IsInterface) { continue; } MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo methodInfo in methods) { string text = methodInfo.Name.ToLower(); if ((text.Contains("upgrade") || text.Contains("upgradeitem") || text.Contains("do_upgrade") || text.Contains("upgrade_piece") || text.Contains("upgradepiece")) && methodInfo.ReturnType == typeof(void)) { list.Add(methodInfo); } } } MethodInfo method = typeof(WeaponCraftingMod).GetMethod("Upgrade_Postfix", BindingFlags.Static | BindingFlags.NonPublic); int num = 0; foreach (MethodInfo item in list) { try { HarmonyMethod val = new HarmonyMethod(method); harmony.Patch((MethodBase)item, (HarmonyMethod)null, val, (HarmonyMethod)null, (HarmonyMethod)null, (HarmonyMethod)null); ((BaseUnityPlugin)this).Logger.LogInfo((object)("WeaponCrafting: patched upgrade method " + item.DeclaringType.FullName + "." + item.Name)); num++; } catch (Exception arg) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"WeaponCrafting: failed to patch {item.DeclaringType.FullName}.{item.Name}: {arg}"); } } ((BaseUnityPlugin)this).Logger.LogInfo((object)$"WeaponCrafting: patched {num} upgrade methods"); } catch (Exception arg2) { ((BaseUnityPlugin)this).Logger.LogWarning((object)$"WeaponCrafting: SetupUpgradePatches error: {arg2}"); } } private static int GetPieceLevel(Piece piece) { if ((Object)(object)piece == (Object)null) { return 1; } try { FieldInfo field = typeof(Piece).GetField("m_level", BindingFlags.Instance | BindingFlags.NonPublic); if (field != null) { object value = field.GetValue(piece); if (value is int) { int num = (int)value; return (num <= 0) ? 1 : num; } } } catch { } return 1; } private static void Upgrade_Postfix(object __instance, object[] __args) { //IL_00b0: Unknown result type (might be due to invalid IL or missing references) //IL_00bb: Unknown result type (might be due to invalid IL or missing references) try { Player val = null; Player val2 = (Player)((__instance is Player) ? __instance : null); if (val2 != null) { val = val2; } if ((Object)(object)val == (Object)null && __args != null) { foreach (object obj in __args) { Player val3 = (Player)((obj is Player) ? obj : null); if (val3 != null) { val = val3; break; } } } if ((Object)(object)val == (Object)null) { val = Player.m_localPlayer; } if ((Object)(object)val == (Object)null) { return; } Piece val4 = null; Piece val5 = null; try { Piece[] array = Object.FindObjectsOfType<Piece>(); float num = 999f; float num2 = 999f; Piece[] array2 = array; foreach (Piece val6 in array2) { if ((Object)(object)val6 == (Object)null || (Object)(object)((Component)val6).gameObject == (Object)null) { continue; } float num3 = Vector3.Distance(((Component)val6).transform.position, ((Component)val).transform.position); if (!(num3 > 3f)) { string text = ((Object)((Component)val6).gameObject).name.ToLower(); if ((text.Contains("blackforge") || text.Contains("forge_black")) && num3 < num2) { val5 = val6; num2 = num3; } if (text.Contains("forge") && !text.Contains("black") && num3 < num) { val4 = val6; num = num3; } } } } catch { } WeaponCraftingMod component = Chainloader.ManagerObject.GetComponent<WeaponCraftingMod>(); if (!((Object)(object)component == (Object)null)) { if ((Object)(object)val5 != (Object)null) { int pieceLevel = GetPieceLevel(val5); int num4 = 13 + 2 * pieceLevel; component.AddSmithingXP(val.GetPlayerName(), num4); Debug.Log((object)$"[WeaponCrafting] Upgrade near black forge level {pieceLevel}: +{num4} XP to {val.GetPlayerName()}"); } else if ((Object)(object)val4 != (Object)null) { int pieceLevel2 = GetPieceLevel(val4); int num5 = 8 + 2 * pieceLevel2; component.AddSmithingXP(val.GetPlayerName(), num5); Debug.Log((object)$"[WeaponCrafting] Upgrade near forge level {pieceLevel2}: +{num5} XP to {val.GetPlayerName()}"); } } } catch { } } private void BroadcastMasterForgeRpc(string playerName, string itemName, string boon) { //IL_0000: Unknown result type (might be due to invalid IL or missing references) //IL_0006: Expected O, but got Unknown try { ZPackage val = new ZPackage(); val.Write(playerName); val.Write(itemName); val.Write(boon ?? string.Empty); ZRoutedRpc.instance.InvokeRoutedRPC(ZRoutedRpc.Everybody, "WeaponCrafting_MasterForge", new object[1] { val }); Debug.Log((object)("[WeaponCrafting] Broadcast master-forge RPC: " + playerName + " -> " + itemName)); } catch (Exception arg) { Debug.LogWarning((object)$"[WeaponCrafting] BroadcastMasterForgeRpc error: {arg}"); } } private static bool InventoryBelongsTo(Inventory inv, params string[] keywords) { try { if (inv == null) { return false; } Type type = ((object)inv).GetType(); FieldInfo[] fields = type.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (FieldInfo fieldInfo in fields) { try { object value = fieldInfo.GetValue(inv); if (value == null) { continue; } GameObject val = (GameObject)((value is GameObject) ? value : null); string[] array; if (val != null) { string text = ((Object)val).name.ToLower(); array = keywords; foreach (string text2 in array) { if (text.Contains(text2.ToLower())) { return true; } } continue; } Component val2 = (Component)((value is Component) ? value : null); if (val2 != null) { string text3 = ((Object)val2.gameObject).name.ToLower(); array = keywords; foreach (string text4 in array) { if (text3.Contains(text4.ToLower())) { return true; } } continue; } string text5 = value.ToString(); if (string.IsNullOrEmpty(text5)) { continue; } string text6 = text5.ToLower(); array = keywords; foreach (string text7 in array) { if (text6.Contains(text7.ToLower())) { return true; } } } catch { } } PropertyInfo[] properties = type.GetProperties(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (PropertyInfo propertyInfo in properties) { try { object value2 = propertyInfo.GetValue(inv); if (value2 == null) { continue; } GameObject val3 = (GameObject)((value2 is GameObject) ? value2 : null); string[] array; if (val3 != null) { string text8 = ((Object)val3).name.ToLower(); array = keywords; foreach (string text9 in array) { if (text8.Contains(text9.ToLower())) { return true; } } continue; } Component val4 = (Component)((value2 is Component) ? value2 : null); if (val4 != null) { string text10 = ((Object)val4.gameObject).name.ToLower(); array = keywords; foreach (string text11 in array) { if (text10.Contains(text11.ToLower())) { return true; } } continue; } string text12 = value2.ToString(); if (string.IsNullOrEmpty(text12)) { continue; } string text13 = text12.ToLower(); array = keywords; foreach (string text14 in array) { if (text13.Contains(text14.ToLower())) { return true; } } } catch { } } } catch { } return false; } public void ApplySmithingOnCreate(Player player, ItemData item) { //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0120: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Unknown result type (might be due to invalid IL or missing references) //IL_0127: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Unknown result type (might be due to invalid IL or missing references) //IL_015f: Unknown result type (might be due to invalid IL or missing references) //IL_017b: Unknown result type (might be due to invalid IL or missing references) //IL_0197: Unknown result type (might be due to invalid IL or missing references) //IL_02b2: Unknown result type (might be due to invalid IL or missing references) //IL_02b7: Unknown result type (might be due to invalid IL or missing references) //IL_02b9: Unknown result type (might be due to invalid IL or missing references) //IL_01b3: Unknown result type (might be due to invalid IL or missing references) //IL_02d7: Unknown result type (might be due to invalid IL or missing references) //IL_01cf: Unknown result type (might be due to invalid IL or missing references) //IL_02f5: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0331: Unknown result type (might be due to invalid IL or missing references) //IL_034f: Unknown result type (might be due to invalid IL or missing references) //IL_036d: Unknown result type (might be due to invalid IL or missing references) //IL_038b: Unknown result type (might be due to invalid IL or missing references) //IL_03f3: Unknown result type (might be due to invalid IL or missing references) //IL_03f8: Unknown result type (might be due to invalid IL or missing references) //IL_03fa: Unknown result type (might be due to invalid IL or missing references) //IL_0422: Unknown result type (might be due to invalid IL or missing references) //IL_040a: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0432: Unknown result type (might be due to invalid IL or missing references) //IL_0472: Unknown result type (might be due to invalid IL or missing references) //IL_045a: Unknown result type (might be due to invalid IL or missing references) //IL_049a: Unknown result type (might be due to invalid IL or missing references) //IL_0482: Unknown result type (might be due to invalid IL or missing references) //IL_04c2: Unknown result type (might be due to invalid IL or missing references) //IL_04aa: Unknown result type (might be due to invalid IL or missing references) //IL_04ea: Unknown result type (might be due to invalid IL or missing references) //IL_04d2: Unknown result type (might be due to invalid IL or missing references) //IL_0512: Unknown result type (might be due to invalid IL or missing references) //IL_04fa: Unknown result type (might be due to invalid IL or missing references) //IL_0525: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)player == (Object)null || item == null) { return; } int level = GetSmithingFor(player.GetPlayerName()).Level; _ = item.m_shared.m_damages; bool flag = item.m_shared.m_damages.m_slash > 0f || item.m_shared.m_damages.m_blunt > 0f || item.m_shared.m_damages.m_pierce > 0f; bool flag2 = item.m_shared.m_armor > 0f || item.m_shared.m_blockPower > 0f; int num = Random.Range(5, 9) + Mathf.FloorToInt((float)level / 3f) + 2; if (item.m_durability > 0f) { item.m_durability += (float)num; } if (item.m_shared.m_maxDurability > 0f) { SharedData shared = item.m_shared; shared.m_maxDurability += (float)num; } if (flag) { int num2 = Random.Range(3, 6) + Mathf.Max(2, Mathf.FloorToInt((float)level / 5f)); DamageTypes damages = item.m_shared.m_damages; if (damages.m_slash > 0f) { damages.m_slash += num2; } if (damages.m_blunt > 0f) { damages.m_blunt += num2; } if (damages.m_pierce > 0f) { damages.m_pierce += num2; } if (damages.m_fire > 0f) { damages.m_fire += num2; } if (damages.m_frost > 0f) { damages.m_frost += num2; } if (damages.m_poison > 0f) { damages.m_poison += num2; } if (damages.m_lightning > 0f) { damages.m_lightning += num2; } if (damages.m_spirit > 0f) { damages.m_spirit += num2; } } if (flag2) { int num3 = Random.Range(4, 7) + Mathf.Max(2, Mathf.FloorToInt((float)level / 4f)); SharedData shared2 = item.m_shared; shared2.m_armor += (float)num3; SharedData shared3 = item.m_shared; shared3.m_blockPower += (float)num3; } int num4 = Mathf.Clamp(level, 1, 100); int num5 = ((num4 <= 40) ? 40 : ((num4 <= 75) ? 50 : 60)); if (Random.Range(0, 100) >= num5) { return; } if (item.m_shared.m_maxDurability > 0f) { SharedData shared4 = item.m_shared; shared4.m_maxDurability += 20f; } DamageTypes damages2 = item.m_shared.m_damages; if (damages2.m_slash > 0f) { damages2.m_slash += 5f; } if (damages2.m_blunt > 0f) { damages2.m_blunt += 5f; } if (damages2.m_pierce > 0f) { damages2.m_pierce += 5f; } if (damages2.m_fire > 0f) { damages2.m_fire += 5f; } if (damages2.m_frost > 0f) { damages2.m_frost += 5f; } if (damages2.m_poison > 0f) { damages2.m_poison += 5f; } if (damages2.m_lightning > 0f) { damages2.m_lightning += 5f; } if (damages2.m_spirit > 0f) { damages2.m_spirit += 5f; } int num6 = 40 + Mathf.FloorToInt((float)level / 3f); int num7 = Random.Range(0, 100); string text = null; if (num7 < num6) { if (flag) { int num8 = Random.Range(0, 100); if (num8 < 40) { text = "Razor"; DamageTypes damages3 = item.m_shared.m_damages; if (damages3.m_slash > 0f) { damages3.m_slash = Mathf.FloorToInt(damages3.m_slash * 1.25f); } if (damages3.m_blunt > 0f) { damages3.m_blunt = Mathf.FloorToInt(damages3.m_blunt * 1.25f); } if (damages3.m_pierce > 0f) { damages3.m_pierce = Mathf.FloorToInt(damages3.m_pierce * 1.25f); } if (damages3.m_fire > 0f) { damages3.m_fire = Mathf.FloorToInt(damages3.m_fire * 1.25f); } if (damages3.m_frost > 0f) { damages3.m_frost = Mathf.FloorToInt(damages3.m_frost * 1.25f); } if (damages3.m_poison > 0f) { damages3.m_poison = Mathf.FloorToInt(damages3.m_poison * 1.25f); } if (damages3.m_lightning > 0f) { damages3.m_lightning = Mathf.FloorToInt(damages3.m_lightning * 1.25f); } if (damages3.m_spirit > 0f) { damages3.m_spirit = Mathf.FloorToInt(damages3.m_spirit * 1.25f); } } else if (num8 < 80) { text = "Ogre"; item.m_shared.m_attackForce = Mathf.FloorToInt(item.m_shared.m_attackForce * 1.75f); } else { text = "Goblin"; if (item.m_customData == null) { item.m_customData = new Dictionary<string, string>(); } item.m_customData["GOBLIN_BOON"] = "1"; } } else if (flag2) { if (item.m_shared.m_blockPower > 0f) { if (Random.Range(0, 100) < 50) { text = "Stalwart"; item.m_shared.m_blockPower = Mathf.FloorToInt(item.m_shared.m_blockPower * 1.6f); } else { text = "Sealed"; item.m_shared.m_armor = Mathf.FloorToInt(item.m_shared.m_armor * 1.35f); } } else if (Random.Range(0, 100) < 60) { text = "Reinforced"; item.m_shared.m_armor = Mathf.FloorToInt(item.m_shared.m_armor * 1.25f); } else { text = "Feather"; if (item.m_customData == null) { item.m_customData = new Dictionary<string, string>(); } item.m_customData["FEATHER_BOON"] = "1"; } } } string playerName = player.GetPlayerName(); string name = item.m_shared.m_name; string text2 = "Odin smiles upon " + playerName + "'s " + name + ", bestowing his great power upon it"; if ((Object)(object)MessageHud.instance != (Object)null) { MessageHud.instance.ShowMessage((MessageType)2, text2, 0, (Sprite)null, false); } ((BaseUnityPlugin)this).Logger.LogInfo((object)("[WeaponCrafting] Master-forged: " + playerName + " -> " + name + " (boon: " + (text ?? "None") + ")")); BroadcastMasterForgeRpc(playerName, name, text ?? string.Empty); } } public class SmithingDataStore { public List<SmithingEntry> Players = new List<SmithingEntry>(); public SmithingEntry GetOrCreate(string name) { SmithingEntry smithingEntry = Players.Find((SmithingEntry x) => x.Name == name); if (smithingEntry == null) { smithingEntry = new SmithingEntry { Name = name, XP = 0, Level = 1 }; Players.Add(smithingEntry); } return smithingEntry; } } public class SmithingEntry { public string Name; public int XP; public int Level; } public static class CharacterExtensions { private static readonly FieldInfo RightItemField = typeof(Humanoid).GetField("m_rightItem", BindingFlags.Instance | BindingFlags.NonPublic); public static ItemData GetRightHandItem(this Character character) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_001b: Expected O, but got Unknown Humanoid val = (Humanoid)(object)((character is Humanoid) ? character : null); if (val != null) { return (ItemData)RightItemField.GetValue(val); } return null; } } [HarmonyPatch(typeof(Inventory), "AddItem")] public class Inventory_AddItem_Smithing_Patch { private static void Postfix(ItemData item, Inventory __instance) { //IL_0375: Unknown result type (might be due to invalid IL or missing references) //IL_037a: Unknown result type (might be due to invalid IL or missing references) //IL_0298: Unknown result type (might be due to invalid IL or missing references) //IL_029d: Unknown result type (might be due to invalid IL or missing references) try { if (item == null || __instance == null) { return; } WeaponCraftingMod component = Chainloader.ManagerObject.GetComponent<WeaponCraftingMod>(); if ((Object)(object)component == (Object)null) { return; } Player localPlayer = Player.m_localPlayer; object obj = ((object)component).GetType().GetMethod("InventoryBelongsTo", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[2] { __instance, new string[1] { "kiln" } }); bool flag = default(bool); int num; if (obj is bool) { flag = (bool)obj; num = 1; } else { num = 0; } if (((uint)num & (flag ? 1u : 0u)) != 0 && item.m_shared.m_name.ToLower().Contains("wood") && (Object)(object)localPlayer != (Object)null) { component.AddSmithingXP(localPlayer.GetPlayerName(), 5); Debug.Log((object)("[WeaponCrafting] Kiln fed by " + localPlayer.GetPlayerName() + ": +5 XP")); } obj = ((object)component).GetType().GetMethod("InventoryBelongsTo", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[2] { __instance, new string[1] { "smelter" } }); bool flag2 = default(bool); int num2; if (obj is bool) { flag2 = (bool)obj; num2 = 1; } else { num2 = 0; } if (((uint)num2 & (flag2 ? 1u : 0u)) != 0) { string text = item.m_shared.m_name.ToLower(); if ((text.Contains("coal") || text.Contains("ore") || text.Contains("iron") || text.Contains("copper") || text.Contains("silver")) && (Object)(object)localPlayer != (Object)null) { component.AddSmithingXP(localPlayer.GetPlayerName(), 10); Debug.Log((object)("[WeaponCrafting] Smelter fed by " + localPlayer.GetPlayerName() + ": +10 XP")); } } obj = ((object)component).GetType().GetMethod("InventoryBelongsTo", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[2] { __instance, new string[1] { "blast" } }); bool flag3 = default(bool); int num3; if (obj is bool) { flag3 = (bool)obj; num3 = 1; } else { num3 = 0; } if (((uint)num3 & (flag3 ? 1u : 0u)) != 0) { string text2 = item.m_shared.m_name.ToLower(); if ((text2.Contains("coal") || text2.Contains("ore") || text2.Contains("iron") || text2.Contains("copper") || text2.Contains("silver")) && (Object)(object)localPlayer != (Object)null) { component.AddSmithingXP(localPlayer.GetPlayerName(), 15); Debug.Log((object)("[WeaponCrafting] Blast furnace fed by " + localPlayer.GetPlayerName() + ": +15 XP")); } } if (!((Object)(object)localPlayer != (Object)null) || __instance != ((Humanoid)localPlayer).GetInventory()) { return; } Vector3 position = ((Component)localPlayer).transform.position; Piece val = null; Piece val2 = null; float num4 = 999f; float num5 = 999f; try { IEnumerable<Piece> enumerable = null; MethodInfo method = typeof(Object).GetMethod("FindObjectsByType", BindingFlags.Static | BindingFlags.Public); if (method != null) { try { MethodInfo methodInfo = (method.IsGenericMethod ? method.MakeGenericMethod(typeof(Piece)) : null); if (methodInfo != null) { enumerable = (IEnumerable<Piece>)methodInfo.Invoke(null, new object[1] { 0 }); } } catch { } } if (enumerable == null) { enumerable = Object.FindObjectsOfType<Piece>(); } foreach (Piece item2 in enumerable) { if ((Object)(object)item2 == (Object)null || (Object)(object)((Component)item2).gameObject == (Object)null) { continue; } float num6 = Vector3.Distance(((Component)item2).transform.position, position); if (!(num6 > 3f)) { string text3 = ((Object)((Component)item2).gameObject).name.ToLower(); if ((text3.Contains("blackforge") || text3.Contains("forge_black")) && num6 < num5) { val2 = item2; num5 = num6; } if (text3.Contains("forge") && !text3.Contains("black") && num6 < num4) { val = item2; num4 = num6; } } } } catch { } if ((Object)(object)val2 != (Object)null) { int num8 = ((!(((object)component).GetType().GetMethod("GetPieceLevel", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[1] { val2 }) is int num7)) ? 1 : num7); int num9 = 26 + 4 * num8; component.AddSmithingXP(localPlayer.GetPlayerName(), num9); component.ApplySmithingOnCreate(localPlayer, item); Debug.Log((object)$"[WeaponCrafting] Craft on black forge level {num8}: +{num9} XP to {localPlayer.GetPlayerName()}"); } else if ((Object)(object)val != (Object)null) { int num11 = ((!(((object)component).GetType().GetMethod("GetPieceLevel", BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[1] { val }) is int num10)) ? 1 : num10); int num12 = 13 + 2 * num11; component.AddSmithingXP(localPlayer.GetPlayerName(), num12); component.ApplySmithingOnCreate(localPlayer, item); Debug.Log((object)$"[WeaponCrafting] Craft on forge level {num11}: +{num12} XP to {localPlayer.GetPlayerName()}"); } } catch (Exception arg) { Debug.LogWarning((object)$"WeaponCrafting: Inventory.AddItem patch error: {arg}"); } } } [HarmonyPatch(typeof(Humanoid), "UpdateEquipment")] public class Humanoid_Equip_Boons_Patch { private static readonly Dictionary<int, float> OrigAttackSpeed = new Dictionary<int, float>(); private static readonly Dictionary<int, float> OrigMoveSpeed = new Dictionary<int, float>(); private static void Postfix(Humanoid __instance) { if ((Object)(object)__instance == (Object)null) { return; } try { ItemData rightHandItem = ((Character)(object)__instance).GetRightHandItem(); int instanceID = ((Object)__instance).GetInstanceID(); FieldInfo fieldInfo = typeof(Humanoid).GetField("m_attackSpeed", BindingFlags.Instance | BindingFlags.NonPublic) ?? typeof(Humanoid).GetField("m_attackSpeedMultiplier", BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo != null) { float value = ((fieldInfo.GetValue(__instance) is float num) ? num : 1f); if (!OrigAttackSpeed.ContainsKey(instanceID)) { OrigAttackSpeed[instanceID] = value; } float num2 = OrigAttackSpeed[instanceID]; if (rightHandItem != null && rightHandItem.m_customData != null && rightHandItem.m_customData.ContainsKey("GOBLIN_BOON")) { fieldInfo.SetValue(__instance, num2 * 0.85f); } else { fieldInfo.SetValue(__instance, num2); } } string[] obj = new string[4] { "m_runSpeed", "m_moveSpeed", "m_walkSpeed", "m_speed" }; FieldInfo fieldInfo2 = null; string[] array = obj; foreach (string name in array) { fieldInfo2 = typeof(Humanoid).GetField(name, BindingFlags.Instance | BindingFlags.NonPublic); if (fieldInfo2 != null) { break; } } if (fieldInfo2 != null) { float value2 = ((fieldInfo2.GetValue(__instance) is float num3) ? num3 : 1f); if (!OrigMoveSpeed.ContainsKey(instanceID)) { OrigMoveSpeed[instanceID] = value2; } float num4 = OrigMoveSpeed[instanceID]; if (rightHandItem != null && rightHandItem.m_customData != null && rightHandItem.m_customData.ContainsKey("FEATHER_BOON")) { fieldInfo2.SetValue(__instance, num4 * 1.03f); } else { fieldInfo2.SetValue(__instance, num4); } } } catch { } } }