Files
AppleHillsProduction/Assets/Scripts/Minigames/FortFight/Projectiles/VacuumProjectile.cs
2025-12-16 19:42:48 +01:00

131 lines
4.8 KiB
C#

using Core;
using Core.Settings;
using UnityEngine;
namespace Minigames.FortFight.Projectiles
{
/// <summary>
/// Vacuum projectile - high mass, slides along ground after landing.
/// Maintains normal physics until it hits the ground layer, then activates sliding mode.
/// While sliding, destroys blocks it encounters.
/// </summary>
public class VacuumProjectile : ProjectileBase
{
private bool isSliding = false;
private int blocksDestroyed = 0;
private int maxBlocksToDestroy = 3;
private Vector2 slideDirection;
protected override void OnHit(Collision2D collision)
{
// Get settings once for all checks
var settings = GameManager.GetSettingsObject<IFortFightSettings>();
// If already sliding, handle block destruction
if (isSliding)
{
var block = collision.gameObject.GetComponent<Fort.FortBlock>();
if (block != null)
{
// Spawn impact effect on each block hit
SpawnImpactEffect(collision.contacts[0].point);
// Get damage from settings
float blockDamage = settings?.VacuumBlockDamage ?? 999f;
// Deal high damage to destroy block instantly
block.TakeDamage(blockDamage);
blocksDestroyed++;
Logging.Debug($"[VacuumProjectile] Destroyed block {blocksDestroyed}/{maxBlocksToDestroy}");
if (blocksDestroyed >= maxBlocksToDestroy)
{
Logging.Debug("[VacuumProjectile] Destroyed max blocks - stopping");
DestroyProjectile();
}
}
// Don't destroy - keep sliding
return;
}
// Check if we hit the ground layer to activate sliding
int groundLayer = settings?.GroundLayer ?? 0;
if (collision.gameObject.layer == groundLayer)
{
// Hit ground - start sliding behavior
SpawnImpactEffect(collision.contacts[0].point);
Logging.Debug($"[VacuumProjectile] Hit ground (layer {groundLayer}) - starting slide");
StartSliding();
// Don't destroy - keep sliding
return;
}
// Hit something else (fort block, etc.) while not sliding - use normal projectile behavior
Logging.Debug($"[VacuumProjectile] Hit {collision.gameObject.name} (layer {collision.gameObject.layer}) - normal impact");
// Deal damage if it's a fort block
var hitBlock = collision.gameObject.GetComponent<Fort.FortBlock>();
if (hitBlock != null)
{
hitBlock.TakeDamage(Damage);
SpawnImpactEffect(collision.contacts[0].point);
}
// Normal projectile destruction
DestroyProjectile();
}
/// <summary>
/// Start sliding behavior after hitting ground surface
/// </summary>
private void StartSliding()
{
if (isSliding) return;
isSliding = true;
// Get settings
var settings = GameManager.GetSettingsObject<IFortFightSettings>();
if (settings != null)
{
maxBlocksToDestroy = settings.VacuumDestroyBlockCount;
}
// Determine slide direction based on horizontal velocity (preserve launch direction)
if (rb2D != null)
{
slideDirection = rb2D.linearVelocity.x >= 0 ? Vector2.right : Vector2.left;
rb2D.gravityScale = 0f;
rb2D.linearVelocity = Vector2.zero; // Stop all momentum
Logging.Debug($"[VacuumProjectile] Started sliding in direction: {slideDirection}");
}
}
private void FixedUpdate()
{
if (isSliding && rb2D != null)
{
// Set constant velocity in slide direction
var settings = GameManager.GetSettingsObject<IFortFightSettings>();
float slideSpeed = settings?.VacuumSlideSpeed ?? 10f;
rb2D.linearVelocity = slideDirection * slideSpeed;
}
}
/// <summary>
/// Clean up when destroyed
/// </summary>
protected override void DestroyProjectile()
{
isSliding = false;
base.DestroyProjectile();
}
}
}