User Tools

Site Tools


guide_firstsrmod

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
guide_firstsrmod [2019/07/04 10:21]
umfdev [Method 4 (Harmony Transpiler)]
guide_firstsrmod [2019/07/04 11:27] (current)
umfdev
Line 1: Line 1:
 ~~NOTOC~~ ~~NOTOC~~
 ~~Title: My First Slime Rancher Mod (Modding Guide) ~~ ~~Title: My First Slime Rancher Mod (Modding Guide) ~~
-{{tag>​Modding}}+{{tag>​Modding ​Guide dnSpy Harmony UnityScripting}}
 ===== My First Slime Rancher Mod (Modding Guide) ===== ===== My First Slime Rancher Mod (Modding Guide) =====
 <WRAP center round info 100%> <WRAP center round info 100%>
Line 181: Line 181:
     * This will make sure that your max health is always 999 every single frame regardless of which health upgrade the player has. This is obviously not normally recommended.     * This will make sure that your max health is always 999 every single frame regardless of which health upgrade the player has. This is obviously not normally recommended.
     * This code also ensures the config value takes effect immediately upon applying it in the UMF Menu.     * This code also ensures the config value takes effect immediately upon applying it in the UMF Menu.
 +    * For more information on the **Awake** function, see [[https://​docs.unity3d.com/​ScriptReference/​MonoBehaviour.Awake.html|Unity Script Reference: Awake]].
 +    * For more information on the **Update** function, see [[https://​docs.unity3d.com/​ScriptReference/​MonoBehaviour.Update.html|Unity Script Reference: Update]].
   - See [[#​Building]] for the next steps.   - See [[#​Building]] for the next steps.
     * WARNING: If this is the first method you try, you will also need to comment out ''​Patch_PURPOSEOFPATCH.cs''​ before building.     * WARNING: If this is the first method you try, you will also need to comment out ''​Patch_PURPOSEOFPATCH.cs''​ before building.
Line 209: Line 211:
     class MyFirstSRMod : MonoBehaviour     class MyFirstSRMod : MonoBehaviour
     {     {
-        //private static PlayerModel playerModel;​ 
- 
         internal static void Log(string text, bool clean = false)         internal static void Log(string text, bool clean = false)
         {         {
Line 222: Line 222:
         }         }
  
- void Awake() +        ​void Awake() 
- +        
- Log("​MyFirstSRMod v" + UMFMod.GetModVersion().ToString(),​ true);+            Log("​MyFirstSRMod v" + UMFMod.GetModVersion().ToString(),​ true);
             UMFGUI.RegisterPauseHandler(Pause);​             UMFGUI.RegisterPauseHandler(Pause);​
-            //​MyFirstSRModConfig.Load();​ 
         }         }
  
Line 244: Line 243:
             else timeDirector.Unpause();​             else timeDirector.Unpause();​
         }         }
- +    ​}
-        /*void Update() +
-        { +
-            if (!Levels.isSpecial() && SRSingleton<​SceneContext>​.Instance?​.GameModel != null) //Makes sure we are in game and that the GameModel exists. +
-            { +
-                playerModel = SRSingleton<​SceneContext>​.Instance.GameModel.GetPlayerModel();​ +
-            } +
-            if (playerModel != null) //Make sure that the PlayerModel has been retrieved. +
-            { +
-                playerModel.maxHealth = MyFirstSRModConfig.MaxHealth;​ //Set the max health to our config value. +
-            } +
-        }*/ +
- }+
 }</​sxh>​ }</​sxh>​
   - Rename ''​Patch_PURPOSEOFPATCH.cs''​ to ''​Patch_MaxHealth.cs''​ along with the class name for it.   - Rename ''​Patch_PURPOSEOFPATCH.cs''​ to ''​Patch_MaxHealth.cs''​ along with the class name for it.
   - Add the following to the top of ''​Patch_MaxHealth.cs'':​ <sxh csharp>​using MonomiPark.SlimeRancher.DataModel;</​sxh>​   - Add the following to the top of ''​Patch_MaxHealth.cs'':​ <sxh csharp>​using MonomiPark.SlimeRancher.DataModel;</​sxh>​
 +    * This lets us target the **PlayerModel** class which is inside the **MonomiPark.SlimeRancher.DataModel** namespace without having to type the full namespace everytime.
   - Set **typeof** in the first HarmonyPatch attribute to use the **PlayerModel** class we discovered with dnSpy. <sxh csharp>​[HarmonyPatch(typeof(PlayerModel))]</​sxh>​   - Set **typeof** in the first HarmonyPatch attribute to use the **PlayerModel** class we discovered with dnSpy. <sxh csharp>​[HarmonyPatch(typeof(PlayerModel))]</​sxh>​
 +    * You could also use **MonomiPark.SlimeRancher.DataModel.PlayerModel** instead for the type.
   - Set the second **HarmonyPatch** attribute to the **ApplyUpgrade** function we discovered with dnSpy. <sxh csharp>​[HarmonyPatch("​ApplyUpgrade"​)]</​sxh>​   - Set the second **HarmonyPatch** attribute to the **ApplyUpgrade** function we discovered with dnSpy. <sxh csharp>​[HarmonyPatch("​ApplyUpgrade"​)]</​sxh>​
   - Inside the patch class create the following postfix function: <sxh csharp> ​       public static void Postfix(PlayerModel __instance)   - Inside the patch class create the following postfix function: <sxh csharp> ​       public static void Postfix(PlayerModel __instance)
