diff options
| author | nokoe <nokoe@mailbox.org> | 2024-06-25 22:31:17 +0200 | 
|---|---|---|
| committer | nokoe <nokoe@mailbox.org> | 2024-06-25 23:39:19 +0200 | 
| commit | 8bb065604fbd12b14a7605cfa265ebf38890f628 (patch) | |
| tree | 811866aec6093924694605155d9962261c57cb17 | |
| parent | ab6279e726ac7e10a4c5211a3d3827471fd35ccf (diff) | |
| download | hurrycurry-8bb065604fbd12b14a7605cfa265ebf38890f628.tar hurrycurry-8bb065604fbd12b14a7605cfa265ebf38890f628.tar.bz2 hurrycurry-8bb065604fbd12b14a7605cfa265ebf38890f628.tar.zst | |
multiplayer refactor
| -rw-r--r-- | client/game.gd | 116 | ||||
| -rw-r--r-- | client/game.tscn | 8 | ||||
| -rw-r--r-- | client/map/map.gd | 37 | ||||
| -rw-r--r-- | client/map/map.tscn | 44 | ||||
| -rw-r--r-- | client/menu/menu_background.gd | 17 | ||||
| -rw-r--r-- | client/menu/menu_background.tscn | 5 | ||||
| -rw-r--r-- | client/multiplayer.gd | 62 | ||||
| -rw-r--r-- | client/player/character/character.gd | 2 | ||||
| -rw-r--r-- | client/player/controllable_player.gd | 9 | 
9 files changed, 179 insertions, 121 deletions
| diff --git a/client/game.gd b/client/game.gd index f3c2f81c..4b90f00c 100644 --- a/client/game.gd +++ b/client/game.gd @@ -18,25 +18,51 @@ class_name Game  extends Node3D  @onready var camera: FollowCamera = $FollowCamera -@onready var map: Map = $Map  @onready var mp: Multiplayer = $Multiplayer  @onready var marker: Marker = $Marker  var marker_target = Vector3(0,0,0) +var player_id: int = -1 +var item_names: Array = [] +var tile_names: Array = [] +var tile_collide: Array = [] +var tile_interact: Array = [] + +var item_idx_from_name: Dictionary = {} +var tile_by_pos: Dictionary = {} +  var players := {}  func _ready(): -	mp.connect("connection_closed", func(reason: String): +	mp.connection_closed.connect(func(reason: String):  		Global.error_message = reason;  		$SceneTransition.instant_to("res://menu/error_menu.tscn")  	) +	mp.init.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 +		): +			item_names = item_names_ +			tile_names = tile_names_ +			tile_collide = tile_collide_ +			tile_interact = tile_interact_ + +			item_idx_from_name.clear() +			for i in range(item_names.size()): +				item_idx_from_name[item_names[i]] = i +	)  	await mp.init -	if mp.player_id == -1: + +	if player_id == -1:  		push_error("multiplayer has not been initialized") -	mp.connect("add_player", func(player: int, player_name: String, pos: Vector2, character: int): +	mp.add_player.connect(func(player: int, player_name: String, pos: Vector2, character: int):  		var player_instance: Player -		if player == mp.player_id: +		if player == player_id:  			player_instance = ControllablePlayer.new(player, player_name, pos, character, self)  			camera.target = player_instance  		else: @@ -45,15 +71,19 @@ func _ready():  		add_child(player_instance)  	) -	mp.connect("update_map", map.update) +	mp.set_tile.connect(set_tile) + +	mp.remove_tile.connect(remove_tile_if_exists) -	mp.connect("position", func(player: int, pos: Vector2, rot: float): +	mp.position.connect(func(player: int, pos: Vector2, rot: float):  		var player_instance: Player = players[player]  		player_instance.update_position(pos, rot)  	) -	mp.connect("remove_player", func(id: int): +	mp.remove_player.connect(func(id: int):  		var player: Player = players.get(id) +		if id == player_id: +			camera.target = self  		if player != null:  			if player.hand != null:  				player.hand.queue_free() @@ -61,56 +91,86 @@ func _ready():  			player.queue_free()  	) -	mp.connect("set_tile_item", func(tile: Vector2i, item: int): -		var t: Tile = map.tile_by_pos[str(tile)] -		var i = ItemFactory.produce(mp.item_names[item], t.item_base) +	mp.set_tile_item.connect(func(tile: Vector2i, item: int): +		var t: Tile = tile_by_pos[str(tile)][1] +		var i = ItemFactory.produce(item_names[item], t.item_base)  		add_child(i) -		i.name = mp.item_names[item] +		i.name = item_names[item]  		t.set_item(i)  	) -	mp.connect("remove_tile_item", func(tile: Vector2i): -		var t: Tile = map.tile_by_pos[str(tile)] +	mp.remove_tile_item.connect(func(tile: Vector2i): +		var t: Tile = tile_by_pos[str(tile)][1]  		t.take_item().queue_free()  	) -	mp.connect("set_player_item", func(player: int, item: int): +	mp.set_player_item.connect(func(player: int, item: int):  		var p: Player = players[player] -		var i = ItemFactory.produce(mp.item_names[item], p.hand_base) +		var i = ItemFactory.produce(item_names[item], p.hand_base)  		add_child(i) -		i.name = mp.item_names[item] +		i.name = item_names[item]  		p.set_item(i)  	) -	mp.connect("remove_player_item", func(player: int): +	mp.remove_player_item.connect(func(player: int):  		var p: Player = players[player]  		p.remove_item().queue_free()  	) -	mp.connect("take_item", func(tile: Vector2i, player: int): -		var t: Tile = map.tile_by_pos[str(tile)] +	mp.take_item.connect(func(tile: Vector2i, player: int): +		var t: Tile = tile_by_pos[str(tile)][1]  		var p: Player = players[player]  		p.take_item(t)  	) -	mp.connect("put_item", func(tile: Vector2i, player: int): -		var t: Tile = map.tile_by_pos[str(tile)] +	mp.put_item.connect(func(tile: Vector2i, player: int): +		var t: Tile = tile_by_pos[str(tile)][1]  		var p: Player = players[player]  		p.put_item(t)  	) -	mp.connect("set_progress", func(tile: Vector2i, progress: float, warn: bool): -		var t: Tile = map.tile_by_pos[str(tile)] +	mp.set_progress.connect(func(tile: Vector2i, progress: float, warn: bool): +		var t: Tile = tile_by_pos[str(tile)][1]  		t.progress(progress, warn)  	) -	mp.connect("set_finished", func(tile: Vector2i, warn: bool): -		var t: Tile = map.tile_by_pos[str(tile)] +	mp.set_finished.connect(func(tile: Vector2i, warn: bool): +		var t: Tile = tile_by_pos[str(tile)][1]  		t.finish(warn)  	) -  	mp.send_join(Global.username, Global.character) -  func _process(delta):  	marker.position = lerp(marker.position, marker_target, delta * 40.0) + +func get_tile_collision(pos: Vector2i) -> bool: +	var t: Array = tile_by_pos.get(str(pos)) +	if t == null: return false +	else: return tile_collide[t[0]] + +func get_tile_interactive(pos: Vector2i) -> bool: +	var t: Array = tile_by_pos.get(str(pos)) +	if t == null: return false +	else: return tile_interact[t[0]] + +func set_tile(tile: Vector2i, kind: int, neighbors: Array): +	remove_tile_if_exists(tile) +	var node_name = str(tile) +	var tile_name: String = tile_names[kind] +	neighbors = neighbors.map(func (x): return tile_names[x] if x != null else null) +	var instance: Tile = TileFactory.produce(tile_name, node_name, neighbors) + +	instance.position = Vector3(tile[0], 0, tile[1]) +	tile_by_pos[node_name] = [kind, instance] +	add_child(instance) + +func remove_tile_if_exists(pos: Vector2i): +	var node_name = str(pos) +	var current = tile_by_pos.get(node_name) +	if current != null: +		var tile: Tile = current[1] +		if tile.item != null: +			tile.item.queue_free() +		tile_by_pos.erase(node_name) +		tile.name += "_queued_free" +		tile.queue_free() diff --git a/client/game.tscn b/client/game.tscn index 32479cf5..cfbde85b 100644 --- a/client/game.tscn +++ b/client/game.tscn @@ -1,6 +1,5 @@ -[gd_scene load_steps=10 format=3 uid="uid://c6krh36hoqfg8"] +[gd_scene load_steps=9 format=3 uid="uid://c6krh36hoqfg8"] -[ext_resource type="PackedScene" uid="uid://cs8gxa22c6joh" path="res://map/map.tscn" id="1_ex12v"]  [ext_resource type="Script" path="res://game.gd" id="1_sftfn"]  [ext_resource type="PackedScene" uid="uid://b31mlnao6ybt8" path="res://player/follow_camera.tscn" id="2_s8y6o"]  [ext_resource type="PackedScene" uid="uid://c0euiv7duqfp4" path="res://player/marker.tscn" id="4_igl0o"] @@ -28,10 +27,9 @@ script = ExtResource("1_sftfn")  [node name="Multiplayer" type="Node" parent="."]  script = ExtResource("6_fbxu8") -[node name="Map" parent="." instance=ExtResource("1_ex12v")] - -[node name="FollowCamera" parent="." instance=ExtResource("2_s8y6o")] +[node name="FollowCamera" parent="." node_paths=PackedStringArray("target") instance=ExtResource("2_s8y6o")]  transform = Transform3D(0.728777, 0.294253, -0.618303, 0, 0.902961, 0.429723, 0.684751, -0.313173, 0.658057, -2.36537, 1.99403, 3.29507) +target = NodePath("..")  [node name="WorldEnvironment" type="WorldEnvironment" parent="."]  environment = SubResource("Environment_m4dli") diff --git a/client/map/map.gd b/client/map/map.gd deleted file mode 100644 index d43d7b45..00000000 --- a/client/map/map.gd +++ /dev/null @@ -1,37 +0,0 @@ -# Undercooked - a game about cooking -# Copyright 2024 nokoe -# Copyright 2024 tpart -# Copyright 2024 metamuffin -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, version 3 of the License only. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program.  If not, see <https://www.gnu.org/licenses/>. -# -class_name Map -extends Node3D - -var tile_by_pos: Dictionary = {} - -func update(pos, tile_name, neighbors): -	var node_name = str(pos) - -	if has_node(node_name): -		queue_free_rename(get_node(node_name)) - -	var instance: Tile = TileFactory.produce(tile_name, node_name, neighbors) - -	instance.position = Vector3(pos[0], 0, pos[1]) -	tile_by_pos[str(Vector2i(pos[0], pos[1]))] = instance -	add_child(instance) - -func queue_free_rename(node: Node) -> void: -	node.name += "_queued_free" -	node.queue_free() diff --git a/client/map/map.tscn b/client/map/map.tscn index 66e2c63a..612729f4 100644 --- a/client/map/map.tscn +++ b/client/map/map.tscn @@ -1,6 +1,44 @@ -[gd_scene load_steps=2 format=3 uid="uid://cs8gxa22c6joh"] +[gd_scene load_steps=2 format=3 uid="uid://duqkg22yre6ry"] -[ext_resource type="Script" path="res://map/map.gd" id="1_stp8c"] +[sub_resource type="GDScript" id="GDScript_qftmc"] +script/source = "# Undercooked - a game about cooking +# Copyright 2024 nokoe +# Copyright 2024 tpart +# Copyright 2024 metamuffin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, version 3 of the License only. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program.  If not, see <https://www.gnu.org/licenses/>. +# +class_name Map +extends Node3D + +var tile_by_pos: Dictionary = {} + +func update(pos, tile_name, neighbors): +	var node_name = str(pos) + +	if has_node(node_name): +		queue_free_rename(get_node(node_name)) + +	var instance: Tile = TileFactory.produce(tile_name, node_name, neighbors) + +	instance.position = Vector3(pos[0], 0, pos[1]) +	tile_by_pos[str(Vector2i(pos[0], pos[1]))] = instance +	add_child(instance) + +func queue_free_rename(node: Node) -> void: +	node.name += \"_queued_free\" +	node.queue_free() +"  [node name="Map" type="Node3D"] -script = ExtResource("1_stp8c") +script = SubResource("GDScript_qftmc") diff --git a/client/menu/menu_background.gd b/client/menu/menu_background.gd index 0e8e87e1..62c38baa 100644 --- a/client/menu/menu_background.gd +++ b/client/menu/menu_background.gd @@ -1,23 +1,21 @@  # Undercooked - a game about cooking  # Copyright 2024 metamuffin  # Copyright 2024 tpart -#  +#  # This program is free software: you can redistribute it and/or modify  # it under the terms of the GNU Affero General Public License as published by  # the Free Software Foundation, version 3 of the License only. -#  +#  # This program is distributed in the hope that it will be useful,  # but WITHOUT ANY WARRANTY; without even the implied warranty of  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  # GNU Affero General Public License for more details. -#  +#  # You should have received a copy of the GNU Affero General Public License  # along with this program.  If not, see <https://www.gnu.org/licenses/>. -#  +#  extends Node3D -@onready var map = $Map -  const NULLS = [null,null,null,null]  const BUCKETS = [[], ["floor","floor","floor","floor","tomato-crate", "raw-steak-crate"], ["table", "chair", "counter"], ["sink", "stove"]] @@ -28,5 +26,8 @@ func _ready():  			var k = randf() * w  			var bucket = BUCKETS[int(floor(k * BUCKETS.size())) % BUCKETS.size()]  			if bucket.size() == 0: continue -			var tile = bucket[randi() % bucket.size()] -			map.update([x,y], tile, NULLS) +			var tile_name = bucket[randi() % bucket.size()] +			var tile = TileFactory.produce(tile_name, tile_name, NULLS) + +			add_child(tile) +			tile.position = Vector3(x, 0, y) diff --git a/client/menu/menu_background.tscn b/client/menu/menu_background.tscn index 88ccf49d..5c29e4ac 100644 --- a/client/menu/menu_background.tscn +++ b/client/menu/menu_background.tscn @@ -1,7 +1,6 @@ -[gd_scene load_steps=11 format=3 uid="uid://l4vm07dtda4j"] +[gd_scene load_steps=10 format=3 uid="uid://l4vm07dtda4j"]  [ext_resource type="Script" path="res://menu/menu_background.gd" id="1_ijsg0"] -[ext_resource type="PackedScene" uid="uid://cs8gxa22c6joh" path="res://map/map.tscn" id="2_eg8f5"]  [ext_resource type="Shader" path="res://menu/menu_background.gdshader" id="3_5mp8y"]  [sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_uw50b"] @@ -42,8 +41,6 @@ shader_parameter/noise = SubResource("NoiseTexture2D_s4fnp")  [node name="MenuBackground" type="Node3D"]  script = ExtResource("1_ijsg0") -[node name="Map" parent="." instance=ExtResource("2_eg8f5")] -  [node name="Camera" type="Camera3D" parent="."]  transform = Transform3D(0.614606, 0.499662, -0.610408, -0.00282255, 0.775198, 0.631712, 0.78883, -0.386531, 0.477852, -9.13611, 4.90356, 1.22532)  projection = 1 diff --git a/client/multiplayer.gd b/client/multiplayer.gd index b9242a41..db891562 100644 --- a/client/multiplayer.gd +++ b/client/multiplayer.gd @@ -19,7 +19,14 @@ class_name Multiplayer  extends Node  signal init(player_id: int) -signal update_map(tile: int, pos: Array, neighbors: Array) +signal data( +	item_names: Array, +	tile_names: Array, +	tile_collide: Array, +	tile_interact: Array +) +signal set_tile(tile: Vector2i, kind: int, neighbors: Array) +signal remove_tile(tile: Vector2i)  signal clear_message(player: int)  signal text_message(player: int, text: String)  signal item_message(player: int, item: int) @@ -40,15 +47,6 @@ signal connection_closed(reason: String)  var connected := false  var socket := WebSocketPeer.new() -var item_names = [] -var tile_names = [] -var tile_collide = [] -var tile_interact = [] -var item_idx_from_name: Dictionary = {} -var player_id = -1 - -var tileid_by_pos: Dictionary = {} -  func _ready():  	print("Multiplayer connect");  	socket.connect_to_url(Global.server_url) @@ -82,14 +80,19 @@ func handle_packet(bytes: PackedByteArray):  	var packet_type: String = decoded["type"]  	match packet_type:  		"init": -			player_id = decoded["id"] -			item_names = decoded["data"]["item_names"] -			tile_names = decoded["data"]["tile_names"] -			tile_collide = decoded["data"]["tile_collide"] -			tile_interact = decoded["data"]["tile_interact"] -			for i in range(item_names.size()): -				item_idx_from_name[item_names[i]] = i +			var player_id = decoded["id"]  			emit_signal("init", player_id) +		"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"] +			emit_signal("data", +				item_names, +				tile_names, +				tile_collide, +				tile_interact +			)  		"add_player":  			var id = decoded["id"]  			var player_name = decoded["name"] @@ -135,11 +138,18 @@ func handle_packet(bytes: PackedByteArray):  			else:  				emit_signal("remove_player_item", player)  		"update_map": -			var tile: int = decoded["tile"] -			var pos: Array = decoded["pos"] +			var tile: Vector2i = pos_to_vec2i(decoded["tile"]) +			var kind = decoded.get("kind")  			var neighbors: Array = decoded["neighbors"] -			tileid_by_pos[str(Vector2i(pos[0],pos[1]))] = tile -			emit_signal("update_map", pos, tile_names[tile], neighbors.map(func (x): return tile_names[x] if x != null else null)) +			if kind != null: +				emit_signal( +					"set_tile", +					tile, +					kind, +					neighbors, +				) +			else: +				emit_signal("remove_tile", tile)  		"communicate":  			var player = decoded["player"]  			var message = decoded.get("message") @@ -200,13 +210,3 @@ func pos_to_vec2(pos: Array) -> Vector2:  func pos_to_vec2i(pos: Array) -> Vector2i:  	return Vector2i(pos[0], pos[1]) - -func get_tile_collision(pos: Vector2i) -> bool: -	var t = tileid_by_pos.get(str(pos)) -	if t == null: return false -	else: return tile_collide[t] - -func get_tile_interactive(pos: Vector2i) -> bool: -	var t = tileid_by_pos.get(str(pos)) -	if t == null: return false -	else: return tile_interact[t] diff --git a/client/player/character/character.gd b/client/player/character/character.gd index dd3e6554..c6ca9b50 100644 --- a/client/player/character/character.gd +++ b/client/player/character/character.gd @@ -71,5 +71,5 @@ func play_animation(name_: String):  	current_animation = name_  	hand_animations.play(name_) -func _on_hand_animations_animation_finished(name_): +func _on_hand_animations_animation_finished(_name):  	hand_animations.play(current_animation) diff --git a/client/player/controllable_player.gd b/client/player/controllable_player.gd index 3012f557..c4691b67 100644 --- a/client/player/controllable_player.gd +++ b/client/player/controllable_player.gd @@ -66,7 +66,7 @@ func collide(dt: float):  	for xo in range(-1,2):  		for yo in range(-1,2):  			var tile = Vector2i(xo, yo) + Vector2i(self.position_); -			if !game.mp.get_tile_collision(tile): continue +			if !game.get_tile_collision(tile): continue  			tile = Vector2(tile)  			var d = aabb_point_distance(tile, tile + Vector2.ONE, self.position_);  			if d > PLAYER_SIZE: continue @@ -97,9 +97,10 @@ func update_position(new_position: Vector2, _new_rotation: float):  func interact():  	var tile_idx = str(target) -	var t: Tile = game.map.tile_by_pos.get(tile_idx) -	if t != null: -		game.marker.set_interactive(game.mp.get_tile_interactive(target)) +	var data = game.tile_by_pos.get(tile_idx) +	if data != null: +		var t: Tile = data[1] +		game.marker.set_interactive(game.get_tile_interactive(target))  		game.marker.visible = true  		game.marker_target = t.item_base.global_position  		if Input.is_action_just_pressed("interact"): | 
