summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/game.gd415
-rw-r--r--client/menu/game.gd4
-rw-r--r--client/multiplayer.gd199
3 files changed, 224 insertions, 394 deletions
diff --git a/client/game.gd b/client/game.gd
index ef7a4575..e769f01c 100644
--- a/client/game.gd
+++ b/client/game.gd
@@ -61,29 +61,26 @@ var spectating_mode: SpectatingMode = SpectatingMode.CENTER
@onready var follow_camera: FollowCamera = $FollowCamera
func _ready():
- mp.replay_start.connect(func(): is_replay = true)
+ mp.packet.connect(handle_packet)
mp.connection_closed.connect(func(reason: String):
Global.error_message = reason;
get_parent().replace_menu("res://menu/error.tscn")
)
- mp.joined.connect(func(player_id_: int): player_id = player_id_)
- mp.data.connect(func(
- item_names_: Array,
- tile_names_: Array,
- tile_collide_: Array,
- tile_interact_: Array,
- maps_: Array,
- bot_algos_: Array
- ):
- item_names = item_names_
- tile_names = tile_names_
- tile_collide = tile_collide_
- tile_interact = tile_interact_
- maps = maps_
- bot_algos = bot_algos_
- tile_index_by_name = {}
+func handle_packet(p):
+ match p.type:
+ "joined":
+ player_id = p["id"]
+ "data":
+ item_names = p["data"]["item_names"]
+ tile_names = p["data"]["tile_names"]
+ tile_collide = p["data"]["tile_collide"]
+ tile_interact = p["data"]["tile_interact"]
+ maps = p["data"]["maps"]
+ bot_algos = p["data"]["bot_algos"]
+
+ tile_index_by_name.clear()
for id in tile_names.size():
tile_index_by_name[tile_names[id]] = id
@@ -92,188 +89,201 @@ func _ready():
item_index_by_name[item_names[i]] = i
data_updated.emit()
- )
-
- mp.add_player.connect(func(player: int, player_name: String, pos: Vector2, character: int):
- var player_instance: Player
- if player == player_id:
- player_instance = ControllablePlayer.new(player, player_name, pos, character, self)
- in_lobby_updated.connect(player_instance.onscreen_controls.in_lobby_updated)
- player_instance.onscreen_controls.in_lobby_updated(in_lobby)
- camera.target = player_instance.movement_base
- is_joined = true
- join_sent = true
- joined.emit()
- else:
- player_instance = Player.new(player, player_name, pos, character, self)
- players[player] = player_instance
- add_child(player_instance)
- update_players.emit(players)
- )
-
- mp.set_tile.connect(set_tile)
- mp.remove_tile.connect(func (pos): map.clear_tile(pos))
-
- mp.movement.connect(func(player: int, pos: Vector2, rot: float, boost: bool, _dir: Vector2):
- var player_instance: Player = players[player]
- player_instance.update_position(pos, rot, boost)
- if player == player_id:
- last_position = pos
- )
-
- mp.movement_sync.connect(func():
- if not players.has(player_id):
- return
- var player_instance: ControllablePlayer = players[player_id]
- player_instance.position_ = last_position
- )
-
- mp.remove_player.connect(func(id: int):
- var player: Player = players.get(id)
- if id == player_id:
- is_joined = false
- join_sent = false
- left.emit()
- camera.target = $Center
- if player != null:
- if player.hand != null:
- player.hand.queue_free()
- players.erase(id)
- player.queue_free()
- update_players.emit(players)
- )
-
- mp.set_tile_item.connect(func(tile: Vector2i, item: int):
- var t: Tile = map.get_tile_instance(tile)
- var i = ItemFactory.produce(item_names[item], t.item_base)
- i.position = t.item_base.global_position
- add_child(i)
- i.name = item_names[item]
- t.set_item(i)
- )
-
- mp.remove_tile_item.connect(func(tile: Vector2i):
- var t: Tile = map.get_tile_instance(tile)
- t.set_item(null)
- )
-
- mp.set_player_item.connect(func(player: int, item: int):
- var p: Player = players[player]
- var i = ItemFactory.produce(item_names[item], p.hand_base)
- add_child(i)
- i.name = item_names[item]
- p.set_item(i)
- )
-
- mp.remove_player_item.connect(func(player: int):
- var p: Player = players[player]
- p.set_item(null)
- )
-
- mp.take_item.connect(func(tile: Vector2i, player: int):
- var t: Tile = map.get_tile_instance(tile)
- var p: Player = players[player]
- p.take_item(t)
- )
-
- mp.put_item.connect(func(player: int, tile: Vector2i):
- var t: Tile = map.get_tile_instance(tile)
- var p: Player = players[player]
- p.put_item(t)
- )
-
- mp.pass_item_player.connect(func(from: int, to: int):
- var from_player: Player = players[from]
- var to_player: Player = players[to]
- from_player.pass_to(to_player)
- )
-
- mp.pass_item_tile.connect(func(from: Vector2i, to: Vector2i):
- var from_tile: Tile = map.get_tile_instance(from)
- var to_tile: Tile = map.get_tile_instance(to)
- from_tile.pass_to(to_tile)
- )
-
- mp.set_tile_progress.connect(func(tile: Vector2i, position_: float, speed: float, warn: bool, acting_player):
- var t: Tile = map.get_tile_instance(tile)
- t.progress(position_, speed, warn, players.get(acting_player))
- )
-
- mp.set_tile_finished.connect(func(tile: Vector2i):
- var t: Tile = map.get_tile_instance(tile)
- t.finish()
- )
-
- mp.set_player_progress.connect(func(player: int, position_: float, speed: float, warn: bool):
- var p: Player = players[player]
- p.progress(position_, speed, warn)
- )
-
- mp.set_player_finished.connect(func(player: int):
- var p: Player = players[player]
- p.finish()
- )
-
- mp.text_message.connect(func(player: int, text: String, timeout_initial: float, timeout_remaining: float):
- var p: Player = players[player]
- p.text_message(text, timeout_initial, timeout_remaining)
- var username: String = players[player].username
- text_message.emit(username, text, timeout_initial, timeout_remaining)
- text_message_history.append([username, text])
- )
-
- mp.item_message.connect(func(player: int, item: int, timeout_initial: float, timeout_remaining: float):
- var p: Player = players[player]
- p.item_message(item_names[item], timeout_initial, timeout_remaining)
- )
-
- mp.effect_message.connect(func(player: int, effect: String, timeout_initial: float, timeout_remaining: float):
- var p: Player = players[player]
- p.effect_message(effect, timeout_initial, timeout_remaining)
- )
-
- mp.clear_message.connect(func(player: int):
- var p: Player = players[player]
- p.clear_message()
- )
-
- mp.set_ingame.connect(func (state, in_lobby_):
- in_lobby = in_lobby_
- in_lobby_updated.emit(in_lobby)
- if state:
- map.gi_bake()
- await get_parent()._menu_open()
- map.autobake = true
-
- if in_lobby_:
- popup_message.lobby()
+ "add_player":
+ var id = p["id"]
+ var player_name = p["name"]
+ var pos = pos_to_vec2(p["position"])
+ var character = p["character"]
+ var player_instance: Player
+ if id == player_id:
+ player_instance = ControllablePlayer.new(id, player_name, pos, character, self)
+ in_lobby_updated.connect(player_instance.onscreen_controls.in_lobby_updated)
+ player_instance.onscreen_controls.in_lobby_updated(in_lobby)
+ camera.target = player_instance.movement_base
+ is_joined = true
+ join_sent = true
+ joined.emit()
else:
- popup_message.ingame()
- else:
- map.autobake = false
- await get_parent()._menu_exit()
- )
-
- mp.server_message.connect(
- func(text):
- print("== ", text)
- popup_message.display_server_msg(text)
- )
+ player_instance = Player.new(id, player_name, pos, character, self)
+ players[id] = player_instance
+ add_child(player_instance)
+ update_players.emit(players)
+ "remove_player":
+ var player: Player = players.get(p.id)
+ if p.id == player_id:
+ is_joined = false
+ join_sent = false
+ left.emit()
+ camera.target = $Center
+ if player != null:
+ if player.hand != null:
+ player.hand.queue_free()
+ players.erase(p.id)
+ player.queue_free()
+ update_players.emit(players)
+ "movement":
+ var player = p["player"]
+ var pos = pos_to_vec2(p["pos"])
+ var rot = p["rot"]
+ var boost = p["boost"]
+ var dir = pos_to_vec2(p["dir"])
+ var player_instance: Player = players[player]
+ player_instance.update_position(pos, rot, boost)
+ if player == player_id:
+ last_position = pos
+ "movement_sync":
+ if not players.has(player_id): return
+ var player_instance: ControllablePlayer = players[player_id]
+ player_instance.position_ = last_position
+ "move_item":
+ var from: Dictionary = p["from"]
+ var to: Dictionary = p["to"]
+ var from_player = from.get("player")
+ var from_tile = from.get("tile")
+ var to_player = to.get("player")
+ var to_tile = to.get("tile")
+ if from_player != null and to_player != null:
+ players[from_player].pass_to(players[to_player])
+ elif from_tile != null and to_player != null:
+ var t: Tile = map.get_tile_instance(pos_to_vec2i(from_tile))
+ players[to_player].take_item(t)
+ elif from_player != null and to_tile != null:
+ var t: Tile = map.get_tile_instance(pos_to_vec2i(to_tile))
+ players[from_player].put_item(t)
+ elif from_tile != null and to_tile != null:
+ var from_tile2: Tile = map.get_tile_instance(pos_to_vec2i(from_tile))
+ var to_tile2: Tile = map.get_tile_instance(pos_to_vec2i(to_tile))
+ from_tile2.pass_to(to_tile2)
+ "set_progress":
+ var warn: bool = p["warn"]
+ var position: float = p["position"]
+ var speed: float = p["speed"]
+ var item: Dictionary = p["item"]
+ var tile = item.get("tile")
+ var player = item.get("player")
+ var acting_player = p.get("player")
+
+ if tile != null:
+ @warning_ignore("incompatible_ternary")
+ var t: Tile = map.get_tile_instance(pos_to_vec2i(tile))
+ t.progress(position, speed, warn, players.get(int(acting_player) if acting_player != null else null))
+ else:
+ players[player].progress(position, speed, warn)
+ "clear_progress":
+ var item: Dictionary = p["item"]
+ var tile = item.get("tile")
+ var player = item.get("player")
+
+ if tile != null:
+ var t: Tile = map.get_tile_instance(pos_to_vec2i(tile))
+ t.finish()
+ else:
+ players[player].finish()
+ "set_item":
+ var location: Dictionary = p["location"]
+ var tile = location.get("tile")
+ var player = location.get("player")
+ var item = p.get("item")
+ if item != null:
+ if tile != null:
+ var t: Tile = map.get_tile_instance(pos_to_vec2i(tile))
+ var i = ItemFactory.produce(item_names[item], t.item_base)
+ i.position = t.item_base.global_position
+ add_child(i)
+ i.name = item_names[item]
+ t.set_item(i)
+ else:
+ var pl: Player = players[player]
+ var i = ItemFactory.produce(item_names[item], pl.hand_base)
+ add_child(i)
+ i.name = item_names[item]
+ pl.set_item(i)
+ else:
+ if tile != null:
+ var t: Tile = map.get_tile_instance(pos_to_vec2i(tile))
+ t.set_item(null)
+ else:
+ players[player].set_item(null)
+ "update_map":
+ var tile: Vector2i = pos_to_vec2i(p["tile"])
+ var kind = p.get("kind")
+ var neighbors: Array = p["neighbors"]
+ if kind != null:
+ if neighbors != null: neighbors = neighbors.map(func(x): return tile_names[x] if x != null else null)
+ map.set_tile(tile, tile_names[kind], neighbors)
+ else: map.clear_tile(tile)
+ "communicate":
+ var player: int = p["player"]
+ var message = p.get("message")
+ var timeout_initial: float = p["timeout"]["initial"] if p["timeout"] != null else 5.
+ var timeout_remaining: float = p["timeout"]["remaining"] if p["timeout"] != null else 5.
+ if message != null:
+ var item = message.get("item")
+ var text = message.get("text")
+ var effect = message.get("effect")
+ if item != null:
+ players[player].item_message(item_names[item], timeout_initial, timeout_remaining)
+ elif text != null:
+ players[player].text_message(text, timeout_initial, timeout_remaining)
+ var username: String = players[player].username
+ text_message.emit(username, text, timeout_initial, timeout_remaining)
+ text_message_history.append([username, text])
+ else:
+ push_error("neither text, item nor effect provided")
+ else:
+ players[player].clear_message()
+ "effect":
+ var player: int = p["player"]
+ var name: int = p["name"]
+ players[player].effect_message(name)
+ "set_ingame":
+ var state = p["state"]
+ var lob = p["lobby"]
+ in_lobby = lob
+ in_lobby_updated.emit(in_lobby)
+ if state:
+ map.gi_bake()
+ await get_parent()._menu_open()
+ map.autobake = true
- mp.score.connect(overlay.update)
- mp.set_ingame.connect(overlay.set_ingame)
- mp.set_ingame.connect(follow_camera.set_ingame)
+ if lobby: popup_message.lobby()
+ else: popup_message.ingame()
+ else:
+ map.autobake = false
+ await get_parent()._menu_exit()
- mp.set_ingame.connect(
- func toggle_lobby(_state: bool, lobby_state: bool):
- lobby.visible = lobby_state
- if lobby_state and not join_sent:
+ lobby.visible = in_lobby
+ if lobby and not join_sent:
join()
- )
-
- mp.show_book.connect(func (): menu.submenu("res://menu/book/book.tscn"))
- mp.environment.connect($Environment.update)
+ overlay.set_ingame(state, lob)
+ follow_camera.set_ingame(state, lob)
+ "error":
+ var message = p["message"]
+ push_warning("server error: %s" % message)
+ "score":
+ var demands_failed: int = p["demands_failed"]
+ var demands_completed: int = p["demands_completed"]
+ var points: int = p["points"]
+ var time_remaining = p.get("time_remaining")
+ if time_remaining != null:
+ overlay.update(demands_failed, demands_completed, points, time_remaining)
+ "menu":
+ var menu_type: String = p["menu"]
+ match menu_type:
+ "book":
+ menu.submenu("res://menu/book/book.tscn")
+ "score":
+ menu.submenu("res://menu/rating/rating.tscn", [p.data.stars, p.data.score])
+ "server_message":
+ var message = p["message"]
+ popup_message.display_server_msg(message)
+ "environment":
+ $Environment.update(p["effects"])
+ "replay_start":
+ is_replay = true
+
+ _: push_error("Unrecognized packet type: %s" % p.type)
func join():
join_sent = true
@@ -299,9 +309,6 @@ func get_tile_interactive(pos: Vector2i) -> bool:
if t == null: return false
else: return tile_interact[tile_index_by_name[t]]
-func set_tile(tile: Vector2i, kind = null, neighbors = null):
- if neighbors != null: neighbors = neighbors.map(func (x): return tile_names[x] if x != null else null)
- map.set_tile(tile, tile_names[kind], neighbors)
func update_center():
if is_joined:
@@ -319,8 +326,8 @@ func update_center():
func spectate_center():
var sum: int = 0
var player_sum: int = 0
- var center: Vector3 = Vector3(0., 0., 0.)
- var player_center: Vector3 = Vector3(0., 0., 0.)
+ var center: Vector3 = Vector3(0.,0.,0.)
+ var player_center: Vector3 = Vector3(0.,0.,0.)
for v in players.values():
var p: Player = v
if p.character_idx >= 0:
@@ -329,7 +336,7 @@ func spectate_center():
sum += 1
center += p.movement_base.position
- var new_center: Vector3 = Vector3(0., 0., 0.)
+ var new_center: Vector3 = Vector3(0.,0.,0.)
if player_sum > 0:
new_center = player_center / player_sum
elif sum > 0:
@@ -337,7 +344,7 @@ func spectate_center():
else:
var extents = map.extents()
var map_center = ((extents[0] + extents[1]) / 2) + Vector2(.5, .5)
- new_center = Vector3(map_center.x, 0., map_center.y)
+ new_center = Vector3(map_center.x, 0.,map_center.y)
$Center.position = new_center
func spectate_free():
@@ -351,3 +358,9 @@ func spectate_free():
var extents = map.extents()
$Center.position.x = clamp($Center.position.x, extents[0].x, extents[1].x)
$Center.position.z = clamp($Center.position.z, extents[0].y, extents[1].y)
+
+func pos_to_vec2(pos: Array) -> Vector2:
+ return Vector2(pos[0], pos[1])
+
+func pos_to_vec2i(pos: Array) -> Vector2i:
+ return Vector2i(pos[0], pos[1])
diff --git a/client/menu/game.gd b/client/menu/game.gd
index a2eb858c..fb0d2fa9 100644
--- a/client/menu/game.gd
+++ b/client/menu/game.gd
@@ -25,7 +25,6 @@ class_name GameMenu
func _ready():
get_tree().get_root().connect("go_back_requested", open_ingame_menu)
- game.mp.show_rating.connect(show_rating)
super()
func _input(_event):
@@ -52,6 +51,3 @@ func open_ingame_menu():
if popup != null: return
Sound.play_click()
submenu("res://menu/ingame.tscn")
-
-func show_rating(stars: int, score: int):
- submenu("res://menu/rating/rating.tscn", [stars, score])
diff --git a/client/multiplayer.gd b/client/multiplayer.gd
index 1a261b99..6b642d90 100644
--- a/client/multiplayer.gd
+++ b/client/multiplayer.gd
@@ -18,47 +18,10 @@
class_name Multiplayer
extends Node
-signal joined(player_id: int)
-signal data(
- item_names: Array[String],
- tile_names: Array[String],
- tile_collide: Array[String],
- tile_interact: Array[String],
- maps: Array,
- bot_algos: Array
-)
-signal set_tile(tile: Vector2i, kind: int, neighbors: Array[String])
-signal remove_tile(tile: Vector2i)
-signal clear_message(player: int)
-signal text_message(player: int, text: String, timeout_initial: float, timeout_remaining: float)
-signal item_message(player: int, item: int, timeout_initial: float, timeout_remaining: float)
-signal effect_message(player: int, effect: String, timeout_initial: float, timeout_remaining: float)
-signal add_player(player: int, name: String, pos: Vector2, character: int)
-signal remove_player(player: int)
-signal movement(player: int, position: Vector2, rotation: float, boost: bool, direction: Vector2)
-signal movement_sync()
-signal take_item(tile: Vector2i, player: int)
-signal put_item(player: int, tile: Vector2i, )
-signal pass_item_player(from: int, to: int)
-signal pass_item_tile(from: Vector2i, to: Vector2i)
-signal set_tile_item(tile: Vector2i, item: int)
-signal remove_tile_item(tile: Vector2i)
-signal set_player_item(player: int, item: int)
-signal remove_player_item(player: int)
-signal set_tile_progress(tile: Vector2i, position: float, speed: float, warn: bool, acting_player)
-signal set_player_progress(player: int, position: float, speed: float, warn: bool)
-signal set_tile_finished(tile: Vector2i, warn: bool)
-signal set_player_finished(player: int, warn: bool)
-signal set_ingame(state: bool, lobby: bool)
-signal score(demands_failed: int, demands_completed: int, points: int, time_remaining: float)
-signal environment(params: Dictionary)
-signal server_message(text: String)
-signal replay_start()
-signal connection_closed(reason: String)
-signal show_rating(stars: int, points: int)
-signal show_book()
+signal packet(packet: Dictionary)
+signal connection_closed()
-const VERSION_MAJOR: int = 6
+const VERSION_MAJOR: int = 7
const VERSION_MINOR: int = 0
var connected := false
@@ -89,162 +52,20 @@ func _process(_delta):
connection_closed.emit(tr("c.error.websocket") % [code, reason, code != -1])
self.queue_free()
-func handle_packet(bytes: PackedByteArray):
- var decoded = decode_packet(bytes)
-
- if decoded == null:
+func handle_packet(coded):
+ var p = decode_packet(coded)
+ if p == null:
return
- var packet_type: String = decoded["type"]
- match packet_type:
- "joined":
- var player_id = decoded["id"]
- joined.emit(player_id)
+ match p["type"]:
"version":
- var major = decoded["major"]
- var minor = decoded["minor"]
+ var major = p["major"]
+ var minor = p["minor"]
if major != VERSION_MAJOR and minor >= VERSION_MINOR:
socket.close()
connected = false
connection_closed.emit(tr("c.error.version_mismatch") % [major, minor, VERSION_MAJOR, VERSION_MINOR])
- "data":
- var item_names = decoded["data"]["item_names"]
- var tile_names = decoded["data"]["tile_names"]
- var tile_collide = decoded["data"]["tile_collide"]
- var tile_interact = decoded["data"]["tile_interact"]
- var maps = decoded["data"]["maps"]
- var bot_algos = decoded["data"]["bot_algos"]
- data.emit(item_names, tile_names, tile_collide, tile_interact, maps, bot_algos)
- "add_player":
- var id = decoded["id"]
- var player_name = decoded["name"]
- var pos = decoded["position"]
- var character = decoded["character"]
- add_player.emit(id, player_name, pos_to_vec2(pos), character)
- "remove_player":
- var id = decoded["id"]
- remove_player.emit(id)
- "movement":
- var player = decoded["player"]
- var pos = decoded["pos"]
- var rot = decoded["rot"]
- var boost = decoded["boost"]
- var dir = decoded["dir"]
- movement.emit(player, pos_to_vec2(pos), rot, boost, pos_to_vec2(dir))
- "movement_sync":
- movement_sync.emit()
- "move_item":
- var from: Dictionary = decoded["from"]
- var to: Dictionary = decoded["to"]
- var from_player = from.get("player")
- var from_tile = from.get("tile")
- var to_player = to.get("player")
- var to_tile = to.get("tile")
- if from_player != null and to_player != null:
- pass_item_player.emit(from_player, to_player)
- elif from_tile != null and to_player != null:
- take_item.emit(pos_to_vec2i(from_tile), to_player)
- elif from_player != null and to_tile != null:
- put_item.emit(from_player, pos_to_vec2i(to_tile))
- elif from_tile != null and to_tile != null:
- pass_item_tile.emit(pos_to_vec2i(from_tile), pos_to_vec2i(to_tile))
- "set_progress":
- var warn: bool = decoded["warn"]
- var position: float = decoded["position"]
- var speed: float = decoded["speed"]
- var item: Dictionary = decoded["item"]
- var tile = item.get("tile")
- var player = item.get("player")
- var acting_player = decoded.get("player")
-
- if tile != null:
- @warning_ignore("incompatible_ternary")
- set_tile_progress.emit(pos_to_vec2i(tile), position, speed, warn, int(acting_player) if acting_player != null else null)
- else:
- set_player_progress.emit(player, position, speed, warn)
- "clear_progress":
- var item: Dictionary = decoded["item"]
- var tile = item.get("tile")
- var player = item.get("player")
-
- if tile != null:
- set_tile_finished.emit(pos_to_vec2i(tile))
- else:
- set_player_finished.emit(player)
- "set_item":
- var location: Dictionary = decoded["location"]
- var tile = location.get("tile")
- var player = location.get("player")
- var item = decoded.get("item")
- if item != null:
- if tile != null:
- set_tile_item.emit(pos_to_vec2i(tile), item)
- else:
- set_player_item.emit(player, item)
- else:
- if tile != null:
- remove_tile_item.emit(pos_to_vec2i(tile))
- else:
- remove_player_item.emit(player)
- "update_map":
- var tile: Vector2i = pos_to_vec2i(decoded["tile"])
- var kind = decoded.get("kind")
- var neighbors: Array = decoded["neighbors"]
- if kind != null:
- set_tile.emit(tile, kind, neighbors)
- else:
- remove_tile.emit(tile)
- "communicate":
- var player: int = decoded["player"]
- var message = decoded.get("message")
- var timeout_initial: float = decoded["timeout"]["initial"] if decoded["timeout"] != null else 5.
- var timeout_remaining: float = decoded["timeout"]["remaining"] if decoded["timeout"] != null else 5.
- if message != null:
- var item = message.get("item")
- var text = message.get("text")
- var effect = message.get("effect")
- if item != null:
- item_message.emit(player, item, timeout_initial, timeout_remaining)
- elif text != null:
- text_message.emit(player, text, timeout_initial, timeout_remaining)
- elif effect != null:
- effect_message.emit(player, effect, timeout_initial, timeout_remaining)
- else:
- push_error("neither text, item nor effect provided")
- else:
- clear_message.emit(player)
- "set_ingame":
- var state = decoded["state"]
- var lobby = decoded["lobby"]
- set_ingame.emit(state, lobby)
- "error":
- var message = decoded["message"]
- push_warning("server error: %s" % message)
- "score":
- var demands_failed: int = decoded["demands_failed"]
- var demands_completed: int = decoded["demands_completed"]
- var points: int = decoded["points"]
- var time_remaining = decoded.get("time_remaining")
- if time_remaining != null:
- score.emit(demands_failed, demands_completed, points, time_remaining)
- "menu":
- var menu: String = decoded["menu"]
- match menu:
- "book":
- show_book.emit()
- "score":
- var d: Dictionary = decoded["data"]
- var stars = d["stars"]
- var points = d["points"]
- show_rating.emit(stars, points)
- "server_message":
- var text = decoded["text"]
- server_message.emit(text)
- "environment":
- environment.emit(decoded["effects"])
- "replay_start": replay_start.emit()
- _:
- push_error("Unrecognized packet type: %s" % packet_type)
+ _: packet.emit(p)
func send_join(player_name: String, character: int):
send_packet({