修种植传递
This commit is contained in:
Binary file not shown.
@@ -86,20 +86,17 @@
|
||||
<Compile Include="JobGiver_MaintainBuildings.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainHarmony.cs" />
|
||||
<Compile Include="ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs" />
|
||||
<Compile Include="CompAdvancedTraining.cs" />
|
||||
<Compile Include="JobGiver_Grower.cs" />
|
||||
<Compile Include="WorkGiver_ArachnaeSow.cs" />
|
||||
<Compile Include="TrainingSystem_Patcher.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="CompProperties_DelayedTerrainSpawn.cs" />
|
||||
<Compile Include="CompDelayedTerrainSpawn.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="MainHarmony.cs" />
|
||||
<Compile Include="ThinkNode_ConditionalAnimalShouldDoGrowingWork.cs" />
|
||||
<Compile Include="CompAdvancedTraining.cs" />
|
||||
<Compile Include="JobGiver_Grower.cs" />
|
||||
<!-- AnimalWorkSystemPatcher.cs is now in its own group -->
|
||||
<!-- TrainingSystem_Patcher.cs is now in its own group -->
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="WULA_AutoMechCarrier\CompAutoMechCarrier.cs" />
|
||||
<Compile Include="WULA_AutoMechCarrier\CompProperties_AutoMechCarrier.cs" />
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace ArachnaeSwarm
|
||||
public class JobGiver_Grower : ThinkNode_JobGiver
|
||||
{
|
||||
private WorkGiver_GrowerHarvest _workGiverHarvest;
|
||||
private WorkGiver_GrowerSow _workGiverSow;
|
||||
private WorkGiver_ArachnaeSow _workGiverArachnaeSow; // 修改为我们的新 WorkGiver
|
||||
|
||||
protected override Job TryGiveJob(Pawn pawn)
|
||||
{
|
||||
@@ -16,11 +16,11 @@ namespace ArachnaeSwarm
|
||||
if (_workGiverHarvest == null)
|
||||
{
|
||||
_workGiverHarvest = WorkGiverDefOf.GrowerHarvest.Worker as WorkGiver_GrowerHarvest;
|
||||
_workGiverSow = WorkGiverDefOf.GrowerSow.Worker as WorkGiver_GrowerSow;
|
||||
_workGiverArachnaeSow = new WorkGiver_ArachnaeSow(); // 直接实例化我们的 WorkGiver
|
||||
|
||||
if (_workGiverHarvest == null || _workGiverSow == null)
|
||||
if (_workGiverHarvest == null || _workGiverArachnaeSow == null)
|
||||
{
|
||||
Log.ErrorOnce("JobGiver_Grower: Failed to get WorkGiver_GrowerHarvest or WorkGiver_GrowerSow. DefOfs might not be initialized or DefNames are incorrect.", 123457);
|
||||
Log.ErrorOnce("JobGiver_Grower: Failed to get WorkGiver_GrowerHarvest or WorkGiver_ArachnaeSow. DefOfs might not be initialized or WorkGiver_ArachnaeSow could not be instantiated.", 123457);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -29,14 +29,16 @@ namespace ArachnaeSwarm
|
||||
Thing bestHarvestable = FindClosestThing(pawn, _workGiverHarvest);
|
||||
if (bestHarvestable != null)
|
||||
{
|
||||
return _workGiverHarvest.JobOnThing(pawn, bestHarvestable);
|
||||
// 调用 JobOnCell 以利用 WorkGiver_GrowerHarvest 的多目标打包逻辑
|
||||
return _workGiverHarvest.JobOnCell(pawn, bestHarvestable.Position);
|
||||
}
|
||||
|
||||
// 2. 其次播种
|
||||
IntVec3 bestSowCell = FindClosestSowableCell(pawn, _workGiverSow);
|
||||
if (bestSowCell.IsValid)
|
||||
(IntVec3 bestSowCell, ThingDef plantToSow) = FindClosestSowableCellAndPlant(pawn, _workGiverArachnaeSow); // 使用我们的新 WorkGiver
|
||||
if (bestSowCell.IsValid && plantToSow != null)
|
||||
{
|
||||
return _workGiverSow.JobOnCell(pawn, bestSowCell);
|
||||
// 现在直接调用 WorkGiver_ArachnaeSow 的 JobOnCell,它会处理 Job 的创建和 plantDefToSow 的设置
|
||||
return _workGiverArachnaeSow.JobOnCell(pawn, bestSowCell);
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -55,30 +57,37 @@ namespace ArachnaeSwarm
|
||||
);
|
||||
}
|
||||
|
||||
private IntVec3 FindClosestSowableCell(Pawn pawn, WorkGiver_Scanner scanner)
|
||||
private (IntVec3, ThingDef) FindClosestSowableCellAndPlant(Pawn pawn, WorkGiver_ArachnaeSow scanner) // 修改为我们的新 WorkGiver 类型
|
||||
{
|
||||
IntVec3 bestCell = IntVec3.Invalid;
|
||||
ThingDef bestPlantToSow = null;
|
||||
float bestDistSq = float.MaxValue;
|
||||
|
||||
foreach (Zone zone in pawn.Map.zoneManager.AllZones)
|
||||
{
|
||||
if (zone is Zone_Growing growingZone)
|
||||
{
|
||||
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 (scanner.HasJobOnCell(pawn, cell))
|
||||
// 这里不再需要 WorkGiver_Grower.wantedPlantDef 的复杂处理
|
||||
// 因为 WorkGiver_ArachnaeSow.JobOnCell 会直接使用它计算出的 wantedPlantDef
|
||||
if (scanner.HasJobOnCell(pawn, cell)) // HasJobOnCell 内部会根据 wantedPlant 计算
|
||||
{
|
||||
bestDistSq = distSq;
|
||||
bestCell = cell;
|
||||
bestPlantToSow = wantedPlant; // 确保返回正确的 plantDef
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return bestCell;
|
||||
return (bestCell, bestPlantToSow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
218
Source/ArachnaeSwarm/WorkGiver_ArachnaeSow.cs
Normal file
218
Source/ArachnaeSwarm/WorkGiver_ArachnaeSow.cs
Normal file
@@ -0,0 +1,218 @@
|
||||
using System.Collections.Generic;
|
||||
using Verse;
|
||||
using Verse.AI;
|
||||
using RimWorld;
|
||||
|
||||
namespace ArachnaeSwarm
|
||||
{
|
||||
public class WorkGiver_ArachnaeSow : WorkGiver_Grower
|
||||
{
|
||||
protected static string CantSowCavePlantBecauseOfLightTrans;
|
||||
protected static string CantSowCavePlantBecauseUnroofedTrans;
|
||||
|
||||
public override PathEndMode PathEndMode => PathEndMode.ClosestTouch;
|
||||
|
||||
public static void ResetStaticData()
|
||||
{
|
||||
CantSowCavePlantBecauseOfLightTrans = "CantSowCavePlantBecauseOfLight".Translate();
|
||||
CantSowCavePlantBecauseUnroofedTrans = "CantSowCavePlantBecauseUnroofed".Translate();
|
||||
}
|
||||
|
||||
protected override bool ExtraRequirements(IPlantToGrowSettable settable, Pawn pawn)
|
||||
{
|
||||
if (!settable.CanAcceptSowNow())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
IntVec3 c;
|
||||
if (settable is Zone_Growing zone_Growing)
|
||||
{
|
||||
if (!zone_Growing.allowSow)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
c = zone_Growing.Cells[0];
|
||||
}
|
||||
else
|
||||
{
|
||||
c = ((Thing)settable).Position;
|
||||
}
|
||||
ThingDef wantedPlantDef = WorkGiver_Grower.CalculateWantedPlantDef(c, pawn.Map);
|
||||
if (wantedPlantDef == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public override Job JobOnCell(Pawn pawn, IntVec3 c, bool forced = false)
|
||||
{
|
||||
Map map = pawn.Map;
|
||||
if (c.GetVacuum(pawn.Map) >= 0.5f)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
// 直接计算 wantedPlantDef,不再依赖静态字段
|
||||
ThingDef wantedPlantDefLocal = WorkGiver_Grower.CalculateWantedPlantDef(c, map);
|
||||
if (wantedPlantDefLocal == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!PlantUtility.GrowthSeasonNow(c, map, wantedPlantDefLocal))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
List<Thing> thingList = c.GetThingList(map);
|
||||
Zone_Growing zone_Growing = c.GetZone(map) as Zone_Growing;
|
||||
bool flag = false;
|
||||
for (int i = 0; i < thingList.Count; i++)
|
||||
{
|
||||
Thing thing = thingList[i];
|
||||
if (thing.def == wantedPlantDef)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if ((thing is Blueprint || thing is Frame) && thing.Faction == pawn.Faction)
|
||||
{
|
||||
flag = true;
|
||||
}
|
||||
}
|
||||
if (flag)
|
||||
{
|
||||
Thing edifice = c.GetEdifice(map);
|
||||
if (edifice == null || edifice.def.fertility < 0f)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (wantedPlantDefLocal.plant.diesToLight)
|
||||
{
|
||||
if (!c.Roofed(map) && !map.GameConditionManager.IsAlwaysDarkOutside)
|
||||
{
|
||||
JobFailReason.Is(CantSowCavePlantBecauseUnroofedTrans);
|
||||
return null;
|
||||
}
|
||||
if (map.glowGrid.GroundGlowAt(c, ignoreCavePlants: true) > 0f)
|
||||
{
|
||||
JobFailReason.Is(CantSowCavePlantBecauseOfLightTrans);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
if (wantedPlantDefLocal.plant.interferesWithRoof && c.Roofed(pawn.Map))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Plant plant = c.GetPlant(map);
|
||||
if (plant != null && plant.def.plant.blockAdjacentSow)
|
||||
{
|
||||
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;
|
||||
}
|
||||
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))
|
||||
{
|
||||
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 = 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()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
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)
|
||||
{
|
||||
return HaulAIUtility.HaulAsideJobFor(pawn, thing2);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (wantedPlantDefLocal.plant.sowMinSkill > 0 && ((pawn.skills != null && pawn.skills.GetSkill(SkillDefOf.Plants).Level < wantedPlantDefLocal.plant.sowMinSkill) || (pawn.IsColonyMech && pawn.RaceProps.mechFixedSkillLevel < wantedPlantDefLocal.plant.sowMinSkill)))
|
||||
{
|
||||
JobFailReason.Is("UnderAllowedSkill".Translate(wantedPlantDefLocal.plant.sowMinSkill), def.label);
|
||||
return null;
|
||||
}
|
||||
for (int j = 0; j < thingList.Count; j++)
|
||||
{
|
||||
Thing thing3 = thingList[j];
|
||||
if (!thing3.def.BlocksPlanting())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (!pawn.CanReserve(thing3, 1, -1, null, forced))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
if (thing3.def.category == ThingCategory.Plant)
|
||||
{
|
||||
if (thing3.IsForbidden(pawn))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
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)
|
||||
{
|
||||
return HaulAIUtility.HaulAsideJobFor(pawn, thing3);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!wantedPlantDefLocal.CanNowPlantAt(c, map) || !PlantUtility.GrowthSeasonNow(c, map, wantedPlantDefLocal) || !pawn.CanReserve(c, 1, -1, null, forced))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
Job job = JobMaker.MakeJob(JobDefOf.Sow, c);
|
||||
job.plantDefToSow = wantedPlantDefLocal;
|
||||
return job;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user