public void TryStartSpawn() { if (CheckIfShouldSpawn() != true) { this.startOfIncubation += 250; return; } if (tickStartHediff > 0 && this.startOfIncubation + this.Props.IncubationData.tickStartHediff.RandomInRange < Find.TickManager.TicksGame) { if (this.parent is Pawn && this.Props.IncubationData.hediff != null) { var hediff = HediffMaker.MakeHediff(HediffDef.Named(this.Props.IncubationData.hediff), (Pawn)this.parent, null); ((Pawn)this.parent).health.AddHediff(hediff, null, null, null); this.tickStartHediff = 0; } } DoWiggle(); if (this.Props.incubationPeriod.min > 0) { if (this.startOfIncubation + this.Props.incubationPeriod.RandomInRange < Find.TickManager.TicksGame) { if (this.maxNumberOfCreatures <= this.currentCountOfCreatures && this.Props.resetIncubation == true) { this.startOfIncubation = Find.TickManager.TicksGame; this.currentCountOfCreatures = 0; this.maxNumberOfCreatures = this.Props.maxNumberOfCreatures.RandomInRange; } if (this.startOfIncubation + this.Props.incubationPeriod.RandomInRange + this.Props.ticksPerSpawn.RandomInRange > Find.TickManager.TicksGame) { return; } } else { return; } } if (this.Props.typesOfCreatures == null) { return; } if (this.maxNumberOfCreatures != 0 && currentCountOfCreatures >= this.maxNumberOfCreatures) { return; } foreach (var newPawn in from defName in this.Props.typesOfCreatures let numberOfSpawn = this.Props.numberOfCreaturesPerSpawn.RandomInRange where numberOfSpawn > 0 from i in Enumerable.Range(0, numberOfSpawn) select PawnKindDef.Named(defName) into pawnKindDef select PawnGenerator.GeneratePawn(pawnKindDef, null)) { Log.Message(this.parent + " produces " + newPawn, true); if (this.Props.ageTick.RandomInRange > 0) { var ageTick = this.Props.ageTick.RandomInRange; newPawn.ageTracker.AgeBiologicalTicks = ageTick; newPawn.ageTracker.AgeChronologicalTicks = ageTick; } else { newPawn.ageTracker.AgeBiologicalTicks = 0; newPawn.ageTracker.AgeChronologicalTicks = 0; } Alien alien = newPawn as Alien; switch (this.parent) { case Corpse _: HatchFromCorpse(newPawn); break; case Pawn _: HatchFromPawn(newPawn); break; case Building _: GenSpawn.Spawn(newPawn, this.parent.Position, this.parent.Map); if (alien.def == PurpleIvyDefOf.Genny_ParasiteOmega) { alien.canHaul = true; } break; default: Log.Error("Unknown parent. Cant spawn. Parent: " + this.parent); break; } if (alien.def == PurpleIvyDefOf.Genny_ParasiteNestGuard) { alien.canGuard = true; alien.SetFocus(); alien.health.AddHediff(PurpleIvyDefOf.PI_Regen); } currentCountOfCreatures++; } }
protected override Job TryGiveJob(Pawn pawn) { if (Find.TickManager.TicksGame < PrevTick + 10) { return(null); } PrevTick = Find.TickManager.TicksGame; if (GridsUtility.Fogged(pawn.Position, pawn.Map)) { return(JobMaker.MakeJob(JobDefOf.LayDown)); } Alien alien = pawn as Alien; // Some optimizations here... //if (pawn.TryGetAttackVerb(null, false) == null) //{ // return null; //} if (pawn.CurJob != null) { Log.Message(pawn + " - " + pawn.CurJob.def.defName); } Pawn pawn2 = null; if ((Find.TickManager.TicksGame - alien.lastAttacked) < 1000) { pawn2 = alien.lastInstigator; } else if ((Find.TickManager.TicksGame - pawn.Map.GetComponent <MapComponent_MapEvents>().LastAttacked) < 1000) { pawn2 = FindPawnTargetNearPlants(pawn); } else { pawn2 = FindPawnTarget(pawn); } if (pawn2 == null) { if (pawn.GetRoom() != null && !pawn.GetRoom().PsychologicallyOutdoors) { Predicate <Thing> validator = delegate(Thing t) { return(t.def.defName.ToLower().Contains("door")); }; var door = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.Touch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false) , 5f, validator); if (door != null) { return(PurpleIvyUtils.MeleeAttackJob(pawn, door)); } else { Predicate <Thing> validator2 = delegate(Thing t) { return(t.def.defName.ToLower().Contains("wall")); }; var wall = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.Touch, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false) , 5f, validator2); if (wall != null) { return(PurpleIvyUtils.MeleeAttackJob(pawn, wall)); } } } } else if (!pawn2.Downed) { var verb = pawn.VerbTracker.AllVerbs.Where(x => x.IsMeleeAttack != true).FirstOrDefault(); if (pawn.def == PurpleIvyDefOf.Genny_ParasiteOmega && pawn.Position.InHorDistOf(pawn2.Position, 15) && Rand.Chance(0.7f)) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - JUMP"); return(PurpleIvyUtils.JumpOnTargetJob(pawn, pawn2)); } else if (pawn.def == PurpleIvyDefOf.Genny_ParasiteBeta && pawn.Position.InHorDistOf(pawn2.Position, 2) && Rand.Chance(0.1f)) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - SMOKE"); return(PurpleIvyUtils.SmokeAttackJob(pawn, pawn2)); } else if (verb != null && Rand.Chance(0.8f) && pawn.Position.InHorDistOf(pawn2.Position, verb.verbProps.range)) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - SHOOT"); return(PurpleIvyUtils.RangeAttackJob(pawn, pawn2)); } else { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - MELEE"); return(PurpleIvyUtils.MeleeAttackJob(pawn, pawn2)); } } else if (pawn2.Downed) { if (pawn2.BodySize >= 0.5f && pawn.def != PurpleIvyDefOf.Genny_ParasiteOmega && pawn.def != PurpleIvyDefOf.Genny_ParasiteGamma && pawn.kindDef != PurpleIvyDefOf.Genny_Queen && pawn.needs.food.CurCategory < HungerCategory.Hungry) { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - Goo"); return(PurpleIvyUtils.EntagleWithGooJob(pawn, pawn2)); } else { //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - KILL"); return(PurpleIvyUtils.KillAttackJob(pawn, pawn2)); } } if (alien.canGuard) { if (alien.mindState?.duty?.focus == null || !PurpleIvyUtils.AlienPlantInCell (alien.Map, alien.mindState.duty.focus.Cell)) { alien.SetFocus(); } } if (alien.canHaul) { Predicate <Thing> validator = delegate(Thing t) { List <Thing> list = pawn.Map.thingGrid.ThingsListAt(t.Position); return(!(list.Count > 0 && list.OfType <Plant>().Any(x => x.def == PurpleIvyDefOf.PurpleIvy || x.def == PurpleIvyDefOf.PI_Nest || x.def == PurpleIvyDefOf.PlantVenomousToothwort))); }; Thing thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForDef(PurpleIvyDefOf.PI_StickyGoo), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.None, TraverseMode.NoPassClosedDoors, false), 9999f, validator, null); if (thing == null) { thing = GenClosest.ClosestThingReachable(pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.Corpse), PathEndMode.ClosestTouch, TraverseParms.For(pawn, Danger.None, TraverseMode.NoPassClosedDoors, false), 50f, validator, null); } if (thing != null && ReservationUtility.CanReserveAndReach(pawn, thing, PathEndMode.ClosestTouch, Danger.None)) { var plants = pawn.Map.listerThings.ThingsOfDef(PurpleIvyDefOf.PurpleIvy); if (plants == null || plants.Count <= 0) { return(null); } var plantToHaul = plants.RandomElement(); if (ReachabilityUtility.CanReach(pawn, plantToHaul, PathEndMode.ClosestTouch, Danger.None, true, TraverseMode.NoPassClosedDoors)) { Job job = JobMaker.MakeJob(PurpleIvyDefOf.PI_HaulToCell, thing, plantToHaul.Position); job.attackDoorIfTargetLost = true; if (job != null && job.TryMakePreToilReservations(pawn, false)) { ReservationUtility.Reserve(pawn, thing, job); return(job); } } } } //Log.Message(Find.TickManager.TicksGame.ToString() + " - " + pawn + " - " + pawn.jobs?.curJob?.def?.defName + " - NULL 1"); //Building building = this.FindTurretTarget(pawn); //if (building != null) //{ // return MeleeAttackJob(pawn, building); //} //if (pawn2 != null) //{ // using (PawnPath pawnPath = pawn.Map.pathFinder.FindPath(pawn.Position, pawn2.Position, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.PassDoors, false), PathEndMode.OnCell)) // { // if (!pawnPath.Found) // { // return null; // } // IntVec3 loc; // if (!pawnPath.TryFindLastCellBeforeBlockingDoor(pawn, out loc)) // { // Log.Error(pawn + " did TryFindLastCellBeforeDoor but found none when it should have been one. Target: " + pawn2.LabelCap, false); // return null; // } // IntVec3 randomCell = CellFinder.RandomRegionNear(loc.GetRegion(pawn.Map, RegionType.Set_Passable), 9, TraverseParms.For(pawn, Danger.Deadly, TraverseMode.ByPawn, false), null, null, RegionType.Set_Passable).RandomCell; // if (randomCell == pawn.Position) // { // return JobMaker.MakeJob(JobDefOf.Wait, 30, false); // } // return JobMaker.MakeJob(JobDefOf.Goto, randomCell); // } //} return(null); }