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; }