How to create a new Hediff

Started by Bolgfred, August 01, 2017, 01:24:44 PM

Previous topic - Next topic

Bolgfred

Dear Colonists,

I want to add a new condition named "poison", caused by... poisoningish things. Question is, how to add a thing like that?

To define the detail I created a file to specifiy the poisons effect in Defs\HediffDefs\Hediff_local_poison.xml

To make the poison usable I have to make an new entry in HediffDef, right? Can I create a new HediffDef.dll? Do I have to put just "public static HediffDef poison;" into it or do I have to put all vanilla entries plus my "poison" into that file?
"The earth has only been lent to us,
but no one has said anything about returning."
-J.R. Van Devil

Distman

Why would you need c# for a new hediff?
Check out the cobra poison or Toxic Buildup hediffs already defined. Should be able to use those as a template.

How do you want the hediff to be applied?
By consuming something? By animal bite? Or something else.

/Distman

Bolgfred

Actually I copied most of it from cobra. The effect should be triggered by an arrow:
<DamageDef ParentName="LocalInjuryBase">
    <defName>arrowPoison</defName>
    <label>arrowPoison</label>
<additionalHediffs>
      <li>
        <hediff>poisonPartial</hediff>
        <severityPerDamageDealt>0.1</severityPerDamageDealt>
      </li>
    </additionalHediffs>
    (...)
  </DamageDef>

The hediff arrowPoison is added in the HediffDef.cs as followed:

namespace RimWorld
{
[DefOf]
public static class HediffDefOf
{
public static HediffDef arrowPoison;
}
}


Currently it works, as I want to. When a shot hits, the hediff is triggered. Now I am curious why it always affects the whole body, and not the body part that was hit by the shot.


"The earth has only been lent to us,
but no one has said anything about returning."
-J.R. Van Devil

Distman

But why are you adding your hediff to the HediffDefOf?
You only need to do that if you want a shortcut when referencing it in c# code.
And you can use DefDatabase<HediffDef>.GetNamed("arrowPoison") just as well.

To be honest i think poison added to the whole body is allright. That's the way poison works any way. It spreads through your body and reach vital organs where it does the most damage. It doesn't do much around the wound itself. But of course, different poisons work differently.

Bolgfred

Thanks for your reply, Sir.
Your words make sense: hediffdef.cs only when used in .cs-files.

I tried to remove the hediffdef.cs entry, but then my code didn't work anymore. I can post the error message, when I am back home, but it was something like hediff poison partial couldn't be found. Is there any other way to call the hediff than I used?

My Idea behind the Poison was, that when Hit by a shot, that body part gets.. well poisoned, which has no effect, butcause another hediff, which affects the whole body.
By this, the effect of the poison can be cured/mildered by cutting that body part off. By doctoring that part, which I reconsider as sucking out that poison, the severity doesn't increase anymore, so the progression of the whole poison can be slowed.

All-in-All I am confused, as I copied the code from wound infections, which is only occuring in a body part, so I expected my poisonPartial to do the same :-)
"The earth has only been lent to us,
but no one has said anything about returning."
-J.R. Van Devil

Distman

It's not the hediff itself that defines if it's applicable on bodypart or not. All hediffs can be applied to specific bodyparts (Pregnancy in a pawn's left eye, no problem!) or whole body, it's controlled in the c# classes handling damage etc.

Sure, hit me up with the error message and supply your c# code (or atleast give me a hint of what classes you have written).

Bolgfred

Attached my mod folder with all files.

The relevant Part would be in DamageDef:

  <DamageDef ParentName="LocalInjuryBase">a
    <defName>ShotArrowPoison</defName>
    <label>ShotArrowPoison</label>
<additionalHediffs>
      <li>
        <hediff>poisonPartial</hediff>
        <severityPerDamageDealt>0.005</severityPerDamageDealt>
      </li>
    </additionalHediffs>


And in HediffDef there is its counterpart:

<HediffDef ParentName="InfectionBase">
    <defName>poisonPartial</defName>
    <label>poison partial</label>
[...]


Questions for now:

1.   Is there an alternate way to include a hediff in damageDef? (not including .cs)
2.   How could be defined that the poison is just applied to a body part?
3.   Can I add some severity for hediff b in hediff a? (eg. Can poisonPartial cause PoisonBody while active?
"The earth has only been lent to us,
but no one has said anything about returning."
-J.R. Van Devil

Distman

Try using <hediff> instead of <additionalHediffs> for main effect (posionPartial), should give you hediff in bodypart instead of whole body.
You could use <additionalHediffs> for secondary effect on hit, but i would put a HediffGiver_Random in the poison hediff instead, that way you can control how long it takes for it to appear, and what severity level that triggers it.

Example (under HediffDef, in a state tag):
<hediffGivers>
<li Class="HediffGiver_Random">
<hediff>OtherHediff</hediff>
<mtbDays>0.5</mtbDays>
<partsToAffect>
<li>Brain</li>
</partsToAffect>
</li>
</hediffGivers>

Edit: See AlcoholHigh for example.

Let me know how it works out!

And remove all c# definitions, if you're not actually using c# classes. They will probably just cause you problems...

Bolgfred

I changed the additionalhediff into hediff, but now I get the error message that <hediff> is defined twice.

<DamageDef ParentName="LocalInjuryBase">
    <defName>ShotArrowPoison</defName>
    <label>ShotArrowPoison</label>
    <hediff>poisonPartial</hediff>
    <hediff>Cut</hediff>
    <hediffSolid>Crack</hediffSolid>



Anyway, the alcohol reference was a very intresting hint. But now I ask myself what <outcomeDoers> mean? I think the usage of this container is, that what is written inside happens to pawn after execution (in case of alcohol: if drink succedd, add "outcomeDoers"), but what does the work mean? outcome = result  and  doers = doing?

"The earth has only been lent to us,
but no one has said anything about returning."
-J.R. Van Devil

Distman

Yeah well, you're defining <hediff> twice... Remove cut.

Quote from: Bolgfred on August 03, 2017, 06:36:05 PM
I changed the additionalhediff into hediff, but now I get the error message that <hediff> is defined twice.

<DamageDef ParentName="LocalInjuryBase">
    <defName>ShotArrowPoison</defName>
    <label>ShotArrowPoison</label>
    <hediff>poisonPartial</hediff>
    <hediff>Cut</hediff>
    <hediffSolid>Crack</hediffSolid>



Anyway, the alcohol reference was a very intresting hint. But now I ask myself what <outcomeDoers> mean? I think the usage of this container is, that what is written inside happens to pawn after execution (in case of alcohol: if drink succedd, add "outcomeDoers"), but what does the work mean? outcome = result  and  doers = doing?

Distman

OutcomeDoers doesn't work in DamageDefs nor HediffDefs. Only used for things that you ingest.

Bolgfred

ah okay, that makes more sense to me then.

Still, the problem with the double <hediff> remains. I am not sure, but I think it makes sense  to define one value twice doesn't work.
Is there any way to put these hediffs in a list? something like
<hediff><li>poison</li><li>cut</li></hediff>

if that ain't work I think I drop the idea of poisoning a single bodypart and directly apply my bodyPoison.
For now, thank you very much for your detailes advice and frequent answers.
"The earth has only been lent to us,
but no one has said anything about returning."
-J.R. Van Devil