| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456 |
- using System.Collections.Generic;
- using Unity.VisualScripting;
- using UnityEngine;
- public class PlayerDecisionController : MonoBehaviour
- {
- [Header("References")]
- public LayerMask enemyLayerMask = 1 << 10; // Enemies are on layer 10
- public LayerMask playerLayerMask = 1 << 9; // Players are on layer 9
- [Header("Settings")]
- public float enemySnapDistance = 1f;
- private List<Character> playerCharacters = new List<Character>();
- private Character selectedCharacter;
- private TargetingLine targetingLine;
- private Camera mainCamera;
- private bool isDragging = false;
- private Vector3 dragStartPosition;
- private bool isEnabled = true;
- private List<TargetingLine> activeActionLines = new List<TargetingLine>();
- void Awake()
- {
- mainCamera = Camera.main;
- targetingLine = GetComponent<TargetingLine>();
- if (targetingLine == null)
- {
- targetingLine = gameObject.AddComponent<TargetingLine>();
- }
- }
- void Start()
- {
- InitializePlayerCharacters();
- }
- void Update()
- {
- HandleInput();
- }
- private void InitializePlayerCharacters()
- {
- // Get player characters from GameManager if available
- if (GameManager.Instance != null)
- {
- playerCharacters.Clear();
- foreach (GameObject playerGO in GameManager.Instance.playerCharacters)
- {
- Character character = playerGO.GetComponent<Character>();
- if (character != null)
- {
- playerCharacters.Add(character);
- }
- }
- }
- else
- {
- // Fallback: find all characters (for testing without GameManager)
- Character[] characters = FindObjectsByType<Character>(FindObjectsSortMode.None);
- playerCharacters.AddRange(characters);
- }
- foreach (Character character in playerCharacters)
- {
- character.actionData.Reset();
- character.SetVisualState(ActionDecisionState.NoAction);
- }
- }
- private void HandleInput()
- {
- if (!isEnabled) return;
- if (Input.GetMouseButtonDown(0)) // Left click
- {
- HandleLeftClickDown();
- }
- else if (Input.GetMouseButton(0) && isDragging) // Left drag
- {
- HandleLeftDrag();
- }
- else if (Input.GetMouseButtonUp(0)) // Left release
- {
- HandleLeftClickUp();
- }
- else if (Input.GetMouseButtonDown(1)) // Right click
- {
- HandleRightClick();
- }
- }
- private void HandleLeftClickDown()
- {
- Vector3 mouseWorldPosition = GetMouseWorldPosition();
- Character clickedCharacter = GetPlayerCharacterAtPosition(mouseWorldPosition);
- if (clickedCharacter != null)
- {
- selectedCharacter = clickedCharacter;
- isDragging = true;
- dragStartPosition = clickedCharacter.transform.position;
- // Clear any existing action lines before starting new targeting
- ClearActionLineForCharacter(clickedCharacter);
- targetingLine.StartTargeting(dragStartPosition);
- // CinemachineCameraController.Instance.FocusOnCharacter(clickedCharacter.transform);
- }
- }
- private void HandleLeftDrag()
- {
- if (selectedCharacter == null) return;
- Vector3 mouseWorldPos = GetMouseWorldPosition();
- GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
- if (enemyAtMouse != null)
- {
- // Snap to enemy
- Vector3 enemyPos = enemyAtMouse.transform.position;
- targetingLine.UpdateTargeting(dragStartPosition, enemyPos, true);
- }
- else
- {
- // Follow mouse
- targetingLine.UpdateTargeting(dragStartPosition, mouseWorldPos, false);
- }
- }
- private void HandleLeftClickUp()
- {
- if (!isDragging || selectedCharacter == null) return;
- Vector3 mouseWorldPos = GetMouseWorldPosition();
- GameObject enemyAtMouse = GetEnemyAtPosition(mouseWorldPos);
- if (enemyAtMouse != null)
- {
- // Set attack target
- selectedCharacter.actionData.SetAttackTarget(enemyAtMouse);
- // Also update enhanced action data if it exists
- UpdateEnhancedActionData(selectedCharacter, BattleActionType.Attack, enemyAtMouse, mouseWorldPos);
- }
- else
- {
- // Set move target
- selectedCharacter.actionData.SetMoveTarget(mouseWorldPos);
- // Also update enhanced action data if it exists
- UpdateEnhancedActionData(selectedCharacter, BattleActionType.Move, null, mouseWorldPos);
- }
- selectedCharacter.SetVisualState(selectedCharacter.actionData.state);
- // Cleanup
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- }
- private void HandleRightClick()
- {
- if (isDragging && selectedCharacter != null)
- {
- // Cancel current action
- selectedCharacter.actionData.Reset();
- selectedCharacter.SetVisualState(ActionDecisionState.NoAction);
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- }
- else
- {
- // Right click on character to reset their action
- Vector3 mouseWorldPos = GetMouseWorldPosition();
- Character clickedCharacter = GetPlayerCharacterAtPosition(mouseWorldPos);
- if (clickedCharacter != null)
- {
- clickedCharacter.actionData.Reset();
- clickedCharacter.SetVisualState(ActionDecisionState.NoAction);
- }
- }
- }
- private Vector3 GetMouseWorldPosition()
- {
- Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
- RaycastHit hit;
- // Raycast against a ground plane or existing colliders
- if (Physics.Raycast(ray, out hit, 200f))
- {
- return hit.point;
- }
- // Fallback: project onto a horizontal plane at y=0
- Plane groundPlane = new Plane(Vector3.up, Vector3.zero);
- if (groundPlane.Raycast(ray, out float distance))
- {
- return ray.GetPoint(distance);
- }
- return Vector3.zero;
- }
- private Character GetPlayerCharacterAtPosition(Vector3 worldPosition)
- {
- Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
- RaycastHit hit;
- if (Physics.Raycast(ray, out hit, 200f, playerLayerMask))
- {
- return hit.collider.GetComponent<Character>();
- }
- // Try raycast without layer mask to see what we're hitting
- if (Physics.Raycast(ray, out hit, 200f))
- {
- }
- else
- {
- }
- return null;
- }
- private GameObject GetEnemyAtPosition(Vector3 worldPosition)
- {
- Ray ray = mainCamera.ScreenPointToRay(Input.mousePosition);
- RaycastHit hit;
- if (Physics.Raycast(ray, out hit, 200f, enemyLayerMask))
- {
- return hit.collider.gameObject;
- }
- return null;
- }
- public bool AllCharactersHaveActions()
- {
- foreach (var character in playerCharacters)
- {
- // Characters need actions if they have no action set
- if (character.actionData.state == ActionDecisionState.NoAction)
- return false;
- }
- return true;
- }
- public void ResetAllCharacterActions()
- {
- foreach (var character in playerCharacters)
- {
- character.actionData.Reset();
- character.SetVisualState(ActionDecisionState.NoAction);
- }
- }
- public void UpdateVisualStates()
- {
- foreach (var character in playerCharacters)
- {
- // Update visual states based on current action status
- if (character.actionData.state == ActionDecisionState.NoAction)
- {
- character.SetVisualState(ActionDecisionState.NoAction); // Pink
- }
- else if (character.HasActionSelected())
- {
- character.SetVisualState(ActionDecisionState.ActionSelected); // Green
- }
- }
- }
- public void RefreshPlayerCharacters()
- {
- InitializePlayerCharacters();
- }
- public void SetEnabled(bool enabled)
- {
- isEnabled = enabled;
- if (!enabled)
- {
- if (isDragging)
- {
- // Cancel any current dragging operation
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- }
- // Don't automatically hide action lines when disabling - let caller decide
- }
- }
- public void ShowActiveActionLines()
- {
- HideActiveActionLines(); // Clear any existing lines first
- foreach (var character in playerCharacters)
- {
- if (character.HasActionSelected() && !character.IsActionComplete())
- {
- GameObject lineObject = new GameObject($"ActionLine_{character.name}");
- TargetingLine line = lineObject.AddComponent<TargetingLine>();
- activeActionLines.Add(line);
- Vector3 startPos = character.transform.position + Vector3.up * 0.5f;
- if (character.actionData.targetEnemy != null)
- {
- Vector3 endPos = character.actionData.targetEnemy.transform.position + Vector3.up * 0.5f;
- line.StartTargeting(startPos);
- line.UpdateTargeting(startPos, endPos, true); // true for enemy target (red line)
- }
- else if (character.actionData.targetPosition != Vector3.zero)
- {
- line.StartTargeting(startPos);
- line.UpdateTargeting(startPos, character.actionData.targetPosition, false); // false for movement (blue line)
- }
- }
- }
- }
- public void HideActiveActionLines()
- {
- foreach (var line in activeActionLines)
- {
- if (line != null)
- {
- line.StopTargeting();
- Destroy(line.gameObject);
- }
- }
- activeActionLines.Clear();
- }
- public void ClearActionLineForCharacter(Character character)
- {
- for (int i = activeActionLines.Count - 1; i >= 0; i--)
- {
- var line = activeActionLines[i];
- if (line != null && line.gameObject.name == $"ActionLine_{character.name}")
- {
- line.StopTargeting();
- Destroy(line.gameObject);
- activeActionLines.RemoveAt(i);
- break;
- }
- }
- }
- private void UpdateEnhancedActionData(Character character, BattleActionType actionType, GameObject targetEnemy, Vector3 targetPosition)
- {
- // Check if character has enhanced action data
- var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
- if (enhancedData != null)
- {
- Debug.Log($"🔄 Updating enhanced action data for {character.CharacterName}: {actionType}");
- // Update the enhanced action data to match the targeting result
- enhancedData.actionType = actionType;
- enhancedData.state = ActionDecisionState.ActionSelected;
- if (actionType == BattleActionType.Attack && targetEnemy != null)
- {
- enhancedData.targetEnemy = targetEnemy;
- enhancedData.targetPosition = Vector3.zero;
- Debug.Log($"🗡️ Enhanced data updated for attack on {targetEnemy.name}");
- }
- else if (actionType == BattleActionType.Move)
- {
- enhancedData.targetPosition = targetPosition;
- enhancedData.targetEnemy = null;
- Debug.Log($"👟 Enhanced data updated for move to {targetPosition}");
- }
- }
- else
- {
- Debug.Log($"ℹ️ No enhanced action data found for {character.CharacterName}");
- }
- }
- /// <summary>
- /// Manually start targeting mode for a specific character and action type
- /// Called by the action wheel system
- /// </summary>
- public void StartTargetingForCharacter(Character character, BattleActionType actionType)
- {
- Debug.Log($"🎯 StartTargetingForCharacter called: {character.CharacterName} -> {actionType}");
- selectedCharacter = character;
- isDragging = true;
- dragStartPosition = character.transform.position;
- // Store the action type for later reference
- var enhancedData = character.GetEnhancedActionData<EnhancedCharacterActionData>();
- if (enhancedData == null)
- {
- enhancedData = new EnhancedCharacterActionData();
- character.SetEnhancedActionData(enhancedData);
- }
- enhancedData.actionType = actionType;
- // Clear any existing action lines before starting new targeting
- ClearActionLineForCharacter(character);
- // Start the targeting line
- targetingLine.StartTargeting(dragStartPosition);
- Debug.Log($"✅ Targeting mode activated for {character.CharacterName}");
- }
- /// <summary>
- /// Cancel current targeting operation
- /// </summary>
- public void CancelTargeting()
- {
- if (isDragging && selectedCharacter != null)
- {
- selectedCharacter.actionData.Reset();
- selectedCharacter.SetVisualState(ActionDecisionState.NoAction);
- targetingLine.StopTargeting();
- selectedCharacter = null;
- isDragging = false;
- Debug.Log("❌ Targeting cancelled");
- }
- }
- }
|