120 lines
3.8 KiB
C#
120 lines
3.8 KiB
C#
|
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<DamageMessage> OnEntityDamaged;
|
||
|
public event Action<DamageMessage> OnEntityKilled;
|
||
|
void Execute(DamageMessage damageMessage);
|
||
|
}
|
||
|
[Serializable]
|
||
|
public class DamageServiceSingleton:IDamageService
|
||
|
{
|
||
|
private IDamageService _damageServiceImplementation => DamageService.Singleton;
|
||
|
public event Action<DamageMessage> OnEntityDamaged
|
||
|
{
|
||
|
add => _damageServiceImplementation.OnEntityDamaged += value;
|
||
|
remove => _damageServiceImplementation.OnEntityDamaged -= value;
|
||
|
}
|
||
|
|
||
|
public event Action<DamageMessage> 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<DamageMessage> OnEntityDamaged
|
||
|
{
|
||
|
add => _damageServiceImplementation.OnEntityDamaged += value;
|
||
|
remove => _damageServiceImplementation.OnEntityDamaged -= value;
|
||
|
}
|
||
|
|
||
|
public event Action<DamageMessage> 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<DamageMessage> 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<IHealth>(out var heal) || !heal.IsAlive) continue;
|
||
|
|
||
|
damageMessage.initiator?.Invoke(damageMessage);
|
||
|
damageMessage.target?.Invoke(damageMessage);
|
||
|
|
||
|
foreach (var x in damageMessage.target?.GetCallbacks<IDamageCallback>()!)
|
||
|
{
|
||
|
x.OnGetDamage(damageMessage);
|
||
|
}
|
||
|
|
||
|
OnEntityDamaged?.Invoke(damageMessage);
|
||
|
if (heal.IsAlive is false)
|
||
|
{
|
||
|
OnEntityKilled?.Invoke(damageMessage);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public event Action<DamageMessage> OnEntityDamaged;
|
||
|
public event Action<DamageMessage> OnEntityKilled;
|
||
|
public void Execute(DamageMessage damageMessage)=>Messages.Enqueue(damageMessage);
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|