class_name Chat extends Menu const BBCODE_TAGS_TO_ESCAPE: PackedStringArray = [ "url", "img", "font", "dropcap", "opentype_features", "outline_size" ] var _chat_message_scene := preload("res://scenes/ui/chat_message.tscn") var _message_history: PackedStringArray = [] var _history_position: int = 0 @onready var _msg_scroll: ScrollContainer = $MsgMargin/MsgVBox/MsgScroll @onready var _msg_container: Container = $MsgMargin/MsgVBox/MsgScroll/MsgMargin/MsgContainer @onready var _msg_margin: Container = $MsgMargin/MsgVBox/MsgScroll/MsgMargin @onready var _message_edit: LineEdit = $EditMargin/EditVBox/MessageEdit func _ready() -> void: _message_edit.text_submitted.connect(_on_message_edit_text_submitted) _message_edit.visible = false _msg_margin.minimum_size_changed.connect(_on_message_margin_minimum_size_changed) Referencer.chat = self func _exit_tree() -> void: Referencer.chat = null func _input(event: InputEvent) -> void: if event.is_action_pressed("menu"): call_deferred("close") if _message_edit.has_focus(): if ( event.is_action_pressed("ui_up") and _history_position + 1 <= _message_history.size() ): _history_position += 1 _set_message_from_history() if event.is_action_pressed("ui_down") and _history_position - 1 >= 0: _history_position -= 1 _set_message_from_history() func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("chat") and not is_open: open() func open() -> void: super.open() _message_edit.visible = true _message_edit.grab_focus() _msg_scroll.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_AUTO func close() -> void: super.close() _message_edit.release_focus() _message_edit.visible = false _msg_scroll.vertical_scroll_mode = ScrollContainer.SCROLL_MODE_SHOW_NEVER @rpc("any_peer", "call_local", "reliable", 1) func _send_message(message: String) -> void: var player_name := ( Networker.players[multiplayer.get_remote_sender_id()]["name"] as String ) var message_node := _make_message_node(player_name, message) _msg_container.add_child(message_node) print(player_name + ": " + message) func _make_message_node(player_name: String, message: String) -> RichTextLabel: var node := _chat_message_scene.instantiate() as RichTextLabel node.text = "[b]" + player_name + ":[/b] " + _escape_bbcode_tags(message) return node func _set_message_from_history() -> void: if _history_position > 0: var message := _message_history[-_history_position] _message_edit.text = message else: _message_edit.text = "" func _escape_bbcode_tags(message: String) -> String: for tag_name in BBCODE_TAGS_TO_ESCAPE: var tag := "[" + tag_name if tag in message: message = message.replace(tag, "[lb]" + tag_name) return message func _on_message_edit_text_submitted(message: String) -> void: if _message_edit.text == "": return _message_edit.text = "" if not (message in _message_history): _message_history.append(message) _history_position = 0 close() _send_message.rpc(message) func _on_message_margin_minimum_size_changed() -> void: _msg_scroll.set_deferred( "scroll_vertical", int(_msg_scroll.get_v_scroll_bar().max_value) + 100 )