近地支援

This commit is contained in:
Tourswen
2025-10-29 02:03:33 +08:00
parent 8c4924144a
commit 9118e6ee58
36 changed files with 1305 additions and 211 deletions

Binary file not shown.

View File

@@ -72,4 +72,47 @@
</li>
</comps>
</AbilityDef>
<!-- 能力定义 -->
<AbilityDef>
<defName>ARA_SpawnFlyAttackerTest</defName>
<label>召唤攻击机物体</label>
<description>测试召唤不同类型的飞越物体</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<drawAimPie>false</drawAimPie>
<requireLineOfSight>false</requireLineOfSight>
<warmupTime>1</warmupTime>
<range>19.9</range>
<targetable>true</targetable>
<targetParams>
<canTargetSelf>false</canTargetSelf>
<canTargetLocations>true</canTargetLocations>
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AbilitySpawnFlyOver">
<flyOverDef>ARA_HiveCorvette</flyOverDef>
<flyOverType>GroundStrafing</flyOverType>
<flightSpeed>1</flightSpeed>
<altitude>20</altitude>
<playFlyOverSound>true</playFlyOverSound>
<approachType>Perpendicular</approachType>
<!-- 扫射参数 -->
<enableGroundStrafing>true</enableGroundStrafing>
<strafeWidth>0.5</strafeWidth>
<strafeLength>1</strafeLength>
<strafeProjectile>Bullet_Shell_AntigrainWarhead</strafeProjectile>
<strafeFireChance>1</strafeFireChance>
<!-- 可视化 -->
<showStrafePreview>true</showStrafePreview>
<strafePreviewColor>(1.0,0.3,0.1,0.2)</strafePreviewColor>
</li>
</comps>
</AbilityDef>
</Defs>

View File

@@ -1537,6 +1537,9 @@
<statOffsets>
<MoveSpeed>2</MoveSpeed>
</statOffsets>
<statFactors>
<CaravanBonusSpeedFactor>2</CaravanBonusSpeedFactor>
</statFactors>
</li>
</stages>
<comps>
@@ -1635,6 +1638,9 @@
<stages>
<li>
<minSeverity>0.01</minSeverity>
<statFactors>
<CaravanBonusSpeedFactor>2</CaravanBonusSpeedFactor>
</statFactors>
</li>
</stages>
<comps>
@@ -1746,6 +1752,9 @@
<stages>
<li>
<minSeverity>0.01</minSeverity>
<statFactors>
<CaravanBonusSpeedFactor>2</CaravanBonusSpeedFactor>
</statFactors>
</li>
</stages>
<comps>

View File

