BITFALL/Assets/BITKit/Unity/Scripts/Entity/Components/Health/DamageService.cs

120 lines
3.8 KiB
C#
Raw Normal View History

2023-08-12 01:43:24 +08:00
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);
}
2023-11-15 23:54:54 +08:00
public struct MeleeDamageMessage:IDamageType{}
public struct BulletDamageMessage:IDamageType{}
2023-08-12 01:43:24 +08:00
[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
{
2023-10-30 01:25:53 +08:00
public IUnityEntity Initiator;
public IUnityEntity Target;
2023-10-24 23:37:59 +08:00
public bool RawDamage;
public int Damage;
public IDamagable Hit;
2023-11-30 00:23:23 +08:00
public Vector3 Position;
public Quaternion Rotation;
2023-10-24 23:37:59 +08:00
public IDamageType DamageType;
2023-08-12 01:43:24 +08:00
}
2023-11-15 23:54:54 +08:00
2023-08-12 01:43:24 +08:00
public interface IDamageCallback
{
void OnGetDamage(DamageMessage message);
}
public interface IDamagable
{
2023-10-30 01:25:53 +08:00
IUnityEntity UnityEntity { get; }
2023-08-12 01:43:24 +08:00
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))
{
2023-10-24 23:37:59 +08:00
var unityEntity = (Entity)damageMessage.Target;
2023-11-30 00:23:23 +08:00
if (!unityEntity || !unityEntity.TryGetComponent<IHealth>(out var heal) || !heal.IsAlive) continue;
2023-08-12 01:43:24 +08:00
2023-10-24 23:37:59 +08:00
damageMessage.Initiator?.Invoke(damageMessage);
damageMessage.Target?.Invoke(damageMessage);
2023-08-12 01:43:24 +08:00
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);
}
}