feat: Introduce lobby functionality with UI, server selection, and game state management.
This commit is contained in:
+21
-9
@@ -41,6 +41,7 @@ extends Control
|
||||
|
||||
# UI References - Player Slots
|
||||
@onready var players_container = $LobbyPanel/PlayersContainer
|
||||
@onready var players_container2 = $LobbyPanel/PlayersContainer2
|
||||
@onready var player_slots: Array[Control] = []
|
||||
|
||||
# UI References - Area Selector
|
||||
@@ -224,23 +225,34 @@ func _setup_scarcity_ui() -> void:
|
||||
# Add to scene
|
||||
settings_section.add_child(scarcity_option)
|
||||
settings_section.add_child(scarcity_label)
|
||||
|
||||
# Initial visibility update will handle showing correct one
|
||||
|
||||
func _setup_player_slots() -> void:
|
||||
"""Get references to all player slot nodes."""
|
||||
player_slots.clear()
|
||||
|
||||
# Slots 1-4 in Container 1
|
||||
for i in range(1, 5):
|
||||
var slot = players_container.get_node_or_null("PlayerSlot%d" % i)
|
||||
if slot:
|
||||
player_slots.append(slot)
|
||||
# Connect character navigation buttons for all slots
|
||||
var left_btn = slot.get_node_or_null("CharacterNav%d/CharLeftBtn%d" % [i, i])
|
||||
var right_btn = slot.get_node_or_null("CharacterNav%d/CharRightBtn%d" % [i, i])
|
||||
if left_btn:
|
||||
left_btn.pressed.connect(func(): LobbyManager.cycle_character(-1))
|
||||
if right_btn:
|
||||
right_btn.pressed.connect(func(): LobbyManager.cycle_character(1))
|
||||
_connect_slot_signals(slot, i)
|
||||
|
||||
# Slots 5-8 in Container 2
|
||||
if players_container2:
|
||||
for i in range(5, 9):
|
||||
var slot = players_container2.get_node_or_null("PlayerSlot%d" % i)
|
||||
if slot:
|
||||
player_slots.append(slot)
|
||||
_connect_slot_signals(slot, i)
|
||||
|
||||
func _connect_slot_signals(slot: Control, i: int):
|
||||
# Connect character navigation buttons for all slots
|
||||
var left_btn = slot.get_node_or_null("CharacterNav%d/CharLeftBtn%d" % [i, i])
|
||||
var right_btn = slot.get_node_or_null("CharacterNav%d/CharRightBtn%d" % [i, i])
|
||||
if left_btn:
|
||||
left_btn.pressed.connect(func(): LobbyManager.cycle_character(-1))
|
||||
if right_btn:
|
||||
right_btn.pressed.connect(func(): LobbyManager.cycle_character(1))
|
||||
|
||||
# =============================================================================
|
||||
# Panel Management
|
||||
|
||||
+266
-12
@@ -220,7 +220,6 @@ layout_mode = 2
|
||||
text = "PROFILE"
|
||||
|
||||
[node name="LobbyPanel" type="Control" parent="." unique_id=1745714811]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
@@ -382,10 +381,10 @@ layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -150.0
|
||||
offset_top = 99.0
|
||||
offset_right = 150.0
|
||||
offset_bottom = 159.0
|
||||
offset_left = 363.0
|
||||
offset_top = 84.0
|
||||
offset_right = 663.0
|
||||
offset_bottom = 144.0
|
||||
grow_horizontal = 2
|
||||
|
||||
[node name="HostBannerLabel" type="Label" parent="LobbyPanel/HostBanner" unique_id=1011182924]
|
||||
@@ -418,10 +417,10 @@ anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -450.0
|
||||
offset_top = -120.0
|
||||
offset_right = 450.0
|
||||
offset_bottom = 200.0
|
||||
offset_left = -678.0
|
||||
offset_top = -299.0
|
||||
offset_right = 222.0
|
||||
offset_bottom = 21.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_constants/separation = 30
|
||||
@@ -488,7 +487,6 @@ text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayerSlot2" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=1012954493]
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
@@ -550,7 +548,6 @@ text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayerSlot3" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=1033758492]
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
@@ -612,7 +609,6 @@ text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayerSlot4" type="VBoxContainer" parent="LobbyPanel/PlayersContainer" unique_id=62963750]
|
||||
visible = false
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
@@ -673,6 +669,264 @@ theme_override_font_sizes/font_size = 12
|
||||
text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayersContainer2" type="HBoxContainer" parent="LobbyPanel" unique_id=76585227]
|
||||
layout_mode = 1
|
||||
anchors_preset = 3
|
||||
anchor_left = 1.0
|
||||
anchor_top = 1.0
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -770.0
|
||||
offset_top = -356.0
|
||||
offset_right = -38.0
|
||||
offset_bottom = -132.0
|
||||
grow_horizontal = 0
|
||||
grow_vertical = 0
|
||||
|
||||
[node name="PlayerSlot5" type="VBoxContainer" parent="LobbyPanel/PlayersContainer2" unique_id=1217356581]
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
alignment = 1
|
||||
|
||||
[node name="PlayerName5" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot5" unique_id=1274835923]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 1, 1, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "Player 5"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CharacterPreview5" type="TextureRect" parent="LobbyPanel/PlayersContainer2/PlayerSlot5" unique_id=2028052012]
|
||||
custom_minimum_size = Vector2(140, 140)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="CharacterNav5" type="HBoxContainer" parent="LobbyPanel/PlayersContainer2/PlayerSlot5" unique_id=955633493]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="CharLeftBtn5" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot5/CharacterNav5" unique_id=1774553781]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "◀"
|
||||
|
||||
[node name="CharacterName5" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot5/CharacterNav5" unique_id=1718870722]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CharRightBtn5" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot5/CharacterNav5" unique_id=766449735]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "▶"
|
||||
|
||||
[node name="CharacterNameLabel5" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot5" unique_id=1436179077]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ReadyStatus5" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot5" unique_id=1075029896]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayerSlot6" type="VBoxContainer" parent="LobbyPanel/PlayersContainer2" unique_id=1038068961]
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
alignment = 1
|
||||
|
||||
[node name="PlayerName6" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot6" unique_id=2146003972]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 1, 1, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "Player 6"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CharacterPreview6" type="TextureRect" parent="LobbyPanel/PlayersContainer2/PlayerSlot6" unique_id=786683689]
|
||||
custom_minimum_size = Vector2(140, 140)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="CharacterNav6" type="HBoxContainer" parent="LobbyPanel/PlayersContainer2/PlayerSlot6" unique_id=344279994]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="CharLeftBtn6" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot6/CharacterNav6" unique_id=1348787091]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "◀"
|
||||
|
||||
[node name="CharacterName6" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot6/CharacterNav6" unique_id=816635166]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CharRightBtn6" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot6/CharacterNav6" unique_id=989121448]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "▶"
|
||||
|
||||
[node name="CharacterNameLabel6" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot6" unique_id=2048468168]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ReadyStatus6" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot6" unique_id=1888412229]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayerSlot7" type="VBoxContainer" parent="LobbyPanel/PlayersContainer2" unique_id=1161417031]
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
alignment = 1
|
||||
|
||||
[node name="PlayerName7" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot7" unique_id=705333888]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 1, 1, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "Player 4"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CharacterPreview7" type="TextureRect" parent="LobbyPanel/PlayersContainer2/PlayerSlot7" unique_id=2051783230]
|
||||
custom_minimum_size = Vector2(140, 140)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="CharacterNav7" type="HBoxContainer" parent="LobbyPanel/PlayersContainer2/PlayerSlot7" unique_id=154400222]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="CharLeftBtn7" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot7/CharacterNav7" unique_id=767340905]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "◀"
|
||||
|
||||
[node name="CharacterName7" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot7/CharacterNav7" unique_id=1897622173]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CharRightBtn7" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot7/CharacterNav7" unique_id=981330220]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "▶"
|
||||
|
||||
[node name="CharacterNameLabel7" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot7" unique_id=1783984199]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ReadyStatus7" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot7" unique_id=2098796095]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="PlayerSlot8" type="VBoxContainer" parent="LobbyPanel/PlayersContainer2" unique_id=2019344700]
|
||||
custom_minimum_size = Vector2(180, 0)
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
alignment = 1
|
||||
|
||||
[node name="PlayerName8" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot8" unique_id=13133480]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(1, 1, 1, 1)
|
||||
theme_override_font_sizes/font_size = 16
|
||||
text = "Player 4"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="CharacterPreview8" type="TextureRect" parent="LobbyPanel/PlayersContainer2/PlayerSlot8" unique_id=2109465785]
|
||||
custom_minimum_size = Vector2(140, 140)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
expand_mode = 1
|
||||
stretch_mode = 5
|
||||
|
||||
[node name="CharacterNav8" type="HBoxContainer" parent="LobbyPanel/PlayersContainer2/PlayerSlot8" unique_id=429359375]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
alignment = 1
|
||||
|
||||
[node name="CharLeftBtn8" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot8/CharacterNav8" unique_id=1934659357]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "◀"
|
||||
|
||||
[node name="CharacterName8" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot8/CharacterNav8" unique_id=1417755564]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="CharRightBtn8" type="Button" parent="LobbyPanel/PlayersContainer2/PlayerSlot8/CharacterNav8" unique_id=513653330]
|
||||
custom_minimum_size = Vector2(40, 36)
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 18
|
||||
text = "▶"
|
||||
|
||||
[node name="CharacterNameLabel8" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot8" unique_id=594360558]
|
||||
custom_minimum_size = Vector2(80, 0)
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.992, 0.796, 0.047, 1)
|
||||
theme_override_font_sizes/font_size = 14
|
||||
text = "Bob"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="ReadyStatus8" type="Label" parent="LobbyPanel/PlayersContainer2/PlayerSlot8" unique_id=434057613]
|
||||
layout_mode = 2
|
||||
theme_override_colors/font_color = Color(0.6, 0.6, 0.6, 1)
|
||||
theme_override_font_sizes/font_size = 12
|
||||
text = "NOT READY"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[node name="AreaSelector" type="HBoxContainer" parent="LobbyPanel" unique_id=696178336]
|
||||
clip_contents = true
|
||||
layout_mode = 1
|
||||
|
||||
+64
-46
@@ -1234,12 +1234,21 @@ func _show_game_over_panel():
|
||||
player_scores.sort_custom(func(a, b): return a.score > b.score)
|
||||
|
||||
# Display each player
|
||||
for i in range(min(player_scores.size(), 4)):
|
||||
for i in range(min(player_scores.size(), 8)):
|
||||
var entry = HBoxContainer.new()
|
||||
entry.add_theme_constant_override("separation", 20)
|
||||
|
||||
var rank_colors = [Color(1.0, 0.84, 0.0), Color(0.75, 0.75, 0.75), Color(0.8, 0.5, 0.2), Color(0.5, 0.5, 0.5)]
|
||||
var rank_emojis = ["🥇", "🥈", "🥉", "4th"]
|
||||
var rank_colors = [
|
||||
Color(1.0, 0.84, 0.0), # Gold
|
||||
Color(0.75, 0.75, 0.75), # Silver
|
||||
Color(0.8, 0.5, 0.2), # Bronze
|
||||
Color(0.5, 0.5, 0.5), # 4th
|
||||
Color(0.5, 0.5, 0.5), # 5th
|
||||
Color(0.5, 0.5, 0.5), # 6th
|
||||
Color(0.5, 0.5, 0.5), # 7th
|
||||
Color(0.5, 0.5, 0.5) # 8th
|
||||
]
|
||||
var rank_emojis = ["🥇", "🥈", "🥉", "4th", "5th", "6th", "7th", "8th"]
|
||||
|
||||
var rank_label = Label.new()
|
||||
rank_label.text = rank_emojis[i]
|
||||
@@ -1349,33 +1358,7 @@ func sync_leaderboard_data(player_data: Array):
|
||||
player_data.sort_custom(func(a, b): return a.score > b.score)
|
||||
|
||||
# Update entries
|
||||
for i in range(4):
|
||||
var entry = vbox.get_node_or_null("Entry" + str(i + 1))
|
||||
if not entry:
|
||||
continue
|
||||
|
||||
if i < player_data.size():
|
||||
var data = player_data[i]
|
||||
var rank_label = entry.get_node_or_null("RankLabel")
|
||||
var name_label = entry.get_node_or_null("NameLabel")
|
||||
var score_label = entry.get_node_or_null("ScoreLabel")
|
||||
|
||||
if rank_label:
|
||||
rank_label.text = _get_ordinal(i + 1)
|
||||
if name_label:
|
||||
name_label.text = str(data.name)
|
||||
if score_label:
|
||||
score_label.text = str(data.score)
|
||||
|
||||
entry.visible = true
|
||||
|
||||
# Highlight check
|
||||
if data.peer_id == multiplayer.get_unique_id():
|
||||
entry.modulate = Color(1.0, 1.0, 0.0) # Yellow
|
||||
else:
|
||||
entry.modulate = Color.WHITE
|
||||
else:
|
||||
entry.visible = false
|
||||
_render_leaderboard_entries(player_data)
|
||||
|
||||
func _update_leaderboard_display():
|
||||
var leaderboard_panel = get_node_or_null("LeaderboardPanel")
|
||||
@@ -1402,30 +1385,66 @@ func _update_leaderboard_display():
|
||||
# Sort by score descending
|
||||
player_data.sort_custom(func(a, b): return a.score > b.score)
|
||||
|
||||
# Update entries
|
||||
for i in range(4): # Max 4 entries
|
||||
var entry = vbox.get_node_or_null("Entry" + str(i + 1))
|
||||
if not entry:
|
||||
continue
|
||||
_render_leaderboard_entries(player_data)
|
||||
|
||||
func _render_leaderboard_entries(sorted_player_data: Array):
|
||||
var leaderboard_panel = get_node_or_null("LeaderboardPanel")
|
||||
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
|
||||
|
||||
var my_id = multiplayer.get_unique_id()
|
||||
var my_index = -1
|
||||
for i in range(sorted_player_data.size()):
|
||||
if sorted_player_data[i].peer_id == my_id:
|
||||
my_index = i
|
||||
break
|
||||
|
||||
# Determine items to display (Max 4 slots for HUD)
|
||||
var items_to_display = []
|
||||
|
||||
# add top 3
|
||||
for i in range(min(3, sorted_player_data.size())):
|
||||
items_to_display.append({"data": sorted_player_data[i], "rank": i + 1})
|
||||
|
||||
if i < player_data.size():
|
||||
var data = player_data[i]
|
||||
# add 4th slot (Smart Slot)
|
||||
if sorted_player_data.size() >= 4:
|
||||
# If local player is outside top 3 (index > 2), show them in 4th slot
|
||||
# But if they are exactly 4th (index 3), it's the same as showing 4th place.
|
||||
# If they are 5th (index 4) or worse, we replace 4th place with them.
|
||||
|
||||
if my_index > 3:
|
||||
# Show local player
|
||||
items_to_display.append({"data": sorted_player_data[my_index], "rank": my_index + 1})
|
||||
else:
|
||||
# Show standard 4th place
|
||||
items_to_display.append({"data": sorted_player_data[3], "rank": 4})
|
||||
|
||||
# Render
|
||||
# We assume the HUD has 4 slots max, but code iterates up to 8 just in case UI has more and we want to hide them.
|
||||
for i in range(8):
|
||||
var entry = vbox.get_node_or_null("Entry" + str(i + 1))
|
||||
if not entry: continue
|
||||
|
||||
# Only show up to 4 entries in this new "Smart" mode
|
||||
if i < items_to_display.size() and i < 4:
|
||||
var item = items_to_display[i]
|
||||
var data = item.data
|
||||
var rank = item.rank
|
||||
|
||||
var rank_label = entry.get_node_or_null("RankLabel")
|
||||
var name_label = entry.get_node_or_null("NameLabel")
|
||||
var score_label = entry.get_node_or_null("ScoreLabel")
|
||||
|
||||
if rank_label:
|
||||
rank_label.text = _get_ordinal(i + 1)
|
||||
if name_label:
|
||||
name_label.text = str(data.name)
|
||||
if score_label:
|
||||
score_label.text = str(data.score)
|
||||
if rank_label: rank_label.text = _get_ordinal(rank)
|
||||
if name_label: name_label.text = str(data.name)
|
||||
if score_label: score_label.text = str(data.score)
|
||||
|
||||
entry.visible = true
|
||||
|
||||
# Highlight check
|
||||
if data.peer_id == multiplayer.get_unique_id():
|
||||
if data.peer_id == my_id:
|
||||
entry.modulate = Color(1.0, 1.0, 0.0) # Yellow
|
||||
else:
|
||||
entry.modulate = Color.WHITE
|
||||
@@ -1437,7 +1456,6 @@ func _get_ordinal(n: int) -> String:
|
||||
1: return "1st"
|
||||
2: return "2nd"
|
||||
3: return "3rd"
|
||||
4: return "4th"
|
||||
_: return str(n) + "th"
|
||||
|
||||
# =============================================================================
|
||||
|
||||
@@ -6,7 +6,7 @@ signal game_started()
|
||||
signal game_state_changed()
|
||||
|
||||
@export var enable_bots: bool = true
|
||||
@export var max_players: int = 4
|
||||
@export var max_players: int = 8
|
||||
|
||||
var players: Array = []
|
||||
var bots: Array = []
|
||||
|
||||
Reference in New Issue
Block a user