feat: update 2.1.9

This commit is contained in:
2026-04-29 01:36:49 +08:00
parent 1585b91509
commit 8a2f865ad8
76 changed files with 2628 additions and 39 deletions
+121
View File
@@ -93,8 +93,16 @@ var doors_goals_option: OptionButton
@onready var leave_btn = $LobbyPanel/BottomBar/LeaveBtn
@onready var ready_btn = $LobbyPanel/BottomBar/ReadyBtn
@onready var start_game_btn = $LobbyPanel/BottomBar/StartGameBtn
var invite_btn: Button
@onready var status_label = $LobbyPanel/StatusLabel
# Social Panel instance
var social_panel_instance: Control
# Lobby invite popup
var _invite_popup: AcceptDialog
var _pending_invite_match_id: String = ""
# UI References - Status
@onready var connection_status = $StatusBar/ConnectionStatus
@@ -175,6 +183,11 @@ func _ready():
if quit_btn:
quit_btn.pressed.connect(_on_quit_pressed)
# Social button (main menu) - connect if node exists
var social_btn = get_node_or_null("%SocialBtn")
if social_btn:
social_btn.pressed.connect(_on_social_pressed)
# Connect Server Selection signals
if server_option:
server_option.item_selected.connect(_on_server_option_selected)
@@ -258,6 +271,12 @@ func _ready():
if chat_input:
chat_input.text_submitted.connect(func(_t): _on_chat_send_pressed())
# Connect Social / Friend UI
invite_btn = get_node_or_null("LobbyPanel/BottomBar/InviteBtn")
if invite_btn:
invite_btn.pressed.connect(_on_invite_friends_pressed)
FriendManager.lobby_invite_received.connect(_on_lobby_invite_received)
# Set initial title if already loaded
_on_profile_updated()
@@ -1075,6 +1094,24 @@ func _update_player_slots() -> void:
ready_label.text = "READY ✓" if is_ready else "NOT READY"
ready_label.add_theme_color_override("font_color",
Color(0.4, 0.8, 0.4) if is_ready else Color(0.6, 0.6, 0.6))
# + Friend button — node must exist in lobby.tscn as "AddFriendBtn1", "AddFriendBtn2"...
var player_nakama_id: String = player.get("nakama_id", "")
var my_nakama_id: String = NakamaManager.session.user_id if NakamaManager.session else ""
var add_friend_btn: Button = slot.get_node_or_null("AddFriendBtn%d" % slot_num)
if add_friend_btn:
if player_nakama_id.is_empty() or player_nakama_id == my_nakama_id:
add_friend_btn.visible = false
else:
add_friend_btn.visible = true
if FriendManager.is_friend(player_nakama_id):
add_friend_btn.text = "Friend ✓"
add_friend_btn.disabled = true
else:
add_friend_btn.text = "+ Friend"
add_friend_btn.disabled = false
if not add_friend_btn.pressed.is_connected(func(): _on_add_friend_pressed(player_nakama_id)):
add_friend_btn.pressed.connect(func(): _on_add_friend_pressed(player_nakama_id))
else:
# Empty slot - show as bot placeholder
slot.visible = true
@@ -1112,6 +1149,11 @@ func _update_player_slots() -> void:
if ready_label:
ready_label.text = "WAITING..."
ready_label.add_theme_color_override("font_color", Color(0.5, 0.5, 0.7))
# Hide friend button for bots/empty slots
var add_friend_btn: Button = slot.get_node_or_null("AddFriendBtn%d" % slot_num)
if add_friend_btn:
add_friend_btn.visible = false
_update_status()
@@ -1158,6 +1200,85 @@ func _apply_loadout_character() -> void:
print("[Lobby] Loadout character applied: ", saved_char)
# =============================================================================
# Social / Friend Functions
# =============================================================================
func _on_add_friend_pressed(nakama_id: String) -> void:
var ok = await FriendManager.add_friend_by_id(nakama_id)
if ok:
_update_player_slots()
func _on_invite_friends_pressed() -> void:
"""Open the invite friends dialog (scene-based)."""
var match_id = current_match_id
if match_id.is_empty():
return
var friends = FriendManager.get_mutual_friends()
var scene = load("res://scenes/ui/invite_friends_dialog.tscn") as PackedScene
if not scene:
return
var dialog = scene.instantiate()
add_child(dialog)
dialog.open(friends, match_id)
dialog.closed.connect(dialog.queue_free)
func _on_lobby_invite_received(from_user_id: String, from_name: String, match_id: String) -> void:
"""Show invite notification popup. Only shown if not already in a game."""
if get_tree().current_scene.scene_file_path != "res://scenes/lobby.tscn":
return
if lobby_panel and lobby_panel.visible:
return
if _invite_popup:
_invite_popup.queue_free()
_pending_invite_match_id = match_id
var scene = load("res://scenes/ui/lobby_invite_popup.tscn") as PackedScene
if scene:
_invite_popup = scene.instantiate()
add_child(_invite_popup)
_invite_popup.setup(from_name)
_invite_popup.accepted.connect(_on_invite_accepted)
_invite_popup.declined.connect(func(): _invite_popup.queue_free())
_invite_popup.popup_centered()
else:
# Fallback if scene not yet added to project
var dlg := AcceptDialog.new()
dlg.title = "Lobby Invitation"
dlg.dialog_text = "%s invited you!\nJoin?" % from_name
dlg.ok_button_text = "Join"
dlg.add_cancel_button("Decline")
add_child(dlg)
dlg.confirmed.connect(_on_invite_accepted)
dlg.canceled.connect(dlg.queue_free)
dlg.popup_centered()
_invite_popup = dlg
func _on_invite_accepted() -> void:
if not _pending_invite_match_id.is_empty():
LobbyManager.join_room(_pending_invite_match_id)
if _invite_popup:
_invite_popup.queue_free()
_pending_invite_match_id = ""
func _on_social_pressed() -> void:
"""Open social / friend list panel."""
if not social_panel_instance:
var scene = load("res://scenes/ui/social_panel.tscn")
if scene:
social_panel_instance = scene.instantiate()
social_panel_instance.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
add_child(social_panel_instance)
if social_panel_instance.has_signal("closed"):
social_panel_instance.closed.connect(func():
social_panel_instance.hide()
if main_menu_panel: main_menu_panel.show()
)
if social_panel_instance:
if main_menu_panel: main_menu_panel.hide()
social_panel_instance.show()
# =============================================================================
# Global Chat System
# =============================================================================