diff --git a/camera/camera.tscn b/camera/camera.tscn index efabb94..d9c9204 100644 --- a/camera/camera.tscn +++ b/camera/camera.tscn @@ -1,13 +1,16 @@ -[gd_scene load_steps=2 format=3 uid="uid://brgqf2ebuyhuy"] +[gd_scene load_steps=3 format=3 uid="uid://brgqf2ebuyhuy"] [ext_resource type="Script" path="res://camera/camera.gd" id="1_veqr4"] +[sub_resource type="SphereShape3D" id="SphereShape3D_5lewf"] + [node name="Camera" type="Node3D"] script = ExtResource("1_veqr4") [node name="SpringArm3D" type="SpringArm3D" parent="."] unique_name_in_owner = true transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 2) +shape = SubResource("SphereShape3D_5lewf") spring_length = 2.0 margin = 0.5 diff --git a/level/StaticBody3D.gd b/level/Ground.gd similarity index 100% rename from level/StaticBody3D.gd rename to level/Ground.gd diff --git a/level/PlayerSpawner.gd b/level/PlayerSpawner.gd index 387e585..4d2b973 100644 --- a/level/PlayerSpawner.gd +++ b/level/PlayerSpawner.gd @@ -6,9 +6,12 @@ func _ready(): func spawn_player(owner_id: int): var player := preload("res://player/player.tscn").instantiate() + player.name = str(owner_id) player.set_multiplayer_authority(owner_id) if multiplayer.get_unique_id() == owner_id: var camera := preload("res://camera/camera.tscn").instantiate() player.add_child(camera) return player +func despawn_player(owner_id: int): + get_node(spawn_path).get_node(str(owner_id)).queue_free() diff --git a/level/level.gd b/level/level.gd index 7f06e7e..a4681e5 100644 --- a/level/level.gd +++ b/level/level.gd @@ -19,6 +19,13 @@ signal state_leave_tagger_ungrounded signal state_enter_tagger_change(new_tagger: Player) signal state_leave_tagger_change +const MIN_PLAYERS := 2 +const global_msg_1 := "Waiting for at least {min_players} players to join" +const global_msg_2 := "Game is starting soon, {tagger_username} is it!" +const global_msg_3 := "{tagger_username} is it! Run!" +const global_msg_4 := "{old_tagger_username} caught {tagger_username}!" +const global_msg_5 := "{old_tagger_username} left. {tagger_username} is now it!" + func set_tagger_grounded(v: bool): if v and game_state == GameState.TAGGER_CHANGE: _change_state(GameState.TAGGER_GROUNDED) @@ -29,10 +36,34 @@ func set_tagger_grounded(v: bool): _change_state(GameState.TAGGER_UNGROUNDED) if v and game_state == GameState.TAGGER_UNGROUNDED: _change_state(GameState.TAGGER_GROUNDED) + + +func not_enough_players() -> bool: + if %Players.get_children().size() < MIN_PLAYERS: + _change_state(GameState.WAITING) + %GlobalMessage.text = global_msg_1.format({"min_players": MIN_PLAYERS}) + return true + return false + +func change_to_random_tagger(): + game_tagger = %Players.get_children().pick_random() + _change_state(GameState.TAGGER_CHANGE) + +func tagger_left_game(): + if not_enough_players(): + return + var old_tagger_username := game_tagger.username + change_to_random_tagger() + var tagger_username := game_tagger.username + %GlobalMessage.text = global_msg_5.format({ + "old_tagger_username": old_tagger_username, + "tagger_username": tagger_username}) func set_tagger(who: Player): if game_state == GameState.WAITING: return + game_tagger.tree_exiting.disconnect(tagger_left_game) + who.tree_exiting.connect(tagger_left_game) game_tagger = who _change_state(GameState.TAGGER_CHANGE) @@ -69,6 +100,9 @@ func _ready(): # Called from the server func server_add_player(id: int): %PlayerSpawner.spawn(id) + +func server_remove_player(id: int): + %PlayerSpawner.despawn_player(id) static func find_level(node: Node) -> Level: while not (node is Level): diff --git a/level/level.tscn b/level/level.tscn index f8451db..0b01d8d 100644 --- a/level/level.tscn +++ b/level/level.tscn @@ -1,23 +1,23 @@ -[gd_scene load_steps=12 format=3 uid="uid://b00brfkibo5cj"] +[gd_scene load_steps=11 format=3 uid="uid://b00brfkibo5cj"] [ext_resource type="PackedScene" uid="uid://bq654gwim6col" path="res://level/level.glb" id="1_s37in"] [ext_resource type="Environment" uid="uid://covjrwmk4rplw" path="res://level/world_environment.tres" id="2_ptkl6"] [ext_resource type="Script" path="res://level/level.gd" id="2_s1bx6"] -[ext_resource type="Script" path="res://level/StaticBody3D.gd" id="4_6rwm2"] [ext_resource type="Script" path="res://addons/smoother/smoother.gd" id="5_2tyle"] [ext_resource type="Script" path="res://level/PlayerSpawner.gd" id="6_7ww0m"] [ext_resource type="MeshLibrary" uid="uid://cgh6y5j8wgi36" path="res://level/mesh_library/level_mesh_library.glb" id="6_d34iv"] - -[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_ujmev"] -margin = 2.067 - -[sub_resource type="BoxShape3D" id="BoxShape3D_qp06x"] -size = Vector3(2, 0.1, 2) +[ext_resource type="Script" path="res://level/Ground.gd" id="7_81ape"] [sub_resource type="QuadMesh" id="QuadMesh_8lqeb"] size = Vector2(100, 100) [sub_resource type="BoxShape3D" id="BoxShape3D_m3lo5"] +size = Vector3(100, 100, 1) + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_285vp"] +properties/0/path = NodePath("SharedUI/SharedMessage:text") +properties/0/spawn = true +properties/0/replication_mode = 1 [node name="level" instance=ExtResource("1_s37in")] script = ExtResource("2_s1bx6") @@ -32,17 +32,6 @@ transform = Transform3D(1, 0, 0, 0, 0.566018, 0.824393, 0, -0.824393, 0.566018, transform = Transform3D(25.5862, 0, 0, 0, 25.5862, 0, 0, 0, 25.5862, 0.00464344, 0, 0.0305362) visible = false -[node name="StaticBody3D" type="StaticBody3D" parent="Plane" index="0" groups=["ground"]] -script = ExtResource("4_6rwm2") - -[node name="CollisionShape3D" type="CollisionShape3D" parent="Plane/StaticBody3D" index="0"] -transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0) -shape = SubResource("WorldBoundaryShape3D_ujmev") - -[node name="CollisionShape3D2" type="CollisionShape3D" parent="Plane/StaticBody3D" index="1"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.05, 0) -shape = SubResource("BoxShape3D_qp06x") - [node name="Cube" parent="." index="2"] visible = false @@ -84,7 +73,27 @@ mesh = SubResource("QuadMesh_8lqeb") skeleton = NodePath("../Cube") [node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D" index="0"] +script = ExtResource("7_81ape") [node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D" index="0"] -transform = Transform3D(100, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, -0.5) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.5) shape = SubResource("BoxShape3D_m3lo5") + +[node name="SharedUI" type="Control" parent="." index="9"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="GlobalMessage" type="Label" parent="SharedUI" index="0"] +unique_name_in_owner = true +layout_mode = 2 +offset_right = 1152.0 +offset_bottom = 23.0 +text = "Waiting for at least 2 players to join" +horizontal_alignment = 1 + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." index="10"] +replication_config = SubResource("SceneReplicationConfig_285vp") diff --git a/player/player.gd b/player/player.gd index c1dae50..8804a99 100644 --- a/player/player.gd +++ b/player/player.gd @@ -5,6 +5,7 @@ class_name Player @export var SPEED = 5.0 @export var JUMP_VELOCITY = 4.5 +var username: String = "" var gravity = ProjectSettings.get_setting("physics/3d/default_gravity") @@ -18,16 +19,19 @@ signal is_bumping(src: Player) var _is_grounded := false signal is_grounded +func _ready(): + if username == "": + username = "Player " + name + func is_on_ground() -> bool: _is_grounded = false - is_grounded.emit() + is_grounded.emit(self) var v := _is_grounded _is_grounded = false return v func _physics_process(delta): - print(is_on_ground()) if not is_on_floor(): velocity.y -= gravity * delta @@ -74,13 +78,12 @@ func _on_tag_detection_area_exited(area): func _on_tag_detection_body_entered(body): - if body.is_in_group("ground"): - print("fuck") + if "grounded" in body: if not is_grounded.is_connected(body.grounded): is_grounded.connect(body.grounded) func _on_tag_detection_body_exited(body): - if body.is_in_group("ground"): + if "grounded" in body: if is_grounded.is_connected(body.grounded): is_grounded.disconnect(body.grounded) diff --git a/player/player.tscn b/player/player.tscn index 8a88c08..f0809ec 100644 --- a/player/player.tscn +++ b/player/player.tscn @@ -26,8 +26,8 @@ replication_config = SubResource("SceneReplicationConfig_u4bmc") shape = SubResource("SphereShape3D_t1htn") [node name="TagDetection" type="Area3D" parent="." index="3"] -collision_layer = 8388608 -collision_mask = 8388608 +collision_layer = 8388609 +collision_mask = 8388609 [node name="CollisionShape3D" type="CollisionShape3D" parent="TagDetection" index="0"] shape = SubResource("SphereShape3D_ylark") diff --git a/server/lobby.gd b/server/lobby.gd index 4a9e8d9..c5c4860 100644 --- a/server/lobby.gd +++ b/server/lobby.gd @@ -1,3 +1,5 @@ +# Runs server side per game + extends Node var port: int @@ -10,7 +12,12 @@ func _ready(): peer.create_server(port, MAX_CLIENTS) m.multiplayer_peer = peer m.peer_connected.connect(peer_connected) + m.peer_disconnected.connect(peer_disconnected) func peer_connected(id: int): print("Client " + str(id) + "connected to lobby " + str(get_path())) $level.server_add_player(id) + +func peer_disconnected(id: int): + print("Client " + str(id) + "disconnected to lobby " + str(get_path())) + $level.server_remove_player(id) diff --git a/server/lobby_list.gd b/server/lobby_list.gd index dbf829e..e2e70e8 100644 --- a/server/lobby_list.gd +++ b/server/lobby_list.gd @@ -6,8 +6,8 @@ signal join_lobby(addr: String, port: int) func add(port: int): var lobby_button := preload("res://server/lobby_list_entry.tscn").instantiate() var addr := "127.0.0.1" - var peer := (multiplayer.multiplayer_peer as ENetMultiplayerPeer).get_peer(1) - if peer != null: + if not multiplayer.is_server(): + var peer := (multiplayer.multiplayer_peer as ENetMultiplayerPeer).get_peer(1) addr = peer.get_remote_address() lobby_button.address = addr lobby_button.port = port