public static void SetupMoveIntoNextCell(ref Pawn_PathFollower instance, Pawn pawn, LocalTargetInfo destination) { if (instance.curPath.NodesLeftCount <= 1) { Log.Error(string.Concat(new object[] { pawn, " at ", pawn.Position, " ran out of path nodes while pathing to ", destination, "." }), false); PatherFailedHelper(ref instance, pawn); return; } instance.nextCell = instance.curPath.ConsumeNextNode(); if (!GenGridShips.Walkable(instance.nextCell, MapExtensionUtility.GetExtensionToMap(pawn.Map))) { Log.Error(string.Concat(new object[] { pawn, " entering ", instance.nextCell, " which is unwalkable." }), false); } int num = CostToMoveIntoCellShips(pawn, instance.nextCell); instance.nextCellCostTotal = (float)num; instance.nextCellCostLeft = (float)num; //Doors? }
public static IntVec3 RandomSpawnCellForPawnNear(IntVec3 root, Map map, int firstTryWithRadius = 4) { MapExtension mapE = MapExtensionUtility.GetExtensionToMap(map); if (GenGridShips.Standable(root, map, mapE) && root.GetFirstPawn(map) is null) { return(root); } IntVec3 result; int num = firstTryWithRadius; for (int i = 0; i < 3; i++) { if (CellFinderExtended.TryFindRandomReachableCellNear(root, map, (float)num, TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false), (IntVec3 c) => GenGridShips.Standable(c, map, mapE) && (root.Fogged(map) || !c.Fogged(map)) && c.GetFirstPawn(map) is null, out result, null, 999999)) { return(result); } num *= 2; } num = firstTryWithRadius + 1; while (!CellFinderExtended.TryRandomClosewalkCellNear(root, map, num, out result, null)) { if (num > map.Size.x / 2 && num > map.Size.z / 2) { return(root); } num *= 2; } return(result); }
private static IntVec3 FindCenterWaterCell(Map map, bool landing = false) { TraverseParms tp = TraverseParms.For(TraverseMode.NoPassClosedDoors, Danger.Deadly, false); MapExtension mapE = MapExtensionUtility.GetExtensionToMap(map); Predicate <IntVec3> validator = (IntVec3 x) => GenGridShips.Standable(x, map, mapE) && !x.Fogged(map) && mapE.getShipReachability.CanReachMapEdge(x, tp); IntVec3 result; if (RCellFinder.TryFindRandomCellNearTheCenterOfTheMapWith(null /*input validator here*/, map, out result)) { return(result); //RECHECK } Log.Warning("Could not find any valid center cell.", false); return(CellFinder.RandomCell(map)); }
private IntVec3 FindShoreline(Pawn p) { IntVec3 curCell = p.Position; int xSize = p.Map.Size.x - p.Position.x; int zSize = p.Map.Size.z - p.Position.z; IntVec3 nextCell; if (p.Rotation == Rot4.North) { } else if (p.Rotation == Rot4.East) { int alternate = 0; int sign = 1; while (alternate < p.Map.Size.z / 2) { sign *= -1; for (int i = 0; i < xSize; i++) { nextCell = new IntVec3(p.Position.x + i, p.Position.y, p.Position.z + (alternate * sign)); TerrainDef terrain = p.Map.terrainGrid.TerrainAt(nextCell); if (!terrain.IsWater && nextCell.Standable(p.Map)) { return(curCell); } curCell = nextCell; if (!curCell.InBoundsShip(p.Map) || !GenGridShips.Standable(curCell, p.Map, MapExtensionUtility.GetExtensionToMap(p.Map))) { break; } } if (sign > 0) { alternate++; } } } else if (p.Rotation == Rot4.South) { } else if (p.Rotation == Rot4.West) { } Log.Error("Unable to find location to disembark " + p.LabelShort); return(IntVec3.Invalid); }
public static RegionType GetExpectedRegionType(this IntVec3 c, Map map) { if (!c.InBoundsShip(map)) { return(RegionType.None); } if (!(c.GetDoor(map) is null)) { return(RegionType.Portal); } if (GenGridShips.Walkable(c, MapExtensionUtility.GetExtensionToMap(map))) { return(RegionType.Normal); } return(RegionType.ImpassableFreeAirExchange); }
private static IntVec3 FindNearEdgeWaterCell(Map map) { Predicate <IntVec3> validator = (IntVec3 x) => GenGridShips.Standable(x, map, MapExtensionUtility.GetExtensionToMap(map)) && !x.Fogged(map); Faction hostFaction = map.ParentFaction; IntVec3 root; if (CellFinder.TryFindRandomEdgeCellWith(validator, map, CellFinder.EdgeRoadChance_Ignore, out root)) { return(CellFinderExtended.RandomClosewalkCellNear(root, map, 5, null)); } if (CellFinder.TryFindRandomEdgeCellWith(validator, map, CellFinder.EdgeRoadChance_Ignore, out root)) { return(CellFinderExtended.RandomClosewalkCellNear(root, map, 5, null)); } Log.Warning("Could not find any valid edge cell.", false); return(CellFinder.RandomCell(map)); }
public static bool TryFindRandomReachableCellNear(IntVec3 root, Map map, float radius, TraverseParms traverseParms, Predicate <IntVec3> validator, out IntVec3 result, Predicate <WaterRegion> regionValidator, int maxRegions = 999999) { if (map is null) { Log.ErrorOnce("Tried to find reachable cell using SPExtended in a null map", 61037855, false); result = IntVec3.Invalid; return(false); } WaterRegion region = WaterGridsUtility.GetRegion(root, map, RegionType.Set_Passable); if (region is null) { result = IntVec3.Invalid; return(false); } Rot4 dir = Find.World.CoastDirectionAt(map.Tile).IsValid ? Find.World.CoastDirectionAt(map.Tile) : Find.WorldGrid[map.Tile].Rivers?.Any() ?? false?SPExtra.RiverDirection(map) : Rot4.Invalid; result = CellFinderExtended.RandomEdgeCell(dir, map, (IntVec3 c) => GenGridShips.Standable(c, map, MapExtensionUtility.GetExtensionToMap(map)) && !c.Fogged(map)); return(true); }
public static bool NeedNewPath(LocalTargetInfo destination, PawnPath curPath, Pawn pawn, PathEndMode peMode, IntVec3 lastPathedTargetPosition) { if (!destination.IsValid || curPath is null || !curPath.Found || curPath.NodesLeftCount == 0) { return(true); } if (destination.HasThing && destination.Thing.Map != pawn.Map) { return(true); } if ((pawn.Position.InHorDistOf(curPath.LastNode, 15f) || pawn.Position.InHorDistOf(destination.Cell, 15f)) && !ShipReachabilityImmediate.CanReachImmediateShip( curPath.LastNode, destination, pawn.Map, peMode, pawn)) { return(true); } if (curPath.UsedRegionHeuristics && curPath.NodesConsumedCount >= 75) { return(true); } if (lastPathedTargetPosition != destination.Cell) { float num = (float)(pawn.Position - destination.Cell).LengthHorizontalSquared; float num2; if (num > 900f) { num2 = 10f; } else if (num > 289f) { num2 = 5f; } else if (num > 100f) { num2 = 3f; } else if (num > 49f) { num2 = 2f; } else { num2 = 0.5f; } if ((float)(lastPathedTargetPosition - destination.Cell).LengthHorizontalSquared > (num2 * num2)) { return(true); } } bool flag = curPath.NodesLeftCount < 30; IntVec3 other = IntVec3.Invalid; IntVec3 intVec = IntVec3.Invalid; int num3 = 0; while (num3 < 20 && num3 < curPath.NodesLeftCount) { intVec = curPath.Peek(num3); if (!GenGridShips.Walkable(intVec, MapExtensionUtility.GetExtensionToMap(pawn.Map))) { return(true); } if (num3 != 0 && intVec.AdjacentToDiagonal(other) && (ShipPathFinder.BlocksDiagonalMovement(pawn.Map.cellIndices.CellToIndex(intVec.x, other.z), pawn.Map, MapExtensionUtility.GetExtensionToMap(pawn.Map)) || ShipPathFinder.BlocksDiagonalMovement(pawn.Map.cellIndices.CellToIndex(other.x, intVec.z), pawn.Map, MapExtensionUtility.GetExtensionToMap(pawn.Map)))) { return(true); } other = intVec; num3++; } return(false); }
public static void EnterSpawn(Caravan caravan, Map map, Func <Pawn, IntVec3> spawnCellGetter, CaravanDropInventoryMode caravanDropInventoryMode = CaravanDropInventoryMode.DoNotDrop, bool draftColonists = true) { List <Pawn> pawns = new List <Pawn>(caravan.PawnsListForReading).Where(x => ShipHarmony.IsShip(x)).ToList(); MapExtension mapE = MapExtensionUtility.GetExtensionToMap(map); Rot4 spawnDir = GetEdgeToSpawnBoatOn(caravan, map); for (int i = 0; i < pawns.Count; i++) { IntVec3 loc = CellFinderExtended.MiddleEdgeCell(spawnDir, map, pawns[i], (IntVec3 c) => GenGridShips.Standable(c, map, mapE) && !c.Fogged(map)); //Change back to spawnCellGetter later pawns[i].GetComp <CompShips>().Angle = 0; Pawn ship = GenSpawn.Spawn(pawns[i], loc, map, spawnDir.Opposite, WipeMode.Vanish, false) as Pawn; ship.drafter.Drafted = draftColonists ? true : false; } caravan.RemoveAllPawns(); if (caravan.Spawned) { Find.WorldObjects.Remove(caravan); } }
protected override bool TryExecuteWorker(IncidentParms parms) { return(false); //Disabled for now Map map = (Map)parms.target; if (!base.TryResolveParms(parms)) { return(false); } if (parms.faction.HostileTo(Faction.OfPlayer)) { return(false); } List <Pawn> list = BoatStrategyWorker.GeneratePawnsForBoats(parms, PawnGroupKindDef); if (list.Count <= 0) { return(false); } foreach (Pawn p in list) { if (p.needs != null && p.needs.food != null) { p.needs.food.CurLevel = p.needs.food.MaxLevel; } } TraderKindDef traderKind = null; foreach (Pawn p in list) { if (p.TraderKind != null) { traderKind = p.TraderKind; break; } } List <Pawn> ships = BoatStrategyWorker.GenerateBoatsForIncident(parms, PawnGroupKindDef, ref list); if (!ships.Any()) { return(false); } List <IntVec3> usedCells = new List <IntVec3>(); Predicate <IntVec3> validator = (IntVec3 c) => GenGridShips.Standable(c, map, MapExtensionUtility.GetExtensionToMap(map)) && !c.Fogged(map); IntVec3 root = CellFinderExtended.MiddleEdgeCell(Find.World.CoastDirectionAt(map.Tile), map, ships.MaxBy(x => x.def.size.z), validator); List <Thing> thingShips = new List <Thing>(); foreach (Pawn s in ships) { IntVec3 loc = !usedCells.Any() ? CellFinderExtended.MiddleEdgeCell(Find.World.CoastDirectionAt(map.Tile), map, s, validator) : CellFinderExtended.RandomEdgeCell(Find.World.CoastDirectionAt(map.Tile), map, validator, usedCells, s); usedCells.Add(loc); Thing shipSpawned = GenSpawn.Spawn(s, loc, map, WipeMode.Vanish); shipSpawned.Rotation = Find.World.CoastDirectionAt(map.Tile).Opposite; thingShips.Add(shipSpawned); } List <Pawn> pawnsLeft = list; pawnsLeft.SortBy(x => x.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation)); foreach (Thing t in thingShips) { for (int i = 0; i < t.TryGetComp <CompShips>().PawnCountToOperate; i++) { if (pawnsLeft.Count <= 0) { break; } t.TryGetComp <CompShips>().BoardDirectly(pawnsLeft.Pop(), t.TryGetComp <CompShips>().NextAvailableHandler.handlers); } if (pawnsLeft.Count <= 0) { break; } } int iter = 0; for (int i = 0; i < pawnsLeft.Count; i++) { Thing ship = thingShips[iter]; Pawn p = pawnsLeft.Pop(); ship.TryGetComp <CompShips>().BoardDirectly(p, ship.TryGetComp <CompShips>().NextAvailableHandler.handlers); iter = iter + 1 >= thingShips.Count ? 0 : iter + 1; } foreach (Thing s in thingShips) { (s as Pawn).drafter.Drafted = true; } string label = "LetterLabelTraderCaravanArrival".Translate(parms.faction.Name, traderKind.label).CapitalizeFirst(); string text = "LetterTraderCaravanArrival".Translate(parms.faction.Name, traderKind.label).CapitalizeFirst(); PawnRelationUtility.Notify_PawnsSeenByPlayer_Letter(ships, ref label, ref text, "LetterRelatedPawnsNeutralGroup".Translate(Faction.OfPlayer.def.pawnsPlural), true, true); Find.LetterStack.ReceiveLetter(label, text, LetterDefOf.PositiveEvent, ships[0], parms.faction, null); RCellFinder.TryFindRandomSpotJustOutsideColony(ships[0], out IntVec3 chillSpot); LordJob_TradeWithColony lordJob = new LordJob_TradeWithColony(parms.faction, chillSpot); foreach (Pawn s in ships) { Job job = new Job(JobDefOf_Ships.DisembarkLord, FindShoreline(s)); s.jobs.TryTakeOrderedJob(job, JobTag.Misc); s.GetComp <CompShips>().lordJobToAssign = lordJob; s.GetComp <CompShips>().lordShipGroup.AddRange(ships); } return(true); }