private IEnumerable <Thing> FindFireInRoomAndDistance(IntVec3 position, float distance) { Room room = RoomQuery.RoomAt(position); if (room == null) { IEnumerable <IntVec3> founds = GenAdj.AdjacentSquares8WayAndInside(position); foreach (IntVec3 found in founds) { if (RoomQuery.RoomAt(found) != null) { room = RoomQuery.RoomAt(found); break; } } } IEnumerable <Thing> fires = Find.ListerThings.ThingsOfDef(ThingDefOf.Fire); if (fires == null) { return(fires); } // Correction here: (room == room OR room == null) && within distance else { return(fires.Where <Thing>(t => (room == RoomQuery.RoomAt(t.Position) || RoomQuery.RoomAt(t.Position) == null) && t.Position.WithinHorizontalDistanceOf(position, distance))); } }
protected override void Impact(Thing hitThing) { if (hitThing == null) { } else { foreach (IntVec3 current in GenAdj.AdjacentSquares8WayAndInside(hitThing.Position)) { MoteMaker.ThrowDustPuff(current, 2f); Thing t = GenAI.BestAttackTarget(hitThing.Position, this, new Predicate <Thing>(this.IsValidTarget), 2f, 0f, false, false, false, true); Pawn pawn = t as Pawn; pawn.thinker.mindState.Sanity.Equals(SanityState.Psychotic); } } }
protected override IEnumerable <Toil> MakeNewToils() { Toil wait = new Toil(); wait.initAction = () => { Find.PawnDestinationManager.ReserveDestinationFor(pawn, pawn.Position); pawn.pather.StopDead(); }; wait.tickAction = () => { if ((Find.TickManager.tickCount + pawn.thingIDNumber) % TargetSearchInterval != 0) { return; } if (pawn.story == null || !pawn.story.WorkTagIsDisabled(WorkTags.Violent)) { //Melee attack adjacent enemy pawns //Barring that, put out fires foreach (IntVec3 neigh in GenAdj.AdjacentSquares8WayAndInside(pawn.Position)) { Fire foundFire = null; foreach (Thing t in Find.ThingGrid.ThingsAt(neigh)) { Pawn p = t as Pawn; if (p != null && pawn.HostileTo(p) && !p.Incapacitated) { pawn.natives.TryMeleeAttack(p); return; } //Note: It checks our position first, so we keep our first found fire //This way, we prioritize a fire we're standing on Fire f = t as Fire; if (f != null && foundFire == null) { foundFire = f; } } if (foundFire != null) { pawn.natives.TryBeatFire(foundFire); } } //Shoot at the closest enemy in range if (pawn.equipment != null && pawn.equipment.primary != null) { //We increase the range because we can hit targets slightly outside range by shooting at their ShootableSquares //We could just put the range at int.MaxValue but this is slightly more optimized so whatever Thing curTarg = pawn.ClosestReachableEnemyTarget (validator: null, maxDistance: pawn.equipment.primary.verb.verbProps.range, needsLOStoDynamic: true, needsLOStoStatic: true); if (curTarg != null) { pawn.equipment.TryStartAttack(curTarg); return; } } ; } }; wait.defaultCompleteMode = ToilCompleteMode.Never; yield return(wait); }