Files
ArachnaeSwarm/Source/ArachnaeSwarm/Jobs/JobDriver_FeedWithHoney/ThinkNode_JobGiver_ExtractHoney.cs
2025-12-16 02:13:18 +08:00

106 lines
3.6 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// File: ThinkNode_JobGiver_ExtractHoney.cs
using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;
using Verse.AI;
namespace ArachnaeSwarm
{
public class ThinkNode_JobGiver_ExtractHoney : ThinkNode_JobGiver
{
private const int ScanIntervalTicks = 300; // 5秒扫描一次
private int lastScanTick = -99999;
protected override Job TryGiveJob(Pawn pawn)
{
// 检查是否应该扫描
int currentTick = Find.TickManager.TicksGame;
if (currentTick - lastScanTick < ScanIntervalTicks)
return null;
lastScanTick = currentTick;
// 检查甲壳剥离组件和开关状态
Comp_ChitinStripping stripComp = pawn.TryGetComp<Comp_ChitinStripping>();
// 检查开关是否开启
if (stripComp == null || !stripComp.CanStripChitin || !stripComp.CanStripNow(pawn))
return null;
// 检查自身需求
Need_HoneyProduction honeyNeed = pawn.needs?.TryGetNeed<Need_HoneyProduction>();
if (honeyNeed == null || !CanExtract(honeyNeed))
return null;
// 如果已经有挤出工作,则不分配新工作
if (pawn.CurJob != null && pawn.CurJob.def == DefDatabase<JobDef>.GetNamed("ARA_ExtractHoney"))
return null;
// 寻找最近的空地
IntVec3 targetCell = FindNearestEmptyCell(pawn);
if (!targetCell.IsValid)
return null;
// 确保可以到达
if (!pawn.CanReach(targetCell, PathEndMode.Touch, Danger.Some))
return null;
// 创建挤出工作
Job job = JobMaker.MakeJob(DefDatabase<JobDef>.GetNamed("ARA_ExtractHoney"), targetCell);
job.count = 1;
return job;
}
// 检查是否可以挤出与JobDriver中的逻辑保持一致
private bool CanExtract(Need_HoneyProduction honeyNeed)
{
// 如果MaxLevel大于1.5需要超过80%储量才考虑挤蜜
if (honeyNeed.MaxLevel > 1.5f)
{
return honeyNeed.CurLevelPercentage > 0.8f;
}
// 否则在大于1时挤蜜
else
{
return honeyNeed.CurLevel >= 1.0f;
}
}
// 寻找最近的空单元格
private IntVec3 FindNearestEmptyCell(Pawn pawn)
{
// 首先检查当前位置周围3格内是否有空地
for (int radius = 1; radius <= 3; radius++)
{
foreach (IntVec3 cell in GenRadial.RadialCellsAround(pawn.Position, radius, true))
{
if (cell.InBounds(pawn.Map) &&
cell.Standable(pawn.Map) &&
cell.GetFirstItem(pawn.Map) == null &&
!cell.GetTerrain(pawn.Map).IsWater)
{
return cell;
}
}
}
// 如果找不到使用CellFinder寻找
if (CellFinder.TryFindBestPawnStandCell(pawn, out IntVec3 bestCell, false))
{
return bestCell;
}
// 最后尝试使用原位置(确保不是水面)
if (!pawn.Position.GetTerrain(pawn.Map).IsWater)
{
return pawn.Position;
}
return IntVec3.Invalid;
}
}
}