public override void MapLoaded(Map map) { base.MapLoaded(map); CompatabilityAddMissingWaterTags(); AddDefaultFishableTags(); AddDefaultWaterAffordances(); Logger.Message("MapLoaded: Fishable terrain options: " + string.Join(", ", FetchFishingTagged().ConvertAll <string>(t => t.ToString()).ToArray())); // Cleanup extra dolphins foreach (Thing d in map.GetDirectlyHeldThings().Where((Thing t) => (t as DolphinAway) != null)) { Logger.Message("Caught a lazy dolphin... teleporting off-world"); d.Destroy(); } IntVec3?launchPoint = RandomFishable(map); if (launchPoint.HasValue) { Logger.Message("Humans are here... so long and thanks for all the fish @ (" + launchPoint + ")"); DolphinAway dolphin = (DolphinAway)ThingMaker.MakeThing(ThingDef.Named("DolphinAway"), null); // Needs his fish before leaving... Thing fish = ThingMaker.MakeThing(ThingDef.Named("DeadFish")); dolphin.innerContainer.TryAdd(fish); this.dolphinLeaving = (DolphinAway)SkyfallerMaker.MakeSkyfaller(ThingDef.Named("DolphinAway"), dolphin); GenSpawn.Spawn(this.dolphinLeaving, launchPoint.GetValueOrDefault(), map); } }
public void OnStartTargeting(int index) { drawAffectedCells = true; if (index == 0) { firstPosition = null; secondPosition = null; keepGoing = false; } }
/** * <summary> * 将人物传送到目标位置附近。 * </summary> * <param name="pawn">需要被传送的人物。</param> * <param name="target">一个位置。</param> * <returns>是否成功地完成了传送。</returns> */ public static bool TeleportPawn(Pawn pawn, IntVec3 target) { bool flag = false; IntVec3?relocated = ScanOccupiablePosition(pawn, target); if (relocated != null) { pawn.SetPositionDirect((IntVec3)relocated); flag = true; } return(flag); }
public override void SpawnSetup(Map map, bool respawningAfterLoad) { base.SpawnSetup(map, respawningAfterLoad); drawAffectedCells = false; firstPosition = null; secondPosition = null; keepGoing = false; isFlying = false; ticksFlying = 0; CurrentShellDef ??= RFDefOf.Shell_HighExplosive; }
public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); parent.Map.roofGrid.SetRoof(parent.Position, DefDatabase <RoofDef> .GetNamed("RoofShip", true)); parent.Map.terrainGrid.SetTerrain(parent.Position, DefDatabase <TerrainDef> .GetNamed("GravityPlating", true)); List <Thing> thingList1 = ((ThingGrid)((Thing)this.parent).Map.thingGrid).ThingsListAt(((Thing)this.parent).Position); new ThingMutator <Thing>() .DeSpawn <Plant>() .Destroy <Building_SteamGeyser>() .UnsafeExecute(thingList1); position = parent.Position; }
public static void DoExplosion(IntVec3 center, Map map, float radius, DamageDef damType, Thing instigator, int damAmount = -1, float armorPenetration = -1f, SoundDef explosionSound = null, ThingDef weapon = null, ThingDef projectile = null, Thing intendedTarget = null, ThingDef postExplosionSpawnThingDef = null, float postExplosionSpawnChance = 0f, int postExplosionSpawnThingCount = 1, bool applyDamageToExplosionCellsNeighbors = false, ThingDef preExplosionSpawnThingDef = null, float preExplosionSpawnChance = 0f, int preExplosionSpawnThingCount = 1, float chanceToStartFire = 0f, bool damageFalloff = false, float?direction = null, List <Thing> ignoredThings = null) { if (map == null) { Log.Warning("Tried to do explosion in a null map."); return; } if (damAmount < 0) { damAmount = damType.defaultDamage; armorPenetration = damType.defaultArmorPenetration; if (damAmount < 0) { Log.ErrorOnce("Attempted to trigger an explosion without defined damage", 91094882); damAmount = 1; } } if (armorPenetration < 0f) { armorPenetration = (float)damAmount * 0.015f; } Explosion obj = (Explosion)GenSpawn.Spawn(ThingDefOf.Explosion, center, map); IntVec3? needLOSToCell = null; IntVec3? needLOSToCell2 = null; if (direction.HasValue) { CalculateNeededLOSToCells(center, map, direction.Value, out needLOSToCell, out needLOSToCell2); } obj.radius = radius; obj.damType = damType; obj.instigator = instigator; obj.damAmount = damAmount; obj.armorPenetration = armorPenetration; obj.weapon = weapon; obj.projectile = projectile; obj.intendedTarget = intendedTarget; obj.preExplosionSpawnThingDef = preExplosionSpawnThingDef; obj.preExplosionSpawnChance = preExplosionSpawnChance; obj.preExplosionSpawnThingCount = preExplosionSpawnThingCount; obj.postExplosionSpawnThingDef = postExplosionSpawnThingDef; obj.postExplosionSpawnChance = postExplosionSpawnChance; obj.postExplosionSpawnThingCount = postExplosionSpawnThingCount; obj.applyDamageToExplosionCellsNeighbors = applyDamageToExplosionCellsNeighbors; obj.chanceToStartFire = chanceToStartFire; obj.damageFalloff = damageFalloff; obj.needLOSToCell1 = needLOSToCell; obj.needLOSToCell2 = needLOSToCell2; obj.StartExplosion(explosionSound, ignoredThings); }
private void TryLand() { //move ship there Map oldMap = parent.Map; Map newMap = Find.Maps.FirstOrDefault(x => x.Tile == oldMap.Tile && x != oldMap); if (newMap == null) { ///OH NOES! throw new Exception("WTF"); } var def = oldMap .GetSpaceAtmosphereMapComponent() .DefinitionAt(parent.Position); IntVec3?landingSpot = null; LongEventHandler.QueueLongEvent(() => { landingSpot = def.DetermineLandingSpot(newMap); if (landingSpot == null) { Find.LetterStack.ReceiveLetter("No Landing Spot", "No suitable landing spot found.", LetterDefOf.NeutralEvent); LongEventHandler.ClearQueuedEvents(); } }, "Landing_Spot", true, Handler); def .Move(oldMap, () => newMap, "Landing", true, Handler, null, () => landingSpot.Value) .Then(() => { Current.Game.CurrentMap = newMap; }, "Landing_Swap", Handler) .Then(() => { foreach (var pawn in Find.CurrentMap.mapPawns.AllPawns.Where(p => p.Faction == Faction.OfPlayer)) { pawn.playerSettings.AreaRestriction = Find.CurrentMap.areaManager.Home; } }, "Landing_Swap", Handler) .Then(() => { Find.World.worldObjects.Remove(oldMap.Parent); Find.Maps.Remove(oldMap); }, "Landing_DestroyOldMap", Handler); //do cool graphic? }
private static void Debug_DoStrike(int count) { if (debug_FirstPoint == null) { debug_FirstPoint = UI.MouseCell(); Messages.Message("First point selected, select second point.", MessageTypeDefOf.NeutralEvent); MoteAt(debug_FirstPoint.Value); } else { var bomb = CECompat.IsCEActive ? CECompat.GetProjectile(RFDefOf.Shell_HighExplosive) : RFDefOf.Shell_HighExplosive.projectileWhenLoaded; DoStrike(null, bomb, debug_FirstPoint.Value, UI.MouseCell(), count); debug_FirstPoint = null; } }
public static bool EnoughPotentialGuestsToStartParty(Map map, IntVec3?partySpot = default(IntVec3?)) { int value = Mathf.RoundToInt((float)((float)map.mapPawns.FreeColonistsSpawnedCount * 0.64999997615814209)); value = Mathf.Clamp(value, 2, 10); int num = 0; foreach (Pawn item in map.mapPawns.FreeColonistsSpawned) { if (PartyUtility.ShouldPawnKeepPartying(item) && (!partySpot.HasValue || !partySpot.Value.IsForbidden(item)) && (!partySpot.HasValue || item.CanReach(partySpot.Value, PathEndMode.Touch, Danger.Some, false, TraverseMode.ByPawn))) { num++; } } return(num >= value); }
public void SetTargetInfo(LocalTargetInfo info, int index) { if (!info.IsValid) { return; } if (index == 0) { firstPosition = info.Cell; } else { secondPosition = info.Cell; } }
public static void DoExplosion(IntVec3 center, Map map, float radius, DamageDef damType, Thing instigator, int damAmount = -1, float armorPenetration = -1f, SoundDef explosionSound = null, ThingDef weapon = null, ThingDef projectile = null, Thing intendedTarget = null, ThingDef postExplosionSpawnThingDef = null, float postExplosionSpawnChance = 0f, int postExplosionSpawnThingCount = 1, bool applyDamageToExplosionCellsNeighbors = false, ThingDef preExplosionSpawnThingDef = null, float preExplosionSpawnChance = 0f, int preExplosionSpawnThingCount = 1, float chanceToStartFire = 0f, bool damageFalloff = false, float?direction = null, List <Thing> ignoredThings = null) { if (map == null) { Log.Warning("Tried to do explosion in a null map.", false); return; } if (damAmount < 0) { damAmount = damType.defaultDamage; armorPenetration = damType.defaultArmorPenetration; if (damAmount < 0) { Log.ErrorOnce("Attempted to trigger an explosion without defined damage", 91094882, false); damAmount = 1; } } if (armorPenetration < 0f) { armorPenetration = (float)damAmount * 0.015f; } ExplosionPlus explosion = (ExplosionPlus)GenSpawn.Spawn(PurpleIvyDefOf.PI_ExplosionPlus, center, map, WipeMode.Vanish); IntVec3? needLOSToCell = null; IntVec3? needLOSToCell2 = null; explosion.radius = radius; explosion.damType = damType; explosion.instigator = instigator; explosion.damAmount = damAmount; explosion.armorPenetration = armorPenetration; explosion.weapon = weapon; explosion.projectile = projectile; explosion.intendedTarget = intendedTarget; explosion.preExplosionSpawnThingDef = preExplosionSpawnThingDef; explosion.preExplosionSpawnChance = preExplosionSpawnChance; explosion.preExplosionSpawnThingCount = preExplosionSpawnThingCount; explosion.postExplosionSpawnThingDef = postExplosionSpawnThingDef; explosion.postExplosionSpawnChance = postExplosionSpawnChance; explosion.postExplosionSpawnThingCount = postExplosionSpawnThingCount; explosion.applyDamageToExplosionCellsNeighbors = applyDamageToExplosionCellsNeighbors; explosion.chanceToStartFire = chanceToStartFire; explosion.center = center; explosion.damageFalloff = damageFalloff; explosion.needLOSToCell1 = needLOSToCell; explosion.needLOSToCell2 = needLOSToCell2; explosion.StartExplosion(explosionSound, ignoredThings); }
public override void PostDeSpawn(Map map) { base.PostDeSpawn(map); if (position == null) { return; } List <Thing> thingList1 = (map.thingGrid).ThingsListAt(position.Value); if (thingList1.Any(t => t.TryGetComp <CompRoofMe>() != null)) { position = null; return; } map.roofGrid.SetRoof(position.Value, null); map.terrainGrid.SetTerrain(position.Value, TerrainDefOf.Gravel); position = null; }
/** * <summary> * 扫描目标周围可被占用的位置。 * </summary> * <param name="pawn">需要被检测的人物。</param> * <param name="target">一个位置。</param> * <returns>最近的可被占用的位置。若无,则返回<c>null</c>。</returns> */ public static IntVec3?ScanOccupiablePosition(Pawn pawn, IntVec3 target) { IntVec3?flag = null; IntVec3 intVec; for (int i = 0; i < GenRadial.RadialPattern.Length; i++) { intVec = target + GenRadial.RadialPattern[i]; if (PawnCanOccupy(pawn, intVec)) { if (intVec == target) { return(target); } flag = intVec; break; } } return(flag); }
/// <summary> /// Finds a pont on the map that can be designated as a safe point for vampires to rest from daylight. /// </summary> /// <param name="pawn"></param> /// <returns></returns> public static IntVec3?DetermineHomePoint(Pawn pawn) { IntVec3?result = null; if (pawn.MapHeld is Map map) { if (map.IsPlayerHome) { if (RestUtility.FindBedFor(pawn) is Building_Bed bed) { result = bed.PositionHeld; } } if (result == null) { result = FindCellSafeFromSunlight(pawn); } } return(result); }
/// <summary> /// Some PRF Buildings are Magic, and can move stuff anywhere into a slotGroup /// (or, you know, they pile stuff up until it falls, or use a machine /// arm to move things, etc) /// </summary> /// <returns><c>true</c>, if thing was placed somewhere; <c>false</c> otherwise.</returns> /// <param name="placer">IPRF Buidling placing.</param> /// <param name="t">thing to place.</param> /// <param name="slotGroup">SlotGroup.</param> /// <param name="cell">optional first cell</param> public static bool PlaceThingAnywhereInSlotGroup(this IPRF_Building placer, Thing t, SlotGroup slotGroup, IntVec3?cell = null) { // Should we even be putting anything here? if (placer.ObeysStorageFilters && !slotGroup.parent.Accepts(t)) { return(false); } Map map = placer.Map; // Go through slotGroup, starting with cell if given // TODO: go thru slotgroup in order of increasing distance from cell? foreach (var c in (cell != null ? ((new[] { (IntVec3)cell }).Concat(slotGroup.CellsList.Where(x => x != cell))) : slotGroup.CellsList)) { if (CallNoStorageBlockersIn(c, map, t)) { Debug.Message(Debug.Flag.PlaceThing, "Found NoStorageBlockersIn(" + cell + ", map, " + t + ") - Placing"); if (t.Spawned) { t.DeSpawn(); } if (!GenPlace.TryPlaceThing(t, c, map, ThingPlaceMode.Direct)) { // This happens if some was absorbed, but not the whole stack // We should continue on, to see if we can place everything Debug.Message(Debug.Flag.PlaceThing, " some was absorbed, still have " + t.stackCount); continue; } placer.EffectOnPlaceThing(t); if (placer.ForbidOnPlacing(t)) { t.SetForbidden(true, false); } return(true); } } Debug.Message(Debug.Flag.PlaceThing, "There were StorageBlockersIn every cell of " + slotGroup.parent + " - cannot place" + t); return(false); }
Stencil?GetStencil(Map map, IntVec3 pos) { if (cachedPos != null && pos == cachedPos) { return(cachedStencil); } cachedPos = pos; var s = new Stencil(map) .MoveTo(pos) .ExpandRegion(IsValidTile, areaConstraints.max); var ratio = (float)s.Width / s.Height; if (s.Area < areaConstraints.min || ratio > maxRatio || 1 / ratio > maxRatio) { return(cachedStencil = null); } return(cachedStencil = s); }
public override void CompTick() { base.CompTick(); if (parent.IsHashIntervalTick(TICK_PERIOD) && ShouldBeCover) { var map = parent.Map; if (map == null) { return; } bool movingNow = Parent.pather.MovingNow; if (movingNow != _movingLast) { _movingLast = movingNow; if (movingNow && _lastPos != null) { RecalculateCell(_lastPos.Value, map.coverGrid); map.coverGrid.DeRegister(parent); } else { _lastPos = Parent.Position; map.coverGrid.Register(parent); } } else if (_lastPos != Parent.Position) { if (_lastPos != null) { RecalculateCell(_lastPos.Value, map.coverGrid); } map.coverGrid.Register(Parent); _lastPos = Parent.Position; } } }
public static bool EnoughPotentialGuestsToStartParty(Map map, IntVec3?partySpot = null) { int num = Mathf.RoundToInt((float)map.mapPawns.FreeColonistsSpawnedCount * 0.65f); num = Mathf.Clamp(num, 2, 10); int num2 = 0; foreach (Pawn current in map.mapPawns.FreeColonistsSpawned) { if (PartyUtility.ShouldPawnKeepPartying(current)) { if (!partySpot.HasValue || !partySpot.Value.IsForbidden(current)) { if (!partySpot.HasValue || current.CanReach(partySpot.Value, PathEndMode.Touch, Danger.Some, false, TraverseMode.ByPawn)) { num2++; } } } } return(num2 >= num); }
/// <summary> /// Ensures the cellrect inhabited by the vehicle contains no Things that will block pathing and movement. /// </summary> /// <param name="pawn"></param> /// <param name="c"></param> public static bool CellRectStandable(this VehiclePawn vehicle, Map map, IntVec3?c = null, Rot4?rot = null) { IntVec3 loc = c ?? vehicle.Position; IntVec2 dimensions = vehicle.VehicleDef.Size; if (rot?.IsHorizontal ?? false) { int x = dimensions.x; dimensions.x = dimensions.z; dimensions.z = x; } foreach (IntVec3 cell in CellRect.CenteredOn(loc, dimensions.x, dimensions.z)) { if (vehicle.IsBoat() && !GenGridVehicles.Standable(cell, map)) { return(false); } else if (!GenGrid.Standable(cell, map)) { return(false); } } return(true); }
private static void EventNotification(string label, string description, LetterDef letterDef, IntVec3?location) { var currentMap = Find.CurrentMap; if (location == null) { Find.LetterStack.ReceiveLetter(label, description, letterDef); } else { // Have to make sure that location isn't null otherwise compiler complains var newVector = location.GetValueOrDefault(); Find.LetterStack.ReceiveLetter(label, description, letterDef, new LookTargets(newVector, currentMap)); } }
public static bool EnoughPotentialGuestsToStartGathering(Map map, GatheringDef gatheringDef, IntVec3?gatherSpot = null) { int value = Mathf.RoundToInt((float)map.mapPawns.FreeColonistsSpawnedCount * 0.65f); value = Mathf.Clamp(value, 2, 10); int num = 0; foreach (Pawn item in map.mapPawns.FreeColonistsSpawned) { if (ShouldPawnKeepGathering(item, gatheringDef) && (!gatherSpot.HasValue || !gatherSpot.Value.IsForbidden(item)) && (!gatherSpot.HasValue || item.CanReach(gatherSpot.Value, PathEndMode.Touch, Danger.Some))) { num++; } } return(num >= value); }
public override void PostSpawnSetup(bool respawningAfterLoad) { base.PostSpawnSetup(respawningAfterLoad); _lastPos = Parent.Position; }
protected override Job TryGiveJob(Pawn pawn) { Room room = pawn.GetRoom(RegionType.Set_Passable); if (room != null) { if (room.PsychologicallyOutdoors) { Area area = pawn.MapHeld.areaManager.Home; if (area != null) { if (area.ActiveCells.FirstOrDefault(x => x.Roofed(pawn.Map) && x.Walkable(pawn.Map)) is IntVec3 safePlace && !IsZero(safePlace) && safePlace.IsValid) { //Log.Message("Safe Place"); return(new Job(JobDefOf.Goto, safePlace) { locomotionUrgency = LocomotionUrgency.Sprint }); } } Thing thing = GenClosest.ClosestThingReachable(pawn.PositionHeld, pawn.Map, ThingRequest.ForDef(ThingDefOf.Fire), PathEndMode.Touch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), 23, null, null, 0, -1, false, RegionType.Set_Passable, false); if (thing != null) { //Log.Message("Flee Place"); IntVec3 fleeLoc = CellFinderLoose.GetFleeDest(pawn, new List <Thing>() { thing }, 23); return(new Job(JobDefOf.FleeAndCower, thing)); } Region region; CellFinder.TryFindClosestRegionWith(pawn.GetRegion(RegionType.Set_Passable), TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn), (x => !x.Room.PsychologicallyOutdoors), 9999, out region, RegionType.Set_All); //.ClosestRegionIndoors(pawn.Position, pawn.Map, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), RegionType.Set_Passable); if (region != null) { IntVec3 result; if (region.TryFindRandomCellInRegion(x => !IsZero(x) && x.IsValid && x.InBounds(pawn.MapHeld) && x.GetDoor(pawn.MapHeld) == null, out result)) { //Log.Message("Region Place"); return(new Job(JobDefOf.Goto, result) { locomotionUrgency = LocomotionUrgency.Sprint }); } } IntVec3?cellResult = null; cellResult = CellFinderLoose.RandomCellWith(x => !IsZero(x) && x.IsValid && x.InBounds(pawn.MapHeld) && x.Roofed(pawn.MapHeld) && x.Walkable(pawn.MapHeld) && pawn.Map.reachability.CanReach(pawn.PositionHeld, x, PathEndMode.OnCell, TraverseMode.ByPawn, Danger.Deadly), pawn.MapHeld, 1000); if (cellResult != null && cellResult.Value.IsValid && !IsZero(cellResult.Value)) { //Log.Message("Random Place"); return(new Job(JobDefOf.Goto, cellResult.Value) { locomotionUrgency = LocomotionUrgency.Sprint }); } if (pawn.Faction != pawn.Map.ParentFaction) { bool flag = false; if (pawn.mindState.duty != null && pawn.mindState.duty.canDig) { flag = true; } IntVec3 c; if (RCellFinder.TryFindBestExitSpot(pawn, out c, (!flag) ? TraverseMode.ByPawn : TraverseMode.PassAllDestroyableThings)) { if (flag) { using (PawnPath pawnPath = pawn.Map.pathFinder.FindPath(pawn.Position, c, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassAllDestroyableThings, false), PathEndMode.OnCell)) { IntVec3 cellBeforeBlocker; Thing thingY = pawnPath.FirstBlockingBuilding(out cellBeforeBlocker, pawn); if (thingY != null) { Job job = DigUtility.PassBlockerJob(pawn, thingY, cellBeforeBlocker, true); if (job != null) { return(job); } } } } return(new Job(JobDefOf.Goto, c) { exitMapOnArrival = true, locomotionUrgency = PawnUtility.ResolveLocomotion(pawn, LocomotionUrgency.Sprint, LocomotionUrgency.Jog), expiryInterval = 400, canBash = true }); } } IntVec3?hideyHoleResult = null; hideyHoleResult = VampireUtility.FindHideyHoleSpot(VampDefOf.ROMV_HideyHole, Rot4.Random, pawn.PositionHeld, pawn.MapHeld); if (hideyHoleResult != null && hideyHoleResult.Value.IsValid) { //Log.Message("Hidey Place"); return(new Job(VampDefOf.ROMV_DigAndHide, hideyHoleResult.Value) { locomotionUrgency = LocomotionUrgency.Sprint }); } } //bool nextMoveOrderIsWait = pawn.mindState.nextMoveOrderIsWait; //pawn.mindState.nextMoveOrderIsWait = !pawn.mindState.nextMoveOrderIsWait; //if (nextMoveOrderIsWait) //{ // return new Job(JobDefOf.WaitWander) // { // expiryInterval = this.ticksBetweenWandersRange.RandomInRange // }; //} //IntVec3 exactWanderDest = this.GetExactWanderDest(pawn); //if (!exactWanderDest.IsValid) //{ // pawn.mindState.nextMoveOrderIsWait = false; // return null; //} //pawn.Map.pawnDestinationManager.ReserveDestinationFor(pawn, exactWanderDest); //return new Job(JobDefOf.GotoWander, exactWanderDest) //{ // locomotionUrgency = this.locomotionUrgency //}; } return(null); }
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); } }
public static IEnumerable <IntVec3> CellsToBurn(IntVec3 center, Map map, float radius, IntVec3?needLOSToCell1 = null, IntVec3?needLOSToCell2 = null) { List <IntVec3> openCells = new List <IntVec3>(); List <IntVec3> adjWallCells = new List <IntVec3>(); int num = GenRadial.NumCellsInRadius(radius); for (int i = 0; i < num; i++) { IntVec3 intVec = center + GenRadial.RadialPattern[i]; if (intVec.InBounds(map) && GenSight.LineOfSight(center, intVec, map, true, null, 0, 0)) { if (needLOSToCell1 != null || needLOSToCell2 != null) { bool flag = needLOSToCell1 != null && GenSight.LineOfSight(needLOSToCell1.Value, intVec, map, false, null, 0, 0); bool flag2 = needLOSToCell2 != null && GenSight.LineOfSight(needLOSToCell2.Value, intVec, map, false, null, 0, 0); if (!flag && !flag2) { continue; } } openCells.Add(intVec); } } foreach (IntVec3 intVec2 in openCells) { if (intVec2.Walkable(map)) { for (int k = 0; k < 4; k++) { IntVec3 intVec3 = intVec2 + GenAdj.CardinalDirections[k]; if (intVec3.InHorDistOf(center, radius) && intVec3.InBounds(map) && !intVec3.Standable(map) && intVec3.GetEdifice(map) != null && !openCells.Contains(intVec3) && adjWallCells.Contains(intVec3)) { adjWallCells.Add(intVec3); } } } } return(openCells.Concat(adjWallCells)); }
public const float MaxExplosionScale = 10f; //as if 1000 shells exploded public static void DoExplosion(IntVec3 center, Map map, float radius, DamageDef damType, Thing instigator, int damAmount = -1, float armorPenetration = -1f, SoundDef explosionSound = null, ThingDef weapon = null, ThingDef projectile = null, Thing intendedTarget = null, ThingDef postExplosionSpawnThingDef = null, float postExplosionSpawnChance = 0f, int postExplosionSpawnThingCount = 1, bool applyDamageToExplosionCellsNeighbors = false, ThingDef preExplosionSpawnThingDef = null, float preExplosionSpawnChance = 0f, int preExplosionSpawnThingCount = 1, float chanceToStartFire = 0f, bool damageFalloff = false, float?direction = null, List <Thing> ignoredThings = null, float height = 0f, float scaleFactor = 1f, bool destroyAfterwards = false, ThingWithComps explosionParentToDestroy = null) { // Allows destroyed things to be exploded with appropriate scaleFactor if (scaleFactor <= 0f) { scaleFactor = 1f; } else { scaleFactor = Mathf.Clamp(scaleFactor, MinExplosionScale, MaxExplosionScale); } if (map == null) { Log.Warning("CombatExtended :: Tried to do explosionCE in a null map."); return; } if (damAmount < 0) { damAmount = damType.defaultDamage; armorPenetration = damType.defaultArmorPenetration; if (damAmount < 0) { Log.ErrorOnce("CombatExtended :: Attempted to trigger an explosionCE without defined damage", 910948823); damAmount = 1; } } explosionSound = explosionSound ?? damType.soundExplosion; if (explosionSound == null) { Log.Error("CombatExtended :: SoundDef was null for DamageDef " + damType.defName + " as well as instigator " + instigator.ThingID); } damAmount = Mathf.RoundToInt(damAmount * scaleFactor); radius *= scaleFactor; armorPenetration *= scaleFactor; ExplosionCE explosion = GenSpawn.Spawn(CE_ThingDefOf.ExplosionCE, center, map) as ExplosionCE; IntVec3? needLOSToCell = null; IntVec3? needLOSToCell2 = null; if (direction.HasValue) { CalculateNeededLOSToCells(center, map, direction.Value, out needLOSToCell, out needLOSToCell2); } explosion.height = height; explosion.radius = radius; explosion.damType = damType; explosion.instigator = instigator; explosion.damAmount = damAmount; explosion.armorPenetration = armorPenetration; explosion.weapon = weapon; explosion.projectile = projectile; explosion.intendedTarget = intendedTarget; explosion.preExplosionSpawnThingDef = preExplosionSpawnThingDef; explosion.preExplosionSpawnChance = preExplosionSpawnChance; explosion.preExplosionSpawnThingCount = preExplosionSpawnThingCount; explosion.postExplosionSpawnThingDef = postExplosionSpawnThingDef; explosion.postExplosionSpawnChance = postExplosionSpawnChance; explosion.postExplosionSpawnThingCount = postExplosionSpawnThingCount; explosion.applyDamageToExplosionCellsNeighbors = applyDamageToExplosionCellsNeighbors; explosion.chanceToStartFire = chanceToStartFire; explosion.damageFalloff = damageFalloff; explosion.needLOSToCell1 = needLOSToCell; explosion.needLOSToCell2 = needLOSToCell2; explosion.StartExplosionCE(explosionSound, ignoredThings); // Needed to allow CompExplosive to use stackCount if (destroyAfterwards && !explosionParentToDestroy.Destroyed) { explosionParentToDestroy?.Kill(); } }
public static void Raid(this Quest quest, Map map, float points, Faction faction, string inSignalLeave = null, string customLetterLabel = null, string customLetterText = null, RulePack customLetterLabelRules = null, RulePack customLetterTextRules = null, IntVec3?walkInSpot = null, string tag = null, string inSignal = null, string rootSymbol = "root", PawnsArrivalModeDef raidArrivalMode = null) { QuestPart_Incident questPart_Incident = new QuestPart_Incident(); questPart_Incident.debugLabel = "raid"; questPart_Incident.incident = IncidentDefOf.RaidEnemy; IncidentParms incidentParms = new IncidentParms(); incidentParms.forced = true; incidentParms.target = map; incidentParms.points = Mathf.Max(points, faction.def.MinPointsToGeneratePawnGroup(PawnGroupKindDefOf.Combat)); incidentParms.faction = faction; incidentParms.pawnGroupMakerSeed = Rand.Int; incidentParms.inSignalEnd = inSignalLeave; incidentParms.questTag = QuestGenUtility.HardcodedTargetQuestTagWithQuestID(tag); incidentParms.raidArrivalMode = raidArrivalMode; if (!customLetterLabel.NullOrEmpty() || customLetterLabelRules != null) { QuestGen.AddTextRequest(rootSymbol, delegate(string x) { incidentParms.customLetterLabel = x; }, QuestGenUtility.MergeRules(customLetterLabelRules, customLetterLabel, rootSymbol)); } if (!customLetterText.NullOrEmpty() || customLetterTextRules != null) { QuestGen.AddTextRequest(rootSymbol, delegate(string x) { incidentParms.customLetterText = x; }, QuestGenUtility.MergeRules(customLetterTextRules, customLetterText, rootSymbol)); } IncidentWorker_Raid obj = (IncidentWorker_Raid)questPart_Incident.incident.Worker; obj.ResolveRaidStrategy(incidentParms, PawnGroupKindDefOf.Combat); obj.ResolveRaidArriveMode(incidentParms); if (incidentParms.raidArrivalMode.walkIn) { incidentParms.spawnCenter = walkInSpot ?? QuestGen.slate.Get <IntVec3?>("walkInSpot") ?? IntVec3.Invalid; } PawnGroupMakerParms defaultPawnGroupMakerParms = IncidentParmsUtility.GetDefaultPawnGroupMakerParms(PawnGroupKindDefOf.Combat, incidentParms); defaultPawnGroupMakerParms.points = IncidentWorker_Raid.AdjustedRaidPoints(defaultPawnGroupMakerParms.points, incidentParms.raidArrivalMode, incidentParms.raidStrategy, defaultPawnGroupMakerParms.faction, PawnGroupKindDefOf.Combat); IEnumerable <PawnKindDef> pawnKinds = PawnGroupMakerUtility.GeneratePawnKindsExample(defaultPawnGroupMakerParms); questPart_Incident.SetIncidentParmsAndRemoveTarget(incidentParms); questPart_Incident.inSignal = inSignal ?? QuestGen.slate.Get <string>("inSignal"); QuestGen.quest.AddPart(questPart_Incident); QuestGen.AddQuestDescriptionRules(new List <Rule> { new Rule_String("raidPawnKinds", PawnUtility.PawnKindsToLineList(pawnKinds, " - ", ColoredText.ThreatColor)), new Rule_String("raidArrivalModeInfo", incidentParms.raidArrivalMode.textWillArrive.Formatted(faction)) }); }
public override IEnumerable <Gizmo> GetGizmos() { foreach (var item in base.GetGizmos()) { yield return(item); } yield return(new Command_Action() { defaultLabel = "RF.DL.ChangeShellLabel".Translate(), defaultDesc = "RF.DL.ChangeShellDesc".Translate(), action = () => { Func <ThingDef, string> labelGetter = shell => shell.LabelCap; Func <ThingDef, Action> actionGetter = shell => { if (shell == CurrentShellDef) { return null; } return () => { EjectLoadedShells(); CurrentShellDef = shell; }; }; FloatMenuUtility.MakeMenu(LoadableBombs, labelGetter, actionGetter); }, icon = CurrentShellDef?.uiIcon }); yield return(new Command_TargetCustom() { times = 2, defaultLabel = "RF.DL.TargetLabel".Translate(), defaultDesc = "RF.DL.TargetDesc".Translate(), icon = Content.MissilesIcon, defaultIconColor = Color.yellow, disabled = drawAffectedCells || isBlocked || LoadedShellCount < 1, disabledReason = LoadedShellCount < 1 ? "RF.DL.NoShells".Translate() : isBlocked ? "RF.DL.Blocked".Translate(blockedBy) : "RF.DL.AlreadyTargeting".Translate(), continueCheck = () => keepGoing, action = (t, i) => { if (!t.IsValid) { return; } if (LoadedShellCount == 1) { firstPosition = t.Cell; secondPosition = t.Cell; keepGoing = false; } else { if (i == 0) { firstPosition = t.Cell; keepGoing = true; } else { secondPosition = t.Cell; } } if (i == 1 || LoadedShellCount == 1) { const float MIN_DST = 5f; bool hasDistance = LoadedShellCount == 1 || (firstPosition.Value - secondPosition.Value).LengthHorizontal >= MIN_DST; if (hasDistance) { DoStrike(); } else { Messages.Message("RF.DL.NotEnoughDistance".Translate(MIN_DST), MessageTypeDefOf.RejectInput, false); } firstPosition = null; secondPosition = null; } }, user = this, targetingParams = new TargetingParameters() { canTargetLocations = true, canTargetPawns = false, canTargetFires = false, mapObjectTargetsMustBeAutoAttackable = false } }); }
//Exact copy (1.1) private static void CalculateNeededLOSToCells(IntVec3 position, Map map, float direction, out IntVec3?needLOSToCell1, out IntVec3?needLOSToCell2) { needLOSToCell1 = null; needLOSToCell2 = null; if (position.CanBeSeenOverFast(map)) { return; } direction = GenMath.PositiveMod(direction, 360f); IntVec3 intVec = position; intVec.z++; IntVec3 intVec2 = position; intVec2.z--; IntVec3 intVec3 = position; intVec3.x--; IntVec3 intVec4 = position; intVec4.x++; if (direction < 90f) { if (intVec3.InBounds(map) && intVec3.CanBeSeenOverFast(map)) { needLOSToCell1 = new IntVec3?(intVec3); } if (intVec.InBounds(map) && intVec.CanBeSeenOverFast(map)) { needLOSToCell2 = new IntVec3?(intVec); return; } } else if (direction < 180f) { if (intVec.InBounds(map) && intVec.CanBeSeenOverFast(map)) { needLOSToCell1 = new IntVec3?(intVec); } if (intVec4.InBounds(map) && intVec4.CanBeSeenOverFast(map)) { needLOSToCell2 = new IntVec3?(intVec4); return; } } else if (direction < 270f) { if (intVec4.InBounds(map) && intVec4.CanBeSeenOverFast(map)) { needLOSToCell1 = new IntVec3?(intVec4); } if (intVec2.InBounds(map) && intVec2.CanBeSeenOverFast(map)) { needLOSToCell2 = new IntVec3?(intVec2); return; } } else { if (intVec2.InBounds(map) && intVec2.CanBeSeenOverFast(map)) { needLOSToCell1 = new IntVec3?(intVec2); } if (intVec3.InBounds(map) && intVec3.CanBeSeenOverFast(map)) { needLOSToCell2 = new IntVec3?(intVec3); } } }
private void CentaurAlphaShipPostProcess(Map spaceMap) { spaceMap.fogGrid.ClearAllFog(); /*foreach (Letter letter in Find.LetterStack.LettersListForReading) * { * Find.LetterStack.RemoveLetter(letter); * }*/ List <Thing> things = spaceMap.listerThings.AllThings; Thing targetTorpedo = null; IntVec3 torpedoToLocation = new IntVec3(0, 0, 0); IntVec3? sunLampLocation = null; foreach (Thing thing in things) { try { if (thing.def == ThingDefOf.MinifiedThing) { Thing thingInside = ((MinifiedThing)thing).InnerThing; if (thingInside.TryGetComp <CompPowerBattery>() != null) { thingInside?.TryGetComp <CompPowerBattery>()?.AddEnergy(float.PositiveInfinity); } } if (sunLampLocation == null && thing.def == DefDatabase <ThingDef> .GetNamed("SunLamp")) { sunLampLocation = thing.Position; } if (thing?.TryGetComp <CompForbiddable>() != null) { thing.TryGetComp <CompForbiddable>().Forbidden = false; } if (thing?.TryGetComp <CompQuality>() != null) { thing.TryGetComp <CompQuality>().SetQuality(QualityCategory.Legendary, ArtGenerationContext.Colony); } if (thing?.TryGetComp <CompArt>() != null) { thing.TryGetComp <CompArt>().JustCreatedBy(spaceMap.mapPawns.AllPawns.RandomElement()); } if (thing?.TryGetComp <CompRefuelable>() != null) { //thing.def == DefDatabase<ThingDef>.GetNamed("Ship_Engine_Small") || //thing.def == DefDatabase<ThingDef>.GetNamed("Ship_Engine") || //thing.def == DefDatabase<ThingDef>.GetNamed("Ship_Engine_Large") CompRefuelable fuelTarget = thing?.TryGetComp <CompRefuelable>(); fuelTarget?.Refuel(fuelTarget.Props.fuelCapacity); } if (thing?.TryGetComp <CompTempControl>() != null) { thing.TryGetComp <CompTempControl>().targetTemperature = 19f; } if (thing?.TryGetComp <CompBreakdownable>() != null) { } if (thing?.TryGetComp <CompPower>() != null) { } if ( thing?.def?.building?.buildingTags?.Contains("Production") == true && thing?.TryGetComp <CompFlickable>() != null && thing.def != DefDatabase <ThingDef> .GetNamed("HydroponicsBasin") ) { thing.TryGetComp <CompFlickable>().SwitchIsOn = false; } if (thing.def == DefDatabase <ThingDef> .GetNamed("HydroponicsBasin")) { ((Building_PlantGrower)thing)?.SetPlantDefToGrow(ThingDefOf.Plant_Potato); thing.TryGetComp <CompForbiddable>().Forbidden = true; } if (thing.def == ThingDefOf.Blight) { ((Blight)thing).Severity = 0.05f; } if (thing.def == DefDatabase <ThingDef> .GetNamed("ShipCombatShieldGenerator")) { thing.TryGetComp <CompFlickable>().SwitchIsOn = false; thing.TryGetComp <CompBreakdownable>()?.DoBreakdown(); } if (thing.def == DefDatabase <ThingDef> .GetNamed("ShipTurret_Laser")) { ((Building_ShipTurret)thing).PointDefenseMode = true; } if (thing.def == DefDatabase <ThingDef> .GetNamed("Plant_Potato")) { ((Plant)thing).Growth = 0.85f; } /*if (thing.def == DefDatabase<ThingDef>.GetNamed("ShipTorpedoOne")) * { * foreach (Thing thingInside in ((Building_ShipTurretTorpedo)thing).Contents.innerContainer) * { * if (thing.def == DefDatabase<ThingDef>.GetNamed("ShipTorpedo_HighExplosive")) * { * thing.def = DefDatabase<ThingDef>.GetNamed("ShipTorpedo_EMP"); * } * } * }*/ if ( thing.def == DefDatabase <ThingDef> .GetNamed("ComponentIndustrial") || thing.def == DefDatabase <ThingDef> .GetNamed("ShipTorpedo_HighExplosive") || thing.def == DefDatabase <ThingDef> .GetNamed("ShipTorpedo_EMP") || thing.def == DefDatabase <ThingDef> .GetNamed("Chemfuel") || thing.def == DefDatabase <ThingDef> .GetNamed("ShuttleFuelPods") || thing.def == DefDatabase <ThingDef> .GetNamed("WoodLog") || thing.def == DefDatabase <ThingDef> .GetNamed("Shell_EMP") ) { //Log.Message("[Explorite]Patching stack."); thing.stackCount = thing.def.stackLimit; foreach (Thing thingInGrid in spaceMap.thingGrid.ThingsAt(thing.Position)) { if (thingInGrid.def == DefDatabase <ThingDef> .GetNamed("Shelf")) { ((Building_Storage)thingInGrid).settings.filter.SetDisallowAll(); ((Building_Storage)thingInGrid).settings.filter.SetAllow(thing.def, true); } } } /*if (thing.def == DefDatabase<ThingDef>.GetNamed("ShipTorpedo_HighExplosive")) * { * //Log.Message("[Explorite]Patching HE."); * thing.stackCount = 1; * //thing.def = DefDatabase<ThingDef>.GetNamed("ShipTorpedo_EMP"); * }*/ if (thing.def == DefDatabase <ThingDef> .GetNamed("Shelf")) { torpedoToLocation.z = Math.Max(thing.Position.z, torpedoToLocation.z); } if (thing.def == DefDatabase <ThingDef> .GetNamed("ShipTorpedo_HighExplosive")) { torpedoToLocation.x = Math.Max(thing.Position.x, torpedoToLocation.x); if (targetTorpedo == null) { targetTorpedo = thing; } else if (thing.Position.z > targetTorpedo.Position.z) { targetTorpedo = thing; } } for (int i = -4; i < 5; i++) { for (int j = -4; j < 5; j++) { spaceMap.areaManager.Home[new IntVec3(i, 0, j) + thing.Position] = true; } } } catch { } } targetTorpedo.Position = torpedoToLocation; /* * Thing InterplanetaryEngineL = ThingMaker.MakeThing(ThingDef.Named("Ship_Engine_Interplanetary")); * InterplanetaryEngineL.SetFaction(Faction.OfPlayer); * GenSpawn.Spawn(InterplanetaryEngineL, new IntVec3(-18,0,-28), spaceMap); * Thing InterplanetaryEngineR = ThingMaker.MakeThing(ThingDef.Named("Ship_Engine_Interplanetary")); * InterplanetaryEngineR.SetFaction(Faction.OfPlayer); * GenSpawn.Spawn(InterplanetaryEngineR, new IntVec3(18,0,-28), spaceMap); * //((Blueprint_Build)InterplanetaryEngineL).; */ if (false && sunLampLocation.HasValue) { IntVec3 leftEngine = new IntVec3(sunLampLocation.Value.ToVector3()); leftEngine.x -= 18; leftEngine.z -= 17; IntVec3 rightEngine = new IntVec3(sunLampLocation.Value.ToVector3()); leftEngine.x += 18; rightEngine.z -= 17; Thing InterplanetaryEngineL = ThingMaker.MakeThing(ThingDef.Named("Blueprint_Ship_Engine_Interplanetary")); InterplanetaryEngineL.SetFaction(Faction.OfPlayer); GenSpawn.Spawn(InterplanetaryEngineL, leftEngine, spaceMap); Thing InterplanetaryEngineR = ThingMaker.MakeThing(ThingDef.Named("Blueprint_Ship_Engine_Interplanetary")); InterplanetaryEngineR.SetFaction(Faction.OfPlayer); GenSpawn.Spawn(InterplanetaryEngineR, rightEngine, spaceMap); } /* * List<Building> thingsRocket = spaceMap.listerBuildings.allBuildingsColonist; * foreach (Building thing in thingsBatteryIn) * { * try * { * if ( * thing?.TryGetComp<CompRefuelable>() != null * //thing.def == DefDatabase<ThingDef>.GetNamed("Ship_Engine_Small") || * //thing.def == DefDatabase<ThingDef>.GetNamed("Ship_Engine") || * //thing.def == DefDatabase<ThingDef>.GetNamed("Ship_Engine_Large") * ) * { * CompRefuelable fuelTarget = thing?.TryGetComp<CompRefuelable>(); * fuelTarget.ConsumeFuel( * fuelTarget.Fuel - * fuelTarget.Props.fuelCapacity * ); * } * } * catch { } * }*/ }