public static IEnumerable <AirDefense> CheckNearbyObjects(AerialVehicleInFlight aerialVehicle, float speedPctPerTick) { float halfTicksPerTileTraveled = Ext_Math.RoundTo(speedPctPerTick * 100, 0.001f); Vector3 start = aerialVehicle.DrawPos; for (int i = 0; i < aerialVehicle.flightPath.Path.Count; i++) { int destination = aerialVehicle.flightPath[i].tile; Vector3 destinationPos = Find.WorldGrid.GetTileCenter(destination); Vector3 position = start; for (float transition = 0; transition < 1; transition += halfTicksPerTileTraveled) { Vector3 partition = Vector3.Slerp(position, destinationPos, transition); foreach (KeyValuePair <WorldObject, AirDefense> defenseCache in airDefenseCache) { float distance = Ext_Math.SphericalDistance(partition, defenseCache.Key.DrawPos); if (distance < defenseCache.Value.MaxDistance) { yield return(defenseCache.Value); } } } start = destinationPos; } }
public virtual bool TryExecuteEvent(AerialVehicleInFlight aerialVehicle, WorldObject shotDownBy, IntVec3?precalculatedCell = null) { try { Map crashSite; int ticksTillArrival = -1; if (Find.WorldObjects.MapParentAt(aerialVehicle.Tile) is MapParent mapParent) { crashSite = mapParent.Map; } else { int num = CaravanIncidentUtility.CalculateIncidentMapSize(aerialVehicle.vehicle.AllPawnsAboard, aerialVehicle.vehicle.AllPawnsAboard); crashSite = GetOrGenerateMapUtility.GetOrGenerateMap(aerialVehicle.Tile, new IntVec3(num, 1, num), WorldObjectDefOfVehicles.CrashedShipSite); if (shotDownBy is Settlement settlement) { ticksTillArrival = (crashSite.Parent as CrashSite).InitiateReinforcementsRequest(settlement); } } bool validator(IntVec3 c) { bool flag = aerialVehicle.vehicle.PawnOccupiedCells(c, Rot4.East).All(c2 => c2.Standable(crashSite) && !c.Roofed(crashSite) && !c.Fogged(crashSite) && c.InBounds(crashSite)); return(flag); } IntVec3 RandomCentercell() { RCellFinder.TryFindRandomCellNearTheCenterOfTheMapWith(validator, crashSite, out IntVec3 result); return(result); } IntVec3 cell = precalculatedCell ?? RandomCentercell(); if (cell == IntVec3.Invalid) { return(false); } AerialVehicleArrivalAction_CrashSpecificCell arrivalAction = new AerialVehicleArrivalAction_CrashSpecificCell(aerialVehicle.vehicle, crashSite.Parent, crashSite.Tile, aerialVehicle.vehicle.CompVehicleLauncher.launchProtocol, cell, Rot4.East); arrivalAction.Arrived(crashSite.Tile); aerialVehicle.Destroy(); string settlementLabel = shotDownBy?.Label ?? string.Empty; if (ticksTillArrival > 0) { string hoursTillArrival = Ext_Math.RoundTo(ticksTillArrival / 2500f, 1).ToString(); SendCrashSiteLetter(shotDownBy, crashSite.Parent, CrashSiteDef.letterLabel, CrashSiteDef.letterTexts[1], CrashSiteDef.letterDef, crashSite.Parent, new NamedArgument[] { aerialVehicle.Label, settlementLabel, hoursTillArrival }); } else { SendCrashSiteLetter(shotDownBy, crashSite.Parent, CrashSiteDef.letterLabel, CrashSiteDef.letterTexts[0], CrashSiteDef.letterDef, crashSite.Parent, new NamedArgument[] { aerialVehicle.Label, settlementLabel }); } return(true); } catch (Exception ex) { Log.Error($"Failed to execute incident {GetType()}. Exception=\"{ex.Message}\""); return(false); } }