Files
2025-09-03 18:13:29 +08:00

131 lines
5.5 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using Data;
namespace Entity
{
public class Attributes
{
public int health = 10;
public float moveSpeed = 1;
public int attack = 1;
public int defense = 0;
public float attackSpeed = 2;
public float attackRange = 3;
public int attackTargetCount = 1;
public Attributes(AttributesDef def)
{
health = def.health;
moveSpeed = def.moveSpeed;
attack = def.attack;
defense = def.defense;
attackSpeed = def.attackSpeed;
attackRange = def.attackRange;
attackTargetCount = def.attackTargetCount;
}
public Attributes(Attributes other)
{
health = other.health;
moveSpeed = other.moveSpeed;
attack = other.attack;
defense = other.defense;
attackSpeed = other.attackSpeed;
attackRange = other.attackRange;
attackTargetCount = other.attackTargetCount;
}
public Attributes()
{
}
/// <summary>
/// 根据给定的属性偏移,生成一个新的 Attributes 实例。
/// 原有的 Attributes 实例保持不变。
/// </summary>
/// <param name="offset">要应用的属性偏移定义。</param>
/// <returns>一个新的 Attributes 实例,包含了应用偏移后的值。</returns>
public Attributes GetModifiedAttributes(AttributesOffsetDef offset)
{
// 1. 创建当前 Attributes 实例的一个副本
var newAttributes = new Attributes(this);
if (offset == null)
{
return newAttributes; // 如果没有偏移,直接返回副本
}
// 2. 在副本上应用绝对值偏移
newAttributes.health += (int)offset.healthOffset;
newAttributes.moveSpeed += offset.moveSpeedOffset;
newAttributes.attack += (int)offset.attackOffset;
newAttributes.defense += (int)offset.defenseOffset;
// 修正: attackSpeed 和 attackRange 是 float不应强制转换为 int
newAttributes.attackSpeed += offset.attackSpeedOffset;
newAttributes.attackRange += offset.attackRangeOffset;
newAttributes.attackTargetCount += (int)offset.attackTargetCountOffset;
// 3. 在副本上应用百分比偏移 (基于应用绝对值偏移后的结果)
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));
// 修正: attackSpeed 和 attackRange 是 float不应强制转换为 int
newAttributes.attackSpeed *= (1 + offset.attackSpeedPercentOffset);
newAttributes.attackRange *= (1 + offset.attackRangePercentOffset);
newAttributes.attackTargetCount =
(int)(newAttributes.attackTargetCount * (1 + offset.attackTargetCountPercentOffset));
// 4. 确保属性不低于最小值
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);
// 修正: Math.Max 期望相同类型0f 对于 float 类型更准确
newAttributes.attackSpeed = Math.Max(0f, newAttributes.attackSpeed);
newAttributes.attackRange = Math.Max(0f, newAttributes.attackRange);
newAttributes.attackTargetCount = Math.Max(1, newAttributes.attackTargetCount);
// 5. 返回修改后的新 Attributes 实例
return newAttributes;
}
/// <summary>
/// 合并两个 Attributes 实例,生成一个新的 Attributes 实例,
/// 其中每个属性值都取自传入两个实例中对应属性的最小值。
/// 这对于应用属性上限或限制非常有用。
/// </summary>
/// <param name="a">第一个 Attributes 实例。</param>
/// <param name="b">第二个 Attributes 实例。</param>
/// <returns>一个新的 Attributes 实例,其属性是输入实例中对应属性的最小值。</returns>
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)
};
return result;
}
}
}