122 lines
4.2 KiB
C#
122 lines
4.2 KiB
C#
using Core;
|
|
using UnityEngine;
|
|
|
|
namespace Minigames.Airplane.Abilities
|
|
{
|
|
/// <summary>
|
|
/// Drop Plane Ability: Press to drop straight down with strong downward force.
|
|
/// Sustained ability - active for up to N seconds, can be interrupted early.
|
|
/// Cooldown is proportional to usage time (full duration = N*2 cooldown).
|
|
/// Good for precision strikes on targets.
|
|
/// Configuration loaded from settings at runtime.
|
|
/// </summary>
|
|
public class DropAbility : BaseAirplaneAbility
|
|
{
|
|
#region Configuration
|
|
|
|
private readonly float dropForce;
|
|
private readonly bool zeroHorizontalVelocity;
|
|
private readonly float cooldownMultiplier;
|
|
|
|
#endregion
|
|
|
|
#region Constructor
|
|
|
|
/// <summary>
|
|
/// Create drop ability with configuration from settings.
|
|
/// </summary>
|
|
public DropAbility(string name, Sprite icon, float cooldown, float force, float maxActiveDuration, float cooldownMult, bool zeroHorizontal = true)
|
|
: base(name, icon, cooldown, reusable: true, activeDuration: maxActiveDuration)
|
|
{
|
|
dropForce = force;
|
|
zeroHorizontalVelocity = zeroHorizontal;
|
|
cooldownMultiplier = cooldownMult;
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region State
|
|
|
|
private float originalXVelocity;
|
|
|
|
#endregion
|
|
|
|
#region Override Methods
|
|
|
|
public override void Execute()
|
|
{
|
|
if (!ValidateAirplane()) return;
|
|
if (!CanActivate) return;
|
|
|
|
StartActivation();
|
|
|
|
var rb = currentAirplane.GetComponent<Rigidbody2D>();
|
|
if (rb != null)
|
|
{
|
|
// Store original velocity
|
|
originalXVelocity = rb.linearVelocity.x;
|
|
|
|
// Zero horizontal velocity if configured
|
|
if (zeroHorizontalVelocity)
|
|
{
|
|
rb.linearVelocity = new Vector2(0f, rb.linearVelocity.y);
|
|
}
|
|
|
|
// Apply strong downward force
|
|
rb.AddForce(Vector2.down * dropForce, ForceMode2D.Impulse);
|
|
}
|
|
|
|
if (showDebugLogs)
|
|
{
|
|
Logging.Debug($"[DropAbility] Activated - Force: {dropForce}, Max Duration: {maxActiveDuration}s");
|
|
}
|
|
}
|
|
|
|
public override void Deactivate()
|
|
{
|
|
if (!isActive) return;
|
|
|
|
// Restore horizontal velocity (optional)
|
|
if (currentAirplane != null)
|
|
{
|
|
var rb = currentAirplane.GetComponent<Rigidbody2D>();
|
|
if (rb != null && zeroHorizontalVelocity)
|
|
{
|
|
Vector2 currentVel = rb.linearVelocity;
|
|
rb.linearVelocity = new Vector2(originalXVelocity * 0.5f, currentVel.y); // Resume at reduced speed
|
|
}
|
|
}
|
|
|
|
if (showDebugLogs)
|
|
{
|
|
Logging.Debug($"[DropAbility] Deactivating after {activeDurationUsed:F2}s usage");
|
|
}
|
|
|
|
// Base.Deactivate() will call CalculateDynamicCooldown and start cooldown
|
|
base.Deactivate();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Calculate dynamic cooldown based on usage time.
|
|
/// Full duration (maxActiveDuration) = maxActiveDuration * cooldownMultiplier cooldown.
|
|
/// Partial usage = proportional cooldown.
|
|
/// </summary>
|
|
protected override float CalculateDynamicCooldown()
|
|
{
|
|
// Calculate proportional cooldown: usedTime * multiplier
|
|
// Example: 3s max, 2x multiplier -> full use = 6s cooldown, 1.5s use = 3s cooldown
|
|
float dynamicCooldown = activeDurationUsed * cooldownMultiplier;
|
|
|
|
if (showDebugLogs)
|
|
{
|
|
Logging.Debug($"[DropAbility] CalculateDynamicCooldown: used={activeDurationUsed:F2}s, multiplier={cooldownMultiplier}, result={dynamicCooldown:F2}s");
|
|
}
|
|
|
|
return dynamicCooldown;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|