Vanilla-Expanded / VanillaExpandedFramework

Vanilla Expanded Framework for RimWorld
Other
69 stars 34 forks source link

[KCSG] CustomGenOption fails if map has custom temporary faction #61

Closed glencoe2004 closed 1 year ago

glencoe2004 commented 1 year ago

As the title says, CustomGenOption fails to create a structure if the map has a temporary faction at the time of creation, throwing this error:

Error while resolving symbol "kcsg_settlement" with params=rect=(58,79,216,175), faction=Archotech Worshippers, custom=null, combatPoints=null, pawnGroupMakerParams=null, pawnGroupKindDef=null, roofDef=null, noRoof=null, addRoomCenterToRootsToUnfog=null, singleThingToSpawn=null, singleThingDef=null, singleThingStuff=null, singleThingStackCount=null, skipSingleThingIfHasToWipeBuildingOrDoesntFit=null, spawnBridgeIfTerrainCantSupportThing=null, singleThingInnerThings=null, singlePawnToSpawn=null, singlePawnKindDef=null, disableSinglePawn=null, singlePawnLord=null, settlementLord=null, singlePawnSpawnCellExtraPredicate=null, singlePawnGenerationRequest=null, postThingSpawn=null, postThingGenerate=null, mechanoidsCount=null, hivesCount=null, disableHives=null, thingRot=null, wallStuff=null, chanceToSkipWallBlock=null, floorDef=null, chanceToSkipFloor=null, filthDef=null, filthDensity=null, floorOnlyIfTerrainSupports=null, allowBridgeOnAnyImpassableTerrain=null, clearEdificeOnly=null, clearFillageOnly=null, clearRoof=null, ancientCryptosleepCasketGroupID=null, podContentsType=null, ancientCryptosleepCasketOpenSignalTag=null, thingSetMakerDef=null, thingSetMakerParams=null, stockpileConcreteContents=null, stockpileMarketValue=null, innerStockpileSize=null, edgeDefenseWidth=null, edgeDefenseTurretsCount=null, edgeDefenseMortarsCount=null, edgeDefenseGuardsCount=null, mortarDef=null, pathwayFloorDef=null, cultivatedPlantDef=null, fixedCulativedPlantGrowth=null, fillWithThingsPadding=null, settlementPawnGroupPoints=null, settlementPawnGroupSeed=null, settlementDontGeneratePawns=null, attackWhenPlayerBecameEnemy=null, streetHorizontal=null, edgeThingAvoidOtherEdgeThings=null, edgeThingMustReachMapEdge=null, allowPlacementOffEdge=null, thrustAxis=null, makeWarningLetter=null, allowedMonumentThings=null, bedCount=null, workSitePoints=null, lootConcereteContents=null, lootMarketValue=null, extraDoorEdge=null, minLengthAfterSplit=null

Exception: System.NullReferenceException: Object reference not set to an instance of an object
  at Verse.GenCollection.Any[T] (System.Collections.Generic.List`1[T] list, System.Predicate`1[T] predicate) [0x00000] in <95de19971c5d40878d8742747904cdcd>:0 
  at KCSG.SymbolResolver_Settlement.AddHostilePawnGroup (RimWorld.Faction faction, Verse.Map map, RimWorld.BaseGen.ResolveParams parms, RimWorld.PawnGroupKindDef pawnGroup) [0x0000e] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at KCSG.SymbolResolver_Settlement.Resolve (RimWorld.BaseGen.ResolveParams rp) [0x0003a] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at RimWorld.BaseGen.BaseGen.Resolve (RimWorld.BaseGen.SymbolStack+Element toResolve) [0x000e5] in <95de19971c5d40878d8742747904cdcd>:0 
  at RimWorld.BaseGen.BaseGen.Generate () [0x000ce] in <95de19971c5d40878d8742747904cdcd>:0 
