This commit is contained in:
Tourswen
2025-11-10 01:19:43 +08:00
parent 2f20af64f3
commit b1fea9a600
16 changed files with 715 additions and 123 deletions

View File

@@ -143,6 +143,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Light_Fighter_Drone_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Fighter_Drone_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks>
@@ -189,6 +192,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Light_Fighter_Drone_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Fighter_Drone_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks>
@@ -243,6 +249,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Striker_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Striker_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks>
@@ -277,7 +286,7 @@
<AbilityDef>
<defName>WULA_Spawn_Striker_RailGun</defName>
<label>攻击机扫射</label>
<description>指挥乌拉帝国的机,高速掠过战场,使用机腹的两台高射速机炮打击目标地点——因为速度原因,打击区会很狭长。</description>
<description>指挥乌拉帝国的攻击机,高速掠过战场,使用机腹的两台高射速机炮打击目标地点——因为速度原因,打击区会很狭长。</description>
<iconPath>Wula/UI/Abilities/WULA_Spawn_Striker_RailGun</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
@@ -295,6 +304,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Striker_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Striker_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks>
@@ -340,7 +352,7 @@
<AbilityDef>
<defName>WULA_Spawn_Striker_EMP</defName>
<label>攻击机电磁压制</label>
<description>指挥乌拉帝国的高速掠过战场快速丢下一组EMP炸弹——因为速度原因打击区会很狭长。</description>
<description>指挥乌拉帝国的攻击高速掠过战场快速丢下一组EMP炸弹——因为速度原因打击区会很狭长。</description>
<iconPath>Wula/UI/Abilities/WULA_Spawn_Striker_EMP</iconPath>
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
@@ -358,6 +370,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Striker_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Striker_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks>
@@ -421,6 +436,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Bomber_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Bomber_Entity</requiredAircraftType>
<aircraftCooldownTicks>10000</aircraftCooldownTicks>
@@ -484,6 +502,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Bomber_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Bomber_Entity</requiredAircraftType>
<aircraftCooldownTicks>5000</aircraftCooldownTicks>
@@ -547,6 +568,9 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
<requiredResearch>WULA_Bomber_Technology</requiredResearch>
</li>
<li Class="WulaFallenEmpire.CompProperties_AircraftStrike">
<requiredAircraftType>WULA_Bomber_Entity</requiredAircraftType>
<aircraftCooldownTicks>10000</aircraftCooldownTicks>
@@ -592,9 +616,9 @@
<!-- 炮击 -->
<AbilityDef>
<defName>WULA_Spawn_ShipChunkIncoming</defName>
<label>战舰轰炸</label>
<description>我炸死你</description>
<defName>WULA_Firepower_Minigun_Strafe</defName>
<label>链炮扫射</label>
<description>以战舰上的自动链炮对目标区域进行可选方向的扫射,射击速度和冷却都很快,但是威力欠佳。</description>
<!-- <iconPath>ArachnaeSwarm/UI/Abilities/ARA_Spawn_ARA_HiveCorvette_Rocket</iconPath> -->
<cooldownTicksRange>1</cooldownTicksRange>
<hotKey>Misc12</hotKey>
@@ -612,6 +636,10 @@
</targetParams>
</verbProperties>
<comps>
<li Class="WulaFallenEmpire.CompProperties_GlobalFlyOverCooldown">
<globalCooldownTicks>1000</globalCooldownTicks>
<requiredFacility>BombardmentFacility</requiredFacility>
</li>
<li Class="WulaFallenEmpire.CompProperties_AbilityBombardment">
<bombardmentWidth>5</bombardmentWidth>
<bombardmentLength>35</bombardmentLength>
@@ -624,7 +652,7 @@
<showBombardmentArea>true</showBombardmentArea>
<effecterScale>1.5</effecterScale>
<areaPreviewColor>1.0,0.3,0.1,0.3</areaPreviewColor>
<skyfallerDef>ShipChunkIncoming</skyfallerDef>
<skyfallerDef>WULA_Firepower_Minigun_Strafe_Skyfaller</skyfallerDef>
</li>
<li Class="WulaFallenEmpire.CompProperties_RequireFlyOverFacility">
<!-- <flyOverDef></flyOverDef> -->

View File

@@ -73,7 +73,7 @@
<comps>
<li Class="HediffCompProperties_GiveAbility">
<abilityDefs>
<li>WULA_Spawn_ShipChunkIncoming</li>
<li>WULA_Firepower_Minigun_Strafe</li>
</abilityDefs>
</li>
</comps>

View File

@@ -56,7 +56,7 @@
<ResearchProjectDef ParentName="WULAtechBase">
<defName>WULA_Striker_Technology</defName>
<label>攻击机调配许可</label>
<description>允许殖民地建立信标增加攻击机配额,并使得机械乌拉可以调频天线以申请航空器空中打击。\n\n乌拉帝国的攻击机是强大的对地支援火力挂载了大量导弹和强大的机炮对敌方目标实施精准收割。\n\n空中打击依赖于战舰的&lt;color=#BD952F>&lt;i>机库&lt;/i>&lt;/color>,只有携带此类设施的战舰出现在地图中时,才能呼叫航空器支援。</description>
<description>允许殖民地建立信标增加攻击机配额,并使得机械乌拉可以调频天线以申请航空器空中打击。\n\n乌拉帝国的攻击机是强大的对地支援火力挂载了大量导弹、EMP炸弹和强大的机炮,对敌方目标实施精准收割。\n\n空中打击依赖于战舰的&lt;color=#BD952F>&lt;i>机库&lt;/i>&lt;/color>,只有携带此类设施的战舰出现在地图中时,才能呼叫航空器支援。</description>
<baseCost>600</baseCost>
<researchViewX>5.00</researchViewX>
<researchViewY>4.40</researchViewY>
@@ -81,7 +81,7 @@
<ResearchProjectDef ParentName="WULAtechBase">
<defName>WULA_Bomber_Technology</defName>
<label>轰炸机调配许可</label>
<description>允许殖民地建立信标增加轰炸机配额,并使得机械乌拉可以调频天线以申请航空器空中打击。\n\n乌拉帝国的轰炸机是可以进入大气层的最大的飞行载具除了可以使用机炮监视航路外,能投下大量炸弹夷平帝国之敌。\n\n空中打击依赖于战舰的&lt;color=#BD952F>&lt;i>机库&lt;/i>&lt;/color>,只有携带此类设施的战舰出现在地图中时,才能呼叫航空器支援。</description>
<description>允许殖民地建立信标增加轰炸机配额,并使得机械乌拉可以调频天线以申请航空器空中打击。\n\n乌拉帝国的轰炸机是可以进入大气层的最大的飞行载具除了投掷功能性的烟雾弹外,能投下大量炸弹或是发射一枚暗物质导弹夷平帝国之敌。\n\n空中打击依赖于战舰的&lt;color=#BD952F>&lt;i>机库&lt;/i>&lt;/color>,只有携带此类设施的战舰出现在地图中时,才能呼叫航空器支援。</description>
<baseCost>600</baseCost>
<researchViewX>9.00</researchViewX>
<researchViewY>4.40</researchViewY>

