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); } public struct MeleeDamageMessage:IDamageType{} public struct BulletDamageMessage:IDamageType{} [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 IUnityEntity Initiator; public IUnityEntity Target; public bool RawDamage; public int Damage; public IDamagable Hit; public Vector3 Position; public Quaternion Rotation; public IDamageType DamageType; } public interface IDamageCallback { void OnGetDamage(DamageMessage message); } public interface IDamagable { IUnityEntity UnityEntity { 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 || !unityEntity.TryGetComponent(out var heal) || !heal.IsAlive) continue; damageMessage.Initiator?.Invoke(damageMessage); damageMessage.Target?.Invoke(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); } }