using System; using Data; namespace Entity { public class Attributes { public int attack = 1; public float attackRange = 3; public float attackSpeed = 2; public int attackTargetCount = 1; public int defense; public int health = 10; public float moveSpeed = 1; public float totalDamageDealtAbsoluteOffset; // 累计造成的伤害绝对值偏移 (原 effectiveDamageOffset 对应) public float totalDamageDealtPercentOffset; // 累计造成的伤害百分比偏移 (原 effectiveDamagePercentOffset 对应) public float totalDamageTakenAbsoluteOffset; // 累计受到的伤害绝对值偏移 public float totalDamageTakenPercentOffset; // 累计受到的伤害百分比偏移 (例如 0.1 表示 +10%) /// /// 根据属性定义初始化 类的新实例。 /// /// 属性定义。 public Attributes(AttributesDef def) { if (def == null) return; health = def.health; moveSpeed = def.moveSpeed; attack = def.attack; defense = def.defense; attackSpeed = MathF.Max(0.0001f, def.attackSpeed); attackRange = def.attackRange; attackTargetCount = def.attackTargetCount; } /// /// 从另一个 实例复制属性,初始化 类的新实例。 /// /// 要复制的 实例。 public Attributes(Attributes other) { if (other == null) return; health = other.health; moveSpeed = other.moveSpeed; attack = other.attack; defense = other.defense; attackSpeed = other.attackSpeed; attackRange = other.attackRange; attackTargetCount = other.attackTargetCount; } /// /// 初始化 类的新实例。 /// public Attributes() { } /// /// 根据给定的属性偏移,生成一个新的 实例。 /// 原有的 实例保持不变。 /// /// 要应用的属性偏移定义。 /// 一个新的 实例,包含了应用偏移后的值。 public Attributes GetModifiedAttributes(AttributesOffsetDef offset) { // 创建当前 Attributes 实例的一个副本 var newAttributes = new Attributes(this); if (offset == null) // 如果没有偏移,直接返回副本 return newAttributes; // 在副本上应用绝对值偏移 newAttributes.health += (int)offset.healthOffset; newAttributes.moveSpeed += offset.moveSpeedOffset; newAttributes.attack += (int)offset.attackOffset; newAttributes.defense += (int)offset.defenseOffset; newAttributes.attackSpeed += offset.attackSpeedOffset; newAttributes.attackRange += offset.attackRangeOffset; newAttributes.attackTargetCount += (int)offset.attackTargetCountOffset; // 在副本上应用百分比偏移 (基于应用绝对值偏移后的结果) newAttributes.health = (int)(newAttributes.health * (1 + offset.healthPercentOffset)); newAttributes.moveSpeed *= 1 + offset.moveSpeedPercentOffset; newAttributes.attack = (int)(newAttributes.attack * (1 + offset.attackPercentOffset)); newAttributes.defense = (int)(newAttributes.defense * (1 + offset.defensePercentOffset)); newAttributes.attackSpeed *= 1 + offset.attackSpeedPercentOffset; newAttributes.attackRange *= 1 + offset.attackRangePercentOffset; newAttributes.attackTargetCount = (int)(newAttributes.attackTargetCount * (1 + offset.attackTargetCountPercentOffset)); newAttributes.totalDamageDealtAbsoluteOffset = offset.effectiveDamageOffset; newAttributes.totalDamageDealtPercentOffset = offset.effectiveDamagePercentOffset; newAttributes.totalDamageTakenAbsoluteOffset = offset.damageTakenOffset; newAttributes.totalDamageTakenPercentOffset = offset.damageTakenPercentOffset; // 确保属性不低于最小值 newAttributes.health = Math.Max(0, newAttributes.health); newAttributes.moveSpeed = Math.Max(0f, newAttributes.moveSpeed); newAttributes.attack = Math.Max(0, newAttributes.attack); newAttributes.defense = Math.Max(0, newAttributes.defense); newAttributes.attackSpeed = Math.Max(0f, newAttributes.attackSpeed); newAttributes.attackRange = Math.Max(0f, newAttributes.attackRange); newAttributes.attackTargetCount = Math.Max(1, newAttributes.attackTargetCount); // 返回修改后的新 Attributes 实例 return newAttributes; } /// /// 合并两个 实例,生成一个新的 实例, /// 其中每个属性值都取自传入两个实例中对应属性的最小值。 /// 这对于应用属性上限或限制非常有用。 /// /// 第一个 实例。 /// 第二个 实例。 /// 一个新的 实例,其属性是输入实例中对应属性的最小值。 public static Attributes Min(Attributes a, Attributes b) { // 处理 null 情况 if (a == null && b == null) return new Attributes(); // 两者都为null,返回默认空属性 if (a == null) return new Attributes(b); // a为null,返回b的副本 if (b == null) return new Attributes(a); // b为null,返回a的副本 // 创建一个新的 Attributes 实例来存储结果 var result = new Attributes { health = Math.Min(a.health, b.health), moveSpeed = Math.Min(a.moveSpeed, b.moveSpeed), attack = Math.Min(a.attack, b.attack), defense = Math.Min(a.defense, b.defense), attackSpeed = Math.Min(a.attackSpeed, b.attackSpeed), attackRange = Math.Min(a.attackRange, b.attackRange), attackTargetCount = Math.Min(a.attackTargetCount, b.attackTargetCount), totalDamageDealtAbsoluteOffset = a.totalDamageDealtAbsoluteOffset, totalDamageDealtPercentOffset = a.totalDamageDealtPercentOffset, totalDamageTakenAbsoluteOffset = a.totalDamageTakenAbsoluteOffset, totalDamageTakenPercentOffset = a.totalDamageTakenPercentOffset }; return result; } /// /// 返回当前 实例的字符串表示形式。 /// /// 包含所有属性名称和值的字符串。 public override string ToString() { return "Attributes {\n" + $" Health: {health}\n" + $" Move Speed: {moveSpeed:F2}\n" + $" Attack: {attack}\n" + $" Defense: {defense}\n" + $" Attack Speed: {attackSpeed:F2}\n" + $" Attack Range: {attackRange:F2}\n" + $" Attack Target Count: {attackTargetCount}\n" + $" Total Damage Dealt (Absolute Offset): {totalDamageDealtAbsoluteOffset:F2}\n" + $" Total Damage Dealt (Percent Offset): {totalDamageDealtPercentOffset:P2}\n" + $" Total Damage Taken (Absolute Offset): {totalDamageTakenAbsoluteOffset:F2}\n" + $" Total Damage Taken (Percent Offset): {totalDamageTakenPercentOffset:P2}\n" + "}"; } } }