UnityEngine.StackTraceUtility:ExtractStackTrace ()
(wrapper dynamic-method) Verse.Log:Verse.Log.Error_Patch2 (string)
RimWorld.BaseGen.BaseGen:Generate ()
KCSG.CustomGenOption:Generate (Verse.IntVec3,Verse.Map)
KCSG.GenStep_WorldObject:ScatterAt (Verse.IntVec3,Verse.Map,Verse.GenStepParams,int)
Verse.GenStep_Scatterer:Generate (Verse.Map,Verse.GenStepParams)
(wrapper dynamic-method) Verse.MapGenerator:Verse.MapGenerator.GenerateContentsIntoMap_Patch1 (System.Collections.Generic.IEnumerable`1<Verse.GenStepWithParams>,Verse.Map,int)
(wrapper dynamic-method) Verse.MapGenerator:Verse.MapGenerator.GenerateMap_Patch2 (Verse.IntVec3,RimWorld.Planet.MapParent,Verse.MapGeneratorDef,System.Collections.Generic.IEnumerable`1<Verse.GenStepWithParams>,System.Action`1<Verse.Map>)
Verse.GetOrGenerateMapUtility:GetOrGenerateMap (int,Verse.IntVec3,RimWorld.WorldObjectDef)
RimworldMod.ArrivalAction.CaravanArrivalAction_VisitArchotechAncientComplex:DoArrivalAction (RimWorld.Planet.Caravan)
RimworldMod.ArrivalAction.CaravanArrivalAction_VisitArchotechAncientComplex/<>c__DisplayClass8_0:<Arrived>b__0 ()
Verse.LongEventHandler:UpdateCurrentSynchronousEvent (bool&)
Verse.LongEventHandler:LongEventsUpdate (bool&)
(wrapper dynamic-method) Verse.Root:Verse.Root.Update_Patch1 (Verse.Root)
Verse.Root_Play:Update ()

It is possible to get around this somewhat by using GenStep_CustomStructureGen in a custom genstep instead, but if your map has mortars on it, generation fails when it encounters a mortar and displays this error:

Error in GenStep: System.NullReferenceException: Object reference not set to an instance of an object
  at Verse.PawnGenerationRequest.AlwaysDownedLifeStages (System.String& stages) [0x00020] in <95de19971c5d40878d8742747904cdcd>:0 
  at Verse.PawnGenerationRequest.ValidateAndFix () [0x000c2] in <95de19971c5d40878d8742747904cdcd>:0 
  at Verse.PawnGenerationRequest..ctor (Verse.PawnKindDef kind, RimWorld.Faction faction, RimWorld.PawnGenerationContext context, System.Int32 tile, System.Boolean forceGenerateNewPawn, System.Boolean allowDead, System.Boolean allowDowned, System.Boolean canGeneratePawnRelations, System.Boolean mustBeCapableOfViolence, System.Single colonistRelationChanceFactor, System.Boolean forceAddFreeWarmLayerIfNeeded, System.Boolean allowGay, System.Boolean allowPregnant, System.Boolean allowFood, System.Boolean allowAddictions, System.Boolean inhabitant, System.Boolean certainlyBeenInCryptosleep, System.Boolean forceRedressWorldPawnIfFormerColonist, System.Boolean worldPawnFactionDoesntMatter, System.Single biocodeWeaponChance, System.Single biocodeApparelChance, Verse.Pawn extraPawnForExtraRelationChance, System.Single relationWithExtraPawnChanceFactor, System.Predicate`1[T] validatorPreGear, System.Predicate`1[T] validatorPostGear, System.Collections.Generic.IEnumerable`1[T] forcedTraits, System.Collections.Generic.IEnumerable`1[T] prohibitedTraits, System.Nullable`1[T] minChanceToRedressWorldPawn, System.Nullable`1[T] fixedBiologicalAge, System.Nullable`1[T] fixedChronologicalAge, System.Nullable`1[T] fixedGender, System.String fixedLastName, System.String fixedBirthName, RimWorld.RoyalTitleDef fixedTitle, RimWorld.Ideo fixedIdeo, System.Boolean forceNoIdeo, System.Boolean forceNoBackstory, System.Boolean forbidAnyTitle, System.Boolean forceDead, System.Collections.Generic.List`1[T] forcedXenogenes, System.Collections.Generic.List`1[T] forcedEndogenes, RimWorld.XenotypeDef forcedXenotype, RimWorld.CustomXenotype forcedCustomXenotype, System.Collections.Generic.List`1[T] allowedXenotypes, System.Single forceBaselinerChance, Verse.DevelopmentalStage developmentalStages, System.Func`2[T,TResult] pawnKindDefGetter, System.Nullable`1[T] excludeBiologicalAgeRange, System.Nullable`1[T] biologicalAgeRange, System.Boolean forceRecruitable) [0x001f9] in <95de19971c5d40878d8742747904cdcd>:0 
  at KCSG.SymbolUtils.SpawnMortar (Verse.Thing thing, RimWorld.Faction faction, Verse.Map map) [0x000e5] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at KCSG.SymbolUtils.GenerateBuildingAt (Verse.Map map, Verse.IntVec3 cell, KCSG.SymbolDef symbol, KCSG.StructureLayoutDef layout, RimWorld.Faction faction, Verse.ThingDef wallStuff) [0x007e3] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at KCSG.SymbolUtils.Generate (KCSG.SymbolDef symbol, KCSG.StructureLayoutDef layout, Verse.Map map, Verse.IntVec3 cell, RimWorld.Faction faction, Verse.ThingDef wallForRoom) [0x0014d] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at KCSG.LayoutUtils.Generate (KCSG.StructureLayoutDef layout, Verse.CellRect rect, Verse.Map map) [0x000a6] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at KCSG.GenStep_CustomStructureGen.Generate (Verse.Map map, Verse.GenStepParams parms) [0x000c1] in <a9de39dbc53949edae6abea9ad76bed0>:0 
  at (wrapper dynamic-method) Verse.MapGenerator.Verse.MapGenerator.GenerateContentsIntoMap_Patch1(System.Collections.Generic.IEnumerable`1<Verse.GenStepWithParams>,Verse.Map,int)