View File

@@ -71,7 +71,7 @@
<ThingDef ParentName="BuildingBase">
<defName>WULA_Fake_Fighter_Drone_Building</defName>
<label>乌拉帝国蜂群无人机</label>
<description>111</description>
<description>一台小型无人机,装备了激光炮和汽油弹,可以为殖民地提供廉价但有效的空中支援。和那些大家伙不同,蜂群无人机不需要机库,并且可以通过舰队的电磁网补充能量,实现永久滞空作战。</description>
<thingClass>Building</thingClass>
<preventDroppingThingsOn>true</preventDroppingThingsOn>
<altitudeLayer>Building</altitudeLayer>
@@ -182,7 +182,7 @@
<ThingDef ParentName="BuildingBase">
<defName>WULA_Fake_Striker_Beacon_Building</defName>
<label>乌拉帝国攻击机信标</label>
<description>111</description>
<description>用于向乌拉帝国舰队提交资源的信标,可以换取一台乌拉帝国攻击机的支援。若想调动大型战机入场,需要轨道上有携带&lt;color=#BD952F>&lt;i>机库&lt;/i>&lt;/color>的战舰。\n\n乌拉帝国的攻击机是强大的对地支援火力挂载了大量导弹、EMP炸弹和强大的机炮对敌方目标实施精准收割。</description>
<thingClass>Building</thingClass>
<preventDroppingThingsOn>true</preventDroppingThingsOn>
<altitudeLayer>Building</altitudeLayer>
@@ -252,7 +252,7 @@
<ThingDef ParentName="BuildingBase">
<defName>WULA_Fake_Bomber_Beacon_Building</defName>
<label>乌拉帝国轰炸机信标</label>
<description>111</description>
<description>用于向乌拉帝国舰队提交资源的信标,可以换取一台乌拉帝国轰炸机的支援。若想调动大型战机入场,需要轨道上有携带&lt;color=#BD952F>&lt;i>机库&lt;/i>&lt;/color>的战舰。\n\n乌拉帝国的轰炸机是可以进入大气层的最大的飞行载具除了投掷功能性的烟雾弹外也能投下大量炸弹或是发射一枚暗物质导弹夷平帝国之敌。</description>
<thingClass>Building</thingClass>
<preventDroppingThingsOn>true</preventDroppingThingsOn>
<altitudeLayer>Building</altitudeLayer>

View File

@@ -63,6 +63,10 @@
<li>BuildingdropperFacility</li>
</availableFacilities>
</li>
<!-- 新增冷却组件 -->
<li Class="WulaFallenEmpire.CompProperties_FlyOverCooldown">
<baseCooldownTicks>60000</baseCooldownTicks> <!-- 1天 -->
</li>
</comps>
</ThingDef>
<ThingDef ParentName="EtherealThingBase">
@@ -125,6 +129,10 @@
<li>BombardmentFacility</li>
</availableFacilities>
</li>
<!-- 新增冷却组件 -->
<li Class="WulaFallenEmpire.CompProperties_FlyOverCooldown">
<baseCooldownTicks>60000</baseCooldownTicks> <!-- 1天 -->
</li>
</comps>
</ThingDef>
<ThingDef ParentName="EtherealThingBase">
@@ -191,6 +199,7 @@
</comps>
</ThingDef>
<!-- 战机 -->
<ThingDef Name="WULA_Fighter_Drone_Base" ParentName="EtherealThingBase" Abstract="True">
<thingClass>WulaFallenEmpire.FlyOver</thingClass>
<tickerType>Normal</tickerType>
@@ -695,4 +704,49 @@
</li>
</modExtensions>
</ThingDef>
<!-- 炮击 -->
<ThingDef ParentName="SkyfallerBase">
<defName>WULA_Firepower_Minigun_Strafe_Skyfaller</defName>
<label>链炮子弹</label>
<size>(1, 1)</size>
<graphicData>
<texPath>Wula/Projectile/WULA_Bullet_ChargeLanceShot_Red</texPath>
<graphicClass>Graphic_Single</graphicClass>
<shaderType>MoteGlow</shaderType>
<drawSize>5</drawSize>
</graphicData>
<skyfaller>
<movementType>Accelerate</movementType>
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
<shadowSize>(1, 1)</shadowSize>
<anticipationSound>DropPod_Fall</anticipationSound>
<anticipationSoundTicks>100</anticipationSoundTicks>
<impactSound>Explosion_Bomb</impactSound>
<moteSpawnTime>0.05</moteSpawnTime>
<motesPerCell>1</motesPerCell>
<cameraShake>1</cameraShake>
<rotationCurve>
<points>
<li>(0,180)</li>
<li>(1, 181)</li>
</points>
</rotationCurve>
<angleCurve>
<points>
<li>(0,0)</li>
<li>(1, 1)</li>
</points>
</angleCurve>
<explosionRadius>4</explosionRadius>
<explosionDamage>WULA_Firepower_Minigun_Strafe_Damage</explosionDamage>
<explosionDamageFactor>1</explosionDamageFactor>
</skyfaller>
</ThingDef>
<DamageDef ParentName="Bullet">
<defName>WULA_Firepower_Minigun_Strafe_Damage</defName>
<label>子弹</label>
<defaultDamage>25</defaultDamage>
<soundExplosion>Explosion_Bomb</soundExplosion>
</DamageDef>
</Defs>

View File

@@ -1,5 +1,25 @@
<?xml version="1.0" encoding="utf-8" ?>
<LanguageData>
<!-- 自动发射相关 -->
<LaunchAircraft>获得航空器</LaunchAircraft>
<LaunchAircraftDesc>获得对应的航空器</LaunchAircraftDesc>
<ToggleAutoLaunch>启用自动发射</ToggleAutoLaunch>
<ToggleAutoLaunchDesc>启用战机自动发射功能</ToggleAutoLaunchDesc>
<CancelAutoLaunch>取消自动发射</CancelAutoLaunch>
<CancelAutoLaunchDesc>取消预定的自动发射</CancelAutoLaunchDesc>
<!-- 状态消息 -->
<AircraftStatusLaunched>状态:已发射</AircraftStatusLaunched>
<AutoLaunchScheduled>自动发射:{0}秒后</AutoLaunchScheduled>
<AutoLaunchReady>自动发射:就绪</AutoLaunchReady>
<!-- 事件消息 -->
<AircraftAutoLaunchScheduled>战机自动发射预定:{0} 将在 {1} 秒后发射</AircraftAutoLaunchScheduled>
<AircraftAutoLaunchThreatDetected>检测到威胁 {0},预定战机自动发射</AircraftAutoLaunchThreatDetected>
<AircraftAutoLaunchManhunterDetected>检测到狂躁动物 {0},预定战机自动发射</AircraftAutoLaunchManhunterDetected>
<AutoLaunchCancelled>自动发射已取消</AutoLaunchCancelled>
<!-- 原有翻译保持不变 -->
<AircraftLaunched>已获得 {0} {1}</AircraftLaunched>
<HangarDamaged>机库已损坏</HangarDamaged>
<!-- Aircraft Strike Messages -->
<AircraftManagerNotFound>战机管理器未找到!</AircraftManagerNotFound>
<AircraftStrikeInitiated>空中打击已启动:{0}</AircraftStrikeInitiated>

