using RimWorld; using System.Linq; using Verse; using Verse.AI; namespace WulaFallenEmpire { public class JobGiver_WulaGetEnergy : ThinkNode_JobGiver { public float minEnergyLevelPercentage = 0.3f; public float maxEnergyLevelPercentage = 0.9f; public override float GetPriority(Pawn pawn) { var energyNeed = pawn.needs.TryGetNeed(); if (energyNeed == null || energyNeed.CurLevelPercentage >= minEnergyLevelPercentage) { return 0f; } return 9.5f; } protected override Job TryGiveJob(Pawn pawn) { var energyNeed = pawn.needs.TryGetNeed(); if (energyNeed == null || energyNeed.CurLevelPercentage >= maxEnergyLevelPercentage) { return null; } if (!TryFindBestEnergySourceFor(pawn, out var energySource)) { return null; } if (energySource is Building_Bed) { return JobMaker.MakeJob(DefDatabase.GetNamed("WULA_LayDownToCharge"), energySource); } var job = JobMaker.MakeJob(DefDatabase.GetNamed("WULA_IngestWulaEnergy"), energySource); job.count = 1; return job; } private bool TryFindBestEnergySourceFor(Pawn pawn, out Thing energySource) { // 优先寻找可用的充电床 energySource = FindChargingBed(pawn); if (energySource != null) { return true; } // 优先从背包中寻找 Thing thing = pawn.inventory.innerContainer.FirstOrFallback(t => t.def.GetModExtension() != null && t.IngestibleNow); if (thing != null) { energySource = thing; return true; } // 否则,在地图上寻找 energySource = GenClosest.ClosestThingReachable( pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.HaulableEver), PathEndMode.ClosestTouch, TraverseParms.For(pawn), 9999f, t => t.def.GetModExtension() != null && t.IngestibleNow && !t.IsForbidden(pawn) && pawn.CanReserve(t) ); return energySource != null; } private Building_Bed FindChargingBed(Pawn pawn) { // 寻找附近可用的 WULA_Charging_Station_Synth Building_Bed bed = (Building_Bed)GenClosest.ClosestThingReachable( pawn.Position, pawn.Map, ThingRequest.ForGroup(ThingRequestGroup.BuildingArtificial), PathEndMode.InteractionCell, TraverseParms.For(pawn), 9999f, b => { if (!(b is Building_Bed bed_internal)) return false; if (bed_internal.GetComp() == null) return false; var powerComp = bed_internal.GetComp(); // 使用 pawn.CanReserve 是最可靠的方法,它包含了对 ملكية، حظر، منطقة، الخ 的所有检查。 return powerComp != null && powerComp.PowerOn && pawn.CanReserve(bed_internal); } ); return bed; } } }