using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using BITKit; using BITKit.SubSystems; using BITKit.Entities; namespace BITKit.Entities { public interface IDamageType { } public interface IDamageService { public event Action OnEntityDamaged; public event Action OnEntityKilled; void Execute(DamageMessage damageMessage); } [Serializable] public class DamageServiceSingleton:IDamageService { private IDamageService _damageServiceImplementation => DamageService.Singleton; public event Action OnEntityDamaged { add => _damageServiceImplementation.OnEntityDamaged += value; remove => _damageServiceImplementation.OnEntityDamaged -= value; } public event Action OnEntityKilled { add => _damageServiceImplementation.OnEntityKilled += value; remove => _damageServiceImplementation.OnEntityKilled -= value; } public void Execute(DamageMessage damageMessage) { _damageServiceImplementation.Execute(damageMessage); } } [Serializable] public class DamageServiceMonoProxy:IDamageService { [SerializeField] private MonoBehaviour monoBehaviour; private IDamageService _damageServiceImplementation=>monoBehaviour as IDamageService; public event Action OnEntityDamaged { add => _damageServiceImplementation.OnEntityDamaged += value; remove => _damageServiceImplementation.OnEntityDamaged -= value; } public event Action OnEntityKilled { add => _damageServiceImplementation.OnEntityKilled += value; remove => _damageServiceImplementation.OnEntityKilled -= value; } public void Execute(DamageMessage damageMessage) { _damageServiceImplementation.Execute(damageMessage); } } public record DamageMessage { public IEntity initiator; public IEntity target; public int damage; public IDamagable hit; public Location location; public IDamageType damageType; } public interface IDamageCallback { void OnGetDamage(DamageMessage message); } public interface IDamagable { IEntity Entity { get; } Rigidbody Rigidbody { get; } void GiveDamage(DamageMessage message); } public class DamageService:MonoBehaviour,IDamageService { internal static IDamageService Singleton { get; set; } private readonly Queue Messages = new(); private void Awake() { Singleton = this; } private void FixedUpdate() { while (Messages.TryDequeue(out var damageMessage)) { var unityEntity = (Entity)damageMessage.target; if (unityEntity is null || !unityEntity.TryGetComponent(out var heal) || !heal.IsAlive) continue; damageMessage.initiator?.Invoke(damageMessage); damageMessage.target?.Invoke(damageMessage); foreach (var x in damageMessage.target?.GetCallbacks()!) { x.OnGetDamage(damageMessage); } OnEntityDamaged?.Invoke(damageMessage); if (heal.IsAlive is false) { OnEntityKilled?.Invoke(damageMessage); } } } public event Action OnEntityDamaged; public event Action OnEntityKilled; public void Execute(DamageMessage damageMessage)=>Messages.Enqueue(damageMessage); } }