diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll
index 300064a..b6ff46b 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/EvolutionDefs/ARA_Evolution.xml b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml
index 2b2efa3..12b2151 100644
--- a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml
+++ b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml
@@ -381,11 +381,11 @@
-->
-
+
ARA_AcidSprayBurst
diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_HiveMind.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_HiveMind.xml
index 62ecf34..199b585 100644
--- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_HiveMind.xml
+++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_HiveMind.xml
@@ -48,13 +48,31 @@
false
+
+
+
+ Consciousness
+ 0.15
+
+
0
0
+
+ Mood
+ Joy
+ Beauty
+ Comfort
+ Outdoors
+ Indoors
+ DrugDesire
+ RoomSize
+
ARA_ChitinArmor
+
1
0
@@ -108,20 +126,69 @@
true
true
-
- ARA_HiveMindDrone_Though
- ThoughtWorker_Hediff
- ARA_HiveMindDrone
- true
- Baby, Child, Adult
+
+ ARA_GestaltNetworkOverload
+
+ 格式塔网络超载导致的精神压力,这会削弱阿拉克涅女皇的总体能力,并增加网络崩溃的风险。
+ HediffWithComps
+ false
-
- 我身体中的本能正在呼唤节点监管!
- -99999
+ 0
+
+ 0.1
+
+
+
+ 0.2
+
+
+ Consciousness
+ -0.05
+
+
+
+ 0.2
+
+
+
+ 0.5
+
+
+ Consciousness
+ -0.1
+
+
+
+ 0.35
+
+
+
+ 0.8
+
+
+ Consciousness
+ -0.15
+
+
+
+ 0.5
+
+
+
+ 0.95
+
+
+ Consciousness
+ 0.1
+
+
+
+ 0.5
+
-
+
ARA_NonPlayer_HiveMindDroneHediff
diff --git a/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml b/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml
index 0651fd5..02cc674 100644
--- a/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml
+++ b/1.6/1.6/Defs/PawnKindDef/ARA_PawnKinds.xml
@@ -60,7 +60,6 @@
0
- ARA_BindDrone
ARA_AcidSprayBurst_Queen
ARA_TumorSpew
@@ -453,9 +452,8 @@
- ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin
+ ArachnaeSwarm/Things/ARA_Scavenger/Scavenger/Naked_Thin
1
- (156,148,125)
(0.4, 0.5, 0.37)
(0,0,-0.15)
@@ -477,7 +475,6 @@
ArachnaeSwarm/Things/ARA_Scavenger/Scavenger/Naked_Thin
1
- (156,148,125)
(0.4, 0.5, 0.37)
(0,0,-0.15)
@@ -490,6 +487,49 @@
+
+ ArachnaeBase_Race_Longpincer
+
+ ArachnaeBase_Race_Longpincer
+
+
+
+ ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin
+ 1
+
+ (0.4, 0.5, 0.37)
+ (0,0,-0.15)
+
+
+
+ Things/Pawn/Animal/Spelopede/Dessicated_Spelopede
+ 1
+
+
+
+
+
+ ArachnaeBase_Race_Hivekeeping
+
+ ArachnaeBase_Race_Hivekeeping
+
+
+
+ ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin
+ 1
+
+ (0.4, 0.5, 0.37)
+ (0,0,-0.15)
+
+
+
+ Things/Pawn/Animal/Spelopede/Dessicated_Spelopede
+ 1
+
+
+
+
+
ArachnaeBase_Race_Acidcut
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 fd10bd2..d581d3d 100644
--- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceBaseSwarm.xml
+++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceBaseSwarm.xml
@@ -225,4 +225,228 @@
-
+
+ ArachnaeBase_Race_Longpincer
+
+ 阿拉克涅辅虫之一,拥有一对相较于其体型来说过于巨大的颚部,可以执行搬运、挖掘工作,如果其监管者督虫处于征召状态,则会跟随督虫一起行动。
+
+ 5.5
+ 0.35
+ 0.35
+
+
+ ARA_Insect_Longpincer_Thinktree
+
+ AttackTarget
+ Dig
+
+
+ DeathActionWorker_Vanish
+ Filth_Slime
+ 1~3
+
+
+
+
+
+
+ Obedience
+ true
+ true
+
+
+ Release
+ true
+ true
+
+
+ Rescue
+ true
+ true
+
+
+ Tameness
+ true
+ true
+
+
+ AttackTarget
+ true
+ true
+
+
+ Dig
+ true
+ true
+
+
+ ARA_Sowing
+ true
+ true
+
+
+ ARA_Cleaning
+ true
+ true
+
+
+ Haul
+ true
+ true
+
+
+ true
+
+
+
+ ARA_HiveMindWorker
+
+ 1.0
+ false
+
+
+
+
+ ArachnaeBase_Race_Acidcut
+
+ 阿拉克涅辅虫之一,智力低下,依靠带酸液的颚撕咬敌军,因为身体结构简单而易于孕育。
+
+ ARA_Insect_Acidcut_Thinktree
+ 0.3
+
+ BeetleLikeWithClaw
+
+ DeathActionWorker_Vanish
+ Filth_Slime
+ 1~3
+
+
+
+ 6
+ 0.3
+ 0.3
+
+
+
+
+
+ ARA_AcidCut
+
+ 6
+ 2.6
+ HeadAttackTool
+ true
+
+
+
+
+
+
+ Obedience
+ true
+ true
+
+
+ Release
+ true
+ true
+
+
+ Rescue
+ true
+ true
+
+
+ Tameness
+ true
+ true
+
+
+ AttackTarget
+ true
+ true
+
+
+ true
+
+
+
+ ARA_HiveMindWorker
+
+ 1.0
+ false
+
+
+
+
+ ArachnaeBase_Race_Hivekeeping
+
+ 阿拉克涅辅虫之一,智力低下,可以执行搬运、清洁和虫群建筑的维护工作,是虫巢中不可或缺的维护者集群的一员。
+
+ ARA_Insect_Hivekeeping_Thinktree
+
+ ARA_Cleaning
+
+
+ DeathActionWorker_Vanish
+ Filth_Slime
+ 1~3
+
+
+
+
+ false
+ Crafting
+ 0
+ true
+
+
+
+
+ Obedience
+ true
+ true
+
+
+ Release
+ true
+ true
+
+
+ Rescue
+ true
+ true
+
+
+ Tameness
+ true
+ true
+
+
+ AttackTarget
+ true
+ true
+
+
+ ARA_Cleaning
+ true
+ true
+
+
+ Haul
+ true
+ true
+
+
+ true
+
+
+
+ ARA_HiveMindWorker
+
+ 1.0
+ false
+
+
+
+
\ No newline at end of file
diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceDroneSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceDroneSwarm.xml
index 1a0967c..d7a10d0 100644
--- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceDroneSwarm.xml
+++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceDroneSwarm.xml
@@ -73,32 +73,6 @@
-
- ArachnaeBase_Race_Acidcut
-
- 阿拉克涅辅虫之一,智力低下,一般被作为活体炮弹打出,击中敌人后若是还没散架,就会继续依靠带酸液的颚撕咬敌军。
-
- WarUrchinConstant
- 0.3
-
- BeetleLikeWithClaw
-
-
- 6
-
-
-
-
-
- ARA_AcidCut
-
- 6
- 2.6
- HeadAttackTool
- true
-
-
-
ArachnaeBase_Race_Skyhive
diff --git a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
index 72349a4..1a1a73a 100644
--- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
+++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml
@@ -831,7 +831,7 @@
ArachnaeNode_Race_ShieldHead
- 阿拉克涅督虫之一,拥有过度生长而覆盖头部和腿部的甲壳,可以定时剥落甲壳素供虫巢使用。\n\n她可以进行搬运、采矿和建筑工作,战斗技能平平无奇,但是拥有较好的防御。\n\n作为督虫,她可以繁育并监管若干阿拉克涅坚颚种辅虫,以协助巢穴开采矿脉。
+ 阿拉克涅督虫之一,拥有过度生长而覆盖头部和腿部的甲壳,可以定时剥落甲壳素供虫巢使用。\n\n她可以进行搬运、采矿和建筑工作,战斗技能平平无奇,但是拥有较好的防御。\n\n作为督虫,她可以繁育并监管若干阿拉克涅坚颚种辅虫,以协助巢穴开采矿脉,这些辅虫在其监管者被征召的状态下,会跟随其一起出击并为保护虫巢而战斗。
@@ -959,8 +959,8 @@
9999
- ArachnaeBase_Race_Scavenger
- 2
+ ArachnaeBase_Race_Longpincer
+ 4
5000
@@ -996,7 +996,7 @@
ArachnaeNode_Race_WeaponSmith
- 阿拉克涅督虫之一,是少数拥有结茧能力的非女皇种阿拉克涅虫族——她们可以排出一枚器官茧,这枚茧将按照其信息素所标定的方向定向演化出一个武装器官,以供虫群使用。\n\n她可以进行搬运、手工和艺术工作,战斗技能平平无奇,但本身极度脆弱。\n\n作为督虫,她可以繁育并监管若干阿拉克涅家政种辅虫,以协助巢穴进行清洁和搬运工作。
+ 阿拉克涅督虫之一,主要负责巢穴的维护,以及使用灵巧的肢体为虫群处理一些精细工作。\n\n她可以进行搬运、手工和艺术工作,战斗技能平平无奇,但本身极度脆弱。\n\n作为督虫,她可以繁育并监管若干阿拉克涅家政种辅虫,以协助巢穴进行清洁、搬运和虫群建筑维护工作。
@@ -1084,8 +1084,8 @@
9999
- ArachnaeBase_Race_Scavenger
- 2
+ ArachnaeBase_Race_Hivekeeping
+ 4
5000
@@ -1127,7 +1127,7 @@
ArachnaeNode_Race_Fighter
- 阿拉克涅督虫之一,是巢穴中真正的战士,其拥有强大的可塑性基因,随着科技的解锁其将获得更多的能力。\n\n她可以进行搬运、狩猎和驯兽工作,战斗技能非常亮眼,并且移动敏捷。\n\n作为督虫,她可以向敌人投射寿命有限但是非常恼人的阿拉克涅酸噬种辅虫,以阻止敌人的远程火力开火。
+ 阿拉克涅督虫之一,是巢穴中真正的战士,其拥有强大的可塑性基因,随着科技的解锁其将获得更多的能力。\n\n她可以进行搬运、狩猎和驯兽工作,战斗技能非常亮眼,并且移动敏捷。\n\n作为督虫,她可以繁育并监管若干阿拉克涅酸噬种辅虫,体型小巧却异常坚韧的战斗型辅虫,除了吸收炮火外也能在近战中使用带酸前颚咬人。
@@ -1225,6 +1225,23 @@
+
+ true
+ ARA_RaceBaseSwarmProduceSwitchHediff
+ ARA_InsectJelly
+ 1
+ 1
+ 1
+ 9999
+
+
+ ArachnaeBase_Race_Acidcut
+ 4
+ 1000
+
+
+ CocoonDestroyed
+
ARA_Cycle_Suppression_Hediff
ARA_LifespanHediff
diff --git a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml
index e68930f..42c1107 100644
--- a/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml
+++ b/1.6/1.6/Defs/ThinkTreeDefs/ARA_ThinkTrees.xml
@@ -71,7 +71,7 @@
None
- 120~240
+ 160~300
@@ -80,7 +80,7 @@
None
- 120~240
+ 160~300
500
@@ -90,7 +90,7 @@
None
- 120~240
+ 160~300
500
@@ -98,7 +98,7 @@
None
- 120~240
+ 160~300
@@ -106,7 +106,7 @@
None
- 120~240
+ 160~300
@@ -121,14 +121,14 @@
Deadly
- 560~670
+ 160~300
Deadly
- 560~670
+ 160~300
@@ -893,6 +893,912 @@
+
+ ARA_Insect_Longpincer_Thinktree
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ Downed
+
+
+ BurningResponse
+
+
+ MentalStateCritical
+
+
+
+
+
+
+
+
+
+
+ MentalStateNonCritical
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+ RopedPawn
+
+
+
+
+ LordDuty
+
+
+
+ true
+
+
+
+ 30
+ 35
+
+
+
+
+ LeaveIfWrongSeason
+
+
+ LeaveIfStarving
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ 30
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SatisfyBasicNeeds
+
+
+
+
+
+
+
+
+
+
+ SatisfyingNeeds
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+ 0.15
+
+
+
+ Manipulation
+
+
+
+ Haul
+
+
+ TrainedAnimalBehavior
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Idle
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+
+ None
+ 160~300
+ 1200
+
+
+
+
+ 0.1
+
+
+ None
+ 160~300
+ 1200
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+ Idle
+
+
+
+
+ Deadly
+ 160~300
+
+
+
+
+
+ Deadly
+ 160~300
+
+
+
+
+
+
+
+
+
+
+ ARA_Insect_Acidcut_Thinktree
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ Downed
+
+
+ BurningResponse
+
+
+ MentalStateCritical
+
+
+
+
+
+
+
+
+
+
+ MentalStateNonCritical
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+ RopedPawn
+
+
+
+
+ LordDuty
+
+
+
+ true
+
+
+
+ 30
+ 35
+
+
+
+
+ LeaveIfWrongSeason
+
+
+ LeaveIfStarving
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+ 50
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SatisfyBasicNeeds
+
+
+
+
+
+
+ Idle
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+
+ None
+ 160~300
+ 1200
+
+
+
+
+ 0.1
+
+
+ None
+ 160~300
+ 1200
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+ Idle
+
+
+
+
+ Deadly
+ 160~300
+
+
+
+
+
+ Deadly
+ 160~300
+
+
+
+
+
+
+
+
+
+
+ ARA_Insect_Hivekeeping_Thinktree
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
+ Downed
+
+
+ BurningResponse
+
+
+ MentalStateCritical
+
+
+
+
+
+
+
+
+
+
+ MentalStateNonCritical
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+ RopedPawn
+
+
+
+
+ LordDuty
+
+
+
+ true
+
+
+
+ 30
+ 35
+
+
+
+
+ LeaveIfWrongSeason
+
+
+ LeaveIfStarving
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+ 60
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ SatisfyBasicNeeds
+
+
+
+
+
+
+
+
+
+
+ SatisfyingNeeds
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+
+
+
+ Misc
+
+
+
+
+
+
+
+
+ 50
+ false
+
+
+ 30
+ 0.5
+
+
+
+
+
+
+ 0.15
+
+
+
+ Manipulation
+
+
+
+ Haul
+
+
+ TrainedAnimalBehavior
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Idle
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+
+ None
+ 160~300
+ 1200
+
+
+
+
+ 0.1
+
+
+ None
+ 160~300
+ 1200
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+ None
+ 160~300
+
+
+
+
+
+
+
+
+
+
+ RestingForMedicalReasons
+
+
+
+
+
+
+ Misc
+
+
+ Walk
+
+
+
+
+
+
+
+
+ Idle
+
+
+
+
+ Deadly
+ 160~300
+
+
+
+
+
+ Deadly
+ 160~300
+
+
+
+
+
+
+
+
+
ARA_Humanlike
diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_QueuedIncubator.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_QueuedIncubator.xml
index e9144b3..aa19c81 100644
--- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_QueuedIncubator.xml
+++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/ARA_QueuedIncubator.xml
@@ -111,11 +111,11 @@
当前: {0} / {1}
每日消耗: {0}
⚠ 维护度严重不足!建筑正在受损
- 需要工艺种进行维护
+ 需要巢穴维护者进行维护
状态良好
- 工艺种会自动前来维护低于90%的建筑
+ 巢穴维护者会自动前来维护低于50%的建筑
- 呼叫工艺种维护者
+ 呼叫维护者,阿拉克涅工艺种和其辅虫家政种都可以执行维护工作
已呼叫 {0} 前来维护建筑
- 未找到空闲且可到达的工艺种维护者!
+ 未找到空闲且可到达的维护者!
diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/GizmoLabels.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/GizmoLabels.xml
index e7e5787..609833b 100644
--- a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/GizmoLabels.xml
+++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/GizmoLabels.xml
@@ -9,5 +9,8 @@
监管网络负荷
蜂巢网络是阿拉克涅虫群用于建立格式塔思维簇的体系,这使得整个族群可以在女皇种的统一指挥下获得强大的一致性。
+ 可用节点:{0}
警告:蜂巢网络正在超载,这将会直接影响女皇种的心情,并有可能导致整个网络的传导性崩溃!
+ 蜂巢网络超载已结束
+ {1} 已经断开与 {0} 的链接!
\ No newline at end of file
diff --git a/Content/Textures/ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin_east.png b/Content/Textures/ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin_east.png
similarity index 100%
rename from Content/Textures/ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin_east.png
rename to Content/Textures/ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin_east.png
diff --git a/Content/Textures/ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin_north.png b/Content/Textures/ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin_north.png
similarity index 100%
rename from Content/Textures/ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin_north.png
rename to Content/Textures/ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin_north.png
diff --git a/Content/Textures/ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin_south.png b/Content/Textures/ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin_south.png
similarity index 100%
rename from Content/Textures/ArachnaeSwarm/Things/ARA_Scavenger/Maid/Naked_Thin_south.png
rename to Content/Textures/ArachnaeSwarm/Things/ARA_Hivekeeping/Bodies/Naked_Thin_south.png
diff --git a/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_east.png b/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_east.png
new file mode 100644
index 0000000..fc11040
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_east.png differ
diff --git a/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_north.png b/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_north.png
new file mode 100644
index 0000000..df748dc
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_north.png differ
diff --git a/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_south.png b/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_south.png
new file mode 100644
index 0000000..8794555
Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Things/ARA_Longpincer/Bodies/Naked_Thin_south.png differ
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo
index de683bc..3663693 100644
Binary files a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo and b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo differ
diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
index e99d121..0f51fb3 100644
--- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
+++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json
@@ -1,22 +1,90 @@
{
"Version": 1,
- "WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
+ "WorkspaceRootPath": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\hediffcomp_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\hediffcomp_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\ara_swarmmaintenance\\comp_swarmmaintenance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\ara_swarmmaintenance\\comp_swarmmaintenance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\gestaltbandwidthgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_swarmmaintain\\jobgiver_swarmmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_swarmmaintain\\jobgiver_swarmmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_swarmmaintain\\thinknode_conditionalshouldmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_swarmmaintain\\thinknode_conditionalshouldmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_swarmmaintain\\jobdriver_swarmmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_swarmmaintain\\jobdriver_swarmmaintain.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_followproducer\\jobgiver_aidefendproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_followproducer\\jobgiver_aidefendproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_followproducer\\jobgiver_aifollowproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_followproducer\\jobgiver_aifollowproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_followproducer\\jobgiver_wandernearproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_followproducer\\jobgiver_wandernearproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\jobs\\jobdriver_followproducer\\thinknode_conditionalshouldfollowproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:jobs\\jobdriver_followproducer\\thinknode_conditionalshouldfollowproducer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_automechcarrier\\compautomechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_automechcarrier\\compautomechcarrier.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\pawn_comps\\ara_automechcarrier\\pawnproductionentry.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:pawn_comps\\ara_automechcarrier\\pawnproductionentry.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_dormancyvat\\building_dormancyvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_dormancyvat\\building_dormancyvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\buildings\\building_dormancyvat\\defmodextension_dormancyvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:buildings\\building_dormancyvat\\defmodextension_dormancyvat.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:ara_hediffdefof.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\pawn_gestalttracker.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\pawn_gestalttracker.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\hediffcompproperties_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\hediffcompproperties_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\pawnrelationworker_gestaltoverseer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\pawnrelationworker_gestaltoverseer.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\gestaltbandwidthgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\gestaltbandwidthgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\gestaltcontrolgroup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\compproperties_gestalt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\compproperties_gestalt.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_gestaltnode\\gestaltcontrolgroupgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\gestaltcontrolgroupgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ },
+ {
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\hediffs\\ara_gestaltnode\\gestaltcontrolgroup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\gestaltcontrolgroup.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
- "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\gestaltcontrolgroupgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
- "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\gestaltcontrolgroupgizmo.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
+ "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|e:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\hediffs\\ara_gestaltnode\\hediffcomp_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
+ "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:hediffs\\ara_gestaltnode\\hediffcomp_gestaltnode.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -26,21 +94,8 @@
"DocumentGroups": [
{
"DockedWidth": 200,
- "SelectedChildIndex": 0,
+ "SelectedChildIndex": 3,
"Children": [
- {
- "$type": "Document",
- "DocumentIndex": 0,
- "Title": "HediffComp_GestaltNode.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
- "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
- "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAAABQAAAAnAAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-20T08:24:06.173Z",
- "EditorCaption": ""
- },
{
"$type": "Bookmark",
"Name": "ST:0:0:{1c4feeaa-4718-4aa9-859d-94ce25d182ba}"
@@ -48,10 +103,257 @@
{
"$type": "Document",
"DocumentIndex": 2,
+ "Title": "ThinkNode_ConditionalShouldMaintain.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\ThinkNode_ConditionalShouldMaintain.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_SwarmMaintain\\ThinkNode_ConditionalShouldMaintain.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\ThinkNode_ConditionalShouldMaintain.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_SwarmMaintain\\ThinkNode_ConditionalShouldMaintain.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAACgAAAAaAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T16:12:54.594Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 1,
+ "Title": "JobGiver_SwarmMaintain.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\JobGiver_SwarmMaintain.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_SwarmMaintain\\JobGiver_SwarmMaintain.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\JobGiver_SwarmMaintain.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_SwarmMaintain\\JobGiver_SwarmMaintain.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAABoAAABJAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T16:12:41.767Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 0,
+ "Title": "Comp_SwarmMaintenance.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
+ "RelativeDocumentMoniker": "Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
+ "RelativeToolTip": "Building_Comps\\ARA_SwarmMaintenance\\Comp_SwarmMaintenance.cs",
+ "ViewState": "AgIAAMAAAAAAAAAAAAAawO8AAAAJAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T15:54:30.103Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 3,
+ "Title": "JobDriver_SwarmMaintain.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_SwarmMaintain\\JobDriver_SwarmMaintain.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T15:53:54.994Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 7,
+ "Title": "ThinkNode_ConditionalShouldFollowProducer.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalShouldFollowProducer.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalShouldFollowProducer.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalShouldFollowProducer.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_FollowProducer\\ThinkNode_ConditionalShouldFollowProducer.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAA6AAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:56:35.323Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 5,
+ "Title": "JobGiver_AIFollowProducer.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\JobGiver_AIFollowProducer.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_FollowProducer\\JobGiver_AIFollowProducer.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\JobGiver_AIFollowProducer.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_FollowProducer\\JobGiver_AIFollowProducer.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAwAAAA+AAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:52:34.404Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 4,
+ "Title": "JobGiver_AIDefendProducer.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\JobGiver_AIDefendProducer.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_FollowProducer\\JobGiver_AIDefendProducer.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\JobGiver_AIDefendProducer.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_FollowProducer\\JobGiver_AIDefendProducer.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAsAAAA3AAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:51:04.617Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 6,
+ "Title": "JobGiver_WanderNearProducer.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\JobGiver_WanderNearProducer.cs",
+ "RelativeDocumentMoniker": "Jobs\\JobDriver_FollowProducer\\JobGiver_WanderNearProducer.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Jobs\\JobDriver_FollowProducer\\JobGiver_WanderNearProducer.cs",
+ "RelativeToolTip": "Jobs\\JobDriver_FollowProducer\\JobGiver_WanderNearProducer.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAYAAAAsAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:50:24.931Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 9,
+ "Title": "PawnProductionEntry.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\PawnProductionEntry.cs",
+ "RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\PawnProductionEntry.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\PawnProductionEntry.cs",
+ "RelativeToolTip": "Pawn_Comps\\ARA_AutoMechCarrier\\PawnProductionEntry.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAADwvwgAAAAkAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:47:44.722Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 8,
+ "Title": "CompAutoMechCarrier.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "RelativeDocumentMoniker": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "RelativeToolTip": "Pawn_Comps\\ARA_AutoMechCarrier\\CompAutoMechCarrier.cs",
+ "ViewState": "AgIAAAwAAAAAAAAAAAASwFkAAAAlAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:44:47.737Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 10,
+ "Title": "Building_DormancyVat.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
+ "RelativeDocumentMoniker": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
+ "RelativeToolTip": "Buildings\\Building_DormancyVat\\Building_DormancyVat.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAADwvxcAAAAPAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:04:41.67Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 11,
+ "Title": "DefModExtension_DormancyVat.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\DefModExtension_DormancyVat.cs",
+ "RelativeDocumentMoniker": "Buildings\\Building_DormancyVat\\DefModExtension_DormancyVat.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Buildings\\Building_DormancyVat\\DefModExtension_DormancyVat.cs",
+ "RelativeToolTip": "Buildings\\Building_DormancyVat\\DefModExtension_DormancyVat.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAADwvwYAAAAFAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T14:04:36.507Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 14,
+ "Title": "HediffCompProperties_GestaltNode.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffCompProperties_GestaltNode.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\HediffCompProperties_GestaltNode.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffCompProperties_GestaltNode.cs",
+ "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\HediffCompProperties_GestaltNode.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T11:47:43.89Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 15,
+ "Title": "PawnRelationWorker_GestaltOverseer.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\PawnRelationWorker_GestaltOverseer.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\PawnRelationWorker_GestaltOverseer.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\PawnRelationWorker_GestaltOverseer.cs",
+ "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\PawnRelationWorker_GestaltOverseer.cs",
+ "ViewState": "AgIAAEwAAAAAAAAAAAAAAF8AAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T11:37:58.614Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 12,
+ "Title": "ARA_HediffDefOf.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
+ "RelativeDocumentMoniker": "ARA_HediffDefOf.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\ARA_HediffDefOf.cs",
+ "RelativeToolTip": "ARA_HediffDefOf.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T10:50:55.466Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 17,
+ "Title": "CompProperties_Gestalt.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\CompProperties_Gestalt.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\CompProperties_Gestalt.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\CompProperties_Gestalt.cs",
+ "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\CompProperties_Gestalt.cs",
+ "ViewState": "AgIAAAAAAAAAAAAAAADwvwAAAAAAAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T11:27:21.969Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 16,
+ "Title": "GestaltBandwidthGizmo.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
+ "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
+ "ViewState": "AgIAABcAAAAAAAAAAAAUwCcAAAASAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T11:26:55.936Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 13,
+ "Title": "Pawn_GestaltTracker.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\Pawn_GestaltTracker.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\Pawn_GestaltTracker.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\Pawn_GestaltTracker.cs",
+ "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\Pawn_GestaltTracker.cs",
+ "ViewState": "AgIAAM0AAAAAAAAAAAD4v/QAAAAJAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T10:50:46.244Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 20,
+ "Title": "HediffComp_GestaltNode.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
+ "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
+ "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\HediffComp_GestaltNode.cs",
+ "ViewState": "AgIAAG8AAAAAAAAAAAAhwIsAAABBAAAAAAAAAA==",
+ "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
+ "WhenOpened": "2026-01-20T08:24:06.173Z",
+ "EditorCaption": ""
+ },
+ {
+ "$type": "Document",
+ "DocumentIndex": 19,
"Title": "GestaltControlGroup.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroup.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroup.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\GestaltControlGroup.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroup.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroup.cs",
"RelativeToolTip": "Hediffs\\ARA_GestaltNode\\GestaltControlGroup.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
@@ -60,29 +362,16 @@
},
{
"$type": "Document",
- "DocumentIndex": 3,
+ "DocumentIndex": 18,
"Title": "GestaltControlGroupGizmo.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroupGizmo.cs",
+ "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroupGizmo.cs",
"RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\GestaltControlGroupGizmo.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroupGizmo.cs",
+ "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltControlGroupGizmo.cs",
"RelativeToolTip": "Hediffs\\ARA_GestaltNode\\GestaltControlGroupGizmo.cs",
- "ViewState": "AgIAAEAAAAAAAAAAAAAUwCwAAABBAAAAAAAAAA==",
+ "ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAABLAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2026-01-20T07:59:09.365Z",
"EditorCaption": ""
- },
- {
- "$type": "Document",
- "DocumentIndex": 1,
- "Title": "GestaltBandwidthGizmo.cs",
- "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
- "RelativeDocumentMoniker": "Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
- "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
- "RelativeToolTip": "Hediffs\\ARA_GestaltNode\\GestaltBandwidthGizmo.cs",
- "ViewState": "AgIAAAAAAAAAAAAAAAAuwBMAAAA2AAAAAAAAAA==",
- "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
- "WhenOpened": "2026-01-20T07:59:08.824Z",
- "EditorCaption": ""
}
]
}
diff --git a/Source/ArachnaeSwarm/ARA_HediffDefOf.cs b/Source/ArachnaeSwarm/ARA_HediffDefOf.cs
index 267eaa0..f18e10c 100644
--- a/Source/ArachnaeSwarm/ARA_HediffDefOf.cs
+++ b/Source/ArachnaeSwarm/ARA_HediffDefOf.cs
@@ -8,8 +8,9 @@ namespace ArachnaeSwarm
{
public static HediffDef ARA_HiveMindMaster;
public static HediffDef ARA_HiveMindDrone;
- public static HediffDef ARA_HiveMindWorker; // 如果存在这个Def
-
+ public static HediffDef ARA_HiveMindWorker;
+ public static HediffDef ARA_GestaltNetworkOverload;
+
static ARA_HediffDefOf()
{
DefOfHelper.EnsureInitializedInCtor(typeof(ARA_HediffDefOf));
@@ -62,4 +63,14 @@ namespace ArachnaeSwarm
}
}
-}
+ [DefOf]
+ public static class ARA_ThoughtDefOf
+ {
+ //public static ThoughtDef ARA_GestaltNetworkOverload;
+
+ static ARA_ThoughtDefOf()
+ {
+ DefOfHelper.EnsureInitializedInCtor(typeof(ARA_ThoughtDefOf));
+ }
+ }
+}
\ No newline at end of file
diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
index 8154645..004557d 100644
--- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
+++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj
@@ -35,8 +35,6 @@
-
-
..\..\..\..\..\..\workshop\content\294100\2009463077\1.5\Assemblies\0Harmony.dll
False
@@ -77,7 +75,359 @@
..\..\..\..\..\..\common\RimWorld\RimWorldWin64_Data\Managed\UnityEngine.TextRenderingModule.dll
False
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Source/ArachnaeSwarm/Building_Comps/ARA_SwarmMaintenance/Comp_SwarmMaintenance.cs b/Source/ArachnaeSwarm/Building_Comps/ARA_SwarmMaintenance/Comp_SwarmMaintenance.cs
index 14e3f31..76d0a23 100644
--- a/Source/ArachnaeSwarm/Building_Comps/ARA_SwarmMaintenance/Comp_SwarmMaintenance.cs
+++ b/Source/ArachnaeSwarm/Building_Comps/ARA_SwarmMaintenance/Comp_SwarmMaintenance.cs
@@ -166,19 +166,22 @@ namespace ArachnaeSwarm
currentMaintenance = MaxMaintenance;
lastWarningState = false;
}
-
+
// 手动呼叫最近的维护者
public void CallMaintainer()
{
if (parent.Map == null) return;
-
Pawn bestPawn = null;
float minDist = float.MaxValue;
+ // 创建包含所有可能维护者的列表
+ List allPossibleMaintainers = new List();
+ allPossibleMaintainers.AddRange(parent.Map.mapPawns.FreeColonistsSpawned);
+ allPossibleMaintainers.AddRange(parent.Map.mapPawns.SpawnedColonyAnimals);
- foreach (Pawn pawn in parent.Map.mapPawns.FreeColonistsSpawned)
+ foreach (Pawn pawn in allPossibleMaintainers)
{
var maintainerComp = pawn.TryGetComp();
- if (maintainerComp != null && !pawn.Downed && !pawn.Dead &&
+ if (maintainerComp != null && !pawn.Downed && !pawn.Dead &&
pawn.CanReserveAndReach(parent, PathEndMode.Touch, Danger.Some))
{
float dist = pawn.Position.DistanceToSquared(parent.Position);
@@ -189,7 +192,6 @@ namespace ArachnaeSwarm
}
}
}
-
if (bestPawn != null)
{
Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_SwarmMaintain, parent);
@@ -231,7 +233,7 @@ namespace ArachnaeSwarm
// 显示警告信息
if (IsCritical)
{
- text += "\n" + "ARA_SwarmMaintenance.CriticalLevel".Translate() + "";
+ text += "\n" + "ARA_SwarmMaintenance_TooltipCritical".Translate() + "";
}
return text;
diff --git a/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/Building_CorpseVat.cs b/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/Building_CorpseVat.cs
new file mode 100644
index 0000000..f9755cc
--- /dev/null
+++ b/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/Building_CorpseVat.cs
@@ -0,0 +1,356 @@
+using RimWorld;
+using System.Collections.Generic;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class Building_CorpseContainer : Building_Enterable, IThingHolder, ISuspendableThingHolder
+ {
+ private ThingOwner corpseContainer;
+ private Corpse storedCorpse;
+
+ // 公开接口:查询是否有尸体
+ public bool HasCorpse => corpseContainer.Any;
+
+ // 公开接口:获取存储的尸体(如果存在)
+ public Corpse StoredCorpse => storedCorpse;
+
+ // 公开接口:获取所有存储的物体(用于兼容性)
+ public IEnumerable StoredThings => corpseContainer;
+
+ // 公开接口:获取尸体数量
+ public int CorpseCount => corpseContainer.Count;
+
+ public Building_CorpseContainer()
+ {
+ corpseContainer = new ThingOwner(this);
+ }
+
+ public override AcceptanceReport CanAcceptPawn(Pawn p)
+ {
+ // 这个建筑不接受活人,只接受尸体
+ // 实际上我们通过特殊方式处理尸体
+ return "CorpseContainer_OnlyAcceptsCorpses".Translate();
+ }
+
+ public override void TryAcceptPawn(Pawn p)
+ {
+ // 不接受活人
+ Messages.Message("CorpseContainer_CannotAcceptLivingPawn".Translate(p.LabelShort), MessageTypeDefOf.RejectInput);
+ }
+
+ ///
+ /// 尝试接收尸体
+ ///
+ public AcceptanceReport TryAcceptCorpse(Corpse corpse)
+ {
+ if (corpse == null || corpse.Destroyed)
+ return false;
+
+ if (corpseContainer.Count >= GetMaxCapacity())
+ {
+ return "CorpseContainer_Full".Translate();
+ }
+
+ // 检查是否已经包含了这个尸体
+ if (corpseContainer.Contains(corpse))
+ {
+ return "CorpseContainer_AlreadyContainsCorpse".Translate(corpse.LabelShort);
+ }
+
+ // 尝试将尸体放入容器
+ bool success = false;
+
+ if (corpse.Spawned)
+ {
+ corpse.DeSpawn();
+ success = corpseContainer.TryAdd(corpse, true);
+ }
+ else
+ {
+ success = corpseContainer.TryAdd(corpse, true);
+ }
+
+ if (success)
+ {
+ storedCorpse = corpse;
+ OnCorpseAdded(corpse);
+ return true;
+ }
+
+ return "CorpseContainer_FailedToAddCorpse".Translate(corpse.LabelShort);
+ }
+
+ ///
+ /// 移除尸体
+ ///
+ public bool TryRemoveCorpse(Corpse corpse)
+ {
+ if (corpse == null || !corpseContainer.Contains(corpse))
+ return false;
+
+ bool removed = corpseContainer.TryRemove(corpse);
+ if (removed)
+ {
+ if (storedCorpse == corpse)
+ storedCorpse = null;
+
+ OnCorpseRemoved(corpse);
+ TryDropCorpseAt(corpse, Position, Map);
+ }
+
+ return removed;
+ }
+
+ ///
+ /// 清空容器
+ ///
+ public void ClearContainer()
+ {
+ List corpsesToRemove = new List(corpseContainer);
+
+ foreach (Corpse corpse in corpsesToRemove)
+ {
+ TryRemoveCorpse(corpse);
+ }
+
+ storedCorpse = null;
+ }
+
+ ///
+ /// 获取最大容量
+ ///
+ public virtual int GetMaxCapacity()
+ {
+ // 默认容量为1,可以在XML中通过扩展属性修改
+ var extension = def.GetModExtension();
+ return extension?.maxCapacity ?? 1;
+ }
+
+ ///
+ /// 尸体添加时的回调
+ ///
+ protected virtual void OnCorpseAdded(Corpse corpse)
+ {
+ // 可以在这里添加音效、视觉效果等
+ // SoundDefOf.ThingInstalled.PlayOneShot(new TargetInfo(Position, Map));
+ }
+
+ ///
+ /// 尸体移除时的回调
+ ///
+ protected virtual void OnCorpseRemoved(Corpse corpse)
+ {
+ // 可以在这里添加音效、视觉效果等
+ // SoundDefOf.ThingUninstalled.PlayOneShot(new TargetInfo(Position, Map));
+ }
+
+ ///
+ /// 尝试在指定位置放置尸体
+ ///
+ protected virtual bool TryDropCorpseAt(Corpse corpse, IntVec3 dropLoc, Map map)
+ {
+ if (corpse == null || map == null)
+ return false;
+
+ // 尝试在交互单元格放置
+ IntVec3 targetCell = InteractionCell;
+
+ // 如果交互单元格被阻挡,尝试附近的单元格
+ if (!targetCell.Walkable(map) || targetCell.GetEdifice(map) != null)
+ {
+ targetCell = GenAdj.CellsAdjacent8Way(this).RandomElement();
+ }
+
+ // 确保目标单元格可通行
+ if (!targetCell.Walkable(map))
+ {
+ targetCell = Position; // 如果都不行,放在建筑自己的位置
+ }
+
+ // 放置尸体
+ bool placed = GenPlace.TryPlaceThing(corpse, targetCell, map, ThingPlaceMode.Near);
+
+ if (!placed)
+ {
+ // 如果还是失败,尝试直接生成
+ corpse.SpawnSetup(map, false);
+ }
+
+ return placed;
+ }
+
+ ///
+ /// 获取Gizmos
+ ///
+ public override IEnumerable GetGizmos()
+ {
+ foreach (Gizmo gizmo in base.GetGizmos())
+ {
+ yield return gizmo;
+ }
+
+ // 清空按钮
+ if (corpseContainer.Any)
+ {
+ Command_Action clearCommand = new Command_Action
+ {
+ defaultLabel = "CorpseContainer_Clear".Translate(),
+ defaultDesc = "CorpseContainer_ClearDesc".Translate(),
+ icon = TexCommand.ClearPrioritizedWork,
+ action = ClearContainer
+ };
+
+ yield return clearCommand;
+ }
+
+ // 取出特定尸体的按钮(如果有多个尸体)
+ if (corpseContainer.Count > 1)
+ {
+ Command_Action removeSpecificCommand = new Command_Action
+ {
+ defaultLabel = "CorpseContainer_RemoveSpecific".Translate(),
+ defaultDesc = "CorpseContainer_RemoveSpecificDesc".Translate(),
+ icon = TexCommand.RemoveFromContainer,
+ action = () =>
+ {
+ List options = new List();
+
+ foreach (Corpse corpse in corpseContainer)
+ {
+ options.Add(new FloatMenuOption(
+ corpse.LabelCap,
+ () => TryRemoveCorpse(corpse),
+ corpse.InnerPawn?.RaceProps?.FleshType?.IconTex() ?? BaseContent.BadTex,
+ Color.white
+ ));
+ }
+
+ if (options.Any())
+ {
+ Find.WindowStack.Add(new FloatMenu(options));
+ }
+ }
+ };
+
+ yield return removeSpecificCommand;
+ }
+ }
+
+ ///
+ /// 获取浮动菜单选项
+ ///
+ public override IEnumerable GetFloatMenuOptions(Pawn selPawn)
+ {
+ foreach (FloatMenuOption option in base.GetFloatMenuOptions(selPawn))
+ {
+ yield return option;
+ }
+
+ // 添加"存储尸体"选项
+ if (selPawn.CanReach(this, PathEndMode.InteractionCell, Danger.Deadly))
+ {
+ // 查找附近可搬运的尸体
+ foreach (Thing thing in GenAdj.CellsAdjacent8Way(this)
+ .SelectMany(cell => cell.GetThingList(Map))
+ .Distinct())
+ {
+ if (thing is Corpse corpse && corpse.InnerPawn != null)
+ {
+ yield return new FloatMenuOption(
+ "CorpseContainer_StoreCorpse".Translate(corpse.LabelCap),
+ () =>
+ {
+ // 创建搬运工作
+ Job job = JobMaker.MakeJob(JobDefOf.HaulCorpseToContainer, corpse, this);
+ job.count = 1;
+ selPawn.jobs.TryTakeOrderedJob(job, JobTag.MiscWork);
+ },
+ MenuOptionPriority.Default,
+ null,
+ corpse
+ );
+ }
+ }
+ }
+ }
+
+ ///
+ /// 获取检查字符串
+ ///
+ public override string GetInspectString()
+ {
+ string baseString = base.GetInspectString();
+
+ string corpseInfo = string.Empty;
+
+ if (corpseContainer.Any)
+ {
+ int count = corpseContainer.Count;
+ int max = GetMaxCapacity();
+
+ corpseInfo = "CorpseContainer_Contains".Translate(count, max);
+
+ if (count == 1 && storedCorpse != null)
+ {
+ corpseInfo += ": " + storedCorpse.LabelCap;
+
+ // 显示尸体的信息
+ Pawn innerPawn = storedCorpse.InnerPawn;
+ if (innerPawn != null)
+ {
+ corpseInfo += " (" + innerPawn.KindLabel + ")";
+ }
+ }
+ }
+ else
+ {
+ corpseInfo = "CorpseContainer_Empty".Translate();
+ }
+
+ if (!string.IsNullOrEmpty(baseString))
+ return baseString + "\n" + corpseInfo;
+ else
+ return corpseInfo;
+ }
+
+ ///
+ /// 保存数据
+ ///
+ public override void ExposeData()
+ {
+ base.ExposeData();
+
+ Scribe_Deep.Look(ref corpseContainer, "corpseContainer", this);
+ Scribe_References.Look(ref storedCorpse, "storedCorpse");
+
+ if (Scribe.mode == LoadSaveMode.PostLoadInit)
+ {
+ // 确保storedCorpse是最新存储的尸体
+ if (corpseContainer.Any && storedCorpse == null)
+ {
+ storedCorpse = corpseContainer[0];
+ }
+ else if (storedCorpse != null && !corpseContainer.Contains(storedCorpse))
+ {
+ storedCorpse = corpseContainer.Any ? corpseContainer[0] : null;
+ }
+ }
+ }
+
+ ///
+ /// 销毁时处理
+ ///
+ public override void DeSpawn(DestroyMode mode = DestroyMode.Vanish)
+ {
+ if (mode != DestroyMode.WillReplace)
+ {
+ // 将尸体全部弹出
+ corpseContainer.TryDropAll(Position, Map, ThingPlaceMode.Near);
+ }
+
+ base.DeSpawn(mode);
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/DefModExtension_CorpseContainer.cs b/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/DefModExtension_CorpseContainer.cs
new file mode 100644
index 0000000..523b22b
--- /dev/null
+++ b/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/DefModExtension_CorpseContainer.cs
@@ -0,0 +1,22 @@
+using Verse;
+
+namespace ArachnaeSwarm
+{
+ public class DefModExtension_CorpseContainer : DefModExtension
+ {
+ // 最大容量
+ public int maxCapacity = 1;
+
+ // 是否允许存储非人类尸体
+ public bool allowNonHumanCorpses = true;
+
+ // 是否允许存储腐烂的尸体
+ public bool allowRottingCorpses = true;
+
+ // 是否自动保鲜(防止腐烂)
+ public bool preserveCorpses = false;
+
+ // 自定义存储效果描述
+ public string storageEffectDescriptionKey;
+ }
+}
diff --git a/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/JobDriver_HaulCorpseToContainer.cs b/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/JobDriver_HaulCorpseToContainer.cs
new file mode 100644
index 0000000..329f0c9
--- /dev/null
+++ b/Source/ArachnaeSwarm/Buildings/Building_CorpseVat/JobDriver_HaulCorpseToContainer.cs
@@ -0,0 +1,64 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class JobDriver_HaulCorpseToContainer : JobDriver
+ {
+ private const TargetIndex CorpseIndex = TargetIndex.A;
+ private const TargetIndex ContainerIndex = TargetIndex.B;
+ private const TargetIndex StoreCellIndex = TargetIndex.C;
+
+ private Corpse Corpse => (Corpse)job.GetTarget(CorpseIndex).Thing;
+ private Building_CorpseContainer Container => (Building_CorpseContainer)job.GetTarget(ContainerIndex).Thing;
+
+ public override bool TryMakePreToilReservations(bool errorOnFailed)
+ {
+ return pawn.Reserve(Corpse, job, 1, -1, null, errorOnFailed) &&
+ pawn.Reserve(Container, job, 1, -1, null, errorOnFailed);
+ }
+
+ protected override IEnumerable MakeNewToils()
+ {
+ // 验证目标
+ this.FailOnDestroyedOrNull(CorpseIndex);
+ this.FailOnDestroyedOrNull(ContainerIndex);
+ this.FailOnForbidden(CorpseIndex);
+ this.FailOnForbidden(ContainerIndex);
+
+ // 前往尸体
+ yield return Toils_Goto.GotoThing(CorpseIndex, PathEndMode.Touch)
+ .FailOnSomeonePhysicallyInteracting(CorpseIndex);
+
+ // 捡起尸体
+ yield return Toils_Haul.StartCarryThing(CorpseIndex);
+
+ // 前往容器
+ yield return Toils_Goto.GotoThing(ContainerIndex, PathEndMode.InteractionCell);
+
+ // 存储尸体到容器
+ Toil storeToil = new Toil();
+ storeToil.initAction = delegate
+ {
+ if (pawn.carryTracker.CarriedThing is Corpse carriedCorpse)
+ {
+ AcceptanceReport report = Container.TryAcceptCorpse(carriedCorpse);
+
+ if (report.Accepted)
+ {
+ // 尸体已成功存储,清空搬运
+ pawn.carryTracker.innerContainer.Clear();
+ }
+ else
+ {
+ // 存储失败,结束工作
+ EndJobWith(JobCondition.Incompletable);
+ }
+ }
+ };
+ storeToil.defaultCompleteMode = ToilCompleteMode.Instant;
+ yield return storeToil;
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/GestaltBandwidthGizmo.cs b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/GestaltBandwidthGizmo.cs
index bd312b6..1a7a792 100644
--- a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/GestaltBandwidthGizmo.cs
+++ b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/GestaltBandwidthGizmo.cs
@@ -19,12 +19,12 @@ namespace ArachnaeSwarm
public override float GetWidth(float maxWidth)
{
- return 140f;
+ return 160f; // 稍微加宽以显示更多信息
}
public override GizmoResult GizmoOnGUI(Vector2 topLeft, float maxWidth, GizmoRenderParms parms)
{
- Rect rect = new Rect(topLeft.x, topLeft.y, GetWidth(maxWidth), 75f);
+ Rect rect = new Rect(topLeft.x, topLeft.y, GetWidth(maxWidth), 75f); // 增加高度以容纳超载信息
Rect rect2 = rect.ContractedBy(6f);
// 背景
@@ -39,13 +39,29 @@ namespace ArachnaeSwarm
// 带宽条
Rect barRect = new Rect(rect2.x, rect2.y + 20f, rect2.width, 20f);
- float fillPercent = (float)tracker.UsedBandwidth / tracker.TotalBandwidth;
- Widgets.FillableBar(barRect, fillPercent, SolidColorMaterials.NewSolidColorTexture(new Color(0.2f, 0.6f, 0.8f)));
+ float fillPercent = tracker.TotalBandwidth > 0 ?
+ Mathf.Clamp01((float)tracker.UsedBandwidth / tracker.TotalBandwidth) :
+ 1f;
+
+ // 超载时使用红色,否则使用蓝色
+ Color barColor = tracker.IsNetworkOverloaded() ?
+ new Color(0.8f, 0.2f, 0.2f) : // 红色
+ new Color(0.2f, 0.6f, 0.8f); // 蓝色
+
+ Widgets.FillableBar(barRect, fillPercent, SolidColorMaterials.NewSolidColorTexture(barColor));
// 带宽文本
Text.Font = GameFont.Small;
Text.Anchor = TextAnchor.MiddleCenter;
- string bandwidthText = $"{tracker.UsedBandwidth}/{tracker.TotalBandwidth}";
+ string bandwidthText = tracker.IsNetworkOverloaded() ?
+ $"{tracker.UsedBandwidth}/{tracker.TotalBandwidth} (+{tracker.NetworkOverload})" :
+ $"{tracker.UsedBandwidth}/{tracker.TotalBandwidth}";
+
+ if (tracker.TotalBandwidth <= 0)
+ {
+ bandwidthText = $"{tracker.UsedBandwidth} (∞)";
+ }
+
Widgets.Label(barRect, bandwidthText);
// 控制组数量
@@ -64,9 +80,10 @@ namespace ArachnaeSwarm
TooltipHandler.TipRegion(rect, () =>
{
string tip = "ARA_GestaltBandwidthTip".Translate(tracker.UsedBandwidth, tracker.TotalBandwidth);
- tip += $"\n\n{"ARA_GestaltGroup".Translate()}: {tracker.ControlGroups.Count}/{tracker.TotalAvailableControlGroups}";
-
- if (tracker.UsedBandwidth > tracker.TotalBandwidth)
+ int availableBandwidth = Mathf.Max(0, tracker.TotalBandwidth - tracker.UsedBandwidth);
+ tip += $"\n\n{"ARA_AvailableBandwidth".Translate(availableBandwidth)}";
+
+ if (tracker.IsNetworkOverloaded())
{
tip += $"\n\n{"ARA_GestaltBandwidthExceeded".Translate()}".Colorize(Color.red);
}
diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs
index 7dcb654..023f31e 100644
--- a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs
+++ b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/HediffComp_GestaltNode.cs
@@ -43,7 +43,7 @@ namespace ArachnaeSwarm
if (tracker == null && NodeType == GestaltNodeType.OverlordNode)
{
- tracker = new Pawn_GestaltTracker(Pawn);
+ tracker = new Pawn_GestaltTracker();
}
return tracker;
}
diff --git a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/Pawn_GestaltTracker.cs b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/Pawn_GestaltTracker.cs
index fa6af55..a78377f 100644
--- a/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/Pawn_GestaltTracker.cs
+++ b/Source/ArachnaeSwarm/Hediffs/ARA_GestaltNode/Pawn_GestaltTracker.cs
@@ -5,20 +5,43 @@ using System.Linq;
using UnityEngine;
using Verse;
-namespace ArachnaeSwarm {
+namespace ArachnaeSwarm
+{
public class Pawn_GestaltTracker : IExposable
{
private Pawn pawn;
private List controlGroups = new List();
private List controlledPawns = new List();
+
+ // 添加网络超载相关字段
+ private int currentOverloadLevel = 0;
+ private int ticksSinceLastOverloadCheck = 0;
+ private const int OVERLOAD_CHECK_INTERVAL = 60; // 每60tick检查一次
+
+ // 超载Hediff相关字段
+ private Hediff networkOverloadHediff;
+ private int ticksSinceLastHediffUpdate = 0;
+ private const int HEDIFF_UPDATE_INTERVAL = 120; // 每120tick更新一次Hediff严重性
+ // 公开属性
public Pawn Pawn => pawn;
public List ControlGroups => controlGroups;
public List ControlledPawns => controlledPawns;
-
+
+ // 计算已使用的带宽(包括超载部分)
public int UsedBandwidth => (int)ControlledPawns.Sum(p => p.GetStatValue(StatDefOf.BandwidthCost));
+
+ // 计算基础带宽限制
public int TotalBandwidth => (int)pawn.GetStatValue(StatDefOf.MechBandwidth);
+
+ // 计算总可用控制组
public int TotalAvailableControlGroups => (int)pawn.GetStatValue(StatDefOf.MechControlGroups);
+
+ // 计算网络超载程度(超出带宽的部分)
+ public int NetworkOverload => Mathf.Max(0, UsedBandwidth - TotalBandwidth);
+
+ // 获取当前超载层数
+ public int CurrentOverloadLevel => currentOverloadLevel;
public AcceptanceReport CanControlPawns
{
@@ -46,11 +69,15 @@ namespace ArachnaeSwarm {
public bool CanControlPawn(Pawn targetPawn)
{
+ // 移除带宽检查,允许超载连接
if (targetPawn.GetOverlord() != null)
return false;
- float bandwidthCost = targetPawn.GetStatValue(StatDefOf.BandwidthCost);
- return UsedBandwidth + bandwidthCost <= TotalBandwidth;
+ // 检查是否在同一地图
+ if (pawn.Map != null && targetPawn.Map != null && pawn.Map != targetPawn.Map)
+ return false;
+
+ return true;
}
public GestaltControlGroup GetControlGroup(Pawn targetPawn)
@@ -78,13 +105,19 @@ namespace ArachnaeSwarm {
// 分配到第一个可用的控制组
controlGroups[0].Assign(targetPawn);
Notify_BandwidthChanged();
+ UpdateNetworkOverload();
}
public void UnassignPawnFromAnyControlGroup(Pawn targetPawn)
{
foreach (GestaltControlGroup group in controlGroups)
{
- group.TryUnassign(targetPawn);
+ if (group.TryUnassign(targetPawn))
+ {
+ Notify_BandwidthChanged();
+ UpdateNetworkOverload();
+ break;
+ }
}
}
@@ -98,24 +131,27 @@ namespace ArachnaeSwarm {
controlGroups.Add(new GestaltControlGroup(this));
}
- // 移除多余的控制组
- while (controlGroups.Count > availableGroups)
+ // 移除多余的控制组(但如果有超载连接,可以保留额外的组)
+ if (!IsNetworkOverloaded())
{
- GestaltControlGroup groupToRemove = controlGroups[controlGroups.Count - 1];
-
- if (!groupToRemove.AssignedPawns.NullOrEmpty())
+ while (controlGroups.Count > availableGroups)
{
- // 将pawn重新分配到其他组
- foreach (Pawn pawn in groupToRemove.AssignedPawns)
+ GestaltControlGroup groupToRemove = controlGroups[controlGroups.Count - 1];
+
+ if (!groupToRemove.AssignedPawns.NullOrEmpty())
{
- if (controlGroups.Count > 1)
+ // 将pawn重新分配到其他组
+ foreach (Pawn pawn in groupToRemove.AssignedPawns)
{
- controlGroups[0].Assign(pawn);
+ if (controlGroups.Count > 1)
+ {
+ controlGroups[0].Assign(pawn);
+ }
}
}
- }
- controlGroups.RemoveAt(controlGroups.Count - 1);
+ controlGroups.RemoveAt(controlGroups.Count - 1);
+ }
}
}
@@ -129,28 +165,113 @@ namespace ArachnaeSwarm {
controlledPawns.AddRange(group.AssignedPawns.Where(p => !controlledPawns.Contains(p)));
}
- // 检查带宽限制,移除超出带宽的pawn
- List toRemove = new List();
- float currentBandwidth = 0f;
+ // 不再自动断开超出带宽的连接
+ UpdateNetworkOverload();
+ }
- foreach (Pawn controlledPawn in controlledPawns)
+ public void UpdateNetworkOverload()
+ {
+ int newOverloadLevel = NetworkOverload;
+
+ // 如果超载级别发生变化
+ if (newOverloadLevel != currentOverloadLevel)
{
- float cost = controlledPawn.GetStatValue(StatDefOf.BandwidthCost);
- if (currentBandwidth + cost <= TotalBandwidth)
+ int oldLevel = currentOverloadLevel;
+ currentOverloadLevel = newOverloadLevel;
+
+ // 发送消息通知
+ if (currentOverloadLevel > 0 && oldLevel == 0)
{
- currentBandwidth += cost;
+ Messages.Message("ARA_GestaltBandwidthExceeded".Translate(),
+ pawn, MessageTypeDefOf.NegativeEvent);
}
- else
+ else if (currentOverloadLevel == 0 && oldLevel > 0)
{
- toRemove.Add(controlledPawn);
+ Messages.Message("ARA_NetworkOverloadCleared".Translate(pawn.LabelShort),
+ pawn, MessageTypeDefOf.PositiveEvent);
+ // 移除超载Hediff
+ RemoveNetworkOverloadHediff();
}
}
+
+ // 更新Hediff严重性
+ UpdateNetworkOverloadHediff();
+ }
- foreach (Pawn pawnToRemove in toRemove)
+ private void UpdateNetworkOverloadHediff()
+ {
+ if (currentOverloadLevel <= 0)
{
- UnassignPawnFromAnyControlGroup(pawnToRemove);
- pawnToRemove.relations.RemoveDirectRelation(ARA_PawnRelationDefOf.ARA_GestaltOverseer, this.pawn);
+ RemoveNetworkOverloadHediff();
+ return;
}
+
+ // 计算超载百分比
+ float overloadPercentage = 0f;
+ if (TotalBandwidth > 0)
+ {
+ overloadPercentage = (float)currentOverloadLevel / TotalBandwidth;
+ }
+ else
+ {
+ // 如果总带宽为0,则超载100%
+ overloadPercentage = 1.0f;
+ }
+
+ // 确保百分比不超过100%
+ overloadPercentage = Mathf.Clamp01(overloadPercentage);
+
+ // 获取或创建超载Hediff
+ HediffDef overloadHediffDef = ARA_HediffDefOf.ARA_GestaltNetworkOverload;
+ if (overloadHediffDef == null)
+ {
+ Log.Error("ARA_GestaltNetworkOverload hediff def not found!");
+ return;
+ }
+
+ if (networkOverloadHediff == null)
+ {
+ // 添加新的超载Hediff
+ networkOverloadHediff = pawn.health.AddHediff(overloadHediffDef);
+ if (networkOverloadHediff == null)
+ {
+ Log.Error("Failed to add network overload hediff to " + pawn.LabelShort);
+ return;
+ }
+ }
+
+ // 设置Hediff严重性
+ networkOverloadHediff.Severity = overloadPercentage;
+ }
+
+ private void RemoveCriticalOverloadEffects()
+ {
+ HediffDef criticalOverloadDef = ARA_HediffDefOf.ARA_GestaltNetworkOverload;
+ if (criticalOverloadDef != null)
+ {
+ Hediff criticalHediff = pawn.health.hediffSet.GetFirstHediffOfDef(criticalOverloadDef);
+ if (criticalHediff != null)
+ {
+ pawn.health.RemoveHediff(criticalHediff);
+ }
+ }
+ }
+
+ private void RemoveNetworkOverloadHediff()
+ {
+ if (networkOverloadHediff != null)
+ {
+ pawn.health.RemoveHediff(networkOverloadHediff);
+ networkOverloadHediff = null;
+ }
+
+ // 同时移除严重的超载效果
+ RemoveCriticalOverloadEffects();
+ }
+
+ public bool IsNetworkOverloaded()
+ {
+ return currentOverloadLevel > 0;
}
public void Notify_ApparelChanged()
@@ -168,6 +289,33 @@ namespace ArachnaeSwarm {
}
}
+ public void GameComponentTick()
+ {
+ if (pawn == null || pawn.Dead || !pawn.Spawned)
+ return;
+
+ ticksSinceLastOverloadCheck++;
+ if (ticksSinceLastOverloadCheck >= OVERLOAD_CHECK_INTERVAL)
+ {
+ ticksSinceLastOverloadCheck = 0;
+
+ // 定期更新超载状态
+ UpdateNetworkOverload();
+ }
+
+ // 定期更新Hediff严重性
+ ticksSinceLastHediffUpdate++;
+ if (ticksSinceLastHediffUpdate >= HEDIFF_UPDATE_INTERVAL)
+ {
+ ticksSinceLastHediffUpdate = 0;
+
+ if (IsNetworkOverloaded())
+ {
+ UpdateNetworkOverloadHediff();
+ }
+ }
+ }
+
public IEnumerable GetGizmos()
{
yield return new GestaltBandwidthGizmo(this);
@@ -180,15 +328,28 @@ namespace ArachnaeSwarm {
public void ExposeData()
{
+ Scribe_References.Look(ref pawn, "pawn");
Scribe_Collections.Look(ref controlGroups, "controlGroups", LookMode.Deep, this);
Scribe_Collections.Look(ref controlledPawns, "controlledPawns", LookMode.Reference);
+ Scribe_Values.Look(ref currentOverloadLevel, "currentOverloadLevel", 0);
+ Scribe_Values.Look(ref ticksSinceLastOverloadCheck, "ticksSinceLastOverloadCheck", 0);
+ Scribe_Values.Look(ref ticksSinceLastHediffUpdate, "ticksSinceLastHediffUpdate", 0);
+
+ // 注意:我们不保存Hediff引用,因为Hediff会在加载时重新添加
if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
- controlledPawns?.RemoveAll(x => x == null);
+ if (controlledPawns == null)
+ controlledPawns = new List();
+ else
+ controlledPawns.RemoveAll(x => x == null);
+
if (controlGroups == null)
controlGroups = new List();
+
+ // 重新连接后更新超载状态
+ UpdateNetworkOverload();
}
}
}
-}
\ No newline at end of file
+}
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_AIDefendProducer.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_AIDefendProducer.cs
new file mode 100644
index 0000000..f38f4ec
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_AIDefendProducer.cs
@@ -0,0 +1,134 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class JobGiver_AIDefendProducer : JobGiver_AIDefendPawn
+ {
+ // 防御半径,可以在thinktree中定义
+ public float defendRadius = 30f;
+ public float extendedDefendRadius = 100f;
+ private bool attackMeleeThreatEvenIfNotHostile;
+
+ // 是否仅防御征召状态的生产者(针对pawn类型生产者)
+ public bool onlyDefendDrafted = true;
+
+ protected override Pawn GetDefendee(Pawn pawn)
+ {
+ // 我们不需要返回Pawn类型的防御者,因为我们实际上防御的是Thing
+ // 但是基类需要Pawn,所以对于非Pawn生产者,我们返回null
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return null;
+
+ Thing producer = producerComp.Producer;
+
+ // 对于Pawn类型生产者,检查是否需要征召状态
+ if (producer is Pawn pawnProducer)
+ {
+ if (onlyDefendDrafted && !pawnProducer.Drafted)
+ return null;
+
+ return pawnProducer;
+ }
+
+ return null;
+ }
+
+ protected override float GetFlagRadius(Pawn pawn)
+ {
+ // 如果没有有效的生产者,返回默认半径
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return defendRadius;
+
+ // 如果生产者是建筑,使用扩展防御半径
+ if (producerComp.Producer is Building)
+ return extendedDefendRadius;
+
+ return defendRadius;
+ }
+
+ // 重写以支持非Pawn生产者
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return null;
+
+ Thing producer = producerComp.Producer;
+ if (producer == null || producer.Destroyed)
+ return null;
+
+ // 对于Pawn类型生产者,检查是否需要征召状态
+ if (producer is Pawn pawnProducer && onlyDefendDrafted)
+ {
+ if (!pawnProducer.Drafted)
+ return null;
+ }
+
+ // 如果生产者在战斗中,让pawn参与防御
+ if (producer is Pawn pawnProducer2 && pawnProducer2.InAggroMentalState)
+ {
+ // 使用基类逻辑来防御Pawn类型生产者
+ return base.TryGiveJob(pawn);
+ }
+
+ // 对于非Pawn生产者或非战斗状态,检查是否需要防御
+ float defendRadiusValue = GetFlagRadius(pawn);
+
+ // 寻找附近的威胁
+ Pawn enemy = FindEnemy(pawn, defendRadiusValue);
+ if (enemy != null)
+ {
+ // 创建攻击工作
+ Job job = JobMaker.MakeJob(JobDefOf.AttackMelee, enemy);
+ job.maxNumMeleeAttacks = 1;
+ job.expiryInterval = 1000;
+ job.checkOverrideOnExpire = true;
+ job.expireRequiresEnemiesNearby = true;
+ return job;
+ }
+
+ return null;
+ }
+
+ private Pawn FindEnemy(Pawn pawn, float radius)
+ {
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return null;
+
+ Thing producer = producerComp.Producer;
+ IntVec3 center = producer.Position;
+
+ return (Pawn)AttackTargetFinder.BestAttackTarget(
+ pawn,
+ TargetScanFlags.NeedLOSToAll,
+ target => target is Pawn p && pawn.HostileTo(p) && p.Spawned && !p.Downed && !p.Dead,
+ 0f,
+ radius,
+ center,
+ float.MaxValue,
+ canBashDoors: false,
+ canTakeTargetsCloserThanEffectiveMinRange: false,
+ canBashFences: false);
+ }
+
+ public override ThinkNode DeepCopy(bool resolve = true)
+ {
+ JobGiver_AIDefendProducer obj = (JobGiver_AIDefendProducer)base.DeepCopy(resolve);
+ obj.attackMeleeThreatEvenIfNotHostile = attackMeleeThreatEvenIfNotHostile;
+ obj.defendRadius = defendRadius;
+ return obj;
+ }
+
+ // 为thinktree提供配置解析
+ public override void ResolveReferences()
+ {
+ base.ResolveReferences();
+ // 可以根据需要在这里初始化字段
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_AIFollowProducer.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_AIFollowProducer.cs
new file mode 100644
index 0000000..59bab68
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_AIFollowProducer.cs
@@ -0,0 +1,125 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+using UnityEngine;
+
+namespace ArachnaeSwarm
+{
+ public class JobGiver_AIFollowProducer : JobGiver_AIFollowPawn
+ {
+ public const float DefaultFollowRadius = 3f;
+ public const float ExtendedFollowRadius = 10f;
+
+ protected override int FollowJobExpireInterval => 200;
+
+ protected override Pawn GetFollowee(Pawn pawn)
+ {
+ // 获取生产者Comp
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return null;
+
+ Thing producer = producerComp.Producer;
+
+ // 如果生产者是Pawn,返回它(但需要检查征召状态)
+ if (producer is Pawn pawnProducer)
+ {
+ // 只在生产者被征召时才返回
+ return pawnProducer.Drafted ? pawnProducer : null;
+ }
+
+ // 对于非Pawn生产者,返回null,我们将使用自定义逻辑
+ return null;
+ }
+
+ protected override float GetRadius(Pawn pawn)
+ {
+ // 如果有特殊需求,可以调整跟随半径
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return DefaultFollowRadius;
+
+ // 如果生产者是建筑,可能需要更大的跟随半径
+ if (producerComp.Producer is Building)
+ return ExtendedFollowRadius;
+
+ return DefaultFollowRadius;
+ }
+
+ // 重写以支持非Pawn生产者
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return null;
+
+ Thing producer = producerComp.Producer;
+
+ // 如果生产者是Pawn,检查征召状态
+ if (producer is Pawn pawnProducer)
+ {
+ // 只在生产者被征召时才跟随
+ if (!pawnProducer.Drafted)
+ return null;
+
+ // 使用基类逻辑
+ return base.TryGiveJob(pawn);
+ }
+
+ // 对于非Pawn生产者,创建自定义跟随逻辑
+ return CreateFollowNonPawnJob(pawn, producer);
+ }
+
+ private Job CreateFollowNonPawnJob(Pawn pawn, Thing producer)
+ {
+ if (producer == null || producer.Destroyed)
+ return null;
+
+ // 检查是否已经在跟随半径内
+ float radius = GetRadius(pawn);
+ if (pawn.Position.DistanceTo(producer.Position) <= radius)
+ {
+ // 已经在范围内,不需要移动
+ return null;
+ }
+
+ // 创建移动到生产者附近的工作
+ IntVec3 targetCell = GetFollowTargetCell(pawn, producer, radius);
+
+ if (!targetCell.IsValid || !pawn.CanReach(targetCell, PathEndMode.OnCell, Danger.Deadly))
+ return null;
+
+ Job job = JobMaker.MakeJob(JobDefOf.Goto, targetCell);
+ job.expiryInterval = FollowJobExpireInterval;
+ job.checkOverrideOnExpire = true;
+ return job;
+ }
+
+ private IntVec3 GetFollowTargetCell(Pawn pawn, Thing producer, float radius)
+ {
+ // 获取生产者位置附近的随机单元格
+ IntVec3 producerPos = producer.Position;
+
+ // 在半径范围内寻找可到达的单元格
+ for (int i = 0; i < 20; i++)
+ {
+ // 修复:正确生成偏移量
+ Vector2 randomOffset = Random.insideUnitCircle * (radius * 0.5f);
+ IntVec3 candidate = producerPos + new IntVec3(Mathf.RoundToInt(randomOffset.x), 0, Mathf.RoundToInt(randomOffset.y));
+
+ if (candidate.InBounds(pawn.Map) &&
+ candidate.Walkable(pawn.Map) &&
+ pawn.CanReach(candidate, PathEndMode.OnCell, Danger.Deadly))
+ {
+ return candidate;
+ }
+ }
+
+ // 如果找不到合适的单元格,返回生产者的交互单元格
+ if (producer is Building building)
+ return building.InteractionCell;
+
+ return producerPos;
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_WanderNearProducer.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_WanderNearProducer.cs
new file mode 100644
index 0000000..652d0c0
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/JobGiver_WanderNearProducer.cs
@@ -0,0 +1,98 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class JobGiver_WanderNearProducer : JobGiver_Wander
+ {
+ public const float DefaultWanderRadius = 5f;
+ public const float ExtendedWanderRadius = 15f;
+
+ public JobGiver_WanderNearProducer()
+ {
+ wanderRadius = DefaultWanderRadius;
+ ticksBetweenWandersRange = new IntRange(125, 200);
+ wanderDestValidator = (Pawn p, IntVec3 c, IntVec3 root) =>
+ {
+ // 检查目标单元格是否有效
+ if (!c.InBounds(p.Map) || !c.Walkable(p.Map))
+ return false;
+
+ // 检查是否在房间内(如果需要)
+ if (MustUseRootRoom(p))
+ {
+ if (root.GetRoom(p.Map) == null)
+ return true;
+
+ return WanderRoomUtility.IsValidWanderDest(p, c, root);
+ }
+
+ return true;
+ };
+ }
+
+ protected override IntVec3 GetWanderRoot(Pawn pawn)
+ {
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return pawn.Position;
+
+ Thing producer = producerComp.Producer;
+
+ // 使用生产者位置作为徘徊根
+ IntVec3 producerPos = producer.Position;
+
+ // 获取最佳徘徊根位置
+ IntVec3 wanderRoot = WanderUtility.BestCloseWanderRoot(producerPos, pawn);
+
+ // 如果找不到合适的徘徊根,返回生产者位置
+ return wanderRoot.IsValid ? wanderRoot : producerPos;
+ }
+
+ protected float GetWanderRadius(Pawn pawn)
+ {
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return DefaultWanderRadius;
+
+ // 如果生产者是建筑,使用更大的徘徊半径
+ if (producerComp.Producer is Building)
+ return ExtendedWanderRadius;
+
+ return DefaultWanderRadius;
+ }
+
+ private bool MustUseRootRoom(Pawn pawn)
+ {
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return false;
+
+ Thing producer = producerComp.Producer;
+
+ // 如果生产者是室内建筑,可能需要限制在房间内
+ if (producer is Building building)
+ {
+ Room room = building.GetRoom();
+ return room != null && !room.PsychologicallyOutdoors;
+ }
+
+ return false;
+ }
+
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ // 先检查是否有有效的生产者
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return null;
+
+ // 更新生产者状态
+ producerComp.TryUpdateProducerStatus();
+
+ // 使用基类逻辑
+ return base.TryGiveJob(pawn);
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/ThinkNode_ConditionalShouldFollowProducer.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/ThinkNode_ConditionalShouldFollowProducer.cs
new file mode 100644
index 0000000..20ae92c
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_FollowProducer/ThinkNode_ConditionalShouldFollowProducer.cs
@@ -0,0 +1,66 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class ThinkNode_ConditionalShouldFollowProducer : ThinkNode_Conditional
+ {
+ protected override bool Satisfied(Pawn pawn)
+ {
+ return ShouldFollowProducer(pawn);
+ }
+
+ public static bool ShouldFollowProducer(Pawn pawn)
+ {
+ if (!pawn.Spawned)
+ return false;
+
+ // 检查是否有生产者Comp
+ CompProducedByMechCarrier producerComp = pawn.TryGetComp();
+ if (producerComp == null || !producerComp.HasValidProducer)
+ return false;
+
+ Thing producer = producerComp.Producer;
+ if (producer == null || producer.Destroyed)
+ return false;
+
+ // 检查生产者是否在同一地图
+ if (producer.Map != pawn.Map)
+ return false;
+
+ // 检查是否可以到达生产者
+ if (!pawn.CanReach(producer, PathEndMode.OnCell, Danger.Deadly))
+ return false;
+
+ // 根据生产者类型决定是否跟随
+ if (producer is Pawn pawnProducer)
+ {
+ // 如果生产者是pawn,则只在征召状态下才跟随
+ // 这是为了模拟原版动物跟随主人的逻辑
+ if (!pawnProducer.Drafted)
+ return false;
+
+ // 可以根据需要添加其他条件,例如:
+ // - 生产者是否在战斗中
+ // - 生产者是否有特定工作标签
+ // 这里我们只检查征召状态,与JobGiver_AIFollowProducer中的逻辑保持一致
+ }
+ else if (producer is Building buildingProducer)
+ {
+ // 如果生产者是建筑,默认跟随
+ // 可以根据需要添加其他条件,例如:
+ // - 建筑是否需要防御
+ // - 建筑是否在工作状态
+ return true;
+ }
+ else
+ {
+ // 对于其他类型的生产者(比如物品),默认不跟随
+ return false;
+ }
+
+ return true;
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_SwarmMaintain/JobGiver_SwarmMaintain.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_SwarmMaintain/JobGiver_SwarmMaintain.cs
new file mode 100644
index 0000000..cb80e61
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_SwarmMaintain/JobGiver_SwarmMaintain.cs
@@ -0,0 +1,131 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+using System.Collections.Generic;
+using System.Linq;
+using UnityEngine;
+
+namespace ArachnaeSwarm
+{
+ public class JobGiver_AIMaintainSwarm : ThinkNode_JobGiver
+ {
+ // 最大搜索半径,可以在thinktree中配置
+ public float maxSearchRadius = 50f;
+
+ // 维护度阈值,低于此值时优先维护
+ public float maintenanceThreshold = 0.3f;
+
+ // 检查间隔
+ private const int CheckInterval = 600; // 10秒
+
+ // 上次检查时间缓存
+ private int lastCheckTick = -99999;
+
+ protected override Job TryGiveJob(Pawn pawn)
+ {
+ // 检查是否有维护者组件
+ var maintainerComp = pawn.TryGetComp();
+ if (maintainerComp == null)
+ return null;
+
+ // 检查冷却时间
+ int currentTick = Find.TickManager.TicksGame;
+ if (currentTick - lastCheckTick < CheckInterval)
+ return null;
+ lastCheckTick = currentTick;
+
+ // 确保pawn处于健康状态
+ if (pawn.Downed || pawn.Dead || !pawn.Spawned)
+ return null;
+
+ // 查找需要维护的建筑
+ Thing target = FindMaintenanceTarget(pawn);
+ if (target == null)
+ return null;
+
+ // 创建维护工作
+ Job job = JobMaker.MakeJob(ARA_JobDefOf.ARA_SwarmMaintain, target);
+ job.expiryInterval = 3000; // 50秒后过期
+ job.checkOverrideOnExpire = true;
+
+ return job;
+ }
+
+ private Thing FindMaintenanceTarget(Pawn pawn)
+ {
+ if (pawn.Map == null)
+ return null;
+
+ // 搜索地图上所有需要维护的建筑
+ List maintenanceBuildings = new List();
+
+ // 使用网格搜索,避免遍历所有建筑
+ CellRect searchRect = CellRect.CenteredOn(pawn.Position, Mathf.CeilToInt(maxSearchRadius));
+ searchRect.ClipInsideMap(pawn.Map);
+
+ // 遍历搜索区域内的所有建筑
+ foreach (IntVec3 cell in searchRect)
+ {
+ if (!cell.InBounds(pawn.Map))
+ continue;
+
+ List things = pawn.Map.thingGrid.ThingsListAt(cell);
+ foreach (Thing thing in things)
+ {
+ // 检查是否为建筑且需要维护
+ if (thing is Building building && !building.Destroyed)
+ {
+ var comp = building.TryGetComp();
+ if (comp != null && comp.NeedsMaintenance)
+ {
+ // 检查是否可以到达
+ if (pawn.CanReach(building, PathEndMode.Touch, Danger.Some))
+ {
+ maintenanceBuildings.Add(building);
+ }
+ }
+ }
+ }
+ }
+
+ if (maintenanceBuildings.Count == 0)
+ return null;
+
+ // 选择最佳目标:维护度最低、距离最近的
+ Thing bestTarget = null;
+ float bestScore = float.MinValue;
+
+ foreach (Thing target in maintenanceBuildings)
+ {
+ var comp = target.TryGetComp();
+ if (comp == null)
+ continue;
+
+ // 计算分数:维护度越低、距离越近,分数越高
+ float maintenancePriority = 1f - comp.MaintenancePercentage; // 维护度越低,优先级越高
+ float distanceFactor = 1f - Mathf.Clamp01(pawn.Position.DistanceTo(target.Position) / maxSearchRadius); // 距离越近,分数越高
+
+ // 对于严重维护的建筑给予额外加分
+ float criticalBonus = comp.IsCritical ? 2f : 1f;
+
+ float score = maintenancePriority * 0.6f + distanceFactor * 0.4f + criticalBonus;
+
+ // 如果分数比当前最佳高,更新最佳目标
+ if (score > bestScore)
+ {
+ bestScore = score;
+ bestTarget = target;
+ }
+ }
+
+ return bestTarget;
+ }
+
+ // 为thinktree提供配置解析
+ public override void ResolveReferences()
+ {
+ base.ResolveReferences();
+ // 可以根据需要在这里初始化字段
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Jobs/JobDriver_SwarmMaintain/ThinkNode_ConditionalShouldMaintain.cs b/Source/ArachnaeSwarm/Jobs/JobDriver_SwarmMaintain/ThinkNode_ConditionalShouldMaintain.cs
new file mode 100644
index 0000000..b07cb4b
--- /dev/null
+++ b/Source/ArachnaeSwarm/Jobs/JobDriver_SwarmMaintain/ThinkNode_ConditionalShouldMaintain.cs
@@ -0,0 +1,113 @@
+using RimWorld;
+using Verse;
+using Verse.AI;
+using System.Collections.Generic;
+using UnityEngine;
+
+namespace ArachnaeSwarm
+{
+ public class ThinkNode_ConditionalShouldMaintain : ThinkNode_Conditional
+ {
+ // 最大维护距离,可以在thinktree中配置
+ public float maxMaintenanceDistance = 50f;
+
+ // 是否只在空闲时执行维护工作
+ public bool onlyWhenIdle = true;
+
+ protected override bool Satisfied(Pawn pawn)
+ {
+ return ShouldMaintainSwarm(pawn);
+ }
+
+ public bool ShouldMaintainSwarm(Pawn pawn)
+ {
+ // 基本检查
+ if (pawn == null || !pawn.Spawned || pawn.Downed || pawn.Dead)
+ return false;
+
+ // 检查是否有维护者组件
+ var maintainerComp = pawn.TryGetComp();
+ if (maintainerComp == null)
+ return false;
+
+ // 检查动物是否在玩家控制下(可选)
+ if (pawn.Faction != Faction.OfPlayer)
+ return false;
+
+ // 检查动物状态
+ if (pawn.InAggroMentalState || pawn.InMentalState)
+ return false;
+
+ // 检查是否在休息或睡眠中
+ if (pawn.CurJob != null && onlyWhenIdle)
+ {
+ // 如果当前有工作且onlyWhenIdle为true,不执行维护
+ // 但某些低优先级工作可以被中断
+ if (!CanInterruptCurrentJob(pawn.CurJob))
+ return false;
+ }
+
+ // 检查附近是否有需要维护的建筑
+ return HasNearbyMaintenanceTarget(pawn);
+ }
+
+ private bool CanInterruptCurrentJob(Job currentJob)
+ {
+ // 定义哪些工作可以被中断
+ //if (currentJob.def == JobDefOf.LayDown ||
+ // currentJob.def == JobDefOf.Wait ||
+ // currentJob.def == JobDefOf.Goto ||
+ // currentJob.def == JobDefOf.GotoWander
+ // )
+ //{
+ // return true;
+ //}
+
+ // 其他工作默认不可中断
+ //return false;
+ return true;
+ }
+
+ private bool HasNearbyMaintenanceTarget(Pawn pawn)
+ {
+ if (pawn.Map == null)
+ return false;
+
+ // 搜索附近需要维护的建筑
+ CellRect searchRect = CellRect.CenteredOn(pawn.Position, Mathf.CeilToInt(maxMaintenanceDistance));
+ searchRect.ClipInsideMap(pawn.Map);
+
+ foreach (IntVec3 cell in searchRect)
+ {
+ if (!cell.InBounds(pawn.Map))
+ continue;
+
+ List things = pawn.Map.thingGrid.ThingsListAt(cell);
+ foreach (Thing thing in things)
+ {
+ if (thing is Building building && !building.Destroyed)
+ {
+ var comp = building.TryGetComp();
+ if (comp != null && comp.NeedsMaintenance)
+ {
+ // 检查是否可以到达
+ if (pawn.CanReach(building, PathEndMode.Touch, Danger.Some))
+ {
+ return true;
+ }
+ }
+ }
+ }
+ }
+
+ return false;
+ }
+
+ // 为thinktree提供配置解析
+ public override void ResolveReferences()
+ {
+ base.ResolveReferences();
+ // 可以根据需要在这里初始化字段
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs
index 312faf0..d550143 100644
--- a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs
+++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompAutoMechCarrier.cs
@@ -1,4 +1,5 @@
using RimWorld;
+using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
@@ -81,9 +82,27 @@ namespace ArachnaeSwarm
{
PawnGenerationRequest request = new PawnGenerationRequest(kind, parent.Faction, PawnGenerationContext.NonPlayer, -1, forceGenerateNewPawn: true);
Pawn pawn = PawnGenerator.GeneratePawn(request);
+
+ // 为pawn添加CompProducedByMechCarrier并初始化
+ var producedComp = pawn.TryGetComp();
+ if (producedComp == null)
+ {
+ // 如果pawn没有这个Comp,添加它
+ var compProps = new CompProperties_ProducedByMechCarrier();
+ compProps.compClass = typeof(CompProducedByMechCarrier);
+ var newComp = (CompProducedByMechCarrier)Activator.CreateInstance(compProps.compClass);
+ newComp.parent = pawn;
+ newComp.props = compProps;
+ pawn.AllComps.Add(newComp);
+ producedComp = newComp;
+ }
+
+ // 初始化生产者信息
+ producedComp.Initialize(parent, this);
+
GenSpawn.Spawn(pawn, parent.Position, parent.Map);
SpawnedPawns.Add(pawn);
-
+
if (parent is Pawn p && p.GetLord() != null)
p.GetLord().AddPawn(pawn);
diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs
new file mode 100644
index 0000000..bc02236
--- /dev/null
+++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProducedByMechCarrier.cs
@@ -0,0 +1,117 @@
+using RimWorld;
+using System.Collections.Generic;
+using UnityEngine;
+using Verse;
+using Verse.AI;
+
+namespace ArachnaeSwarm
+{
+ public class CompProducedByMechCarrier : ThingComp
+ {
+ private Thing producer;
+ private CompAutoMechCarrier producerComp;
+ private int lastProducerCheckTick = -1;
+ private const int PRODUCER_CHECK_INTERVAL = 60;
+
+ public Thing Producer => producer;
+ public CompAutoMechCarrier ProducerComp => producerComp;
+
+ // 公开属性,用于其他类访问
+ public bool HasValidProducer
+ {
+ get
+ {
+ if (producer == null || producer.Destroyed)
+ return false;
+
+ // 如果是pawn,检查是否死亡或倒下
+ if (producer is Pawn pawn && (pawn.Dead || pawn.Downed))
+ return false;
+
+ return true;
+ }
+ }
+
+ // 检查是否应该跟随生产者
+ public bool ShouldFollowProducer
+ {
+ get
+ {
+ if (!HasValidProducer)
+ return false;
+
+ // 确保pawn是有效的
+ Pawn pawn = parent as Pawn;
+ if (pawn == null || !pawn.Spawned || pawn.Downed || pawn.Dead)
+ return false;
+
+ // 确保生产者在同一地图且可以到达
+ if (producer.Map != pawn.Map || !pawn.CanReach(producer, PathEndMode.OnCell, Danger.Deadly))
+ return false;
+
+ // 可以根据需要添加更多条件
+ return true;
+ }
+ }
+
+ // 初始化方法
+ public void Initialize(Thing producer, CompAutoMechCarrier producerComp)
+ {
+ this.producer = producer;
+ this.producerComp = producerComp;
+ }
+
+ // 尝试更新生产者状态
+ public void TryUpdateProducerStatus()
+ {
+ if (Find.TickManager.TicksGame - lastProducerCheckTick < PRODUCER_CHECK_INTERVAL)
+ return;
+
+ lastProducerCheckTick = Find.TickManager.TicksGame;
+
+ // 检查生产者是否仍然有效
+ if (producer != null && (producer.Destroyed || (producer is Pawn p && (p.Dead || p.Downed))))
+ {
+ producer = null;
+ producerComp = null;
+ }
+ }
+
+ // 获取生产者的位置
+ public IntVec3 GetProducerPosition()
+ {
+ if (!HasValidProducer)
+ return IntVec3.Invalid;
+
+ return producer.Position;
+ }
+
+ // 获取生产者的交互单元格
+ public IntVec3 GetProducerInteractionCell()
+ {
+ if (!HasValidProducer)
+ return IntVec3.Invalid;
+
+ if (producer is Building building)
+ return building.InteractionCell;
+
+ return producer.Position;
+ }
+
+ // 检查是否在生产者附近
+ public bool IsNearProducer(Pawn pawn, float radius)
+ {
+ if (!HasValidProducer)
+ return false;
+
+ return pawn.Position.DistanceTo(producer.Position) <= radius;
+ }
+
+ public override void PostExposeData()
+ {
+ base.PostExposeData();
+ Scribe_References.Look(ref producer, "producer");
+ Scribe_Values.Look(ref lastProducerCheckTick, "lastProducerCheckTick", -1);
+ }
+ }
+}
diff --git a/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProperties_ProducedByMechCarrier.cs b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProperties_ProducedByMechCarrier.cs
new file mode 100644
index 0000000..b163231
--- /dev/null
+++ b/Source/ArachnaeSwarm/Pawn_Comps/ARA_AutoMechCarrier/CompProperties_ProducedByMechCarrier.cs
@@ -0,0 +1,12 @@
+using Verse;
+
+namespace ArachnaeSwarm
+{
+ public class CompProperties_ProducedByMechCarrier : CompProperties
+ {
+ public CompProperties_ProducedByMechCarrier()
+ {
+ this.compClass = typeof(CompProducedByMechCarrier);
+ }
+ }
+}
diff --git a/非公开资源/Content/Textures/Things/ARA_Longpincer/Bodies/Naked_Thin_east.sai2 b/非公开资源/Content/Textures/Things/ARA_Longpincer/Bodies/Naked_Thin_east.sai2
new file mode 100644
index 0000000..f98d2f6
Binary files /dev/null and b/非公开资源/Content/Textures/Things/ARA_Longpincer/Bodies/Naked_Thin_east.sai2 differ