This commit is contained in:
2025-10-30 11:43:20 +08:00
parent a3fb539bbe
commit f969798670
22 changed files with 1067 additions and 476 deletions

Binary file not shown.

View File

@@ -3,7 +3,7 @@
<AbilityDef>
<defName>ARA_SpawnFlyOverTest</defName>
<label>母舰召唤</label>
<description>召唤虫巢母舰,启动攻击事件链(测试用)</description>
<description>召唤虫巢母舰,启动虫群入侵终局事件链(测试用,乱用后果自负</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
@@ -35,8 +35,8 @@
<AbilityDef>
<defName>ARA_Spawn_ARA_HiveCorvette_Rocket</defName>
<label>天巫巡航:酸烧炮扫射</label>
<description>召唤天巫种兽虫,高速掠过战场,使用其迅捷天灾炮对目标区域发起打击。\n\n在飞行期间它会使用血链棘刺炮打击遇到的敌人由于攻击区间较少血链棘刺炮只能打击前7个遇到的目标。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph</iconPath>
<description>引航种指挥阿拉克涅天巫种兽虫,高速掠过战场,使用其附带阿拉克涅虫酸效果的迅捷天灾炮对目标区域发起打击。\n\n在飞行期间它会使用血链棘刺炮打击遇到的敌人由于攻击区间较少血链棘刺炮只能打击前7个遇到的目标。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Rocket</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
@@ -53,6 +53,11 @@
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AircraftStrike">
<requiredAircraftType>ARA_HiveCorvette_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks> <!-- 2小时冷却 -->
<aircraftsPerUse>1</aircraftsPerUse>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilitySpawnFlyOver">
<flyOverDef>ARA_HiveCorvette</flyOverDef>
<flyOverType>GroundStrafing</flyOverType>
@@ -77,7 +82,6 @@
<!-- 预览配置 -->
<showSectorPreview>true</showSectorPreview>
<strafeWidth>4</strafeWidth> <!-- 用于预览的近似宽度 -->
<sectorPreviewColor>(0.3,0.7,1.0,0.3)</sectorPreviewColor>
</li>
</comps>
@@ -85,8 +89,8 @@
<AbilityDef>
<defName>ARA_Spawn_ARA_HiveCorvette_Bombardment</defName>
<label>天巫巡航:酸液轰炸</label>
<description>召唤天巫种兽虫,慢速掠过战场,对大范围目标区域进行酸团轰炸。\n\n在飞行期间它会使用血链棘刺炮打击遇到的所有敌人。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Ability_Morph</iconPath>
<description>引航种指挥阿拉克涅天巫种兽虫,慢速掠过战场,对大范围目标区域进行附带阿拉克涅虫酸效果的酸团轰炸。\n\n在飞行期间它会使用高伤害、高穿甲能力的血链棘刺炮打击遇到的所有敌人。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Bombardment</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
<casterMustBeCapableOfViolence>false</casterMustBeCapableOfViolence>
@@ -105,7 +109,7 @@
<comps>
<li Class="ArachnaeSwarm.CompProperties_AircraftStrike">
<requiredAircraftType>ARA_HiveCorvette_Entity</requiredAircraftType>
<aircraftCooldownTicks>120</aircraftCooldownTicks> <!-- 2冷却 -->
<aircraftCooldownTicks>5000</aircraftCooldownTicks> <!-- 2小时冷却 -->
<aircraftsPerUse>1</aircraftsPerUse>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilitySpawnFlyOver">
@@ -131,6 +135,49 @@
<showStrafePreview>true</showStrafePreview>
<strafePreviewColor>(1.0,0.3,0.1,0.2)</strafePreviewColor>
<!-- 预览配置 -->
<showSectorPreview>true</showSectorPreview>
<sectorPreviewColor>(0.3,0.7,1.0,0.3)</sectorPreviewColor>
</li>
</comps>
</AbilityDef>
<AbilityDef>
<defName>ARA_Spawn_ARA_HiveCorvette_Strike</defName>
<label>天巫巡航:血棘监视</label>
<description>引航种指挥阿拉克涅天巫种兽虫,缓慢掠过战场,使用高伤害、高穿甲能力的血链棘刺炮打击遇到的所有敌人。该攻击模式下天巫种视野较为狭小,难以打击整个集群。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Strike</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>120</range>
<targetable>true</targetable>
<targetParams>
<canTargetSelf>false</canTargetSelf>
<canTargetLocations>true</canTargetLocations>
</targetParams>
</verbProperties>
<comps>
<li Class="ArachnaeSwarm.CompProperties_AircraftStrike">
<requiredAircraftType>ARA_HiveCorvette_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks> <!-- 2小时冷却 -->
<aircraftsPerUse>1</aircraftsPerUse>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilitySpawnFlyOver">
<flyOverDef>ARA_HiveCorvette_Strike</flyOverDef>
<flyOverType>GroundStrafing</flyOverType>
<flightSpeed>1</flightSpeed>
<altitude>20</altitude>
<playFlyOverSound>true</playFlyOverSound>
<approachType>Perpendicular</approachType>
<!-- 只传递信号,不传递具体参数 -->
<enableSectorSurveillance>true</enableSectorSurveillance>
<!-- 预览配置 -->
<showSectorPreview>true</showSectorPreview>
<strafeWidth>4</strafeWidth> <!-- 用于预览的近似宽度 -->

View File

@@ -1814,13 +1814,78 @@
<li>ARA_Praetorian_jump</li>
<li>ARA_Praetorian_Commander_Ability_On</li>
<li>ARA_Praetorian_Commander_Ability_Off</li>
<li>ARA_Praetorian_Navigator</li>
</abilityDefs>
</li>
<!-- <li Class="HediffCompProperties_RemoveIfOtherHediff">
<li Class="HediffCompProperties_RemoveIfOtherHediff">
<hediffs>
<li>ARA_Skyraider_Hivelord</li>
<li>ARA_Praetorian_Navigator</li>
</hediffs>
</li> -->
</li>
</comps>
</HediffDef>
<AbilityDef>
<defName>ARA_Praetorian_Navigator</defName>
<label>禁卫种转换——引航灯塔</label>
<description>使禁卫种发生内驱性进化,以牺牲射击能力、跳跃能力、指挥能力为代价,使其换取指挥空中兽虫的能力。\n\n该进化过程不可逆另外空中兽虫必须成功升空才能进行指挥——在你解锁这个进化路径时应该还不能建造空中兽虫。</description>
<iconPath>ArachnaeSwarm/UI/Abilities/ARA_Praetorian_Navigator</iconPath>
<cooldownTicksRange>1800</cooldownTicksRange>
<hostile>false</hostile>
<groupAbility>true</groupAbility>
<displayGizmoWhileUndrafted>true</displayGizmoWhileUndrafted>
<disableGizmoWhileUndrafted>false</disableGizmoWhileUndrafted>
<aiCanUse>false</aiCanUse>
<ai_IsOffensive>true</ai_IsOffensive>
<targetRequired>false</targetRequired>
<jobDef>CastAbilityOnThing</jobDef>
<verbProperties>
<verbClass>Verb_CastAbility</verbClass>
<range>1</range>
<warmupTime>12</warmupTime>
<soundCast>AcidSpray_Resolve</soundCast>
<violent>false</violent>
<targetable>false</targetable>
<targetParams>
<canTargetSelf>True</canTargetSelf>
</targetParams>
</verbProperties>
<comps>
<li Class="CompProperties_AbilityGiveHediff">
<compClass>CompAbilityEffect_GiveHediff</compClass>
<hediffDef>ARA_Praetorian_Navigator</hediffDef>
<onlyApplyToSelf>True</onlyApplyToSelf>
<replaceExisting>true</replaceExisting>
<severity>1</severity>
</li>
<li Class="ArachnaeSwarm.CompProperties_AbilityResearchPrereq">
<requiredResearch>ARA_Technology_9NAV</requiredResearch>
<failMessage>需要科技 节点NAV-9"领航使者" 以解锁进化</failMessage>
</li>
</comps>
</AbilityDef>
<HediffDef>
<defName>ARA_Praetorian_Navigator</defName>
<label>亚种-引航种</label>
<description>这只阿拉克涅禁卫种已经获得拔耀,虽然失去了直接的战斗能力,但是可以指挥空中兽虫,以虫群绝对的空中优势碾压敌军。</description>
<hediffClass>HediffWithComps</hediffClass>
<defaultLabelColor>(0.6, 0.4, 0.8)</defaultLabelColor>
<isBad>false</isBad>
<scenarioCanAdd>false</scenarioCanAdd>
<maxSeverity>1.0</maxSeverity>
<stages>
<li>
<minSeverity>0</minSeverity>
</li>
</stages>
<comps>
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>ARA_SpawnFlyOverTest</li>
<li>ARA_Spawn_ARA_HiveCorvette_Rocket</li>
<li>ARA_Spawn_ARA_HiveCorvette_Bombardment</li>
<li>ARA_HiveCorvette_Strike</li>
</abilityDefs>
</li>
</comps>
</HediffDef>
</Defs>

View File

@@ -702,6 +702,18 @@
<li>ARA_Technology_6GUT</li>
</prerequisites>
</ResearchProjectDef>
<ResearchProjectDef ParentName="ARA_techBase_Needtechprint">
<defName>ARA_Technology_9NAV</defName>
<label>节点NAV-9"领航使者"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许禁卫种进行定向进化抛弃直接战斗能力和指挥地面虫群部队的能力换取指挥空中兽虫群的能力。\n\n阿拉克涅虫群所有需要蓝图的科技其蓝图只能通过女皇种的基因试验卵获取。</description>
<baseCost>3500</baseCost>
<researchViewX>11.00</researchViewX>
<researchViewY>3.80</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding>
<prerequisites>
<li>ARA_Technology_7KYC</li>
</prerequisites>
</ResearchProjectDef>
<!-- 改造发展 -->
<ResearchProjectDef ParentName="ARA_techBase">
<defName>ARA_Technology_1EVO</defName>
@@ -814,7 +826,7 @@
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许实行新的阿拉克涅进化手术允许阿拉克涅虫族以丧失自愈能力为代价摆脱寿命的限制。</description>
<baseCost>4000</baseCost>
<researchViewX>11.00</researchViewX>
<researchViewY>3.80</researchViewY>
<researchViewY>2.10</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding> <!-- ARA_MorphableResearchBench-->
<hiddenPrerequisites>
<li>ARA_Technology_5ESS</li>
@@ -844,11 +856,24 @@
<label>节点SYM-2"霜结体"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许阿拉克涅虫族建造特殊的活体建筑——阿拉克涅共生肌群一种可以和督虫融合的无意识组织体能为督虫提供强大的战斗力。\n\n霜结体共生肌群可以支持与其融合的阿拉克涅督虫使用多种急冻类武装可以在控制大范围人群和快速点杀高价值目标间切换。</description>
<baseCost>4000</baseCost>
<researchViewX>12.00</researchViewX>
<researchViewX>11.00</researchViewX>
<researchViewY>4.30</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding> <!-- ARA_MorphableResearchBench-->
<prerequisites>
<li>ARA_Technology_8EVO</li>
</prerequisites>
</ResearchProjectDef>
<!-- 兽虫发展 -->
<ResearchProjectDef ParentName="ARA_techBase_Needtechprint">
<defName>ARA_Technology_4COV</defName>
<label>节点COV-4"天巫兽群"</label>
<description>&lt;color=#887E78>&lt;i>阿拉克涅虫群-主巢触须\n主巢触须的进化路径是包含于每一支虫群中的通用进化路径它们奠定了虫群在生物学上的优越性。&lt;/i>&lt;/color>\n\n允许阿拉克涅虫族建造特殊的活体建筑——天巫种兽虫一种由引航种指挥的半自主个体能依据指令灵活地从天上袭击敌军以降下死亡之雨。</description>
<baseCost>3000</baseCost>
<researchViewX>12.00</researchViewX>
<researchViewY>3.80</researchViewY>
<requiredResearchBuilding>ARA_ResearchBench</requiredResearchBuilding> <!-- ARA_MorphableResearchBench-->
<prerequisites>
<li>ARA_Technology_9NAV</li>
</prerequisites>
</ResearchProjectDef>
</Defs>

View File

@@ -3,23 +3,24 @@
<ThingDef ParentName="BuildingBase">
<defName>ARA_HiveCorvette_Building</defName>
<label>天巫种兽虫</label>
<description>天巫种兽虫</description>
<thingClass>Building_PassengerShuttle</thingClass>
<description>天巫种兽虫是阿拉克涅虫群舰队中的对地攻击机,它们长长的触须和强大的灵能悬浮能力使得它们可以在引航种的指挥下高速掠过战场,并依据指令打击不长眼的敌军集群或援助虫群的进攻。\n\n它们需要起飞才能发挥效果</description>
<thingClass>Building</thingClass>
<preventDroppingThingsOn>true</preventDroppingThingsOn>
<altitudeLayer>Building</altitudeLayer>
<pathCost>50</pathCost>
<blockWind>true</blockWind>
<passability>PassThroughOnly</passability>
<fillPercent>0.5</fillPercent>
<size>(5,5)</size>
<fillPercent>1</fillPercent>
<size>(6,14)</size>
<drawHighlight>true</drawHighlight>
<highlightColor>(0.56, 0.62, 0.9)</highlightColor>
<uiIconScale>1</uiIconScale>
<uiIconPath>ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving</uiIconPath>
<graphicData>
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow</texPath>
<texPath>ArachnaeSwarm/Building/ARA_HiveCorvetteB</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(5,5)</drawSize>
<drawSize>(5,16)</drawSize>
<color>(195,195,195,255)</color>
</graphicData>
<statBases>
@@ -33,10 +34,10 @@
<designationCategory>ARA_Buildings</designationCategory>
<constructionSkillPrerequisite>6</constructionSkillPrerequisite>
<costList>
<Steel>250</Steel>
<Plasteel>150</Plasteel>
<ComponentIndustrial>6</ComponentIndustrial>
<ShuttleEngine>1</ShuttleEngine>
<ARA_Carapace>500</ARA_Carapace>
<Plasteel>250</Plasteel>
<ARA_Activated_Bacterium>100</ARA_Activated_Bacterium>
<ARA_Gene_Essence>100</ARA_Gene_Essence>
</costList>
<canOverlapZones>true</canOverlapZones>
<killedLeavings>
@@ -51,6 +52,9 @@
<drawerType>RealtimeOnly</drawerType>
<repairEffect>ConstructMetal</repairEffect>
<forceDebugSpawnable>true</forceDebugSpawnable>
<researchPrerequisites>
<li>ARA_Technology_4COV</li>
</researchPrerequisites>
<building>
<destroySound>BuildingDestroyed_Metal_Big</destroySound>
<paintable>true</paintable>
@@ -60,7 +64,7 @@
<li Class="ArachnaeSwarm.CompProperties_AircraftHangar">
<aircraftDef>ARA_HiveCorvette_Entity</aircraftDef>
<aircraftCount>1</aircraftCount>
<skyfallerLeaving>PassengerShuttleLeaving</skyfallerLeaving>
<skyfallerLeaving>ARA_HiveCorvette_Leaving</skyfallerLeaving>
</li>
</comps>
<placeWorkers>
@@ -72,6 +76,54 @@
<defName>ARA_HiveCorvette_Entity</defName>
<label>天巫种兽虫</label>
<description>什么这是个记录数量用的thingdef你不应该在任何场合下看到这个。</description>
<thingClass>Thing</thingClass>
</ThingDef>
<ThingDef ParentName="SkyfallerBase" Name="DropPodLeaving">
<defName>ARA_HiveCorvette_Leaving</defName>
<label>天巫种兽虫 (起飞中)</label>
<thingClass>FlyShipLeaving</thingClass>
<skyfaller>
<reversed>true</reversed>
<anticipationSound>Shuttle_Leaving</anticipationSound>
<anticipationSoundTicks>-10</anticipationSoundTicks>
<ticksToImpactRange>-40~-15</ticksToImpactRange>
<moteSpawnTime>0.05</moteSpawnTime>
<shadow>Things/Skyfaller/SkyfallerShadowRectangle</shadow>
<shadowSize>(5.5,3.5)</shadowSize>
<motesPerCell>1</motesPerCell>
<angleCurve>
<points>
<li>(0,90)</li>
<li>(1,110)</li>
</points>
</angleCurve>
<rotationCurve>
<points>
<li>(0,0)</li>
<li>(0,10)</li>
</points>
</rotationCurve>
<zPositionCurve>
<points>
<li>(0,0)</li>
<li>(0.08,2)</li>
</points>
</zPositionCurve>
<speedCurve>
<points>
<li>(0,0.2)</li>
<li>(0.4,0.7)</li>
</points>
</speedCurve>
</skyfaller>
<graphicData>
<texPath>ArachnaeSwarm/Building/ARA_HiveCorvetteB_Leaving</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(16,5)</drawSize>
<color>(195,195,195,255)</color>
</graphicData>
<altitudeLayer>MetaOverlays</altitudeLayer>
</ThingDef>
<ThingDef Parent="EtherealThingBase">
@@ -209,7 +261,7 @@
<!-- 生成配置 -->
<spawnIntervalTicks>250</spawnIntervalTicks> <!-- 5秒 -->
<maxEscorts>60</maxEscorts>
<maxEscorts>30</maxEscorts>
<spawnCount>1</spawnCount>
<!-- 位置配置 -->
@@ -217,6 +269,136 @@
<lateralOffset>100</lateralOffset>
<verticalOffset>5</verticalOffset>
<useRandomOffset>true</useRandomOffset>
<minSafeDistanceBetweenEscorts>10</minSafeDistanceBetweenEscorts> <!-- 伴飞物之间的距离 -->
<minSafeDistanceFromMain>70</minSafeDistanceFromMain> <!-- 与主飞行物的距离检查 -->
<!-- 飞行配置 -->
<escortSpeedMultiplier>20</escortSpeedMultiplier> <!-- 比主舰稍快 -->
<escortAltitudeOffset>10</escortAltitudeOffset> <!-- 比主舰稍高 -->
<mirrorMovement>false</mirrorMovement>
<!-- 行为配置 -->
<spawnOnStart>true</spawnOnStart>
<destroyWithParent>false</destroyWithParent>
<continuousSpawning>true</continuousSpawning>
<!-- 外观配置 -->
<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>
<!-- 伴飞 -->
<li Class="ArachnaeSwarm.CompProperties_FlyOverEscort">
<escortFlyOverDef>ARA_HiveShip_Fake</escortFlyOverDef>
<!-- 生成配置 -->
<spawnIntervalTicks>3000</spawnIntervalTicks> <!-- 5秒 -->
<maxEscorts>3</maxEscorts>
<spawnCount>1</spawnCount>
<!-- 位置配置 -->
<spawnDistance>20</spawnDistance>
<lateralOffset>380</lateralOffset>
<verticalOffset>5</verticalOffset>
<useRandomOffset>true</useRandomOffset>
<minSafeDistanceBetweenEscorts>25</minSafeDistanceBetweenEscorts> <!-- 伴飞物之间的距离 -->
<minSafeDistanceFromMain>100</minSafeDistanceFromMain> <!-- 与主飞行物的距离检查 -->
<!-- 飞行配置 -->
<escortSpeedMultiplier>1</escortSpeedMultiplier> <!-- 比主舰稍快 -->
<escortAltitudeOffset>10</escortAltitudeOffset> <!-- 比主舰稍高 -->
<mirrorMovement>false</mirrorMovement>
<!-- 行为配置 -->
<spawnOnStart>true</spawnOnStart>
<destroyWithParent>true</destroyWithParent>
<continuousSpawning>true</continuousSpawning>
<!-- 外观配置 -->
<useParentRotation>true</useParentRotation>
<!-- 缩放区间配置 -->
<escortScaleRange>
<min>0.3</min>
<max>0.5</max>
</escortScaleRange>
<!-- 高度遮罩配置 -->
<useHeightMask>true</useHeightMask>
<heightMaskAlphaRange>
<min>0.3</min>
<max>0.6</max>
</heightMaskAlphaRange>
<heightMaskColor>(0.7,0.85,1.0,1.0)</heightMaskColor>
<heightMaskScaleMultiplier>1.3</heightMaskScaleMultiplier>
</li>
</comps>
</ThingDef>
<ThingDef Parent="EtherealThingBase">
<defName>ARA_HiveShip_Fake</defName>
<label>虫巢母舰</label>
<thingClass>ArachnaeSwarm.FlyOver</thingClass>
<tickerType>Normal</tickerType>
<drawerType>RealtimeOnly</drawerType>
<graphicData>
<!-- <texPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</texPath> -->
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveShip_Shadow</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(100,250)</drawSize>
<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>
<impactSound>FlyOver/Landing</impactSound>
</skyfaller>
<modExtensions>
<li Class="ArachnaeSwarm.FlyOverShadowExtension">
<customShadowPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</customShadowPath>
<useCustomShadow>true</useCustomShadow>
<shadowIntensity>0.8</shadowIntensity>
<minShadowAlpha>0</minShadowAlpha>
<maxShadowAlpha>0</maxShadowAlpha>
<minShadowScale>0</minShadowScale>
<maxShadowScale>0</maxShadowScale>
</li>
</modExtensions>
<seeThroughFog>true</seeThroughFog>
<useHitPoints>false</useHitPoints>
<selectable>false</selectable>
<alwaysHaulable>false</alwaysHaulable>
<altitudeLayer>MetaOverlays</altitudeLayer>
<comps>
<!-- 伴飞 -->
<li Class="ArachnaeSwarm.CompProperties_FlyOverEscort">
<escortFlyOverDef>ARA_HiveCorvette_Fake</escortFlyOverDef>
<!-- 生成配置 -->
<spawnIntervalTicks>250</spawnIntervalTicks> <!-- 5秒 -->
<maxEscorts>5</maxEscorts>
<spawnCount>1</spawnCount>
<!-- 位置配置 -->
<spawnDistance>0</spawnDistance>
<lateralOffset>50</lateralOffset>
<verticalOffset>5</verticalOffset>
<useRandomOffset>true</useRandomOffset>
<!-- 飞行配置 -->
<escortSpeedMultiplier>20</escortSpeedMultiplier> <!-- 比主舰稍快 -->
@@ -247,10 +429,10 @@
<heightMaskScaleMultiplier>1.3</heightMaskScaleMultiplier>
</li>
</comps>
</ThingDef>
</ThingDef>
<ThingDef Parent="EtherealThingBase">
<defName>ARA_HiveCorvette_Fake</defName>
<label>种兽虫</label>
<label>种兽虫</label>
<thingClass>ArachnaeSwarm.FlyOver</thingClass>
<tickerType>Normal</tickerType>
<drawerType>RealtimeOnly</drawerType>
@@ -298,7 +480,7 @@
<drawerType>RealtimeOnly</drawerType>
<graphicData>
<!-- <texPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</texPath> -->
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow</texPath>
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(20,30)</drawSize>
@@ -352,7 +534,7 @@
<drawerType>RealtimeOnly</drawerType>
<graphicData>
<!-- <texPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</texPath> -->
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvette_Shadow</texPath>
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_Shadow</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>TransparentPostLight</shaderType>
<drawSize>(20,30)</drawSize>
@@ -398,6 +580,56 @@
</li>
</comps>
</ThingDef>
<ThingDef Parent="EtherealThingBase">
<defName>ARA_HiveCorvette_Strike</defName>
<label>天巫种兽虫(棘刺扫射)</label>
<thingClass>ArachnaeSwarm.FlyOver</thingClass>
<tickerType>Normal</tickerType>
<drawerType>RealtimeOnly</drawerType>
<graphicData>
<!-- <texPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</texPath> -->
<texPath>ArachnaeSwarm/FlyOverThing/ARA_HiveCorvetteB_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>
<impactSound>FlyOver/Landing</impactSound>
</skyfaller>
<modExtensions>
<li Class="ArachnaeSwarm.FlyOverShadowExtension">
<customShadowPath>ArachnaeSwarm/Weapon/ARA_Weapon_Empty</customShadowPath>
<useCustomShadow>true</useCustomShadow>
<shadowIntensity>0.8</shadowIntensity>
<minShadowAlpha>0</minShadowAlpha>
<maxShadowAlpha>0</maxShadowAlpha>
<minShadowScale>0</minShadowScale>
<maxShadowScale>0</maxShadowScale>
</li>
</modExtensions>
<seeThroughFog>true</seeThroughFog>
<useHitPoints>false</useHitPoints>
<selectable>false</selectable>
<alwaysHaulable>false</alwaysHaulable>
<altitudeLayer>MetaOverlays</altitudeLayer>
<comps>
<li Class="ArachnaeSwarm.CompProperties_SectorSurveillance">
<projectileDef>Bullet_ARA_HiveCorvette</projectileDef>
<sectorAngle>30</sectorAngle> <!-- 扇形角度 -->
<sectorRange>50</sectorRange> <!-- 射程 -->
<shotCount>10</shotCount> <!-- 发射次数 -->
<shotInterval>0.5</shotInterval> <!-- 发射间隔 -->
<maxProjectiles>-1</maxProjectiles><!-- 最大射弹数量限制-->
</li>
</comps>
</ThingDef>
<ThingDef ParentName="SkyfallerBase">
<defName>ARA_HiveShip_Fire_Incoming</defName>
@@ -416,7 +648,7 @@
<shadowSize>(2.5, 2.5)</shadowSize>
<explosionRadius>10</explosionRadius>
<explosionDamage>ARA_AcidBurn</explosionDamage>
<explosionDamageFactor>0.5</explosionDamageFactor>
<explosionDamageFactor>0.1</explosionDamageFactor>
<cameraShake>1</cameraShake>
<angleCurve>
<points>

View File

@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<!-- Aircraft Strike Messages -->
<AircraftManagerNotFound>战机管理器未找到!</AircraftManagerNotFound>
<AircraftStrikeInitiated>空中打击已启动:{0}</AircraftStrikeInitiated>
<AircraftStrikeSuccess>空中打击:成功使用 {0} 只 {1}</AircraftStrikeSuccess>
<NoAvailableAircraft>没有可用的空中兽虫:{0}</NoAvailableAircraft>
<AircraftStrikeFailed>空中兽虫打击:{1} 没有可用的 {0}</AircraftStrikeFailed>
<NoAircraftForStrike>没有可用的 {0} 进行打击</NoAircraftForStrike>
<!-- Mouse Overlay Text -->
<AvailableAircraft>{0}{1}</AvailableAircraft>
<CooldownAircraft>冷却中:{0}</CooldownAircraft>
<CostPerUse>消耗:{0}</CostPerUse>
<!-- Tooltip Text -->
<AircraftStatusTooltip>兽虫群状态:</AircraftStatusTooltip>
<TotalAircraft>兽虫总数:{0}</TotalAircraft>
<ReadyAircraft>准备发射:{0}</ReadyAircraft>
<CooldownAircraft>冷却中:{0}</CooldownAircraft>
<AircraftCost>每次使用消耗:{0}</AircraftCost>
<!-- Existing keys... -->
<!-- New Aircraft Cooldown Time Keys -->
<AircraftCooldownTime>冷却时间:{0}小时</AircraftCooldownTime>
<AircraftAbilityDescription>\n需要 {0} 参与打击\n每次使用占用 {1} 兽虫\n冷却时间{2}小时</AircraftAbilityDescription>
<!-- Miscellaneous -->
<UnknownFaction>未知派系</UnknownFaction>
<!-- Aircraft Hangar Gizmo Text -->
<LaunchAircraft>兽虫起飞</LaunchAircraft>
<LaunchAircraftDesc>命令空中兽虫起飞。起飞的空中兽虫将永不落地,如果想要使用它们就需要有引航种的指挥。</LaunchAircraftDesc>
<HangarDamaged>兽虫受损</HangarDamaged>
<!-- Aircraft Hangar Messages -->
<AircraftLaunched>兽虫已起飞:{0} 只 {1}</AircraftLaunched>
<AircraftManagerNotFound>战机管理器未找到!</AircraftManagerNotFound>
<!-- Takeoff Effect Messages -->
<TakeoffEffectMapNull>无法创建起飞效果:父级地图为空</TakeoffEffectMapNull>
<TakeoffSkyfallerCreated>在 {0} 创建了起飞天空坠落者携带1单位化学燃料</TakeoffSkyfallerCreated>
<TakeoffEffectError>创建起飞效果时出错:{0}</TakeoffEffectError>
<!-- Aircraft Manager Error Messages -->
<AddAircraftNullFaction>尝试将战机添加到空派系</AddAircraftNullFaction>
<!-- Aircraft Status Messages -->
<AircraftCooldownEnded>{0} 准备好再次进行打击</AircraftCooldownEnded>
<NoAircraftStatus>没有可用的兽虫</NoAircraftStatus>
<AircraftStatusLine>{0}{1}/{2}(冷却中:{3}</AircraftStatusLine>
</LanguageData>

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

View File

@@ -3,56 +3,40 @@
"WorkspaceRootPath": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\",
"Documents": [
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\ara_aircrafthangar\\compaircrafthangar.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\compaircrafthangar.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\ara_aircrafthangar\\compabilityeffect_aircraftstrike.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_aircrafthangar\\compabilityeffect_aircraftstrike.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\compabilityeffect_aircraftstrike.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\building_comps\\comprefuelablenutrition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:building_comps\\comprefuelablenutrition.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_givehediffwithskillduration\\compabilityeffect_givehediffwithskillduration.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_givehediffwithskillduration\\compabilityeffect_givehediffwithskillduration.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\ara_sectorsurveillance\\compsectorsurveillance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_sectorsurveillance\\compsectorsurveillance.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_showtemperaturerange\\compabilityeffect_abilityshowtemperaturerange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showtemperaturerange\\compabilityeffect_abilityshowtemperaturerange.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\thingclassflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:abilities\\ara_showspawnablepawnslist\\compabilityeffect_abilityshowspawnablepawns.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_spawnflyover\\compabilityeffect_spawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_spawnflyover\\compabilityeffect_spawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|d:\\steamlibrary\\steamapps\\common\\rimworld\\mods\\arachnaeswarm\\source\\arachnaeswarm\\flyover\\ara_spawnflyover\\compproperties_abilityspawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_spawnflyover\\compproperties_abilityspawnflyover.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_aircrafthangar\\compaircrafthangar.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\compaircrafthangar.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_groundstrafing\\compgroundstrafing.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_groundstrafing\\compgroundstrafing.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_flyoverescort\\compflyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_flyoverescort\\compflyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_aircrafthangar\\worldcomponent_aircraftmanager.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_flyoverescort\\compproperties_flyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_flyoverescort\\compproperties_flyoverescort.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_shipartillery\\compshipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_shipartillery\\compshipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
},
{
"AbsoluteMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\flyover\\ara_shipartillery\\compproperties_shipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}",
"RelativeMoniker": "D:0:0:{EAE0DB6B-E282-C812-7F5A-6D13E9D24581}|ArachnaeSwarm.csproj|solutionrelative:flyover\\ara_shipartillery\\compproperties_shipartillery.cs||{A6C744A8-0E4A-4FC6-886A-064283054674}"
}
],
"DocumentGroupContainers": [
@@ -70,167 +54,112 @@
},
{
"$type": "Document",
"DocumentIndex": 1,
"Title": "CompAircraftHangar.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"RelativeToolTip": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"ViewState": "AgIAAEoAAAAAAAAAAAAswFkAAAAdAAAAAAAAAA==",
"DocumentIndex": 2,
"Title": "CompAbilityEffect_GiveHediffWithSkillDuration.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs",
"RelativeToolTip": "Abilities\\ARA_GiveHediffWithSkillDuration\\CompAbilityEffect_GiveHediffWithSkillDuration.cs",
"ViewState": "AgIAAEsAAAAAAAAAAAAWwGAAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T06:31:52.619Z",
"EditorCaption": ""
"WhenOpened": "2025-10-29T14:40:47.422Z"
},
{
"$type": "Document",
"DocumentIndex": 3,
"Title": "CompRefuelableNutrition.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompRefuelableNutrition.cs",
"RelativeDocumentMoniker": "Building_Comps\\CompRefuelableNutrition.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Building_Comps\\CompRefuelableNutrition.cs",
"RelativeToolTip": "Building_Comps\\CompRefuelableNutrition.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAAUAAAAXAAAAAAAAAA==",
"Title": "CompAbilityEffect_AbilityShowTemperatureRange.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
"RelativeToolTip": "Abilities\\ARA_ShowTemperatureRange\\CompAbilityEffect_AbilityShowTemperatureRange.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABcAAAArAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T06:31:46.148Z",
"EditorCaption": ""
"WhenOpened": "2025-10-29T14:40:43.525Z"
},
{
"$type": "Document",
"DocumentIndex": 2,
"DocumentIndex": 1,
"Title": "CompAbilityEffect_AircraftStrike.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs",
"RelativeToolTip": "Flyover\\ARA_AircraftHangar\\CompAbilityEffect_AircraftStrike.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAACMAAAAAAAAAAAAAAA==",
"ViewState": "AgIAAHYAAAAAAAAAAAAtwJcAAAArAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T06:30:49.523Z",
"EditorCaption": ""
"WhenOpened": "2025-10-29T11:22:34.783Z"
},
{
"$type": "Document",
"DocumentIndex": 0,
"Title": "WorldComponent_AircraftManager.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"RelativeToolTip": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"ViewState": "AgIAAKsAAAAAAAAAAAAowBEAAAASAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T06:30:44.854Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 4,
"Title": "CompSectorSurveillance.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs",
"RelativeToolTip": "Flyover\\ARA_SectorSurveillance\\CompSectorSurveillance.cs",
"ViewState": "AgIAAMYAAAAAAAAAAAAqwNUAAAARAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T02:30:42.063Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "CompGroundStrafing.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
"RelativeToolTip": "Flyover\\ARA_GroundStrafing\\CompGroundStrafing.cs",
"ViewState": "AgIAAB0AAAAAAAAAAAAQwCYAAABFAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T16:19:23.118Z"
},
{
"$type": "Document",
"DocumentIndex": 6,
"Title": "CompAbilityEffect_SpawnFlyOver.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABYAAABOAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T14:51:14.836Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "CompProperties_AbilitySpawnFlyOver.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
"RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompProperties_AbilitySpawnFlyOver.cs",
"ViewState": "AgIAABgAAAAAAAAAAAAswDQAAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T13:51:12.201Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "ThingclassFlyOver.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
"RelativeDocumentMoniker": "Flyover\\ThingclassFlyOver.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ThingclassFlyOver.cs",
"RelativeToolTip": "Flyover\\ThingclassFlyOver.cs",
"ViewState": "AgIAAAkCAAAAAAAAAAAqwCYCAAB/AAAAAAAAAA==",
"ViewState": "AgIAAC0CAAAAAAAAAAAawCUCAAANAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T09:09:22.03Z",
"WhenOpened": "2025-10-29T14:17:06.867Z",
"EditorCaption": ""
},
{
"$type": "Document",
"DocumentIndex": 9,
"Title": "CompFlyOverEscort.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
"RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompFlyOverEscort.cs",
"ViewState": "AgIAAKYBAAAAAAAAAAAWwNEBAAAAAAAAAAAAAA==",
"DocumentIndex": 4,
"Title": "CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeDocumentMoniker": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"RelativeToolTip": "Abilities\\ARA_ShowSpawnablePawnsList\\CompAbilityEffect_AbilityShowSpawnablePawns.cs",
"ViewState": "AgIAABYAAAAAAAAAAAAuwBYAAAArAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T07:30:55.268Z"
"WhenOpened": "2025-10-29T14:40:40.237Z"
},
{
"$type": "Document",
"DocumentIndex": 10,
"DocumentIndex": 6,
"Title": "CompAircraftHangar.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"RelativeToolTip": "Flyover\\ARA_AircraftHangar\\CompAircraftHangar.cs",
"ViewState": "AgIAABcAAAAAAAAAAAAQwCQAAAAnAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T11:39:22.563Z"
},
{
"$type": "Document",
"DocumentIndex": 5,
"Title": "CompAbilityEffect_SpawnFlyOver.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"RelativeToolTip": "Flyover\\ARA_SpawnFlyOver\\CompAbilityEffect_SpawnFlyOver.cs",
"ViewState": "AgIAAFMDAAAAAAAAAAAawG8DAAAAAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T13:37:35.758Z"
},
{
"$type": "Document",
"DocumentIndex": 7,
"Title": "WorldComponent_AircraftManager.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"RelativeToolTip": "Flyover\\ARA_AircraftHangar\\WorldComponent_AircraftManager.cs",
"ViewState": "AgIAAJUAAAAAAAAAAAAowK4AAAAUAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-29T14:05:39.817Z"
},
{
"$type": "Document",
"DocumentIndex": 8,
"Title": "CompProperties_FlyOverEscort.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
"RelativeToolTip": "Flyover\\ARA_FlyOverEscort\\CompProperties_FlyOverEscort.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABgAAAAPAAAAAAAAAA==",
"ViewState": "AgIAAAAAAAAAAAAAAAAAABAAAAAvAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T07:30:47.27Z"
},
{
"$type": "Document",
"DocumentIndex": 12,
"Title": "CompProperties_ShipArtillery.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
"RelativeToolTip": "Flyover\\ARA_ShipArtillery\\CompProperties_ShipArtillery.cs",
"ViewState": "AgIAAAAAAAAAAAAAAAAAAA8AAAAhAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T06:21:06.271Z"
},
{
"$type": "Document",
"DocumentIndex": 11,
"Title": "CompShipArtillery.cs",
"DocumentMoniker": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
"RelativeDocumentMoniker": "Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
"ToolTip": "D:\\SteamLibrary\\steamapps\\common\\RimWorld\\Mods\\ArachnaeSwarm\\Source\\ArachnaeSwarm\\Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
"RelativeToolTip": "Flyover\\ARA_ShipArtillery\\CompShipArtillery.cs",
"ViewState": "AgIAALEAAAAAAAAAAAAywNEAAABcAAAAAAAAAA==",
"Icon": "ae27a6b0-e345-4288-96df-5eaf394ee369.000738|",
"WhenOpened": "2025-10-28T06:21:04.222Z"
"WhenOpened": "2025-10-29T12:59:07.753Z"
}
]
}

