extends Control class_name EnhancedDialogueBox ## 增强对话框 UI ## 支持表情符号、群组对话、历史记录等功能 # UI 元素 var message_display: RichTextLabel var message_input: LineEdit var send_button: Button var emoji_button: Button var history_button: Button var group_button: Button var close_button: Button var target_label: Label var container: VBoxContainer var scroll_container: ScrollContainer # 表情符号选择器 var emoji_picker: Control var emoji_picker_visible: bool = false # 历史记录面板 var history_panel: Control var history_list: ItemList var history_visible: bool = false # 群组面板 var group_panel: Control var group_list: ItemList var create_group_button: Button var join_group_button: Button var group_visible: bool = false # 管理器引用 var emoji_manager: EmojiManager var dialogue_filter: DialogueFilter var group_manager: GroupDialogueManager var history_manager: DialogueHistoryManager # 当前对话目标 var current_target_id: String = "" var current_target_name: String = "" var is_group_chat: bool = false # 信号 signal message_sent(target_id: String, message: String, is_group: bool) signal dialogue_closed() signal emoji_selected(emoji: String) func _ready(): """初始化增强对话框""" setup_ui() setup_managers() connect_signals() print("EnhancedDialogueBox initialized") ## 设置UI元素 func setup_ui() -> void: """设置UI元素和布局""" # 主容器 container = VBoxContainer.new() add_child(container) container.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) # 目标标签 target_label = Label.new() target_label.text = "对话" target_label.add_theme_font_size_override("font_size", 16) container.add_child(target_label) # 消息显示区域 scroll_container = ScrollContainer.new() scroll_container.custom_minimum_size = Vector2(400, 300) container.add_child(scroll_container) message_display = RichTextLabel.new() message_display.bbcode_enabled = true message_display.fit_content = true scroll_container.add_child(message_display) # 按钮行 var button_row = HBoxContainer.new() container.add_child(button_row) emoji_button = Button.new() emoji_button.text = "😊" emoji_button.custom_minimum_size = Vector2(40, 30) button_row.add_child(emoji_button) history_button = Button.new() history_button.text = "历史" history_button.custom_minimum_size = Vector2(60, 30) button_row.add_child(history_button) group_button = Button.new() group_button.text = "群组" group_button.custom_minimum_size = Vector2(60, 30) button_row.add_child(group_button) close_button = Button.new() close_button.text = "关闭" close_button.custom_minimum_size = Vector2(60, 30) button_row.add_child(close_button) # 输入行 var input_row = HBoxContainer.new() container.add_child(input_row) message_input = LineEdit.new() message_input.placeholder_text = "输入消息..." message_input.custom_minimum_size = Vector2(300, 30) input_row.add_child(message_input) send_button = Button.new() send_button.text = "发送" send_button.custom_minimum_size = Vector2(60, 30) input_row.add_child(send_button) # 创建弹出面板 create_emoji_picker() create_history_panel() create_group_panel() ## 创建表情符号选择器 func create_emoji_picker() -> void: """创建表情符号选择器面板""" emoji_picker = Control.new() emoji_picker.visible = false add_child(emoji_picker) var picker_bg = NinePatchRect.new() picker_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) emoji_picker.add_child(picker_bg) var picker_container = VBoxContainer.new() picker_container.position = Vector2(10, 10) picker_container.custom_minimum_size = Vector2(300, 200) emoji_picker.add_child(picker_container) # 表情符号网格 var emoji_grid = GridContainer.new() emoji_grid.columns = 8 picker_container.add_child(emoji_grid) # 添加常用表情符号 var common_emojis = ["😊", "😢", "😃", "😉", "😛", "😮", "😲", "😐", "😕", "😭", "😂", "😍", "😠", "😡", "😎", "👍", "👎", "👏", "❤️", "🔥"] for emoji in common_emojis: var emoji_btn = Button.new() emoji_btn.text = emoji emoji_btn.custom_minimum_size = Vector2(30, 30) emoji_btn.pressed.connect(_on_emoji_button_pressed.bind(emoji)) emoji_grid.add_child(emoji_btn) ## 创建历史记录面板 func create_history_panel() -> void: """创建历史记录面板""" history_panel = Control.new() history_panel.visible = false add_child(history_panel) var history_bg = NinePatchRect.new() history_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) history_panel.add_child(history_bg) var history_container = VBoxContainer.new() history_container.position = Vector2(10, 10) history_container.custom_minimum_size = Vector2(350, 250) history_panel.add_child(history_container) var history_title = Label.new() history_title.text = "对话历史" history_title.add_theme_font_size_override("font_size", 14) history_container.add_child(history_title) history_list = ItemList.new() history_list.custom_minimum_size = Vector2(330, 200) history_container.add_child(history_list) ## 创建群组面板 func create_group_panel() -> void: """创建群组管理面板""" group_panel = Control.new() group_panel.visible = false add_child(group_panel) var group_bg = NinePatchRect.new() group_bg.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) group_panel.add_child(group_bg) var group_container = VBoxContainer.new() group_container.position = Vector2(10, 10) group_container.custom_minimum_size = Vector2(300, 250) group_panel.add_child(group_container) var group_title = Label.new() group_title.text = "群组管理" group_title.add_theme_font_size_override("font_size", 14) group_container.add_child(group_title) var group_buttons = HBoxContainer.new() group_container.add_child(group_buttons) create_group_button = Button.new() create_group_button.text = "创建群组" group_buttons.add_child(create_group_button) join_group_button = Button.new() join_group_button.text = "加入群组" group_buttons.add_child(join_group_button) group_list = ItemList.new() group_list.custom_minimum_size = Vector2(280, 180) group_container.add_child(group_list) ## 设置管理器 func setup_managers() -> void: """设置各种管理器""" # 延迟初始化管理器以避免性能问题 call_deferred("_initialize_managers") func _initialize_managers() -> void: """延迟初始化管理器""" emoji_manager = EmojiManager.new() add_child(emoji_manager) dialogue_filter = DialogueFilter.new() add_child(dialogue_filter) group_manager = GroupDialogueManager.new() add_child(group_manager) history_manager = DialogueHistoryManager.new() add_child(history_manager) ## 连接信号 func connect_signals() -> void: """连接UI信号""" send_button.pressed.connect(_on_send_button_pressed) message_input.text_submitted.connect(_on_message_submitted) emoji_button.pressed.connect(_on_emoji_button_pressed_toggle) history_button.pressed.connect(_on_history_button_pressed) group_button.pressed.connect(_on_group_button_pressed) close_button.pressed.connect(_on_close_button_pressed) # 管理器信号 dialogue_filter.message_blocked.connect(_on_message_blocked) group_manager.group_message_received.connect(_on_group_message_received) ## 开始对话 func start_dialogue(target_id: String, target_name: String, is_group: bool = false) -> void: """ 开始与指定目标的对话 @param target_id: 目标ID @param target_name: 目标名称 @param is_group: 是否为群组对话 """ current_target_id = target_id current_target_name = target_name is_group_chat = is_group # 更新UI if is_group: target_label.text = "群组: " + target_name else: target_label.text = "对话: " + target_name # 加载历史记录 load_dialogue_history() # 显示对话框 visible = true message_input.grab_focus() ## 发送消息 func send_message(message: String) -> void: """ 发送消息 @param message: 消息内容 """ if message.strip_edges().is_empty(): return var sender_id = "player" # 过滤消息(添加安全检查) if not dialogue_filter: show_error_message("对话过滤器未初始化") return var filter_result = dialogue_filter.filter_message(sender_id, message) if not filter_result.allowed: show_error_message(filter_result.reason) return var filtered_message = filter_result.filtered_message # 转换表情符号 var final_message = EmojiManager.convert_text_to_emoji(filtered_message) # 发送消息 if is_group_chat: group_manager.send_group_message(current_target_id, sender_id, final_message) else: # 通过NetworkManager发送消息(如果连接到服务器) var network_manager = get_node("/root/Main/NetworkManager") if network_manager and network_manager.is_server_connected(): var dialogue_message = MessageProtocol.create_dialogue_send(sender_id, current_target_id, final_message) network_manager.send_message(dialogue_message) message_sent.emit(current_target_id, final_message, false) # 添加到历史记录 history_manager.add_message_to_history(current_target_id, sender_id, final_message) # 显示在对话框中 display_message(sender_id, final_message) # 清空输入框 message_input.text = "" ## 接收消息 func receive_message(sender_id: String, message: String) -> void: """ 接收消息 @param sender_id: 发送者ID @param message: 消息内容 """ # 添加到历史记录 history_manager.add_message_to_history(current_target_id, sender_id, message) # 显示在对话框中 display_message(sender_id, message) ## 显示消息 func display_message(sender_id: String, message: String) -> void: """ 在对话框中显示消息 @param sender_id: 发送者ID @param message: 消息内容 """ var timestamp = Time.get_datetime_string_from_system() var sender_name = sender_id if sender_id != "player" else "我" var formatted_message = "[color=gray][%s][/color] [color=blue]%s[/color]: %s\n" % [timestamp, sender_name, message] message_display.append_text(formatted_message) # 滚动到底部 await get_tree().process_frame scroll_container.scroll_vertical = scroll_container.get_v_scroll_bar().max_value ## 加载对话历史 func load_dialogue_history() -> void: """加载当前目标的对话历史""" message_display.clear() var history = history_manager.get_character_history(current_target_id, 20) for message_record in history: var sender_name = message_record.sender if message_record.sender != "player" else "我" var timestamp = Time.get_datetime_string_from_unix_time(message_record.timestamp) var formatted_message = "[color=gray][%s][/color] [color=blue]%s[/color]: %s\n" % [timestamp, sender_name, message_record.message] message_display.append_text(formatted_message) ## 显示错误消息 func show_error_message(error_text: String) -> void: """ 显示错误消息 @param error_text: 错误文本 """ var error_message = "[color=red]系统: %s[/color]\n" % error_text message_display.append_text(error_message) ## 信号处理函数 func _on_send_button_pressed() -> void: """发送按钮点击处理""" send_message(message_input.text) func _on_message_submitted(text: String) -> void: """消息输入提交处理""" send_message(text) func _on_emoji_button_pressed_toggle() -> void: """表情符号按钮点击处理""" emoji_picker_visible = not emoji_picker_visible emoji_picker.visible = emoji_picker_visible # 隐藏其他面板 if emoji_picker_visible: history_panel.visible = false group_panel.visible = false history_visible = false group_visible = false func _on_emoji_button_pressed(emoji: String) -> void: """表情符号选择处理""" message_input.text += emoji emoji_manager.add_to_recent(emoji) emoji_selected.emit(emoji) # 隐藏选择器 emoji_picker.visible = false emoji_picker_visible = false # 聚焦输入框 message_input.grab_focus() func _on_history_button_pressed() -> void: """历史记录按钮点击处理""" history_visible = not history_visible history_panel.visible = history_visible # 隐藏其他面板 if history_visible: emoji_picker.visible = false group_panel.visible = false emoji_picker_visible = false group_visible = false # 更新历史记录列表 update_history_list() func _on_group_button_pressed() -> void: """群组按钮点击处理""" group_visible = not group_visible group_panel.visible = group_visible # 隐藏其他面板 if group_visible: emoji_picker.visible = false history_panel.visible = false emoji_picker_visible = false history_visible = false # 更新群组列表 update_group_list() func _on_close_button_pressed() -> void: """关闭按钮点击处理""" visible = false dialogue_closed.emit() func _on_message_blocked(user_id: String, message: String, reason: String) -> void: """消息被阻止处理""" show_error_message("消息被阻止: " + reason) func _on_group_message_received(group_id: String, sender_id: String, message: String) -> void: """群组消息接收处理""" if group_id == current_target_id and is_group_chat: receive_message(sender_id, message) ## 更新历史记录列表 func update_history_list() -> void: """更新历史记录列表""" history_list.clear() var recent_conversations = history_manager.get_recent_conversations(10) for conversation in recent_conversations: var item_text = "%s: %s" % [conversation.character_id, conversation.last_message] if item_text.length() > 50: item_text = item_text.substr(0, 47) + "..." history_list.add_item(item_text) ## 更新群组列表 func update_group_list() -> void: """更新群组列表""" group_list.clear() var player_groups = group_manager.get_player_groups() for group_info in player_groups: var item_text = "%s (%d人)" % [group_info.name, group_info.participant_count] group_list.add_item(item_text)