134 lines
4.1 KiB
C#
134 lines
4.1 KiB
C#
using Kryz.CharacterStats.Examples;
|
|
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
using UnityEngine.AI;
|
|
using UnityEngine.Events;
|
|
|
|
public class CastingStateController : MonoBehaviour
|
|
{
|
|
public bool isCasting;
|
|
public PlayerMovement playerMovement;
|
|
public LayerMask movementMask;
|
|
|
|
private MovementSpeedModifierEffectInstance movementSpeedModifier;
|
|
private Camera cam;
|
|
private Ray ray;
|
|
private RaycastHit hit;
|
|
private ProjectileSpawnLocationController projectileSpawnLocationController;
|
|
private CharacterStats stats;
|
|
|
|
public UnityEvent<BaseAbility> OnAbilityQueued = new UnityEvent<BaseAbility>();
|
|
|
|
private void Awake()
|
|
{
|
|
cam = Camera.main;
|
|
movementSpeedModifier = playerMovement.GetComponent<MovementSpeedModifierEffectInstance>();
|
|
stats = playerMovement.GetComponent<CharacterStats>();
|
|
projectileSpawnLocationController = transform.root.GetComponentInChildren<ProjectileSpawnLocationController>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate current attack interval based on base speed and modifiers
|
|
/// </summary>
|
|
private float GetCurrentAttackInterval()
|
|
{
|
|
float totalAttackSpeed = GameConstants.CharacterStatsBalancing.BaseAttacksPerSecond * (1f + (MathHelpers.NormalizePercentage(stats.AttackSpeed.Value) / 100f));
|
|
float interval = 1f / totalAttackSpeed;
|
|
return Mathf.Max(interval, GameConstants.CharacterStatsBalancing.FastestAttacksPerSecond);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Get current attacks per second
|
|
/// </summary>
|
|
public float GetCurrentAttacksPerSecond()
|
|
{
|
|
return 1f / GetCurrentAttackInterval();
|
|
}
|
|
|
|
public void RequestAbilityCast(BaseAbility ability, Action abilityExecution)
|
|
{
|
|
if (isCasting) return;
|
|
|
|
if (!ability.castableWhileMoving)
|
|
{
|
|
movementSpeedModifier.ToggleCastPenalty(true);
|
|
}
|
|
|
|
OnAbilityQueued.Invoke(ability);
|
|
StartCoroutine(Casting(ability, abilityExecution));
|
|
}
|
|
|
|
public void RequestAbilityChannel(BaseAbility channeledAbility, Action abilityChannelExecution)
|
|
{
|
|
if (isCasting) return;
|
|
|
|
if (!channeledAbility.castableWhileMoving)
|
|
{
|
|
movementSpeedModifier.ToggleCastPenalty(true);
|
|
}
|
|
|
|
OnAbilityQueued.Invoke(channeledAbility);
|
|
StartCoroutine(Channeling(channeledAbility, abilityChannelExecution));
|
|
}
|
|
|
|
private IEnumerator Casting(BaseAbility ability, Action abilityExecution)
|
|
{
|
|
isCasting = true;
|
|
|
|
// Use player attack speed instead of ability cast time
|
|
float castTime = GetCurrentAttackInterval();
|
|
|
|
CastBarHandler.Instance.ShowCastBar(ability, abilityExecution, castTime);
|
|
playerMovement.InstantFaceCast(projectileSpawnLocationController.GetLookat());
|
|
|
|
// Wait for the calculated attack interval
|
|
yield return new WaitForSeconds(castTime);
|
|
|
|
if (!GameConstants.Animation.IsAnimationEventBasedAbility(ability.animationType))
|
|
{
|
|
abilityExecution.Invoke();
|
|
}
|
|
|
|
isCasting = false;
|
|
|
|
if (!ability.castableWhileMoving)
|
|
{
|
|
movementSpeedModifier.ToggleCastPenalty(false);
|
|
}
|
|
}
|
|
|
|
private IEnumerator Channeling(BaseAbility channeledAbility, Action abilityChannelExecution)
|
|
{
|
|
isCasting = true;
|
|
|
|
// For channeled abilities, you might want different behavior
|
|
// This maintains the original channeling logic
|
|
CastBarHandler.Instance.ShowChannelingBar(channeledAbility, abilityChannelExecution);
|
|
playerMovement.InstantFaceCast(projectileSpawnLocationController.GetLookat());
|
|
abilityChannelExecution.Invoke();
|
|
|
|
if (!channeledAbility.castableWhileMoving)
|
|
{
|
|
movementSpeedModifier.ToggleCastPenalty(true);
|
|
}
|
|
|
|
yield return null;
|
|
}
|
|
|
|
public void ResetChannelingCast()
|
|
{
|
|
isCasting = false;
|
|
movementSpeedModifier.ToggleCastPenalty(false);
|
|
}
|
|
|
|
public void ResetCastingOnMeleeAnimationEvent()
|
|
{
|
|
isCasting = false;
|
|
movementSpeedModifier.ToggleCastPenalty(false);
|
|
StopAllCoroutines();
|
|
}
|
|
|
|
|
|
} |