@@ -168,6 +168,174 @@
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_TerrainAccuracyHediff</defName>
<label>菌毯加成:射击准度</label>
<description>这只阿拉克捏督虫所着织物使其可以在菌毯上获得更高的射击准度。在菌毯上呆的越久,效果越强,离开菌毯后效果将逐渐衰减。</description>
<hediffClass>HediffWithComps</hediffClass>
<maxSeverity>1.0</maxSeverity>
<minSeverity>0.01</minSeverity>
<isBad>false</isBad>
<comps>
<li Class="ArachnaeSwarm.HediffCompProperties_TerrainBasedSeverity">
<interval>180</interval>
<!-- 目标地形列表 -->
<terrainDefs>
<!--<li>SterileTile</li> 无菌地砖 -->
<!-- 您可以在这里添加更多地形, 比如: -->
<li>ARA_InsectCreep</li>
<li>ARA_InsectCreepFloor</li>
<li>ARA_InsectCreepTile</li>
</terrainDefs>
<!-- 站在目标地形上时,每次检查的严重性变化量 -->
<severityOnTerrain>0.05</severityOnTerrain>
<!-- 不在目标地形上时,每次检查的严重性变化量 (负数表示减少) -->
<severityOffTerrain>-0.0249</severityOffTerrain>
</li>
<li Class="HediffCompProperties_RemoveIfApparelDropped" />
</comps>
<stages>
<li>
<becomeVisible>false</becomeVisible>
<minSeverity>0</minSeverity>
<label></label>
</li>
<li>
<minSeverity>0.1</minSeverity>
<statOffsets>
<ShootingAccuracyPawn>0.5</ShootingAccuracyPawn>
</statOffsets>
</li>
<li>
<minSeverity>0.5</minSeverity>
<statOffsets>
<ShootingAccuracyPawn>1</ShootingAccuracyPawn>
</statOffsets>
</li>
<li>
<minSeverity>0.8</minSeverity>
<statOffsets>
<ShootingAccuracyPawn>2</ShootingAccuracyPawn>
</statOffsets>
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_TerrainCaravanSpeedHediff</defName>
<label>菌毯加成:远行队强化</label>
<description>这只阿拉克捏督虫所着织物使其可以在菌毯上获得更高的远行队速度和贸易能力。在菌毯上呆的越久,效果越强,离开菌毯后效果将以较为缓慢的速度衰减。</description>
<hediffClass>HediffWithComps</hediffClass>
<maxSeverity>1.0</maxSeverity>
<minSeverity>0.01</minSeverity>
<isBad>false</isBad>
<comps>
<li Class="ArachnaeSwarm.HediffCompProperties_TerrainBasedSeverity">
<interval>180</interval>
<!-- 目标地形列表 -->
<terrainDefs>
<!--<li>SterileTile</li> 无菌地砖 -->
<!-- 您可以在这里添加更多地形, 比如: -->
<li>ARA_InsectCreep</li>
<li>ARA_InsectCreepFloor</li>
<li>ARA_InsectCreepTile</li>
</terrainDefs>
<!-- 站在目标地形上时,每次检查的严重性变化量 -->
<severityOnTerrain>0.05</severityOnTerrain>
<!-- 不在目标地形上时,每次检查的严重性变化量 (负数表示减少) -->
<severityOffTerrain>-0.0005</severityOffTerrain>
</li>
<li Class="HediffCompProperties_RemoveIfApparelDropped" />
</comps>
<stages>
<li>
<becomeVisible>false</becomeVisible>
<minSeverity>0</minSeverity>
<label></label>
</li>
<li>
<minSeverity>0.1</minSeverity>
<statFactors>
<CaravanBonusSpeedFactor>1</CaravanBonusSpeedFactor>
<TradePriceImprovement>1.1</TradePriceImprovement>
</statFactors>
</li>
<li>
<minSeverity>0.5</minSeverity>
<statFactors>
<CaravanBonusSpeedFactor>2</CaravanBonusSpeedFactor>
<TradePriceImprovement>1.25</TradePriceImprovement>
</statFactors>
</li>
<li>
<minSeverity>0.8</minSeverity>
<statFactors>
<CaravanBonusSpeedFactor>3</CaravanBonusSpeedFactor>
<TradePriceImprovement>1.5</TradePriceImprovement>
</statFactors>
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_TerrainRestRateHediff</defName>
<label>菌毯加成:休息速率</label>
<description>这只阿拉克捏督虫所着织物使其可以在菌毯上获得更高的休息速率。在菌毯上呆的越久,效果越强,离开菌毯后效果将逐渐衰减。</description>
<hediffClass>HediffWithComps</hediffClass>
<maxSeverity>1.0</maxSeverity>
<minSeverity>0.01</minSeverity>
<isBad>false</isBad>
<comps>
<li Class="ArachnaeSwarm.HediffCompProperties_TerrainBasedSeverity">
<interval>180</interval>
<!-- 目标地形列表 -->
<terrainDefs>
<!--<li>SterileTile</li> 无菌地砖 -->
<!-- 您可以在这里添加更多地形, 比如: -->
<li>ARA_InsectCreep</li>
<li>ARA_InsectCreepFloor</li>
<li>ARA_InsectCreepTile</li>
</terrainDefs>
<!-- 站在目标地形上时,每次检查的严重性变化量 -->
<severityOnTerrain>0.05</severityOnTerrain>
<!-- 不在目标地形上时,每次检查的严重性变化量 (负数表示减少) -->
<severityOffTerrain>-0.0249</severityOffTerrain>
</li>
<li Class="HediffCompProperties_RemoveIfApparelDropped" />
</comps>
<stages>
<li>
<becomeVisible>false</becomeVisible>
<minSeverity>0</minSeverity>
<label></label>
</li>
<li>
<minSeverity>0.1</minSeverity>
<statFactors>
<RestRateMultiplier>1.1</RestRateMultiplier>
</statFactors>
</li>
<li>
<minSeverity>0.5</minSeverity>
<statFactors>
<RestRateMultiplier>1.25</RestRateMultiplier>
</statFactors>
</li>
<li>
<minSeverity>0.8</minSeverity>
<statFactors>
<RestRateMultiplier>1.5</RestRateMultiplier>
</statFactors>
</li>
</stages>
</HediffDef>
<HediffDef>
<defName>ARA_TerrainHealHediff</defName>

