Stupid question

Started by TrashMan, January 16, 2020, 06:40:52 AM

Previous topic - Next topic

TrashMan

If I want to create a headdiff that boosts size and HP (let's call it genetic enhacement)

I would basically create a sickenss, with 1 stage, flag it as not bad and non-curable, and put increase baseBodySize and BaseHealthScale using the same synatax like one would use to boost manipulation, or conciounsess, or any other attribute  (irrc, that was using offset, so 2.0 for 200% increase), correct?


Here is the current file:

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

  <HediffDef>
    <defName>TM40_supremegenes</defName>
<hediffClass>HediffWithComps</hediffClass>
    <defaultLabelColor>(0.55, 0.05, 1)</defaultLabelColor>
    <label>supreme genes</label>
<!--     <lethalSeverity>40</lethalSeverity> -->
<tendable>false</tendable>
<makesSickThought>false</makesSickThought>
<isBad>false</isBad>
<comps>
    </comps>
    <stages>
  <li>
        <label>empowered</label>
<minSeverity>.001</minSeverity>
        <restFallFactor>0.5</restFallFactor>
<hungerRateFactor>0.5</hungerRateFactor>
<painOffset>-0.5</painOffset>
        <capMods>
          <li>
            <capacity>Moving</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
          <li>
            <capacity>Manipulation</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
          <li>
            <capacity>Consciousness</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
  <li>
            <capacity>Sight</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
  <li>
            <capacity>Talking</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
  <li>
            <capacity>Eating</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>  
  <li>
            <capacity>BloodFiltration</capacity>
            <offset>4.0</offset>
          </li>
  <li>
            <capacity>BloodPumping</capacity>
            <offset>2.0</offset>
          </li>
        </capMods>
      </li>
    </stages>
  </HediffDef>
 
</Defs>



Basically, I also want to set body size to 1.25 and boost HP

Halp pls

K

That won't work because manipulation, consciousness, and all those "stats" you see on the health panel are actually called capacities, and they function independently of the stats system. Luckily, hediffStages can have stat offsets. All you need to do is add a new section like this:
<statOffsets>
  <li>
     <stat>BaseBodySize</stat>
     <offset>2</offset>
  </li>
</statOffsets>


Just from a balance perspective, a bigger body is probably a bad thing since it makes a pawn easier to hit!

TrashMan

Well, I'm trying to make a Primarch/Emperor, so size is a must

So this should work then?

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

  <HediffDef>
    <defName>TM40_supremegenes</defName>
<hediffClass>HediffWithComps</hediffClass>
    <defaultLabelColor>(0.55, 0.05, 1)</defaultLabelColor>
    <label>supreme genes</label>
<!--     <lethalSeverity>40</lethalSeverity> -->
<tendable>false</tendable>
<makesSickThought>false</makesSickThought>
<isBad>false</isBad>
<comps>
    </comps>
    <stages>
  <li>
        <label>empowered</label>
<minSeverity>.001</minSeverity>
        <restFallFactor>0.5</restFallFactor>
<hungerRateFactor>0.5</hungerRateFactor>
<painOffset>-0.5</painOffset>
        <capMods>
          <li>
            <capacity>Moving</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
          <li>
            <capacity>Manipulation</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
          <li>
            <capacity>Metabolism</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>  
          <li>
            <capacity>Consciousness</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
  <li>
            <capacity>Sight</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
  <li>
            <capacity>Talking</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>
  <li>
            <capacity>Eating</capacity>
            <setMax>5.0</setMax>
            <offset>2.0</offset>
          </li>  
  <li>
            <capacity>BloodFiltration</capacity>
            <offset>4.0</offset>
          </li>
  <li>
            <capacity>BloodPumping</capacity>
            <offset>2.0</offset>
          </li>
        </capMods>
<statOffsets>
  <li>
<stat>BaseBodySize</stat>
<offset>1.5</offset>
  </li>
  <li>
<stat>BaseHealthScale</stat>
<offset>3.0</offset>
  </li>  
</statOffsets>
      </li>
    </stages>
  </HediffDef>
 
</Defs>

K

Looks like it should work to me. With stats like health and body size which are a bit "special" it may not work quite right - test it to make sure it's working.

TrashMan

nope


Exception in custom XML loader for RimWorld.StatModifier. Node is:
<li><stat>BaseHealthScale</stat><offset>3.0</offset></li>

Exception is:
System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.ArgumentNullException: Argument cannot be null.
Parameter name: s
  at System.Double.Parse (System.String s, NumberStyles style, IFormatProvider provider) [0x00000] in <filename unknown>:0
  at System.Single.Parse (System.String s, IFormatProvider provider) [0x00000] in <filename unknown>:0
  at Verse.ParseHelper.ParseFloat (System.String str) [0x00000] in <filename unknown>:0
  at Verse.ParseHelper.FromString[Single] (System.String str) [0x00000] in <filename unknown>:0
  at RimWorld.StatModifier.LoadDataFromXmlCustom (System.Xml.XmlNode xmlRoot) [0x00000] in <filename unknown>:0
  at (wrapper managed-to-native) System.Reflection.MonoMethod:InternalInvoke (object,object[],System.Exception&)
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
  --- End of inner exception stack trace ---
  at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00000] in <filename unknown>:0
  at System.Reflection.MethodBase.Invoke (System.Object obj, System.Object[] parameters) [0x00000] in <filename unknown>:0
  at Verse.DirectXmlToObject.ObjectFromXml[StatModifier] (System.Xml.XmlNode xmlRoot, Boolean doPostLoad) [0x00000] in <filename unknown>:0
