64 lines
2.1 KiB
C#
64 lines
2.1 KiB
C#
using RimWorld;
|
|
using System.Collections.Generic;
|
|
using Verse;
|
|
using Verse.AI;
|
|
|
|
namespace ArachnaeSwarm
|
|
{
|
|
public class JobDriver_CarryPrisonerToNutrientVat : JobDriver
|
|
{
|
|
private const TargetIndex PrisonerInd = TargetIndex.A;
|
|
private const TargetIndex VatInd = TargetIndex.B;
|
|
|
|
protected Pawn Prisoner => (Pawn)job.GetTarget(PrisonerInd).Thing;
|
|
protected Building_NutrientVat Vat => (Building_NutrientVat)job.GetTarget(VatInd).Thing;
|
|
|
|
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
|
{
|
|
return pawn.Reserve(Prisoner, job, 1, -1, null, errorOnFailed)
|
|
&& pawn.Reserve(Vat, job, 1, -1, null, errorOnFailed);
|
|
}
|
|
|
|
protected override IEnumerable<Toil> MakeNewToils() // 改为 protected
|
|
{
|
|
// 验证目标
|
|
this.FailOnDestroyedOrNull(PrisonerInd);
|
|
this.FailOnDestroyedOrNull(VatInd);
|
|
this.FailOn(() => !Vat.CanAcceptPawn(Prisoner).Accepted);
|
|
|
|
// 1. 前往囚犯位置
|
|
yield return Toils_Goto.GotoThing(PrisonerInd, PathEndMode.OnCell)
|
|
.FailOn(() => Prisoner.IsInNutrientVat())
|
|
.FailOnSomeonePhysicallyInteracting(PrisonerInd);
|
|
|
|
// 2. 开始搬运囚犯
|
|
yield return Toils_Haul.StartCarryThing(PrisonerInd);
|
|
|
|
// 3. 前往消化缸
|
|
yield return Toils_Goto.GotoThing(VatInd, PathEndMode.InteractionCell);
|
|
|
|
// 4. 将囚犯放入消化缸
|
|
yield return new Toil
|
|
{
|
|
initAction = () =>
|
|
{
|
|
if (Vat.CanAcceptPawn(Prisoner).Accepted)
|
|
{
|
|
Vat.TryAcceptPawn(Prisoner);
|
|
}
|
|
},
|
|
defaultCompleteMode = ToilCompleteMode.Instant
|
|
};
|
|
}
|
|
}
|
|
|
|
// 扩展方法检查pawn是否在消化缸中
|
|
public static class PawnExtensions
|
|
{
|
|
public static bool IsInNutrientVat(this Pawn pawn)
|
|
{
|
|
return pawn?.Spawned == false && pawn.ParentHolder is Building_NutrientVat;
|
|
}
|
|
}
|
|
}
|