Ignoring certain floors from being used by the ruins generator

Started by Maatss, February 01, 2019, 04:01:40 AM

Previous topic - Next topic

Maatss

I've been bashing my head against this issue for the past two days now, tried everything I can think of.

The problem is:
I create any TerrainDef (a new floor)
Includes <Blocks#anyStoneType#> to its <costList>
Set <Beauty> to more than 1 (that is, higher than the vanilla stone tile)

Now no matter what I do, the game ALWAYS uses this floor over the vanilla stone tile (of the same stone type).
Doesn't matter if I change the cost to include 1000 Gold, silver, plasteel etc.

I've searched the forum and only found this thread
https://ludeon.com/forums/index.php?topic=34051.msg347133#msg347133

Which basically concludes that
QuoteRuins are generated using material selected by a method in RimWorld.BaseGen.BaseGenUtility called "RandomCheapWallStuff." It does pretty much exactly what it sounds like it does: it randomly selects an available material that can be used to make walls and isn't expensive.

and

QuoteIn order to be considered "cheap", the material needs to cost less than $5 per unit. However, small-volume materials are accounted for, meaning things like silver cost 10x their normal market value for the purpose of the cheapness function.

There's another parameter that will prevent it from using anything with 50% or more flammability, which I assume is true for ruins because you don't see ruins with wooden walls by default.

The third requirement is that it is in the list of stuffs that can be used to build walls.

Once it's picked out a wall material, it uses the first floor it can find that uses that material, or concrete as a fallback.

But according to my tests the cost of the tiles are never considered, nor the order of the floors inside the XML.
The only thing that seem to matter is that the resulting ruin floor is the one with the highest beauty and that its
recipe includes either a <Blocks#anyStoneType#> or <Steel> (In the cases where the ruin walls are steel walls)

I have not tested the flammability parameter as it doesn't make sense in my case.


So my question is how do I get around this without getting into C#?
At the very least, how do I make it use this floor at random and not 100% of the time  :'(

Side note:
I believe that the issue originates from this nasty if-statement inside the method CorrespondingTerrainDef in BaseGenUtility

if (allDefsListForReading[i].costList[j].thingDef == stuffDef && (terrainDef == null || ((!beautiful) ? (terrainDef.statBases.GetStatOffsetFromList(StatDefOf.Beauty) > allDefsListForReading[i].statBases.GetStatOffsetFromList(StatDefOf.Beauty)) : (terrainDef.statBases.GetStatOffsetFromList(StatDefOf.Beauty) < allDefsListForReading[i].statBases.GetStatOffsetFromList(StatDefOf.Beauty)))))
{
terrainDef = allDefsListForReading[i];
}



Also, thank you for taking your time to read all of this.

Distman

Yeah, this has been a problem for many modders since the beginning. It's not super easy to solve.
You have to get down and dirty with c# modding.

If you look at the two for loops in the method, it will chose the last TerrainDef it can find that corresponds with all those IF statements. If it can't find any, it uses Concrete.

The best way would be to have a bool variable in Def, something like <useForBaseGen>, so it can be skipped in a modified version of that BaseGenUtility method. I'm just a nood at Harmony so i can't supply any solution to you, unfortunately.

Maatss

Ah I see, will look into it. Appreciate the quick answer.