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); } }
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; } }