Files
Cielonos/Assets/Scripts/MainGame/Characters/Base/Submodules/AttributeSubmodule.cs

152 lines
5.6 KiB
C#
Raw Normal View History

2026-05-23 08:27:50 -04:00
using System;
2025-11-25 08:19:33 -05:00
using System.Collections.Generic;
using UnityEngine;
namespace Cielonos.MainGame.Characters
{
public partial class AttributeSubmodule : SubmoduleBase<CharacterBase>
{
public AttributeGroup attributeGroup;
2026-05-23 08:27:50 -04:00
/// <summary>
/// 属性值变更回调表。Key 为属性名Value 为回调委托 (oldValue, newValue)。
/// 当属性值通过 indexer 或 RefreshAttribute 发生实际变化时自动触发。
/// </summary>
private readonly Dictionary<string, Action<float, float>> _onValueChanged = new();
/// <summary>
/// 当为 true 时,暂时不触发属性变更回调。
/// 用于批量修改属性时避免中间状态触发回调。
/// </summary>
private bool _suppressCallbacks;
2026-03-20 12:07:44 -04:00
public bool Has(string attributeName) => attributeGroup.current.ContainsKey(attributeName);
public float Get(string attributeName, float defaultValue) => attributeGroup.current.GetValueOrDefault(attributeName, defaultValue);
2025-11-25 08:19:33 -05:00
public float this[string attributeName]
{
get => attributeGroup.current.GetValueOrDefault(attributeName, attributeName.Contains("Multiplier") ? 1 : 0);
2026-05-23 08:27:50 -04:00
set
{
float oldValue = attributeGroup.current.GetValueOrDefault(attributeName, 0f);
attributeGroup.current[attributeName] = value;
if (!_suppressCallbacks && Math.Abs(oldValue - value) > float.Epsilon)
{
NotifyValueChanged(attributeName, oldValue, value);
}
}
2025-11-25 08:19:33 -05:00
}
public AttributeSubmodule(CharacterBase character) : base(character)
{
Initialize(character.attributeData);
}
2026-03-20 12:07:44 -04:00
public AttributeSubmodule(CharacterBase character, AttributeData attributeData) : base(character)
{
Initialize(attributeData);
}
2025-11-25 08:19:33 -05:00
private void Initialize(AttributeData attributeData)
{
attributeGroup = new AttributeGroup(attributeData.originalAttributes);
attributeGroup.SetUpEndowments(attributeData.runtimeAttributes);
}
2025-12-08 05:27:53 -05:00
public void RefreshAttribute(string attributeName)
{
2026-05-23 08:27:50 -04:00
float oldValue = attributeGroup.current.GetValueOrDefault(attributeName, 0f);
2025-12-08 05:27:53 -05:00
attributeGroup.ResetAttribute(attributeName);
2026-01-03 18:19:39 -05:00
float numeric = 0;
float pAccumulation = 0;
float pMultiplication = 1;
if (owner is Player player)
{
player.inventorySc.ApplyAttributeChange(attributeName, ref numeric, ref pAccumulation, ref pMultiplication);
}
owner.buffSm.ApplyAttributeChange(attributeName, ref numeric, ref pAccumulation, ref pMultiplication);
2025-12-08 05:27:53 -05:00
attributeGroup.ModifyAttribute(attributeName, numeric, pAccumulation, pMultiplication);
2026-05-23 08:27:50 -04:00
float newValue = attributeGroup.current.GetValueOrDefault(attributeName, 0f);
if (!_suppressCallbacks && Math.Abs(oldValue - newValue) > float.Epsilon)
{
NotifyValueChanged(attributeName, oldValue, newValue);
}
2025-12-08 05:27:53 -05:00
}
2026-01-03 18:19:39 -05:00
public void RefreshAllAttributes()
{
foreach (var attributeName in attributeGroup.original.Keys)
{
RefreshAttribute(attributeName);
}
}
2025-11-25 08:19:33 -05:00
}
2026-05-23 08:27:50 -04:00
/// <summary>
/// 属性变更回调注册与触发
/// </summary>
public partial class AttributeSubmodule
{
/// <summary>
/// 为指定属性注册一个值变更回调。多次注册同一属性会追加委托。
/// </summary>
/// <param name="attributeName">属性名(使用 CharacterAttribute 常量)</param>
/// <param name="callback">回调委托,参数为 (oldValue, newValue)</param>
public void RegisterValueChangedCallback(string attributeName, Action<float, float> callback)
{
if (_onValueChanged.TryGetValue(attributeName, out var existing))
{
_onValueChanged[attributeName] = existing + callback;
}
else
{
_onValueChanged[attributeName] = callback;
}
}
/// <summary>
/// 为指定属性注销一个值变更回调。
/// </summary>
public void UnregisterValueChangedCallback(string attributeName, Action<float, float> callback)
{
if (_onValueChanged.TryGetValue(attributeName, out var existing))
{
var updated = existing - callback;
if (updated == null)
{
_onValueChanged.Remove(attributeName);
}
else
{
_onValueChanged[attributeName] = updated;
}
}
}
/// <summary>
/// 暂时挂起所有属性变更回调。调用 ResumeCallbacks 恢复。
/// 适用于批量初始化等不需要触发 UI 更新的场景。
/// </summary>
public void SuppressCallbacks() => _suppressCallbacks = true;
/// <summary>
/// 恢复属性变更回调触发。
/// </summary>
public void ResumeCallbacks() => _suppressCallbacks = false;
private void NotifyValueChanged(string attributeName, float oldValue, float newValue)
{
if (_onValueChanged.TryGetValue(attributeName, out var callback))
{
callback.Invoke(oldValue, newValue);
}
}
}
2025-11-25 08:19:33 -05:00
}