protected override IEnumerable <Toil> MakeNewToils() { var followAndAttack = new Toil(); followAndAttack.initAction = delegate() { var actor = followAndAttack.actor; var curJob = actor.jobs.curJob; var thing = curJob.GetTarget(this.a).Thing; var pawn1 = thing as Pawn; pawn1.pather.StopDead(); pawn1.TakeDamage(new DamageInfo(PurpleIvyDefOf.PI_ToxicExplosion, 3, 0f, -1f, actor, null, null)); PurpleIvyUtils.DoExplosion(pawn1.Position, actor.Map, 3f, PurpleIvyDefOf.PI_ToxicExplosion, actor); if (actor.jobs.curJob != null) { actor.jobs.curDriver.Notify_PatherArrived(); } actor.jobs.TryTakeOrderedJob(PurpleIvyUtils.MeleeAttackJob(actor, pawn1)); }; followAndAttack.defaultCompleteMode = ToilCompleteMode.Never; followAndAttack.EndOnDespawnedOrNull <Toil>(this.a, JobCondition.Succeeded); followAndAttack.FailOn <Toil>(new Func <bool>(this.hunterIsKilled)); yield return(followAndAttack); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { var followAndAttack = new Toil(); followAndAttack.initAction = delegate() { var actor = followAndAttack.actor; var curJob = actor.jobs.curJob; var thing = curJob.GetTarget(this.a).Thing; var pawn1 = thing as Pawn; if (thing != actor.pather.Destination.Thing || (!this.pawn.pather.Moving && !this.pawn.Position.AdjacentTo8WayOrInside(thing))) { RoofDef roofDef = actor.Map.roofGrid.RoofAt(actor.Position); if (roofDef != null) { if (roofDef != RoofDefOf.RoofConstructed) { return; } if (!SoundDefHelper.NullOrUndefined(roofDef.soundPunchThrough)) { SoundStarter.PlayOneShot(roofDef.soundPunchThrough, new TargetInfo(actor.Position, actor.Map, false)); CellRect.CellRectIterator iterator = CellRect.CenteredOn(actor.Position, 1).GetIterator(); while (!iterator.Done()) { Find.CurrentMap.roofGrid.SetRoof(iterator.Current, null); iterator.MoveNext(); } } } RoofDef roofDef2 = actor.Map.roofGrid.RoofAt(thing.Position); if (roofDef2 != null) { if (roofDef2 != RoofDefOf.RoofConstructed) { return; } if (!SoundDefHelper.NullOrUndefined(roofDef2.soundPunchThrough)) { SoundStarter.PlayOneShot(roofDef2.soundPunchThrough, new TargetInfo(actor.Position, actor.Map, false)); CellRect.CellRectIterator iterator2 = CellRect.CenteredOn(thing.Position, 1).GetIterator(); while (!iterator2.Done()) { Find.CurrentMap.roofGrid.SetRoof(iterator2.Current, null); iterator2.MoveNext(); } } } } actor.pather.StartPath(thing, PathEndMode.OnCell); actor.Position = thing.Position; actor.pather.StopDead(); pawn1.pather.StopDead(); pawn1.TakeDamage(new DamageInfo(PurpleIvyDefOf.AlienToxicSting, 3, 0f, -1f, actor, null, null)); if (actor.jobs.curJob != null) { actor.jobs.curDriver.Notify_PatherArrived(); } actor.jobs.TryTakeOrderedJob(PurpleIvyUtils.MeleeAttackJob(actor, pawn1)); }; followAndAttack.defaultCompleteMode = ToilCompleteMode.Never; followAndAttack.EndOnDespawnedOrNull <Toil>(this.a, JobCondition.Succeeded); followAndAttack.FailOn <Toil>(new Func <bool>(this.hunterIsKilled)); yield return(followAndAttack); yield break; }
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); }