forked from woofmeow/straywild
fix: preserve multiplayer voice playback and chat focus
This commit is contained in:
parent
a88e76848b
commit
d3272953a5
4 changed files with 93 additions and 13 deletions
|
|
@ -625,6 +625,15 @@ func _on_session_state_changed(state: NetworkSession.State) -> void:
|
|||
_latest_check_name = ""
|
||||
_session.set_local_appearance_snapshot(_appearance_store.get_snapshot())
|
||||
_apply_to_avatar(1, _appearance_store.get_snapshot())
|
||||
return
|
||||
if state in [
|
||||
NetworkSession.State.PRIVATE_HOST,
|
||||
NetworkSession.State.OPEN_HOST,
|
||||
NetworkSession.State.JOINED_CLIENT,
|
||||
]:
|
||||
var local_peer_id := _session.get_local_peer_id()
|
||||
_apply_to_avatar(local_peer_id, _appearance_store.get_snapshot())
|
||||
_apply_local_voice_to_avatar()
|
||||
|
||||
|
||||
func _emit_conflict_result(data: Dictionary) -> void:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
extends SceneTree
|
||||
|
||||
const MainScene: PackedScene = preload("res://main/main.tscn")
|
||||
const AnimaleseVoiceType = preload("res://ui/animalese_voice.gd")
|
||||
const TEST_PORT: int = 18144
|
||||
const HOST_VOICE_MESSAGE: String = "remote voice playback"
|
||||
|
||||
|
||||
func _initialize() -> void:
|
||||
|
|
@ -23,8 +25,24 @@ func _run() -> void:
|
|||
func _run_host() -> void:
|
||||
var main: Node = await _create_initialized_main()
|
||||
var session := main.get_node("%NetworkSession") as NetworkSession
|
||||
var profile := main.get_node(
|
||||
"%NetworkProfilePreferences"
|
||||
) as NetworkProfilePreferences
|
||||
assert(profile.set_profile_identity(
|
||||
profile.display_name,
|
||||
"deep",
|
||||
profile.speech_speed_id,
|
||||
profile.call_id,
|
||||
"kim",
|
||||
))
|
||||
var save_manager := main.get("_save_manager") as PlayerSaveManager
|
||||
assert(session.start_private_host(TEST_PORT))
|
||||
var local_avatar := main.get_node("%PlayerSpawnService").get_avatar(
|
||||
1
|
||||
) as Player
|
||||
assert(local_avatar != null)
|
||||
assert(local_avatar.get_animalese_voice_id() == "deep")
|
||||
assert(local_avatar.get_animalese_sample_set_id() == "kim")
|
||||
assert(save_manager.initialize_new_game())
|
||||
main.call("_enter_gameplay")
|
||||
for _frame: int in 4:
|
||||
|
|
@ -58,6 +76,11 @@ func _run_host() -> void:
|
|||
assert(avatar != null)
|
||||
assert(avatar.appearance_snapshot == changed)
|
||||
assert(record.display_name != "NetworkProfileService")
|
||||
assert(chat_service.send_local_message(
|
||||
HOST_VOICE_MESSAGE,
|
||||
profile.voice_id,
|
||||
profile.sample_set_id,
|
||||
))
|
||||
var voice_message_deadline: int = Time.get_ticks_msec() + 8000
|
||||
while (
|
||||
Time.get_ticks_msec() < voice_message_deadline
|
||||
|
|
@ -80,6 +103,14 @@ func _run_host() -> void:
|
|||
|
||||
func _run_client() -> void:
|
||||
var main: Node = await _create_initialized_main()
|
||||
var chat_ui := main.get_node("%GameUI").get_node("%ChatUI") as ChatUI
|
||||
var animalese := chat_ui.get("_animalese_voice") as AnimaleseVoiceType
|
||||
assert(animalese != null)
|
||||
var remote_voice_samples: Array[String] = []
|
||||
animalese.character_sample_played.connect(
|
||||
func(sample_set_id: String, _character: String) -> void:
|
||||
remote_voice_samples.append(sample_set_id)
|
||||
)
|
||||
main.call("_on_title_join_game_requested", "127.0.0.1:%d" % TEST_PORT)
|
||||
var session := main.get_node("%NetworkSession") as NetworkSession
|
||||
var join_deadline: int = Time.get_ticks_msec() + 20000
|
||||
|
|
@ -132,6 +163,29 @@ func _run_client() -> void:
|
|||
var chat_service := main.get_node(
|
||||
"%NetworkChatService"
|
||||
) as NetworkChatService
|
||||
var host_voice_messages: Array[Dictionary] = []
|
||||
for message: Dictionary in chat_service.get_history():
|
||||
if str(message.get("body", "")) == HOST_VOICE_MESSAGE:
|
||||
host_voice_messages.append(message)
|
||||
var host_voice_deadline: int = Time.get_ticks_msec() + 8000
|
||||
while (
|
||||
Time.get_ticks_msec() < host_voice_deadline
|
||||
and (
|
||||
host_voice_messages.is_empty()
|
||||
or remote_voice_samples.is_empty()
|
||||
)
|
||||
):
|
||||
await process_frame
|
||||
for message: Dictionary in chat_service.get_history():
|
||||
if (
|
||||
str(message.get("body", "")) == HOST_VOICE_MESSAGE
|
||||
and message not in host_voice_messages
|
||||
):
|
||||
host_voice_messages.append(message)
|
||||
assert(not host_voice_messages.is_empty())
|
||||
assert(str(host_voice_messages[0].get("voice_id", "")) == "deep")
|
||||
assert(str(host_voice_messages[0].get("sample_set_id", "")) == "kim")
|
||||
assert(remote_voice_samples.has("kim"))
|
||||
var local_confirmations: Array[Dictionary] = []
|
||||
chat_service.local_message_confirmed.connect(
|
||||
func(message: Dictionary) -> void:
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
class_name AnimaleseVoice
|
||||
extends Node
|
||||
|
||||
signal character_sample_played(sample_set_id: String, character: String)
|
||||
|
||||
const SUPPORTED_CHARACTERS := "abcdefghijklmnopqrstuvwxyz0123456789"
|
||||
const DEFAULT_CHARACTERS_PER_SECOND: float = 28.0
|
||||
const POLYPHONY: int = 8
|
||||
|
|
@ -144,3 +146,4 @@ func _play_character(
|
|||
1.45,
|
||||
)
|
||||
_playback.play_stream(sample, 0.0, volume_db, pitch)
|
||||
character_sample_played.emit(sample_set_id, normalized)
|
||||
|
|
|
|||
|
|
@ -322,10 +322,11 @@ func set_available(value: bool) -> void:
|
|||
_refresh_visibility()
|
||||
|
||||
|
||||
func close_chat() -> void:
|
||||
func close_chat(preserve_status: bool = false) -> void:
|
||||
var ownership_was_active: bool = _opened or _input_lock_applied
|
||||
_opened = false
|
||||
_set_status("")
|
||||
if not preserve_status:
|
||||
_set_status("")
|
||||
_entry.virtual_keyboard_enabled = false
|
||||
_entry.release_focus()
|
||||
_entry.hide()
|
||||
|
|
@ -860,37 +861,46 @@ func _handle_chat_command(body: String) -> bool:
|
|||
"weather":
|
||||
_handle_weather_command(parts)
|
||||
"":
|
||||
_set_status("Enter a command after /.")
|
||||
_show_command_error("Enter a command after /.")
|
||||
_:
|
||||
_set_status("Unknown command: /%s" % command)
|
||||
_show_command_error("Unknown command: /%s" % command)
|
||||
_entry.clear()
|
||||
_flush_draft()
|
||||
return true
|
||||
|
||||
|
||||
func _show_command_error(message: String) -> void:
|
||||
_set_status(message)
|
||||
close_chat(true)
|
||||
|
||||
|
||||
func _handle_time_command(parts: PackedStringArray) -> void:
|
||||
if parts.size() != 2:
|
||||
_set_status("Usage: /time [dawn, day, dusk, night]")
|
||||
_show_command_error("Usage: /time [dawn, day, dusk, night]")
|
||||
return
|
||||
if _service == null or _world_time == null:
|
||||
_set_status("World time is unavailable.")
|
||||
_show_command_error("World time is unavailable.")
|
||||
return
|
||||
var phase_name := String(parts[1]).to_lower()
|
||||
if phase_name not in ["dawn", "day", "dusk", "night"]:
|
||||
_set_status("Usage: /time [dawn, day, dusk, night]")
|
||||
_show_command_error("Usage: /time [dawn, day, dusk, night]")
|
||||
return
|
||||
if not _service.request_world_time_change(phase_name):
|
||||
_set_status("Only the host or an operator can change world time.")
|
||||
_show_command_error(
|
||||
"Only the host or an operator can change world time."
|
||||
)
|
||||
return
|
||||
close_chat()
|
||||
|
||||
|
||||
func _handle_weather_command(parts: PackedStringArray) -> void:
|
||||
if parts.size() != 2:
|
||||
_set_status("Usage: /weather [clear, cloudy, rainy, foggy]")
|
||||
_show_command_error(
|
||||
"Usage: /weather [clear, cloudy, rainy, foggy]"
|
||||
)
|
||||
return
|
||||
if _service == null or _world_weather == null:
|
||||
_set_status("World weather is unavailable.")
|
||||
_show_command_error("World weather is unavailable.")
|
||||
return
|
||||
var weather_name := String(parts[1]).to_lower()
|
||||
match weather_name:
|
||||
|
|
@ -899,10 +909,14 @@ func _handle_weather_command(parts: PackedStringArray) -> void:
|
|||
"cloudy", "rainy", "foggy":
|
||||
pass
|
||||
_:
|
||||
_set_status("Usage: /weather [clear, cloudy, rainy, foggy]")
|
||||
_show_command_error(
|
||||
"Usage: /weather [clear, cloudy, rainy, foggy]"
|
||||
)
|
||||
return
|
||||
if not _service.request_world_weather_change(weather_name):
|
||||
_set_status("Only the host or an operator can change world weather.")
|
||||
_show_command_error(
|
||||
"Only the host or an operator can change world weather."
|
||||
)
|
||||
return
|
||||
close_chat()
|
||||
|
||||
|
|
@ -1009,7 +1023,7 @@ func _show_speech_bubble(
|
|||
speaker_avatar.get_animalese_sample_set_id()
|
||||
)
|
||||
_animalese_voice.speak_text(
|
||||
label,
|
||||
_animalese_voice,
|
||||
label.text,
|
||||
str(peer_id),
|
||||
voice_profile_id,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue