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()
        {
            if (pawn.Faction != Faction.OfPlayer)
            {
                TargetThingB.SetForbidden(false, false);
                this.FailOnDestroyedOrNull(TargetIndex.A);
                this.FailOnDestroyedOrNull(TargetIndex.B);
            }
            else
            {
                this.FailOnDestroyedNullOrForbidden(TargetIndex.A);
                this.FailOnDestroyedNullOrForbidden(TargetIndex.B);
            }

            // Haul ammo
            yield return(Toils_Reserve.Reserve(TargetIndex.A, 1));

            yield return(Toils_Reserve.Reserve(TargetIndex.B, 1));

            yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.ClosestTouch));

            yield return(Toils_Haul.StartCarryThing(TargetIndex.B));

            yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch));

            yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.A, null, false));

            // Wait in place
            Toil waitToil = new Toil();

            waitToil.initAction = delegate
            {
                waitToil.actor.pather.StopDead();
                compReloader.TryStartReload();
            };
            waitToil.defaultCompleteMode = ToilCompleteMode.Delay;
            waitToil.defaultDuration     = Mathf.CeilToInt(compReloader.Props.reloadTicks / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed));
            yield return(waitToil.WithProgressBarToilDelay(TargetIndex.A));

            //Actual reloader
            Toil reloadToil = new Toil();

            reloadToil.defaultCompleteMode = ToilCompleteMode.Instant;
            reloadToil.initAction          = delegate
            {
                Building_TurretGunCE turret = TargetThingA as Building_TurretGunCE;
                if (compReloader != null && turret.compAmmo != null)
                {
                    compReloader.LoadAmmo(TargetThingB);
                }
            };
            reloadToil.EndOnDespawnedOrNull(TargetIndex.B);
            yield return(reloadToil);
        }
        protected override IEnumerable <Toil> MakeNewToils()
        {
            var followAndAttack = new Toil();

            followAndAttack.tickAction = 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)))
                {
                    actor.pather.StartPath(thing, PathEndMode.Touch);
                }
                else
                {
                    if (!this.pawn.Position.AdjacentTo8WayOrInside(thing))
                    {
                        return;
                    }
                    if (thing is Pawn && pawn1.Downed && !curJob.killIncappedTarget)
                    {
                        this.EndJobWith(JobCondition.Succeeded);
                    }
                    var victim = (Pawn)thing;
                    if (actor.meleeVerbs.TryMeleeAttack(thing, null, true))
                    {
                        this.numMeleeAttacksLanded++;
                        if (this.numMeleeAttacksLanded >= curJob.maxNumMeleeAttacks)
                        {
                            this.EndJobWith(JobCondition.Succeeded);
                        }
                        if (10f >= Rand.Range(0f, 100f))
                        {
                            if (!victim.RaceProps.IsMechanoid && PurpleIvyData.maxNumberOfCreatures.ContainsKey(actor.def.defName) &&
                                thing.TryGetComp <AlienInfection>() == null)
                            {
                                AlienInfectionHediff hediff = (AlienInfectionHediff)HediffMaker.MakeHediff
                                                                  (PurpleIvyDefOf.PI_AlienInfection, victim);
                                hediff.instigator = this.pawn.kindDef;
                                victim.health.AddHediff(hediff);
                            }
                        }
                    }
                }
            };
            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()
        {
            // 水ツールを手に取る
            yield return(Toils_Goto.GotoThing(ToolInd, PathEndMode.Touch));

            yield return(Toils_Haul.StartCarryThing(ToolInd));

            // 水汲み設備へ移動
            PathEndMode peMode = PathEndMode.ClosestTouch;

            if (SourceThing.def.hasInteractionCell)
            {
                peMode = PathEndMode.InteractionCell;
            }
            yield return(Toils_Goto.GotoThing(SourceInd, peMode));

            // 水汲み
            Toil supplyToil = new Toil();

            supplyToil.initAction = () =>
            {
                var compSource = SourceThing.GetComp <CompWaterSource>();
                this.needManipulate = compSource.NeedManipulate;

                // 水汲み速度関連はリファクタリングしたい
                var ticksForFull = compSource.BaseDrinkTicks;

                var compTool   = Tool.GetComp <CompWaterTool>();
                var totalTicks = (int)(ticksForFull * (1f - compTool.StoredWaterVolumePercent));
                if (!needManipulate)
                {
                    // 手が必要ない→水にドボンですぐに補給できる
                    totalTicks /= 10;
                }
                // 小数の誤差を考慮して1Tick余分に多く実行する
                totalTicks += 1;

                this.maxTick           = totalTicks;
                this.ticksLeftThisToil = totalTicks;
            };
            supplyToil.tickAction = () =>
            {
                var compSource = SourceThing.GetComp <CompWaterSource>();
                var compTool   = Tool.GetComp <CompWaterTool>();
                var building   = SourceThing as IBuilding_DrinkWater;

                var supplyWaterVolume = compTool.MaxWaterVolume / compSource.BaseDrinkTicks;
                if (!needManipulate)
                {
                    supplyWaterVolume *= 10;
                }
                compTool.StoredWaterVolume += supplyWaterVolume;
                compTool.StoredWaterType    = building.WaterType;

                building.DrawWater(supplyWaterVolume);

                if (building.IsEmpty)
                {
                    this.ReadyForNextToil();
                }
            };
            supplyToil.defaultCompleteMode = ToilCompleteMode.Delay;
            supplyToil.WithProgressBar(SourceInd, () => 1f - (float)this.ticksLeftThisToil / this.maxTick, true, -0.5f);
            supplyToil.EndOnDespawnedOrNull(SourceInd);
            yield return(supplyToil);

            // 水ツールを戻す
            yield return(Toils_Mizu.TryFindStoreCell(ToolInd, StoreToolPosInd));

            yield return(Toils_Goto.GotoCell(StoreToolPosInd, PathEndMode.OnCell));

            yield return(Toils_Haul.PlaceHauledThingInCell(StoreToolPosInd, null, true));
        }
        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;
        }