Modding:Monkey patching: Difference between revisions

From Vintage Story Wiki
m
Updated to 1.19.3. Fixed some code issues.
(→‎Cleaning Up: handle harmony possibly being null in single player)
m (Updated to 1.19.3. Fixed some code issues.)
Line 1: Line 1:
{{GameVersion|1.18}}
{{GameVersion|1.19.3}}


Monkey patching (changing code at runtime) in Vintage Story is available through [https://harmony.pardeike.net/articles/basics.html Harmony].  
Monkey patching (changing code at runtime) in Vintage Story is available through [https://harmony.pardeike.net/articles/basics.html Harmony].  
Line 21: Line 21:
[HarmonyPatch] // Place on any class with harmony patches
[HarmonyPatch] // Place on any class with harmony patches
public class MyModSystem : ModSystem {
public class MyModSystem : ModSystem {
     public ICoreAPI api;
     public static ICoreAPI api;
     public Harmony harmony;
     public Harmony harmony;
      
      
     public void Start(ICoreAPI api) {
     public override void Start(ICoreAPI api) {
         this.api = api;
         MyModSystem.api = api;
         // The mod is started once for the server and once for the client.
         // The mod is started once for the server and once for the client.
         // Prevent the patches from being applied by both in the same process.
         // Prevent the patches from being applied by both in the same process.
Line 46: Line 46:
     // Note that the name of the function does not matter
     // Note that the name of the function does not matter
     public static void ItemReceivedDamage(EntityItem __instance, float damage) { // For methods, use __instance to obtain the caller object
     public static void ItemReceivedDamage(EntityItem __instance, float damage) { // For methods, use __instance to obtain the caller object
         api.Logger.Event("{0} is about to take {1} damage!", __instance.Slot.ItemStack, damage);
         api.Logger.Event("{0} is about to take {1} damage!", __instance.Slot.Itemstack, damage);
     }
     }
</syntaxhighlight>
</syntaxhighlight>
Line 55: Line 55:
     [HarmonyPatch(typeof(EntityItem), "ReceiveDamage")]
     [HarmonyPatch(typeof(EntityItem), "ReceiveDamage")]
     public static void ItemReceivedDamageAfter(EntityItem __instance, float damage) {
     public static void ItemReceivedDamageAfter(EntityItem __instance, float damage) {
         api.Logger.Event("{0} took {1} damage!", __instance.Slot.ItemStack, damage);
         api.Logger.Event("{0} took {1} damage!", __instance.Slot.Itemstack, damage);
         api.Logger.Event("Is it still alive? {0}", __instance.Alive);
         api.Logger.Event("Is it still alive? {0}", __instance.Alive);
     }
     }
Line 97: Line 97:
For good practice, if you patch the game with your mod, make sure you unpatch it when your mod unloads. The easiest way to do this is to run <code>harmony.UnpatchAll("MyModId")</code> in the <code>Dispose</code> method of a ModSystem. Make sure you include the id in the call to <code>UnpatchAll()</code>, as otherwise you may accidentally unpatch other mods before they expect.
For good practice, if you patch the game with your mod, make sure you unpatch it when your mod unloads. The easiest way to do this is to run <code>harmony.UnpatchAll("MyModId")</code> in the <code>Dispose</code> method of a ModSystem. Make sure you include the id in the call to <code>UnpatchAll()</code>, as otherwise you may accidentally unpatch other mods before they expect.
<syntaxhighlight lang="c#">
<syntaxhighlight lang="c#">
     public void Dispose() {
     public override void Dispose() {
         harmony?.UnpatchAll(Mod.Info.ModID);
         harmony?.UnpatchAll(Mod.Info.ModID);
     }
     }
Confirmedusers
711

edits