Fix weapon selection issues and shot tracking
This commit is contained in:
@@ -220,6 +220,34 @@ namespace Minigames.FortFight.Core
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Select the first available (non-cooldown) ammo for a player.
|
||||||
|
/// Called at the start of each turn to reset selection.
|
||||||
|
/// </summary>
|
||||||
|
public bool SelectFirstAvailableAmmo(int playerIndex)
|
||||||
|
{
|
||||||
|
if (!_playerStates.ContainsKey(playerIndex))
|
||||||
|
{
|
||||||
|
Logging.Warning($"[AmmunitionManager] Player {playerIndex} state not found!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var configs = AvailableConfigs;
|
||||||
|
foreach (var config in configs)
|
||||||
|
{
|
||||||
|
if (IsAmmoAvailable(config.projectileType, playerIndex))
|
||||||
|
{
|
||||||
|
return SelectAmmo(config.projectileType, playerIndex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: select default even if on cooldown (shouldn't happen in normal gameplay)
|
||||||
|
Logging.Warning($"[AmmunitionManager] Player {playerIndex}: No ammo available! Falling back to default.");
|
||||||
|
_playerStates[playerIndex].SelectedAmmo = defaultProjectileType;
|
||||||
|
OnAmmoSelected?.Invoke(defaultProjectileType, playerIndex);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Get currently selected projectile type for a specific player
|
/// Get currently selected projectile type for a specific player
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using AppleHills.Core.Settings;
|
using Core;
|
||||||
using Core;
|
|
||||||
using Core.Settings;
|
using Core.Settings;
|
||||||
using Minigames.FortFight.Data;
|
using Minigames.FortFight.Data;
|
||||||
using Minigames.FortFight.Projectiles;
|
using Minigames.FortFight.Projectiles;
|
||||||
@@ -13,14 +12,14 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class ProjectileTurnAction
|
public class ProjectileTurnAction
|
||||||
{
|
{
|
||||||
private SlingshotController slingshot;
|
private SlingshotController _slingshot;
|
||||||
private AmmunitionManager ammoManager;
|
private AmmunitionManager _ammoManager;
|
||||||
private CameraController cameraController;
|
private CameraController _cameraController;
|
||||||
private int playerIndex;
|
private int _playerIndex;
|
||||||
private ProjectileBase activeProjectile;
|
private ProjectileBase _activeProjectile;
|
||||||
private bool launchComplete = false;
|
private bool _launchComplete = false;
|
||||||
private bool projectileSettled = false;
|
private bool _projectileSettled = false;
|
||||||
private float settleTimer = 0f;
|
private float _settleTimer = 0f;
|
||||||
|
|
||||||
private IFortFightSettings _cachedSettings;
|
private IFortFightSettings _cachedSettings;
|
||||||
private IFortFightSettings CachedSettings
|
private IFortFightSettings CachedSettings
|
||||||
@@ -35,14 +34,14 @@ namespace Minigames.FortFight.Core
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsComplete => projectileSettled;
|
public bool IsComplete => _projectileSettled;
|
||||||
|
|
||||||
public ProjectileTurnAction(SlingshotController slingshot, AmmunitionManager ammoManager, CameraController cameraController, int playerIndex)
|
public ProjectileTurnAction(SlingshotController slingshot, AmmunitionManager ammoManager, CameraController cameraController, int playerIndex)
|
||||||
{
|
{
|
||||||
this.slingshot = slingshot;
|
this._slingshot = slingshot;
|
||||||
this.ammoManager = ammoManager;
|
this._ammoManager = ammoManager;
|
||||||
this.cameraController = cameraController;
|
this._cameraController = cameraController;
|
||||||
this.playerIndex = playerIndex;
|
this._playerIndex = playerIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -53,12 +52,12 @@ namespace Minigames.FortFight.Core
|
|||||||
Logging.Debug("[ProjectileTurnAction] Executing - enabling slingshot");
|
Logging.Debug("[ProjectileTurnAction] Executing - enabling slingshot");
|
||||||
|
|
||||||
// Enable slingshot
|
// Enable slingshot
|
||||||
if (slingshot != null)
|
if (_slingshot != null)
|
||||||
{
|
{
|
||||||
slingshot.Enable();
|
_slingshot.Enable();
|
||||||
|
|
||||||
// Subscribe to launch event
|
// Subscribe to launch event
|
||||||
slingshot.OnProjectileLaunched += HandleProjectileLaunched;
|
_slingshot.OnProjectileLaunched += HandleProjectileLaunched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,28 +66,28 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Update()
|
public void Update()
|
||||||
{
|
{
|
||||||
if (!launchComplete) return;
|
if (!_launchComplete) return;
|
||||||
|
|
||||||
// Check if projectile is destroyed or stopped
|
// Check if projectile is destroyed or stopped
|
||||||
if (activeProjectile == null)
|
if (_activeProjectile == null)
|
||||||
{
|
{
|
||||||
// Projectile destroyed - start settle timer
|
// Projectile destroyed - start settle timer
|
||||||
if (settleTimer == 0f)
|
if (_settleTimer == 0f)
|
||||||
{
|
{
|
||||||
Logging.Debug("[ProjectileTurnAction] Projectile destroyed - starting settle timer");
|
Logging.Debug("[ProjectileTurnAction] Projectile destroyed - starting settle timer");
|
||||||
}
|
}
|
||||||
|
|
||||||
settleTimer += Time.deltaTime;
|
_settleTimer += Time.deltaTime;
|
||||||
|
|
||||||
float settleDelay = CachedSettings?.ProjectileSettleDelay ?? 2.5f;
|
float settleDelay = CachedSettings?.ProjectileSettleDelay ?? 2.5f;
|
||||||
if (settleTimer >= settleDelay)
|
if (_settleTimer >= settleDelay)
|
||||||
{
|
{
|
||||||
projectileSettled = true;
|
_projectileSettled = true;
|
||||||
|
|
||||||
// Stop camera tracking when projectile settles
|
// Stop camera tracking when projectile settles
|
||||||
if (cameraController != null)
|
if (_cameraController != null)
|
||||||
{
|
{
|
||||||
cameraController.StopFollowingProjectile();
|
_cameraController.StopFollowingProjectile();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.Debug("[ProjectileTurnAction] Turn action complete");
|
Logging.Debug("[ProjectileTurnAction] Turn action complete");
|
||||||
@@ -97,20 +96,20 @@ namespace Minigames.FortFight.Core
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Check if projectile has stopped moving
|
// Check if projectile has stopped moving
|
||||||
Rigidbody2D rb = activeProjectile.GetComponent<Rigidbody2D>();
|
Rigidbody2D rb = _activeProjectile.GetComponent<Rigidbody2D>();
|
||||||
if (rb != null && rb.linearVelocity.magnitude < 0.5f)
|
if (rb != null && rb.linearVelocity.magnitude < 0.5f)
|
||||||
{
|
{
|
||||||
settleTimer += Time.deltaTime;
|
_settleTimer += Time.deltaTime;
|
||||||
|
|
||||||
float settleDelay = CachedSettings?.ProjectileSettleDelay ?? 2.5f;
|
float settleDelay = CachedSettings?.ProjectileSettleDelay ?? 2.5f;
|
||||||
if (settleTimer >= settleDelay)
|
if (_settleTimer >= settleDelay)
|
||||||
{
|
{
|
||||||
projectileSettled = true;
|
_projectileSettled = true;
|
||||||
|
|
||||||
// Stop camera tracking when projectile settles
|
// Stop camera tracking when projectile settles
|
||||||
if (cameraController != null)
|
if (_cameraController != null)
|
||||||
{
|
{
|
||||||
cameraController.StopFollowingProjectile();
|
_cameraController.StopFollowingProjectile();
|
||||||
}
|
}
|
||||||
|
|
||||||
Logging.Debug("[ProjectileTurnAction] Projectile settled - turn action complete");
|
Logging.Debug("[ProjectileTurnAction] Projectile settled - turn action complete");
|
||||||
@@ -119,7 +118,7 @@ namespace Minigames.FortFight.Core
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Reset settle timer if still moving
|
// Reset settle timer if still moving
|
||||||
settleTimer = 0f;
|
_settleTimer = 0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -129,10 +128,10 @@ namespace Minigames.FortFight.Core
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Cancel()
|
public void Cancel()
|
||||||
{
|
{
|
||||||
if (slingshot != null)
|
if (_slingshot != null)
|
||||||
{
|
{
|
||||||
slingshot.Disable();
|
_slingshot.Disable();
|
||||||
slingshot.OnProjectileLaunched -= HandleProjectileLaunched;
|
_slingshot.OnProjectileLaunched -= HandleProjectileLaunched;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,26 +139,47 @@ namespace Minigames.FortFight.Core
|
|||||||
{
|
{
|
||||||
Logging.Debug($"[ProjectileTurnAction] Projectile launched: {projectile.gameObject.name}");
|
Logging.Debug($"[ProjectileTurnAction] Projectile launched: {projectile.gameObject.name}");
|
||||||
|
|
||||||
launchComplete = true;
|
_launchComplete = true;
|
||||||
activeProjectile = projectile;
|
_activeProjectile = projectile;
|
||||||
|
|
||||||
// Disable slingshot after launch
|
// Disable slingshot after launch
|
||||||
if (slingshot != null)
|
if (_slingshot != null)
|
||||||
{
|
{
|
||||||
slingshot.Disable();
|
_slingshot.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Trigger cooldown for used ammo for this player
|
// Trigger cooldown for used ammo for this player
|
||||||
if (ammoManager != null)
|
if (_ammoManager != null)
|
||||||
{
|
{
|
||||||
ProjectileType usedAmmoType = ammoManager.GetSelectedAmmoType(playerIndex);
|
ProjectileType usedAmmoType = _ammoManager.GetSelectedAmmoType(_playerIndex);
|
||||||
ammoManager.UseAmmo(usedAmmoType, playerIndex);
|
_ammoManager.UseAmmo(usedAmmoType, _playerIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if this is a TrashBag projectile to handle explosion tracking
|
||||||
|
var trashBag = projectile as TrashBagProjectile;
|
||||||
|
if (trashBag != null)
|
||||||
|
{
|
||||||
|
trashBag.OnTrashPiecesSpawned += HandleTrashPiecesSpawned;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start camera tracking the projectile
|
// Start camera tracking the projectile
|
||||||
if (cameraController != null && projectile != null)
|
if (_cameraController != null && projectile != null)
|
||||||
{
|
{
|
||||||
cameraController.StartFollowingProjectile(projectile.transform);
|
_cameraController.StartFollowingProjectile(projectile.transform);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Handle trash bag explosion - switch camera to follow a trash piece
|
||||||
|
/// </summary>
|
||||||
|
private void HandleTrashPiecesSpawned(Transform trashPiece)
|
||||||
|
{
|
||||||
|
if (trashPiece != null && _cameraController != null)
|
||||||
|
{
|
||||||
|
Logging.Debug($"[ProjectileTurnAction] TrashBag exploded - switching camera to trash piece");
|
||||||
|
_cameraController.StartFollowingProjectile(trashPiece);
|
||||||
|
|
||||||
|
// The turn will complete when the trash piece settles (using existing settle logic)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -210,9 +210,12 @@ namespace Minigames.FortFight.Core
|
|||||||
// Set slingshot owner (used for projectile ownership tracking)
|
// Set slingshot owner (used for projectile ownership tracking)
|
||||||
activeSlingshot.SetOwner(_currentPlayer.PlayerIndex, _currentPlayer.IsAI);
|
activeSlingshot.SetOwner(_currentPlayer.PlayerIndex, _currentPlayer.IsAI);
|
||||||
|
|
||||||
// Set current ammo on slingshot for this player
|
// Reset ammo selection to first available weapon at start of turn
|
||||||
if (AmmunitionManager.Instance != null)
|
if (AmmunitionManager.Instance != null)
|
||||||
{
|
{
|
||||||
|
AmmunitionManager.Instance.SelectFirstAvailableAmmo(_currentPlayer.PlayerIndex);
|
||||||
|
|
||||||
|
// Set the selected ammo on slingshot
|
||||||
ProjectileConfig currentAmmo = AmmunitionManager.Instance.GetSelectedAmmoConfig(_currentPlayer.PlayerIndex);
|
ProjectileConfig currentAmmo = AmmunitionManager.Instance.GetSelectedAmmoConfig(_currentPlayer.PlayerIndex);
|
||||||
if (currentAmmo != null)
|
if (currentAmmo != null)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
using System.Collections;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
using Core;
|
using Core;
|
||||||
using Core.Settings;
|
using Core.Settings;
|
||||||
using Input;
|
using Input;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using Random = UnityEngine.Random;
|
||||||
|
|
||||||
namespace Minigames.FortFight.Projectiles
|
namespace Minigames.FortFight.Projectiles
|
||||||
{
|
{
|
||||||
@@ -23,6 +25,12 @@ namespace Minigames.FortFight.Projectiles
|
|||||||
private bool inputEnabled = false;
|
private bool inputEnabled = false;
|
||||||
private bool hasExploded = false;
|
private bool hasExploded = false;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fired when trash bag explodes and spawns pieces.
|
||||||
|
/// Parameters: (Transform trashPieceToFollow) - a piece for camera to follow
|
||||||
|
/// </summary>
|
||||||
|
public event Action<Transform> OnTrashPiecesSpawned;
|
||||||
|
|
||||||
public override void Launch(Vector2 direction, float force)
|
public override void Launch(Vector2 direction, float force)
|
||||||
{
|
{
|
||||||
base.Launch(direction, force);
|
base.Launch(direction, force);
|
||||||
@@ -145,13 +153,14 @@ namespace Minigames.FortFight.Projectiles
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Spawn multiple trash pieces in a cone away from the hit surface.
|
/// Spawn multiple trash pieces in a cone away from the hit surface.
|
||||||
/// Uses hit normal + projectile momentum for realistic splash effect.
|
/// Uses hit normal + projectile momentum for realistic splash effect.
|
||||||
|
/// Returns the first spawned trash piece for camera tracking.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private void SpawnTrashPieces(Vector2 impactPoint, Vector2 hitNormal)
|
private Transform SpawnTrashPieces(Vector2 impactPoint, Vector2 hitNormal)
|
||||||
{
|
{
|
||||||
if (trashPiecePrefab == null)
|
if (trashPiecePrefab == null)
|
||||||
{
|
{
|
||||||
Logging.Warning("[TrashBagProjectile] No trash piece prefab assigned!");
|
Logging.Warning("[TrashBagProjectile] No trash piece prefab assigned!");
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get settings
|
// Get settings
|
||||||
@@ -175,6 +184,8 @@ namespace Minigames.FortFight.Projectiles
|
|||||||
// 70% normal (splash away from surface) + 30% reflection (maintain some momentum direction)
|
// 70% normal (splash away from surface) + 30% reflection (maintain some momentum direction)
|
||||||
Vector2 baseDirection = (hitNormal * 0.7f + reflectDirection * 0.3f).normalized;
|
Vector2 baseDirection = (hitNormal * 0.7f + reflectDirection * 0.3f).normalized;
|
||||||
|
|
||||||
|
Transform firstPiece = null;
|
||||||
|
|
||||||
// Spawn pieces in a cone around the base direction
|
// Spawn pieces in a cone around the base direction
|
||||||
for (int i = 0; i < pieceCount; i++)
|
for (int i = 0; i < pieceCount; i++)
|
||||||
{
|
{
|
||||||
@@ -189,6 +200,12 @@ namespace Minigames.FortFight.Projectiles
|
|||||||
Vector2 spawnOffset = pieceDirection * 0.2f; // Small offset to prevent clipping
|
Vector2 spawnOffset = pieceDirection * 0.2f; // Small offset to prevent clipping
|
||||||
GameObject piece = Instantiate(trashPiecePrefab, (Vector2)impactPoint + spawnOffset, Quaternion.identity);
|
GameObject piece = Instantiate(trashPiecePrefab, (Vector2)impactPoint + spawnOffset, Quaternion.identity);
|
||||||
|
|
||||||
|
// Store first piece for camera tracking
|
||||||
|
if (i == 0 && piece != null)
|
||||||
|
{
|
||||||
|
firstPiece = piece.transform;
|
||||||
|
}
|
||||||
|
|
||||||
// Setup trash piece physics
|
// Setup trash piece physics
|
||||||
Rigidbody2D pieceRb = piece.GetComponent<Rigidbody2D>();
|
Rigidbody2D pieceRb = piece.GetComponent<Rigidbody2D>();
|
||||||
if (pieceRb != null)
|
if (pieceRb != null)
|
||||||
@@ -203,6 +220,14 @@ namespace Minigames.FortFight.Projectiles
|
|||||||
|
|
||||||
Logging.Debug($"[TrashBagProjectile] Spawned trash piece {i} in direction {pieceDirection}");
|
Logging.Debug($"[TrashBagProjectile] Spawned trash piece {i} in direction {pieceDirection}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Fire event with first piece for camera tracking
|
||||||
|
if (firstPiece != null)
|
||||||
|
{
|
||||||
|
OnTrashPiecesSpawned?.Invoke(firstPiece);
|
||||||
|
}
|
||||||
|
|
||||||
|
return firstPiece;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region ITouchInputConsumer Implementation
|
#region ITouchInputConsumer Implementation
|
||||||
|
|||||||
Reference in New Issue
Block a user