// make zombies die if necessary ============================================================ // public static bool ShouldDie(this JobDriver_Stumble driver, Zombie zombie) { if (zombie.Dead || zombie.Spawned == false) { driver.EndJobWith(JobCondition.InterruptForced); return(true); } if (zombie.state == ZombieState.ShouldDie) { driver.EndJobWith(JobCondition.InterruptForced); zombie.Kill(null); return(true); } if (zombie.IsSuicideBomber) { if (zombie.bombWillGoOff && zombie.EveryNTick(NthTick.Every10)) { zombie.bombTickingInterval -= 2f; } if (zombie.bombTickingInterval <= 0f) { zombie.Kill(null); return(true); } } if (zombie.EveryNTick(NthTick.Every10)) { if (ZombieSettings.Values.zombiesDieVeryEasily) { if (zombie.hasTankySuit <= 0f && zombie.health.hediffSet.GetHediffs <Hediff_Injury>().Any()) { zombie.Kill(null); return(true); } } else { var hediffs = zombie.health.hediffSet.hediffs .Where(hediff => hediff.def == HediffDefOf.WoundInfection) .ToArray(); foreach (var hediff in hediffs) { zombie.health.RemoveHediff(hediff); } } } return(false); }
// subroutines ============================================================================== static Thing CanIngest(Zombie zombie) { if (zombie.EveryNTick(NthTick.Every2) == false) { return(null); } if (ZombieSettings.Values.zombiesEatDowned || ZombieSettings.Values.zombiesEatCorpses) { var enumerator = GetAdjacted <ThingWithComps>(zombie).GetEnumerator(); while (enumerator.MoveNext()) { var twc = enumerator.Current; if (twc is Pawn p && ZombieSettings.Values.zombiesEatDowned) { if (p.Spawned && p.RaceProps.IsFlesh && (p.Downed || p.Dead)) { return(p); } } if (twc is Corpse c && ZombieSettings.Values.zombiesEatCorpses) { if (c.Spawned && c.InnerPawn != null && c.InnerPawn.RaceProps.IsFlesh) { return(c); } } } } return(null); }
public static bool Track(this JobDriver_Stumble driver, Zombie zombie, PheromoneGrid grid) { if (zombie.EveryNTick(NthTick.Every60) || fadeOff == -1) { fadeOff = Tools.PheromoneFadeoff(); wasColonistFadeoff = fadeOff / 6; agitatedFadeoff = fadeOff / 4; checkSmashableFadeoff1 = agitatedFadeoff / 4; checkSmashableFadeoff2 = agitatedFadeoff * 3 / 4; } var trackingMoves = new List <IntVec3>(8); var currentTicks = Tools.Ticks(); var timeDelta = long.MaxValue; var fmin = long.MaxValue; if (zombie.raging == 0) { for (var i = 0; i < 8; i++) { var pos = zombie.Position + GenAdj.AdjacentCells[i]; if (zombie.HasValidDestination(pos)) { var f = zombie.wasMapPawnBefore ? wasColonistFadeoff : fadeOff; var tdiff = currentTicks - grid.GetTimestamp(pos); fmin = Math.Min(fmin, tdiff); if (tdiff < f) { trackingMoves.Add(pos); } } } } if (trackingMoves.Count > 0) { trackingMoves.Sort((p1, p2) => grid.GetTimestamp(p2).CompareTo(grid.GetTimestamp(p1))); trackingMoves = trackingMoves.Take(Constants.NUMBER_OF_TOP_MOVEMENT_PICKS).ToList(); trackingMoves = trackingMoves.OrderBy(p => grid.GetZombieCount(p)).ToList(); var nextMove = trackingMoves.First(); timeDelta = currentTicks - (grid.GetTimestamp(nextMove)); driver.destination = nextMove; if (zombie.state == ZombieState.Wandering) { Tools.ChainReact(zombie.Map, zombie.Position, nextMove); if (timeDelta <= agitatedFadeoff) { CastBrainzThought(zombie); } } zombie.state = ZombieState.Tracking; } if (driver.destination.IsValid == false) { zombie.state = ZombieState.Wandering; } if (zombie.wasMapPawnBefore) { return(true); } var checkSmashable = timeDelta >= checkSmashableFadeoff1 && timeDelta < checkSmashableFadeoff2; if (ZombieSettings.Values.smashOnlyWhenAgitated) { checkSmashable &= (zombie.state == ZombieState.Tracking || zombie.raging > 0); } return(checkSmashable); }