View File

@@ -240,7 +240,7 @@
<!-- 织物发展 -->
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_4DIL</defName>
<label>节点DIL-4"女仆"</label>
<label>节点DIL-4"初级织物"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许工艺种在织物茧孵化新的织物。</description>
<baseCost>250</baseCost>
<researchViewX>1.00</researchViewX>
@@ -252,21 +252,9 @@
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_5DIL</defName>
<label>节点DIL-5"护士"</label>
<label>节点DIL-5"中级织物"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许工艺种在织物茧孵化新的织物。</description>
<baseCost>800</baseCost>
<researchViewX>6.50</researchViewX>
<researchViewY>3.80</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding>
<prerequisites>
<li>ARA_Technology_1WMT</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_6DIL</defName>
<label>节点DIL-6"兔女郎"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许工艺种在织物茧孵化新的织物。</description>
<baseCost>800</baseCost>
<baseCost>600</baseCost>
<researchViewX>5.50</researchViewX>
<researchViewY>3.80</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding>
@@ -275,25 +263,13 @@
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_7DIL</defName>
<label>节点DIL-7"花嫁"</label>
<defName>ARA_Technology_6DIL</defName>
<label>节点DIL-6"高级织物"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许工艺种在织物茧孵化新的织物。</description>
<baseCost>1000</baseCost>
<baseCost>1200</baseCost>
<researchViewX>10.00</researchViewX>
<researchViewY>4.80</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding> <!-- ARA_MorphableResearchBench-->
<prerequisites>
<li>ARA_Technology_2WMT</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_8DIL</defName>
<label>节点DIL-8"卫兵"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许工艺种在织物茧孵化新的织物。</description>
<baseCost>1800</baseCost>
<researchViewX>11.00</researchViewX>
<researchViewY>4.80</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding> <!-- ARA_MorphableResearchBench-->
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding>
<prerequisites>
<li>ARA_Technology_2WMT</li>
</prerequisites>

View File

@@ -345,6 +345,9 @@
<li>ARA_Nurse_Uniform</li>
<li>ARA_Bunny_Girl_Uniform</li>
<li>ARA_Maid_Uniform</li>
<li>ARA_Maid_Dress</li>
<li>ARA_Daily_Wear</li>
<li>ARA_Nightdress</li>
<li>ARA_Bodystocking_White</li>
<li>ARA_Bodystocking_Black</li>
<li>ARA_Latex_Catsuit</li>

View File

