aboutsummaryrefslogtreecommitdiff
path: root/client
diff options
context:
space:
mode:
Diffstat (limited to 'client')
-rw-r--r--client/game.gd116
-rw-r--r--client/game.tscn8
-rw-r--r--client/map/map.gd37
-rw-r--r--client/map/map.tscn44
-rw-r--r--client/menu/menu_background.gd17
-rw-r--r--client/menu/menu_background.tscn5
-rw-r--r--client/multiplayer.gd62
-rw-r--r--client/player/character/character.gd2
-rw-r--r--client/player/controllable_player.gd9
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"):