131 lines
5.5 KiB
C#
131 lines
5.5 KiB
C#
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 = MathF.Max(0.0001f,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;
|
||
}
|
||
|
||
}
|
||
}
|