diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index a961278..4060780 100644 Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ diff --git a/Source/ArachnaeSwarm/JobGiver_Grower.cs b/Source/ArachnaeSwarm/JobGiver_Grower.cs index babf782..0e42089 100644 --- a/Source/ArachnaeSwarm/JobGiver_Grower.cs +++ b/Source/ArachnaeSwarm/JobGiver_Grower.cs @@ -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.GetNamed("GrowerHarvest").Worker as WorkGiver_GrowerHarvest; + _workGiverPlantsCut = DefDatabase.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)); - } } \ No newline at end of file diff --git a/Source/ArachnaeSwarm/WorkGiver_ArachnaeSow.cs b/Source/ArachnaeSwarm/WorkGiver_ArachnaeSow.cs index ca6c4a3..6ff01b2 100644 --- a/Source/ArachnaeSwarm/WorkGiver_ArachnaeSow.cs +++ b/Source/ArachnaeSwarm/WorkGiver_ArachnaeSow.cs @@ -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(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(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(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(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); }