private PawnKindDef ResolveTransformationKind(out HediffDef zHDef) { var zombieInfo = ZombieUtility.GetPawnKindDefForRandomResurrectedZombie(); zHDef = zombieInfo.zHediff; return(zombieInfo.zKind); }
//Zombies will "shamble" public static void CostToMoveIntoCell_PostFix(Pawn pawn, IntVec3 c, ref int __result) { if (ZombieUtility.IsZombie(pawn)) { var cHead = pawn?.kindDef?.defName == "RE_CrimsonHeadKind"; var randPct = Rand.Range(0.4f * (cHead ? 0.2f : 1f), 3.2f * (cHead ? 0.5f : 1f)); __result = Mathf.Clamp((int)(__result * randPct), 1, int.MaxValue); } }
//Zombies don't receive thoughts public static bool CanGetThought_PreFix(Pawn pawn, ThoughtDef def, ref bool __result) { if (ZombieUtility.IsZombie(pawn)) { __result = false; return(false); } return(true); }
// RimWorld.GenHostility public static void HostileTo_PostFix(Thing a, Thing b, ref bool __result) { if (a != null && b != null) { if (a is Pawn pawnA && b is Pawn pawnB) { if (ZombieUtility.IsZombie(pawnA) && !ZombieUtility.IsZombie(pawnB)) { __result = true; } } } }
private bool ResolveTransformations() { if (!hadTransformationChance) { hadTransformationChance = true; if (Rand.Value <= RESettings.MUTATION_CHANCE) { var curLoc = this.PositionHeld; var curMap = this.MapHeld; var zFaction = Find.FactionManager.FirstFactionOfDef(FactionDef.Named("RE_Zombies")); HediffDef zHDef; PawnKindDef zKind = ResolveTransformationKind(out zHDef); Pawn newThing; if (zKind.defName != "RE_CrimsonHeadKind") { this.Destroy(); FilthMaker.TryMakeFilth(curLoc, curMap, ThingDefOf.Filth_Blood, Rand.Range(5, 8)); newThing = PawnGenerator.GeneratePawn(zKind, zFaction); } else { //The function here actually destroys the zombie var facName = this?.Faction?.def?.defName ?? "RE_Zombies"; newThing = ZombieUtility.CreateZombieAtSourcePawnLocation(this, "RE_CrimsonHeadKind", facName); } HealthUtility.AdjustSeverity(newThing, zHDef, 1.0f); GenSpawn.Spawn(newThing, curLoc, curMap); ((Zombie)newThing).hadTransformationChance = true; return(true); } } return(false); }
public override void Tick() { try { if (DebugSettings.noAnimals && base.RaceProps.Animal) { this.Destroy(0); } if (this.needs != null && this.needs.mood != null) { this.needs.mood = null; } else if (!base.Downed) { if (Find.TickManager.TicksGame % 250 == 0) { var zombieDangerMap = this.Map.GetComponent <ZombieDangerMap>(); if (!zombieDangerMap.regionDangers.ContainsKey(this.GetRegion())) { zombieDangerMap.regionDangers.Add(this.GetRegion(), 1000); } zombieDangerMap.regionDangers[this.GetRegion()] += 1000; foreach (var reg in this.GetRegion().Neighbors) { if (!zombieDangerMap.regionDangers.ContainsKey(reg)) { zombieDangerMap.regionDangers.Add(reg, 1000); } zombieDangerMap.regionDangers[reg] += 510; } this.TickRare(); } if (base.Spawned) { this.pather.PatherTick(); rotationTracker.RotationTrackerTick(); } base.Drawer.DrawTrackerTick(); this.health.HealthTick(); this.records.RecordsTick(); if (base.Spawned) { this.stances.StanceTrackerTick(); this.verbTracker.VerbsTick(); this.natives.NativeVerbsTick(); } if (this.equipment != null) { this.equipment.EquipmentTrackerTick(); } if (this.apparel != null) { this.apparel.ApparelTrackerTick(); } if (base.Spawned) { this.jobs.JobTrackerTick(); } if (!base.Dead) { this.carryTracker.CarryHandsTick(); } if (this.skills != null) { this.skills.SkillsTick(); } if (this.inventory != null) { this.inventory.InventoryTrackerTick(); } } if (this.needs != null && this.needs.food != null && this.needs.food.CurLevel <= 0.95f) { this.needs.food.CurLevel = 1f; } if (this.needs != null && this.needs.joy != null && this.needs.joy.CurLevel <= 0.95f) { this.needs.joy.CurLevel = 1f; } if (this.needs != null && this.needs.beauty != null && this.needs.beauty.CurLevel <= 0.95f) { this.needs.beauty.CurLevel = 1f; } if (this.needs != null && this.needs.comfort != null && this.needs.comfort.CurLevel <= 0.95f) { this.needs.comfort.CurLevel = 1f; } if (this.needs != null && this.needs.rest != null && this.needs.rest.CurLevel <= 0.95f) { this.needs.rest.CurLevel = 1f; } if (this.needs != null && this.needs.mood != null && this.needs.mood.CurLevel <= 0.45f) { this.needs.mood.CurLevel = 0.5f; } if (!this.setZombie) { this.mindState.mentalStateHandler.neverFleeIndividual = true; this.setZombie = ZombieUtility.Zombify(this); //ZombieMod_Utility.SetZombieName(this); } if (base.Downed || this.health.Downed || this.health.InPainShock) { if (intervalUntilTransformation == -1) { intervalUntilTransformation = Find.TickManager.TicksGame + new IntRange(RESettings.DOWNZOMBIE_TRANSFORM_INTERVAL_MIN, RESettings.DOWNZOMBIE_TRANSFORM_INTERVAL_MAX).RandomInRange; } if (Find.TickManager.TicksGame > intervalUntilTransformation) { if (ResolveTransformations()) { return; } } //DamageInfo damageInfo = new DamageInfo(DamageDefOf.Blunt, 9999, 1f, -1f, this, null, null); //damageInfo.SetHitPart(this.health.hediffSet.GetBrain()); //damageInfo.SetPart(new BodyPartDamageInfo(this.health.hediffSet.GetBrain(), false, HediffDefOf.Cut)); //base.TakeDamage(damageInfo); } } catch (Exception) { } }
public override void MapComponentTick() { base.MapComponentTick(); //Bring back some of the dead if (Find.TickManager.TicksGame % 500 == 0) { if (deadToRise != null && deadToRise?.Count > 0) { HashSet <Pawn> risen = new HashSet <Pawn>(); foreach (var dtr in deadToRise) { if (dtr.Value < Find.TickManager.TicksGame) { if (dtr.Key.Dead) { ResurrectionUtility.Resurrect(dtr.Key); } risen.Add(dtr.Key); } } if (risen != null && risen?.Count() > 0) { foreach (var r in risen) { deadToRise.RemoveAll(x => x.Key == r); } } } } //Only perform this action after a certain time if (Find.TickManager.TicksGame % RESettings.RESSURECTION_TIME == 0) { //Log.Message($"ZT Tick : { Find.TickManager.TicksGame}"); //If no infected dead locations exist, we shouldn't continue if (infectedDeadLocations == null || infectedDeadLocations.Count <= 0) { return; } //Log.Message($"ZT Pass 1"); //Clean out destroyed corpses, and then exit if none remain infectedDeadLocations.RemoveAll(x => x.Value == null); if (infectedDeadLocations == null || infectedDeadLocations.Count <= 0) { return; } //Log.Message($"ZT Pass 2"); //Check all active humanoid pawns. // If any are setting foot on infectedDeadLocations, // then trigger zombies based on percentages. var humanoids = (from p in map.mapPawns.AllPawnsSpawned where !p.NonHumanlikeOrWildMan() select p).ToArray(); //Log.Message($"ZT Pass 3"); //Track new resurrections HashSet <Pawn> toBeResurrected = new HashSet <Pawn>(); for (int i = 0; i < humanoids?.Count(); i++) { var humanoid = humanoids[i]; if (toBeResurrected.Contains(humanoid)) { continue; } if (infectedDeadLocations.Keys.Contains(humanoid.PositionHeld)) { ////30% chance of resurrection //if (Rand.Range(0.0f, 1.0f) < 0.6f) // continue; //Add zombie to be resurrected var newZombie = infectedDeadLocations[humanoid.PositionHeld]; toBeResurrected.Add(newZombie); } } //Log.Message($"ZT Pass 4"); //Resurrect each lucky new zombie if (toBeResurrected == null || toBeResurrected?.Count <= 0) { return; } foreach (var newZombie in toBeResurrected) { //Log.Message($"ZT {newZombie.Label} resurected"); ZombieUtility.CreateZombieAtSourcePawnLocation(newZombie); infectedDeadLocations.RemoveAll(x => x.Value == newZombie); } //Log.Message($"ZT Pass Complete"); } }