天锁机制
This commit is contained in:
Binary file not shown.
@@ -661,4 +661,66 @@
|
|||||||
<li>Placeworker_AttachedToWall</li>
|
<li>Placeworker_AttachedToWall</li>
|
||||||
</placeWorkers>
|
</placeWorkers>
|
||||||
</ThingDef>
|
</ThingDef>
|
||||||
|
|
||||||
|
<!-- 装饰品 -->
|
||||||
|
<ThingDef ParentName="BuildingBase">
|
||||||
|
<defName>WULA_Sky_Lock</defName>
|
||||||
|
<label>天锁</label>
|
||||||
|
<description>天锁</description>
|
||||||
|
<thingClass>Building</thingClass>
|
||||||
|
<preventDroppingThingsOn>true</preventDroppingThingsOn>
|
||||||
|
<altitudeLayer>Building</altitudeLayer>
|
||||||
|
<pathCost>50</pathCost>
|
||||||
|
<blockWind>true</blockWind>
|
||||||
|
<passability>PassThroughOnly</passability>
|
||||||
|
<fillPercent>1</fillPercent>
|
||||||
|
<size>(3,3)</size>
|
||||||
|
<drawHighlight>true</drawHighlight>
|
||||||
|
<highlightColor>(0.56, 0.62, 0.9)</highlightColor>
|
||||||
|
<graphicData>
|
||||||
|
<texPath>Wula/Building/WULA_Fake_Fighter_Drone_Building</texPath>
|
||||||
|
<graphicClass>Graphic_Single</graphicClass>
|
||||||
|
<shaderType>TransparentPostLight</shaderType>
|
||||||
|
<drawSize>(3,3)</drawSize>
|
||||||
|
<color>(195,195,195,255)</color>
|
||||||
|
</graphicData>
|
||||||
|
<statBases>
|
||||||
|
<MaxHitPoints>100</MaxHitPoints>
|
||||||
|
<Flammability>0.5</Flammability>
|
||||||
|
<WorkToBuild>36000</WorkToBuild>
|
||||||
|
<Mass>125</Mass>
|
||||||
|
<Comfort>0.65</Comfort>
|
||||||
|
</statBases>
|
||||||
|
<costList>
|
||||||
|
<WULA_Alloy>50</WULA_Alloy>
|
||||||
|
<ComponentIndustrial>1</ComponentIndustrial>
|
||||||
|
</costList>
|
||||||
|
<!-- <designationCategory>WULA_Buildings</designationCategory> -->
|
||||||
|
<tickerType>Normal</tickerType>
|
||||||
|
<canOverlapZones>true</canOverlapZones>
|
||||||
|
<rotatable>true</rotatable>
|
||||||
|
<hasInteractionCell>false</hasInteractionCell>
|
||||||
|
<defaultPlacingRot>East</defaultPlacingRot>
|
||||||
|
<selectable>true</selectable>
|
||||||
|
<terrainAffordanceNeeded>Light</terrainAffordanceNeeded>
|
||||||
|
<soundImpactDefault>BulletImpact_Metal</soundImpactDefault>
|
||||||
|
<preventSkyfallersLandingOn>true</preventSkyfallersLandingOn>
|
||||||
|
<drawerType>RealtimeOnly</drawerType>
|
||||||
|
<repairEffect>ConstructMetal</repairEffect>
|
||||||
|
<forceDebugSpawnable>true</forceDebugSpawnable>
|
||||||
|
<building>
|
||||||
|
<destroySound>BuildingDestroyed_Metal_Big</destroySound>
|
||||||
|
<paintable>true</paintable>
|
||||||
|
<isInert>true</isInert>
|
||||||
|
</building>
|
||||||
|
<comps>
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_DamageReceiver">
|
||||||
|
<maxDamageCapacity>5000</maxDamageCapacity>
|
||||||
|
<damageDecayRate>10</damageDecayRate>
|
||||||
|
<damageDecayInterval>30</damageDecayInterval>
|
||||||
|
<showDamageBar>true</showDamageBar>
|
||||||
|
<canBeDestroyedByDamage>true</canBeDestroyedByDamage>
|
||||||
|
</li>
|
||||||
|
</comps>
|
||||||
|
</ThingDef>
|
||||||
</Defs>
|
</Defs>
|
||||||
@@ -1646,7 +1646,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</tools>
|
</tools>
|
||||||
<comps>
|
<comps>
|
||||||
<!-- 护盾无法在此绘制 -->
|
|
||||||
<li Class="WulaFallenEmpire.CompProperties_AreaShield">
|
<li Class="WulaFallenEmpire.CompProperties_AreaShield">
|
||||||
<radius>9</radius>
|
<radius>9</radius>
|
||||||
<baseHitPoints>500</baseHitPoints>
|
<baseHitPoints>500</baseHitPoints>
|
||||||
@@ -1673,6 +1672,15 @@
|
|||||||
<reflectCost>0</reflectCost>
|
<reflectCost>0</reflectCost>
|
||||||
<reflectEffecter>Interceptor_BlockedProjectile</reflectEffecter>
|
<reflectEffecter>Interceptor_BlockedProjectile</reflectEffecter>
|
||||||
</li>
|
</li>
|
||||||
|
<li Class="WulaFallenEmpire.CompProperties_DamageTransfer">
|
||||||
|
<damageTransferRatio>0.75</damageTransferRatio>
|
||||||
|
<maxTransferRange>25</maxTransferRange>
|
||||||
|
<requireLineOfSight>false</requireLineOfSight>
|
||||||
|
<healthThreshold>
|
||||||
|
<min>0.1</min>
|
||||||
|
<max>0.9</max>
|
||||||
|
</healthThreshold>
|
||||||
|
</li>
|
||||||
<!-- 飞行组件 -->
|
<!-- 飞行组件 -->
|
||||||
<li Class="WulaFallenEmpire.CompProperties_PawnFlight">
|
<li Class="WulaFallenEmpire.CompProperties_PawnFlight">
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,107 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using UnityEngine;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
public class CompDamageReceiver : ThingComp
|
||||||
|
{
|
||||||
|
private CompProperties_DamageReceiver Props => (CompProperties_DamageReceiver)props;
|
||||||
|
|
||||||
|
private float currentDamage;
|
||||||
|
private int lastDamageTick;
|
||||||
|
|
||||||
|
public float CurrentDamage => currentDamage;
|
||||||
|
public float MaxDamageCapacity => Props.maxDamageCapacity;
|
||||||
|
public float DamageRatio => currentDamage / Props.maxDamageCapacity;
|
||||||
|
|
||||||
|
public override void PostExposeData()
|
||||||
|
{
|
||||||
|
base.PostExposeData();
|
||||||
|
Scribe_Values.Look(ref currentDamage, "currentDamage", 0f);
|
||||||
|
Scribe_Values.Look(ref lastDamageTick, "lastDamageTick", 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CompTick()
|
||||||
|
{
|
||||||
|
base.CompTick();
|
||||||
|
|
||||||
|
// 定期衰减伤害
|
||||||
|
if (Find.TickManager.TicksGame % Props.damageDecayInterval == 0 && currentDamage > 0)
|
||||||
|
{
|
||||||
|
currentDamage = Mathf.Max(0f, currentDamage - Props.damageDecayRate);
|
||||||
|
|
||||||
|
// 如果伤害为0,重置最后伤害时间
|
||||||
|
if (currentDamage <= 0f)
|
||||||
|
{
|
||||||
|
lastDamageTick = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接收伤害
|
||||||
|
/// </summary>
|
||||||
|
public bool ReceiveDamage(float damageAmount, Pawn sourcePawn = null)
|
||||||
|
{
|
||||||
|
float oldDamage = currentDamage;
|
||||||
|
currentDamage += damageAmount;
|
||||||
|
lastDamageTick = Find.TickManager.TicksGame;
|
||||||
|
|
||||||
|
// 检查是否超过容量
|
||||||
|
if (currentDamage >= Props.maxDamageCapacity)
|
||||||
|
{
|
||||||
|
if (Props.canBeDestroyedByDamage)
|
||||||
|
{
|
||||||
|
// 摧毁建筑
|
||||||
|
parent.Destroy(DestroyMode.Vanish);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 只是达到上限,不再接收更多伤害
|
||||||
|
currentDamage = Props.maxDamageCapacity;
|
||||||
|
}
|
||||||
|
return false; // 无法接收更多伤害
|
||||||
|
}
|
||||||
|
|
||||||
|
// 触发效果
|
||||||
|
OnDamageReceived(damageAmount, sourcePawn);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDamageReceived(float damageAmount, Pawn sourcePawn)
|
||||||
|
{
|
||||||
|
// 记录日志
|
||||||
|
Log.Message($"[DamageReceiver] {parent.Label} 接收 {damageAmount} 点伤害,当前伤害: {currentDamage}/{Props.maxDamageCapacity}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void PostDraw()
|
||||||
|
{
|
||||||
|
base.PostDraw();
|
||||||
|
|
||||||
|
// 绘制伤害条
|
||||||
|
if (Props.showDamageBar && currentDamage > 0f)
|
||||||
|
{
|
||||||
|
Vector3 drawPos = parent.DrawPos;
|
||||||
|
drawPos.y += 0.5f; // 在建筑上方显示
|
||||||
|
|
||||||
|
GenDraw.DrawFillableBar(new GenDraw.FillableBarRequest
|
||||||
|
{
|
||||||
|
center = drawPos,
|
||||||
|
size = new Vector2(1f, 0.15f),
|
||||||
|
fillPercent = DamageRatio,
|
||||||
|
filledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.red),
|
||||||
|
unfilledMat = SolidColorMaterials.SimpleSolidColorMaterial(Color.gray),
|
||||||
|
margin = 0.1f,
|
||||||
|
rotation = Rot4.North
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取接收器状态
|
||||||
|
public string GetStatusString()
|
||||||
|
{
|
||||||
|
return $"伤害吸收: {currentDamage:F0}/{Props.maxDamageCapacity:F0} ({DamageRatio * 100:F1}%)";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,123 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Verse.Sound;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
public class CompDamageTransfer : ThingComp
|
||||||
|
{
|
||||||
|
private CompProperties_DamageTransfer Props => (CompProperties_DamageTransfer)props;
|
||||||
|
private Pawn Pawn => (Pawn)parent;
|
||||||
|
|
||||||
|
public override void PostPostApplyDamage(DamageInfo dinfo, float totalDamageDealt)
|
||||||
|
{
|
||||||
|
base.PostPostApplyDamage(dinfo, totalDamageDealt);
|
||||||
|
|
||||||
|
// 检查是否应该转移伤害
|
||||||
|
if (ShouldTransferDamage(dinfo, totalDamageDealt))
|
||||||
|
{
|
||||||
|
TryTransferDamage(dinfo, totalDamageDealt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool ShouldTransferDamage(DamageInfo dinfo, float totalDamageDealt)
|
||||||
|
{
|
||||||
|
if (parent == null || !parent.Spawned)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// 检查生命值阈值
|
||||||
|
if (Pawn.health != null)
|
||||||
|
{
|
||||||
|
float healthRatio = Pawn.health.summaryHealth.SummaryHealthPercent;
|
||||||
|
if (healthRatio < Props.healthThreshold.min || healthRatio > Props.healthThreshold.max)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查伤害类型
|
||||||
|
if (!Props.transferAllDamageTypes)
|
||||||
|
{
|
||||||
|
// 这里可以添加特定伤害类型检查
|
||||||
|
// 例如:只转移物理伤害,不转移火焰伤害等
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TryTransferDamage(DamageInfo dinfo, float totalDamageDealt)
|
||||||
|
{
|
||||||
|
// 计算转移的伤害量
|
||||||
|
float transferDamage = totalDamageDealt * Props.damageTransferRatio;
|
||||||
|
|
||||||
|
// 寻找可用的伤害接收器
|
||||||
|
CompDamageReceiver receiver = FindAvailableDamageReceiver();
|
||||||
|
if (receiver != null)
|
||||||
|
{
|
||||||
|
// 执行伤害转移
|
||||||
|
if (receiver.ReceiveDamage(transferDamage, Pawn))
|
||||||
|
{
|
||||||
|
OnDamageTransferred(dinfo, transferDamage, receiver);
|
||||||
|
|
||||||
|
// 记录日志
|
||||||
|
Log.Message($"[DamageTransfer] {Pawn.LabelShort} 将 {transferDamage} 点伤害转移至 {receiver.parent.Label}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompDamageReceiver FindAvailableDamageReceiver()
|
||||||
|
{
|
||||||
|
if (parent?.Map == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
var map = parent.Map;
|
||||||
|
var faction = parent.Faction;
|
||||||
|
|
||||||
|
// 搜索范围内的同派系建筑
|
||||||
|
foreach (var thing in GenRadial.RadialDistinctThingsAround(parent.Position, map, Props.maxTransferRange, true))
|
||||||
|
{
|
||||||
|
if (thing is Building building &&
|
||||||
|
building.Faction == faction &&
|
||||||
|
building != parent)
|
||||||
|
{
|
||||||
|
var receiver = building.TryGetComp<CompDamageReceiver>();
|
||||||
|
if (receiver != null && receiver.CurrentDamage < receiver.MaxDamageCapacity)
|
||||||
|
{
|
||||||
|
// 检查视线(如果需要)
|
||||||
|
if (Props.requireLineOfSight)
|
||||||
|
{
|
||||||
|
if (!GenSight.LineOfSight(parent.Position, building.Position, map))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return receiver;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnDamageTransferred(DamageInfo dinfo, float transferDamage, CompDamageReceiver receiver)
|
||||||
|
{
|
||||||
|
// 创建转移效果
|
||||||
|
if (Props.transferEffecter != null)
|
||||||
|
{
|
||||||
|
Effecter effect = Props.transferEffecter.Spawn();
|
||||||
|
effect.Trigger(new TargetInfo(parent.Position, parent.Map), new TargetInfo(receiver.parent.Position, parent.Map));
|
||||||
|
effect.Cleanup();
|
||||||
|
}
|
||||||
|
|
||||||
|
// 播放音效
|
||||||
|
if (Props.transferSound != null)
|
||||||
|
{
|
||||||
|
Props.transferSound.PlayOneShot(new TargetInfo(parent.Position, parent.Map));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取组件状态
|
||||||
|
public string GetStatusString()
|
||||||
|
{
|
||||||
|
return $"伤害转移: {Props.damageTransferRatio * 100}% (范围: {Props.maxTransferRange})";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
public class CompProperties_DamageReceiver : CompProperties
|
||||||
|
{
|
||||||
|
public float maxDamageCapacity = 1000f; // 最大伤害容量
|
||||||
|
public float damageDecayRate = 5f; // 每 tick 衰减的伤害量
|
||||||
|
public float damageDecayInterval = 60f; // 伤害衰减间隔(ticks)
|
||||||
|
public bool showDamageBar = true; // 是否显示伤害条
|
||||||
|
public bool canBeDestroyedByDamage = true; // 是否可以被伤害摧毁
|
||||||
|
|
||||||
|
public CompProperties_DamageReceiver()
|
||||||
|
{
|
||||||
|
compClass = typeof(CompDamageReceiver);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
public class CompProperties_DamageTransfer : CompProperties
|
||||||
|
{
|
||||||
|
public float damageTransferRatio = 0.8f; // 伤害转移比例 (80%)
|
||||||
|
public float maxTransferRange = 30f; // 最大转移范围
|
||||||
|
public bool requireLineOfSight = false; // 是否需要视线
|
||||||
|
public bool transferAllDamageTypes = true; // 是否转移所有伤害类型
|
||||||
|
public FloatRange healthThreshold = new FloatRange(0f, 1f); // 生命值阈值(低于此值才触发)
|
||||||
|
|
||||||
|
// 效果设置
|
||||||
|
public EffecterDef transferEffecter;
|
||||||
|
public SoundDef transferSound;
|
||||||
|
|
||||||
|
public CompProperties_DamageTransfer()
|
||||||
|
{
|
||||||
|
compClass = typeof(CompDamageTransfer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
using HarmonyLib;
|
||||||
|
using RimWorld;
|
||||||
|
using Verse;
|
||||||
|
|
||||||
|
namespace WulaFallenEmpire
|
||||||
|
{
|
||||||
|
[HarmonyPatch(typeof(Pawn), "PostApplyDamage")]
|
||||||
|
public static class Patch_Pawn_PostApplyDamage
|
||||||
|
{
|
||||||
|
[HarmonyPostfix]
|
||||||
|
public static void Postfix(Pawn __instance, DamageInfo dinfo, float totalDamageDealt)
|
||||||
|
{
|
||||||
|
// 检查Pawn是否有伤害转移组件
|
||||||
|
var transferComp = __instance.TryGetComp<CompDamageTransfer>();
|
||||||
|
if (transferComp != null)
|
||||||
|
{
|
||||||
|
// 组件会在PostPostApplyDamage中自动处理
|
||||||
|
// 这里主要用于调试和日志记录
|
||||||
|
Log.Message($"[DamageTransfer] {__instance.LabelShort} 受到 {totalDamageDealt} 点伤害,转移组件已激活");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPatch(typeof(Pawn), "PreApplyDamage")]
|
||||||
|
public static class Patch_Pawn_PreApplyDamage
|
||||||
|
{
|
||||||
|
[HarmonyPrefix]
|
||||||
|
public static bool Prefix(Pawn __instance, ref DamageInfo dinfo, out bool __state)
|
||||||
|
{
|
||||||
|
__state = false;
|
||||||
|
|
||||||
|
// 检查Pawn是否有伤害转移组件
|
||||||
|
var transferComp = __instance.TryGetComp<CompDamageTransfer>();
|
||||||
|
if (transferComp != null && __instance.Spawned && !__instance.Dead)
|
||||||
|
{
|
||||||
|
// 这里可以添加预处理逻辑
|
||||||
|
// 例如:在某些条件下完全阻止伤害
|
||||||
|
__state = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
[HarmonyPostfix]
|
||||||
|
public static void Postfix(Pawn __instance, DamageInfo dinfo, bool __state)
|
||||||
|
{
|
||||||
|
if (__state)
|
||||||
|
{
|
||||||
|
// 后处理逻辑
|
||||||
|
// 例如:记录伤害转移统计
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -267,6 +267,11 @@
|
|||||||
<Compile Include="ThingComp\WULA_AreaTeleporter\ThingComp_AreaTeleporter.cs" />
|
<Compile Include="ThingComp\WULA_AreaTeleporter\ThingComp_AreaTeleporter.cs" />
|
||||||
<Compile Include="ThingComp\WULA_CustomUniqueWeapon\CompCustomUniqueWeapon.cs" />
|
<Compile Include="ThingComp\WULA_CustomUniqueWeapon\CompCustomUniqueWeapon.cs" />
|
||||||
<Compile Include="ThingComp\WULA_CustomUniqueWeapon\CompProperties_CustomUniqueWeapon.cs" />
|
<Compile Include="ThingComp\WULA_CustomUniqueWeapon\CompProperties_CustomUniqueWeapon.cs" />
|
||||||
|
<Compile Include="ThingComp\WULA_DamageReceiver\CompDamageReceiver.cs" />
|
||||||
|
<Compile Include="ThingComp\WULA_DamageReceiver\CompDamageTransfer.cs" />
|
||||||
|
<Compile Include="ThingComp\WULA_DamageReceiver\CompProperties_DamageReceiver.cs" />
|
||||||
|
<Compile Include="ThingComp\WULA_DamageReceiver\CompProperties_DamageTransfer.cs" />
|
||||||
|
<Compile Include="ThingComp\WULA_DamageReceiver\Patch_Pawn_DamageTransfer.cs" />
|
||||||
<Compile Include="ThingComp\WULA_GiveHediffsInRange\CompGiveHediffsInRange.cs" />
|
<Compile Include="ThingComp\WULA_GiveHediffsInRange\CompGiveHediffsInRange.cs" />
|
||||||
<Compile Include="ThingComp\WULA_GiveHediffsInRange\CompProperties_GiveHediffsInRange.cs" />
|
<Compile Include="ThingComp\WULA_GiveHediffsInRange\CompProperties_GiveHediffsInRange.cs" />
|
||||||
<Compile Include="ThingComp\WULA_MechRepairKit\CompUseEffect_FixAllHealthConditions.cs" />
|
<Compile Include="ThingComp\WULA_MechRepairKit\CompUseEffect_FixAllHealthConditions.cs" />
|
||||||
|
|||||||
Reference in New Issue
Block a user