View File

@@ -2,6 +2,7 @@ using RimWorld;
using Verse;
using RimWorld.Planet;
using System.Collections.Generic;
using System.Text;
namespace ArachnaeSwarm
{
@@ -30,40 +31,24 @@ namespace ArachnaeSwarm
if (aircraftManager == null)
{
Log.Error("Aircraft manager not found!");
Log.Error("AircraftManagerNotFound".Translate());
return;
}
// 检查并消耗战机
if (aircraftManager.TryUseAircraft(Props.requiredAircraftType, Props.aircraftsPerUse, parent.pawn.Faction, Props.aircraftCooldownTicks))
{
// 执行打击效果
ExecuteStrikeEffect(target);
Messages.Message($"Aircraft strike initiated: {Props.requiredAircraftType.LabelCap}", MessageTypeDefOf.PositiveEvent);
// 成功消耗战机,发送消息
Messages.Message("AircraftStrikeInitiated".Translate(Props.requiredAircraftType.LabelCap), MessageTypeDefOf.PositiveEvent);
Log.Message("AircraftStrikeSuccess".Translate(Props.aircraftsPerUse, Props.requiredAircraftType.LabelCap));
}
else
{
Messages.Message($"No available aircraft: {Props.requiredAircraftType.LabelCap}", MessageTypeDefOf.NegativeEvent);
Messages.Message("NoAvailableAircraft".Translate(Props.requiredAircraftType.LabelCap), MessageTypeDefOf.NegativeEvent);
Log.Warning("AircraftStrikeFailed".Translate(Props.requiredAircraftType.LabelCap, parent.pawn.Faction?.Name ?? "UnknownFaction".Translate()));
}
}
private void ExecuteStrikeEffect(LocalTargetInfo target)
{
// 这里实现具体的打击效果
// 例如:轰炸、空投、侦察等
// 示例:在目标位置创建爆炸效果
GenExplosion.DoExplosion(
target.Cell,
parent.pawn.Map,
radius: 3.5f,
DamageDefOf.Bomb,
instigator: parent.pawn,
damAmount: 50
);
}
public override bool CanApplyOn(LocalTargetInfo target, LocalTargetInfo dest)
{
// 检查是否有可用的战机
@@ -81,10 +66,97 @@ namespace ArachnaeSwarm
if (aircraftManager != null)
{
int available = aircraftManager.GetAvailableAircraftCount(Props.requiredAircraftType, parent.pawn.Faction);
return $"Available {Props.requiredAircraftType.LabelCap}: {available}";
int onCooldown = aircraftManager.GetCooldownAircraftCount(Props.requiredAircraftType, parent.pawn.Faction);
// 使用符号显示飞机状态
string availableSymbols = GetAircraftSymbols(available, "◆");
string cooldownSymbols = GetAircraftSymbols(onCooldown, "◇");
StringBuilder sb = new StringBuilder();
sb.AppendLine("AvailableAircraft".Translate(Props.requiredAircraftType.LabelCap, availableSymbols));
sb.AppendLine("CooldownAircraft".Translate(cooldownSymbols));
sb.Append("CostPerUse".Translate(Props.aircraftsPerUse));
return sb.ToString();
}
return base.ExtraLabelMouseAttachment(target);
}
// 生成飞机符号表示
private string GetAircraftSymbols(int count, string symbol)
{
if (count <= 0) return "—"; // 无飞机时显示破折号
StringBuilder sb = new StringBuilder();
int displayCount = count;
// 如果数量过多,用数字+符号表示
if (count > 10)
{
return $"{count}{symbol}";
}
// 直接显示符号
for (int i = 0; i < displayCount; i++)
{
sb.Append(symbol);
}
return sb.ToString();
}
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
if (!base.Valid(target, throwMessages))
return false;
// 检查战机可用性
WorldComponent_AircraftManager aircraftManager = Find.World.GetComponent<WorldComponent_AircraftManager>();
if (aircraftManager == null || !aircraftManager.HasAvailableAircraft(Props.requiredAircraftType, Props.aircraftsPerUse, parent.pawn.Faction))
{
if (throwMessages)
{
Messages.Message("NoAircraftForStrike".Translate(Props.requiredAircraftType.LabelCap), MessageTypeDefOf.RejectInput);
}
return false;
}
return true;
}
// 鼠标悬停时的工具提示
public override string ExtraTooltipPart()
{
WorldComponent_AircraftManager aircraftManager = Find.World.GetComponent<WorldComponent_AircraftManager>();
if (aircraftManager != null)
{
int available = aircraftManager.GetAvailableAircraftCount(Props.requiredAircraftType, parent.pawn.Faction);
int onCooldown = aircraftManager.GetCooldownAircraftCount(Props.requiredAircraftType, parent.pawn.Faction);
int total = available + onCooldown;
// 将冷却时间从 tick 转换为小时
float cooldownHours = TicksToHours(Props.aircraftCooldownTicks);
StringBuilder sb = new StringBuilder();
sb.AppendLine("AircraftStatusTooltip".Translate());
sb.AppendLine("• " + "TotalAircraft".Translate(total));
sb.AppendLine("• " + "ReadyAircraft".Translate(available));
sb.AppendLine("• " + "CooldownAircraft".Translate(onCooldown));
sb.AppendLine("AircraftAbilityDescription".Translate(Props.requiredAircraftType.LabelCap, Props.aircraftsPerUse, cooldownHours.ToString("F1")));
return sb.ToString();
}
return base.ExtraTooltipPart();
}
// 将 tick 转换为小时
private float TicksToHours(int ticks)
{
// RimWorld 中 1 小时 = 2500 tick
return ticks / 2500f;
}
}
}

