Modifying basic needs

Started by phr43k, January 16, 2018, 10:52:59 AM

Previous topic - Next topic

phr43k

Hi all,

I'm totally new to modding RimWorld, so I don't have complete overview over what is possible and how. I have general programming knowledge, but am not familiar with the intricacies of C#.

I wanted to fiddle with the needs of pawns and have hit a wall. Looking at the source code, needs are stored in a Pawn_NeedsTracker. Adding new needs is easily done via causesNeed in HeDiffDef, but changing or disabling the base needs seems way more difficult.

For testing purposes I tried to remove the need to eat. As Pawn_NeedsTracker explicitly stores a Need_Food object, I created a child class, inheriting from Need_Food, overrode the functionality, and put it there via XML in a HeDiffDef:

<?xml version="1.0" encoding="utf-8" ?>
<Defs>
<HediffDef Name="ImplantHediffBase" Abstract="True">
    <hediffClass>Hediff_Implant</hediffClass>
    <defaultLabelColor>(0.65, 0.3, 0.9)</defaultLabelColor>
    <isBad>false</isBad>
  </HediffDef>

  <HediffDef ParentName="ImplantHediffBase">
    <defName>KyberneticInterface</defName>
    <label>kybernetic interface</label>
    <labelNoun>a kybernetic interface</labelNoun>
    <spawnThingOnRemoved>KyberneticInterface</spawnThingOnRemoved>
    <concreteExampleInt>
    <pawn>
    <needs>
    <food>
    <Need_Food_Kybernetic class="Kybernetics.Need_Food_Kybernetics"/>
    </food>
    </needs>
    </pawn>
    </concreteExampleInt>
  </HediffDef>
</Defs>

(I'm not even sure that this works like I want it to.)

But it looks like the source code calls the default constructor of Need_Food, so you get an error if you use a child class of that.

Is there something I can do to make it work this way or do I have to use a different approach?

BrokenValkyrie

You should not modify core code in that fashion. Making modification to core like this  harmony and quiet possible harmony transpiler. There no easier way to make this kind of modification. Need_Food is tied to so many part of the code, I'm not sure how rimworld will react if you successfully remove it.

I don't recommend getting stuck behind this "wall" . Instead for testing purpose just set pawn hunger rate at 0 and work on the rest of the code. Base pawn does not have hunger stat on xml, you need to add it in. Since you are using HeDiffDef using hunger rate offset might work. Both method may have problem whenever the hunger rate is modified.

Might be easier just creating a new food group and making colonist switch to new food group under your condition.


<hungerRateFactorOffset>-1</hungerRateFactorOffset>

jamaicancastle

I'm not sure what your use case is, but I agree that's probably not the best way to go about it.

If you want to remove a basic need from a pawn, the best way would be the see if one of the configuration flags in its race properties (the <race> tag in its thingDef) can be set to negate that need. For instance, pawns with less than humanlike intelligence won't have thought-related human needs (mood, beauty, space, etc.). Pawns with the EatsFood and needsRest flags set to false won't have a food or rest need, respectively.

For more comprehensive needs changes you could try using Harmony, which is a library designed specifically for patching Rimworld's existing C# code safely and (relatively) painlessly. You would want to create a postfix on Pawn_NeedTracker.ShouldHaveNeed(), which as the name implies is the function that checks if a pawn should have a need by referencing the flags I discussed earlier. The postfix would allow you to compare any of the pawn's attributes, including its defName or any other convenient feature, and exclude or include specific needs.

phr43k

Thank you both for your response.

My goal is basically to make it possible to implant certain systems into my pawns that remove needs like hunger and rest or replace them with the need to recharge internal batteries.
I guess, I'll go check out HugsLib. Maybe I'll find what I want.