1
This commit is contained in:
89
Src/Health/HealthService.cs
Normal file
89
Src/Health/HealthService.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BITKit;
|
||||
using Cysharp.Threading.Tasks;
|
||||
|
||||
|
||||
namespace Net.Project.B.Health
|
||||
{
|
||||
/// <summary>
|
||||
/// 生命值服务
|
||||
/// </summary>
|
||||
public interface IHealthService
|
||||
{
|
||||
/// <summary>
|
||||
/// 已缓存的生命值
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<int,int> Healths { get; }
|
||||
/// <summary>
|
||||
/// 在改变生命值前,ID,当前生命值,新的生命值,来源
|
||||
/// <returns>增加的数值</returns>
|
||||
/// </summary>
|
||||
public event Func<int,int,int,object,int> OnHealthPlus;
|
||||
/// <summary>
|
||||
/// 在改变生命值后
|
||||
/// </summary>
|
||||
/// /// <summary>
|
||||
/// 当健康值发生变化时触发的事件。
|
||||
/// </summary>
|
||||
public event Action<int,int,int,object> OnHealthChanged;
|
||||
/// <summary>
|
||||
/// 调整生命值
|
||||
/// </summary>
|
||||
/// <param name="id"></param>
|
||||
/// <param name="value">+- not set</param>
|
||||
/// <returns></returns>
|
||||
public UniTask<int> 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<int, int> IHealthService.Healths => Healths;
|
||||
private static event Func<int,int,int,object,int> OnHealthChange;
|
||||
private static event Action<int,int,int,object> OnHealthChanged;
|
||||
private static readonly ConcurrentDictionary<int, int> Healths = new();
|
||||
|
||||
event Func<int,int,int,object,int> IHealthService.OnHealthPlus
|
||||
{
|
||||
add => OnHealthChange += value;
|
||||
remove => OnHealthChange -= value;
|
||||
}
|
||||
event Action<int,int,int,object> IHealthService.OnHealthChanged
|
||||
{
|
||||
add => OnHealthChanged += value;
|
||||
remove => OnHealthChanged -= value;
|
||||
}
|
||||
public UniTask<int> 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);
|
||||
}
|
||||
}
|
||||
}
|
11
Src/Health/HealthService.cs.meta
Normal file
11
Src/Health/HealthService.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 128dfad42ea28ca458121d3ca6b70ffc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
109
Src/Health/KnockedService.cs
Normal file
109
Src/Health/KnockedService.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BITKit;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Net.Project.B.Health
|
||||
{
|
||||
/// <summary>
|
||||
/// 击倒服务
|
||||
/// </summary>
|
||||
public interface IKnockedService
|
||||
{
|
||||
/// <summary>
|
||||
/// 击倒列表
|
||||
/// </summary>
|
||||
public HashSet<int> Knocked { get; }
|
||||
/// <summary>
|
||||
/// 击倒生命值
|
||||
/// </summary>
|
||||
public IReadOnlyDictionary<int,int> KnockedHealth { get; }
|
||||
/// <summary>
|
||||
/// 击倒回调
|
||||
/// </summary>
|
||||
public event Action<int, bool> OnKnocked;
|
||||
/// <summary>
|
||||
/// 击倒生命值回调
|
||||
/// </summary>
|
||||
public event Action<int, int, int> OnKnockedHealthChanged;
|
||||
}
|
||||
|
||||
public class KnockedService : IKnockedService,IDisposable
|
||||
{
|
||||
private readonly IHealthService _healthService;
|
||||
private readonly ILogger<KnockedService> _logger;
|
||||
|
||||
public KnockedService(IHealthService healthService, ILogger<KnockedService> logger)
|
||||
{
|
||||
_healthService = healthService;
|
||||
_logger = logger;
|
||||
_healthService.OnHealthPlus += OnHealthPlus;
|
||||
_healthService.OnHealthChanged += OnHealthChanged;
|
||||
}
|
||||
|
||||
private int OnHealthPlus(int id, int oldHp, int plus, object sendor)
|
||||
{
|
||||
var isKnocked = _knocked.Contains(id);
|
||||
if (oldHp < 0) return plus;
|
||||
if ((oldHp + plus) > -1) return plus;
|
||||
if (plus > 0) return plus;
|
||||
if (isKnocked)
|
||||
{
|
||||
var currentHealth = _knockedHealth.GetOrAdd(id,100);
|
||||
if (currentHealth + plus > -1)
|
||||
{
|
||||
var nextHealth = currentHealth + plus;
|
||||
_knockedHealth[id] = nextHealth;
|
||||
_onKnockedHealthChanged?.Invoke(id, currentHealth, nextHealth);
|
||||
_logger.LogInformation($"Entity {id} 的击倒生命值减少了,剩余{_knockedHealth[id]}");
|
||||
return 0;
|
||||
}
|
||||
_knockedHealth.Set(id,-1);
|
||||
return plus;
|
||||
}
|
||||
_knockedHealth.TryAdd(id, 100);
|
||||
_knocked.Add(id);
|
||||
_onKnocked?.Invoke(id, true);
|
||||
_logger.LogInformation($"Entity {id} 被击倒了");
|
||||
return 0;
|
||||
}
|
||||
|
||||
private void OnHealthChanged(int arg1, int arg2, int arg3, object arg4)
|
||||
{
|
||||
var isKnocked = _knocked.Contains(arg1);
|
||||
if(isKnocked is false)return;
|
||||
if (arg3 <= arg2) return;
|
||||
_knocked.Remove(arg1);
|
||||
_knockedHealth.TryRemove(arg1,out _);
|
||||
_onKnocked?.Invoke(arg1, false);
|
||||
|
||||
_logger.LogInformation($"Entity {arg1} 自起了");
|
||||
}
|
||||
|
||||
private static readonly HashSet<int> _knocked = new();
|
||||
private static readonly ConcurrentDictionary<int,int> _knockedHealth = new();
|
||||
private static event Action<int, bool> _onKnocked;
|
||||
private static event Action<int, int, int> _onKnockedHealthChanged;
|
||||
public HashSet<int> Knocked=> _knocked;
|
||||
public IReadOnlyDictionary<int, int> KnockedHealth => _knockedHealth;
|
||||
public event Action<int, bool> OnKnocked
|
||||
{
|
||||
add => _onKnocked += value;
|
||||
remove => _onKnocked -= value;
|
||||
}
|
||||
public event Action<int, int, int> OnKnockedHealthChanged
|
||||
{
|
||||
add => _onKnockedHealthChanged += value;
|
||||
remove => _onKnockedHealthChanged -= value;
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_healthService.OnHealthPlus -= OnHealthPlus;
|
||||
_healthService.OnHealthChanged -= OnHealthChanged;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
11
Src/Health/KnockedService.cs.meta
Normal file
11
Src/Health/KnockedService.cs.meta
Normal file
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 1eec6f99cef0ae14ab1593764fad6a50
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
17
Src/Health/Net.Project.B.Health.asmdef
Normal file
17
Src/Health/Net.Project.B.Health.asmdef
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "Net.Project.B.Health",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [],
|
||||
"noEngineReferences": true
|
||||
}
|
7
Src/Health/Net.Project.B.Health.asmdef.meta
Normal file
7
Src/Health/Net.Project.B.Health.asmdef.meta
Normal file
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8f79dfa3edfa9514b8f6d7d2f0102ccc
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user