BITFALL/Assets/Artists/Scripts/MeleeService/MeleeService.cs

99 lines
2.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using BITKit;
using BITKit.Entities;
using BITKit.Entities.Melee;
using Cysharp.Threading.Tasks;
using Cysharp.Threading.Tasks.Triggers;
using Unity.Collections;
using UnityEngine;
using UnityEngine.VFX;
namespace BITFALL.Melee
{
[Serializable]
public class MeleeServiceSingleton : IMeleeService
{
public void Melee(MeleeCommand command) => MeleeService.Melee(command);
}
public struct MeleeDamageMessage:IDamageType{}
public class MeleeService : MonoBehaviour,IMeleeService
{
internal static MeleeService Singleton;
[RuntimeInitializeOnLoadMethod]
private static void Initialize()
{
Queue.Clear();
}
private static readonly Queue<MeleeCommand> Queue = new();
public static void Melee(MeleeCommand command)=>Queue.Enqueue(command);
[SerializeField] private LayerMask detectLayer;
[SerializeReference, SubclassSelector] private IDamageService damageService;
private void Awake()
{
Singleton = this;
}
private void FixedUpdate()
{
if (Queue.TryDequeue(out var command) is false) return;
var colliders = Physics.OverlapSphere(command.Position, command.Range,detectLayer);
var damaged= new List<IEntity>();
foreach (var x in colliders.Where(x=>x.GetComponent<IDamagable>() is not null))
{
try
{
var damageable = x.GetComponent<IDamagable>();
if (damaged.Contains(damageable.Entity) || damageable.Entity.Id == command.PlayerId)
{
continue;
}
damaged.Add(damageable.Entity);
var damageMsg =
new DamageMessage()
{
Initiator = UnityEntitiesService.Get(command.PlayerId) as IEntity,
DamageType = new MeleeDamageMessage
{
},
Target = damageable.Entity,
Damage = command.Damage is 0 ? 64 : command.Damage,
Hit = damageable,
};
if (command.PlayerId !=default)
{
damageMsg.Initiator = UnityEntitiesService.Get(command.PlayerId) as IEntity;
}
damageService.Execute(damageMsg);
damageable.Rigidbody.AddForceAtPositionAsync(command.Force, command.Position, ForceMode.Impulse)
.Forget();
if (x.TryGetComponent<ITag>(out var _tag))
{
DI.Get<VFXService>().Spawn(new Location
{
position = x.transform.position,
//rotation = Quaternion.identity,
}, _tag.GetTags());
}
}
catch (UnassignedReferenceException e)
{
Debug.LogWarning(x.name);
Debug.LogException(e);
}
}
}
void IMeleeService.Melee(MeleeCommand command) => Melee(command);
}
}