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;
}
}