diff --git a/Assets/Scripts/Minigames/FortFight/AI/FortFightAIController.cs b/Assets/Scripts/Minigames/FortFight/AI/FortFightAIController.cs index 840ab5e9..424d7598 100644 --- a/Assets/Scripts/Minigames/FortFight/AI/FortFightAIController.cs +++ b/Assets/Scripts/Minigames/FortFight/AI/FortFightAIController.cs @@ -454,6 +454,12 @@ namespace Minigames.FortFight.AI return; } + // Subscribe to projectile launch for TrashBag detonation + if (_selectedAmmo == ProjectileType.TrashBag) + { + aiSlingshot.OnProjectileLaunched += HandleTrashBagLaunched; + } + // Fire projectile using velocity-based launch (proper ballistic physics) aiSlingshot.LaunchWithVelocity(launchVelocity); @@ -466,6 +472,68 @@ namespace Minigames.FortFight.AI Logging.Debug($"[FortFightAIController] Shot executed: {_selectedAmmo} with velocity {launchVelocity}"); } + /// + /// Handle TrashBag launch - calculate and trigger detonation at strategic point + /// + private void HandleTrashBagLaunched(Projectiles.ProjectileBase projectile) + { + // Unsubscribe immediately + aiSlingshot.OnProjectileLaunched -= HandleTrashBagLaunched; + + var trashBag = projectile as Projectiles.TrashBagProjectile; + if (trashBag == null) + { + Logging.Warning("[FortFightAIController] Launched projectile is not a TrashBag!"); + return; + } + + // Calculate detonation distance based on difficulty + float detonationDistance = Random.Range( + _currentDifficultyData.trashBagDetonationDistanceMin, + _currentDifficultyData.trashBagDetonationDistanceMax + ); + + // Calculate total trajectory distance + float trajectoryDistance = Vector2.Distance(aiSlingshot.transform.position, _targetPosition); + + // Convert normalized distance from target to world distance + // detonationDistance is FROM target, so detonation point is at (1 - detonationDistance) along trajectory + float detonationPointNormalized = 1f - detonationDistance; + float worldDetonationDistance = trajectoryDistance * detonationPointNormalized; + + Logging.Debug($"[FortFightAIController] TrashBag detonation planned: {detonationDistance:F2} from target ({worldDetonationDistance:F1} world units from launch)"); + + // Start monitoring for detonation + StartCoroutine(MonitorTrashBagDetonation(trashBag, worldDetonationDistance)); + } + + /// + /// Monitor TrashBag distance and trigger detonation at calculated point + /// + private IEnumerator MonitorTrashBagDetonation(Projectiles.TrashBagProjectile trashBag, float targetDistance) + { + Vector2 launchPosition = aiSlingshot.transform.position; + + // Wait a brief moment for projectile to get airborne + yield return new WaitForSeconds(0.1f); + + // Monitor distance traveled + while (trashBag != null && !trashBag.AbilityActivated) + { + float distanceTraveled = Vector2.Distance(launchPosition, trashBag.transform.position); + + // Check if we've reached or passed the detonation point + if (distanceTraveled >= targetDistance) + { + Logging.Debug($"[FortFightAIController] Detonating TrashBag at distance {distanceTraveled:F1} (target: {targetDistance:F1})"); + trashBag.ActivateAbility(); + yield break; + } + + yield return new WaitForFixedUpdate(); + } + } + #endregion #region Debug Visualization diff --git a/Assets/Scripts/Minigames/FortFight/Core/FortFightSettings.cs b/Assets/Scripts/Minigames/FortFight/Core/FortFightSettings.cs index c51b3fe9..629d2cdb 100644 --- a/Assets/Scripts/Minigames/FortFight/Core/FortFightSettings.cs +++ b/Assets/Scripts/Minigames/FortFight/Core/FortFightSettings.cs @@ -32,9 +32,9 @@ namespace Minigames.FortFight.Core [Tooltip("AI behavior parameters for each difficulty level")] [SerializeField] private List aiDifficultyConfigs = new List { - new AIDifficultyConfig { difficulty = AIDifficulty.Easy, data = new AIDifficultyData(45f, 0.3f, 0.5f, 2f) }, // ±45° angle, ±30% force, 0.5-2s think time - new AIDifficultyConfig { difficulty = AIDifficulty.Medium, data = new AIDifficultyData(30f, 0.2f, 0.5f, 2f) }, // ±30° angle, ±20% force, 0.5-2s think time - new AIDifficultyConfig { difficulty = AIDifficulty.Hard, data = new AIDifficultyData(10f, 0.1f, 0.5f, 2f) } // ±10° angle, ±10% force, 0.5-2s think time + new AIDifficultyConfig { difficulty = AIDifficulty.Easy, data = new AIDifficultyData(45f, 0.3f, 0.5f, 2f, 0.3f, 0.5f) }, // ±45° angle, ±30% force, 0.5-2s think, trash detonate 0.3-0.5 from target + new AIDifficultyConfig { difficulty = AIDifficulty.Medium, data = new AIDifficultyData(30f, 0.2f, 0.5f, 2f, 0.2f, 0.4f) }, // ±30° angle, ±20% force, 0.5-2s think, trash detonate 0.2-0.4 from target + new AIDifficultyConfig { difficulty = AIDifficulty.Hard, data = new AIDifficultyData(10f, 0.1f, 0.5f, 2f, 0.1f, 0.5f) } // ±10° angle, ±10% force, 0.5-2s think, trash detonate 0.1-0.5 from target }; [Tooltip("Default AI difficulty level for single-player games")] diff --git a/Assets/Scripts/Minigames/FortFight/Data/AIDifficultyData.cs b/Assets/Scripts/Minigames/FortFight/Data/AIDifficultyData.cs index 7b26c773..48937f35 100644 --- a/Assets/Scripts/Minigames/FortFight/Data/AIDifficultyData.cs +++ b/Assets/Scripts/Minigames/FortFight/Data/AIDifficultyData.cs @@ -22,15 +22,25 @@ namespace Minigames.FortFight.Data [Tooltip("Maximum thinking time in seconds")] public float thinkTimeMax; + [Header("TrashBag Detonation")] + [Tooltip("Minimum detonation distance from target (0-1, normalized along trajectory)")] + public float trashBagDetonationDistanceMin; + + [Tooltip("Maximum detonation distance from target (0-1, normalized along trajectory)")] + public float trashBagDetonationDistanceMax; + /// /// Create AI difficulty data with specified parameters /// - public AIDifficultyData(float angleDeviation, float forceDeviation, float thinkTimeMin, float thinkTimeMax) + public AIDifficultyData(float angleDeviation, float forceDeviation, float thinkTimeMin, float thinkTimeMax, + float trashBagDetonationDistanceMin = 0.2f, float trashBagDetonationDistanceMax = 0.4f) { this.angleDeviation = angleDeviation; this.forceDeviation = forceDeviation; this.thinkTimeMin = thinkTimeMin; this.thinkTimeMax = thinkTimeMax; + this.trashBagDetonationDistanceMin = trashBagDetonationDistanceMin; + this.trashBagDetonationDistanceMax = trashBagDetonationDistanceMax; } }