115 lines
4.3 KiB
C#
115 lines
4.3 KiB
C#
|
|
using System;
|
|||
|
|
using Cielonos.MainGame.Characters;
|
|||
|
|
using SLSUtilities.General;
|
|||
|
|
using UnityEngine;
|
|||
|
|
|
|||
|
|
namespace Cielonos.MainGame.Inventory.Collections
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// “背水”协议 / Last Stand Protocol
|
|||
|
|
/// 当玩家生命值低于一定百分比(25%)时,增加造成的伤害(25%)但同时也增加受到的伤害(25%)。当生命值回升到阈值以上时,效果消失。
|
|||
|
|
/// </summary>
|
|||
|
|
public partial class LastStandProtocol : PassiveEquipmentBase
|
|||
|
|
{
|
|||
|
|
// 触发阈值(生命值百分比),从 passiveAttributeData 读取
|
|||
|
|
private float HealthThreshold => passiveAttributeData.itemAttributes.GetValueOrDefault("HealthThreshold", 0.25f);
|
|||
|
|
|
|||
|
|
// Last Stand 激活时,FinalDamageDealtMultiplier 的叠加量
|
|||
|
|
private float DamageDealtBonus => passiveAttributeData.itemAttributes.GetValueOrDefault("DamageDealtBonus", 0.25f);
|
|||
|
|
|
|||
|
|
// Last Stand 激活时,FinalDamageReceivedMultiplier 的叠加量(承受更多伤害)
|
|||
|
|
private float DamageReceivedAmplifier => passiveAttributeData.itemAttributes.GetValueOrDefault("DamageReceivedAmplifier", 0.25f);
|
|||
|
|
|
|||
|
|
private bool _isActive;
|
|||
|
|
|
|||
|
|
private bool IsInLastStand => GetHealthPercentage() < HealthThreshold;
|
|||
|
|
|
|||
|
|
public override void OnObtained()
|
|||
|
|
{
|
|||
|
|
base.OnObtained();
|
|||
|
|
|
|||
|
|
Action<float> onHealthChanged = OnHealthChanged;
|
|||
|
|
player.eventSm.onHealthChanged.Add("LastStandProtocol", onHealthChanged.ToPrioritized());
|
|||
|
|
|
|||
|
|
// 装备获取时立即检查当前状态
|
|||
|
|
EvaluateState();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public override void OnDiscarded()
|
|||
|
|
{
|
|||
|
|
// 移除前先清理激活状态
|
|||
|
|
if (_isActive)
|
|||
|
|
{
|
|||
|
|
DeactivateLastStand();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
player.eventSm.onHealthChanged.Remove("LastStandProtocol");
|
|||
|
|
base.OnDiscarded();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public partial class LastStandProtocol
|
|||
|
|
{
|
|||
|
|
private void OnHealthChanged(float delta)
|
|||
|
|
{
|
|||
|
|
EvaluateState();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 根据当前生命值比例评估 Last Stand 状态,处理激活/关闭切换。
|
|||
|
|
/// </summary>
|
|||
|
|
private void EvaluateState()
|
|||
|
|
{
|
|||
|
|
bool shouldBeActive = IsInLastStand;
|
|||
|
|
|
|||
|
|
if (shouldBeActive && !_isActive)
|
|||
|
|
{
|
|||
|
|
ActivateLastStand();
|
|||
|
|
}
|
|||
|
|
else if (!shouldBeActive && _isActive)
|
|||
|
|
{
|
|||
|
|
DeactivateLastStand();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 激活 Last Stand:修改角色属性并刷新,显示提示文本。
|
|||
|
|
/// </summary>
|
|||
|
|
private void ActivateLastStand()
|
|||
|
|
{
|
|||
|
|
_isActive = true;
|
|||
|
|
|
|||
|
|
passiveAttributeSm.chaAttrPercentageChangeOfAccumulation[CharacterAttribute.FinalDamageDealtMultiplier] = DamageDealtBonus;
|
|||
|
|
passiveAttributeSm.chaAttrPercentageChangeOfAccumulation[CharacterAttribute.FinalDamageReceivedMultiplier] = DamageReceivedAmplifier;
|
|||
|
|
|
|||
|
|
player.attributeSm.RefreshAttribute(CharacterAttribute.FinalDamageDealtMultiplier);
|
|||
|
|
player.attributeSm.RefreshAttribute(CharacterAttribute.FinalDamageReceivedMultiplier);
|
|||
|
|
|
|||
|
|
MainGameManager.BaseCollection.InfoText().Spawn(player.centerPosition, "Last Stand Protocol: On");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/// <summary>
|
|||
|
|
/// 关闭 Last Stand:还原角色属性修改并刷新,显示提示文本。
|
|||
|
|
/// </summary>
|
|||
|
|
private void DeactivateLastStand()
|
|||
|
|
{
|
|||
|
|
_isActive = false;
|
|||
|
|
|
|||
|
|
passiveAttributeSm.chaAttrPercentageChangeOfAccumulation.Remove(CharacterAttribute.FinalDamageDealtMultiplier);
|
|||
|
|
passiveAttributeSm.chaAttrPercentageChangeOfAccumulation.Remove(CharacterAttribute.FinalDamageReceivedMultiplier);
|
|||
|
|
|
|||
|
|
player.attributeSm.RefreshAttribute(CharacterAttribute.FinalDamageDealtMultiplier);
|
|||
|
|
player.attributeSm.RefreshAttribute(CharacterAttribute.FinalDamageReceivedMultiplier);
|
|||
|
|
|
|||
|
|
MainGameManager.BaseCollection.InfoText().Spawn(player.centerPosition, "Last Stand Protocol: Off");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private float GetHealthPercentage()
|
|||
|
|
{
|
|||
|
|
float maxHealth = player.attributeSm[CharacterAttribute.MaximumHealth];
|
|||
|
|
if (maxHealth <= 0f) return 1f;
|
|||
|
|
return player.attributeSm[CharacterAttribute.Health] / maxHealth;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|