diff --git a/1.6/1.6/Assemblies/ArachnaeSwarm.dll b/1.6/1.6/Assemblies/ArachnaeSwarm.dll index 32f0661..4d4fd13 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_Morph.xml b/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml index 34183df..4fd0bfd 100644 --- a/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml +++ b/1.6/1.6/Defs/AbilityDefs/Ability_Morph.xml @@ -72,4 +72,47 @@ + + + ARA_SpawnFlyAttackerTest + + 测试召唤不同类型的飞越物体 + ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph + 1 + Misc12 + false + + Verb_CastAbility + false + false + 1 + 19.9 + true + + false + true + + + +
  • + ARA_HiveCorvette + GroundStrafing + 1 + 20 + true + Perpendicular + + + true + 0.5 + 1 + Bullet_Shell_AntigrainWarhead + 1 + + + true + (1.0,0.3,0.1,0.2) +
  • +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml index 229d196..915db40 100644 --- a/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml +++ b/1.6/1.6/Defs/EvolutionDefs/ARA_Evolution.xml @@ -1537,6 +1537,9 @@ 2 + + 2 + @@ -1635,6 +1638,9 @@
  • 0.01 + + 2 +
  • @@ -1746,6 +1752,9 @@
  • 0.01 + + 2 +
  • diff --git a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Terrain.xml b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Terrain.xml index 393a92a..f2fa529 100644 --- a/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Terrain.xml +++ b/1.6/1.6/Defs/HediffDefs/ARA_Hediffs_Terrain.xml @@ -168,6 +168,174 @@ + + ARA_TerrainAccuracyHediff + + 这只阿拉克捏督虫所着织物使其可以在菌毯上获得更高的射击准度。在菌毯上呆的越久,效果越强,离开菌毯后效果将逐渐衰减。 + HediffWithComps + 1.0 + 0.01 + false + +
  • + 180 + + + + + +
  • ARA_InsectCreep
  • +
  • ARA_InsectCreepFloor
  • +
  • ARA_InsectCreepTile
  • + + + + 0.05 + + + -0.0249 + +
  • + + +
  • + false + 0 + +
  • +
  • + 0.1 + + 0.5 + +
  • +
  • + 0.5 + + 1 + +
  • +
  • + 0.8 + + 2 + +
  • + +
    + + ARA_TerrainCaravanSpeedHediff + + 这只阿拉克捏督虫所着织物使其可以在菌毯上获得更高的远行队速度和贸易能力。在菌毯上呆的越久,效果越强,离开菌毯后效果将以较为缓慢的速度衰减。 + HediffWithComps + 1.0 + 0.01 + false + +
  • + 180 + + + + + +
  • ARA_InsectCreep
  • +
  • ARA_InsectCreepFloor
  • +
  • ARA_InsectCreepTile
  • + + + + 0.05 + + + -0.0005 + +
  • + + +
  • + false + 0 + +
  • +
  • + 0.1 + + 1 + 1.1 + +
  • +
  • + 0.5 + + 2 + 1.25 + +
  • +
  • + 0.8 + + 3 + 1.5 + +
  • + +
    + + ARA_TerrainRestRateHediff + + 这只阿拉克捏督虫所着织物使其可以在菌毯上获得更高的休息速率。在菌毯上呆的越久,效果越强,离开菌毯后效果将逐渐衰减。 + HediffWithComps + 1.0 + 0.01 + false + +
  • + 180 + + + + + +
  • ARA_InsectCreep
  • +
  • ARA_InsectCreepFloor
  • +
  • ARA_InsectCreepTile
  • + + + + 0.05 + + + -0.0249 + +
  • + + +
  • + false + 0 + +
  • +
  • + 0.1 + + 1.1 + +
  • +
  • + 0.5 + + 1.25 + +
  • +
  • + 0.8 + + 1.5 + +
  • + +
    ARA_TerrainHealHediff diff --git a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml index 83f0c16..720f82b 100644 --- a/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml +++ b/1.6/1.6/Defs/ResearchProjectDefs/ARA_ResearchProjects.xml @@ -240,7 +240,7 @@ ARA_Technology_4DIL - + <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许工艺种在织物茧孵化新的织物。 250 1.00 @@ -252,21 +252,9 @@ ARA_Technology_5DIL - + <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许工艺种在织物茧孵化新的织物。 - 800 - 6.50 - 3.80 - ARA_ResearchBench - -
  • ARA_Technology_1WMT
  • -
    -
    - - ARA_Technology_6DIL - - <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许工艺种在织物茧孵化新的织物。 - 800 + 600 5.50 3.80 ARA_ResearchBench @@ -275,25 +263,13 @@ - ARA_Technology_7DIL - + ARA_Technology_6DIL + <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许工艺种在织物茧孵化新的织物。 - 1000 + 1200 10.00 4.80 - ARA_ResearchBench - -
  • ARA_Technology_2WMT
  • -
    -
    - - ARA_Technology_8DIL - - <color=#887E78><i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径,它们奠定了虫群在生物学上的优越性。</i></color>\n\n允许工艺种在织物茧孵化新的织物。 - 1800 - 11.00 - 4.80 - ARA_ResearchBench + ARA_ResearchBench
  • ARA_Technology_2WMT
  • 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 65e180b..bf6e6a2 100644 --- a/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml +++ b/1.6/1.6/Defs/ThingDef_Races/ARA_RaceNodeSwarm.xml @@ -345,6 +345,9 @@
  • ARA_Nurse_Uniform
  • ARA_Bunny_Girl_Uniform
  • ARA_Maid_Uniform
  • +
  • ARA_Maid_Dress
  • +
  • ARA_Daily_Wear
  • +
  • ARA_Nightdress
  • ARA_Bodystocking_White
  • ARA_Bodystocking_Black
  • ARA_Latex_Catsuit
  • 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 71c4230..12e9c8f 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 @@ -15,6 +15,7 @@ (195,195,195,45) + ArachnaeSwarm/Weapon/ARA_Weapon_Empty (0, 0) 0 FlyOver/Flying @@ -22,19 +23,20 @@
  • - ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow - false - + 0 + 0
  • + true false false false - FogOfWar + MetaOverlays
  • @@ -137,8 +139,8 @@ 1 - 15 - 200 + 0 + 100 5 true @@ -153,8 +155,22 @@ true - 0.6 true + + + + 0.3 + 1.2 + + + + true + + 0.2 + 0.6 + + (0.7,0.85,1.0,1.0) + 1.3
  • @@ -166,13 +182,16 @@ RealtimeOnly - ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow + ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow Graphic_Single TransparentPostLight (20,30) (195,195,195,45) + false + 0 + ArachnaeSwarm/Weapon/ARA_Weapon_Empty (0, 0) 0 FlyOver/Flying @@ -180,27 +199,41 @@
  • - ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow - false - + 0 + 0
  • + true false false false - FogOfWar + MetaOverlays + +
  • + Bullet_Shell_AntigrainWarhead + 35 +
  • +
    ARA_HiveShip_Fire_Incoming - (2, 2) + (1, 1) + + Graphic_Single_AgeSecs + ArachnaeSwarm/Item/ARA_HiveShip_Fire_Incoming + (4,4) + MoteGlow + + true - Decelerate + Accelerate Things/Skyfaller/SkyfallerShadowDropPod (2.5, 2.5) 10 @@ -215,4 +248,35 @@ + + Proj_ARA_HiveCorvette + + Projectile_Explosive + Projectile + Normal + Projectile + False + True + + Graphic_Single_AgeSecs + ArachnaeSwarm/Mote/ARA_CatastropheMissile_Shell + (1.25,1.25) + MoteGlow + + + Bomb + 2.9 + 120 + Filth_SpentAcid + 2 + true + 24 + Explosion_EMP + Shell_AcidSpitImpact + 60 + 0.25 + 0.5 + true + + \ No newline at end of file diff --git a/1.6/1.6/Defs/Thing_Misc/Apparels/ARA_Apparel.xml b/1.6/1.6/Defs/Thing_Misc/Apparels/ARA_Apparel.xml index 496fdcc..3d8a328 100644 --- a/1.6/1.6/Defs/Thing_Misc/Apparels/ARA_Apparel.xml +++ b/1.6/1.6/Defs/Thing_Misc/Apparels/ARA_Apparel.xml @@ -280,6 +280,7 @@ 1 + ARA_Maid_Uniform @@ -331,6 +332,109 @@
    + + ARA_Maid_Dress + + 阿拉克涅督虫们所着织物中的一种,设计上典雅古朴,可以使其在阿拉克捏菌毯上稳定身形以获得射击精度,是她们永远服侍虫巢的形象的完美具现化。 + + ARA_Cocoon_Cloth + + + + ARA_Technology_4DIL + UnfinishedArmor + + + 25 + + + ArachnaeSwarm/Apparel/ARA_Maid_Dress + + + +
  • Torso
  • +
  • Shoulders
  • +
  • Arms
  • +
  • Legs
  • +
    + + +
  • Middle
  • +
    + ArachnaeSwarm/Apparel/ARA_Maid_Dress +
    + + + + 10 + 1 + + 0 + +
  • + ARA_TerrainAccuracyHediff +
  • +
  • + +
  • ARA_Cocoon_Cloth
  • +
  • ARA_Cocoon_Cloth_From_Death
  • +
  • ARA_BioforgeIncubator_Thing
  • + + +
    +
    + + ARA_Daily_Wear + + 阿拉克涅督虫们所着织物中的一种,可以使其在阿拉克捏菌毯上获得远行队移动速度,在离开菌毯后缓慢衰减。这套可爱的常服可以和虫群的灵能扭曲效果一起作用于人类,使他们发出“真可爱”的感慨。 + + ARA_Cocoon_Cloth + + + + ARA_Technology_4DIL + UnfinishedArmor + + + 25 + + + ArachnaeSwarm/Apparel/ARA_Daily_Wear + + + +
  • Torso
  • +
  • Shoulders
  • +
  • Arms
  • +
  • Legs
  • +
    + + +
  • Middle
  • +
    + ArachnaeSwarm/Apparel/ARA_Daily_Wear +
    + + + + 10 + 1 + + 0 + +
  • + ARA_TerrainCaravanSpeedHediff +
  • +
  • + +
  • ARA_Cocoon_Cloth
  • +
  • ARA_Cocoon_Cloth_From_Death
  • +
  • ARA_BioforgeIncubator_Thing
  • + + +
    +
    + ARA_Bunny_Girl_Uniform @@ -340,7 +444,7 @@ - ARA_Technology_6DIL + ARA_Technology_5DIL UnfinishedArmor @@ -434,6 +538,59 @@
    + + ARA_Nightdress + + 阿拉克涅督虫们所着织物中的一种,可以使其在阿拉克捏菌毯上获得额外的休息效率速度,睡眠是虫巢少数需要频繁维持的需求,因此这套织物的价值不言而喻。 + + ARA_Cocoon_Cloth_1Stage + ARA_TerrainHeal_Ability + + + + ARA_Technology_5DIL + UnfinishedArmor + + + 25 + + + 50 + 3 + + + ArachnaeSwarm/Apparel/ARA_Nightdress + + + +
  • Torso
  • +
  • Shoulders
  • +
  • Arms
  • +
  • Legs
  • +
    + + +
  • Middle
  • +
    + ArachnaeSwarm/Apparel/ARA_Nightdress +
    + + + 0 + +
  • + ARA_TerrainRestRateHediff +
  • +
  • + +
  • ARA_Cocoon_Cloth_1Stage
  • +
  • ARA_Cocoon_Cloth_1Stage_From_Death
  • +
  • ARA_BioforgeIncubator_Thing
  • + + +
    +
    + ARA_Wedding_Dress @@ -444,7 +601,7 @@ - ARA_Technology_7DIL + ARA_Technology_6DIL UnfinishedArmor @@ -496,7 +653,7 @@ - ARA_Technology_8DIL + ARA_Technology_6DIL UnfinishedArmor diff --git a/1.6/1.6/Defs/Thing_building/ARA_Building.xml b/1.6/1.6/Defs/Thing_building/ARA_Building.xml index 754988a..9dc872e 100644 --- a/1.6/1.6/Defs/Thing_building/ARA_Building.xml +++ b/1.6/1.6/Defs/Thing_building/ARA_Building.xml @@ -122,7 +122,7 @@ 1 - 10 + 0 ConstructMetal 6 diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear.png new file mode 100644 index 0000000..ebd56fa Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_east.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_east.png new file mode 100644 index 0000000..f76a7a3 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_east.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_north.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_north.png new file mode 100644 index 0000000..c3ab0a9 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_north.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_south.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_south.png new file mode 100644 index 0000000..d5ac206 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Daily_Wear_Thin_south.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress.png new file mode 100644 index 0000000..28bad9c Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_east.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_east.png new file mode 100644 index 0000000..d654ae2 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_east.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_north.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_north.png new file mode 100644 index 0000000..462927d Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_north.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_south.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_south.png new file mode 100644 index 0000000..e130cee Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Maid_Dress_Thin_south.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress.png new file mode 100644 index 0000000..6c4c3f6 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_east.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_east.png new file mode 100644 index 0000000..4f90c8b Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_east.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_north.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_north.png new file mode 100644 index 0000000..6923f9f Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_north.png differ diff --git a/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_south.png b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_south.png new file mode 100644 index 0000000..5c40212 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Apparel/ARA_Nightdress_Thin_south.png differ diff --git a/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow.png b/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow.png new file mode 100644 index 0000000..73d0b18 Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow.png differ diff --git a/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow.png b/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow.png index 1a40e74..d5849af 100644 Binary files a/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow.png and b/Content/Textures/ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow.png differ diff --git a/Content/Textures/ArachnaeSwarm/Item/ARA_HiveShip_Fire_Incoming.png b/Content/Textures/ArachnaeSwarm/Item/ARA_HiveShip_Fire_Incoming.png new file mode 100644 index 0000000..4aebc2f Binary files /dev/null and b/Content/Textures/ArachnaeSwarm/Item/ARA_HiveShip_Fire_Incoming.png differ diff --git a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/.suo index a551e25..ad89863 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 3308eeb..d2d7ab9 100644 --- a/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json +++ b/Source/ArachnaeSwarm/.vs/ArachnaeSwarm/v17/DocumentLayout.json @@ -1,25 +1,37 @@ { "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\\flyover\\thingclassflyover.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\\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|e:\\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|e:\\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|e:\\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_flyoverescort\\compflyoverescort.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\\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_flyoverescort\\compproperties_flyoverescort.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\\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}", + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\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}", + "AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|E:\\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}" } ], @@ -39,67 +51,102 @@ { "$type": "Document", "DocumentIndex": 0, + "Title": "CompGroundStrafing.cs", + "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", + "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", + "RelativeToolTip": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs", + "ViewState": "AgIAAB0AAAAAAAAAAAAQwCkAAAAIAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-28T16:19:23.118Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 1, + "Title": "CompAbilityEffect_SpawnFlyOver.cs", + "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs", + "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs*", + "RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs*", + "ViewState": "AgIAAPEAAAAAAAAAAAAawAsBAAAWAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-28T14:51:14.836Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 2, + "Title": "CompProperties_AbilitySpawnFlyOver.cs", + "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", + "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", + "RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAACsAAAAJAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-28T13:51:12.201Z", + "EditorCaption": "" + }, + { + "$type": "Document", + "DocumentIndex": 3, "Title": "ThingclassFlyOver.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs", + "DocumentMoniker": "E:\\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", + "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs", "RelativeToolTip": "Flyover\\ThingclassFlyOver.cs", - "ViewState": "AgIAAAMCAAAAAAAAAAAAABcCAAAeAAAAAAAAAA==", + "ViewState": "AgIAALAAAAAAAAAAAAAWwNQAAAAlAAAAAAAAAA==", "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", "WhenOpened": "2025-10-28T09:09:22.03Z", "EditorCaption": "" }, - { - "$type": "Document", - "DocumentIndex": 1, - "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": "AgIAAAAAAAAAAAAAAAAAAAMAAAAMAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T07:30:55.268Z", - "EditorCaption": "" - }, - { - "$type": "Document", - "DocumentIndex": 2, - "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": "AgIAAAMAAAAAAAAAAAAAABUAAAAjAAAAAAAAAA==", - "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", - "WhenOpened": "2025-10-28T07:30:47.27Z", - "EditorCaption": "" - }, { "$type": "Document", "DocumentIndex": 4, + "Title": "CompFlyOverEscort.cs", + "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", + "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", + "RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs", + "ViewState": "AgIAAKYBAAAAAAAAAAAWwNEBAAAAAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-28T07:30:55.268Z" + }, + { + "$type": "Document", + "DocumentIndex": 5, + "Title": "CompProperties_FlyOverEscort.cs", + "DocumentMoniker": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", + "RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", + "ToolTip": "E:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", + "RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs", + "ViewState": "AgIAAAAAAAAAAAAAAAAAABgAAAAPAAAAAAAAAA==", + "Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|", + "WhenOpened": "2025-10-28T07:30:47.27Z" + }, + { + "$type": "Document", + "DocumentIndex": 7, "Title": "CompProperties_ShipArtillery.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs", + "DocumentMoniker": "E:\\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", + "ToolTip": "E:\\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", - "EditorCaption": "" + "WhenOpened": "2025-10-28T06:21:06.271Z" }, { "$type": "Document", - "DocumentIndex": 3, + "DocumentIndex": 6, "Title": "CompShipArtillery.cs", - "DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs", + "DocumentMoniker": "E:\\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", + "ToolTip": "E:\\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", - "EditorCaption": "" + "WhenOpened": "2025-10-28T06:21:04.222Z" } ] } diff --git a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj index 672f645..5a1c934 100644 --- a/Source/ArachnaeSwarm/ArachnaeSwarm.csproj +++ b/Source/ArachnaeSwarm/ArachnaeSwarm.csproj @@ -140,6 +140,7 @@ + diff --git a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverDropPod/CompProperties_FlyOverDropPod.cs b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverDropPod/CompProperties_FlyOverDropPod.cs index 98ff8f0..85f10a2 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverDropPod/CompProperties_FlyOverDropPod.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverDropPod/CompProperties_FlyOverDropPod.cs @@ -318,7 +318,6 @@ namespace ArachnaeSwarm } IntVec3 dropCenter = GetDropCenter(flyOver); - Log.Message($"DropPods triggered at progress {flyOver.currentProgress}, center: {dropCenter}"); // 如果在投掷时生成 Pawn,现在生成 @@ -330,16 +329,24 @@ namespace ArachnaeSwarm // 准备要投掷的物品列表 List thingsToDrop = new List(); - // 添加预生成的内容物 - thingsToDrop.AddRange(items); - - // 添加生成的 Pawn - thingsToDrop.AddRange(pawns); - - // 如果设置了投掷所有内容物,添加 FlyOver 的内容物 - if (Props.dropAllContents && flyOver.innerContainer != null) + // 添加预生成的内容物(确保不在容器中) + foreach (Thing item in items) { - thingsToDrop.AddRange(flyOver.innerContainer); + if (item.holdingOwner != null) + { + item.holdingOwner.Remove(item); + } + thingsToDrop.Add(item); + } + + // 添加生成的 Pawn(确保不在容器中) + foreach (Pawn pawn in pawns) + { + if (pawn.holdingOwner != null) + { + pawn.holdingOwner.Remove(pawn); + } + thingsToDrop.Add(pawn); } if (!thingsToDrop.Any()) @@ -371,6 +378,10 @@ namespace ArachnaeSwarm } Log.Message($"Drop pods completed: {thingsToDrop.Count} items dropped, including {pawns.Count} pawns"); + + // 清空已投掷的物品列表,避免重复投掷 + items.Clear(); + pawns.Clear(); } // 设置 Pawn 的派系和行为 @@ -499,56 +510,49 @@ namespace ArachnaeSwarm { List> podGroups = new List>(); + // 首先,确保所有物品都不在任何容器中 + foreach (Thing thing in thingsToDrop) + { + if (thing.holdingOwner != null) + { + thing.holdingOwner.Remove(thing); + } + } + if (Props.dropAllInSamePod) { // 所有物品在一个空投仓中,但生成多个相同的空投仓 for (int i = 0; i < Props.dropCount; i++) { - // 为每个空投仓创建新的物品实例 - List podItems = new List(); - foreach (Thing original in thingsToDrop) - { - if (original is Pawn originalPawn) - { - // 对于 Pawn,我们需要重新生成 - Pawn newPawn = GeneratePawn(originalPawn.kindDef); - if (newPawn != null) - { - podItems.Add(newPawn); - } - } - else - { - Thing copy = ThingMaker.MakeThing(original.def, original.Stuff); - copy.stackCount = original.stackCount; - podItems.Add(copy); - } - } + List podItems = CreatePodItemsCopy(thingsToDrop); podGroups.Add(podItems); } } else { - // 将物品分配到多个空投仓中 - List currentPod = new List(); - foreach (Thing thing in thingsToDrop) + // 将原始物品分配到多个空投仓中 + List remainingItems = new List(thingsToDrop); + + for (int i = 0; i < Props.dropCount; i++) { - currentPod.Add(thing); - if (currentPod.Count >= thingsToDrop.Count / Props.dropCount) + List podItems = new List(); + int itemsPerPod = Mathf.CeilToInt((float)remainingItems.Count / (Props.dropCount - i)); + + for (int j = 0; j < itemsPerPod && remainingItems.Count > 0; j++) { - podGroups.Add(currentPod); - currentPod = new List(); + podItems.Add(remainingItems[0]); + remainingItems.RemoveAt(0); } - } - if (currentPod.Any()) - { - podGroups.Add(currentPod); + + podGroups.Add(podItems); } } // 投掷多个空投仓组 foreach (List podGroup in podGroups) { + if (podGroup.Count == 0) continue; + IntVec3 scatterPos = GetScatteredDropPos(dropCenter, map); DropPodUtility.DropThingGroupsNear( scatterPos, @@ -566,6 +570,41 @@ namespace ArachnaeSwarm } } + // 创建物品的深拷贝 + private List CreatePodItemsCopy(List originalItems) + { + List copies = new List(); + + foreach (Thing original in originalItems) + { + if (original is Pawn originalPawn) + { + // 对于 Pawn,重新生成 + Pawn newPawn = GeneratePawn(originalPawn.kindDef); + if (newPawn != null) + { + copies.Add(newPawn); + } + } + else + { + // 对于物品,创建副本 + Thing copy = ThingMaker.MakeThing(original.def, original.Stuff); + copy.stackCount = original.stackCount; + + // 复制其他重要属性 + if (original.def.useHitPoints) + { + copy.HitPoints = original.HitPoints; + } + + copies.Add(copy); + } + } + + return copies; + } + private IntVec3 GetDropCenter(FlyOver flyOver) { // 计算投掷中心位置(基于当前飞行位置 + 偏移) diff --git a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs index a6e7038..51bc83e 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompFlyOverEscort.cs @@ -14,6 +14,9 @@ namespace ArachnaeSwarm private List activeEscorts = new List(); private bool hasInitialized = false; + // 存储每个伴飞的缩放和遮罩数据 + private Dictionary escortVisualData = new Dictionary(); + public override void Initialize(CompProperties props) { base.Initialize(props); @@ -45,7 +48,7 @@ namespace ArachnaeSwarm } // 清理已销毁的伴飞 - activeEscorts.RemoveAll(escort => escort == null || escort.Destroyed || !escort.Spawned); + CleanupDestroyedEscorts(); // 检查是否应该生成新伴飞 if (ShouldSpawnEscort(mainFlyOver)) @@ -63,6 +66,20 @@ namespace ArachnaeSwarm UpdateEscortPositions(mainFlyOver); } + private void CleanupDestroyedEscorts() + { + // 清理已销毁的伴飞 + for (int i = activeEscorts.Count - 1; i >= 0; i--) + { + if (activeEscorts[i] == null || activeEscorts[i].Destroyed || !activeEscorts[i].Spawned) + { + FlyOver removedEscort = activeEscorts[i]; + activeEscorts.RemoveAt(i); + escortVisualData.Remove(removedEscort); + } + } + } + private bool ShouldSpawnEscort(FlyOver mainFlyOver) { if (!mainFlyOver.hasStarted || mainFlyOver.hasCompleted) @@ -83,16 +100,39 @@ namespace ArachnaeSwarm for (int i = 0; i < escortsToSpawn; i++) { - FlyOver escort = CreateEscort(mainFlyOver); + // 先生成视觉数据 + EscortVisualData visualData = GenerateEscortVisualData(); + + FlyOver escort = CreateEscort(mainFlyOver, visualData); if (escort != null) { activeEscorts.Add(escort); - Log.Message($"Spawned escort #{i+1} for FlyOver at {mainFlyOver.DrawPos}"); + escortVisualData[escort] = visualData; + + Log.Message($"Spawned escort #{i+1} for FlyOver at {mainFlyOver.DrawPos}, scale: {visualData.scale:F2}, maskAlpha: {visualData.heightMaskAlpha:F2}"); } } } - private FlyOver CreateEscort(FlyOver mainFlyOver) + private EscortVisualData GenerateEscortVisualData() + { + EscortVisualData data = new EscortVisualData(); + + // 随机生成缩放比例 + data.scale = Props.escortScaleRange.RandomInRange; + + // 根据缩放计算遮罩透明度(小的飞得更高,更透明) + float scaleFactor = Mathf.InverseLerp(Props.escortScaleRange.min, Props.escortScaleRange.max, data.scale); + data.heightMaskAlpha = Mathf.Lerp(Props.heightMaskAlphaRange.max, Props.heightMaskAlphaRange.min, scaleFactor); + + // 计算遮罩缩放 + data.heightMaskScale = data.scale * Props.heightMaskScaleMultiplier; + + return data; + } + + // 修改:添加 visualData 参数 + private FlyOver CreateEscort(FlyOver mainFlyOver, EscortVisualData visualData) { try { @@ -130,8 +170,8 @@ namespace ArachnaeSwarm mainFlyOver.fadeInDuration ); - // 设置伴飞属性 - SetupEscortProperties(escort, mainFlyOver); + // 设置伴飞属性 - 现在传入 visualData + SetupEscortProperties(escort, mainFlyOver, visualData); Log.Message($"Created escort: {escortStart} -> {escortEnd}, speed: {escortSpeed}, altitude: {escortAltitude}"); @@ -235,13 +275,12 @@ namespace ArachnaeSwarm ); } - private void SetupEscortProperties(FlyOver escort, FlyOver mainFlyOver) + // 修改:添加 visualData 参数 + private void SetupEscortProperties(FlyOver escort, FlyOver mainFlyOver, EscortVisualData visualData) { - // 设置缩放 - if (Props.escortScale != 1f) - { - // 这里可能需要通过ModExtension或其他方式设置缩放 - } + // 设置伴飞缩放 - 现在直接从参数获取 + escort.escortScale = visualData.scale; + escort.isEscort = true; // 禁用阴影(如果需要) if (!mainFlyOver.createShadow) @@ -254,6 +293,8 @@ namespace ArachnaeSwarm { escort.playFlyOverSound = false; } + + Log.Message($"Set escort properties: scale={visualData.scale:F2}, isEscort={escort.isEscort}"); } private void UpdateEscortPositions(FlyOver mainFlyOver) @@ -262,6 +303,82 @@ namespace ArachnaeSwarm // 目前伴飞会按照自己的路径飞行 } + // 新增:在绘制时调用 + public override void PostDraw() + { + base.PostDraw(); + DrawEscortHeightMasks(); + } + + // 新增:绘制伴飞的高度遮罩 + public void DrawEscortHeightMasks() + { + if (!Props.useHeightMask || escortVisualData.Count == 0) + return; + + foreach (var kvp in escortVisualData) + { + FlyOver escort = kvp.Key; + EscortVisualData visualData = kvp.Value; + + if (escort == null || escort.Destroyed || !escort.Spawned) + continue; + + DrawHeightMaskForEscort(escort, visualData); + } + } + + private void DrawHeightMaskForEscort(FlyOver escort, EscortVisualData visualData) + { + if (visualData.heightMaskAlpha <= 0.01f) + return; + + // 获取伴飞的绘制位置 + Vector3 drawPos = escort.DrawPos; + drawPos.y = AltitudeLayer.MetaOverlays.AltitudeFor() + 0.01f; // 稍微高于伴飞本身 + + // 计算遮罩矩阵 + Matrix4x4 matrix = Matrix4x4.TRS( + drawPos, + escort.ExactRotation, + new Vector3(visualData.heightMaskScale, 1f, visualData.heightMaskScale) + ); + + // 设置遮罩材质属性 + Material heightMaskMat = GetHeightMaskMaterial(); + if (heightMaskMat != null) + { + // 计算最终颜色和透明度 + Color finalColor = Props.heightMaskColor; + finalColor.a *= visualData.heightMaskAlpha * escort.OverallAlpha; + + var propertyBlock = new MaterialPropertyBlock(); + propertyBlock.SetColor(ShaderPropertyIDs.Color, finalColor); + + // 绘制遮罩 + Graphics.DrawMesh( + MeshPool.plane10, + matrix, + heightMaskMat, + 0, // layer + null, // camera + 0, // submeshIndex + propertyBlock + ); + } + } + + private Material heightMaskMaterial; + private Material GetHeightMaskMaterial() + { + if (heightMaskMaterial == null) + { + // 创建一个简单的圆形遮罩材质 + heightMaskMaterial = MaterialPool.MatFrom("UI/Overlays/SoftShadowCircle", ShaderDatabase.Transparent); + } + return heightMaskMaterial; + } + public override void PostDestroy(DestroyMode mode, Map previousMap) { base.PostDestroy(mode, previousMap); @@ -277,6 +394,7 @@ namespace ArachnaeSwarm } } activeEscorts.Clear(); + escortVisualData.Clear(); } } @@ -286,37 +404,30 @@ namespace ArachnaeSwarm Scribe_Values.Look(ref ticksUntilNextSpawn, "ticksUntilNextSpawn", 0f); Scribe_Collections.Look(ref activeEscorts, "activeEscorts", LookMode.Reference); Scribe_Values.Look(ref hasInitialized, "hasInitialized", false); - } - - public override IEnumerable CompGetGizmosExtra() - { - if (DebugSettings.ShowDevGizmos && parent is FlyOver) + + // 保存视觉数据(如果需要) + if (Scribe.mode == LoadSaveMode.Saving) { - yield return new Command_Action + List keys = new List(escortVisualData.Keys); + List values = new List(escortVisualData.Values); + Scribe_Collections.Look(ref keys, "escortKeys", LookMode.Reference); + Scribe_Collections.Look(ref values, "escortValues", LookMode.Deep); + } + else if (Scribe.mode == LoadSaveMode.LoadingVars) + { + List keys = new List(); + List values = new List(); + Scribe_Collections.Look(ref keys, "escortKeys", LookMode.Reference); + Scribe_Collections.Look(ref values, "escortValues", LookMode.Deep); + + if (keys != null && values != null && keys.Count == values.Count) { - defaultLabel = "Dev: Spawn Escort", - action = () => SpawnEscorts(parent as FlyOver) - }; - - yield return new Command_Action - { - defaultLabel = $"Dev: Escort Status - Active: {activeEscorts.Count}/{Props.maxEscorts}", - action = () => {} - }; - - yield return new Command_Action - { - defaultLabel = "Dev: Clear All Escorts", - action = () => + escortVisualData.Clear(); + for (int i = 0; i < keys.Count; i++) { - foreach (var escort in activeEscorts) - { - if (escort != null && escort.Spawned) - escort.Destroy(); - } - activeEscorts.Clear(); + escortVisualData[keys[i]] = values[i]; } - }; + } } } @@ -334,5 +445,30 @@ namespace ArachnaeSwarm { return activeEscorts.Count; } + + // 新增:获取伴飞的视觉数据 + public EscortVisualData GetEscortVisualData(FlyOver escort) + { + if (escortVisualData.TryGetValue(escort, out var data)) + { + return data; + } + return new EscortVisualData { scale = 1f, heightMaskAlpha = 1f, heightMaskScale = 1f }; + } + } + + // 伴飞视觉数据类 + public class EscortVisualData : IExposable + { + public float scale = 1f; + public float heightMaskAlpha = 1f; + public float heightMaskScale = 1f; + + public void ExposeData() + { + Scribe_Values.Look(ref scale, "scale", 1f); + Scribe_Values.Look(ref heightMaskAlpha, "heightMaskAlpha", 1f); + Scribe_Values.Look(ref heightMaskScale, "heightMaskScale", 1f); + } } } diff --git a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs index 6b23e49..6b66d82 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_FlyOverEscort/CompProperties_FlyOverEscort.cs @@ -1,5 +1,6 @@ using RimWorld; using System.Collections.Generic; +using UnityEngine; using Verse; namespace ArachnaeSwarm @@ -32,9 +33,16 @@ namespace ArachnaeSwarm public bool destroyWithParent = true; // 是否随父级销毁 // 外观配置 - public float escortScale = 1f; // 缩放比例 + public float escortScale = 1f; // 缩放比例(向后兼容) + public FloatRange escortScaleRange = new FloatRange(0.5f, 1.5f); // 缩放比例区间 public bool useParentRotation = true; // 使用父级旋转 + // 新增:高度遮罩配置 + public bool useHeightMask = true; // 是否使用高度遮罩 + public FloatRange heightMaskAlphaRange = new FloatRange(0.3f, 0.8f); // 遮罩透明度区间 + public Color heightMaskColor = new Color(0.8f, 0.9f, 1.0f, 1f); // 遮罩颜色(淡蓝色) + public float heightMaskScaleMultiplier = 1.2f; // 遮罩缩放倍数 + public CompProperties_FlyOverEscort() { compClass = typeof(CompFlyOverEscort); diff --git a/Source/ArachnaeSwarm/Flyover/ARA_GroundStrafing/CompGroundStrafing.cs b/Source/ArachnaeSwarm/Flyover/ARA_GroundStrafing/CompGroundStrafing.cs new file mode 100644 index 0000000..9de3592 --- /dev/null +++ b/Source/ArachnaeSwarm/Flyover/ARA_GroundStrafing/CompGroundStrafing.cs @@ -0,0 +1,191 @@ +using System.Collections.Generic; +using RimWorld; +using UnityEngine; +using Verse; + +namespace ArachnaeSwarm +{ + public class CompGroundStrafing : ThingComp + { + public CompProperties_GroundStrafing Props => (CompProperties_GroundStrafing)props; + + // 简化的扫射状态 - 只存储需要射击的单元格 + private List confirmedTargetCells = new List(); + private HashSet firedCells = new HashSet(); + + public override void PostSpawnSetup(bool respawningAfterLoad) + { + base.PostSpawnSetup(respawningAfterLoad); + + // 简化的初始化日志 + Log.Message($"GroundStrafing: Initialized with {confirmedTargetCells.Count} confirmed targets, Range: {Props.range}"); + } + + public override void CompTick() + { + base.CompTick(); + + if (confirmedTargetCells.Count == 0) + { + return; + } + + // 检查可攻击的目标单元格 + CheckAndFireAtTargets(); + + // 每120 ticks输出一次状态,避免日志过多 + if (Find.TickManager.TicksGame % 120 == 0 && confirmedTargetCells.Count > 0) + { + Log.Message($"GroundStrafing: {firedCells.Count}/{confirmedTargetCells.Count + firedCells.Count} targets fired"); + } + } + + private void CheckAndFireAtTargets() + { + Vector3 currentPos = parent.DrawPos; + + // 检查所有确认的目标单元格 + for (int i = confirmedTargetCells.Count - 1; i >= 0; i--) + { + IntVec3 targetCell = confirmedTargetCells[i]; + + // 跳过已发射过的单元格 + if (firedCells.Contains(targetCell)) + { + confirmedTargetCells.RemoveAt(i); + continue; + } + + // 关键修复:使用水平距离计算,忽略高度差 + float horizontalDistance = GetHorizontalDistance(currentPos, targetCell); + if (horizontalDistance <= Props.range) + { + // 立即发射(不再检查概率,因为已经在预处理阶段决定) + if (LaunchProjectileAt(targetCell)) + { + // 发射成功,标记该单元格 + firedCells.Add(targetCell); + confirmedTargetCells.RemoveAt(i); + + // 调试:输出第一次射击的信息 + if (firedCells.Count == 1) + { + Log.Message($"First strafing shot at {targetCell}, Horizontal distance: {horizontalDistance:F1}"); + } + } + } + } + } + + // 新增:计算水平距离(忽略高度) + private float GetHorizontalDistance(Vector3 fromPos, IntVec3 toCell) + { + Vector2 fromPos2D = new Vector2(fromPos.x, fromPos.z); + Vector2 toPos2D = new Vector2(toCell.x, toCell.z); + return Vector2.Distance(fromPos2D, toPos2D); + } + + // 新增:调试方法,输出距离信息 + private void DebugDistanceInfo(Vector3 currentPos, IntVec3 targetCell) + { + float horizontalDistance = GetHorizontalDistance(currentPos, targetCell); + float fullDistance = Vector3.Distance(currentPos, targetCell.ToVector3()); + + Log.Message($"Distance Debug - Horizontal: {horizontalDistance:F1}, Full: {fullDistance:F1}, " + + $"Range: {Props.range}, Position: {currentPos}, Target: {targetCell}"); + } + + private bool LaunchProjectileAt(IntVec3 targetCell) + { + if (Props.projectileDef == null) + { + Log.Error("No projectile defined for ground strafing"); + return false; + } + + try + { + // 使用 DrawPos 而不是 Position 来生成抛射体 + Vector3 spawnPos = parent.DrawPos; + IntVec3 spawnCell = spawnPos.ToIntVec3(); + + // 创建抛射体 - 使用当前实际位置 + Projectile projectile = (Projectile)GenSpawn.Spawn(Props.projectileDef, spawnCell, parent.Map); + + if (projectile != null) + { + // 获取发射者 + Thing launcher = GetLauncher(); + Vector3 launchPos = parent.DrawPos; + + LocalTargetInfo target = new LocalTargetInfo(targetCell); + + // 发射抛射体 + projectile.Launch( + launcher, + launchPos, + target, + target, + ProjectileHitFlags.IntendedTarget, + false + ); + + return true; + } + } + catch (System.Exception ex) + { + Log.Error($"Error launching ground strafing projectile: {ex}"); + } + + return false; + } + + private Thing GetLauncher() + { + // 如果 FlyOver 有施法者引用,使用施法者,否则使用 FlyOver 自身 + FlyOver flyOver = parent as FlyOver; + if (flyOver != null && flyOver.caster != null) + { + return flyOver.caster; + } + return parent; + } + + // 设置确认的目标单元格(由技能调用,已经过预处理) + public void SetConfirmedTargets(List targets) + { + confirmedTargetCells.Clear(); + firedCells.Clear(); + confirmedTargetCells.AddRange(targets); + + // 只输出关键信息 + Log.Message($"GroundStrafing: Set {confirmedTargetCells.Count} confirmed targets"); + + // 调试:输出一些目标单元格的位置信息 + if (confirmedTargetCells.Count > 0) + { + Log.Message($"First target: {confirmedTargetCells[0]}, Last target: {confirmedTargetCells[confirmedTargetCells.Count - 1]}"); + } + } + + public override void PostExposeData() + { + base.PostExposeData(); + + Scribe_Collections.Look(ref confirmedTargetCells, "confirmedTargetCells", LookMode.Value); + Scribe_Collections.Look(ref firedCells, "firedCells", LookMode.Value); + } + } + + public class CompProperties_GroundStrafing : CompProperties + { + public ThingDef projectileDef; // 抛射体定义 + public float range = 15f; // 射程 + + public CompProperties_GroundStrafing() + { + compClass = typeof(CompGroundStrafing); + } + } +} diff --git a/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs b/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs index 54a0e21..959c559 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompAbilityEffect_SpawnFlyOver.cs @@ -1,5 +1,6 @@ using RimWorld; using System.Collections.Generic; +using System.Linq; using UnityEngine; using Verse; @@ -69,6 +70,9 @@ namespace ArachnaeSwarm default: CreateStandardFlyOver(startPos, endPos); break; + case FlyOverType.GroundStrafing: + CreateGroundStrafingFlyOver(startPos, endPos); + break; } // 显示效果消息 @@ -80,7 +84,225 @@ namespace ArachnaeSwarm } } - // 新增:计算垂直线进场路径 + + // 新增:在目标选择时显示扫射范围预览 + public override void DrawEffectPreview(LocalTargetInfo target) + { + base.DrawEffectPreview(target); + + if (Props.enableGroundStrafing && Props.showStrafePreview && parent.pawn != null && parent.pawn.Map != null) + { + // 计算飞行路径 + IntVec3 startPos, endPos; + if (Props.approachType == ApproachType.Perpendicular) + { + CalculatePerpendicularPath(target, out startPos, out endPos); + } + else + { + startPos = CalculateStartPosition(target); + endPos = CalculateEndPosition(target, startPos); + } + + // 绘制扫射区域预览 + DrawStrafingAreaPreview(startPos, endPos); + } + } + + // 新增:绘制扫射区域预览 + private void DrawStrafingAreaPreview(IntVec3 startPos, IntVec3 endPos) + { + Map map = parent.pawn.Map; + + // 计算飞行方向 + Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized; + if (flightDirection == Vector3.zero) + { + flightDirection = Vector3.forward; + } + // 只计算扫射影响区域的单元格(不是整个飞行路径) + List strafeImpactCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection); + + // 绘制扫射影响区域的预览单元格 + foreach (IntVec3 cell in strafeImpactCells) + { + if (cell.InBounds(map)) + { + // 使用更明显的预览效果 + GenDraw.DrawFieldEdges(new List { cell }, Props.strafePreviewColor, 0.5f); + } + } + + // 绘制飞行路径线(只显示线条,不显示格子) + GenDraw.DrawLineBetween(startPos.ToVector3Shifted(), endPos.ToVector3Shifted(), SimpleColor.Red, 0.2f); + + // 绘制扫射范围边界 + DrawStrafingBoundaries(startPos, endPos, flightDirection); + } + // 新增:计算扫射影响区域的单元格(只计算扫射实际影响的区域,不是整个路径) + private List CalculateStrafingImpactCells(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection) + { + List cells = new List(); + Map map = parent.pawn.Map; + // 计算垂直于飞行方向的方向 + Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized; + // 计算飞行路径的总长度 + float totalPathLength = startPos.DistanceTo(endPos); + // 计算扫射区域的中心点(目标位置附近) + 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); + for (int i = 0; i <= steps; i++) + { + float progress = (float)i / steps; + Vector3 centerPoint = Vector3.Lerp(strafeStart, strafeEnd, progress); + // 在垂直方向扩展扫射宽度 + for (int w = -Props.strafeWidth; w <= Props.strafeWidth; w++) + { + Vector3 offset = perpendicular * w; + Vector3 cellPos = centerPoint + offset; + IntVec3 cell = new IntVec3((int)cellPos.x, (int)cellPos.y, (int)cellPos.z); + if (cell.InBounds(map)) + { + if (!cells.Contains(cell)) + { + cells.Add(cell); + } + } + } + } + // 只输出最终结果 + Log.Message($"Strafing Area: Calculated {cells.Count} impact cells ({Props.strafeWidth * 2 + 1}x{Props.strafeLength})"); + return cells; + } + + + // 新增:绘制扫射范围边界 + private void DrawStrafingBoundaries(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection) + { + Map map = parent.pawn.Map; + Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized; + // 计算飞行路径的总长度 + float totalPathLength = startPos.DistanceTo(endPos); + + // 计算扫射区域的中心点(目标位置附近) + 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; + // 计算扫射区域的四个角 + Vector3 startLeft = strafeStart + perpendicular * Props.strafeWidth; + Vector3 startRight = strafeStart - perpendicular * Props.strafeWidth; + Vector3 endLeft = strafeEnd + perpendicular * Props.strafeWidth; + Vector3 endRight = strafeEnd - perpendicular * Props.strafeWidth; + // 转换为 IntVec3 来使用 ToVector3Shifted + 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); + // 使用带颜色的绘制方法 + 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); + } + + // 新增:预处理扫射目标单元格 + private List PreprocessStrafingTargets(List potentialTargets, float fireChance) + { + List confirmedTargets = new List(); + foreach (IntVec3 cell in potentialTargets) + { + // 使用概率决定这个单元格是否会被射击 + if (Rand.Value <= fireChance) + { + confirmedTargets.Add(cell); + } + } + // 只输出预处理结果 + Log.Message($"Strafing Preprocess: {confirmedTargets.Count}/{potentialTargets.Count} cells confirmed ({fireChance:P0} chance)"); + return confirmedTargets; + } + // 修改后的创建地面扫射飞越方法 + private void CreateGroundStrafingFlyOver(IntVec3 startPos, IntVec3 endPos) + { + ThingDef flyOverDef = Props.flyOverDef ?? DefDatabase.GetNamedSilentFail("ARA_HiveCorvette"); + if (flyOverDef == null) + { + Log.Warning("No fly over def specified for ground strafing fly over"); + return; + } + FlyOver flyOver = FlyOver.MakeFlyOver( + flyOverDef, + startPos, + endPos, + parent.pawn.Map, + Props.flightSpeed, + Props.altitude, + casterPawn: parent.pawn + ); + // 设置基本属性 + flyOver.spawnContentsOnImpact = Props.dropContentsOnImpact; + flyOver.playFlyOverSound = Props.playFlyOverSound; + // 获取扫射组件并设置预处理后的目标单元格 + CompGroundStrafing strafingComp = flyOver.GetComp(); + if (strafingComp != null) + { + // 计算扫射区域的所有单元格 + Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized; + List potentialTargetCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection); + if (potentialTargetCells.Count > 0) + { + // 预处理:根据概率筛选实际会被射击的单元格 + List confirmedTargetCells = PreprocessStrafingTargets( + potentialTargetCells, + Props.strafeFireChance + ); + if (confirmedTargetCells.Count > 0) + { + strafingComp.SetConfirmedTargets(confirmedTargetCells); + } + else + { + Log.Warning("No confirmed target cells after preprocessing!"); + } + } + else + { + Log.Error("No potential target cells calculated for ground strafing!"); + } + } + else + { + Log.Error("FlyOver def does not have CompGroundStrafing component!"); + } + } + + // 新增:获取扫射区域描述(用于技能提示) + public override string ExtraLabelMouseAttachment(LocalTargetInfo target) + { + if (Props.enableGroundStrafing) + { + string projectileInfo = Props.strafeProjectile != null ? + $"抛射体: {Props.strafeProjectile.label}" : + "抛射体: 无"; + + return $"扫射区域: {Props.strafeWidth * 2 + 1}x{Props.strafeLength} 单元格\n{projectileInfo}"; + } + return base.ExtraLabelMouseAttachment(target); + } + + + + // 原有的其他方法保持不变... private void CalculatePerpendicularPath(LocalTargetInfo target, out IntVec3 startPos, out IntVec3 endPos) { Map map = parent.pawn.Map; @@ -123,7 +345,6 @@ namespace ArachnaeSwarm Log.Message($"Perpendicular path: {startPos} -> {targetPos} -> {endPos}"); } - // 新增:在指定方向上找到地图边缘 private IntVec3 FindMapEdgeInDirection(Map map, IntVec3 fromPos, Vector3 direction) { // 计算最大搜索距离(地图对角线的一半) @@ -151,7 +372,6 @@ namespace ArachnaeSwarm return GetRandomMapEdgePosition(map); } - // 原有的位置计算方法 private IntVec3 CalculateStartPosition(LocalTargetInfo target) { Map map = parent.pawn.Map; @@ -211,7 +431,7 @@ namespace ArachnaeSwarm return endPos; } - // 原有的辅助方法保持不变 + // 原有的辅助方法保持不变... private IntVec3 GetOppositeMapEdgeThroughCenter(Map map, IntVec3 startPos) { IntVec3 center = map.Center; @@ -404,6 +624,8 @@ namespace ArachnaeSwarm 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.Standard: default: return "FlyOverInitiated".Translate(parent.pawn.LabelShort); diff --git a/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompProperties_AbilitySpawnFlyOver.cs b/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompProperties_AbilitySpawnFlyOver.cs index f975d7f..a87737a 100644 --- a/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompProperties_AbilitySpawnFlyOver.cs +++ b/Source/ArachnaeSwarm/Flyover/ARA_SpawnFlyOver/CompProperties_AbilitySpawnFlyOver.cs @@ -1,6 +1,7 @@ using RimWorld; using System.Collections.Generic; using Verse; +using UnityEngine; namespace ArachnaeSwarm { @@ -16,16 +17,27 @@ namespace ArachnaeSwarm public bool dropContentsOnImpact = true; // 是否在终点投放内容物 public SoundDef customSound; // 自定义音效 public bool playFlyOverSound = true; // 是否播放飞越音效 - + // 起始位置选项(当approachType为Standard时使用) public StartPosition startPosition = StartPosition.Caster; public IntVec3 customStartOffset = IntVec3.Zero; - + // 终点位置选项(当approachType为Standard时使用) public EndPosition endPosition = EndPosition.TargetCell; public IntVec3 customEndOffset = IntVec3.Zero; public int flyOverDistance = 30; // 飞越距离(当终点为自定义时) - + + // 新增:简化的地面扫射配置 + public bool enableGroundStrafing = false; // 是否启用地面扫射 + public int strafeWidth = 3; // 扫射宽度(垂直于飞行方向的单元格数) + public int strafeLength = 15; // 扫射长度(沿着飞行方向的单元格数) + public float strafeFireChance = 0.7f; // 扫射发射概率(用于预处理) + public ThingDef strafeProjectile; // 抛射体定义(用于后续攻击) + + // 新增:扫射可视化 + public bool showStrafePreview = true; // 是否显示扫射预览 + public Color strafePreviewColor = new Color(1f, 0.3f, 0.3f, 0.3f); // 扫射预览颜色 + public CompProperties_AbilitySpawnFlyOver() { this.compClass = typeof(CompAbilityEffect_SpawnFlyOver); @@ -39,10 +51,11 @@ namespace ArachnaeSwarm HighAltitude, // 高空飞越 CargoDrop, // 货运飞越 BombingRun, // 轰炸飞越 - Reconnaissance // 侦察飞越 + Reconnaissance, // 侦察飞越 + GroundStrafing // 地面扫射 } - // 新增:进场类型枚举 + // 进场类型枚举 public enum ApproachType { Standard, // 标准进场(使用原有的位置计算) diff --git a/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs b/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs index 3407018..b29d2b6 100644 --- a/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs +++ b/Source/ArachnaeSwarm/Flyover/ThingclassFlyOver.cs @@ -29,6 +29,10 @@ namespace ArachnaeSwarm public bool fadeOutCompleted = false; // 淡出是否完成 public float fadeOutStartProgress = 0.7f; // 开始淡出的进度阈值(0-1) public float defaultFadeOutDuration = 1.5f; // 默认淡出持续时间(仅用于销毁) + + // 伴飞相关 + public float escortScale = 1f; // 伴飞缩放比例 + public bool isEscort = false; // 是否是伴飞 // 状态标志 public bool hasStarted = false; @@ -46,6 +50,8 @@ namespace ArachnaeSwarm public bool spawnContentsOnImpact = false; // 是否在结束时生成内容物 public bool playFlyOverSound = true; // 是否播放飞越音效 public bool createShadow = true; // 是否创建阴影 + + public Pawn caster; // 施法者引用 // 属性 public override Vector3 DrawPos @@ -195,6 +201,8 @@ namespace ArachnaeSwarm Scribe_Values.Look(ref fadeOutCompleted, "fadeOutCompleted", false); Scribe_Values.Look(ref fadeOutStartProgress, "fadeOutStartProgress", 0.7f); Scribe_Values.Look(ref defaultFadeOutDuration, "defaultFadeOutDuration", 1.5f); + + Scribe_References.Look(ref caster, "caster"); } public override void SpawnSetup(Map map, bool respawningAfterLoad) @@ -391,9 +399,10 @@ namespace ArachnaeSwarm } } - // 绘制方法保持不变,使用OverallAlpha + // 关键修复:重写 DrawAt 方法,绕过探索状态检查 protected override void DrawAt(Vector3 drawLoc, bool flip = false) { + // 直接绘制,不检查探索状态 Vector3 finalDrawPos = drawLoc; if (createShadow) @@ -408,41 +417,50 @@ namespace ArachnaeSwarm { Thing thingForGraphic = GetThingForGraphic(); Graphic graphic = thingForGraphic.Graphic; - if (graphic == null) return; - Material material = graphic.MatSingle; if (material == null) return; - float alpha = OverallAlpha; - if (alpha <= 0.001f) return; - if (fadeInCompleted && !fadeOutStarted && alpha >= 0.999f) { Vector3 highAltitudePos = drawPos; highAltitudePos.y = AltitudeLayer.MetaOverlays.AltitudeFor(); - graphic.Draw(highAltitudePos, Rot4.North, thingForGraphic, ExactRotation.eulerAngles.y); + + // 应用伴飞缩放 + Vector3 finalScale = Vector3.one; + if (def.graphicData != null) + { + finalScale = new Vector3(def.graphicData.drawSize.x * escortScale, 1f, def.graphicData.drawSize.y * escortScale); + } + else + { + finalScale = new Vector3(escortScale, 1f, escortScale); + } + + Matrix4x4 matrix = Matrix4x4.TRS(highAltitudePos, ExactRotation, finalScale); + Graphics.DrawMesh(MeshPool.plane10, matrix, material, 0); return; } - fadePropertyBlock.SetColor(ShaderPropertyIDs.Color, new Color(graphic.Color.r, graphic.Color.g, graphic.Color.b, graphic.Color.a * alpha)); - + // 应用伴飞缩放 Vector3 scale = Vector3.one; if (def.graphicData != null) { - scale = new Vector3(def.graphicData.drawSize.x, 1f, def.graphicData.drawSize.y); + scale = new Vector3(def.graphicData.drawSize.x * escortScale, 1f, def.graphicData.drawSize.y * escortScale); + } + else + { + scale = new Vector3(escortScale, 1f, escortScale); } - Vector3 highPos = drawPos; highPos.y = AltitudeLayer.MetaOverlays.AltitudeFor(); - - Matrix4x4 matrix = Matrix4x4.TRS(highPos, ExactRotation, scale); - Graphics.DrawMesh(MeshPool.plane10, matrix, material, 0, null, 0, fadePropertyBlock); + Matrix4x4 matrix2 = Matrix4x4.TRS(highPos, ExactRotation, scale); + Graphics.DrawMesh(MeshPool.plane10, matrix2, material, 0, null, 0, fadePropertyBlock); } protected virtual void DrawFlightShadow() @@ -486,7 +504,7 @@ namespace ArachnaeSwarm Graphics.DrawMesh(MeshPool.plane10, matrix, shadowMaterial, 0); } - // IThingHolder 接口实现和其他方法保持不变 + // IThingHolder 接口实现 public ThingOwner GetDirectlyHeldThings() { return innerContainer; @@ -509,7 +527,7 @@ namespace ArachnaeSwarm // 工具方法:创建飞越物体 public static FlyOver MakeFlyOver(ThingDef flyOverDef, IntVec3 start, IntVec3 end, Map map, float speed = 1f, float height = 10f, ThingOwner contents = null, - float fadeInDuration = 1.5f, float defaultFadeOutDuration = 1.5f) + float fadeInDuration = 1.5f, float defaultFadeOutDuration = 1.5f, Pawn casterPawn = null) { FlyOver flyOver = (FlyOver)ThingMaker.MakeThing(flyOverDef); flyOver.startPosition = start; @@ -518,6 +536,7 @@ namespace ArachnaeSwarm flyOver.altitude = height; flyOver.fadeInDuration = fadeInDuration; flyOver.defaultFadeOutDuration = defaultFadeOutDuration; + flyOver.caster = casterPawn; if (contents != null) { @@ -529,11 +548,9 @@ namespace ArachnaeSwarm Log.Message($"FlyOver created: {flyOver} from {start} to {end} at altitude {height}"); return flyOver; } - - // 其他工具方法... } - // 更新的 ModExtension,添加淡出配置 + // ModExtension 配置 public class FlyOverShadowExtension : DefModExtension { public string customShadowPath; @@ -544,13 +561,13 @@ 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 = 1.5f; public float fadeOutStartProgress = 0.98f; - // 新增:动态淡出配置 - public float minFadeOutDuration = 0.5f; // 最小淡出持续时间 - public float maxFadeOutDuration = 3f; // 最大淡出持续时间 - public float fadeOutDistanceFactor = 0.3f; // 淡出距离因子(剩余时间的百分比) + // 动态淡出配置 + public float minFadeOutDuration = 0.5f; + public float maxFadeOutDuration = 0.5f; + public float fadeOutDistanceFactor = 0.01f; public float ActuallyHeight = 150f; } diff --git a/非公开资源/Content/Textures/FlyOverThing/ARA_HiveCorvette_Shadow.sai2 b/非公开资源/Content/Textures/FlyOverThing/ARA_HiveCorvette_Shadow.sai2 new file mode 100644 index 0000000..331fe29 Binary files /dev/null and b/非公开资源/Content/Textures/FlyOverThing/ARA_HiveCorvette_Shadow.sai2 differ diff --git a/非公开资源/Content/Textures/FlyOverThing/ARA_HiveShip_Shadow.sai2 b/非公开资源/Content/Textures/FlyOverThing/ARA_HiveShip_Shadow.sai2 index d162184..64b050f 100644 Binary files a/非公开资源/Content/Textures/FlyOverThing/ARA_HiveShip_Shadow.sai2 and b/非公开资源/Content/Textures/FlyOverThing/ARA_HiveShip_Shadow.sai2 differ