EnhancedTravelEventSystem.cs 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  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. }
  57. void OnDestroy()
  58. {
  59. if (combatEventPopup != null)
  60. combatEventPopup.OnCombatDecision -= HandleCombatDecision;
  61. }
  62. /// <summary>
  63. /// Enhanced combat event handler that shows popup before battle
  64. /// Call this instead of the original HandleBattleEvent
  65. /// </summary>
  66. public void HandleEnhancedBattleEvent(BattleEventData battleData, TravelEventContext context, string eventDescription)
  67. {
  68. if (battleData == null || waitingForCombatDecision)
  69. return;
  70. // Store pending battle data
  71. pendingBattleData = battleData;
  72. pendingContext = context;
  73. waitingForCombatDecision = true;
  74. // Show combat popup
  75. combatEventPopup.ShowCombatEncounter(battleData, context, eventDescription);
  76. }
  77. /// <summary>
  78. /// Handle the player's combat decision from the popup
  79. /// </summary>
  80. private void HandleCombatDecision(bool chooseToAttack)
  81. {
  82. if (!waitingForCombatDecision || pendingBattleData == null)
  83. return;
  84. waitingForCombatDecision = false;
  85. if (chooseToAttack)
  86. {
  87. HandleAttackChoice();
  88. }
  89. else
  90. {
  91. HandleRunAwayChoice();
  92. }
  93. // Clear pending data
  94. pendingBattleData = null;
  95. pendingContext = null;
  96. }
  97. /// <summary>
  98. /// Handle when player chooses to attack
  99. /// </summary>
  100. private void HandleAttackChoice()
  101. {
  102. // Call the original battle setup logic
  103. if (originalEventSystem != null)
  104. {
  105. // Use reflection to call the private HandleBattleEvent method
  106. var method = originalEventSystem.GetType().GetMethod("HandleBattleEvent",
  107. System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
  108. if (method != null)
  109. {
  110. method.Invoke(originalEventSystem, new object[] { pendingBattleData, pendingContext });
  111. }
  112. else
  113. {
  114. Debug.LogError("❌ Could not find HandleBattleEvent method in TravelEventSystem");
  115. // Fallback: just log the battle setup
  116. LogBattleSetup(pendingBattleData);
  117. }
  118. }
  119. }
  120. /// <summary>
  121. /// Handle when player chooses to run away
  122. /// </summary>
  123. private void HandleRunAwayChoice()
  124. {
  125. if (!allowRunningAway)
  126. {
  127. HandleAttackChoice();
  128. return;
  129. }
  130. bool escapeSuccessful = Random.value <= runAwaySuccessChance;
  131. if (escapeSuccessful)
  132. {
  133. HandleSuccessfulEscape();
  134. }
  135. else
  136. {
  137. HandleFailedEscape();
  138. }
  139. }
  140. /// <summary>
  141. /// Handle successful escape attempt
  142. /// </summary>
  143. private void HandleSuccessfulEscape()
  144. {
  145. string message = successfulRunAwayMessages[Random.Range(0, successfulRunAwayMessages.Length)];
  146. // Show escape message
  147. if (eventUI != null)
  148. {
  149. eventUI.ShowEventMessage(message, EventType.Discovery, false);
  150. }
  151. // Continue travel (no resource penalties for successful escape)
  152. ResumeTravelAfterEvent();
  153. }
  154. /// <summary>
  155. /// Handle failed escape attempt
  156. /// </summary>
  157. private void HandleFailedEscape()
  158. {
  159. string message = failedRunAwayMessages[Random.Range(0, failedRunAwayMessages.Length)];
  160. message = message.Replace("{damage}", runAwayHealthPenalty.ToString());
  161. // Apply health penalty
  162. ApplyRunAwayPenalty();
  163. // Show failure message
  164. if (eventUI != null)
  165. {
  166. eventUI.ShowEventMessage(message, EventType.Hazard, false);
  167. }
  168. // Start combat anyway
  169. StartCoroutine(DelayedCombatStart());
  170. }
  171. /// <summary>
  172. /// Apply penalties for failed escape attempt
  173. /// </summary>
  174. private void ApplyRunAwayPenalty()
  175. {
  176. // This would integrate with your character health system
  177. Debug.Log($"❤️ Party takes {runAwayHealthPenalty} damage from failed escape attempt");
  178. // TODO: Actually apply health damage to party members
  179. // Example: TeamHealthManager.ApplyDamageToParty(runAwayHealthPenalty);
  180. }
  181. /// <summary>
  182. /// Resume travel after successful escape
  183. /// </summary>
  184. private void ResumeTravelAfterEvent()
  185. {
  186. // The travel system should continue normally
  187. Debug.Log("🚗 Resuming travel after event...");
  188. // No need to stop travel for successful escapes
  189. }
  190. /// <summary>
  191. /// Start combat after a delay (for failed escape)
  192. /// </summary>
  193. private IEnumerator DelayedCombatStart()
  194. {
  195. yield return new WaitForSeconds(3f); // Wait for escape message to be read
  196. Debug.Log("⚔️ Starting combat after failed escape...");
  197. HandleAttackChoice();
  198. }
  199. /// <summary>
  200. /// Fallback battle setup logging
  201. /// </summary>
  202. private void LogBattleSetup(BattleEventData battleData)
  203. {
  204. Debug.Log($"⚔️ Setting up battle: {battleData.enemyCount} {battleData.enemyType}(s)");
  205. if (battleData.enemyCharacterData != null)
  206. {
  207. Debug.Log($"🎯 Using enemy data: {battleData.enemyCharacterData.enemyName}");
  208. Debug.Log($"📊 Enemy stats: HP={battleData.enemyCharacterData.maxHealth}, " +
  209. $"AC={battleData.enemyCharacterData.armorClass}, " +
  210. $"Threat={battleData.enemyCharacterData.threatLevel}");
  211. }
  212. // TODO: Actually set up battle scene transition
  213. Debug.Log("🎬 Transitioning to battle scene...");
  214. }
  215. /// <summary>
  216. /// Check if the system is currently waiting for player input
  217. /// </summary>
  218. public bool IsWaitingForCombatDecision => waitingForCombatDecision;
  219. /// <summary>
  220. /// Cancel pending combat (for cleanup)
  221. /// </summary>
  222. public void CancelPendingCombat()
  223. {
  224. if (waitingForCombatDecision)
  225. {
  226. waitingForCombatDecision = false;
  227. pendingBattleData = null;
  228. pendingContext = null;
  229. if (combatEventPopup != null)
  230. combatEventPopup.ForceClose();
  231. }
  232. }
  233. }