@@ -15,6 +15,7 @@
<color>(195,195,195,45)</color>
</graphicData>
<skyfaller>
<shadow>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</shadow>
<shadowSize>(0, 0)</shadowSize>
<motesPerCell>0</motesPerCell>
<floatingSound>FlyOver/Flying</floatingSound>
@@ -22,19 +23,20 @@
</skyfaller>
<modExtensions>
<li Class="ArachnaeSwarm.FlyOverShadowExtension">
<customShadowPath>ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow</customShadowPath>
<useCustomShadow>false</useCustomShadow>
<!-- <shadowIntensity>0.8</shadowIntensity>
<customShadowPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</customShadowPath>
<useCustomShadow>true</useCustomShadow>
<shadowIntensity>0.8</shadowIntensity>
<minShadowAlpha>0</minShadowAlpha>
<maxShadowAlpha>0</maxShadowAlpha>
<minShadowScale>15</minShadowScale>
<maxShadowScale>15</maxShadowScale> -->
<minShadowScale>0</minShadowScale>
<maxShadowScale>0</maxShadowScale>
</li>
</modExtensions>
<seeThroughFog>true</seeThroughFog>
<useHitPoints>false</useHitPoints>
<selectable>false</selectable>
<alwaysHaulable>false</alwaysHaulable>
<altitudeLayer>FogOfWar</altitudeLayer>
<altitudeLayer>MetaOverlays</altitudeLayer>
<comps>
<!-- 入场信封信息 -->
<li Class="ArachnaeSwarm.CompProperties_SendLetterAfterTicks">
@@ -137,8 +139,8 @@
<spawnCount>1</spawnCount>
<!-- 位置配置 -->
<spawnDistance>15</spawnDistance>
<lateralOffset>200</lateralOffset>
<spawnDistance>0</spawnDistance>
<lateralOffset>100</lateralOffset>
<verticalOffset>5</verticalOffset>
<useRandomOffset>true</useRandomOffset>
@@ -153,8 +155,22 @@
<continuousSpawning>true</continuousSpawning>
<!-- 外观配置 -->
<escortScale>0.6</escortScale>
<useParentRotation>true</useParentRotation>
<!-- 缩放区间配置 -->
<escortScaleRange>
<min>0.3</min>
<max>1.2</max>
</escortScaleRange>
<!-- 高度遮罩配置 -->
<useHeightMask>true</useHeightMask>
<heightMaskAlphaRange>
<min>0.2</min>
<max>0.6</max>
</heightMaskAlphaRange>
<heightMaskColor>(0.7,0.85,1.0,1.0)</heightMaskColor>
<heightMaskScaleMultiplier>1.3</heightMaskScaleMultiplier>
</li>
</comps>
</ThingDef>
@@ -166,13 +182,16 @@
<drawerType>RealtimeOnly</drawerType>
<graphicData>
<!-- <texPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</texPath> -->
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow</texPath>
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(20,30)</drawSize>
<color>(195,195,195,45)</color>
</graphicData>
<castEdgeShadows>false</castEdgeShadows>
<staticSunShadowHeight>0</staticSunShadowHeight>
<skyfaller>
<shadow>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</shadow>
<shadowSize>(0, 0)</shadowSize>
<motesPerCell>0</motesPerCell>
<floatingSound>FlyOver/Flying</floatingSound>
@@ -180,27 +199,41 @@
</skyfaller>
<modExtensions>
<li Class="ArachnaeSwarm.FlyOverShadowExtension">
<customShadowPath>ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow</customShadowPath>
<useCustomShadow>false</useCustomShadow>
<!-- <shadowIntensity>0.8</shadowIntensity>
<customShadowPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</customShadowPath>
<useCustomShadow>true</useCustomShadow>
<shadowIntensity>0.8</shadowIntensity>
<minShadowAlpha>0</minShadowAlpha>
<maxShadowAlpha>0</maxShadowAlpha>
<minShadowScale>15</minShadowScale>
<maxShadowScale>15</maxShadowScale> -->
<minShadowScale>0</minShadowScale>
<maxShadowScale>0</maxShadowScale>
</li>
</modExtensions>
<seeThroughFog>true</seeThroughFog>
<useHitPoints>false</useHitPoints>
<selectable>false</selectable>
<alwaysHaulable>false</alwaysHaulable>
<altitudeLayer>FogOfWar</altitudeLayer>
<altitudeLayer>MetaOverlays</altitudeLayer>
<comps>
<li Class="ArachnaeSwarm.CompProperties_GroundStrafing">
<projectileDef>Bullet_Shell_AntigrainWarhead</projectileDef>
<range>35</range>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
<defName>ARA_HiveShip_Fire_Incoming</defName>
<label>天灾酸烧炮炮弹(虫巢母舰)</label>
<size>(2, 2)</size>
<size>(1, 1)</size>
<graphicData>
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
<texPath>ArachnaeSwarm/Item/ARA_HiveShip_Fire_Incoming</texPath>
<drawSize>(4,4)</drawSize>
<shaderType>MoteGlow</shaderType>
</graphicData>
<seeThroughFog>true</seeThroughFog>
<skyfaller>
<movementType>Decelerate</movementType>
<movementType>Accelerate</movementType>
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
<shadowSize>(2.5, 2.5)</shadowSize>
<explosionRadius>10</explosionRadius>
@@ -215,4 +248,35 @@
</angleCurve>
</skyfaller>
</ThingDef>
<ThingDef>
<defName>Proj_ARA_HiveCorvette</defName>
<label>天巫酸团</label>
<thingClass>Projectile_Explosive</thingClass>
<category>Projectile</category>
<tickerType>Normal</tickerType>
<altitudeLayer>Projectile</altitudeLayer>
<useHitPoints>False</useHitPoints>
<neverMultiSelect>True</neverMultiSelect>
<graphicData>
<graphicClass>Graphic_Single_AgeSecs</graphicClass>
<texPath>ArachnaeSwarm/Mote/ARA_CatastropheMissile_Shell</texPath>
<drawSize>(1.25,1.25)</drawSize>
<shaderType>MoteGlow</shaderType>
</graphicData>
<projectile>
<damageDef>Bomb</damageDef>
<explosionRadius>2.9</explosionRadius>
<speed>120</speed>
<filth>Filth_SpentAcid</filth>
<filthCount>2</filthCount>
<explosionSpawnsSingleFilth>true</explosionSpawnsSingleFilth>
<damageAmountBase>24</damageAmountBase>
<soundExplode>Explosion_EMP</soundExplode>
<explosionEffect>Shell_AcidSpitImpact</explosionEffect>
<explosionEffectLifetimeTicks>60</explosionEffectLifetimeTicks>
<armorPenetrationBase>0.25</armorPenetrationBase>
<screenShakeFactor>0.5</screenShakeFactor>
<flyOverhead>true</flyOverhead>
</projectile>
</ThingDef>
</Defs>

