失败
This commit is contained in:
Binary file not shown.
@@ -22,6 +22,15 @@
|
|||||||
</trainables>
|
</trainables>
|
||||||
</li>
|
</li>
|
||||||
<li Class="ArachnaeSwarm.CompProperties_AnimalWorkSettings">
|
<li Class="ArachnaeSwarm.CompProperties_AnimalWorkSettings">
|
||||||
|
<!-- 定义技能等级 -->
|
||||||
|
<skillLevels>
|
||||||
|
<li>
|
||||||
|
<skill>Plants</skill>
|
||||||
|
<level>10</level>
|
||||||
|
<disableDecay>true</disableDecay>
|
||||||
|
</li>
|
||||||
|
</skillLevels>
|
||||||
|
<!-- 定义训练项与工作类型的映射 -->
|
||||||
<workTypeMap>
|
<workTypeMap>
|
||||||
<li>
|
<li>
|
||||||
<trainable>ARA_Sowing</trainable>
|
<trainable>ARA_Sowing</trainable>
|
||||||
|
|||||||
@@ -107,7 +107,7 @@
|
|||||||
<subNodes>
|
<subNodes>
|
||||||
<!-- Wild insects with no lord will fight nearby enemies -->
|
<!-- Wild insects with no lord will fight nearby enemies -->
|
||||||
<li Class="JobGiver_AIFightEnemies">
|
<li Class="JobGiver_AIFightEnemies">
|
||||||
<targetAcquireRadius>30</targetAcquireRadius> <!-- Same as DefendAndExpandHive -->
|
<targetAcquireRadius>30</targetAcquireRadius> <!-- Same as DefendAndExpandHive -->
|
||||||
<targetKeepRadius>35</targetKeepRadius>
|
<targetKeepRadius>35</targetKeepRadius>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -324,6 +324,45 @@
|
|||||||
</subNodes>
|
</subNodes>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
|
<!-- OUR CUSTOM LOGIC INJECTION FOR PLANT HARVESTING -->
|
||||||
|
<li Class="ThinkNode_ConditionalTrainableCompleted">
|
||||||
|
<trainable>ARA_Sowing</trainable> <!-- Harvesting is part of Sowing skill -->
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ArachnaeSwarm.ThinkNode_ConditionalAnimalShouldSow">
|
||||||
|
<subNodes>
|
||||||
|
<!-- 优先执行收割 -->
|
||||||
|
<li Class="ArachnaeSwarm.JobGiver_PlantHarvest" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- OUR CUSTOM LOGIC INJECTION FOR PLANT SOWING -->
|
||||||
|
<li Class="ThinkNode_ConditionalTrainableCompleted">
|
||||||
|
<trainable>ARA_Sowing</trainable>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ArachnaeSwarm.ThinkNode_ConditionalAnimalShouldSow">
|
||||||
|
<subNodes>
|
||||||
|
<!-- 然后执行播种 -->
|
||||||
|
<li Class="ArachnaeSwarm.JobGiver_PlantSow" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
|
<!-- OUR CUSTOM LOGIC INJECTION FOR PLANT CUTTING -->
|
||||||
|
<li Class="ThinkNode_ConditionalTrainableCompleted">
|
||||||
|
<trainable>ARA_PlantCutting</trainable>
|
||||||
|
<subNodes>
|
||||||
|
<li Class="ArachnaeSwarm.ThinkNode_ConditionalAnimalShouldPlantCut">
|
||||||
|
<subNodes>
|
||||||
|
<!-- 最后执行割除 -->
|
||||||
|
<li Class="ArachnaeSwarm.JobGiver_PlantCutting" />
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
</subNodes>
|
||||||
|
</li>
|
||||||
|
|
||||||
</subNodes>
|
</subNodes>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
@@ -335,31 +374,6 @@
|
|||||||
<insertTag>Insect_PreWander</insertTag>
|
<insertTag>Insect_PreWander</insertTag>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<!-- OUR CUSTOM LOGIC INJECTION -->
|
|
||||||
<li Class="ArachnaeSwarm.ThinkNode_ConditionalAnimalShouldSow">
|
|
||||||
<subNodes>
|
|
||||||
<li Class="ThinkNode_Tagger">
|
|
||||||
<tagToGive>TrainedAnimalBehavior</tagToGive>
|
|
||||||
<subNodes>
|
|
||||||
<li Class="RimWorld.JobGiver_Work" />
|
|
||||||
</subNodes>
|
|
||||||
</li>
|
|
||||||
</subNodes>
|
|
||||||
</li>
|
|
||||||
<!-- END OF CUSTOM LOGIC -->
|
|
||||||
|
|
||||||
<!-- OUR CUSTOM LOGIC INJECTION FOR PLANT CUTTING -->
|
|
||||||
<li Class="ArachnaeSwarm.ThinkNode_ConditionalAnimalShouldPlantCut">
|
|
||||||
<subNodes>
|
|
||||||
<li Class="ThinkNode_Tagger">
|
|
||||||
<tagToGive>TrainedAnimalBehavior</tagToGive>
|
|
||||||
<subNodes>
|
|
||||||
<li Class="RimWorld.JobGiver_Work" />
|
|
||||||
</subNodes>
|
|
||||||
</li>
|
|
||||||
</subNodes>
|
|
||||||
</li>
|
|
||||||
|
|
||||||
<!-- Tame insect: wander near colony if possible -->
|
<!-- Tame insect: wander near colony if possible -->
|
||||||
<li Class="ThinkNode_ConditionalOfPlayerFaction">
|
<li Class="ThinkNode_ConditionalOfPlayerFaction">
|
||||||
<subNodes>
|
<subNodes>
|
||||||
|
|||||||
@@ -96,8 +96,10 @@
|
|||||||
<Compile Include="CompNoTrainingDecay.cs" />
|
<Compile Include="CompNoTrainingDecay.cs" />
|
||||||
<Compile Include="ThinkNode_ConditionalAnimalShouldSow.cs" />
|
<Compile Include="ThinkNode_ConditionalAnimalShouldSow.cs" />
|
||||||
<Compile Include="ThinkNode_ConditionalAnimalShouldPlantCut.cs" />
|
<Compile Include="ThinkNode_ConditionalAnimalShouldPlantCut.cs" />
|
||||||
<Compile Include="CompProperties_AnimalWorkSettings.cs" />
|
|
||||||
<Compile Include="CompAnimalWorkSettings.cs" />
|
<Compile Include="CompAnimalWorkSettings.cs" />
|
||||||
|
<Compile Include="JobGiver_PlantCutting.cs" />
|
||||||
|
<Compile Include="JobGiver_PlantHarvest.cs" />
|
||||||
|
<Compile Include="JobGiver_PlantSow.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="WULA_AutoMechCarrier\CompAutoMechCarrier.cs" />
|
<Compile Include="WULA_AutoMechCarrier\CompAutoMechCarrier.cs" />
|
||||||
|
|||||||
@@ -4,6 +4,35 @@ using RimWorld;
|
|||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
|
public class CompProperties_AnimalWorkSettings : CompProperties
|
||||||
|
{
|
||||||
|
// 使用列表存储键值对,因为RimWorld的XML解析器对字典有特殊要求
|
||||||
|
public List<WorkTypeMapEntry> workTypeMap = new List<WorkTypeMapEntry>();
|
||||||
|
// 定义动物的技能等级
|
||||||
|
public List<SkillLevelEntry> skillLevels = new List<SkillLevelEntry>();
|
||||||
|
|
||||||
|
public CompProperties_AnimalWorkSettings()
|
||||||
|
{
|
||||||
|
this.compClass = typeof(CompAnimalWorkSettings);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义键值对的结构
|
||||||
|
public class WorkTypeMapEntry
|
||||||
|
{
|
||||||
|
public TrainableDef trainable;
|
||||||
|
public WorkTypeDef workType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定义技能和等级的结构
|
||||||
|
public class SkillLevelEntry
|
||||||
|
{
|
||||||
|
public SkillDef skill;
|
||||||
|
public int level = 0; // 默认等级为0
|
||||||
|
// 可选:是否阻止技能衰减
|
||||||
|
public bool disableDecay = true;
|
||||||
|
}
|
||||||
|
|
||||||
public class CompAnimalWorkSettings : ThingComp
|
public class CompAnimalWorkSettings : ThingComp
|
||||||
{
|
{
|
||||||
public CompProperties_AnimalWorkSettings Props => (CompProperties_AnimalWorkSettings)this.props;
|
public CompProperties_AnimalWorkSettings Props => (CompProperties_AnimalWorkSettings)this.props;
|
||||||
@@ -15,35 +44,54 @@ namespace ArachnaeSwarm
|
|||||||
Pawn pawn = this.parent as Pawn;
|
Pawn pawn = this.parent as Pawn;
|
||||||
if (pawn == null) return;
|
if (pawn == null) return;
|
||||||
|
|
||||||
// 关键:如果 pawn 没有 workSettings,则为其创建一个
|
// 1. 确保 workSettings 存在
|
||||||
if (pawn.workSettings == null)
|
if (pawn.workSettings == null)
|
||||||
{
|
{
|
||||||
// Log.Message($"Initializing Pawn_WorkSettings for animal: {pawn.LabelShort}");
|
|
||||||
pawn.workSettings = new Pawn_WorkSettings(pawn);
|
pawn.workSettings = new Pawn_WorkSettings(pawn);
|
||||||
pawn.workSettings.EnableAndInitializeIfNotAlreadyInitialized();
|
pawn.workSettings.EnableAndInitializeIfNotAlreadyInitialized();
|
||||||
|
|
||||||
// 注意:Pawn_WorkSettings 的构造函数和 EnableAndInitializeIfNotAlreadyInitialized()
|
|
||||||
// 通常会处理所有可用的 WorkTypeDef,并将它们的优先级初始化为 0。
|
|
||||||
// 这正是我们想要的初始状态。具体的优先级将由其他逻辑(如你的 CompInstantTrain 或 ThinkNode)来设置。
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 设置工作优先级
|
// 2. 设置技能等级 (如果定义了)
|
||||||
if (pawn.workSettings != null)
|
if (pawn.skills != null && Props.skillLevels != null)
|
||||||
|
{
|
||||||
|
foreach (var entry in Props.skillLevels)
|
||||||
|
{
|
||||||
|
if (entry.skill != null)
|
||||||
|
{
|
||||||
|
var skillRecord = pawn.skills.GetSkill(entry.skill);
|
||||||
|
if (skillRecord != null)
|
||||||
|
{
|
||||||
|
// 设置技能等级
|
||||||
|
skillRecord.Level = entry.level;
|
||||||
|
|
||||||
|
// 可选:阻止技能衰减
|
||||||
|
// 在新版本中,将激情设置为 None 可以阻止自然增长和衰减
|
||||||
|
if (entry.disableDecay)
|
||||||
|
{
|
||||||
|
skillRecord.passion = Passion.None;
|
||||||
|
// 注意:仅设置 passion=None 可能不足以完全阻止衰减
|
||||||
|
// 如果仍有问题,可能需要在 ThinkNode 或其他地方定期重置技能等级
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 设置工作优先级 (如果定义了映射关系)
|
||||||
|
// 这里我们不检查 pawn.training.HasLearned,因为这个组件只负责提供"能力"
|
||||||
|
// 具体是否执行工作由 ThinkNode_Conditional 控制
|
||||||
|
if (pawn.workSettings != null && Props.workTypeMap != null)
|
||||||
{
|
{
|
||||||
foreach (var entry in Props.workTypeMap)
|
foreach (var entry in Props.workTypeMap)
|
||||||
{
|
{
|
||||||
TrainableDef trainable = entry.trainable;
|
if (entry.trainable != null && entry.workType != null)
|
||||||
WorkTypeDef workType = entry.workType;
|
|
||||||
|
|
||||||
// 检查动物是否学会了对应的 Trainable
|
|
||||||
if (pawn.training != null && pawn.training.HasLearned(trainable))
|
|
||||||
{
|
{
|
||||||
// 设置一个默认的非零优先级,例如 3 (Medium)
|
// 为相关工作类型设置默认优先级
|
||||||
// 真正的"开关"由 ThinkNode_Conditional 的 GetWanted 控制
|
// 实际是否执行由 ThinkNode_Conditional 的 GetWanted 控制
|
||||||
pawn.workSettings.SetPriority(workType, 3);
|
pawn.workSettings.SetPriority(entry.workType, 3);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,36 @@ using RimWorld;
|
|||||||
|
|
||||||
namespace ArachnaeSwarm
|
namespace ArachnaeSwarm
|
||||||
{
|
{
|
||||||
|
public class CompInstantTrain : ThingComp
|
||||||
|
{
|
||||||
|
public CompProperties_InstantTrain Props => (CompProperties_InstantTrain)this.props;
|
||||||
|
|
||||||
|
public override void PostSpawnSetup(bool respawningAfterLoad)
|
||||||
|
{
|
||||||
|
base.PostSpawnSetup(respawningAfterLoad);
|
||||||
|
|
||||||
|
// 只在初次生成时执行,加载存档时不需要重新训练
|
||||||
|
if (respawningAfterLoad) return;
|
||||||
|
|
||||||
|
Pawn pawn = this.parent as Pawn;
|
||||||
|
if (pawn?.training == null) return;
|
||||||
|
|
||||||
|
// 瞬间训练所有在 Props 中指定的技能
|
||||||
|
foreach (var trainable in Props.trainables)
|
||||||
|
{
|
||||||
|
if (trainable != null && !pawn.training.HasLearned(trainable))
|
||||||
|
{
|
||||||
|
// 注意:直接调用 Train 方法,它会内部处理 SetWanted 的逻辑
|
||||||
|
// 原版的 SetWanted 方法可能已被移除或变为内部方法
|
||||||
|
pawn.training.Train(trainable, null, true); // true表示瞬间完成
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// CompInstantTrain 的职责到此结束
|
||||||
|
// 工作优先级设置由 CompAnimalWorkSettings 负责
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public class CompProperties_InstantTrain : CompProperties
|
public class CompProperties_InstantTrain : CompProperties
|
||||||
{
|
{
|
||||||
public List<TrainableDef> trainables = new List<TrainableDef>();
|
public List<TrainableDef> trainables = new List<TrainableDef>();
|
||||||
@@ -13,32 +43,4 @@ namespace ArachnaeSwarm
|
|||||||
this.compClass = typeof(CompInstantTrain);
|
this.compClass = typeof(CompInstantTrain);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
public class CompInstantTrain : ThingComp
|
|
||||||
{
|
|
||||||
public CompProperties_InstantTrain Props => (CompProperties_InstantTrain)this.props;
|
|
||||||
|
|
||||||
public override void PostSpawnSetup(bool respawningAfterLoad)
|
|
||||||
{
|
|
||||||
base.PostSpawnSetup(respawningAfterLoad);
|
|
||||||
|
|
||||||
if (!respawningAfterLoad) // 只在初次生成时执行
|
|
||||||
{
|
|
||||||
Pawn pawn = this.parent as Pawn;
|
|
||||||
if (pawn == null || pawn.training == null)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 瞬间训练技能
|
|
||||||
foreach (TrainableDef trainableDef in Props.trainables)
|
|
||||||
{
|
|
||||||
if (!pawn.training.HasLearned(trainableDef))
|
|
||||||
{
|
|
||||||
pawn.training.Train(trainableDef, null, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,25 +0,0 @@
|
|||||||
using System.Collections.Generic;
|
|
||||||
using Verse;
|
|
||||||
using RimWorld;
|
|
||||||
|
|
||||||
namespace ArachnaeSwarm
|
|
||||||
{
|
|
||||||
public class CompProperties_AnimalWorkSettings : CompProperties
|
|
||||||
{
|
|
||||||
// 使用列表存储键值对,因为RimWorld的XML解析器对字典有特殊要求
|
|
||||||
public List<WorkTypeMapEntry> workTypeMap = new List<WorkTypeMapEntry>();
|
|
||||||
|
|
||||||
// 可以在这里添加一些配置选项,比如默认优先级等,但现在简单起见,可以留空或只做基本初始化
|
|
||||||
public CompProperties_AnimalWorkSettings()
|
|
||||||
{
|
|
||||||
this.compClass = typeof(CompAnimalWorkSettings);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 定义键值对的结构
|
|
||||||
public class WorkTypeMapEntry
|
|
||||||
{
|
|
||||||
public TrainableDef trainable;
|
|
||||||
public WorkTypeDef workType;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
56
Source/ArachnaeSwarm/JobGiver_PlantCutting.cs
Normal file
56
Source/ArachnaeSwarm/JobGiver_PlantCutting.cs
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Verse;
|
||||||
|
using Verse.AI;
|
||||||
|
using RimWorld;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class JobGiver_PlantCutting : ThinkNode_JobGiver
|
||||||
|
{
|
||||||
|
private WorkGiverDef cutWorkGiverDef = null;
|
||||||
|
private bool triedToLoad = false;
|
||||||
|
|
||||||
|
protected override Job TryGiveJob(Pawn pawn)
|
||||||
|
{
|
||||||
|
if (!triedToLoad || cutWorkGiverDef == null)
|
||||||
|
{
|
||||||
|
triedToLoad = true;
|
||||||
|
cutWorkGiverDef = DefDatabase<WorkGiverDef>.GetNamed("PlantsCut", false);
|
||||||
|
if (cutWorkGiverDef == null)
|
||||||
|
{
|
||||||
|
Log.ErrorOnce("[ArachnaeSwarm] Could not find WorkGiverDef named 'PlantsCut'. Plant Cutting will not work.", 847595);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cutWorkGiverDef?.Worker is WorkGiver_Scanner workGiver)
|
||||||
|
{
|
||||||
|
// ... (你的逻辑,调用 workGiver 的方法) ...
|
||||||
|
IEnumerable<Thing> potentialPlants = workGiver.PotentialWorkThingsGlobal(pawn);
|
||||||
|
// ... (后续逻辑,确保都用 workGiver 实例) ...
|
||||||
|
if (!workGiver.ShouldSkip(pawn) && workGiver.MissingRequiredCapacity(pawn) == null)
|
||||||
|
{
|
||||||
|
return workGiver.NonScanJob(pawn);
|
||||||
|
}
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Warning($"[ArachnaeSwarm] WorkGiverDef 'PlantsCut' Worker is not a WorkGiver_Scanner for pawn {pawn?.LabelShort ?? "NULL"}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... (Validator 方法也需要修改) ...
|
||||||
|
private static bool Validator(Pawn pawn, WorkGiver_Scanner workGiver, Thing t)
|
||||||
|
{
|
||||||
|
if (t.IsForbidden(pawn))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// if (workGiver.ShouldSkip(pawn)) { return false; } // 这个检查可以保留或去掉
|
||||||
|
return workGiver.JobOnThing(pawn, t) != null; // 使用传入的实例
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
63
Source/ArachnaeSwarm/JobGiver_PlantHarvest.cs
Normal file
63
Source/ArachnaeSwarm/JobGiver_PlantHarvest.cs
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
using System.Collections.Generic;
|
||||||
|
using Verse;
|
||||||
|
using Verse.AI;
|
||||||
|
using RimWorld;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class JobGiver_PlantHarvest : ThinkNode_JobGiver
|
||||||
|
{
|
||||||
|
// 声明变量,但不立即初始化
|
||||||
|
private WorkGiverDef harvestWorkGiverDef = null;
|
||||||
|
// 用一个标志位确保只尝试加载一次
|
||||||
|
private bool triedToLoad = false;
|
||||||
|
|
||||||
|
protected override Job TryGiveJob(Pawn pawn)
|
||||||
|
{
|
||||||
|
// 如果还没尝试加载,或者之前加载失败了
|
||||||
|
if (!triedToLoad || harvestWorkGiverDef == null)
|
||||||
|
{
|
||||||
|
triedToLoad = true; // 标记为已尝试
|
||||||
|
// 在需要时才查找 Def
|
||||||
|
harvestWorkGiverDef = DefDatabase<WorkGiverDef>.GetNamed("GrowerHarvest", false);
|
||||||
|
if (harvestWorkGiverDef == null)
|
||||||
|
{
|
||||||
|
// 这个 Log 可以保留,方便调试
|
||||||
|
Log.ErrorOnce("[ArachnaeSwarm] Could not find WorkGiverDef named 'GrowerHarvest'. Harvesting will not work.", 847593);
|
||||||
|
return null; // 找不到就直接返回
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 现在可以安全地使用 harvestWorkGiverDef 了
|
||||||
|
if (harvestWorkGiverDef?.Worker is WorkGiver_Scanner workGiver)
|
||||||
|
{
|
||||||
|
// ... (你原来的逻辑) ...
|
||||||
|
IEnumerable<Thing> potentialPlants = workGiver.PotentialWorkThingsGlobal(pawn);
|
||||||
|
// ... (后续逻辑) ...
|
||||||
|
// 确保调用的是 workGiver (已解析的实例)
|
||||||
|
if (!workGiver.ShouldSkip(pawn) && workGiver.MissingRequiredCapacity(pawn) == null)
|
||||||
|
{
|
||||||
|
return workGiver.NonScanJob(pawn);
|
||||||
|
}
|
||||||
|
// ... 其他逻辑 ...
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Warning($"[ArachnaeSwarm] WorkGiverDef 'GrowerHarvest' Worker is not a WorkGiver_Scanner for pawn {pawn?.LabelShort ?? "NULL"}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ... (Validator 方法也需要确保使用传入的 workGiver 实例) ...
|
||||||
|
private static bool HarvestValidator(Pawn pawn, WorkGiver_Scanner workGiver, Thing t)
|
||||||
|
{
|
||||||
|
if (t.IsForbidden(pawn))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// 使用传入的已解析实例
|
||||||
|
return workGiver.JobOnThing(pawn, t) != null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
41
Source/ArachnaeSwarm/JobGiver_PlantSow.cs
Normal file
41
Source/ArachnaeSwarm/JobGiver_PlantSow.cs
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
using Verse;
|
||||||
|
using Verse.AI;
|
||||||
|
using RimWorld;
|
||||||
|
|
||||||
|
namespace ArachnaeSwarm
|
||||||
|
{
|
||||||
|
public class JobGiver_PlantSow : ThinkNode_JobGiver
|
||||||
|
{
|
||||||
|
private WorkGiverDef sowWorkGiverDef = null;
|
||||||
|
private bool triedToLoad = false;
|
||||||
|
|
||||||
|
protected override Job TryGiveJob(Pawn pawn)
|
||||||
|
{
|
||||||
|
if (!triedToLoad || sowWorkGiverDef == null)
|
||||||
|
{
|
||||||
|
triedToLoad = true;
|
||||||
|
sowWorkGiverDef = DefDatabase<WorkGiverDef>.GetNamed("GrowerSow", false);
|
||||||
|
if (sowWorkGiverDef == null)
|
||||||
|
{
|
||||||
|
Log.ErrorOnce("[ArachnaeSwarm] Could not find WorkGiverDef named 'GrowerSow'. Sowing will not work.", 847594);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sowWorkGiverDef?.Worker is WorkGiver_Scanner sowerScanner) // 直接用 Scanner 接口
|
||||||
|
{
|
||||||
|
// ... (你的逻辑,调用 sowerScanner 的方法) ...
|
||||||
|
if (!sowerScanner.ShouldSkip(pawn) && sowerScanner.MissingRequiredCapacity(pawn) == null)
|
||||||
|
{
|
||||||
|
return sowerScanner.NonScanJob(pawn); // 使用 Scanner 接口
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.Warning($"[ArachnaeSwarm] WorkGiverDef 'GrowerSow' Worker is not a WorkGiver_Scanner for pawn {pawn?.LabelShort ?? "NULL"}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user