(Solved?)Harmony Constructor Patching

Started by BrokenValkyrie, January 21, 2018, 01:01:41 AM

Previous topic - Next topic

BrokenValkyrie

Anyone know of any example to patching constructor in harmony. I know harmony can supports it but I'm struggling to get harmony to recognize constructor with Target Method. I'm at a lost how to do with manual patching as well.

I'm revisiting a mod for a completely assembly solution, the goal is to set resourcesFractionWhenDeconstructed default to 1.

Here is my current code.

[StaticConstructorOnStartup]

static class HarmonyPatches
{
static HarmonyPatches()
{
HarmonyInstance harmony = HarmonyInstance.Create("com.github.rimworld.mod.FullResourceRefund");
harmony.PatchAll(Assembly.GetExecutingAssembly());
}
}

[HarmonyPatch(typeof(GenLeaving), "GetBuildingResourcesLeaveCalculator")]
public static class LeaveNoResourceBehind
{
[HarmonyPostfix]
static void Postfix(Thing diedThing, DestroyMode mode, ref Func<int, int> __result)
{
if (mode == DestroyMode.Deconstruct)
{
__result = (Func<int, int>)(count => GenMath.RoundRandom(Mathf.Min((float)count * diedThing.def.resourcesFractionWhenDeconstructed)));
}
}
         
}

[HarmonyPatch(typeof(BuildableDef))]
[HarmonyPatch(".ctor")]
public static class fullResource_Patch
{
static IEnumerable<CodeInstruction> Transpiler(IEnumerable<CodeInstruction> instructions )
{
//The code we want is on the 2nd ldc.r4
int startIndex = -1, ldc_r4Count = 0;

var codes = new List<CodeInstruction>(instructions);
for (int i = 0; i < codes.Count; i++)
{
if (codes[i].opcode == OpCodes.Ldc_R4)
{
ldc_r4Count++;
if (ldc_r4Count >= 2)
{
//This should place the index direcly on the wanted Ldc_R4
startIndex = i;
//Log.Message("2nd Ldc_R4 found");
break;
}

}
}


if (startIndex > -1)
{

//codes[startIndex].operand = 1; Ignore this for now as I want to confirm IL code first
Log.Message("Current IL code " + codes[startIndex]);
}
return codes;
}
}

BrokenValkyrie

#1
I just remembered abstract class don't have constructor, while it can be declared it doesn't actually have one. Because well abstract class is abstract and you can't create new instance of abstract class. I'll be trying alternate method of patching.

I solved it, I manage to access to variable by just having [HarmonyPatch(typeof(BuildableDef))] target method and nothing else. Now the issue is that it doesn't seem to have an affect.

CannibarRechter

> Now the issue is that it doesn't seem to have an affect.

My recollection is that Harmony will often silently fail when attempting to patch a method with generic<> parameters. This is a known issue, and should probably be documented more clearly, as it can lead to a lot of frustration.

My suggestion would be to try your patch higher or lower in the call tree.

CR All Mods and Tools Download Link
CR Total Texture Overhaul : Gives RimWorld a Natural Feel
CR Moddable: make RimWorld more moddable.
CR CompFX: display dynamic effects over RimWorld objects