What does this mean? And how do I fix it?

Started by BaconHer0, September 15, 2018, 11:48:52 PM

Previous topic - Next topic

BaconHer0

BodyDef SquishableBody has BodyPartRecord of SquishableTorso whose children have more coverage than 1.

How do I fix this?

It leads to a red error in combat... something about torso being untargettable yet it still can get hit

PleccyMM

It's a problem with the BodyDef you're using for your animal, one or more of your parent nodes have child nodes with coverage tags that in total exceeds a value of 1.0. To help describe your problem and how to go about fixing it I'm going to be using and referencing the BodyDef QuadrupedAnimalWithPaws from the games core code as a form of visual representation:

Quote from: RimWorld's Code
<BodyDef>
<defName>QuadrupedAnimalWithPaws</defName>
<label>quadruped animal</label>
<corePart>
<def>Body</def>
<height>Middle</height>
<depth>Outside</depth>
<parts>
<li>
<def>Spine</def>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Stomach</def>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Heart</def>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Lung</def>
<customLabel>left lung</customLabel>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Lung</def>
<customLabel>right lung</customLabel>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Kidney</def>
<customLabel>left kidney</customLabel>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Kidney</def>
<customLabel>right kidney</customLabel>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Liver</def>
<coverage>0.03</coverage>
<depth>Inside</depth>
</li>
<li>
<def>Neck</def>
<coverage>0.22</coverage>
<height>Top</height>
<parts>
<li>
<def>Head</def>
<coverage>0.75</coverage>
                                                          <groups>
                                                            <li>HeadAttackTool</li>
                                                          </groups>
<parts>
<li>
<def>Skull</def>
<coverage>0.25</coverage>
<depth>Inside</depth>
<parts>
<li>
<def>Brain</def>
<coverage>0.70</coverage>
<depth>Inside</depth>
</li>
</parts>
</li>
<li>
<def>Eye</def>
<customLabel>left eye</customLabel>
<coverage>0.12</coverage>
</li>
<li>
<def>Eye</def>
<customLabel>right eye</customLabel>
<coverage>0.12</coverage>
</li>
<li>
<def>Ear</def>
<customLabel>left ear</customLabel>
<coverage>0.08</coverage>
</li>
<li>
<def>Ear</def>
<customLabel>right ear</customLabel>
<coverage>0.08</coverage>
</li>
<li>
<def>Nose</def>
<coverage>0.10</coverage>
</li>
<li>
<def>AnimalJaw</def>
<coverage>0.10</coverage>
<groups>
<li>Teeth</li>
</groups>
</li>
</parts>
</li>
</parts>
</li>
<li>
<def>Leg</def>
<customLabel>front left leg</customLabel>
<coverage>0.07</coverage>
<height>Bottom</height>
<parts>
<li>
<def>Paw</def>
<customLabel>front left paw</customLabel>
<coverage>0.15</coverage>
<groups>
<li>FrontLeftPaw</li>
</groups>
</li>
</parts>
</li>
<li>
<def>Leg</def>
<customLabel>front right leg</customLabel>
<coverage>0.07</coverage>
<height>Bottom</height>
<parts>
<li>
<def>Paw</def>
<customLabel>front right paw</customLabel>
<coverage>0.15</coverage>
<groups>
<li>FrontRightPaw</li>
</groups>
</li>
</parts>
</li>
<li>
<def>Leg</def>
<customLabel>rear left leg</customLabel>
<coverage>0.07</coverage>
<height>Bottom</height>
<parts>
<li>
<def>Paw</def>
<customLabel>rear left paw</customLabel>
<coverage>0.15</coverage>
</li>
</parts>
</li>
<li>
<def>Leg</def>
<customLabel>rear right leg</customLabel>
<coverage>0.07</coverage>
<height>Bottom</height>
<parts>
<li>
<def>Paw</def>
<customLabel>rear right paw</customLabel>
<coverage>0.15</coverage>
</li>
</parts>
</li>
</parts>
</corePart>
</BodyDef>

QuadrupedAnimalWithPaws code

You'll notice that throughout there are a lot of tags with the name "coverage" followed by a number, you'll also notice that these numbers are all decimals. These numbers are effectively the percentage to hit a set body part, however there is a bit more to it than just this.

When a bullet hits a pawn what happens is it will begin to work out where the wound is to be placed. If you look at the top of the code you'll notice the def Body, this is basically the name for the entire pawns self in the games code and the parent node for all body parts - this can differ in name for different BodyDefs, for example human BodyDefs have a Torso instead of a Body. The bullet upon impact will begin to try and figure out which body part to hit through working out the percentage for each one. It immediately checks to see whether it will hit any direct children of Body, these children are things such as lungs, legs, neck - but not the head as this is a child of the neck def and not a direct child of the body. If by chance it hits the lung then the lung takes damage and that's the end, though if it hits a def with children of their own - such as the neck which I just mentioned - then it has to work out a bit more. Say it has successfully hits the neck now it must look at the necks own direct children and figure out whether it's to hit them, for the neck it's only direct child is the head. If it is unsuccessful in hitting the child, in this case the head, then it will settle for just hitting the parent, in our case the neck; however if is successful in hitting the head it will look to see if it has any children - which it does the skull - and then if it's successful in that attempt it will look to hit any children of the child - with the skull this is all the facial features.

To put this in terms found within RimWorld's own code:

Quote from: RimWorld's CodeEach coverage value is relative to its parent. Remaining body part coverage (100% minus coverage of all child nodes) is a chance to hit exactly this part.Damage "starts" at corePart, and then "goes deeper" until it hits remaining body part coverage or leaf node - this body part is then hit.

Now how does this all relate to your current problem: as I mentioned earlier all the coverage tags contain numbers that are decimals this is because if a nodes direct children exceed a coverage value of 1.0 then the game can't run the percentage chance of body parts from getting hit - this is of course because 1.0 is 100%. Once again using the QuadrupedAnimalWithPaws BodyDef as an example, if you were to add all the direct children of the Body node up it would equal 0.52 - this being the immediate percentage to hit the pawn without any cover. Another example is the skull which direct children add up to 0.6 meaning that once you hit the skull there is a 60% chance that it will instead of hitting the skull it will deal damage to the pawns facial features.

What you need to do to fix your code is add together all the direct children of nodes and see which one exceeds a coverage of 1.0 then change values of it's children accordingly so they add up to less than 1.0, I'd suggest also looking through pre-existing BodyDefs in the games code and try to create yours based off already existing ones. If you continue to have problems post your code and I'll be able to take a look through to help identify problems.

Let me know if any of this doesn't make sense and good luck - PleccyMM

BaconHer0

Thank you for the in-depth explanation. What confused me before was why humanlikes had total coverage values >1

The problem is now fixed