View File

@@ -187,25 +187,6 @@
<WULA_NoFactoryFlyOver>需要拥有-生产设施-的战舰部署在殖民地轨道上才能空投</WULA_NoFactoryFlyOver>
<WULA_NoFactoryFlyOverDesc>当前地图上没有拥有-生产设施-的战舰部署在殖民地轨道上,无法进行空投</WULA_NoFactoryFlyOverDesc>
<!-- 自动发射相关 -->
<LaunchAircraft>发射战机</LaunchAircraft>
<LaunchAircraftDesc>手动发射战机到战机库</LaunchAircraftDesc>
<ToggleAutoLaunch>启用自动发射</ToggleAutoLaunch>
<ToggleAutoLaunchDesc>启用战机自动发射功能</ToggleAutoLaunchDesc>
<CancelAutoLaunch>取消自动发射</CancelAutoLaunch>
<CancelAutoLaunchDesc>取消预定的自动发射</CancelAutoLaunchDesc>
<!-- 状态消息 -->
<AircraftStatusLaunched>状态:已发射</AircraftStatusLaunched>
<AutoLaunchScheduled>自动发射:{0}秒后</AutoLaunchScheduled>
<AutoLaunchReady>自动发射:就绪</AutoLaunchReady>
<!-- 事件消息 -->
<AircraftAutoLaunchScheduled>战机自动发射预定:{0} 将在 {1} 秒后发射</AircraftAutoLaunchScheduled>
<AircraftAutoLaunchThreatDetected>检测到威胁 {0},预定战机自动发射</AircraftAutoLaunchThreatDetected>
<AircraftAutoLaunchManhunterDetected>检测到狂躁动物 {0},预定战机自动发射</AircraftAutoLaunchManhunterDetected>
<AutoLaunchCancelled>自动发射已取消</AutoLaunchCancelled>
<!-- 原有翻译保持不变 -->
<AircraftLaunched>已发射 {0} 架 {1}</AircraftLaunched>
<HangarDamaged>机库已损坏</HangarDamaged>
<WULA_LaunchToGlobalStorage>发射到乌拉帝国舰队</WULA_LaunchToGlobalStorage>
<WULA_LaunchToGlobalStorageDesc>将物品发送到乌拉帝国舰队,以便其使用这些材料进行加工。\n\n如果装备、武器和尸体被送到乌拉帝国舰队则它们会在下一次成品空投被扔回来其他的物资若被乌拉帝国舰队接收则一概不退。</WULA_LaunchToGlobalStorageDesc>
@@ -331,4 +312,27 @@
<WULA_OverflowStored>超出经验已存储</WULA_OverflowStored>
<WULA_DataPackPartiallyAbsorbed>吸收了 {0} 经验,{1} 转换为溢出数据包</WULA_DataPackPartiallyAbsorbed>
<WULA_DataPackOverflowOnly>所有 {0} 经验转换为溢出数据包(已达到最大品质)</WULA_DataPackOverflowOnly>
<WULA_ResearchRequired>使用该技能需要研究科技 {0}</WULA_ResearchRequired>
<!-- 轰炸能力相关翻译 -->
<SelectBombardmentStart>选择轰炸起点</SelectBombardmentStart>
<SelectBombardmentDirection>选择轰炸方向</SelectBombardmentDirection>
<CannotBombardInvalidLocation>无法在此位置进行轰炸</CannotBombardInvalidLocation>
<BombardmentInProgress>轰炸进行中</BombardmentInProgress>
<BombardmentCompleted>轰炸完成</BombardmentCompleted>
<WULA_GlobalFlyOverCooldown.CannotUseOutsideMap>无法在地图外使用</WULA_GlobalFlyOverCooldown.CannotUseOutsideMap>
<WULA_GlobalFlyOverCooldown.NoAvailableFacilities>轨道上的战舰没有可用的武器阵列(共{0}个,全部冷却中)</WULA_GlobalFlyOverCooldown.NoAvailableFacilities>
<WULA_GlobalFlyOverCooldown.FacilityStatus>武器阵列:{0}个就绪,{1}个冷却中</WULA_GlobalFlyOverCooldown.FacilityStatus>
<WULA_GlobalFlyOverCooldown.FacilityStatusError>设施状态错误</WULA_GlobalFlyOverCooldown.FacilityStatusError>
<WULA_GlobalFlyOverCooldown.FacilityStatusDetailed>武器阵列:{0}个就绪,{1}个冷却中</WULA_GlobalFlyOverCooldown.FacilityStatusDetailed>
<WULA_GlobalFlyOverCooldown.CooldownTime>冷却时间:{0}</WULA_GlobalFlyOverCooldown.CooldownTime>
<WULA_GlobalFlyOverCooldown.NoAvailableFacilitiesSimple>没有可用的武器阵列</WULA_GlobalFlyOverCooldown.NoAvailableFacilitiesSimple>
<!-- FlyOverCooldown 翻译 -->
<WULA_FlyOverCooldown.Ready>就绪</WULA_FlyOverCooldown.Ready>
<WULA_FlyOverCooldown.CooldownRemaining>冷却:{0}</WULA_FlyOverCooldown.CooldownRemaining>
<WULA_FlyOverCooldown.BombardmentFacilityStatus>武器阵列:{0}</WULA_FlyOverCooldown.BombardmentFacilityStatus>
<WULA_FlyOverCooldown.BombardmentFacilityReady>武器阵列:就绪</WULA_FlyOverCooldown.BombardmentFacilityReady>
</LanguageData>

View File

