diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index b47907e..3559f7a 100644
Binary files a/1.6/1.6/Assemblies/ArachnaeSwarm.dll and b/1.6/1.6/Assemblies/ArachnaeSwarm.dll differ
diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceBaseSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceBaseSwarm.xml
index 8f8c58d..a958794 100644
--- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceBaseSwarm.xml
+++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceBaseSwarm.xml
@@ -14,6 +14,14 @@
0.3
1.1
+
+
+
+ ARA_Sowing
+ ARA_PlantCutting
+
+
+
@@ -38,6 +46,7 @@
BeetleLikeWithClaw
+ ARA_Insect_WithPlanting
0.25
0.8
1.7
@@ -46,6 +55,8 @@
Advanced
Dig
+ ARA_Sowing
+ ARA_PlantCutting
diff --git a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml
index 7a49c85..8523c7a 100644
--- a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml
+++ b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml
@@ -1,7 +1,466 @@
-
+
+
- ARA_Humanlike
+ ARA_Insect_WithPlanting
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ Downed
+
+
+ BurningResponse
+
+
+ MentalStateCritical
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+ 0.7
+
+
+ DigOutIfCannotReachMapEdge
+
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+ MentalStateNonCritical
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+ RopedPawn
+
+
+
+
+ LordDuty
+
+
+
+
+ Animal_PreMain
+
+
+ Insect_PreMain
+
+
+
+
+
+
+ TrainedAnimalBehavior
+
+
+ Growing
+
+
+
+
+
+
+
+
+
+
+ TrainedAnimalBehavior
+
+
+ PlantCutting
+
+
+
+
+
+
+
+ true
+
+
+
+ 30
+ 35
+
+
+
+
+ LeaveIfWrongSeason
+
+
+ LeaveIfStarving
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ TrainedAnimalBehavior
+
+
+
+ Obedience
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+ Rescue
+
+
+ 75
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 60
+
+
+ SatisfyingNeeds
+
+
+
+
+
+
+
+
+
+ SatisfyBasicNeeds
+
+
+
+
+
+
+
+
+ SatisfyingNeeds
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+ 1.5
+
+
+
+ Manipulation
+
+
+
+ Haul
+
+
+ TrainedAnimalBehavior
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Forage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dig
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Animal_PreWander
+
+
+ Insect_PreWander
+
+
+
+
+
+
+ Idle
+
+
+
+
+
+ None
+ 120~240
+
+
+
+
+
+
+
+ None
+ 120~240
+ 500
+
+
+
+
+ 0.1
+
+
+ None
+ 120~240
+ 500
+
+
+
+
+
+ None
+ 120~240
+
+
+
+
+
+
+ None
+ 120~240
+
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+ Idle
+
+
+
+
+ Deadly
+ 120~240
+
+
+
+
+
+ Deadly
+ 120~240
+
+
+
+
+
+
+
+
+
+
+ ARA_Humanlike
@@ -20,7 +479,7 @@
-
+
@@ -45,12 +504,12 @@
-
+
-
+
Downed
@@ -65,7 +524,7 @@
Abilities_Escape
-
+
@@ -83,7 +542,7 @@
Humanlike_PostMentalState
-
+
@@ -109,393 +568,4 @@
- HighPriority
-
-
- LordDuty
-
-
-
-
-
-
- Humanlike_PostDuty
-
-
-
-
- 2.5
-
-
-
- ARA_InteractiveEggSac
-
-
-
-
-
-
- ARA_InteractiveEggSac
-
- true
-
-
-
-
-
- true
-
-
-
- true
-
-
-
- Idle
-
-
- Deadly
-
-
-
-
-
-
- Escaping
-
-
-
-
-
-
-
-
-
-
-
- Misc
-
-
- Walk
-
-
-
-
-
-
-
- RestingForMedicalReasons
-
-
-
-
-
-
- ChangingApparel
-
-
-
-
-
-
- SatisfyingNeeds
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
-
-
- Escaping
-
-
-
-
-
-
-
-
- Idle
-
-
- Deadly
-
-
-
-
-
-
-
- Idle
-
-
- Deadly
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- true
- true
-
-
-
-
-
-
- SatisfyingNeeds
-
-
- true
-
-
-
-
-
-
-
-
- Misc
-
-
-
-
-
-
-
- MediumPriority
-
-
- LordDuty
-
-
-
-
-
-
- true
-
-
-
-
- ChangingApparel
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- TakeForInventoryStock
-
-
- true
-
-
-
-
-
-
- UnloadingOwnInventory
-
-
-
-
-
-
-
- Food
- 0.6
-
-
- true
-
-
-
-
-
-
-
-
-
-
-
- Humanlike_PreMain
-
-
-
-
-
-
- MainColonistBehaviorCore
- true
-
-
-
-
-
- WildMan
-
-
- MainWildManBehaviorCore
- true
-
-
-
-
-
-
- Humanlike_PostMain
-
-
-
-
-
-
- Idle
-
-
-
- Joy
- 0.9
- true
-
-
-
-
-
-
-
- None
-
-
-
-
-
-
-
-
- WildMan
-
-
- Idle
-
-
-
- Deadly
- 120~240
-
-
-
-
-
-
-
-
-
-
-
-
- RestingForMedicalReasons
-
-
-
-
-
-
- Misc
-
-
- Walk
-
-
-
-
-
-
-
-
-
-
- true
-
-
- Misc
-
-
- Walk
-
-
-
-
-
-
-
-
- Idle
-
-
- Deadly
-
-
-
-
-
-
-
-
-
\ No newline at end of file
+ HighPriority
\ No newline at end of file
diff --git a/1.6/1.6/Defs/TrainableDefs/ARA_PlantCutting.xml b/1.6/1.6/Defs/TrainableDefs/ARA_PlantCutting.xml
new file mode 100644
index 0000000..9dcdf64
--- /dev/null
+++ b/1.6/1.6/Defs/TrainableDefs/ARA_PlantCutting.xml
@@ -0,0 +1,19 @@
+
+
+
+
+ ARA_PlantCutting
+
+ 允许该生物执行植物割除任务。
+
+ true
+
+ 3
+ Advanced
+
+ 1
+
+ 99
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/TrainableDefs/ARA_Sowing.xml b/1.6/1.6/Defs/TrainableDefs/ARA_Sowing.xml
new file mode 100644
index 0000000..9c3fcde
--- /dev/null
+++ b/1.6/1.6/Defs/TrainableDefs/ARA_Sowing.xml
@@ -0,0 +1,23 @@
+
+
+
+
+ ARA_Sowing
+
+ 允许该生物执行播种任务。
+
+
+ true
+
+
+ 5
+ Advanced
+
+
+ 1
+
+
+ 100
+
+
+
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index e339504..3cbdda3 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -89,6 +89,14 @@
+
+
+
+
+
+
+
+
diff --git a/Source/ArachnaeSwarm/CompInstantTrain.cs b/Source/ArachnaeSwarm/CompInstantTrain.cs
new file mode 100644
index 0000000..cec6bde
--- /dev/null
+++ b/Source/ArachnaeSwarm/CompInstantTrain.cs
@@ -0,0 +1,51 @@
+using System.Collections.Generic;
+using Verse;
+using RimWorld;
+
+namespace ArachnaeSwarm
+{
+ // 定义在 XML 中使用的属性
+ public class CompProperties_InstantTrain : CompProperties
+ {
+ public List trainables = new List();
+
+ public CompProperties_InstantTrain()
+ {
+ this.compClass = typeof(CompInstantTrain);
+ }
+ }
+
+ // 实现组件的逻辑
+ public class CompInstantTrain : ThingComp
+ {
+ // 方便地访问属性
+ public CompProperties_InstantTrain Props => (CompProperties_InstantTrain)this.props;
+
+ // 在 Pawn 生成到地图上后被调用
+ public override void PostSpawnSetup(bool respawningAfterLoad)
+ {
+ base.PostSpawnSetup(respawningAfterLoad);
+
+ // 如果不是在加载存档时重生,则执行训练逻辑
+ if (!respawningAfterLoad)
+ {
+ Pawn pawn = this.parent as Pawn;
+ if (pawn == null || pawn.training == null)
+ {
+ return;
+ }
+
+ // 遍历在 XML 中定义的需要训练的技能列表
+ foreach (TrainableDef trainableDef in Props.trainables)
+ {
+ // 检查 Pawn 是否还未学会此技能
+ if (!pawn.training.HasLearned(trainableDef))
+ {
+ // 调用原版方法,瞬间完成训练
+ pawn.training.Train(trainableDef, null, true);
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/CompNoTrainingDecay.cs b/Source/ArachnaeSwarm/CompNoTrainingDecay.cs
new file mode 100644
index 0000000..f612d2a
--- /dev/null
+++ b/Source/ArachnaeSwarm/CompNoTrainingDecay.cs
@@ -0,0 +1,15 @@
+using Verse;
+
+namespace ArachnaeSwarm
+{
+ // 这是一个“标记”组件。它的唯一目的就是在 XML 中被添加到 ThingDef,
+ // 以便我们的 Harmony 补丁可以识别哪些 Pawn 的训练不应该衰减。
+ // 它本身不需要任何逻辑。
+ public class CompProperties_NoTrainingDecay : CompProperties
+ {
+ public CompProperties_NoTrainingDecay()
+ {
+ this.compClass = typeof(ThingComp); // 我们可以使用一个通用的、空的 ThingComp
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/MainHarmony.cs b/Source/ArachnaeSwarm/MainHarmony.cs
new file mode 100644
index 0000000..8d6fe4d
--- /dev/null
+++ b/Source/ArachnaeSwarm/MainHarmony.cs
@@ -0,0 +1,21 @@
+using Verse;
+using HarmonyLib;
+using System.Reflection;
+
+namespace ArachnaeSwarm
+{
+ // [StaticConstructorOnStartup] 属性确保这个类的静态构造函数在游戏启动时被调用
+ [StaticConstructorOnStartup]
+ public static class MainHarmony
+ {
+ static MainHarmony()
+ {
+ // 创建一个 Harmony 实例。ID 应该是唯一的,通常使用 "作者.Mod名称" 的格式。
+ var harmony = new Harmony("com.kalospacer.arachnaeswarm");
+
+ // Harmony 会自动扫描当前整个程序集(我们的 .dll 文件),
+ // 寻找所有带有 [HarmonyPatch] 属性的类,并应用它们。
+ harmony.PatchAll(Assembly.GetExecutingAssembly());
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/Patch_TrainingTracker_TickRare.cs b/Source/ArachnaeSwarm/Patch_TrainingTracker_TickRare.cs
new file mode 100644
index 0000000..e4fa9ac
--- /dev/null
+++ b/Source/ArachnaeSwarm/Patch_TrainingTracker_TickRare.cs
@@ -0,0 +1,31 @@
+using Verse;
+using HarmonyLib;
+using RimWorld;
+
+namespace ArachnaeSwarm
+{
+ [HarmonyPatch(typeof(Pawn_TrainingTracker), "TrainingTrackerTickRare")]
+ public static class Patch_TrainingTracker_TickRare
+ {
+ // [HarmonyPrefix] 表示这是一个“前缀”补丁,在原方法执行前运行
+ // 它返回一个 bool 值:
+ // - return true: 继续执行原方法 (TrainingTrackerTickRare)
+ // - return false: 阻止执行原方法,直接跳过
+ [HarmonyPrefix]
+ public static bool PreventDecayForSpecialAnimals(Pawn_TrainingTracker __instance)
+ {
+ // __instance 是原方法的实例对象,我们可以通过它访问 pawn
+ Pawn pawn = __instance.pawn;
+
+ // 检查 Pawn 的 ThingDef 是否有我们的“标记”组件
+ if (pawn.def.HasComp(typeof(CompProperties_NoTrainingDecay)))
+ {
+ // 如果有,则这是一个不应衰减训练度的特殊动物,返回 false 阻止原方法执行
+ return false;
+ }
+
+ // 如果没有,则这是一个普通动物,返回 true 让原版的衰减逻辑正常执行
+ return true;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ThinkNode_ConditionalAnimalShouldPlantCut.cs b/Source/ArachnaeSwarm/ThinkNode_ConditionalAnimalShouldPlantCut.cs
new file mode 100644
index 0000000..4489b91
--- /dev/null
+++ b/Source/ArachnaeSwarm/ThinkNode_ConditionalAnimalShouldPlantCut.cs
@@ -0,0 +1,21 @@
+using Verse;
+using Verse.AI;
+using RimWorld;
+
+namespace ArachnaeSwarm
+{
+ public class ThinkNode_ConditionalAnimalShouldPlantCut : ThinkNode_Conditional
+ {
+ protected override bool Satisfied(Pawn pawn)
+ {
+ if (pawn.training == null)
+ {
+ return false;
+ }
+
+ // 使用我们之前创建的静态 DefOf 类来安全地引用 Def
+ return pawn.training.HasLearned(ARA_TrainableDefOf.ARA_PlantCutting) &&
+ pawn.training.GetWanted(ARA_TrainableDefOf.ARA_PlantCutting);
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ThinkNode_ConditionalAnimalShouldSow.cs b/Source/ArachnaeSwarm/ThinkNode_ConditionalAnimalShouldSow.cs
new file mode 100644
index 0000000..da6319c
--- /dev/null
+++ b/Source/ArachnaeSwarm/ThinkNode_ConditionalAnimalShouldSow.cs
@@ -0,0 +1,37 @@
+using Verse;
+using Verse.AI;
+using RimWorld;
+
+namespace ArachnaeSwarm
+{
+ // 使用 [DefOf] 属性,让游戏在启动时自动为我们填充这些字段
+ [DefOf]
+ public static class ARA_TrainableDefOf
+ {
+ // 确保这些字段名与你在 XML 中定义的 defName 完全一致
+ public static TrainableDef ARA_Sowing;
+ public static TrainableDef ARA_PlantCutting;
+
+ // 静态构造函数,确保 DefOf 被初始化
+ static ARA_TrainableDefOf()
+ {
+ DefOfHelper.EnsureInitializedInCtor(typeof(ARA_TrainableDefOf));
+ }
+ }
+
+ public class ThinkNode_ConditionalAnimalShouldSow : ThinkNode_Conditional
+ {
+ protected override bool Satisfied(Pawn pawn)
+ {
+ // MCP 已证实:对于野生动物等情况,pawn.training 可能为 null,此检查是必要的。
+ if (pawn.training == null)
+ {
+ return false;
+ }
+
+ // 使用静态缓存的 Def,检查动物是否学会了该技能,并且玩家是否在“动物”标签页中勾选了允许
+ return pawn.training.HasLearned(ARA_TrainableDefOf.ARA_Sowing) &&
+ pawn.training.GetWanted(ARA_TrainableDefOf.ARA_Sowing);
+ }
+ }
+}
\ No newline at end of file