public override void Resolve(ResolveParams rp) { Map map = BaseGen.globalSettings.map; TerrainGrid terrainGrid = map.terrainGrid; TerrainDef terrainDef = rp.floorDef ?? BaseGenUtility.RandomBasicFloorDef(rp.faction, false); bool? floorOnlyIfTerrainSupports = rp.floorOnlyIfTerrainSupports; bool flag = floorOnlyIfTerrainSupports.HasValue && floorOnlyIfTerrainSupports.Value; CellRect.CellRectIterator iterator = rp.rect.GetIterator(); while (!iterator.Done()) { if (!rp.chanceToSkipFloor.HasValue || !Rand.Chance(rp.chanceToSkipFloor.Value)) { if (!flag || GenConstruct.CanBuildOnTerrain(terrainDef, iterator.Current, map, Rot4.North, null)) { terrainGrid.SetTerrain(iterator.Current, terrainDef); if (rp.filthDef != null) { FilthMaker.MakeFilth(iterator.Current, map, rp.filthDef, (!rp.filthDensity.HasValue) ? 1 : Mathf.RoundToInt(rp.filthDensity.Value.RandomInRange)); } } } iterator.MoveNext(); } }
// Extracted and modified from GenStep_ScatterShrines: private static bool IsMapRectClear(CellRect mapRect, Map map) { foreach (IntVec3 cell in mapRect) { if (cell.InBounds(map)) { TerrainDef terrainDef = map.terrainGrid.TerrainAt(cell); if (terrainDef.HasTag("River") || terrainDef.HasTag("Road")) { return(false); } if (!GenConstruct.CanBuildOnTerrain(ThingDefOf.Wall, cell, map, Rot4.North, null, null)) { return(false); } } List <Thing> thingList = cell.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { if (thingList[i].def.category == ThingCategory.Building || thingList[i].def.category == ThingCategory.Pawn || thingList[i].def.category == ThingCategory.Ethereal) { return(false); } } } return(true); }
private void TrySpawnWall(IntVec3 c, Map map, ResolveParams rp, ThingDef wallDef, ThingDef wallStuff) { // Not in bounds if (!c.InBounds(map)) { return; } if (TryClearCell(c, map)) { // Try and make it buildable if (!GenConstruct.CanBuildOnTerrain(wallDef, c, map, Rot4.North)) { if (GenConstruct.CanBuildOnTerrain(TerrainDefOf.PavedTile, c, map, Rot4.North)) { map.terrainGrid.SetTerrain(c, TerrainDefOf.PavedTile); } else if (GenConstruct.CanBuildOnTerrain(TerrainDefOf.Bridge, c, map, Rot4.North)) { map.terrainGrid.SetTerrain(c, TerrainDefOf.Bridge); } } if (!GenConstruct.CanBuildOnTerrain(wallDef, c, map, Rot4.North) || (rp.chanceToSkipWallBlock != null && Rand.Chance(rp.chanceToSkipWallBlock.Value))) { return; } var wall = ThingMaker.MakeThing(wallDef, wallStuff); wall.SetFaction(rp.faction, null); GenSpawn.Spawn(wall, c, map, WipeMode.Vanish); } }
private void TrySpawnSandbags(IntVec3 c, Map map, Faction faction, ThingDef stuff) { if (!c.InBounds(map)) { return; } if (TryClearCell(c, map)) { // Try and make it buildable if (!GenConstruct.CanBuildOnTerrain(DefToUse, c, map, Rot4.North)) { if (GenConstruct.CanBuildOnTerrain(TerrainDefOf.PavedTile, c, map, Rot4.North)) { map.terrainGrid.SetTerrain(c, TerrainDefOf.PavedTile); } else if (GenConstruct.CanBuildOnTerrain(TerrainDefOf.Bridge, c, map, Rot4.North)) { map.terrainGrid.SetTerrain(c, TerrainDefOf.Bridge); } } if (!GenConstruct.CanBuildOnTerrain(DefToUse, c, map, Rot4.North)) { return; } var usedStuff = DefToUse.MadeFromStuff ? (stuff ?? GenStuff.DefaultStuffFor(DefToUse)) : null; Thing thing = ThingMaker.MakeThing(DefToUse, usedStuff); thing.SetFaction(faction, null); GenSpawn.Spawn(thing, c, map, WipeMode.Vanish); } }
public override bool TryExecuteWorker(IncidentParms parms) { Map map = (Map)parms.target; List <TargetInfo> list = new List <TargetInfo>(); ThingDef shipPartDef = def.mechClusterBuilding; IntVec3 intVec = FindDropPodLocation(map, (IntVec3 spot) => CanPlaceAt(spot)); if (intVec == IntVec3.Invalid) { return(false); } float points = Mathf.Max(parms.points * 0.9f, 300f); Thing thing = ThingMaker.MakeThing(shipPartDef); Building building_CrashedShipPart = (Building)thing; CompPawnSpawnerOnDamaged damaged = building_CrashedShipPart.TryGetCompFast <CompPawnSpawnerOnDamaged>(); thing.SetFaction(faction, null); List <Pawn> list2 = PawnGroupMakerUtility.GeneratePawns(new PawnGroupMakerParms { groupKind = PawnGroupKindDefOf.Combat, tile = map.Tile, faction = faction, points = points }).ToList(); LordMaker.MakeNewLord(faction, new LordJob_SleepThenMechanoidsDefend(new List <Thing> { thing }, faction, 28f, intVec, canAssaultColony: false, isMechCluster: false), map, list2); DropPodUtility.DropThingsNear(intVec, map, list2.Cast <Thing>()); foreach (Pawn item in list2) { item.TryGetCompFast <CompCanBeDormant>()?.ToSleep(); } list.AddRange(list2.Select((Pawn p) => new TargetInfo(p))); GenSpawn.Spawn(SkyfallerMaker.MakeSkyfaller(ThingDefOf.CrashedShipPartIncoming, thing), intVec, map); list.Add(new TargetInfo(intVec, map)); SendStandardLetter(parms, list); return(true); bool CanPlaceAt(IntVec3 loc) { CellRect cellRect = GenAdj.OccupiedRect(loc, Rot4.North, shipPartDef.Size); if (loc.Fogged(map) || !cellRect.InBounds(map)) { return(false); } foreach (IntVec3 item2 in cellRect) { RoofDef roof = item2.GetRoof(map); if (roof != null && roof.isNatural) { return(false); } } return(GenConstruct.CanBuildOnTerrain(shipPartDef, loc, map, Rot4.North)); } }
private void TrySpawnFloor(IntVec3 c, Map map) { if (!c.InBounds(map)) { return; } if (TryClearCell(c, map)) { var floorDef = GenConstruct.CanBuildOnTerrain(TerrainDefOf.WoodPlankFloor, c, map, Rot4.North) ? TerrainDefOf.WoodPlankFloor : TerrainDefOf.Bridge; map.terrainGrid.SetTerrain(c, floorDef); } }
public static bool CanReplaceStuffFor(ThingDef stuff, Thing thing, ThingDef matchDef = null) { if (thing.Faction != Faction.OfPlayer && thing.Faction != null) //can't replace enemy things { return(false); } BuildableDef builtDef = GenConstruct.BuiltDefOf(thing.def); if (matchDef != null && builtDef != matchDef) { return(false); } if (thing is Blueprint bp) { if (bp.EntityToBuildStuff() == stuff) { return(false); } } else if (thing is Frame frame) { if (frame.EntityToBuildStuff() == stuff) { return(false); } } else if (thing.def.HasReplaceFrame()) { if (thing.Stuff == stuff) { return(false); } } else { return(false); } if (!GenConstruct.CanBuildOnTerrain(builtDef, thing.Position, thing.Map, thing.Rotation, thing, stuff)) { return(false); //TODO: place bridges under && } if (thing.BeingReplacedByNewThing() != null) { return(false); //being upgraded. } return(GenStuff.AllowedStuffsFor(builtDef).Contains(stuff)); }
/// <summary> /// Tries to execute the worker. /// </summary> /// <param name="parms">The parms.</param> /// <returns></returns> protected override bool TryExecuteWorker(IncidentParms parms) { var map = (Map)parms.target; var targetInfoList = new List <TargetInfo>(); ThingDef shipPartDef = def.mechClusterBuilding; IntVec3 dropPodLocation = MechClusterUtility.FindDropPodLocation(map, spot => { if (!spot.Fogged(map) && GenConstruct.CanBuildOnTerrain(shipPartDef, spot, map, Rot4.North)) { return(GenConstruct.CanBuildOnTerrain(shipPartDef, new IntVec3(spot.x - Mathf.CeilToInt(shipPartDef.size.x / 2f), spot.y, spot.z), map, Rot4.North)); } return(false); }); if (dropPodLocation == IntVec3.Invalid) { return(false); } float num = Mathf.Max(parms.points * 0.9f, 300f); var genParams = new PawnGroupMakerParms { groupKind = PawnGroupKindDefOf.Combat, tile = map.Tile, faction = Faction.OfMechanoids, points = num }; List <Pawn> list = PawnGroupMakerUtility.GeneratePawns(genParams) .ToList(); Thing innerThing = ThingMaker.MakeThing(shipPartDef); innerThing.SetFaction(Faction.OfMechanoids); LordMaker.MakeNewLord(Faction.OfMechanoids, new LordJob_SleepThenMechanoidsDefend(new List <Thing> { innerThing }, Faction.OfMechanoids, 28f, dropPodLocation, false, false), map, list); DropPodUtility.DropThingsNear(dropPodLocation, map, list); foreach (Thing thing in list) { thing.TryGetComp <CompCanBeDormant>()?.ToSleep(); } targetInfoList.AddRange(list.Select(p => new TargetInfo(p))); GenSpawn.Spawn(SkyfallerMaker.MakeSkyfaller(PMThingDefOf.CrashedMutagenicShipPartIncoming, innerThing), dropPodLocation, map); targetInfoList.Add(new TargetInfo(dropPodLocation, map)); SendStandardLetter(parms, targetInfoList, Array.Empty <NamedArgument>()); return(true); }
/// <summary> /// Tries to execute the worker. /// </summary> /// <param name="parms">The parms.</param> /// <returns></returns> protected override bool TryExecuteWorker(IncidentParms parms) { var map = (Map)parms.target; var list = new List <TargetInfo>(); ThingDef shipPartDef = def.mechClusterBuilding; IntVec3 intVec = FindDropPodLocation(map, CanPlaceAt); if (intVec == IntVec3.Invalid) { return(false); } float points = Mathf.Max(parms.points * 0.9f, 300f); List <Pawn> list2 = PawnGroupMakerUtility.GeneratePawns(new PawnGroupMakerParms { groupKind = PawnGroupKindDefOf.Combat, tile = map.Tile, faction = Faction.OfMechanoids, points = points }) .ToList(); Thing thing = ThingMaker.MakeThing(shipPartDef); thing.SetFaction(Faction.OfMechanoids); LordMaker.MakeNewLord(Faction.OfMechanoids, new LordJob_SleepThenMechanoidsDefend(new List <Thing> { thing }, Faction.OfMechanoids, 28f, intVec, false, false), map, list2); DropPodUtility.DropThingsNear(intVec, map, list2); foreach (Pawn item in list2) { item.TryGetComp <CompCanBeDormant>()?.ToSleep(); } list.AddRange(list2.Select(p => new TargetInfo(p))); GenSpawn.Spawn(SkyfallerMaker.MakeSkyfaller(PMThingDefOf.CrashedMutagenicShipPartIncoming, thing), intVec, map); list.Add(new TargetInfo(intVec, map)); SendStandardLetter(parms, list); return(true); bool CanPlaceAt(IntVec3 loc) { if (loc.Fogged(map) || !GenAdj.OccupiedRect(loc, Rot4.North, shipPartDef.Size).InBounds(map)) { return(false); } return(GenConstruct.CanBuildOnTerrain(shipPartDef, loc, map, Rot4.North)); } }
//public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode = false, Thing thingToIgnore = null) public static void Postfix(ref AcceptanceReport __result, BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode, Thing thingToIgnore) { if (__result.Reason != "IdenticalThingExists".Translate() && __result.Reason != "IdenticalBlueprintExists".Translate()) { return; } if (!entDef.MadeFromStuff) { return; } ThingDef newStuff = DesignatorContext.stuffDef; //It would not be so easy to transpile this part //it doesn't simply change __result to true when a replace frame can be placed, //it also checks if the replace frame is already there and overrides that with false foreach (Thing thing in center.GetThingList(map)) { if (thing.IsNewThingReplacement(out Thing oldThing)) { __result = false; return; } if (thing != thingToIgnore && thing.Position == center && (thing.Rotation == rot || PlacingRotationDoesntMatter(entDef)) && GenConstruct.BuiltDefOf(thing.def) == entDef) { ThingDef oldStuff = thing is Blueprint bp?bp.EntityToBuildStuff() : thing.Stuff; if (thing is ReplaceFrame rf && oldStuff == newStuff) { __result = false; return; } if (newStuff != oldStuff && GenConstruct.CanBuildOnTerrain(entDef, center, map, rot, thing, newStuff)) { __result = true; } } } }
private bool CanPlaceInRange(CellRect rect, Map map) { foreach (IntVec3 c in rect.Cells) { if (c.InBounds(map)) { TerrainDef terrainDef = map.terrainGrid.TerrainAt(c); if (terrainDef.HasTag("River")) { return(false); } if (!GenConstruct.CanBuildOnTerrain(ThingDefOf.Wall, c, map, Rot4.North, null, ThingDefOf.Granite)) { return(false); } } } return(true); }
public static void CheckSpawnBridgeUnder(ThingDef thingDef, IntVec3 c, Rot4 rot) { if (thingDef.category != ThingCategory.Building) { return; } Map map = BaseGen.globalSettings.map; CellRect cellRect = GenAdj.OccupiedRect(c, rot, thingDef.size); BaseGenUtility.bridgeCells.Clear(); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { if (!iterator.Current.SupportsStructureType(map, thingDef.terrainAffordanceNeeded) && GenConstruct.CanBuildOnTerrain(TerrainDefOf.Bridge, iterator.Current, map, Rot4.North, null)) { BaseGenUtility.bridgeCells.Add(iterator.Current); } iterator.MoveNext(); } if (!BaseGenUtility.bridgeCells.Any <IntVec3>()) { return; } if (thingDef.size.x != 1 || thingDef.size.z != 1) { for (int i = BaseGenUtility.bridgeCells.Count - 1; i >= 0; i--) { for (int j = 0; j < 8; j++) { IntVec3 intVec = BaseGenUtility.bridgeCells[i] + GenAdj.AdjacentCells[j]; if (!BaseGenUtility.bridgeCells.Contains(intVec) && intVec.InBounds(map) && !intVec.SupportsStructureType(map, thingDef.terrainAffordanceNeeded) && GenConstruct.CanBuildOnTerrain(TerrainDefOf.Bridge, intVec, map, Rot4.North, null)) { BaseGenUtility.bridgeCells.Add(intVec); } } } } for (int k = 0; k < BaseGenUtility.bridgeCells.Count; k++) { map.terrainGrid.SetTerrain(BaseGenUtility.bridgeCells[k], TerrainDefOf.Bridge); } }
public static void CheckSpawnBridgeUnder(ThingDef thingDef, IntVec3 c, Rot4 rot) { if (thingDef.category != ThingCategory.Building) { return; } Map map = BaseGen.globalSettings.map; CellRect cellRect = GenAdj.OccupiedRect(c, rot, thingDef.size); bridgeCells.Clear(); foreach (IntVec3 item in cellRect) { if (!item.SupportsStructureType(map, thingDef.terrainAffordanceNeeded) && GenConstruct.CanBuildOnTerrain(TerrainDefOf.Bridge, item, map, Rot4.North)) { bridgeCells.Add(item); } } if (!bridgeCells.Any()) { return; } if (thingDef.size.x != 1 || thingDef.size.z != 1) { for (int num = bridgeCells.Count - 1; num >= 0; num--) { for (int i = 0; i < 8; i++) { IntVec3 intVec = bridgeCells[num] + GenAdj.AdjacentCells[i]; if (!bridgeCells.Contains(intVec) && intVec.InBounds(map) && !intVec.SupportsStructureType(map, thingDef.terrainAffordanceNeeded) && GenConstruct.CanBuildOnTerrain(TerrainDefOf.Bridge, intVec, map, Rot4.North)) { bridgeCells.Add(intVec); } } } } for (int j = 0; j < bridgeCells.Count; j++) { map.terrainGrid.SetTerrain(bridgeCells[j], TerrainDefOf.Bridge); } }
public override void Resolve(ResolveParams rp) { Map map = BaseGen.globalSettings.map; TerrainGrid terrainGrid = map.terrainGrid; TerrainDef terrainDef = rp.floorDef ?? BaseGenUtility.RandomBasicFloorDef(rp.faction); bool flag = rp.floorOnlyIfTerrainSupports ?? false; bool flag2 = rp.allowBridgeOnAnyImpassableTerrain ?? false; foreach (IntVec3 item in rp.rect) { if ((!rp.chanceToSkipFloor.HasValue || !Rand.Chance(rp.chanceToSkipFloor.Value)) && (!flag || GenConstruct.CanBuildOnTerrain(terrainDef, item, map, Rot4.North) || (flag2 && item.GetTerrain(map).passability == Traversability.Impassable))) { terrainGrid.SetTerrain(item, terrainDef); if (rp.filthDef != null) { FilthMaker.TryMakeFilth(item, map, rp.filthDef, (!rp.filthDensity.HasValue) ? 1 : Mathf.RoundToInt(rp.filthDensity.Value.RandomInRange)); } } } }
public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, ThingDef stuff, bool godMode = false, Thing thingToIgnore = null) { CellRect cellRect = GenAdj.OccupiedRect(center, rot, entDef.Size); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (!current.InBounds(map)) { return(new AcceptanceReport("OutOfBounds".Translate())); } if (current.InNoBuildEdgeArea(map) && !DebugSettings.godMode) { return("TooCloseToMapEdge".Translate()); } iterator.MoveNext(); } if (center.Fogged(map)) { return("CannotPlaceInUndiscovered".Translate()); } List <Thing> thingList = center.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing != thingToIgnore) { if (thing.Position == center && thing.Rotation == rot) { if (thing.def == entDef) { //Start my code, this code allows blueprint to be placed, so canPlaceOverWall can do it's thing. if (((walls.Contains(thing.def.defName) && walls.Contains(entDef.defName)) || (doors.Contains(thing.def.defName) && doors.Contains(entDef.defName))) && thing.Stuff != stuff) { return(AcceptanceReport.WasAccepted); } //End my code return(new AcceptanceReport("IdenticalThingExists".Translate())); } if (thing.def.entityDefToBuild == entDef) { if (thing is Blueprint) { return(new AcceptanceReport("IdenticalBlueprintExists".Translate())); } return(new AcceptanceReport("IdenticalThingExists".Translate())); } } } } ThingDef thingDef = entDef as ThingDef; if (thingDef != null && thingDef.hasInteractionCell) { IntVec3 c = ThingUtility.InteractionCellWhenAt(thingDef, center, rot, map); if (!c.InBounds(map)) { return(new AcceptanceReport("InteractionSpotOutOfBounds".Translate())); } List <Thing> list = map.thingGrid.ThingsListAtFast(c); for (int j = 0; j < list.Count; j++) { if (list[j] != thingToIgnore) { if (list[j].def.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotBlocked".Translate(new object[] { list[j].LabelNoCount }).CapitalizeFirst())); } Blueprint blueprint = list[j] as Blueprint; if (blueprint != null && blueprint.def.entityDefToBuild.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotWillBeBlocked".Translate(new object[] { blueprint.LabelNoCount }).CapitalizeFirst())); } } } } if (entDef.passability != Traversability.Standable) { foreach (IntVec3 current2 in GenAdj.CellsAdjacentCardinal(center, rot, entDef.Size)) { if (current2.InBounds(map)) { thingList = current2.GetThingList(map); for (int k = 0; k < thingList.Count; k++) { Thing thing2 = thingList[k]; if (thing2 != thingToIgnore) { Blueprint blueprint2 = thing2 as Blueprint; ThingDef thingDef3; if (blueprint2 != null) { ThingDef thingDef2 = blueprint2.def.entityDefToBuild as ThingDef; if (thingDef2 == null) { goto IL_37E; } thingDef3 = thingDef2; } else { thingDef3 = thing2.def; } if (thingDef3.hasInteractionCell && cellRect.Contains(ThingUtility.InteractionCellWhenAt(thingDef3, thing2.Position, thing2.Rotation, thing2.Map))) { return(new AcceptanceReport("WouldBlockInteractionSpot".Translate(new object[] { entDef.label, thingDef3.label }).CapitalizeFirst())); } } IL_37E :; } } } } TerrainDef terrainDef = entDef as TerrainDef; if (terrainDef != null) { if (map.terrainGrid.TerrainAt(center) == terrainDef) { return(new AcceptanceReport("TerrainIsAlready".Translate(new object[] { terrainDef.label }))); } if (map.designationManager.DesignationAt(center, DesignationDefOf.SmoothFloor) != null) { return(new AcceptanceReport("BeingSmoothed".Translate())); } } if (!GenConstruct.CanBuildOnTerrain(entDef, center, map, rot, thingToIgnore)) { return(new AcceptanceReport("TerrainCannotSupport".Translate())); } if (!godMode) { CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { thingList = iterator2.Current.GetThingList(map); for (int l = 0; l < thingList.Count; l++) { Thing thing3 = thingList[l]; if (thing3 != thingToIgnore) { if (!GenConstruct.CanPlaceBlueprintOver(entDef, thing3.def)) { //Start my code, entDef is new, thing3 is old //Allows for doors to replace each other only if different stuff or door <--> autodoor if (thing3?.def?.defName != null) { if ((doors.Contains(entDef.defName) && doors.Contains(thing3.def.defName)) && //New and old are both doors (thing3.Stuff != stuff || !entDef.defName.Equals(thing3.def.defName))) //Not the same stuff or not same thing { return(AcceptanceReport.WasAccepted); } //Allow placing over mineable if (thing3 is Mineable && (doors.Contains(entDef.defName) || walls.Contains(entDef.defName))) { return(AcceptanceReport.WasAccepted); } //Allow walls and doors to be placed over walls if ((walls.Contains(entDef.defName) || doors.Contains(entDef.defName)) && walls.Contains(thing3.def.defName)) { return(AcceptanceReport.WasAccepted); } //Allow replacing invisible power lines from PowerSwitch by Haplo if (conduits.Contains(entDef.defName) && conduits.Contains(thing3.def.defName)) { return(AcceptanceReport.WasAccepted); } } //End my code return(new AcceptanceReport("SpaceAlreadyOccupied".Translate())); } } } iterator2.MoveNext(); } } if (entDef.PlaceWorkers != null) { for (int m = 0; m < entDef.PlaceWorkers.Count; m++) { AcceptanceReport result = entDef.PlaceWorkers[m].AllowsPlacing(entDef, center, rot, map, thingToIgnore); if (!result.Accepted) { return(result); } } } return(AcceptanceReport.WasAccepted); }
public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode = false, Thing thingToIgnore = null) { CellRect cellRect = GenAdj.OccupiedRect(center, rot, entDef.Size); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { IntVec3 current = iterator.Current; if (!current.InBounds(map)) { return(new AcceptanceReport("OutOfBounds".Translate())); } if (current.InNoBuildEdgeArea(map) && !DebugSettings.godMode && entDef != ThingDefOf.DeepDrill) { return("TooCloseToMapEdge".Translate()); } iterator.MoveNext(); } if (center.Fogged(map)) { return("CannotPlaceInUndiscovered".Translate()); } List <Thing> thingList = center.GetThingList(map); for (int i = 0; i < thingList.Count; i++) { Thing thing = thingList[i]; if (thing != thingToIgnore) { if (thing.Position == center && thing.Rotation == rot) { if (thing.def == entDef) { return(new AcceptanceReport("IdenticalThingExists".Translate())); } if (thing.def.entityDefToBuild == entDef) { if (thing is Blueprint) { return(new AcceptanceReport("IdenticalBlueprintExists".Translate())); } return(new AcceptanceReport("IdenticalThingExists".Translate())); } } } } ThingDef thingDef = entDef as ThingDef; if (thingDef != null && thingDef.hasInteractionCell) { IntVec3 c = Thing.InteractionCellWhenAt(thingDef, center, rot, map); if (!c.InBounds(map)) { return(new AcceptanceReport("InteractionSpotOutOfBounds".Translate())); } List <Thing> list = map.thingGrid.ThingsListAtFast(c); for (int j = 0; j < list.Count; j++) { if (list[j] != thingToIgnore) { if (list[j].def.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotBlocked".Translate(list[j].LabelNoCount).CapitalizeFirst())); } Blueprint blueprint = list[j] as Blueprint; if (blueprint != null && blueprint.def.entityDefToBuild.passability == Traversability.Impassable) { return(new AcceptanceReport("InteractionSpotWillBeBlocked".Translate(blueprint.LabelNoCount).CapitalizeFirst())); } } } } if (entDef.passability != Traversability.Standable) { foreach (IntVec3 current2 in GenAdj.CellsAdjacentCardinal(center, rot, entDef.Size)) { if (current2.InBounds(map)) { thingList = current2.GetThingList(map); for (int k = 0; k < thingList.Count; k++) { Thing thing2 = thingList[k]; if (thing2 != thingToIgnore) { Blueprint blueprint2 = thing2 as Blueprint; ThingDef thingDef3; if (blueprint2 != null) { ThingDef thingDef2 = blueprint2.def.entityDefToBuild as ThingDef; if (thingDef2 == null) { goto IL_37E; } thingDef3 = thingDef2; } else { thingDef3 = thing2.def; } if (thingDef3.hasInteractionCell && cellRect.Contains(Thing.InteractionCellWhenAt(thingDef3, thing2.Position, thing2.Rotation, thing2.Map))) { return(new AcceptanceReport("WouldBlockInteractionSpot".Translate(entDef.label, thingDef3.label).CapitalizeFirst())); } } IL_37E :; } } } } TerrainDef terrainDef = entDef as TerrainDef; if (terrainDef != null) { if (map.terrainGrid.TerrainAt(center) == terrainDef) { return(new AcceptanceReport("TerrainIsAlready".Translate(terrainDef.label))); } if (map.designationManager.DesignationAt(center, DesignationDefOf.SmoothFloor) != null) { return(new AcceptanceReport("BeingSmoothed".Translate())); } } if (!GenConstruct.CanBuildOnTerrain(entDef, center, map, rot, thingToIgnore)) { return(new AcceptanceReport("TerrainCannotSupport".Translate())); } if (!godMode) { CellRect.CellRectIterator iterator2 = cellRect.GetIterator(); while (!iterator2.Done()) { thingList = iterator2.Current.GetThingList(map); for (int l = 0; l < thingList.Count; l++) { Thing thing3 = thingList[l]; if (thing3 != thingToIgnore) { if (!GenConstruct.CanPlaceBlueprintOver(entDef, thing3.def)) { return(new AcceptanceReport("SpaceAlreadyOccupied".Translate())); } } } iterator2.MoveNext(); } } if (entDef.PlaceWorkers != null) { for (int m = 0; m < entDef.PlaceWorkers.Count; m++) { AcceptanceReport result = entDef.PlaceWorkers[m].AllowsPlacing(entDef, center, rot, thingToIgnore); if (!result.Accepted) { return(result); } } } return(AcceptanceReport.WasAccepted); }
public static IntVec3 FindNoWipeSpawnLocNear(IntVec3 near, Map map, ThingDef thingToSpawn, Rot4 rot, int maxDist = 2, Predicate <IntVec3> extraValidator = null) { int num = GenRadial.NumCellsInRadius((float)maxDist); IntVec3 intVec = IntVec3.Invalid; float num2 = 0f; for (int i = 0; i < num; i++) { IntVec3 intVec2 = near + GenRadial.RadialPattern[i]; if (intVec2.InBounds(map)) { CellRect cellRect = GenAdj.OccupiedRect(intVec2, rot, thingToSpawn.size); if (cellRect.InBounds(map)) { if (GenSight.LineOfSight(near, intVec2, map, true, null, 0, 0)) { if (extraValidator == null || extraValidator(intVec2)) { if (thingToSpawn.category != ThingCategory.Building || GenConstruct.CanBuildOnTerrain(thingToSpawn, intVec2, map, rot, null)) { bool flag = false; bool flag2 = false; CellFinder.tmpUniqueWipedThings.Clear(); CellRect.CellRectIterator iterator = cellRect.GetIterator(); while (!iterator.Done()) { if (iterator.Current.Impassable(map)) { flag2 = true; } List <Thing> thingList = iterator.Current.GetThingList(map); for (int j = 0; j < thingList.Count; j++) { if (thingList[j] is Pawn) { flag = true; } else if (GenSpawn.SpawningWipes(thingToSpawn, thingList[j].def) && !CellFinder.tmpUniqueWipedThings.Contains(thingList[j])) { CellFinder.tmpUniqueWipedThings.Add(thingList[j]); } } iterator.MoveNext(); } if (flag && thingToSpawn.passability == Traversability.Impassable) { CellFinder.tmpUniqueWipedThings.Clear(); } else if (flag2 && thingToSpawn.category == ThingCategory.Item) { CellFinder.tmpUniqueWipedThings.Clear(); } else { float num3 = 0f; for (int k = 0; k < CellFinder.tmpUniqueWipedThings.Count; k++) { if (CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Building && !CellFinder.tmpUniqueWipedThings[k].def.costList.NullOrEmpty <ThingDefCountClass>() && CellFinder.tmpUniqueWipedThings[k].def.costStuffCount == 0) { List <ThingDefCountClass> list = CellFinder.tmpUniqueWipedThings[k].CostListAdjusted(); for (int l = 0; l < list.Count; l++) { num3 += list[l].thingDef.GetStatValueAbstract(StatDefOf.MarketValue, null) * (float)list[l].count * (float)CellFinder.tmpUniqueWipedThings[k].stackCount; } } else { num3 += CellFinder.tmpUniqueWipedThings[k].MarketValue * (float)CellFinder.tmpUniqueWipedThings[k].stackCount; } if (CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Building || CellFinder.tmpUniqueWipedThings[k].def.category == ThingCategory.Item) { num3 = Mathf.Max(num3, 0.001f); } } CellFinder.tmpUniqueWipedThings.Clear(); if (!intVec.IsValid || num3 < num2) { if (num3 == 0f) { return(intVec2); } intVec = intVec2; num2 = num3; } } } } } } } } return((!intVec.IsValid) ? near : intVec); }
private void DoTerrainChangedEffects(IntVec3 c) { this.map.mapDrawer.MapMeshDirty(c, MapMeshFlag.Terrain, true, false); List <Thing> thingList = c.GetThingList(this.map); for (int index = thingList.Count - 1; index >= 0; --index) { if (thingList[index].def.category == ThingCategory.Plant && (double)this.map.fertilityGrid.FertilityAt(c) < (double)thingList[index].def.plant.fertilityMin) { thingList[index].Destroy(DestroyMode.Vanish); } else if (thingList[index].def.category == ThingCategory.Filth && !this.TerrainAt(c).acceptFilth) { thingList[index].Destroy(DestroyMode.Vanish); } else if ((thingList[index].def.IsBlueprint || thingList[index].def.IsFrame) && !GenConstruct.CanBuildOnTerrain(thingList[index].def.entityDefToBuild, thingList[index].Position, this.map, thingList[index].Rotation, (Thing)null)) { thingList[index].Destroy(DestroyMode.Cancel); } } this.map.pathGrid.RecalculatePerceivedPathCostAt(c); Region rebuildInvalidAllowed = this.map.regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(c); if (rebuildInvalidAllowed == null || rebuildInvalidAllowed.Room == null) { return; } rebuildInvalidAllowed.Room.Notify_TerrainChanged(); }
//public static AcceptanceReport CanPlaceBlueprintAt(BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode = false, Thing thingToIgnore = null) public static void Postfix(ref AcceptanceReport __result, BuildableDef entDef, IntVec3 center, Rot4 rot, Map map, bool godMode, Thing thingToIgnore) { if (__result.Reason != "IdenticalThingExists".Translate() && __result.Reason != "IdenticalBlueprintExists".Translate()) { return; } if (!(entDef is ThingDef)) { return; } if (!entDef.MadeFromStuff) { return; } ThingDef newStuff = DesignatorContext.stuffDef; //It would not be so easy to transpile this part //it doesn't simply change __result to true when a replace frame can be placed, //it also checks if the replace frame is already there and overrides that with false bool makeItTrue = false; foreach (Thing thing in center.GetThingList(map)) { if (thing == thingToIgnore) { continue; } if (thing.Position == center && (thing.Rotation == rot || PlacingRotationDoesntMatter(entDef)) && GenConstruct.BuiltDefOf(thing.def) == entDef) { //Same thing or Building the same thing ThingDef oldStuff = thing is Blueprint bp?bp.EntityToBuildStuff() : thing.Stuff; if (thing is ReplaceFrame rf && oldStuff == newStuff) { //Identical things already exists return; } if (newStuff != oldStuff) { if (GenConstruct.CanBuildOnTerrain(entDef, center, map, rot, thing, newStuff)) { makeItTrue = true; } else { __result = "TerrainCannotSupport_TerrainAffordanceFromStuff".Translate(entDef, entDef.GetTerrainAffordanceNeed(newStuff), newStuff).CapitalizeFirst(); } } } else if ((thing is Blueprint || thing is Frame) && thing.def.entityDefToBuild is ThingDef) { //Upgrade blueprint/frame exists __result = "TD.ReplacementAlreadyInProgess".Translate(); return; } } if (makeItTrue) //Only if We found a replaceable, identical thing, and no other blueprints/frames for other defs { __result = true; } }
public static IntVec3 FindNoWipeSpawnLocNear(IntVec3 near, Map map, ThingDef thingToSpawn, Rot4 rot, int maxDist = 2, Predicate <IntVec3> extraValidator = null) { int num = GenRadial.NumCellsInRadius(maxDist); IntVec3 result = IntVec3.Invalid; float num2 = 0f; for (int i = 0; i < num; i++) { IntVec3 intVec = near + GenRadial.RadialPattern[i]; if (!intVec.InBounds(map)) { continue; } CellRect cellRect = GenAdj.OccupiedRect(intVec, rot, thingToSpawn.size); if (!cellRect.InBounds(map) || !GenSight.LineOfSight(near, intVec, map, skipFirstCell: true) || (extraValidator != null && !extraValidator(intVec)) || (thingToSpawn.category == ThingCategory.Building && !GenConstruct.CanBuildOnTerrain(thingToSpawn, intVec, map, rot))) { continue; } bool flag = false; bool flag2 = false; tmpUniqueWipedThings.Clear(); foreach (IntVec3 item in cellRect) { if (item.Impassable(map)) { flag2 = true; } List <Thing> thingList = item.GetThingList(map); for (int j = 0; j < thingList.Count; j++) { if (thingList[j] is Pawn) { flag = true; } else if (GenSpawn.SpawningWipes(thingToSpawn, thingList[j].def) && !tmpUniqueWipedThings.Contains(thingList[j])) { tmpUniqueWipedThings.Add(thingList[j]); } } } if (flag && thingToSpawn.passability == Traversability.Impassable) { tmpUniqueWipedThings.Clear(); continue; } if (flag2 && thingToSpawn.category == ThingCategory.Item) { tmpUniqueWipedThings.Clear(); continue; } float num3 = 0f; for (int k = 0; k < tmpUniqueWipedThings.Count; k++) { if (tmpUniqueWipedThings[k].def.category == ThingCategory.Building && !tmpUniqueWipedThings[k].def.costList.NullOrEmpty() && tmpUniqueWipedThings[k].def.costStuffCount == 0) { List <ThingDefCountClass> list = tmpUniqueWipedThings[k].CostListAdjusted(); for (int l = 0; l < list.Count; l++) { num3 += list[l].thingDef.GetStatValueAbstract(StatDefOf.MarketValue) * (float)list[l].count * (float)tmpUniqueWipedThings[k].stackCount; } } else { num3 += tmpUniqueWipedThings[k].MarketValue * (float)tmpUniqueWipedThings[k].stackCount; } if (tmpUniqueWipedThings[k].def.category == ThingCategory.Building || tmpUniqueWipedThings[k].def.category == ThingCategory.Item) { num3 = Mathf.Max(num3, 0.001f); } } tmpUniqueWipedThings.Clear(); if (!result.IsValid || num3 < num2) { if (num3 == 0f) { return(intVec); } result = intVec; num2 = num3; } } if (!result.IsValid) { return(near); } return(result); }
private void DoTerrainChangedEffects(IntVec3 c) { map.mapDrawer.MapMeshDirty(c, MapMeshFlag.Terrain, regenAdjacentCells: true, regenAdjacentSections: false); List <Thing> thingList = c.GetThingList(map); for (int num = thingList.Count - 1; num >= 0; num--) { if (thingList[num].def.category == ThingCategory.Plant && map.fertilityGrid.FertilityAt(c) < thingList[num].def.plant.fertilityMin) { thingList[num].Destroy(); } else if (thingList[num].def.category == ThingCategory.Filth && !FilthMaker.TerrainAcceptsFilth(TerrainAt(c), thingList[num].def)) { thingList[num].Destroy(); } else if ((thingList[num].def.IsBlueprint || thingList[num].def.IsFrame) && !GenConstruct.CanBuildOnTerrain(thingList[num].def.entityDefToBuild, thingList[num].Position, map, thingList[num].Rotation, null, ((IConstructible)thingList[num]).EntityToBuildStuff())) { thingList[num].Destroy(DestroyMode.Cancel); } } map.pathGrid.RecalculatePerceivedPathCostAt(c); if (drawerInt != null) { drawerInt.SetDirty(); } map.fertilityGrid.Drawer.SetDirty(); Region regionAt_NoRebuild_InvalidAllowed = map.regionGrid.GetRegionAt_NoRebuild_InvalidAllowed(c); if (regionAt_NoRebuild_InvalidAllowed != null && regionAt_NoRebuild_InvalidAllowed.Room != null) { regionAt_NoRebuild_InvalidAllowed.Room.Notify_TerrainChanged(); } }