EnhancedTravelEventSystem.cs 9.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296
  1. using UnityEngine;
  2. using System.Collections;
  3. /// <summary>
  4. /// Enhanced Travel Event System that provides player choice for combat encounters
  5. /// Integrates CombatEventPopup for better user experience
  6. /// </summary>
  7. public class EnhancedTravelEventSystem : MonoBehaviour
  8. {
  9. [Header("Enhanced Event System")]
  10. public CombatEventPopup combatEventPopup;
  11. public bool allowRunningAway = true;
  12. [Range(0f, 1f)]
  13. public float runAwaySuccessChance = 0.75f;
  14. public int runAwayHealthPenalty = 5;
  15. [Header("Run Away Messages")]
  16. [TextArea(2, 4)]
  17. public string[] successfulRunAwayMessages = {
  18. "Your party successfully escapes from the enemies!",
  19. "Quick thinking allows your party to avoid the confrontation!",
  20. "Your party slips away unnoticed by the enemies."
  21. };
  22. [TextArea(2, 4)]
  23. public string[] failedRunAwayMessages = {
  24. "The enemies catch up to your party! You take {damage} damage while trying to escape.",
  25. "Your escape attempt fails! The enemies pursue and wound your party for {damage} damage.",
  26. "The enemies block your escape route! Your party suffers {damage} damage in the failed attempt."
  27. };
  28. // Component references
  29. private TravelEventSystem originalEventSystem;
  30. private TravelEventUI eventUI;
  31. // Current combat state
  32. private BattleEventData pendingBattleData;
  33. private TravelEventContext pendingContext;
  34. private bool waitingForCombatDecision = false;
  35. void Start()
  36. {
  37. // Find required components
  38. originalEventSystem = FindFirstObjectByType<TravelEventSystem>();
  39. eventUI = FindFirstObjectByType<TravelEventUI>();
  40. if (combatEventPopup == null)
  41. combatEventPopup = FindFirstObjectByType<CombatEventPopup>();
  42. if (originalEventSystem == null)
  43. {
  44. Debug.LogError("❌ Enhanced Travel Event System requires a TravelEventSystem component!");
  45. enabled = false;
  46. return;
  47. }
  48. if (combatEventPopup == null)
  49. {
  50. Debug.LogError("❌ Enhanced Travel Event System requires a CombatEventPopup component!");
  51. enabled = false;
  52. return;
  53. }
  54. // Setup combat popup callback
  55. combatEventPopup.OnCombatDecision += HandleCombatDecision;
  56. Debug.Log("✅ Enhanced Travel Event System initialized");
  57. }
  58. void OnDestroy()
  59. {
  60. if (combatEventPopup != null)
  61. combatEventPopup.OnCombatDecision -= HandleCombatDecision;
  62. }
  63. /// <summary>
  64. /// Enhanced combat event handler that shows popup before battle
  65. /// Call this instead of the original HandleBattleEvent
  66. /// </summary>
  67. public void HandleEnhancedBattleEvent(BattleEventData battleData, TravelEventContext context, string eventDescription)
  68. {
  69. if (battleData == null || waitingForCombatDecision)
  70. return;
  71. Debug.Log($"🎭 Enhanced battle event triggered: {eventDescription}");
  72. // Store pending battle data
  73. pendingBattleData = battleData;
  74. pendingContext = context;
  75. waitingForCombatDecision = true;
  76. // Show combat popup
  77. combatEventPopup.ShowCombatEncounter(battleData, context, eventDescription);
  78. }
  79. /// <summary>
  80. /// Handle the player's combat decision from the popup
  81. /// </summary>
  82. private void HandleCombatDecision(bool chooseToAttack)
  83. {
  84. if (!waitingForCombatDecision || pendingBattleData == null)
  85. return;
  86. waitingForCombatDecision = false;
  87. if (chooseToAttack)
  88. {
  89. HandleAttackChoice();
  90. }
  91. else
  92. {
  93. HandleRunAwayChoice();
  94. }
  95. // Clear pending data
  96. pendingBattleData = null;
  97. pendingContext = null;
  98. }
  99. /// <summary>
  100. /// Handle when player chooses to attack
  101. /// </summary>
  102. private void HandleAttackChoice()
  103. {
  104. Debug.Log("⚔️ Player chose to fight! Setting up battle...");
  105. // Call the original battle setup logic
  106. if (originalEventSystem != null)
  107. {
  108. // Use reflection to call the private HandleBattleEvent method
  109. var method = originalEventSystem.GetType().GetMethod("HandleBattleEvent",
  110. System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
  111. if (method != null)
  112. {
  113. method.Invoke(originalEventSystem, new object[] { pendingBattleData, pendingContext });
  114. }
  115. else
  116. {
  117. Debug.LogError("❌ Could not find HandleBattleEvent method in TravelEventSystem");
  118. // Fallback: just log the battle setup
  119. LogBattleSetup(pendingBattleData);
  120. }
  121. }
  122. }
  123. /// <summary>
  124. /// Handle when player chooses to run away
  125. /// </summary>
  126. private void HandleRunAwayChoice()
  127. {
  128. Debug.Log("🏃 Player chose to run away! Rolling for escape...");
  129. if (!allowRunningAway)
  130. {
  131. Debug.Log("❌ Running away is not allowed! Forcing combat...");
  132. HandleAttackChoice();
  133. return;
  134. }
  135. bool escapeSuccessful = Random.value <= runAwaySuccessChance;
  136. if (escapeSuccessful)
  137. {
  138. HandleSuccessfulEscape();
  139. }
  140. else
  141. {
  142. HandleFailedEscape();
  143. }
  144. }
  145. /// <summary>
  146. /// Handle successful escape attempt
  147. /// </summary>
  148. private void HandleSuccessfulEscape()
  149. {
  150. string message = successfulRunAwayMessages[Random.Range(0, successfulRunAwayMessages.Length)];
  151. Debug.Log($"✅ Escape successful: {message}");
  152. // Show escape message
  153. if (eventUI != null)
  154. {
  155. eventUI.ShowEventMessage(message, EventType.Discovery, false);
  156. }
  157. else
  158. {
  159. Debug.Log($"📜 ESCAPE: {message}");
  160. }
  161. // Continue travel (no resource penalties for successful escape)
  162. ResumeTravelAfterEvent();
  163. }
  164. /// <summary>
  165. /// Handle failed escape attempt
  166. /// </summary>
  167. private void HandleFailedEscape()
  168. {
  169. string message = failedRunAwayMessages[Random.Range(0, failedRunAwayMessages.Length)];
  170. message = message.Replace("{damage}", runAwayHealthPenalty.ToString());
  171. Debug.Log($"❌ Escape failed: {message}");
  172. // Apply health penalty
  173. ApplyRunAwayPenalty();
  174. // Show failure message
  175. if (eventUI != null)
  176. {
  177. eventUI.ShowEventMessage(message, EventType.Hazard, false);
  178. }
  179. else
  180. {
  181. Debug.Log($"📜 ESCAPE FAILED: {message}");
  182. }
  183. // Start combat anyway
  184. StartCoroutine(DelayedCombatStart());
  185. }
  186. /// <summary>
  187. /// Apply penalties for failed escape attempt
  188. /// </summary>
  189. private void ApplyRunAwayPenalty()
  190. {
  191. // This would integrate with your character health system
  192. Debug.Log($"❤️ Party takes {runAwayHealthPenalty} damage from failed escape attempt");
  193. // TODO: Actually apply health damage to party members
  194. // Example: TeamHealthManager.ApplyDamageToParty(runAwayHealthPenalty);
  195. }
  196. /// <summary>
  197. /// Resume travel after successful escape
  198. /// </summary>
  199. private void ResumeTravelAfterEvent()
  200. {
  201. // The travel system should continue normally
  202. Debug.Log("🚗 Resuming travel after event...");
  203. // No need to stop travel for successful escapes
  204. }
  205. /// <summary>
  206. /// Start combat after a delay (for failed escape)
  207. /// </summary>
  208. private IEnumerator DelayedCombatStart()
  209. {
  210. yield return new WaitForSeconds(3f); // Wait for escape message to be read
  211. Debug.Log("⚔️ Starting combat after failed escape...");
  212. HandleAttackChoice();
  213. }
  214. /// <summary>
  215. /// Fallback battle setup logging
  216. /// </summary>
  217. private void LogBattleSetup(BattleEventData battleData)
  218. {
  219. Debug.Log($"⚔️ Setting up battle: {battleData.enemyCount} {battleData.enemyType}(s)");
  220. if (battleData.enemyCharacterData != null)
  221. {
  222. Debug.Log($"🎯 Using enemy data: {battleData.enemyCharacterData.enemyName}");
  223. Debug.Log($"📊 Enemy stats: HP={battleData.enemyCharacterData.maxHealth}, " +
  224. $"AC={battleData.enemyCharacterData.armorClass}, " +
  225. $"Threat={battleData.enemyCharacterData.threatLevel}");
  226. }
  227. // TODO: Actually set up battle scene transition
  228. Debug.Log("🎬 Transitioning to battle scene...");
  229. }
  230. /// <summary>
  231. /// Check if the system is currently waiting for player input
  232. /// </summary>
  233. public bool IsWaitingForCombatDecision => waitingForCombatDecision;
  234. /// <summary>
  235. /// Cancel pending combat (for cleanup)
  236. /// </summary>
  237. public void CancelPendingCombat()
  238. {
  239. if (waitingForCombatDecision)
  240. {
  241. waitingForCombatDecision = false;
  242. pendingBattleData = null;
  243. pendingContext = null;
  244. if (combatEventPopup != null)
  245. combatEventPopup.ForceClose();
  246. }
  247. }
  248. }