| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424 |
- using UnityEngine;
- using UnityEngine.SceneManagement;
- using System.Collections.Generic;
- using System.Collections;
- /// <summary>
- /// Manages the transition from travel events to battle scenes
- /// Handles terrain setup, team data transfer, and battle initialization
- /// </summary>
- 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<CombatDataTransfer.CombatSessionData> 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<BFMTerrainGenerator>();
- }
- }
- /// <summary>
- /// Start a combat encounter by transitioning to the battle scene
- /// </summary>
- public void StartCombatEncounter(BattleEventData battleData, TravelEventContext context)
- {
- // Get team members from the game state
- List<TeamCharacter> 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());
- }
- /// <summary>
- /// Get current team members from various sources
- /// </summary>
- private List<TeamCharacter> GetCurrentTeamMembers()
- {
- List<TeamCharacter> teamMembers = new List<TeamCharacter>();
- // Method 1: Try MainTeamSelectScript first (if available)
- var teamSelectScript = FindFirstObjectByType<MainTeamSelectScript>();
- 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<string>();
- 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<string>();
- 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;
- }
- /// <summary>
- /// Coroutine to handle battle scene loading
- /// </summary>
- 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());
- }
- /// <summary>
- /// Set up the battle terrain based on the combat session data
- /// </summary>
- 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<BFMTerrainGenerator>();
- }
- 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<MonoBehaviour>() != 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}");
- }
- }
- /// <summary>
- /// Convert TerrainType to BFMTerrainType for battle field generation
- /// </summary>
- 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
- };
- }
- /// <summary>
- /// Check if a scene exists in build settings
- /// </summary>
- 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;
- }
- /// <summary>
- /// End the current combat session and return to the map
- /// </summary>
- 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());
- }
- /// <summary>
- /// Return to the map scene after combat
- /// </summary>
- 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!");
- }
- }
- /// <summary>
- /// Get current battle context for UI display
- /// </summary>
- 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)";
- }
- /// <summary>
- /// Convert time of day to readable description
- /// </summary>
- private string GetTimeDescription(float timeOfDay)
- {
- return timeOfDay switch
- {
- >= 6f and < 12f => "morning",
- >= 12f and < 18f => "afternoon",
- >= 18f and < 22f => "evening",
- _ => "night"
- };
- }
- /// <summary>
- /// Debug method to manually start a test combat
- /// </summary>
- [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);
- }
- }
|