99
This commit is contained in:
Binary file not shown.
@@ -173,6 +173,7 @@
|
|||||||
</comps>
|
</comps>
|
||||||
</AbilityDef>
|
</AbilityDef>
|
||||||
|
|
||||||
|
<!-- 全域封锁 -->
|
||||||
<AbilityDef>
|
<AbilityDef>
|
||||||
<defName>WULA_Spawn_BattleShip_Artillery</defName>
|
<defName>WULA_Spawn_BattleShip_Artillery</defName>
|
||||||
<label>呼叫全域封锁舰队</label>
|
<label>呼叫全域封锁舰队</label>
|
||||||
@@ -899,7 +900,7 @@
|
|||||||
<AbilityDef>
|
<AbilityDef>
|
||||||
<defName>WULA_Firepower_EnergyLance_Surveillance</defName>
|
<defName>WULA_Firepower_EnergyLance_Surveillance</defName>
|
||||||
<label>光矛监视</label>
|
<label>光矛监视</label>
|
||||||
<description>指挥战舰侧弦的副炮,监视一个区域1小时,对任何进入范围的敌对目标进行炮击。</description>
|
<description>指挥战舰侧弦的光矛阵列,监视一个区域1小时,对任何进入范围的敌对目标进行持续照射。</description>
|
||||||
<iconPath>Wula/UI/Abilities/WULA_Firepower_EnergyLance_Surveillance</iconPath>
|
<iconPath>Wula/UI/Abilities/WULA_Firepower_EnergyLance_Surveillance</iconPath>
|
||||||
<cooldownTicksRange>1</cooldownTicksRange>
|
<cooldownTicksRange>1</cooldownTicksRange>
|
||||||
<hotKey>Misc12</hotKey>
|
<hotKey>Misc12</hotKey>
|
||||||
@@ -1027,4 +1028,47 @@
|
|||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
</AbilityDef>
|
</AbilityDef>
|
||||||
|
|
||||||
|
<!-- 支援 -->
|
||||||
|
<AbilityDef>
|
||||||
|
<defName>WULA_Support_Shield_Projection</defName>
|
||||||
|
<label>护盾投射</label>
|
||||||
|
<description>以启动拒止舰的止戈立场,在指定地点投射一面球形护盾,阻挡并反射所有的外来射弹。</description>
|
||||||
|
<iconPath>Wula/UI/Abilities/WULA_Firepower_Minigun_Strafe</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="WulaFallenEmpire.CompProperties_GlobalFlyOverCooldown">
|
||||||
|
<globalCooldownTicks>1000</globalCooldownTicks>
|
||||||
|
<requiredFacility>BombardmentFacility</requiredFacility>
|
||||||
|
</li>
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_AbilityCallSkyfaller">
|
||||||
|
<delayTicks>0</delayTicks>
|
||||||
|
<skyfallerDef>WULA_Support_Shield_Projection_Skyfaller</skyfallerDef>
|
||||||
|
<previewRadius>12</previewRadius>
|
||||||
|
<previewColor>(0.6,0.8,0.8,0.5)</previewColor>
|
||||||
|
</li>
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_RequireFlyOverFacility">
|
||||||
|
<!-- <flyOverDef></flyOverDef> -->
|
||||||
|
<requiredFacility>FactoryFacility</requiredFacility>
|
||||||
|
<facilityNotFoundMessage>需要拥有<color=#BD2F31><i>支援设施</i></color>设施的战舰在地图上才能进行轨道炮击支援</facilityNotFoundMessage>
|
||||||
|
</li>
|
||||||
|
<!-- <li Class="WulaFallenEmpire.CompProperties_AbilityResearchPrereq">
|
||||||
|
<requiredResearch>WULA_Firepower_Minigun_Technology</requiredResearch>
|
||||||
|
</li> -->
|
||||||
|
</comps>
|
||||||
|
</AbilityDef>
|
||||||
</Defs>
|
</Defs>
|
||||||
@@ -167,6 +167,7 @@
|
|||||||
<li>WULA_CallMotherShip</li>
|
<li>WULA_CallMotherShip</li>
|
||||||
<li>WULA_CallConstructionShip</li>
|
<li>WULA_CallConstructionShip</li>
|
||||||
<li>WULA_ClearFlightPath</li>
|
<li>WULA_ClearFlightPath</li>
|
||||||
|
<li>WULA_Support_Shield_Projection</li>
|
||||||
</abilityDefs>
|
</abilityDefs>
|
||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
|
|||||||
@@ -636,10 +636,10 @@
|
|||||||
<Steel>5</Steel>
|
<Steel>5</Steel>
|
||||||
</costList>
|
</costList>
|
||||||
<statBases>
|
<statBases>
|
||||||
<MaxHitPoints>600</MaxHitPoints>
|
<MaxHitPoints>50</MaxHitPoints>
|
||||||
<Flammability>0.5</Flammability>
|
<Flammability>0.5</Flammability>
|
||||||
<WorkToBuild>1000</WorkToBuild>
|
<WorkToBuild>1000</WorkToBuild>
|
||||||
<Mass>125</Mass>
|
<Mass>5</Mass>
|
||||||
<Comfort>0.65</Comfort>
|
<Comfort>0.65</Comfort>
|
||||||
</statBases>
|
</statBases>
|
||||||
<tickerType>Normal</tickerType>
|
<tickerType>Normal</tickerType>
|
||||||
@@ -728,7 +728,6 @@
|
|||||||
<MaxHitPoints>50</MaxHitPoints>
|
<MaxHitPoints>50</MaxHitPoints>
|
||||||
<Flammability>1.0</Flammability>
|
<Flammability>1.0</Flammability>
|
||||||
<WorkToBuild>330</WorkToBuild>
|
<WorkToBuild>330</WorkToBuild>
|
||||||
<MaxHitPoints>35</MaxHitPoints>
|
|
||||||
<Mass>2</Mass>
|
<Mass>2</Mass>
|
||||||
</statBases>
|
</statBases>
|
||||||
<uiOrder>2991</uiOrder>
|
<uiOrder>2991</uiOrder>
|
||||||
|
|||||||
@@ -2176,4 +2176,165 @@
|
|||||||
</li>
|
</li>
|
||||||
</comps>
|
</comps>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
|
<ThingDef ParentName="SkyfallerBase">
|
||||||
|
<defName>WULA_Support_Shield_Projection_Skyfaller</defName>
|
||||||
|
<label>拒止护盾(落地中)</label>
|
||||||
|
<size>(1,1)</size>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>Wula/Building/Flag/WULA_Flag_Building_Mount</texPath>
|
||||||
|
<graphicClass>Graphic_Single</graphicClass>
|
||||||
|
<shaderType>TransparentPostLight</shaderType>
|
||||||
|
<drawSize>(1,1)</drawSize>
|
||||||
|
<damageData>
|
||||||
|
<enabled>false</enabled>
|
||||||
|
</damageData>
|
||||||
|
</graphicData>
|
||||||
|
<skyfaller>
|
||||||
|
<movementType>Accelerate</movementType>
|
||||||
|
<shadow>Things/Skyfaller/SkyfallerShadowDropPod</shadow>
|
||||||
|
<shadowSize>(0, 0)</shadowSize>
|
||||||
|
<anticipationSound>DropPod_Fall</anticipationSound>
|
||||||
|
<anticipationSoundTicks>100</anticipationSoundTicks>
|
||||||
|
<!-- <impactSound>Explosion_Vaporize</impactSound> -->
|
||||||
|
<moteSpawnTime>0.05</moteSpawnTime>
|
||||||
|
<motesPerCell>0</motesPerCell>
|
||||||
|
<cameraShake>0</cameraShake>
|
||||||
|
<angleCurve>
|
||||||
|
<points>
|
||||||
|
<li>(0,0)</li>
|
||||||
|
<li>(1, 1)</li>
|
||||||
|
</points>
|
||||||
|
</angleCurve>
|
||||||
|
<spawnThing>WULA_Support_Shield</spawnThing>
|
||||||
|
</skyfaller>
|
||||||
|
</ThingDef>
|
||||||
|
<ThingDef ParentName="BuildingBase">
|
||||||
|
<defName>WULA_Support_Shield</defName>
|
||||||
|
<label>全反射拒止护盾</label>
|
||||||
|
<description>一面大型护盾,反射所有的敌方射弹,己方的开火不受影响。</description>
|
||||||
|
<thingClass>WulaFallenEmpire.Building_ExtraGraphics</thingClass>
|
||||||
|
<preventDroppingThingsOn>true</preventDroppingThingsOn>
|
||||||
|
<altitudeLayer>BuildingOnTop</altitudeLayer>
|
||||||
|
<pathCost>50</pathCost>
|
||||||
|
<blockWind>true</blockWind>
|
||||||
|
<passability>PassThroughOnly</passability>
|
||||||
|
<fillPercent>1</fillPercent>
|
||||||
|
<size>(1,1)</size>
|
||||||
|
<drawHighlight>true</drawHighlight>
|
||||||
|
<highlightColor>(0.56, 0.62, 0.9)</highlightColor>
|
||||||
|
<uiIconPath>Wula/Building/Flag/WULA_Flag_Building_A</uiIconPath>
|
||||||
|
<rotatable>false</rotatable>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>Wula/Building/Flag/WULA_Flag_Building_Mount</texPath>
|
||||||
|
<graphicClass>Graphic_Single</graphicClass>
|
||||||
|
<shaderType>TransparentPostLight</shaderType>
|
||||||
|
<drawSize>(1,1)</drawSize>
|
||||||
|
</graphicData>
|
||||||
|
<costList>
|
||||||
|
<Steel>5</Steel>
|
||||||
|
</costList>
|
||||||
|
<statBases>
|
||||||
|
<MaxHitPoints>100</MaxHitPoints>
|
||||||
|
<Flammability>0.5</Flammability>
|
||||||
|
<WorkToBuild>1000</WorkToBuild>
|
||||||
|
<Mass>125</Mass>
|
||||||
|
<Comfort>0.65</Comfort>
|
||||||
|
</statBases>
|
||||||
|
<tickerType>Normal</tickerType>
|
||||||
|
<canOverlapZones>true</canOverlapZones>
|
||||||
|
<hasInteractionCell>false</hasInteractionCell>
|
||||||
|
<defaultPlacingRot>North</defaultPlacingRot>
|
||||||
|
<selectable>true</selectable>
|
||||||
|
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||||
|
<soundImpactDefault>BulletImpact_Metal</soundImpactDefault>
|
||||||
|
<preventSkyfallersLandingOn>true</preventSkyfallersLandingOn>
|
||||||
|
<drawerType>RealtimeOnly</drawerType>
|
||||||
|
<repairEffect>ConstructMetal</repairEffect>
|
||||||
|
<forceDebugSpawnable>true</forceDebugSpawnable>
|
||||||
|
<designationCategory>WULA_Buildings</designationCategory>
|
||||||
|
<building>
|
||||||
|
<expandHomeArea>false</expandHomeArea>
|
||||||
|
<destroySound>BuildingDestroyed_Metal_Big</destroySound>
|
||||||
|
<paintable>true</paintable>
|
||||||
|
<isInert>true</isInert>
|
||||||
|
</building>
|
||||||
|
<modExtensions>
|
||||||
|
<li Class="WulaFallenEmpire.ExtraGraphicsExtension">
|
||||||
|
<globalHoverSpeed>0</globalHoverSpeed>
|
||||||
|
<globalHoverIntensity>0</globalHoverIntensity>
|
||||||
|
|
||||||
|
<graphicLayers>
|
||||||
|
<li>
|
||||||
|
<texturePath>Wula/Building/Flag/WULA_Flag_Building_A</texturePath>
|
||||||
|
<scale>(3,3)</scale>
|
||||||
|
<drawOrder>0</drawOrder>
|
||||||
|
<offset>(0,1,3)</offset>
|
||||||
|
<hoverSpeed>1.5</hoverSpeed> <!-- 比全局慢 -->
|
||||||
|
<hoverIntensity>0.2</hoverIntensity> <!-- 比全局弱 -->
|
||||||
|
<hoverPhase>0</hoverPhase>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<texturePath>Wula/Building/Flag/WULA_Flag_Building_Mount</texturePath>
|
||||||
|
<scale>(1,1)</scale>
|
||||||
|
<drawOrder>1</drawOrder>
|
||||||
|
<offset>(0,1,0)</offset>
|
||||||
|
<hoverSpeed>0</hoverSpeed> <!-- 比全局慢 -->
|
||||||
|
<hoverIntensity>0</hoverIntensity> <!-- 比全局弱 -->
|
||||||
|
<hoverPhase>0</hoverPhase>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<texturePath>Wula/Building/WULA_Support_Shield_Building</texturePath>
|
||||||
|
<scale>(24,24)</scale>
|
||||||
|
<drawOrder>2</drawOrder>
|
||||||
|
<offset>(0,1,0)</offset>
|
||||||
|
<hoverSpeed>0</hoverSpeed>
|
||||||
|
<hoverIntensity>0</hoverIntensity>
|
||||||
|
<hoverPhase>0</hoverPhase>
|
||||||
|
</li>
|
||||||
|
</graphicLayers>
|
||||||
|
</li>
|
||||||
|
</modExtensions>
|
||||||
|
<comps>
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_FactionSetter">
|
||||||
|
<!-- <factionDef>Mechanoid</factionDef> 不写默认玩家派系-->
|
||||||
|
<usePlayerFactionIfNull>true</usePlayerFactionIfNull>
|
||||||
|
<overrideExistingFaction>false</overrideExistingFaction>
|
||||||
|
</li>
|
||||||
|
<li Class="CompProperties_Glower">
|
||||||
|
<glowRadius>3</glowRadius>
|
||||||
|
<glowColor>(120,240,252,0)</glowColor>
|
||||||
|
</li>
|
||||||
|
<li Class="CompProperties_Lifespan">
|
||||||
|
<lifespanTicks>3600</lifespanTicks>
|
||||||
|
</li>
|
||||||
|
<!-- 护盾无法在此绘制 -->
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_AreaShield">
|
||||||
|
<radius>12</radius>
|
||||||
|
<baseHitPoints>150000</baseHitPoints>
|
||||||
|
<rechargeDelay>2400</rechargeDelay>
|
||||||
|
<rechargeHitPointsIntervalTicks>30</rechargeHitPointsIntervalTicks>
|
||||||
|
|
||||||
|
<!-- 效果器配置 -->
|
||||||
|
<absorbEffecter>Interceptor_BlockedProjectile</absorbEffecter>
|
||||||
|
<interceptEffecter>Interceptor_BlockedProjectile</interceptEffecter>
|
||||||
|
<breakEffecter>Shield_Break</breakEffecter>
|
||||||
|
<reactivateEffecter>BulletShieldGenerator_Reactivate</reactivateEffecter>
|
||||||
|
|
||||||
|
<color>(0.9, 0.2, 0.2, 0.5)</color> <!-- 护盾气泡的颜色 (RGBA) -->
|
||||||
|
|
||||||
|
<!-- 拦截设置 -->
|
||||||
|
<interceptGroundProjectiles>true</interceptGroundProjectiles>
|
||||||
|
<interceptNonHostileProjectiles>false</interceptNonHostileProjectiles>
|
||||||
|
<interceptAirProjectiles>true</interceptAirProjectiles>
|
||||||
|
|
||||||
|
<!-- 反射设置 -->
|
||||||
|
<canReflect>true</canReflect>
|
||||||
|
<reflectChance>1</reflectChance>
|
||||||
|
<reflectAngleRange>30</reflectAngleRange>
|
||||||
|
<reflectCost>0</reflectCost>
|
||||||
|
<reflectEffecter>Interceptor_BlockedProjectile</reflectEffecter>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</ThingDef>
|
||||||
</Defs>
|
</Defs>
|
||||||
BIN
Content/Textures/Wula/Building/WULA_Support_Shield_Building.png
Normal file
BIN
Content/Textures/Wula/Building/WULA_Support_Shield_Building.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 375 KiB |
@@ -16,11 +16,13 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
if (map == null)
|
if (map == null)
|
||||||
yield break;
|
yield break;
|
||||||
|
|
||||||
if (Find.TickManager.TicksGame - lastUpdateTick > UPDATE_INTERVAL_TICKS)
|
if (Find.TickManager.TicksGame - lastUpdateTick > UPDATE_INTERVAL_TICKS)
|
||||||
{
|
{
|
||||||
UpdateShieldCache();
|
UpdateShieldCache();
|
||||||
lastUpdateTick = Find.TickManager.TicksGame;
|
lastUpdateTick = Find.TickManager.TicksGame;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeShieldsByMap.TryGetValue(map, out var shields))
|
if (activeShieldsByMap.TryGetValue(map, out var shields))
|
||||||
{
|
{
|
||||||
foreach (var shield in shields)
|
foreach (var shield in shields)
|
||||||
@@ -30,36 +32,57 @@ namespace WulaFallenEmpire
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void UpdateShieldCache()
|
private static void UpdateShieldCache()
|
||||||
{
|
{
|
||||||
activeShieldsByMap.Clear();
|
activeShieldsByMap.Clear();
|
||||||
|
|
||||||
foreach (var map in Find.Maps)
|
foreach (var map in Find.Maps)
|
||||||
{
|
{
|
||||||
if (map == null) continue;
|
if (map == null) continue;
|
||||||
|
|
||||||
var shieldSet = new HashSet<ThingComp_AreaShield>();
|
var shieldSet = new HashSet<ThingComp_AreaShield>();
|
||||||
|
|
||||||
|
// 搜索装备上的护盾
|
||||||
foreach (var pawn in map.mapPawns.AllPawnsSpawned)
|
foreach (var pawn in map.mapPawns.AllPawnsSpawned)
|
||||||
{
|
{
|
||||||
if (pawn?.apparel == null || pawn.Destroyed)
|
if (pawn?.apparel == null || pawn.Destroyed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
foreach (var apparel in pawn.apparel.WornApparel)
|
foreach (var apparel in pawn.apparel.WornApparel)
|
||||||
{
|
{
|
||||||
if (apparel == null || apparel.Destroyed)
|
if (apparel == null || apparel.Destroyed)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var shield = apparel.TryGetComp<ThingComp_AreaShield>();
|
var shield = apparel.TryGetComp<ThingComp_AreaShield>();
|
||||||
// 修改:只有立定且激活的护盾才加入缓存
|
// 修改:只有立定且激活的护盾才加入缓存
|
||||||
if (shield != null && shield.Active && !shield.IsWearerMoving)
|
if (shield != null && shield.Active && !shield.IsHolderMoving)
|
||||||
{
|
{
|
||||||
shieldSet.Add(shield);
|
shieldSet.Add(shield);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 搜索固定物品上的护盾(新增)
|
||||||
|
foreach (var thing in map.listerThings.AllThings)
|
||||||
|
{
|
||||||
|
if (thing == null || thing.Destroyed || thing is Apparel)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var shield = thing.TryGetComp<ThingComp_AreaShield>();
|
||||||
|
if (shield != null && shield.Active)
|
||||||
|
{
|
||||||
|
shieldSet.Add(shield);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
activeShieldsByMap[map] = shieldSet;
|
activeShieldsByMap[map] = shieldSet;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void NotifyShieldStateChanged(ThingComp_AreaShield shield)
|
public static void NotifyShieldStateChanged(ThingComp_AreaShield shield)
|
||||||
{
|
{
|
||||||
if (shield?.Wearer?.Map != null)
|
if (shield?.Holder?.Map != null)
|
||||||
{
|
{
|
||||||
lastUpdateTick = 0;
|
lastUpdateTick = 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ namespace WulaFallenEmpire
|
|||||||
public ThingComp_AreaShield shield;
|
public ThingComp_AreaShield shield;
|
||||||
private static readonly Texture2D FullShieldBarTex = SolidColorMaterials.NewSolidColorMaterial(new Color(0.2f, 0.8f, 0.85f), ShaderDatabase.MetaOverlay).mainTexture as Texture2D;
|
private static readonly Texture2D FullShieldBarTex = SolidColorMaterials.NewSolidColorMaterial(new Color(0.2f, 0.8f, 0.85f), ShaderDatabase.MetaOverlay).mainTexture as Texture2D;
|
||||||
private static readonly Texture2D EmptyShieldBarTex = SolidColorMaterials.NewSolidColorMaterial(new Color(0.2f, 0.2f, 0.24f), ShaderDatabase.MetaOverlay).mainTexture as Texture2D;
|
private static readonly Texture2D EmptyShieldBarTex = SolidColorMaterials.NewSolidColorMaterial(new Color(0.2f, 0.2f, 0.24f), ShaderDatabase.MetaOverlay).mainTexture as Texture2D;
|
||||||
// 新增:移动状态的颜色
|
|
||||||
|
// 新增:移动状态的颜色(仅对装备有效)
|
||||||
private static readonly Texture2D MovingShieldBarTex = SolidColorMaterials.NewSolidColorMaterial(new Color(0.5f, 0.5f, 0.5f), ShaderDatabase.MetaOverlay).mainTexture as Texture2D;
|
private static readonly Texture2D MovingShieldBarTex = SolidColorMaterials.NewSolidColorMaterial(new Color(0.5f, 0.5f, 0.5f), ShaderDatabase.MetaOverlay).mainTexture as Texture2D;
|
||||||
|
|
||||||
public override float GetWidth(float maxWidth) => 140f;
|
public override float GetWidth(float maxWidth) => 140f;
|
||||||
@@ -39,11 +40,11 @@ namespace WulaFallenEmpire
|
|||||||
barTex = EmptyShieldBarTex;
|
barTex = EmptyShieldBarTex;
|
||||||
statusText = "ShieldOnCooldown".Translate();
|
statusText = "ShieldOnCooldown".Translate();
|
||||||
}
|
}
|
||||||
else if (shield.IsWearerMoving)
|
else if (shield.IsEquipment && shield.IsHolderMoving)
|
||||||
{
|
{
|
||||||
// 移动时显示灰色状态条和"移动中"文本
|
// 移动时显示灰色状态条和"移动中"文本(仅对装备有效)
|
||||||
barTex = MovingShieldBarTex;
|
barTex = MovingShieldBarTex;
|
||||||
statusText = "ShieldOfflineByMoving".Translate(); // 你可以根据需要修改这个文本
|
statusText = "ShieldOfflineByMoving".Translate();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -21,42 +21,205 @@ namespace WulaFallenEmpire
|
|||||||
private bool drawInterceptCone;
|
private bool drawInterceptCone;
|
||||||
|
|
||||||
public CompProperties_AreaShield Props => (CompProperties_AreaShield)props;
|
public CompProperties_AreaShield Props => (CompProperties_AreaShield)props;
|
||||||
|
|
||||||
|
// 回退机制:支持装备和普通物品
|
||||||
public Pawn Wearer => (parent as Apparel)?.Wearer;
|
public Pawn Wearer => (parent as Apparel)?.Wearer;
|
||||||
|
public bool IsEquipment => parent is Apparel;
|
||||||
|
public bool IsStandalone => !IsEquipment;
|
||||||
|
|
||||||
|
// 获取护盾持有者(回退机制)
|
||||||
|
public Thing Holder => IsEquipment ? (Thing)Wearer : parent;
|
||||||
|
|
||||||
public bool IsOnCooldown => ticksToReset > 0;
|
public bool IsOnCooldown => ticksToReset > 0;
|
||||||
public int HitPointsMax => Props.baseHitPoints;
|
public int HitPointsMax => Props.baseHitPoints;
|
||||||
|
|
||||||
private bool initialized = false;
|
private bool initialized = false;
|
||||||
private StunHandler stunner;
|
private StunHandler stunner;
|
||||||
|
|
||||||
// 新增:移动状态检测
|
// 材质定义
|
||||||
public bool IsWearerMoving
|
private static readonly Material ForceFieldMat = MaterialPool.MatFrom("Other/ForceField", ShaderDatabase.MoteGlow);
|
||||||
|
private static readonly Material ForceFieldConeMat = MaterialPool.MatFrom("Other/ForceFieldCone", ShaderDatabase.MoteGlow);
|
||||||
|
private static readonly MaterialPropertyBlock MatPropertyBlock = new MaterialPropertyBlock();
|
||||||
|
private const float TextureActualRingSizeFactor = 1.1601562f;
|
||||||
|
private static readonly Color InactiveColor = new Color(0.2f, 0.2f, 0.2f);
|
||||||
|
|
||||||
|
// 护盾绘制方法 - 参考原版实现
|
||||||
|
public override void CompDrawWornExtras()
|
||||||
|
{
|
||||||
|
base.CompDrawWornExtras();
|
||||||
|
|
||||||
|
if (!IsEquipment) return; // 只有装备使用这个方法
|
||||||
|
|
||||||
|
DrawShield();
|
||||||
|
}
|
||||||
|
public override void PostDraw()
|
||||||
|
{
|
||||||
|
base.PostDraw();
|
||||||
|
|
||||||
|
if (IsEquipment) return; // 装备使用 CompDrawWornExtras
|
||||||
|
|
||||||
|
DrawShield();
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 统一的护盾绘制方法 - 参考原版实现
|
||||||
|
/// </summary>
|
||||||
|
private void DrawShield()
|
||||||
|
{
|
||||||
|
if (!Active || Holder?.Map == null || Holder.Destroyed)
|
||||||
|
return;
|
||||||
|
Vector3 drawPos = GetHolderDrawPos();
|
||||||
|
drawPos.y = AltitudeLayer.MoteOverhead.AltitudeFor();
|
||||||
|
float currentAlpha = GetCurrentAlpha();
|
||||||
|
if (currentAlpha > 0f)
|
||||||
|
{
|
||||||
|
// 参考原版:未激活但被选中时使用灰色
|
||||||
|
Color color = (!Active && Find.Selector.IsSelected(parent)) ? InactiveColor : Props.color;
|
||||||
|
color.a *= currentAlpha;
|
||||||
|
MatPropertyBlock.SetColor(ShaderPropertyIDs.Color, color);
|
||||||
|
|
||||||
|
Matrix4x4 matrix = default;
|
||||||
|
float scale = Props.radius * 2f * TextureActualRingSizeFactor;
|
||||||
|
matrix.SetTRS(drawPos, Quaternion.identity, new Vector3(scale, 1f, scale));
|
||||||
|
Graphics.DrawMesh(MeshPool.plane10, matrix, ForceFieldMat, 0, null, 0, MatPropertyBlock);
|
||||||
|
}
|
||||||
|
// 添加拦截锥形效果
|
||||||
|
float coneAlpha = GetCurrentConeAlpha();
|
||||||
|
if (coneAlpha > 0f)
|
||||||
|
{
|
||||||
|
Color color = Props.color;
|
||||||
|
color.a *= coneAlpha;
|
||||||
|
MatPropertyBlock.SetColor(ShaderPropertyIDs.Color, color);
|
||||||
|
|
||||||
|
Matrix4x4 matrix = default;
|
||||||
|
float scale = Props.radius * 2f;
|
||||||
|
matrix.SetTRS(drawPos, Quaternion.Euler(0f, lastInterceptAngle - 90f, 0f), new Vector3(scale, 1f, scale));
|
||||||
|
Graphics.DrawMesh(MeshPool.plane10, matrix, ForceFieldConeMat, 0, null, 0, MatPropertyBlock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取当前透明度 - 参考原版的多状态叠加
|
||||||
|
/// </summary>
|
||||||
|
private float GetCurrentAlpha()
|
||||||
|
{
|
||||||
|
// 多个透明度来源叠加,取最大值
|
||||||
|
return Mathf.Max(
|
||||||
|
Mathf.Max(
|
||||||
|
Mathf.Max(
|
||||||
|
GetCurrentAlpha_Idle(),
|
||||||
|
GetCurrentAlpha_Selected()
|
||||||
|
),
|
||||||
|
GetCurrentAlpha_RecentlyIntercepted()
|
||||||
|
),
|
||||||
|
0.1f // 最小透明度
|
||||||
|
);
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 空闲状态透明度
|
||||||
|
/// </summary>
|
||||||
|
private float GetCurrentAlpha_Idle()
|
||||||
|
{
|
||||||
|
if (!Active) return 0f;
|
||||||
|
|
||||||
|
// 固定物品:始终显示空闲状态
|
||||||
|
if (IsStandalone)
|
||||||
|
{
|
||||||
|
// 脉冲效果
|
||||||
|
return Mathf.Lerp(0.3f, 0.6f,
|
||||||
|
(Mathf.Sin((float)Gen.HashCombineInt(parent.thingIDNumber, 35990913) + Time.realtimeSinceStartup * 2f) + 1f) / 2f);
|
||||||
|
}
|
||||||
|
// 装备:只在特定条件下显示
|
||||||
|
else if (IsEquipment)
|
||||||
|
{
|
||||||
|
// 装备护盾只在以下情况显示空闲状态:
|
||||||
|
if (Holder is Pawn pawn)
|
||||||
|
{
|
||||||
|
if (pawn.Drafted || pawn.InAggroMentalState ||
|
||||||
|
(pawn.Faction != null && pawn.Faction.HostileTo(Faction.OfPlayer) && !pawn.IsPrisoner))
|
||||||
|
{
|
||||||
|
return Mathf.Lerp(0.3f, 0.6f,
|
||||||
|
(Mathf.Sin((float)Gen.HashCombineInt(parent.thingIDNumber, 35990913) + Time.realtimeSinceStartup * 2f) + 1f) / 2f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 被选中状态透明度 - 参考原版实现
|
||||||
|
/// </summary>
|
||||||
|
private float GetCurrentAlpha_Selected()
|
||||||
|
{
|
||||||
|
// 如果被选中,显示更高的透明度
|
||||||
|
if (Find.Selector.IsSelected(parent) && Active)
|
||||||
|
{
|
||||||
|
return Mathf.Lerp(0.4f, 0.8f,
|
||||||
|
(Mathf.Sin((float)Gen.HashCombineInt(parent.thingIDNumber, 96804938) + Time.realtimeSinceStartup * 2.5f) + 1f) / 2f);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0f;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 最近拦截状态透明度
|
||||||
|
/// </summary>
|
||||||
|
private float GetCurrentAlpha_RecentlyIntercepted()
|
||||||
|
{
|
||||||
|
int ticksSinceIntercept = Find.TickManager.TicksGame - lastInterceptTicks;
|
||||||
|
return Mathf.Clamp01(1f - (float)ticksSinceIntercept / 40f) * 0.3f;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 拦截锥形透明度
|
||||||
|
/// </summary>
|
||||||
|
private float GetCurrentConeAlpha()
|
||||||
|
{
|
||||||
|
if (!drawInterceptCone) return 0f;
|
||||||
|
|
||||||
|
int ticksSinceIntercept = Find.TickManager.TicksGame - lastInterceptTicks;
|
||||||
|
return Mathf.Clamp01(1f - (float)ticksSinceIntercept / 40f) * 0.82f;
|
||||||
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 获取持有者绘制位置(回退机制)
|
||||||
|
/// </summary>
|
||||||
|
private Vector3 GetHolderDrawPos()
|
||||||
|
{
|
||||||
|
if (Holder is Pawn pawn)
|
||||||
|
return pawn.Drawer?.DrawPos ?? pawn.Position.ToVector3Shifted();
|
||||||
|
else
|
||||||
|
return Holder.DrawPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 移动状态检测(仅对装备有效)
|
||||||
|
public bool IsHolderMoving
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
|
if (IsStandalone) return false; // 固定物品不会移动
|
||||||
if (Wearer == null || !Wearer.Spawned) return false;
|
if (Wearer == null || !Wearer.Spawned) return false;
|
||||||
return Wearer.pather.Moving;
|
return Wearer.pather.Moving;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改Active属性:只有在立定时才激活
|
// 修改Active属性:装备只有在立定时才激活,固定物品始终激活
|
||||||
public bool Active
|
public bool Active
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Wearer == null || !Wearer.Spawned || Wearer.Dead || Wearer.Downed || IsOnCooldown)
|
if (Holder == null || !Holder.Spawned || Holder.Destroyed)
|
||||||
return false;
|
return false;
|
||||||
// 新增:只有在立定时才激活
|
|
||||||
if (IsWearerMoving)
|
if (Holder is Pawn pawn && (pawn.Dead || pawn.Downed))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (IsOnCooldown)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 装备:只有在立定时才激活
|
||||||
|
if (IsEquipment && IsHolderMoving)
|
||||||
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 材质定义
|
|
||||||
private static readonly Material ForceFieldMat = MaterialPool.MatFrom("Other/ForceField", ShaderDatabase.MoteGlow);
|
|
||||||
private static readonly Material ForceFieldConeMat = MaterialPool.MatFrom("Other/ForceFieldCone", ShaderDatabase.MoteGlow);
|
|
||||||
private static readonly MaterialPropertyBlock MatPropertyBlock = new MaterialPropertyBlock();
|
|
||||||
|
|
||||||
public override void PostPostMake()
|
public override void PostPostMake()
|
||||||
{
|
{
|
||||||
base.PostPostMake();
|
base.PostPostMake();
|
||||||
@@ -84,7 +247,7 @@ namespace WulaFallenEmpire
|
|||||||
wasActiveLastCheck = isActive;
|
wasActiveLastCheck = isActive;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Wearer == null) return;
|
if (Holder == null) return;
|
||||||
|
|
||||||
if (IsOnCooldown)
|
if (IsOnCooldown)
|
||||||
{
|
{
|
||||||
@@ -125,14 +288,15 @@ namespace WulaFallenEmpire
|
|||||||
public bool TryIntercept(Projectile projectile, Vector3 lastExactPos, Vector3 newExactPos)
|
public bool TryIntercept(Projectile projectile, Vector3 lastExactPos, Vector3 newExactPos)
|
||||||
{
|
{
|
||||||
// 增强安全检查
|
// 增强安全检查
|
||||||
if (!Active || projectile == null || projectile.Destroyed || Wearer == null || Wearer.Map == null)
|
if (!Active || projectile == null || projectile.Destroyed || Holder == null || Holder.Map == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (currentHitPoints <= 0)
|
if (currentHitPoints <= 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (!GenGeo.IntersectLineCircleOutline(Wearer.Position.ToVector2(), Props.radius, lastExactPos.ToVector2(), newExactPos.ToVector2()))
|
if (!GenGeo.IntersectLineCircleOutline(Holder.Position.ToVector2(), Props.radius, lastExactPos.ToVector2(), newExactPos.ToVector2()))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -140,27 +304,27 @@ namespace WulaFallenEmpire
|
|||||||
return false;
|
return false;
|
||||||
if (!projectile.def.projectile.flyOverhead && !Props.interceptGroundProjectiles)
|
if (!projectile.def.projectile.flyOverhead && !Props.interceptGroundProjectiles)
|
||||||
return false;
|
return false;
|
||||||
if (projectile.Launcher != null && !projectile.Launcher.HostileTo(Wearer.Faction) && !Props.interceptNonHostileProjectiles)
|
if (projectile.Launcher != null && !projectile.Launcher.HostileTo(Holder.Faction) && !Props.interceptNonHostileProjectiles)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
lastInterceptTicks = Find.TickManager.TicksGame;
|
lastInterceptTicks = Find.TickManager.TicksGame;
|
||||||
|
|
||||||
// 记录拦截角度用于视觉效果
|
// 记录拦截角度用于视觉效果
|
||||||
lastInterceptAngle = projectile.ExactPosition.AngleToFlat(Wearer.TrueCenter());
|
lastInterceptAngle = projectile.ExactPosition.AngleToFlat(GetHolderCenter());
|
||||||
drawInterceptCone = true;
|
drawInterceptCone = true;
|
||||||
|
|
||||||
// 尝试反射
|
// 尝试反射
|
||||||
if (Props.canReflect && TryReflectProjectile(projectile, lastExactPos, newExactPos))
|
if (Props.canReflect && TryReflectProjectile(projectile, lastExactPos, newExactPos))
|
||||||
{
|
{
|
||||||
// 反射成功,播放反射特效
|
// 反射成功,播放反射特效
|
||||||
Props.reflectEffecter?.Spawn(projectile.ExactPosition.ToIntVec3(), Wearer.Map).Cleanup();
|
Props.reflectEffecter?.Spawn(projectile.ExactPosition.ToIntVec3(), Holder.Map).Cleanup();
|
||||||
ApplyCosts(Props.reflectCost);
|
ApplyCosts(Props.reflectCost);
|
||||||
return false; // 不销毁原抛射体,让它继续飞行(我们会在反射中销毁它)
|
return false; // 不销毁原抛射体,让它继续飞行(我们会在反射中销毁它)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// 普通拦截,播放拦截特效
|
// 普通拦截,播放拦截特效
|
||||||
Props.interceptEffecter?.Spawn(projectile.ExactPosition.ToIntVec3(), Wearer.Map).Cleanup();
|
Props.interceptEffecter?.Spawn(projectile.ExactPosition.ToIntVec3(), Holder.Map).Cleanup();
|
||||||
ApplyCosts();
|
ApplyCosts();
|
||||||
return true; // 销毁抛射体
|
return true; // 销毁抛射体
|
||||||
}
|
}
|
||||||
@@ -172,6 +336,17 @@ namespace WulaFallenEmpire
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取持有者中心位置(回退机制)
|
||||||
|
/// </summary>
|
||||||
|
private Vector3 GetHolderCenter()
|
||||||
|
{
|
||||||
|
if (Holder is Pawn pawn)
|
||||||
|
return pawn.TrueCenter();
|
||||||
|
else
|
||||||
|
return Holder.DrawPos;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 尝试反射抛射体 - 现在会创建新的抛射体
|
/// 尝试反射抛射体 - 现在会创建新的抛射体
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -183,13 +358,14 @@ namespace WulaFallenEmpire
|
|||||||
// 检查反射概率
|
// 检查反射概率
|
||||||
if (Rand.Value > Props.reflectChance)
|
if (Rand.Value > Props.reflectChance)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// 计算入射方向
|
// 计算入射方向
|
||||||
Vector3 incomingDirection = (newExactPos - lastExactPos).normalized;
|
Vector3 incomingDirection = (newExactPos - lastExactPos).normalized;
|
||||||
|
|
||||||
// 计算法线方向(从护盾中心到碰撞点)
|
// 计算法线方向(从护盾中心到碰撞点)
|
||||||
Vector3 normal = (newExactPos - Wearer.DrawPos).normalized;
|
Vector3 normal = (newExactPos - GetHolderCenter()).normalized;
|
||||||
|
|
||||||
// 计算反射方向(镜面反射)
|
// 计算反射方向(镜面反射)
|
||||||
Vector3 reflectDirection = Vector3.Reflect(incomingDirection, normal);
|
Vector3 reflectDirection = Vector3.Reflect(incomingDirection, normal);
|
||||||
@@ -216,28 +392,34 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (originalProjectile == null || originalProjectile.Destroyed || Wearer == null || Wearer.Map == null)
|
if (originalProjectile == null || originalProjectile.Destroyed || Holder == null || Holder.Map == null)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// 计算新的发射位置(护盾位置附近)
|
// 计算新的发射位置(护盾位置附近)
|
||||||
Vector3 spawnPosition = GetReflectSpawnPosition(collisionPoint);
|
Vector3 spawnPosition = GetReflectSpawnPosition(collisionPoint);
|
||||||
|
|
||||||
// 确保位置在地图内
|
// 确保位置在地图内
|
||||||
IntVec3 spawnCell = spawnPosition.ToIntVec3();
|
IntVec3 spawnCell = spawnPosition.ToIntVec3();
|
||||||
if (!spawnCell.InBounds(Wearer.Map))
|
if (!spawnCell.InBounds(Holder.Map))
|
||||||
{
|
{
|
||||||
spawnCell = Wearer.Position;
|
spawnCell = Holder.Position;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算新的目标位置
|
// 计算新的目标位置
|
||||||
Vector3 targetPosition = spawnCell.ToVector3Shifted() + reflectDirection * 30f;
|
Vector3 targetPosition = spawnCell.ToVector3Shifted() + reflectDirection * 30f;
|
||||||
IntVec3 targetCell = targetPosition.ToIntVec3();
|
IntVec3 targetCell = targetPosition.ToIntVec3();
|
||||||
|
|
||||||
// 创建新的抛射体
|
// 创建新的抛射体
|
||||||
Projectile newProjectile = (Projectile)GenSpawn.Spawn(originalProjectile.def, spawnCell, Wearer.Map);
|
Projectile newProjectile = (Projectile)GenSpawn.Spawn(originalProjectile.def, spawnCell, Holder.Map);
|
||||||
if (newProjectile == null)
|
if (newProjectile == null)
|
||||||
{
|
{
|
||||||
Log.Warning("Failed to spawn reflected projectile");
|
Log.Warning("Failed to spawn reflected projectile");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// 设置发射者为装备穿戴者
|
|
||||||
Thing launcher = Wearer;
|
// 设置发射者为护盾持有者
|
||||||
|
Thing launcher = Holder;
|
||||||
|
|
||||||
// 发射新抛射体
|
// 发射新抛射体
|
||||||
newProjectile.Launch(
|
newProjectile.Launch(
|
||||||
launcher,
|
launcher,
|
||||||
@@ -247,11 +429,14 @@ namespace WulaFallenEmpire
|
|||||||
ProjectileHitFlags.All,
|
ProjectileHitFlags.All,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
// 复制重要的属性
|
// 复制重要的属性
|
||||||
CopyProjectileProperties(originalProjectile, newProjectile);
|
CopyProjectileProperties(originalProjectile, newProjectile);
|
||||||
|
|
||||||
// 使用延迟销毁而不是立即销毁
|
// 使用延迟销毁而不是立即销毁
|
||||||
ReflectedProjectileManager.MarkForDelayedDestroy(originalProjectile);
|
ReflectedProjectileManager.MarkForDelayedDestroy(originalProjectile);
|
||||||
Log.Message($"反射抛射体: 由 {Wearer?.LabelShort} 从 {spawnCell} 向 {targetCell} 发射");
|
|
||||||
|
Log.Message($"反射抛射体: 由 {Holder?.LabelShort} 从 {spawnCell} 向 {targetCell} 发射");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch (System.Exception ex)
|
catch (System.Exception ex)
|
||||||
@@ -266,15 +451,15 @@ namespace WulaFallenEmpire
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private Vector3 GetReflectSpawnPosition(Vector3 collisionPoint)
|
private Vector3 GetReflectSpawnPosition(Vector3 collisionPoint)
|
||||||
{
|
{
|
||||||
if (Wearer == null)
|
if (Holder == null)
|
||||||
return collisionPoint;
|
return collisionPoint;
|
||||||
|
|
||||||
// 计算从护盾中心到碰撞点的方向
|
// 计算从护盾中心到碰撞点的方向
|
||||||
Vector3 directionFromCenter = (collisionPoint - Wearer.DrawPos).normalized;
|
Vector3 directionFromCenter = (collisionPoint - GetHolderCenter()).normalized;
|
||||||
|
|
||||||
// 在护盾边界上生成(稍微向内一点避免立即再次碰撞)
|
// 在护盾边界上生成(稍微向内一点避免立即再次碰撞)
|
||||||
float spawnDistance = Props.radius * 0.9f;
|
float spawnDistance = Props.radius * 0.9f;
|
||||||
Vector3 spawnPosition = Wearer.DrawPos + directionFromCenter * spawnDistance;
|
Vector3 spawnPosition = GetHolderCenter() + directionFromCenter * spawnDistance;
|
||||||
|
|
||||||
return spawnPosition;
|
return spawnPosition;
|
||||||
}
|
}
|
||||||
@@ -310,26 +495,26 @@ namespace WulaFallenEmpire
|
|||||||
public override void PostPreApplyDamage(ref DamageInfo dinfo, out bool absorbed)
|
public override void PostPreApplyDamage(ref DamageInfo dinfo, out bool absorbed)
|
||||||
{
|
{
|
||||||
absorbed = false;
|
absorbed = false;
|
||||||
if (!Active || Wearer == null) return;
|
if (!Active || Holder == null) return;
|
||||||
|
|
||||||
if (dinfo.Def.isRanged) return;
|
if (dinfo.Def.isRanged) return;
|
||||||
|
|
||||||
if (dinfo.Instigator != null)
|
if (dinfo.Instigator != null)
|
||||||
{
|
{
|
||||||
float distance = Wearer.Position.DistanceTo(dinfo.Instigator.Position);
|
float distance = Holder.Position.DistanceTo(dinfo.Instigator.Position);
|
||||||
if (distance > Props.radius) return;
|
if (distance > Props.radius) return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentHitPoints <= 0) return;
|
if (currentHitPoints <= 0) return;
|
||||||
|
|
||||||
Props.absorbEffecter?.Spawn(Wearer.Position, Wearer.Map).Cleanup();
|
Props.absorbEffecter?.Spawn(Holder.Position, Holder.Map).Cleanup();
|
||||||
ApplyCosts();
|
ApplyCosts();
|
||||||
absorbed = true;
|
absorbed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Break()
|
private void Break()
|
||||||
{
|
{
|
||||||
Props.breakEffecter?.Spawn(Wearer.Position, Wearer.Map).Cleanup();
|
Props.breakEffecter?.Spawn(Holder.Position, Holder.Map).Cleanup();
|
||||||
ticksToReset = Props.rechargeDelay;
|
ticksToReset = Props.rechargeDelay;
|
||||||
currentHitPoints = 0;
|
currentHitPoints = 0;
|
||||||
AreaShieldManager.NotifyShieldStateChanged(this);
|
AreaShieldManager.NotifyShieldStateChanged(this);
|
||||||
@@ -337,85 +522,50 @@ namespace WulaFallenEmpire
|
|||||||
|
|
||||||
private void Reset()
|
private void Reset()
|
||||||
{
|
{
|
||||||
if (Wearer != null && Wearer.Spawned)
|
if (Holder != null && Holder.Spawned)
|
||||||
{
|
{
|
||||||
Props.reactivateEffecter?.Spawn(Wearer.Position, Wearer.Map).Cleanup();
|
Props.reactivateEffecter?.Spawn(Holder.Position, Holder.Map).Cleanup();
|
||||||
}
|
}
|
||||||
currentHitPoints = HitPointsMax;
|
currentHitPoints = HitPointsMax;
|
||||||
AreaShieldManager.NotifyShieldStateChanged(this);
|
AreaShieldManager.NotifyShieldStateChanged(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// 护盾绘制方法 - 只有在立定时才绘制
|
// 显示条件 - 修改为固定物品始终显示,装备有条件显示
|
||||||
public override void CompDrawWornExtras()
|
|
||||||
{
|
|
||||||
base.CompDrawWornExtras();
|
|
||||||
|
|
||||||
// 修改:移动时不绘制护盾
|
|
||||||
if (!Active || Wearer?.Map == null || !ShouldDisplay || IsWearerMoving)
|
|
||||||
return;
|
|
||||||
|
|
||||||
Vector3 drawPos = Wearer.Drawer?.DrawPos ?? Wearer.Position.ToVector3Shifted();
|
|
||||||
drawPos.y = AltitudeLayer.MoteOverhead.AltitudeFor();
|
|
||||||
|
|
||||||
float alpha = GetCurrentAlpha();
|
|
||||||
if (alpha > 0f)
|
|
||||||
{
|
|
||||||
Color color = Props.color;
|
|
||||||
color.a *= alpha;
|
|
||||||
MatPropertyBlock.SetColor(ShaderPropertyIDs.Color, color);
|
|
||||||
Matrix4x4 matrix = default;
|
|
||||||
|
|
||||||
float scale = Props.radius * 2f * 1.1601562f;
|
|
||||||
matrix.SetTRS(drawPos, Quaternion.identity, new Vector3(scale, 1f, scale));
|
|
||||||
Graphics.DrawMesh(MeshPool.plane10, matrix, ForceFieldMat, 0, null, 0, MatPropertyBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 添加拦截锥形效果
|
|
||||||
float coneAlpha = GetCurrentConeAlpha();
|
|
||||||
if (coneAlpha > 0f)
|
|
||||||
{
|
|
||||||
Color color = Props.color;
|
|
||||||
color.a *= coneAlpha;
|
|
||||||
MatPropertyBlock.SetColor(ShaderPropertyIDs.Color, color);
|
|
||||||
Matrix4x4 matrix = default;
|
|
||||||
float scale = Props.radius * 2f;
|
|
||||||
matrix.SetTRS(drawPos, Quaternion.Euler(0f, lastInterceptAngle - 90f, 0f), new Vector3(scale, 1f, scale));
|
|
||||||
Graphics.DrawMesh(MeshPool.plane10, matrix, ForceFieldConeMat, 0, null, 0, MatPropertyBlock);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示条件
|
|
||||||
protected bool ShouldDisplay
|
protected bool ShouldDisplay
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Wearer == null || !Wearer.Spawned || Wearer.Dead || Wearer.Downed || !Active)
|
if (Holder == null || !Holder.Spawned || Holder.Destroyed || !Active)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (Wearer.Drafted || Wearer.InAggroMentalState ||
|
// 对于装备:只在特定条件下显示
|
||||||
(Wearer.Faction != null && Wearer.Faction.HostileTo(Faction.OfPlayer) && !Wearer.IsPrisoner))
|
if (IsEquipment && Holder is Pawn pawn)
|
||||||
|
{
|
||||||
|
if (pawn.Dead || pawn.Downed)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 装备护盾只在以下情况显示:
|
||||||
|
// 1. 穿戴者被选中
|
||||||
|
// 2. 穿戴者处于战斗状态(征召状态或敌对)
|
||||||
|
// 3. 穿戴者处于攻击性精神状态
|
||||||
|
if (Find.Selector.IsSelected(pawn))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (pawn.Drafted || pawn.InAggroMentalState)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
if (pawn.Faction != null && pawn.Faction.HostileTo(Faction.OfPlayer) && !pawn.IsPrisoner)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 对于固定物品:始终显示(只要护盾激活)
|
||||||
|
else if (IsStandalone)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
|
}
|
||||||
if (Find.Selector.IsSelected(Wearer))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private float GetCurrentAlpha()
|
|
||||||
{
|
|
||||||
float idleAlpha = Mathf.Lerp(0.3f, 0.6f, (Mathf.Sin((float)Gen.HashCombineInt(parent.thingIDNumber, 35990913) + Time.realtimeSinceStartup * 2f) + 1f) / 2f);
|
|
||||||
float interceptAlpha = Mathf.Clamp01(1f - (float)(Find.TickManager.TicksGame - lastInterceptTicks) / 40f);
|
|
||||||
return Mathf.Max(idleAlpha, interceptAlpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
private float GetCurrentConeAlpha()
|
|
||||||
{
|
|
||||||
if (!drawInterceptCone) return 0f;
|
|
||||||
return Mathf.Clamp01(1f - (float)(Find.TickManager.TicksGame - lastInterceptTicks) / 40f) * 0.82f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void EnsureInitialized()
|
private void EnsureInitialized()
|
||||||
{
|
{
|
||||||
if (initialized) return;
|
if (initialized) return;
|
||||||
@@ -433,7 +583,18 @@ namespace WulaFallenEmpire
|
|||||||
{
|
{
|
||||||
EnsureInitialized();
|
EnsureInitialized();
|
||||||
|
|
||||||
if (Wearer != null && Find.Selector.SingleSelectedThing == Wearer)
|
if (IsEquipment && Wearer != null && Find.Selector.SingleSelectedThing == Wearer)
|
||||||
|
{
|
||||||
|
yield return new Gizmo_AreaShieldStatus { shield = this };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IEnumerable<Gizmo> CompGetGizmosExtra()
|
||||||
|
{
|
||||||
|
EnsureInitialized();
|
||||||
|
|
||||||
|
// 固定物品也显示护盾状态
|
||||||
|
if (IsStandalone && Find.Selector.SingleSelectedThing == parent)
|
||||||
{
|
{
|
||||||
yield return new Gizmo_AreaShieldStatus { shield = this };
|
yield return new Gizmo_AreaShieldStatus { shield = this };
|
||||||
}
|
}
|
||||||
|
|||||||
BIN
美术与文本源文件/Wula/Building/WULA_Support_Shield_Building.sai2
Normal file
BIN
美术与文本源文件/Wula/Building/WULA_Support_Shield_Building.sai2
Normal file
Binary file not shown.
Reference in New Issue
Block a user