soil/src/ingame/ingame.gd
2025-02-12 12:44:39 +03:00

159 lines
4.4 KiB
GDScript

extends Node3D
@export var _player_scene: PackedScene
@export var _players: Node3D
@export var _chat_panel: Panel
@export var _chat_input: LineEdit
@export var _chat_history_scroll: ScrollContainer
@export var _chat_history: VBoxContainer
@export var _chat_panel_inactive: Panel
@export var _chat_history_inactive: VBoxContainer
@export var _chat_history_scroll_inactive: ScrollContainer
## Things to yet play, so to not repeat ourselves much.
const PLAYLIST: Array[String] = [
"res://assets/musics/mod118.ogg",
"res://assets/musics/mod147-medley.mp3",
"res://assets/musics/mod170-toomanyfuckingdoors.ogg",
"res://assets/musics/sho.ogg",
]
var _playlist_remaining: Array[String]
func _ready() -> void:
print("ingame ready")
_chat_history_scroll.get_v_scroll_bar().changed.connect(
_on_chat_history_scroll_changed.bind(_chat_history_scroll)
)
_chat_history_scroll_inactive.get_v_scroll_bar().changed.connect(
_on_chat_history_scroll_changed.bind(_chat_history_scroll_inactive)
)
if "--on-top" in OS.get_cmdline_args():
get_window().grab_focus()
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
if not multiplayer.is_server():
return
multiplayer.peer_connected.connect(_add_player)
multiplayer.peer_disconnected.connect(_remove_player)
for id in multiplayer.get_peers():
_add_player.call_deferred(id)
if not OS.has_feature("dedicated_server"):
_add_player.call_deferred(1)
if not "--join" in OS.get_cmdline_args():
$Soundtrack.finished.connect(_play_new_track)
_play_new_track()
# TODO: sync what's played for peers, server controlled
func _play_new_track():
if _playlist_remaining.size() == 0:
_playlist_remaining = PLAYLIST.duplicate()
var selection = _playlist_remaining.pick_random()
_playlist_remaining.erase(selection)
$Soundtrack.stream = load(selection)
$Soundtrack.play()
func _exit_tree() -> void:
if not multiplayer.is_server():
return
multiplayer.peer_connected.disconnect(_add_player)
multiplayer.peer_disconnected.disconnect(_remove_player)
func _unhandled_input(event: InputEvent) -> void:
if event.is_action_pressed("chat"):
get_viewport().set_input_as_handled()
_activate_chat()
func _input(event: InputEvent) -> void:
if event.is_action_pressed("ui_cancel"):
get_viewport().set_input_as_handled()
_deactivate_chat()
func _activate_chat() -> void:
_chat_panel.show()
_chat_panel_inactive.hide()
_chat_input.grab_focus.call_deferred()
_players.get_node(str(multiplayer.get_unique_id())).controls_disabled = true
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
func _deactivate_chat() -> void:
_chat_panel.hide()
_chat_panel_inactive.show()
_players.get_node(str(multiplayer.get_unique_id())).controls_disabled = false
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
func _add_player(id: int) -> void:
print("add player %d" % id)
var character: Player = _player_scene.instantiate()
character.id = id
character.name = str(id)
_players.add_child(character, true)
_set_character_authority.rpc(id)
func _remove_player(id: int) -> void:
if not _players.has_node(str(id)):
return
print("remove player %d" % id)
_players.get_node(str(id)).queue_free()
@rpc("authority", "call_local", "reliable")
func _set_character_authority(id: int) -> void:
if not _players.has_node(str(id)):
return
_players.get_node(str(id)).set_multiplayer_authority(id)
@rpc("any_peer", "call_local", "reliable", 1)
func _submit_chat_message(text: String) -> void:
var id := multiplayer.get_remote_sender_id()
var username: String = GameState.fetch().player_data[id].username
_add_chat_message.rpc(username, text)
@rpc("authority", "call_local", "reliable", 1)
func _add_chat_message(username: String, text: String) -> void:
_chat_history.add_child(_make_chat_message(username, text))
_chat_history_inactive.add_child(_make_chat_message(username, text))
func _on_chat_history_scroll_changed(history: ScrollContainer) -> void:
# keep history scrolled to the bottom
history.scroll_vertical = history.get_v_scroll_bar().max_value
func _make_chat_message(username: String, text: String) -> RichTextLabel:
var label := RichTextLabel.new()
label.bbcode_enabled = true
label.fit_content = true
label.append_text("[color=red]%s[/color] %s" % [username.replace("[", "[lb]"), text.replace("[", "[lb]")])
return label
func _on_chat_message_submitted(new_text := "") -> void:
if _chat_input.text.is_empty():
_deactivate_chat()
return
_submit_chat_message.rpc_id(1, _chat_input.text)
_chat_input.clear()
_deactivate_chat()