protected override void ScatterAt(IntVec3 loc, Map map, int stackCount = 1) { int randomInRange = GenStep_ScatterShrinesMedieval.ShrinesCountX.RandomInRange; int randomInRange2 = GenStep_ScatterShrinesMedieval.ShrinesCountZ.RandomInRange; int randomInRange3 = GenStep_ScatterShrinesMedieval.ExtraHeightRange.RandomInRange; IntVec2 standardAncientShrineSize = SymbolResolver_AncientShrinesGroupMedieval.StandardAncientShrineSize; int num = 1; int num2 = randomInRange * standardAncientShrineSize.x + (randomInRange - 1) * num; int num3 = randomInRange2 * standardAncientShrineSize.z + (randomInRange2 - 1) * num; int num4 = num2 + 2; int num5 = num3 + 2 + randomInRange3; CellRect rect = new CellRect(loc.x, loc.z, num4, num5); rect.ClipInsideMap(map); if (rect.Width != num4 || rect.Height != num5) { return; } foreach (IntVec3 c in rect.Cells) { List <Thing> list = map.thingGrid.ThingsListAt(c); for (int i = 0; i < list.Count; i++) { if (list[i].def == ThingDefOf.AncientCryptosleepCasket) { return; } } } if (!base.CanPlaceAncientBuildingInRange(rect, map)) { return; } ResolveParams resolveParams = default(ResolveParams); resolveParams.rect = rect; resolveParams.disableSinglePawn = new bool?(true); resolveParams.disableHives = new bool?(true); resolveParams.ancientTempleEntranceHeight = new int?(randomInRange3); BaseGen.globalSettings.map = map; BaseGen.symbolStack.Push("ancientTemple", resolveParams); BaseGen.Generate(); 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(rect.CenterCell, map, false)); GenSpawn.Spawn(signalAction_Letter, rect.CenterCell, map); RectTrigger rectTrigger = (RectTrigger)ThingMaker.MakeThing(ThingDefOf.RectTrigger, null); rectTrigger.signalTag = signalTag; rectTrigger.Rect = rect.ExpandedBy(1).ClipInsideMap(map); rectTrigger.destroyIfUnfogged = true; GenSpawn.Spawn(rectTrigger, rect.CenterCell, map); }
public static void CreateBlueprintAt(IntVec3 c, Map map, BaseBlueprintDef blueprint, Faction faction, ThingDef wallStuff, out Dictionary <Pawn, LordType> pawns, out float totalThreat, bool useOneFaction = false, bool useAdditionThreat = false, float additionalPoints = 0f) { pawns = null; totalThreat = 0; 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 Dictionary <Pawn, LordType>(); 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; // } // 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.defaultBuildingMaterial != null) { wallStuff = blueprint.defaultBuildingMaterial; } // Make all buildings from the same random stuff if (wallStuff == null) { wallStuff = BaseGenUtility.RandomCheapWallStuff(faction, false); } MakeBlueprintObject(map, faction, mapRect, blueprint, wallStuff, out pawns, out totalThreat, useOneFaction, useAdditionThreat, additionalPoints); if (blueprint.createTrigger) { int nextSignalTagID = Find.UniqueIDsManager.GetNextSignalTagID(); string signalTag = "unfogBaseAreaTriggerSignal-" + nextSignalTagID; SignalAction_Letter signalAction_Letter = (SignalAction_Letter)ThingMaker.MakeThing(ThingDefOf.SignalAction_Letter, null); signalAction_Letter.signalTag = signalTag; if (blueprint.TriggerLetterMessageText != null) { if (blueprint.TriggerLetterDef == null) { blueprint.TriggerLetterDef = LetterDefOf.ThreatSmall; } 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_UnfogBaseArea rectTrigger = (RectTrigger_UnfogBaseArea)ThingMaker.MakeThing(ThingDef.Named("RectTrigger_UnfogBaseArea"), 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); } } // Add rooms to unfog area AddRoomCentersToRootsToUnfog(rooms.ToList()); // Create roof foreach (Room room in rooms) { BuildRoofToRoom(room, false); } 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; rooms = null; } }
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); } }
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; } }
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; } }
public override void Resolve(ResolveParams rp) { Map map = BaseGen.globalSettings.map; CellRect cellRect = CellRect.Empty; RimWorld.SketchGen.ResolveParams parms = default(RimWorld.SketchGen.ResolveParams); parms.sketch = new Sketch(); parms.monumentOpen = false; parms.monumentSize = new IntVec2(rp.rect.Width, rp.rect.Height); parms.allowMonumentDoors = false; parms.allowWood = false; parms.allowFlammableWalls = false; if (rp.allowedMonumentThings != null) { parms.allowedMonumentThings = rp.allowedMonumentThings; } else { parms.allowedMonumentThings = new ThingFilter(); parms.allowedMonumentThings.SetAllowAll(null, includeNonStorable: true); } parms.allowedMonumentThings.SetAllow(ThingDefOf.Drape, allow: false); Sketch sketch = RimWorld.SketchGen.SketchGen.Generate(SketchResolverDefOf.Monument, parms); sketch.Spawn(map, rp.rect.CenterCell, null, Sketch.SpawnPosType.Unchanged, Sketch.SpawnMode.Normal, wipeIfCollides: true, clearEdificeWhereFloor: true, null, dormant: false, buildRoofsInstantly: true); CellRect rect = SketchGenUtility.FindBiggestRect(sketch, (IntVec3 x) => sketch.TerrainAt(x) != null && !sketch.ThingsAt(x).Any((SketchThing y) => y.def == ThingDefOf.Wall)).MovedBy(rp.rect.CenterCell); for (int i = 0; i < sketch.Things.Count; i++) { if (sketch.Things[i].def == ThingDefOf.Wall) { IntVec3 c = sketch.Things[i].pos + rp.rect.CenterCell; cellRect = ((!cellRect.IsEmpty) ? CellRect.FromLimits(Mathf.Min(cellRect.minX, c.x), Mathf.Min(cellRect.minZ, c.z), Mathf.Max(cellRect.maxX, c.x), Mathf.Max(cellRect.maxZ, c.z)) : CellRect.SingleCell(c)); } } if (!rect.IsEmpty) { ResolveParams resolveParams = rp; resolveParams.rect = rect; if (rp.allowedMonumentThings != null) { resolveParams.allowedMonumentThings = rp.allowedMonumentThings; } else { resolveParams.allowedMonumentThings = new ThingFilter(); resolveParams.allowedMonumentThings.SetAllowAll(null, includeNonStorable: true); } if (ModsConfig.RoyaltyActive) { resolveParams.allowedMonumentThings.SetAllow(ThingDefOf.Drape, allow: false); } BaseGen.symbolStack.Push("interior_ancientTemple", resolveParams); } if (rp.makeWarningLetter.HasValue && rp.makeWarningLetter.Value) { int nextSignalTagID = Find.UniqueIDsManager.GetNextSignalTagID(); string signalTag = "ancientTempleApproached-" + nextSignalTagID; SignalAction_Letter obj = (SignalAction_Letter)ThingMaker.MakeThing(ThingDefOf.SignalAction_Letter); obj.signalTag = signalTag; obj.letter = LetterMaker.MakeLetter("LetterLabelAncientShrineWarning".Translate(), "AncientShrineWarning".Translate(), LetterDefOf.ThreatBig, new TargetInfo(cellRect.CenterCell, map)); GenSpawn.Spawn(obj, cellRect.CenterCell, map); RectTrigger obj2 = (RectTrigger)ThingMaker.MakeThing(ThingDefOf.RectTrigger); obj2.signalTag = signalTag; obj2.Rect = cellRect.ExpandedBy(1).ClipInsideMap(map); obj2.destroyIfUnfogged = true; GenSpawn.Spawn(obj2, cellRect.CenterCell, map); } }