UnityEngine.StackTraceUtility:ExtractStackTrace ()
(wrapper dynamic-method) Verse.Log:Verse.Log.Error_Patch2 (string)
(wrapper dynamic-method) Verse.MapGenerator:Verse.MapGenerator.GenerateContentsIntoMap_Patch1 (System.Collections.Generic.IEnumerable`1<Verse.GenStepWithParams>,Verse.Map,int)
(wrapper dynamic-method) Verse.MapGenerator:Verse.MapGenerator.GenerateMap_Patch2 (Verse.IntVec3,RimWorld.Planet.MapParent,Verse.MapGeneratorDef,System.Collections.Generic.IEnumerable`1<Verse.GenStepWithParams>,System.Action`1<Verse.Map>)
Verse.GetOrGenerateMapUtility:GetOrGenerateMap (int,Verse.IntVec3,RimWorld.WorldObjectDef)
RimworldMod.ArrivalAction.CaravanArrivalAction_VisitArchotechAncientComplex:DoArrivalAction (RimWorld.Planet.Caravan)
RimworldMod.ArrivalAction.CaravanArrivalAction_VisitArchotechAncientComplex/<>c__DisplayClass8_0:<Arrived>b__0 ()
Verse.LongEventHandler:UpdateCurrentSynchronousEvent (bool&)
Verse.LongEventHandler:LongEventsUpdate (bool&)
(wrapper dynamic-method) Verse.Root:Verse.Root.Update_Patch1 (Verse.Root)
Verse.Root_Play:Update ()

Based on the errors, this seems to be because the code is either attempting to spawn a group of hostile pawns in the first error, or is attempting to do... something in the second error (generate pawns?). Either way, this could potentially be solved by adding a boolean that doesn't attempt to do pawn stuff if set to true/false.

KylianB commented 1 year ago

Do you happen to have a mod I can use to reproduce this easily?

glencoe2004 commented 1 year ago

Do you happen to have a mod I can use to reproduce this easily?

Sure, here's my work in progress mod that throws the issue. The files you're mainly looking for are: (Source) CaravanArrivalAction_VisitArchotechAncientComplex.cs (Defines the temporary faction) (1.4/defs) WorldObjects.xml & SpaceMapGenerator.xml (Don't mind the non-KCSG stuff, that's unrelated to the issue)

SaveOurShip2Experimental-main.zip

glencoe2004 commented 1 year ago

Also, for the worldobject, this is what causes the error:

        <modExtensions>
            <li Class="KCSG.CustomGenOption">
                <chooseFromlayouts>
                    <li>ArchotechWorshippers</li>
                </chooseFromlayouts>
                <preventBridgeable>true</preventBridgeable>
                <tryFindFreeArea>False</tryFindFreeArea>
            </li>
        </modExtensions>
glencoe2004 commented 1 year ago

@KylianB I forgot to mention: to replicate the error, start a game, research the "Locate first pillar" research, then visit the object on the map

KylianB commented 1 year ago

With this I was able to arrive to the worldObject without errors

glencoe2004 commented 1 year ago

Nice, have you tried it with the modextension on the worldobject as well?

KylianB commented 1 year ago

No I forgot, trying now

KylianB commented 1 year ago

With those two commits, it should fix both issues. Thank you for the report!

One last thing, when creating and exporting structures, I recommend enabling "Verbose logging" under "Custom Structure Generation" on the first page of the Vanilla Framework Expanded settings. When enabled, you will see the missing symbols, you have quite a few!

Feel free to close the issue if it's also working for you

glencoe2004 commented 1 year ago

I'll have to test it in a bit, I'm running out of the house right now, regardless thanks for the assistance

glencoe2004 commented 1 year ago

Yup, the issue appears to be fixed. Thanks!