View File

@@ -280,6 +280,7 @@
<StuffEffectMultiplierInsulation_Heat>1</StuffEffectMultiplierInsulation_Heat>
</statBases>
</ThingDef>
<!-- T1 -->
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Maid_Uniform</defName>
<label>阿拉克涅女仆装</label>
@@ -331,6 +332,109 @@
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Maid_Dress</defName>
<label>阿拉克涅武装女仆装</label>
<description>阿拉克涅督虫们所着织物中的一种,设计上典雅古朴,可以使其在阿拉克捏菌毯上稳定身形以获得射击精度,是她们永远服侍虫巢的形象的完美具现化。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_4DIL</researchPrerequisite>
<unfinishedThingDef>UnfinishedArmor</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
<ARA_Carapace>25</ARA_Carapace>
</costList>
<graphicData>
<texPath>ArachnaeSwarm/Apparel/ARA_Maid_Dress</texPath>
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
<li>Middle</li>
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Maid_Dress</wornGraphicPath>
</apparel>
<equippedStatOffsets>
</equippedStatOffsets>
<statBases>
<ARA_IncubationCost>10</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<costStuffCount>0</costStuffCount>
<comps>
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainAccuracyHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDefs>
<li>ARA_Cocoon_Cloth</li>
<li>ARA_Cocoon_Cloth_From_Death</li>
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Daily_Wear</defName>
<label>阿拉克涅常服</label>
<description>阿拉克涅督虫们所着织物中的一种,可以使其在阿拉克捏菌毯上获得远行队移动速度,在离开菌毯后缓慢衰减。这套可爱的常服可以和虫群的灵能扭曲效果一起作用于人类,使他们发出“真可爱”的感慨。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth</ThingDef>
</descriptionHyperlinks>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_4DIL</researchPrerequisite>
<unfinishedThingDef>UnfinishedArmor</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
<ARA_Carapace>25</ARA_Carapace>
</costList>
<graphicData>
<texPath>ArachnaeSwarm/Apparel/ARA_Daily_Wear</texPath>
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
<li>Middle</li>
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Daily_Wear</wornGraphicPath>
</apparel>
<equippedStatOffsets>
</equippedStatOffsets>
<statBases>
<ARA_IncubationCost>10</ARA_IncubationCost>
<ARA_IncubationTime>1</ARA_IncubationTime>
</statBases>
<costStuffCount>0</costStuffCount>
<comps>
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainCaravanSpeedHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDefs>
<li>ARA_Cocoon_Cloth</li>
<li>ARA_Cocoon_Cloth_From_Death</li>
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
</comps>
</ThingDef>
<!-- T2 -->
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Bunny_Girl_Uniform</defName>
<label>阿拉克涅兔女郎装</label>
@@ -340,7 +444,7 @@
</descriptionHyperlinks>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_6DIL</researchPrerequisite>
<researchPrerequisite>ARA_Technology_5DIL</researchPrerequisite>
<unfinishedThingDef>UnfinishedArmor</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
@@ -434,6 +538,59 @@
</li>
</comps>
</ThingDef>
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Nightdress</defName>
<label>阿拉克涅睡裙</label>
<description>阿拉克涅督虫们所着织物中的一种,可以使其在阿拉克捏菌毯上获得额外的休息效率速度,睡眠是虫巢少数需要频繁维持的需求,因此这套织物的价值不言而喻。</description>
<descriptionHyperlinks>
<ThingDef>ARA_Cocoon_Cloth_1Stage</ThingDef>
<AbilityDef>ARA_TerrainHeal_Ability</AbilityDef>
</descriptionHyperlinks>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_5DIL</researchPrerequisite>
<unfinishedThingDef>UnfinishedArmor</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
<ARA_Carapace>25</ARA_Carapace>
</costList>
<statBases>
<ARA_IncubationCost>50</ARA_IncubationCost>
<ARA_IncubationTime>3</ARA_IncubationTime>
</statBases>
<graphicData>
<texPath>ArachnaeSwarm/Apparel/ARA_Nightdress</texPath>
</graphicData>
<apparel>
<bodyPartGroups>
<li>Torso</li>
<li>Shoulders</li>
<li>Arms</li>
<li>Legs</li>
</bodyPartGroups>
<layers>
<!-- <li>OnSkin</li> -->
<li>Middle</li>
</layers>
<wornGraphicPath>ArachnaeSwarm/Apparel/ARA_Nightdress</wornGraphicPath>
</apparel>
<equippedStatOffsets>
</equippedStatOffsets>
<costStuffCount>0</costStuffCount>
<comps>
<li Class="CompProperties_CauseHediff_Apparel">
<hediff>ARA_TerrainRestRateHediff</hediff>
</li>
<li Class="ArachnaeSwarm.CompProperties_ExtraIncubationInfo">
<cocoonDefs>
<li>ARA_Cocoon_Cloth_1Stage</li>
<li>ARA_Cocoon_Cloth_1Stage_From_Death</li>
<li>ARA_BioforgeIncubator_Thing</li>
</cocoonDefs>
</li>
</comps>
</ThingDef>
<!-- T3 -->
<ThingDef ParentName="ARA_ClothBase">
<defName>ARA_Wedding_Dress</defName>
<label>阿拉克涅花嫁连衣裙</label>
@@ -444,7 +601,7 @@
</descriptionHyperlinks>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_7DIL</researchPrerequisite>
<researchPrerequisite>ARA_Technology_6DIL</researchPrerequisite>
<unfinishedThingDef>UnfinishedArmor</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">
@@ -496,7 +653,7 @@
</descriptionHyperlinks>
<recipeMaker>
<recipeUsers Inherit="False" />
<researchPrerequisite>ARA_Technology_8DIL</researchPrerequisite>
<researchPrerequisite>ARA_Technology_6DIL</researchPrerequisite>
<unfinishedThingDef>UnfinishedArmor</unfinishedThingDef>
</recipeMaker>
<costList Inherit="False">