View File

@@ -31,8 +31,8 @@ namespace ArachnaeSwarm
// 起飞命令
Command_Action launchCommand = new Command_Action
{
defaultLabel = "Launch Aircraft",
defaultDesc = "Launch aircraft for orbital support",
defaultLabel = "LaunchAircraft".Translate(),
defaultDesc = "LaunchAircraftDesc".Translate(),
icon = TexCommand.Attack,
action = LaunchAircraft
};
@@ -40,7 +40,7 @@ namespace ArachnaeSwarm
// 检查条件:建筑完好
if (parent.HitPoints <= 0)
{
launchCommand.Disable("Hangar damaged");
launchCommand.Disable("HangarDamaged".Translate());
}
yield return launchCommand;
@@ -53,15 +53,15 @@ namespace ArachnaeSwarm
if (aircraftManager == null)
{
Log.Error("Aircraft manager not found!");
Log.Error("AircraftManagerNotFound".Translate());
return;
}
// 立即向全局管理器注册战机(在创建 Skyfaller 之前)
// 立即向全局管理器注册战机
aircraftManager.AddAircraft(Props.aircraftDef, Props.aircraftCount, parent.Faction);
// 显示消息
Messages.Message($"Aircraft launched: {Props.aircraftCount}x {Props.aircraftDef.LabelCap}", MessageTypeDefOf.PositiveEvent);
Messages.Message("AircraftLaunched".Translate(Props.aircraftCount, Props.aircraftDef.LabelCap), MessageTypeDefOf.PositiveEvent);
// 创建起飞效果(仅视觉效果)
if (Props.skyfallerLeaving != null)
@@ -77,17 +77,39 @@ namespace ArachnaeSwarm
private void CreateTakeoffEffect()
{
// 创建起飞天空坠落者
Skyfaller skyfaller = SkyfallerMaker.MakeSkyfaller(Props.skyfallerLeaving, parent);
// 设置起飞位置(建筑当前位置)
IntVec3 takeoffPos = parent.Position;
// 生成 Skyfaller
GenSpawn.Spawn(skyfaller, takeoffPos, parent.Map);
// 立即销毁原建筑Skyfaller 只是视觉效果
parent.Destroy();
try
{
// 创建 1 单位 Chemfuel 作为 Skyfaller 的内容物
Thing chemfuel = ThingMaker.MakeThing(ThingDefOf.Chemfuel);
chemfuel.stackCount = 1;
// 创建包含 Chemfuel 的 Skyfaller
Skyfaller skyfaller = SkyfallerMaker.MakeSkyfaller(Props.skyfallerLeaving, chemfuel);
// 设置起飞位置(建筑当前位置
IntVec3 takeoffPos = parent.Position;
// 检查地图是否有效
if (parent.Map == null)
{
Log.Error("TakeoffEffectMapNull".Translate());
return;
}
// 生成 Skyfaller
GenSpawn.Spawn(skyfaller, takeoffPos, parent.Map);
Log.Message("TakeoffSkyfallerCreated".Translate(takeoffPos));
// 销毁原建筑
parent.Destroy(DestroyMode.Vanish);
}
catch (System.Exception ex)
{
Log.Error("TakeoffEffectError".Translate(ex.Message));
// 如果Skyfaller创建失败直接销毁建筑
parent.Destroy(DestroyMode.Vanish);
}
}
public override void PostExposeData()

