Files
tekton/scripts/managers/player_action_manager.gd
T

219 lines
7.8 KiB
GDScript

extends Node
# PlayerActionManager - Handles action points, highlights, and visual feedback
var player: Node3D
var enhanced_gridmap: Node
var highlighted_cells = [] # List of positions
# highlight_restore_items no longer needed for Layer 2
func initialize(p_player: Node3D, p_gridmap: Node):
player = p_player
enhanced_gridmap = p_gridmap
# =============================================================================
# Action Point Management
# =============================================================================
func consume_action_points(points: int):
if not is_instance_valid(player) or not player.is_multiplayer_authority():
return
var main = player.get_tree().get_root().get_node_or_null("Main")
if not main:
return
# Non-turn-based mode: unlimited action points for real-time fast-paced gameplay
if not TurnManager.turn_based_mode:
after_action_completed()
return
# Turn-based mode: consume action points normally
player.action_points -= points
if player.action_points <= 0:
main.request_next_turn()
after_action_completed()
func after_action_completed():
# Guard against recursive calls
if player._is_processing_action:
return
player._is_processing_action = true
if player.is_multiplayer_authority():
player.update_finish_availability()
# Clear the highlights after placing the tiles. (Quickfix for Clientside)
clear_highlights()
# Only update UI if this is the LOCAL HUMAN PLAYER
# Bots are owned by the host (authority match) but shouldn't trigger UI updates
if multiplayer.get_unique_id() == player.get_multiplayer_authority():
# Sync playerboard (Bots DO need to sync their board logic, just not update local UI)
if player.is_multiplayer_authority() and player.has_method("can_rpc") and player.can_rpc():
var main = player.get_tree().get_root().get_node_or_null("Main")
if main:
main.rpc("sync_playerboard", player.name.to_int(), player.playerboard)
player._is_processing_action = false
# =============================================================================
# Highlight Operations
# =============================================================================
func highlight_cells_if_authorized(cells_to_highlight: Array, item_id: int = -1):
if not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots"):
return
# Start with fresh highlights if logical state changes?
# But dragging mouse calls this every frame. We need to clear previous calls.
# The simplistic clear_highlights() clears ALL highlights.
# Which is fine for targeting mode as we only highlight the target area.
clear_highlights()
var highlight_item = item_id if item_id != -1 else enhanced_gridmap.hover_item
for cell in cells_to_highlight:
highlighted_cells.append(cell)
# Use Layer 2 for overlay highlights (prevents overwriting Execution on Layer 0)
enhanced_gridmap.set_cell_item(
Vector3i(cell.x, 2, cell.y),
highlight_item
)
func highlight_empty_adjacent_cells():
if player.is_bot == true or player.is_in_group("Bots"):
return
# Debug print
print("Highlighting empty adjacent cells. Current position: ", player.current_position)
# Clear previous highlights
clear_highlights()
# Highlight current position if empty
var current_cell = Vector3i(player.current_position.x, 1, player.current_position.y)
if enhanced_gridmap.get_cell_item(current_cell) == -1:
highlighted_cells.append(player.current_position)
# Set on Layer 2 (Overlay)
enhanced_gridmap.set_cell_item(Vector3i(player.current_position.x, 2, player.current_position.y),
enhanced_gridmap.hover_item)
print("Highlighted current position: ", player.current_position)
# Highlight empty adjacent cells
var neighbors = enhanced_gridmap.get_neighbors(player.current_position, 0)
for neighbor in neighbors:
if neighbor.is_walkable:
var cell_pos = neighbor.position
var cell = Vector3i(cell_pos.x, 1, cell_pos.y)
if enhanced_gridmap.get_cell_item(cell) == -1: # Check if cell is empty
highlighted_cells.append(cell_pos)
# Set on Layer 2 (Overlay)
enhanced_gridmap.set_cell_item(Vector3i(cell_pos.x, 2, cell_pos.y),
enhanced_gridmap.hover_item)
print("Highlighted adjacent cell: ", cell_pos)
func highlight_random_valid_cells():
if player.is_bot == true or player.is_in_group("Bots") or not player.is_multiplayer_authority():
return
clear_highlights()
# First check the current position
var current_cell = Vector3i(player.current_position.x, 1, player.current_position.y)
var current_item = enhanced_gridmap.get_cell_item(current_cell)
if current_item != -1:
highlighted_cells.append(player.current_position)
# Set on Layer 2 (Overlay)
enhanced_gridmap.set_cell_item(Vector3i(player.current_position.x, 2, player.current_position.y),
enhanced_gridmap.hover_item)
# Then check all adjacent cells for items
var neighbors = enhanced_gridmap.get_neighbors(player.current_position, 0)
for neighbor in neighbors:
if neighbor.is_walkable:
var cell_pos = neighbor.position
var cell = Vector3i(cell_pos.x, 1, cell_pos.y)
if enhanced_gridmap.get_cell_item(cell) != -1: # Only highlight cells with items
highlighted_cells.append(cell_pos)
# Set on Layer 2 (Overlay)
enhanced_gridmap.set_cell_item(Vector3i(cell_pos.x, 2, cell_pos.y),
enhanced_gridmap.hover_item)
func highlight_occupied_playerboard_slots():
if player.is_bot == true or player.is_in_group("Bots") or not player.is_multiplayer_authority():
return
var main = player.get_tree().get_root().get_node_or_null("Main")
if not main or not main.ui_manager.playerboard_ui:
return
# First reset all slots to normal
for i in range(player.playerboard.size()):
var slot = main.ui_manager.playerboard_ui.get_child(i)
for child in slot.get_children():
child.hide()
# Highlight occupied slots that match goals
for i in range(player.playerboard.size()):
if player.playerboard[i] in player.goals:
var slot = main.ui_manager.playerboard_ui.get_child(i)
if slot.get_child_count() > 0:
slot.get_child(0).show() # Show highlight for matching items
highlighted_cells.append(i) # Add to highlighted cells for tracking
# Update the UI to reflect changes
main.ui_manager.update_playerboard_ui()
func clear_highlights():
# Never allow bots to clear highlights for human players
if player.is_bot or player.is_in_group("Bots"):
return
if not enhanced_gridmap or not player.is_multiplayer_authority():
return
# Clear highlights normally
var main = player.get_tree().get_root().get_node_or_null("Main")
var hover_id = enhanced_gridmap.hover_item
for cell in highlighted_cells:
if cell is Vector2i:
# Check Layer 2 (Overlay Highlight)
var l2_pos = Vector3i(cell.x, 2, cell.y)
var l2_item = enhanced_gridmap.get_cell_item(l2_pos)
# Only clear if it is a highlight and NOT a Safe Zone (ID 2) or Freeze Area (ID 5)
if l2_item != -1 and l2_item != 2 and l2_item != 5:
enhanced_gridmap.set_cell_item(l2_pos, -1)
highlighted_cells.clear()
if main and main.ui_manager.playerboard_ui:
for i in range(main.ui_manager.playerboard_ui.get_child_count()):
var slot = main.ui_manager.playerboard_ui.get_child(i)
for child in slot.get_children():
child.hide()
func clear_playerboard_highlights():
# Never allow bots to clear highlights for human players
if player.is_bot or player.is_in_group("Bots"):
return
if not player.is_multiplayer_authority():
return
var main = player.get_tree().get_root().get_node_or_null("Main")
if main and main.ui_manager.playerboard_ui:
for i in range(main.ui_manager.playerboard_ui.get_child_count()):
var slot = main.ui_manager.playerboard_ui.get_child(i)
if slot.get_child_count() > 0: slot.get_child(0).hide()
if slot.get_child_count() > 1: slot.get_child(1).hide()
if slot.get_child_count() > 2: slot.get_child(2).hide()
highlighted_cells.clear()