Files
tekton/scripts/managers/ui_manager.gd
T

300 lines
9.7 KiB
GDScript

extends Node
# UIManager - Handles all UI setup and updates
const item_tex = [
preload("res://assets/textures/player_board_and_blue_print/tile_null.tres"),
preload("res://assets/textures/player_board_and_blue_print/tile_heart.tres"),
preload("res://assets/textures/player_board_and_blue_print/tile_diamond.tres"),
preload("res://assets/textures/player_board_and_blue_print/tile_star.tres"),
preload("res://assets/textures/player_board_and_blue_print/tile_coin.tres")
]
# Node references - will be set by Main
var action_menu
var move_button
var grab_button
var put_button
var randomize_button
var arrange_button
var playerboard_ui
var local_player_character
enum ActionState {
NONE,
MOVING,
GRABBING,
PUTTING,
RANDOMIZING,
ARRANGING,
PLACING_OBSTACLE
}
var current_action_state = ActionState.NONE
func initialize(main_node):
# Get node references from main scene
action_menu = main_node.get_node("ActionMenu")
move_button = main_node.get_node("ActionMenu/ActionButtonContainer/MoveButton")
grab_button = main_node.get_node("ActionMenu/ActionButtonContainer/GrabButton")
put_button = main_node.get_node("ActionMenu/ActionButtonContainer/PutButton")
randomize_button = main_node.get_node("ActionMenu/ActionButtonContainer/RandomizeButton")
arrange_button = main_node.get_node("ActionMenu/ActionButtonContainer/ArrangeButton")
playerboard_ui = main_node.get_node("PlayerboardUI")
func setup_action_buttons(action_state_callback):
move_button.pressed.connect(func(): action_state_callback.call(ActionState.MOVING))
grab_button.pressed.connect(func(): action_state_callback.call(ActionState.GRABBING))
put_button.pressed.connect(func():
if local_player_character:
local_player_character.auto_put_item()
)
randomize_button.pressed.connect(func(): action_state_callback.call(ActionState.RANDOMIZING))
arrange_button.pressed.connect(func():
if local_player_character and local_player_character.action_points >= 2:
action_state_callback.call(ActionState.ARRANGING)
)
func setup_playerboard_ui():
for child in playerboard_ui.get_children():
child.queue_free()
playerboard_ui.columns = 5
for i in range(25):
var slot = TextureRect.new()
var highlight_rect = TextureRect.new()
var hr_tex = load("res://assets/models/pboard/HighlightRect.tres")
var select_rect = TextureRect.new()
var sr_tex = load("res://assets/models/pboard/SelectRect.tres")
var adjacent_rect = TextureRect.new()
var ar_tex = load("res://assets/models/pboard/AdjacentRect.tres")
slot.custom_minimum_size = Vector2(36, 36)
slot.texture = item_tex[0]
playerboard_ui.add_child(slot, true)
highlight_rect.texture = hr_tex
highlight_rect.size = Vector2(36, 36)
select_rect.texture = sr_tex
select_rect.size = Vector2(36, 36)
adjacent_rect.texture = ar_tex
adjacent_rect.size = Vector2(36, 36)
slot.add_child(highlight_rect)
slot.add_child(select_rect)
slot.add_child(adjacent_rect)
slot.get_child(0).hide()
slot.get_child(1).hide()
slot.get_child(2).hide()
func update_playerboard_ui():
if not local_player_character:
return
for i in range(25):
var slot = playerboard_ui.get_child(i)
# Safety check: Ensure playerboard has enough items
if i >= local_player_character.playerboard.size():
continue
var item = local_player_character.playerboard[i]
slot.texture = item_tex[0]
match item:
7: slot.texture = item_tex[1]
8: slot.texture = item_tex[2]
9: slot.texture = item_tex[3]
10: slot.texture = item_tex[4]
func update_button_states():
if not local_player_character or local_player_character.is_in_group("Bots"):
move_button.visible = false
grab_button.visible = false
put_button.visible = false
randomize_button.visible = false
arrange_button.visible = false
return
move_button.visible = true
grab_button.visible = true
put_button.visible = true
randomize_button.visible = true
arrange_button.visible = true
move_button.disabled = false
grab_button.disabled = false
put_button.disabled = false
arrange_button.disabled = false
func set_local_player(player):
local_player_character = player
# Connect to powerup signals with deferred call (manager needs time to initialize)
_connect_powerup_manager_deferred(player)
func _connect_powerup_manager_deferred(player):
"""Wait for PowerUpManager to be initialized before connecting."""
await player.get_tree().create_timer(0.3).timeout
var powerup_manager = player.get_node_or_null("PowerUpManager")
if powerup_manager:
if not powerup_manager.points_changed.is_connected(_on_powerup_points_changed):
powerup_manager.points_changed.connect(_on_powerup_points_changed)
# Initialize bar with current values
update_powerup_bar(powerup_manager.get_points(), powerup_manager.get_max_points())
# =============================================================================
# Power-Up Bar UI (Battery Style)
# =============================================================================
var powerup_bar: PanelContainer
var powerup_segments: Array = []
func setup_powerup_bar_ui(main_node):
"""Get reference to existing PowerUpBar in scene and cache segment references."""
powerup_bar = main_node.get_node_or_null("PowerUpBar")
if not powerup_bar:
push_warning("PowerUpBar node not found in scene")
return
# Get segment references from scene
powerup_segments.clear()
var hbox = powerup_bar.get_node_or_null("HBox")
if hbox:
for i in range(4):
var segment = hbox.get_node_or_null("Segment" + str(i))
if segment:
# Apply initial empty style
var style = StyleBoxFlat.new()
style.bg_color = Color(0.15, 0.15, 0.15, 1.0)
style.border_color = Color(0.3, 0.7, 0.3, 1.0)
style.set_border_width_all(2)
style.corner_radius_top_left = 4 if i == 0 else 0
style.corner_radius_bottom_left = 4 if i == 0 else 0
style.corner_radius_top_right = 4 if i == 3 else 0
style.corner_radius_bottom_right = 4 if i == 3 else 0
segment.add_theme_stylebox_override("panel", style)
powerup_segments.append(segment)
func update_powerup_bar(current_points: int, max_points: int):
"""Update battery segments based on current power-up points."""
var bars_filled = current_points / 4 # 4 points per bar
for i in range(powerup_segments.size()):
var segment = powerup_segments[i]
var style = segment.get_theme_stylebox("panel").duplicate()
if i < bars_filled:
# Filled segment - bright green
style.bg_color = Color(0.3, 0.9, 0.3, 1.0)
else:
# Empty segment - dark
style.bg_color = Color(0.2, 0.2, 0.2, 0.8)
segment.add_theme_stylebox_override("panel", style)
func _on_powerup_points_changed(current: int, max_points: int):
update_powerup_bar(current, max_points)
# =============================================================================
# Leaderboard UI
# =============================================================================
var leaderboard_panel: PanelContainer
func setup_leaderboard_ui(main_node):
"""Get reference to existing LeaderboardPanel in scene."""
leaderboard_panel = main_node.get_node_or_null("LeaderboardPanel")
if not leaderboard_panel:
push_warning("LeaderboardPanel node not found in scene")
return
# Apply styling to the panel
var style = StyleBoxFlat.new()
style.bg_color = Color(0.08, 0.08, 0.12, 0.92)
style.border_color = Color(0.85, 0.75, 0.25, 1.0) # Gold border
style.set_border_width_all(2)
style.corner_radius_top_left = 8
style.corner_radius_top_right = 8
style.corner_radius_bottom_left = 8
style.corner_radius_bottom_right = 8
leaderboard_panel.add_theme_stylebox_override("panel", style)
func _get_rank_text(rank: int) -> String:
match rank:
1: return "1st"
2: return "2nd"
3: return "3rd"
4: return "4th"
_: return str(rank) + "th"
# =============================================================================
# Timer Labels for Goal Panels
# =============================================================================
func setup_timer_labels(main_node):
"""Apply styling to standalone GoalsTimer in scene."""
var goals_timer = main_node.get_node_or_null("GoalsTimer")
if not goals_timer:
push_warning("GoalsTimer node not found in scene")
return
# Apply dark background style
var style = StyleBoxFlat.new()
style.bg_color = Color(0.1, 0.1, 0.15, 0.9)
style.border_color = Color(1.0, 0.85, 0.2, 1.0) # Gold border
style.set_border_width_all(2)
style.corner_radius_top_left = 8
style.corner_radius_top_right = 8
style.corner_radius_bottom_left = 8
style.corner_radius_bottom_right = 8
goals_timer.add_theme_stylebox_override("panel", style)
# Style the timer label
var timer_label = goals_timer.get_node_or_null("VBox/TimerLabel")
if timer_label:
timer_label.add_theme_color_override("font_color", Color(1.0, 0.85, 0.2))
var suffix_label = goals_timer.get_node_or_null("VBox/SuffixLabel")
if suffix_label:
suffix_label.add_theme_color_override("font_color", Color(0.7, 0.7, 0.7))
# Method to update leaderboard with all players in match
func initialize_leaderboard_with_players(players: Array):
"""Initialize leaderboard showing all players with score 0."""
if not leaderboard_panel:
return
var vbox = leaderboard_panel.get_node_or_null("MarginContainer/VBox")
if not vbox:
vbox = leaderboard_panel.get_node_or_null("VBox")
if not vbox:
return
for i in range(4):
var entry = vbox.get_node_or_null("Entry" + str(i + 1))
if not entry:
continue
if i < players.size():
var player = players[i]
var name_label = entry.get_node_or_null("NameLabel")
var score_label = entry.get_node_or_null("ScoreLabel")
if name_label:
name_label.text = str(player.name) if player else "Player " + str(i + 1)
if score_label:
score_label.text = str(player.score) if player and player.get("score") else "0"
entry.visible = true
else:
entry.visible = false