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; }
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 override IEnumerable<Toil> MakeNewToils() { ToilFailConditions.FailOnMentalState(this, TargetIndex.A); Toil waitToil = new Toil(); waitToil.initAction = delegate { waitToil.actor.pather.StopDead(); }; waitToil.defaultCompleteMode = ToilCompleteMode.Delay; waitToil.defaultDuration = this.CompReloader.reloaderProp.reloadTick; yield return waitToil; Toil toil = new Toil(); toil.AddFinishAction(new Action(this.CompReloader.FinishReload)); yield return toil; yield break; }
protected override IEnumerable<Toil> MakeNewToils() { //Set what will cause the job to fail this.FailOnBurningImmobile(RepairStationIndex); this.FailOnDestroyedOrForbidden(RepairStationIndex); this.FailOn(delegate { return Repairee == null || !Repairee.ShouldGetRepairs; }); //Reserve the repair station yield return Toils_Reserve.Reserve(RepairStationIndex); //Go to the repair station interaction cell yield return Toils_Goto.GotoThing(RepairStationIndex, PathEndMode.InteractionCell); //Make a new toil that sets the droid to repair mode, then wait until fully repaired Toil toil = new Toil(); toil.FailOnDestroyedOrForbidden(RepairStationIndex); toil.FailOn(() => { return Repairee == null || RPS == null || Repairee.Pawn.Position != TargetThingA.InteractionCell || !RPS.IsAvailable(Repairee); }); toil.initAction = () => { //Log.Message("initAction"); Repairee.BeingRepaired = true; RPS.RegisterRepairee(Repairee); }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.AddFinishAction(delegate { //Log.Message("Finish action"); RPS.DeregisterRepairee(Repairee); Repairee.BeingRepaired = false; }); toil.AddEndCondition(() => { if (Repairee.ShouldGetRepairs) return JobCondition.Ongoing; return JobCondition.Succeeded; }); toil.WithEffect(DefDatabase<EffecterDef>.GetNamed("Repair"), TargetIndex.A); toil.WithSustainer(() => { return DefDatabase<SoundDef>.GetNamed("Interact_Repair"); }); yield return toil; }
public Toil CollectSand(int ticksToCollect) { var targetCell = CurJob.targetA.Cell; var toil = new Toil(); toil.initAction = () => { pawn.jobs.curDriver.ticksLeftThisToil = Mathf.RoundToInt(ticksToCollect*pawn.GetStatValue(StatDef.Named("CollectingSpeed"))); }; toil.AddFinishAction(() => { // remove designation var designation = Find.DesignationManager.DesignationAt(targetCell, DefDatabase<DesignationDef>.GetNamed("CollectSand")); if (designation != null) { Find.DesignationManager.RemoveDesignation(designation); } // replace terrain if (Find.TerrainGrid.TerrainAt(targetCell) == TerrainDef.Named("Sand")) Find.TerrainGrid.SetTerrain(targetCell, DefDatabase<TerrainDef>.GetNamed("Gravel")); // spawn resources var SandYellow = ThingMaker.MakeThing(ThingDef.Named("PileSandYellow")); SandYellow.stackCount = Rand.RangeInclusive(20, 30); GenPlace.TryPlaceThing(SandYellow, targetCell, ThingPlaceMode.Near); // Rand.Value = Rand.Range(0, 1) if (Rand.Value < RareResourceSpawnChance) { var SandWhite = ThingMaker.MakeThing(ThingDef.Named("PileSandWhite")); SandWhite.stackCount = Rand.RangeInclusive(5, 10); GenPlace.TryPlaceThing(SandWhite, targetCell, ThingPlaceMode.Near); } }); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.FailOnCellMissingDesignation(CellInd, DefDatabase<DesignationDef>.GetNamed("CollectSand")); toil.WithEffect(() => EffecterDef.Named("CutStone"), CellInd); return toil; }
protected override IEnumerable<Toil> MakeNewToils() { ICharge chargee = (ICharge)this.pawn; CompDroidCharger charger =TargetThingA.TryGetComp<CompDroidCharger>(); yield return Toils_Reserve.Reserve(TargetIndex.A); Toil goToPad = Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.InteractionCell); goToPad.AddFailCondition(() => { return !charger.IsAvailable(chargee); }); yield return goToPad; Toil charge = new Toil(); charge.initAction = () => { if (charger.parent.InteractionCell != chargee.Parent.Position) { pawn.jobs.EndCurrentJob(JobCondition.Errored); } else { charger.BeginCharge(chargee); chargee.ShouldUsePower = false; } }; charge.defaultCompleteMode = ToilCompleteMode.Never; charge.AddFailCondition(() => { return !charger.IsAvailable(chargee); }); charge.AddEndCondition(() => { if (!chargee.DesiresCharge) { return JobCondition.Succeeded; } return JobCondition.Ongoing; }); charge.AddFinishAction(() => { charger.EndCharge(); chargee.ShouldUsePower = true; }); yield return charge; }
private static Toil TakeFromSynthesier( TargetIndex ind, Pawn eater, Func<ThingDef,bool> validator, Func<ThingDef,ThingDef,int> sorter ) { var synthesizer = (Building_AutomatedFactory) eater.jobs.curJob.GetTarget( ind ).Thing; var bestDef = synthesizer.BestProduct( validator, sorter ); var takeFromSynthesizer = new Toil(); //Log.Message( string.Format( "{0}.TakeMealFromSynthesizier( {1}, {2} )", eater == null ? "null" : eater.NameStringShort, synthesizer == null ? "null" : synthesizer.ThingID, bestDef == null ? "null" : bestDef.defName ) ); if( bestDef == null ) { takeFromSynthesizer.defaultCompleteMode = ToilCompleteMode.Delay; takeFromSynthesizer.AddEndCondition( () => { return JobCondition.Incompletable; } ); takeFromSynthesizer.defaultDuration = 999; } else { takeFromSynthesizer.defaultCompleteMode = ToilCompleteMode.Delay; takeFromSynthesizer.AddFinishAction( () => { Thing thing = synthesizer.TryProduceThingDef( bestDef ); if( thing == null ) { Log.Error( eater.Label + " unable to take " + bestDef.label + " from " + synthesizer.ThingID ); eater.jobs.curDriver.EndJobWith( JobCondition.Incompletable ); } else { eater.carrier.TryStartCarry( thing ); eater.jobs.curJob.targetA = (TargetInfo) eater.carrier.CarriedThing; } } ); takeFromSynthesizer.defaultDuration = synthesizer.ProductionTicks( bestDef ); } return takeFromSynthesizer; }
public static Toil MonitorStation( TargetIndex StationInd, TargetIndex WardenInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = Data.MonitorRemoteJobTicks; toil.WithProgressBarToilDelay( WardenInd ); toil.AddFinishAction( () => { var stationThing = toil.actor.CurJob.GetTarget( StationInd ).Thing; if( stationThing == null ) { throw new Exception( "Target thing is null for Toils_SecurityStation.MonitorStation!" ); } var stationComp = stationThing.TryGetComp<CompSecurityStation>(); if( stationComp == null ) { throw new Exception( "Target thing is missing CompSecurityStation for Toils_SecurityStation.MonitorStation!" ); } stationComp.FinishMonitoring(); Find.Reservations.Release( toil.actor.jobs.curJob.GetTarget( StationInd ), toil.actor ); } ); toil.tickAction = () => { var stationThing = toil.actor.CurJob.GetTarget( StationInd ).Thing; if( stationThing == null ) { throw new Exception( "Target thing is null for Toils_SecurityStation.MonitorStation!" ); } var stationComp = stationThing.TryGetComp<CompSecurityStation>(); if( stationComp == null ) { throw new Exception( "Target thing is missing CompSecurityStation for Toils_SecurityStation.MonitorStation!" ); } stationComp.UpdateMonitor(); }; return toil; }
public static Toil DropCarriedPawnRightHere() { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Instant; toil.AddFinishAction( () => { var pawn = toil.actor; var carriedPawn = pawn.carrier.CarriedThing as Pawn; if( carriedPawn == null ) { throw new Exception( string.Format( "{0} tried to drop pawn but carried thing isn't a pawn!", pawn.NameStringShort ) ); } var cell = pawn.Position; Thing resultingThing; if( !pawn.carrier.TryDropCarriedThing( cell, ThingPlaceMode.Direct, out resultingThing ) ) { if( !pawn.carrier.TryDropCarriedThing( cell, ThingPlaceMode.Near, out resultingThing ) ) { Log.Error( string.Format( "{0} tried to drop {1} but no free cells for placement near {2}", pawn.NameStringShort, carriedPawn.NameStringShort, cell.ToString() ) ); } } } ); return toil; }
public bool MoveNext() { uint num = (uint)this.$PC; this.$PC = -1; switch (num) { case 0u: this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); if (base.HasChair) { this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable); } if (base.HasDrink) { this.FailOnDestroyedNullOrForbidden(TargetIndex.C); this.$current = Toils_Goto.GotoThing(TargetIndex.C, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(TargetIndex.C); if (!this.$disposing) { this.$PC = 1; } return(true); } break; case 1u: this.$current = Toils_Haul.StartCarryThing(TargetIndex.C, false, false, false); if (!this.$disposing) { this.$PC = 2; } return(true); case 2u: break; case 3u: chew = new Toil(); chew.tickAction = delegate() { this.pawn.rotationTracker.FaceCell(base.ClosestGatherSpotParentCell); this.pawn.GainComfortFromCellIfPossible(); JoyUtility.JoyTickCheckEnd(this.pawn, JoyTickFullJoyAction.GoToNextToil, 1f, null); }; chew.handlingFacing = true; chew.defaultCompleteMode = ToilCompleteMode.Delay; chew.defaultDuration = this.job.def.joyDuration; chew.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(this.pawn); }); chew.socialMode = RandomSocialMode.SuperActive; Toils_Ingest.AddIngestionEffects(chew, this.pawn, TargetIndex.C, TargetIndex.None); this.$current = chew; if (!this.$disposing) { this.$PC = 4; } return(true); case 4u: if (base.HasDrink) { this.$current = Toils_Ingest.FinalizeIngest(this.pawn, TargetIndex.C); if (!this.$disposing) { this.$PC = 5; } return(true); } goto IL_1D9; case 5u: goto IL_1D9; default: return(false); } this.$current = Toils_Goto.GotoCell(TargetIndex.B, PathEndMode.OnCell); if (!this.$disposing) { this.$PC = 3; } return(true); IL_1D9: this.$PC = -1; return(false); }
public static Toil Enslave( TargetIndex PrisonerInd, TargetIndex CollarInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = 250; toil.WithProgressBarToilDelay( PrisonerInd ); toil.AddFinishAction( () => { try { var prisoner = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn; var collar = toil.actor.CurJob.GetTarget( CollarInd ).Thing as Apparel; var compPrisoner = prisoner.TryGetComp<CompPrisoner>(); if( ( prisoner == null ) || ( collar == null ) || ( compPrisoner == null ) ) { throw new Exception( string.Format( "prisoner = {0}\n\tcollar = {1}\n\tcompPrisoner = {2}", prisoner == null ? "null" : prisoner.ThingID, collar == null ? "null" : collar.ThingID, compPrisoner == null ? "null" : "valid" ) ); } if( prisoner.apparel == null ) { throw new Exception( "Prisoner " + prisoner.Name + " is missing Pawn_ApparelTracker!" ); } // Make sure the prisoner has worksettings if( prisoner.workSettings == null ) { prisoner.workSettings = new Pawn_WorkSettings( prisoner ); prisoner.workSettings.Disable( WorkTypeDefOf.Warden ); } // Get the prisoners original faction and pawk kind compPrisoner.originalFaction = prisoner.Faction; compPrisoner.originalPawnKind = prisoner.kindDef; // Assign the prisoner faction and pawn kind then update guest status prisoner.SetFaction( Faction.OfPlayer ); prisoner.kindDef = Data.PawnKindDefOf.Slave; prisoner.guest.SetGuestStatus( Faction.OfPlayer, true ); // Now put the collar on the prisoner toil.actor.inventory.container.Remove( collar ); compPrisoner.ForceApparelOnPawn( prisoner, collar ); // Update the interaction mode prisoner.guest.interactionMode = PrisonerInteractionMode.NoInteraction; // Update doors Data.UpdateAllDoors(); } catch( Exception e ) { Log.Error( "Prisoners & Slaves :: Could not enslave prisoner!\n\t" + e.Message ); } } ); return toil; }
public static Toil Restrain( TargetIndex PrisonerInd, TargetIndex RestraintInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = 250; toil.WithProgressBarToilDelay( PrisonerInd ); toil.AddFinishAction( () => { try { var prisoner = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn; var restraint = toil.actor.CurJob.GetTarget( RestraintInd ).Thing as Apparel; var compPrisoner = prisoner.TryGetComp<CompPrisoner>(); if( ( prisoner == null ) || ( restraint == null ) || ( compPrisoner == null ) ) { throw new Exception( string.Format( "prisoner = {0}\n\trestraint = {1}\n\tcompPrisoner = {2}", prisoner == null ? "null" : prisoner.ThingID, restraint == null ? "null" : restraint.ThingID, compPrisoner == null ? "null" : "valid" ) ); } if( prisoner.apparel == null ) { throw new Exception( "Prisoner " + prisoner.Name + " is missing Pawn_ApparelTracker!" ); } // Put the restraint on the prisoner toil.actor.inventory.container.Remove( restraint ); compPrisoner.ForceApparelOnPawn( prisoner, restraint ); } catch( Exception e ) { Log.Error( "Prisoners & Slaves :: Could not restrain pawn!\n\t" + e.Message ); } } ); return toil; }
public static Toil FreeSlave( TargetIndex PrisonerInd, TargetIndex CollarInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = 250; toil.WithProgressBarToilDelay( PrisonerInd ); toil.AddFinishAction( () => { try { var slave = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn; var collar = toil.actor.CurJob.GetTarget( CollarInd ).Thing as Apparel; var compPrisoner = slave.TryGetComp<CompPrisoner>(); if( ( slave == null ) || ( collar == null ) || ( compPrisoner == null ) ) { throw new Exception( string.Format( "slave = {0}\n\tcollar = {1}\n\tcompPrisoner = {2}", slave == null ? "null" : slave.ThingID, collar == null ? "null" : collar.ThingID, compPrisoner == null ? "null" : "valid" ) ); } compPrisoner.RemoveApparelFromPawn( slave, collar, toil.actor.Position ); if( slave.ownership != null ) { slave.ownership.UnclaimAll(); } var faction = compPrisoner.originalFaction; if( ( faction == null ) || ( faction == Faction.OfPlayer ) ) { // Unknown faction or originally from the colony // Pick outlander faction faction = Find.FactionManager.FirstFactionOfDef( FactionDefOf.Outlander ); if( faction == null ) { // No outlander faction, pick a random non-colony faction Find.FactionManager.TryGetRandomNonColonyHumanlikeFaction( out faction, false ); } } // Update control flags compPrisoner.wasSlave = true; compPrisoner.freeSlave = false; slave.guest.released = true; slave.guest.interactionMode = PrisonerInteractionMode.NoInteraction; // Remove enslaved trait slave.story.traits.RemoveTrait( Data.TraitDefOf.Enslaved ); if( slave.workSettings != null ) { slave.workSettings.Notify_GainedTrait(); } // Adjust thoughts if( ( slave.needs != null ) && ( slave.needs.mood != null ) && ( slave.needs.mood.thoughts != null ) ) { slave.needs.mood.thoughts.memories.TryGainMemoryThought( Data.ThoughtDefOf.Freed ); } // Restore faction slave.SetFaction( faction, null ); // Restore PawnKindDef slave.kindDef = compPrisoner.originalPawnKind; // Update doors Data.UpdateAllDoors(); } catch( Exception e ) { Log.Error( "Prisoners & Slaves :: Could not free slave!\n\t" + e.Message ); } } ); return toil; }
protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch).FailOnForbidden(TargetIndex.A)); var labelLoopStart = Toils_General.Label(); var labelLoopEnd = Toils_General.Label(); yield return(labelLoopStart); yield return(Toils_General.Do(() => { Zone_Growing zone = this.TargetA.Cell.GetZone(this.Map) as Zone_Growing; Thing thing = null; if (zone == null || !zone.AllContainedThings.Where(x => x is Plant && !x.HostileTo(this.pawn) && !x.IsForbidden(this.pawn) && !((Plant)x).HarvestableNow && this.pawn.CanReserveAndReach(x, PathEndMode.Touch, Danger.None) && !listChecked.Contains(x.Position)).TryRandomElement(out thing)) { this.job.SetTarget(TargetIndex.A, LocalTargetInfo.Invalid); } else { this.Map.reservationManager.Reserve(this.pawn, this.job, thing); this.job.SetTarget(TargetIndex.A, thing); } })); yield return(Toils_Jump.JumpIf(labelLoopEnd, () => !this.job.targetA.IsValid || this.plantCount >= this.plantWant)); yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.Touch).FailOnDestroyedOrNull(TargetIndex.A)); Toil gardening = new Toil().FailOnDestroyedNullOrForbidden(TargetIndex.A); gardening.defaultCompleteMode = ToilCompleteMode.Never; gardening.socialMode = RandomSocialMode.SuperActive; gardening.WithProgressBar(TargetIndex.A, () => (float)workDone / workTotal); gardening.PlaySustainerOrSound(SoundDefOf.Interact_Sow); gardening.WithEffect(() => EffecterDefOf.Harvest_Plant, TargetIndex.A); gardening.initAction = () => { this.workDone = 0; this.reportState = Rand.Bool ? ReportStringState.A : ReportStringState.B; }; gardening.tickAction = () => { this.workDone++; this.pawn.skills.Learn(SkillDefOf.Plants, 0.01f); if (this.workDone >= workTotal) { this.ReadyForNextToil(); } }; gardening.AddFinishAction(() => { this.plantCount++; this.Map.reservationManager.Release(this.job.targetA, this.pawn, this.job); var plant = this.job.targetA.Thing as Plant; plant.Growth += plant.GrowthRate * 2000f / (60000f * plant.def.plant.growDays); this.listChecked.Add(this.job.targetA.Cell); this.reportState = ReportStringState.None; }); yield return(gardening); yield return(Toils_Jump.Jump(labelLoopStart)); yield return(labelLoopEnd); yield break; }
protected override IEnumerable <Toil> MakeNewToils() { setup_ticks(); //this.FailOn(() => PawnUtility.PlayerForcedJobNowOrSoon(pawn)); this.FailOn(() => pawn.health.Downed); this.FailOn(() => pawn.IsBurning()); this.FailOn(() => pawn.IsFighting()); this.FailOn(() => pawn.Drafted); Toil findfapspot = new Toil { initAction = delegate { pawn.pather.StartPath(Bed.Position, PathEndMode.OnCell); }, defaultCompleteMode = ToilCompleteMode.PatherArrival }; yield return(findfapspot); Toil fap = Toils_General.Wait(duration); fap.handlingFacing = true; fap.initAction = delegate { Start(); }; fap.tickAction = delegate { --duration; if (pawn.IsHashIntervalTick(ticks_between_hearts)) { ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); } SexTick(pawn, null); SexUtility.reduce_rest(pawn, 1); if (duration <= 0) { ReadyForNextToil(); } }; fap.AddFinishAction(delegate { End(); }); yield return(fap); yield return(new Toil { initAction = delegate { SexUtility.Aftersex(pawn, xxx.rjwSextype.Masturbation); if (!SexUtility.ConsiderCleaning(pawn)) { return; } LocalTargetInfo own_cum = pawn.PositionHeld.GetFirstThing <Filth>(pawn.Map); Job clean = JobMaker.MakeJob(JobDefOf.Clean); clean.AddQueuedTarget(TargetIndex.A, own_cum); pawn.jobs.jobQueue.EnqueueFirst(clean); }, defaultCompleteMode = ToilCompleteMode.Instant }); }
protected override IEnumerable<Toil> MakeNewToils() { // Just on the off-chance the rock is on fire... this.FailOnBurningImmobile( TargetIndex.A ); // Reserve the target yield return Toils_Reserve.Reserve( TargetIndex.A ); // Go to the target Toil toilGoto = Toils_Goto.GotoCell( TargetIndex.A, PathEndMode.Touch ); // Fail going to the target if it becomes unreachable toilGoto.FailOn( ( Func< bool > )(() => { if( pawn.CanReach( (TargetInfo)TargetLocA, PathEndMode.Touch, pawn.NormalMaxDanger() ) ) return false; return true; })); yield return toilGoto; // Now the work toil itself Toil toilWork = new Toil { // Continue until done defaultCompleteMode = ToilCompleteMode.Never, // When the job starts... initAction = new Action(() => { smoothTicks = 0; } ), // The work tick tickAction = new Action(() => { if( pawn.skills != null ) { const float constructionXP = 0.11f / 5f; const float miningXP = 0.11f / 5f; const float artisticXP = 0.11f / 5f; pawn.skills.Learn( SkillDefOf.Construction, constructionXP ); pawn.skills.Learn( SkillDefOf.Mining, miningXP ); pawn.skills.Learn( SkillDefOf.Artistic, artisticXP ); } smoothTicks += 1; if( smoothTicks < nextSmoothStrike ) return; // Reset counter, damage rock smoothTicks = 0; mineable.HitPoints -= DamagePerStrike; } ) }; // When should we stop? toilWork.endConditions.Add( ( Func< JobCondition > )(() => { // Go until the rock is fully damaged if( mineable.HitPoints > 0 ) return JobCondition.Ongoing; return JobCondition.Succeeded; } ) ); // Do something when done toilWork.AddFinishAction( new Action(() => { // If the job failed, abort if( mineable.HitPoints > 0 ) return; // Clear the designation at this cell Common.RemoveDesignationDefOfAt( SmoothWall.designationDef, TargetA.Cell ); // Better have associated stone blocks... string blocksDef = "Blocks" + mineable.def.defName; ThingDef stoneBlocks = DefDatabase<ThingDef>.GetNamed( blocksDef, true ); // Replace the rock with a stone wall var wallThing = ThingMaker.MakeThing( SmoothWall.thingDef, stoneBlocks ); if( wallThing != null ) { var wall = GenSpawn.Spawn( wallThing, TargetA.Cell ); if( wall != null ) { wall.SetFaction( Faction.OfPlayer ); } } } ) ); // Some fun sounds while working toilWork.WithSustainer( ( Func< SoundDef > )(() => { return SmoothWall.soundDef; } ) ); // Some fun effects while working toilWork.WithEffect( "Mine", TargetIndex.A ); yield return toilWork; // And we're done. yield break; }
Toil SowSeedToil() { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Never; toil.initAction = delegate { var actor = toil.actor; if (IsActorCarryingAppropriateSeed(actor, job.plantDefToSow)) { var plant = (Plant)GenSpawn.Spawn(job.plantDefToSow, TargetLocA, actor.Map); plant.Growth = 0; plant.sown = true; job.targetC = plant; actor.Reserve(job.targetC, job, 1); sowWorkDone = 0; } else { EndJobWith(JobCondition.Incompletable); } }; toil.tickAction = delegate { var actor = toil.actor; var plant = (Plant)job.targetC.Thing; if (actor.skills != null) { actor.skills.Learn(SkillDefOf.Growing, 0.22f); } if (plant.LifeStage != PlantLifeStage.Sowing) { Log.Error(this + " getting sowing work while not in Sowing life stage."); } sowWorkDone += StatExtension.GetStatValue(actor, StatDefOf.PlantWorkSpeed, true); if (sowWorkDone >= plant.def.plant.sowWork) { if (!IsActorCarryingAppropriateSeed(actor, job.plantDefToSow)) { EndJobWith(JobCondition.Incompletable); return; } if (actor.carryTracker.CarriedThing.stackCount <= 1) { actor.carryTracker.CarriedThing.Destroy(DestroyMode.Cancel); } else { actor.carryTracker.CarriedThing.stackCount--; } if (actor.story.traits.HasTrait(TraitDefOf.GreenThumb)) { actor.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.GreenThumbHappy, null); } plant.Growth = 0.05f; plant.Map.mapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things); actor.records.Increment(RecordDefOf.PlantsSown); ReadyForNextToil(); } }; toil.defaultCompleteMode = ToilCompleteMode.Never; toil.FailOnDespawnedNullOrForbidden(TargetIndex.A); toil.WithEffect(EffecterDefOf.Sow, TargetIndex.A); toil.WithProgressBar(TargetIndex.A, () => sowWorkDone / job.plantDefToSow.plant.sowWork, true, -0.5f); toil.PlaySustainerOrSound(() => SoundDefOf.Interact_Sow); toil.AddFinishAction(delegate { var actor = toil.actor; var thing = job.targetC.Thing; if (thing != null) { var plant = (Plant)thing; if (sowWorkDone < plant.def.plant.sowWork && !thing.Destroyed) { thing.Destroy(DestroyMode.Vanish); } actor.Map.reservationManager.Release(job.targetC, actor, job); job.targetC = null; } }); return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { setup_ticks(); //--Log.Message("JobDriver_Breeding::MakeNewToils() - setting fail conditions"); this.FailOnDespawnedNullOrForbidden(iTarget); this.FailOn(() => !pawn.CanReserve(Partner, BreederHelper.max_animals_at_once, 0)); // Fail if someone else reserves the target before the animal arrives. this.FailOn(() => !pawn.CanReach(Partner, PathEndMode.Touch, Danger.Some)); // Fail if animal cannot reach target. this.FailOn(() => pawn.Drafted); // Path to target yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell)); //if (!(pawn.IsDesignatedBreedingAnimal() && Partner.IsDesignatedBreeding())); if (!(pawn.IsAnimal() && Partner.IsAnimal())) { SexUtility.RapeTargetAlert(pawn, Partner); } Toil StartPartnerJob = new Toil(); StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant; StartPartnerJob.socialMode = RandomSocialMode.Off; StartPartnerJob.initAction = delegate { var dri = Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped; if (dri == null) { Job gettin_raped = JobMaker.MakeJob(xxx.gettin_raped, pawn); Building_Bed Bed = null; if (Partner.GetPosture() == PawnPosture.LayingInBed) { Bed = Partner.CurrentBed(); } Partner.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null); if (Bed != null) { (Partner.jobs.curDriver as JobDriver_SexBaseRecieverRaped)?.Set_bed(Bed); } } }; yield return(StartPartnerJob); // Breed target var breed = new Toil(); breed.defaultCompleteMode = ToilCompleteMode.Delay; breed.defaultDuration = duration; breed.handlingFacing = true; breed.initAction = delegate { Start(); }; breed.tickAction = delegate { if (pawn.IsHashIntervalTick(ticks_between_hearts)) { if (xxx.is_zoophile(pawn) || xxx.is_animal(pawn)) { ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); } else { ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart); } } if (pawn.IsHashIntervalTick(ticks_between_hits) && !xxx.is_zoophile(Partner)) { Roll_to_hit(pawn, Partner); } SexTick(pawn, Partner); if (!Partner.Dead) { SexUtility.reduce_rest(Partner, 1); } SexUtility.reduce_rest(pawn, 2); }; breed.AddFinishAction(delegate { End(); }); yield return(breed); yield return(new Toil { initAction = delegate { //Log.Message("JobDriver_Breeding::MakeNewToils() - Calling aftersex"); //// Trying to add some interactions and social logs bool isRape = !(pawn.relations.DirectRelationExists(PawnRelationDefOf.Bond, Partner) || (xxx.is_animal(pawn) && (pawn.RaceProps.wildness - pawn.RaceProps.petness + 0.18f) > Rand.Range(0.36f, 1.8f))); SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, rape: isRape, sextype: sexType); }, defaultCompleteMode = ToilCompleteMode.Instant }); }
/// <summary> /// Generates a series of actions (toils) that the pawn should perform. /// </summary> /// <returns>Ienumerable of type Toil</returns> /// <remarks>Remember that, in the case of jobs, effectively the entire method is executed before any actual activity occurs.</remarks> protected override IEnumerable <Toil> MakeNewToils() { // Error checking and 'helpful' messages for what is wrong. if (holder == null) // A later check will catch this (failon) but that fails silently. { Log.Error(errorBase + "TargetThingA is null. A Pawn is required to perform a reload."); yield return(null); } if (weapon == null) // Required. { Log.Error(errorBase + "TargetThingB is null. A weapon (ThingWithComps) is required to perform a reload."); yield return(null); } if (compReloader == null) // Required. { Log.Error(errorBase + pawn + " tried to do reload job on " + weapon.LabelCap + " which doesn't have a required CompAmmoUser."); yield return(null); } if (holder != pawn) // Helps restrict what this job does, not really necessary and may work fine (though possibly undesirable behavior) without this check. { Log.Error(errorBase + "TargetThingA (" + holder.Name + ") is not the same Pawn (" + pawn.Name + ") that was given the job."); yield return(null); } // get the state of the job (inventory vs other) at the start. reloadingInventory = weaponInInventory; reloadingEquipment = weaponEquipped; // A couple more more 'helpful' error check/message. if (!reloadingInventory && !reloadingEquipment) // prevent some bad states/behavior on FailOn and job text. { Log.Error(errorBase + "Unable to find the weapon to be reloaded (" + weapon.LabelCap + ") in the inventory nor equipment of " + pawn.Name); yield return(null); } if (reloadingInventory && reloadingEquipment) // prevent incorrect information on job text. If somehow this was true may cause a FailOn to trip. { Log.Error(errorBase + "Something went spectacularly wrong as the weapon to be reloaded was found in both the Pawn's equipment AND inventory at the same time."); yield return(null); } // current state of equipment, want to interrupt the reload if a pawn's equipment changes. initEquipment = pawn.equipment?.Primary; // choose ammo to be loaded and set failstate for no ammo in inventory if (compReloader.UseAmmo) { this.FailOn(() => !compReloader.TryFindAmmoInInventory(out initAmmo)); } // setup fail states, if something goes wrong with the pawn performing the reload, the weapon, or something else that we want to fail on. this.FailOnDespawnedOrNull(indReloader); this.FailOnMentalState(indReloader); this.FailOnDestroyedOrNull(indWeapon); this.FailOn(HasNoGunOrAmmo); this.FailOn(DisabledViolance); // Throw mote if (compReloader.ShouldThrowMote) { MoteMaker.ThrowText(pawn.Position.ToVector3Shifted(), Find.CurrentMap, string.Format("CE_ReloadingMote".Translate(), weapon.def.LabelCap)); } //Toil of do-nothing Toil waitToil = new Toil() { actor = pawn }; // actor was always null in testing... waitToil.initAction = () => waitToil.actor.pather.StopDead(); waitToil.defaultCompleteMode = ToilCompleteMode.Delay; waitToil.defaultDuration = Mathf.CeilToInt(compReloader.Props.reloadTime.SecondsToTicks() / pawn.GetStatValue(CE_StatDefOf.ReloadSpeed)); yield return(waitToil.WithProgressBarToilDelay(indReloader)); //Actual reloader Toil reloadToil = new Toil(); reloadToil.AddFinishAction(() => compReloader.LoadAmmo(initAmmo)); yield return(reloadToil); //Continue previous job if possible Toil continueToil = new Toil { defaultCompleteMode = ToilCompleteMode.Instant }; yield return(continueToil); }
public static Toil ChewIngestible(Pawn chewer, float durationMultiplier, TargetIndex ingestibleInd, TargetIndex eatSurfaceInd = TargetIndex.None) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Thing thing = actor.CurJob.GetTarget(ingestibleInd).Thing; if (!thing.IngestibleNow) { chewer.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } actor.jobs.curDriver.ticksLeftThisToil = Mathf.RoundToInt((float)thing.def.ingestible.baseIngestTicks * durationMultiplier); if (thing.Spawned) { thing.Map.physicalInteractionReservationManager.Reserve(chewer, actor.CurJob, thing); } }; toil.tickAction = delegate { if (chewer != toil.actor) { toil.actor.rotationTracker.FaceCell(chewer.Position); } else { Thing thing = toil.actor.CurJob.GetTarget(ingestibleInd).Thing; if (thing != null && thing.Spawned) { toil.actor.rotationTracker.FaceCell(thing.Position); } else if (eatSurfaceInd != TargetIndex.None && toil.actor.CurJob.GetTarget(eatSurfaceInd).IsValid) { toil.actor.rotationTracker.FaceCell(toil.actor.CurJob.GetTarget(eatSurfaceInd).Cell); } } toil.actor.GainComfortFromCellIfPossible(); }; toil.WithProgressBar(ingestibleInd, delegate { Pawn actor = toil.actor; Thing thing = actor.CurJob.GetTarget(ingestibleInd).Thing; if (thing == null) { return(1f); } return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / Mathf.Round((float)thing.def.ingestible.baseIngestTicks * durationMultiplier)); }, false, -0.5f); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.FailOnDestroyedOrNull(ingestibleInd); toil.AddFinishAction(delegate { if (chewer == null) { return; } if (chewer.CurJob == null) { return; } Thing thing = chewer.CurJob.GetTarget(ingestibleInd).Thing; if (thing == null) { return; } if (chewer.Map.physicalInteractionReservationManager.IsReservedBy(chewer, thing)) { chewer.Map.physicalInteractionReservationManager.Release(chewer, toil.actor.CurJob, thing); } }); toil.handlingFacing = true; Toils_ItemBelt.AddIngestionEffects(toil, chewer, ingestibleInd, eatSurfaceInd); return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { //--Log.Message("[RJW] JobDriver_RandomRape::MakeNewToils() called"); duration = (int)(2000.0f * Rand.Range(0.50f, 0.90f)); ticks_between_hearts = Rand.RangeInclusive(70, 130); ticks_between_hits = Rand.Range(xxx.config.min_ticks_between_hits, xxx.config.max_ticks_between_hits); ticks_between_thrusts = 100; bool pawnHasPenis = Genital_Helper.has_penis(pawn); if (xxx.is_bloodlust(pawn)) { ticks_between_hits = (int)(ticks_between_hits * 0.75); } if (xxx.is_brawler(pawn)) { ticks_between_hits = (int)(ticks_between_hits * 0.90); } this.FailOnDespawnedNullOrForbidden(iTarget); this.FailOn(() => (!Target.health.capacities.CanBeAwake)); // || (!comfort_prisoners.is_designated (Prisoner))); this.FailOn(() => !pawn.CanReserve(Target, comfort_prisoners.max_rapists_per_prisoner, 0)); // Fail if someone else reserves the prisoner before the pawn arrives yield return(Toils_Goto.GotoThing(iTarget, PathEndMode.OnCell)); Messages.Message(pawn.NameStringShort + " is trying to rape " + Target.NameStringShort + ".", pawn, MessageTypeDefOf.NegativeEvent); var rape = new Toil(); rape.initAction = delegate { //pawn.Reserve(Target, comfort_prisoners.max_rapists_per_prisoner, 0); //if (!pawnHasPenis) // Target.rotationTracker.Face(pawn.DrawPos); var dri = Target.jobs.curDriver as JobDriver_GettinRaped; if (dri == null) { var gettin_raped = new Job(xxx.gettin_raped); Target.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, false, true, null); (Target.jobs.curDriver as JobDriver_GettinRaped).increase_time(duration); } else { dri.rapist_count += 1; dri.increase_time(duration); } rape.FailOn(() => (Target.CurJob == null) || (Target.CurJob.def != xxx.gettin_raped)); }; rape.tickAction = delegate { if (pawn.IsHashIntervalTick(ticks_between_hearts)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); } if (pawn.IsHashIntervalTick(ticks_between_thrusts)) { xxx.sexTick(pawn, Target); } if (pawn.IsHashIntervalTick(ticks_between_hits)) { roll_to_hit(pawn, Target); } }; rape.AddFinishAction(delegate { //// Trying to add some interactions and social logs xxx.processAnalSex(pawn, Target, ref isAnalSex, pawnHasPenis); if ((Target.jobs != null) && (Target.jobs.curDriver != null) && (Target.jobs.curDriver as JobDriver_GettinRaped != null)) { (Target.jobs.curDriver as JobDriver_GettinRaped).rapist_count -= 1; } }); rape.defaultCompleteMode = ToilCompleteMode.Delay; rape.defaultDuration = duration; yield return(rape); yield return(new Toil { initAction = delegate { aftersex(pawn, Target, true, isAnalSex: isAnalSex); pawn.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(pawn); if (!Target.Dead) { Target.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(Target); } }, defaultCompleteMode = ToilCompleteMode.Instant }); }
protected override IEnumerable <Toil> MakeNewToils() { Pawn student = TargetA.Thing as Pawn; Toil gotoStudent = new Toil() { initAction = () => { pawn.pather.StartPath(TargetA, PathEndMode.Touch); }, defaultCompleteMode = ToilCompleteMode.PatherArrival }; yield return(gotoStudent); Toil doTeaching = new Toil(); doTeaching.initAction = delegate { CompAbilityUserMagic compMagic = student.GetComp <CompAbilityUserMagic>(); CompAbilityUserMight compMight = student.GetComp <CompAbilityUserMight>(); if (compMagic.IsMagicUser && !student.story.traits.HasTrait(TorannMagicDefOf.Faceless)) { this.isMageTeaching = true; } else if (compMight.IsMightUser) { this.isFighterTeaching = true; } else { Log.Message("ending teaching job due to undetected class - should never occur unless initializing verb is faulty"); this.EndJobWith(JobCondition.Incompletable); } if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } if (student.DestroyedOrNull() || student.Dead) { this.EndJobWith(JobCondition.Incompletable); } this.pawn.rotationTracker.FaceTarget(TargetA); student.rotationTracker.FaceTarget(this.pawn); student.ClearAllReservations(false); this.pawn.ClearAllReservations(false); }; doTeaching.tickAction = delegate { if (student.DestroyedOrNull() || student.Dead) { this.EndJobWith(JobCondition.Incompletable); } if (age > (lastEffect + ticksTillEffects)) { DoTeachingEffects(student); lastEffect = age; } if (!student.Drafted && student.CurJobDef != JobDefOf.Wait) { if (student.jobs.posture == PawnPosture.Standing) { Job job = new Job(JobDefOf.Wait, student); student.jobs.TryTakeOrderedJob(job, JobTag.Misc); } } if (student.Drafted && student.CurJobDef != JobDefOf.Wait_Combat) { this.EndJobWith(JobCondition.InterruptForced); } age++; ticksLeftThisToil = duration - age; if ((student.Position - this.pawn.Position).LengthHorizontal > 5) { age = duration + 1; } if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } }; doTeaching.defaultCompleteMode = ToilCompleteMode.Delay; doTeaching.defaultDuration = this.duration; doTeaching.WithProgressBar(TargetIndex.B, delegate { if (this.pawn.DestroyedOrNull() || this.pawn.Dead) { return(1f); } return(1f - (float)doTeaching.actor.jobs.curDriver.ticksLeftThisToil / this.duration); }, false, 0f); doTeaching.AddFinishAction(delegate { if (this.isMageTeaching) { AssignMagicXP(student); } if (this.isFighterTeaching) { AssignMightXP(student); } student.jobs.EndCurrentJob(JobCondition.Succeeded, false); }); yield return(doTeaching); }
//public override bool TryMakePreToilReservations(bool errorOnFailed) //{ // if(TargetA.Thing != null) // { // return true; // } // if (pawn.Reserve(TargetA, this.job, 1, 1, null, errorOnFailed)) // { // return true; // } // return false; //} protected override IEnumerable <Toil> MakeNewToils() { yield return(Toils_Misc.ThrowColonistAttackingMote(TargetIndex.A)); this.verb = this.pawn.CurJob.verbToUse as Verb_UseAbility; if (base.TargetA.HasThing && base.TargetA.Thing is Pawn && (!pawn.Position.InHorDistOf(base.TargetA.Cell, pawn.CurJob.verbToUse.verbProps.range) || !Verb.UseAbilityProps.canCastInMelee)) { //if (!base.GetActor().IsFighting() ? true : !verb.UseAbilityProps.canCastInMelee && !this.job.endIfCantShootTargetFromCurPos) //{ Toil toil = Toils_Combat.GotoCastPosition(TargetIndex.A); yield return(toil); //toil = null; //} } if (this.Context == AbilityContext.Player) { Find.Targeter.targetingSource = this.verb; } Pawn targetPawn = null; if (this.TargetThingA != null) { targetPawn = TargetThingA as Pawn; } if (targetPawn != null) { //yield return Toils_Combat.CastVerb(TargetIndex.A, false); Toil combatToil = new Toil(); //combatToil.FailOnDestroyedOrNull(TargetIndex.A); //combatToil.FailOnDespawnedOrNull(TargetIndex.A); //combatToil.FailOnDowned(TargetIndex.A); //CompAbilityUserMagic comp = this.pawn.GetComp<CompAbilityUserMagic>(); //JobDriver curDriver = this.pawn.jobs.curDriver; combatToil.initAction = delegate { this.verb = combatToil.actor.jobs.curJob.verbToUse as Verb_UseAbility; if (verb != null && verb.verbProps != null) { this.duration = (int)((this.verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false)); if (this.pawn.RaceProps.Humanlike) { //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) //{ // RemoveMimicAbility(verb); //} if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic)) { PsionicEnergyCost(verb); } if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.DeathKnight)) { HateCost(verb); } if (verb.Ability?.CooldownTicksLeft != -1) { this.EndJobWith(JobCondition.Incompletable); } } LocalTargetInfo target = combatToil.actor.jobs.curJob.GetTarget(TargetIndex.A); if (target != null) { verb.TryStartCastOn(target, false, true); } using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator()) { while (enumerator.MoveNext()) { Hediff rec = enumerator.Current; if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III) { this.pawn.health.RemoveHediff(rec); } } } } else { this.EndJobWith(JobCondition.Errored); } }; combatToil.tickAction = delegate { if (this.pawn.Downed) { EndJobWith(JobCondition.InterruptForced); } if (Find.TickManager.TicksGame % 12 == 0) { if (verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitThief || verb.Ability.Def == TorannMagicDefOf.TM_Artifact_TraitInfuse) { float direction = Rand.Range(0, 360); TM_MoteMaker.ThrowGenericMote(ThingDef.Named("Mote_Psi_Arcane"), pawn.DrawPos, pawn.Map, Rand.Range(.1f, .4f), 0.2f, .02f, .1f, 0, Rand.Range(8, 10), direction, direction); } else { TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f)); } } this.duration--; if (!wildCheck && this.duration <= 6) { wildCheck = true; if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f)) { verb.Ability.PostAbilityAttempt(); TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA); EndJobWith(JobCondition.InterruptForced); } } }; combatToil.AddFinishAction(delegate { if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed) { //ShootLine shootLine; //bool validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine); //bool inRange = (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range; //if (inRange && validTarg) //{ TMAbilityDef tmad = (TMAbilityDef)(verb.Ability.Def); if (tmad != null && tmad.relationsAdjustment != 0 && targetPawn.Faction != null && targetPawn.Faction != this.pawn.Faction && !targetPawn.Faction.HostileTo(this.pawn.Faction)) { targetPawn.Faction.TryAffectGoodwillWith(this.pawn.Faction, tmad.relationsAdjustment, true, false, null, null); } verb.Ability.PostAbilityAttempt(); this.pawn.ClearReservationsForJob(this.job); //} } }); //if (combatToil.actor.CurJob != this.job) //{ // curDriver.ReadyForNextToil(); //} combatToil.defaultCompleteMode = ToilCompleteMode.FinishedBusy; this.pawn.ClearReservationsForJob(this.job); yield return(combatToil); //Toil toil2 = new Toil() //{ // initAction = () => // { // if (curJob.UseAbilityProps.isViolent) // { // JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn); // } // }, // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil2; //Toil toil1 = new Toil() //{ // initAction = () => curJob.Ability.PostAbilityAttempt(), // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil1; } else { if (verb != null && verb.verbProps != null && (pawn.Position - TargetLocA).LengthHorizontal < verb.verbProps.range) { if (TargetLocA.IsValid && TargetLocA.InBounds(pawn.Map) && !TargetLocA.Fogged(pawn.Map)) //&& TargetLocA.Walkable(pawn.Map) { ShootLine shootLine; bool validTarg = verb.TryFindShootLineFromTo(pawn.Position, TargetLocA, out shootLine); if (validTarg) { //yield return Toils_Combat.CastVerb(TargetIndex.A, false); //Toil toil2 = new Toil() //{ // initAction = () => // { // if (curJob.UseAbilityProps.isViolent) // { // JobDriver_CastAbilityVerb.CheckForAutoAttack(this.pawn); // } // }, // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil2; this.duration = (int)((verb.verbProps.warmupTime * 60) * this.pawn.GetStatValue(StatDefOf.AimingDelayFactor, false)); Toil toil = new Toil(); toil.initAction = delegate { this.verb = toil.actor.jobs.curJob.verbToUse as Verb_UseAbility; if (this.pawn.RaceProps.Humanlike) { //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) //{ // RemoveMimicAbility(verb); //} if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic)) { PsionicEnergyCost(verb); } if (verb.Ability?.CooldownTicksLeft != -1) { this.EndJobWith(JobCondition.Incompletable); } } LocalTargetInfo target = toil.actor.jobs.curJob.GetTarget(TargetIndex.A); //TargetLocA; // bool canFreeIntercept2 = false; if (target != null) { verb.TryStartCastOn(target, false, canFreeIntercept2); } using (IEnumerator <Hediff> enumerator = this.pawn.health.hediffSet.GetHediffs <Hediff>().GetEnumerator()) { while (enumerator.MoveNext()) { Hediff rec = enumerator.Current; if (rec.def == TorannMagicDefOf.TM_PossessionHD || rec.def == TorannMagicDefOf.TM_DisguiseHD || rec.def == TorannMagicDefOf.TM_DisguiseHD_I || rec.def == TorannMagicDefOf.TM_DisguiseHD_II || rec.def == TorannMagicDefOf.TM_DisguiseHD_III) { this.pawn.health.RemoveHediff(rec); } } } }; toil.tickAction = delegate { if (Find.TickManager.TicksGame % 12 == 0) { TM_MoteMaker.ThrowCastingMote(pawn.DrawPos, pawn.Map, Rand.Range(1.2f, 2f)); } this.duration--; if (!wildCheck && this.duration <= 6) { wildCheck = true; if (this.pawn.story != null && this.pawn.story.traits != null && this.pawn.story.traits.HasTrait(TorannMagicDefOf.ChaosMage) && Rand.Chance(.1f)) { bool completeJob = TM_Action.DoWildSurge(this.pawn, this.pawn.GetComp <CompAbilityUserMagic>(), (MagicAbility)verb.Ability, (TMAbilityDef)verb.Ability.Def, TargetA); if (!completeJob) { verb.Ability.PostAbilityAttempt(); EndJobWith(JobCondition.InterruptForced); } } } }; toil.AddFinishAction(delegate { if (this.duration <= 5 && !this.pawn.DestroyedOrNull() && !this.pawn.Dead && !this.pawn.Downed) { verb.Ability.PostAbilityAttempt(); } this.pawn.ClearReservationsForJob(this.job); }); toil.defaultCompleteMode = ToilCompleteMode.FinishedBusy; yield return(toil); //Toil toil1 = new Toil() //{ // initAction = () => curJob.Ability.PostAbilityAttempt(), // defaultCompleteMode = ToilCompleteMode.Instant //}; //yield return toil1; } else { //No LoS if (pawn.IsColonist) { Messages.Message("TM_OutOfLOS".Translate( pawn.LabelShort ), MessageTypeDefOf.RejectInput); } pawn.ClearAllReservations(false); } } else { pawn.ClearAllReservations(false); } } else { if (pawn.IsColonist) { //out of range Messages.Message("TM_OutOfRange".Translate(), MessageTypeDefOf.RejectInput); } } } }
protected override IEnumerable <Toil> MakeNewToils() { Pawn mentalPawn = TargetA.Thing as Pawn; Toil gotoPawn = new Toil() { initAction = () => { pawn.pather.StartPath(TargetA, PathEndMode.Touch); }, defaultCompleteMode = ToilCompleteMode.PatherArrival }; yield return(gotoPawn); Toil doMotivate = new Toil(); doMotivate.initAction = delegate { if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } if (mentalPawn.DestroyedOrNull() || mentalPawn.Dead) { this.EndJobWith(JobCondition.Incompletable); } this.pawn.rotationTracker.FaceTarget(TargetA); mentalPawn.rotationTracker.FaceTarget(this.pawn); mentalPawn.ClearAllReservations(false); this.pawn.ClearAllReservations(false); }; doMotivate.tickAction = delegate { if (mentalPawn.DestroyedOrNull() || mentalPawn.Dead || !mentalPawn.InMentalState) { this.EndJobWith(JobCondition.Incompletable); } if (age > (lastEffect + ticksTillEffects)) { DoSpeechEffects(mentalPawn); lastEffect = age; } if (!mentalPawn.Drafted && mentalPawn.CurJobDef != JobDefOf.Wait) { if (mentalPawn.jobs.posture == PawnPosture.Standing) { Job job = new Job(JobDefOf.Wait, mentalPawn); mentalPawn.jobs.TryTakeOrderedJob(job, JobTag.InMentalState); } } if (mentalPawn.Drafted && mentalPawn.CurJobDef != JobDefOf.Wait_Combat) { this.EndJobWith(JobCondition.InterruptForced); } age++; ticksLeftThisToil = duration - age; if ((mentalPawn.Position - this.pawn.Position).LengthHorizontal > 5) { age = duration + 1; } if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } }; doMotivate.defaultCompleteMode = ToilCompleteMode.Delay; doMotivate.defaultDuration = this.duration; doMotivate.WithProgressBar(TargetIndex.B, delegate { if (this.pawn.DestroyedOrNull() || this.pawn.Dead) { return(1f); } return(1f - ((float)doMotivate.actor.jobs.curDriver.ticksLeftThisToil / this.duration)); }, false, 0f); doMotivate.AddFinishAction(delegate { mentalPawn.MentalState.RecoverFromState(); AssignXP(); mentalPawn.jobs.EndCurrentJob(JobCondition.Succeeded, false); }); yield return(doMotivate); }
// Token: 0x06000013 RID: 19 RVA: 0x00002336 File Offset: 0x00000536 protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedNullOrForbidden(TargetIndex.A); bool flag = !base.TargetB.IsValid; if (flag) { base.AddFailCondition(() => this.energyNeed == null); } yield return(Toils_Reserve.Reserve(TargetIndex.A, 1, -1, null)); bool isValid = base.TargetB.IsValid; if (isValid) { yield return(Toils_Reserve.Reserve(TargetIndex.B, 1, -1, null)); } yield return(Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.ClosestTouch).FailOnSomeonePhysicallyInteracting(TargetIndex.A)); yield return(Toils_Reserve.Release(TargetIndex.A)); yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false)); bool isValid2 = base.TargetB.IsValid; if (isValid2) { yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.Touch).FailOnForbidden(TargetIndex.B)); yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f)); Toil rechargeToil = new Toil(); rechargeToil.AddFinishAction(delegate { Thing carriedThing = this.pawn.carryTracker.CarriedThing; bool flag2 = carriedThing != null; if (flag2) { EnergySourceComp energySourceComp = carriedThing.TryGetComp <EnergySourceComp>(); bool flag3 = energySourceComp != null; if (flag3) { energySourceComp.RechargeEnergyNeed((Pawn)base.TargetB.Thing); } this.pawn.carryTracker.DestroyCarriedThing(); } }); yield return(rechargeToil); yield return(Toils_Reserve.Release(TargetIndex.B)); rechargeToil = null; } else { yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false, -0.5f)); Toil rechargeToil2 = new Toil(); rechargeToil2.AddFinishAction(delegate { Thing carriedThing = this.pawn.carryTracker.CarriedThing; bool flag2 = carriedThing != null; if (flag2) { EnergySourceComp energySourceComp = carriedThing.TryGetComp <EnergySourceComp>(); bool flag3 = energySourceComp != null; if (flag3) { energySourceComp.RechargeEnergyNeed(this.pawn); } this.pawn.carryTracker.DestroyCarriedThing(); } }); yield return(rechargeToil2); rechargeToil2 = null; } yield break; }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedOrNull(TargetIndex.A); Toil gotoThing = new Toil(); gotoThing.initAction = delegate { this.pawn.pather.StartPath(this.TargetThingA, PathEndMode.Touch); }; gotoThing.defaultCompleteMode = ToilCompleteMode.PatherArrival; gotoThing.FailOnDespawnedNullOrForbidden(TargetIndex.A); yield return(gotoThing); Toil enchanting = new Toil();//actions performed to enchant an item enchanting.FailOnCannotTouch(TargetIndex.A, PathEndMode.Touch); enchanting.FailOnDestroyedOrNull(TargetIndex.A); enchanting.initAction = delegate { actor = enchanting.actor; thing = TargetThingA; thingLoc = thing.Position; if (!(thing.def.IsMeleeWeapon || thing.def.IsRangedWeapon || thing.def.IsApparel)) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); Log.Message("Failed to initialize enchanting - invalid item type."); } }; enchanting.tickAction = delegate { if (thing.Position != thingLoc || thing.Destroyed) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); Log.Message("Failed to complete enchanting - item being enchanted not at enchanting location or destroyed"); } if (Find.TickManager.TicksGame % 5 == 0) { TM_MoteMaker.ThrowEnchantingMote(TargetLocA.ToVector3Shifted(), actor.Map, .6f); } }; enchanting.WithProgressBar(TargetIndex.A, delegate { if (thing == null) { return(1f); } return(1f - (float)enchanting.actor.jobs.curDriver.ticksLeftThisToil / 240); }, false, 0f); enchanting.defaultCompleteMode = ToilCompleteMode.Delay; enchanting.defaultDuration = 240; enchanting.AddFinishAction(delegate { CompEnchantedItem enchantment = thing.TryGetComp <CompEnchantedItem>(); CompEnchant enchantingItem = actor.TryGetComp <CompEnchant>(); CompAbilityUserMagic pawnComp = actor.TryGetComp <CompAbilityUserMagic>(); if (enchantment != null && enchantingItem != null && enchanting.actor.jobs.curDriver.ticksLeftThisToil < 1) { EnchantItem(enchantingItem.enchantingContainer[0], enchantment); enchantingItem.enchantingContainer[0].Destroy(); pawnComp.Mana.CurLevel -= .5f; MoteMaker.ThrowText(TargetLocA.ToVector3Shifted(), actor.Map, "TM_Enchanted".Translate(), -1); SoundStarter.PlayOneShotOnCamera(TorannMagicDefOf.ItemEnchanted, null); //DestroyEnchantingStone(enchantingItem.innerContainer[0]); } else { Log.Message("Detected null enchanting comp."); } }); yield return(enchanting); }
protected override IEnumerable <Toil> MakeNewToils() { if (spot != null && !spot.Destroyed) { Toil CallVictim = new Toil() { initAction = () => { Pawn target = TargetA.Thing as Pawn; if (Prefs.DevMode) { Log.Message("JobDriver_AnimalGatheringOnSpot: goto spot with " + target); } pawn.pather.StartPath(spot.Position, PathEndMode.Touch); Job gotojob = new Job(JobDefOf.GotoWander, spot.Position); gotojob.locomotionUrgency = LocomotionUrgency.Sprint; target.jobs.StartJob(gotojob, JobCondition.InterruptOptional, null, true, false, null, JobTag.MiscWork, false); }, defaultCompleteMode = ToilCompleteMode.PatherArrival }; CallVictim.FailOnDespawnedOrNull(TargetIndex.A); yield return(CallVictim); Toil WaitVictim = new Toil() { defaultCompleteMode = ToilCompleteMode.Never, tickAction = () => { if (Find.TickManager.TicksGame % 200 == 0) { Pawn target = TargetA.Thing as Pawn; if (Prefs.DevMode) { Log.Message("JobDriver_AnimalGatheringOnSpot: waiting target " + target); } if (pawn.Position.DistanceToSquared(target.Position) < 32f) { Job waitjob = new Job(JobDefOf.Wait); target.jobs.StartJob(waitjob, JobCondition.InterruptForced, null, false, true, null, JobTag.MiscWork, false); this.ReadyForNextToil(); } else { target.jobs.EndCurrentJob(JobCondition.InterruptForced, false); Job gotojob = new Job(JobDefOf.GotoWander, spot.Position); gotojob.locomotionUrgency = LocomotionUrgency.Sprint; target.jobs.StartJob(gotojob, JobCondition.InterruptOptional, null, true, false, null, JobTag.MiscWork, false); } } } }; WaitVictim.AddFinishAction(() => { Pawn target = TargetA.Thing as Pawn; target.jobs.EndCurrentJob(JobCondition.InterruptForced, true); }); WaitVictim.FailOnDespawnedOrNull(TargetIndex.A); yield return(WaitVictim); Toil ReleaseVictim = new Toil() { defaultCompleteMode = ToilCompleteMode.Instant, }; ReleaseVictim.AddFinishAction(() => { Pawn target = TargetA.Thing as Pawn; if (target != null) { target.ClearMind(true); } }); yield return(ReleaseVictim); } foreach (Toil toil in base.MakeNewToils()) { yield return(toil); } }
protected override IEnumerable <Toil> MakeNewToils() { Toil layDown = new Toil(); float num = 1.25f; layDown.initAction = delegate { Pawn actor = layDown.actor; actor.pather.StopDead(); JobDriver curDriver = actor.jobs.curDriver; curDriver.layingDown = LayingDownState.LayingSurface; curDriver.asleep = false; if (actor.mindState.applyBedThoughtsTick == 0) { actor.mindState.applyBedThoughtsTick = Find.TickManager.TicksGame + Rand.Range(2500, 10000); actor.mindState.applyBedThoughtsOnLeave = false; } if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed) { ThoughtUtility.RemovePositiveBedroomThoughts(actor); } }; layDown.tickAction = delegate { Pawn actor = layDown.actor; Job curJob = actor.CurJob; JobDriver curDriver = actor.jobs.curDriver; actor.GainComfortFromCellIfPossible(); if (!curDriver.asleep) { if (actor.needs.rest != null && actor.needs.rest.CurLevel < .99f * RestUtility.WakeThreshold(actor)) { curDriver.asleep = true; } } else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor))) { actor.mindState.priorityWork.ClearPrioritizedWorkAndJobQueue(); this.EndJobWith(JobCondition.Incompletable); } if (curDriver.asleep && actor.needs.rest != null) { float num2 = RestUtility.PawnHealthRestEffectivenessFactor(actor); num = 0.7f * num + 0.3f * num * num2; //talk about convoluted calculations... actor.needs.rest.TickResting(num); if (actor.needs.rest.CurLevel >= .99f * RestUtility.WakeThreshold(actor)) { curDriver.asleep = false; actor.mindState.priorityWork.ClearPrioritizedWorkAndJobQueue(); this.EndJobWith(JobCondition.Succeeded); } } if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame) { ApplyBedThoughts(actor); actor.mindState.applyBedThoughtsTick += 60000; actor.mindState.applyBedThoughtsOnLeave = true; } if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map)) { if (curDriver.asleep) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ); } if (actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>()) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross); } } }; layDown.defaultCompleteMode = ToilCompleteMode.Never; layDown.AddFinishAction(delegate { Pawn actor = layDown.actor; JobDriver curDriver = actor.jobs.curDriver; if (actor.mindState.applyBedThoughtsOnLeave) { ApplyBedThoughts(actor); } curDriver.layingDown = LayingDownState.NotLaying; curDriver.asleep = false; }); yield return(layDown); }
private static Toil DrinkSomeone(TargetIndex thingIndex, Func <Toil, Func <LocalTargetInfo> > funcGetter) { Toil toil = new Toil(); toil.initAction = delegate { Pawn actor = toil.actor; Thing thing = actor.CurJob.GetTarget(thingIndex).Thing; var comp = thing.TryGetComp <CompWaterSource>(); if (comp == null || comp.SourceType != CompProperties_WaterSource.SourceType.Item) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } actor.rotationTracker.FaceCell(actor.Position); if (!thing.CanDrinkWaterNow()) { actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } actor.jobs.curDriver.ticksLeftThisToil = comp.BaseDrinkTicks; if (thing.Spawned) { thing.Map.physicalInteractionReservationManager.Reserve(actor, actor.CurJob, thing); } }; toil.tickAction = delegate { toil.actor.GainComfortFromCellIfPossible(); }; toil.WithProgressBar(thingIndex, delegate { Pawn actor = toil.actor; Thing thing = actor.CurJob.GetTarget(thingIndex).Thing; var comp = thing.TryGetComp <CompWaterSource>(); if (thing == null || comp == null || comp.SourceType != CompProperties_WaterSource.SourceType.Item) { return(1f); } return(1f - (float)toil.actor.jobs.curDriver.ticksLeftThisToil / (float)comp.BaseDrinkTicks); }, false, -0.5f); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.FailOnDestroyedOrNull(thingIndex); toil.AddFinishAction(delegate { Pawn actor = toil.actor; if (actor == null) { return; } if (actor.CurJob == null) { return; } Thing thing = actor.CurJob.GetTarget(thingIndex).Thing; if (thing == null) { return; } if (actor.Map.physicalInteractionReservationManager.IsReservedBy(actor, thing)) { actor.Map.physicalInteractionReservationManager.Release(actor, actor.CurJob, thing); } }); // エフェクト追加 toil.WithEffect(delegate { Pawn actor = toil.actor; LocalTargetInfo target = toil.actor.CurJob.GetTarget(thingIndex); if (!target.HasThing) { return(null); } EffecterDef effecter = null; var comp = target.Thing.TryGetComp <CompWaterSource>(); if (comp != null) { effecter = comp.GetEffect; } return(effecter); }, funcGetter(toil)); toil.PlaySustainerOrSound(delegate { Pawn actor = toil.actor; if (!actor.RaceProps.Humanlike) { return(null); } LocalTargetInfo target = toil.actor.CurJob.GetTarget(thingIndex); if (!target.HasThing) { return(null); } var comp = target.Thing.TryGetComp <CompWaterSource>(); if (comp == null) { return(null); } return(comp.Props.getSound); }); return(toil); }
public static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true) { Toil layDown = new Toil(); layDown.initAction = delegate() { Pawn actor = layDown.actor; actor.pather.StopDead(); JobDriver curDriver = actor.jobs.curDriver; if (hasBed) { Building_Bed t = (Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing; if (!t.OccupiedRect().Contains(actor.Position)) { Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor, false); actor.jobs.EndCurrentJob(JobCondition.Errored, true); return; } actor.jobs.posture = PawnPosture.LayingInBed; } else { actor.jobs.posture = PawnPosture.LayingOnGroundNormal; } curDriver.asleep = false; if (actor.mindState.applyBedThoughtsTick == 0) { actor.mindState.applyBedThoughtsTick = Find.TickManager.TicksGame + Rand.Range(2500, 10000); actor.mindState.applyBedThoughtsOnLeave = false; } if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed) { ThoughtUtility.RemovePositiveBedroomThoughts(actor); } }; layDown.tickAction = delegate() { Pawn actor = layDown.actor; Job curJob = actor.CurJob; JobDriver curDriver = actor.jobs.curDriver; Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing; actor.GainComfortFromCellIfPossible(); if (!curDriver.asleep) { if (canSleep && ((actor.needs.rest != null && actor.needs.rest.CurLevel < RestUtility.FallAsleepMaxLevel(actor)) || curJob.forceSleep)) { curDriver.asleep = true; } } else if (!canSleep) { curDriver.asleep = false; } else if ((actor.needs.rest == null || actor.needs.rest.CurLevel >= RestUtility.WakeThreshold(actor)) && !curJob.forceSleep) { curDriver.asleep = false; } if (curDriver.asleep && gainRestAndHealth && actor.needs.rest != null) { float restEffectiveness; if (building_Bed != null && building_Bed.def.statBases.StatListContains(StatDefOf.BedRestEffectiveness)) { restEffectiveness = building_Bed.GetStatValue(StatDefOf.BedRestEffectiveness, true); } else { restEffectiveness = 0.8f; } actor.needs.rest.TickResting(restEffectiveness); } if (actor.mindState.applyBedThoughtsTick != 0 && actor.mindState.applyBedThoughtsTick <= Find.TickManager.TicksGame) { Toils_LayDown.ApplyBedThoughts(actor); actor.mindState.applyBedThoughtsTick += 60000; actor.mindState.applyBedThoughtsOnLeave = true; } if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map)) { if (curDriver.asleep) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ); } if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>()) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross); } } if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.owners.Contains(actor)) { if (actor.Downed) { actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null); } actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (lookForOtherJobs && actor.IsHashIntervalTick(211)) { actor.jobs.CheckForJobOverride(); return; } }; layDown.defaultCompleteMode = ToilCompleteMode.Never; if (hasBed) { layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex); } layDown.AddFinishAction(delegate { Pawn actor = layDown.actor; JobDriver curDriver = actor.jobs.curDriver; if (actor.mindState.applyBedThoughtsOnLeave) { Toils_LayDown.ApplyBedThoughts(actor); } curDriver.asleep = false; }); return(layDown); }
protected override IEnumerable <Toil> MakeNewToils() { //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - making toils"); setup_ticks(); this.FailOnDespawnedOrNull(iTarget); this.FailOnDespawnedNullOrForbidden(iBed); //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() fail conditions check " + !xxx.CanUse(pawn, Bed) + " " + !pawn.CanReserve(Partner)); this.FailOn(() => !xxx.CanUse(pawn, Bed) || !pawn.CanReserve(Partner)); this.FailOn(() => pawn.Drafted); this.FailOn(() => Partner.IsFighting()); this.FailOn(() => !Partner.CanReach(pawn, PathEndMode.Touch, Danger.Deadly)); yield return(Toils_Reserve.Reserve(iTarget, 1, 0)); //yield return Toils_Reserve.Reserve(BedInd, Bed.SleepingSlotsCount, 0); //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - generate toils"); Toil gotoBed = new Toil(); gotoBed.defaultCompleteMode = ToilCompleteMode.PatherArrival; gotoBed.FailOnWhorebedNoLongerUsable(iBed, Bed); gotoBed.AddFailCondition(() => Partner.Downed); gotoBed.FailOn(() => !Partner.CanReach(Bed, PathEndMode.Touch, Danger.Deadly)); gotoBed.initAction = delegate { //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - gotoWhoreBed initAction is called"); pawn.pather.StartPath(SleepSpot, PathEndMode.OnCell); Partner.jobs.StopAll(); Job job = JobMaker.MakeJob(JobDefOf.GotoMindControlled, SleepSpot); Partner.jobs.StartJob(job, JobCondition.InterruptForced); }; yield return(gotoBed); ticks_left = (int)(2000.0f * Rand.Range(0.30f, 1.30f)); Toil waitInBed = new Toil(); waitInBed.initAction = delegate { ticksLeftThisToil = 5000; }; waitInBed.tickAction = delegate { pawn.GainComfortFromCellIfPossible(); if (IsInOrByBed(Bed, Partner) && pawn.PositionHeld == Partner.PositionHeld) { ReadyForNextToil(); } }; waitInBed.defaultCompleteMode = ToilCompleteMode.Delay; yield return(waitInBed); Toil StartPartnerJob = new Toil(); StartPartnerJob.defaultCompleteMode = ToilCompleteMode.Instant; StartPartnerJob.socialMode = RandomSocialMode.Off; StartPartnerJob.initAction = delegate { //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - StartPartnerJob"); var gettin_loved = JobMaker.MakeJob(xxx.gettin_loved, pawn, Bed); Partner.jobs.StartJob(gettin_loved, JobCondition.InterruptForced); }; yield return(StartPartnerJob); Toil loveToil = new Toil(); loveToil.AddFailCondition(() => Partner.Dead || Partner.CurJobDef != xxx.gettin_loved); loveToil.defaultCompleteMode = ToilCompleteMode.Never; loveToil.socialMode = RandomSocialMode.Off; loveToil.handlingFacing = true; loveToil.initAction = delegate { //Log.Message("[RJW]JobDriver_WhoreIsServingVisitors::MakeNewToils() - loveToil"); // TODO: replace this quick n dirty way CondomUtility.GetCondomFromRoom(pawn); // Try to use w***e's condom first, then client's usedCondom = CondomUtility.TryUseCondom(pawn) || CondomUtility.TryUseCondom(Partner); Start(); if (xxx.HasNonPolyPartnerOnCurrentMap(Partner)) { Pawn lover = LovePartnerRelationUtility.ExistingLovePartner(Partner); // We have to do a few other checks because the pawn might have multiple lovers and ExistingLovePartner() might return the wrong one if (lover != null && pawn != lover && !lover.Dead && (lover.Map == Partner.Map || Rand.Value < 0.25)) { lover.needs.mood.thoughts.memories.TryGainMemory(ThoughtDefOf.CheatedOnMe, Partner); } } }; loveToil.AddPreTickAction(delegate { --ticks_left; if (pawn.IsHashIntervalTick(ticks_between_hearts)) { if (xxx.is_nympho(pawn)) { ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); } else { ThrowMetaIcon(pawn.Position, pawn.Map, xxx.mote_noheart); } } SexUtility.reduce_rest(Partner, 1); SexUtility.reduce_rest(pawn, 2); if (ticks_left <= 0) { ReadyForNextToil(); } }); loveToil.AddFinishAction(delegate { End(); }); yield return(loveToil); Toil afterSex = new Toil { initAction = delegate { // Adding interactions, social logs, etc SexUtility.ProcessSex(pawn, Partner, usedCondom: usedCondom, whoring: isWhoring, sextype: sexType); if (!(Partner.IsColonist && (pawn.IsPrisonerOfColony || pawn.IsColonist))) { int price = WhoringHelper.PriceOfWhore(pawn); //--Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Partner should pay the price now in afterSex.initAction"); int remainPrice = WhoringHelper.PayPriceToWhore(Partner, price, pawn); /*if (remainPrice <= 0) * { * --Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Paying price is success"); * } * else * { * --Log.Message("JobDriver_WhoreIsServingVisitors::MakeNewToils() - Paying price failed"); * }*/ xxx.UpdateRecords(pawn, price - remainPrice); } var thought = (pawn.IsPrisoner || xxx.is_slave(pawn)) ? thought_captive : thought_free; pawn.needs.mood.thoughts.memories.TryGainMemory(thought); if (SexUtility.ConsiderCleaning(pawn)) { LocalTargetInfo cum = pawn.PositionHeld.GetFirstThing <Filth>(pawn.Map); Job clean = JobMaker.MakeJob(JobDefOf.Clean); clean.AddQueuedTarget(TargetIndex.A, cum); pawn.jobs.jobQueue.EnqueueFirst(clean); } }, defaultCompleteMode = ToilCompleteMode.Instant }; yield return(afterSex); }
public static Toil IssueLeaveJob( TargetIndex PrisonerInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Instant; toil.AddFinishAction( () => { try { var slave = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn; // Find an exit spot IntVec3 spot; if( !RCellFinder.TryFindBestExitSpot( slave, out spot, TraverseMode.ByPawn ) ) { Log.Warning( string.Format( "Tried to make pawn {0} leave but couldn't find an exit spot", slave.NameStringShort ) ); return; } // Stop any other jobs slave.jobs.StopAll( true ); var newJob = new Job( JobDefOf.Goto, spot ); newJob.exitMapOnArrival = true; // Assign new exit job slave.jobs.StartJob( newJob, JobCondition.None, (ThinkNode) null, false, true, (ThinkTreeDef) null ); } catch( Exception e ) { Log.Error( "Prisoners & Slaves :: Could not issue leave job to pawn!\n\t" + e.Message ); } } ); return toil; }
protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDestroyedNullOrForbidden(PowerDestIndex); if (!TargetB.IsValid) { AddFailCondition(() => energyNeed == null); } if (!isUsedFromInventory) { yield return(Toils_Reserve.Reserve(PowerDestIndex)); if (TargetB.IsValid) { yield return(Toils_Reserve.Reserve(OtherPawnIndex)); } yield return(Toils_Goto.GotoThing(PowerDestIndex, PathEndMode.OnCell).FailOnSomeonePhysicallyInteracting(PowerDestIndex)); yield return(Toils_Reserve.Release(PowerDestIndex)); } else { yield return(new Toil() { initAction = delegate() { if (!thingIsSplitOff && pawn.carryTracker.CarriedThing != TargetThingA) { Thing splitOffThing = TargetThingA.SplitOff(job.count); thingIsSplitOff = true; GenPlace.TryPlaceThing(splitOffThing, pawn.Position, pawn.Map, ThingPlaceMode.Near); TargetThingA = splitOffThing; } } }); } yield return(Toils_Haul.StartCarryThing(TargetIndex.A, false, true, false)); this.AddFinishAction(delegate() { if (pawn.carryTracker is Pawn_CarryTracker carryTracker && carryTracker.CarriedThing is Thing thing) { if (isUsedFromInventory) { //Thing takenThing = carryTracker.innerContainer.Take(thing); pawn.inventory.innerContainer.TryAddOrTransfer(thing, true); } else { carryTracker.TryDropCarriedThing(pawn.Position, ThingPlaceMode.Near, out Thing resultThing); } } }); if (TargetB.IsValid) { //Recharge someone else. yield return(Toils_Goto.GotoThing(OtherPawnIndex, PathEndMode.Touch).FailOnForbidden(OtherPawnIndex)); yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false)); Toil rechargeToil = new Toil(); rechargeToil.AddFinishAction(delegate() { //Use up the carried stack Thing carriedThing = pawn.carryTracker.CarriedThing; if (carriedThing != null) { EnergySourceComp energyComp = carriedThing.TryGetComp <EnergySourceComp>(); if (energyComp != null) { energyComp.RechargeEnergyNeed((Pawn)TargetB.Thing); } pawn.carryTracker.DestroyCarriedThing(); } }); yield return(rechargeToil); yield return(Toils_Reserve.Release(OtherPawnIndex)); } else { yield return(Toils_General.Wait(100).WithProgressBarToilDelay(TargetIndex.A, false)); //Recharge user. Toil rechargeToil = new Toil(); rechargeToil.AddFinishAction(delegate() { //Use up the carried stack Thing carriedThing = pawn.carryTracker.CarriedThing; if (carriedThing != null) { EnergySourceComp energyComp = carriedThing.TryGetComp <EnergySourceComp>(); if (energyComp != null) { energyComp.RechargeEnergyNeed(pawn); } pawn.carryTracker.DestroyCarriedThing(); } }); yield return(rechargeToil); } }
public static Toil Unrestrain( TargetIndex PrisonerInd, TargetIndex RestraintInd ) { var toil = new Toil(); toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = 250; toil.WithProgressBarToilDelay( PrisonerInd ); toil.AddFinishAction( () => { try { var slave = toil.actor.CurJob.GetTarget( PrisonerInd ).Thing as Pawn; var restraint = toil.actor.CurJob.GetTarget( RestraintInd ).Thing as Apparel; var compPrisoner = slave.TryGetComp<CompPrisoner>(); if( ( slave == null ) || ( restraint == null ) || ( compPrisoner == null ) ) { throw new Exception( string.Format( "slave = {0}\n\trestraint = {1}\n\tcompPrisoner = {2}", slave == null ? "null" : slave.ThingID, restraint == null ? "null" : restraint.ThingID, compPrisoner == null ? "null" : "valid" ) ); } compPrisoner.RemoveApparelFromPawn( slave, restraint, toil.actor.Position ); } catch( Exception e ) { Log.Error( "Prisoners & Slaves :: Could not unrestrain pawn!\n\t" + e.Message ); } } ); return toil; }
private Toil SowSeedToil() { Toil sowToil = new Toil(); sowToil.initAction = () => { sowToil.actor.pather.StopDead(); if (IsActorCarryingAppropriateSeed()) { Thing newPlantThing = GenSpawn.Spawn(CurJob.plantDefToSow, CurJob.GetTarget(targetCellIndex).Cell); if (newPlantThing != null) { // no type checking here as this job is only created for plants with this type PlantWithSeeds newPlant = (PlantWithSeeds)newPlantThing; newPlant.growth = 0F; newPlant.genome = ((ThingDef_PlantWithSeeds)newPlant.def).genome.RandomGenome();//((Thing_PlantSeedsItem)sowToil.actor.carryHands.CarriedThing).genome; CurJob.SetTarget(TargetIndex.C, new TargetInfo(newPlantThing)); m_fSowWorkRemaining = CurJob.plantDefToSow.plant.sowWork; // effect has to be added here in the initAction so that it appears if // the sow toil is repeated multiple times in a single job sowToil.WithEffect("Sow", targetCellIndex); } } }; sowToil.AddFinishAction(() => { // if the job finishes before the plant has progressed past the sowing stage, destroy it TargetInfo plantTargetInfo = CurJob.GetTarget(TargetIndex.C); if (plantTargetInfo != null) { if (plantTargetInfo.HasThing && !plantTargetInfo.ThingDestroyed) { Plant plant = (Plant)plantTargetInfo.Thing; if (plant.LifeStage == PlantLifeStage.Sowing) { plant.Destroy(); } } CurJob.SetTarget(TargetIndex.C, null); } }); sowToil.tickAction = () => { Pawn actor = sowToil.actor; TargetInfo plantTargetInfo = CurJob.GetTarget(TargetIndex.C); if (!IsActorCarryingAppropriateSeed() || plantTargetInfo == null || !plantTargetInfo.HasThing || plantTargetInfo.ThingDestroyed) { // fail if the actor is no longer carrying seeds or if the plant being sowed is messed up EndJobWith(JobCondition.Incompletable); } else { SkillRecord actorsGrowingSkill = actor.skills.GetSkill(SkillDefOf.Growing); if (actorsGrowingSkill != null) { // FCTODO: No idea if the learning rate here is appropriate. Current value taken from Verse.AI.Toils_Recipe.DoRecipeWork() // assuming a learn factor of 1 on the "recipe" actorsGrowingSkill.Learn(0.11f * actorsGrowingSkill.LearningFactor); } m_fSowWorkRemaining -= actor.GetStatValue(StatDefOf.PlantWorkSpeed); if (m_fSowWorkRemaining <= 0F) { if (sowToil.actor.carryHands.CarriedThing.stackCount <= 1) { sowToil.actor.carryHands.CarriedThing.Destroy(); } else { sowToil.actor.carryHands.CarriedThing.stackCount--; } if (actor.needs.mood != null) { actor.needs.mood.thoughts.TryGainThought(DefDatabase<ThoughtDef>.GetNamed("GreenThumbHappy")); } Plant plant = (Plant)plantTargetInfo.Thing; plant.growth = Plant.BaseGrowthPercent; Find.MapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things); ReadyForNextToil(); } } }; sowToil.defaultCompleteMode = ToilCompleteMode.Never; return sowToil; }
// Token: 0x06000063 RID: 99 RVA: 0x00004318 File Offset: 0x00002518 protected override IEnumerable <Toil> MakeNewToils() { this.FailOnDespawnedOrNull(TargetIndex.A); var toilInv = new Toil(); var toilEquipGoto = new Toil(); var toilEquip = new Toil(); var toilGoto = new Toil(); var toilCast = new Toil(); var toilTouch = new Toil(); var toilBeat = new Toil(); var toilBash = new Toil(); var HasPrimFE = false; var HasPrimFB = false; if (pawn.equipment.Primary != null) { if (pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary)) { HasPrimFE = true; } else if (pawn.equipment.Primary.def.defName == FBDefName) { HasPrimFB = true; } } if (!HasPrimFE) { var fb = HasPrimFB; toilInv.initAction = delegate { var Swap = false; ThingWithComps invGearToEquip2 = null; ThingWithComps primToSwap2 = null; Thing RemoveThing = null; Thing BackupThing2 = null; if (pawn.equipment.Primary != null) { primToSwap2 = pawn.equipment.Primary; } foreach (var invThing2 in pawn.inventory.innerContainer) { if (invThing2.def.defName != FEDefName || !FWFoamUtility.HasFEFoam(invThing2)) { if (invThing2.def.defName == FBDefName) { BackupThing2 = invThing2; } } else { RemoveThing = invThing2; invGearToEquip2 = (ThingWithComps)invThing2; if (primToSwap2 != null) { Swap = true; } break; } } if (invGearToEquip2 == null && !fb && BackupThing2 != null) { RemoveThing = BackupThing2; invGearToEquip2 = (ThingWithComps)BackupThing2; if (primToSwap2 != null) { Swap = true; } } if (invGearToEquip2 == null) { return; } var primDef = ""; if (Swap) { primDef = pawn.equipment.Primary.def.defName; pawn.equipment.Remove(pawn.equipment.Primary); } pawn.inventory.innerContainer.Remove(RemoveThing); pawn.equipment.MakeRoomFor(invGearToEquip2); pawn.equipment.AddEquipment(invGearToEquip2); if (Swap) { pawn.inventory.innerContainer.TryAdd(primToSwap2); } if (!Swap) { return; } var returnType = "SI"; if (pawn.equipment.Primary.def.defName != FEDefName && pawn.equipment.Primary.def.defName != FBDefName) { return; } var primary = pawn.equipment.Primary; ((FireWardenData)primary).FWSwapType = returnType; ((FireWardenData)primary).FWPawnID = pawn.thingIDNumber; ((FireWardenData)primary).FWPrimDef = primDef; if (!DebugFWData) { return; } var Test = pawn.equipment.Primary; var debugTest = pawn.Label + " : "; debugTest = debugTest + Test.Label + " : "; debugTest = debugTest + pawn.equipment.Primary.GetType() + " : "; if (((FireWardenData)Test).FWSwapType != null) { debugTest = debugTest + ((FireWardenData)Test).FWSwapType + " : "; } else { debugTest += "null : "; } debugTest = debugTest + ((FireWardenData)Test).FWPawnID + " : "; if (((FireWardenData)Test).FWPrimDef != null) { debugTest += ((FireWardenData)Test).FWPrimDef; } else { debugTest += "null"; } Messages.Message(debugTest, pawn, MessageTypeDefOf.NeutralEvent, false); }; toilInv.defaultCompleteMode = ToilCompleteMode.FinishedBusy; yield return(toilInv); } var FWEquipping = Controller.Settings.EquippingDone; var FWSearchRange = (float)Controller.Settings.SearchRange; if (FWSearchRange < 25f) { FWSearchRange = 25f; } if (FWSearchRange > 75f) { FWSearchRange = 75f; } HasPrimFE = false; HasPrimFB = false; if (pawn.equipment.Primary != null) { if (pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary)) { HasPrimFE = true; } else if (pawn.equipment.Primary.def.defName == FBDefName) { HasPrimFB = true; } } if (!HasPrimFE && !HasPrimFB && FWEquipping) { ThingWithComps invGearToEquip = null; ThingWithComps primToSwap = null; Thing BackupThing = null; if (pawn.equipment.Primary != null) { primToSwap = pawn.equipment.Primary; } foreach (var invThing in pawn.inventory.innerContainer) { if (invThing.def.defName == FEDefName && FWFoamUtility.HasFEFoam(invThing)) { invGearToEquip = (ThingWithComps)invThing; if (primToSwap != null) { } break; } if (invThing.def.defName == FBDefName) { BackupThing = invThing; } } if (invGearToEquip == null && BackupThing != null) { invGearToEquip = (ThingWithComps)BackupThing; } if (invGearToEquip == null) { Thing ThingToGrab = null; var skip = Controller.Settings.BrawlerNotOK && pawn.story.traits.HasTrait(TraitDefOf.Brawler); var traverseParams = TraverseParms.For(pawn); bool validatorFE(Thing t) { return(!t.IsForbidden(pawn) && pawn.CanReserve(t) && FWFoamUtility.HasFEFoam(t) && !FWFoamUtility.ReplaceFEFoam(t)); } bool validatorFB(Thing t) { return(!t.IsForbidden(pawn) && pawn.CanReserve(t)); } if (!skip) { var FElist = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FEDefName)); var FEGrab = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FElist, PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFE); if (FEGrab != null) { ThingToGrab = FEGrab; } else { var FBlist = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FBDefName)); var FBGrab = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FBlist, PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFB); if (FBGrab != null) { ThingToGrab = FBGrab; } } } else { var FBlist2 = pawn.Map.listerThings.ThingsOfDef(DefDatabase <ThingDef> .GetNamed(FBDefName)); var FBGrab2 = GenClosest.ClosestThing_Global_Reachable(pawn.Position, pawn.Map, FBlist2, PathEndMode.OnCell, traverseParams, FWSearchRange, validatorFB); if (FBGrab2 != null) { ThingToGrab = FBGrab2; } } if (ThingToGrab != null) { toilEquipGoto.initAction = delegate { if (Map.reservationManager.CanReserve(pawn, ThingToGrab)) { pawn.Reserve(ThingToGrab, job); } pawn.pather.StartPath(ThingToGrab, PathEndMode.OnCell); }; toilEquipGoto.FailOn(ThingToGrab.DestroyedOrNull); toilEquipGoto.AddFailCondition(() => FWHasFE(pawn) && ThingToGrab.def.defName == FEDefName); toilEquipGoto.AddFailCondition(() => FWHasFB(pawn) && ThingToGrab.def.defName == FBDefName); toilEquipGoto.defaultCompleteMode = ToilCompleteMode.PatherArrival; yield return(toilEquipGoto); toilEquip.initAction = delegate { var primDeEquip = pawn.equipment.Primary; var primDef = "N"; if (primDeEquip != null) { primDef = pawn.equipment.Primary.def.defName; pawn.equipment.Remove(pawn.equipment.Primary); pawn.inventory.innerContainer.TryAdd(primDeEquip); } var FWGrabWithComps = (ThingWithComps)ThingToGrab; ThingWithComps FWGrabbed; if (FWGrabWithComps.def.stackLimit > 1 && FWGrabWithComps.stackCount > 1) { FWGrabbed = (ThingWithComps)FWGrabWithComps.SplitOff(1); } else { FWGrabbed = FWGrabWithComps; FWGrabbed.DeSpawn(); } pawn.equipment.MakeRoomFor(FWGrabbed); pawn.equipment.AddEquipment(FWGrabbed); var returnType = "EN"; if (pawn.equipment.Primary.def.defName != FEDefName && pawn.equipment.Primary.def.defName != FBDefName) { return; } var primary = pawn.equipment.Primary; ((FireWardenData)primary).FWSwapType = returnType; ((FireWardenData)primary).FWPawnID = pawn.thingIDNumber; ((FireWardenData)primary).FWPrimDef = primDef; if (!DebugFWData) { return; } var Test = pawn.equipment.Primary; var debugTest = pawn.Label + " : "; debugTest = debugTest + Test.Label + " : "; debugTest = debugTest + pawn.equipment.Primary.GetType() + " : "; if ((Test as FireWardenData)?.FWSwapType != null) { debugTest = debugTest + ((FireWardenData)Test).FWSwapType + " : "; } else { debugTest += "null : "; } debugTest = debugTest + ((FireWardenData)Test).FWPawnID + " : "; if (((FireWardenData)Test).FWPrimDef != null) { debugTest += ((FireWardenData)Test).FWPrimDef; } else { debugTest += "null"; } Messages.Message(debugTest, pawn, MessageTypeDefOf.NeutralEvent, false); }; toilEquip.AddFailCondition(() => FWHasFE(pawn) && ThingToGrab.def.defName == FEDefName); toilEquip.AddFailCondition(() => FWHasFB(pawn) && ThingToGrab.def.defName == FBDefName); toilEquip.defaultCompleteMode = ToilCompleteMode.FinishedBusy; yield return(toilEquip); } } } var HasPrimFEEq = pawn.equipment.Primary != null && pawn.equipment.Primary.def.defName == FEDefName && FWFoamUtility.HasFEFoam(pawn.equipment.Primary); if (HasPrimFEEq) { var FEVerbToUse = pawn.TryGetAttackVerb(TargetFire); var RangeFireExt = 10f; if (FEVerbToUse != null) { pawn.jobs.curJob.verbToUse = FEVerbToUse; RangeFireExt = pawn.jobs.curJob.verbToUse.verbProps.range; RangeFireExt *= (float)(Controller.Settings.HowClose / 100.0); if (RangeFireExt < 3f) { RangeFireExt = 3f; } if (RangeFireExt > pawn.jobs.curJob.verbToUse.verbProps.range) { RangeFireExt = pawn.jobs.curJob.verbToUse.verbProps.range; } } toilGoto.initAction = delegate { if (Map.reservationManager.CanReserve(pawn, TargetFire)) { pawn.Reserve(TargetFire, job); } if (!CastPositionFinder.TryFindCastPosition(new CastPositionRequest { caster = pawn, target = TargetFire, verb = pawn.jobs.curJob.verbToUse, maxRangeFromTarget = RangeFireExt, wantCoverFromTarget = false }, out var dest)) { toilGoto.actor.jobs.EndCurrentJob(JobCondition.Incompletable); return; } toilGoto.actor.pather.StartPath(dest, PathEndMode.OnCell); pawn.Map.pawnDestinationReservationManager.Reserve(pawn, pawn.jobs.curJob, dest); }; toilGoto.tickAction = delegate { if (Controller.Settings.TooBrave) { return; } if (pawn.pather.Moving && pawn.pather.nextCell != TargetFire.Position) { StartTacklingFireIfAnyAt(pawn.pather.nextCell, toilCast); } if (pawn.Position != TargetFire.Position) { StartTacklingFireIfAnyAt(pawn.Position, toilCast); } }; toilGoto.FailOnDespawnedOrNull(TargetIndex.A); toilGoto.defaultCompleteMode = ToilCompleteMode.PatherArrival; toilGoto.atomicWithPrevious = true; yield return(toilGoto); toilCast.initAction = delegate { pawn.jobs.curJob.verbToUse.TryStartCastOn(TargetFire); if (!TargetFire.Destroyed) { return; } pawn.records.Increment(RecordDefOf.FiresExtinguished); pawn.jobs.EndCurrentJob(JobCondition.Succeeded); }; toilCast.FailOnDespawnedOrNull(TargetIndex.A); toilCast.defaultCompleteMode = ToilCompleteMode.FinishedBusy; yield return(toilCast); } else { toilTouch.initAction = delegate { if (Map.reservationManager.CanReserve(pawn, TargetFire)) { pawn.Reserve(TargetFire, job); } pawn.pather.StartPath(TargetFire, PathEndMode.Touch); }; toilTouch.tickAction = delegate { if (Controller.Settings.TooBrave) { return; } if (pawn.pather.Moving && pawn.pather.nextCell != TargetFire.Position) { StartTacklingFireIfAnyAt(pawn.pather.nextCell, toilBeat); } if (pawn.Position != TargetFire.Position) { StartTacklingFireIfAnyAt(pawn.Position, toilBeat); } }; toilTouch.FailOnDespawnedOrNull(TargetIndex.A); toilTouch.defaultCompleteMode = ToilCompleteMode.PatherArrival; toilTouch.atomicWithPrevious = true; yield return(toilTouch); toilBeat.tickAction = delegate { if (!pawn.CanReachImmediate(TargetFire, PathEndMode.Touch)) { JumpToToil(toilTouch); return; } if (pawn.Position != TargetFire.Position && StartTacklingFireIfAnyAt(pawn.Position, toilBeat)) { return; } if (pawn.equipment.Primary != null) { if (pawn.equipment.Primary.def.defName == FBDefName) { JumpToToil(toilBash); } else { pawn.natives.TryBeatFire(TargetFire); } } else { pawn.natives.TryBeatFire(TargetFire); } if (!TargetFire.Destroyed) { return; } pawn.records.Increment(RecordDefOf.FiresExtinguished); pawn.jobs.EndCurrentJob(JobCondition.Succeeded); }; toilBeat.FailOnDespawnedOrNull(TargetIndex.A); toilBeat.defaultCompleteMode = ToilCompleteMode.Never; yield return(toilBeat); if (pawn.equipment.Primary == null || pawn.equipment.Primary.def.defName != FBDefName) { yield break; } toilBash.initAction = delegate { if (TargetFire != null && Map.reservationManager.CanReserve(pawn, TargetFire)) { pawn.Reserve(TargetFire, job); } pawn.pather.StopDead(); }; toilBash.handlingFacing = true; toilBash.tickAction = delegate { pawn.rotationTracker.FaceTarget(pawn.CurJob.GetTarget(TargetIndex.A)); if (TargetFire != null) { pawn.Drawer.Notify_MeleeAttackOn(TargetFire); } }; toilBash.PlaySoundAtStart(SoundDefOf.Interact_BeatFire); toilBash.WithProgressBarToilDelay(TargetIndex.A); toilBash.AddFinishAction(delegate { if (TargetFire != null && !TargetFire.Destroyed) { TargetFire.Destroy(); } }); toilBash.FailOnDespawnedOrNull(TargetIndex.A); toilBash.defaultCompleteMode = ToilCompleteMode.Delay; var ticks = 50; var WorkSpeed = pawn.GetStatValue(StatDefOf.WorkSpeedGlobal); if (WorkSpeed <= 0f) { WorkSpeed = 1f; } ticks = (int)(ticks * (1f / WorkSpeed)); if (ticks < 25) { ticks = 25; } if (ticks > 200) { ticks = 200; } toilBash.defaultDuration = ticks; yield return(toilBash); } }
public static Toil DoWeaponRepairWork(int duration, string soundDefName, float maxAllowedRepair) { float expPerSecond = 25f; FloatRange gainHitpointRange = new FloatRange(0.6f, 0.95f); // Note: result = gainHitpointRange * skillRecord.Level / 12 SkillDef skillDef = SkillDefOf.Crafting; int maxSkillLevel = 12; Toil toil = new Toil(); //toil.initAction = delegate //{ //}; toil.tickAction = delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; SkillRecord skillRecord = actor.skills.GetSkill(skillDef); // actor learns something actor.skills.Learn(SkillDefOf.Crafting, expPerSecond / 60); }; toil.AddFinishAction(delegate { Pawn actor = toil.actor; Job curJob = actor.jobs.curJob; // Calculate possible hitpoint gain multiplicator SkillRecord skillRecord = actor.skills.GetSkill(skillDef); float gainHitpointMulti = gainHitpointRange.RandomInRange * Mathf.Clamp(skillRecord.Level, 1, maxSkillLevel) / maxSkillLevel; //20; // Get the target hitpoint to use Thing master = curJob.GetTarget(WeaponMasterIndex).Thing; int hitpointsMasterMax = master.MaxHitPoints; int hitpointsMaster = master.HitPoints; Thing ingredient = curJob.GetTarget(WeaponIngredientIndex).Thing; int hitpointsIngredient = ingredient.HitPoints; // Hitpoints will only be increased to XX% of the ingredient hitpoints int newHitpoints = hitpointsMaster + (int)(hitpointsIngredient * gainHitpointMulti); if (newHitpoints > hitpointsMasterMax * maxAllowedRepair) { newHitpoints = (int)(hitpointsMasterMax * maxAllowedRepair) + 1; } // repair master master.HitPoints = newHitpoints; // vanish ingredient ingredient.Destroy(DestroyMode.Vanish); }); toil.handlingFacing = true; toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = duration; toil.WithProgressBarToilDelay(WorkbenchIndex, false, -0.5f); //toil.WithEffect(() => toil.actor.CurJob.bill.recipe.effectWorking, WorkbenchIndex); toil.PlaySustainerOrSound(() => SoundDef.Named(soundDefName)); return(toil); }
protected override IEnumerable <Toil> MakeNewToils() { Toil meditate = new Toil { socialMode = RandomSocialMode.Off }; if (FromBed) { this.KeepLyingDown(TargetIndex.B); meditate = Toils_LayDown.LayDown(TargetIndex.B, job.GetTarget(TargetIndex.B).Thing is Building_Bed, lookForOtherJobs: false, canSleep: false); } else { yield return(Toils_Goto.GotoCell(TargetIndex.A, PathEndMode.OnCell)); meditate.initAction = delegate { LocalTargetInfo target = job.GetTarget(TargetIndex.C); if (target.IsValid) { faceDir = target.Cell - pawn.Position; } else { faceDir = (job.def.faceDir.IsValid ? job.def.faceDir : Rot4.Random).FacingCell; } }; if (Focus != null) { meditate.FailOnDespawnedNullOrForbidden(TargetIndex.C); } meditate.handlingFacing = true; } meditate.defaultCompleteMode = ToilCompleteMode.Delay; meditate.defaultDuration = job.def.joyDuration; meditate.FailOn(() => !MeditationUtility.CanMeditateNow(pawn) || !MeditationUtility.SafeEnvironmentalConditions(pawn, base.TargetLocA, base.Map)); meditate.AddPreTickAction(delegate { if (faceDir.IsValid && !FromBed) { pawn.rotationTracker.FaceCell(pawn.Position + faceDir); } pawn.GainComfortFromCellIfPossible(); MeditationTick(); if (ModLister.RoyaltyInstalled && MeditationFocusDefOf.Natural.CanPawnUse(pawn)) { int num = GenRadial.NumCellsInRadius(MeditationUtility.FocusObjectSearchRadius); for (int i = 0; i < num; i++) { IntVec3 c = pawn.Position + GenRadial.RadialPattern[i]; if (c.InBounds(pawn.Map)) { Plant plant = c.GetPlant(pawn.Map); if (plant != null && plant.def == ThingDefOf.Plant_TreeAnima) { plant.TryGetComp <CompSpawnSubplant>()?.AddProgress(AnimaTreeSubplantProgressPerTick); } } } } }); meditate.AddFinishAction(delegate { if (sustainer != null) { sustainer.End(); } }); yield return(meditate); }
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 it's 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); } // Set fail condition on turret. if (pawn.Faction != Faction.OfPlayer) { this.FailOnDestroyedOrNull(TargetIndex.A); } else { this.FailOnDestroyedNullOrForbidden(TargetIndex.A); } if (compReloader.UseAmmo) { // Perform ammo system specific activities, failure condition and hauling if (pawn.Faction != Faction.OfPlayer) { ammo.SetForbidden(false, false); this.FailOnDestroyedOrNull(TargetIndex.B); } else { this.FailOnDestroyedNullOrForbidden(TargetIndex.B); } // Haul ammo yield return(Toils_Reserve.Reserve(TargetIndex.B, 1)); yield return(Toils_Goto.GotoCell(ammo.Position, PathEndMode.ClosestTouch)); yield return(Toils_Haul.StartCarryThing(TargetIndex.B)); yield return(Toils_Goto.GotoCell(turret.Position, PathEndMode.ClosestTouch)); //yield return Toils_Haul.PlaceHauledThingInCell(TargetIndex.A, null, false); } else { // If ammo system is turned off we just need to go to the turret. yield return(Toils_Goto.GotoCell(turret.Position, PathEndMode.ClosestTouch)); } // Wait in place Toil waitToil = new Toil() { actor = pawn }; waitToil.initAction = delegate { // Initial relaod process activities. waitToil.actor.pather.StopDead(); turret.isReloading = true; 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.AddFinishAction(() => turret.isReloading = false); 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); }; //if (compReloader.useAmmo) reloadToil.EndOnDespawnedOrNull(TargetIndex.B); yield return(reloadToil); }
private Toil SowSeedToil() { Toil sowToil = new Toil(); sowToil.initAction = delegate { sowToil.actor.pather.StopDead(); if (this.IsActorCarryingAppropriateSeed()) { Thing thing = GenSpawn.Spawn(this.CurJob.plantDefToSow, this.CurJob.GetTarget(TargetIndex.A).Cell); if (thing != null) { PlantWithSeeds expr_5D = (PlantWithSeeds)thing; expr_5D.growth = 0f; expr_5D.genome = ((ThingDef_PlantWithSeeds)expr_5D.def).genome.RandomGenome(); this.CurJob.SetTarget(TargetIndex.C, new TargetInfo(thing)); this.m_fSowWorkRemaining = this.CurJob.plantDefToSow.plant.sowWork; sowToil.WithEffect("Sow", TargetIndex.A); } } }; sowToil.AddFinishAction(delegate { TargetInfo target = base.CurJob.GetTarget(TargetIndex.C); if (target != null) { if (target.HasThing && !target.ThingDestroyed) { Plant plant = (Plant)target.Thing; if (plant.LifeStage == PlantLifeStage.Sowing) { plant.Destroy(DestroyMode.Vanish); } } base.CurJob.SetTarget(TargetIndex.C, null); } }); sowToil.tickAction = delegate { Pawn actor = sowToil.actor; TargetInfo target = this.CurJob.GetTarget(TargetIndex.C); if (!this.IsActorCarryingAppropriateSeed() || target == null || !target.HasThing || target.ThingDestroyed) { this.EndJobWith(JobCondition.Incompletable); return; } SkillRecord skill = actor.skills.GetSkill(SkillDefOf.Growing); if (skill != null) { skill.Learn(0.11f * skill.LearningFactor); } this.m_fSowWorkRemaining -= actor.GetStatValue(StatDefOf.PlantWorkSpeed, true); if (this.m_fSowWorkRemaining <= 0f) { if (sowToil.actor.carrier.CarriedThing.stackCount <= 1) { sowToil.actor.carrier.CarriedThing.Destroy(DestroyMode.Vanish); } else { sowToil.actor.carrier.CarriedThing.stackCount--; } if (actor.needs.mood != null) { actor.needs.mood.thoughts.TryGainThought(DefDatabase<ThoughtDef>.GetNamed("GreenThumbHappy", true)); } Plant plant = (Plant)target.Thing; plant.growth = 0.05f; Find.MapDrawer.MapMeshDirty(plant.Position, MapMeshFlag.Things); this.ReadyForNextToil(); } }; sowToil.defaultCompleteMode = ToilCompleteMode.Never; return sowToil; }
protected override IEnumerable <Toil> MakeNewToils() { CompAbilityUserMight comp = this.pawn.GetComp <CompAbilityUserMight>(); float radius = 2.5f; radius += (.75f * TM_Calc.GetMightSkillLevel(pawn, comp.MightData.MightPowerSkill_PsionicBarrier, "TM_PsionicBarrier", "_ver", true)); //if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.TM_Psionic)) //{ // radius = 2 + (.5f * comp.MightData.MightPowerSkill_PsionicBarrier.FirstOrDefault((MightPowerSkill x) => x.label == "TM_PsionicBarrier_ver").level); //} //else if(this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) //{ // radius = 2 + (.5f * comp.MightData.MightPowerSkill_Mimic.FirstOrDefault((MightPowerSkill x) => x.label == "TM_Mimic_ver").level); //} this.psiFlag = this.pawn.health.hediffSet.HasHediff(HediffDef.Named("TM_PsionicHD"), false); Toil psionicBarrier = new Toil(); psionicBarrier.initAction = delegate { if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } Map map = this.pawn.Map; this.barrierCells = new List <IntVec3>(); this.barrierCells.Clear(); this.GetCellList(radius); ticksLeftThisToil = 10; comp.shouldDrawPsionicShield = true; }; psionicBarrier.tickAction = delegate { //DrawBarrier(radius); if (Find.TickManager.TicksGame % this.barrierSearchFrequency == 0) { if (psiFlag) { if (Rand.Chance(.15f * comp.MightData.MightPowerSkill_PsionicBarrier.FirstOrDefault((MightPowerSkill x) => x.label == "TM_PsionicBarrier_pwr").level)) { RepelProjectiles(false, radius); } else { RepelProjectiles(psiFlag, radius); } if (this.pawn.IsColonist) { HealthUtility.AdjustSeverity(this.pawn, HediffDef.Named("TM_PsionicHD"), -.004f); } else { HealthUtility.AdjustSeverity(this.pawn, HediffDef.Named("TM_PsionicHD"), -.04f); } psiEnergy = this.pawn.health.hediffSet.GetFirstHediffOfDef(HediffDef.Named("TM_PsionicHD"), false).Severity; if (psiEnergy < 1) { this.EndJobWith(JobCondition.Succeeded); } if (this.psiFlag) { ticksLeftThisToil = (int)psiEnergy; } } else { RepelProjectiles(false, radius); comp.Stamina.CurLevel -= .00035f; } } age++; if (!psiFlag) { ticksLeftThisToil = Mathf.RoundToInt(((float)(duration - age) / (float)duration) * 100f); if (age > duration) { this.EndJobWith(JobCondition.Succeeded); } if (comp.Stamina.CurLevel < .01f) { this.EndJobWith(JobCondition.Succeeded); } } }; psionicBarrier.defaultCompleteMode = ToilCompleteMode.Delay; psionicBarrier.defaultDuration = this.duration; psionicBarrier.WithProgressBar(TargetIndex.A, delegate { if (this.pawn.DestroyedOrNull() || this.pawn.Dead || this.pawn.Downed) { return(1f); } return(1f - (float)psionicBarrier.actor.jobs.curDriver.ticksLeftThisToil / 100); }, false, 0f); psionicBarrier.AddFinishAction(delegate { if (this.pawn.story.traits.HasTrait(TorannMagicDefOf.Faceless)) { CompAbilityUserMight mightComp = this.pawn.GetComp <CompAbilityUserMight>(); if (mightComp.mimicAbility != null) { mightComp.RemovePawnAbility(mightComp.mimicAbility); } } comp.shouldDrawPsionicShield = false; //do soemthing? }); yield return(psionicBarrier); }
protected override IEnumerable<Toil> MakeNewToils() { //Set what will cause the job to fail this.FailOnBurningImmobile(RepairStationIndex); this.FailOnDestroyedOrForbidden(RepairStationIndex); this.FailOn(delegate { return Droid != null && !Droid.ShouldGetRepairs; }); //Reserve the repair station yield return Toils_Reserve.Reserve(RepairStationIndex); //Go to the repair station interaction cell yield return Toils_Goto.GotoThing(RepairStationIndex, PathEndMode.InteractionCell); //Make a new toil that sets the droid to repair mode, then wait until fully repaired IRepairable droid = pawn as IRepairable; Building_RepairStation rps = TargetThingA as Building_RepairStation; Toil toil = new Toil(); toil.FailOnDestroyedOrForbidden(RepairStationIndex); toil.FailOn(() => { Pawn p = toil.GetActor(); Building_RepairStation rps2 = TargetThingA as Building_RepairStation; if (!(p is IRepairable)) return true; if (p.Position != TargetThingA.InteractionCell) return true; if (rps2 == null || !rps2.IsAvailable(p)) return true; return false; }); toil.initAction = () => { //Log.Message("initAction"); droid.BeingRepaired = true; rps.RegisterRepairee(droid); }; toil.defaultCompleteMode = ToilCompleteMode.Delay; toil.defaultDuration = rps.Def.ticksPerRepairCycle * droid.RepairsNeededCount + 1; toil.tickAction = () => { //Log.Message("Toil tick"); if ( droid.RepairStation != null && Find.TickManager.TicksGame % droid.RepairStation.Def.ticksPerRepairCycle == 0) { if (droid.RepairStation.Power != null && !droid.RepairStation.Power.PowerOn) { return; } //Log.Message("Repaired"); droid.RepairTick(); } }; toil.AddFinishAction(delegate { //Log.Message("Finish action"); rps.DeregisterRepairee(droid); droid.BeingRepaired = false; }); toil.WithEffect(DefDatabase<EffecterDef>.GetNamed("Repair"), TargetIndex.A); toil.WithSustainer(() => { return DefDatabase<SoundDef>.GetNamed("Interact_Repair"); }); yield return toil; }
protected override IEnumerable <Toil> MakeNewToils() { this.EndOnDespawnedOrNull(TargetIndex.A, JobCondition.Incompletable); this.EndOnDespawnedOrNull(TargetIndex.B, JobCondition.Incompletable); this.FailOnForbidden(TargetIndex.A); yield return(Toils_Goto.GotoThing(TargetIndex.B, PathEndMode.OnCell)); float statValue = TargetThingA.GetStatValue(StatDefOf.JoyGainFactor, true); Building building = (Building)pawn.CurJob.targetA.Thing; //CompRunningGenerator comp = (CompRunningGenerator)building.GetComp<CompRunningGenerator>(); //int storedEnergy = 0; //int skipTick = 0; //int sameValueTimes = 0; Toil use = new Toil(); use.tickAction = delegate { pawn.rotationTracker.FaceCell(TargetA.Cell); pawn.GainComfortFromCellIfPossible(); building.GetComp <CompMannable>().ManForATick(pawn); if (TargetC.IsValid) { JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.None, statValue); //Log.Message(building + " current stored energy = " + (int)comp.PowerNet.CurrentStoredEnergy()); /* * if (skipTick < 60) * { * //Log.Message(building + " stored energy = " + storedEnergy); * if ((int)comp.PowerNet.CurrentStoredEnergy() == storedEnergy) * { * if (sameValueTimes < 60) * { * sameValueTimes++; * } * else pawn.jobs.curDriver.EndJobWith(JobCondition.Succeeded); * } * else sameValueTimes = 0; * * skipTick++; * } * else * { * storedEnergy = (int)comp.PowerNet.CurrentStoredEnergy(); * skipTick = 0; * } */ } else { JoyUtility.JoyTickCheckEnd(pawn, JoyTickFullJoyAction.EndJob, statValue); } }; if (!TargetC.IsValid) { use.defaultCompleteMode = ToilCompleteMode.Delay; use.defaultDuration = job.def.joyDuration; } else { use.defaultCompleteMode = ToilCompleteMode.Never; } use.handlingFacing = true; use.AddFinishAction(delegate { JoyUtility.TryGainRecRoomThought(pawn); }); yield return(use); yield break; }
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 static Toil LayDown(TargetIndex bedOrRestSpotIndex, bool hasBed, bool lookForOtherJobs, bool canSleep = true, bool gainRestAndHealth = true) { Toil layDown = new Toil(); layDown.initAction = delegate { Pawn actor = layDown.actor; actor.pather.StopDead(); JobDriver curDriver = actor.jobs.curDriver; if (hasBed) { Building_Bed t = (Building_Bed)actor.CurJob.GetTarget(bedOrRestSpotIndex).Thing; if (!t.OccupiedRect().Contains(actor.Position)) { Log.Error("Can't start LayDown toil because pawn is not in the bed. pawn=" + actor, false); actor.jobs.EndCurrentJob(JobCondition.Errored, true); return; } actor.jobs.posture = PawnPosture.LayingInBed; } else { actor.jobs.posture = PawnPosture.LayingOnGroundNormal; } curDriver.asleep = false; if (actor.mindState.applyBedThoughtsTick == 0) { actor.mindState.applyBedThoughtsTick = Find.TickManager.TicksGame + Rand.Range(2500, 10000); actor.mindState.applyBedThoughtsOnLeave = false; } if (actor.ownership != null && actor.CurrentBed() != actor.ownership.OwnedBed) { ThoughtUtility.RemovePositiveBedroomThoughts(actor); } }; layDown.tickAction = delegate { Pawn actor = layDown.actor; Job curJob = actor.CurJob; JobDriver curDriver = actor.jobs.curDriver; Building_Bed building_Bed = (Building_Bed)curJob.GetTarget(bedOrRestSpotIndex).Thing; actor.GainComfortFromCellIfPossible(); if (actor.IsHashIntervalTick(100) && !actor.Position.Fogged(actor.Map)) { if (curDriver.asleep) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_SleepZ); } if (gainRestAndHealth && actor.health.hediffSet.GetNaturallyHealingInjuredParts().Any <BodyPartRecord>()) { MoteMaker.ThrowMetaIcon(actor.Position, actor.Map, ThingDefOf.Mote_HealingCross); } } if (actor.ownership != null && building_Bed != null && !building_Bed.Medical && !building_Bed.OwnersForReading.Contains(actor)) { if (actor.Downed) { actor.Position = CellFinder.RandomClosewalkCellNear(actor.Position, actor.Map, 1, null); } actor.jobs.EndCurrentJob(JobCondition.Incompletable, true); return; } if (lookForOtherJobs && actor.IsHashIntervalTick(211)) { actor.jobs.CheckForJobOverride(); return; } //Fin recharche ou pod non alimenté ou non operationel if (actor.needs.food.CurLevelPercentage >= 1.0f || building_Bed.Destroyed || building_Bed.IsBrokenDown() || !building_Bed.TryGetComp <CompPowerTrader>().PowerOn) { actor.jobs.EndCurrentJob(JobCondition.Succeeded, true); } }; layDown.defaultCompleteMode = ToilCompleteMode.Never; if (hasBed) { layDown.FailOnBedNoLongerUsable(bedOrRestSpotIndex); } layDown.AddFinishAction(delegate { Pawn actor = layDown.actor; JobDriver curDriver = actor.jobs.curDriver; curDriver.asleep = false; }); return(layDown); }
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); }
protected override IEnumerable <Toil> MakeNewToils() { //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() called"); duration = (int)(2500.0f * Rand.Range(0.50f, 0.90f)); ticks_between_hearts = Rand.RangeInclusive(70, 130); ticks_between_hits = Rand.Range(xxx.config.min_ticks_between_hits, xxx.config.max_ticks_between_hits); ticks_between_thrusts = 100; bool pawnHasPenis = Genital_Helper.has_penis(pawn); if (xxx.is_bloodlust(pawn)) { ticks_between_hits = (int)(ticks_between_hits * 0.75); } if (xxx.is_brawler(pawn)) { ticks_between_hits = (int)(ticks_between_hits * 0.90); } //this.FailOnDespawnedNullOrForbidden (iprisoner); //this.FailOn (() => (!Prisoner.health.capacities.CanBeAwake) || (!comfort_prisoners.is_designated (Prisoner))); this.FailOn(() => !pawn.CanReserve(animal, 1, 0)); // Fail if someone else reserves the prisoner before the pawn arrives yield return(Toils_Reserve.Reserve(iprisoner, 1, 0)); //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - moving towards animal"); yield return(Toils_Goto.GotoThing(iprisoner, PathEndMode.OnCell)); Messages.Message(pawn.NameStringShort + " is trying to rape " + animal.NameStringShort + ".", pawn, MessageTypeDefOf.NeutralEvent); var rape = new Toil(); rape.initAction = delegate { //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - reserving animal"); //pawn.Reserve(animal, 1, 0); // animal rapin seems like a solitary activity //if (!pawnHasPenis) // animal.rotationTracker.Face(pawn.DrawPos); //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - Setting animal job driver"); var dri = animal.jobs.curDriver as JobDriver_GettinRaped; if (dri == null) { var gettin_raped = new Job(xxx.gettin_raped); animal.jobs.StartJob(gettin_raped, JobCondition.InterruptForced, null, true, true, null); (animal.jobs.curDriver as JobDriver_GettinRaped).increase_time(duration); } else { dri.rapist_count += 1; dri.increase_time(duration); } // Try to take off the attacker's clothing //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - stripping necro lover"); /* Edited by nizhuan-jjr: No Dropping Clothes on attackes! * worn_apparel = pawn.apparel.WornApparel.ListFullCopy<Apparel>(); * while (pawn.apparel != null && pawn.apparel.WornApparelCount > 0) { * Apparel apparel = pawn.apparel.WornApparel.RandomElement<Apparel>(); * pawn.apparel.Remove(apparel); * } */ }; rape.tickAction = delegate { if (pawn.IsHashIntervalTick(ticks_between_hearts)) { MoteMaker.ThrowMetaIcon(pawn.Position, pawn.Map, ThingDefOf.Mote_Heart); } if (pawn.IsHashIntervalTick(ticks_between_thrusts)) { xxx.sexTick(pawn, animal); } /* * if (pawn.IsHashIntervalTick (ticks_between_hits)) * roll_to_hit (pawn, animal); */ }; rape.AddFinishAction(delegate { //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - finished violating"); //// Trying to add some interactions and social logs xxx.processAnalSex(pawn, animal, ref isAnalSex, pawnHasPenis); if ((animal.jobs != null) && (animal.jobs.curDriver != null) && (animal.jobs.curDriver as JobDriver_GettinRaped != null)) { (animal.jobs.curDriver as JobDriver_GettinRaped).rapist_count -= 1; } }); rape.defaultCompleteMode = ToilCompleteMode.Delay; rape.defaultDuration = duration; yield return(rape); yield return(new Toil { initAction = delegate { //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - creating aftersex toil"); xxx.aftersex(pawn, animal, false, false, isAnalSex); pawn.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(pawn); if (!animal.Dead) { animal.mindState.canLovinTick = Find.TickManager.TicksGame + xxx.generate_min_ticks_to_next_lovin(animal); } //--Log.Message("[RJW] JobDriver_Beastiality::MakeNewToils() - putting clothes back on"); /* Edited by nizhuan-jjr: No Dropping Clothes on attackers! * if (pawn.apparel != null) { * foreach (Apparel apparel in worn_apparel) { * pawn.apparel.Wear(apparel);// WornApparel.Add(apparel); * } * } */ }, defaultCompleteMode = ToilCompleteMode.Instant }); }