diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index b51d6a3..5687951 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/AbilityDefs/Ability_Flyover.xml b/1.6/1.6/Defs/AbilityDefs/Ability_Flyover.xml index 07f2d42..b007df6 100644 --- a/1.6/1.6/Defs/AbilityDefs/Ability_Flyover.xml +++ b/1.6/1.6/Defs/AbilityDefs/Ability_Flyover.xml @@ -3,7 +3,7 @@ ARA_SpawnFlyOverTest - 召唤虫巢母舰,启动攻击事件链(测试用) + 召唤虫巢母舰,启动虫群入侵终局事件链(测试用,乱用后果自负) ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph 1 Misc12 @@ -35,8 +35,8 @@ ARA_Spawn_ARA_HiveCorvette_Rocket - 召唤天巫种兽虫,高速掠过战场,使用其迅捷天灾炮对目标区域发起打击。\n\n在飞行期间,它会使用血链棘刺炮打击遇到的敌人,由于攻击区间较少,血链棘刺炮只能打击前7个遇到的目标。 - ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph + 引航种指挥阿拉克涅天巫种兽虫,高速掠过战场,使用其附带阿拉克涅虫酸效果的迅捷天灾炮对目标区域发起打击。\n\n在飞行期间,它会使用血链棘刺炮打击遇到的敌人,由于攻击区间较少,血链棘刺炮只能打击前7个遇到的目标。 + ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Rocket 1 Misc12 false @@ -53,6 +53,11 @@ +
  • + ARA_HiveCorvette_Entity + 5000 + 1 +
  • ARA_HiveCorvette GroundStrafing @@ -77,7 +82,6 @@ true - 4 (0.3,0.7,1.0,0.3)
  • @@ -85,8 +89,8 @@ ARA_Spawn_ARA_HiveCorvette_Bombardment - 召唤天巫种兽虫,慢速掠过战场,对大范围目标区域进行酸团轰炸。\n\n在飞行期间,它会使用血链棘刺炮打击遇到的所有敌人。 - ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph + 引航种指挥阿拉克涅天巫种兽虫,慢速掠过战场,对大范围目标区域进行附带阿拉克涅虫酸效果的酸团轰炸。\n\n在飞行期间,它会使用高伤害、高穿甲能力的血链棘刺炮打击遇到的所有敌人。 + ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Bombardment 1 Misc12 false @@ -105,7 +109,7 @@
  • ARA_HiveCorvette_Entity - 120 + 5000 1
  • @@ -131,6 +135,49 @@ true (1.0,0.3,0.1,0.2) + + true + (0.3,0.7,1.0,0.3) +
  • +
    +
    + + ARA_Spawn_ARA_HiveCorvette_Strike + + 引航种指挥阿拉克涅天巫种兽虫,缓慢掠过战场,使用高伤害、高穿甲能力的血链棘刺炮打击遇到的所有敌人。该攻击模式下天巫种视野较为狭小,难以打击整个集群。 + ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Strike + 1 + Misc12 + false + + Verb_CastAbility + false + false + 1 + 120 + true + + false + true + + + +
  • + ARA_HiveCorvette_Entity + 5000 + 1 +
  • +
  • + ARA_HiveCorvette_Strike + GroundStrafing + 1 + 20 + true + Perpendicular + + + true + true 4 diff --git a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml index 915db40..d2d2283 100644 --- a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml +++ b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml @@ -1814,13 +1814,78 @@
  • ARA_Praetorian_jump
  • ARA_Praetorian_Commander_Ability_On
  • ARA_Praetorian_Commander_Ability_Off
  • +
  • ARA_Praetorian_Navigator
  • - + +
    + + + ARA_Praetorian_Navigator + + 使禁卫种发生内驱性进化,以牺牲射击能力、跳跃能力、指挥能力为代价,使其换取指挥空中兽虫的能力。\n\n该进化过程不可逆!另外,空中兽虫必须成功升空才能进行指挥——在你解锁这个进化路径时,应该还不能建造空中兽虫。 + ArachnaeSwarm/UI/Abilities/ARA_Praetorian_Navigator + 1800 + false + true + true + false + false + true + false + CastAbilityOnThing + + Verb_CastAbility + 1 + 12 + AcidSpray_Resolve + false + false + + True + + + +
  • + CompAbilityEffect_GiveHediff + ARA_Praetorian_Navigator + True + true + 1 +
  • +
  • + ARA_Technology_9NAV + 需要科技 节点NAV-9"领航使者" 以解锁进化 +
  • +
    +
    + + ARA_Praetorian_Navigator + + 这只阿拉克涅禁卫种已经获得拔耀,虽然失去了直接的战斗能力,但是可以指挥空中兽虫,以虫群绝对的空中优势碾压敌军。 + HediffWithComps + (0.6, 0.4, 0.8) + false + false + 1.0 + +
  • + 0 +
  • +
    + +
  • + +
  • ARA_SpawnFlyOverTest
  • +
  • ARA_Spawn_ARA_HiveCorvette_Rocket
  • +
  • ARA_Spawn_ARA_HiveCorvette_Bombardment
  • +
  • ARA_HiveCorvette_Strike
  • + +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml index 720f82b..0fffede 100644 --- a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml +++ b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml @@ -702,6 +702,18 @@
  • ARA_Technology_6GUT
  • + + ARA_Technology_9NAV + + <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许禁卫种进行定向进化,抛弃直接战斗能力和指挥地面虫群部队的能力,换取指挥空中兽虫群的能力。\n\n阿拉克涅虫群所有需要蓝图的科技,其蓝图只能通过女皇种的基因试验卵获取。 + 3500 + 11.00 + 3.80 + ARA_ResearchBench + +
  • ARA_Technology_7KYC
  • +
    +
    ARA_Technology_1EVO @@ -814,7 +826,7 @@ <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许实行新的阿拉克涅进化手术,允许阿拉克涅虫族以丧失自愈能力为代价摆脱寿命的限制。 4000 11.00 - 3.80 + 2.10 ARA_ResearchBench
  • ARA_Technology_5ESS
  • @@ -844,11 +856,24 @@ <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许阿拉克涅虫族建造特殊的活体建筑——阿拉克涅共生肌群,一种可以和督虫融合的无意识组织体,能为督虫提供强大的战斗力。\n\n霜结体共生肌群可以支持与其融合的阿拉克涅督虫使用多种急冻类武装,可以在控制大范围人群和快速点杀高价值目标间切换。 4000 - 12.00 + 11.00 4.30 ARA_ResearchBench
  • ARA_Technology_8EVO
  • + + + ARA_Technology_4COV + + <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许阿拉克涅虫族建造特殊的活体建筑——天巫种兽虫,一种由引航种指挥的半自主个体,能依据指令灵活地从天上袭击敌军,以降下死亡之雨。 + 3000 + 12.00 + 3.80 + ARA_ResearchBench + +
  • ARA_Technology_9NAV
  • +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/Thing_Misc/ARA_Flyover_Item.xml b/1.6/1.6/Defs/Thing_Misc/ARA_Flyover_Item.xml index 2a3ae99..455e146 100644 --- a/1.6/1.6/Defs/Thing_Misc/ARA_Flyover_Item.xml +++ b/1.6/1.6/Defs/Thing_Misc/ARA_Flyover_Item.xml @@ -3,23 +3,24 @@ ARA_HiveCorvette_Building - 天巫种兽虫 - Building_PassengerShuttle + 天巫种兽虫是阿拉克涅虫群舰队中的对地攻击机,它们长长的触须和强大的灵能悬浮能力使得它们可以在引航种的指挥下高速掠过战场,并依据指令打击不长眼的敌军集群或援助虫群的进攻。\n\n它们需要起飞才能发挥效果! + Building true Building 50 true PassThroughOnly - 0.5 - (5,5) + 1 + (6,14) true (0.56, 0.62, 0.9) 1 + ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving - ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow + ArachnaeSwarm/Building/ARA_HiveCorvetteB Graphic_Single TransparentPostLight - (5,5) + (5,16) (195,195,195,255) @@ -33,10 +34,10 @@ ARA_Buildings 6 - 250 - 150 - 6 - 1 + 500 + 250 + 100 + 100 true @@ -51,6 +52,9 @@ RealtimeOnly ConstructMetal true + +
  • ARA_Technology_4COV
  • +
    BuildingDestroyed_Metal_Big true @@ -60,7 +64,7 @@
  • ARA_HiveCorvette_Entity 1 - PassengerShuttleLeaving + ARA_HiveCorvette_Leaving
  • @@ -72,6 +76,54 @@ ARA_HiveCorvette_Entity 什么?这是个记录数量用的thingdef,你不应该在任何场合下看到这个。 + Thing +
    + + ARA_HiveCorvette_Leaving + + FlyShipLeaving + + true + Shuttle_Leaving + -10 + -40~-15 + 0.05 + Things/Skyfaller/SkyfallerShadowRectangle + (5.5,3.5) + 1 + + +
  • (0,90)
  • +
  • (1,110)
  • +
    +
    + + +
  • (0,0)
  • +
  • (0,10)
  • +
    +
    + + +
  • (0,0)
  • +
  • (0.08,2)
  • +
    +
    + + +
  • (0,0.2)
  • +
  • (0.4,0.7)
  • +
    +
    +
    + + ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving + Graphic_Single + TransparentPostLight + (16,5) + (195,195,195,255) + + MetaOverlays
    @@ -209,7 +261,7 @@ 250 - 60 + 30 1 @@ -217,6 +269,136 @@ 100 5 true + 10 + 70 + + + 20 + 10 + false + + + true + false + true + + + true + + + + 0.3 + 1.2 + + + + true + + 0.2 + 0.6 + + (0.7,0.85,1.0,1.0) + 1.3 + + +
  • + ARA_HiveShip_Fake + + + 3000 + 3 + 1 + + + 20 + 380 + 5 + true + 25 + 100 + + + 1 + 10 + false + + + true + true + true + + + true + + + + 0.3 + 0.5 + + + + true + + 0.3 + 0.6 + + (0.7,0.85,1.0,1.0) + 1.3 +
  • + +
    + + ARA_HiveShip_Fake + + ArachnaeSwarm.FlyOver + Normal + RealtimeOnly + + + ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow + Graphic_Single + TransparentPostLight + (100,250) + (195,195,195,45) + + + ArachnaeSwarm/Weapon/ARA_Weapon_Empty + (0, 0) + 0 + FlyOver/Flying + FlyOver/Landing + + +
  • + ArachnaeSwarm/Weapon/ARA_Weapon_Empty + true + 0.8 + 0 + 0 + 0 + 0 +
  • +
    + true + false + false + false + MetaOverlays + + +
  • + ARA_HiveCorvette_Fake + + + 250 + 5 + 1 + + + 0 + 50 + 5 + true 20 @@ -247,10 +429,10 @@ 1.3
  • -
    + ARA_HiveCorvette_Fake - + ArachnaeSwarm.FlyOver Normal RealtimeOnly @@ -298,7 +480,7 @@ RealtimeOnly - ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow + ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow Graphic_Single TransparentPostLight (20,30) @@ -352,7 +534,7 @@ RealtimeOnly - ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow + ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow Graphic_Single TransparentPostLight (20,30) @@ -398,6 +580,56 @@ + + ARA_HiveCorvette_Strike + + ArachnaeSwarm.FlyOver + Normal + RealtimeOnly + + + ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow + Graphic_Single + TransparentPostLight + (20,30) + (195,195,195,45) + + false + 0 + + ArachnaeSwarm/Weapon/ARA_Weapon_Empty + (0, 0) + 0 + FlyOver/Flying + FlyOver/Landing + + +
  • + ArachnaeSwarm/Weapon/ARA_Weapon_Empty + true + 0.8 + 0 + 0 + 0 + 0 +
  • +
    + true + false + false + false + MetaOverlays + +
  • + Bullet_ARA_HiveCorvette + 30 + 50 + 10 + 0.5 + -1 +
  • +
    +
    ARA_HiveShip_Fire_Incoming @@ -416,7 +648,7 @@ (2.5, 2.5) 10 ARA_AcidBurn - 0.5 + 0.1 1 diff --git a/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/AirStrike_Keys.xml b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/AirStrike_Keys.xml new file mode 100644 index 0000000..ff5d420 --- /dev/null +++ b/1.6/1.6/Languages/ChineseSimplified (简体中文)/Keyed/AirStrike_Keys.xml @@ -0,0 +1,53 @@ + + + + 战机管理器未找到! + 空中打击已启动:{0} + 空中打击:成功使用 {0} 只 {1} + 没有可用的空中兽虫:{0} + 空中兽虫打击:{1} 没有可用的 {0} + 没有可用的 {0} 进行打击 + + + {0}:{1} + 冷却中:{0} + 消耗:{0} + + + 兽虫群状态: + 兽虫总数:{0} + 准备发射:{0} + 冷却中:{0} + 每次使用消耗:{0} + + + + 冷却时间:{0}小时 + \n需要 {0} 参与打击\n每次使用占用 {1} 兽虫\n冷却时间:{2}小时 + + + 未知派系 + + + + 兽虫起飞 + 命令空中兽虫起飞。起飞的空中兽虫将永不落地,如果想要使用它们就需要有引航种的指挥。 + 兽虫受损 + + + 兽虫已起飞:{0} 只 {1} + 战机管理器未找到! + + + 无法创建起飞效果:父级地图为空 + 在 {0} 创建了起飞天空坠落者,携带1单位化学燃料 + 创建起飞效果时出错:{0} + + + 尝试将战机添加到空派系 + + + {0} 准备好再次进行打击 + 没有可用的兽虫 + {0}:{1}/{2}(冷却中:{3}) + \ No newline at end of file diff --git a/Content/Textures/ArachnaeSwarm/Building/ARA_HiveCorvetteB.png b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveCorvetteB.png new file mode 100644 index 0000000..499e9d4 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveCorvetteB.png differ diff --git a/Content/Textures/ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving.png b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving.png new file mode 100644 index 0000000..c50eaf8 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving.png differ diff --git a/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow.png b/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow.png new file mode 100644 index 0000000..2603b3c Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Praetorian_Navigator.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Praetorian_Navigator.png new file mode 100644 index 0000000..a6e8331 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Praetorian_Navigator.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Bombardment.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Bombardment.png new file mode 100644 index 0000000..e9c3aee Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Bombardment.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Rocket.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Rocket.png new file mode 100644 index 0000000..148ea1d Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Rocket.png differ diff --git a/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Strike.png b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Strike.png new file mode 100644 index 0000000..bfc9ea7 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Strike.png differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index 8a0f789..9fac849 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 b60b58f..2aa2ecd 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -3,56 +3,40 @@ "WorkspaceRootPath": "D:\\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\\flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.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\\flyover\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\thingclassflyover.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\\flyover\\ara_aircrafthangar\\compaircrafthangar.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\compaircrafthangar.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\\flyover\\ara_aircrafthangar\\compabilityeffect_aircraftstrike.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\\flyover\\ara_aircrafthangar\\compabilityeffect_aircraftstrike.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\compabilityeffect_aircraftstrike.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\\building_comps\\comprefuelablenutrition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\comprefuelablenutrition.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\\abilities\\ara_givehediffwithskillduration\\compabilityeffect_givehediffwithskillduration.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_givehediffwithskillduration\\compabilityeffect_givehediffwithskillduration.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\\flyover\\ara_sectorsurveillance\\compsectorsurveillance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_sectorsurveillance\\compsectorsurveillance.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\\abilities\\ara_showtemperaturerange\\compabilityeffect_abilityshowtemperaturerange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showtemperaturerange\\compabilityeffect_abilityshowtemperaturerange.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\\flyover\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\thingclassflyover.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\\abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.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\\flyover\\ara_spawnflyover\\compabilityeffect_spawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_spawnflyover\\compabilityeffect_spawnflyover.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\\flyover\\ara_spawnflyover\\compproperties_abilityspawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_spawnflyover\\compproperties_abilityspawnflyover.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\\flyover\\ara_aircrafthangar\\compaircrafthangar.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\compaircrafthangar.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\\flyover\\ara_groundstrafing\\compgroundstrafing.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_groundstrafing\\compgroundstrafing.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\\flyover\\ara_flyoverescort\\compflyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_flyoverescort\\compflyoverescort.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\\flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", + "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.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\\flyover\\ara_flyoverescort\\compproperties_flyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_flyoverescort\\compproperties_flyoverescort.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\\flyover\\ara_shipartillery\\compshipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_shipartillery\\compshipartillery.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\\flyover\\ara_shipartillery\\compproperties_shipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}", - "RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_shipartillery\\compproperties_shipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}" } ], "DocumentGroupContainers": [ @@ -70,167 +54,112 @@ }, { "$type": "Document", - "DocumentIndex": 1, - "Title": "CompAircraftHangar.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", - "RelativeToolTip": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", - "ViewState": "AgIAAEoAAAAAAAAAAAAswFkAAAAdAAAAAAAAAA==", + "DocumentIndex": 2, + "Title": "CompAbilityEffect_GiveHediffWithSkillDuration.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs", + "RelativeDocumentMoniker": "Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs", + "RelativeToolTip": "Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs", + "ViewState": "AgIAAEsAAAAAAAAAAAAWwGAAAAAAAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-29T06:31:52.619Z", - "EditorCaption": "" + "WhenOpened": "2025-10-29T14:40:47.422Z" }, { "$type": "Document", "DocumentIndex": 3, - "Title": "CompRefuelableNutrition.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompRefuelableNutrition.cs", - "RelativeDocumentMoniker": "Building_Comps\\CompRefuelableNutrition.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompRefuelableNutrition.cs", - "RelativeToolTip": "Building_Comps\\CompRefuelableNutrition.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAAXAAAAAAAAAA==", + "Title": "CompAbilityEffect_AbilityShowTemperatureRange.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs", + "RelativeDocumentMoniker": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs", + "RelativeToolTip": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAArAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-29T06:31:46.148Z", - "EditorCaption": "" + "WhenOpened": "2025-10-29T14:40:43.525Z" }, { "$type": "Document", - "DocumentIndex": 2, + "DocumentIndex": 1, "Title": "CompAbilityEffect_AircraftStrike.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs", "RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs", "RelativeToolTip": "Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAACMAAAAAAAAAAAAAAA==", + "ViewState": "AgIAAHYAAAAAAAAAAAAtwJcAAAArAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-29T06:30:49.523Z", - "EditorCaption": "" + "WhenOpened": "2025-10-29T11:22:34.783Z" }, { "$type": "Document", "DocumentIndex": 0, - "Title": "WorldComponent_AircraftManager.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", - "RelativeToolTip": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", - "ViewState": "AgIAAKsAAAAAAAAAAAAowBEAAAASAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-29T06:30:44.854Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 4, - "Title": "CompSectorSurveillance.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs", - "RelativeToolTip": "Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs", - "ViewState": "AgIAAMYAAAAAAAAAAAAqwNUAAAARAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-29T02:30:42.063Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 8, - "Title": "CompGroundStrafing.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", - "RelativeToolTip": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", - "ViewState": "AgIAAB0AAAAAAAAAAAAQwCYAAABFAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T16:19:23.118Z" - }, - { - "$type": "Document", - "DocumentIndex": 6, - "Title": "CompAbilityEffect_SpawnFlyOver.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", - "RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAABOAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T14:51:14.836Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 7, - "Title": "CompProperties_AbilitySpawnFlyOver.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", - "RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", - "ViewState": "AgIAABgAAAAAAAAAAAAswDQAAAAAAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T13:51:12.201Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 5, "Title": "ThingclassFlyOver.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs", "RelativeDocumentMoniker": "Flyover\\ThingclassFlyOver.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs", "RelativeToolTip": "Flyover\\ThingclassFlyOver.cs", - "ViewState": "AgIAAAkCAAAAAAAAAAAqwCYCAAB/AAAAAAAAAA==", + "ViewState": "AgIAAC0CAAAAAAAAAAAawCUCAAANAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T09:09:22.03Z", + "WhenOpened": "2025-10-29T14:17:06.867Z", "EditorCaption": "" }, { "$type": "Document", - "DocumentIndex": 9, - "Title": "CompFlyOverEscort.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", - "RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", - "ViewState": "AgIAAKYBAAAAAAAAAAAWwNEBAAAAAAAAAAAAAA==", + "DocumentIndex": 4, + "Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "RelativeToolTip": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs", + "ViewState": "AgIAABYAAAAAAAAAAAAuwBYAAAArAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T07:30:55.268Z" + "WhenOpened": "2025-10-29T14:40:40.237Z" }, { "$type": "Document", - "DocumentIndex": 10, + "DocumentIndex": 6, + "Title": "CompAircraftHangar.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", + "RelativeToolTip": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs", + "ViewState": "AgIAABcAAAAAAAAAAAAQwCQAAAAnAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-29T11:39:22.563Z" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "CompAbilityEffect_SpawnFlyOver.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", + "RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", + "ViewState": "AgIAAFMDAAAAAAAAAAAawG8DAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-29T13:37:35.758Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, + "Title": "WorldComponent_AircraftManager.cs", + "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", + "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", + "RelativeToolTip": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs", + "ViewState": "AgIAAJUAAAAAAAAAAAAowK4AAAAUAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-29T14:05:39.817Z" + }, + { + "$type": "Document", + "DocumentIndex": 8, "Title": "CompProperties_FlyOverEscort.cs", "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", "RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", "RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAABgAAAAPAAAAAAAAAA==", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAvAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T07:30:47.27Z" - }, - { - "$type": "Document", - "DocumentIndex": 12, - "Title": "CompProperties_ShipArtillery.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs", - "RelativeToolTip": "Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs", - "ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAAhAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T06:21:06.271Z" - }, - { - "$type": "Document", - "DocumentIndex": 11, - "Title": "CompShipArtillery.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs", - "RelativeDocumentMoniker": "Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs", - "ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs", - "RelativeToolTip": "Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs", - "ViewState": "AgIAALEAAAAAAAAAAAAywNEAAABcAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T06:21:04.222Z" + "WhenOpened": "2025-10-29T12:59:07.753Z" } ] } diff --git a/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAbilityEffect_AircraftStrike.cs b/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAbilityEffect_AircraftStrike.cs index 6cfeab0..cd058a9 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAbilityEffect_AircraftStrike.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAbilityEffect_AircraftStrike.cs @@ -2,6 +2,7 @@ using RimWorld; using Verse; using RimWorld.Planet; using System.Collections.Generic; +using System.Text; namespace ArachnaeSwarm { @@ -30,40 +31,24 @@ namespace ArachnaeSwarm if (aircraftManager == null) { - Log.Error("Aircraft manager not found!"); + Log.Error("AircraftManagerNotFound".Translate()); return; } // 检查并消耗战机 if (aircraftManager.TryUseAircraft(Props.requiredAircraftType, Props.aircraftsPerUse, parent.pawn.Faction, Props.aircraftCooldownTicks)) { - // 执行打击效果 - ExecuteStrikeEffect(target); - - Messages.Message($"Aircraft strike initiated: {Props.requiredAircraftType.LabelCap}", MessageTypeDefOf.PositiveEvent); + // 成功消耗战机,发送消息 + Messages.Message("AircraftStrikeInitiated".Translate(Props.requiredAircraftType.LabelCap), MessageTypeDefOf.PositiveEvent); + Log.Message("AircraftStrikeSuccess".Translate(Props.aircraftsPerUse, Props.requiredAircraftType.LabelCap)); } else { - Messages.Message($"No available aircraft: {Props.requiredAircraftType.LabelCap}", MessageTypeDefOf.NegativeEvent); + Messages.Message("NoAvailableAircraft".Translate(Props.requiredAircraftType.LabelCap), MessageTypeDefOf.NegativeEvent); + Log.Warning("AircraftStrikeFailed".Translate(Props.requiredAircraftType.LabelCap, parent.pawn.Faction?.Name ?? "UnknownFaction".Translate())); } } - private void ExecuteStrikeEffect(LocalTargetInfo target) - { - // 这里实现具体的打击效果 - // 例如:轰炸、空投、侦察等 - - // 示例:在目标位置创建爆炸效果 - GenExplosion.DoExplosion( - target.Cell, - parent.pawn.Map, - radius: 3.5f, - DamageDefOf.Bomb, - instigator: parent.pawn, - damAmount: 50 - ); - } - public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest) { // 检查是否有可用的战机 @@ -81,10 +66,97 @@ namespace ArachnaeSwarm if (aircraftManager != null) { int available = aircraftManager.GetAvailableAircraftCount(Props.requiredAircraftType, parent.pawn.Faction); - return $"Available {Props.requiredAircraftType.LabelCap}: {available}"; + int onCooldown = aircraftManager.GetCooldownAircraftCount(Props.requiredAircraftType, parent.pawn.Faction); + + // 使用符号显示飞机状态 + string availableSymbols = GetAircraftSymbols(available, "◆"); + string cooldownSymbols = GetAircraftSymbols(onCooldown, "◇"); + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("AvailableAircraft".Translate(Props.requiredAircraftType.LabelCap, availableSymbols)); + sb.AppendLine("CooldownAircraft".Translate(cooldownSymbols)); + sb.Append("CostPerUse".Translate(Props.aircraftsPerUse)); + + return sb.ToString(); } return base.ExtraLabelMouseAttachment(target); } + + // 生成飞机符号表示 + private string GetAircraftSymbols(int count, string symbol) + { + if (count <= 0) return "—"; // 无飞机时显示破折号 + + StringBuilder sb = new StringBuilder(); + int displayCount = count; + + // 如果数量过多,用数字+符号表示 + if (count > 10) + { + return $"{count}{symbol}"; + } + + // 直接显示符号 + for (int i = 0; i < displayCount; i++) + { + sb.Append(symbol); + } + + return sb.ToString(); + } + + public override bool Valid(LocalTargetInfo target, bool throwMessages = false) + { + if (!base.Valid(target, throwMessages)) + return false; + + // 检查战机可用性 + WorldComponent_AircraftManager aircraftManager = Find.World.GetComponent(); + if (aircraftManager == null || !aircraftManager.HasAvailableAircraft(Props.requiredAircraftType, Props.aircraftsPerUse, parent.pawn.Faction)) + { + if (throwMessages) + { + Messages.Message("NoAircraftForStrike".Translate(Props.requiredAircraftType.LabelCap), MessageTypeDefOf.RejectInput); + } + return false; + } + + return true; + } + + // 鼠标悬停时的工具提示 + public override string ExtraTooltipPart() + { + WorldComponent_AircraftManager aircraftManager = Find.World.GetComponent(); + + if (aircraftManager != null) + { + int available = aircraftManager.GetAvailableAircraftCount(Props.requiredAircraftType, parent.pawn.Faction); + int onCooldown = aircraftManager.GetCooldownAircraftCount(Props.requiredAircraftType, parent.pawn.Faction); + int total = available + onCooldown; + + // 将冷却时间从 tick 转换为小时 + float cooldownHours = TicksToHours(Props.aircraftCooldownTicks); + + StringBuilder sb = new StringBuilder(); + sb.AppendLine("AircraftStatusTooltip".Translate()); + sb.AppendLine("• " + "TotalAircraft".Translate(total)); + sb.AppendLine("• " + "ReadyAircraft".Translate(available)); + sb.AppendLine("• " + "CooldownAircraft".Translate(onCooldown)); + sb.AppendLine("AircraftAbilityDescription".Translate(Props.requiredAircraftType.LabelCap, Props.aircraftsPerUse, cooldownHours.ToString("F1"))); + + return sb.ToString(); + } + + return base.ExtraTooltipPart(); + } + + // 将 tick 转换为小时 + private float TicksToHours(int ticks) + { + // RimWorld 中 1 小时 = 2500 tick + return ticks / 2500f; + } } } diff --git a/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAircraftHangar.cs b/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAircraftHangar.cs index 07a6998..beef9c1 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAircraftHangar.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/CompAircraftHangar.cs @@ -31,8 +31,8 @@ namespace ArachnaeSwarm // 起飞命令 Command_Action launchCommand = new Command_Action { - defaultLabel = "Launch Aircraft", - defaultDesc = "Launch aircraft for orbital support", + defaultLabel = "LaunchAircraft".Translate(), + defaultDesc = "LaunchAircraftDesc".Translate(), icon = TexCommand.Attack, action = LaunchAircraft }; @@ -40,7 +40,7 @@ namespace ArachnaeSwarm // 检查条件:建筑完好 if (parent.HitPoints <= 0) { - launchCommand.Disable("Hangar damaged"); + launchCommand.Disable("HangarDamaged".Translate()); } yield return launchCommand; @@ -53,15 +53,15 @@ namespace ArachnaeSwarm if (aircraftManager == null) { - Log.Error("Aircraft manager not found!"); + Log.Error("AircraftManagerNotFound".Translate()); return; } - // 立即向全局管理器注册战机(在创建 Skyfaller 之前) + // 立即向全局管理器注册战机 aircraftManager.AddAircraft(Props.aircraftDef, Props.aircraftCount, parent.Faction); // 显示消息 - Messages.Message($"Aircraft launched: {Props.aircraftCount}x {Props.aircraftDef.LabelCap}", MessageTypeDefOf.PositiveEvent); + Messages.Message("AircraftLaunched".Translate(Props.aircraftCount, Props.aircraftDef.LabelCap), MessageTypeDefOf.PositiveEvent); // 创建起飞效果(仅视觉效果) if (Props.skyfallerLeaving != null) @@ -77,17 +77,39 @@ namespace ArachnaeSwarm private void CreateTakeoffEffect() { - // 创建起飞天空坠落者 - Skyfaller skyfaller = SkyfallerMaker.MakeSkyfaller(Props.skyfallerLeaving, parent); - - // 设置起飞位置(建筑当前位置) - IntVec3 takeoffPos = parent.Position; - - // 生成 Skyfaller - GenSpawn.Spawn(skyfaller, takeoffPos, parent.Map); - - // 立即销毁原建筑(Skyfaller 只是视觉效果) - parent.Destroy(); + try + { + // 创建 1 单位 Chemfuel 作为 Skyfaller 的内容物 + Thing chemfuel = ThingMaker.MakeThing(ThingDefOf.Chemfuel); + chemfuel.stackCount = 1; + + // 创建包含 Chemfuel 的 Skyfaller + Skyfaller skyfaller = SkyfallerMaker.MakeSkyfaller(Props.skyfallerLeaving, chemfuel); + + // 设置起飞位置(建筑当前位置) + IntVec3 takeoffPos = parent.Position; + + // 检查地图是否有效 + if (parent.Map == null) + { + Log.Error("TakeoffEffectMapNull".Translate()); + return; + } + + // 生成 Skyfaller + GenSpawn.Spawn(skyfaller, takeoffPos, parent.Map); + + Log.Message("TakeoffSkyfallerCreated".Translate(takeoffPos)); + + // 销毁原建筑 + parent.Destroy(DestroyMode.Vanish); + } + catch (System.Exception ex) + { + Log.Error("TakeoffEffectError".Translate(ex.Message)); + // 如果Skyfaller创建失败,直接销毁建筑 + parent.Destroy(DestroyMode.Vanish); + } } public override void PostExposeData() diff --git a/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/WorldComponent_AircraftManager.cs b/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/WorldComponent_AircraftManager.cs index 99c8b72..e198d34 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/WorldComponent_AircraftManager.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_AircraftHangar/WorldComponent_AircraftManager.cs @@ -8,55 +8,43 @@ namespace ArachnaeSwarm { public class WorldComponent_AircraftManager : WorldComponent { - private Dictionary> factionAircraftData = - new Dictionary>(); - + // 使用列表而不是嵌套字典,更容易序列化 + private List allFactionAircraftData = new List(); private List cooldownEvents = new List(); public WorldComponent_AircraftManager(World world) : base(world) { } - // 战机派系数据类 - private class AircraftFactionData : IExposable + // 派系战机数据 + private class FactionAircraftData : IExposable { - public int totalCount; // 总战机数量 - public int availableCount; // 可用战机数量 + public Faction faction; + public ThingDef aircraftDef; + public int totalCount; + public int availableCount; public void ExposeData() { - Scribe_Values.Look(ref totalCount, "totalCount"); - Scribe_Values.Look(ref availableCount, "availableCount"); + Scribe_References.Look(ref faction, "faction"); + Scribe_Defs.Look(ref aircraftDef, "aircraftDef"); + Scribe_Values.Look(ref totalCount, "totalCount", 0); + Scribe_Values.Look(ref availableCount, "availableCount", 0); } } - // 冷却事件类 + // 冷却事件 private class AircraftCooldownEvent : IExposable { public Faction faction; public ThingDef aircraftDef; public int endTick; - public int aircraftCount; // 冷却中的战机数量 + public int aircraftCount; public void ExposeData() { Scribe_References.Look(ref faction, "faction"); Scribe_Defs.Look(ref aircraftDef, "aircraftDef"); - Scribe_Values.Look(ref endTick, "endTick"); - Scribe_Values.Look(ref aircraftCount, "aircraftCount"); - } - } - - // 用于序列化的包装类 - private class SerializableFactionAircraftData : IExposable - { - public Faction faction; - public ThingDef aircraftDef; - public AircraftFactionData data; - - public void ExposeData() - { - Scribe_References.Look(ref faction, "faction"); - Scribe_Defs.Look(ref aircraftDef, "aircraftDef"); - Scribe_Deep.Look(ref data, "data"); + Scribe_Values.Look(ref endTick, "endTick", 0); + Scribe_Values.Look(ref aircraftCount, "aircraftCount", 0); } } @@ -64,50 +52,25 @@ namespace ArachnaeSwarm { base.ExposeData(); - // 保存派系战机数据 - List serializableData = new List(); + // 使用简单的列表序列化 + Scribe_Collections.Look(ref allFactionAircraftData, "allFactionAircraftData", LookMode.Deep); + Scribe_Collections.Look(ref cooldownEvents, "cooldownEvents", LookMode.Deep); + // 确保列表不为null + if (allFactionAircraftData == null) + allFactionAircraftData = new List(); + if (cooldownEvents == null) + cooldownEvents = new List(); + + // 调试日志 if (Scribe.mode == LoadSaveMode.Saving) { - // 将字典数据转换为可序列化的列表 - foreach (var factionPair in factionAircraftData) - { - foreach (var aircraftPair in factionPair.Value) - { - serializableData.Add(new SerializableFactionAircraftData - { - faction = factionPair.Key, - aircraftDef = aircraftPair.Key, - data = aircraftPair.Value - }); - } - } + Log.Message($"Saving aircraft data: {allFactionAircraftData.Count} faction entries, {cooldownEvents.Count} cooldown events"); } - - Scribe_Collections.Look(ref serializableData, "factionAircraftData", LookMode.Deep); - - if (Scribe.mode == LoadSaveMode.LoadingVars) + else if (Scribe.mode == LoadSaveMode.PostLoadInit) { - // 从序列化数据重建字典 - factionAircraftData.Clear(); - if (serializableData != null) - { - foreach (var item in serializableData) - { - if (item.faction != null && item.aircraftDef != null && item.data != null) - { - if (!factionAircraftData.ContainsKey(item.faction)) - { - factionAircraftData[item.faction] = new Dictionary(); - } - factionAircraftData[item.faction][item.aircraftDef] = item.data; - } - } - } + Log.Message($"Loaded aircraft data: {allFactionAircraftData.Count} faction entries, {cooldownEvents.Count} cooldown events"); } - - // 保存冷却事件 - 显式指定泛型类型 - Scribe_Collections.Look(ref cooldownEvents, "cooldownEvents", LookMode.Deep); } public override void WorldComponentTick() @@ -122,35 +85,50 @@ namespace ArachnaeSwarm if (currentTick >= cooldownEvent.endTick) { - // 冷却结束,恢复战机可用性 RestoreAircraftAfterCooldown(cooldownEvent); cooldownEvents.RemoveAt(i); } } } + // 获取或创建派系战机数据 + private FactionAircraftData GetOrCreateFactionAircraftData(Faction faction, ThingDef aircraftDef) + { + var data = allFactionAircraftData.FirstOrDefault(x => x.faction == faction && x.aircraftDef == aircraftDef); + if (data == null) + { + data = new FactionAircraftData + { + faction = faction, + aircraftDef = aircraftDef, + totalCount = 0, + availableCount = 0 + }; + allFactionAircraftData.Add(data); + } + return data; + } + + // 获取派系战机数据(可能为null) + private FactionAircraftData GetFactionAircraftData(Faction faction, ThingDef aircraftDef) + { + return allFactionAircraftData.FirstOrDefault(x => x.faction == faction && x.aircraftDef == aircraftDef); + } + // 添加战机到派系 public void AddAircraft(ThingDef aircraftDef, int count, Faction faction) { if (faction == null) { - Log.Error("Attempted to add aircraft to null faction"); + Log.Error("AddAircraftNullFaction".Translate()); return; } - if (!factionAircraftData.ContainsKey(faction)) - { - factionAircraftData[faction] = new Dictionary(); - } - - if (!factionAircraftData[faction].ContainsKey(aircraftDef)) - { - factionAircraftData[faction][aircraftDef] = new AircraftFactionData(); - } - - var data = factionAircraftData[faction][aircraftDef]; + var data = GetOrCreateFactionAircraftData(faction, aircraftDef); data.totalCount += count; data.availableCount += count; + + Log.Message($"Added {count} {aircraftDef.LabelCap} to {faction.Name}. Total: {data.totalCount}, Available: {data.availableCount}"); } // 尝试使用战机 @@ -159,10 +137,9 @@ namespace ArachnaeSwarm if (!HasAvailableAircraft(aircraftDef, count, faction)) return false; - var data = factionAircraftData[faction][aircraftDef]; + var data = GetFactionAircraftData(faction, aircraftDef); data.availableCount -= count; - // 创建冷却事件 AircraftCooldownEvent cooldownEvent = new AircraftCooldownEvent { faction = faction, @@ -173,86 +150,75 @@ namespace ArachnaeSwarm cooldownEvents.Add(cooldownEvent); + Log.Message($"Used {count} {aircraftDef.LabelCap} from {faction.Name}. Available now: {data.availableCount}, Cooldown until: {cooldownEvent.endTick}"); + return true; } // 检查是否有可用战机 public bool HasAvailableAircraft(ThingDef aircraftDef, int count, Faction faction) { - return factionAircraftData.ContainsKey(faction) && - factionAircraftData[faction].ContainsKey(aircraftDef) && - factionAircraftData[faction][aircraftDef].availableCount >= count; + var data = GetFactionAircraftData(faction, aircraftDef); + return data != null && data.availableCount >= count; } // 获取可用战机数量 public int GetAvailableAircraftCount(ThingDef aircraftDef, Faction faction) { - if (factionAircraftData.ContainsKey(faction) && - factionAircraftData[faction].ContainsKey(aircraftDef)) - { - return factionAircraftData[faction][aircraftDef].availableCount; - } - return 0; + var data = GetFactionAircraftData(faction, aircraftDef); + return data?.availableCount ?? 0; } // 获取总战机数量 public int GetTotalAircraftCount(ThingDef aircraftDef, Faction faction) { - if (factionAircraftData.ContainsKey(faction) && - factionAircraftData[faction].ContainsKey(aircraftDef)) - { - return factionAircraftData[faction][aircraftDef].totalCount; - } - return 0; + var data = GetFactionAircraftData(faction, aircraftDef); + return data?.totalCount ?? 0; } // 冷却结束后恢复战机 private void RestoreAircraftAfterCooldown(AircraftCooldownEvent cooldownEvent) { - if (cooldownEvent.faction != null && - factionAircraftData.ContainsKey(cooldownEvent.faction) && - factionAircraftData[cooldownEvent.faction].ContainsKey(cooldownEvent.aircraftDef)) + var data = GetFactionAircraftData(cooldownEvent.faction, cooldownEvent.aircraftDef); + if (data != null) { - var data = factionAircraftData[cooldownEvent.faction][cooldownEvent.aircraftDef]; data.availableCount += cooldownEvent.aircraftCount; - // 可选:显示冷却结束消息 if (cooldownEvent.aircraftDef != null) { - Messages.Message($"{cooldownEvent.aircraftDef.LabelCap} cooldown ended", MessageTypeDefOf.PositiveEvent); + Messages.Message("AircraftCooldownEnded".Translate(cooldownEvent.aircraftDef.LabelCap), MessageTypeDefOf.PositiveEvent); + Log.Message($"Cooldown ended for {cooldownEvent.aircraftCount} {cooldownEvent.aircraftDef.LabelCap}. Available now: {data.availableCount}"); } } } - // 获取战机状态信息(用于调试或UI显示) - public string GetAircraftStatus(Faction faction) - { - if (!factionAircraftData.ContainsKey(faction)) - return "No aircraft"; - - var status = new List(); - foreach (var kvp in factionAircraftData[faction]) - { - var data = kvp.Value; - int inCooldown = data.totalCount - data.availableCount; - status.Add($"{kvp.Key.LabelCap}: {data.availableCount}/{data.totalCount} (In cooldown: {inCooldown})"); - } - - return string.Join("\n", status); - } - // 获取冷却中的战机数量 public int GetCooldownAircraftCount(ThingDef aircraftDef, Faction faction) { - int totalCooldown = 0; - foreach (var cooldownEvent in cooldownEvents) + return cooldownEvents + .Where(e => e.faction == faction && e.aircraftDef == aircraftDef) + .Sum(e => e.aircraftCount); + } + + // 调试方法:显示当前状态 + public void DebugLogStatus() + { + Log.Message("=== Aircraft Manager Status ==="); + Log.Message($"Total faction entries: {allFactionAircraftData.Count}"); + + var factions = allFactionAircraftData.Select(x => x.faction).Distinct(); + foreach (var faction in factions) { - if (cooldownEvent.faction == faction && cooldownEvent.aircraftDef == aircraftDef) + Log.Message($"Faction: {faction?.Name ?? "Unknown"}"); + var factionData = allFactionAircraftData.Where(x => x.faction == faction); + foreach (var data in factionData) { - totalCooldown += cooldownEvent.aircraftCount; + Log.Message($" {data.aircraftDef.LabelCap}: {data.availableCount}/{data.totalCount} available"); } } - return totalCooldown; + + Log.Message($"Active cooldown events: {cooldownEvents.Count}"); + Log.Message("==============================="); } } } diff --git a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs index 51bc83e..a3d0886 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs @@ -31,6 +31,7 @@ namespace ArachnaeSwarm } Log.Message($"FlyOver Escort initialized: {Props.spawnIntervalTicks} ticks interval, max {Props.maxEscorts} escorts"); + Log.Message($"Safe distances - From Main: {Props.minSafeDistanceFromMain}, Between Escorts: {Props.minSafeDistanceBetweenEscorts}"); } public override void CompTick() @@ -97,8 +98,10 @@ namespace ArachnaeSwarm private void SpawnEscorts(FlyOver mainFlyOver) { int escortsToSpawn = Mathf.Min(Props.spawnCount, Props.maxEscorts - activeEscorts.Count); + int successfulSpawns = 0; + int maxAttempts = escortsToSpawn * 5; // 最多尝试5倍的数量 - for (int i = 0; i < escortsToSpawn; i++) + for (int attempt = 0; attempt < maxAttempts && successfulSpawns < escortsToSpawn; attempt++) { // 先生成视觉数据 EscortVisualData visualData = GenerateEscortVisualData(); @@ -106,12 +109,68 @@ namespace ArachnaeSwarm FlyOver escort = CreateEscort(mainFlyOver, visualData); if (escort != null) { - activeEscorts.Add(escort); - escortVisualData[escort] = visualData; - - Log.Message($"Spawned escort #{i+1} for FlyOver at {mainFlyOver.DrawPos}, scale: {visualData.scale:F2}, maskAlpha: {visualData.heightMaskAlpha:F2}"); + // 检查安全距离 + if (IsSafeDistance(escort, mainFlyOver)) + { + activeEscorts.Add(escort); + escortVisualData[escort] = visualData; + successfulSpawns++; + + Log.Message($"Spawned escort #{successfulSpawns} for FlyOver at {mainFlyOver.DrawPos}, scale: {visualData.scale:F2}, maskAlpha: {visualData.heightMaskAlpha:F2}"); + } + else + { + // 不安全,销毁这个伴飞 + escort.Destroy(); + Log.Message($"Escort spawn attempt {attempt + 1}: Position too close to existing escort, trying again"); + } + } + + // 如果已经生成足够数量,提前退出 + if (successfulSpawns >= escortsToSpawn) + break; + } + + if (successfulSpawns < escortsToSpawn) + { + Log.Message($"Spawned {successfulSpawns}/{escortsToSpawn} escorts (some positions were too close to existing escorts)"); + } + } + + // 修改:分别检查与主飞行物和伴飞物的安全距离 + private bool IsSafeDistance(FlyOver newEscort, FlyOver mainFlyOver) + { + Vector3 newPos = newEscort.DrawPos; + + // 检查与主FlyOver的距离 + if (Props.minSafeDistanceFromMain > 0) + { + float distToMain = Vector3.Distance(newPos, mainFlyOver.DrawPos); + if (distToMain < Props.minSafeDistanceFromMain) + { + Log.Message($"Escort too close to main FlyOver: {distToMain:F1} < {Props.minSafeDistanceFromMain}"); + return false; } } + + // 检查与其他伴飞的距离 + if (Props.minSafeDistanceBetweenEscorts > 0) + { + foreach (FlyOver existingEscort in activeEscorts) + { + if (existingEscort == null || existingEscort.Destroyed) + continue; + + float distToEscort = Vector3.Distance(newPos, existingEscort.DrawPos); + if (distToEscort < Props.minSafeDistanceBetweenEscorts) + { + Log.Message($"Escort too close to existing escort: {distToEscort:F1} < {Props.minSafeDistanceBetweenEscorts}"); + return false; + } + } + } + + return true; } private EscortVisualData GenerateEscortVisualData() @@ -131,7 +190,6 @@ namespace ArachnaeSwarm return data; } - // 修改:添加 visualData 参数 private FlyOver CreateEscort(FlyOver mainFlyOver, EscortVisualData visualData) { try @@ -275,7 +333,6 @@ namespace ArachnaeSwarm ); } - // 修改:添加 visualData 参数 private void SetupEscortProperties(FlyOver escort, FlyOver mainFlyOver, EscortVisualData visualData) { // 设置伴飞缩放 - 现在直接从参数获取 diff --git a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs index 6b66d82..65d502a 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs @@ -22,6 +22,10 @@ namespace ArachnaeSwarm public float verticalOffset = 2f; // 垂直偏移量(高度差) public bool useRandomOffset = true; // 是否使用随机偏移 + // 修改:独立的安全距离配置 + public float minSafeDistanceFromMain = 8f; // 与主飞行物的最小安全距离(单元格) + public float minSafeDistanceBetweenEscorts = 3f; // 伴飞物之间的最小安全距离(单元格) + // 飞行配置 public float escortSpeedMultiplier = 1f; // 速度乘数(相对于主FlyOver) public float escortAltitudeOffset = 0f; // 高度偏移 diff --git a/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs b/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs index 099224e..d69f154 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs @@ -36,6 +36,10 @@ namespace ArachnaeSwarm endPos = CalculateEndPosition(target, startPos); } + // 确保位置安全 + startPos = GetSafeMapPosition(startPos, parent.pawn.Map); + endPos = GetSafeMapPosition(endPos, parent.pawn.Map); + Log.Message($"Final positions - Start: {startPos}, End: {endPos}"); // 验证位置是否有效 @@ -57,10 +61,7 @@ namespace ArachnaeSwarm Log.Warning($"FlyOver start and end positions are the same: {startPos}. Adjusting end position."); IntVec3 randomOffset = new IntVec3(Rand.Range(-10, 11), 0, Rand.Range(-10, 11)); endPos += randomOffset; - if (!endPos.InBounds(parent.pawn.Map)) - { - endPos = parent.pawn.Map.Center; - } + endPos = GetSafeMapPosition(endPos, parent.pawn.Map); } // 根据类型创建不同的飞越物体 @@ -71,15 +72,12 @@ namespace ArachnaeSwarm CreateStandardFlyOver(startPos, endPos); break; case FlyOverType.GroundStrafing: - CreateGroundStrafingFlyOver(startPos, endPos); + CreateGroundStrafingFlyOver(startPos, endPos, target.Cell); break; case FlyOverType.SectorSurveillance: CreateSectorSurveillanceFlyOver(startPos, endPos); break; } - - // 显示效果消息 - ShowEffectMessage(); } catch (System.Exception ex) { @@ -87,39 +85,88 @@ namespace ArachnaeSwarm } } - // 新增:在目标选择时显示预览 + // 修复的预览绘制方法 public override void DrawEffectPreview(LocalTargetInfo target) { base.DrawEffectPreview(target); if (parent.pawn != null && parent.pawn.Map != null) { - // 计算飞行路径 - IntVec3 startPos, endPos; - if (Props.approachType == ApproachType.Perpendicular) + Map map = parent.pawn.Map; + + try { - CalculatePerpendicularPath(target, out startPos, out endPos); - } - else - { - startPos = CalculateStartPosition(target); - endPos = CalculateEndPosition(target, startPos); - } + // 计算飞行路径 + IntVec3 startPos, endPos; + if (Props.approachType == ApproachType.Perpendicular) + { + CalculatePerpendicularPath(target, out startPos, out endPos); + } + else + { + startPos = CalculateStartPosition(target); + endPos = CalculateEndPosition(target, startPos); + } - // 根据不同类型显示不同的预览 - if (Props.enableGroundStrafing && Props.showStrafePreview) - { - DrawStrafingAreaPreview(startPos, endPos); + // 确保位置在地图范围内 + startPos = GetSafeMapPosition(startPos, map); + endPos = GetSafeMapPosition(endPos, map); + + // 检查预览稳定性 + if (!IsPreviewStable(startPos, endPos, map)) + { + return; + } + + // 根据不同类型显示不同的预览 + if (Props.enableGroundStrafing && Props.showStrafePreview) + { + DrawStrafingAreaPreview(startPos, endPos, target.Cell); + } + else if (Props.enableSectorSurveillance && Props.showSectorPreview) + { + DrawSectorAreaPreview(startPos, endPos); + } } - else if (Props.enableSectorSurveillance && Props.showSectorPreview) + catch (System.Exception) { - DrawSectorAreaPreview(startPos, endPos); + // 忽略预览绘制中的错误,避免影响游戏体验 } } } - // 绘制地面扫射预览 - private void DrawStrafingAreaPreview(IntVec3 startPos, IntVec3 endPos) + // 安全的位置计算方法 + private IntVec3 GetSafeMapPosition(IntVec3 pos, Map map) + { + if (map == null) return pos; + + // 确保位置在地图范围内 + pos.x = Mathf.Clamp(pos.x, 0, map.Size.x - 1); + pos.z = Mathf.Clamp(pos.z, 0, map.Size.z - 1); + + return pos; + } + + // 预览绘制稳定性检查 + private bool IsPreviewStable(IntVec3 startPos, IntVec3 endPos, Map map) + { + if (map == null) return false; + + // 检查位置是否有效 + if (!startPos.IsValid || !endPos.IsValid) return false; + + // 检查位置是否在地图范围内 + if (!startPos.InBounds(map) || !endPos.InBounds(map)) return false; + + // 检查距离是否合理(避免过短的路径) + float distance = Vector3.Distance(startPos.ToVector3(), endPos.ToVector3()); + if (distance < 5f) return false; + + return true; + } + + // 修复:绘制地面扫射预览,现在接受目标单元格参数 + private void DrawStrafingAreaPreview(IntVec3 startPos, IntVec3 endPos, IntVec3 targetCell) { Map map = parent.pawn.Map; @@ -131,7 +178,7 @@ namespace ArachnaeSwarm } // 只计算扫射影响区域的单元格 - List strafeImpactCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection); + List strafeImpactCells = CalculateStrafingImpactCells(targetCell, flightDirection); // 绘制扫射影响区域的预览单元格 foreach (IntVec3 cell in strafeImpactCells) @@ -146,11 +193,11 @@ namespace ArachnaeSwarm GenDraw.DrawLineBetween(startPos.ToVector3Shifted(), endPos.ToVector3Shifted(), SimpleColor.Red, 0.2f); // 绘制扫射范围边界 - DrawStrafingBoundaries(startPos, endPos, flightDirection); + DrawStrafingBoundaries(targetCell, flightDirection); } - // 计算扫射影响区域的单元格 - private List CalculateStrafingImpactCells(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection) + // 修复:计算扫射影响区域的单元格,现在以目标单元格为中心 + private List CalculateStrafingImpactCells(IntVec3 targetCell, Vector3 flightDirection) { List cells = new List(); Map map = parent.pawn.Map; @@ -158,19 +205,16 @@ namespace ArachnaeSwarm // 计算垂直于飞行方向的方向 Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized; - // 计算飞行路径的总长度 - float totalPathLength = startPos.DistanceTo(endPos); + // 修复:以目标单元格为中心计算扫射区域 + Vector3 targetCenter = targetCell.ToVector3(); - // 计算扫射区域的中心点(目标位置附近) - Vector3 targetCenter = Vector3.Lerp(startPos.ToVector3(), endPos.ToVector3(), 0.5f); - - // 计算扫射区域的起始和结束位置(基于扫射长度) + // 计算扫射区域的起始和结束位置(基于扫射长度,以目标为中心) float strafeHalfLength = Props.strafeLength * 0.5f; Vector3 strafeStart = targetCenter - flightDirection * strafeHalfLength; Vector3 strafeEnd = targetCenter + flightDirection * strafeHalfLength; - // 沿着扫射区域计算单元格 - int steps = Mathf.CeilToInt(Props.strafeLength / 1f); + // 使用整数步进避免浮点精度问题 + int steps = Mathf.Max(1, Mathf.CeilToInt(Props.strafeLength)); for (int i = 0; i <= steps; i++) { float progress = (float)i / steps; @@ -181,7 +225,13 @@ namespace ArachnaeSwarm { Vector3 offset = perpendicular * w; Vector3 cellPos = centerPoint + offset; - IntVec3 cell = new IntVec3((int)cellPos.x, (int)cellPos.y, (int)cellPos.z); + + // 使用更精确的单元格转换 + IntVec3 cell = new IntVec3( + Mathf.RoundToInt(cellPos.x), + Mathf.RoundToInt(cellPos.y), + Mathf.RoundToInt(cellPos.z) + ); if (cell.InBounds(map) && !cells.Contains(cell)) { @@ -190,18 +240,18 @@ namespace ArachnaeSwarm } } - Log.Message($"Strafing Area: Calculated {cells.Count} impact cells ({Props.strafeWidth * 2 + 1}x{Props.strafeLength})"); + Log.Message($"Strafing Area: Calculated {cells.Count} impact cells centered at {targetCell}"); return cells; } - // 绘制扫射范围边界 - private void DrawStrafingBoundaries(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection) + // 修复:绘制扫射范围边界,现在以目标单元格为中心 + private void DrawStrafingBoundaries(IntVec3 targetCell, Vector3 flightDirection) { Map map = parent.pawn.Map; Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized; - // 计算扫射区域的中心点 - Vector3 targetCenter = Vector3.Lerp(startPos.ToVector3(), endPos.ToVector3(), 0.5f); + // 修复:以目标单元格为中心 + Vector3 targetCenter = targetCell.ToVector3(); // 计算扫射区域的起始和结束位置 float strafeHalfLength = Props.strafeLength * 0.5f; @@ -214,20 +264,27 @@ namespace ArachnaeSwarm Vector3 endLeft = strafeEnd + perpendicular * Props.strafeWidth; Vector3 endRight = strafeEnd - perpendicular * Props.strafeWidth; - // 转换为 IntVec3 - IntVec3 startLeftCell = new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z); - IntVec3 startRightCell = new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z); - IntVec3 endLeftCell = new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z); - IntVec3 endRightCell = new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z); + // 转换为 IntVec3 并确保在地图范围内 + IntVec3 startLeftCell = GetSafeMapPosition(new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z), map); + IntVec3 startRightCell = GetSafeMapPosition(new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z), map); + IntVec3 endLeftCell = GetSafeMapPosition(new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z), map); + IntVec3 endRightCell = GetSafeMapPosition(new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z), map); - // 绘制边界线 - GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); - GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); - GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); - GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); + // 绘制边界线 - 只绘制在地图范围内的线段 + if (startLeftCell.InBounds(map) && endLeftCell.InBounds(map)) + GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); + + if (startRightCell.InBounds(map) && endRightCell.InBounds(map)) + GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); + + if (startLeftCell.InBounds(map) && startRightCell.InBounds(map)) + GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); + + if (endLeftCell.InBounds(map) && endRightCell.InBounds(map)) + GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f); } - // 新增:绘制扇形区域预览 - 使用strafeWidth来近似扇形扫过的区域宽度 + // 绘制扇形区域预览 private void DrawSectorAreaPreview(IntVec3 startPos, IntVec3 endPos) { Map map = parent.pawn.Map; @@ -268,10 +325,10 @@ namespace ArachnaeSwarm Map map = parent.pawn.Map; // 计算飞行路径的总长度 - float totalPathLength = startPos.DistanceTo(endPos); + float totalPathLength = Vector3.Distance(startPos.ToVector3(), endPos.ToVector3()); // 沿着飞行路径计算预览单元格 - int steps = Mathf.CeilToInt(totalPathLength / 1f); + int steps = Mathf.Max(1, Mathf.CeilToInt(totalPathLength)); for (int i = 0; i <= steps; i++) { float progress = (float)i / steps; @@ -282,7 +339,13 @@ namespace ArachnaeSwarm { Vector3 offset = perpendicular * w; Vector3 cellPos = centerPoint + offset; - IntVec3 cell = new IntVec3((int)cellPos.x, (int)cellPos.y, (int)cellPos.z); + + // 使用精确的单元格转换 + IntVec3 cell = new IntVec3( + Mathf.RoundToInt(cellPos.x), + Mathf.RoundToInt(cellPos.y), + Mathf.RoundToInt(cellPos.z) + ); if (cell.InBounds(map) && !cells.Contains(cell)) { @@ -305,17 +368,24 @@ namespace ArachnaeSwarm Vector3 endLeft = endPos.ToVector3() + perpendicular * Props.strafeWidth; Vector3 endRight = endPos.ToVector3() - perpendicular * Props.strafeWidth; - // 转换为 IntVec3 - IntVec3 startLeftCell = new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z); - IntVec3 startRightCell = new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z); - IntVec3 endLeftCell = new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z); - IntVec3 endRightCell = new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z); + // 转换为 IntVec3 并确保在地图范围内 + IntVec3 startLeftCell = GetSafeMapPosition(new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z), map); + IntVec3 startRightCell = GetSafeMapPosition(new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z), map); + IntVec3 endLeftCell = GetSafeMapPosition(new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z), map); + IntVec3 endRightCell = GetSafeMapPosition(new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z), map); - // 绘制边界线 - GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); - GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); - GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); - GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); + // 绘制边界线 - 只绘制在地图范围内的线段 + if (startLeftCell.InBounds(map) && endLeftCell.InBounds(map)) + GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); + + if (startRightCell.InBounds(map) && endRightCell.InBounds(map)) + GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); + + if (startLeftCell.InBounds(map) && startRightCell.InBounds(map)) + GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); + + if (endLeftCell.InBounds(map) && endRightCell.InBounds(map)) + GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f); } // 预处理扫射目标单元格 @@ -335,8 +405,8 @@ namespace ArachnaeSwarm return confirmedTargets; } - // 创建地面扫射飞越 - private void CreateGroundStrafingFlyOver(IntVec3 startPos, IntVec3 endPos) + // 修复:创建地面扫射飞越,现在接受目标单元格参数 + private void CreateGroundStrafingFlyOver(IntVec3 startPos, IntVec3 endPos, IntVec3 targetCell) { ThingDef flyOverDef = Props.flyOverDef ?? DefDatabase.GetNamedSilentFail("ARA_HiveCorvette"); if (flyOverDef == null) @@ -363,9 +433,9 @@ namespace ArachnaeSwarm CompGroundStrafing strafingComp = flyOver.GetComp(); if (strafingComp != null) { - // 计算扫射区域的所有单元格 + // 修复:计算扫射区域的所有单元格,以目标单元格为中心 Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized; - List potentialTargetCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection); + List potentialTargetCells = CalculateStrafingImpactCells(targetCell, flightDirection); if (potentialTargetCells.Count > 0) { @@ -395,7 +465,7 @@ namespace ArachnaeSwarm } } - // 新增:创建扇形监视飞越 + // 创建扇形监视飞越 private void CreateSectorSurveillanceFlyOver(IntVec3 startPos, IntVec3 endPos) { ThingDef flyOverDef = Props.flyOverDef ?? DefDatabase.GetNamedSilentFail("ARA_HiveCorvette"); @@ -420,9 +490,6 @@ namespace ArachnaeSwarm flyOver.playFlyOverSound = Props.playFlyOverSound; Log.Message($"SectorSurveillance FlyOver created: {flyOver} from {startPos} to {endPos}"); - - // 注意:扇形监视的具体参数(角度、射程、发射次数等)在FlyOver的CompProperties_SectorSurveillance中定义 - // 这里只负责创建FlyOver,不传递具体参数 } // 计算垂直线进场路径 @@ -471,27 +538,107 @@ namespace ArachnaeSwarm // 在指定方向上找到地图边缘 private IntVec3 FindMapEdgeInDirection(Map map, IntVec3 fromPos, Vector3 direction) { - // 计算最大搜索距离(地图对角线的一半) - float maxDistance = Mathf.Sqrt(map.Size.x * map.Size.x + map.Size.z * map.Size.z) * 0.6f; - - // 沿着方向逐步搜索,直到找到地图边界 - for (float distance = 10f; distance <= maxDistance; distance += 5f) + // 确保方向向量有效 + if (direction == Vector3.zero) { - IntVec3 testPos = fromPos + new IntVec3( - Mathf.RoundToInt(direction.x * distance), - 0, - Mathf.RoundToInt(direction.z * distance)); + direction = new Vector3(Rand.Range(-1f, 1f), 0, Rand.Range(-1f, 1f)).normalized; + } + + // 使用更精确的地图边界计算 + IntVec3 mapCenter = map.Center; + IntVec3 mapSize = new IntVec3(map.Size.x, 0, map.Size.z); + + // 计算与地图边界的交点 + Vector3 fromVec = fromPos.ToVector3(); + Vector3 dirNormalized = direction.normalized; + + // 计算到各个边界的距离 + float tMin = float.MaxValue; + IntVec3? bestEdgePos = null; + + // 检查四个边界 + for (int i = 0; i < 4; i++) + { + float t = 0f; + IntVec3 edgePos = IntVec3.Invalid; - if (!testPos.InBounds(map)) + switch (i) { - // 找到边界,返回最近的有效位置 - IntVec3 edgePos = FindClosestValidPosition(testPos, map); - Log.Message($"Found map edge at {edgePos} (direction: {direction}, distance: {distance})"); - return edgePos; + case 0: // 左边界 (x = 0) + if (Mathf.Abs(dirNormalized.x) > 0.001f) + { + t = (0 - fromVec.x) / dirNormalized.x; + if (t > 0) + { + float z = fromVec.z + dirNormalized.z * t; + if (z >= 0 && z < map.Size.z) + { + edgePos = new IntVec3(0, 0, Mathf.RoundToInt(z)); + } + } + } + break; + + case 1: // 右边界 (x = map.Size.x - 1) + if (Mathf.Abs(dirNormalized.x) > 0.001f) + { + t = (map.Size.x - 1 - fromVec.x) / dirNormalized.x; + if (t > 0) + { + float z = fromVec.z + dirNormalized.z * t; + if (z >= 0 && z < map.Size.z) + { + edgePos = new IntVec3(map.Size.x - 1, 0, Mathf.RoundToInt(z)); + } + } + } + break; + + case 2: // 下边界 (z = 0) + if (Mathf.Abs(dirNormalized.z) > 0.001f) + { + t = (0 - fromVec.z) / dirNormalized.z; + if (t > 0) + { + float x = fromVec.x + dirNormalized.x * t; + if (x >= 0 && x < map.Size.x) + { + edgePos = new IntVec3(Mathf.RoundToInt(x), 0, 0); + } + } + } + break; + + case 3: // 上边界 (z = map.Size.z - 1) + if (Mathf.Abs(dirNormalized.z) > 0.001f) + { + t = (map.Size.z - 1 - fromVec.z) / dirNormalized.z; + if (t > 0) + { + float x = fromVec.x + dirNormalized.x * t; + if (x >= 0 && x < map.Size.x) + { + edgePos = new IntVec3(Mathf.RoundToInt(x), 0, map.Size.z - 1); + } + } + } + break; + } + + // 找到最近的有效边界点 + if (edgePos.IsValid && edgePos.InBounds(map) && t > 0 && t < tMin) + { + tMin = t; + bestEdgePos = edgePos; } } - // 如果没找到边界,使用随机边缘位置 + if (bestEdgePos.HasValue) + { + return bestEdgePos.Value; + } + + // 如果没找到合适的边界点,使用随机边缘位置 Log.Warning($"Could not find map edge in direction {direction}, using random edge"); return GetRandomMapEdgePosition(map); } @@ -510,7 +657,7 @@ namespace ArachnaeSwarm return GetMapEdgePosition(map, GetDirectionFromCasterToTarget(target)); case StartPosition.CustomOffset: - return parent.pawn.Position + Props.customStartOffset; + return GetSafeMapPosition(parent.pawn.Position + Props.customStartOffset, map); case StartPosition.RandomMapEdge: return GetRandomMapEdgePosition(map); @@ -536,7 +683,7 @@ namespace ArachnaeSwarm break; case EndPosition.CustomOffset: - endPos = target.Cell + Props.customEndOffset; + endPos = GetSafeMapPosition(target.Cell + Props.customEndOffset, map); break; case EndPosition.FixedDistance: @@ -553,10 +700,10 @@ namespace ArachnaeSwarm break; } - return endPos; + return GetSafeMapPosition(endPos, map); } - // 原有的辅助方法保持不变 + // 原有的辅助方法 private IntVec3 GetOppositeMapEdgeThroughCenter(Map map, IntVec3 startPos) { IntVec3 center = map.Center; @@ -731,34 +878,6 @@ namespace ArachnaeSwarm Log.Message($"Standard FlyOver created: {flyOver} from {startPos} to {endPos}"); } - private void ShowEffectMessage() - { - string message = GetFlyOverMessage(); - Messages.Message(message, parent.pawn, MessageTypeDefOf.NeutralEvent); - } - - private string GetFlyOverMessage() - { - switch (Props.flyOverType) - { - case FlyOverType.HighAltitude: - return "HighAltitudeReconArrival".Translate(parent.pawn.LabelShort); - case FlyOverType.CargoDrop: - return "CargoDropIncoming".Translate(parent.pawn.LabelShort); - case FlyOverType.BombingRun: - return "BombingRunInitiated".Translate(parent.pawn.LabelShort); - case FlyOverType.Reconnaissance: - return "ReconnaissanceFlyOver".Translate(parent.pawn.LabelShort); - case FlyOverType.GroundStrafing: - return "GroundStrafingIncoming".Translate(parent.pawn.LabelShort); - case FlyOverType.SectorSurveillance: - return "SectorSurveillanceActive".Translate(parent.pawn.LabelShort); - case FlyOverType.Standard: - default: - return "FlyOverInitiated".Translate(parent.pawn.LabelShort); - } - } - // 更新技能提示信息 public override string ExtraLabelMouseAttachment(LocalTargetInfo target) { diff --git a/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs b/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs index 3961b91..4898c18 100644 --- a/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs +++ b/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs @@ -575,7 +575,7 @@ namespace ArachnaeSwarm public float minShadowScale = 0.5f; public float maxShadowScale = 1.0f; public float defaultFadeInDuration = 1.5f; - public float defaultFadeOutDuration = 1.5f; + public float defaultFadeOutDuration = 0.5f; public float fadeOutStartProgress = 0.98f; // 动态淡出配置