diff --git a/entities/coffin.gd b/entities/coffin.gd index 78e1a6d..363bb70 100644 --- a/entities/coffin.gd +++ b/entities/coffin.gd @@ -8,10 +8,13 @@ func _on_dropoff(body: Node3D) -> void: var player: Player = body if player.caught_player and !caught_player: caught_player = player.caught_player - player.caught_player.get_imprisoned.rpc_id(player.caught_player.get_multiplayer_authority(), get_path()) + caught_player.get_imprisoned.rpc_id(caught_player.get_multiplayer_authority(), get_path()) player.released_player.rpc_id(player.get_multiplayer_authority()) (player.get_node("ReleaseTimer") as Timer).stop() ($DamageTimer as Timer).start() + for i: int in range(Multiplayer.players.size()): + if Multiplayer.players[i].id == caught_player.get_multiplayer_authority(): + Multiplayer.players[i].captured = true elif !player.hunter and player.visible and caught_player and caught_player.health > 0: caught_player.go_free.rpc_id(caught_player.get_multiplayer_authority()) caught_player = null diff --git a/entities/escape_area.gd b/entities/escape_area.gd new file mode 100644 index 0000000..20fd34b --- /dev/null +++ b/entities/escape_area.gd @@ -0,0 +1,10 @@ +extends Area3D + +func _on_body_entered(body: Node3D) -> void: + if multiplayer.is_server() and body is Player: + var player: Player = body + if !player.hunter: + for i: int in range(Multiplayer.players.size()): + if Multiplayer.players[i].id == player.get_multiplayer_authority(): + Multiplayer.players[i].escaped = true + player.get_caught.rpc_id(player.get_multiplayer_authority(), $"../SpectatorCamera".get_path()) diff --git a/entities/escape_area.gd.uid b/entities/escape_area.gd.uid new file mode 100644 index 0000000..b3b9571 --- /dev/null +++ b/entities/escape_area.gd.uid @@ -0,0 +1 @@ +uid://bvjyyj4m56b7b diff --git a/entities/escape_area.tscn b/entities/escape_area.tscn new file mode 100644 index 0000000..1c5b1b0 --- /dev/null +++ b/entities/escape_area.tscn @@ -0,0 +1,14 @@ +[gd_scene load_steps=3 format=3 uid="uid://dbgqg1wtqmhw3"] + +[ext_resource type="Script" uid="uid://bvjyyj4m56b7b" path="res://entities/escape_area.gd" id="1_ubptc"] + +[sub_resource type="BoxShape3D" id="BoxShape3D_eij3b"] +size = Vector3(10, 10, 10) + +[node name="EscapeArea" type="Area3D"] +script = ExtResource("1_ubptc") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +shape = SubResource("BoxShape3D_eij3b") + +[connection signal="body_entered" from="." to="." method="_on_body_entered"] diff --git a/entities/fuse_box.gd b/entities/fuse_box.gd new file mode 100644 index 0000000..a27bf88 --- /dev/null +++ b/entities/fuse_box.gd @@ -0,0 +1,19 @@ +class_name FuseBox +extends StaticBody3D + +var done: bool = false + +func _ready() -> void: + if multiplayer.is_server(): + Multiplayer.fuseboxes += 1 + +func _on_fixing_started(body: Node3D) -> void: + if multiplayer.is_server() and !done and body is Player: + var player: Player = body + if !player.hunter: + complete_fusebox() + +func complete_fusebox() -> void: + ($Hinge as Node3D).rotation.y = 0 + done = true + Multiplayer.fuseboxes -= 1 diff --git a/entities/fuse_box.gd.uid b/entities/fuse_box.gd.uid new file mode 100644 index 0000000..c450745 --- /dev/null +++ b/entities/fuse_box.gd.uid @@ -0,0 +1 @@ +uid://cclwbdyr23has diff --git a/entities/fuse_box.tscn b/entities/fuse_box.tscn new file mode 100644 index 0000000..1176eff --- /dev/null +++ b/entities/fuse_box.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=6 format=3 uid="uid://d1d30fwvkx66s"] + +[ext_resource type="Script" uid="uid://cclwbdyr23has" path="res://entities/fuse_box.gd" id="1_x8jfh"] + +[sub_resource type="BoxMesh" id="BoxMesh_dwu7d"] +size = Vector3(0.2, 1, 1) + +[sub_resource type="BoxShape3D" id="BoxShape3D_g83f7"] +size = Vector3(0.2, 1, 1) + +[sub_resource type="BoxShape3D" id="BoxShape3D_uyarn"] + +[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_o4y3h"] +properties/0/path = NodePath("Hinge:rotation:y") +properties/0/spawn = true +properties/0/replication_mode = 1 + +[node name="FuseBox" type="StaticBody3D"] +script = ExtResource("1_x8jfh") + +[node name="FuseBoxMesh" type="MeshInstance3D" parent="."] +mesh = SubResource("BoxMesh_dwu7d") + +[node name="Hinge" type="Node3D" parent="."] +transform = Transform3D(-0.707107, 0, -0.707107, 0, 1, 0, 0.707107, 0, -0.707107, 0.1, 0, 0.5) + +[node name="DoorMesh" type="MeshInstance3D" parent="Hinge"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.1, 0, -0.5) +mesh = SubResource("BoxMesh_dwu7d") +skeleton = NodePath("../../FuseBoxMesh") + +[node name="Collision" type="CollisionShape3D" parent="."] +shape = SubResource("BoxShape3D_g83f7") + +[node name="FixingArea" type="Area3D" parent="."] + +[node name="Shape" type="CollisionShape3D" parent="FixingArea"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.6, 0, 0) +shape = SubResource("BoxShape3D_uyarn") + +[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="."] +replication_config = SubResource("SceneReplicationConfig_o4y3h") + +[connection signal="body_entered" from="FixingArea" to="." method="_on_fixing_started"] diff --git a/global/multiplayer.gd b/global/multiplayer.gd index 496d9f1..26679c4 100644 --- a/global/multiplayer.gd +++ b/global/multiplayer.gd @@ -5,7 +5,10 @@ const ADDRESS: String = "127.0.0.1" const PORT: int = 4516 var peer: ENetMultiplayerPeer = null -var players: Array = [] +var players: Array[Dictionary] = [] +var fuseboxes: int = 0 + +var playerlist_label: Label = null ## Host Specific @@ -28,15 +31,31 @@ func _on_player_joined(id: int) -> void: "id": id, "loaded": false, "hunter": false, + "captured": false, + "escaped": false, }) + + send_playerlist() # Runs when player leaves func _on_player_left(id: int) -> void: players = players.filter(func (player: Dictionary) -> bool: return player.id != id) + send_playerlist() + +# Prepares the label text for the playerlist on the join/host screen +func send_playerlist() -> void: + var playerlist: String = "" + + for player: Dictionary in players: + playerlist += str(player.id) + playerlist += "\n" + + update_playerlist.rpc(playerlist) # Switches the scene, and waits until everyone is fully loaded. @rpc("authority", "call_local", "reliable") func switch_scene(path: String) -> void: + playerlist_label = null if multiplayer.is_server(): _scene_loaded.rpc_id(1) while true: @@ -64,6 +83,15 @@ func _scene_loaded() -> void: if players[i].id == multiplayer.get_remote_sender_id(): players[i].loaded = true +func _process(_delta: float) -> void: + if multiplayer.multiplayer_peer and multiplayer.is_server() and !players.is_empty(): + var lost: bool = true + for player: Dictionary in players: + if (!player.captured or !player.escaped) and !player.hunter: + lost = false + if lost: + terminate_multiplayer.rpc() + ## Client Specific # Joins a server @@ -77,5 +105,17 @@ func join_server() -> void: ## Shared # Terminates all Multiplayer functionality. +@rpc("authority", "call_local", "reliable") func terminate_multiplayer() -> void: multiplayer.multiplayer_peer = null + players = [] + fuseboxes = 0 + Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE) + if get_tree().change_scene_to_file("res://ui/main_menu.tscn") != OK: + print("Failed to change to scene.") + +# Updates the player list +@rpc("authority", "call_local", "reliable") +func update_playerlist(list: String) -> void: + if playerlist_label != null: + playerlist_label.text = list diff --git a/maps/test_map.tscn b/maps/test_map.tscn index 16eef78..ca5700d 100644 --- a/maps/test_map.tscn +++ b/maps/test_map.tscn @@ -1,8 +1,19 @@ -[gd_scene load_steps=4 format=3 uid="uid://dn53itmhhlru8"] +[gd_scene load_steps=9 format=3 uid="uid://dn53itmhhlru8"] [ext_resource type="Script" uid="uid://btt55t6akawwc" path="res://maps/map.gd" id="1_6slyc"] [ext_resource type="PackedScene" uid="uid://cu1d6uwha7jm2" path="res://entities/player_spawner.tscn" id="2_b71ab"] [ext_resource type="PackedScene" uid="uid://dx0yaqaccakh" path="res://entities/coffin.tscn" id="3_pwco0"] +[ext_resource type="PackedScene" uid="uid://d1d30fwvkx66s" path="res://entities/fuse_box.tscn" id="4_42yok"] +[ext_resource type="PackedScene" uid="uid://dbgqg1wtqmhw3" path="res://entities/escape_area.tscn" id="5_cabd0"] + +[sub_resource type="PhysicalSkyMaterial" id="PhysicalSkyMaterial_pwco0"] + +[sub_resource type="Sky" id="Sky_42yok"] +sky_material = SubResource("PhysicalSkyMaterial_pwco0") + +[sub_resource type="Environment" id="Environment_cabd0"] +background_mode = 2 +sky = SubResource("Sky_42yok") [node name="TestMap" type="Node3D"] script = ExtResource("1_6slyc") @@ -29,5 +40,17 @@ size = Vector3(25, 1, 25) transform = Transform3D(0.866025, 0.433012, -0.25, 0, 0.5, 0.866025, 0.5, -0.75, 0.433013, 0, 0, 0) shadow_enabled = true +[node name="WorldEnvironment" type="WorldEnvironment" parent="."] +environment = SubResource("Environment_cabd0") + [node name="Coffin" parent="." instance=ExtResource("3_pwco0")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.1, 0) + +[node name="Fusebox" parent="." instance=ExtResource("4_42yok")] +transform = Transform3D(-4.37114e-08, 0, -1, 0, 1, 0, 1, 0, -4.37114e-08, -0.0538549, 1, -11.7148) + +[node name="EscapeArea" parent="." instance=ExtResource("5_cabd0")] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0880795, 0.500002, 14.7871) + +[node name="SpectatorCamera" type="Camera3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0880795, 0.500002, 14.7871) diff --git a/ui/host_game.gd b/ui/host_game.gd index a99b1a2..ff75f48 100644 --- a/ui/host_game.gd +++ b/ui/host_game.gd @@ -1,5 +1,5 @@ class_name HostGame -extends Control +extends JoinGame func _on_start_game_button_pressed() -> void: Multiplayer.switch_scene.rpc("res://maps/test_map.tscn") diff --git a/ui/host_game.tscn b/ui/host_game.tscn index 7ff71c8..51c7965 100644 --- a/ui/host_game.tscn +++ b/ui/host_game.tscn @@ -26,4 +26,12 @@ grow_horizontal = 2 grow_vertical = 2 text = "Start Game" +[node name="PlayerList" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 1.0 +grow_vertical = 2 +text = "1" + [connection signal="pressed" from="StartGameButton" to="." method="_on_start_game_button_pressed"] diff --git a/ui/join_game.gd b/ui/join_game.gd new file mode 100644 index 0000000..0940961 --- /dev/null +++ b/ui/join_game.gd @@ -0,0 +1,5 @@ +class_name JoinGame +extends Control + +func _ready() -> void: + Multiplayer.playerlist_label = $PlayerList diff --git a/ui/join_game.gd.uid b/ui/join_game.gd.uid new file mode 100644 index 0000000..a980f95 --- /dev/null +++ b/ui/join_game.gd.uid @@ -0,0 +1 @@ +uid://b5gc2gq5adxsf diff --git a/ui/join_game.tscn b/ui/join_game.tscn index 1dc3483..0366bf4 100644 --- a/ui/join_game.tscn +++ b/ui/join_game.tscn @@ -1,4 +1,6 @@ -[gd_scene format=3 uid="uid://dpxam8lwgsd6q"] +[gd_scene load_steps=2 format=3 uid="uid://dpxam8lwgsd6q"] + +[ext_resource type="Script" uid="uid://b5gc2gq5adxsf" path="res://ui/join_game.gd" id="1_ju2tq"] [node name="JoinGame" type="Control"] layout_mode = 3 @@ -7,3 +9,11 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +script = ExtResource("1_ju2tq") + +[node name="PlayerList" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 9 +anchor_bottom = 1.0 +offset_right = 1.0 +grow_vertical = 2