View File

@@ -8,55 +8,43 @@ namespace ArachnaeSwarm
{
public class WorldComponent_AircraftManager : WorldComponent
{
private Dictionary<Faction, Dictionary<ThingDef, AircraftFactionData>> factionAircraftData =
new Dictionary<Faction, Dictionary<ThingDef, AircraftFactionData>>();
// 使用列表而不是嵌套字典,更容易序列化
private List<FactionAircraftData> allFactionAircraftData = new List<FactionAircraftData>();
private List<AircraftCooldownEvent> cooldownEvents = new List<AircraftCooldownEvent>();
public WorldComponent_AircraftManager(World world) : base(world) { }
// 战机派系数据
private class AircraftFactionData : IExposable
// 派系战机数据
private class FactionAircraftData : IExposable
{
public int totalCount; // 总战机数量
public int availableCount; // 可用战机数量
public Faction faction;
public ThingDef aircraftDef;
public int totalCount;
public int availableCount;
public void ExposeData()
{
Scribe_Values.Look(ref totalCount, "totalCount");
Scribe_Values.Look(ref availableCount, "availableCount");
Scribe_References.Look(ref faction, "faction");
Scribe_Defs.Look(ref aircraftDef, "aircraftDef");
Scribe_Values.Look(ref totalCount, "totalCount", 0);
Scribe_Values.Look(ref availableCount, "availableCount", 0);
}
}
// 冷却事件
// 冷却事件
private class AircraftCooldownEvent : IExposable
{
public Faction faction;
public ThingDef aircraftDef;
public int endTick;
public int aircraftCount; // 冷却中的战机数量
public int aircraftCount;
public void ExposeData()
{
Scribe_References.Look(ref faction, "faction");
Scribe_Defs.Look(ref aircraftDef, "aircraftDef");
Scribe_Values.Look(ref endTick, "endTick");
Scribe_Values.Look(ref aircraftCount, "aircraftCount");
}
}
// 用于序列化的包装类
private class SerializableFactionAircraftData : IExposable
{
public Faction faction;
public ThingDef aircraftDef;
public AircraftFactionData data;
public void ExposeData()
{
Scribe_References.Look(ref faction, "faction");
Scribe_Defs.Look(ref aircraftDef, "aircraftDef");
Scribe_Deep.Look(ref data, "data");
Scribe_Values.Look(ref endTick, "endTick", 0);
Scribe_Values.Look(ref aircraftCount, "aircraftCount", 0);
}
}
@@ -64,50 +52,25 @@ namespace ArachnaeSwarm
{
base.ExposeData();
// 保存派系战机数据
List<SerializableFactionAircraftData> serializableData = new List<SerializableFactionAircraftData>();
// 使用简单的列表序列化
Scribe_Collections.Look(ref allFactionAircraftData, "allFactionAircraftData", LookMode.Deep);
Scribe_Collections.Look(ref cooldownEvents, "cooldownEvents", LookMode.Deep);
// 确保列表不为null
if (allFactionAircraftData == null)
allFactionAircraftData = new List<FactionAircraftData>();
if (cooldownEvents == null)
cooldownEvents = new List<AircraftCooldownEvent>();
// 调试日志
if (Scribe.mode == LoadSaveMode.Saving)
{
// 将字典数据转换为可序列化的列表
foreach (var factionPair in factionAircraftData)
{
foreach (var aircraftPair in factionPair.Value)
{
serializableData.Add(new SerializableFactionAircraftData
{
faction = factionPair.Key,
aircraftDef = aircraftPair.Key,
data = aircraftPair.Value
});
}
}
Log.Message($"Saving aircraft data: {allFactionAircraftData.Count} faction entries, {cooldownEvents.Count} cooldown events");
}
Scribe_Collections.Look(ref serializableData, "factionAircraftData", LookMode.Deep);
if (Scribe.mode == LoadSaveMode.LoadingVars)
else if (Scribe.mode == LoadSaveMode.PostLoadInit)
{
// 从序列化数据重建字典
factionAircraftData.Clear();
if (serializableData != null)
{
foreach (var item in serializableData)
{
if (item.faction != null && item.aircraftDef != null && item.data != null)
{
if (!factionAircraftData.ContainsKey(item.faction))
{
factionAircraftData[item.faction] = new Dictionary<ThingDef, AircraftFactionData>();
}
factionAircraftData[item.faction][item.aircraftDef] = item.data;
}
}
}
Log.Message($"Loaded aircraft data: {allFactionAircraftData.Count} faction entries, {cooldownEvents.Count} cooldown events");
}
// 保存冷却事件 - 显式指定泛型类型
Scribe_Collections.Look(ref cooldownEvents, "cooldownEvents", LookMode.Deep);
}
public override void WorldComponentTick()
@@ -122,35 +85,50 @@ namespace ArachnaeSwarm
if (currentTick >= cooldownEvent.endTick)
{
// 冷却结束,恢复战机可用性
RestoreAircraftAfterCooldown(cooldownEvent);
cooldownEvents.RemoveAt(i);
}
}
}
// 获取或创建派系战机数据
private FactionAircraftData GetOrCreateFactionAircraftData(Faction faction, ThingDef aircraftDef)
{
var data = allFactionAircraftData.FirstOrDefault(x => x.faction == faction && x.aircraftDef == aircraftDef);
if (data == null)
{
data = new FactionAircraftData
{
faction = faction,
aircraftDef = aircraftDef,
totalCount = 0,
availableCount = 0
};
allFactionAircraftData.Add(data);
}
return data;
}
// 获取派系战机数据可能为null
private FactionAircraftData GetFactionAircraftData(Faction faction, ThingDef aircraftDef)
{
return allFactionAircraftData.FirstOrDefault(x => x.faction == faction && x.aircraftDef == aircraftDef);
}
// 添加战机到派系
public void AddAircraft(ThingDef aircraftDef, int count, Faction faction)
{
if (faction == null)
{
Log.Error("Attempted to add aircraft to null faction");
Log.Error("AddAircraftNullFaction".Translate());
return;
}
if (!factionAircraftData.ContainsKey(faction))
{
factionAircraftData[faction] = new Dictionary<ThingDef, AircraftFactionData>();
}
if (!factionAircraftData[faction].ContainsKey(aircraftDef))
{
factionAircraftData[faction][aircraftDef] = new AircraftFactionData();
}
var data = factionAircraftData[faction][aircraftDef];
var data = GetOrCreateFactionAircraftData(faction, aircraftDef);
data.totalCount += count;
data.availableCount += count;
Log.Message($"Added {count} {aircraftDef.LabelCap} to {faction.Name}. Total: {data.totalCount}, Available: {data.availableCount}");
}
// 尝试使用战机
@@ -159,10 +137,9 @@ namespace ArachnaeSwarm
if (!HasAvailableAircraft(aircraftDef, count, faction))
return false;
var data = factionAircraftData[faction][aircraftDef];
var data = GetFactionAircraftData(faction, aircraftDef);
data.availableCount -= count;
// 创建冷却事件
AircraftCooldownEvent cooldownEvent = new AircraftCooldownEvent
{
faction = faction,
@@ -173,86 +150,75 @@ namespace ArachnaeSwarm
cooldownEvents.Add(cooldownEvent);
Log.Message($"Used {count} {aircraftDef.LabelCap} from {faction.Name}. Available now: {data.availableCount}, Cooldown until: {cooldownEvent.endTick}");
return true;
}
// 检查是否有可用战机
public bool HasAvailableAircraft(ThingDef aircraftDef, int count, Faction faction)
{
return factionAircraftData.ContainsKey(faction) &&
factionAircraftData[faction].ContainsKey(aircraftDef) &&
factionAircraftData[faction][aircraftDef].availableCount >= count;
var data = GetFactionAircraftData(faction, aircraftDef);
return data != null && data.availableCount >= count;
}
// 获取可用战机数量
public int GetAvailableAircraftCount(ThingDef aircraftDef, Faction faction)
{
if (factionAircraftData.ContainsKey(faction) &&
factionAircraftData[faction].ContainsKey(aircraftDef))
{
return factionAircraftData[faction][aircraftDef].availableCount;
}
return 0;
var data = GetFactionAircraftData(faction, aircraftDef);
return data?.availableCount ?? 0;
}
// 获取总战机数量
public int GetTotalAircraftCount(ThingDef aircraftDef, Faction faction)
{
if (factionAircraftData.ContainsKey(faction) &&
factionAircraftData[faction].ContainsKey(aircraftDef))
{
return factionAircraftData[faction][aircraftDef].totalCount;
}
return 0;
var data = GetFactionAircraftData(faction, aircraftDef);
return data?.totalCount ?? 0;
}
// 冷却结束后恢复战机
private void RestoreAircraftAfterCooldown(AircraftCooldownEvent cooldownEvent)
{
if (cooldownEvent.faction != null &&
factionAircraftData.ContainsKey(cooldownEvent.faction) &&
factionAircraftData[cooldownEvent.faction].ContainsKey(cooldownEvent.aircraftDef))
var data = GetFactionAircraftData(cooldownEvent.faction, cooldownEvent.aircraftDef);
if (data != null)
{
var data = factionAircraftData[cooldownEvent.faction][cooldownEvent.aircraftDef];
data.availableCount += cooldownEvent.aircraftCount;
// 可选:显示冷却结束消息
if (cooldownEvent.aircraftDef != null)
{
Messages.Message($"{cooldownEvent.aircraftDef.LabelCap} cooldown ended", MessageTypeDefOf.PositiveEvent);
Messages.Message("AircraftCooldownEnded".Translate(cooldownEvent.aircraftDef.LabelCap), MessageTypeDefOf.PositiveEvent);
Log.Message($"Cooldown ended for {cooldownEvent.aircraftCount} {cooldownEvent.aircraftDef.LabelCap}. Available now: {data.availableCount}");
}
}
}
// 获取战机状态信息用于调试或UI显示
public string GetAircraftStatus(Faction faction)
{
if (!factionAircraftData.ContainsKey(faction))
return "No aircraft";
var status = new List<string>();
foreach (var kvp in factionAircraftData[faction])
{
var data = kvp.Value;
int inCooldown = data.totalCount - data.availableCount;
status.Add($"{kvp.Key.LabelCap}: {data.availableCount}/{data.totalCount} (In cooldown: {inCooldown})");
}
return string.Join("\n", status);
}
// 获取冷却中的战机数量
public int GetCooldownAircraftCount(ThingDef aircraftDef, Faction faction)
{
int totalCooldown = 0;
foreach (var cooldownEvent in cooldownEvents)
return cooldownEvents
.Where(e => e.faction == faction && e.aircraftDef == aircraftDef)
.Sum(e => e.aircraftCount);
}
// 调试方法:显示当前状态
public void DebugLogStatus()
{
Log.Message("=== Aircraft Manager Status ===");
Log.Message($"Total faction entries: {allFactionAircraftData.Count}");
var factions = allFactionAircraftData.Select(x => x.faction).Distinct();
foreach (var faction in factions)
{
if (cooldownEvent.faction == faction && cooldownEvent.aircraftDef == aircraftDef)
Log.Message($"Faction: {faction?.Name ?? "Unknown"}");
var factionData = allFactionAircraftData.Where(x => x.faction == faction);
foreach (var data in factionData)
{
totalCooldown += cooldownEvent.aircraftCount;
Log.Message($" {data.aircraftDef.LabelCap}: {data.availableCount}/{data.totalCount} available");
}
}
return totalCooldown;
Log.Message($"Active cooldown events: {cooldownEvents.Count}");
Log.Message("===============================");
}
}
}

