Relation between "mustBeWildToSow" and "sowResearchPrerequisites"

Started by Kopp, September 25, 2020, 05:03:41 PM

Previous topic - Next topic

Kopp

Hello ladies and gentleman,

I did quite a lot of xpathing the last days/weeks to balance my modlist.

One thing I do not understand is the relation between plant/mustBeWildToSow and plant/sowResearchPrerequisites.
Biomes! Islands adds the pineapple plant which can be grown everywhere. I tried to change that and added the mustBeWildToSow tag.
But it did not work. Only after adding the sowResearchPrerequisites tag it worked.

The same thing the other way around happened with "glowstool" mushroom from alpha biomes.
In its xml it says "mustBeWildToSow true" but it can be grown in every biome.
I locked it behind a research and afterwards I could only grow it in a biome where it is domestic.

Sooo... Am I missing something? Any idea how I can get the pineapples to only be growable in certain biomes without the need of a research?

Have a nice day!


GhostData

If mustBeWildToSow is true, then the plant must be present in the map biome in order to be planted. Meaning, if you try to grow a palm tree on an icesheet, this setting would block you, since palm trees do not exist in ice sheets.

If sowResearchPrerequisites is null, the colony may always plant the plant. If it is not null, research requirements are evaluated. If all prereqs are met, mustBeWildToSow is evaluated.

Here, have a truth table: sowResearchPrerequisites=true assumes you have unlocked the research necessary, false assumes there are no prereqs










sowResearchPrerequisites |mustBeWildToSow |plant in biome |can plant without research |can plant with research
falsefalsefalsetruen/a
falsefalsetruetruen/a
falsetruefalsetruen/a
falsetruetruetruen/a
truefalsefalsefalsetrue
truefalsetruefalsetrue
truetruefalsefalsefalse
truetruetruefalsetrue

Kopp

Hello Tragix,

thanks for your wonderful explanation!
As english is not my native language maybe I could not get my problem to the point or I am not able to fully understand your answer.
Thanks for your patience :)

In your first sentence you said "mustBeWildToSow is true, then the plant must be present in the map biome in order to be planted."
(This is exactly what I did presume but what is obviously not the case. That is my whole problem.)

Line 3 of your table says: We have no research needed. "mustBeWildToSow" is true. The plant is not present in the specific biome. I can plant the plant (in the specific biome).
That is complementary to your first sentence, is it?

I will post a xml from alpha biomes at the end to have a example.
The parents (PlantBase and PlantBaseNonEdible)  do not specify one of the relevant things.

Here we have no sowResearchPrerequisites.
We have   <mustBeWildToSow>true</mustBeWildToSow>.
The plant only gets added to grow wild in a specific biome. (Mycotic jungle)

But the plant can be grown in every biome.
So in this case the <mustBeWildToSow>true</mustBeWildToSow> does not do anything.
Is this intended?

*\Steam\steamapps\workshop\content\294100\1841354677\1.2\Defs\ThingDefs_Plants\Plants_Mycotic.xml

   <ThingDef Name="AB_CavePlantBase" ParentName="PlantBase" Abstract="True">
      <plant>
         <neverBlightable>true</neverBlightable>
         <wildOrder>1</wildOrder>
         <wildEqualLocalDistribution>false</wildEqualLocalDistribution>
      </plant>
   </ThingDef>


   <ThingDef ParentName="AB_CavePlantBase">
      <defName>AB_Glowstool</defName>
      <label>glowstool</label>
      <description>*</description>
      <descriptionHyperlinks>
         <ThingDef>RawFungus</ThingDef>
      </descriptionHyperlinks>
      <statBases>
         <MaxHitPoints>100</MaxHitPoints>
         <Beauty>2</Beauty>
         <Nutrition>0.35</Nutrition>
      </statBases>
      <graphicData>
         <texPath>Things/Plant/Glowstool</texPath>
         <graphicClass>Graphic_Random</graphicClass>
      </graphicData>
      <selectable>true</selectable>
      <neverMultiSelect>false</neverMultiSelect>
      <pathCost>10</pathCost>
      <ingestible />
      <plant>
         <fertilityMin>0.95</fertilityMin>
         <fertilitySensitivity>0.15</fertilitySensitivity>
         <growDays>10</growDays>
         <dieIfLeafless>true</dieIfLeafless>
         <harvestYield>10</harvestYield>
         <harvestTag>Standard</harvestTag>
         <harvestedThingDef>RawFungus</harvestedThingDef>
         <maxMeshCount>4</maxMeshCount>
         <neverBlightable>true</neverBlightable>
         <visualSizeRange>0.4~0.7</visualSizeRange>
         <topWindExposure>0.05</topWindExposure>
         <wildClusterRadius>3</wildClusterRadius>
         <wildClusterWeight>5</wildClusterWeight>
          <mustBeWildToSow>true</mustBeWildToSow>
         <purpose>Food</purpose>
         <sowTags>
            <li>Ground</li>

         </sowTags>
      </plant>

   </ThingDef>

GhostData

Consider it this way: if sowResearchPrerequisites is not specified, a plant may always be planted, even if there are biome restrictions. At least as far as these two fields are concerned - there may be checks in other parts of the code that prevent it.

QuoteHere we have no sowResearchPrerequisites.
We have   <mustBeWildToSow>true</mustBeWildToSow>.
The plant only gets added to grow wild in a specific biome. (Mycotic jungle)

But the plant can be grown in every biome.
So in this case the <mustBeWildToSow>true</mustBeWildToSow> does not do anything.
Is this intended?
Based on the code, I believe this is correct.

I don't know if this will help, but if you can read some basic c# the logic might make more sense than my explanations:


      if (researchPrerequisites == null)
        return true;
      for (int index = 0; index < researchPrerequisites.Count; ++index)
      {
        if (!researchPrerequisites[index].IsFinished)
          return false;
      }
      return !plantDef.plant.mustBeWildToSow || map.Biome.AllWildPlants.Contains(plantDef);
So you see the first check we perform is to determine if there are any research requirements. If there aren't, we skip the rest and return true - meaning the plant should be plantable.
If there ARE research requirements, the next step is to make sure all of the requirements are finished. If any of the requirements are not finished, we return false, meaning the plant may not be planted.
Finally, if all of the requirements are met, the last check is to determine if there are biome requirements. This is the only time we check mustBeWildToSow, and if it is true, we go on to see if the plant belongs in this biome.

Based on the fields themselves, it seems like it would make more sense if the biome requirement was applied first, but that's not what happens behind the scenes.

Maybe to summarize: If you would like to restrict the biomes a plant may grow in, you will also have to specify at least one research requirement.

Kopp

Wow, thanks for your detailed answer.
It is now fully understandable for me why it works the way it does.
I am a bit sorry that it didnt came to my mind checking what happens with the data stored in the xml.
Thanks for your patience and your time Tragix!