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