Verse.Log:Error(String, Boolean)
Verse.DirectXmlToObject:ObjectFromXml(XmlNode, Boolean)
Verse.DirectXmlToObject:ListFromXml(XmlNode)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.DirectXmlToObject:ObjectFromXml(XmlNode, Boolean)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.DirectXmlToObject:ObjectFromXml(XmlNode, Boolean)
Verse.DirectXmlToObject:ListFromXml(XmlNode)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.DirectXmlToObject:ObjectFromXml(XmlNode, Boolean)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.DirectXmlToObject:ObjectFromXml(XmlNode, Boolean)
System.Reflection.MonoMethod:InternalInvoke(Object, Object[], Exception&)
System.Reflection.MonoMethod:Invoke(Object, BindingFlags, Binder, Object[], CultureInfo)
System.Reflection.MethodBase:Invoke(Object, Object[])
Verse.DirectXmlLoader:DefFromNode_Patch1(XmlNode, LoadableXmlAsset)
Verse.LoadedModManager:ParseAndProcessXML_Patch1(XmlDocument, Dictionary`2)
Verse.LoadedModManager:LoadAllActiveMods()
Verse.PlayDataLoader:DoPlayLoad()
Verse.PlayDataLoader:LoadAllPlayData(Boolean)
Verse.Root:<Start>m__1()
Verse.LongEventHandler:RunEventFromAnotherThread(Action)
Verse.LongEventHandler:<UpdateCurrentAsynchronousEvent>m__1()

K

BaseHealthScale isn't a stat I don't think. The stat for health is MaxHitPoints.

TrashMan

The syntax is the sour point. Is it even specified anywhere what you can and cannot call/change from where? Waht exactly are the proper stat names?

BTW, I also get a similar error for baseBodySize.

K

I don't think BaseBodySize is a stat either, now that I think about it.

Every stat has to have a StatDef. Vanilla StatDefs are stored in the StatDefs folder in Core, so check them to see what stats are available. As a general rule though, if Tynan didn't use it he didn't add it, so you may have to venture into C# modding to add the stats you need.

TrashMan

I can' believe nobody knows this...

I've been looking around a a bit and the only thing I can find regarding body size is baseBodySize and bodySizeFactor.
MaxHitpoints seem to be used to objects, not pawns...

Anyone?

TrashMan

Quote from: K on January 20, 2020, 10:12:04 AM
I don't think BaseBodySize is a stat either, now that I think about it.

Every stat has to have a StatDef. Vanilla StatDefs are stored in the StatDefs folder in Core, so check them to see what stats are available. As a general rule though, if Tynan didn't use it he didn't add it, so you may have to venture into C# modding to add the stats you need.

There is only a stats folder ,and there is barely anything in there, which is odd.

LWM

I did a quick search for baseBodySize in the code, and it looks like you have a few options:

1.  Make your own race for this one person.  Because everything checks pawn.race.baseBodySize.  ("race" here is the raceDef)
2.  (C#, Harmony): See if it's possible to Patch Verse.Pawn's BodySize function - that may let you adjust it for the god emperor.
3.  (C#? XML?) See if it's possible to define a specific custom LifeStage for your pawn that has a very large bodySizeFactor.  (Maybe using C# to adjust the LifeStage for this one pawn?)

I may have missed something, but it's another start?

TrashMan

Not exactly a coder, so going deep into C# is a no-go.

What's even odder is that there IS a carrying capacity stat defined, and I tried changing that instead (I can't make the pawn bigger, can I make it stronger?) but still get the same problem.

LWM

Okay - I see another, easier, way to do it via C#: a drug that triggers some C# that replaces the pawn's ageTracker, which would let you have a God-Emperor life stage that could work.

That opens the field up much more for finding a sympathetic C# coder ^.^

Re: carrying capacity - did you check a caravan to see if it changed?  There's that 1-stack minimum in Vanilla no matter the weight...

TrashMan

It didn't change in caravan. The emperor can still carry only 35 kg (really?35? Why is the vanilla value trash?) despite also having a power armor with +300 carry capacity.
I guess that apparel addition is only for non-caravan capacity. I wonder is caravan capacity can be changed?