diff --git a/1.6/1.6/Assemblies/WulaFallenEmpire.dll b/1.6/1.6/Assemblies/WulaFallenEmpire.dll index 79ea5b67..6e5ce682 100644 Binary files a/1.6/1.6/Assemblies/WulaFallenEmpire.dll and b/1.6/1.6/Assemblies/WulaFallenEmpire.dll differ diff --git a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml index 4c7da254..8daefb2b 100644 --- a/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml +++ b/1.6/1.6/Defs/ThingDefs_Buildings/WULA_Misc_Buildings.xml @@ -661,4 +661,66 @@
  • Placeworker_AttachedToWall
  • + + + + WULA_Sky_Lock + + 天锁 + Building + true + Building + 50 + true + PassThroughOnly + 1 + (3,3) + true + (0.56, 0.62, 0.9) + + Wula/Building/WULA_Fake_Fighter_Drone_Building + Graphic_Single + TransparentPostLight + (3,3) + (195,195,195,255) + + + 100 + 0.5 + 36000 + 125 + 0.65 + + + 50 + 1 + + + Normal + true + true + false + East + true + Light + BulletImpact_Metal + true + RealtimeOnly + ConstructMetal + true + + BuildingDestroyed_Metal_Big + true + true + + +
  • + 5000 + 10 + 30 + true + true +
  • +
    +
    \ No newline at end of file diff --git a/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml b/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml index ea724eed..16f13b29 100644 --- a/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml +++ b/1.6/1.6/Defs/ThingDefs_Races/Races_Wulaspecies.xml @@ -1646,7 +1646,6 @@ -
  • 9 500 @@ -1673,6 +1672,15 @@ 0 Interceptor_BlockedProjectile
  • +
  • + 0.75 + 25 + false + + 0.1 + 0.9 + +
  • diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompDamageReceiver.cs b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompDamageReceiver.cs new file mode 100644 index 00000000..505c7ef8 --- /dev/null +++ b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompDamageReceiver.cs @@ -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; + } + } + } + + /// + /// 接收伤害 + /// + 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}%)"; + } + } +} diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompDamageTransfer.cs b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompDamageTransfer.cs new file mode 100644 index 00000000..a22b5d26 --- /dev/null +++ b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompDamageTransfer.cs @@ -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(); + 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})"; + } + } +} diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompProperties_DamageReceiver.cs b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompProperties_DamageReceiver.cs new file mode 100644 index 00000000..7b073903 --- /dev/null +++ b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompProperties_DamageReceiver.cs @@ -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); + } + } +} diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompProperties_DamageTransfer.cs b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompProperties_DamageTransfer.cs new file mode 100644 index 00000000..50db0710 --- /dev/null +++ b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/CompProperties_DamageTransfer.cs @@ -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); + } + } +} diff --git a/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/Patch_Pawn_DamageTransfer.cs b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/Patch_Pawn_DamageTransfer.cs new file mode 100644 index 00000000..b90d7918 --- /dev/null +++ b/Source/WulaFallenEmpire/ThingComp/WULA_DamageReceiver/Patch_Pawn_DamageTransfer.cs @@ -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(); + 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(); + if (transferComp != null && __instance.Spawned && !__instance.Dead) + { + // 这里可以添加预处理逻辑 + // 例如:在某些条件下完全阻止伤害 + __state = true; + } + + return true; + } + + [HarmonyPostfix] + public static void Postfix(Pawn __instance, DamageInfo dinfo, bool __state) + { + if (__state) + { + // 后处理逻辑 + // 例如:记录伤害转移统计 + } + } + } +} diff --git a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj index 04b4f7c4..3b4af3bc 100644 --- a/Source/WulaFallenEmpire/WulaFallenEmpire.csproj +++ b/Source/WulaFallenEmpire/WulaFallenEmpire.csproj @@ -267,6 +267,11 @@ + + + + +