spels47 Posted April 14, 2021 Share Posted April 14, 2021 (edited) i have set everything up and ive found the code i want to alter using ILSpy. first question, is it necessary to be able to reference the method i want to alter with HarmonyPatch? if so is there any way to set private methods to public scope? or can i just not mod methods that has a private accessor? using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using BepInEx; using HarmonyLib; using UnityEngine; namespace ValheimIronMod { [BepInPlugin("patrick.ValheimIronMod", "valheim iron mod", "1.0.0")] [BepInProcess("valheim.exe")] public class ValheimIronMod : BaseUnityPlugin { private readonly Harmony harmony = new Harmony("patrick.ValheimIronMod"); void Awake() { harmony.PatchAll(); } [HarmonyPatch(typeof(MineRock5), nameof(MineRock5.DamageArea))] class MineRock5_Patch { //static void Prefix(ref float ___m_jumpForce) //{ // Debug.Log($"Jump Force: {___m_jumpForce}"); // ___m_jumpForce = 15; // Debug.Log($"Modified Jump Force: {___m_jumpForce}"); //} } } } also, how do i alter methods in valheim? ive seen a couple of tutorial videos on youtube but they only cover changing a public variables value in the game not alter a method MineRock5 => DamageArea(int hitAreaIndex, HitData hit) this is the method as is vanilla that i want to alter private bool DamageArea(int hitAreaIndex, HitData hit) { ZLog.Log((object)("hit mine rock " + hitAreaIndex)); HitArea hitArea = GetHitArea(hitAreaIndex); if (hitArea == null) { ZLog.Log((object)("Missing hit area " + hitAreaIndex)); return false; } LoadHealth(); if (hitArea.m_health <= 0f) { ZLog.Log((object)"Already destroyed"); return false; } hit.ApplyResistance(m_damageModifiers, out var significantModifier); float totalDamage = hit.GetTotalDamage(); if (hit.m_toolTier < m_minToolTier) { DamageText.instance.ShowText(DamageText.TextType.TooHard, hit.m_point, 0f); return false; } DamageText.instance.ShowText(significantModifier, hit.m_point, totalDamage); if (totalDamage <= 0f) { return false; } hitArea.m_health -= totalDamage; SaveHealth(); m_hitEffect.Create(hit.m_point, Quaternion.identity); Player closestPlayer = Player.GetClosestPlayer(hit.m_point, 10f); if ((bool)closestPlayer) { closestPlayer.AddNoise(100f); } if (hitArea.m_health <= 0f) { m_nview.InvokeRPC(ZNetView.Everybody, "SetAreaHealth", hitAreaIndex, hitArea.m_health); m_destroyedEffect.Create(hit.m_point, Quaternion.identity); foreach (GameObject drop in m_dropItems.GetDropList()) { Vector3 position = hit.m_point + Random.insideUnitSphere * 0.3f; Object.Instantiate(drop, position, Quaternion.identity); } if (AllDestroyed()) { m_nview.Destroy(); } return true; } return false; }also using this class in the alterations for the method above ObjectDB => GetItemPrefab(string name) inside that method i want to alter one of the loops a little var objectDB = new ObjectDB(); // i want to add this line var ironOre = objectDB.GetItemPrefab("IronScrap"); // i want to add this line foreach (GameObject drop in m_dropItems.GetDropList()) { Vector3 position = hit.m_point + Random.insideUnitSphere * 0.3f; var percentageDiceRoll = Random.Range(0,100); // i want to add this line if(percentageDiceRoll <= 20) Object.Instantiate(ironOre, position, Quaternion.identity); // i want to add this line Object.Instantiate(drop, position, Quaternion.identity); }but how can i do this? Edited April 14, 2021 by spels47 Link to comment Share on other sites More sharing options...
billwerth2 Posted April 14, 2021 Share Posted April 14, 2021 (edited) Yes, you can call private methods, what you need is to make a reverse patch, which creates your own method that is public that calls the private method (at least that is my simple explanation). There is documentation on how it works here:https://harmony.pardeike.net/articles/reverse-patching.html To alter a function, you need a transpiler. How to do this is in the above documentation too. I've yet to make one. So for I've just created prefix methods and the reverse patch. BTW, since it looks like you are just adding some code, not modifying the code, you could probably just use a postfix method on the above function. Your method would add the iron drop in addition to the normal drop. BTW, much better help for this stuff can be found in this discord:https://discord.com/channels/807356896637354004/807360834892202015 Edited April 14, 2021 by billwerth2 Link to comment Share on other sites More sharing options...
spels47 Posted April 19, 2021 Author Share Posted April 19, 2021 thanks, i cant seem to get that discord link to work, it opens discord but other than that it does nothing for me, is the link correct? Link to comment Share on other sites More sharing options...
billwerth2 Posted April 26, 2021 Share Posted April 26, 2021 Yes, you can call private methods, what you need is to make a reverse patch, which creates your own method that is public that calls the private method (at least that is my simple explanation). There is documentation on how it works here:https://harmony.pardeike.net/articles/reverse-patching.html To alter a function, you need a transpiler. How to do this is in the above documentation too. I've yet to make one. So for I've just created prefix methods and the reverse patch. thanks, i cant seem to get that discord link to work, it opens discord but other than that it does nothing for me, is the link correct? BTW, since it looks like you are just adding some code, not modifying the code, you could probably just use a postfix method on the above function. Your method would add the iron drop in addition to the normal drop. BTW, much better help for this stuff can be found in this discord:https://discord.com/channels/807356896637354004/807360834892202015 As far as I know, that is the link. It works for me. Link to comment Share on other sites More sharing options...
Recommended Posts