BattleActionIntegration.cs 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860
  1. using UnityEngine;
  2. using UnityEngine.UIElements;
  3. /// <summary>
  4. /// Integration script that connects the new battle action system with existing character selection
  5. /// This allows switching between the old click-drag system and the new action wheel system
  6. /// </summary>
  7. public class BattleActionIntegration : MonoBehaviour
  8. {
  9. [Header("System References")]
  10. public PlayerDecisionController playerDecisionController;
  11. public BattleActionSystem battleActionSystem;
  12. public BattleActionWheel actionWheel; // Legacy Canvas-based wheel
  13. public EnemySelectionUI enemySelectionUI; // TODO: Add after compilation
  14. public BattleItemSelector itemSelectionUI;
  15. [Header("Settings")]
  16. [Tooltip("Enable new action wheel system (false = use old click-drag system)")]
  17. public bool useNewActionSystem = false; // Changed to false by default for simpler testing
  18. [Space]
  19. [Tooltip("Press this key to toggle between action systems")]
  20. public KeyCode toggleSystemKey = KeyCode.T;
  21. private Character lastSelectedCharacter;
  22. private MonoBehaviour simpleWheelComponent;
  23. private string currentInstruction = "";
  24. private float instructionTimer = 0f;
  25. private float instructionDuration = 5f;
  26. void Start()
  27. {
  28. Debug.Log("🚀 BattleActionIntegration starting...");
  29. // FORCE useNewActionSystem to false to preserve drag functionality
  30. useNewActionSystem = false;
  31. // Find components if not assigned
  32. if (playerDecisionController == null)
  33. playerDecisionController = FindFirstObjectByType<PlayerDecisionController>();
  34. if (battleActionSystem == null)
  35. battleActionSystem = FindFirstObjectByType<BattleActionSystem>();
  36. if (actionWheel == null)
  37. actionWheel = FindFirstObjectByType<BattleActionWheel>();
  38. if (enemySelectionUI == null)
  39. enemySelectionUI = FindFirstObjectByType<EnemySelectionUI>();
  40. if (itemSelectionUI == null)
  41. itemSelectionUI = FindFirstObjectByType<BattleItemSelector>();
  42. // Ensure PlayerDecisionController is always enabled for drag functionality
  43. if (playerDecisionController != null)
  44. {
  45. playerDecisionController.enabled = true;
  46. playerDecisionController.SetEnabled(true);
  47. Debug.Log("🎮 PlayerDecisionController enabled for drag functionality");
  48. }
  49. // Try to find or create a simple wheel component
  50. var existingWheels = FindObjectsByType<MonoBehaviour>(FindObjectsSortMode.None);
  51. foreach (var comp in existingWheels)
  52. {
  53. if (comp.GetType().Name == "SimpleActionWheel")
  54. {
  55. simpleWheelComponent = comp;
  56. Debug.Log("🎮 Found existing SimpleActionWheel");
  57. break;
  58. }
  59. }
  60. if (simpleWheelComponent == null)
  61. {
  62. // Create simple wheel if it doesn't exist
  63. GameObject wheelObj = new GameObject("SimpleActionWheel");
  64. // Use reflection to add the component
  65. var componentType = System.Type.GetType("SimpleActionWheel");
  66. if (componentType != null)
  67. {
  68. simpleWheelComponent = wheelObj.AddComponent(componentType) as MonoBehaviour;
  69. Debug.Log("🎮 Created SimpleActionWheel automatically");
  70. }
  71. else
  72. {
  73. Debug.LogError("❌ Could not find SimpleActionWheel type");
  74. }
  75. }
  76. // Subscribe to events
  77. if (battleActionSystem != null)
  78. {
  79. battleActionSystem.OnActionCompleted += OnCharacterActionCompleted;
  80. }
  81. // Connect SimpleActionWheel events using reflection
  82. if (simpleWheelComponent != null)
  83. {
  84. ConnectSimpleWheelEvents();
  85. }
  86. Debug.Log($"✅ BattleActionIntegration initialized - useNewActionSystem: {useNewActionSystem}");
  87. }
  88. void Update()
  89. {
  90. // Allow toggling between systems
  91. if (Input.GetKeyDown(toggleSystemKey))
  92. {
  93. ToggleActionSystem();
  94. }
  95. // Handle action wheel key from SimpleActionWheel
  96. // Get the key from SimpleActionWheel component if available
  97. KeyCode wheelKey = KeyCode.Q; // Default fallback
  98. if (simpleWheelComponent != null)
  99. {
  100. var toggleKeyField = simpleWheelComponent.GetType().GetField("toggleKey");
  101. if (toggleKeyField != null)
  102. {
  103. wheelKey = (KeyCode)toggleKeyField.GetValue(simpleWheelComponent);
  104. }
  105. }
  106. if (Input.GetKeyDown(wheelKey))
  107. {
  108. // Clear any existing instruction when opening wheel
  109. currentInstruction = "";
  110. instructionTimer = 0f;
  111. // When using old system, get the selected character from PlayerDecisionController
  112. Character characterForWheel = lastSelectedCharacter;
  113. if (!useNewActionSystem && playerDecisionController != null)
  114. {
  115. Character currentlySelected = playerDecisionController.GetSelectedCharacter();
  116. if (currentlySelected != null)
  117. {
  118. characterForWheel = currentlySelected;
  119. lastSelectedCharacter = currentlySelected; // Update for consistency
  120. }
  121. }
  122. if (characterForWheel != null)
  123. {
  124. // Allow reopening the action wheel even if an action is already selected
  125. // This enables canceling/changing the selected action
  126. Debug.Log($"⌨️ {wheelKey} pressed, showing wheel for {characterForWheel.CharacterName}");
  127. ShowActionWheelForCharacter(characterForWheel);
  128. }
  129. else
  130. {
  131. Debug.Log($"⌨️ {wheelKey} pressed but no character selected");
  132. }
  133. }
  134. if (useNewActionSystem)
  135. {
  136. HandleNewActionSystemInput();
  137. }
  138. else
  139. {
  140. // When using old system, track character selection for action wheel
  141. // Monitor PlayerDecisionController's targeting state to update lastSelectedCharacter
  142. if (playerDecisionController != null && playerDecisionController.IsInTargetingMode)
  143. {
  144. Character currentlySelected = playerDecisionController.GetSelectedCharacter();
  145. if (currentlySelected != null && currentlySelected != lastSelectedCharacter)
  146. {
  147. lastSelectedCharacter = currentlySelected;
  148. Debug.Log($"🖱️ Character selected for action wheel: {currentlySelected.CharacterName}");
  149. // Clear any old instructions and show current action status
  150. ShowCharacterActionStatus(currentlySelected);
  151. }
  152. }
  153. }
  154. // Note: When useNewActionSystem is false, the old PlayerDecisionController.Update()
  155. // will handle input automatically - no need to interfere
  156. // Update instruction timer
  157. if (instructionTimer > 0f)
  158. {
  159. instructionTimer -= Time.deltaTime;
  160. if (instructionTimer <= 0f)
  161. {
  162. currentInstruction = "";
  163. }
  164. }
  165. }
  166. /// <summary>
  167. /// Get the action wheel key from SimpleActionWheel component
  168. /// </summary>
  169. private KeyCode GetActionWheelKey()
  170. {
  171. if (simpleWheelComponent != null)
  172. {
  173. var toggleKeyField = simpleWheelComponent.GetType().GetField("toggleKey");
  174. if (toggleKeyField != null)
  175. {
  176. return (KeyCode)toggleKeyField.GetValue(simpleWheelComponent);
  177. }
  178. }
  179. return KeyCode.Q; // Default fallback
  180. }
  181. void OnGUI()
  182. {
  183. // Show instruction message if active
  184. if (!string.IsNullOrEmpty(currentInstruction))
  185. {
  186. GUIStyle instructionStyle = new GUIStyle(GUI.skin.label);
  187. instructionStyle.fontSize = 18;
  188. instructionStyle.fontStyle = FontStyle.Bold;
  189. instructionStyle.alignment = TextAnchor.MiddleCenter;
  190. instructionStyle.normal.textColor = Color.yellow;
  191. Rect instructionRect = new Rect(0, 50, Screen.width, 30);
  192. // Background
  193. GUI.color = new Color(0, 0, 0, 0.7f);
  194. GUI.Box(instructionRect, "");
  195. // Text
  196. GUI.color = Color.white;
  197. GUI.Label(instructionRect, currentInstruction, instructionStyle);
  198. }
  199. // Simple UI for testing - show regardless of system mode
  200. GUILayout.BeginArea(new Rect(10, 10, 300, 250));
  201. GUILayout.Label($"Battle Action System (Mode: {(useNewActionSystem ? "New" : "Old")})");
  202. GUILayout.Label($"Action Key: {GetActionWheelKey()}");
  203. GUILayout.Label($"Simple Wheel: {(simpleWheelComponent != null ? "✅" : "❌")}");
  204. if (lastSelectedCharacter != null)
  205. {
  206. GUILayout.Label($"Selected: {lastSelectedCharacter.CharacterName}");
  207. var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
  208. if (actionData != null && actionData.hasValidAction)
  209. {
  210. GUILayout.Label($"Action: {actionData.GetActionDescription()}");
  211. GUILayout.Label($"Press {GetActionWheelKey()} again to change action", GUI.skin.box);
  212. }
  213. else
  214. {
  215. GUILayout.Label($"Press {GetActionWheelKey()} to choose action");
  216. }
  217. }
  218. else
  219. {
  220. GUILayout.Label("No character selected");
  221. GUILayout.Label("Click a player character to select");
  222. }
  223. GUILayout.Label($"Press {GetActionWheelKey()} to show action wheel");
  224. if (GUILayout.Button("Test Action Wheel"))
  225. {
  226. var testCharacter = FindFirstObjectByType<Character>();
  227. if (testCharacter != null)
  228. {
  229. ShowActionWheelForCharacter(testCharacter);
  230. }
  231. }
  232. if (GUILayout.Button("Reset PlayerDecisionController"))
  233. {
  234. if (playerDecisionController != null)
  235. {
  236. playerDecisionController.ResetState();
  237. }
  238. }
  239. GUILayout.EndArea();
  240. }
  241. private void HandleNewActionSystemInput()
  242. {
  243. // Don't interfere with mouse input if PlayerDecisionController is in targeting mode
  244. if (playerDecisionController != null && playerDecisionController.IsInTargetingMode)
  245. {
  246. // Let PlayerDecisionController handle the input for targeting
  247. return;
  248. }
  249. // Check for character selection
  250. if (Input.GetMouseButtonDown(0))
  251. {
  252. Character selectedCharacter = GetCharacterAtMousePosition();
  253. if (selectedCharacter != null)
  254. {
  255. Debug.Log($"🖱️ Clicked on character: {selectedCharacter.CharacterName} - Tag: {selectedCharacter.tag}");
  256. if (selectedCharacter.CompareTag("Player"))
  257. {
  258. Debug.Log($"✅ Confirmed player character: {selectedCharacter.CharacterName}");
  259. SelectCharacterForAction(selectedCharacter);
  260. }
  261. else
  262. {
  263. Debug.Log($"❌ Not a player character: {selectedCharacter.CharacterName} (Tag: {selectedCharacter.tag})");
  264. // Try to force selection anyway for testing
  265. Debug.Log($"🧪 Trying to select anyway for testing...");
  266. SelectCharacterForAction(selectedCharacter);
  267. }
  268. }
  269. else
  270. {
  271. Debug.Log("🖱️ Clicked but no character found");
  272. }
  273. }
  274. }
  275. private Character GetCharacterAtMousePosition()
  276. {
  277. Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
  278. RaycastHit hit;
  279. if (Physics.Raycast(ray, out hit))
  280. {
  281. return hit.collider.GetComponent<Character>();
  282. }
  283. return null;
  284. }
  285. private void SelectCharacterForAction(Character character)
  286. {
  287. // Only clear visual state of previous selection if they don't have an action
  288. if (lastSelectedCharacter != null)
  289. {
  290. var prevActionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
  291. if (prevActionData == null || !prevActionData.hasValidAction)
  292. {
  293. // Only reset to NoAction if they don't have a valid action
  294. lastSelectedCharacter.SetVisualState(ActionDecisionState.NoAction);
  295. }
  296. else
  297. {
  298. // Preserve their action state
  299. lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
  300. }
  301. }
  302. lastSelectedCharacter = character;
  303. // Initialize enhanced action data if needed
  304. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  305. if (actionData == null)
  306. {
  307. // Create instance at runtime to avoid compilation issues
  308. actionData = new EnhancedCharacterActionData();
  309. character.SetEnhancedActionData(actionData);
  310. }
  311. // Highlight selected character (use a different state for "currently selected")
  312. character.SetVisualState(ActionDecisionState.NoAction);
  313. // Update all character visual states to maintain proper color coding
  314. UpdateAllCharacterVisualStates();
  315. Debug.Log($"🎯 Selected character for action: {character.CharacterName}");
  316. // Don't auto-show wheel - let user press Q manually
  317. // if (useNewActionSystem)
  318. // {
  319. // ShowActionWheelForCharacter(character);
  320. // }
  321. }
  322. /// <summary>
  323. /// Update visual states for all characters to properly show action status
  324. /// </summary>
  325. private void UpdateAllCharacterVisualStates()
  326. {
  327. Character[] allCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
  328. foreach (Character character in allCharacters)
  329. {
  330. if (character.CompareTag("Player"))
  331. {
  332. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  333. if (character == lastSelectedCharacter)
  334. {
  335. // Currently selected character - show selection highlight
  336. character.SetVisualState(ActionDecisionState.NoAction); // Pink for selection
  337. }
  338. else if (actionData != null && actionData.hasValidAction)
  339. {
  340. // Has valid action selected - show action confirmed state
  341. character.SetVisualState(ActionDecisionState.ActionSelected); // Green for confirmed action
  342. }
  343. else
  344. {
  345. // No action selected
  346. character.SetVisualState(ActionDecisionState.NoAction); // Pink for no action
  347. }
  348. }
  349. }
  350. }
  351. private void ShowActionWheelForCharacter(Character character)
  352. {
  353. Debug.Log($"🎯 ShowActionWheelForCharacter called for: {character.CharacterName}");
  354. // Clear any existing instruction when showing the wheel
  355. currentInstruction = "";
  356. instructionTimer = 0f;
  357. // Reset PlayerDecisionController state to ensure clean state
  358. if (playerDecisionController != null)
  359. {
  360. playerDecisionController.ResetState();
  361. }
  362. // Reset any existing action for this character to allow changing selection
  363. var existingActionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  364. if (existingActionData != null && existingActionData.hasValidAction)
  365. {
  366. Debug.Log($"🔄 Resetting existing action for {character.CharacterName}: {existingActionData.GetActionDescription()}");
  367. existingActionData.Reset();
  368. character.SetVisualState(ActionDecisionState.NoAction);
  369. }
  370. // Try simple wheel first
  371. if (simpleWheelComponent != null)
  372. {
  373. Debug.Log($"🎮 Found SimpleActionWheel component: {simpleWheelComponent.GetType().Name}");
  374. // Use reflection to call ShowWheelForCharacter
  375. var method = simpleWheelComponent.GetType().GetMethod("ShowWheelForCharacter");
  376. if (method != null)
  377. {
  378. Debug.Log("🔧 Calling ShowWheelForCharacter via reflection...");
  379. method.Invoke(simpleWheelComponent, new object[] { character });
  380. return;
  381. }
  382. else
  383. {
  384. Debug.LogError("❌ ShowWheelForCharacter method not found on SimpleActionWheel!");
  385. }
  386. }
  387. else
  388. {
  389. Debug.LogError("❌ simpleWheelComponent is null!");
  390. }
  391. // Fallback to battle action system
  392. if (battleActionSystem != null)
  393. {
  394. Debug.Log("🔄 Falling back to BattleActionSystem...");
  395. battleActionSystem.ShowActionWheel(character);
  396. }
  397. else
  398. {
  399. Debug.LogError("BattleActionIntegration: No action wheel system found!");
  400. }
  401. }
  402. private void ConnectSimpleWheelEvents()
  403. {
  404. if (simpleWheelComponent == null)
  405. {
  406. Debug.LogError("❌ simpleWheelComponent is null in ConnectSimpleWheelEvents");
  407. return;
  408. }
  409. Debug.Log($"🔧 Connecting events for SimpleActionWheel component: {simpleWheelComponent.GetType().Name}");
  410. // Use reflection to connect to OnActionSelected event
  411. var eventInfo = simpleWheelComponent.GetType().GetEvent("OnActionSelected");
  412. if (eventInfo != null)
  413. {
  414. Debug.Log($"✅ Found OnActionSelected event: {eventInfo.EventHandlerType}");
  415. // Create delegate that matches the event signature: Action<BattleActionType>
  416. var delegateType = eventInfo.EventHandlerType;
  417. var methodInfo = this.GetType().GetMethod("OnActionSelected", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
  418. if (methodInfo != null)
  419. {
  420. Debug.Log($"✅ Found OnActionSelected method: {methodInfo.Name}");
  421. var handler = System.Delegate.CreateDelegate(delegateType, this, methodInfo);
  422. eventInfo.AddEventHandler(simpleWheelComponent, handler);
  423. Debug.Log("✅ Successfully connected SimpleActionWheel.OnActionSelected event");
  424. }
  425. else
  426. {
  427. Debug.LogError("❌ Could not find OnActionSelected method in BattleActionIntegration");
  428. }
  429. }
  430. else
  431. {
  432. Debug.LogError("❌ Could not find OnActionSelected event in SimpleActionWheel");
  433. }
  434. }
  435. private void OnActionSelected(BattleActionType actionType)
  436. {
  437. Debug.Log($"🔥 OnActionSelected called with: {actionType}");
  438. if (lastSelectedCharacter == null)
  439. {
  440. Debug.LogWarning("❌ Action selected but no character selected!");
  441. return;
  442. }
  443. Debug.Log($"🎯 {lastSelectedCharacter.CharacterName} selected action: {actionType}");
  444. // Set action data for the character
  445. var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
  446. if (actionData == null)
  447. {
  448. actionData = new EnhancedCharacterActionData();
  449. lastSelectedCharacter.SetEnhancedActionData(actionData);
  450. Debug.Log($"📝 Created new EnhancedCharacterActionData for {lastSelectedCharacter.CharacterName}");
  451. }
  452. // Configure action based on type and enable targeting mode
  453. switch (actionType)
  454. {
  455. case BattleActionType.Attack:
  456. actionData.actionType = actionType;
  457. Debug.Log("🗡️ Attack selected - Now drag from character to target enemy!");
  458. ShowInstructionMessage("ATTACK: Drag from character to enemy");
  459. StartTargetingMode(lastSelectedCharacter, actionType);
  460. break;
  461. case BattleActionType.Move:
  462. actionData.actionType = actionType;
  463. Debug.Log("👟 Move selected - Now drag from character to target position!");
  464. ShowInstructionMessage("MOVE: Drag from character to target position");
  465. StartTargetingMode(lastSelectedCharacter, actionType);
  466. break;
  467. case BattleActionType.UseItem:
  468. actionData.actionType = actionType;
  469. Debug.Log("🧪 Use Item selected - showing item selection UI");
  470. ShowInstructionMessage("USE ITEM: Select item from list");
  471. ShowItemSelection(lastSelectedCharacter);
  472. break;
  473. case BattleActionType.CastSpell:
  474. actionData.actionType = actionType;
  475. actionData.state = ActionDecisionState.ActionSelected;
  476. lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
  477. Debug.Log("✨ Cast Spell selected - implement spell selection UI");
  478. break;
  479. case BattleActionType.Defend:
  480. actionData.actionType = actionType;
  481. actionData.state = ActionDecisionState.ActionSelected;
  482. lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
  483. Debug.Log("🛡️ Defend action set - character will defend this turn");
  484. break;
  485. case BattleActionType.RunAway:
  486. actionData.actionType = actionType;
  487. actionData.state = ActionDecisionState.ActionSelected;
  488. lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
  489. Debug.Log("💨 Run Away action set - character will attempt to flee");
  490. break;
  491. }
  492. Debug.Log($"✅ Action {actionType} configured for {lastSelectedCharacter.CharacterName}");
  493. // Update all character visual states to show proper action status
  494. UpdateAllCharacterVisualStates();
  495. }
  496. private void StartTargetingMode(Character character, BattleActionType actionType)
  497. {
  498. Debug.Log($"🎯 Starting targeting mode for {character.CharacterName} with action {actionType}");
  499. // Enable the PlayerDecisionController to handle targeting
  500. if (playerDecisionController != null)
  501. {
  502. // Use the new public method to start targeting
  503. playerDecisionController.StartTargetingForCharacter(character, actionType);
  504. Debug.Log($"✅ PlayerDecisionController targeting started for {actionType}");
  505. }
  506. else
  507. {
  508. Debug.LogError("❌ PlayerDecisionController not found - cannot start targeting mode");
  509. }
  510. }
  511. private void ShowItemSelection(Character character)
  512. {
  513. Debug.Log($"🧪 Showing item selection for {character.CharacterName}");
  514. if (itemSelectionUI != null)
  515. {
  516. // Subscribe to item selection events
  517. itemSelectionUI.OnItemSelected -= OnItemSelected;
  518. itemSelectionUI.OnSelectionCancelled -= OnItemSelectionCancelled;
  519. itemSelectionUI.OnItemSelected += OnItemSelected;
  520. itemSelectionUI.OnSelectionCancelled += OnItemSelectionCancelled;
  521. itemSelectionUI.ShowItemSelection(character);
  522. }
  523. else
  524. {
  525. Debug.LogError("❌ BattleItemSelector not found!");
  526. // Fallback: Complete action immediately
  527. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  528. if (actionData != null)
  529. {
  530. actionData.state = ActionDecisionState.ActionSelected;
  531. character.SetVisualState(ActionDecisionState.ActionSelected);
  532. }
  533. }
  534. }
  535. private void OnItemSelected(string itemName, int itemIndex)
  536. {
  537. Debug.Log($"📦 Item selected: {itemName} (index: {itemIndex})");
  538. if (lastSelectedCharacter != null)
  539. {
  540. var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
  541. if (actionData != null)
  542. {
  543. // Check if item requires targeting (healing potions, etc. might target allies)
  544. bool requiresTargeting = IsItemRequiringTargeting(itemName);
  545. // Properly set the item action using the SetItemAction method
  546. actionData.SetItemAction(itemName, itemIndex, requiresTargeting);
  547. if (!requiresTargeting)
  548. {
  549. lastSelectedCharacter.SetVisualState(ActionDecisionState.ActionSelected);
  550. Debug.Log($"✅ {lastSelectedCharacter.CharacterName} will use {itemName}");
  551. // Show the updated action status
  552. ShowCharacterActionStatus(lastSelectedCharacter);
  553. }
  554. else
  555. {
  556. Debug.Log($"🎯 {itemName} requires targeting - start targeting mode");
  557. ShowInstructionMessage($"TARGET: Select target for {itemName}");
  558. StartTargetingMode(lastSelectedCharacter, BattleActionType.UseItem);
  559. }
  560. }
  561. }
  562. }
  563. /// <summary>
  564. /// Check if an item requires targeting (healing items, targeted attacks, etc.)
  565. /// </summary>
  566. private bool IsItemRequiringTargeting(string itemName)
  567. {
  568. // Add logic here to determine if item needs targeting
  569. // For now, assume most items are self-use (like health potions)
  570. // Healing items that can target others would return true
  571. if (itemName.ToLower().Contains("heal") && itemName.ToLower().Contains("other"))
  572. return true;
  573. if (itemName.ToLower().Contains("revive"))
  574. return true;
  575. if (itemName.ToLower().Contains("bomb") || itemName.ToLower().Contains("throw"))
  576. return true;
  577. return false; // Most items are self-use
  578. }
  579. private void OnItemSelectionCancelled()
  580. {
  581. Debug.Log("❌ Item selection cancelled");
  582. if (lastSelectedCharacter != null)
  583. {
  584. var actionData = lastSelectedCharacter.GetEnhancedActionData<EnhancedCharacterActionData>();
  585. if (actionData != null)
  586. {
  587. actionData.Reset();
  588. lastSelectedCharacter.SetVisualState(ActionDecisionState.NoAction);
  589. }
  590. }
  591. }
  592. private void OnCharacterActionCompleted(Character character)
  593. {
  594. Debug.Log($"✅ Action completed for {character.CharacterName}");
  595. // Clear selection after action is complete
  596. if (character == lastSelectedCharacter)
  597. {
  598. lastSelectedCharacter = null;
  599. }
  600. }
  601. /// <summary>
  602. /// Manually trigger action selection for a character (for use by other systems)
  603. /// </summary>
  604. public void SelectCharacter(Character character)
  605. {
  606. SelectCharacterForAction(character);
  607. }
  608. /// <summary>
  609. /// Execute all selected actions (for turn-based systems)
  610. /// </summary>
  611. public void ExecuteAllPlayerActions()
  612. {
  613. Character[] playerCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
  614. foreach (Character character in playerCharacters)
  615. {
  616. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  617. if (character.CompareTag("Player") && actionData != null && actionData.hasValidAction)
  618. {
  619. if (battleActionSystem != null)
  620. {
  621. battleActionSystem.ExecuteCharacterAction(character);
  622. }
  623. }
  624. }
  625. }
  626. /// <summary>
  627. /// Switch between old and new action systems
  628. /// </summary>
  629. public void ToggleActionSystem()
  630. {
  631. useNewActionSystem = !useNewActionSystem;
  632. // Enable/disable appropriate systems
  633. if (playerDecisionController != null)
  634. {
  635. // Keep PlayerDecisionController enabled for targeting support
  636. // Just control its input handling behavior
  637. playerDecisionController.enabled = true;
  638. playerDecisionController.SetEnabled(true);
  639. }
  640. // Clear any instruction messages when switching
  641. currentInstruction = "";
  642. instructionTimer = 0f;
  643. Debug.Log($"🎯 Action system switched to: {(useNewActionSystem ? "New Action Wheel (Q to open wheel)" : "Old Click-Drag (direct drag to move/attack)")}");
  644. }
  645. /// <summary>
  646. /// Check if all players have selected actions
  647. /// </summary>
  648. public bool AllPlayersHaveActions()
  649. {
  650. Character[] playerCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
  651. foreach (Character character in playerCharacters)
  652. {
  653. if (character.CompareTag("Player"))
  654. {
  655. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  656. if (actionData == null || !actionData.hasValidAction)
  657. {
  658. return false;
  659. }
  660. }
  661. }
  662. return true;
  663. }
  664. /// <summary>
  665. /// Reset all player actions (useful for new turns)
  666. /// </summary>
  667. public void ResetAllPlayerActions()
  668. {
  669. Character[] playerCharacters = FindObjectsByType<Character>(FindObjectsSortMode.None);
  670. foreach (Character character in playerCharacters)
  671. {
  672. if (character.CompareTag("Player"))
  673. {
  674. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  675. if (actionData != null)
  676. actionData.Reset();
  677. character.SetVisualState(ActionDecisionState.NoAction);
  678. }
  679. }
  680. lastSelectedCharacter = null;
  681. Debug.Log("🔄 All player actions reset");
  682. }
  683. /// <summary>
  684. /// Cancel action for a specific character (useful for undoing individual selections)
  685. /// </summary>
  686. public void CancelCharacterAction(Character character)
  687. {
  688. if (character == null) return;
  689. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  690. if (actionData != null && actionData.hasValidAction)
  691. {
  692. Debug.Log($"❌ Canceling action for {character.CharacterName}: {actionData.GetActionDescription()}");
  693. actionData.Reset();
  694. character.SetVisualState(ActionDecisionState.NoAction);
  695. ShowInstructionMessage($"Action canceled for {character.CharacterName}");
  696. }
  697. else
  698. {
  699. Debug.Log($"No action to cancel for {character.CharacterName}");
  700. }
  701. }
  702. private void ShowInstructionMessage(string message)
  703. {
  704. currentInstruction = message;
  705. instructionTimer = instructionDuration;
  706. Debug.Log($"📢 Instruction: {message}");
  707. }
  708. /// <summary>
  709. /// Show the current action status for a character or clear instructions if no action
  710. /// </summary>
  711. private void ShowCharacterActionStatus(Character character)
  712. {
  713. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  714. if (actionData != null && actionData.hasValidAction)
  715. {
  716. // Show current action
  717. ShowInstructionMessage($"Current action: {actionData.GetActionDescription()}");
  718. }
  719. else
  720. {
  721. // Clear instructions if no action set
  722. currentInstruction = "";
  723. instructionTimer = 0f;
  724. Debug.Log($"📢 No action set for {character.CharacterName} - instructions cleared");
  725. }
  726. }
  727. /// <summary>
  728. /// Called by PlayerDecisionController when targeting is complete
  729. /// </summary>
  730. public void OnTargetingComplete(Character character)
  731. {
  732. Debug.Log($"✅ Targeting complete for {character.CharacterName}");
  733. // Update lastSelectedCharacter so action wheel knows which character was last used
  734. lastSelectedCharacter = character;
  735. // Update all character visual states to reflect the completed action
  736. UpdateAllCharacterVisualStates();
  737. // Show instruction that action is set
  738. var actionData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
  739. if (actionData != null && actionData.hasValidAction)
  740. {
  741. ShowInstructionMessage($"Action set: {actionData.GetActionDescription()}");
  742. }
  743. }
  744. }