@@ -0,0 +1,32 @@
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class CompProperties_AbilityResearchPrereq : CompProperties_AbilityEffect
{
public ResearchProjectDef requiredResearch;
public CompProperties_AbilityResearchPrereq()
{
compClass = typeof(CompAbilityEffect_ResearchPrereq);
}
}
public class CompAbilityEffect_ResearchPrereq : CompAbilityEffect
{
public new CompProperties_AbilityResearchPrereq Props => (CompProperties_AbilityResearchPrereq)props;
public override bool GizmoDisabled(out string reason)
{
if (Props.requiredResearch != null && !Props.requiredResearch.IsFinished)
{
reason = "WULA_ResearchRequired".Translate(Props.requiredResearch.LabelCap);
return true;
}
reason = null;
return false;
}
}
}

View File

@@ -1,4 +1,3 @@
// CompAbilityEffect_Bombardment.cs
using RimWorld;
using Verse;
using UnityEngine;
@@ -7,7 +6,7 @@ using System.Linq;
namespace WulaFallenEmpire
{
public class CompAbilityEffect_Bombardment : CompAbilityEffect
public class CompAbilityEffect_Bombardment : CompAbilityEffect_WithDest
{
public new CompProperties_AbilityBombardment Props => (CompProperties_AbilityBombardment)props;
@@ -16,7 +15,7 @@ namespace WulaFallenEmpire
private List<IntVec3> targetCells = new List<IntVec3>();
private List<BombardmentRow> bombardmentRows = new List<BombardmentRow>();
private IntVec3 bombardmentCenter;
private Vector3 bombardmentDirection; // 轰炸前进方向(长度方向)
private Vector3 bombardmentDirection; // 轰炸前进方向
private int currentRowIndex = 0;
private int currentCellIndex = 0;
private int warmupTicksRemaining = 0;
@@ -37,15 +36,15 @@ namespace WulaFallenEmpire
try
{
Log.Message($"[Bombardment] Starting bombardment at {target.Cell}");
Log.Message($"[Bombardment] Starting bombardment at {target.Cell} with direction to {dest.Cell}");
// 计算轰炸区域和方向
CalculateBombardmentArea(target.Cell);
// 计算轰炸区域和方向(基于两个目标点)
CalculateBombardmentArea(target.Cell, dest.Cell);
// 选择目标格子
SelectTargetCells();
// 组织成排
// 组织成排 - 修复:确保正确的排序
OrganizeTargetCellsIntoRows();
// 开始前摇
@@ -59,6 +58,7 @@ namespace WulaFallenEmpire
}
}
// 重写:绘制双目标预览
public override void DrawEffectPreview(LocalTargetInfo target)
{
base.DrawEffectPreview(target);
@@ -68,11 +68,15 @@ namespace WulaFallenEmpire
try
{
// 动态计算轰炸区域
CalculateDynamicBombardmentArea(target.Cell);
// 绘制轰炸区域预览
DrawBombardmentAreaPreview(target.Cell);
// 如果正在选择第二个目标(方向点),则显示轰炸区域预览
if (selectedTarget.IsValid)
{
// 动态计算轰炸区域(基于第一个目标和当前鼠标位置)
CalculateDynamicBombardmentArea(selectedTarget.Cell, target.Cell);
// 绘制轰炸区域预览
DrawBombardmentAreaPreview(selectedTarget.Cell, target.Cell);
}
}
catch (System.Exception)
{
@@ -80,29 +84,26 @@ namespace WulaFallenEmpire
}
}
// 修复:动态计算轰炸区域,确保矩形长边垂直于施法者-目标连线
private void CalculateDynamicBombardmentArea(IntVec3 targetCell)
// 新增:基于两个目标点动态计算轰炸区域
private void CalculateDynamicBombardmentArea(IntVec3 startCell, IntVec3 directionCell)
{
Map map = parent.pawn.Map;
// 计算施法者到目标的方向
Vector3 casterToTarget = (targetCell.ToVector3() - parent.pawn.Position.ToVector3()).normalized;
// 计算轰炸方向(从起点指向方向点)
Vector3 direction = (directionCell.ToVector3() - startCell.ToVector3()).normalized;
// 如果方向为零向量,使用默认方向
if (casterToTarget == Vector3.zero)
if (direction == Vector3.zero)
{
casterToTarget = Vector3.forward;
direction = Vector3.forward;
}
// 修复:计算垂直于施法者-目标连线的方向(作为轰炸区域的长边方向)
Vector3 perpendicularDirection = new Vector3(-casterToTarget.z, 0, casterToTarget.x).normalized;
// 计算轰炸区域的所有单元格(使用正确的方向)
currentPreviewCells = CalculateBombardmentAreaCells(targetCell, perpendicularDirection, casterToTarget);
// 计算轰炸区域的所有单元格
currentPreviewCells = CalculateBombardmentAreaCells(startCell, direction);
}
// 绘制轰炸区域预览
private void DrawBombardmentAreaPreview(IntVec3 targetCell)
// 绘制轰炸区域预览(基于两个目标点)
private void DrawBombardmentAreaPreview(IntVec3 startCell, IntVec3 directionCell)
{
Map map = parent.pawn.Map;
@@ -116,37 +117,40 @@ namespace WulaFallenEmpire
}
// 绘制轰炸区域边界
DrawBombardmentBoundaries(targetCell);
DrawBombardmentBoundaries(startCell, directionCell);
}
// 修复:绘制轰炸区域边界,确保矩形长边垂直于施法者-目标连线
private void DrawBombardmentBoundaries(IntVec3 targetCell)
// 绘制轰炸区域边界(基于两个目标点)
private void DrawBombardmentBoundaries(IntVec3 startCell, IntVec3 directionCell)
{
Map map = parent.pawn.Map;
// 计算施法者到目标的方向
Vector3 casterToTarget = (targetCell.ToVector3() - parent.pawn.Position.ToVector3()).normalized;
// 计算轰炸方向
Vector3 direction = (directionCell.ToVector3() - startCell.ToVector3()).normalized;
// 如果方向为零向量,使用默认方向
if (casterToTarget == Vector3.zero)
if (direction == Vector3.zero)
{
casterToTarget = Vector3.forward;
direction = Vector3.forward;
}
// 修复:计算垂直于施法者-目标连线的方向(作为轰炸区域的长边方向)
Vector3 lengthDirection = new Vector3(-casterToTarget.z, 0, casterToTarget.x).normalized;
Vector3 widthDirection = casterToTarget; // 宽度方向沿着施法者-目标连线
// 计算垂直于轰炸方向的方向(作为轰炸区域的宽度方向)
Vector3 perpendicularDirection = new Vector3(-direction.z, 0, direction.x).normalized;
// 计算轰炸区域的四个角
Vector3 targetCenter = targetCell.ToVector3();
Vector3 startCenter = startCell.ToVector3();
float halfWidth = Props.bombardmentWidth * 0.5f;
float halfLength = Props.bombardmentLength * 0.5f;
float totalLength = Props.bombardmentLength;
Vector3 startLeft = targetCenter - lengthDirection * halfLength + widthDirection * halfWidth;
Vector3 startRight = targetCenter - lengthDirection * halfLength - widthDirection * halfWidth;
Vector3 endLeft = targetCenter + lengthDirection * halfLength + widthDirection * halfWidth;
Vector3 endRight = targetCenter + lengthDirection * halfLength - widthDirection * halfWidth;
// 轰炸起点
Vector3 startLeft = startCenter + perpendicularDirection * halfWidth;
Vector3 startRight = startCenter - perpendicularDirection * halfWidth;
// 轰炸终点(沿方向前进轰炸长度)
Vector3 endCenter = startCenter + direction * totalLength;
Vector3 endLeft = endCenter + perpendicularDirection * halfWidth;
Vector3 endRight = endCenter - perpendicularDirection * halfWidth;
// 转换为 IntVec3 并确保在地图范围内
IntVec3 startLeftCell = GetSafeMapPosition(new IntVec3((int)startLeft.x, (int)startLeft.y, (int)startLeft.z), map);
@@ -166,18 +170,39 @@ namespace WulaFallenEmpire
if (endLeftCell.InBounds(map) && endRightCell.InBounds(map))
GenDraw.DrawLineBetween(endLeftCell.ToVector3Shifted(), endRightCell.ToVector3Shifted(), SimpleColor.Red, 0.2f);
// 绘制方向箭头
DrawDirectionArrow(startCell, directionCell);
}
// 修复:计算轰炸区域的所有单元格,确保正确的方向
private List<IntVec3> CalculateBombardmentAreaCells(IntVec3 centerCell, Vector3 lengthDirection, Vector3 widthDirection)
// 绘制方向箭头
private void DrawDirectionArrow(IntVec3 startCell, IntVec3 directionCell)
{
Map map = parent.pawn.Map;
Vector3 startPos = startCell.ToVector3Shifted();
Vector3 directionPos = directionCell.ToVector3Shifted();
// 绘制从起点到方向点的连线
GenDraw.DrawLineBetween(startPos, directionPos, SimpleColor.Yellow, 0.1f);
// 在方向点绘制箭头标记
GenDraw.DrawTargetHighlight(directionCell);
}
// 计算轰炸区域的所有单元格(基于起点和方向)
private List<IntVec3> CalculateBombardmentAreaCells(IntVec3 startCell, Vector3 direction)
{
var areaCells = new List<IntVec3>();
Map map = parent.pawn.Map;
Vector3 center = centerCell.ToVector3();
Vector3 start = startCell.ToVector3();
// 计算垂直于轰炸方向的方向(宽度方向)
Vector3 perpendicularDirection = new Vector3(-direction.z, 0, direction.x).normalized;
float halfWidth = Props.bombardmentWidth * 0.5f;
float halfLength = Props.bombardmentLength * 0.5f;
float totalLength = Props.bombardmentLength;
// 使用浮点步进计算所有单元格
int widthSteps = Mathf.Max(1, Props.bombardmentWidth);
@@ -186,15 +211,15 @@ namespace WulaFallenEmpire
for (int l = 0; l <= lengthSteps; l++)
{
float lengthProgress = (float)l / lengthSteps;
float lengthOffset = Mathf.Lerp(-halfLength, halfLength, lengthProgress);
float lengthOffset = Mathf.Lerp(0, totalLength, lengthProgress);
for (int w = 0; w <= widthSteps; w++)
{
float widthProgress = (float)w / widthSteps;
float widthOffset = Mathf.Lerp(-halfWidth, halfWidth, widthProgress);
// 修复:使用正确的方向计算单元格位置
Vector3 cellPos = center + lengthDirection * lengthOffset + widthDirection * widthOffset;
// 计算单元格位置
Vector3 cellPos = start + direction * lengthOffset + perpendicularDirection * widthOffset;
IntVec3 cell = new IntVec3(
Mathf.RoundToInt(cellPos.x),
@@ -212,44 +237,29 @@ namespace WulaFallenEmpire
return areaCells;
}
// 修复:计算轰炸区域和方向,确保轰炸前进方向垂直于施法者-目标连线
private void CalculateBombardmentArea(IntVec3 targetCell)
// 计算轰炸区域和方向(基于两个目标点)
private void CalculateBombardmentArea(IntVec3 startCell, IntVec3 directionCell)
{
bombardmentCenter = targetCell;
bombardmentCenter = startCell;
// 计算施法者到目标的方向
Vector3 casterToTarget = (targetCell.ToVector3() - parent.pawn.Position.ToVector3()).normalized;
// 计算轰炸方向(从起点指向方向点)
Vector3 direction = (directionCell.ToVector3() - startCell.ToVector3()).normalized;
// 如果方向为零向量,使用默认方向
if (casterToTarget == Vector3.zero)
if (direction == Vector3.zero)
{
casterToTarget = Vector3.forward;
direction = Vector3.forward;
}
// 修复:计算垂直于施法者-目标连线的两个方向(作为可能的轰炸前进方向)
Vector3 perpendicular1 = new Vector3(-casterToTarget.z, 0, casterToTarget.x).normalized;
Vector3 perpendicular2 = new Vector3(casterToTarget.z, 0, -casterToTarget.x).normalized;
bombardmentDirection = direction;
// 随机选择轰炸前进方向(垂直于施法者-目标连线)
bombardmentDirection = Rand.Value < 0.5f ? perpendicular1 : perpendicular2;
Log.Message($"[Bombardment] Bombardment direction: {bombardmentDirection} (perpendicular to caster-target line)");
Log.Message($"[Bombardment] Bombardment direction: {bombardmentDirection} (from {startCell} to {directionCell})");
}
private void SelectTargetCells()
{
// 计算施法者到目标的方向
Vector3 casterToTarget = (bombardmentCenter.ToVector3() - parent.pawn.Position.ToVector3()).normalized;
// 如果方向为零向量,使用默认方向
if (casterToTarget == Vector3.zero)
{
casterToTarget = Vector3.forward;
}
// 修复:使用正确的方向计算轰炸区域
Vector3 widthDirection = casterToTarget; // 宽度方向沿着施法者-目标连线
var areaCells = CalculateBombardmentAreaCells(bombardmentCenter, bombardmentDirection, widthDirection);
// 计算轰炸区域的所有单元格
var areaCells = CalculateBombardmentAreaCells(bombardmentCenter, bombardmentDirection);
var selectedCells = new List<IntVec3>();
var missedCells = new List<IntVec3>();
@@ -287,21 +297,20 @@ namespace WulaFallenEmpire
Log.Message($"[Bombardment] Selected {targetCells.Count} target cells from {areaCells.Count} area cells");
}
// 修复:组织目标格子成排,按照轰炸前进方向分组
// 修复:重新组织目标格子成排,确保正确的渐进顺序
private void OrganizeTargetCellsIntoRows()
{
bombardmentRows.Clear();
// 计算施法者到目标的方向(作为宽度方向)
Vector3 casterToTarget = (bombardmentCenter.ToVector3() - parent.pawn.Position.ToVector3()).normalized;
Vector3 widthDirection = casterToTarget;
// 计算垂直于轰炸方向的方向(宽度方向)
Vector3 perpendicularDirection = new Vector3(-bombardmentDirection.z, 0, bombardmentDirection.x).normalized;
// 根据轰炸前进方向将格子分组到不同的排
var rows = new Dictionary<int, List<IntVec3>>();
foreach (var cell in targetCells)
{
// 计算格子相对于轰炸中心的"行索引"(在轰炸前进方向上的投影)
// 计算格子相对于轰炸起点的"行索引"(在轰炸前进方向上的投影)
Vector3 cellVector = cell.ToVector3() - bombardmentCenter.ToVector3();
float dotProduct = Vector3.Dot(cellVector, bombardmentDirection);
int rowIndex = Mathf.RoundToInt(dotProduct);
@@ -313,22 +322,28 @@ namespace WulaFallenEmpire
rows[rowIndex].Add(cell);
}
// 按行索引排序并创建 BombardmentRow
// 修复:按照轰炸方向正确排序行索引
// 从起点(行索引=0开始向轰炸方向前进
var sortedRowIndices = rows.Keys.OrderBy(x => x).ToList();
foreach (var rowIndex in sortedRowIndices)
{
// 修复:在每排内按照宽度方向正确排序
// 从轰炸区域的一侧到另一侧
var sortedCells = rows[rowIndex].OrderBy(cell =>
{
Vector3 cellVector = cell.ToVector3() - bombardmentCenter.ToVector3();
return Vector3.Dot(cellVector, perpendicularDirection);
}).ToList();
bombardmentRows.Add(new BombardmentRow
{
rowIndex = rowIndex,
cells = rows[rowIndex].OrderBy(cell =>
{
Vector3 cellVector = cell.ToVector3() - bombardmentCenter.ToVector3();
return Vector3.Dot(cellVector, widthDirection); // 在宽度方向上排序
}).ToList()
cells = sortedCells
});
}
Log.Message($"[Bombardment] Organized into {bombardmentRows.Count} rows");
Log.Message($"[Bombardment] Organized into {bombardmentRows.Count} rows in progressive order");
}
private void StartWarmup()
@@ -356,7 +371,7 @@ namespace WulaFallenEmpire
// 前摇结束,开始轰炸
currentState = BombardmentState.Bombarding;
nextBombardmentTick = Find.TickManager.TicksGame;
Log.Message($"[Bombardment] Warmup completed, starting bombardment");
Log.Message($"[Bombardment] Warmup completed, starting progressive bombardment");
}
}
@@ -369,7 +384,7 @@ namespace WulaFallenEmpire
{
// 所有排都轰炸完毕
currentState = BombardmentState.Completed;
Log.Message($"[Bombardment] Bombardment completed");
Log.Message($"[Bombardment] Progressive bombardment completed");
return;
}
@@ -381,7 +396,7 @@ namespace WulaFallenEmpire
currentRowIndex++;
currentCellIndex = 0;
nextBombardmentTick = Find.TickManager.TicksGame + Props.rowDelayTicks;
Log.Message($"[Bombardment] Moving to row {currentRowIndex + 1}/{bombardmentRows.Count}");
Log.Message($"[Bombardment] Moving to next row {currentRowIndex + 1}/{bombardmentRows.Count}");
return;
}
@@ -391,6 +406,9 @@ namespace WulaFallenEmpire
currentCellIndex++;
nextBombardmentTick = Find.TickManager.TicksGame + Props.impactDelayTicks;
// 记录轰炸进度
Log.Message($"[Bombardment] Bombarding cell {currentCellIndex}/{currentRow.cells.Count} in row {currentRowIndex + 1}/{bombardmentRows.Count}");
}
private void LaunchBombardment(IntVec3 targetCell)
@@ -511,6 +529,80 @@ namespace WulaFallenEmpire
Scribe_Values.Look(ref warmupTicksRemaining, "warmupTicksRemaining", 0);
Scribe_Values.Look(ref nextBombardmentTick, "nextBombardmentTick", 0);
}
// 重写:获取目标参数
public override TargetingParameters targetParams => new TargetingParameters
{
canTargetLocations = true,
canTargetPawns = false,
canTargetBuildings = false,
canTargetItems = false,
mapObjectTargetsMustBeAutoAttackable = false
};
// 重写:验证目标
public override bool ValidateTarget(LocalTargetInfo target, bool showMessages = true)
{
if (!target.IsValid)
{
return false;
}
// 检查是否可以放置目标
if (!CanPlaceSelectedTargetAt(target))
{
if (showMessages)
{
// 修复:使用 LookTargets 而不是 LocalTargetInfo
Messages.Message("CannotBombardInvalidLocation".Translate(), new LookTargets(target.Cell, parent.pawn.Map), MessageTypeDefOf.RejectInput);
}
return false;
}
return true;
}
// 修复:使用 new 而不是 override因为基类方法不是 virtual
public new void DrawHighlight(LocalTargetInfo target)
{
if (selectedTarget.IsValid)
{
// 当选择第二个目标时,显示轰炸区域
CalculateDynamicBombardmentArea(selectedTarget.Cell, target.Cell);
DrawBombardmentAreaPreview(selectedTarget.Cell, target.Cell);
}
else
{
// 当选择第一个目标时,显示普通高亮
GenDraw.DrawTargetHighlight(target);
}
}
// 修复:使用 new 而不是 override因为基类方法不是 virtual
public new void OnGUI(LocalTargetInfo target)
{
Texture2D icon = ((!target.IsValid) ? TexCommand.CannotShoot : parent.def.uiIcon);
GenUI.DrawMouseAttachment(icon);
string text = ExtraLabelMouseAttachment(target);
if (!text.NullOrEmpty())
{
Widgets.MouseAttachedLabel(text);
}
}
// 重写:额外标签
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{
if (selectedTarget.IsValid)
{
return "SelectBombardmentDirection".Translate();
}
else
{
return "SelectBombardmentStart".Translate();
}
}
}
// 轰炸状态枚举

