public static void PlaceWaitingBuildings() { GenConstruct_CanPlaceBlueprintAt_Patch.Mode = BlueprintMode.Place; foreach (RemoveRoofModel model in _removeRoofModels) { foreach (Thing thing in model.WaitingThings.ToList()) { if (thing.DestroyedOrNull() || thing.MapHeld != model.Map) { model.WaitingThings.Remove(thing); continue; } IntVec3 deltaCell = GetDeltaCell(thing, model.MousePos, model.GhostPosition); Thing inner = thing.GetInnerIfMinified(); if (GenConstruct.CanPlaceBlueprintAt(inner.def, deltaCell, inner.Rotate(model.Rotation), inner.MapHeld, thing: inner).Accepted) { if (thing is MinifiedThing minifiedThing) { GenConstruct.PlaceBlueprintForInstall(minifiedThing, deltaCell, minifiedThing.MapHeld, inner.Rotate(model.Rotation), Faction.OfPlayer); } else { GenConstruct.PlaceBlueprintForReinstall(thing as Building, deltaCell, thing.MapHeld, thing.Rotate(model.Rotation), Faction.OfPlayer); } model.WaitingThings.Remove(thing); } } } }
private AcceptanceReport CanReinstallAllThings(IntVec3 mousePos) { AcceptanceReport result = AcceptanceReport.WasAccepted; GenConstruct_CanPlaceBlueprintAt_Patch.Mode = BlueprintMode.Check; this.TraverseDesignateThings( mousePos , (drawCell, thing) => { AcceptanceReport report = GenConstruct.CanPlaceBlueprintAt( thing.def , drawCell , GetRotation(thing) , thing.MapHeld , false , null , thing); if (!report.Accepted) { result = report; return(true); } return(false); }); return(result); }
public void ScheduleReplacement(CompAutoReplaceable replaceableComp) { var building = replaceableComp.parent; if (building?.def == null) { return; } if ((building.Stuff == null && building.def.MadeFromStuff) || (building.Stuff != null && !building.def.MadeFromStuff)) { RemoteTechController.Instance.Logger.Warning("Could not schedule {0} auto-replacement due to Stuff discrepancy.", building); return; } var report = GenConstruct.CanPlaceBlueprintAt(building.def, replaceableComp.ParentPosition, replaceableComp.ParentRotation, map); if (!report.Accepted) { RemoteTechController.Instance.Logger.Message($"Could not auto-replace {building.LabelCap}: {report.Reason}"); return; } var blueprint = GenConstruct.PlaceBlueprintForBuild(building.def, replaceableComp.ParentPosition, map, replaceableComp.ParentRotation, Faction.OfPlayer, building.Stuff); var entry = new ReplacementEntry { position = replaceableComp.ParentPosition, unforbidTick = Find.TickManager.TicksGame + RemoteTechController.Instance.BlueprintForbidDuration * GenTicks.TicksPerRealSecond, savedVars = new Dictionary <string, string>() }; InvokeExposableCallbacks(building, entry.savedVars, LoadSaveMode.Saving); pendingSettings.Add(entry); if (RemoteTechController.Instance.BlueprintForbidDuration > 0) { blueprint.SetForbidden(true, false); pendingForbiddenBlueprints.Add(entry); } }
protected override bool TryExecuteWorker(IncidentParms parms) { bool result = false; List <IntVec3> targets = new List <IntVec3>(); int numOffset = Mathf.Min((int)(((Map)parms.target).wealthWatcher.WealthTotal / 100000), 7); int num = Rand.Range(1, 1 + numOffset); for (int i = 0; i < num; i++) { if (this.TryFindRandomPowerConduitInMap((Map)parms.target, out Building tempConduit)) { IntVec3 intVec = new IntVec3(tempConduit.Position.x, tempConduit.Position.y, tempConduit.Position.z); Rot4 rot = new Rot4(tempConduit.Rotation.AsByte); targets.Add(intVec); tempConduit.Destroy(DestroyMode.Deconstruct); if (Find.PlaySettings.autoRebuild && tempConduit.def.blueprintDef != null && tempConduit.def.IsResearchFinished && ((Map)parms.target).areaManager.Home[tempConduit.Position]) { if (GenConstruct.CanPlaceBlueprintAt(tempConduit.def, intVec, rot, (Map)parms.target, false, null).Accepted) { GenConstruct.PlaceBlueprintForBuild(tempConduit.def, intVec, (Map)parms.target, rot, Faction.OfPlayer, tempConduit.Stuff); } } } } if (!targets.NullOrEmpty()) { result = true; LookTargets letterTargets = new LookTargets(this.GetLetterTargets(targets, (Map)parms.target)); Find.LetterStack.ReceiveLetter(this.def.letterLabel, this.def.letterText, this.def.letterDef, letterTargets); } return(result); }
public void AttemptToPlace(ThingDef thingDef, CellRect rect, Rot4 rotation, Faction faction) { Map map = BaseGen.globalSettings.map; Thing thing; IntVec3 loc = (from cell in rect.Cells.InRandomOrder(null) where GenConstruct.CanPlaceBlueprintAt(thingDef, cell, rotation, map, false, null).Accepted&& GenAdj.OccupiedRect(cell, rotation, thingDef.Size).AdjacentCellsCardinal.Any(delegate(IntVec3 edgeCell) { bool result; if (edgeCell.InBounds(map)) { result = edgeCell.GetThingList(map).Any((Thing thing) => thing.def == ThingDefOf.Ship_Beam); } else { result = false; } return(result); }) select cell).FirstOrFallback(IntVec3.Invalid); if (loc.IsValid) { thing = ThingMaker.MakeThing(thingDef, null); thing.SetFaction(faction, null); CompHibernatable compHibernatable = thing.TryGetComp <CompHibernatable>(); if (compHibernatable != null) { compHibernatable.State = HibernatableStateDefOf.Hibernating; } GenSpawn.Spawn(thing, loc, BaseGen.globalSettings.map, rotation, WipeMode.Vanish, false); } }
private AcceptanceReport CanReinstall(Thing thing, IntVec3 drawCell) { GenConstruct_CanPlaceBlueprintAt_Patch.Mode = BlueprintMode.Check; AcceptanceReport report = GenConstruct.CanPlaceBlueprintAt(thing.def, drawCell, GetRotation(thing), thing.MapHeld, false, null, thing); return(report); }
private void CheckAutoRebuild(Map map) { if (this.autoRearm && this.CanSetAutoRearm && map != null && GenConstruct.CanPlaceBlueprintAt(this.def, base.Position, base.Rotation, map, false, null, null, base.Stuff).Accepted) { GenConstruct.PlaceBlueprintForBuild(this.def, base.Position, map, base.Rotation, Faction.OfPlayer, base.Stuff); } }
//private void UnfogWorker(IntVec3 c) public static void Postfix(FogGrid __instance, IntVec3 c, Map ___map) { Map map = ___map; if (c.GetThingList(map).FirstOrDefault(t => t.def.IsBlueprint) is Thing blueprint && !blueprint.IsUnderFog()) { if (!GenConstruct.CanPlaceBlueprintAt(blueprint.def.entityDefToBuild, blueprint.Position, blueprint.Rotation, map, false, blueprint).Accepted) { blueprint.Destroy(); } else { blueprint.Notify_ColorChanged(); //does the job, haha. } } }
internal bool <> m__0(IntVec3 cell) { return(GenConstruct.CanPlaceBlueprintAt(this.thingDef, cell, this.rotation, this.map, false, null).Accepted&& GenAdj.OccupiedRect(cell, this.rotation, this.thingDef.Size).AdjacentCellsCardinal.Any(delegate(IntVec3 edgeCell) { bool result; if (edgeCell.InBounds(this.map)) { result = edgeCell.GetThingList(this.map).Any((Thing thing) => thing.def == ThingDefOf.Ship_Beam); } else { result = false; } return result; })); }
public ConstructionStatus TargetConstructionStatus(Map map) { if (BuildableDef == null || target == null || target.HasThing || !target.IsValid) { return(ConstructionStatus.Invalid); } if (target.Cell.GetTerrain(map) == blueprintTerrainDef) { return(ConstructionStatus.Complete); } foreach (Thing thing in target.Cell.GetThingList(map)) { Blueprint_Build blueprintBuild = thing as Blueprint_Build; Frame frame = thing as Frame; if (blueprintBuild != null && blueprintBuild.stuffToUse == blueprintStuff && thing.def.entityDefToBuild == BuildableDef) { return(ConstructionStatus.InProgress); } if (frame != null && thing.Stuff == blueprintStuff && thing.def.entityDefToBuild == BuildableDef) { return(ConstructionStatus.InProgress); } if (thing.Stuff == blueprintStuff && thing.def == blueprintThingDef && blueprintBuild == null && frame == null) { return(ConstructionStatus.Complete); } } if (blueprintTerrainDef != null && !GenConstruct.CanPlaceBlueprintAt(blueprintTerrainDef, target.Cell, blueprintRotation, map, false, null, null, blueprintStuff).Accepted) { return(ConstructionStatus.Blocked); } if (blueprintThingDef != null && !GenConstruct.CanPlaceBlueprintAt(blueprintThingDef, target.Cell, blueprintRotation, map, false, null, null, blueprintStuff).Accepted) { return(ConstructionStatus.Blocked); } return(ConstructionStatus.None); }
public static bool CanPlaceBlueprintAt(IntVec3 spot, ThingDef def, Rot4 rot = default(Rot4)) { if (!spot.IsValid) { return(false); } // Cheaty cheaty bool isEdifice = def.IsEdifice(); def.building.isEdifice = true; bool result = GenConstruct.CanPlaceBlueprintAt(def, spot, rot, info.map, false, null).Accepted; def.building.isEdifice = isEdifice; return(result); }
public void AttemptToPlace(ThingDef thingDef, CellRect rect, Rot4 rotation, Faction faction) { Map map = BaseGen.globalSettings.map; IntVec3 loc = (from cell in rect.Cells.InRandomOrder() where GenConstruct.CanPlaceBlueprintAt(thingDef, cell, rotation, map).Accepted&& GenAdj.OccupiedRect(cell, rotation, thingDef.Size).AdjacentCellsCardinal.Any((IntVec3 edgeCell) => edgeCell.InBounds(map) && edgeCell.GetThingList(map).Any((Thing thing) => thing.def == ThingDefOf.Ship_Beam)) select cell).FirstOrFallback(IntVec3.Invalid); if (loc.IsValid) { Thing thing2 = ThingMaker.MakeThing(thingDef); thing2.SetFaction(faction); CompHibernatable compHibernatable = thing2.TryGetComp <CompHibernatable>(); if (compHibernatable != null) { compHibernatable.State = HibernatableStateDefOf.Hibernating; } GenSpawn.Spawn(thing2, loc, BaseGen.globalSettings.map, rotation); } }
public static bool PlaceThing(this Thing wanted, Pawn pawn, IEnumerable <IntVec3> roomCells, Rot4 rot, Room room, out Job furnitureJobResult) { rot = wanted.def.rotatable ? rot: Rot4.North; foreach (var vec3 in roomCells.InRandomOrder()) { if (!GenConstruct.CanPlaceBlueprintAt(wanted.GetInnerIfMinified().def, vec3, rot, room.Map) .Accepted) { #if DEBUG Log.Message("Not Place-able"); #endif continue; } var bp = wanted.BlueprintInstall(pawn, vec3, room, rot); if (bp == null) { #if DEBUG Log.Message("Couldn't place blueprint, oops"); #endif continue; } var job = bp.InstallJob(pawn); if (job != null) { { furnitureJobResult = job; return(true); } } #if DEBUG Log.Message("No job for bp"); #endif } furnitureJobResult = null; return(false); }
// RimWorld.SiegeBlueprintPlacer public static IntVec3 FindHideyHoleSpot(ThingDef holeDef, Rot4 rot, IntVec3 center, Map map) { if (GenConstruct.CanPlaceBlueprintAt(holeDef, center, rot, map, false, null).Accepted) { return(center); } CellRect cellRect = CellRect.CenteredOn(center, 8); cellRect.ClipInsideMap(map); IntVec3 randomCell = cellRect.RandomCell; if (!CellFinder.TryFindRandomCellNear(center, map, 5, (IntVec3 c) => c.Standable(map) && (GenConstruct.CanPlaceBlueprintAt(holeDef, c, rot, map, false, null).Accepted) && (map?.reachability?.CanReach(c, randomCell, PathEndMode.Touch, TraverseParms.For(TraverseMode.PassDoors, Danger.Deadly, false)) ?? false), out randomCell)) { Log.Error("Found no place to build hideyhole for burning vampire."); randomCell = IntVec3.Invalid; } return(randomCell); }
//A lot like CheckAutoRebuildOnDestroyed public static void CheckAutoRebuildOnLaunch(Thing thing, Map map, BuildableDef buildingDef) { if (!Settings.Get().autoRebuildTransportPod) { return; } if (Find.PlaySettings.autoRebuild && thing.Faction == Faction.OfPlayer && buildingDef.blueprintDef != null && buildingDef.IsResearchFinished && map.areaManager.Home[thing.Position] && GenConstruct.CanPlaceBlueprintAt(buildingDef, thing.Position, thing.Rotation, map, false, null).Accepted) { GenConstruct.PlaceBlueprintForBuild(buildingDef, thing.Position, map, thing.Rotation, Faction.OfPlayer, thing.Stuff); } }
public static bool PlaceThing(this Thing wanted, Pawn pawn, IEnumerable <IntVec3> roomCells, Rot4 rot, Room room, out Job furnitureJobResult) { var defToPlace = wanted.GetInnerIfMinified().def; rot = defToPlace.rotatable ? rot : Rot4.North; var roomBorder = room.BorderCells; var wallCells = roomCells.Where(cell => IsNextToBorder(cell, roomBorder)).InRandomOrder(); var innerCells = roomCells.Where(cell => !wallCells.Contains(cell)).InRandomOrder(); var firstList = true; foreach (var listOfCells in new List <IEnumerable <IntVec3> > { wallCells, innerCells }) { foreach (var vec3 in listOfCells) { var placeRot = rot; if (defToPlace.rotatable && firstList) { for (var i = 0; i < 4; i++) { if (roomCells.Contains(vec3 + GenAdj.CardinalDirections[i])) { continue; } placeRot = new Rot4(i).Opposite; #if DEBUG Log.Message($"Found cell next to a wall, will place with rotation {placeRot}"); #endif if (new Random().Next(2) == 0) { break; } } } if (defToPlace.size.Area > 1) { var cellsCovered = GenAdj.OccupiedRect(vec3, placeRot, defToPlace.Size); if (cellsCovered.Any(cell => !roomCells.Contains(cell))) { #if DEBUG Log.Message("Placed furniture would cover a non-room cell (probably the door-entrance)"); #endif continue; } } if (!GenConstruct.CanPlaceBlueprintAt(defToPlace, vec3, placeRot, room.Map).Accepted) { #if DEBUG Log.Message("Not Place-able"); #endif continue; } if (vec3.GetFirstBuilding(room.Map)?.def == defToPlace) { #if DEBUG Log.Message("Placed furniture would have replaced an item"); #endif continue; } var bp = wanted.BlueprintInstall(pawn, vec3, room, placeRot); if (bp == null) { #if DEBUG Log.Message("Couldn't place blueprint, oops"); #endif continue; } var job = bp.InstallJob(pawn); if (job == null) { continue; } furnitureJobResult = job; return(true); #if DEBUG Log.Message("No job for bp"); #endif } firstList = false; } furnitureJobResult = null; return(false); }
public static void CheckAutoRebuildTerrainOnDestroyed(TerrainDef terrainDef, IntVec3 pos, Map map) { if (Find.PlaySettings.autoRebuild && terrainDef.autoRebuildable && terrainDef.blueprintDef != null && terrainDef.IsResearchFinished && map.areaManager.Home[pos] && GenConstruct.CanPlaceBlueprintAt(terrainDef, pos, Rot4.South, map).Accepted) { GenConstruct.PlaceBlueprintForBuild(terrainDef, pos, map, Rot4.South, Faction.OfPlayer, null); } }
static Job FindBedrollJob(Job fallbackJob, Pawn pawn) { if (!pawn.IsColonistPlayerControlled) { return(fallbackJob); } Log.Message(pawn + " looking for inventory beds"); MinifiedThing invBed = (MinifiedThing)FindMinifiedBed(pawn); if (invBed == null) { return(fallbackJob); } Log.Message(pawn + " found " + invBed); Map map = pawn.Map; Building_Bed bed = (Building_Bed)invBed.GetInnerIfMinified(); Func <IntVec3, Rot4, bool> cellValidatorDir = delegate(IntVec3 c, Rot4 direction) { if (RegionAndRoomQuery.RoomAtFast(c, map).isPrisonCell != pawn.IsPrisoner) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted) { return(false); } if (c.IsForbidden(pawn)) { return(false); } for (CellRect.CellRectIterator iterator = GenAdj.OccupiedRect(c, direction, bed.def.size).GetIterator(); !iterator.Done(); iterator.MoveNext()) { foreach (Thing t in iterator.Current.GetThingList(map)) { if (!(t is Pawn) && GenConstruct.BlocksConstruction(bed, t)) { return(false); } } if (!(map.zoneManager.ZoneAt(c) is null)) { return(false); } } return(true); }; // North/East would be redundant, except for cells on edge ; oh well, too much code to handle that Predicate <IntVec3> cellValidator = c => cellValidatorDir(c, Rot4.South) || cellValidatorDir(c, Rot4.West); Predicate <IntVec3> goodCellValidator = c => !RegionAndRoomQuery.RoomAt(c, map).PsychologicallyOutdoors&& cellValidator(c); IntVec3 placePosition = IntVec3.Invalid; IntVec3 root = pawn.Position; TraverseParms trav = TraverseParms.For(pawn); if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, cellValidator, null, out placePosition)) { CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, cellValidator, null, out placePosition); } } } if (placePosition.IsValid) { Rot4 dir = cellValidatorDir(placePosition, Rot4.South) ? Rot4.South : Rot4.West; Blueprint_Install blueprint = GenConstruct.PlaceBlueprintForInstall(invBed, placePosition, map, dir, pawn.Faction); Log.Message(pawn + " placing " + blueprint + " at " + placePosition); return(new Job(JobDefOf.PlaceBedroll, invBed, blueprint) { haulMode = HaulMode.ToContainer }); } Log.Message(pawn + " couldn't find place for " + invBed); return(fallbackJob); }
protected override IEnumerable <Toil> MakeNewToils() { /* * * Toil Configurations * */ var prepareToSpin = new Toil { initAction = delegate { if (Prey == null && Corpse == null) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); return; } if (Prey != null && Prey.Dead) { pawn.CurJob.SetTarget(TargetIndex.A, Prey.Corpse); } if (!pawn.CanReserveAndReach(TargetA, PathEndMode.Touch, Danger.None)) { pawn.jobs.EndCurrentJob(JobCondition.Incompletable); } } }; var gotoBody = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); gotoBody.AddPreInitAction(delegate { pawn.ClearAllReservations(); pawn.Reserve(TargetA, job); //this.Map.physicalInteractionReservationManager.ReleaseAllForTarget(TargetA); //this.Map.physicalInteractionReservationManager.Reserve(this.GetActor(), TargetA); currentActivity = "ROM_SpinPreyJob1".Translate(TargetA.Thing?.LabelShort ?? ""); }); var spinDelay = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 500, initAction = delegate { currentActivity = "ROM_SpinPreyJob2".Translate(); } }; spinDelay.WithProgressBarToilDelay(TargetIndex.B); var spinBody = new Toil { initAction = delegate { //Log.Message("5"); if (GetActor() is not PawnWebSpinner spinner) { return; } Thing toLoad; IntVec3 newPosition; if (Prey.Dead) { toLoad = Prey.Corpse; newPosition = Prey.Corpse.Position; } else { toLoad = Prey; newPosition = Prey.Position; //Tend prey's wounds by luck if (!Prey.health.HasHediffsNeedingTend()) { return; } var unused = ThingDefOf.MedicineHerbal; var quality = 0.5f; //Not a doctor or attentive to human needs var hediffsToTend = new List <Hediff>(); var hediffs = Prey.health.hediffSet.hediffs; foreach (var hediff in hediffs) { if (hediff.TendableNow()) { hediffsToTend.Add(hediff); } } for (var i = 0; i < hediffsToTend.Count; i++) { hediffsToTend[i].Tended(quality, i); } } if (!toLoad.Spawned) { EndJobWith(JobCondition.Incompletable); return; } toLoad.DeSpawn(); toLoad.holdingOwner = null; if (!GenConstruct.CanPlaceBlueprintAt(CocoonDef, newPosition, Rot4.North, pawn.Map).Accepted) { var cells = GenAdj.CellsAdjacent8Way(new TargetInfo(newPosition, pawn.Map)); foreach (var cell in cells) { if (!GenConstruct.CanPlaceBlueprintAt(CocoonDef, cell, Rot4.North, Map).Accepted) { continue; } newPosition = cell; break; } } var newCocoon = (Building_Cocoon)GenSpawn.Spawn(CocoonDef, newPosition, spinner.Map); newCocoon.Spinner = spinner; if (spinner.Faction == Faction.OfPlayerSilentFail) { newCocoon.SetFactionDirect(Faction.OfPlayerSilentFail); } //Log.Message("New Spinner: " + newCocoon.Spinner.Label); newCocoon.TryGetInnerInteractableThingOwner().TryAdd(toLoad); pawn?.CurJob?.SetTarget(TargetIndex.B, newCocoon); },
public void TryStartUseJob(Pawn user) { Find.DesignatorManager.Deselect(); if (!user.CanReserveAndReach(this.parent, PathEndMode.Touch, Danger.Deadly, 1)) { return; } if (!user.CanReach(this.targetPos, PathEndMode.Touch, Danger.Deadly)) { return; } if (this.parent.HitPoints <= 0) { Messages.Message("Cannot place a fully damaged tent.", MessageTypeDefOf.RejectInput); return; } CellRect cellRect = new CellRect(this.targetPos.x - 2, this.targetPos.z - 2, 5, 4); List <IntVec3> everything = new List <IntVec3>(); everything.AddRange(this.wallCells); everything.AddRange(this.doorCells); foreach (IntVec3 current in everything) { if (!GenConstruct.CanPlaceBlueprintAt(ThingDefOf.Wall, current, Rot4.North, user.Map, false, null).Accepted) { Messages.Message("Tent placement blocked. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } if (current.GetFirstItem(user.Map) != null || current.GetFirstPawn(user.Map) != null || current.GetFirstHaulable(user.Map) != null) { Messages.Message("Tent placement blocked by a item, pawn or a building. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } Building building = current.GetFirstBuilding(user.Map); if (building != null) { if (building.def.IsEdifice()) { Messages.Message("Tent placement blocked by a item, pawn or a building. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } } Plant plant = current.GetPlant(user.Map); if (plant != null) { if (plant.def.plant.IsTree) { Messages.Message("Tent placement blocked by a tree. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } } } Job job = new Job(DefDatabase <JobDef> .GetNamed("DeployTent", true), this.parent, this.targetInfo1); user.jobs.TryTakeOrderedJob(job); }
private static bool TargetValidator(IntVec3 c, Map map, CompTargetable_Tent t) { if (!c.InBounds(map) || !c.Standable(map)) { return(false); } if (!c.Walkable(map)) { return(false); } t.HandleRotation(); t.GetPlacements(c); CellRect cellRect = new CellRect(c.x - 2, c.z - 2, 5, 4); List <IntVec3> clist = new List <IntVec3>(); Color color = new Color(1f, 1f, 1f, 0.4f); List <IntVec3> everything = new List <IntVec3>(); everything.AddRange(t.wallCells); everything.AddRange(t.doorCells); foreach (IntVec3 current in everything) { if (!current.InBounds(map)) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(ThingDefOf.Wall, current, Rot4.North, map, false, null).Accepted) { color = new Color(1f, 0f, 0f, 0.4f); } if (current.GetFirstItem(map) != null || current.GetFirstPawn(map) != null || current.GetFirstHaulable(map) != null) { color = new Color(1f, 0f, 0f, 0.4f); } Building building = current.GetFirstBuilding(map); if (building != null) { if (building.def.IsEdifice()) { color = new Color(1f, 0f, 0f, 0.4f); } } Plant plant = current.GetPlant(map); if (plant != null) { if (plant.def.plant.IsTree) { color = new Color(1f, 0f, 0f, 0.4f); } } } foreach (IntVec3 doorCell in t.doorCells) { GhostDrawer.DrawGhostThing(doorCell, t.placingRot, ThingDef.Named("TentDoor"), null, color, AltitudeLayer.Blueprint); } GenDraw.DrawFieldEdges(t.wallCells, color); return(true); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 500, initAction = delegate { var i = 999; var breakNow = false; while (i > 0) { pawn.CurJob.SetTarget(TargetIndex.A, RCellFinder.RandomWanderDestFor(pawn, pawn.Position, 5f, null, Danger.Some)); var cellRect = GenAdj.OccupiedRect(TargetLocA, Rot4.North, WebDef.Size); foreach (var cellRectCell in cellRect.Cells) { if (cellRectCell.Walkable(Map)) { breakNow = true; } } if (GenConstruct.CanPlaceBlueprintAt(WebDef, TargetLocA, Rot4.North, pawn.Map).Accepted) { if (pawn?.Faction == null || pawn?.Faction != Faction.OfPlayerSilentFail) { break; } if (pawn?.Faction == Faction.OfPlayerSilentFail && !TargetA.Cell.IsForbidden(pawn)) { breakNow = true; } } else { breakNow = false; } if (breakNow) { break; } i--; } } }); yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); yield return(new Toil { initAction = delegate { if (GetActor() is not PawnWebSpinner spinner || spinner.Position.CloseToEdge(spinner.Map, 2)) { return; } var web = (Building_Web)GenSpawn.Spawn(WebDef, spinner.Position, spinner.Map); spinner.Web = web; spinner.WebsMade++; web.Spinner = spinner; },
public override void Destroy(DestroyMode mode = DestroyMode.Vanish) { bool spawned = base.Spawned; Map map = base.Map; SmoothableWallUtility.Notify_BuildingDestroying(this, mode); base.Destroy(mode); InstallBlueprintUtility.CancelBlueprintsFor(this); if (mode == DestroyMode.Deconstruct && spawned) { SoundDefOf.Building_Deconstructed.PlayOneShot(new TargetInfo(base.Position, map, false)); } if (Find.PlaySettings.autoRebuild && mode == DestroyMode.KillFinalize && base.Faction == Faction.OfPlayer && spawned && this.def.blueprintDef != null && this.def.IsResearchFinished && map.areaManager.Home[base.Position] && GenConstruct.CanPlaceBlueprintAt(this.def, base.Position, base.Rotation, map, false, null).Accepted) { GenConstruct.PlaceBlueprintForBuild(this.def, base.Position, map, base.Rotation, Faction.OfPlayer, base.Stuff); } }
//protected override Job TryGiveJob(Pawn pawn) public static void Postfix(ref Job __result, Pawn pawn) { if (__result == null) { return; } if (!pawn.IsColonistPlayerControlled) { return; } Map map = pawn.Map; if (!Settings.Get().alsoColonies&& map.IsPlayerHome) { if (!Settings.Get().alsoColoniesKnown) { Settings.Get().alsoColoniesKnown = true; Settings.Get().Write(); Find.LetterStack.ReceiveLetter("TD.UseBedrollsUpdated".Translate(), TranslatorFormattedStringExtensions.Translate("TD.UpdateNewsColonyMaps", pawn), LetterDefOf.NeutralEvent, pawn); // I don't think this really needs to be hugslibs update news or anything. alsoColoniesKnown defaults } return; } if (__result.targetA.Thing is Building_Bed ownedBed) { if (!Settings.Get().distanceCheck || (ownedBed.Position).DistanceTo(pawn.Position) < Settings.Get().distance) { return; //Have a bed that close enough, no need to get from inventory } } MinifiedThing invBed = (MinifiedThing)FindMinifiedBed(pawn); if (invBed == null) { return; } Log.Message($"{pawn} found {invBed}"); Building_Bed bed = (Building_Bed)invBed.GetInnerIfMinified(); Func <IntVec3, Rot4, bool> cellValidatorDir = delegate(IntVec3 c, Rot4 direction) { if (RegionAndRoomQuery.RoomAt(c, map).isPrisonCell != pawn.IsPrisoner) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted) { return(false); } //Support ReplaceStuff allowing blueprints over beds if (EdificeBlocking(invBed.GetInnerIfMinified().def, c, direction, map)) { return(false); } if (!GenConstruct.CanPlaceBlueprintAt(invBed.GetInnerIfMinified().def, c, direction, map).Accepted) { return(false); } //Each cell of bed: foreach (var pos in GenAdj.OccupiedRect(c, direction, bed.def.size)) { if (map.zoneManager.ZoneAt(pos) != null) { return(false); } foreach (Thing t in pos.GetThingList(map)) { if (!(t is Pawn) && GenConstruct.BlocksConstruction(bed, t)) { return(false); } } } return(true); }; IntVec3 root = invBed.PositionHeld; // North/East would be redundant, except for cells on edge ; oh well, too much code to handle that Predicate <IntVec3> cellValidator = delegate(IntVec3 c) { if (!cellValidatorDir(c, Rot4.South) && !cellValidatorDir(c, Rot4.West)) { return(false); } using (PawnPath path = map.pathFinder.FindPath(root, c, pawn)) { return(path.TotalCost < 500); } }; Predicate <IntVec3> goodCellValidator = c => !RegionAndRoomQuery.RoomAt(c, map).PsychologicallyOutdoors&& cellValidator(c); IntVec3 placePosition = IntVec3.Invalid; TraverseParms trav = TraverseParms.For(pawn); if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, goodCellValidator, null, out placePosition)) { if (!CellFinder.TryFindRandomReachableCellNear(root, map, 4, trav, cellValidator, null, out placePosition)) { CellFinder.TryFindRandomReachableCellNear(root, map, 12, trav, cellValidator, null, out placePosition); } } } if (placePosition.IsValid) { Rot4 dir = cellValidatorDir(placePosition, Rot4.South) ? Rot4.South : Rot4.West; Blueprint_Install blueprint = GenConstruct.PlaceBlueprintForInstall(invBed, placePosition, map, dir, pawn.Faction); Log.Message($"{pawn} placing {blueprint} at {placePosition}"); __result = new Job(JobDefOf.PlaceBedroll, invBed, blueprint) { haulMode = HaulMode.ToContainer }; } }
public static void CheckAutoRebuildOnDestroyed(Thing thing, DestroyMode mode, Map map, BuildableDef buildingDef) { if (Find.PlaySettings.autoRebuild && mode == DestroyMode.KillFinalize && thing.Faction == Faction.OfPlayer && buildingDef.blueprintDef != null && buildingDef.IsResearchFinished && map.areaManager.Home[thing.Position] && GenConstruct.CanPlaceBlueprintAt(buildingDef, thing.Position, thing.Rotation, map).Accepted) { GenConstruct.PlaceBlueprintForBuild(buildingDef, thing.Position, map, thing.Rotation, Faction.OfPlayer, thing.Stuff); } }
public override void DoEffect(Pawn usedBy) { if (this.target != null && !this.GetTargetingParameters().CanTarget(this.target)) { return; } base.DoEffect(usedBy); if (this.parent.Stuff == null) { this.parent.SetStuffDirect(ThingDefOf.Cloth); } CellRect cellRect = new CellRect(this.targetPos.x - 2, this.targetPos.z - 2, 5, 4); double hitpoints = (double)this.parent.HitPoints / 10; int wallsToPlace = (int)Math.Floor(hitpoints); //int wallsToPlace = 49; List <IntVec3> everything = new List <IntVec3>(); everything.AddRange(this.wallCells); everything.AddRange(this.doorCells); foreach (IntVec3 current in everything) { if (!GenConstruct.CanPlaceBlueprintAt(ThingDef.Named("TentWall"), current, Rot4.North, usedBy.Map, false, null).Accepted) { Messages.Message("Tent placement blocked. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } if (current.GetFirstItem(usedBy.Map) != null || current.GetFirstPawn(usedBy.Map) != null || current.GetFirstHaulable(usedBy.Map) != null) { Messages.Message("Tent placement blocked. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } Building building = current.GetFirstBuilding(usedBy.Map); if (building != null) { if (building.def.IsEdifice()) { Messages.Message("Tent placement blocked by a item, pawn or a building. Please deploy on a suitable space.", MessageTypeDefOf.RejectInput); return; } } } foreach (IntVec3 current in this.wallCells) { if (usedBy.Map.roofGrid.RoofAt(current) == null) { usedBy.Map.roofGrid.SetRoof(current, RoofDefOf.RoofConstructed); } } foreach (IntVec3 current in this.doorCells) { if (usedBy.Map.roofGrid.RoofAt(current) == null) { usedBy.Map.roofGrid.SetRoof(current, RoofDefOf.RoofConstructed); } } foreach (IntVec3 current in this.roofCells) { if (usedBy.Map.roofGrid.RoofAt(current) == null) { usedBy.Map.roofGrid.SetRoof(current, RoofDefOf.RoofConstructed); } } if (usedBy.Map.roofGrid.RoofAt(supportCell) == null) { usedBy.Map.roofGrid.SetRoof(supportCell, RoofDefOf.RoofConstructed); } if (wallsToPlace < wallCells.Count + doorCells.Count) { Messages.Message("Damaged tent deployed. Some walls will be missing.", MessageTypeDefOf.NegativeEvent); } int wallsPlaced = 0; this.GetPlacements(this.targetPos); foreach (IntVec3 current in this.wallCells) { if (wallsPlaced < wallsToPlace) { TrySpawnWall(current, usedBy); wallsPlaced++; } } foreach (IntVec3 DoorPos in this.doorCells) { if (wallsPlaced < wallsToPlace) { Thing door = ThingMaker.MakeThing(ThingDef.Named("TentDoor"), this.parent.Stuff); door.SetFaction(usedBy.Faction, null); door.Rotation = Building_Door.DoorRotationAt(DoorPos, usedBy.Map); GenSpawn.Spawn(door, DoorPos, usedBy.Map); wallsPlaced++; } } this.parent.Destroy(DestroyMode.Vanish); SoundDefOf.DesignatePlaceBuilding.PlayOneShotOnCamera(); Thing tent = ThingMaker.MakeThing(ThingDef.Named("TentDeployed"), this.parent.Stuff); tent.SetFaction(usedBy.Faction, null); tent.TryGetComp <CompPackTent>().tentName = this.parent.def.defName; tent.TryGetComp <CompPackTent>().placingRot = this.placingRot; GenSpawn.Spawn(tent, this.supportCell, usedBy.Map); return; }
protected override IEnumerable <Toil> MakeNewToils() { /* * * Toil Configurations * */ Toil prepareToSpin = new Toil(); prepareToSpin.initAction = delegate { if (Prey == null && Corpse == null) { this.pawn.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (Prey.Dead) { this.pawn.CurJob.SetTarget(TargetIndex.A, Prey.Corpse); } }; Toil gotoBody = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); gotoBody.AddPreInitAction(new Action(delegate { this.pawn.ClearAllReservations(); this.pawn.Reserve(TargetA, this.job); //this.Map.physicalInteractionReservationManager.ReleaseAllForTarget(TargetA); //this.Map.physicalInteractionReservationManager.Reserve(this.GetActor(), TargetA); currentActivity = "Spinning Cocoon"; })); Toil spinDelay = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 500, initAction = delegate { currentActivity = "Spinning Cocoon"; } }; spinDelay.WithProgressBarToilDelay(TargetIndex.B); Toil spinBody = new Toil { initAction = delegate { //Log.Message("5"); var spinner = this.GetActor() as Spider; if (spinner != null) { Building_Cocoon newCocoon; Thing toLoad; IntVec3 newPosition; if (Prey.Dead) { toLoad = Prey.Corpse; newPosition = Prey.Corpse.Position; } else { toLoad = Prey; newPosition = Prey.Position; } if (!toLoad.Spawned) { this.EndJobWith(JobCondition.Incompletable); return; } toLoad.DeSpawn(); toLoad.holdingOwner = null; if (!GenConstruct.CanPlaceBlueprintAt(CocoonDef, newPosition, Rot4.North, this.pawn.Map).Accepted) { var cells = GenAdj.CellsAdjacent8Way(new TargetInfo(newPosition, this.pawn.Map)); foreach (IntVec3 cell in cells) { if (GenConstruct.CanPlaceBlueprintAt(CocoonDef, cell, Rot4.North, this.Map).Accepted) { newPosition = cell; break; } } } newCocoon = (Building_Cocoon)GenSpawn.Spawn(CocoonDef, newPosition, spinner.Map); //Log.Message("New Spinner: " + newCocoon.Spinner.Label); newCocoon.TryGetInnerInteractableThingOwner().TryAdd(toLoad); this.pawn?.CurJob?.SetTarget(TargetIndex.B, newCocoon); } }, defaultCompleteMode = ToilCompleteMode.Instant }; Toil pickupCocoon = Toils_Haul.StartCarryThing(TargetIndex.B); pickupCocoon.AddPreInitAction(new Action(delegate { //this.TargetB.Thing.DeSpawn(); this.pawn.CurJob.SetTarget(TargetIndex.C, TargetB.Thing); this.pawn.Reserve(TargetC, this.job); //this.pawn.Map.physicalInteractionReservationManager.Reserve(this.pawn, TargetC); })); Toil relocateCocoon = Toils_Haul.CarryHauledThingToCell(TargetIndex.C); Toil dropCocoon = Toils_Haul.PlaceHauledThingInCell(TargetIndex.C, relocateCocoon, false).FailOn(() => !GenConstruct.CanPlaceBlueprintAt(CocoonDef, TargetC.Cell, Rot4.North, this.Map).Accepted); this.AddFinishAction(new Action(delegate { this.pawn.Map.physicalInteractionReservationManager.ReleaseAllClaimedBy(this.pawn); })); /* * * Toil Execution * */ yield return(new Toil { initAction = delegate { this.Map.attackTargetsCache.UpdateTarget(this.pawn); }, atomicWithPrevious = true, defaultCompleteMode = ToilCompleteMode.Instant }); Action onHitAction = delegate { Pawn prey = this.Prey; bool surpriseAttack = this.firstHit && !prey.IsColonist; if (this.pawn.meleeVerbs.TryMeleeAttack(prey, this.job.verbToUse, surpriseAttack)) { if (!this.notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { this.notifiedPlayer = true; Messages.Message("MessageAttackedByPredator".Translate(new object[] { prey.LabelShort, this.pawn.LabelIndefinite() }).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig);// MessageSound.SeriousAlert); } this.Map.attackTargetsCache.UpdateTarget(this.pawn); } this.firstHit = false; }; //yield return Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, onHitAction).JumpIf(() => Prey.Downed || Prey.Dead, prepareToSpin).FailOn(() => Find.TickManager.TicksGame > this.startTick + 5000 && (float)(this.job.GetTarget(TargetIndex.A).Cell - this.pawn.Position).LengthHorizontalSquared > 4f); yield return(prepareToSpin.FailOn(() => Prey == null)); yield return(gotoBody.FailOn(() => Prey == null)); yield return(spinDelay.FailOn(() => Prey == null)); yield return(spinBody.FailOn(() => Prey == null)); //yield return pickupCocoon; //yield return relocateCocoon; //yield return dropCocoon; //float durationMultiplier = 1f / this.pawn.GetStatValue(StatDefOf.EatingSpeed, true); //yield return Toils_Ingest.ChewIngestible(this.pawn, durationMultiplier, TargetIndex.A, TargetIndex.None).FailOnDespawnedOrNull(TargetIndex.A).FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); //yield return Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.A); //yield return Toils_Jump.JumpIf(gotoCorpse, () => this.pawn.needs.food.CurLevelPercentage < 0.9f); }
public override void DesignateSingleCell(IntVec3 c) { if (_mode == Mode.Select) { List <Thing> things = this.ReinstallableInCell(c); if (things.Any()) { if (_originFound == false) { _originFound = true; _origin = c; } DesignatedThings.AddRange(things); things.ForEach(thing => DesignateThing(thing)); } } else if (_mode == Mode.Place) { GenConstruct_CanPlaceBlueprintAt_Patch.Mode = BlueprintMode.Place; HashSet <Thing> placedThings = new HashSet <Thing>(); Dictionary <Thing, Thing> twinThings = new Dictionary <Thing, Thing>(); Dictionary <Thing, Blueprint_Install> blueprintWork = new Dictionary <Thing, Blueprint_Install>(); Dictionary <Thing, IntVec3> siblingWork = new Dictionary <Thing, IntVec3>(); IntVec3 mousePos = UI.MouseCell(); foreach (Thing designatedThing in DesignatedThings) { IntVec3 drawCell = GetDeltaCell(designatedThing, mousePos, _ghostPos); List <Thing> things = drawCell.GetThingList(designatedThing.MapHeld); bool foundTwin = false; bool foundSibling = false; foreach (Thing thingOnCell in things) { if (DesignatedThings.Contains(thingOnCell)) { if (designatedThing.IdenticalWith(_rotation, thingOnCell)) { if (blueprintWork.TryGetValue(thingOnCell, out Blueprint_Install install)) { Thing twin = this.GetTailInTwinThings(twinThings, designatedThing); _setBuildingToReinstall.Invoke(install, new[] { twin }); blueprintWork[twin] = install; blueprintWork.Remove(thingOnCell); placedThings.Add(twin); } else if (siblingWork.TryGetValue(thingOnCell, out IntVec3 position)) { Thing twin = this.GetTailInTwinThings(twinThings, designatedThing); _ghostPos[twin] = position; siblingWork.Remove(thingOnCell); siblingWork[twin] = position; placedThings.Add(thingOnCell); } else { twinThings[thingOnCell] = designatedThing; _ghostPos[designatedThing] = _ghostPos[thingOnCell]; placedThings.Add(thingOnCell); } this.Map.designationManager.TryRemoveDesignationOn(thingOnCell, MoveBaseDefOf.MoveBase); foundTwin = true; break; } else if (!GenConstruct.BlocksConstruction(designatedThing, thingOnCell)) { continue; } else { foundSibling = true; Thing twin = this.GetTailInTwinThings(twinThings, designatedThing); siblingWork[twin] = _ghostPos[twin] = _ghostPos[designatedThing]; break; } } } if (foundTwin || foundSibling) { continue; } Thing twin1 = this.GetTailInTwinThings(twinThings, designatedThing); AcceptanceReport report = GenConstruct.CanPlaceBlueprintAt( twin1.def , drawCell , GetRotation(twin1) , twin1.MapHeld , false , null , twin1); if (report.Accepted) { Building building = twin1 as Building; blueprintWork[building] = GenConstruct.PlaceBlueprintForReinstall(building, drawCell, building.MapHeld, GetRotation(building), Faction.OfPlayer); placedThings.Add(building); } } RemoveRoofModel model = InitModel( DesignatedThings , DesignatedThings.Except(placedThings).ToList() , DesignatedThings.First().MapHeld , mousePos , _rotation , _ghostPos); ResolveDeadLock(model); this.KeepDesignation = true; _mode = Mode.Select; Find.DesignatorManager.Deselect(); } }