// Token: 0x0600001D RID: 29 RVA: 0x000042EC File Offset: 0x000024EC private PawnKindDef TryGetPawnKindDefFromPawnData(MapGeneratorBlueprintDef blueprint, int itemPos) { PawnKindDef result; if (blueprint.pawnData == null || blueprint.pawnData.Length - 1 < itemPos || blueprint.pawnLegend == null) { result = null; } else { var key = blueprint.pawnData.ElementAt(itemPos).ToString(); result = !blueprint.pawnLegend.ContainsKey(key) ? null : blueprint.pawnLegend[key]; } return(result); }
// 2nd step: Get the ThingDef of the position from the BuildingData of the blueprint. private static ThingDef TryGetThingDefFromBuildingData(MapGeneratorBlueprintDef blueprint, int itemPos) { if (blueprint.buildingData == null || blueprint.buildingData.Count() - 1 < itemPos || blueprint.buildingLegend == null) { return(null); } char keyChar = blueprint.buildingData.ElementAt(itemPos); string key = keyChar.ToString(); if (!blueprint.buildingLegend.ContainsKey(key)) { return(null); } return(blueprint.buildingLegend[key]); }
// 4th step: Get the PawnKindDef of the position from the PawnData of the blueprint. private PawnKindDef TryGetPawnKindDefFromPawnData(MapGeneratorBlueprintDef blueprint, int itemPos) { if (blueprint.pawnData == null || blueprint.pawnData.Count() - 1 < itemPos || blueprint.pawnLegend == null) { return(null); } char keyChar = blueprint.pawnData.ElementAt(itemPos); string key = keyChar.ToString(); if (!blueprint.pawnLegend.ContainsKey(key)) { return(null); } return(blueprint.pawnLegend[key]); }
// 3rd step: Get the ThingDef of the position from the ItemData of the blueprint. private ThingDef TryGetItemDefFromItemData(MapGeneratorBlueprintDef blueprint, int itemPos) { if (blueprint.itemData == null || blueprint.itemData.Count() - 1 < itemPos || blueprint.itemLegend == null) { return(null); } char keyChar = blueprint.itemData.ElementAt(itemPos); string key = keyChar.ToString(); if (!blueprint.itemLegend.ContainsKey(key)) { return(null); } return(DefDatabase <ThingDef> .GetNamedSilentFail(blueprint.itemLegend[key])); }
// Token: 0x0600001B RID: 27 RVA: 0x000041F4 File Offset: 0x000023F4 private Rot4 TryGetRotationFromBuildingData(MapGeneratorBlueprintDef blueprint, int itemPos) { Rot4 result; if (blueprint.buildingData == null || blueprint.buildingData.Length - 1 < itemPos || blueprint.rotationLegend == null) { result = Rot4.Invalid; } else { var key = blueprint.buildingData.ElementAt(itemPos).ToString(); result = !blueprint.rotationLegend.ContainsKey(key) ? Rot4.Invalid : blueprint.rotationLegend[key]; } return(result); }
// 2nd step (b): Get the Rotation of the position from the BuildingData of the blueprint. private Rot4 TryGetRotationFromBuildingData(MapGeneratorBlueprintDef blueprint, int itemPos) { // Using buildingData and rotationLegend here.. if (blueprint.buildingData == null || blueprint.buildingData.Count() - 1 < itemPos || blueprint.rotationLegend == null) { return(Rot4.Invalid); } char keyChar = blueprint.buildingData.ElementAt(itemPos); string key = keyChar.ToString(); if (!blueprint.rotationLegend.ContainsKey(key)) { return(Rot4.Invalid); } return(blueprint.rotationLegend[key]); }
private void MakeBlueprintRoom(CellRect mapRect, Map map, MapGeneratorBlueprintDef blueprint, ThingDef stuffDef) { blueprint.buildingData = CleanUpBlueprintData(blueprint.buildingData); blueprint.floorData = CleanUpBlueprintData(blueprint.floorData); blueprint.pawnData = CleanUpBlueprintData(blueprint.pawnData); blueprint.itemData = CleanUpBlueprintData(blueprint.itemData); if (blueprint.buildingData == null && blueprint.floorData == null) { Log.ErrorOnce(string.Format("After cleaning the BlueprintData and FloorData of blueprint {0} -> both are null, nothing will be done!", blueprint.defName), 313001); return; } IntVec3 spawnBaseCell = new IntVec3(mapRect.BottomLeft.x, mapRect.TopRight.y, mapRect.TopRight.z); IntVec3 spawnCell; foreach (IntVec3 cell in mapRect) { // Check all cells and abort if there is something indestructible found if (!CheckCell(cell, map)) { return; } } allSpawnedPawns = null; try { // Work through blueprint. Note: top-left to bottom-right for (int zn = 0; zn < blueprint.size.z; zn++) { for (int x = 0; x < blueprint.size.x; x++) { //// map can be clipped, don't work with the clipped parts //if (x > mapRect.Width - 1 || zn > mapRect.Height - 1) // continue; spawnCell = spawnBaseCell + new IntVec3(x, 0, -zn); int itemPos = x + blueprint.size.x * zn; ThingDef thingDef = TryGetThingDefFromBuildingData(blueprint, itemPos); Rot4 thingRot = TryGetRotationFromBuildingData(blueprint, itemPos); TerrainDef terrainDef = TryGetTerrainDefFromFloorData(blueprint, itemPos); PawnKindDef pawnKindDef = TryGetPawnKindDefFromPawnData(blueprint, itemPos); ThingDef itemDef = TryGetItemDefFromItemData(blueprint, itemPos); List <Thing> list = map.thingGrid.ThingsListAt(spawnCell); for (int i = 0; i < list.Count; i++) { if (list[i].def == thingDef) { continue; } } //Only clear the space, if something will be made here if (thingDef != null || terrainDef != null || pawnKindDef != null || itemDef != null) { ClearCell(spawnCell, map); } if ((blueprint.canHaveHoles || (MapGenerator_ModSettings.createAllNonPawnBPsWithHoles && (blueprint.pawnLegend == null || blueprint.pawnLegend.Count <= 0))) && Rand.Value < MapGenerator_ModSettings.chanceForHoles) { continue; } // If placed on water, increase the hole chance, if no pawns are to be placed! if (spawnCell.GetTerrain(map).defName.ToLower().Contains("water") && (blueprint.pawnLegend == null || blueprint.pawnLegend.Count <= 0) && Rand.Value < MapGenerator_ModSettings.chanceForHolesOnWater) { continue; } TrySetCellAs(spawnCell, map, thingDef, thingRot, stuffDef, terrainDef, pawnKindDef, itemDef, blueprint); } } } catch (Exception ex) { Log.Warning("Misc. MapGenerator -- Error with blueprint '" + blueprint.defName + "'. Placement position at " + mapRect.CenterCell.ToString() + " on a map of the size " + map.Size.ToString() + "\n" + ex.Message + "\n" + ex.StackTrace); } // If pawns are spawned, place ancient shrine trigger if (allSpawnedPawns != null && allSpawnedPawns.Count > 0) { int nextSignalTagID = Find.UniqueIDsManager.GetNextSignalTagID(); string signalTag = "ancientTempleApproached-" + nextSignalTagID; SignalAction_Letter signalAction_Letter = (SignalAction_Letter)ThingMaker.MakeThing(ThingDefOf.SignalAction_Letter, null); signalAction_Letter.signalTag = signalTag; signalAction_Letter.letter = LetterMaker.MakeLetter("LetterLabelAncientShrineWarning".Translate(), "AncientShrineWarning".Translate(), LetterDefOf.NeutralEvent, new TargetInfo(mapRect.CenterCell, map, false)); GenSpawn.Spawn(signalAction_Letter, mapRect.CenterCell, map); RectTrigger rectTrigger = (RectTrigger)ThingMaker.MakeThing(ThingDefOf.RectTrigger, null); rectTrigger.signalTag = signalTag; rectTrigger.Rect = mapRect.ExpandedBy(1).ClipInsideMap(map); rectTrigger.destroyIfUnfogged = true; GenSpawn.Spawn(rectTrigger, mapRect.CenterCell, map); } // also if pawns are spawned make the appropriate LordJob LordJob lordJob; if (allSpawnedPawns != null && allSpawnedPawns.Count > 0) { if (blueprint.factionSelection == FactionSelection.friendly) { lordJob = new LordJob_AssistColony(allSpawnedPawns[0].Faction, allSpawnedPawns[0].Position); } else { if (Rand.Value < 0.5f) { lordJob = new LordJob_DefendPoint(allSpawnedPawns[0].Position); } else { lordJob = new LordJob_AssaultColony(allSpawnedPawns[0].Faction, false, false, false, false, false); } } LordMaker.MakeNewLord(allSpawnedPawns[0].Faction, lordJob, map, allSpawnedPawns); allSpawnedPawns = null; } }
// Token: 0x06000003 RID: 3 RVA: 0x00002218 File Offset: 0x00000418 private void ScatterBlueprintAt(IntVec3 loc, MapGeneratorBlueprintDef blueprint, Map map, ref ThingDef wallStuff) { var cellRect = new CellRect(loc.x, loc.z, blueprint.size.x, blueprint.size.z); cellRect.ClipInsideMap(map); if (cellRect.Width != blueprint.size.x || cellRect.Height != blueprint.size.z) { return; } foreach (var intVec in cellRect.Cells) { var list = map.thingGrid.ThingsListAt(intVec); foreach (var thing in list) { if (thing.def == ThingDefOf.AncientCryptosleepCasket) { return; } } usedSpots.Add(intVec); } if (blueprint.buildingMaterial != null) { wallStuff = blueprint.buildingMaterial; } if (wallStuff == null) { wallStuff = RandomWallStuff(); } MakeBlueprintRoom(cellRect, blueprint, map, wallStuff); if (!blueprint.createTrigger) { return; } var rectTrigger_UnfogArea = (RectTrigger_UnfogArea)ThingMaker.MakeThing(ThingDef.Named("RectTrigger_UnfogArea")); rectTrigger_UnfogArea.destroyIfUnfogged = true; rectTrigger_UnfogArea.Rect = cellRect; //bool flag5 = blueprint.TriggerLetterMessageText != null; //if (flag5) //{ // bool flag6 = blueprint.TriggerLetterLabel != null; // if (flag6) // { // rectTrigger_UnfogArea.letter = new Letter(Translator.Translate(blueprint.TriggerLetterLabel), Translator.Translate(blueprint.TriggerLetterMessageText), blueprint.TriggerLetterType, cellRect.CenterCell); // } // else // { // rectTrigger_UnfogArea.letter = new Letter("", Translator.Translate(blueprint.TriggerLetterMessageText), blueprint.TriggerLetterType, cellRect.CenterCell); // } //} GenSpawn.Spawn(rectTrigger_UnfogArea, cellRect.CenterCell, map); }
// Token: 0x0600000D RID: 13 RVA: 0x00002BAC File Offset: 0x00000DAC private void TrySetCellAs(IntVec3 c, ThingDef thingDef, Rot4 thingRot, Map map, ThingDef stuffDef = null, TerrainDef terrainDef = null, PawnKindDef pawnKindDef = null, ThingDef itemDef = null, MapGeneratorBlueprintDef blueprint = null) { if (!c.InBounds(map)) { Log.Warning("GenStep_CreateBlueprint: Invalid Target-Cell: cell is null or out of bounds."); } else { var thingList = c.GetThingList(map); foreach (var thing in thingList) { if (!thing.def.destroyable) { return; } } if (terrainDef != null) { map.terrainGrid.SetTerrain(c, terrainDef); } else { if (thingDef != null && stuffDef != null) { map.terrainGrid.SetTerrain(c, CorrespondingTileDef(stuffDef)); } } if (thingDef != null) { var stuff = stuffDef; if (!thingDef.MadeFromStuff) { stuff = null; } var thing = ThingMaker.MakeThing(thingDef, stuff); if (thingRot == Rot4.Invalid) { GenSpawn.Spawn(thing, c, map); } else { GenSpawn.Spawn(thing, c, map, thingRot); } } if (blueprint == null) { return; } if (itemDef != null && blueprint.itemSpawnChance / 100f > Rand.Value) { var isApparel = itemDef.IsApparel; ThingDef thingDef2; if (isApparel) { var num = 0; for (;;) { thingDef2 = DefDatabase <ThingDef> .GetRandom(); if (thingDef2.IsStuff && thingDef2.stuffCategories.Contains(StuffCategoryDefOf.Fabric)) { break; } num++; if (num > 100) { goto Block_17; } } goto IL_18F; Block_17: thingDef2 = DefDatabase <ThingDef> .GetNamedSilentFail("Synthread"); IL_18F :; } else { var source = new List <string> { "Steel", "Steel", "Steel", "Steel", "Steel", "Plasteel" }; thingDef2 = DefDatabase <ThingDef> .GetNamedSilentFail(source.RandomElement()); } if (!itemDef.MadeFromStuff) { thingDef2 = null; } var thing2 = TryGetTreasure(itemDef, thingDef2); thing2 = GenSpawn.Spawn(thing2, c, map); if (thing2.TryGetComp <CompForbiddable>() != null) { thing2.SetForbidden(true); } if (thing2 is Hive hive) { hive.CompDormant.WakeUp(); } } if (pawnKindDef == null || !(blueprint.pawnSpawnChance / 100f > Rand.Value)) { return; } if (faction == null) { faction = Find.FactionManager.FirstFactionOfDef(blueprint.factionDef); } if (faction == null) { switch (blueprint.factionSelection) { case FactionSelection.none: { faction = Find.FactionManager.AllFactions.RandomElementByWeight(fac => fac.def.settlementGenerationWeight); if (faction == null) { faction = Faction.OfMechanoids; } break; } case FactionSelection.hostile: { faction = (from fac in Find.FactionManager.AllFactions where fac.HostileTo(Faction.OfPlayer) select fac).RandomElementByWeight(fac => 101f - fac.def.settlementGenerationWeight); if (faction == null) { faction = Faction.OfMechanoids; } break; } case FactionSelection.friendly: { faction = (from fac in Find.FactionManager.AllFactions where !fac.HostileTo(Faction.OfPlayer) && fac.PlayerGoodwill > 0f && fac != Faction.OfPlayer select fac).RandomElementByWeight(fac => 101f - fac.def.settlementGenerationWeight); if (faction == null) { faction = Find.FactionManager.AllFactions.RandomElementByWeight(fac => fac.def.settlementGenerationWeight); } break; } } } var pawn = PawnGenerator.GeneratePawn(pawnKindDef, faction); pawn.mindState.Active = false; pawn = GenSpawn.Spawn(pawn, c, map) as Pawn; if (pawn == null) { return; } if (allSpawnedPawns == null) { allSpawnedPawns = new List <Pawn>(); } allSpawnedPawns.Add(pawn); } }
// Token: 0x06000004 RID: 4 RVA: 0x00002428 File Offset: 0x00000628 private void MakeBlueprintRoom(CellRect mapRect, MapGeneratorBlueprintDef blueprint, Map map, ThingDef stuffDef) { blueprint.buildingData = CleanUpBlueprintData(blueprint.buildingData); blueprint.floorData = CleanUpBlueprintData(blueprint.floorData); blueprint.pawnData = CleanUpBlueprintData(blueprint.pawnData); blueprint.itemData = CleanUpBlueprintData(blueprint.itemData); if (blueprint.buildingData == null && blueprint.floorData == null) { Log.ErrorOnce( $"After cleaning the BlueprintData and FloorData of blueprint {blueprint.defName} -> both are null, nothing will be done!", 313001); } else { var a = new IntVec3(mapRect.BottomLeft.x, mapRect.TopRight.y, mapRect.TopRight.z); foreach (var c in mapRect) { if (!CheckCell(c, map)) { return; } } allSpawnedPawns = null; for (var i = 0; i < blueprint.size.z; i++) { for (var j = 0; j < blueprint.size.x; j++) { var c2 = a + new IntVec3(j, 0, -i); var itemPos = j + (blueprint.size.x * i); var thingDef = TryGetThingDefFromBuildingData(blueprint, itemPos); var thingRot = TryGetRotationFromBuildingData(blueprint, itemPos); var terrainDef = TryGetTerrainDefFromFloorData(blueprint, itemPos); var pawnKindDef = TryGetPawnKindDefFromPawnData(blueprint, itemPos); var thingDef2 = TryGetItemDefFromItemData(blueprint, itemPos); var list = map.thingGrid.ThingsListAt(c2); foreach (var thing in list) { if (thing.def == thingDef) { } } if (thingDef != null || terrainDef != null || pawnKindDef != null || thingDef2 != null) { ClearCell(c2, map); } if (!(blueprint.canHaveHoles && Rand.Value < 0.08f)) { TrySetCellAs(c2, thingDef, thingRot, map, stuffDef, terrainDef, pawnKindDef, thingDef2, blueprint); } } } if (allSpawnedPawns != null && allSpawnedPawns.Count > 0) { var rectTrigger = (RectTrigger)ThingMaker.MakeThing(ThingDefOf.RectTrigger); rectTrigger.Rect = mapRect.ExpandedBy(1).ClipInsideMap(map); //rectTrigger.letter = new Letter(Translator.Translate("LetterLabelAncientShrineWarning"), Translator.Translate("AncientShrineWarning"), 1, mapRect.CenterCell); rectTrigger.destroyIfUnfogged = false; GenSpawn.Spawn(rectTrigger, mapRect.CenterCell, map); } if (allSpawnedPawns == null || allSpawnedPawns.Count <= 0) { return; } LordJob lordJob; if (blueprint.factionSelection == FactionSelection.friendly) { lordJob = new LordJob_AssistColony(allSpawnedPawns[0].Faction, allSpawnedPawns[0].Position); } else { if (Rand.Value < 0.5f) { lordJob = new LordJob_DefendPoint(allSpawnedPawns[0].Position); } else { lordJob = new LordJob_AssaultColony(allSpawnedPawns[0].Faction, false, false); } } LordMaker.MakeNewLord(allSpawnedPawns[0].Faction, lordJob, map, allSpawnedPawns); allSpawnedPawns = null; } }
// Fill the cell with Pawn private static void TrySetCell_5_SetPawn(IntVec3 c, Map map, Faction faction, PawnKindDef pawnKindDef = null, MapGeneratorBlueprintDef blueprint = null) { //Note: Here is no functionality to clear the cell by design, because it is possible to place items that are larger than 1x1 // The following needs blueprint data to work if (blueprint == null) { return; } // 5th step - work with the Pawn if (pawnKindDef != null && blueprint.pawnSpawnChance / 100 > Rand.Value) { if (blueprint.factionDef != null) { faction = Find.FactionManager.FirstFactionOfDef(blueprint.factionDef); } // still null - find a valid faction. if (faction == null) { switch (blueprint.factionSelection) { case FactionSelection.friendly: faction = (from fac in Find.FactionManager.AllFactions where !fac.HostileTo(Faction.OfPlayer) && fac.PlayerGoodwill > 0 && !(fac == Faction.OfPlayer) select fac) .RandomElementByWeight((Faction fac) => 101 - fac.def.RaidCommonalityFromPoints(1)); if (faction == null) { faction = Find.FactionManager.AllFactions.RandomElementByWeight((Faction fac) => fac.def.RaidCommonalityFromPoints(1)); } break; case FactionSelection.hostile: faction = (from fac in Find.FactionManager.AllFactions where fac.HostileTo(Faction.OfPlayer) select fac) .RandomElementByWeight((Faction fac) => 101 - fac.def.RaidCommonalityFromPoints(1)); if (faction == null) { faction = Faction.OfMechanoids; } break; case FactionSelection.none: faction = Find.FactionManager.AllFactions .RandomElementByWeight((Faction fac) => fac.def.RaidCommonalityFromPoints(1)); if (faction == null) { faction = Faction.OfMechanoids; } break; } } Pawn pawn = PawnGenerator.GeneratePawn(pawnKindDef, faction); pawn.mindState.Active = false; pawn = GenSpawn.Spawn(pawn, c, map) as Pawn; if (pawn != null) { if (allSpawnedPawns == null) { allSpawnedPawns = new List <Pawn>(); } allSpawnedPawns.Add(pawn); } } }
public static void CreateBlueprintAt(IntVec3 c, Map map, MapGeneratorBlueprintDef blueprint, Faction faction, ref ThingDef wallStuff, ref List <IntVec3> usedSpots) { if (working) { Log.Error("Called BlueprintHandler.CreateBlueprintAt(..) while it's still working. This is not allowed!"); return; } if (map == null) { Log.Error("Called BlueprintHandler.CreateBlueprintAt(..) with null map."); return; } working = true; allSpawnedPawns = new List <Pawn>(); pawnLord = null; rooms = new HashSet <Room>(); try { CellRect mapRect = new CellRect(c.x, c.z, blueprint.size.x, blueprint.size.z); mapRect.ClipInsideMap(map); // if mapRect was clipped -> the blueprint doesn't fit inside the map... if (mapRect.Width != blueprint.size.x || mapRect.Height != blueprint.size.z) { return; } // Don't do anything, if there is an cryosleep casket at the building site foreach (IntVec3 current in mapRect.Cells) { List <Thing> list = map.thingGrid.ThingsListAt(current); for (int i = 0; i < list.Count; i++) { if (list[i].def == ThingDefOf.AncientCryptosleepCasket) { return; } // Don't do anything if there is a pawn (mechanoid? insect?) here foreach (Pawn pawn in map.mapPawns.AllPawnsSpawned) { if (pawn != null && pawn.Spawned && pawn.Position == current) { return; } } } if (usedSpots != null) { usedSpots.Add(current); // prevent the base scatterer to use this spot again } } // If a building material is defined, use this if (blueprint.buildingMaterial != null) { wallStuff = blueprint.buildingMaterial; } int w = 0; while (true) { w++; if (w > 100) { break; } // Make all buildings from the same random stuff -- In BaseGen use faction, in MapGen use null! if (wallStuff == null) { wallStuff = BaseGenUtility.RandomCheapWallStuff(null, true); //BaseGenUtility.RandomCheapWallStuff(faction, true); } //If not specified, don't use wood or leather -- Faction Base: Disabled if (blueprint.buildingMaterial != null || (!wallStuff.defName.ToLower().Contains("wood") && !wallStuff.defName.ToLower().Contains("leather"))) { break; } } MakeBlueprintObject(mapRect, map, faction, blueprint, wallStuff); if (blueprint.createTrigger) { int nextSignalTagID = Find.UniqueIDsManager.GetNextSignalTagID(); string signalTag = "unfogTriggerSignal-" + nextSignalTagID; SignalAction_Letter signalAction_Letter = (SignalAction_Letter)ThingMaker.MakeThing(ThingDefOf.SignalAction_Letter, null); signalAction_Letter.signalTag = signalTag; if (blueprint.TriggerLetterMessageText != null) { if (blueprint.TriggerLetterLabel != null) { signalAction_Letter.letter = LetterMaker.MakeLetter(blueprint.TriggerLetterLabel.Translate(), blueprint.TriggerLetterMessageText.Translate(), blueprint.TriggerLetterDef, new GlobalTargetInfo(mapRect.CenterCell, map, false)); } else { signalAction_Letter.letter = LetterMaker.MakeLetter("", blueprint.TriggerLetterMessageText.Translate(), blueprint.TriggerLetterDef, new GlobalTargetInfo(mapRect.CenterCell, map)); } GenSpawn.Spawn(signalAction_Letter, mapRect.CenterCell, map); } RectTrigger_UnfogArea rectTrigger = (RectTrigger_UnfogArea)ThingMaker.MakeThing(ThingDef.Named("RectTrigger_UnfogArea"), null); rectTrigger.signalTag = signalTag; rectTrigger.destroyIfUnfogged = true; rectTrigger.Rect = mapRect; GenSpawn.Spawn(rectTrigger, mapRect.CenterCell, map); } map.regionAndRoomUpdater.RebuildAllRegionsAndRooms(); HashSet <Room> rooms = new HashSet <Room>(); foreach (IntVec3 current in mapRect.Cells) { // Find all created rooms Room room = current.GetRoom(map); if (room != null && !room.TouchesMapEdge) { rooms.Add(room); } } //// Create roof //foreach (Room room in rooms) //{ // foreach (IntVec3 roofCell in room.Cells) // { // map.roofGrid.SetRoof(c, RoofDefOf.RoofConstructed); // } //} //map.roofGrid.RoofGridUpdate(); } catch (Exception ex) { Log.Error("Error in BlueprintHandler.CreateBlueprintAt(..): " + ex); } finally { // Whatever happends, when its done, reset the working state. working = false; // Clear all data holder allSpawnedPawns = null; pawnLord = null; rooms = null; } }
private static void MakeBlueprintObject(CellRect mapRect, Map map, Faction faction, MapGeneratorBlueprintDef blueprint, ThingDef stuffDef) { blueprint.buildingData = GetCleanedBlueprintData(blueprint.buildingData); blueprint.floorData = GetCleanedBlueprintData(blueprint.floorData); blueprint.pawnData = GetCleanedBlueprintData(blueprint.pawnData); blueprint.itemData = GetCleanedBlueprintData(blueprint.itemData); if (blueprint.buildingData == null && blueprint.floorData == null) { Log.Error(string.Format("After cleaning the BlueprintData and FloorData of blueprint {0} -> both are null, nothing will be done!", blueprint.defName)); return; } IntVec3 spawnBaseCell = new IntVec3(mapRect.BottomLeft.x, mapRect.TopRight.y, mapRect.TopRight.z); IntVec3 spawnCell; // Check all cells and abort if there is something indestructible found foreach (IntVec3 cell in mapRect) { if (!CheckCell(cell, map)) { return; } } allSpawnedPawns = null; // Disable automatic room updating map.regionAndRoomUpdater.Enabled = false; int step = 1; while (step <= 4) { // Work through blueprint - Note: top-left to bottom-right // Work step by step: 1st all floors, 2nd all things, 3rd all items, 4th all pawns for (int zn = 0; zn < blueprint.size.z; zn++) { for (int x = 0; x < blueprint.size.x; x++) { // map can be clipped, don't work with the clipped parts if (x > mapRect.Width - 1 || zn > mapRect.Height - 1) { continue; } if (blueprint.canHaveHoles && Rand.Value < 0.08f) { continue; } spawnCell = spawnBaseCell + new IntVec3(x, 0, -zn); if (!TrySetCell_prepare_CheckCell(spawnCell, map)) { continue; } int itemPos = x + blueprint.size.x * zn; try { ThingDef thingDef = TryGetThingDefFromBuildingData(blueprint, itemPos); Rot4 thingRot = TryGetRotationFromBuildingData(blueprint, itemPos); TerrainDef terrainDef = TryGetTerrainDefFromFloorData(blueprint, itemPos); PawnKindDef pawnKindDef = TryGetPawnKindDefFromPawnData(blueprint, itemPos); ThingDef itemDef = TryGetItemDefFromItemData(blueprint, itemPos); //Only clear the space, if something will be made here // Do only in step 1: if (step == 1) { if (thingDef != null || terrainDef != null || pawnKindDef != null || itemDef != null) { ClearCell(spawnCell, map); } } switch (step) { case 1: // Terrain TrySetCell_1_SetFloor(spawnCell, map, terrainDef, thingDef, stuffDef); break; case 2: // Building TrySetCell_2_SetThing(spawnCell, map, thingDef, thingRot, stuffDef); break; case 3: // Item TrySetCell_4_SetItem(spawnCell, map, itemDef, blueprint); break; case 4: // Pawn TrySetCell_5_SetPawn(spawnCell, map, faction, pawnKindDef, blueprint); break; default: return; } } catch (Exception ex) { Log.Warning("MapGeneratorFactionBase - Error while creating the blueprint (" + blueprint.defName + ")\n" + ex.Message + "\n" + ex.StackTrace); } } } step++; } // Update the powernets map.powerNetManager.UpdatePowerNetsAndConnections_First(); // Enable automatic room updating and rebuild all rooms map.regionAndRoomUpdater.Enabled = true; map.regionAndRoomUpdater.RebuildAllRegionsAndRooms(); LordJob lordJob; if (allSpawnedPawns != null && allSpawnedPawns.Count > 0) { if (blueprint.factionSelection == FactionSelection.friendly) { lordJob = new LordJob_AssistColony(allSpawnedPawns[0].Faction, allSpawnedPawns[0].Position); } else { if (Rand.Value < 0.5f) { lordJob = new LordJob_DefendPoint(allSpawnedPawns[0].Position); } else { lordJob = new LordJob_AssaultColony(allSpawnedPawns[0].Faction, false, false, false); } } LordMaker.MakeNewLord(allSpawnedPawns[0].Faction, lordJob, map, allSpawnedPawns); // make the appropriate Lord pawnLord = LordMaker.MakeNewLord(faction, lordJob, map, null); // Get points used by current pawns float pointsUsed = 0f; if (allSpawnedPawns != null && allSpawnedPawns.Count > 0) { foreach (Pawn pawnSpawned in allSpawnedPawns) { pointsUsed += pawnSpawned.kindDef.combatPower; } } if (allSpawnedPawns != null) { foreach (Pawn pawn in allSpawnedPawns) { pawnLord.AddPawn(pawn); } } allSpawnedPawns = null; } }
// This function may need some work... private IntVec3 TryFindValidScatterCellNear(IntVec3 loc, Map map, MapGeneratorBlueprintDef blueprint, HashSet <IntVec3> invalidCells) { if (usedCells.Count == 0) { return(loc); } IntVec2 size = blueprint.size; bool allowCenter = blueprint.mapCenterBlueprint; int searchTry = 0; int searchTriesMax = 30; while (searchTry < searchTriesMax) { if (!allowCenter) { // Check if the loc is near the spawn location -> move loc by +20, 0, -20 IntVec2 nogoCenter = new IntVec2(map.Size.x / 2, map.Size.z / 2); CellRect nogoCenterRect = new CellRect(nogoCenter.x, nogoCenter.z, 1, 1); nogoCenterRect = nogoCenterRect.ExpandedBy(10); if (nogoCenterRect.Contains(loc)) { loc = new IntVec3(loc.x + 20, loc.y, loc.z - 20); } } int placement = Rand.RangeInclusive(0, 7); // Find nearest used cell to the distance IntVec3 workCell = IntVec3.Invalid; foreach (IntVec3 cell in usedCells) { switch (placement) { case 0: // north workCell = workCell == IntVec3.Invalid || cell.z > workCell.z ? cell : workCell; break; case 1: // north-east workCell = workCell == IntVec3.Invalid || cell.z > workCell.z && cell.x > workCell.x ? cell : workCell; break; case 2: // east workCell = workCell == IntVec3.Invalid || cell.x > workCell.x ? cell : workCell; break; case 3: // south-east workCell = workCell == IntVec3.Invalid || cell.z <workCell.z && cell.x> workCell.x ? cell : workCell; break; case 4: // south workCell = workCell == IntVec3.Invalid || cell.z < workCell.z ? cell : workCell; break; case 5: // south-west workCell = workCell == IntVec3.Invalid || cell.z < workCell.z && cell.x < workCell.x ? cell : workCell; break; case 6: // west workCell = workCell == IntVec3.Invalid || cell.x < workCell.x ? cell : workCell; break; case 7: // north-west workCell = workCell == IntVec3.Invalid || cell.z > workCell.z && cell.x < workCell.x ? cell : workCell; break; default: // error workCell = IntVec3.Invalid; break; } } // No valid cell found if (workCell == IntVec3.Invalid) { return(IntVec3.Invalid); } IntVec3 tmpCell = IntVec3.Invalid; int workDistance = ruinDistanceRange.RandomInRange; // set workDistance according to blueprint size if (size.x > size.z) { workDistance = size.x + Rand.RangeInclusive(1, 5); } else { workDistance = size.z + Rand.RangeInclusive(1, 5); } // set new cell switch (placement) { case 0: // north tmpCell = new IntVec3(0, 0, +workDistance); workCell += tmpCell; break; case 1: // north-east tmpCell = new IntVec3(+workDistance, 0, +workDistance); workCell += tmpCell; break; case 2: // east tmpCell = new IntVec3(+workDistance, 0, 0); workCell += tmpCell; break; case 3: // south-east tmpCell = new IntVec3(+workDistance, 0, -workDistance - (int)ruinOffsetVerticalRange.Average); workCell += tmpCell; break; case 4: // south tmpCell = new IntVec3(0, 0, -workDistance - (int)ruinOffsetVerticalRange.Average); workCell += tmpCell; break; case 5: // south-west tmpCell = new IntVec3(-workDistance - (int)ruinOffsetHorizontalRange.Average, 0, -workDistance - (int)ruinOffsetVerticalRange.Average); workCell += tmpCell; break; case 6: // west tmpCell = new IntVec3(-workDistance - (int)ruinOffsetHorizontalRange.Average, 0, 0); workCell += tmpCell; break; case 7: // north-west tmpCell = new IntVec3(-workDistance - (int)ruinOffsetHorizontalRange.Average, 0, +workDistance); workCell += tmpCell; break; default: // error workCell = IntVec3.Invalid; break; } // set new min distance according to tmpCell if (tmpCell.IsValid) { if (Math.Abs(tmpCell.x) / 2 < ruinDistanceRange.max && Math.Abs(tmpCell.z) / 2 < ruinDistanceRange.max) { if (Math.Abs(tmpCell.x) > Math.Abs(tmpCell.z)) { ruinDistanceRange.min = Math.Abs(tmpCell.x) / 2; } else { ruinDistanceRange.min = Math.Abs(tmpCell.z) / 2; } if (ruinDistanceRange.min > ruinDistanceRange.max) { ruinDistanceRange.max = ruinDistanceRange.min; } } } if (workCell.InBounds(map) && CanScatterAt(workCell, map) && IsPositionValidForBlueprint(workCell, size, invalidCells)) { return(workCell); } searchTry++; } return(IntVec3.Invalid); }
// Token: 0x06000014 RID: 20 RVA: 0x0000339C File Offset: 0x0000159C private IntVec3 TryFindValidScatterCellNear(IntVec3 loc, MapGeneratorBlueprintDef blueprint, Map map, List <IntVec3> invalidCells) { IntVec3 result; if (usedCells.Count == 0) { result = loc; } else { var size = blueprint.size; var mapCenterBlueprint = blueprint.mapCenterBlueprint; var i = 0; var num = 30; while (i < num) { if (!mapCenterBlueprint) { var intVec = new IntVec2(map.Size.x / 2, map.Size.z / 2); var cellRect = new CellRect(intVec.x, intVec.z, 1, 1); cellRect = cellRect.ExpandedBy(10); if (cellRect.Contains(loc)) { loc = new IntVec3(loc.x + 20, loc.y, loc.z - 20); } } var num2 = Rand.RangeInclusive(0, 7); var intVec2 = IntVec3.Invalid; foreach (var intVec3 in usedCells) { switch (num2) { case 0: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z > intVec2.z ? intVec3 : intVec2; break; case 1: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z > intVec2.z && intVec3.x > intVec2.x ? intVec3 : intVec2; break; case 2: intVec2 = intVec2 == IntVec3.Invalid || intVec3.x > intVec2.x ? intVec3 : intVec2; break; case 3: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z <intVec2.z && intVec3.x> intVec2.x ? intVec3 : intVec2; break; case 4: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z < intVec2.z ? intVec3 : intVec2; break; case 5: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z < intVec2.z && intVec3.x < intVec2.x ? intVec3 : intVec2; break; case 6: intVec2 = intVec2 == IntVec3.Invalid || intVec3.x < intVec2.x ? intVec3 : intVec2; break; case 7: intVec2 = intVec2 == IntVec3.Invalid || intVec3.z > intVec2.z && intVec3.x < intVec2.x ? intVec3 : intVec2; break; default: intVec2 = IntVec3.Invalid; break; } } if (intVec2 == IntVec3.Invalid) { return(IntVec3.Invalid); } var invalid = IntVec3.Invalid; int num3; if (size.x > size.z) { num3 = size.x + Rand.RangeInclusive(1, 5); } else { num3 = size.z + Rand.RangeInclusive(1, 5); } switch (num2) { case 0: invalid = new IntVec3(0, 0, num3); intVec2 += invalid; break; case 1: invalid = new IntVec3(num3, 0, num3); intVec2 += invalid; break; case 2: invalid = new IntVec3(num3, 0, 0); intVec2 += invalid; break; case 3: invalid = new IntVec3(num3, 0, -num3 - (int)ruinOffsetVerticalRange.Average); intVec2 += invalid; break; case 4: invalid = new IntVec3(0, 0, -num3 - (int)ruinOffsetVerticalRange.Average); intVec2 += invalid; break; case 5: invalid = new IntVec3(-num3 - (int)ruinOffsetHorizontalRange.Average, 0, -num3 - (int)ruinOffsetVerticalRange.Average); intVec2 += invalid; break; case 6: invalid = new IntVec3(-num3 - (int)ruinOffsetHorizontalRange.Average, 0, 0); intVec2 += invalid; break; case 7: invalid = new IntVec3(-num3 - (int)ruinOffsetHorizontalRange.Average, 0, num3); intVec2 += invalid; break; default: intVec2 = IntVec3.Invalid; break; } var isValid = invalid.IsValid; if (isValid) { if (Math.Abs(invalid.x) / 2 < ruinDistanceRange.max && Math.Abs(invalid.z) / 2 < ruinDistanceRange.max) { if (Math.Abs(invalid.x) > Math.Abs(invalid.z)) { ruinDistanceRange.min = Math.Abs(invalid.x) / 2; } else { ruinDistanceRange.min = Math.Abs(invalid.z) / 2; } if (ruinDistanceRange.min > ruinDistanceRange.max) { ruinDistanceRange.max = ruinDistanceRange.min; } } } if (intVec2.InBounds(map) && CanScatterAt(intVec2, map) && IsPositionValidForBlueprint(intVec2, size, invalidCells)) { return(intVec2); } i++; } result = IntVec3.Invalid; } return(result); }
// Fill the cell private void TrySetCellAs(IntVec3 c, Map map, ThingDef thingDef, Rot4 thingRot, ThingDef stuffDef = null, TerrainDef terrainDef = null, PawnKindDef pawnKindDef = null, ThingDef itemDef = null, MapGeneratorBlueprintDef blueprint = null) { //Note: Here is no functionality to clear the cell by design, because it is possible to place items that are larger than 1x1 // Check the cell information if (c == null || !c.InBounds(map)) { Log.Warning("GenStep_CreateBlueprint: Invalid Target-Cell: cell is null or out of bounds."); return; } // only continue to do work if here isn't anything indestructable List <Thing> thingList = c.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { if (!thingList[i].def.destroyable) { return; } } // 1st step - work with the Terrain if (terrainDef != null) { map.terrainGrid.SetTerrain(c, terrainDef); } else if (terrainDef == null && thingDef != null && stuffDef != null) { map.terrainGrid.SetTerrain(c, this.CorrespondingTileDef(stuffDef)); } // 2nd step - work with the Thing (Buildings) if (thingDef != null) { ThingDef stuffDef1 = stuffDef; if (!thingDef.MadeFromStuff) { stuffDef1 = null; } Thing newThing = ThingMaker.MakeThing(thingDef, stuffDef1); if (thingRot == null || thingRot == Rot4.Invalid) { GenSpawn.Spawn(newThing, c, map); } else { GenSpawn.Spawn(newThing, c, map, thingRot); } CompGatherSpot compGathering = newThing.TryGetComp <CompGatherSpot>(); if (compGathering != null) { compGathering.Active = false; } } // The following needs blueprint data to work if (blueprint == null) { return; } // 3rd step - work with the Item //if (itemDef != null) // && blueprint.itemSpawnChance / 100 > Rand.Value) if (itemDef != null && blueprint.itemSpawnChance / 100 > Rand.Value) { ThingDef stuffDef2; if (itemDef.IsApparel) { if (!DefDatabase <ThingDef> .AllDefs.Where <ThingDef>(t => t.IsStuff && t.stuffProps != null && t.stuffProps.categories != null && t.stuffProps.categories.Contains(StuffCategoryDefOf.Fabric)) .TryRandomElement(out stuffDef2)) { stuffDef2 = DefDatabase <ThingDef> .GetNamedSilentFail("Synthread"); } } else { List <string> stuffPossibles = new List <string>() { "Steel", "Steel", "Steel", "Steel", "Silver", "Gold", "Jade", "Plasteel" }; stuffDef2 = DefDatabase <ThingDef> .GetNamedSilentFail(stuffPossibles.RandomElement()); } if (!itemDef.MadeFromStuff) { stuffDef2 = null; } Thing newItem = TryGetTreasure(itemDef, stuffDef2); newItem = GenSpawn.Spawn(newItem, c, map); // Don't forget to set the items to forbidden! if (newItem.TryGetComp <CompForbiddable>() != null) { newItem.SetForbidden(true, false); } // If it is a hive, it needs to be deactivated Hive newHive = newItem as Hive; if (newHive != null) { newHive.active = false; } } // 4th step - work with the Pawn if (pawnKindDef != null && blueprint.pawnSpawnChance / 100 > Rand.Value) { if (this.faction == null) { this.faction = Find.FactionManager.FirstFactionOfDef(blueprint.factionDef); } float pointsForRaid = map.IncidentPointsRandomFactorRange.RandomInRange; // still null - find a valid faction. if (this.faction == null) { switch (blueprint.factionSelection) { case FactionSelection.friendly: faction = (from fac in Find.FactionManager.AllFactions where !fac.HostileTo(Faction.OfPlayer) && fac.PlayerGoodwill > 0 && !(fac == Faction.OfPlayer) select fac) .RandomElementByWeight((Faction fac) => 101 - fac.def.RaidCommonalityFromPoints(pointsForRaid)); if (faction == null) { faction = Find.FactionManager.AllFactions.RandomElementByWeight((Faction fac) => fac.def.RaidCommonalityFromPoints(pointsForRaid)); } break; case FactionSelection.hostile: faction = (from fac in Find.FactionManager.AllFactions where fac.HostileTo(Faction.OfPlayer) select fac) .RandomElementByWeight((Faction fac) => 101 - fac.def.RaidCommonalityFromPoints(pointsForRaid)); if (faction == null) { faction = Faction.OfMechanoids; } break; case FactionSelection.none: faction = Find.FactionManager.AllFactions .RandomElementByWeight((Faction fac) => fac.def.RaidCommonalityFromPoints(pointsForRaid)); if (faction == null) { faction = Faction.OfMechanoids; } break; } } Pawn pawn = PawnGenerator.GeneratePawn(pawnKindDef, faction); pawn.mindState.Active = false; pawn = GenSpawn.Spawn(pawn, c, map) as Pawn; if (pawn != null) { if (allSpawnedPawns == null) { allSpawnedPawns = new List <Pawn>(); } allSpawnedPawns.Add(pawn); } } }
private void ScatterBlueprintAt(IntVec3 loc, Map map, MapGeneratorBlueprintDef blueprint, ref ThingDef wallStuff, HashSet <IntVec3> listOfUsedCells) { CellRect mapRect = new CellRect(loc.x, loc.z, blueprint.size.x, blueprint.size.z); mapRect.ClipInsideMap(map); // if mapRect was clipped -> the blueprint doesn't fit inside the map... if (mapRect.Width != blueprint.size.x || mapRect.Height != blueprint.size.z) { return; } // Check if we will build on a usedCell bool usedCellFound = false; foreach (IntVec3 cell in mapRect.Cells) { if (listOfUsedCells != null && listOfUsedCells.Contains(cell)) { usedCellFound = true; break; } } if (usedCellFound) { return; } // Don't do anything, if there is an cryosleep casket at the building site foreach (IntVec3 current in mapRect.Cells) { List <Thing> list = map.thingGrid.ThingsListAt(current); for (int i = 0; i < list.Count; i++) { if (list[i].def == ThingDefOf.AncientCryptosleepCasket) { return; } } // Don't do anything if there is a pawn (mechanoid? insect?) here foreach (Pawn pawn in map.mapPawns.AllPawnsSpawned) { if (pawn != null && pawn.Spawned && pawn.Position == current) { return; } } usedSpots.Add(current); // prevent the base scatterer to use this spot usedCells.Add(current); usedCells_lastChange = DateTime.UtcNow; } // Remove this blueprints map cells from the unfogging list List <IntVec3> rootsToUnfog = Verse.MapGenerator.rootsToUnfog; foreach (IntVec3 cell in mapRect.Cells) { if (rootsToUnfog != null && rootsToUnfog.Contains(cell)) { rootsToUnfog.Remove(cell); } } // If a building material is defined, use this if (blueprint.buildingMaterial != null) { wallStuff = blueprint.buildingMaterial; } int w = 0; while (true) { w++; if (w > 100) { break; } // Make all buildings from the same random stuff -- In BaseGen use faction, in MapGen use null! if (wallStuff == null) { wallStuff = BaseGenUtility.RandomCheapWallStuff(null, true); // BaseGenUtility.RandomCheapWallStuff(faction, true); } //If not specified, don't use wood or leather if (blueprint.buildingMaterial != null || (!wallStuff.defName.ToLower().Contains("wood") && !wallStuff.defName.ToLower().Contains("leather"))) { break; } } MakeBlueprintRoom(mapRect, map, blueprint, wallStuff); if (blueprint.createTrigger) { int nextSignalTagID = Find.UniqueIDsManager.GetNextSignalTagID(); string signalTag = "unfogTriggerSignal-" + nextSignalTagID; SignalAction_Letter signalAction_Letter = (SignalAction_Letter)ThingMaker.MakeThing(ThingDefOf.SignalAction_Letter, null); signalAction_Letter.signalTag = signalTag; if (blueprint.TriggerLetterMessageText != null) { if (blueprint.TriggerLetterLabel != null) { signalAction_Letter.letter = LetterMaker.MakeLetter(blueprint.TriggerLetterLabel.Translate(), blueprint.TriggerLetterMessageText.Translate(), blueprint.TriggerLetterDef, new GlobalTargetInfo(mapRect.CenterCell, map, false)); } else { signalAction_Letter.letter = LetterMaker.MakeLetter("", blueprint.TriggerLetterMessageText.Translate(), blueprint.TriggerLetterDef, new GlobalTargetInfo(mapRect.CenterCell, map)); } GenSpawn.Spawn(signalAction_Letter, mapRect.CenterCell, map); } RectTrigger_UnfogArea rectTrigger = (RectTrigger_UnfogArea)ThingMaker.MakeThing(ThingDef.Named("RectTrigger_UnfogArea"), null); rectTrigger.signalTag = signalTag; rectTrigger.destroyIfUnfogged = true; rectTrigger.Rect = mapRect; GenSpawn.Spawn(rectTrigger, mapRect.CenterCell, map); } }
// Fill the cell with Item private static void TrySetCell_4_SetItem(IntVec3 c, Map map, ThingDef itemDef = null, MapGeneratorBlueprintDef blueprint = null) { //Note: Here is no functionality to clear the cell by design, because it is possible to place items that are larger than 1x1 // The following needs blueprint data to work if (blueprint == null) { return; } // 4th step - work with the Item //if (itemDef != null) // && blueprint.itemSpawnChance / 100 > Rand.Value) if (itemDef != null && blueprint.itemSpawnChance / 100 > Rand.Value) { ThingDef stuffDef2; if (itemDef.IsApparel) { if (!DefDatabase <ThingDef> .AllDefs.Where <ThingDef>(t => t.IsStuff && t.stuffProps != null && t.stuffProps.categories != null && t.stuffProps.categories.Contains(StuffCategoryDefOf.Fabric)) .TryRandomElement(out stuffDef2)) { stuffDef2 = DefDatabase <ThingDef> .GetNamedSilentFail("Synthread"); } } else { List <string> stuffPossibles = new List <string>() { "Steel", "Steel", "Steel", "Steel", "Steel", "Silver", "Plasteel" }; stuffDef2 = DefDatabase <ThingDef> .GetNamedSilentFail(stuffPossibles.RandomElement()); } if (!itemDef.MadeFromStuff) { stuffDef2 = null; } Thing newItem = TryGetTreasure(itemDef, stuffDef2); newItem = GenSpawn.Spawn(newItem, c, map); // Don't forget to set the items to forbidden! if (newItem.TryGetComp <CompForbiddable>() != null) { newItem.SetForbidden(true, false); } // If it is a hive, it needs to be deactivated Hive newHive = newItem as Hive; if (newHive != null) { newHive.active = false; } } }