extends SceneTree const CHAT_UI_SCENE: PackedScene = preload("res://scenes/ui/ChatUI.tscn") func _initialize() -> void: call_deferred("_run") func _run() -> void: var chatUi := CHAT_UI_SCENE.instantiate() root.add_child(chatUi) await process_frame chatUi.call("start_npc_whisper", "npc_niulai", "牛来", "欢迎来到鲸鱼小镇!") await process_frame var panel := chatUi.get_node("ChatPanel") as PanelContainer var worldTab := chatUi.get_node("ChatPanel/PanelMargin/ContentVBox/Tabs/PopularTab") as Control var npcTabButton := chatUi.get_node("ChatPanel/PanelMargin/ContentVBox/Tabs/RecentTab/RecentTabButton") as Button var friendsTab := chatUi.get_node("ChatPanel/PanelMargin/ContentVBox/Tabs/FriendsTab") as Control var inputRow := chatUi.get_node("ChatPanel/PanelMargin/ContentVBox/InputRow") as Control assert(panel.visible, "NPC interaction must open the dialogue panel") assert(is_equal_approx(panel.anchor_left, 0.5) and is_equal_approx(panel.anchor_right, 0.5), "NPC dialogue must be horizontally centered") assert((panel.get_theme_stylebox("panel") as StyleBoxFlat).border_width_left == 4, "NPC dialogue must use the framed dialogue style") assert(not worldTab.visible and not friendsTab.visible, "Channel tabs must be hidden during an NPC dialogue") assert(npcTabButton.text == "牛来", "The dialogue header must show the NPC name") assert(inputRow.visible, "AI NPC dialogue must retain the message input") var dialogueMessage := chatUi.find_child("ChatMessage", true, false) as Control assert(dialogueMessage != null, "NPC greeting must render in the dialogue") assert(not dialogueMessage.get_node("MessageRow/LeftAvatarPanel").visible, "NPC dialogue messages must not render chat bubbles or avatars") root.size = Vector2i(640, 360) await process_frame var mobileRect := panel.get_rect() var mobileCanvasSize: Vector2 = chatUi.size assert(mobileRect.position.x >= 0.0 and mobileRect.end.x <= mobileCanvasSize.x, "NPC dialogue must fit the mobile canvas horizontally") assert(mobileRect.position.y >= 0.0 and mobileRect.end.y <= mobileCanvasSize.y, "NPC dialogue must fit the mobile canvas vertically") chatUi.call("hide_chat", true) await process_frame assert(is_equal_approx(panel.anchor_left, 0.024), "Closing an NPC dialogue must restore the normal chat layout") assert(worldTab.visible and friendsTab.visible, "Closing an NPC dialogue must restore channel tabs") chatUi.call("show_npc_dialogue", "虾小满", "码头今天风平浪静。") await process_frame assert(panel.visible, "Static NPC interaction must use the same dialogue panel") assert(not inputRow.visible, "Static NPC dialogue must not show an unusable input") assert(npcTabButton.text == "虾小满", "Static NPC dialogue must show its speaker") assert(root.get_node_or_null("WorldChatBubbleLayer") == null, "NPC dialogue must not create a world bubble layer") print("NPC_DIALOGUE_UI_OK") quit()