1
This commit is contained in:
@@ -2,11 +2,25 @@ using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BITKit;
|
||||
using BITKit.Entities;
|
||||
using BITKit.WorldNode;
|
||||
using Cysharp.Threading.Tasks;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
|
||||
|
||||
namespace Net.Project.B.Health
|
||||
{
|
||||
public interface IHealthComponent
|
||||
{
|
||||
public int MaxHealthPoint { get; }
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class HealthComponent:IHealthComponent,IWorldNode
|
||||
{
|
||||
public int maxHealthPoint = 100;
|
||||
public int MaxHealthPoint => maxHealthPoint;
|
||||
}
|
||||
/// <summary>
|
||||
/// 生命值服务
|
||||
/// </summary>
|
||||
@@ -36,13 +50,31 @@ namespace Net.Project.B.Health
|
||||
/// <returns></returns>
|
||||
public UniTask<int> AddHealth(int id,int value,object arg);
|
||||
}
|
||||
public class HealthService:IHealthService
|
||||
{
|
||||
private static HealthService _singleton;
|
||||
public HealthService()
|
||||
public class HealthService:IHealthService,IDisposable
|
||||
{ private static HealthService _singleton;
|
||||
private readonly IEntitiesService _entitiesService;
|
||||
|
||||
private static readonly ConcurrentDictionary<int, IHealthComponent> HealthComponents = new();
|
||||
|
||||
public HealthService(IEntitiesService entitiesService)
|
||||
{
|
||||
_entitiesService = entitiesService;
|
||||
_singleton = this;
|
||||
|
||||
_entitiesService.OnAdd += OnAdd;
|
||||
}
|
||||
|
||||
private void OnAdd(IEntity obj)
|
||||
{
|
||||
if (obj.ServiceProvider.GetService<IHealthComponent>() is {} healthComponent)
|
||||
{
|
||||
if (HealthComponents.TryAdd(obj.Id, healthComponent))
|
||||
{
|
||||
Healths.TryAdd(obj.Id, healthComponent.MaxHealthPoint <=0 ? 100 : healthComponent.MaxHealthPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[BITCommand]
|
||||
public static void SetHealth(int id, int newHealth)
|
||||
{
|
||||
@@ -55,6 +87,7 @@ namespace Net.Project.B.Health
|
||||
{
|
||||
Healths.GetOrAdd(id,100);
|
||||
_singleton.AddHealth(id, newHealth, null).Forget();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -75,15 +108,21 @@ namespace Net.Project.B.Health
|
||||
}
|
||||
public UniTask<int> AddHealth(int id, int value,object arg)
|
||||
{
|
||||
var current = Healths.GetOrAdd(id,100);
|
||||
if (Healths.TryGetValue(id,out var current) is false) return UniTask.FromResult(-1);
|
||||
|
||||
foreach (var func in OnHealthChange.CastAsFunc())
|
||||
{
|
||||
value =func.Invoke(id,current, value, arg);
|
||||
}
|
||||
var newHp = Math.Clamp(current + value, -1, 100);
|
||||
var newHp = Math.Clamp(current + value, -1, HealthComponents[id].MaxHealthPoint);
|
||||
Healths.Set(id,newHp);
|
||||
OnHealthChanged?.Invoke(id,current,newHp,arg);
|
||||
return UniTask.FromResult(newHp);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
_entitiesService.OnAdd -= OnAdd;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -3,10 +3,19 @@ using System.Collections;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using BITKit;
|
||||
using BITKit.Entities;
|
||||
using BITKit.WorldNode;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
|
||||
namespace Net.Project.B.Health
|
||||
{
|
||||
[Serializable]
|
||||
public class KnockedComponent:IKnockedComponent,IWorldNode{}
|
||||
public interface IKnockedComponent
|
||||
{
|
||||
|
||||
}
|
||||
/// <summary>
|
||||
/// 击倒服务
|
||||
/// </summary>
|
||||
@@ -32,19 +41,25 @@ namespace Net.Project.B.Health
|
||||
|
||||
public class KnockedService : IKnockedService,IDisposable
|
||||
{
|
||||
private readonly IEntitiesService _entitiesService;
|
||||
private readonly IHealthService _healthService;
|
||||
private readonly ILogger<KnockedService> _logger;
|
||||
|
||||
public KnockedService(IHealthService healthService, ILogger<KnockedService> logger)
|
||||
public KnockedService(IHealthService healthService, ILogger<KnockedService> logger, IEntitiesService entitiesService)
|
||||
{
|
||||
_healthService = healthService;
|
||||
_logger = logger;
|
||||
_entitiesService = entitiesService;
|
||||
_healthService.OnHealthPlus += OnHealthPlus;
|
||||
_healthService.OnHealthChanged += OnHealthChanged;
|
||||
}
|
||||
|
||||
private int OnHealthPlus(int id, int oldHp, int plus, object sendor)
|
||||
{
|
||||
if (_entitiesService.TryGetEntity(id, out var entity) is false) return plus;
|
||||
|
||||
if (entity.ServiceProvider.GetService<IKnockedComponent>() is null) return plus;
|
||||
|
||||
var isKnocked = _knocked.Contains(id);
|
||||
if (oldHp < 0) return plus;
|
||||
if ((oldHp + plus) > -1) return plus;
|
||||
@@ -57,7 +72,7 @@ namespace Net.Project.B.Health
|
||||
var nextHealth = currentHealth + plus;
|
||||
_knockedHealth[id] = nextHealth;
|
||||
_onKnockedHealthChanged?.Invoke(id, currentHealth, nextHealth);
|
||||
_logger.LogInformation($"Entity {id} 的击倒生命值减少了,剩余{_knockedHealth[id]}");
|
||||
// _logger.LogInformation($"Entity {id} 的击倒生命值减少了,剩余{_knockedHealth[id]}");
|
||||
return 0;
|
||||
}
|
||||
_knockedHealth.Set(id,-1);
|
||||
@@ -66,7 +81,7 @@ namespace Net.Project.B.Health
|
||||
_knockedHealth.TryAdd(id, 100);
|
||||
_knocked.Add(id);
|
||||
_onKnocked?.Invoke(id, true);
|
||||
_logger.LogInformation($"Entity {id} 被击倒了");
|
||||
// _logger.LogInformation($"Entity {id} 被击倒了");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -79,7 +94,7 @@ namespace Net.Project.B.Health
|
||||
_knockedHealth.TryRemove(arg1,out _);
|
||||
_onKnocked?.Invoke(arg1, false);
|
||||
|
||||
_logger.LogInformation($"Entity {arg1} 自起了");
|
||||
// _logger.LogInformation($"Entity {arg1} 自起了");
|
||||
}
|
||||
|
||||
private static readonly HashSet<int> _knocked = new();
|
||||
|
@@ -3,7 +3,8 @@
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:14fe60d984bf9f84eac55c6ea033a8f4",
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23"
|
||||
"GUID:f51ebe6a0ceec4240a699833d6309b23",
|
||||
"GUID:d750d221812bb1d48baff92e6ef73e28"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
|
Reference in New Issue
Block a user