Menu

Show posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Show posts Menu

Messages - ilikegoodfood

#106
wwWrith, do you remeber that when we switched the patch operation for the RangeAnimalFramwork from <success>Always</success> to <success>Normal</success>, we received a log for a phantom error that didn't seem to have any impact, so we ignored it?

Well, further investigation of the current issue shows that the error is preventing the patch sequence from continuing.
This means that, if I have more than one animal with a ranged attack, only the first one listed is implemented.
The code is an exact copy, with different figures, from the template mod provided by BrokenValkyrie along with the RangeAnimalFramework, the MegaSpider Range Attack mod. That mod only adds a range attack to a single creature, so I suspect he/she/other may be unaware of the issue.

I'm going to re-subscribe to the Dragon mod, since it has multiple creatures, and see if that presents a solution.
Unfortunately, because of the way that RangeAnimalFramework calculates attack jobs, I'm probably going to have to remove the ranged attack from the Sanguine Drake anyway, but this bug really need squashing first.

Thanks again for your help.

EDIT: There was a tiny variation, one line to be exact, but that hasn't solved the issue.
I'm beginning to wonder if it's an issue with my using the inclusive assembly instead of making a direct reference to a separately installed mod, as all of BrokenValkyrie's sub-mods do. I'm going to quote this whole discussion (not much of a discussion with only 1 poster at the moment :P) over and ask for help directly.
He/other/she hasn't responded to my previous question yet though... We'll see.
#107
I think that I have found the source of my current issue:

I am using an xpath patch to enable the ranged shots when and if Ranged Animal Framework is detected, which it always is because it's in my assemblies folder, however, the second PatchOperationAdd doesn't work, despite being a copy-paste of the first.
I have also tried it with only the 1st, and the testing marker appears correctly, and only the second, which doesn't work. I have tried it with the 1st's projectile, in case there was a problem and I have compared them, word for word. I can't find the error at all, but I know that it is this part that fails.

If someone would look it over, that'd be great.
As soon as this bug is squashed, I can perform final tests and then release the SanguineDrake, which is much stronger than it used to be.

<?xml version="1.0" encoding="UTF-8"?>

<Patch>
<Operation Class="PatchOperationSequence">
<success>Normal</success>
<operations>
<!--Continue if combat extended does not exist IE patch vanilla-->
<li Class="ModCheck.isModLoaded">
<modName>Combat Extended</modName>
<yourMod>Monster Mash</yourMod>
<success>Invert</success>
<customMessageFail>Monster Mash :: Implementing ranged attack framework for vanilla RimWorld...</customMessageFail>
</li>

<!--Accuracy needs to be high, because animals don't have shooting skill-->
<li Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "InfernoBeetle"]</xpath>
<value>
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<accuracyTouch>0.8</accuracyTouch>
<accuracyShort>0.9</accuracyShort>
<accuracyMedium>0.9</accuracyMedium>
<accuracyLong>0.8</accuracyLong>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>MM_InfernoBeetleProjectile</defaultProjectile>
<warmupTime>3.5</warmupTime>
<burstShotCount>1</burstShotCount>
<ticksBetweenBurstShots>1</ticksBetweenBurstShots>
<minRange>4</minRange>
<range>16</range>
<soundCast>Pawn_BigInsect_Call</soundCast>
<muzzleFlashScale>4</muzzleFlashScale>
</li>
</verbs>
</value>
</li>

<li Class="PatchOperationAdd">
<xpath>Defs/ThingDef[defName = "SanguineDrake"]</xpath>
<value>
<verbs>
<li>
<verbClass>Verb_Shoot</verbClass>
<accuracyTouch>0.7</accuracyTouch>
<accuracyShort>0.8</accuracyShort>
<accuracyMedium>0.9</accuracyMedium>
<accuracyLong>0.95</accuracyLong>
<hasStandardCommand>true</hasStandardCommand>
<defaultProjectile>MM_SanguineDrakeProjectile</defaultProjectile>
<warmupTime>10</warmupTime>
<burstShotCount>1</burstShotCount>
<ticksBetweenBurstShots>1</ticksBetweenBurstShots>
<minRange>12</minRange>
<range>30</range>
<soundCast>Pawn_Iguana_Wounded</soundCast>
<muzzleFlashScale>1</muzzleFlashScale>
<commonality>0.6</commonality>
</li>
</verbs>
</value>
</li>

