using System;
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
{
}
///
/// 击倒服务
///
public interface IKnockedService
{
///
/// 击倒列表
///
public HashSet Knocked { get; }
///
/// 击倒生命值
///
public IReadOnlyDictionary KnockedHealth { get; }
///
/// 击倒回调
///
public event Action OnKnocked;
///
/// 击倒生命值回调
///
public event Action OnKnockedHealthChanged;
}
public class KnockedService : IKnockedService,IDisposable
{
private readonly IEntitiesService _entitiesService;
private readonly IHealthService _healthService;
private readonly ILogger _logger;
public KnockedService(IHealthService healthService, ILogger 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() is null) return plus;
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 oldHp-1;
}
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 _knocked = new();
private static readonly ConcurrentDictionary _knockedHealth = new();
private static event Action _onKnocked;
private static event Action _onKnockedHealthChanged;
public HashSet Knocked=> _knocked;
public IReadOnlyDictionary KnockedHealth => _knockedHealth;
public event Action OnKnocked
{
add => _onKnocked += value;
remove => _onKnocked -= value;
}
public event Action OnKnockedHealthChanged
{
add => _onKnockedHealthChanged += value;
remove => _onKnockedHealthChanged -= value;
}
public void Dispose()
{
_healthService.OnHealthPlus -= OnHealthPlus;
_healthService.OnHealthChanged -= OnHealthChanged;
}
}
}