BITFALL/Assets/Artists/Scripts/Equip/MeleeController.cs

170 lines
4.0 KiB
C#

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<IPlayerMeleeControllerState>
{
[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 AssetableMelee melee => assetableItem as AssetableMelee;
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<IMeleeCombat>();
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<Draw>();
}
public override void Exited()
{
base.Exited();
_movement.ExecuteCommand<PlayerPauseRunCommand>(new(this,false));
TransitionState<Empty>();
}
public override void OnUpdate(float deltaTime)
{
base.OnUpdate(deltaTime);
var position = velocityReference.position;
_velocity = (position - _lastPosition).normalized;
_lastPosition = position;
UpdateState(deltaTime);
_movement.ExecuteCommand<PlayerPauseRunCommand>(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;
}
}
}
}