修反复割除
This commit is contained in:
Binary file not shown.
@@ -13,13 +13,14 @@ namespace ArachnaeSwarm
|
||||
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
// 懒加载 WorkGiver 实例,确保 DefOf 已被初始化
|
||||
if (_workGiverHarvest == null)
|
||||
{
|
||||
_workGiverHarvest = WorkGiverDefOf.GrowerHarvest.Worker as WorkGiver_GrowerHarvest;
|
||||
_workGiverPlantsCut = WorkGiverDefOf.PlantsCut.Worker as WorkGiver_Scanner;
|
||||
_workGiverHarvest = DefDatabase<WorkGiverDef>.GetNamed("GrowerHarvest").Worker as WorkGiver_GrowerHarvest;
|
||||
_workGiverPlantsCut = DefDatabase<WorkGiverDef>.GetNamed("PlantsCut").Worker as WorkGiver_Scanner;
|
||||
_workGiverArachnaeSow = new WorkGiver_ArachnaeSow();
|
||||
|
||||
if (_workGiverHarvest == null || _workGiverPlantsCut == null)
|
||||
if (_workGiverHarvest == null || _workGiverPlantsCut == null || _workGiverArachnaeSow == null)
|
||||
{
|
||||
Log.ErrorOnce("JobGiver_Grower: Failed to get a required WorkGiver. DefOfs might not be initialized.", 123458);
|
||||
return null;
|
||||
@@ -30,21 +31,29 @@ namespace ArachnaeSwarm
|
||||
IntVec3 bestHarvestCell = FindClosestHarvestableCell(pawn);
|
||||
if (bestHarvestCell.IsValid)
|
||||
{
|
||||
return _workGiverHarvest.JobOnCell(pawn, bestHarvestCell);
|
||||
Job harvestJob = _workGiverHarvest.JobOnCell(pawn, bestHarvestCell);
|
||||
if (harvestJob != null)
|
||||
{
|
||||
return harvestJob;
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 其次处理手动指定的砍伐/收获任务
|
||||
Thing bestCuttable = FindClosestWorkableThing(pawn, _workGiverPlantsCut);
|
||||
if (bestCuttable != null)
|
||||
{
|
||||
return _workGiverPlantsCut.JobOnThing(pawn, bestCuttable);
|
||||
Job cutJob = _workGiverPlantsCut.JobOnThing(pawn, bestCuttable);
|
||||
if (cutJob != null)
|
||||
{
|
||||
return cutJob;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 最后播种(自动,并清理障碍)
|
||||
(IntVec3 bestSowCell, ThingDef plantToSow) = FindClosestSowableCellAndPlant(pawn, _workGiverArachnaeSow);
|
||||
if (bestSowCell.IsValid && plantToSow != null)
|
||||
// 3. 最后处理播种或清理障碍(由 WorkGiver_ArachnaeSow 处理)
|
||||
Job sowOrClearJob = FindClosestSowableOrClearJob(pawn, _workGiverArachnaeSow);
|
||||
if (sowOrClearJob != null)
|
||||
{
|
||||
return _workGiverArachnaeSow.JobOnCell(pawn, bestSowCell);
|
||||
return sowOrClearJob;
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -53,9 +62,9 @@ namespace ArachnaeSwarm
|
||||
private Thing FindClosestWorkableThing(Pawn pawn, WorkGiver_Scanner scanner)
|
||||
{
|
||||
return GenClosest.ClosestThing_Global(
|
||||
pawn.Position,
|
||||
scanner.PotentialWorkThingsGlobal(pawn),
|
||||
maxDistance: 9999f,
|
||||
pawn.Position,
|
||||
scanner.PotentialWorkThingsGlobal(pawn),
|
||||
maxDistance: 9999f,
|
||||
validator: t => t != null && !t.IsForbidden(pawn) && scanner.HasJobOnThing(pawn, t) && pawn.CanReach(t, PathEndMode.Touch, Danger.Deadly)
|
||||
);
|
||||
}
|
||||
@@ -86,47 +95,64 @@ namespace ArachnaeSwarm
|
||||
return bestCell;
|
||||
}
|
||||
|
||||
private (IntVec3, ThingDef) FindClosestSowableCellAndPlant(Pawn pawn, WorkGiver_ArachnaeSow scanner)
|
||||
// 修改后的方法:寻找最近的播种或清理 Job
|
||||
private Job FindClosestSowableOrClearJob(Pawn pawn, WorkGiver_ArachnaeSow scanner)
|
||||
{
|
||||
IntVec3 bestCell = IntVec3.Invalid;
|
||||
ThingDef bestPlantToSow = null;
|
||||
float bestDistSq = float.MaxValue;
|
||||
IntVec3 bestClearCell = IntVec3.Invalid;
|
||||
Job bestClearJob = null;
|
||||
float bestClearDistSq = float.MaxValue;
|
||||
|
||||
IntVec3 bestSowCell = IntVec3.Invalid;
|
||||
Job bestSowJob = null;
|
||||
float bestSowDistSq = float.MaxValue;
|
||||
|
||||
foreach (Zone zone in pawn.Map.zoneManager.AllZones)
|
||||
{
|
||||
if (zone is Zone_Growing growingZone)
|
||||
{
|
||||
ThingDef wantedPlant = growingZone.GetPlantDefToGrow();
|
||||
ThingDef wantedPlant = growingZone.GetPlantDefToGrow();
|
||||
if (wantedPlant == null) continue;
|
||||
|
||||
foreach (IntVec3 cell in growingZone.Cells)
|
||||
{
|
||||
float distSq = pawn.Position.DistanceToSquared(cell);
|
||||
if (distSq < bestDistSq && pawn.CanReach(cell, PathEndMode.ClosestTouch, Danger.Deadly))
|
||||
if (pawn.CanReach(cell, PathEndMode.ClosestTouch, Danger.Deadly))
|
||||
{
|
||||
if (scanner.HasJobOnCell(pawn, cell))
|
||||
Job potentialJob = scanner.JobOnCell(pawn, cell);
|
||||
if (potentialJob != null)
|
||||
{
|
||||
bestDistSq = distSq;
|
||||
bestCell = cell;
|
||||
bestPlantToSow = wantedPlant;
|
||||
if (potentialJob.def == JobDefOf.CutPlant || potentialJob.def == JobDefOf.HaulToContainer || potentialJob.def == JobDefOf.HaulToCell)
|
||||
{
|
||||
if (distSq < bestClearDistSq)
|
||||
{
|
||||
bestClearDistSq = distSq;
|
||||
bestClearJob = potentialJob;
|
||||
}
|
||||
}
|
||||
else if (potentialJob.def == JobDefOf.Sow)
|
||||
{
|
||||
if (distSq < bestSowDistSq)
|
||||
{
|
||||
bestSowDistSq = distSq;
|
||||
bestSowJob = potentialJob;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return (bestCell, bestPlantToSow);
|
||||
// 优先返回清理 Job
|
||||
if (bestClearJob != null)
|
||||
{
|
||||
return bestClearJob;
|
||||
}
|
||||
// 其次返回播种 Job
|
||||
if (bestSowJob != null)
|
||||
{
|
||||
return bestSowJob;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[DefOf]
|
||||
public static class WorkGiverDefOf
|
||||
{
|
||||
public static WorkGiverDef GrowerHarvest;
|
||||
public static WorkGiverDef PlantsCut;
|
||||
|
||||
static WorkGiverDefOf()
|
||||
{
|
||||
DefOfHelper.EnsureInitializedInCtor(typeof(WorkGiverDefOf));
|
||||
}
|
||||
}
|
||||
@@ -52,8 +52,8 @@ namespace ArachnaeSwarm
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 直接计算 wantedPlantDef,不再依赖静态字段
|
||||
|
||||
// 直接计算 wantedPlantDef
|
||||
ThingDef wantedPlantDefLocal = WorkGiver_Grower.CalculateWantedPlantDef(c, map);
|
||||
if (wantedPlantDefLocal == null)
|
||||
{
|
||||
@@ -105,56 +105,65 @@ namespace ArachnaeSwarm
|
||||
return null;
|
||||
}
|
||||
Plant plant = c.GetPlant(map);
|
||||
if (plant != null && plant.def.plant.blockAdjacentSow)
|
||||
if (plant != null) // 只要地块上有植物
|
||||
{
|
||||
if (!pawn.CanReserve(plant, 1, -1, null, forced) || plant.IsForbidden(pawn))
|
||||
// 如果地块上的植物不是我们想要种植的植物,就割除
|
||||
if (plant.def != wantedPlantDefLocal)
|
||||
{
|
||||
if (!pawn.CanReserve(plant, 1, -1, null, forced) || plant.IsForbidden(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (zone_Growing != null && !zone_Growing.allowCut)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!forced && plant.TryGetComp<CompPlantPreventCutting>(out var comp) && comp.PreventCutting)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JobMaker.MakeJob(JobDefOf.CutPlant, plant);
|
||||
}
|
||||
// 如果地块上的植物是我们想要种植的植物,并且它阻碍了相邻播种,则不割除
|
||||
// 因为它已经是我们想要种植的植物了
|
||||
if (plant.def.plant.blockAdjacentSow)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (zone_Growing != null && !zone_Growing.allowCut)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!forced && plant.TryGetComp<CompPlantPreventCutting>(out var comp) && comp.PreventCutting)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!PlantUtility.PawnWillingToCutPlant_Job(plant, pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JobMaker.MakeJob(JobDefOf.CutPlant, plant);
|
||||
}
|
||||
Thing thing2 = PlantUtility.AdjacentSowBlocker(wantedPlantDefLocal, c, map);
|
||||
if (thing2 != null)
|
||||
{
|
||||
if (thing2 is Plant plant2 && pawn.CanReserveAndReach(plant2, PathEndMode.Touch, Danger.Deadly, 1, -1, null, forced) && !plant2.IsForbidden(pawn))
|
||||
if (thing2 is Plant plant2)
|
||||
{
|
||||
IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map);
|
||||
if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def)
|
||||
// 如果阻碍播种的是植物,并且不是我们想要种植的植物,就割除
|
||||
if (plant2.def != wantedPlantDefLocal)
|
||||
{
|
||||
Zone_Growing zone_Growing2 = c.GetZone(map) as Zone_Growing;
|
||||
Zone_Growing zone_Growing3 = plant2.Position.GetZone(map) as Zone_Growing;
|
||||
if ((zone_Growing2 != null && !zone_Growing2.allowCut) || (zone_Growing3 != null && !zone_Growing3.allowCut && plant2.def == zone_Growing3.GetPlantDefToGrow()))
|
||||
if (pawn.CanReserveAndReach(plant2, PathEndMode.Touch, Danger.Deadly, 1, -1, null, forced) && !plant2.IsForbidden(pawn))
|
||||
{
|
||||
return null;
|
||||
IPlantToGrowSettable plantToGrowSettable = plant2.Position.GetPlantToGrowSettable(plant2.Map);
|
||||
if (plantToGrowSettable == null || plantToGrowSettable.GetPlantDefToGrow() != plant2.def)
|
||||
{
|
||||
Zone_Growing zone_Growing2 = c.GetZone(map) as Zone_Growing;
|
||||
Zone_Growing zone_Growing3 = c.GetZone(map) as Zone_Growing;
|
||||
if ((zone_Growing2 != null && !zone_Growing2.allowCut) || (zone_Growing3 != null && !zone_Growing3.allowCut && plant2.def == zone_Growing3.GetPlantDefToGrow()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (!forced && thing2.TryGetComp(out CompPlantPreventCutting comp2) && comp2.PreventCutting)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (PlantUtility.TreeMarkedForExtraction(plant2))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JobMaker.MakeJob(JobDefOf.CutPlant, plant2);
|
||||
}
|
||||
}
|
||||
if (!forced && thing2.TryGetComp(out CompPlantPreventCutting comp2) && comp2.PreventCutting)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (PlantUtility.TreeMarkedForExtraction(plant2))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!PlantUtility.PawnWillingToCutPlant_Job(plant2, pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JobMaker.MakeJob(JobDefOf.CutPlant, plant2);
|
||||
}
|
||||
if (thing2.def.EverHaulable)
|
||||
else if (thing2.def.EverHaulable)
|
||||
{
|
||||
return HaulAIUtility.HaulAsideJobFor(pawn, thing2);
|
||||
}
|
||||
@@ -178,29 +187,29 @@ namespace ArachnaeSwarm
|
||||
}
|
||||
if (thing3.def.category == ThingCategory.Plant)
|
||||
{
|
||||
if (thing3.IsForbidden(pawn))
|
||||
// 如果阻碍播种的是植物,并且不是我们想要种植的植物,就割除
|
||||
if (thing3.def != wantedPlantDefLocal)
|
||||
{
|
||||
return null;
|
||||
if (thing3.IsForbidden(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (zone_Growing != null && !zone_Growing.allowCut)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!forced && thing3.TryGetComp<CompPlantPreventCutting>(out var comp3) && comp3.PreventCutting)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (PlantUtility.TreeMarkedForExtraction(thing3))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JobMaker.MakeJob(JobDefOf.CutPlant, thing3);
|
||||
}
|
||||
if (zone_Growing != null && !zone_Growing.allowCut)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!forced && plant.TryGetComp<CompPlantPreventCutting>(out var comp3) && comp3.PreventCutting)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (!PlantUtility.PawnWillingToCutPlant_Job(thing3, pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (PlantUtility.TreeMarkedForExtraction(thing3))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return JobMaker.MakeJob(JobDefOf.CutPlant, thing3);
|
||||
}
|
||||
if (thing3.def.EverHaulable)
|
||||
else if (thing3.def.EverHaulable)
|
||||
{
|
||||
return HaulAIUtility.HaulAsideJobFor(pawn, thing3);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user