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 = true;
// 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)
{
if (showDebugLogs)
{
Debug.Log("βοΈ CombatSceneManager: Starting combat encounter...");
}
// Get team members from the game state
List teamMembers = GetCurrentTeamMembers();
if (teamMembers == null || teamMembers.Count == 0)
{
Debug.LogError("β No team members found! Cannot start combat.");
return;
}
// Initialize the combat session data
CombatDataTransfer.InitializeCombatSession(battleData, context, teamMembers);
if (showDebugLogs)
{
CombatDataTransfer.DebugLogSession();
}
// 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);
}
}