Files
AppleHillsProduction/Assets/Scripts/Minigames/Airplane/Abilities/DropAbility.cs
2025-12-18 12:09:58 +01:00

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
}
}