Variable Bleed Rate Framework (SOLVED)

Started by ilikegoodfood, September 03, 2018, 07:00:43 AM

Previous topic - Next topic

ilikegoodfood

As part of my MonsterMash [B18] mod I created a small harmony patch and some defs so that I could manipulate the total bleed rate of a pawn.

Now that I have to update my mod to B19 anyway, I would like to separate out the Variable Bleed Rate as a standalone framework that other modders can use. This should reduce the likelihood of conflicts in future when other mods start to use similar methods, as well as make it easier for everyone. I know that another mod is already using my code, and will inform them of the change if I get it working.

It works by creating a hidden Capacity and Stat on organic pawns, both called BleedRate, and then multiplying the final BleedRate value by that modifier. The stat can then be freely manipulated by hediffDefs to get the desired result.

Ultimately I would like to update it into a .dll only mod for more general use. Please help!
As far as I can tell, the harmony patch works perfectly, but I have no idea how to add the PawnCapacity and Stat through the assembly.


Here is the current [B18] code for the mod:
PawmCapacity.xml
<?xml version="1.0" encoding="utf-8" ?>

<Defs>

<PawnCapacityDef>
<defName>BleedRate</defName>
<label>bleed rate</label>
<listOrder>9</listOrder>
<showOnHumanlikes>false</showOnHumanlikes>
<showOnAnimals>false</showOnAnimals>
<showOnMechanoids>false</showOnMechanoids>
</PawnCapacityDef>

</Defs>


Stats_Pawns_General.xml
<?xml version="1.0" encoding="utf-8" ?>

<Defs>

<StatDef>
<defName>BleedRate</defName>
<label>bleed rate</label>
<description>Multiplier on bleed rate.</description>
<category>BasicsPawn</category>
<defaultBaseValue>1</defaultBaseValue>
<toStringStyle>PercentZero</toStringStyle>
<hideAtValue>1</hideAtValue>
<minValue>0.1</minValue>
<showOnMechanoids>false</showOnMechanoids>
<capacityFactors>
<li>
<capacity>BleedRate</capacity>
<weight>1</weight>
</li>
<li>
<capacity>BloodPumping</capacity>
<weight>0.5</weight>
</li>
</capacityFactors>
</StatDef>
 
</Defs>


HarmonyPatches.cs
using System;
using System.Reflection;
using Harmony;
using RimWorld;
using Verse;

namespace MonsterMash
{
    [StaticConstructorOnStartup]
    class Main
    {
        static Main()
        {
            var harmony = HarmonyInstance.Create("com.mash.monster");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

    [HarmonyPatch(typeof(HediffSet), "CalculateBleedRate")]
    static class bleedRatePatch
    {
        public static void bleedRatePostfix(ref float __result, HediffSet __instance)
        {
            __result *= StatExtension.GetStatValue(__instance.pawn, StatDef.Named("BleedRate"), true);
        }
    }

    [HarmonyPatch(typeof(CompArt), "JustCreatedBy", new Type[] { typeof(Pawn) })]
    static class artNamePatch
    {
        public static bool checkNamePrefix(ref Pawn pawn)
        {
            Log.Message("Checking for Pawn Name");
            bool result;
            if (pawn.Name == null)
            {
                Log.Message("No Pawn Name Found");
                Traverse.Create<CompArt>().Property("authorNameInt", null).SetValue("None");
                result = false;
            }
            else
            {
                Log.Message("Pawn Name Found");
                result = true;
            }
            return result;
        }
    }
}


Thank you all very much for your help.

ilikegoodfood

So, after looking at a similar framework that I'm using, I realized that I don't need to move the Stats and PawnCapacity Defs from the Defs to the .dll. Not sure why I thought I did in the first place, but oh well.

I have split out the various files that I need and rebuilt the assembly to now only apply that one harmony patch. Low and behold, it isn't applying it. I made a quick hediffDef that increased applies an offset to the BleedRate Stat as a test, but applying it has no effect on the total bleed rate.

RawCode

issue with frameworks and stuff - people unlikely to use your framework for thing that literally single line code injection.

ilikegoodfood

#3
You saying that this can be done with a single line of code? Sorry, yes, the injection is only one line.

And if that's the case, why couldn't I find any way of doing it when I first needed it? I had to make it up as I went along... Not a light learning curve.

Also, as I understand it, harmony patches prevents the same thing being patched multiple times by the same patch, thus preventing compatibility issues. While it is an extremely small feature, it is one that seems to be needed.

EDIT:

Regardless of whether I release it as a framework or not, I still need to get my code working again, since it isn't right now.
The Capacity is showing up correctly and the offset works perfectly, however the BleedRate isn't actually multiplying by the new value, and I'm not sure why.

using System;
using System.Reflection;
using Harmony;
using RimWorld;
using Verse;

namespace VariableBleedRate
{
    [StaticConstructorOnStartup]
    class Main
    {
        static Main()
        {
            var harmony = HarmonyInstance.Create("com.rate.bleed");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

    [HarmonyPatch(typeof(HediffSet), "CalculateBleedRate")]
    static class bleedRatePatch
    {
        public static void bleedRatePostfix(ref float __result, HediffSet __instance)
        {
            __result *= StatExtension.GetStatValue(__instance.pawn, StatDef.Named("BleedRate"), true);
        }
    }
}

RawCode

you lack ever basic debug\trace output, start from addig some to check is your code ever run...

ilikegoodfood

Sorry for the extremely long delay. There's been a lot of irl stuff going on, so I had to drop my updates for a while.

Thank you for trying to help such a complete noob. I have now fixed the code and it all works perfectly. I'll be uploading it shortly.