115 lines
3.1 KiB
GDScript
115 lines
3.1 KiB
GDScript
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
|
|
)
|