106 lines
3.6 KiB
C#
106 lines
3.6 KiB
C#
// 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;
|
||
}
|
||
}
|
||
}
|