120 lines
4.6 KiB
C#
120 lines
4.6 KiB
C#
// File: JobDriver_FeedWithHoney.cs
|
||
using System.Collections.Generic;
|
||
using RimWorld;
|
||
using Verse;
|
||
using Verse.AI;
|
||
|
||
namespace ArachnaeSwarm
|
||
{
|
||
public class JobDriver_FeedWithHoney : JobDriver
|
||
{
|
||
private const int FeedDurationTicks = 180; // 3秒 = 180 ticks (60 ticks/秒)
|
||
private const float FoodTransferPerTick = 0.01f; // 每tick传输的食物量
|
||
|
||
private Pawn TargetPawn => job.targetA.Pawn;
|
||
|
||
// 获取喂食者的蜜罐需求
|
||
private Need_HoneyProduction FeederHoneyNeed => pawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||
|
||
// 获取目标的食物需求
|
||
private Need_Food TargetFoodNeed => TargetPawn.needs?.TryGetNeed<Need_Food>();
|
||
|
||
// 检查目标是否有蜜罐需求
|
||
private Need_HoneyProduction TargetHoneyNeed => TargetPawn.needs?.TryGetNeed<Need_HoneyProduction>();
|
||
|
||
// 使用喂养效果
|
||
private static readonly EffecterDef FeedEffect = ARA_EffecterDefOf.EatVegetarian;
|
||
private static readonly SoundDef FeedSound = SoundDefOf.RawMeat_Eat;
|
||
|
||
public override bool TryMakePreToilReservations(bool errorOnFailed)
|
||
{
|
||
if (TargetPawn == null || TargetFoodNeed == null || FeederHoneyNeed == null)
|
||
return false;
|
||
|
||
// 检查目标是否有蜜罐需求,如果有则不能喂食
|
||
if (TargetHoneyNeed != null)
|
||
return false;
|
||
|
||
// 保留目标pawn的位置,以便接近
|
||
return true;
|
||
}
|
||
|
||
protected override IEnumerable<Toil> MakeNewToils()
|
||
{
|
||
// 确保目标有效
|
||
this.FailOnDespawnedOrNull(TargetIndex.A);
|
||
this.FailOn(() => TargetPawn.Dead || TargetFoodNeed == null || FeederHoneyNeed == null);
|
||
|
||
// 额外检查:目标不能有蜜罐需求
|
||
this.FailOn(() => TargetHoneyNeed != null);
|
||
|
||
// Toil 1: 移动到目标面前
|
||
yield return Toils_Goto.GotoThing(TargetIndex.A, PathEndMode.Touch)
|
||
.FailOnDespawnedOrNull(TargetIndex.A);
|
||
|
||
// Toil 2: 进行喂养工作
|
||
Toil feedToil = new Toil
|
||
{
|
||
initAction = delegate
|
||
{
|
||
// 初始化喂养动作
|
||
},
|
||
tickAction = delegate
|
||
{
|
||
// 每tick检查是否还能继续喂养
|
||
if (FeederHoneyNeed.CurLevel <= 0 || TargetFoodNeed.CurLevelPercentage >= 1.0f)
|
||
{
|
||
ReadyForNextToil();
|
||
return;
|
||
}
|
||
|
||
// 计算本次tick传输的量
|
||
float transferAmount = FoodTransferPerTick;
|
||
float honeyAvailable = FeederHoneyNeed.CurLevel;
|
||
|
||
// 确保不超过蜜罐存量
|
||
if (transferAmount > honeyAvailable)
|
||
transferAmount = honeyAvailable;
|
||
|
||
// 确保不超过目标的需求
|
||
float targetFoodSpace = TargetFoodNeed.MaxLevel - TargetFoodNeed.CurLevel;
|
||
if (transferAmount > targetFoodSpace)
|
||
transferAmount = targetFoodSpace;
|
||
|
||
// 执行传输
|
||
FeederHoneyNeed.ExtractHoney(transferAmount);
|
||
TargetFoodNeed.CurLevel += transferAmount;
|
||
},
|
||
defaultCompleteMode = ToilCompleteMode.Delay,
|
||
defaultDuration = FeedDurationTicks
|
||
};
|
||
|
||
// 添加特效和音效
|
||
feedToil.WithEffect(() => FeedEffect, TargetIndex.A);
|
||
feedToil.PlaySustainerOrSound(() => FeedSound);
|
||
|
||
feedToil.AddFinishAction(delegate
|
||
{
|
||
// 喂养完成后给予社交互动奖励
|
||
TargetPawn.interactions?.TryInteractWith(pawn, InteractionDefOf.Chitchat);
|
||
});
|
||
|
||
feedToil.WithProgressBar(TargetIndex.A,
|
||
() => feedToil.actor.jobs.curDriver.ticksLeftThisToil / (float)FeedDurationTicks,
|
||
interpolateBetweenActorAndTarget: true);
|
||
|
||
yield return feedToil;
|
||
|
||
// 完成Toil
|
||
yield return new Toil
|
||
{
|
||
initAction = delegate
|
||
{
|
||
// 清理代码
|
||
},
|
||
defaultCompleteMode = ToilCompleteMode.Instant
|
||
};
|
||
}
|
||
}
|
||
}
|