View File

@@ -122,7 +122,7 @@
<costList>
<ARA_Carapace>1</ARA_Carapace>
</costList>
<pathCost>10</pathCost>
<pathCost>0</pathCost>
<constructEffect>ConstructMetal</constructEffect>
<constructionSkillPrerequisite>6</constructionSkillPrerequisite>
<researchPrerequisites>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 58 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 44 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB

View File

@@ -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"
}
]
}

View File

@@ -140,6 +140,7 @@
<Compile Include="EventSystem\QuestNode_Root_EventLetter.cs" />
<Compile Include="Flyover\ARA_FlyOverEscort\CompFlyOverEscort.cs" />
<Compile Include="Flyover\ARA_FlyOverEscort\CompProperties_FlyOverEscort.cs" />
<Compile Include="Flyover\ARA_GroundStrafing\CompGroundStrafing.cs" />
<Compile Include="Flyover\ARA_SendLetterAfterTicks\CompProperties_SendLetterAfterTicks.cs" />
<Compile Include="Flyover\ARA_SendLetterAfterTicks\CompSendLetterAfterTicks.cs" />
<Compile Include="Flyover\ARA_ShipArtillery\CompProperties_ShipArtillery.cs" />

View File

@@ -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<Thing> thingsToDrop = new List<Thing>();
// 添加预生成的内容物
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<List<Thing>> podGroups = new List<List<Thing>>();
// 首先,确保所有物品都不在任何容器中
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<Thing> podItems = new List<Thing>();
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<Thing> podItems = CreatePodItemsCopy(thingsToDrop);
podGroups.Add(podItems);
}
}
else
{
// 将物品分配到多个空投仓中
List<Thing> currentPod = new List<Thing>();
foreach (Thing thing in thingsToDrop)
// 将原始物品分配到多个空投仓中
List<Thing> remainingItems = new List<Thing>(thingsToDrop);
for (int i = 0; i < Props.dropCount; i++)
{
currentPod.Add(thing);
if (currentPod.Count >= thingsToDrop.Count / Props.dropCount)
List<Thing> podItems = new List<Thing>();
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<Thing>();
podItems.Add(remainingItems[0]);
remainingItems.RemoveAt(0);
}
}
if (currentPod.Any())
{
podGroups.Add(currentPod);
podGroups.Add(podItems);
}
}
// 投掷多个空投仓组
foreach (List<Thing> podGroup in podGroups)
{
if (podGroup.Count == 0) continue;
IntVec3 scatterPos = GetScatteredDropPos(dropCenter, map);
DropPodUtility.DropThingGroupsNear(
scatterPos,
@@ -566,6 +570,41 @@ namespace ArachnaeSwarm
}
}
// 创建物品的深拷贝
private List<Thing> CreatePodItemsCopy(List<Thing> originalItems)
{
List<Thing> copies = new List<Thing>();
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)
{
// 计算投掷中心位置(基于当前飞行位置 + 偏移)

View File

@@ -14,6 +14,9 @@ namespace ArachnaeSwarm
private List<FlyOver> activeEscorts = new List<FlyOver>();
private bool hasInitialized = false;
// 存储每个伴飞的缩放和遮罩数据
private Dictionary<FlyOver, EscortVisualData> escortVisualData = new Dictionary<FlyOver, EscortVisualData>();
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<Gizmo> CompGetGizmosExtra()
{
if (DebugSettings.ShowDevGizmos && parent is FlyOver)
// 保存视觉数据(如果需要)
if (Scribe.mode == LoadSaveMode.Saving)
{
yield return new Command_Action
List<FlyOver> keys = new List<FlyOver>(escortVisualData.Keys);
List<EscortVisualData> values = new List<EscortVisualData>(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<FlyOver> keys = new List<FlyOver>();
List<EscortVisualData> values = new List<EscortVisualData>();
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);
}
}
}

