forked from xiangwang25/whale-town-front-v2
570 lines
23 KiB
GDScript
570 lines
23 KiB
GDScript
extends Control
|
|
|
|
# ============================================================================
|
|
# PlayerHud.gd - 右上角玩家头像与快捷入口
|
|
# ============================================================================
|
|
# 展示当前玩家头像入口,以及地图/任务/背包/好友/设置入口。
|
|
# 好友入口只负责打开或收起右下角好友列表。
|
|
# ============================================================================
|
|
|
|
const HUD_MARGIN: Vector2 = Vector2(16, 16)
|
|
const SHORTCUT_BAR_SIZE: Vector2 = Vector2(406, 86)
|
|
const PLAYER_PROFILE_BUTTON_SIZE: Vector2 = Vector2(210, 78)
|
|
const PLAYER_AVATAR_SIZE: Vector2 = Vector2(58, 58)
|
|
const HUD_SEPARATION: int = 18
|
|
const HUD_TOTAL_WIDTH: float = SHORTCUT_BAR_SIZE.x + PLAYER_PROFILE_BUTTON_SIZE.x + HUD_SEPARATION
|
|
const TEXT_COLOR: Color = Color(0.188, 0.294, 0.424)
|
|
const MUTED_COLOR: Color = Color(0.560, 0.639, 0.733)
|
|
const ACCENT_COLOR: Color = Color(0.258824, 0.627451, 0.913725)
|
|
const WALLET_REFRESH_INTERVAL: float = 15.0
|
|
const HUD_SHORTCUT_ICON_SCRIPT: Script = preload("res://scenes/ui/HudShortcutIcon.gd")
|
|
|
|
var _usernameLabel: Label
|
|
var _walletLabel: Label
|
|
var _avatarLabel: Label
|
|
var _avatarPanel: PanelContainer
|
|
var _walletRefreshTimer: Timer
|
|
var _taskShortcutButton: Button
|
|
var _taskRewardBadge: Label
|
|
|
|
var _currentUsername: String = "玩家"
|
|
var _walletBalance: int = 0
|
|
var _walletLoaded: bool = false
|
|
var _walletLoading: bool = false
|
|
|
|
func _ready() -> void:
|
|
mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_build_ui()
|
|
_build_wallet_refresh_timer()
|
|
_subscribe_to_events()
|
|
_load_current_user()
|
|
_refresh_wallet()
|
|
|
|
func _exit_tree() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("disconnect_event", EventNames.CHAT_LOGIN_SUCCESS, _on_chat_login_success, self)
|
|
eventSystem.call("disconnect_event", EventNames.AUTH_LOGIN_SUCCESS, _on_auth_login_success, self)
|
|
eventSystem.call("disconnect_event", EventNames.AUTH_REGISTER_SUCCESS, _on_auth_register_success, self)
|
|
eventSystem.call("disconnect_event", EventNames.AUTH_LOGOUT, _on_auth_logout, self)
|
|
eventSystem.call("disconnect_event", EventNames.APPEARANCE_AVATAR_CHANGED, _on_appearance_avatar_changed, self)
|
|
eventSystem.call("disconnect_event", EventNames.MALL_PURCHASE_SUCCEEDED, _on_wallet_mutation_event, self)
|
|
eventSystem.call("disconnect_event", EventNames.CAFE_COMPANION_CHAT_TIME_PURCHASED, _on_wallet_mutation_event, self)
|
|
eventSystem.call("disconnect_event", EventNames.CAFE_COMPANION_EMPLOYMENT_RESIGNED, _on_wallet_mutation_event, self)
|
|
var playerStateManager := get_node_or_null("/root/PlayerStateManager")
|
|
if playerStateManager != null and playerStateManager.has_signal("wallet_changed"):
|
|
var walletCallback := Callable(self, "_on_player_wallet_changed")
|
|
if playerStateManager.is_connected("wallet_changed", walletCallback):
|
|
playerStateManager.disconnect("wallet_changed", walletCallback)
|
|
var authManager := get_node_or_null("/root/AuthManager")
|
|
if authManager != null and authManager.has_signal("auth_state_changed"):
|
|
var callback := Callable(self, "_on_auth_state_changed")
|
|
if authManager.is_connected("auth_state_changed", callback):
|
|
authManager.disconnect("auth_state_changed", callback)
|
|
var taskManager := get_node_or_null("/root/TaskManager")
|
|
if taskManager != null and taskManager.has_signal("board_changed"):
|
|
var taskCallback := Callable(self, "_on_task_board_changed")
|
|
if taskManager.is_connected("board_changed", taskCallback):
|
|
taskManager.disconnect("board_changed", taskCallback)
|
|
|
|
func _build_ui() -> void:
|
|
var rootRow := HBoxContainer.new()
|
|
rootRow.name = "HudRoot"
|
|
rootRow.set_anchors_preset(Control.PRESET_TOP_RIGHT)
|
|
rootRow.offset_left = -HUD_TOTAL_WIDTH - HUD_MARGIN.x
|
|
rootRow.offset_top = HUD_MARGIN.y
|
|
rootRow.offset_right = -HUD_MARGIN.x
|
|
rootRow.add_theme_constant_override("separation", HUD_SEPARATION)
|
|
add_child(rootRow)
|
|
|
|
rootRow.add_child(_build_shortcut_bar())
|
|
rootRow.add_child(_build_player_avatar_button())
|
|
|
|
func _build_shortcut_bar() -> PanelContainer:
|
|
var panel := PanelContainer.new()
|
|
panel.custom_minimum_size = SHORTCUT_BAR_SIZE
|
|
panel.mouse_filter = Control.MOUSE_FILTER_STOP
|
|
panel.add_theme_stylebox_override("panel", _create_panel_style(32))
|
|
|
|
var margin := MarginContainer.new()
|
|
margin.add_theme_constant_override("margin_left", 18)
|
|
margin.add_theme_constant_override("margin_top", 12)
|
|
margin.add_theme_constant_override("margin_right", 18)
|
|
margin.add_theme_constant_override("margin_bottom", 12)
|
|
panel.add_child(margin)
|
|
|
|
var row := HBoxContainer.new()
|
|
row.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
row.add_theme_constant_override("separation", 8)
|
|
margin.add_child(row)
|
|
|
|
row.add_child(_create_shortcut_button("map", "地图", _on_map_pressed))
|
|
_taskShortcutButton = _create_shortcut_button("task", "任务", _on_task_pressed)
|
|
_taskShortcutButton.tooltip_text = "打开任务书"
|
|
_taskRewardBadge = Label.new()
|
|
_taskRewardBadge.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_taskRewardBadge.visible = false
|
|
_taskRewardBadge.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
_taskRewardBadge.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
_taskRewardBadge.add_theme_color_override("font_color", Color.WHITE)
|
|
_taskRewardBadge.add_theme_font_size_override("font_size", 12)
|
|
_taskRewardBadge.add_theme_stylebox_override("normal", _create_pill_style(Color(0.92, 0.30, 0.24), 12))
|
|
_taskRewardBadge.set_anchors_preset(Control.PRESET_TOP_RIGHT)
|
|
_taskRewardBadge.offset_left = -20
|
|
_taskRewardBadge.offset_top = 1
|
|
_taskRewardBadge.offset_right = 4
|
|
_taskRewardBadge.offset_bottom = 25
|
|
_taskRewardBadge.z_index = 1
|
|
_taskShortcutButton.add_child(_taskRewardBadge)
|
|
row.add_child(_taskShortcutButton)
|
|
row.add_child(_create_shortcut_button("backpack", "背包", _on_backpack_pressed))
|
|
row.add_child(_create_shortcut_button("friends", "好友", _on_friends_pressed))
|
|
row.add_child(_create_shortcut_button("activity", "通知", _on_notifications_pressed))
|
|
row.add_child(_create_shortcut_button("settings", "设置", _on_settings_pressed))
|
|
|
|
return panel
|
|
|
|
func _build_player_avatar_button() -> Button:
|
|
var button := Button.new()
|
|
button.custom_minimum_size = PLAYER_PROFILE_BUTTON_SIZE
|
|
button.tooltip_text = "角色设置"
|
|
button.focus_mode = Control.FOCUS_NONE
|
|
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
button.text = ""
|
|
button.add_theme_stylebox_override("normal", _create_avatar_button_style(Color(1, 1, 1, 0.94), 39))
|
|
button.add_theme_stylebox_override("hover", _create_avatar_button_style(Color(0.918, 0.961, 0.992, 0.98), 39))
|
|
button.add_theme_stylebox_override("pressed", _create_avatar_button_style(Color(0.858, 0.925, 0.980, 1.0), 39))
|
|
button.add_theme_stylebox_override("focus", _create_empty_style())
|
|
button.pressed.connect(_on_avatar_pressed)
|
|
|
|
var margin := MarginContainer.new()
|
|
margin.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
margin.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
margin.add_theme_constant_override("margin_left", 10)
|
|
margin.add_theme_constant_override("margin_top", 10)
|
|
margin.add_theme_constant_override("margin_right", 14)
|
|
margin.add_theme_constant_override("margin_bottom", 10)
|
|
button.add_child(margin)
|
|
|
|
var row := HBoxContainer.new()
|
|
row.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
row.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
row.add_theme_constant_override("separation", 10)
|
|
margin.add_child(row)
|
|
|
|
var avatar := PanelContainer.new()
|
|
_avatarPanel = avatar
|
|
avatar.custom_minimum_size = PLAYER_AVATAR_SIZE
|
|
avatar.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
avatar.clip_contents = true
|
|
row.add_child(avatar)
|
|
|
|
_avatarLabel = Label.new()
|
|
_avatarLabel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_avatarLabel.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
_avatarLabel.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
_avatarLabel.add_theme_color_override("font_color", Color.WHITE)
|
|
_avatarLabel.add_theme_font_size_override("font_size", 22)
|
|
avatar.add_child(_avatarLabel)
|
|
_apply_current_avatar()
|
|
|
|
_usernameLabel = Label.new()
|
|
_usernameLabel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_usernameLabel.text = _currentUsername
|
|
_usernameLabel.custom_minimum_size = Vector2(96, 0)
|
|
_usernameLabel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
_usernameLabel.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
|
|
_usernameLabel.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
|
_usernameLabel.add_theme_color_override("font_color", TEXT_COLOR)
|
|
_usernameLabel.add_theme_font_size_override("font_size", 18)
|
|
|
|
var info := VBoxContainer.new()
|
|
info.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
info.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
info.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
info.add_theme_constant_override("separation", 2)
|
|
row.add_child(info)
|
|
info.add_child(_usernameLabel)
|
|
|
|
_walletLabel = Label.new()
|
|
_walletLabel.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_walletLabel.text = "鲸币 --"
|
|
_walletLabel.custom_minimum_size = Vector2(112, 0)
|
|
_walletLabel.size_flags_horizontal = Control.SIZE_EXPAND_FILL
|
|
_walletLabel.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
|
_walletLabel.add_theme_color_override("font_color", ACCENT_COLOR)
|
|
_walletLabel.add_theme_font_size_override("font_size", 14)
|
|
info.add_child(_walletLabel)
|
|
|
|
return button
|
|
|
|
func _create_shortcut_button(iconName: String, text: String, callback: Callable) -> Button:
|
|
var button := Button.new()
|
|
button.custom_minimum_size = Vector2(56, 60)
|
|
button.focus_mode = Control.FOCUS_NONE
|
|
button.mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
button.text = ""
|
|
button.add_theme_stylebox_override("normal", _create_empty_style())
|
|
button.add_theme_stylebox_override("hover", _create_pill_style(Color(0.918, 0.961, 0.992, 0.86), 18))
|
|
button.add_theme_stylebox_override("pressed", _create_pill_style(Color(0.858, 0.925, 0.980, 0.98), 18))
|
|
button.add_theme_stylebox_override("focus", _create_empty_style())
|
|
button.pressed.connect(callback)
|
|
|
|
var content := VBoxContainer.new()
|
|
content.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
content.set_anchors_preset(Control.PRESET_FULL_RECT)
|
|
content.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
content.add_theme_constant_override("separation", 1)
|
|
button.add_child(content)
|
|
|
|
var icon := HUD_SHORTCUT_ICON_SCRIPT.new() as Control
|
|
icon.set("iconName", iconName)
|
|
icon.custom_minimum_size = Vector2(31, 31)
|
|
content.add_child(icon)
|
|
|
|
var label := Label.new()
|
|
label.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
label.text = text
|
|
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
label.add_theme_color_override("font_color", MUTED_COLOR)
|
|
label.add_theme_font_size_override("font_size", 14)
|
|
content.add_child(label)
|
|
|
|
button.mouse_entered.connect(func() -> void:
|
|
if is_instance_valid(label):
|
|
label.add_theme_color_override("font_color", ACCENT_COLOR)
|
|
)
|
|
button.mouse_exited.connect(func() -> void:
|
|
if is_instance_valid(label):
|
|
label.add_theme_color_override("font_color", MUTED_COLOR)
|
|
)
|
|
return button
|
|
|
|
func _subscribe_to_events() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem == null:
|
|
push_warning("PlayerHud: EventSystem autoload is not available.")
|
|
return
|
|
|
|
eventSystem.call("connect_event", EventNames.CHAT_LOGIN_SUCCESS, _on_chat_login_success, self)
|
|
eventSystem.call("connect_event", EventNames.AUTH_LOGIN_SUCCESS, _on_auth_login_success, self)
|
|
eventSystem.call("connect_event", EventNames.AUTH_REGISTER_SUCCESS, _on_auth_register_success, self)
|
|
eventSystem.call("connect_event", EventNames.AUTH_LOGOUT, _on_auth_logout, self)
|
|
eventSystem.call("connect_event", EventNames.APPEARANCE_AVATAR_CHANGED, _on_appearance_avatar_changed, self)
|
|
eventSystem.call("connect_event", EventNames.MALL_PURCHASE_SUCCEEDED, _on_wallet_mutation_event, self)
|
|
eventSystem.call("connect_event", EventNames.CAFE_COMPANION_CHAT_TIME_PURCHASED, _on_wallet_mutation_event, self)
|
|
eventSystem.call("connect_event", EventNames.CAFE_COMPANION_EMPLOYMENT_RESIGNED, _on_wallet_mutation_event, self)
|
|
var playerStateManager := get_node_or_null("/root/PlayerStateManager")
|
|
if playerStateManager != null and playerStateManager.has_signal("wallet_changed"):
|
|
var walletCallback := Callable(self, "_on_player_wallet_changed")
|
|
if not playerStateManager.is_connected("wallet_changed", walletCallback):
|
|
playerStateManager.connect("wallet_changed", walletCallback)
|
|
var authManager := get_node_or_null("/root/AuthManager")
|
|
if authManager != null and authManager.has_signal("auth_state_changed"):
|
|
var callback := Callable(self, "_on_auth_state_changed")
|
|
if not authManager.is_connected("auth_state_changed", callback):
|
|
authManager.connect("auth_state_changed", callback)
|
|
var taskManager := get_node_or_null("/root/TaskManager")
|
|
if taskManager != null and taskManager.has_signal("board_changed"):
|
|
var taskCallback := Callable(self, "_on_task_board_changed")
|
|
if not taskManager.is_connected("board_changed", taskCallback):
|
|
taskManager.connect("board_changed", taskCallback)
|
|
if taskManager.has_method("get_board"):
|
|
var boardVariant: Variant = taskManager.call("get_board")
|
|
if boardVariant is Dictionary:
|
|
_on_task_board_changed(boardVariant as Dictionary)
|
|
|
|
func _load_current_user() -> void:
|
|
var authManager := get_node_or_null("/root/AuthManager")
|
|
if authManager != null and authManager.has_method("get_current_username"):
|
|
var username := str(authManager.call("get_current_username")).strip_edges()
|
|
if not username.is_empty():
|
|
_set_username(username)
|
|
|
|
func _on_chat_login_success(data: Dictionary) -> void:
|
|
var username := str(data.get("username", "")).strip_edges()
|
|
if not username.is_empty():
|
|
_set_username(username)
|
|
|
|
func _on_auth_login_success(data: Dictionary) -> void:
|
|
_apply_auth_user_payload(data)
|
|
|
|
func _on_auth_register_success(data: Dictionary) -> void:
|
|
_apply_auth_user_payload(data)
|
|
|
|
func _on_auth_state_changed(isAuthenticated: bool, user: Dictionary) -> void:
|
|
if not isAuthenticated:
|
|
_set_username("玩家")
|
|
_reset_wallet()
|
|
return
|
|
_apply_auth_user_payload({"user": user})
|
|
_refresh_wallet()
|
|
|
|
func _apply_auth_user_payload(data: Dictionary) -> void:
|
|
var userVariant: Variant = data.get("user", {})
|
|
if userVariant is Dictionary:
|
|
var username := str((userVariant as Dictionary).get("username", "")).strip_edges()
|
|
if not username.is_empty():
|
|
_set_username(username)
|
|
|
|
func _on_auth_logout(_data: Variant = null) -> void:
|
|
_set_username("玩家")
|
|
_reset_wallet()
|
|
_on_task_board_changed({})
|
|
|
|
func _on_task_board_changed(board: Dictionary) -> void:
|
|
if not is_instance_valid(_taskShortcutButton):
|
|
return
|
|
var claimableCount: int = _count_claimable_task_rewards(board)
|
|
if claimableCount > 0:
|
|
_taskShortcutButton.tooltip_text = "任务书:有 %d 项奖励可领取" % claimableCount
|
|
_taskShortcutButton.modulate = Color(1.0, 0.855, 0.470, 1.0)
|
|
if is_instance_valid(_taskRewardBadge):
|
|
_taskRewardBadge.text = str(mini(claimableCount, 9)) if claimableCount < 10 else "9+"
|
|
_taskRewardBadge.visible = true
|
|
return
|
|
_taskShortcutButton.tooltip_text = "打开任务书"
|
|
_taskShortcutButton.modulate = Color.WHITE
|
|
if is_instance_valid(_taskRewardBadge):
|
|
_taskRewardBadge.visible = false
|
|
|
|
func _count_claimable_task_rewards(board: Dictionary) -> int:
|
|
var claimableCount: int = 0
|
|
claimableCount += _count_claimable_tasks(board.get("newbie_tasks", []))
|
|
claimableCount += _count_claimable_tasks(board.get("weekly_tasks", []))
|
|
var weeklyBonusVariant: Variant = board.get("weekly_bonus", {})
|
|
if weeklyBonusVariant is Dictionary:
|
|
var weeklyBonus: Dictionary = weeklyBonusVariant as Dictionary
|
|
if bool(weeklyBonus.get("claimable", false)):
|
|
claimableCount += 1
|
|
return claimableCount
|
|
|
|
func _count_claimable_tasks(tasksVariant: Variant) -> int:
|
|
if not (tasksVariant is Array):
|
|
return 0
|
|
var claimableCount: int = 0
|
|
for taskVariant: Variant in tasksVariant as Array:
|
|
if taskVariant is Dictionary:
|
|
var task: Dictionary = taskVariant as Dictionary
|
|
if bool(task.get("claimable", false)):
|
|
claimableCount += 1
|
|
return claimableCount
|
|
|
|
func _on_appearance_avatar_changed(_data: Dictionary) -> void:
|
|
_apply_current_avatar()
|
|
|
|
func _set_username(username: String) -> void:
|
|
_currentUsername = username.strip_edges()
|
|
if _currentUsername.is_empty():
|
|
_currentUsername = "玩家"
|
|
if is_instance_valid(_usernameLabel):
|
|
_usernameLabel.text = _currentUsername
|
|
_apply_current_avatar()
|
|
|
|
func _on_wallet_mutation_event(data: Dictionary) -> void:
|
|
var balanceVariant: Variant = data.get("balance", null)
|
|
if balanceVariant != null and (balanceVariant is int or balanceVariant is float):
|
|
_apply_wallet_balance(int(balanceVariant))
|
|
return
|
|
_refresh_wallet()
|
|
|
|
func _build_wallet_refresh_timer() -> void:
|
|
_walletRefreshTimer = Timer.new()
|
|
_walletRefreshTimer.name = "HudWalletRefreshTimer"
|
|
_walletRefreshTimer.wait_time = WALLET_REFRESH_INTERVAL
|
|
_walletRefreshTimer.autostart = true
|
|
_walletRefreshTimer.timeout.connect(_on_wallet_refresh_timer_timeout)
|
|
add_child(_walletRefreshTimer)
|
|
|
|
func _on_wallet_refresh_timer_timeout() -> void:
|
|
_refresh_wallet()
|
|
|
|
func _refresh_wallet() -> void:
|
|
if not _is_wallet_available():
|
|
_reset_wallet()
|
|
return
|
|
var playerStateManager := get_node_or_null("/root/PlayerStateManager")
|
|
if playerStateManager == null:
|
|
_reset_wallet()
|
|
return
|
|
if playerStateManager.has_method("get_wallet"):
|
|
var walletVariant: Variant = playerStateManager.call("get_wallet")
|
|
if walletVariant is Dictionary and not (walletVariant as Dictionary).is_empty():
|
|
_on_player_wallet_changed(walletVariant as Dictionary)
|
|
return
|
|
if _walletLoading:
|
|
return
|
|
_walletLoading = true
|
|
_update_wallet_label()
|
|
if playerStateManager.has_method("refresh_snapshot"):
|
|
playerStateManager.call("refresh_snapshot")
|
|
|
|
func _on_player_wallet_changed(wallet: Dictionary) -> void:
|
|
if wallet.is_empty():
|
|
_reset_wallet()
|
|
return
|
|
_apply_wallet_balance(int(wallet.get("balance", 0)))
|
|
|
|
func _apply_wallet_balance(balance: int) -> void:
|
|
_walletBalance = max(0, balance)
|
|
_walletLoaded = true
|
|
_walletLoading = false
|
|
_update_wallet_label()
|
|
|
|
func _reset_wallet() -> void:
|
|
_walletBalance = 0
|
|
_walletLoaded = false
|
|
_walletLoading = false
|
|
_update_wallet_label()
|
|
|
|
func _update_wallet_label(overrideText: String = "") -> void:
|
|
if not is_instance_valid(_walletLabel):
|
|
return
|
|
if not overrideText.is_empty():
|
|
_walletLabel.text = "鲸币 %s" % overrideText
|
|
_walletLabel.tooltip_text = "鲸币余额"
|
|
return
|
|
if _walletLoading:
|
|
_walletLabel.text = "鲸币 读取中"
|
|
elif _walletLoaded:
|
|
_walletLabel.text = "鲸币 %s" % _format_number(_walletBalance)
|
|
else:
|
|
_walletLabel.text = "鲸币 --"
|
|
_walletLabel.tooltip_text = "鲸币余额"
|
|
|
|
func _format_number(value: int) -> String:
|
|
var text := str(value)
|
|
var result := ""
|
|
var count := 0
|
|
for i in range(text.length() - 1, -1, -1):
|
|
if count > 0 and count % 3 == 0:
|
|
result = "," + result
|
|
result = text[i] + result
|
|
count += 1
|
|
return result
|
|
|
|
func _is_wallet_available() -> bool:
|
|
var authManager := get_node_or_null("/root/AuthManager")
|
|
return authManager != null and authManager.has_method("is_authenticated") and bool(authManager.call("is_authenticated")) and authManager.has_method("get_access_token")
|
|
|
|
func _on_map_pressed() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.HUD_MAP_TOGGLE, {})
|
|
|
|
func _on_notifications_pressed() -> void:
|
|
var socialManager := get_node_or_null("/root/SocialManager")
|
|
if socialManager != null and socialManager.has_method("toggle_notifications"):
|
|
socialManager.call("toggle_notifications")
|
|
|
|
func _on_task_pressed() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.HUD_TASK_BOOK_REQUESTED, {})
|
|
|
|
func _on_backpack_pressed() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.HUD_BACKPACK_TOGGLE, {})
|
|
|
|
func _on_friends_pressed() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.HUD_FRIEND_LIST_TOGGLE, {})
|
|
|
|
func _on_settings_pressed() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.HUD_SETTINGS_REQUESTED, {})
|
|
|
|
func _on_avatar_pressed() -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.HUD_SETTINGS_REQUESTED, {})
|
|
|
|
func _emit_status_message(message: String) -> void:
|
|
var eventSystem := _get_event_system()
|
|
if eventSystem != null:
|
|
eventSystem.call("emit_event", EventNames.CHAT_MESSAGE_RECEIVED, {
|
|
"from_user": "系统",
|
|
"content": message,
|
|
"timestamp": Time.get_unix_time_from_system(),
|
|
"is_self": false,
|
|
"scope": "system",
|
|
"tab": "world"
|
|
})
|
|
|
|
func _create_panel_style(radius: int) -> StyleBoxFlat:
|
|
var style := StyleBoxFlat.new()
|
|
style.bg_color = Color(1, 1, 1, 0.925)
|
|
style.corner_radius_top_left = radius
|
|
style.corner_radius_top_right = radius
|
|
style.corner_radius_bottom_left = radius
|
|
style.corner_radius_bottom_right = radius
|
|
style.shadow_color = Color(0.12549, 0.282353, 0.407843, 0.15)
|
|
style.shadow_size = 18
|
|
style.shadow_offset = Vector2(0, 7)
|
|
return style
|
|
|
|
func _create_avatar_style() -> StyleBoxFlat:
|
|
var style := StyleBoxFlat.new()
|
|
style.bg_color = Color(0.361, 0.690, 0.914)
|
|
style.corner_radius_top_left = 32
|
|
style.corner_radius_top_right = 32
|
|
style.corner_radius_bottom_left = 32
|
|
style.corner_radius_bottom_right = 32
|
|
return style
|
|
|
|
func _apply_current_avatar() -> void:
|
|
if not is_instance_valid(_avatarPanel) or not is_instance_valid(_avatarLabel):
|
|
return
|
|
var appearanceManager := get_node_or_null("/root/AppearanceManager")
|
|
if appearanceManager != null and appearanceManager.has_method("apply_avatar_to_panel"):
|
|
appearanceManager.call("apply_avatar_to_panel", _avatarPanel, _avatarLabel, "", _currentUsername)
|
|
_avatarPanel.add_theme_stylebox_override("panel", _create_round_avatar_style(_avatarPanel))
|
|
return
|
|
_avatarPanel.add_theme_stylebox_override("panel", _create_avatar_style())
|
|
_avatarLabel.visible = true
|
|
_avatarLabel.text = _currentUsername.substr(0, 1).to_upper()
|
|
|
|
func _create_avatar_button_style(color: Color, radius: int) -> StyleBoxFlat:
|
|
var style := _create_pill_style(color, radius)
|
|
style.shadow_color = Color(0.12549, 0.282353, 0.407843, 0.14)
|
|
style.shadow_size = 16
|
|
style.shadow_offset = Vector2(0, 6)
|
|
return style
|
|
|
|
func _create_round_avatar_style(panel: PanelContainer) -> StyleBoxFlat:
|
|
var style := StyleBoxFlat.new()
|
|
style.bg_color = Color(0.361, 0.690, 0.914)
|
|
var radius := int(round(minf(panel.custom_minimum_size.x, panel.custom_minimum_size.y) * 0.5))
|
|
style.corner_radius_top_left = radius
|
|
style.corner_radius_top_right = radius
|
|
style.corner_radius_bottom_left = radius
|
|
style.corner_radius_bottom_right = radius
|
|
style.border_width_left = 2
|
|
style.border_width_top = 2
|
|
style.border_width_right = 2
|
|
style.border_width_bottom = 2
|
|
style.border_color = Color(1, 1, 1, 0.78)
|
|
return style
|
|
|
|
func _create_pill_style(color: Color, radius: int) -> StyleBoxFlat:
|
|
var style := StyleBoxFlat.new()
|
|
style.bg_color = color
|
|
style.corner_radius_top_left = radius
|
|
style.corner_radius_top_right = radius
|
|
style.corner_radius_bottom_left = radius
|
|
style.corner_radius_bottom_right = radius
|
|
style.content_margin_left = 8
|
|
style.content_margin_right = 8
|
|
style.content_margin_top = 5
|
|
style.content_margin_bottom = 5
|
|
return style
|
|
|
|
func _create_empty_style() -> StyleBoxEmpty:
|
|
return StyleBoxEmpty.new()
|
|
|
|
func _get_event_system() -> Node:
|
|
return get_node_or_null("/root/EventSystem")
|