<li Class="ModCheck.isModLoaded">
<modName>Core</modName>
<yourMod>Monster Mash</yourMod>
<customMessageSuccess>Monster Mash :: Testing Marker...</customMessageSuccess>
</li>
</operations>
</Operation>
</Patch>
#108
Help / Re: Bleeding Rate Multiplier (C#)
February 14, 2018, 08:13:29 AM
Solution:
In order to create the offset controls for the bleed rate I needed three things:

The first is a Capacity Def for the pawns:
<PawnCapacityDef>
<defName>BleedRate</defName>
<label>bleed rate</label>
<listOrder>9</listOrder>
<showOnHumanlikes>false</showOnHumanlikes>
<showOnAnimals>false</showOnAnimals>
<showOnMechanoids>false</showOnMechanoids>
</PawnCapacityDef>


The second is a Stat that uses the new hidden capacity:
<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>
</capacityFactors>
</StatDef>


The final step is to create a Harmony Patch in your assembly that modifies the CalculateBleedRate method:
{
    [StaticConstructorOnStartup]
    class Main
    {
        static Main()
        {
            var harmony = HarmonyInstance.Create("com.mash.monster");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

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


This method uses the Harmony library to function, so you must have it in the assemblies folder of your mod if you wish to use patches like this.
A number of useful tutorials exist for setting up your own assembly, but you will need at least some knowledge of C# if you wish to edit the patch.

You can then use a capMod offset in the Hediff to increase the BleedRate capacity, which in turn increases the BleedRate stat and multiplies the bleeding from injuries by that raised stat. For Example, here is the SanguineDrake Venom from my Monster Mash mod:
<HediffDef>
<defName>MM_SanguineDrakeVenom</defName>
<hediffClass>HediffWithComps</hediffClass>
<defaultLabelColor>(1, 0.2, 0.2)</defaultLabelColor>
<label>sanguine drake venom</label>
<lethalSeverity>1</lethalSeverity>
<makesSickThought>true</makesSickThought>
<scenarioCanAdd>true</scenarioCanAdd>
<comps>
<li Class="HediffCompProperties_Immunizable">
<severityPerDayNotImmune>-0.1</severityPerDayNotImmune>
</li>
</comps>
<stages>
<li>
<label>initial</label>
<becomeVisible>true</becomeVisible>
</li>
<li>
<label>initial</label>
<minSeverity>0.04</minSeverity>
<capMods>
<li>
<capacity>BleedRate</capacity>
<offset>0.1</offset>
</li>
</capMods>
</li>
<li>
<label>minor</label>
<minSeverity>0.14</minSeverity>
<capMods>
<li>
<capacity>BleedRate</capacity>
<offset>0.25</offset>
</li>
</capMods>
</li>
<li>
<label>moderate</label>
<minSeverity>0.39</minSeverity>
<capMods>
<li>
<capacity>BleedRate</capacity>
<offset>0.7</offset>
</li>
</capMods>
</li>
<li>
<label>serious</label>
<minSeverity>0.64</minSeverity>
<capMods>
<li>
<capacity>BleedRate</capacity>
<offset>1.25</offset>
</li>
</capMods>
</li>
<li>
<label>extreme</label>
<minSeverity>0.84</minSeverity>
<capMods>
<li>
<capacity>BleedRate</capacity>
<offset>1.8</offset>
</li>
</capMods>
</li>
</stages>
</HediffDef>
#109
The Sanguine Drake is almost ready for release.

Sorry for the delays, but I had to learn to use Harmony Patching and the person who was helping me only came online late in the day for me, so work has been very slow.

I have finally created a system that allows me to control the bleed-rate total, created the damage types, hediff and projectiles to go along with it and added the ranged attack to the Sanguine Drake, however, for reasons unknown, it refuses to use it's ranged attack.
I'm uncertain as to what the bug is, since I'm not getting any errors from it, and will not be able to resume work on it until later today.
#110
Help / Re: Bleeding Rate Multiplier (C#)
February 14, 2018, 06:20:50 AM
Thank you very much for your help.
I managed to get the version using BloodPumping working after I made that change.

EDIT 2: Creating a BleedRate Stat that requires the BleedRate Capacity with a weight of 1 worked perfectly! You don't need to read the rest of this comment.
Thank you very much for your assistance. :D


After that I began trying to formulate a workaround to not having a PawnCapacityDefOf my new BleedRate Capacity and I came up with the following:
{
    [StaticConstructorOnStartup]
    class Main
    {
        static Main()
        {
            var harmony = HarmonyInstance.Create("com.mash.monster");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

    [HarmonyPatch(typeof(HediffSet), "CalculateBleedRate")]
    static class harmonyPatches
    {
        static void Postfix(ref float __result, HediffSet __instance)
        {
            bleedOffset bo = new bleedOffset();
            float bleedOffset = bo.get(__instance);
            __result *= bleedOffset;
            // __result *= (1f + (1f - __instance.pawn.health.capacities.GetLevel(PawnCapacityDefOf.BloodPumping)));
        }
    }

    class bleedOffset
    {
        public float get(HediffSet __instance)
        {
            float bleedOffset = 0f;

            if (__instance.hediffs.Count != 0)
            {
                foreach (Hediff T in __instance.hediffs)
                {
                    foreach (PawnCapacityModifier U in T.CapMods)
                    {
                        if (U.capacity.defName == "BleedRate")
                        {
                            bleedOffset += U.offset;
                        }
                    }
                }
            }

            return bleedOffset;
        }
    }
}


As you can see, I have created a custom method that takes the HediffSet __instance and reads the offset directly from the Hediffs, thus bypassing the need to reference the Capacity altogether.
It doesn't flag up any errors in Visual Studios, but on loading RimWorld I get the following error for every living thing in the ticker list:
QuoteException ticking [NAME]: System.NullReferenceException: Object reference not set to and instance of an object at MonsterMash.bleedOffset.get(Verse.HediffSet) <0x000a9>

I'm unsure of what I need to do to fix it, having already followed the MyClass steps that I found in online tutorials.
Also, such a workaround may well be terrible for the overall performance, so if you do know/have access to the Syntax for creating a new Capacity, or you know of an easier way to assign a code-readable per-pawn value, that would be fantastic. I don't even know where I would look to try and work that out.

Thanks again for your help.

EDIT: I am now experimenting with a stat that uses the BleedRate Capacity as an alternative and less resource-intensive work-around.
#111
Help / Re: Bleeding Rate Multiplier (C#)
February 13, 2018, 06:11:57 PM
So after some minor tinkering and changes I managed to get both the initialization message and the BleedRate Postfix messages showing up in the log, however, the bleeding isn't actually updating.

{
    [StaticConstructorOnStartup]
    class Main
    {
        static Main()
        {
            var harmony = HarmonyInstance.Create("com.mash.monster");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
            Log.Message("Monster Mash :: Harmony initialized.");
        }
    }

    [HarmonyPatch(typeof(HediffSet), "CalculateBleedRate")]
    static class harmonyPatches
    {
        static void Postfix(ref float __result, HediffSet __instance)
        {
            float num = __result * (1f + (1f - __instance.pawn.health.capacities.GetLevel(PawnCapacityDefOf.BloodPumping)));
            Log.Message("Monster Mash :: Bleeding Postfix applied.");
        }
    }
}
#112
Help / Re: Bleeding Rate Multiplier (C#)
February 13, 2018, 06:43:35 AM
I've tried a number of things and I can't seem to work out where the problem is:

At first I added the BleedRate PawnCapacityDef, but left out the workerClass so that it would auto-create one, as the code seems to do when it returns null, but then I couldn't make a reference to it, because it didn't have a PawnCapacityDefOf entry.
Then I tried creating a simple workerClass and PawnCapacityDefOf in my own namespace, but, of course, the game doesn't look anywhere but in its own directory for them, so that didn't seem to work.

Finally, I tried bypassing my new PawnCapacity altogether, tying it to loss of blood pumping, but also without success.
At this point I don't know if the error is in the calculation or the patch. If it's not applying the patch, then that would certainly explain it nor working... Here is the patch itself:

namespace MonsterMash
{
    class initializeHamrony
    {
        static void patchHarmony()
        {
            var harmony = HarmonyInstance.Create("com.mash.monster");
            harmony.PatchAll(Assembly.GetExecutingAssembly());
        }
    }

    [HarmonyPatch(typeof(HediffSet), "CalculateBleedRate")]
    static class HarmonyPatches
    {
        static void Postfix(ref float _result, HediffSet _instance)
        {
            float num = _result * (1f + (1f - _instance.pawn.health.capacities.GetLevel(PawnCapacityDefOf.BloodPumping)));
        }
    }
}


Also, just out of curiosity, what chaos would occur if you created a duplicate file in the original namespace used by an existing RimWorld file, such as PawnCapacityDefOf?
#113
Help / Re: Bleeding Rate Multiplier (C#)
February 12, 2018, 06:20:30 PM
I think that I have found a way to make the equation work specifically to each character while still being an XML value.
I have created a new PawnCapacityDef that is present but hidden on all pawn types called BleedRate and applied a capMod to the Hediff.

I have tested the venom in game and it seems to be working just fine, however, I don't know if it is possible for my new CalculateBleedRate equation to read the Capacity and use it as a multiplier, or what call I would need to put in place to do it.
Also, If I am calling a value from the pawn, would it still be achievable as a Postfix?

EDIT: Okay, now I understand stats a little better. I'll have to come back to this at another time. I have other things need doing too.
#114
Help / Re: Bleeding Rate Multiplier (C#)
February 12, 2018, 06:27:58 AM
So, as far as I can tell, there are few methods that I need to create and add to various places in the game using Harmony patches.

The first step is to add the following two values to Verse.HediffStages:
        public float bleedRateFactor = 1f;

        public float bleedRateFactorOffset;


Then I need to add the following bleedRateFactor method to HediffSet:
        public float bleedRateFactor
        {
            get
            {
                float num = 1f;
                for (int i = 0; i < this.pawn.hediffs.Count; i++)
                {
                    HediffStage curStage = this.hediffs[i].CurStage;
                    if (curStage != null)
                    {
                        num *= curStage.bleedRateFactor;
                    }
                }
                for (int j = 0; j < this.hediffs.Count; j++)
                {
                    HediffStage curStage2 = this.hediffs[j].CurStage;
                    if (curStage2 != null)
                    {
                        num += curStage2.bleedRateFactorOffset;
                    }
                }
                return Mathf.Max(num, 0f);
            }
        }


And finally, I need to use the Hamrony Transpiler to replace the default CalculateBleedRate in HediffSet to the following:
        private float CalculateBleedRate()
        {
            if (!this.pawn.RaceProps.IsFlesh || this.pawn.health.Dead)
            {
                return 0f;
            }
            float num = 0f;
            for (int i = 0; i < this.hediffs.Count; i++)
            {
                num += this.hediffs[i].BleedRate;
            }
            float num2 = num / this.pawn.HealthScale;
            for (int j = 0; j < this.hediffs.Count; j++)
            {
                num2 *= this.hediffs[j].bleedRateFactor;
            }
            return num2;
        }


Using the Various Space Ship Chunks mod as a template (link to Transpiler use), I think I can duplicate the Transpiler code, but even after reading the Harmony wiki tutorial, I have no idea what I need in order to add the other three methods.

Could someone please help me understand it all?
And am I missing any steps?

Thanks again.
#115
Help / Re: Bleeding Rate Multiplier (C#)
February 12, 2018, 04:04:46 AM
HungerRate is a topical (per creature) effect that has hooks similar to what I would need.
Am I correct in thinking that I could use it's code as a template for my new bleedRate property?

Also, The bleed rate is only calculated on the overall bleeding and isn't displayed on the individual wounds. This would result in the bleed Rate total being higher than the sum of its parts.
Would that confuse you, as a user, or would the +X% bleed Rate in the Hediff be clear enough?

EDIT:

This doesn't actually look as bad as I feared.
The BleedRateTotal is already calculated per pawn in the HediffSet file using the follwoing calculation:
// Token: 0x17000AA2 RID: 2722
// (get) Token: 0x06004388 RID: 17288 RVA: 0x001E90F4 File Offset: 0x001E74F4
public float PainTotal
{
get
{
if (this.cachedPain < 0f)
{
this.cachedPain = this.CalculatePain();
}
return this.cachedPain;
}
}


As such, all I should need is to set a bleedRateFactorOffset, a get function, and substitute the CalculatedPain() function to include the offset value, which I believe can be done using the Harmony Library which I already have.
#116
I sure do create a lot of help threads....

Here's the latest one.
#117
Help / Bleeding Rate Multiplier (C#) (Solved)
February 11, 2018, 06:10:10 PM
I'm trying to create a venom for my newest monster for my Monster Mash mod that acts as an anticoagulant (increases bleeding rate).

To do that I need to create a HediffDef that modifies the bleedingRateMultiplier, which is set as 1f in the game's code (BodyPartDef, line 95).
// Token: 0x04002469 RID: 9321
public float bleedingRateMultiplier = 1f;


By expanding my limited assembly, is it possible to implement a bleedingRateMultiplier that is defined by the creature, default of 1, and add a HediffDef stage to allow a HediffDef to modify it?

If yes, how hard is it likely to be and what would be required (this is my first mod)?

Thanks.
#118
Quote from: Harry_Dicks on February 11, 2018, 03:31:24 PM
You can't define "where" they actually go on an animal, but it does have two presets.
I know that the mod has the option to set the rider as either drawn over the creature's graphic (used for most creatures) or behind the creature's graphic (usually reserved for long-necked creatures such as the Thrumbo).
Drawing them over the top looks fine, but because the creature is 50% tail, 50% body, the default position is on the rear hip instead of the body behind the fore-leg.
I was hoping that the mod allowed the definition of an offset at least in the front-back direction, so that I could move the rider forwards. I'll look into it further tomorrow.
#119
So, I have whittled away the day, still fighting with this bug, sleepily creating the Sanguine Drake.

I have everything working, but haven't decided on the unique hediff or ranged attack, for a few reasons:

Ranged Attack:
Animals with ranged attacks seek cover to shoot from instead of charging at their enemy. I wan t to make the blood projectile attack have a very long recharge so that it is only really used once at the beginning of combat, but that will then delay the creature charging in with the melee attacks. Furthermore, I'm not entirely sure if it will charge in, or just wait for the attack to re-charge.
I'll have to make it and then run some tests once i have the Hediff.

Hediff:
I have discovered several interesting things. The first is how to define the bleeding rate of a damage type, which is useful. The second is that Komodo Dragons have a powerful anticoagulant in their venom, which contains at least two major compound groups.
As such, I would like to give the Sanguine Drake a Venom Hediff that applies a multiplier to bleeding, but I'm not sure if that is possible. Do any of you know of a way to do that?

Also, how do you define an offset for the pawn location with Giddy-up! ? The dude needs to sit further forwards...

A few other balance changes have been made as well, and all monster spawn rates have been more than halved, since they were way too common. (6 Inferno Beetles on my temperate forest map).
The updates will be released along with the Sanguidne Drake, hopefully some time in the next few days.
#120
I have just re-read your post with the edits.

My first thought is to combine the Lizard that shoots blood from its eyes with a Cammodo Dragon, to create a large powerful lizard; the Sanguine Drake.

Sanguine (noun) in archaic English also means blood-red or blood and Drake is related to Dragon, so it roughly means Blood Dragon or Blood Lizard.