Modding Help How to detect farming actions

Discussion in 'Mods' started by Alphablackwolf, Nov 27, 2016.

Tags:
  1. Alphablackwolf

    Alphablackwolf Void-Bound Voyager

    So I'm working in SMAPI and I am currently struggling to catch certain events in Stardew Valley. I needed a way to capture tools that consume stamina being used, and managed to catch that with a half second tick update routine that checks a few variables for the tool being actively used (tools take at least 600ms to use). I'm not sure if that is the best way to go about that, though.

    My current problem is that I am now trying to improve the quality of crops when harvested. However, I can only find a way to do this with Junimo Harvesters, but not with manually harvested crops. The game just calls an add to inventory, so I can't detect when something is harvested vs it just being retrieved from a chest. Does anyone know how I might go about trapping that event?
     
    • Alphablackwolf

      Alphablackwolf Void-Bound Voyager

      Well, I've abandoned that approach for now, and have gone with something much more dangerous. I'm just going to replace the game's method with my own using reflection and unsafe code. In case anyone ever needs to do the same, here's an extension method I put together to accomplish the replacement. please note you will need to turn on unsafe code in your project in order to compile it.


      public static void ReplaceMethod(this Type typeToReplace, string methodNameToReplace, Delegate replacementMethod)
      {
      var methodToReplace = typeToReplace.GetMethod(methodNameToReplace, BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public);
      var methodToInject = replacementMethod.Method;
      RuntimeHelpers.PrepareMethod(methodToReplace.MethodHandle);
      RuntimeHelpers.PrepareMethod(methodToInject.MethodHandle);

      unsafe
      {
      if (IntPtr.Size == 4)
      {
      var injectedMethodPointer = (int*) methodToInject.MethodHandle.Value.ToPointer() + 2;
      var targetMethodPointer = (int*) methodToReplace.MethodHandle.Value.ToPointer() + 2;
      *targetMethodPointer = *injectedMethodPointer;
      }
      else
      {

      var injectedMethodPointer = (long*) methodToInject.MethodHandle.Value.ToPointer() + 1;
      var targetMethodPointer = (long*) methodToReplace.MethodHandle.Value.ToPointer() + 1;
      *targetMethodPointer = *injectedMethodPointer;
      }
      }
      }
       

      Share This Page