View File

@@ -1,11 +1,10 @@
// CompProperties_AbilityBombardment.cs
using RimWorld;
using Verse;
using UnityEngine;
namespace WulaFallenEmpire
{
public class CompProperties_AbilityBombardment : CompProperties_AbilityEffect
public class CompProperties_AbilityBombardment : CompProperties_EffectWithDest
{
// 轰炸区域配置
public int bombardmentWidth = 5; // 轰炸区域宽度
@@ -33,6 +32,8 @@ namespace WulaFallenEmpire
public CompProperties_AbilityBombardment()
{
this.compClass = typeof(CompAbilityEffect_Bombardment);
// 设置双目标选择
this.destination = AbilityEffectDestination.Selected;
}
}
}

View File

@@ -7,6 +7,27 @@ namespace WulaFallenEmpire
{
public class CompFlyOverFacilities : ThingComp
{
// 在 CompFlyOverFacilities 类中添加以下方法
public bool IsFacilityReady(string facilityName)
{
if (!HasFacility(facilityName))
return false;
var cooldownComp = parent.GetComp<CompFlyOverCooldown>();
return cooldownComp == null || !cooldownComp.IsOnCooldown;
}
public string GetFacilityStatus(string facilityName)
{
if (!HasFacility(facilityName))
return "Not Available";
var cooldownComp = parent.GetComp<CompFlyOverCooldown>();
if (cooldownComp == null)
return "Ready (No Cooldown)";
return cooldownComp.IsOnCooldown ? $"Cooldown: {cooldownComp.CooldownTicksRemaining.ToStringTicksToPeriod()}" : "Ready";
}
public CompProperties_FlyOverFacilities Props => (CompProperties_FlyOverFacilities)props;
// 当前激活的设施列表
@@ -62,6 +83,8 @@ namespace WulaFallenEmpire
}
}
public class CompProperties_FlyOverFacilities : CompProperties
{
// 可用的设施列表(简单的字符串列表)

View File

@@ -0,0 +1,238 @@
using RimWorld;
using Verse;
using System.Collections.Generic;
using System.Linq;
namespace WulaFallenEmpire
{
public class CompAbilityEffect_GlobalFlyOverCooldown : CompAbilityEffect
{
public new CompProperties_GlobalFlyOverCooldown Props => (CompProperties_GlobalFlyOverCooldown)props;
public override void Apply(LocalTargetInfo target, LocalTargetInfo dest)
{
base.Apply(target, dest);
if (parent.pawn == null || parent.pawn.Map == null)
return;
// 获取所有可用的轰炸设施FlyOver
var availableFlyOvers = GetAvailableFlyOvers();
if (availableFlyOvers.Count == 0)
{
Log.Error($"[GlobalFlyOverCooldown] No available FlyOver with BombardmentFacility found");
return;
}
// 随机选择一个FlyOver来执行任务
var selectedFlyOver = availableFlyOvers.RandomElement();
var facilitiesComp = selectedFlyOver.GetComp<CompFlyOverFacilities>();
if (facilitiesComp == null)
{
Log.Error($"[GlobalFlyOverCooldown] Selected FlyOver has no CompFlyOverFacilities");
return;
}
// 设置冷却时间
SetCooldown(selectedFlyOver, Props.globalCooldownTicks);
Log.Message($"[GlobalFlyOverCooldown] Set cooldown on FlyOver at {selectedFlyOver.Position} for {Props.globalCooldownTicks} ticks");
}
public override bool GizmoDisabled(out string reason)
{
if (parent.pawn?.Map == null)
{
reason = "WULA_GlobalFlyOverCooldown.CannotUseOutsideMap".Translate();
return true;
}
var availableFlyOvers = GetAvailableFlyOvers();
var totalFlyOvers = GetTotalFlyOvers();
if (availableFlyOvers.Count == 0)
{
reason = "WULA_GlobalFlyOverCooldown.NoAvailableFacilities".Translate(totalFlyOvers.Count);
return true;
}
return base.GizmoDisabled(out reason);
}
public override string ExtraLabelMouseAttachment(LocalTargetInfo target)
{
try
{
var availableFlyOvers = GetAvailableFlyOvers();
var totalFlyOvers = GetTotalFlyOvers();
var cooldownFlyOvers = totalFlyOvers.Count - availableFlyOvers.Count;
return "WULA_GlobalFlyOverCooldown.FacilityStatus".Translate(availableFlyOvers.Count, cooldownFlyOvers);
}
catch (System.Exception ex)
{
Log.Error($"[GlobalFlyOverCooldown] Error in ExtraLabelMouseAttachment: {ex}");
return "WULA_GlobalFlyOverCooldown.FacilityStatusError".Translate();
}
}
// 重写:添加额外的工具提示信息
public override string ExtraTooltipPart()
{
var availableFlyOvers = GetAvailableFlyOvers();
var totalFlyOvers = GetTotalFlyOvers();
var cooldownFlyOvers = totalFlyOvers.Count - availableFlyOvers.Count;
var baseTooltip = base.ExtraTooltipPart() ?? "";
var facilityDesc = "\n" + "WULA_GlobalFlyOverCooldown.FacilityStatusDetailed".Translate(availableFlyOvers.Count, cooldownFlyOvers);
if (availableFlyOvers.Count > 0)
{
var cooldownComp = availableFlyOvers[0].GetComp<CompFlyOverCooldown>();
if (cooldownComp != null)
{
facilityDesc += "\n" + "WULA_GlobalFlyOverCooldown.CooldownTime".Translate(Props.globalCooldownTicks.ToStringTicksToPeriod());
}
}
return baseTooltip + facilityDesc;
}
// 重写:验证目标时检查设施可用性
public override bool Valid(LocalTargetInfo target, bool throwMessages = false)
{
if (!base.Valid(target, throwMessages))
return false;
var availableFlyOvers = GetAvailableFlyOvers();
if (availableFlyOvers.Count == 0)
{
if (throwMessages)
{
Messages.Message("WULA_GlobalFlyOverCooldown.NoAvailableFacilitiesSimple".Translate(), parent.pawn, MessageTypeDefOf.RejectInput);
}
return false;
}
return true;
}
// 获取可用的FlyOver不在冷却中的
private List<FlyOver> GetAvailableFlyOvers()
{
var availableFlyOvers = new List<FlyOver>();
if (parent.pawn?.Map == null)
return availableFlyOvers;
try
{
var allFlyOvers = GetTotalFlyOvers();
foreach (var flyOver in allFlyOvers)
{
if (!IsOnCooldown(flyOver))
{
availableFlyOvers.Add(flyOver);
}
}
return availableFlyOvers;
}
catch (System.Exception ex)
{
Log.Error($"[GlobalFlyOverCooldown] Error in GetAvailableFlyOvers: {ex}");
return new List<FlyOver>();
}
}
// 获取所有具有轰炸设施的FlyOver
private List<FlyOver> GetTotalFlyOvers()
{
var totalFlyOvers = new List<FlyOver>();
if (parent.pawn?.Map == null)
return totalFlyOvers;
try
{
// 获取地图上所有FlyOver
var allFlyOvers = new List<Thing>();
var dynamicObjects = parent.pawn.Map.dynamicDrawManager.DrawThings;
foreach (var thing in dynamicObjects)
{
if (thing is FlyOver flyOver && !flyOver.Destroyed)
{
allFlyOvers.Add(thing);
}
}
// 筛选具有轰炸设施的FlyOver
foreach (var thing in allFlyOvers)
{
if (thing is FlyOver flyOver)
{
var facilitiesComp = flyOver.GetComp<CompFlyOverFacilities>();
if (facilitiesComp != null && facilitiesComp.HasFacility("BombardmentFacility"))
{
totalFlyOvers.Add(flyOver);
}
}
}
return totalFlyOvers;
}
catch (System.Exception ex)
{
Log.Error($"[GlobalFlyOverCooldown] Error in GetTotalFlyOvers: {ex}");
return new List<FlyOver>();
}
}
// 检查FlyOver是否在冷却中
private bool IsOnCooldown(FlyOver flyOver)
{
if (flyOver == null)
return true;
// 从FlyOver的comps中查找冷却组件
var cooldownComp = flyOver.GetComp<CompFlyOverCooldown>();
return cooldownComp?.IsOnCooldown ?? false;
}
// 设置FlyOver的冷却时间
private void SetCooldown(FlyOver flyOver, int cooldownTicks)
{
if (flyOver == null)
return;
// 获取或添加冷却组件
var cooldownComp = flyOver.GetComp<CompFlyOverCooldown>();
if (cooldownComp == null)
{
Log.Error($"[GlobalFlyOverCooldown] FlyOver at {flyOver.Position} has no CompFlyOverCooldown");
return;
}
cooldownComp.StartCooldown(cooldownTicks);
}
}
public class CompProperties_GlobalFlyOverCooldown : CompProperties_AbilityEffect
{
// 全局冷却时间ticks
public int globalCooldownTicks = 60000; // 默认1天
// 必需的设施名称
public string requiredFacility = "BombardmentFacility";
public CompProperties_GlobalFlyOverCooldown()
{
compClass = typeof(CompAbilityEffect_GlobalFlyOverCooldown);
}
}
}

View File

@@ -0,0 +1,96 @@
using RimWorld;
using Verse;
namespace WulaFallenEmpire
{
public class CompFlyOverCooldown : ThingComp
{
public CompProperties_FlyOverCooldown Props => (CompProperties_FlyOverCooldown)props;
// 冷却结束的tick
private int cooldownEndTick = -1;
// 是否在冷却中
public bool IsOnCooldown => Find.TickManager.TicksGame < cooldownEndTick;
// 剩余冷却时间ticks
public int CooldownTicksRemaining => IsOnCooldown ? cooldownEndTick - Find.TickManager.TicksGame : 0;
// 冷却进度0-1
public float CooldownProgress
{
get
{
if (!IsOnCooldown) return 0f;
int totalCooldown = cooldownEndTick - (cooldownEndTick - Props.baseCooldownTicks);
return 1f - ((float)CooldownTicksRemaining / Props.baseCooldownTicks);
}
}
public override void PostExposeData()
{
base.PostExposeData();
Scribe_Values.Look(ref cooldownEndTick, "cooldownEndTick", -1);
}
// 开始冷却
public void StartCooldown(int cooldownTicks = -1)
{
int actualCooldown = cooldownTicks > 0 ? cooldownTicks : Props.baseCooldownTicks;
cooldownEndTick = Find.TickManager.TicksGame + actualCooldown;
Log.Message($"[FlyOverCooldown] Cooldown started for {actualCooldown} ticks, ends at tick {cooldownEndTick}");
}
// 强制结束冷却
public void EndCooldown()
{
cooldownEndTick = -1;
}
// 获取冷却状态描述
public string GetCooldownStatus()
{
if (!IsOnCooldown)
return "WULA_FlyOverCooldown.Ready".Translate();
return "WULA_FlyOverCooldown.CooldownRemaining".Translate(CooldownTicksRemaining.ToStringTicksToPeriod());
}
public override void CompTick()
{
base.CompTick();
// 可以在这里添加冷却期间的视觉效果或逻辑
if (IsOnCooldown && Find.TickManager.TicksGame % 60 == 0) // 每60ticks检查一次
{
// 可选:在冷却期间添加一些视觉效果
if (Rand.MTBEventOccurs(10f, 1f, 1f))
{
FleckMaker.ThrowMetaIcon(parent.Position, parent.Map, FleckDefOf.SleepZ);
}
}
}
// 在检视面板中显示冷却信息
public override string CompInspectStringExtra()
{
if (IsOnCooldown)
{
return "WULA_FlyOverCooldown.BombardmentFacilityStatus".Translate(GetCooldownStatus());
}
return "WULA_FlyOverCooldown.BombardmentFacilityReady".Translate();
}
}
public class CompProperties_FlyOverCooldown : CompProperties
{
// 基础冷却时间ticks
public int baseCooldownTicks = 60000; // 默认1天
public CompProperties_FlyOverCooldown()
{
compClass = typeof(CompFlyOverCooldown);
}
}
}

View File

@@ -62,7 +62,7 @@ namespace WulaFallenEmpire
BombingRun, // 轰炸飞越
Reconnaissance, // 侦察飞越
GroundStrafing, // 地面扫射
SectorSurveillance // 扇形区域监视
SectorSurveillance, // 扇形区域监视
}
// 进场类型枚举

