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 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(); foreach (var x in colliders.Where(x=>x.GetComponent() is not null)) { try { var damageable = x.GetComponent(); 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(out var _tag)) { DI.Get().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); } }