using UnityEngine; /// /// Integration manager that connects TravelEventSystem with CombatEventPopup /// Handles the choice between battle and escape when combat events occur /// public class CombatEventIntegration : MonoBehaviour { [Header("Combat Popup Integration")] [Tooltip("Use either the original CombatEventPopup or the new CombatEventPopupUXML")] public CombatEventPopup combatEventPopup; // Original popup (legacy) public CombatEventPopupUXML combatEventPopupUXML; // New UXML-based popup public GameObject combatPopupPrefab; // Optional: if popup component not already in scene // Component references private TravelEventSystem travelEventSystem; private TravelEventUI eventUI; private TeamTravelSystem teamTravelSystem; // Current combat state private bool isHandlingCombat = false; private CombatTravelEvent currentCombatEvent; // Store reference to the current combat event void Start() { Debug.Log("🔧 Combat Event Integration starting..."); // Find required components - try same GameObject first, then search scene travelEventSystem = GetComponent(); if (travelEventSystem == null) travelEventSystem = FindFirstObjectByType(); eventUI = FindFirstObjectByType(); teamTravelSystem = FindFirstObjectByType(); if (travelEventSystem == null) { Debug.LogError("❌ Combat Event Integration requires TravelEventSystem in the scene!"); Debug.LogError(" Please ensure you have a GameObject with TravelEventSystem component."); enabled = false; return; } else if (GetComponent() == null) { Debug.LogWarning("⚠️ CombatEventIntegration is not on the same GameObject as TravelEventSystem."); Debug.LogWarning(" Consider moving it to the TravelEventSystem GameObject for better organization."); } // Try to find existing popup components first if (combatEventPopup == null) combatEventPopup = FindFirstObjectByType(); if (combatEventPopupUXML == null) combatEventPopupUXML = FindFirstObjectByType(); // If no popup component found and we have a prefab, instantiate it if (combatEventPopup == null && combatEventPopupUXML == null && combatPopupPrefab != null) { Debug.Log("📦 Instantiating combat popup from prefab..."); GameObject popupInstance = Instantiate(combatPopupPrefab); combatEventPopup = popupInstance.GetComponent(); combatEventPopupUXML = popupInstance.GetComponent(); if (combatEventPopup == null && combatEventPopupUXML == null) { Debug.LogError("❌ Combat popup prefab does not contain CombatEventPopup or CombatEventPopupUXML component!"); enabled = false; return; } } if (combatEventPopup == null && combatEventPopupUXML == null) { Debug.LogError("❌ Combat Event Integration requires a CombatEventPopup or CombatEventPopupUXML component!"); Debug.LogError(" Either add one of these components to a GameObject in the scene,"); Debug.LogError(" or assign a prefab with one of these components to combatPopupPrefab field."); enabled = false; return; } // Setup combat popup callbacks if (combatEventPopup != null) combatEventPopup.OnCombatDecision += HandleCombatDecision; if (combatEventPopupUXML != null) combatEventPopupUXML.OnCombatDecision += HandleCombatDecision; Debug.Log("✅ Combat Event Integration initialized successfully"); } void OnDestroy() { if (combatEventPopup != null) combatEventPopup.OnCombatDecision -= HandleCombatDecision; if (combatEventPopupUXML != null) combatEventPopupUXML.OnCombatDecision -= HandleCombatDecision; } /// /// Call this method when a combat event occurs to show the popup /// This should be called from TravelEventTypes.cs in the ExecuteEvent method /// public void ShowCombatChoicePopup(BattleEventData battleData, TravelEventContext context, string eventDescription, CombatTravelEvent combatEvent = null) { if (isHandlingCombat || battleData == null) return; Debug.Log($"🎭 Showing combat choice popup: {eventDescription}"); isHandlingCombat = true; currentCombatEvent = combatEvent; // Store reference to the original combat event // Store battle data for later use currentBattleData = battleData; currentContext = context; // Show combat popup - try UXML version first, then fallback to original if (combatEventPopupUXML != null) { Debug.Log("Using UXML-based combat popup"); combatEventPopupUXML.OnCombatDecision = HandleCombatDecision; combatEventPopupUXML.ShowCombatEncounter(battleData, context, eventDescription); } else if (combatEventPopup != null) { Debug.Log("Using original combat popup"); combatEventPopup.OnCombatDecision = HandleCombatDecision; combatEventPopup.ShowCombatEncounter(battleData, context, eventDescription); } else { Debug.LogError("No combat popup component assigned! Please assign either CombatEventPopup or CombatEventPopupUXML."); isHandlingCombat = false; } } // Store current battle data private BattleEventData currentBattleData; private TravelEventContext currentContext; /// /// Handle the player's combat decision from the popup /// private void HandleCombatDecision(bool chooseToAttack) { if (!isHandlingCombat || currentBattleData == null) return; isHandlingCombat = false; if (chooseToAttack) { HandleAttackChoice(); } else { HandleRunAwayChoice(); } // Clear stored data currentBattleData = null; currentContext = null; } /// /// Handle when player chooses to attack /// private void HandleAttackChoice() { Debug.Log("⚔️ Player chose to fight! Setting up battle..."); // Create and return the battle result that will start the battle var battleResult = EventResult.SimpleBattle( $"Your party prepares for battle against {currentBattleData.enemyCount} {currentBattleData.enemyType}!", currentBattleData.enemyCount, currentBattleData.enemyType ); // Copy over the enemy character data battleResult.battleData.enemyCharacterData = currentBattleData.enemyCharacterData; // Apply the battle result through the travel event system ApplyBattleResult(battleResult); } /// /// Handle when player chooses to run away /// private void HandleRunAwayChoice() { Debug.Log("🏃 Player chose to run away!"); EventResult escapeResult = null; // Use the combat event's escape handling if available if (currentCombatEvent != null) { Debug.Log($"🎯 Using escape configuration from {currentCombatEvent.eventName}"); escapeResult = currentCombatEvent.HandleEscapeAttempt(currentContext); } else { Debug.LogWarning("⚠️ No combat event reference - using hardcoded fallback escape handling"); // Hardcoded fallback values when no combat event is available const float fallbackSuccessChance = 0.75f; bool escapeSuccessful = Random.value <= fallbackSuccessChance; if (escapeSuccessful) { escapeResult = CreateFallbackSuccessfulEscape(); } else { escapeResult = CreateFallbackFailedEscape(); } } // Apply the escape result if (escapeResult != null) { ApplyBattleResult(escapeResult); } else { Debug.LogWarning("⚠️ Escape not allowed by combat event - forcing battle"); HandleAttackChoice(); } } /// /// Create fallback successful escape result when no combat event is available /// private EventResult CreateFallbackSuccessfulEscape() { string message = "Your party successfully escapes from the enemies!"; Debug.Log($"✅ Fallback escape successful: {message}"); return new EventResult(message) { shouldStopTravel = false, startBattle = false, eventOccurred = true, healthChange = 0 }; } /// /// Create fallback failed escape result when no combat event is available /// private EventResult CreateFallbackFailedEscape() { const int fallbackHealthPenalty = 5; // Hardcoded fallback value string message = $"The enemies catch up to your party! You take {fallbackHealthPenalty} damage while trying to escape."; Debug.Log($"❌ Fallback escape failed: {message}"); return new EventResult(message) { shouldStopTravel = true, startBattle = false, eventOccurred = true, healthChange = -fallbackHealthPenalty }; } /// /// Apply battle result through the travel event system /// private void ApplyBattleResult(EventResult result) { // Apply resource changes if (result.healthChange != 0) { Debug.Log($"❤️ Health changed by {result.healthChange}"); // TODO: Actually apply health changes to party } if (result.goldChange != 0) { Debug.Log($"💰 Gold changed by {result.goldChange}"); // TODO: Actually apply gold changes to party } // Handle travel stopping if (result.shouldStopTravel && teamTravelSystem != null) { teamTravelSystem.CancelJourney(); Debug.Log("🛑 Travel stopped due to event"); } // Handle battle start if (result.startBattle) { Debug.Log($"⚔️ Starting battle: {result.battleData.enemyCount} {result.battleData.enemyType}(s)"); // Use the new CombatSceneManager to handle battle transition MonoBehaviour combatSceneManager = FindCombatSceneManager(); if (combatSceneManager != null) { Debug.Log("🎬 Transitioning to battle scene with CombatSceneManager..."); // Use reflection to call StartCombatEncounter method var method = combatSceneManager.GetType().GetMethod("StartCombatEncounter"); if (method != null) { method.Invoke(combatSceneManager, new object[] { result.battleData, currentContext }); } else { Debug.LogError("❌ StartCombatEncounter method not found on CombatSceneManager"); HandleLegacyBattleStart(result.battleData); } } else { Debug.LogWarning("⚠️ CombatSceneManager not found! Looking for alternative battle systems..."); // Fallback to legacy battle system if available HandleLegacyBattleStart(result.battleData); } if (result.battleData.enemyCharacterData != null) { Debug.Log($"🎯 Using enemy data: {result.battleData.enemyCharacterData.enemyName}"); Debug.Log($"📊 Enemy stats: HP={result.battleData.enemyCharacterData.maxHealth}, " + $"AC={result.battleData.enemyCharacterData.armorClass}, " + $"Threat={result.battleData.enemyCharacterData.threatLevel}"); } } } /// /// Check if the system is currently handling a combat choice /// public bool IsHandlingCombat => isHandlingCombat; /// /// Cancel current combat handling (for cleanup) /// public void CancelCombatHandling() { if (isHandlingCombat) { isHandlingCombat = false; currentBattleData = null; currentContext = null; if (combatEventPopup != null) combatEventPopup.ForceClose(); } } /// /// Handle legacy battle start when CombatSceneManager is not available /// private void HandleLegacyBattleStart(BattleEventData battleData) { Debug.Log("🔧 Using legacy battle system..."); // Try to find and use existing battle systems var enhancedEventSystem = FindFirstObjectByType(); if (enhancedEventSystem != null) { Debug.Log("📞 Delegating to EnhancedTravelEventSystem"); // This system should have methods to handle battle setup } else { Debug.Log("📝 Logging battle setup for manual handling"); Debug.Log($"⚔️ Battle Setup Required:"); Debug.Log($" - Enemies: {battleData.enemyCount}x {battleData.enemyType}"); if (battleData.enemyCharacterData != null) { Debug.Log($" - Enemy Data: {battleData.enemyCharacterData.enemyName}"); Debug.Log($" - Enemy HP: {battleData.enemyCharacterData.maxHealth}"); Debug.Log($" - Enemy AC: {battleData.enemyCharacterData.armorClass}"); } } } /// /// Find CombatSceneManager using reflection to avoid compilation issues /// private MonoBehaviour FindCombatSceneManager() { // First try to find it by component type name var allComponents = FindObjectsByType(FindObjectsSortMode.None); var combatSceneManager = System.Array.Find(allComponents, comp => comp.GetType().Name == "CombatSceneManager"); return combatSceneManager; } }