diff options
Diffstat (limited to 'client/game.gd')
| -rw-r--r-- | client/game.gd | 415 | 
1 files changed, 214 insertions, 201 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]) | 
