131 lines
4.8 KiB
C#
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();
|
|
}
|
|
}
|
|
}
|
|
|