Line 287: Line 276:
     * A Harmony **Postfix** patch will make the code in it execute at the end of the function when all other code in the original function has executed.     * A Harmony **Postfix** patch will make the code in it execute at the end of the function when all other code in the original function has executed.
     * You could change it to a **Prefix** by simply renaming the function to **Prefix**. This would cause the code to be run before the other code in the original function. However that would not work for this scenario since the other code then overwrites our max health again.     * You could change it to a **Prefix** by simply renaming the function to **Prefix**. This would cause the code to be run before the other code in the original function. However that would not work for this scenario since the other code then overwrites our max health again.
 +    * It would also be a good idea to set the current health to be equal to your max health here, however we show you this in Method 6.
     * You can also alternatively apply this patch to the **Reset** function instead if you do not have any upgrades at all.     * You can also alternatively apply this patch to the **Reset** function instead if you do not have any upgrades at all.
   - See [[#​Building]] for the next steps.   - See [[#​Building]] for the next steps.
Line 319: Line 309:
     * The Traverse will bypass any private or readonly variable and let you read/write to it.     * The Traverse will bypass any private or readonly variable and let you read/write to it.
     * Traverse does not need to be used inside a Harmony patch, it can be used anywhere anytime in any code, however you have to make sure it doesn'​t try to access code that has not yet been loaded into the game.     * Traverse does not need to be used inside a Harmony patch, it can be used anywhere anytime in any code, however you have to make sure it doesn'​t try to access code that has not yet been loaded into the game.
 +    * This will function exactly like Method 2, and is wholly unnecessary since **maxHealth** is public and not readonly.
   - See [[#​Building]] for the next steps.   - See [[#​Building]] for the next steps.
 \\ \\
Line 696: Line 687:
     * We have also made sure that the current player health is set to the new max health when applied, just like the normal game code does.     * We have also made sure that the current player health is set to the new max health when applied, just like the normal game code does.
   - Change the **UMFHarmony** attribute to 2 in ''​MyFirstSRMod.cs''​. <sxh csharp>​[UMFHarmony(2)]</​sxh>​   - Change the **UMFHarmony** attribute to 2 in ''​MyFirstSRMod.cs''​. <sxh csharp>​[UMFHarmony(2)]</​sxh>​
 +    * This tells UMF the number of patches that is expected to be successfully applied, and will show a warning to the user should any of them fail.
 +    * Since you now have two patches, one targeting the **ApplyUpgrade** function, and one targeting the **Reset** function, this number should be 2.
   - Your ''​MyFirstSRMod.cs''​ should now look something like this: <sxh csharp>​using UnityEngine;​   - Your ''​MyFirstSRMod.cs''​ should now look something like this: <sxh csharp>​using UnityEngine;​
 using UModFramework.API;​ using UModFramework.API;​

This topic does not exist yet

You've followed a link to a topic that doesn't exist yet. If permissions allow, you may create it by clicking on “Create this page”.

guide_firstsrmod.1562235683.txt.gz · Last modified: 2019/07/04 10:21 by umfdev