public static Toil SipWater(Pawn drinker, Need_Water pawnNeed, CompWaterContainer waterContainer, bool wornByActor) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = sipTicks; toil.initAction = delegate { bool fromThing = toil.actor.jobs.curJob.GetTarget(TargetIndex.A).HasThing; if (fromThing) { toil.FailOnForbidden(TargetIndex.A); if (!wornByActor) { toil.FailOnDespawned(TargetIndex.A); } } float wantDrink = Math.Min(pawnNeed.HydrationWantedLitres, sipLitres); float didDrink = pawnNeed.DrinkFrom(waterContainer, wantDrink); }; toil.FailOn(() => waterContainer.IsEmpty); // TODO: toil.WithEffect(); toil.WithSustainer(delegate { if (drinker.RaceProps.Humanlike) { return DefDatabase<SoundDef>.GetNamed(drinkSoundName); } return null; }); return toil; }
protected override IEnumerable<Toil> MakeNewToils() { /// //Set fail conditions /// this.FailOnBurningImmobile(TargetAInd); this.FailOnDestroyed(TargetAInd); /// //Define Toil /// /// //Toils Start /// //Reserve thing to be stored and storage cell //yield return Toils_Reserve.Reserve(MountableInd, ReservationType.Total); //Mount on Target yield return Toils_Goto.GotoThing(TargetAInd, PathEndMode.ClosestTouch); yield return Toils_General.Wait(TickForClaim); Toil toilClaim = new Toil(); toilClaim.initAction = () => { Pawn actor = toilClaim.actor; TargetThingA.SetFaction(actor.Faction); }; yield return toilClaim; }
protected override IEnumerable<Toil> MakeNewToils() { this.FailOnBroken(TargetIndex.A); //Define Toil Toil toilWait = new Toil(); toilWait.initAction = () => { toilWait.actor.pather.StopDead(); }; Toil toilNothing = new Toil(); //toilNothing.initAction = () => {}; toilNothing.defaultCompleteMode = ToilCompleteMode.Delay; toilNothing.defaultDuration = getUpCheckInterval; // Start Toil yield return toilWait; yield return toilNothing; yield return Toils_Jump.JumpIf(toilNothing, () => { CompSuppressable comp = pawn.TryGetComp<CompSuppressable>(); if (comp == null) { return false; } float distToSuppressor = (pawn.Position - comp.suppressorLoc).LengthHorizontal; if (distToSuppressor < CompSuppressable.minSuppressionDist) { return false; } return comp.isHunkering; }); }
protected override IEnumerable<Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(filthIndex); yield return Toils_Reserve.Reserve(filthIndex, 1); yield return Toils_Goto.GotoThing(filthIndex, PathEndMode.Touch); Toil openCasketToil = new Toil() { initAction = () => { this.totalCleaningWorkRequired = this.Filth.def.filth.cleaningWorkToReduceThickness * (float)this.Filth.thickness; }, tickAction = () => { Filth filth = this.Filth; this.cleaningWorkDone += 1f; this.totalCleaningWorkDone += 1f; if (this.cleaningWorkDone > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); this.cleaningWorkDone = 0f; if (filth.Destroyed) { this.GetActor().records.Increment(RecordDefOf.MessesCleaned); this.ReadyForNextToil(); return; } } }, defaultCompleteMode = ToilCompleteMode.Never }.WithEffect("Clean", filthIndex).WithProgressBar(filthIndex, () => this.totalCleaningWorkDone / this.totalCleaningWorkRequired, true, -0.5f).PlaySustainerOrSound(SoundDefOf.Interact_CleanFilth); yield return openCasketToil; }
protected override IEnumerable<Toil> MakeNewToils() { //Set what will cause the job to fail: this.FailOnDestroyedOrForbidden(CorpseIndex); this.FailOnBurningImmobile(CorpseIndex); this.FailOn(() => !(pawn is Droid)); //Reserve the corpse yield return Toils_Reserve.Reserve(CorpseIndex); //Go to the corpse yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch); Toil toil = new Toil(); toil.initAction = () => { //Check if the pawn is set to strip bodies, if yes then strip it, otherwise skip this step Droid droid = (Droid)pawn; CremationWorker worker = droid.work.specialist.GetWorker<CremationWorker>(); if (worker.StripBodies) { Corpse corpse = (Corpse)TargetThingA; if (corpse.AnythingToStrip()) corpse.Strip(); } }; toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = 300; toil.WithEffect(() => DefDatabase<EffecterDef>.GetNamed("Cremate"), CorpseIndex); toil.WithSustainer(() => DefDatabase<SoundDef>.GetNamed("Recipe_Cremate")); toil.AddFinishAction(() => TargetA.Thing.Destroy()); toil.FailOnBurningImmobile(CorpseIndex); toil.FailOnDestroyedOrForbidden(CorpseIndex); toil.AddEndCondition(() => this.ticksLeftThisToil <= 0 ? JobCondition.Succeeded : JobCondition.Ongoing); yield return toil; }
private Toil Ignite(Thing target) { Toil toil = new Toil(); toil.initAction = delegate { Pawn feenix = this.pawn; if (target.FlammableNow && !target.IsBurning()) { if (target.CanEverAttachFire()) { target.TryAttachFire(1f); } else { FireUtility.TryStartFireIn(target.Position, 1f); } PawnUtility.ForceWait(feenix, 250, target); } else { return; } }; toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = 250; return toil; }
public Toil DepositFuelIntoBurner(TargetIndex burnerIndex) { var toil = new Toil(); toil.initAction = delegate { var actor = toil.actor; var curJob = actor.jobs.curJob; if (actor.carrier.CarriedThing == null) { Log.Error(actor + " tried to place hauled thing in container but is not hauling anything."); return; } var thingContainerOwner = curJob.GetTarget(burnerIndex).Thing.TryGetComp<CompFueled>() as IThingContainerOwner; if (thingContainerOwner != null) { var num = actor.carrier.CarriedThing.stackCount; actor.carrier.container.TransferToContainer(actor.carrier.CarriedThing, thingContainerOwner.GetContainer(), num); } else if (curJob.GetTarget(burnerIndex).Thing.def.Minifiable) { actor.carrier.container.Clear(); } else { Log.Error("Could not deposit hauled thing in container: " + curJob.GetTarget(burnerIndex).Thing); } }; return toil; }
protected override IEnumerable<Toil> MakeNewToils() { Building_DroidChargePad charger = (Building_DroidChargePad)TargetThingA; Toil goToPad = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell); goToPad.AddFailCondition(() => { return !charger.IsAvailable(pawn); }); yield return goToPad; Droid droid = (Droid)this.pawn; Toil charge = new Toil(); charge.initAction = () => { if (charger.Position != droid.Position) { pawn.jobs.EndCurrentJob(JobCondition.Errored); } }; charge.defaultCompleteMode = ToilCompleteMode.Never; charge.AddFailCondition(() => { return !charger.IsAvailable(pawn); }); charge.AddEndCondition(() => { if (!droid.DesiresCharge()) { return JobCondition.Succeeded; } return JobCondition.Ongoing; }); yield return charge; }
protected override IEnumerable<Toil> MakeNewToils() { var slotter = CurJob.GetTarget(SlotterInd).Thing as ThingWithComps; var compSlots = slotter.GetComp<CompSlots>(); // no free slots this.FailOn(() => compSlots.slots.Count >= compSlots.Properties.maxSlots); // reserve resources yield return Toils_Reserve.ReserveQueue(HaulableInd); // extract next target thing from targetQueue var toilExtractNextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(HaulableInd); yield return toilExtractNextTarget; var toilGoToThing = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDespawnedOrNull(HaulableInd); yield return toilGoToThing; var pickUpThingIntoSlot = new Toil { initAction = () => { if (!compSlots.slots.TryAdd(CurJob.targetA.Thing)) EndJobWith(JobCondition.Incompletable); } }; yield return pickUpThingIntoSlot; yield return Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, toilExtractNextTarget); }
public static Toil CheckArrestable( TargetIndex PrisonerInd, TargetIndex BedInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Instant; toil.initAction = () => { var prisoner = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn; var bed = toil.actor.CurJob.GetTarget( BedInd ).Thing as Building_Bed; if( !bed.ForPrisoners ) { return; } var lord = prisoner.GetLord(); if( lord != null ) { lord.Notify_PawnAttemptArrested( prisoner ); } GenClamor.DoClamor( prisoner, 10f, ClamorType.Harm ); if( prisoner.CheckAcceptArrest( toil.actor ) ) { return; } //Log.Message( "Toils_Prisoner.CheckArrestable returning JobCondition.Incompleteable!" ); toil.actor.jobs.EndCurrentJob( JobCondition.Incompletable ); }; return toil; }
public static Toil CheckNeedStorageCell(Toil jumpToil, TargetIndex CarrierInd, TargetIndex StoreCellInd) { Toil toil = new Toil(); toil.initAction = () => { Pawn actor = toil.actor; Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; Apparel_Backpack backpack = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Apparel_Backpack; if (cart == null && backpack == null) { Log.Error(actor.LabelCap + " Report: Don't have Carrier"); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); } ThingContainer container = cart != null ? cart.storage : actor.inventory.container; if (container.Count == 0) return; IntVec3 cell = ToolsForHaulUtility.FindStorageCell(actor, container.First()); if (cell != IntVec3.Invalid) { toil.actor.jobs.curJob.SetTarget(StoreCellInd, cell); Find.Reservations.Reserve(actor, cell); toil.actor.jobs.curDriver.JumpToToil(jumpToil); } }; return toil; }
// ignites burner to start consume fuel, if needed public Toil WaitUntilBurnerReady() { var burner = CurJob.GetTarget(TargetIndex.A).Thing as RA_Building_WorkTable; var toil = new Toil { initAction = () => { if (burner == null) { return; } pawn.pather.StopDead(); }, tickAction = () => { //if (burner.internalTemp > burner.compFueled.Props.operatingTemp) // ReadyForNextToil(); } }; // fails if no more heat generation and temperature is no enough //toil.FailOn(() => burner.currentFuelBurnDuration == 0 && !burner.UsableNow); toil.defaultCompleteMode = ToilCompleteMode.Never; return toil; }
protected Toil GetToilPlayTheGuitar() { int tickCounter = 0; Toil toil = new Toil() { initAction = () => { tickCounter = Rand.Range(35, 50); MoteDualAttached moteAttached = (MoteDualAttached)ThingMaker.MakeThing(Util_CampfireParty.Mote_Guitar); moteAttached.Attach(this.pawn); GenSpawn.Spawn(moteAttached, this.pawn.Position); this.pawn.Drawer.rotator.FaceCell(this.pawn.Position + new IntVec3(0, 0, -1)); }, tickAction = () => { tickCounter--; if (tickCounter <= 0) { tickCounter = Rand.Range(35, 50); MoteMaker.MakeColonistActionOverlay(this.pawn, Util_CampfireParty.Mote_MusicNote); } // Gain some joy. this.pawn.needs.joy.GainJoy(this.CurJob.def.joyGainRate * 0.000144f, Util_CampfireParty.JoyKindDefOf_Social); this.pawn.Drawer.rotator.FaceCell(this.pawn.Position + new IntVec3(0, 0, -1)); }, defaultDuration = 240, defaultCompleteMode = ToilCompleteMode.Delay }; return toil; }
protected override IEnumerable<Toil> MakeNewToils() { /// //Set fail conditions /// this.FailOnBurningImmobile(StoreCellInd); Vehicle vehicle = pawn as Vehicle; this.FailOn(() => { return (vehicle.IsMounted) ? false : true; }); /// //Define Toil /// Toil toilDismount = new Toil(); toilDismount.initAction = () => { vehicle.Dismount(); }; /// //Toils Start /// //Reserve thing to be stored and storage cell yield return Toils_Reserve.Reserve(StoreCellInd); //Dismount yield return Toils_Goto.GotoCell(StoreCellInd, PathEndMode.OnCell); yield return toilDismount; }
protected override IEnumerable<Toil> MakeNewToils() { #if DEBUG Log.Message("StartToils OK"); Log.Message(Takee.ToString()); Log.Message(pawn.ToString()); Log.Message(DropPod.ToString()); #endif yield return Toils_Reserve.Reserve(TargetIndex.A, 1); yield return Toils_Reserve.Reserve(TargetIndex.B, 1); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.OnCell).FailOnDestroyedOrForbidden(TargetIndex.A).FailOnDespawnedOrForbidden(TargetIndex.B).FailOn(() => DropPod.GetContainer().Count > 0); //.FailOn(() => pawn.CanReach(Takee, PathEndMode.Touch, Danger.Deadly, false)); yield return Toils_Haul.StartCarryThing(TargetIndex.A); yield return Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.InteractionCell).FailOnDestroyed(TargetIndex.B); Toil prepare = new Toil(); prepare.defaultCompleteMode = ToilCompleteMode.Delay; prepare.defaultDuration = 500; yield return prepare; Toil putInPod = new Toil(); putInPod.initAction = delegate { pawn.carrier.GetContainer().TransferToContainer(Takee, DropPod.GetContainer(), 1); }; putInPod.defaultCompleteMode = ToilCompleteMode.Instant; yield return putInPod; yield break; }
public Toil Cultivate() { var targetCell = CurJob.targetA.Cell; var toil = new Toil(); toil.initAction = () => { workTicks = Mathf.RoundToInt(terrainReplacements[targetCell.GetTerrain()].GetStatValueAbstract(StatDefOf.WorkToMake) * pawn.GetStatValue(StatDefOf.PlantWorkSpeed)); pawn.jobs.curDriver.ticksLeftThisToil = workTicks; }; toil.tickAction = () => { if (--pawn.jobs.curDriver.ticksLeftThisToil < 0) { // remove designation var designation = Find.DesignationManager.DesignationAt(targetCell, DefDatabase<DesignationDef>.GetNamed("CultivateLand")); if (designation != null) { Find.DesignationManager.RemoveDesignation(designation); } // replace terrain Find.TerrainGrid.SetTerrain(targetCell, terrainReplacements[targetCell.GetTerrain()]); ReadyForNextToil(); } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.FailOnCellMissingDesignation(CellInd, DefDatabase<DesignationDef>.GetNamed("CultivateLand")); toil.WithEffect(() => EffecterDef.Named("CutStone"), CellInd); toil.PlaySustainerOrSound(() => DefDatabase<SoundDef>.GetNamedSilentFail("Recipe_Surgery")); toil.WithProgressBar(CellInd, () => 1f - (float) pawn.jobs.curDriver.ticksLeftThisToil/workTicks); return toil; }
private Toil Manage( TargetIndex targetIndex ) { Building_ManagerStation station = CurJob.GetTarget( targetIndex ).Thing as Building_ManagerStation; if ( station == null ) { Log.Error( "Target of manager job was not a manager station. This should never happen." ); return null; } Comp_ManagerStation comp = station.GetComp<Comp_ManagerStation>(); if ( comp == null ) { Log.Error( "Target of manager job does not have manager station comp. This should never happen." ); return null; } Toil toil = new Toil(); toil.defaultDuration = (int)( comp.props.Speed * ( 1 - pawn.GetStatValue( StatDef.Named( "ManagingSpeed" ) ) + .5 ) ); #if DEBUG_WORKGIVER Log.Message("Pawn stat: " + pawn.GetStatValue(StatDef.Named("ManagingSpeed")) + " (+0.5) Station speed: " + comp.props.Speed + "Total time: " + toil.defaultDuration); #endif toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.tickAction = delegate { toil.actor.skills.GetSkill( DefDatabase<SkillDef>.GetNamed( "Managing" ) ).Learn( 0.11f ); }; List<Action> finishers = new List<Action>(); finishers.Add( delegate { Manager.Get.DoWork(); } ); toil.finishActions = finishers; return toil; }
// can bash doors public Toil SearchForTargetToStealInColony() { var checkInterval = GenTicks.TickRareInterval; var searchRadius = 10f; var minimumStealValue = 100f; var toil = new Toil(); toil.initAction = () => { var actor = toil.actor; CurJob.locomotionUrgency = LocomotionUrgency.Jog; actor.pather.StartPath(FindRandomSearchPointInsideColony(), PathEndMode.OnCell); }; toil.tickAction = () => { var actor = toil.actor; if (actor.IsHashIntervalTick(checkInterval)) { var traverseParams = TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, true); // search for kidnap victim Predicate<Thing> validatorSteal = thing => { var victim = thing as Pawn; return victim.RaceProps.Humanlike && victim.Downed && victim.Faction == Faction.OfPlayer && actor.CanReserve(victim); }; var targetThing = GenClosest.ClosestThingReachable(actor.Position, ThingRequest.ForGroup(ThingRequestGroup.Pawn), PathEndMode.ClosestTouch, traverseParams, searchRadius, validatorSteal); if (targetThing != null) { actor.CurJob.SetTarget(targetToSteal, targetThing); CurJob.locomotionUrgency = LocomotionUrgency.Sprint; ReadyForNextToil(); } else { // search for thing to steal validatorSteal = thing => thing.def.stackLimit == 1 && thing.MarketValue >= minimumStealValue && actor.CanReserve(thing); targetThing = GenClosest.ClosestThingReachable(actor.Position, ThingRequest.ForGroup(ThingRequestGroup.HaulableAlways), PathEndMode.ClosestTouch, traverseParams, searchRadius, validatorSteal); if (targetThing != null) { actor.CurJob.SetTarget(targetToSteal, targetThing); CurJob.locomotionUrgency = LocomotionUrgency.Sprint; ReadyForNextToil(); } } } }; toil.defaultCompleteMode = ToilCompleteMode.PatherArrival; return toil; }
protected override IEnumerable<Toil> MakeNewToils() { Passion passion = Passion.None; const float skillGainPerTick = 0.15f; float skillGainFactor = 0f; int reroutingDuration = 0; float statValue = this.pawn.GetStatValue(StatDefOf.ResearchSpeed, true); reroutingDuration = (int)Math.Round((double)(1200f / statValue)); yield return Toils_Reserve.Reserve(terraformerIndex); yield return Toils_Goto.GotoCell(terraformerIndex, PathEndMode.InteractionCell).FailOnDestroyed(terraformerIndex); Toil rerouteToil = new Toil() { initAction = () => { passion = this.pawn.skills.MaxPassionOfRelevantSkillsFor(WorkTypeDefOf.Research); if (passion == Passion.None) { skillGainFactor = 0.3f; } else if (passion == Passion.Minor) { skillGainFactor = 1f; } else { skillGainFactor = 1.5f; } }, tickAction = () => { this.pawn.skills.Learn(SkillDefOf.Research, skillGainPerTick * skillGainFactor); }, defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = reroutingDuration }; yield return rerouteToil.FailOnDestroyed(terraformerIndex); Toil incrementReroutingCounterToil = new Toil() { initAction = () => { Building_MechanoidTerraformer terraformer = this.TargetThingA as Building_MechanoidTerraformer; terraformer.reroutingCounter++; if (terraformer.reroutingCounter >= Building_MechanoidTerraformer.reroutingCounterTargetValue) { terraformer.FinishPowerRerouting(); } }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return incrementReroutingCounterToil; yield return Toils_Reserve.Release(terraformerIndex); }
protected override IEnumerable<Toil> MakeNewToils() { this.FailOnDestroyedOrForbidden<JobDriver_PlantHarvestWithSeeds>(TargetIndex.A); yield return Toils_Reserve.Reserve(TargetIndex.A, 1); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); var toil = new Toil(); toil.tickAction = () => { Pawn actor = toil.actor; if (actor.skills != null) actor.skills.Learn(SkillDefOf.Growing, 0.154f); float num = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); Plant plant = (Plant)actor.jobs.curJob.GetTarget(TargetIndex.A).Thing; harvestWorkDone += num; if (harvestWorkDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { int num2 = plant.YieldNow(); if (plant is PlantWithSeeds) num2 = ((PlantWithSeeds)plant).YieldNow(); if (num2 > 0) { Thing t = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null); t.stackCount = num2; if (actor.Faction != Faction.OfColony) t.SetForbidden(true, true); GenPlace.TryPlaceThing(t, actor.Position, ThingPlaceMode.Near); } if (plant is PlantWithSeeds) { PlantWithSeeds seeds = plant as PlantWithSeeds; float num3 = Mathf.Max(Mathf.InverseLerp(seeds.def.plant.harvestMinGrowth, 1.2f, seeds.growth), 1f); if (seeds.m_CustomPlantDef != null && seeds.m_CustomPlantDef.SeedDef != null && Rand.Value < (seeds.genome.baseSeedChance * num3)) { Thing thing = ThingMaker.MakeThing(seeds.m_CustomPlantDef.SeedDef, null); if (Rand.Value < (seeds.genome.addSeedChance * num3)) thing.stackCount = 2; else thing.stackCount = 1; GenPlace.TryPlaceThing(thing, actor.Position, ThingPlaceMode.Near); } } } plant.PlantCollected(); plant.def.plant.soundHarvestFinish.PlayOneShot(actor); harvestWorkDone = 0f; ReadyForNextToil(); } }; toil.FailOnDestroyedOrForbidden<Toil>(TargetIndex.A); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect("Harvest", TargetIndex.A); toil.WithSustainer(() => toil.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing.def.plant.soundHarvesting); yield return toil; yield return Toils_General.RemoveDesignationsOnThing(TargetIndex.A, DesignationDefOf.HarvestPlant); }
protected override IEnumerable<Toil> MakeNewToils() { //this.EndOnDespawned(TargetIndex.A, JobCondition.Succeeded); //this.FailOn(hunterIsKilled); //yield return Toils_Combat.TrySetJobToUseAttackVerb(); //Toil gotoPosition = Toils_Combat.GotoCastPosition(TargetIndex.A); //yield return gotoPosition; //Toil jump = Toils_Jump.JumpIfTargetNotHittable(TargetIndex.A, gotoPosition); //yield return jump; //Log.Message(string.Concat(pawn, " trying to kill ", TargetA)); //yield return Toils_Combat.TrySetJobToUseAttackVerb(); //yield return Toils_Combat.CastVerb(TargetIndex.A); //yield return Toils_Jump.Jump(jump); Toil followAndAttack = new Toil(); followAndAttack.tickAction = () => { Pawn actor = followAndAttack.actor; Job curJob = actor.jobs.curJob; Thing t = curJob.GetTarget(TargetIndex.A).Thing; Pawn pawn2 = t as Pawn; if (pawn.Faction != Faction.OfColony) { actor.mindState.broken.StartBrokenState(DefDatabase<SK_Enviro.AI.BrokenStateDef>.GetNamed("HungerState")); } if (t.Faction == Faction.OfColony) { Find.TickManager.slower.SignalForceNormalSpeedShort(); } if ((t != actor.pather.Destination.Thing) || (!pawn.pather.Moving && !pawn.Position.AdjacentTo8WayOrInside(t))) { actor.pather.StartPath(t, PathEndMode.Touch); } else if (pawn.Position.AdjacentTo8WayOrInside(t)) { if (((t is Pawn) && pawn2.Downed) && !curJob.killIncappedTarget) { EndJobWith(JobCondition.Succeeded); } if (actor.natives.TryMeleeAttack(t)) { this.numMeleeAttacksLanded++; if (numMeleeAttacksLanded >= curJob.maxNumMeleeAttacks) { EndJobWith(JobCondition.Succeeded); } } } }; followAndAttack.defaultCompleteMode = ToilCompleteMode.Never; followAndAttack.EndOnDespawned(TargetIndex.A, JobCondition.Succeeded); followAndAttack.FailOn(hunterIsKilled); yield return followAndAttack; }
public static Toil GotoGuest(Pawn pawn, Pawn talkee, Func<Pawn,bool> condition, bool mayBeSleeping = false) { var toil = new Toil { initAction = () => pawn.pather.StartPath(talkee, PathEndMode.Touch), defaultCompleteMode = ToilCompleteMode.PatherArrival }; toil.AddFailCondition(() => !GuestUtility.ViableGuestTarget(talkee, mayBeSleeping) || !condition(talkee)); return toil; }
public static Toil CheckDuplicates(Toil jumpToil, TargetIndex CarrierInd, TargetIndex HaulableInd) { Toil toil = new Toil(); toil.initAction = () => { IntVec3 storeCell = IntVec3.Invalid; Pawn actor = toil.GetActor(); TargetInfo target = toil.actor.jobs.curJob.GetTarget(HaulableInd); if (target.Thing.def.stackLimit <= 1) return; List<TargetInfo> targetQueue = toil.actor.jobs.curJob.GetTargetQueue(HaulableInd); if (!targetQueue.NullOrEmpty() && target.Thing.def.defName == targetQueue.First().Thing.def.defName) { toil.actor.jobs.curJob.SetTarget(HaulableInd, targetQueue.First()); Find.Reservations.Reserve(actor, targetQueue.First()); targetQueue.RemoveAt(0); toil.actor.jobs.curDriver.JumpToToil(jumpToil); return; } Vehicle_Cart cart = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Vehicle_Cart; Apparel_Backpack backpack = toil.actor.jobs.curJob.GetTarget(CarrierInd).Thing as Apparel_Backpack; if (cart == null && backpack == null) { Log.Error(actor.LabelCap + " Report: Don't have Carrier"); toil.actor.jobs.curDriver.EndJobWith(JobCondition.Errored); return; } int curItemCount = (cart != null ? cart.storage.Count : actor.inventory.container.Count) + targetQueue.Count; int curItemStack = (cart != null ? cart.storage.TotalStackCount : actor.inventory.container.TotalStackCount) + targetQueue.Sum(item => item.Thing.stackCount); int maxItem = cart != null ? cart.MaxItem : backpack.MaxItem; int maxStack = cart != null ? cart.MaxStack : backpack.MaxStack; if (curItemCount >= maxItem || curItemStack >= maxStack) return; //Check target's nearby Thing thing = GenClosest.ClosestThing_Global_Reachable(actor.Position, ListerHaulables.ThingsPotentiallyNeedingHauling(), PathEndMode.Touch, TraverseParms.For(actor, Danger.Some), NearbyCell, item => !targetQueue.Contains(item) && item.def.defName == target.Thing.def.defName && !FireUtility.IsBurning(item) && Find.Reservations.CanReserve(actor, item)); if (thing != null) { toil.actor.jobs.curJob.SetTarget(HaulableInd, thing); Find.Reservations.Reserve(actor, thing); toil.actor.jobs.curDriver.JumpToToil(jumpToil); return; } }; return toil; }
public static Toil FaceThing(TargetIndex thingInd) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Instant; toil.initAction = delegate { Pawn actor = toil.actor; actor.drawer.rotator.FaceCell(actor.jobs.curJob.GetTarget(thingInd).Cell); }; return toil; }
public static Toil RemoveDesignationAtPosition(IntVec3 pos,DesignationDef dDef) { Toil toil = new Toil(); toil.initAction= delegate{ Designation des = Find.DesignationManager.DesignationAt(pos, dDef); if(des!=null) { Find.DesignationManager.RemoveDesignation(des); } }; return toil; }
public static Toil PrepareDoorInteraction( TargetIndex DoorInd, Toil interactionToil ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Instant; toil.initAction = () => { var door = toil.actor.CurJob.GetTarget( DoorInd ).Thing as Building_RestrictedDoor; var compLock = door.TryGetComp<CompLockable>(); interactionToil.defaultDuration = compLock.LockToggleTime( toil.actor ); }; return toil; }
protected override IEnumerable<Toil> MakeNewToils() { yield return Toils_Goto.GotoThing( TargetIndex.A, PathMode.Touch ) .FailOnBurningImmobile( TargetIndex.A ); Toil ignite = new Toil(); ignite.initAction = ()=> { pawn.natives.TryIgnite( TargetThingA ); }; yield return ignite; }
protected override IEnumerable<Toil> MakeNewToils() { this.FailOnDestroyedOrForbidden(TargetIndex.A); yield return Toils_Reserve.Reserve(TargetIndex.A); yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); var toil = new Toil(); toil.tickAction = () => { Pawn actor = toil.actor; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Growing, 0.154f); } float statValue = actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); Plant plant = (Plant)actor.jobs.curJob.GetTarget(TargetIndex.A).Thing; harvestWorkDone += statValue; if (harvestWorkDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { int num3 = plant.YieldNow(); if (plant is PlantWithSeeds) { Log.Message("We harvest a PlantWithSeeds"); num3 = ((PlantWithSeeds)plant).YieldNow(); } if (num3 > 0) { Thing thing = ThingMaker.MakeThing(plant.def.plant.harvestedThingDef, null); thing.stackCount = num3; if (actor.Faction != Faction.OfColony) { thing.SetForbidden(true, true); } GenPlace.TryPlaceThing(thing, actor.Position, ThingPlaceMode.Near); } } plant.PlantCollected(); plant.def.plant.soundHarvestFinish.PlayOneShot(actor); harvestWorkDone = 0; ReadyForNextToil(); } }; toil.FailOnDestroyedOrForbidden(TargetIndex.A); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect("Harvest", TargetIndex.A); toil.WithSustainer(() => toil.actor.jobs.curJob.GetTarget(TargetIndex.A).Thing.def.plant.soundHarvesting); yield return toil; yield return Toils_General.RemoveDesignationsOnThing(TargetIndex.A, DesignationDefOf.HarvestPlant); }
protected override IEnumerable<Toil> MakeNewToils() { Pawn driver = CurJob.targetA.Thing as Pawn; Vehicle vehicle = pawn as Vehicle; /// //Set fail conditions /// Job jobNew = new Job(DefDatabase<JobDef>.GetNamed("Mount"), vehicle, vehicle.MountPos); this.FailOnDowned(DriverInd); this.AddEndCondition(() => { return vehicle.IsMounted ? JobCondition.Succeeded : JobCondition.Ongoing; }); /// //Define Toil /// Toil toilCallDriver = new Toil(); toilCallDriver.initAction = () => { driver.jobs.StartJob(jobNew, JobCondition.Incompletable); }; Toil toilCheckDriverOnGoing = new Toil(); toilCheckDriverOnGoing.initAction = () => { if (driver.CurJob != jobNew) this.EndJobWith(JobCondition.Incompletable); }; Toil toilUnmounted = new Toil(); toilUnmounted.initAction = () => { vehicle.pather.StopDead(); }; toilUnmounted.defaultCompleteMode = ToilCompleteMode.Delay; toilUnmounted.defaultDuration = 120; /// //Toils Start /// //Reserve thing to be stored and storage cell yield return Toils_Reserve.Reserve(DriverInd); yield return toilCallDriver; yield return toilCheckDriverOnGoing; yield return toilUnmounted; yield return Toils_Jump.Jump(toilCheckDriverOnGoing); }
public static Toil DoorUnLock( TargetIndex DoorInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.WithProgressBarToilDelay( DoorInd ); toil.AddFinishAction( () => { var door = toil.actor.CurJob.GetTarget( DoorInd ).Thing as Building_RestrictedDoor; var compLock = door.TryGetComp<CompLockable>(); compLock.ChangeLockState( false ); } ); return toil; }
protected Toil AttemptCalm(TargetIndex ctrg) { Pawn subjectee = (Pawn)this.pawn.CurJob.targetA.Thing; var toil = new Toil { initAction = () => { if (subjectee == null) { return; } subjectee.jobs.EndCurrentJob(JobCondition.InterruptForced); this.TargetThingB = this.pawn; // Defining our initiator pawn float rand = Rand.RangeSeeded(0f, 0.70f, Find.TickManager.TicksAbs); pawn.interactions.TryInteractWith(subjectee, SnapDefOf.CalmDownInteraction); float num = SnapUtils.DoFormula(pawn, subjectee); if (SOMod.Settings.AlwaysSucceed) { rand = 0f; } SnapUtils.DebugLog(string.Format("Success chance of {0} opposed to failure chance of {1}", num.ToString(), rand.ToString())); if (rand > num) { if (SOMod.Settings.MessagesEnabled) { SnapUtils.CalmText(this.pawn, Color.red); } if (subjectee.InAggroMentalState) { subjectee.TryStartAttack(pawn); SnapUtils.DoStatusMessage(3, pawn, subjectee); subjectee.mindState.lastAssignedInteractTime = Find.TickManager.TicksGame; return; } SnapUtils.DoStatusMessage(2, pawn, subjectee); subjectee.mindState.lastAssignedInteractTime = Find.TickManager.TicksGame; SnapUtils.AttemptSendSafety(subjectee); return; } if (SOMod.Settings.MessagesEnabled) { SnapUtils.CalmText(this.pawn, Color.green); } if (subjectee.InAggroMentalState) { subjectee.MentalState.RecoverFromState(); subjectee.mindState.mentalStateHandler.TryStartMentalState(MentalStateDefOf.Wander_Sad); } SnapUtils.DoStatusMessage(1, pawn, subjectee); pawn.needs.mood.thoughts.memories.TryGainMemory(SnapDefOf.HelpedThought, null); pawn.skills.Learn(SkillDefOf.Social, Rand.RangeSeeded(50, 125, Find.TickManager.TicksAbs)); subjectee.jobs.EndCurrentJob(JobCondition.Succeeded); recoverjob.playerForced = true; subjectee.jobs.StartJob(recoverjob, JobCondition.Succeeded); subjectee.mindState.lastAssignedInteractTime = Find.TickManager.TicksGame; }, socialMode = RandomSocialMode.Off, defaultCompleteMode = ToilCompleteMode.Instant, defaultDuration = SOMod.Settings.CalmDuration }; return(toil.WithProgressBarToilDelay(TargetIndex.B)); }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_General.Wait(10, TargetIndex.None)); yield return(new Toil { initAction = delegate() { if (!this.pawn.inventory.UnloadEverything) { base.EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = this.pawn.inventory.FirstUnloadableThing; IntVec3 c; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.pawn, out c)) { Thing thing; this.pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = firstUnloadableThing.Count; } } } }); yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(new Toil { initAction = delegate() { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { base.EndJobWith(JobCondition.Incompletable); } else { if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing, true); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); } thing.SetForbidden(false, false); } } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); yield break; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.$current = Toils_General.Wait(10, TargetIndex.None); if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: { Toil pickItem = new Toil(); pickItem.initAction = delegate() { if (!this.pawn.inventory.UnloadEverything) { base.EndJobWith(JobCondition.Succeeded); } else { ThingCount firstUnloadableThing = this.pawn.inventory.FirstUnloadableThing; IntVec3 c; if (!StoreUtility.TryFindStoreCellNearColonyDesperate(firstUnloadableThing.Thing, this.pawn, out c)) { Thing thing; this.pawn.inventory.innerContainer.TryDrop(firstUnloadableThing.Thing, ThingPlaceMode.Near, firstUnloadableThing.Count, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.job.SetTarget(TargetIndex.A, firstUnloadableThing.Thing); this.job.SetTarget(TargetIndex.B, c); this.countToDrop = firstUnloadableThing.Count; } } }; this.$current = pickItem; if (!this.$disposing) { this.$PC = 2; } return(true); } case 2u: this.$current = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null); if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch); if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: { Toil dropOrStartCarrying = new Toil(); dropOrStartCarrying.initAction = delegate() { Thing thing = this.job.GetTarget(TargetIndex.A).Thing; if (thing == null || !this.pawn.inventory.innerContainer.Contains(thing)) { base.EndJobWith(JobCondition.Incompletable); } else { if (!this.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { this.pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, this.countToDrop, out thing, null, null); base.EndJobWith(JobCondition.Succeeded); } else { this.pawn.inventory.innerContainer.TryTransferToContainer(thing, this.pawn.carryTracker.innerContainer, this.countToDrop, out thing, true); this.job.count = this.countToDrop; this.job.SetTarget(TargetIndex.A, thing); } thing.SetForbidden(false, false); } }; this.$current = dropOrStartCarrying; if (!this.$disposing) { this.$PC = 5; } return(true); } case 5u: carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); this.$current = carryToCell; if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$current = Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true); if (!this.$disposing) { this.$PC = 7; } return(true); case 7u: this.$PC = -1; break; } return(false); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedNullOrForbidden(PowerDestIndex); AddFailCondition(() => energyNeed == null); yield return(Toils_Reserve.Reserve(PowerDestIndex)); if (!TargetB.IsValid) { yield return(Toils_Goto.GotoThing(PowerDestIndex, PathEndMode.ClosestTouch)); } else { yield return(Toils_Reserve.Reserve(AlternateDestIndex)); yield return(Toils_Goto.GotoThing(AlternateDestIndex, PathEndMode.OnCell)); } Toil rechargeToil = new Toil(); rechargeToil.tickAction = delegate { //Drain the powernet. CompPowerBattery compBattery = powerBuilding.PowerComp?.PowerNet?.batteryComps?.FirstOrDefault(battery => battery.StoredEnergy > PowerNetEnergyDrainedPerTick); if (compBattery != null) { compBattery.DrawPower(PowerNetEnergyDrainedPerTick); //Add to our energy. energyNeed.CurLevel += energyNeed.MaxLevel / MaxTicksSpentCharging; } ticksSpentCharging++; }; rechargeToil.AddEndCondition(delegate { if (powerBuilding == null || powerBuilding.PowerComp == null /*|| temporaryTrader == null*/) { return(JobCondition.Incompletable); } if (powerBuilding.PowerComp?.PowerNet.CurrentStoredEnergy() < PowerNetEnergyDrainedPerTick) { return(JobCondition.Incompletable); } if (energyNeed.CurLevelPercentage >= 0.99f) { return(JobCondition.Succeeded); } if (ticksSpentCharging > MaxTicksSpentCharging) { return(JobCondition.Incompletable); } return(JobCondition.Ongoing); }); if (!TargetB.IsValid) { rechargeToil.FailOnCannotTouch(PowerDestIndex, PathEndMode.ClosestTouch); } else { rechargeToil.FailOnCannotTouch(AlternateDestIndex, PathEndMode.OnCell); } rechargeToil.WithProgressBar(TargetIndex.A, () => energyNeed.CurLevelPercentage, false); rechargeToil.defaultCompleteMode = ToilCompleteMode.Never; yield return(rechargeToil); }
public override void DecorateWaitToil(Toil wait) { base.DecorateWaitToil(wait); wait.AddFailCondition(() => !pawn.Downed); }
public static Toil makeCleanToil(TargetIndex progListIndex, TargetIndex filthListIndex, Toil nextTarget) { Toil toil = new Toil(); toil.initAction = delegate() { Filth filth = toil.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth; var progQue = toil.actor.jobs.curJob.GetTargetQueue(progListIndex); progQue[0] = new IntVec3(0, 0, (int)filth.def.filth.cleaningWorkToReduceThickness * filth.thickness); }; toil.tickAction = delegate() { Filth filth = toil.actor.jobs.curJob.GetTarget(filthListIndex).Thing as Filth; var progQue = toil.actor.jobs.curJob.GetTargetQueue(progListIndex); IntVec3 iv = progQue[0].Cell; iv.x += 1; iv.y += 1; if (iv.x > filth.def.filth.cleaningWorkToReduceThickness) { filth.ThinFilth(); iv.x = 0; if (filth.Destroyed) { toil.actor.records.Increment(RecordDefOf.MessesCleaned); toil.actor.jobs.curDriver.ReadyForNextToil(); return; } } progQue[0] = iv; }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.WithEffect(EffecterDefOf.Clean, filthListIndex); toil.WithProgressBar(filthListIndex, delegate() { var q = toil.actor.CurJob.GetTargetQueue(progListIndex)[0]; float result = (float)q.Cell.y / q.Cell.z; return(result); } , true, -0.5f); toil.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); toil.JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget); toil.JumpIfOutsideHomeArea(filthListIndex, nextTarget); toil.FailOnDestroyedOrNull(TargetIndex.A); return(toil); }
public static Toil reserveChewSpot(TargetIndex ingestibleInd, TargetIndex StoreToInd) { Toil toil = new Toil(); toil.initAction = delegate() { Pawn actor = toil.actor; IntVec3 intVec = IntVec3.Invalid; Thing thing = null; Thing thing2 = actor.CurJob.GetTarget(ingestibleInd).Thing; Predicate <Thing> baseChairValidator = delegate(Thing t) { if (t.def.building == null || !t.def.building.isSittable) { return(false); } if (t.IsForbidden(actor)) { return(false); } if (!actor.CanReserve(t, 1, -1, null, false)) { return(false); } if (!t.IsSociallyProper(actor)) { return(false); } if (t.IsBurning()) { return(false); } if (t.HostileTo(actor)) { return(false); } bool result = false; for (int i = 0; i < 4; i++) { Building edifice = (t.Position + GenAdj.CardinalDirections[i]).GetEdifice(t.Map); if (edifice != null && edifice.def.surfaceType == SurfaceType.Eat) { result = true; break; } } return(result); }; if (thing2.def.ingestible.chairSearchRadius > 0f) { thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.OnCell, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), thing2.def.ingestible.chairSearchRadius, (Thing t) => baseChairValidator(t) && t.Position.GetDangerFor(actor, t.Map) == Danger.None, null, 0, -1, false, RegionType.Set_Passable, false); } if (thing == null) { intVec = RCellFinder.SpotToChewStandingNear(actor, actor.CurJob.GetTarget(ingestibleInd).Thing); Danger chewSpotDanger = intVec.GetDangerFor(actor, actor.Map); if (chewSpotDanger != Danger.None) { thing = GenClosest.ClosestThingReachable(actor.Position, actor.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.OnCell, TraverseParms.For(actor, Danger.Deadly, TraverseMode.ByPawn, false), thing2.def.ingestible.chairSearchRadius, (Thing t) => baseChairValidator(t) && t.Position.GetDangerFor(actor, t.Map) <= chewSpotDanger, null, 0, -1, false, RegionType.Set_Passable, false); } } if (thing == null) { actor.Map.pawnDestinationReservationManager.Reserve(actor, actor.CurJob, intVec); actor.CurJob.SetTarget(StoreToInd, intVec); } else { intVec = thing.Position; actor.Reserve(thing, actor.CurJob, 1, -1, null, true); actor.Map.pawnDestinationReservationManager.Reserve(actor, actor.CurJob, intVec); actor.CurJob.SetTarget(StoreToInd, thing); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { //Commence fail checks! this.FailOnDestroyedOrNull(TargetIndex.A); this.FailOnDestroyedOrNull(TargetIndex.B); yield return(Toils_Reserve.Reserve(TakeeIndex, 1)); yield return(Toils_Reserve.Reserve(AltarIndex, 1)); yield return(new Toil { initAction = delegate { DropPoint.IsLoading = true; customString = "BloodHaulPrisoner_Gathering".Translate(); } }); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(Toils_Construct.UninstallIfMinifiable(TargetIndex.A).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(Toils_Haul.StartCarryThing(TargetIndex.A)); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch)); Toil waitingTime = new Toil(); waitingTime.defaultCompleteMode = ToilCompleteMode.Delay; waitingTime.defaultDuration = 400; waitingTime.WithProgressBarToilDelay(TargetIndex.A, false, -0.5f); waitingTime.initAction = delegate { customString = "BloodHaulPrisoner_Strapping".Translate(new object[] { this.Takee.LabelShort }); }; yield return(waitingTime); yield return(new Toil { initAction = delegate { customString = "BloodHaulPrisoner_Finished".Translate(); IntVec3 position = this.DropPoint.Position; Thing thing; this.pawn.carryTracker.TryDropCarriedThing(position, ThingPlaceMode.Direct, out thing, null); if (!this.DropPoint.Destroyed) { PrisonerHaulCompleted(); } }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Reserve.Release(TargetIndex.B)); //Toil 9: Think about that. yield return(new Toil { initAction = delegate { ////It's a day to remember //TaleDef taleToAdd = TaleDef.Named("HeldSermon"); //if ((this.pawn.IsColonist || this.pawn.HostFaction == Faction.OfPlayer) && taleToAdd != null) //{ // TaleRecorder.RecordTale(taleToAdd, new object[] // { // this.pawn, // }); //} }, defaultCompleteMode = ToilCompleteMode.Instant }); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { if (TargetA.Thing != null) { targetThing = TargetA.Thing; } Toil gotoThing = new Toil() { initAction = () => { pawn.pather.StartPath(TargetA, PathEndMode.Touch); }, defaultCompleteMode = ToilCompleteMode.PatherArrival }; yield return(gotoThing); Toil doSpell = new Toil(); doSpell.initAction = delegate { if (ability != null) { this.duration = (int)(ability.Def.MainVerb.warmupTime * 60 * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false)); } if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } if (targetThing != null && (targetThing.DestroyedOrNull() || targetThing.Map == null)) { this.EndJobWith(JobCondition.Incompletable); } if (targetThing != null) { this.pawn.rotationTracker.FaceTarget(targetThing); } }; doSpell.tickAction = delegate { if (targetThing != null && (targetThing.DestroyedOrNull() || targetThing.Map == null)) { this.EndJobWith(JobCondition.Incompletable); } age++; ticksLeftThisToil = duration - age; if (Find.TickManager.TicksGame % 12 == 0) { TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f)); } if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } }; doSpell.defaultCompleteMode = ToilCompleteMode.Never; doSpell.defaultDuration = this.duration; doSpell.AddFinishAction(delegate { if (ability != null) { if (ability.Def == TorannMagicDefOf.TM_Transmutate && targetThing != null) { bool flagRawResource = false; bool flagStuffItem = false; bool flagNoStuffItem = false; bool flagNutrition = false; bool flagCorpse = false; TM_Calc.GetTransmutableThingFromCell(targetThing.Position, pawn, out flagRawResource, out flagStuffItem, out flagNoStuffItem, out flagNutrition, out flagCorpse); TM_Action.DoTransmutate(pawn, targetThing, flagNoStuffItem, flagRawResource, flagStuffItem, flagNutrition, flagCorpse); } else if (ability.Def == TorannMagicDefOf.TM_RegrowLimb) { AbilityUser.SpawnThings tempThing = new SpawnThings(); tempThing.def = ThingDef.Named("SeedofRegrowth"); Verb_RegrowLimb.SingleSpawnLoop(tempThing, TargetA.Cell, pawn.Map); } ability.PostAbilityAttempt(); } //AssignXP(); }); yield return(doSpell); }
/// <summary> /// Find spot, reserve spot, pull thing out of inventory, go to spot, drop stuff, repeat. /// </summary> /// <returns></returns> protected override IEnumerable <Toil> MakeNewToils() { CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>(); HashSet <Thing> carriedThing = takenToInventory.GetHashSet(); if (ModCompatibilityCheck.ExtendedStorageIsActive) { unloadDuration = 20; } Toil wait = Toils_General.Wait(unloadDuration); Toil celebrate = Toils_General.Wait(unloadDuration); yield return(wait); Toil findSpot = new Toil { initAction = () => { ThingCount unloadableThing = FirstUnloadableThing(pawn); if (unloadableThing.Count == 0 && carriedThing.Count == 0) { EndJobWith(JobCondition.Succeeded); } if (unloadableThing.Count != 0) { //StoragePriority currentPriority = StoreUtility.StoragePriorityAtFor(pawn.Position, unloadableThing.Thing); if (!StoreUtility.TryFindStoreCellNearColonyDesperate(unloadableThing.Thing, pawn, out IntVec3 c)) { pawn.inventory.innerContainer.TryDrop(unloadableThing.Thing, ThingPlaceMode.Near, unloadableThing.Thing.stackCount, out Thing _); EndJobWith(JobCondition.Succeeded); } else { job.SetTarget(TargetIndex.A, unloadableThing.Thing); job.SetTarget(TargetIndex.B, c); countToDrop = unloadableThing.Thing.stackCount; } } } }; yield return(findSpot); yield return(Toils_Reserve.Reserve(TargetIndex.B)); yield return(new Toil { initAction = delegate { Thing thing = job.GetTarget(TargetIndex.A).Thing; if (thing == null || !pawn.inventory.innerContainer.Contains(thing)) { carriedThing.Remove(thing); pawn.jobs.curDriver.JumpToToil(wait); return; } if (!pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation) || !thing.def.EverStorable(false)) { pawn.inventory.innerContainer.TryDrop(thing, ThingPlaceMode.Near, countToDrop, out thing); EndJobWith(JobCondition.Succeeded); carriedThing.Remove(thing); } else { pawn.inventory.innerContainer.TryTransferToContainer(thing, pawn.carryTracker.innerContainer, countToDrop, out thing); job.count = countToDrop; job.SetTarget(TargetIndex.A, thing); carriedThing.Remove(thing); } try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = pawn.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.UpdateInventory(); } }))(); } catch (TypeLoadException) { } thing.SetForbidden(false, false); } }); Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.Touch)); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, true)); //If the original cell is full, PlaceHauledThingInCell will set a different TargetIndex resulting in errors on yield return Toils_Reserve.Release. //We still gotta release though, mostly because of Extended Storage. Toil releaseReservation = new Toil { initAction = () => { if (pawn.Map.reservationManager.ReservedBy(job.targetB, pawn, pawn.CurJob) && !ModCompatibilityCheck.HCSKIsActive) { pawn.Map.reservationManager.Release(job.targetB, pawn, pawn.CurJob); } } }; yield return(releaseReservation); yield return(Toils_Jump.Jump(wait)); yield return(celebrate); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOn(delegate { if (!CurJob.ignoreDesignations) { Pawn victim = Victim; if (victim != null && !victim.Dead && Map.designationManager.DesignationOn(victim, DesignationDefOf.Hunt) == null) { return(true); } } return(false); }); yield return(Toils_Reserve.Reserve(VictimInd, 1)); var init = new Toil(); init.initAction = delegate { jobStartTick = Find.TickManager.TicksGame; }; yield return(init); yield return(Toils_Combat.TrySetJobToUseAttackVerb()); var comp = (pawn.equipment != null && pawn.equipment.Primary != null) ? pawn.equipment.Primary.TryGetComp <CompAmmoUser>() : null; var startCollectCorpse = StartCollectCorpseToil(); var gotoCastPos = GotoCastPosition(VictimInd, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse).FailOn(() => Find.TickManager.TicksGame > jobStartTick + MaxHuntTicks); yield return(gotoCastPos); //var moveIfCannotHit = Toils_Jump.JumpIfTargetNotHittable(VictimInd, gotoCastPos); var moveIfCannotHit = Toils_Jump.JumpIf(gotoCastPos, delegate { var verb = CurJob.verbToUse; var optimalRange = HuntRangePerBodysize(Victim.RaceProps.baseBodySize, Victim.RaceProps.executionRange, verb.verbProps.range); if (pawn.Position.DistanceTo(Victim.Position) > optimalRange) { return(true); } return(!verb.CanHitTarget(Victim)); }); yield return(moveIfCannotHit); yield return(Toils_Jump.JumpIfTargetDespawnedOrNull(VictimInd, startCollectCorpse)); var startExecuteDowned = Toils_Goto.GotoThing(VictimInd, PathEndMode.Touch).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse); yield return(Toils_Jump.JumpIf(startExecuteDowned, () => Victim.Downed && Victim.RaceProps.executionRange <= 2)); yield return(Toils_Jump.JumpIfTargetDownedDistant(VictimInd, gotoCastPos)); yield return(Toils_Combat.CastVerb(VictimInd, false).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse) .FailOn(() => { if (Find.TickManager.TicksGame <= jobStartTick + MaxHuntTicks) { if (comp == null || comp.HasAndUsesAmmoOrMagazine) { return false; } } return true; })); yield return(Toils_Jump.Jump(moveIfCannotHit)); // Execute downed animal - adapted from JobDriver_Slaughter yield return(startExecuteDowned); yield return(Toils_General.WaitWith(VictimInd, 180, true).JumpIfDespawnedOrNull(VictimInd, startCollectCorpse)); yield return(new Toil { initAction = delegate { ExecutionUtility.DoExecutionByCut(pawn, Victim); }, defaultCompleteMode = ToilCompleteMode.Instant }); // Haul corpse to stockpile yield return(startCollectCorpse); yield return(Toils_Goto.GotoCell(VictimInd, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(VictimInd).FailOnSomeonePhysicallyInteracting(VictimInd)); yield return(Toils_Haul.StartCarryThing(VictimInd)); var carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, true)); }
public static IEnumerable <Toil> MakeFeedToils(JobDef job, JobDriver thisDriver, Pawn actor, LocalTargetInfo TargetA, ThoughtDef victimThoughtDef, ThoughtDef actorThoughtDef, float workLeft, Action effect, Func <Pawn, Pawn, bool> stopCondition, bool needsGrapple = true, bool cleansWound = true, bool neverGiveUp = false) { yield return(Toils_Reserve.Reserve(TargetIndex.A)); Toil gotoToil = actor?.Faction == TargetA.Thing?.Faction && (!actor.InAggroMentalState && !((Pawn)TargetA.Thing).InAggroMentalState) ? Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch) : Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); yield return(gotoToil); Toil grappleToil = new Toil() { initAction = delegate { MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); workLeft = BaseFeedTime; Pawn victim = TargetA.Thing as Pawn; if (victim != null) { // if (!AllowFeeding(actor, victim)) // { // actor.jobs.EndCurrentJob(JobCondition.Incompletable); // } if (actor.InAggroMentalState || victim.InAggroMentalState || victim.Faction != actor.Faction) { if (needsGrapple) { int grappleBonus = actor is PawnTemporary ? 100 : 0; if (!JecsTools.GrappleUtility.TryGrapple(actor, victim, grappleBonus)) { thisDriver.EndJobWith(JobCondition.Incompletable); PawnUtility.ForceWait(actor, (int)(BaseFeedTime * 0.15f)); return; } } } if (actor.IsVampire()) { VampireBiteUtility.MakeNew(actor, victim); } victim.stances.stunner.StunFor((int)BaseFeedTime); } } }; yield return(grappleToil); Toil feedToil = new Toil() { tickAction = delegate { //try //{ if (TargetA.Thing is Pawn victim && victim.Spawned && !victim.Dead) { workLeft--; VampireWitnessUtility.HandleWitnessesOf(job, actor, victim); if (victim?.needs?.mood?.thoughts?.memories != null) { Thought_Memory victimThought = null; if (victimThoughtDef != null) { victimThought = (Thought_Memory)ThoughtMaker.MakeThought(victimThoughtDef); } if (victimThought != null) { victim.needs.mood.thoughts.memories.TryGainMemory(victimThought); } } if (actor?.needs?.mood?.thoughts?.memories != null) { Thought_Memory actorThought = null; if (actorThoughtDef != null) { actorThought = (Thought_Memory)ThoughtMaker.MakeThought(actorThoughtDef); } if (actorThought != null) { actor.needs.mood.thoughts.memories.TryGainMemory(actorThought); } } if (workLeft <= 0f) { if (actor?.VampComp() is CompVampire v && v.IsVampire && actor.Faction == Faction.OfPlayer) { MoteMaker.ThrowText(actor.DrawPos, actor.Map, "XP +" + 15); v.XP += 15; } workLeft = BaseFeedTime; MoteMaker.MakeColonistActionOverlay(actor, ThingDefOf.Mote_ColonistAttacking); effect(); if (victim != null && !victim.Dead && needsGrapple) { if (!JecsTools.GrappleUtility.TryGrapple(actor, victim)) { thisDriver.EndJobWith(JobCondition.Incompletable); } } if (!stopCondition(actor, victim)) { thisDriver.ReadyForNextToil(); if (actor.IsVampire() && cleansWound) { VampireBiteUtility.CleanBite(actor, victim); } } else { if (victim != null && !victim.Dead) { victim.stances.stunner.StunFor((int)BaseFeedTime); PawnUtility.ForceWait((Pawn)TargetA.Thing, (int)BaseFeedTime, actor); } } } }
protected override IEnumerable <Toil> MakeNewToils() { Vehicle_Cart cart = CurJob.GetTarget(CartInd).Thing as Vehicle_Cart; Job jobNew = new Job(); /// //Set fail conditions /// this.FailOnDestroyedOrNull(CartInd); this.FailOn(() => !cart.mountableComp.IsMounted); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items if (!TargetThingA.IsForbidden(pawn.Faction)) { this.FailOnForbidden(CartInd); } /// //Define Toil /// Toil releaseAnimalCart = Toils_Cart.ReleaseAnimalCart(CartInd); Toil checkCartEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => cart.storage.Count <= 0); Toil checkStoreCellEmpty = Toils_Jump.JumpIf(releaseAnimalCart, () => CurJob.GetTargetQueue(StoreCellInd).NullOrEmpty()); Toil checkHaulableEmpty = Toils_Jump.JumpIf(checkStoreCellEmpty, () => CurJob.GetTargetQueue(HaulableInd).NullOrEmpty()); /// //Toils Start /// //Reserve thing to be stored and storage cell yield return(Toils_Reserve.Reserve(CartInd)); yield return(Toils_Reserve.ReserveQueue(HaulableInd)); yield return(Toils_Reserve.ReserveQueue(StoreCellInd)); yield return(Toils_Goto.GotoThing(CartInd, PathEndMode.Touch) .FailOn(() => cart.Destroyed || !cart.TryGetComp <CompMountable>().IsMounted)); //JumpIf toilCheckStoreCellEmpty yield return(checkHaulableEmpty); //Collect TargetQueue { Toil extractA = Toils_Collect.Extract(HaulableInd); yield return(extractA); Toil callAnimalCartForCollect = Toils_Cart.CallAnimalCart(CartInd, HaulableInd) .FailOnDestroyedOrNull(HaulableInd); yield return(callAnimalCartForCollect); yield return(Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnDestroyedOrNull(HaulableInd)); yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd)); yield return(Toils_Collect.CollectInCarrier(CartInd, HaulableInd)); yield return(Toils_Collect.CheckDuplicates(callAnimalCartForCollect, CartInd, HaulableInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(HaulableInd, extractA)); } //JumpIf releaseAnimalCart yield return(checkStoreCellEmpty); //Drop TargetQueue { yield return(checkCartEmpty); Toil extractB = Toils_Collect.Extract(StoreCellInd); yield return(extractB); Toil callAnimalCartForDrop = Toils_Cart.CallAnimalCart(CartInd, StoreCellInd); yield return(callAnimalCartForDrop); yield return(Toils_Goto.GotoCell(StoreCellInd, PathEndMode.ClosestTouch) .FailOnBurningImmobile(StoreCellInd)); yield return(Toils_Cart.WaitAnimalCart(CartInd, HaulableInd)); yield return(Toils_Collect.DropTheCarriedInCell(StoreCellInd, ThingPlaceMode.Direct, CartInd)); yield return(Toils_Jump.JumpIfHaveTargetInQueue(StoreCellInd, checkCartEmpty)); yield return(Toils_Collect.CheckNeedStorageCell(callAnimalCartForDrop, CartInd, StoreCellInd)); } yield return(releaseAnimalCart); }
//get next, goto, take, check for more. Branches off to "all over the place" protected override IEnumerable <Toil> MakeNewToils() { CompHauledToInventory takenToInventory = pawn.TryGetComp <CompHauledToInventory>(); Toil wait = Toils_General.Wait(2); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(TargetIndex.A); //also does count yield return(nextTarget); //honestly the workgiver checks for encumbered, so until CE checks are in this is unnecessary //yield return CheckForOverencumbered();//Probably redundant without CE checks var gotoThing = new Toil { initAction = () => pawn.pather.StartPath(TargetThingA, PathEndMode.ClosestTouch), defaultCompleteMode = ToilCompleteMode.PatherArrival }; gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(gotoThing); var takeThing = new Toil { initAction = () => { Pawn actor = pawn; Thing thing = actor.CurJob.GetTarget(TargetIndex.A).Thing; Toils_Haul.ErrorCheckForCarry(actor, thing); //get max we can pick up var countToPickUp = Mathf.Min(job.count, MassUtility.CountToPickUpUntilOverEncumbered(actor, thing)); Log.Message($"{actor} is hauling to inventory {thing}:{countToPickUp}"); // yo dawg, I heard you like delegates so I put delegates in your delegate, so you can delegate your delegates. // because compilers don't respect IF statements in delegates and toils are fully iterated over as soon as the job starts. try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.CanFitInInventory(thing, out countToPickUp); } }))(); } catch (TypeLoadException) { } if (countToPickUp > 0) { Thing splitThing = thing.SplitOff(countToPickUp); var shouldMerge = takenToInventory.GetHashSet().Any(x => x.def == thing.def); actor.inventory.GetDirectlyHeldThings().TryAdd(splitThing, shouldMerge); takenToInventory.RegisterHauledItem(splitThing); try { ((Action)(() => { if (ModCompatibilityCheck.CombatExtendedIsActive) { //CombatExtended.CompInventory ceCompInventory = actor.GetComp<CombatExtended.CompInventory>(); //ceCompInventory.UpdateInventory(); } }))(); } catch (TypeLoadException) { } } //thing still remains, so queue up hauling if we can + end the current job (smooth/instant transition) //This will technically release the reservations in the queue, but what can you do if (thing.Spawned) { Job haul = HaulAIUtility.HaulToStorageJob(actor, thing); if (haul?.TryMakePreToilReservations(actor, false) ?? false) { actor.jobs.jobQueue.EnqueueFirst(haul, JobTag.Misc); } actor.jobs.curDriver.JumpToToil(wait); } } }; yield return(takeThing); yield return(Toils_Jump.JumpIf(nextTarget, () => !job.targetQueueA.NullOrEmpty())); //Find more to haul, in case things spawned while this was in progess yield return(new Toil { initAction = () => { List <Thing> haulables = pawn.Map.listerHaulables.ThingsPotentiallyNeedingHauling(); var haulMoreWork = DefDatabase <WorkGiverDef> .AllDefsListForReading.First(wg => wg.Worker is WorkGiver_HaulToInventory).Worker as WorkGiver_HaulToInventory; Thing haulMoreThing = GenClosest.ClosestThing_Global(pawn.Position, haulables, 12, t => haulMoreWork.HasJobOnThing(pawn, t)); //WorkGiver_HaulToInventory found more work nearby if (haulMoreThing != null) { Log.Message($"{pawn} hauling again : {haulMoreThing}"); Job haulMoreJob = haulMoreWork.JobOnThing(pawn, haulMoreThing); if (haulMoreJob.TryMakePreToilReservations(pawn, false)) { pawn.jobs.jobQueue.EnqueueFirst(haulMoreJob, JobTag.Misc); EndJobWith(JobCondition.Succeeded); } } } }); //maintain cell reservations on the trip back //TODO: do that when we carry things //I guess that means TODO: implement carrying the rest of the items in this job instead of falling back on HaulToStorageJob yield return(Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.ClosestTouch)); yield return(new Toil //Queue next job { initAction = () => { Pawn actor = pawn; Job curJob = actor.jobs.curJob; LocalTargetInfo storeCell = curJob.targetB; Job unloadJob = JobMaker.MakeJob(PickUpAndHaulJobDefOf.UnloadYourHauledInventory, storeCell); if (unloadJob.TryMakePreToilReservations(actor, false)) { actor.jobs.jobQueue.EnqueueFirst(unloadJob, JobTag.Misc); EndJobWith(JobCondition.Succeeded); //This will technically release the cell reservations in the queue, but what can you do } } }); yield return(wait); }
public static new Toil PlaceHauledThingInCell(TargetIndex cellInd, Toil nextToilOnPlaceFailOrIncomplete, bool storageMode, bool tryStoreInSameStorageIfSpotCantHoldWholeStack = false) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; IntVec3 cell = curJob.GetTarget(cellInd).Cell; if (actor.carryTracker.CarriedThing == null) { Log.Error(string.Concat(actor, " tried to place hauled thing in cell but is not hauling anything.")); } else { SlotGroup slotGroup = actor.Map.haulDestinationManager.SlotGroupAt(cell); if (slotGroup != null && slotGroup.Settings.AllowedToAccept(actor.carryTracker.CarriedThing)) { actor.Map.designationManager.TryRemoveDesignationOn(actor.carryTracker.CarriedThing, DesignationDefOf.Haul); } Action <Thing, int> placedAction = null; if (curJob.def == CultsDefOf.Cults_DoBill /*JobDefOf.DoBill*/ || curJob.def == JobDefOf.RefuelAtomic || curJob.def == JobDefOf.RearmTurretAtomic) { placedAction = delegate(Thing th, int added) { if (curJob.placedThings == null) { curJob.placedThings = new List <ThingCountClass>(); } ThingCountClass thingCountClass = curJob.placedThings.Find((ThingCountClass x) => x.thing == th); if (thingCountClass != null) { thingCountClass.Count += added; } else { curJob.placedThings.Add(new ThingCountClass(th, added)); if (th is Pawn) // inserted code, sacrifice must not move { Pawn sacrifice = (Pawn)th; Job job = JobMaker.MakeJob(Cults.CultsDefOf.Cults_WaitDemise); sacrifice.jobs.TryTakeOrderedJob(job); Log.Message("sacrificing: " + sacrifice.LabelShort.ToString()); } } }; } if (!actor.carryTracker.TryDropCarriedThing(cell, ThingPlaceMode.Direct, out Thing _, placedAction)) { if (storageMode) { if (nextToilOnPlaceFailOrIncomplete != null && ((tryStoreInSameStorageIfSpotCantHoldWholeStack && StoreUtility.TryFindBestBetterStoreCellForIn(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, cell.GetSlotGroup(actor.Map), out IntVec3 foundCell)) || StoreUtility.TryFindBestBetterStoreCellFor(actor.carryTracker.CarriedThing, actor, actor.Map, StoragePriority.Unstored, actor.Faction, out foundCell))) { if (actor.CanReserve(foundCell)) { actor.Reserve(foundCell, actor.CurJob); } actor.CurJob.SetTarget(cellInd, foundCell); actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); } else { Job job = HaulAIUtility.HaulAsideJobFor(actor, actor.carryTracker.CarriedThing); if (job != null) { curJob.targetA = job.targetA; curJob.targetB = job.targetB; curJob.targetC = job.targetC; curJob.count = job.count; curJob.haulOpportunisticDuplicates = job.haulOpportunisticDuplicates; curJob.haulMode = job.haulMode; actor.jobs.curDriver.JumpToToil(nextToilOnPlaceFailOrIncomplete); } else { Log.Error(string.Concat("Incomplete haul for ", actor, ": Could not find anywhere to put ", actor.carryTracker.CarriedThing, " near ", actor.Position, ". Destroying. This should never happen!")); actor.carryTracker.CarriedThing.Destroy(); } } }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Reserve.Reserve(terraformerIndex)); yield return(Toils_Goto.GotoCell(terraformerIndex, PathEndMode.InteractionCell).FailOnDestroyed(terraformerIndex)); yield return(Toils_General.Wait(1500).FailOnDestroyed(terraformerIndex)); Toil beaconDisablingResultToil = new Toil() { initAction = () => { string eventTitle = ""; string eventText = ""; float raidPointsFactor = 1f; int dropsNumber = 0; LetterType letterType = LetterType.BadUrgent; Building_MechanoidTerraformer terraformer = this.TargetThingA as Building_MechanoidTerraformer; terraformer.invasionIsDone = true; string sheHeOrIt = "it"; string herHimOrIt = "it"; string herHisOrIts = "its"; if (pawn.gender == Gender.Female) { sheHeOrIt = "she"; herHisOrIts = "her"; herHimOrIt = "her"; } else if (pawn.gender == Gender.Male) { sheHeOrIt = "he"; herHisOrIts = "his"; herHimOrIt = "him"; } if ((this.pawn.skills.GetSkill(SkillDefOf.Research).TotallyDisabled == true) || (this.pawn.skills.GetSkill(SkillDefOf.Research).level < 3)) { eventTitle = "Invasion"; eventText = " " + this.pawn.Name.ToStringShort + " has tried to disable the terraformer beacon but technology is not " + herHisOrIts + " big passion... " + sheHeOrIt.CapitalizeFirst() + " just pressed on every button alerting by the way every nearby mechanoid shuttles.\n\n" + "Be prepared to welcome some nasty and numerous visitors from nearby mechanoid hives!"; raidPointsFactor = 1.4f; dropsNumber = 5; letterType = LetterType.BadUrgent; } else if (this.pawn.skills.GetSkill(SkillDefOf.Research).level == 20) { eventTitle = "Beacon disabled"; eventText = " " + this.pawn.Name.ToStringShort + " is a real crack in alien technology. Disabling the terraformer beacon was just another game for " + herHimOrIt + "\n\n" + "You have nothing to fear from it anymore."; raidPointsFactor = 0f; dropsNumber = 0; letterType = LetterType.Good; } else { float rand = Rand.Value * 100; if (rand < this.pawn.skills.GetSkill(SkillDefOf.Research).level *chanceToSucceedPerResearchLevel) { // Disable sucessfull. eventTitle = "Beacon disabled"; eventText = " Even if " + this.pawn.Name.ToStringShort + " is not the best about alien technology, " + sheHeOrIt + " successfully disabled the terraformer beacon!\n\n" + "You have nothing to fear from it anymore."; raidPointsFactor = 0f; dropsNumber = 0; letterType = LetterType.Good; } else { // Bad luck. eventTitle = "Invasion"; eventText = " " + this.pawn.Name.ToStringShort + " has some knowledge about alien technology but " + sheHeOrIt + " still failed at properly disabling the terraformer beacon.\n\n" + "Be prepared to welcome the incoming terrafomer defending force."; raidPointsFactor = 0.4f; dropsNumber = 2; letterType = LetterType.BadUrgent; } } terraformer.LaunchInvasion(eventTitle, eventText, raidPointsFactor, dropsNumber, letterType); }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return(beaconDisablingResultToil); yield return(Toils_Reserve.Release(terraformerIndex)); }
protected override IEnumerable <Toil> MakeNewToils() { //this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOn(delegate { return(pawn == Victim); }); this.FailOn(delegate { return(BloodMaster.CurBloodPoints == 0); }); this.FailOnAggroMentalState(TargetIndex.A); yield return(Toils_Reserve.Reserve(TargetIndex.A)); var toil = GetActor()?.Faction == TargetA.Thing?.Faction ? Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch) : Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch); Toil gotoToil = toil; yield return(gotoToil); Toil grappleToil = new Toil() { initAction = delegate { MoteMaker.MakeColonistActionOverlay(GetActor(), ThingDefOf.Mote_ColonistAttacking); workLeft = BaseFeedTime; Pawn victim = TargetA.Thing as Pawn; if (victim != null) { if (GetActor().InAggroMentalState || victim.InAggroMentalState || victim.Faction != GetActor().Faction) { int grappleBonus = GetActor() is PawnTemporary ? 100 : 0; if (!JecsTools.GrappleUtility.TryGrapple(GetActor(), victim, grappleBonus)) { this.EndJobWith(JobCondition.Incompletable); PawnUtility.ForceWait(GetActor(), (int)(BaseFeedTime * 0.15f)); return; } } if (GetActor().IsVampire()) { //VampireBiteUtility.MakeNew(GetActor(), GetActor()); //Actor opens their own wound. victim.stances.stunner.StunFor((int)BaseFeedTime); } } } }; yield return(grappleToil); Toil feedToil = new Toil() { tickAction = delegate { //try //{ if (TargetA.Thing is Pawn victim && victim.Spawned && !victim.Dead) { workLeft--; VampireWitnessUtility.HandleWitnessesOf(this.job.def, GetActor(), victim); // if (victim?.needs?.mood?.thoughts?.memories != null) // { // var victimThoughtDef = VampDefOf.ROMV_IDrankVitae; // Thought_Memory victimThought = null; // if (victimThoughtDef != null) victimThought = (Thought_Memory)ThoughtMaker.MakeThought(victimThoughtDef); // if (victimThought != null) // { // victim.needs.mood.thoughts.memories.TryGainMemory(victimThought); // } // } if (workLeft <= 0f) { if (GetActor()?.VampComp() is CompVampire v && v.IsVampire && GetActor().Faction == Faction.OfPlayer) { MoteMaker.ThrowText(GetActor().DrawPos, GetActor().Map, "XP +" + 15); v.XP += 15; } workLeft = BaseFeedTime; MoteMaker.MakeColonistActionOverlay(GetActor(), ThingDefOf.Mote_ColonistAttacking); if (!victim.IsGhoul()) { CompThrall.InitializeGhoul(GetActor()); } else { CompThrall.ThrallData.TryAdjustBondStage(GetActor(), 1); } BloodMaster.TransferBloodTo(1, BloodThrall, true, true); GhoulUtility.GiveVitaeEffects(victim, GetActor()); //VampireBiteUtility.CleanBite(GetActor(), GetActor()); this.ReadyForNextToil(); } }
protected override IEnumerable <Toil> MakeNewToils() { if (thing == null) { pawn.jobs.EndCurrentJob(JobCondition.InterruptForced); } bool err = false; Toil error = Toils_General.Do(delegate { Log.Error("Error in Toils_Haul.PlaceHauledThingInCell. Breaking job."); Log.Error("thing = " + thing); Log.Error("building = " + building); Log.Error("buildingCell = " + buildingCell); err = true; }); CompProperties_TextThing textThing = thing.TryGetComp <CompTextThing>().Props; if (textThing != null) { float num = 0; //int workLeft = thing.TryGetComp<CompTextThing>().workLeft; CompTextThing compTextThing = thing.TryGetComp <CompTextThing>(); if (building != null && building.GetStatValue(StatDefOf.ResearchSpeedFactor, true) > 0) { num = 1.1f * pawn.GetStatValue(StatDefOf.ResearchSpeed, true); // 1.1 * 0.58 = 0.638 num *= building.GetStatValue(StatDefOf.ResearchSpeedFactor, true); // 0.638 * 1 = 0.638 ticksPerWorkPoint = ticksPerWorkPoint / num; // 60 / 0.638 = 94 } else if (textThing.workSkill != null) { num = (pawn.skills.GetSkill(textThing.workSkill).Level - textThing.minSkillLevel) * 2; if (ticksPerWorkPoint - num > 0) { ticksPerWorkPoint = ticksPerWorkPoint - num; } else { ticksPerWorkPoint = 1; } } this.FailOnForbidden(thingInd); if (building != null) { this.FailOnDespawnedOrNull(buildingInd); this.FailOnForbidden(buildingInd); } //Log.Message("num = " + num); //Log.Message("ticksPerWorkPoint = " + ticksPerWorkPoint); //Log.Message("workLeft = " + workLeft); yield return(Toils_Goto.GotoThing(thingInd, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(thingInd).FailOnSomeonePhysicallyInteracting(thingInd)); yield return(Toils_Misc.SetForbidden(thingInd, false)); yield return(Toils_Haul.StartCarryThing(thingInd, false, false, false)); if (building != null) { if (buildingCell != new IntVec3(-1000, -1000, -1000)) { yield return(Toils_Goto.GotoThing(buildingInd, PathEndMode.InteractionCell).FailOnDespawnedOrNull(buildingInd)); } else { yield return(Toils_Goto.GotoThing(buildingInd, PathEndMode.OnCell).FailOnDespawnedOrNull(buildingInd)); } } if (buildingCell != new IntVec3(-1000, -1000, -1000)) { //Log.Message("buildingCell = " + buildingCell); yield return(Toils_Haul.PlaceHauledThingInCell(buildingCellInd, Toils_Jump.Jump(error), false)); } //IntVec3 thingPosition = thing.PositionHeld; //IntVec3 buildingPosition = building.PositionHeld; float workLeftInTicks = compTextThing.workLeft * (ticksPerWorkPoint * 1.1f); Toil translate = Toils_General.Wait((int)workLeftInTicks).FailOnDespawnedNullOrForbidden(thingInd).FailOnDespawnedNullOrForbidden(buildingInd);; translate.tickAction = delegate { if (textThing.workSkill != null) { pawn.skills.Learn(textThing.workSkill, 0.11f, false); } pawn.GainComfortFromCellIfPossible(); if (pawn.IsHashIntervalTick((int)ticksPerWorkPoint)) { //Log.Message("workLeft = " + compTextThing.workLeft); compTextThing.workLeft--; if (textThing.showTranslator) { if (compTextThing.translator == "") { compTextThing.translator += pawn.Name; } else { if (!compTextThing.translator.Contains(pawn.ToString())) { compTextThing.translator += pawn.Name.ToString(); compTextThing.translator += ", " + pawn.Name; } } } } if (compTextThing.workLeft <= 0) { compTextThing.workLeft = 0; thing.def.BaseMarketValue = textThing.translatedMarketValue; if (textThing.taleWhenTranslated != null) { TaleRecorder.RecordTale(textThing.taleWhenTranslated, new object[] { pawn, thing.def }); } if (textThing.thoughtWhenTranslated != null) { Thought_Memory newThought = (Thought_Memory)ThoughtMaker.MakeThought(textThing.thoughtWhenTranslated); pawn.needs.mood.thoughts.memories.TryGainMemory(newThought, null); } pawn.jobs.EndCurrentJob(JobCondition.Succeeded); } }; //Log.Message("Translate"); yield return(translate); } if (err) { yield return(error); } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { // var toil = new Toil { initAction = delegate { //Empty } }; this.EndOnDespawnedOrNull(InquisitorIndex); this.EndOnDespawnedOrNull(PreacherIndex); //this.EndOnDespawnedOrNull(Build, JobCondition.Incompletable); yield return(Toils_Reserve.Reserve(PreacherIndex, job.def.joyMaxParticipants)); var gotoPreacher = Toils_Goto.GotoThing(PreacherIndex, PathEndMode.ClosestTouch); yield return(gotoPreacher); if (Preacher.jobs.curDriver.asleep) { var watchToil = new Toil { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = job.def.joyDuration }; watchToil.AddPreTickAction(() => { pawn.rotationTracker.FaceCell(Preacher.Position); pawn.GainComfortFromCellIfPossible(); }); yield return(watchToil); } void hitAction() { var prey = Preacher; var surpriseAttack = firstHit; if (pawn.meleeVerbs.TryMeleeAttack(prey, job.verbToUse, surpriseAttack)) { if (!notifiedPlayer && PawnUtility.ShouldSendNotificationAbout(prey)) { notifiedPlayer = true; if (Prefs.AutomaticPauseMode > AutomaticPauseMode.Never && !Find.TickManager.Paused) { Find.TickManager.TogglePaused(); } Messages.Message("MessageAttackedByPredator".Translate( prey.LabelShort, pawn.LabelShort ).CapitalizeFirst(), prey, MessageTypeDefOf.ThreatBig); } pawn.Map.attackTargetsCache.UpdateTarget(pawn); } firstHit = false; } yield return(Toils_Combat.FollowAndMeleeAttack(TargetIndex.A, hitAction) .JumpIfDespawnedOrNull(TargetIndex.A, toil).FailOn(() => Find.TickManager.TicksGame > startTick + 5000 && (job.GetTarget(TargetIndex.A).Cell - pawn.Position).LengthHorizontalSquared > 4f)); yield return(toil); AddFinishAction(() => { //if (this.TargetB.HasThing) //{ // Find.Reservations.Release(this.job.targetC.Thing, pawn); //} }); }
protected override IEnumerable <Toil> MakeNewToils() { // Error checking/input validation. if (turret == null) { Log.Error(string.Concat(errorBase, "TargetThingA isn't a Building_TurretGunCE")); yield return(null); } if (compReloader == null) { Log.Error(string.Concat(errorBase, "TargetThingA (Building_TurretGunCE) is missing its CompAmmoUser.")); yield return(null); } if (compReloader.UseAmmo && ammo == null) { Log.Error(string.Concat(errorBase, "TargetThingB is either null or not an AmmoThing.")); yield return(null); } AddEndCondition(delegate { return((pawn.Downed || pawn.Dead || pawn.InMentalState || pawn.IsBurning()) ? JobCondition.Incompletable : JobCondition.Ongoing); }); this.FailOnIncapable(PawnCapacityDefOf.Manipulation); // Set fail condition on turret. if (pawn.Faction != Faction.OfPlayer) { this.FailOnDestroyedOrNull(TargetIndex.A); } else { this.FailOnDestroyedNullOrForbidden(TargetIndex.A); } // Perform ammo system specific activities, failure condition and hauling if (compReloader.UseAmmo) { var toilGoToCell = Toils_Goto.GotoCell(ammo.Position, PathEndMode.Touch).FailOnBurningImmobile(TargetIndex.B); var toilCarryThing = Toils_Haul.StartCarryThing(TargetIndex.B).FailOnBurningImmobile(TargetIndex.B); if (TargetThingB is AmmoThing) { toilGoToCell.AddEndCondition(delegate { return((TargetThingB as AmmoThing).IsCookingOff ? JobCondition.Incompletable : JobCondition.Ongoing); }); toilCarryThing.AddEndCondition(delegate { return((TargetThingB as AmmoThing).IsCookingOff ? JobCondition.Incompletable : JobCondition.Ongoing); }); } if (pawn.Faction != Faction.OfPlayer) { ammo.SetForbidden(true, false); toilGoToCell.FailOnDestroyedOrNull(TargetIndex.B); toilCarryThing.FailOnDestroyedOrNull(TargetIndex.B); } else { toilGoToCell.FailOnDestroyedNullOrForbidden(TargetIndex.B); toilCarryThing.FailOnDestroyedNullOrForbidden(TargetIndex.B); } //yield return Toils_Reserve.Reserve(TargetIndex.B, Mathf.Max(1, TargetThingB.stackCount - job.count), job.count); yield return(toilGoToCell); yield return(toilCarryThing); //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.A, null, false); } // If ammo system is turned off we just need to go to the turret. yield return(Toils_Goto.GotoCell(turret.Position, PathEndMode.Touch)); //If pawn fails reloading from this point, reset isReloading this.AddFinishAction(delegate { turret.isReloading = false; }); // Wait in place Toil waitToil = new Toil() { actor = pawn }; waitToil.initAction = delegate { // Initial relaod process activities. turret.isReloading = true; waitToil.actor.pather.StopDead(); if (compReloader.ShouldThrowMote) { MoteMaker.ThrowText(turret.Position.ToVector3Shifted(), turret.Map, string.Format("CE_ReloadingTurretMote".Translate(), TargetThingA.LabelCapNoCount)); } Thing newAmmo; compReloader.TryUnload(out newAmmo); if (newAmmo?.CanStackWith(ammo) ?? false) { pawn.carryTracker.TryStartCarry(newAmmo, Mathf.Min(newAmmo.stackCount, compReloader.Props.magazineSize - ammo.stackCount)); } }; waitToil.defaultCompleteMode = ToilCompleteMode.Delay; waitToil.defaultDuration = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed)); yield return(waitToil.WithProgressBarToilDelay(TargetIndex.A)); //Actual reloader Toil reloadToil = new Toil(); reloadToil.defaultCompleteMode = ToilCompleteMode.Instant; reloadToil.initAction = delegate { compReloader.LoadAmmo(ammo); turret.isReloading = false; }; //if (compReloader.useAmmo) reloadToil.EndOnDespawnedOrNull(TargetIndex.B); yield return(reloadToil); }
static IEnumerable <Toil> prepToils(JobDriver_Ingest driver, Toil chewToil) { if ((bool)LeatingFromInventory.GetValue(driver)) { yield return(Toils_Misc.TakeItemFromInventoryToCarrier(driver.pawn, TargetIndex.A)); } else { yield return((Toil)LReserveFood.Invoke(driver, new object[] { })); Toil gotoToPickup = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(Toils_Jump.JumpIf(gotoToPickup, () => driver.pawn.health.capacities.CapableOf(PawnCapacityDefOf.Manipulation))); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch).FailOnDespawnedNullOrForbidden(TargetIndex.A)); yield return(Toils_Jump.Jump(chewToil)); yield return(gotoToPickup); yield return(Toils_Ingest.PickupIngestible(TargetIndex.A, driver.pawn)); gotoToPickup = null; } if (driver.job.takeExtraIngestibles > 0) { foreach (Toil toil in (IEnumerable <Toil>)LTakeExtraIngestibles.Invoke(driver, new object[] { })) { yield return(toil); } } if (!driver.pawn.Drafted) { yield return(reserveChewSpot(TargetIndex.A, TargetIndex.B)); Toil gotospot = gotoSpot(TargetIndex.B).FailOnDestroyedOrNull(TargetIndex.A); if (!Utility.IncapableOfCleaning(driver.pawn)) { TargetIndex filthListIndex = TargetIndex.B; TargetIndex progListIndex = TargetIndex.A; Toil FilthList = makeFilthListToil(filthListIndex); yield return(FilthList); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); Toil nextTarget = Toils_JobTransforms.ExtractNextTargetFromQueue(filthListIndex, true); yield return(nextTarget); yield return(Toils_Jump.JumpIf(gotospot, () => driver.job.GetTargetQueue(filthListIndex).NullOrEmpty())); yield return(Toils_Goto.GotoThing(filthListIndex, PathEndMode.Touch).JumpIfDespawnedOrNullOrForbidden(filthListIndex, nextTarget).JumpIfOutsideHomeArea(filthListIndex, nextTarget)); // if (driver.job.GetTargetQueue(progListIndex).Count == 0) { driver.job.GetTargetQueue(progListIndex).Add(new IntVec3(0, 0, 0)); } // Toil clean = makeCleanToil(progListIndex, filthListIndex, nextTarget); yield return(clean); yield return(Toils_Jump.Jump(nextTarget)); } yield return(gotospot); } yield return(Toils_Ingest.FindAdjacentEatSurface(TargetIndex.B, TargetIndex.A)); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { //Commence fail checks! this.FailOnDestroyedOrNull(TargetIndex.A); yield return(Toils_Reserve.Reserve(AltarIndex, 1)); yield return(new Toil { initAction = delegate { this.DropAltar.IsFilling = true; this.customString = "FillChthonianPitGoing".Translate(); } }); yield return(Toils_Goto.GotoThing(AltarIndex, PathEndMode.Touch)); Toil chantingTime = new Toil() { defaultCompleteMode = ToilCompleteMode.Delay, defaultDuration = 5000 }; chantingTime.WithProgressBarToilDelay(AltarIndex, false, -0.5f); chantingTime.PlaySustainerOrSound(() => SoundDefOf.Interact_CleanFilth); chantingTime.initAction = delegate { this.customString = "FillChthonianPitFilling".Translate(); }; chantingTime.AddPreTickAction(() => { if (this.DropAltar.IsActive) { if (Rand.Range(1, 100) > 95) { this.DropAltar.TrySpawnChthonian(); } } if (this.DropAltar.GaveSacrifice) { if (this.pawn.IsHashIntervalTick(300)) { if (Rand.Range(1, 100) > 60) { Messages.Message("CriesFromBelow".Translate(new object[] { this.pawn.LabelShort, this.pawn.gender.GetPronoun() }), MessageTypeDefOf.NegativeEvent); } } } }); yield return(chantingTime); yield return(new Toil { initAction = delegate { this.customString = "FillChthonianPitFinished".Translate(); IntVec3 position = this.DropAltar.Position; FillingCompleted(); }, defaultCompleteMode = ToilCompleteMode.Instant }); yield return(Toils_Reserve.Release(TargetIndex.A)); //Toil 9: Think about that. yield return(new Toil { initAction = delegate { ////It's a day to remember //TaleDef taleToAdd = TaleDef.Named("HeldSermon"); //if ((this.pawn.IsColonist || this.pawn.HostFaction == Faction.OfPlayer) && taleToAdd != null) //{ // TaleRecorder.RecordTale(taleToAdd, new object[] // { // this.pawn, // }); //} }, defaultCompleteMode = ToilCompleteMode.Instant }); yield break; }
static bool Prefix(ref IEnumerable <Toil> __result, JobDriver_Ingest __instance, Toil chewToil) { if (!Settings.adv_cleaning_ingest) { return(true); } // __result = prepToils(__instance, chewToil); return(false); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); chooseCell = Toils_Misc.FindRandomAdjacentReachableCell(TargetIndex.A, TargetIndex.B); this.$current = chooseCell; if (!this.$disposing) { this.$PC = 1; } return(true); case 1u: this.$current = Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell); if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: play = new Toil(); play.initAction = delegate() { this.job.locomotionUrgency = LocomotionUrgency.Walk; }; play.tickAction = delegate() { this.pawn.rotationTracker.FaceCell(base.TargetA.Thing.OccupiedRect().ClosestCellTo(this.pawn.Position)); if (this.ticksLeftThisToil == 300) { SoundDefOf.PlayBilliards.PlayOneShot(new TargetInfo(this.pawn.Position, this.pawn.Map, false)); } if (Find.TickManager.TicksGame > this.startTick + this.job.def.joyDuration) { base.EndJobWith(JobCondition.Succeeded); return; } Pawn pawn = this.pawn; Building joySource = (Building)base.TargetThingA; JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, 1f, joySource); }; play.handlingFacing = true; play.socialMode = RandomSocialMode.SuperActive; play.defaultCompleteMode = ToilCompleteMode.Delay; play.defaultDuration = 600; play.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(this.pawn); }); this.$current = play; if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: this.$current = Toils_Reserve.Release(TargetIndex.B); if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = Toils_Jump.Jump(chooseCell); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: this.$PC = -1; break; } return(false); }
public override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); //this.FailOnBurningImmobile(TargetIndex.B); if (!forbiddenInitially) { this.FailOnForbidden(TargetIndex.A); } var ZTracker = ZUtils.ZTracker; if (pawn.Map == this.job.targetA.Thing.Map && pawn.Map == ZTracker.jobTracker[pawn].targetDest.Map) { ZLogger.Message("pawn map and thing map and dest map are same, yield breaking in JobDriver_HaulThingToDest"); yield break; } ZLogger.Message($"JobDriver HaulThingToDestAndCell1 About to call findRouteWithStairs, with pawn {GetActor()}, dest {new TargetInfo(TargetA.Thing)}, instance {this}"); Log.Message("1 - pawn.Map: " + pawn.Map + " - dest: " + new TargetInfo(TargetA.Thing).Map, true); foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), new TargetInfo(TargetA.Thing).Map, this)) { yield return(toil); } Toil reserveTargetA = Toils_Reserve.Reserve(TargetIndex.A); Toil toilGoto = null; toilGoto = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A).FailOn((Func <bool>) delegate { Pawn actor = toilGoto.actor; Job curJob = actor.jobs.curJob; if (curJob.haulMode == HaulMode.ToCellStorage) { Thing thing = curJob.GetTarget(TargetIndex.A).Thing; if (!actor.jobs.curJob.GetTarget(TargetIndex.B).Cell.IsValidStorageFor(base.Map, thing)) { return(true); } } return(false); }); yield return(new Toil { initAction = delegate() { ZLogger.Message("JobDriver_HaulThingToDestAndToCell 1: " + pawn + " trying to reserve: " + TargetA, true); } }); yield return(reserveTargetA); yield return(toilGoto); yield return(new Toil { initAction = delegate() { this.savedThing = TargetA.Thing; } }); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, putRemainderInQueue: false, subtractNumTakenFromJobCount: true)); if (job.haulOpportunisticDuplicates) { yield return(new Toil { initAction = delegate() { ZLogger.Message("JobDriver_HaulThingToDestAndToCell 2: " + pawn + " trying to reserve other things: " + TargetA, true); } }); yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, TargetIndex.A, TargetIndex.B)); } ZLogger.Message($"JobDriver HaulThingToDestAndCell2 About to call findRouteWithStairs, with pawn {GetActor()}, dest {ZTracker.jobTracker[pawn].targetDest}, instance {this}"); Log.Message("2 - pawn.Map: " + pawn.Map + " - dest: " + ZTracker.jobTracker[pawn].targetDest.Map, true); foreach (var toil in Toils_ZLevels.GoToMap(GetActor(), ZTracker.jobTracker[pawn].targetDest.Map, this)) { yield return(toil); } Toil carryToCell = Toils_Haul.CarryHauledThingToCell(TargetIndex.B); yield return(carryToCell); yield return(new Toil { initAction = delegate() { if (TargetB.Cell.GetFirstItem(pawn.Map) != null) { IntVec3 newPosition = IntVec3.Invalid; IntVec3 center = (from x in GenRadial.RadialCellsAround(pawn.Position, 3f, useCenter: true) where x.InBounds(pawn.Map) && x.GetFirstItem(pawn.Map) == null select x).FirstOrDefault(); if (center != null) { job.targetB = new LocalTargetInfo(center); } else if (CellFinder.TryFindRandomCellNear(TargetB.Cell, pawn.Map, 3, (IntVec3 c) => c.GetFirstItem(pawn.Map)?.def != TargetA.Thing.def, out newPosition)) { job.targetB = new LocalTargetInfo(newPosition); } } } }); yield return(Toils_Haul.PlaceHauledThingInCell(TargetIndex.B, carryToCell, false)); }
private Toil HarvestSeedsToil() { Toil toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.tickAction = delegate { Pawn actor = toil.actor; Plant plant = Plant; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Growing, xpPerTick); } workDone += actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); if (workDone >= plant.def.plant.harvestWork) { if (plant.def.plant.harvestedThingDef != null) { if (actor.RaceProps.Humanlike && plant.def.plant.harvestFailable && Rand.Value < actor.GetStatValue(StatDefOf.HarvestFailChance, true)) { MoteMaker.ThrowText((actor.DrawPos + plant.DrawPos) / 2, actor.Map, "HarvestFailed".Translate(), 3.65f); } else { int plantYield = plant.YieldNow(); ThingDef harvestedThingDef; SeedDef seedDef = plant.def.blueprintDef as SeedDef; if (seedDef != null) { float parameter = Mathf.Max(Mathf.InverseLerp(plant.def.plant.harvestMinGrowth, 1.2f, plant.Growth), 1f); if (seedDef.seed.seedFactor > 0 && Rand.Value < seedDef.seed.baseChance * parameter) { int count; if (Rand.Value < seedDef.seed.extraChance) { count = 2; } else { count = 1; } Thing seeds = ThingMaker.MakeThing(seedDef, null); seeds.stackCount = Mathf.RoundToInt(seedDef.seed.seedFactor * count); GenPlace.TryPlaceThing(seeds, actor.Position, actor.Map, ThingPlaceMode.Near); } plantYield = Mathf.RoundToInt(plantYield * seedDef.seed.harvestFactor); harvestedThingDef = seedDef.harvest; } else { harvestedThingDef = plant.def.plant.harvestedThingDef; } if (plantYield > 0) { Thing thing = ThingMaker.MakeThing(harvestedThingDef, null); thing.stackCount = plantYield; if (actor.Faction != Faction.OfPlayer) { thing.SetForbidden(true, true); } GenPlace.TryPlaceThing(thing, actor.Position, actor.Map, ThingPlaceMode.Near, null); } actor.records.Increment(RecordDefOf.PlantsHarvested); } } plant.def.plant.soundHarvestFinish.PlayOneShot(actor); plant.PlantCollected(); workDone = 0; ReadyForNextToil(); return; } }; toil.FailOnDespawnedNullOrForbidden(TargetIndex.A); toil.WithEffect(EffecterDefOf.Harvest, TargetIndex.A); toil.WithProgressBar(TargetIndex.A, () => workDone / Plant.def.plant.harvestWork, true, -0.5f); toil.PlaySustainerOrSound(() => Plant.def.plant.soundHarvesting); return(toil); }
private Toil Collect() { Toil toil = new Toil(); toil.initAction = delegate { // Increment the record for how many cells this pawn has mined since this counts as mining pawn.records.Increment(RecordDefOf.CellsMined); // Start with None to act as a fallback. Rubble will be returned with this parameter ResourceRequest req = ResourceRequest.None; // Use the mineModeToggle to determine the request req = (Quarry.mineModeToggle ? ResourceRequest.Resources : ResourceRequest.Blocks); MoteType mote = MoteType.None; // Get the resource from the quarry Thing haulableResult = Quarry.GiveResources(req, out mote); // Place the resource near the pawn GenPlace.TryPlaceThing(haulableResult, pawn.Position, Map, ThingPlaceMode.Near); // If the resource had a mote, throw it if (mote == MoteType.LargeVein) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_LargeVein, Color.green, 3f); } else if (mote == MoteType.Failure) { MoteMaker.ThrowText(haulableResult.DrawPos, Map, Static.TextMote_MiningFailed, Color.red, 3f); } // Prevent the colonists from trying to haul rubble, which just makes them visit the platform if (haulableResult.def == ThingDefOf.RockRubble) { EndJobWith(JobCondition.Succeeded); } // If this is a chunk or slag, mark it as haulable if allowed to if (haulableResult.def.designateHaulable && Quarry.autoHaul) { Map.designationManager.AddDesignation(new Designation(haulableResult, DesignationDefOf.Haul)); } // Setup IntVec for assigning IntVec3 c; // Try to find a suitable storage spot for the resource, removing it from the quarry // If there are no platforms, hauling will be done by haulers if (Quarry.autoHaul && Quarry.TryFindBestStoreCellFor(haulableResult, pawn, Map, pawn.Faction, out c)) { CurJob.SetTarget(TargetIndex.B, haulableResult); CurJob.count = haulableResult.stackCount; CurJob.SetTarget(TargetIndex.C, c); } // If there is no spot to store the resource, end this job else { EndJobWith(JobCondition.Succeeded); } }; toil.defaultCompleteMode = ToilCompleteMode.Instant; return(toil); }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; Toil toil; switch (num) { case 0u: this.FailOnDespawnedOrNull(TargetIndex.B); if (this.eatingFromInventory) { this.$current = Toils_Misc.TakeItemFromInventoryToCarrier(this.pawn, TargetIndex.A); if (!this.$disposing) { this.$PC = 1; } return(true); } if (this.usingNutrientPasteDispenser) { this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell).FailOnForbidden(TargetIndex.A); if (!this.$disposing) { this.$PC = 2; } return(true); } this.$current = Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null); if (!this.$disposing) { this.$PC = 4; } return(true); case 1u: break; case 2u: this.$current = Toils_Ingest.TakeMealFromDispenser(TargetIndex.A, this.pawn); if (!this.$disposing) { this.$PC = 3; } return(true); case 3u: break; case 4u: this.$current = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnForbidden(TargetIndex.A); if (!this.$disposing) { this.$PC = 5; } return(true); case 5u: this.$current = Toils_Ingest.PickupIngestible(TargetIndex.A, base.Deliveree); if (!this.$disposing) { this.$PC = 6; } return(true); case 6u: break; case 7u: { Toil toil = new Toil(); toil.initAction = delegate() { Thing thing; this.pawn.carryTracker.TryDropCarriedThing(toil.actor.jobs.curJob.targetC.Cell, ThingPlaceMode.Direct, out thing, null); }; toil.defaultCompleteMode = ToilCompleteMode.Instant; this.$current = toil; if (!this.$disposing) { this.$PC = 8; } return(true); } case 8u: this.$PC = -1; return(false); default: return(false); } toil = new Toil(); toil.initAction = delegate() { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; actor.pather.StartPath(curJob.targetC, PathEndMode.OnCell); }; toil.defaultCompleteMode = ToilCompleteMode.PatherArrival; toil.FailOnDestroyedNullOrForbidden(TargetIndex.B); toil.AddFailCondition(delegate { Pawn pawn = (Pawn)toil.actor.jobs.curJob.targetB.Thing; return(!pawn.IsPrisonerOfColony || !pawn.guest.CanBeBroughtFood); }); this.$current = toil; if (!this.$disposing) { this.$PC = 7; } return(true); }
protected override IEnumerable <Toil> MakeNewToils() { //Set fail conditions this.FailOnDestroyedOrNull(HaulableInd); this.FailOnBurningImmobile(StoreCellInd); //Note we only fail on forbidden if the target doesn't start that way //This helps haul-aside jobs on forbidden items // // TODO instead of this, just use Job.ignoreForbidden where appropriate // if (!forbiddenInitially) { this.FailOnForbidden(HaulableInd); } //Reserve thing to be stored //This is redundant relative to MakePreToilReservations(), but the redundancy doesn't hurt, and if we end up looping and grabbing more things, it's necessary var reserveTargetA = Toils_Reserve.Reserve(HaulableInd); yield return(reserveTargetA); #if DEBUG HaulToStack.Instance.Logger.Trace("Current Job: " + pawn.CurJob.def.defName); #endif //Reserve the location to store //Only do this if (current stack size + what pawn is currently holding + targetA stack size) >= things max stack size //if (HaulUtils.ShouldReserveHaulLocation(job.targetA.Thing, job.targetB.Cell, pawn, Map)) //{ var reserveTargetB = Toils_Reserve.Reserve(StoreCellInd); yield return(reserveTargetB); //} Toil toilGoto = null; toilGoto = Toils_Goto.GotoThing(HaulableInd, PathEndMode.ClosestTouch) .FailOnSomeonePhysicallyInteracting(HaulableInd) .FailOn(() => { //Note we don't fail on losing hauling designation //Because that's a special case anyway //While hauling to cell storage, ensure storage dest is still valid Pawn actor = toilGoto.actor; Job curJob = actor.jobs.curJob; if (curJob.haulMode == HaulMode.ToCellStorage) { Thing haulThing = curJob.GetTarget(HaulableInd).Thing; IntVec3 destLoc = actor.jobs.curJob.GetTarget(TargetIndex.B).Cell; if (!destLoc.IsValidStorageFor(Map, haulThing)) { return(true); } } return(false); }); yield return(toilGoto); yield return(Toils_Haul.StartCarryThing(HaulableInd, subtractNumTakenFromJobCount: true)); if (job.haulOpportunisticDuplicates) { yield return(Toils_Haul.CheckForGetOpportunityDuplicate(reserveTargetA, HaulableInd, StoreCellInd)); //yield return HaulUtils.CheckForGetOpportunityDuplicateReplace(reserveTargetA, HaulableInd, StoreCellInd); //#if DEBUG // HaulToStack.Instance.Logger.Trace("Opportunistic pickup"); // if (getDups == null) // HaulToStack.Instance.Logger.Trace("There are no opportunistic dups"); //#endif // if (HaulUtils.ShouldReserveHaulLocation(nextJob.job.targetA.Thing, job.targetB.Cell, pawn, Map)) // { // var reserveTargetB = Toils_Reserve.Reserve(StoreCellInd); // yield return reserveTargetB; // } } Toil carryToCell = Toils_Haul.CarryHauledThingToCell(StoreCellInd); yield return(carryToCell); yield return(Toils_Haul.PlaceHauledThingInCell(StoreCellInd, carryToCell, true)); }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedNullOrForbidden(TargetIndex.A); this.FailOnCellMissingDesignation(TargetIndex.A, DesignationDefOf.Mine); yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)); Toil mine = new Toil(); mine.tickAction = delegate { Pawn actor = mine.actor; Thing mineTarget = MineTarget; if (ticksToPickHit < -100) { ResetTicksToPickHit(); } if (actor.skills != null && (mineTarget.Faction != actor.Faction || actor.Faction == null)) { actor.skills.Learn(SkillDefOf.Mining, 0.07f); } ticksToPickHit--; if (ticksToPickHit <= 0) { IntVec3 position = mineTarget.Position; if (effecter == null) { effecter = EffecterDefOf.Mine.Spawn(); } effecter.Trigger(actor, mineTarget); int num = mineTarget.def.building.isNaturalRock ? 80 : 40; Mineable mineable = mineTarget as Mineable; if (mineable == null || mineTarget.HitPoints > num) { DamageInfo dinfo = new DamageInfo(DamageDefOf.Mining, num, 0f, -1f, mine.actor); mineTarget.TakeDamage(dinfo); } else { mineable.Notify_TookMiningDamage(mineTarget.HitPoints, mine.actor); mineable.HitPoints = 0; mineable.DestroyMined(actor); } if (mineTarget.Destroyed) { actor.Map.mineStrikeManager.CheckStruckOre(position, mineTarget.def, actor); actor.records.Increment(RecordDefOf.CellsMined); if (pawn.Faction != Faction.OfPlayer) { List <Thing> thingList = position.GetThingList(base.Map); for (int i = 0; i < thingList.Count; i++) { thingList[i].SetForbidden(value: true, warnOnFail: false); } } if (pawn.Faction == Faction.OfPlayer && MineStrikeManager.MineableIsVeryValuable(mineTarget.def)) { TaleRecorder.RecordTale(TaleDefOf.MinedValuable, pawn, mineTarget.def.building.mineableThing); } if (pawn.Faction == Faction.OfPlayer && MineStrikeManager.MineableIsValuable(mineTarget.def) && !pawn.Map.IsPlayerHome) { TaleRecorder.RecordTale(TaleDefOf.CaravanRemoteMining, pawn, mineTarget.def.building.mineableThing); } ReadyForNextToil(); } else { ResetTicksToPickHit(); } } }; mine.defaultCompleteMode = ToilCompleteMode.Never; mine.WithProgressBar(TargetIndex.A, () => 1f - (float)MineTarget.HitPoints / (float)MineTarget.MaxHitPoints); mine.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); mine.activeSkill = (() => SkillDefOf.Mining); yield return(mine); }