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