using System.Collections.Generic; using Verse; using RimWorld; namespace WulaFallenEmpire { public class DamageDef_ExtraDamageExtension : DefModExtension { /// /// 额外伤害列表 /// public List extraDamages = new List(); /// /// 条件触发器列表 /// public List conditions = new List(); /// /// 是否显示额外的战斗日志信息 /// public bool showExtraLog = true; /// /// 额外伤害标签 /// public string extraLabel = ""; /// /// 获取所有适用于特定目标的额外伤害 /// public List GetApplicableExtraDamages(Thing target, DamageInfo originalDinfo) { List result = new List(); foreach (var extraDamage in extraDamages) { if (IsConditionMet(extraDamage.conditions, target, originalDinfo)) { result.Add(extraDamage); } } return result; } /// /// 检查条件是否满足 /// private bool IsConditionMet(List conditions, Thing target, DamageInfo originalDinfo) { if (conditions == null || conditions.Count == 0) return true; foreach (var condition in conditions) { if (!condition.IsMet(target, originalDinfo)) return false; } return true; } } /// /// 额外伤害定义 /// public class ExtraDamageDef { /// /// 伤害类型 /// public DamageDef damageDef; /// /// 伤害数值(如果是百分比,基于原始伤害) /// public float amount = 10f; /// /// 是否为百分比伤害(相对于原始伤害) /// public bool isPercentage = false; /// /// 百分比倍数(当isPercentage为true时有效) /// public float percentageMultiplier = 0.5f; /// /// 护甲穿透值 /// public float armorPenetration = -1f; // -1表示使用damageDef的默认值 /// /// 命中部位(可选) /// public BodyPartDef targetBodyPart; /// /// 伤害应用条件 /// public List conditions = new List(); /// /// 伤害应用后的效果器 /// public EffecterDef effecterDef; /// /// 伤害应用后的粒子 /// public FleckDef fleckDef; /// /// 伤害应用后的音效 /// public SoundDef soundDef; /// /// 最小触发伤害阈值 /// public float minTriggerDamage = 0f; /// /// 是否可以被护甲抵抗 /// public bool canBeBlockedByArmor = true; /// /// 是否为真实伤害(忽略所有抗性) /// public bool isTrueDamage = false; /// /// 计算实际伤害值 /// public float CalculateActualAmount(DamageInfo originalDinfo, Thing target) { if (isPercentage) { return originalDinfo.Amount * percentageMultiplier; } return amount; } /// /// 计算实际护甲穿透值 /// public float CalculateActualArmorPenetration() { if (armorPenetration >= 0) return armorPenetration; return damageDef.defaultArmorPenetration; } } /// /// 伤害条件 /// public class DamageCondition { /// /// 目标类型 /// public ConditionTarget targetType = ConditionTarget.Any; /// /// 特定种族列表(当targetType为SpecificRaces时有效) /// public List specificRaces = new List(); /// /// 目标血量百分比阈值 /// public FloatRange healthPercentRange = new FloatRange(0f, 1f); /// /// 目标是否必须存活 /// public bool targetMustBeAlive = true; /// /// 目标是否必须有特定标签 /// public List requiredTags = new List(); /// /// 原始伤害类型限制 /// public List requiredOriginalDamageTypes = new List(); /// /// 原始伤害必须大于 /// public float originalDamageMustBeGreaterThan = 0f; /// /// 检查条件是否满足 /// public bool IsMet(Thing target, DamageInfo originalDinfo) { // 检查目标类型 if (!CheckTargetType(target)) return false; // 检查血量百分比 if (!CheckHealthPercentage(target)) return false; // 检查存活状态 if (targetMustBeAlive && target is Pawn pawn && (pawn.Dead || pawn.Downed)) return false; // 检查标签 if (!CheckTags(target)) return false; // 检查原始伤害类型 if (!CheckOriginalDamageType(originalDinfo)) return false; // 检查原始伤害大小 if (originalDinfo.Amount <= originalDamageMustBeGreaterThan) return false; return true; } private bool CheckTargetType(Thing target) { switch (targetType) { case ConditionTarget.Any: return true; case ConditionTarget.Pawn: return target is Pawn; case ConditionTarget.Building: return target is Building; default: return true; } } private bool CheckHealthPercentage(Thing target) { if (target is Pawn pawn) { float healthPercent = pawn.health.summaryHealth.SummaryHealthPercent; return healthPercentRange.Includes(healthPercent); } return true; } private bool CheckTags(Thing target) { if (requiredTags == null || requiredTags.Count == 0) return true; return false; } private bool CheckOriginalDamageType(DamageInfo originalDinfo) { if (requiredOriginalDamageTypes == null || requiredOriginalDamageTypes.Count == 0) return true; return requiredOriginalDamageTypes.Contains(originalDinfo.Def); } } /// /// 条件目标类型 /// public enum ConditionTarget { Any, Pawn, Animal, Humanlike, Mechanoid, Building, SpecificRaces } }