using System.Collections.Generic; using RimWorld; using Verse; using System.Linq; using System.Text; namespace WulaFallenEmpire { public class DamageWorker_ExtraDamage : DamageWorker { /// /// 重写伤害应用方法 /// public override DamageResult Apply(DamageInfo dinfo, Thing victim) { // 先应用原始伤害 DamageResult originalResult = base.Apply(dinfo, victim); // 获取额外伤害扩展 DamageDef_ExtraDamageExtension extension = dinfo.Def.GetModExtension(); if (extension != null && victim != null && !victim.Destroyed) { // 应用额外伤害 var extraDamageResults = ApplyExtraDamages(extension, dinfo, victim, originalResult); // 如果需要,添加战斗日志 if (extension.showExtraLog && extraDamageResults.Count > 0) { AddCombatLog(extension, dinfo, victim, extraDamageResults); } } return originalResult; } /// /// 应用额外伤害 /// private List ApplyExtraDamages( DamageDef_ExtraDamageExtension extension, DamageInfo originalDinfo, Thing victim, DamageResult originalResult) { List results = new List(); var applicableDamages = extension.GetApplicableExtraDamages(victim, originalDinfo); foreach (var extraDamage in applicableDamages) { if (ShouldApplyExtraDamage(extraDamage, originalDinfo, victim)) { DamageResult result = ApplySingleExtraDamage(extraDamage, originalDinfo, victim); if (result != null) { results.Add(result); } } } return results; } /// /// 检查是否应该应用额外伤害 /// private bool ShouldApplyExtraDamage(ExtraDamageDef extraDamage, DamageInfo originalDinfo, Thing victim) { // 检查最小触发伤害 if (originalDinfo.Amount < extraDamage.minTriggerDamage) return false; return true; } /// /// 应用单个额外伤害 /// private DamageResult ApplySingleExtraDamage(ExtraDamageDef extraDamage, DamageInfo originalDinfo, Thing victim) { try { // 计算伤害值 float damageAmount = extraDamage.CalculateActualAmount(originalDinfo, victim); if (damageAmount <= 0) return null; // 计算护甲穿透 float armorPenetration = extraDamage.CalculateActualArmorPenetration(); // 创建伤害信息 DamageInfo extraDinfo = new DamageInfo( def: extraDamage.damageDef, amount: damageAmount, armorPenetration: armorPenetration, angle: originalDinfo.Angle, instigator: originalDinfo.Instigator, hitPart: GetTargetBodyPart(victim, extraDamage.targetBodyPart), weapon: originalDinfo.Weapon, category: DamageInfo.SourceCategory.ThingOrUnknown, intendedTarget: originalDinfo.IntendedTarget ); // 如果是真实伤害,设置特殊标志(如果需要特殊处理) if (extraDamage.isTrueDamage) { // 这里可能需要特殊的处理方式 // 例如,可以设置伤害信息中的特殊标志 } // 应用伤害 DamageResult result = victim.TakeDamage(extraDinfo); // 播放效果 PlayExtraDamageEffects(extraDamage, victim, damageAmount); return result; } catch (System.Exception ex) { Log.Warning($"应用额外伤害时出错: {ex.Message}"); return null; } } /// /// 获取目标部位 /// private BodyPartRecord GetTargetBodyPart(Thing victim, BodyPartDef bodyPartDef) { if (bodyPartDef == null || !(victim is Pawn pawn)) return null; return pawn.RaceProps.body.GetPartsWithDef(bodyPartDef).FirstOrDefault(); } /// /// 播放额外伤害效果 /// private void PlayExtraDamageEffects(ExtraDamageDef extraDamage, Thing victim, float damageAmount) { if (victim.Map == null) return; // 播放音效 if (extraDamage.soundDef != null) { extraDamage.soundDef.PlayOneShot(new TargetInfo(victim.Position, victim.Map)); } // 播放粒子效果 if (extraDamage.fleckDef != null) { FleckMaker.Static(victim.DrawPos, victim.Map, extraDamage.fleckDef); } // 播放效果器 if (extraDamage.effecterDef != null) { Effecter effecter = extraDamage.effecterDef.Spawn(); effecter.Trigger(new TargetInfo(victim.Position, victim.Map), new TargetInfo(victim.Position, victim.Map)); effecter.Cleanup(); } } /// /// 添加战斗日志 /// private void AddCombatLog( DamageDef_ExtraDamageExtension extension, DamageInfo originalDinfo, Thing victim, List extraResults) { if (victim is Pawn victimPawn) { StringBuilder sb = new StringBuilder(); sb.AppendLine($"{extension.extraLabel} - 额外伤害:"); foreach (var result in extraResults) { if (result != null && result.totalDamageDealt > 0) { sb.AppendLine($" {result.totalDamageDealt:F1} 伤害"); } } // 这里可以添加更详细的战斗日志逻辑 // 例如,创建一个自定义的战斗日志条目 } } /// /// 重写爆炸伤害处理 /// protected override void ExplosionDamageThing(Explosion explosion, Thing t, List damagedThings, List ignoredThings, IntVec3 cell) { base.ExplosionDamageThing(explosion, t, damagedThings, ignoredThings, cell); // 检查并应用额外伤害 DamageDef_ExtraDamageExtension extension = explosion.damType.GetModExtension(); if (extension != null && !t.Destroyed) { // 为爆炸中的每个目标应用额外伤害 // 注意:这里需要创建适当的DamageInfo } } /// /// 获取伤害描述(用于UI显示) /// public string GetExtraDamageDescription(DamageDef damageDef) { DamageDef_ExtraDamageExtension extension = damageDef.GetModExtension(); if (extension == null || extension.extraDamages.Count == 0) return ""; StringBuilder sb = new StringBuilder(); sb.AppendLine("额外伤害效果:"); foreach (var extraDamage in extension.extraDamages) { string damageType = extraDamage.damageDef.label; string amountStr = extraDamage.isPercentage ? $"{extraDamage.percentageMultiplier * 100}% 原始伤害" : $"{extraDamage.amount} 点"; sb.AppendLine($" {damageType}: {amountStr}"); if (extraDamage.minTriggerDamage > 0) { sb.AppendLine($" 触发条件: 原始伤害 > {extraDamage.minTriggerDamage}"); } } return sb.ToString(); } } }