public static bool CompleteConstructionVehicle(Pawn worker, Frame __instance) { if (__instance.def.entityDefToBuild is VehicleBuildDef def && def.thingToSpawn != null) { VehiclePawn vehicle = VehicleSpawner.GenerateVehicle(def.thingToSpawn, worker.Faction); __instance.resourceContainer.ClearAndDestroyContents(DestroyMode.Vanish); Map map = __instance.Map; __instance.Destroy(DestroyMode.Vanish); if (def.soundBuilt != null) { def.soundBuilt.PlayOneShot(new TargetInfo(__instance.Position, map, false)); } vehicle.SetFaction(worker.Faction); GenSpawn.Spawn(vehicle, __instance.Position, map, __instance.Rotation, WipeMode.FullRefund, false); worker.records.Increment(RecordDefOf.ThingsConstructed); vehicle.Rename(); //Quality? //Art? //Tale RecordTale LongConstructionProject? AchievementsHelper.TriggerVehicleConstructionEvent(vehicle); return(false); } return(true); }
/// <summary> /// Catch All for vehicle related Things spawned in. Handles GodMode placing of vehicle buildings, corrects immovable spawn locations, and registers air defenses /// </summary> /// <param name="newThing"></param> /// <param name="loc"></param> /// <param name="map"></param> /// <param name="rot"></param> /// <param name="__result"></param> /// <param name="wipeMode"></param> /// <param name="respawningAfterLoad"></param> /// <returns></returns> public static bool RegisterThingSpawned(Thing newThing, ref IntVec3 loc, Map map, Rot4 rot, Thing __result, WipeMode wipeMode, bool respawningAfterLoad) { if (newThing.def is VehicleBuildDef def) { if (!VehicleMod.settings.debug.debugSpawnVehicleBuildingGodMode && newThing.HitPoints == newThing.MaxHitPoints) { VehiclePawn vehiclePawn = VehicleSpawner.GenerateVehicle(def.thingToSpawn, newThing.Faction); // (VehiclePawn)PawnGenerator.GeneratePawn(def.thingToSpawn); if (def.soundBuilt != null) { def.soundBuilt.PlayOneShot(new TargetInfo(loc, map, false)); } VehiclePawn vehicleSpawned = (VehiclePawn)GenSpawn.Spawn(vehiclePawn, loc, map, rot, WipeMode.FullRefund, false); vehicleSpawned.Rename(); __result = vehicleSpawned; AchievementsHelper.TriggerVehicleConstructionEvent(vehicleSpawned); return(false); } } else if (newThing is VehiclePawn vehicle) { bool standable = true; foreach (IntVec3 c in vehicle.PawnOccupiedCells(loc, rot)) { if (!c.InBounds(map) || (vehicle.IsBoat() ? GenGridVehicles.Impassable(c, map) : GenGrid.Impassable(c, map))) { standable = false; break; } } bool validator(IntVec3 c) { foreach (IntVec3 c2 in vehicle.PawnOccupiedCells(c, rot)) { if (vehicle.IsBoat() ? GenGridVehicles.Impassable(c, map) : GenGrid.Impassable(c, map)) { return(false); } } return(true); } if (standable) { return(true); } if (!CellFinder.TryFindRandomCellNear(loc, map, 20, validator, out IntVec3 newLoc, 100)) { Log.Error($"Unable to find location to spawn {newThing.LabelShort} after 100 attempts. Aborting spawn."); return(false); } loc = newLoc; } else if (newThing is Pawn pawn && !pawn.Dead) { try { var positionManager = map.GetCachedMapComponent <VehiclePositionManager>(); if (positionManager.PositionClaimed(loc)) { VehiclePawn inPlaceVehicle = positionManager.ClaimedBy(loc); CellRect occupiedRect = inPlaceVehicle.OccupiedRect().ExpandedBy(1); Rand.PushState(); for (int i = 0; i < 3; i++) { IntVec3 newLoc = occupiedRect.EdgeCells.Where(c => GenGrid.InBounds(c, map) && GenGrid.Standable(c, map)).RandomElementWithFallback(inPlaceVehicle.Position); if (occupiedRect.EdgeCells.Contains(newLoc)) { loc = newLoc; break; } occupiedRect = occupiedRect.ExpandedBy(1); } Rand.PopState(); } } catch (Exception ex) { Log.Error($"Pawn {newThing.Label} could not be readjusted for spawn location. Exception={ex.Message}"); } }