using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using BITKit;
using Cysharp.Threading.Tasks;
namespace Net.Project.B.Health
{
///
/// 生命值服务
///
public interface IHealthService
{
///
/// 已缓存的生命值
///
public IReadOnlyDictionary Healths { get; }
///
/// 在改变生命值前,ID,当前生命值,新的生命值,来源
/// 增加的数值
///
public event Func OnHealthPlus;
///
/// 在改变生命值后
///
/// ///
/// 当健康值发生变化时触发的事件。
///
public event Action OnHealthChanged;
///
/// 调整生命值
///
///
/// +- not set
///
public UniTask AddHealth(int id,int value,object arg);
}
public class HealthService:IHealthService
{
private static HealthService _singleton;
public HealthService()
{
_singleton = this;
}
[BITCommand]
public static void SetHealth(int id, int newHealth)
{
Healths.GetOrAdd(id,100);
Healths.Set(id,newHealth);
OnHealthChanged?.Invoke(id,newHealth,newHealth,null);
}
[BITCommand]
public static void AddHealth(int id, int newHealth)
{
Healths.GetOrAdd(id,100);
_singleton.AddHealth(id, newHealth, null).Forget();
}
IReadOnlyDictionary IHealthService.Healths => Healths;
private static event Func OnHealthChange;
private static event Action OnHealthChanged;
private static readonly ConcurrentDictionary Healths = new();
event Func IHealthService.OnHealthPlus
{
add => OnHealthChange += value;
remove => OnHealthChange -= value;
}
event Action IHealthService.OnHealthChanged
{
add => OnHealthChanged += value;
remove => OnHealthChanged -= value;
}
public UniTask AddHealth(int id, int value,object arg)
{
var current = Healths.GetOrAdd(id,100);
foreach (var func in OnHealthChange.CastAsFunc())
{
value =func.Invoke(id,current, value, arg);
}
var newHp = Math.Clamp(current + value, -1, 100);
Healths.Set(id,newHp);
OnHealthChanged?.Invoke(id,current,newHp,arg);
return UniTask.FromResult(newHp);
}
}
}