using UnityEngine; using UnityEngine.SceneManagement; using System.Collections.Generic; using System.Collections; /// /// Manages the transition from travel events to battle scenes /// Handles terrain setup, team data transfer, and battle initialization /// public class CombatSceneManager : MonoBehaviour { [Header("Scene Management")] [Tooltip("Name of the battle scene to load")] public string battleSceneName = "BattleScene"; [Header("Terrain Generation")] [Tooltip("Reference to BFM Terrain Generator for battle field terrain")] public BFMTerrainGenerator terrainGenerator; [Header("Debug Settings")] public bool showDebugLogs = false; // Singleton instance public static CombatSceneManager Instance { get; private set; } // Events for other systems to hook into public System.Action OnCombatSessionStarted; public System.Action OnBattleSceneLoaded; private void Awake() { // Ensure singleton pattern if (Instance == null) { Instance = this; DontDestroyOnLoad(gameObject); } else { Destroy(gameObject); return; } } private void Start() { // Try to find terrain generator if not assigned if (terrainGenerator == null) { terrainGenerator = FindFirstObjectByType(); } } /// /// Start a combat encounter by transitioning to the battle scene /// public void StartCombatEncounter(BattleEventData battleData, TravelEventContext context) { // Get team members from the game state List teamMembers = GetCurrentTeamMembers(); if (teamMembers == null || teamMembers.Count == 0) { return; } // Initialize the combat session data CombatDataTransfer.InitializeCombatSession(battleData, context, teamMembers); // Populate legacy battle setup data for compatibility CombatDataTransfer.PopulateLegacyBattleSetupData(); // Notify listeners OnCombatSessionStarted?.Invoke(CombatDataTransfer.GetCurrentSession()); // Load the battle scene StartCoroutine(LoadBattleSceneCoroutine()); } /// /// Get current team members from various sources /// private List GetCurrentTeamMembers() { List teamMembers = new List(); // Method 1: Try MainTeamSelectScript first (if available) var teamSelectScript = FindFirstObjectByType(); if (teamSelectScript != null) { var characters = teamSelectScript.GetConfiguredCharacters(); if (characters != null && characters.Count > 0) { teamMembers.AddRange(characters); if (showDebugLogs) { Debug.Log($"πŸ“‹ Found {teamMembers.Count} team members from MainTeamSelectScript"); } return teamMembers; } } // Method 2: Try GameStateManager if (GameStateManager.Instance != null && GameStateManager.Instance.savedTeam != null) { foreach (var character in GameStateManager.Instance.savedTeam) { if (character != null) { teamMembers.Add(character); } } if (teamMembers.Count > 0) { if (showDebugLogs) { Debug.Log($"πŸ“‹ Found {teamMembers.Count} team members from GameStateManager"); } return teamMembers; } } // Method 3: Try loading from PlayerPrefs as fallback for (int i = 0; i < 4; i++) { string prefix = $"Character{i}_"; if (PlayerPrefs.HasKey(prefix + "Exists") && PlayerPrefs.GetInt(prefix + "Exists") == 1) { var character = new TeamCharacter(); character.name = PlayerPrefs.GetString(prefix + "Name", ""); character.isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1; character.strength = PlayerPrefs.GetInt(prefix + "Strength", 10); character.dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10); character.constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10); character.wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10); character.perception = PlayerPrefs.GetInt(prefix + "Perception", 10); character.gold = PlayerPrefs.GetInt(prefix + "Gold", 25); character.silver = PlayerPrefs.GetInt(prefix + "Silver", 0); character.copper = PlayerPrefs.GetInt(prefix + "Copper", 0); character.equippedWeapon = PlayerPrefs.GetString(prefix + "EquippedWeapon", ""); character.equippedArmor = PlayerPrefs.GetString(prefix + "EquippedArmor", ""); // Load weapon list using the same format as MainTeamSelectScript character.weapons = new List(); int weaponCount = PlayerPrefs.GetInt(prefix + "WeaponCount", 0); for (int j = 0; j < weaponCount; j++) { string weapon = PlayerPrefs.GetString(prefix + $"Weapon{j}", ""); if (!string.IsNullOrEmpty(weapon)) { character.weapons.Add(weapon); } } // Load armor list using the same format as MainTeamSelectScript character.armor = new List(); int armorCount = PlayerPrefs.GetInt(prefix + "ArmorCount", 0); for (int j = 0; j < armorCount; j++) { string armor = PlayerPrefs.GetString(prefix + $"Armor{j}", ""); if (!string.IsNullOrEmpty(armor)) { character.armor.Add(armor); } } // Debug the loaded character data if (showDebugLogs) { Debug.Log($"πŸ”§ Loaded character '{character.name}': equippedWeapon='{character.equippedWeapon}', weapons=[{string.Join(", ", character.weapons)}]"); } teamMembers.Add(character); } } if (teamMembers.Count > 0) { if (showDebugLogs) { Debug.Log($"πŸ“‹ Found {teamMembers.Count} team members from PlayerPrefs"); } } else { Debug.LogWarning("⚠️ No team members found in any data source!"); } return teamMembers; } /// /// Coroutine to handle battle scene loading /// private IEnumerator LoadBattleSceneCoroutine() { if (showDebugLogs) { Debug.Log($"🎬 Loading battle scene: {battleSceneName}"); } // Check if scene exists in build settings if (!IsSceneInBuildSettings(battleSceneName)) { Debug.LogError($"❌ Battle scene '{battleSceneName}' not found in Build Settings!"); yield break; } // Start loading the scene asynchronously AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(battleSceneName); // Wait for the scene to load while (!asyncLoad.isDone) { // You could update a loading bar here yield return null; } if (showDebugLogs) { Debug.Log("βœ… Battle scene loaded successfully"); } // Notify that the battle scene has loaded OnBattleSceneLoaded?.Invoke(); // Set up the terrain in the battle scene yield return StartCoroutine(SetupBattleTerrainCoroutine()); } /// /// Set up the battle terrain based on the combat session data /// private IEnumerator SetupBattleTerrainCoroutine() { // Wait a frame to ensure the scene is fully loaded yield return null; var session = CombatDataTransfer.GetCurrentSession(); if (session == null) { Debug.LogWarning("⚠️ No combat session data available for terrain setup"); yield break; } // Find or create terrain generator in the new scene if (terrainGenerator == null) { terrainGenerator = FindFirstObjectByType(); } if (terrainGenerator != null) { // Convert TerrainType to BFMTerrainType BFMTerrainType bfmTerrain = ConvertToBFMTerrainType(session.battleTerrain); if (showDebugLogs) { Debug.Log($"🌍 Setting battle terrain to: {bfmTerrain} (from {session.battleTerrain})"); } // Set the terrain type terrainGenerator.SetTerrainType(bfmTerrain); // Regenerate the terrain if there's a method for it if (terrainGenerator.GetComponent() != null) { // You might need to call a regeneration method here // terrainGenerator.RegenerateTerrain(); // If such method exists } } else { if (showDebugLogs) { Debug.LogWarning("⚠️ No BFMTerrainGenerator found in battle scene - terrain setup skipped"); } } // Log the battle setup information if (showDebugLogs) { string terrainDesc = CombatDataTransfer.GetTerrainDescription(session.battleTerrain, session.battleFeature); Debug.Log($"🎯 Battle setup complete: Fighting {terrainDesc}"); Debug.Log($"⏰ Time: {session.timeOfDay:F1}h, Weather: {session.weather}"); } } /// /// Convert TerrainType to BFMTerrainType for battle field generation /// private BFMTerrainType ConvertToBFMTerrainType(TerrainType terrainType) { return terrainType switch { TerrainType.Plains => BFMTerrainType.Plain, TerrainType.Forest => BFMTerrainType.Forest, TerrainType.Mountain => BFMTerrainType.Mountain, TerrainType.ForestRiver => BFMTerrainType.Forest, // Forest with river features _ => BFMTerrainType.Plain // Default to plains for other terrain types }; } /// /// Check if a scene exists in build settings /// private bool IsSceneInBuildSettings(string sceneName) { for (int i = 0; i < SceneManager.sceneCountInBuildSettings; i++) { string scenePath = UnityEngine.SceneManagement.SceneUtility.GetScenePathByBuildIndex(i); string sceneNameFromPath = System.IO.Path.GetFileNameWithoutExtension(scenePath); if (sceneNameFromPath.Equals(sceneName, System.StringComparison.OrdinalIgnoreCase)) { return true; } } return false; } /// /// End the current combat session and return to the map /// public void EndCombatSession(bool playerVictory) { if (showDebugLogs) { Debug.Log($"πŸ† Combat session ended - Player victory: {playerVictory}"); } // Clear the combat session data CombatDataTransfer.ClearSession(); // Return to the map scene // You might want to load "MapScene2" or whatever your main map scene is called StartCoroutine(ReturnToMapCoroutine()); } /// /// Return to the map scene after combat /// private IEnumerator ReturnToMapCoroutine() { yield return new WaitForSeconds(2f); // Brief delay for any end-of-combat UI string mapSceneName = "MapScene2"; // Adjust this to your actual map scene name if (IsSceneInBuildSettings(mapSceneName)) { if (showDebugLogs) { Debug.Log($"πŸ—ΊοΈ Returning to map scene: {mapSceneName}"); } SceneManager.LoadScene(mapSceneName); } else { Debug.LogError($"❌ Map scene '{mapSceneName}' not found in Build Settings!"); } } /// /// Get current battle context for UI display /// public string GetBattleContextDescription() { var session = CombatDataTransfer.GetCurrentSession(); if (session == null) return "Unknown battle"; string terrainDesc = CombatDataTransfer.GetTerrainDescription(session.battleTerrain, session.battleFeature); string timeDesc = GetTimeDescription(session.timeOfDay); string weatherDesc = session.weather.ToString().ToLower(); return $"Battle {terrainDesc} during {timeDesc} ({weatherDesc} weather)"; } /// /// Convert time of day to readable description /// private string GetTimeDescription(float timeOfDay) { return timeOfDay switch { >= 6f and < 12f => "morning", >= 12f and < 18f => "afternoon", >= 18f and < 22f => "evening", _ => "night" }; } /// /// Debug method to manually start a test combat /// [ContextMenu("Start Test Combat")] public void StartTestCombat() { // Create test battle data var testBattleData = new BattleEventData { enemyCount = 2, enemyType = "Test Bandit", battleDescription = "A test combat encounter" }; // Create test context var testContext = new TravelEventContext(Vector2Int.zero, null, null) { currentWeather = Weather.Clear, timeOfDay = 14f }; // Use fake tile data testContext.currentTile = new MapTile(0, 0) { terrainType = TerrainType.Plains, featureType = FeatureType.Road }; StartCombatEncounter(testBattleData, testContext); } }