248 lines
8.7 KiB
GDScript
248 lines
8.7 KiB
GDScript
extends Node
|
|
|
|
# PlayerActionManager - Handles action points, highlights, and visual feedback
|
|
|
|
var player: Node3D
|
|
var enhanced_gridmap: Node
|
|
|
|
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
|
|
|
|
# Don't consume points for bots in non-turn-based mode
|
|
if player.is_bot == true and not TurnManager.turn_based_mode:
|
|
after_action_completed()
|
|
return
|
|
|
|
player.action_points -= points
|
|
|
|
if player.action_points <= 0:
|
|
if TurnManager.turn_based_mode:
|
|
main.request_next_turn()
|
|
else:
|
|
player.action_points = 2
|
|
player.has_performed_action = false
|
|
player.has_moved_this_turn = false
|
|
player.rpc("display_message", "Action Points Reset!")
|
|
|
|
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()
|
|
|
|
if multiplayer.get_unique_id() == player.get_multiplayer_authority():
|
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
|
if main:
|
|
# Add this condition for bots
|
|
if not TurnManager.turn_based_mode and (player.action_points <= 0 or player.is_bot):
|
|
player.action_points = 20 # For bots in non-turn-based mode, this will keep refreshing
|
|
player.has_performed_action = false
|
|
player.has_moved_this_turn = false
|
|
|
|
main.ui_manager.update_button_states()
|
|
main.ui_manager.update_playerboard_ui()
|
|
|
|
# Add this line to sync all boards
|
|
main.update_all_players_boards()
|
|
|
|
# Add sync for playerboard
|
|
if player.is_multiplayer_authority():
|
|
main.rpc("sync_playerboard", player.get_multiplayer_authority(), player.playerboard)
|
|
|
|
player._is_processing_action = false
|
|
|
|
# =============================================================================
|
|
# Highlight Operations
|
|
# =============================================================================
|
|
|
|
func highlight_cells_if_authorized(cells_to_highlight: Array):
|
|
if not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots"):
|
|
return
|
|
|
|
clear_highlights()
|
|
for cell in cells_to_highlight:
|
|
player.highlighted_cells.append(cell)
|
|
enhanced_gridmap.set_cell_item(
|
|
Vector3i(cell.x, 0, cell.y),
|
|
enhanced_gridmap.hover_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:
|
|
player.highlighted_cells.append(player.current_position)
|
|
enhanced_gridmap.set_cell_item(Vector3i(player.current_position.x, 0, 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
|
|
player.highlighted_cells.append(cell_pos)
|
|
enhanced_gridmap.set_cell_item(Vector3i(cell_pos.x, 0, 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:
|
|
player.highlighted_cells.append(player.current_position)
|
|
enhanced_gridmap.set_cell_item(Vector3i(player.current_position.x, 0, 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
|
|
player.highlighted_cells.append(cell_pos)
|
|
enhanced_gridmap.set_cell_item(Vector3i(cell_pos.x, 0, 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
|
|
player.highlighted_cells.append(i) # Add to highlighted cells for tracking
|
|
|
|
# Update the UI to reflect changes
|
|
main.ui_manager.update_playerboard_ui()
|
|
|
|
func highlight_valid_obstacle_cells():
|
|
if not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots"):
|
|
return
|
|
|
|
clear_highlights()
|
|
|
|
var cells_to_highlight = []
|
|
|
|
# Highlight all empty cells on the grid except those occupied by players or obstacles
|
|
for x in range(enhanced_gridmap.columns):
|
|
for z in range(enhanced_gridmap.rows):
|
|
var pos = Vector2i(x, z)
|
|
var cell = Vector3i(x, 3, z) # Check floor 3 for occupancy
|
|
var occupied_by_player = false
|
|
var occupied_by_obstacle = false
|
|
|
|
# Check if cell is occupied by any player
|
|
for p in player.get_tree().get_nodes_in_group("Players"):
|
|
if p.current_position == pos:
|
|
occupied_by_player = true
|
|
break
|
|
|
|
# Check if cell is occupied by an obstacle
|
|
if enhanced_gridmap.get_cell_item(cell) in enhanced_gridmap.obstacle_items:
|
|
occupied_by_obstacle = true
|
|
|
|
# Only add to highlights if not occupied by player or obstacle
|
|
if not occupied_by_player and not occupied_by_obstacle:
|
|
cells_to_highlight.append(pos)
|
|
|
|
highlight_cells_if_authorized(cells_to_highlight)
|
|
|
|
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
|
|
|
|
# Store the current action state before clearing
|
|
var main = player.get_tree().get_root().get_node_or_null("Main")
|
|
var current_state = main.ui_manager.current_action_state if main else null
|
|
|
|
for cell in player.highlighted_cells:
|
|
if cell is Vector2i:
|
|
enhanced_gridmap.set_cell_item(Vector3i(cell.x, 0, cell.y), enhanced_gridmap.normal_items[0])
|
|
|
|
player.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()
|
|
|
|
# Restore highlights based on current action state
|
|
if main and current_state == main.ui_manager.ActionState.MOVING and player.is_my_turn and current_state != main.ui_manager.ActionState.PLACING_OBSTACLE:
|
|
player.highlight_movement_range()
|
|
|
|
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()
|
|
|
|
player.highlighted_cells.clear()
|