Compare commits
No commits in common. "00ff4fd9c568b4e5119818d6e6c395d95ad3ae04" and "c9edb73c5052bab0e3c8cddce5ae2652115f82ff" have entirely different histories.
00ff4fd9c5
...
c9edb73c50
|
@ -1,19 +0,0 @@
|
||||||
extends Control
|
|
||||||
|
|
||||||
@onready var level := Level.find_level(self)
|
|
||||||
|
|
||||||
const personal_msg_1 := "You're not it, run!"
|
|
||||||
const personal_msg_2 := "You're it, run!"
|
|
||||||
|
|
||||||
func get_player() -> Player:
|
|
||||||
return owner.get_parent()
|
|
||||||
|
|
||||||
func _ready():
|
|
||||||
level.state_enter_tagger_change.connect(tagger_change)
|
|
||||||
|
|
||||||
func tagger_change(next: Player):
|
|
||||||
if get_player() == next:
|
|
||||||
$Label.text = personal_msg_2
|
|
||||||
else:
|
|
||||||
$Label.text = personal_msg_1
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
[gd_scene load_steps=4 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"]
|
[ext_resource type="Script" path="res://camera/camera.gd" id="1_veqr4"]
|
||||||
[ext_resource type="Script" path="res://camera/PersonalUI.gd" id="2_u54jc"]
|
|
||||||
|
|
||||||
[sub_resource type="SphereShape3D" id="SphereShape3D_5lewf"]
|
[sub_resource type="SphereShape3D" id="SphereShape3D_5lewf"]
|
||||||
|
|
||||||
|
@ -17,26 +16,3 @@ margin = 0.5
|
||||||
|
|
||||||
[node name="Camera3D" type="Camera3D" parent="SpringArm3D"]
|
[node name="Camera3D" type="Camera3D" parent="SpringArm3D"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
|
||||||
[node name="PersonalUI" type="Control" parent="."]
|
|
||||||
layout_mode = 3
|
|
||||||
anchors_preset = 12
|
|
||||||
anchor_top = 1.0
|
|
||||||
anchor_right = 1.0
|
|
||||||
anchor_bottom = 1.0
|
|
||||||
offset_top = -126.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
grow_vertical = 0
|
|
||||||
size_flags_vertical = 8
|
|
||||||
script = ExtResource("2_u54jc")
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="PersonalUI"]
|
|
||||||
layout_mode = 1
|
|
||||||
anchors_preset = 5
|
|
||||||
anchor_left = 0.5
|
|
||||||
anchor_right = 0.5
|
|
||||||
offset_left = -20.0
|
|
||||||
offset_right = 20.0
|
|
||||||
offset_bottom = 23.0
|
|
||||||
grow_horizontal = 2
|
|
||||||
theme_override_colors/font_color = Color(1, 0, 0, 1)
|
|
||||||
|
|
|
@ -14,6 +14,4 @@ func spawn_player(owner_id: int):
|
||||||
return player
|
return player
|
||||||
|
|
||||||
func despawn_player(owner_id: int):
|
func despawn_player(owner_id: int):
|
||||||
var node := get_node(spawn_path).get_node(str(owner_id))
|
get_node(spawn_path).get_node(str(owner_id)).queue_free()
|
||||||
node.queue_free()
|
|
||||||
await node.tree_exited
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ enum GameState {
|
||||||
}
|
}
|
||||||
|
|
||||||
var game_state: GameState = GameState.WAITING
|
var game_state: GameState = GameState.WAITING
|
||||||
var safe_player: Player
|
|
||||||
var game_tagger: Player
|
var game_tagger: Player
|
||||||
|
|
||||||
signal state_change(old: GameState, new: GameState)
|
signal state_change(old: GameState, new: GameState)
|
||||||
|
@ -20,18 +19,13 @@ signal state_leave_tagger_ungrounded
|
||||||
signal state_enter_tagger_change(new_tagger: Player)
|
signal state_enter_tagger_change(new_tagger: Player)
|
||||||
signal state_leave_tagger_change
|
signal state_leave_tagger_change
|
||||||
|
|
||||||
const MIN_PLAYERS := 3
|
const MIN_PLAYERS := 2
|
||||||
const global_msg_1 := "Waiting for at least {min_players} players to join"
|
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_2 := "Game is starting soon, {tagger_username} is it!"
|
||||||
const global_msg_3 := "{tagger_username} is it! Run!"
|
const global_msg_3 := "{tagger_username} is it! Run!"
|
||||||
const global_msg_4 := "{old_tagger_username} caught {tagger_username}!"
|
const global_msg_4 := "{old_tagger_username} caught {tagger_username}!"
|
||||||
const global_msg_5 := "{old_tagger_username} left. {tagger_username} is now it!"
|
const global_msg_5 := "{old_tagger_username} left. {tagger_username} is now it!"
|
||||||
|
|
||||||
@rpc("any_peer", "reliable", "call_local")
|
|
||||||
func push_global_message(msg: String):
|
|
||||||
%GlobalMessage.text = msg
|
|
||||||
print(msg)
|
|
||||||
|
|
||||||
func set_tagger_grounded(v: bool):
|
func set_tagger_grounded(v: bool):
|
||||||
if v and game_state == GameState.TAGGER_CHANGE:
|
if v and game_state == GameState.TAGGER_CHANGE:
|
||||||
_change_state(GameState.TAGGER_GROUNDED)
|
_change_state(GameState.TAGGER_GROUNDED)
|
||||||
|
@ -46,14 +40,12 @@ func set_tagger_grounded(v: bool):
|
||||||
|
|
||||||
func not_enough_players() -> bool:
|
func not_enough_players() -> bool:
|
||||||
if %Players.get_children().size() < MIN_PLAYERS:
|
if %Players.get_children().size() < MIN_PLAYERS:
|
||||||
game_tagger = null
|
|
||||||
_change_state(GameState.WAITING)
|
_change_state(GameState.WAITING)
|
||||||
push_global_message.rpc(global_msg_1.format({"min_players": MIN_PLAYERS}))
|
%GlobalMessage.text = global_msg_1.format({"min_players": MIN_PLAYERS})
|
||||||
return true
|
return true
|
||||||
return false
|
return false
|
||||||
|
|
||||||
func change_to_random_tagger():
|
func change_to_random_tagger():
|
||||||
safe_player = null
|
|
||||||
game_tagger = %Players.get_children().pick_random()
|
game_tagger = %Players.get_children().pick_random()
|
||||||
_change_state(GameState.TAGGER_CHANGE)
|
_change_state(GameState.TAGGER_CHANGE)
|
||||||
|
|
||||||
|
@ -63,32 +55,19 @@ func tagger_left_game():
|
||||||
var old_tagger_username := game_tagger.username
|
var old_tagger_username := game_tagger.username
|
||||||
change_to_random_tagger()
|
change_to_random_tagger()
|
||||||
var tagger_username := game_tagger.username
|
var tagger_username := game_tagger.username
|
||||||
push_global_message.rpc(global_msg_5.format({
|
%GlobalMessage.text = global_msg_5.format({
|
||||||
"old_tagger_username": old_tagger_username,
|
"old_tagger_username": old_tagger_username,
|
||||||
"tagger_username": tagger_username}))
|
"tagger_username": tagger_username})
|
||||||
|
|
||||||
func set_tagger(who: Player):
|
func set_tagger(who: Player):
|
||||||
safe_player = game_tagger
|
if game_state == GameState.WAITING:
|
||||||
|
return
|
||||||
|
game_tagger.tree_exiting.disconnect(tagger_left_game)
|
||||||
|
who.tree_exiting.connect(tagger_left_game)
|
||||||
game_tagger = who
|
game_tagger = who
|
||||||
_change_state(GameState.TAGGER_CHANGE)
|
_change_state(GameState.TAGGER_CHANGE)
|
||||||
|
|
||||||
func _change_state(new_state: GameState):
|
func _change_state(new_state: GameState):
|
||||||
var id := -1
|
|
||||||
if game_tagger != null:
|
|
||||||
id = game_tagger.get_multiplayer_authority()
|
|
||||||
var safe_player_id := -1
|
|
||||||
if safe_player != null:
|
|
||||||
safe_player_id = safe_player.get_multiplayer_authority()
|
|
||||||
_change_state_full.rpc(new_state, id, safe_player_id)
|
|
||||||
|
|
||||||
@rpc("any_peer", "reliable", "call_local")
|
|
||||||
func _change_state_full(new_state: GameState, new_tagger_id: int, new_safe_player_id: int):
|
|
||||||
game_tagger = null
|
|
||||||
safe_player = null
|
|
||||||
if new_tagger_id != -1:
|
|
||||||
game_tagger = find_player_by_id(new_tagger_id)
|
|
||||||
if new_safe_player_id != -1:
|
|
||||||
safe_player = find_player_by_id(new_safe_player_id)
|
|
||||||
if game_state == new_state:
|
if game_state == new_state:
|
||||||
return
|
return
|
||||||
if new_state == GameState.WAITING:
|
if new_state == GameState.WAITING:
|
||||||
|
@ -110,66 +89,22 @@ func _change_state_full(new_state: GameState, new_tagger_id: int, new_safe_playe
|
||||||
state_leave_tagger_ungrounded.emit()
|
state_leave_tagger_ungrounded.emit()
|
||||||
if old_state == GameState.TAGGER_CHANGE:
|
if old_state == GameState.TAGGER_CHANGE:
|
||||||
state_leave_tagger_change.emit()
|
state_leave_tagger_change.emit()
|
||||||
|
|
||||||
|
|
||||||
func tagging_possible(_tagger: Player, tagee: Player) -> bool:
|
|
||||||
if game_state != GameState.TAGGER_GROUNDED and game_state != GameState.TAGGER_UNGROUNDED:
|
|
||||||
return false
|
|
||||||
return safe_player != tagee
|
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
# Hacky way to start level without going though multiplayer screens
|
# Hacky way to start level without going though multiplayer screens
|
||||||
if get_parent() == get_tree().root:
|
if get_parent() == get_tree().root:
|
||||||
%PlayerSpawner.spawn(multiplayer.get_unique_id())
|
%PlayerSpawner.spawn(multiplayer.get_unique_id())
|
||||||
|
|
||||||
|
|
||||||
func player_ground(v: bool, player: Player):
|
|
||||||
if game_tagger == player:
|
|
||||||
set_tagger_grounded(v)
|
|
||||||
|
|
||||||
func player_tag(who: Player, player: Player):
|
|
||||||
if not tagging_possible(player, who) or game_tagger != player:
|
|
||||||
return
|
|
||||||
var old_tagger_username := game_tagger.username
|
|
||||||
var tagger_username := player.username
|
|
||||||
push_global_message.rpc(global_msg_4.format({
|
|
||||||
"old_tagger_username": old_tagger_username,
|
|
||||||
"tagger_username": tagger_username}))
|
|
||||||
set_tagger(who)
|
|
||||||
|
|
||||||
func start_game():
|
|
||||||
change_to_random_tagger()
|
|
||||||
push_global_message.rpc(global_msg_3.format({"tagger_username" : game_tagger.username}))
|
|
||||||
|
|
||||||
# Called from the server
|
# Called from the server
|
||||||
func server_add_player(id: int):
|
func server_add_player(id: int):
|
||||||
%PlayerSpawner.spawn(id)
|
%PlayerSpawner.spawn(id)
|
||||||
if not not_enough_players() and game_state == GameState.WAITING:
|
|
||||||
start_game()
|
|
||||||
|
|
||||||
|
|
||||||
func server_remove_player(id: int):
|
func server_remove_player(id: int):
|
||||||
var player := find_player_by_id(id)
|
%PlayerSpawner.despawn_player(id)
|
||||||
var tagger_left := (game_tagger == player)
|
|
||||||
await %PlayerSpawner.despawn_player(id)
|
|
||||||
if not_enough_players():
|
|
||||||
return
|
|
||||||
if tagger_left:
|
|
||||||
tagger_left_game()
|
|
||||||
|
|
||||||
func client_add_player(player: Player):
|
|
||||||
if not player.is_multiplayer_authority():
|
|
||||||
return
|
|
||||||
player.ground.connect(player_ground.bind(player))
|
|
||||||
player.tag.connect(player_tag.bind(player))
|
|
||||||
|
|
||||||
|
|
||||||
func client_remove_player(_node):
|
|
||||||
pass
|
|
||||||
|
|
||||||
static func find_level(node: Node) -> Level:
|
static func find_level(node: Node) -> Level:
|
||||||
while not (node is Level):
|
while not (node is Level):
|
||||||
node = node.get_parent()
|
node = node.get_parent()
|
||||||
return node
|
return node
|
||||||
|
|
||||||
func find_player_by_id(id: int) -> Player:
|
|
||||||
return %Players.get_node(str(id))
|
|
||||||
|
|
|
@ -20,7 +20,6 @@ size = Vector2(100, 100)
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_m3lo5"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_m3lo5"]
|
||||||
|
|
||||||
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_285vp"]
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_kefm0"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_kefm0"]
|
||||||
size = Vector3(6.87, 1, 1)
|
size = Vector3(6.87, 1, 1)
|
||||||
|
|
||||||
|
@ -96,20 +95,6 @@ shape = SubResource("BoxShape3D_m3lo5")
|
||||||
|
|
||||||
[node name="StaticBody3D" type="StaticBody3D" parent="." index="9"]
|
[node name="StaticBody3D" type="StaticBody3D" parent="." index="9"]
|
||||||
|
|
||||||
[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
|
|
||||||
theme_override_colors/font_color = Color(1, 0, 0, 1)
|
|
||||||
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")
|
|
||||||
|
|
||||||
[connection signal="despawned" from="PlayerSpawner" to="." method="client_remove_player"]
|
|
||||||
[connection signal="spawned" from="PlayerSpawner" to="." method="client_add_player"]
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" index="0"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" index="0"]
|
||||||
transform = Transform3D(1.5, 0, 0, 0, 3.2, 0, 0, 0, 10, 5.01694, 11.1202, -5.176)
|
transform = Transform3D(1.5, 0, 0, 0, 3.2, 0, 0, 0, 10, 5.01694, 11.1202, -5.176)
|
||||||
shape = SubResource("BoxShape3D_kefm0")
|
shape = SubResource("BoxShape3D_kefm0")
|
||||||
|
|
|
@ -12,23 +12,12 @@ var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
|
||||||
# Set by camera child, switch to signals if becomes too spaghetti
|
# Set by camera child, switch to signals if becomes too spaghetti
|
||||||
var movement_dir: Vector2 = Vector2.ZERO
|
var movement_dir: Vector2 = Vector2.ZERO
|
||||||
|
|
||||||
|
|
||||||
# Signals fire continously every frame they're true
|
|
||||||
signal tag(player: Player)
|
|
||||||
signal ground(v: bool)
|
|
||||||
|
|
||||||
func _process(_delta):
|
|
||||||
ground.emit(is_on_ground())
|
|
||||||
var player := get_first_bumper()
|
|
||||||
if player != null:
|
|
||||||
tag.emit(player)
|
|
||||||
|
|
||||||
# Using signals to maintain a list of currently colliding players because it simplifies
|
# Using signals to maintain a list of currently colliding players because it simplifies
|
||||||
# Memory management substantially since nodes are not GC'd
|
# Memory management substantially since nodes are not GC'd
|
||||||
# Connected nodes are the colliding nodes
|
# Connected nodes are the colliding nodes
|
||||||
signal check_bumping(src: Player)
|
signal is_bumping(src: Player)
|
||||||
var _is_grounded := false
|
var _is_grounded := false
|
||||||
signal check_grounded
|
signal is_grounded
|
||||||
|
|
||||||
func _ready():
|
func _ready():
|
||||||
if username == "":
|
if username == "":
|
||||||
|
@ -36,7 +25,7 @@ func _ready():
|
||||||
|
|
||||||
func is_on_ground() -> bool:
|
func is_on_ground() -> bool:
|
||||||
_is_grounded = false
|
_is_grounded = false
|
||||||
check_grounded.emit(self)
|
is_grounded.emit(self)
|
||||||
var v := _is_grounded
|
var v := _is_grounded
|
||||||
_is_grounded = false
|
_is_grounded = false
|
||||||
return v
|
return v
|
||||||
|
@ -66,7 +55,7 @@ func _bump_check(src: Player):
|
||||||
|
|
||||||
func get_first_bumper() -> Player:
|
func get_first_bumper() -> Player:
|
||||||
_first_bumper = null
|
_first_bumper = null
|
||||||
check_bumping.emit(self)
|
is_bumping.emit(self)
|
||||||
var player := _first_bumper
|
var player := _first_bumper
|
||||||
_first_bumper = null
|
_first_bumper = null
|
||||||
return player
|
return player
|
||||||
|
@ -75,26 +64,26 @@ func _on_tag_detection_area_entered(area):
|
||||||
if not (area.get_parent() is Player):
|
if not (area.get_parent() is Player):
|
||||||
return
|
return
|
||||||
var _other_player: Player = area.get_parent()
|
var _other_player: Player = area.get_parent()
|
||||||
if check_bumping.is_connected(_bump_check):
|
if is_bumping.is_connected(_bump_check):
|
||||||
return
|
return
|
||||||
check_bumping.connect(_bump_check)
|
is_bumping.connect(_bump_check)
|
||||||
|
|
||||||
func _on_tag_detection_area_exited(area):
|
func _on_tag_detection_area_exited(area):
|
||||||
if not (area.get_parent() is Player):
|
if not (area.get_parent() is Player):
|
||||||
return
|
return
|
||||||
var _other_player: Player = area.get_parent()
|
var _other_player: Player = area.get_parent()
|
||||||
if not check_bumping.is_connected(_bump_check):
|
if not is_bumping.is_connected(_bump_check):
|
||||||
return
|
return
|
||||||
check_bumping.disconnect(_bump_check)
|
is_bumping.disconnect(_bump_check)
|
||||||
|
|
||||||
|
|
||||||
func _on_tag_detection_body_entered(body):
|
func _on_tag_detection_body_entered(body):
|
||||||
if "grounded" in body:
|
if "grounded" in body:
|
||||||
if not check_grounded.is_connected(body.grounded):
|
if not is_grounded.is_connected(body.grounded):
|
||||||
check_grounded.connect(body.grounded)
|
is_grounded.connect(body.grounded)
|
||||||
|
|
||||||
|
|
||||||
func _on_tag_detection_body_exited(body):
|
func _on_tag_detection_body_exited(body):
|
||||||
if "grounded" in body:
|
if "grounded" in body:
|
||||||
if check_grounded.is_connected(body.grounded):
|
if is_grounded.is_connected(body.grounded):
|
||||||
check_grounded.disconnect(body.grounded)
|
is_grounded.disconnect(body.grounded)
|
||||||
|
|
Loading…
Reference in New Issue