This commit is contained in:
Patrick 2025-07-31 13:57:50 +02:00
parent fadea22b9d
commit d72b5ac57b
14 changed files with 184 additions and 5 deletions

View file

@ -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

10
entities/escape_area.gd Normal file
View file

@ -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())

View file

@ -0,0 +1 @@
uid://bvjyyj4m56b7b

14
entities/escape_area.tscn Normal file
View file

@ -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"]

19
entities/fuse_box.gd Normal file
View file

@ -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

1
entities/fuse_box.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://cclwbdyr23has

44
entities/fuse_box.tscn Normal file
View file

@ -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"]

View file

@ -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

View file

@ -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)

View file

@ -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")

View file

@ -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"]

5
ui/join_game.gd Normal file
View file

@ -0,0 +1,5 @@
class_name JoinGame
extends Control
func _ready() -> void:
Multiplayer.playerlist_label = $PlayerList

1
ui/join_game.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://b5gc2gq5adxsf

View file

@ -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