Files
tekton/scenes/ui/lobby_main_menu.gd
T
adtpdn decdb74ade chore: release version 2.3.5 and refactor lobby
Bump export_presets.cfg version to 2.3.5. Update CHANGELOG_DRAFT.md.
Refactor lobby.gd into LobbyChat, LobbyMainMenu, LobbyRoomList, LobbyRoom.
Move Nakama config to environment variables in nakama_manager.gd.
Derive auth_manager.gd encryption key from OS.get_unique_id().sha256_text().
Remove Steam email auth fallback. Require auth ticket.
Make GachaManager.pull() async in gacha_panel.gd.
Remove dummy wallet seeding. Add store_type to IAP payload.
Validate IAP receipts server-side in economy.lua.
Register gacha module in main.lua.
Clean backend_service.gd stubs.
Fix featured_banners type safety in gacha_manager.gd. Guards non-array responses.
Move tiles_armagedon_a1.res to assets/models/meshes/. Fix import fallback_path.
2026-05-22 12:08:11 +08:00

331 lines
12 KiB
GDScript

class_name LobbyMainMenu
extends RefCounted
var lobby: Control
func _init(p_lobby: Control):
lobby = p_lobby
if lobby.create_room_btn:
lobby.create_room_btn.pressed.connect(on_create_room_pressed)
if lobby.browse_rooms_btn:
lobby.browse_rooms_btn.pressed.connect(on_browse_rooms_pressed)
if lobby.tutorial_btn:
lobby.tutorial_btn.pressed.connect(on_tutorial_pressed)
if lobby.main_menu_profile_btn:
lobby.main_menu_profile_btn.pressed.connect(on_profile_btn_pressed)
if lobby.top_right_profile_btn:
lobby.top_right_profile_btn.pressed.connect(on_profile_btn_pressed)
if lobby.mailbox_btn:
lobby.mailbox_btn.pressed.connect(on_mailbox_pressed)
if lobby.lobby_settings_btn:
lobby.lobby_settings_btn.pressed.connect(on_settings_pressed)
if lobby.shop_btn:
lobby.shop_btn.pressed.connect(on_shop_pressed)
if lobby.banner1_btn:
lobby.banner1_btn.disabled = false
lobby.banner1_btn.text = "✨ Gacha"
lobby.banner1_btn.pressed.connect(on_banner1_pressed)
if lobby.leaderboard_btn:
lobby.leaderboard_btn.pressed.connect(on_leaderboard_pressed)
if lobby.ticket_btn:
lobby.ticket_btn.pressed.connect(on_ticket_pressed)
if lobby.quit_btn:
lobby.quit_btn.pressed.connect(on_quit_pressed)
var social_btn = lobby.get_node_or_null("%SocialBtn")
if social_btn:
social_btn.pressed.connect(on_social_pressed)
if lobby.logout_btn:
lobby.logout_btn.pressed.connect(on_logout_pressed)
# Connect Play Tab mode buttons
var free_mode_btn = lobby.get_node_or_null("%FreeModeBtn")
var stop_n_go_btn = lobby.get_node_or_null("%StopNGoBtn")
if free_mode_btn:
free_mode_btn.pressed.connect(func(): host_room("Freemode"))
if stop_n_go_btn:
stop_n_go_btn.pressed.connect(func(): host_room("Stop n Go"))
func on_tutorial_pressed() -> void:
if AuthManager.is_guest:
if LobbyManager.local_player_name.is_empty() or LobbyManager.local_player_name == "Player":
LobbyManager.local_player_name = NameGenerator.generate_guest_name()
else:
LobbyManager.local_player_name = UserProfileManager.get_display_name()
lobby.connection_status.text = "Starting Tutorial Scenario..."
lobby._apply_loadout_character()
LobbyManager.start_tutorial("Freemode")
await lobby.get_tree().process_frame
await lobby.get_tree().process_frame
LobbyManager.start_game(true)
func on_create_room_pressed() -> void:
lobby._show_panel("room_list")
var tabs = lobby.get_node_or_null("%RoomListTabs")
if tabs:
tabs.current_tab = 0
if lobby.get_node_or_null("%PlayTabSideBtn"): lobby.get_node("%PlayTabSideBtn").button_pressed = true
if lobby.get_node_or_null("%RoomTabSideBtn"): lobby.get_node("%RoomTabSideBtn").button_pressed = false
lobby._sync_room_profile_card()
func host_room(game_mode: String) -> void:
if AuthManager.is_guest:
if LobbyManager.local_player_name.is_empty() or LobbyManager.local_player_name == "Player":
LobbyManager.local_player_name = NameGenerator.generate_guest_name()
else:
LobbyManager.local_player_name = UserProfileManager.get_display_name()
if not game_mode.is_empty():
LobbyManager.game_mode = game_mode
LobbyManager._update_available_areas(game_mode)
lobby._apply_loadout_character()
var mode_prefix := "[%s] " % game_mode if not game_mode.is_empty() else ""
if LobbyManager.is_lan_mode:
lobby.connection_status.text = "Starting LAN room..."
var room_label := "%sLAN Room %d" % [mode_prefix, randi_range(100, 999)]
var ok = await LobbyManager.create_room_lan(room_label)
if not ok:
lobby.connection_status.text = "Failed to start LAN room. Check port 7777."
else:
lobby.connection_status.text = "Creating Nakama room..."
var room_label := "%sRoom %d" % [mode_prefix, randi_range(1000, 9999)]
LobbyManager.create_room(room_label)
func on_browse_rooms_pressed() -> void:
lobby._show_panel("room_list")
var tabs = lobby.get_node_or_null("%RoomListTabs")
if tabs:
tabs.current_tab = 1
if lobby.get_node_or_null("%PlayTabSideBtn"): lobby.get_node("%PlayTabSideBtn").button_pressed = false
if lobby.get_node_or_null("%RoomTabSideBtn"): lobby.get_node("%RoomTabSideBtn").button_pressed = true
lobby._sync_room_profile_card()
var match_id_label = lobby.get_node_or_null("%RoomListPanel/RoomListTabs/RoomTab/HBoxContainer/RightCol/MatchIdLabel")
if LobbyManager.is_lan_mode:
lobby.connection_status.text = "LAN Mode - Enter Host IP to join"
lobby.match_id_input.placeholder_text = "Enter Host IP (e.g. 192.168.1.10)..."
if match_id_label: match_id_label.text = "DIRECT CONNECT (HOST IP)"
lobby._on_refresh_pressed()
else:
lobby.connection_status.text = "Loading Nakama rooms..."
lobby.match_id_input.placeholder_text = "Paste match ID here..."
if match_id_label: match_id_label.text = "DIRECT CONNECT (MATCH ID)"
LobbyManager.refresh_room_list()
func on_profile_btn_pressed() -> void:
if not lobby.profile_panel_instance:
var profile_panel_scene := load("res://scenes/ui/profile_panel.tscn")
lobby.profile_panel_instance = profile_panel_scene.instantiate()
lobby.profile_panel_instance.closed.connect(func():
lobby.profile_panel_instance.hide()
if lobby.main_menu_panel:
lobby.main_menu_panel.show()
)
lobby.profile_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
lobby.add_child(lobby.profile_panel_instance)
if lobby.profile_panel_instance:
if lobby.main_menu_panel:
lobby.main_menu_panel.hide()
lobby.profile_panel_instance.show_panel()
func on_mailbox_pressed() -> void:
if not lobby._mailbox_panel_instance:
var scene = load("res://scenes/ui/mailbox_panel.tscn")
if scene:
lobby._mailbox_panel_instance = scene.instantiate()
lobby._mailbox_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
var cl := CanvasLayer.new()
cl.layer = 100
cl.name = "MailboxCanvasLayer"
lobby.add_child(cl)
cl.add_child(lobby._mailbox_panel_instance)
if lobby._mailbox_panel_instance.has_signal("closed"):
lobby._mailbox_panel_instance.closed.connect(func():
lobby._mailbox_panel_instance.get_parent().queue_free()
lobby._mailbox_panel_instance = null
)
if lobby._mailbox_panel_instance:
lobby._mailbox_panel_instance.show_panel()
func on_settings_pressed():
var settings_menu = lobby.get_node_or_null("SettingsMenu")
if not settings_menu:
var scene = load("res://scenes/ui/settings_menu.tscn")
if scene:
settings_menu = scene.instantiate()
settings_menu.name = "SettingsMenu"
lobby.add_child(settings_menu)
var close_btn = settings_menu.get_node_or_null("PanelContainer/VBoxContainer/Header/CloseButton")
if close_btn:
close_btn.pressed.connect(func():
restore_after_settings()
)
if settings_menu:
settings_menu.set_meta("from_lobby", lobby.lobby_panel.visible if lobby.lobby_panel else false)
lobby.main_menu_panel.hide()
if lobby.lobby_panel: lobby.lobby_panel.hide()
settings_menu.open()
func restore_after_settings() -> void:
var settings_menu = lobby.get_node_or_null("SettingsMenu")
var from_lobby: bool = settings_menu.get_meta("from_lobby", false) if settings_menu else false
if from_lobby:
if lobby.lobby_panel: lobby.lobby_panel.show()
else:
if lobby.main_menu_panel: lobby.main_menu_panel.show()
func on_shop_pressed() -> void:
if not NakamaManager.session:
lobby.connection_status.text = "Must be logged in"
return
if not lobby.shop_panel_instance:
var shop_scene = load("res://scenes/ui/shop_panel.tscn")
if shop_scene:
lobby.shop_panel_instance = shop_scene.instantiate()
lobby.add_child(lobby.shop_panel_instance)
lobby.shop_panel_instance.closed.connect(func(): if lobby.main_menu_panel: lobby.main_menu_panel.show())
if lobby.shop_panel_instance:
if lobby.main_menu_panel: lobby.main_menu_panel.hide()
lobby.shop_panel_instance.show_panel()
func on_banner1_pressed() -> void:
var gacha_scene = load("res://scenes/ui/gacha_panel.tscn")
if not gacha_scene:
lobby.connection_status.text = "Gacha panel not found"
return
var gacha = gacha_scene.instantiate()
gacha.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
lobby.add_child(gacha)
if lobby.main_menu_panel: lobby.main_menu_panel.hide()
if gacha.has_signal("closed"):
gacha.closed.connect(func():
gacha.queue_free()
if lobby.main_menu_panel: lobby.main_menu_panel.show()
)
else:
var back = gacha.get_node_or_null("%BackBtn")
if back:
back.pressed.connect(func():
gacha.queue_free()
if lobby.main_menu_panel: lobby.main_menu_panel.show()
)
func on_leaderboard_pressed() -> void:
if not lobby.leaderboard_panel_instance:
var leaderboard_panel_scene := load("res://scenes/ui/leaderboard_panel.tscn")
if leaderboard_panel_scene:
lobby.leaderboard_panel_instance = leaderboard_panel_scene.instantiate()
lobby.leaderboard_panel_instance.closed.connect(func():
lobby.leaderboard_panel_instance.hide()
if lobby.main_menu_panel:
lobby.main_menu_panel.show()
)
lobby.leaderboard_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
lobby.add_child(lobby.leaderboard_panel_instance)
if lobby.leaderboard_panel_instance:
if lobby.main_menu_panel:
lobby.main_menu_panel.hide()
lobby.leaderboard_panel_instance.show_panel()
func on_ticket_pressed() -> void:
if not NakamaManager.session:
lobby.connection_status.text = "Must be logged in"
return
if not lobby.daily_reward_panel_instance:
var scene = load("res://scenes/ui/daily_reward_panel.tscn")
if scene:
lobby.daily_reward_panel_instance = scene.instantiate()
lobby.daily_reward_panel_instance.closed.connect(func():
if lobby.main_menu_panel: lobby.main_menu_panel.show()
)
lobby.add_child(lobby.daily_reward_panel_instance)
if lobby.daily_reward_panel_instance:
if lobby.main_menu_panel:
lobby.main_menu_panel.hide()
lobby.daily_reward_panel_instance.show_panel()
func on_social_pressed() -> void:
if not lobby.social_panel_instance:
var scene = load("res://scenes/ui/social_panel.tscn")
if scene:
lobby.social_panel_instance = scene.instantiate()
lobby.social_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
var cl := CanvasLayer.new()
cl.layer = 100
cl.name = "SocialCanvasLayer"
lobby.add_child(cl)
cl.add_child(lobby.social_panel_instance)
if lobby.social_panel_instance.has_signal("dm_requested"):
lobby.social_panel_instance.dm_requested.connect(func(user_id, username):
lobby.social_panel_instance.hide()
lobby.chat._open_dm_tab(user_id, username)
if lobby.main_menu_panel:
var main_hbox = lobby.main_menu_panel.get_node_or_null("MainMargin/MainHBox")
if main_hbox:
var left_col = main_hbox.get_node_or_null("LeftCol")
if left_col:
for child in left_col.get_children():
child.show()
var right_col = main_hbox.get_node_or_null("RightCol")
if right_col: right_col.show()
)
if lobby.social_panel_instance.has_signal("closed"):
lobby.social_panel_instance.closed.connect(func():
lobby.social_panel_instance.hide()
if lobby.main_menu_panel:
var main_hbox = lobby.main_menu_panel.get_node_or_null("MainMargin/MainHBox")
if main_hbox:
var left_col = main_hbox.get_node_or_null("LeftCol")
if left_col:
for child in left_col.get_children():
child.show()
var right_col = main_hbox.get_node_or_null("RightCol")
if right_col: right_col.show()
)
if lobby.social_panel_instance:
if lobby.main_menu_panel:
var main_hbox = lobby.main_menu_panel.get_node_or_null("MainMargin/MainHBox")
if main_hbox:
var left_col = main_hbox.get_node_or_null("LeftCol")
if left_col:
for child in left_col.get_children():
if child.name not in ["ChatPanel", "HBoxContainer", "SpacerMiddle"]:
child.hide()
var right_col = main_hbox.get_node_or_null("RightCol")
if right_col: right_col.hide()
lobby.social_panel_instance.show()
func on_logout_pressed() -> void:
AuthManager.logout()
go_to_login()
func on_quit_pressed() -> void:
print("[Lobby] Quitting game...")
lobby.get_tree().quit()
func go_to_login() -> void:
if lobby.get_tree():
lobby.get_tree().change_scene_to_file("res://scenes/ui/login_screen.tscn")