mirror of
http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite.git
synced 2025-11-19 23:37:13 +08:00
Co-authored-by: m0_75251201 <m0_75251201@noreply.gitcode.com> Reviewed-on: http://47.107.252.169:3000/Roguelite-Game-Developing-Team/Gen_Hack-and-Slash-Roguelite/pulls/60
169 lines
8.2 KiB
C#
169 lines
8.2 KiB
C#
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%)
|
||
|
||
/// <summary>
|
||
/// 根据属性定义初始化 <see cref="Attributes" /> 类的新实例。
|
||
/// </summary>
|
||
/// <param name="def">属性定义。</param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从另一个 <see cref="Attributes" /> 实例复制属性,初始化 <see cref="Attributes" /> 类的新实例。
|
||
/// </summary>
|
||
/// <param name="other">要复制的 <see cref="Attributes" /> 实例。</param>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 初始化 <see cref="Attributes" /> 类的新实例。
|
||
/// </summary>
|
||
public Attributes()
|
||
{
|
||
}
|
||
|
||
/// <summary>
|
||
/// 根据给定的属性偏移,生成一个新的 <see cref="Attributes" /> 实例。
|
||
/// 原有的 <see cref="Attributes" /> 实例保持不变。
|
||
/// </summary>
|
||
/// <param name="offset">要应用的属性偏移定义。</param>
|
||
/// <returns>一个新的 <see cref="Attributes" /> 实例,包含了应用偏移后的值。</returns>
|
||
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;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 合并两个 <see cref="Attributes" /> 实例,生成一个新的 <see cref="Attributes" /> 实例,
|
||
/// 其中每个属性值都取自传入两个实例中对应属性的最小值。
|
||
/// 这对于应用属性上限或限制非常有用。
|
||
/// </summary>
|
||
/// <param name="a">第一个 <see cref="Attributes" /> 实例。</param>
|
||
/// <param name="b">第二个 <see cref="Attributes" /> 实例。</param>
|
||
/// <returns>一个新的 <see cref="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),
|
||
totalDamageDealtAbsoluteOffset = a.totalDamageDealtAbsoluteOffset,
|
||
totalDamageDealtPercentOffset = a.totalDamageDealtPercentOffset,
|
||
totalDamageTakenAbsoluteOffset = a.totalDamageTakenAbsoluteOffset,
|
||
totalDamageTakenPercentOffset = a.totalDamageTakenPercentOffset
|
||
};
|
||
|
||
return result;
|
||
}
|
||
|
||
/// <summary>
|
||
/// 返回当前 <see cref="Attributes" /> 实例的字符串表示形式。
|
||
/// </summary>
|
||
/// <returns>包含所有属性名称和值的字符串。</returns>
|
||
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" +
|
||
"}";
|
||
}
|
||
}
|
||
} |