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); } } }