View File

@@ -31,6 +31,7 @@ namespace ArachnaeSwarm
}
Log.Message($"FlyOver Escort initialized: {Props.spawnIntervalTicks} ticks interval, max {Props.maxEscorts} escorts");
Log.Message($"Safe distances - From Main: {Props.minSafeDistanceFromMain}, Between Escorts: {Props.minSafeDistanceBetweenEscorts}");
}
public override void CompTick()
@@ -97,8 +98,10 @@ namespace ArachnaeSwarm
private void SpawnEscorts(FlyOver mainFlyOver)
{
int escortsToSpawn = Mathf.Min(Props.spawnCount, Props.maxEscorts - activeEscorts.Count);
int successfulSpawns = 0;
int maxAttempts = escortsToSpawn * 5; // 最多尝试5倍的数量
for (int i = 0; i < escortsToSpawn; i++)
for (int attempt = 0; attempt < maxAttempts && successfulSpawns < escortsToSpawn; attempt++)
{
// 先生成视觉数据
EscortVisualData visualData = GenerateEscortVisualData();
@@ -106,12 +109,68 @@ namespace ArachnaeSwarm
FlyOver escort = CreateEscort(mainFlyOver, visualData);
if (escort != null)
{
activeEscorts.Add(escort);
escortVisualData[escort] = visualData;
Log.Message($"Spawned escort #{i+1} for FlyOver at {mainFlyOver.DrawPos}, scale: {visualData.scale:F2}, maskAlpha: {visualData.heightMaskAlpha:F2}");
// 检查安全距离
if (IsSafeDistance(escort, mainFlyOver))
{
activeEscorts.Add(escort);
escortVisualData[escort] = visualData;
successfulSpawns++;
Log.Message($"Spawned escort #{successfulSpawns} for FlyOver at {mainFlyOver.DrawPos}, scale: {visualData.scale:F2}, maskAlpha: {visualData.heightMaskAlpha:F2}");
}
else
{
// 不安全,销毁这个伴飞
escort.Destroy();
Log.Message($"Escort spawn attempt {attempt + 1}: Position too close to existing escort, trying again");
}
}
// 如果已经生成足够数量,提前退出
if (successfulSpawns >= escortsToSpawn)
break;
}
if (successfulSpawns < escortsToSpawn)
{
Log.Message($"Spawned {successfulSpawns}/{escortsToSpawn} escorts (some positions were too close to existing escorts)");
}
}
// 修改:分别检查与主飞行物和伴飞物的安全距离
private bool IsSafeDistance(FlyOver newEscort, FlyOver mainFlyOver)
{
Vector3 newPos = newEscort.DrawPos;
// 检查与主FlyOver的距离
if (Props.minSafeDistanceFromMain > 0)
{
float distToMain = Vector3.Distance(newPos, mainFlyOver.DrawPos);
if (distToMain < Props.minSafeDistanceFromMain)
{
Log.Message($"Escort too close to main FlyOver: {distToMain:F1} < {Props.minSafeDistanceFromMain}");
return false;
}
}
// 检查与其他伴飞的距离
if (Props.minSafeDistanceBetweenEscorts > 0)
{
foreach (FlyOver existingEscort in activeEscorts)
{
if (existingEscort == null || existingEscort.Destroyed)
continue;
float distToEscort = Vector3.Distance(newPos, existingEscort.DrawPos);
if (distToEscort < Props.minSafeDistanceBetweenEscorts)
{
Log.Message($"Escort too close to existing escort: {distToEscort:F1} < {Props.minSafeDistanceBetweenEscorts}");
return false;
}
}
}
return true;
}
private EscortVisualData GenerateEscortVisualData()
@@ -131,7 +190,6 @@ namespace ArachnaeSwarm
return data;
}
// 修改:添加 visualData 参数
private FlyOver CreateEscort(FlyOver mainFlyOver, EscortVisualData visualData)
{
try
@@ -275,7 +333,6 @@ namespace ArachnaeSwarm
);
}
// 修改:添加 visualData 参数
private void SetupEscortProperties(FlyOver escort, FlyOver mainFlyOver, EscortVisualData visualData)
{
// 设置伴飞缩放 - 现在直接从参数获取

View File

@@ -22,6 +22,10 @@ namespace ArachnaeSwarm
public float verticalOffset = 2f; // 垂直偏移量(高度差)
public bool useRandomOffset = true; // 是否使用随机偏移
// 修改:独立的安全距离配置
public float minSafeDistanceFromMain = 8f; // 与主飞行物的最小安全距离(单元格)
public float minSafeDistanceBetweenEscorts = 3f; // 伴飞物之间的最小安全距离(单元格)
// 飞行配置
public float escortSpeedMultiplier = 1f; // 速度乘数相对于主FlyOver
public float escortAltitudeOffset = 0f; // 高度偏移

View File

@@ -36,6 +36,10 @@ namespace ArachnaeSwarm
endPos = CalculateEndPosition(target, startPos);
}
// 确保位置安全
startPos = GetSafeMapPosition(startPos, parent.pawn.Map);
endPos = GetSafeMapPosition(endPos, parent.pawn.Map);
Log.Message($"Final positions - Start: {startPos}, End: {endPos}");
// 验证位置是否有效
@@ -57,10 +61,7 @@ namespace ArachnaeSwarm
Log.Warning($"FlyOver start and end positions are the same: {startPos}. Adjusting end position.");
IntVec3 randomOffset = new IntVec3(Rand.Range(-10, 11), 0, Rand.Range(-10, 11));
endPos += randomOffset;
if (!endPos.InBounds(parent.pawn.Map))
{
endPos = parent.pawn.Map.Center;
}
endPos = GetSafeMapPosition(endPos, parent.pawn.Map);
}
// 根据类型创建不同的飞越物体
@@ -71,15 +72,12 @@ namespace ArachnaeSwarm
CreateStandardFlyOver(startPos, endPos);
break;
case FlyOverType.GroundStrafing:
CreateGroundStrafingFlyOver(startPos, endPos);
CreateGroundStrafingFlyOver(startPos, endPos, target.Cell);
break;
case FlyOverType.SectorSurveillance:
CreateSectorSurveillanceFlyOver(startPos, endPos);
break;
}
// 显示效果消息
ShowEffectMessage();
}
catch (System.Exception ex)
{
@@ -87,39 +85,88 @@ namespace ArachnaeSwarm
}
}
// 新增:在目标选择时显示预览
// 修复的预览绘制方法
public override void DrawEffectPreview(LocalTargetInfo target)
{
base.DrawEffectPreview(target);
if (parent.pawn != null && parent.pawn.Map != null)
{
// 计算飞行路径
IntVec3 startPos, endPos;
if (Props.approachType == ApproachType.Perpendicular)
Map map = parent.pawn.Map;
try
{
CalculatePerpendicularPath(target, out startPos, out endPos);
}
else
{
startPos = CalculateStartPosition(target);
endPos = CalculateEndPosition(target, startPos);
}
// 计算飞行路径
IntVec3 startPos, endPos;
if (Props.approachType == ApproachType.Perpendicular)
{
CalculatePerpendicularPath(target, out startPos, out endPos);
}
else
{
startPos = CalculateStartPosition(target);
endPos = CalculateEndPosition(target, startPos);
}
// 根据不同类型显示不同的预览
if (Props.enableGroundStrafing && Props.showStrafePreview)
{
DrawStrafingAreaPreview(startPos, endPos);
// 确保位置在地图范围内
startPos = GetSafeMapPosition(startPos, map);
endPos = GetSafeMapPosition(endPos, map);
// 检查预览稳定性
if (!IsPreviewStable(startPos, endPos, map))
{
return;
}
// 根据不同类型显示不同的预览
if (Props.enableGroundStrafing && Props.showStrafePreview)
{
DrawStrafingAreaPreview(startPos, endPos, target.Cell);
}
else if (Props.enableSectorSurveillance && Props.showSectorPreview)
{
DrawSectorAreaPreview(startPos, endPos);
}
}
else if (Props.enableSectorSurveillance && Props.showSectorPreview)
catch (System.Exception)
{
DrawSectorAreaPreview(startPos, endPos);
// 忽略预览绘制中的错误,避免影响游戏体验
}
}
}
// 绘制地面扫射预览
private void DrawStrafingAreaPreview(IntVec3 startPos, IntVec3 endPos)
// 安全的位置计算方法
private IntVec3 GetSafeMapPosition(IntVec3 pos, Map map)
{
if (map == null) return pos;
// 确保位置在地图范围内
pos.x = Mathf.Clamp(pos.x, 0, map.Size.x - 1);
pos.z = Mathf.Clamp(pos.z, 0, map.Size.z - 1);
return pos;
}
// 预览绘制稳定性检查
private bool IsPreviewStable(IntVec3 startPos, IntVec3 endPos, Map map)
{
if (map == null) return false;
// 检查位置是否有效
if (!startPos.IsValid || !endPos.IsValid) return false;
// 检查位置是否在地图范围内
if (!startPos.InBounds(map) || !endPos.InBounds(map)) return false;
// 检查距离是否合理(避免过短的路径)
float distance = Vector3.Distance(startPos.ToVector3(), endPos.ToVector3());
if (distance < 5f) return false;
return true;
}
// 修复:绘制地面扫射预览,现在接受目标单元格参数
private void DrawStrafingAreaPreview(IntVec3 startPos, IntVec3 endPos, IntVec3 targetCell)
{
Map map = parent.pawn.Map;
@@ -131,7 +178,7 @@ namespace ArachnaeSwarm
}
// 只计算扫射影响区域的单元格
List<IntVec3> strafeImpactCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection);
List<IntVec3> strafeImpactCells = CalculateStrafingImpactCells(targetCell, flightDirection);
// 绘制扫射影响区域的预览单元格
foreach (IntVec3 cell in strafeImpactCells)
@@ -146,11 +193,11 @@ namespace ArachnaeSwarm
GenDraw.DrawLineBetween(startPos.ToVector3Shifted(), endPos.ToVector3Shifted(), SimpleColor.Red, 0.2f);
// 绘制扫射范围边界
DrawStrafingBoundaries(startPos, endPos, flightDirection);
DrawStrafingBoundaries(targetCell, flightDirection);
}
// 计算扫射影响区域的单元格
private List<IntVec3> CalculateStrafingImpactCells(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection)
// 修复:计算扫射影响区域的单元格,现在以目标单元格为中心
private List<IntVec3> CalculateStrafingImpactCells(IntVec3 targetCell, Vector3 flightDirection)
{
List<IntVec3> cells = new List<IntVec3>();
Map map = parent.pawn.Map;
@@ -158,19 +205,16 @@ namespace ArachnaeSwarm
// 计算垂直于飞行方向的方向
Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized;
// 计算飞行路径的总长度
float totalPathLength = startPos.DistanceTo(endPos);
// 修复:以目标单元格为中心计算扫射区域
Vector3 targetCenter = targetCell.ToVector3();
// 计算扫射区域的中心点(目标位置附近
Vector3 targetCenter = Vector3.Lerp(startPos.ToVector3(), endPos.ToVector3(), 0.5f);
// 计算扫射区域的起始和结束位置(基于扫射长度)
// 计算扫射区域的起始和结束位置(基于扫射长度,以目标为中心)
float strafeHalfLength = Props.strafeLength * 0.5f;
Vector3 strafeStart = targetCenter - flightDirection * strafeHalfLength;
Vector3 strafeEnd = targetCenter + flightDirection * strafeHalfLength;
// 沿着扫射区域计算单元格
int steps = Mathf.CeilToInt(Props.strafeLength / 1f);
// 使用整数步进避免浮点精度问题
int steps = Mathf.Max(1, Mathf.CeilToInt(Props.strafeLength));
for (int i = 0; i <= steps; i++)
{
float progress = (float)i / steps;
@@ -181,7 +225,13 @@ namespace ArachnaeSwarm
{
Vector3 offset = perpendicular * w;
Vector3 cellPos = centerPoint + offset;
IntVec3 cell = new IntVec3((int)cellPos.x, (int)cellPos.y, (int)cellPos.z);
// 使用更精确的单元格转换
IntVec3 cell = new IntVec3(
Mathf.RoundToInt(cellPos.x),
Mathf.RoundToInt(cellPos.y),
Mathf.RoundToInt(cellPos.z)
);
if (cell.InBounds(map) && !cells.Contains(cell))
{
@@ -190,18 +240,18 @@ namespace ArachnaeSwarm
}
}
Log.Message($"Strafing Area: Calculated {cells.Count} impact cells ({Props.strafeWidth * 2 + 1}x{Props.strafeLength})");
Log.Message($"Strafing Area: Calculated {cells.Count} impact cells centered at {targetCell}");
return cells;
}
// 绘制扫射范围边界
private void DrawStrafingBoundaries(IntVec3 startPos, IntVec3 endPos, Vector3 flightDirection)
// 修复:绘制扫射范围边界,现在以目标单元格为中心
private void DrawStrafingBoundaries(IntVec3 targetCell, Vector3 flightDirection)
{
Map map = parent.pawn.Map;
Vector3 perpendicular = new Vector3(-flightDirection.z, 0f, flightDirection.x).normalized;
// 计算扫射区域的中心
Vector3 targetCenter = Vector3.Lerp(startPos.ToVector3(), endPos.ToVector3(), 0.5f);
// 修复:以目标单元格为中心
Vector3 targetCenter = targetCell.ToVector3();
// 计算扫射区域的起始和结束位置
float strafeHalfLength = Props.strafeLength * 0.5f;
@@ -214,20 +264,27 @@ namespace ArachnaeSwarm
Vector3 endLeft = strafeEnd + perpendicular * Props.strafeWidth;
Vector3 endRight = strafeEnd - perpendicular * Props.strafeWidth;
// 转换为 IntVec3
IntVec3 startLeftCell = new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z);
IntVec3 startRightCell = new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z);
IntVec3 endLeftCell = new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z);
IntVec3 endRightCell = new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z);
// 转换为 IntVec3 并确保在地图范围内
IntVec3 startLeftCell = GetSafeMapPosition(new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z), map);
IntVec3 startRightCell = GetSafeMapPosition(new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z), map);
IntVec3 endLeftCell = GetSafeMapPosition(new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z), map);
IntVec3 endRightCell = GetSafeMapPosition(new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z), map);
// 绘制边界线
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
// 绘制边界线 - 只绘制在地图范围内的线段
if (startLeftCell.InBounds(map) && endLeftCell.InBounds(map))
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
if (startRightCell.InBounds(map) && endRightCell.InBounds(map))
GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
if (startLeftCell.InBounds(map) && startRightCell.InBounds(map))
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
if (endLeftCell.InBounds(map) && endRightCell.InBounds(map))
GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
}
// 新增:绘制扇形区域预览 - 使用strafeWidth来近似扇形扫过的区域宽度
// 绘制扇形区域预览
private void DrawSectorAreaPreview(IntVec3 startPos, IntVec3 endPos)
{
Map map = parent.pawn.Map;
@@ -268,10 +325,10 @@ namespace ArachnaeSwarm
Map map = parent.pawn.Map;
// 计算飞行路径的总长度
float totalPathLength = startPos.DistanceTo(endPos);
float totalPathLength = Vector3.Distance(startPos.ToVector3(), endPos.ToVector3());
// 沿着飞行路径计算预览单元格
int steps = Mathf.CeilToInt(totalPathLength / 1f);
int steps = Mathf.Max(1, Mathf.CeilToInt(totalPathLength));
for (int i = 0; i <= steps; i++)
{
float progress = (float)i / steps;
@@ -282,7 +339,13 @@ namespace ArachnaeSwarm
{
Vector3 offset = perpendicular * w;
Vector3 cellPos = centerPoint + offset;
IntVec3 cell = new IntVec3((int)cellPos.x, (int)cellPos.y, (int)cellPos.z);
// 使用精确的单元格转换
IntVec3 cell = new IntVec3(
Mathf.RoundToInt(cellPos.x),
Mathf.RoundToInt(cellPos.y),
Mathf.RoundToInt(cellPos.z)
);
if (cell.InBounds(map) && !cells.Contains(cell))
{
@@ -305,17 +368,24 @@ namespace ArachnaeSwarm
Vector3 endLeft = endPos.ToVector3() + perpendicular * Props.strafeWidth;
Vector3 endRight = endPos.ToVector3() - perpendicular * Props.strafeWidth;
// 转换为 IntVec3
IntVec3 startLeftCell = new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z);
IntVec3 startRightCell = new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z);
IntVec3 endLeftCell = new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z);
IntVec3 endRightCell = new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z);
// 转换为 IntVec3 并确保在地图范围内
IntVec3 startLeftCell = GetSafeMapPosition(new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z), map);
IntVec3 startRightCell = GetSafeMapPosition(new IntVec3((int)startRight.x, (int)startRight.y, (int)startRight.z), map);
IntVec3 endLeftCell = GetSafeMapPosition(new IntVec3((int)endLeft.x, (int)endLeft.y, (int)endLeft.z), map);
IntVec3 endRightCell = GetSafeMapPosition(new IntVec3((int)endRight.x, (int)endRight.y, (int)endRight.z), map);
// 绘制边界线
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
// 绘制边界线 - 只绘制在地图范围内的线段
if (startLeftCell.InBounds(map) && endLeftCell.InBounds(map))
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), endLeftCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
if (startRightCell.InBounds(map) && endRightCell.InBounds(map))
GenDraw.DrawLineBetween(startRightCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
if (startLeftCell.InBounds(map) && startRightCell.InBounds(map))
GenDraw.DrawLineBetween(startLeftCell.ToVector3Shifted(), startRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
if (endLeftCell.InBounds(map) && endRightCell.InBounds(map))
GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Blue, 0.2f);
}
// 预处理扫射目标单元格
@@ -335,8 +405,8 @@ namespace ArachnaeSwarm
return confirmedTargets;
}
// 创建地面扫射飞越
private void CreateGroundStrafingFlyOver(IntVec3 startPos, IntVec3 endPos)
// 修复:创建地面扫射飞越,现在接受目标单元格参数
private void CreateGroundStrafingFlyOver(IntVec3 startPos, IntVec3 endPos, IntVec3 targetCell)
{
ThingDef flyOverDef = Props.flyOverDef ?? DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveCorvette");
if (flyOverDef == null)
@@ -363,9 +433,9 @@ namespace ArachnaeSwarm
CompGroundStrafing strafingComp = flyOver.GetComp<CompGroundStrafing>();
if (strafingComp != null)
{
// 计算扫射区域的所有单元格
// 修复:计算扫射区域的所有单元格,以目标单元格为中心
Vector3 flightDirection = (endPos.ToVector3() - startPos.ToVector3()).normalized;
List<IntVec3> potentialTargetCells = CalculateStrafingImpactCells(startPos, endPos, flightDirection);
List<IntVec3> potentialTargetCells = CalculateStrafingImpactCells(targetCell, flightDirection);
if (potentialTargetCells.Count > 0)
{
@@ -395,7 +465,7 @@ namespace ArachnaeSwarm
}
}
// 新增:创建扇形监视飞越
// 创建扇形监视飞越
private void CreateSectorSurveillanceFlyOver(IntVec3 startPos, IntVec3 endPos)
{
ThingDef flyOverDef = Props.flyOverDef ?? DefDatabase<ThingDef>.GetNamedSilentFail("ARA_HiveCorvette");
@@ -420,9 +490,6 @@ namespace ArachnaeSwarm
flyOver.playFlyOverSound = Props.playFlyOverSound;
Log.Message($"SectorSurveillance FlyOver created: {flyOver} from {startPos} to {endPos}");
// 注意扇形监视的具体参数角度、射程、发射次数等在FlyOver的CompProperties_SectorSurveillance中定义
// 这里只负责创建FlyOver不传递具体参数
}
// 计算垂直线进场路径
@@ -471,27 +538,107 @@ namespace ArachnaeSwarm
// 在指定方向上找到地图边缘
private IntVec3 FindMapEdgeInDirection(Map map, IntVec3 fromPos, Vector3 direction)
{
// 计算最大搜索距离(地图对角线的一半)
float maxDistance = Mathf.Sqrt(map.Size.x * map.Size.x + map.Size.z * map.Size.z) * 0.6f;
// 沿着方向逐步搜索,直到找到地图边界
for (float distance = 10f; distance <= maxDistance; distance += 5f)
// 确保方向向量有效
if (direction == Vector3.zero)
{
IntVec3 testPos = fromPos + new IntVec3(
Mathf.RoundToInt(direction.x * distance),
0,
Mathf.RoundToInt(direction.z * distance));
direction = new Vector3(Rand.Range(-1f, 1f), 0, Rand.Range(-1f, 1f)).normalized;
}
// 使用更精确的地图边界计算
IntVec3 mapCenter = map.Center;
IntVec3 mapSize = new IntVec3(map.Size.x, 0, map.Size.z);
// 计算与地图边界的交点
Vector3 fromVec = fromPos.ToVector3();
Vector3 dirNormalized = direction.normalized;
// 计算到各个边界的距离
float tMin = float.MaxValue;
IntVec3? bestEdgePos = null;
// 检查四个边界
for (int i = 0; i < 4; i++)
{
float t = 0f;
IntVec3 edgePos = IntVec3.Invalid;
if (!testPos.InBounds(map))
switch (i)
{
// 找到边界,返回最近的有效位置
IntVec3 edgePos = FindClosestValidPosition(testPos, map);
Log.Message($"Found map edge at {edgePos} (direction: {direction}, distance: {distance})");
return edgePos;
case 0: // 左边界 (x = 0)
if (Mathf.Abs(dirNormalized.x) > 0.001f)
{
t = (0 - fromVec.x) / dirNormalized.x;
if (t > 0)
{
float z = fromVec.z + dirNormalized.z * t;
if (z >= 0 && z < map.Size.z)
{
edgePos = new IntVec3(0, 0, Mathf.RoundToInt(z));
}
}
}
break;
case 1: // 右边界 (x = map.Size.x - 1)
if (Mathf.Abs(dirNormalized.x) > 0.001f)
{
t = (map.Size.x - 1 - fromVec.x) / dirNormalized.x;
if (t > 0)
{
float z = fromVec.z + dirNormalized.z * t;
if (z >= 0 && z < map.Size.z)
{
edgePos = new IntVec3(map.Size.x - 1, 0, Mathf.RoundToInt(z));
}
}
}
break;
case 2: // 下边界 (z = 0)
if (Mathf.Abs(dirNormalized.z) > 0.001f)
{
t = (0 - fromVec.z) / dirNormalized.z;
if (t > 0)
{
float x = fromVec.x + dirNormalized.x * t;
if (x >= 0 && x < map.Size.x)
{
edgePos = new IntVec3(Mathf.RoundToInt(x), 0, 0);
}
}
}
break;
case 3: // 上边界 (z = map.Size.z - 1)
if (Mathf.Abs(dirNormalized.z) > 0.001f)
{
t = (map.Size.z - 1 - fromVec.z) / dirNormalized.z;
if (t > 0)
{
float x = fromVec.x + dirNormalized.x * t;
if (x >= 0 && x < map.Size.x)
{
edgePos = new IntVec3(Mathf.RoundToInt(x), 0, map.Size.z - 1);
}
}
}
break;
}
// 找到最近的有效边界点
if (edgePos.IsValid && edgePos.InBounds(map) && t > 0 && t < tMin)
{
tMin = t;
bestEdgePos = edgePos;
}
}
// 如果没找到边界,使用随机边缘位置
if (bestEdgePos.HasValue)
{
return bestEdgePos.Value;
}
// 如果没找到合适的边界点,使用随机边缘位置
Log.Warning($"Could not find map edge in direction {direction}, using random edge");
return GetRandomMapEdgePosition(map);
}
@@ -510,7 +657,7 @@ namespace ArachnaeSwarm
return GetMapEdgePosition(map, GetDirectionFromCasterToTarget(target));
case StartPosition.CustomOffset:
return parent.pawn.Position + Props.customStartOffset;
return GetSafeMapPosition(parent.pawn.Position + Props.customStartOffset, map);
case StartPosition.RandomMapEdge:
return GetRandomMapEdgePosition(map);
@@ -536,7 +683,7 @@ namespace ArachnaeSwarm
break;
case EndPosition.CustomOffset:
endPos = target.Cell + Props.customEndOffset;
endPos = GetSafeMapPosition(target.Cell + Props.customEndOffset, map);
break;
case EndPosition.FixedDistance:
@@ -553,10 +700,10 @@ namespace ArachnaeSwarm
break;
}
return endPos;
return GetSafeMapPosition(endPos, map);
}
// 原有的辅助方法保持不变
// 原有的辅助方法
private IntVec3 GetOppositeMapEdgeThroughCenter(Map map, IntVec3 startPos)
{
IntVec3 center = map.Center;
@@ -731,34 +878,6 @@ namespace ArachnaeSwarm
Log.Message($"Standard FlyOver created: {flyOver} from {startPos} to {endPos}");
}
private void ShowEffectMessage()
{
string message = GetFlyOverMessage();
Messages.Message(message, parent.pawn, MessageTypeDefOf.NeutralEvent);
}
private string GetFlyOverMessage()
{
switch (Props.flyOverType)
{
case FlyOverType.HighAltitude:
return "HighAltitudeReconArrival".Translate(parent.pawn.LabelShort);
case FlyOverType.CargoDrop:
return "CargoDropIncoming".Translate(parent.pawn.LabelShort);
case FlyOverType.BombingRun:
return "BombingRunInitiated".Translate(parent.pawn.LabelShort);
case FlyOverType.Reconnaissance:
return "ReconnaissanceFlyOver".Translate(parent.pawn.LabelShort);
case FlyOverType.GroundStrafing:
return "GroundStrafingIncoming".Translate(parent.pawn.LabelShort);
case FlyOverType.SectorSurveillance:
return "SectorSurveillanceActive".Translate(parent.pawn.LabelShort);
case FlyOverType.Standard:
default:
return "FlyOverInitiated".Translate(parent.pawn.LabelShort);
}
}
// 更新技能提示信息
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{

View File

@@ -575,7 +575,7 @@ namespace ArachnaeSwarm
public float minShadowScale = 0.5f;
public float maxShadowScale = 1.0f;
public float defaultFadeInDuration = 1.5f;
public float defaultFadeOutDuration = 1.5f;
public float defaultFadeOutDuration = 0.5f;
public float fadeOutStartProgress = 0.98f;
// 动态淡出配置