View File

@@ -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);

View File

@@ -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<IntVec3> confirmedTargetCells = new List<IntVec3>();
private HashSet<IntVec3> firedCells = new HashSet<IntVec3>();
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<IntVec3> 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);
}
}
}

View File

@@ -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<IntVec3> strafeImpactCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection);
// 绘制扫射影响区域的预览单元格
foreach (IntVec3 cell in strafeImpactCells)
{
if (cell.InBounds(map))
{
// 使用更明显的预览效果
GenDraw.DrawFieldEdges(new List<IntVec3> { cell }, Props.strafePreviewColor, 0.5f);
}
}
// 绘制飞行路径线(只显示线条,不显示格子)
GenDraw.DrawLineBetween(startPos.ToVector3Shifted(), endPos.ToVector3Shifted(), SimpleColor.Red, 0.2f);
// 绘制扫射范围边界
DrawStrafingBoundaries(startPos, endPos, flightDirection);
}
// 新增:计算扫射影响区域的单元格(只计算扫射实际影响的区域,不是整个路径)
private List<IntVec3> CalculateStrafingImpactCells(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection)
{
List<IntVec3> cells = new List<IntVec3>();
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<IntVec3> PreprocessStrafingTargets(List<IntVec3> potentialTargets, float fireChance)
{
List<IntVec3> confirmedTargets = new List<IntVec3>();
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<ThingDef>.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<CompGroundStrafing>();
if (strafingComp != null)
{
// 计算扫射区域的所有单元格
Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized;
List<IntVec3> potentialTargetCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection);
if (potentialTargetCells.Count > 0)
{
// 预处理:根据概率筛选实际会被射击的单元格
List<IntVec3> 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);

View File

@@ -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, // 标准进场(使用原有的位置计算)

View File

@@ -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;
}