using System; using System.Collections; using System.Collections.Generic; using BITFALL.Items.Melee; using BITFALL.Combat; using BITFALL.Player.Movement; using BITKit; using BITKit.Entities; using BITKit.Entities.Melee; using BITKit.StateMachine; using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.InputSystem.Interactions; namespace BITFALL.Entities.Equipment.Melee { public interface IPlayerMeleeControllerState : IState { } public abstract class PlayerMeleeControllerState : IPlayerMeleeControllerState { [SerializeField] protected MeleeController my; public virtual bool Enabled { get; set; } public virtual void Initialize() { my.Entity.Inject(this); } public virtual void OnStateEntry(IState old) { } public virtual void OnStateUpdate(float deltaTime) { } public virtual void OnStateExit(IState old, IState newState) { } } public sealed class MeleeController : StateWeaponController { [Header(Constant.Header.Input)] [SerializeField] internal InputActionReference attackAction; [SerializeField] internal InputActionReference blockAction; [Header(Constant.Header.Gameobjects)] [SerializeField] private Transform velocityReference; [Header(Constant.Header.Services)] [SerializeReference,SubclassSelector] private IMeleeService _meleeService; public ScriptableMelee melee => scriptableItem as ScriptableMelee; private Vector3 _velocity; private Vector3 _lastPosition; [Inject] internal IEntityMovement _movement; [Inject(true)] internal IPlayerMovement _playerMovement; [Inject] internal IHealth _health; public override void OnAwake() { base.OnAwake(); if (_playerMovement is not null) _health.OnDamageFactory += OnDamageFactory; } private int OnDamageFactory(DamageMessage arg1, int arg2) { if (Enabled is false || arg1.Initiator is null) return arg2; if (CurrentState is not Blocking blocking) return arg2; var combat = arg1.Initiator.Get(); if (combat is null) return arg2; if (blocking.AllowBlockStun && _playerMovement.Stamina >= melee.BlockStaminaCost) { arg2 =0; combat.HitStun(); _playerMovement.Stamina -= melee.BlockStaminaCost*0.5f; } else { // if (_playerMovement.Stamina > melee.BlockStaminaCost) // { // animator.Play(BITConstant.Player.BlockStun); // arg2 /= 3; // } // else // { // animator.Play(BITConstant.Player.BlockBreak); // arg2 /= 2; // } _playerMovement.Stamina -= melee.BlockStaminaCost; } return arg2; } public override void Entry() { base.Entry(); TransitionState(); } public override void Exited() { base.Exited(); _movement.ExecuteCommand(new(this,false)); TransitionState(); } public override void OnUpdate(float deltaTime) { base.OnUpdate(deltaTime); var position = velocityReference.position; _velocity = (position - _lastPosition).normalized; _lastPosition = position; UpdateState(deltaTime); _movement.ExecuteCommand(new(this,CurrentState is not Idle)); } public override void AnimationEvent(string eventName) { base.AnimationEvent(eventName); switch (eventName) { case BITConstant.Player.Attack: case BITConstant.Player.Melee: _meleeService.Melee(new MeleeCommand() { Damage =melee.MeleeDamage, Force = melee.MeleeForce, Forward = transform.forward, Limit = 1, PlayerId = Entity.Id, Position = transform.position, Range = melee.MeleeRange, }); break; case BITConstant.Player.HeavyAttack: _playerMovement.Stamina -= melee.HeavyAttackStaminaCost; _meleeService.Melee(new MeleeCommand() { Damage =melee.HeavyMeleeDamage, Force = melee.HeavyMeleeForce, Forward = transform.forward, Limit = 1, PlayerId = Entity.Id, Position = transform.position, Range = melee.HeavyMeleeRange, }); break; } } } }