View File

@@ -71,6 +71,7 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Ability\CompAbilityEffect_ResearchPrereq.cs" />
<Compile Include="Ability\WULA_AbilityBombardment\CompAbilityEffect_Bombardment.cs" />
<Compile Include="Ability\WULA_AbilityBombardment\CompProperties_AbilityBombardment.cs" />
<Compile Include="BuildingComp\Building_TurretGunHasSpeed.cs" />
@@ -102,6 +103,9 @@
<Compile Include="Flyover\WULA_FlyOverEscort\CompProperties_FlyOverEscort.cs" />
<Compile Include="Flyover\WULA_FlyOverFacilities\CompAbilityEffect_RequireFlyOverFacility.cs" />
<Compile Include="Flyover\WULA_FlyOverFacilities\CompFlyOverFacilities.cs" />
<Compile Include="Flyover\WULA_FlyOverFormation\CompFlyOverFormation.cs" />
<Compile Include="Flyover\WULA_GlobalFlyOverCooldown\CompAbilityEffect_GlobalFlyOverCooldown.cs" />
<Compile Include="Flyover\WULA_GlobalFlyOverCooldown\CompFlyOverCooldown.cs" />
<Compile Include="Flyover\WULA_GroundStrafing\CompGroundStrafing.cs" />
<Compile Include="Flyover\WULA_SectorSurveillance\CompSectorSurveillance.cs" />
<Compile Include="Flyover\WULA_SendLetterAfterTicks\CompProperties_SendLetterAfterTicks.cs" />