broken ass code'

This commit is contained in:
Spencer Killen 2024-06-03 11:05:52 -06:00
parent a88607a316
commit c3e5073011
Signed by: sjkillen
GPG Key ID: 3AF3117BA6FBB75B
6 changed files with 150 additions and 28 deletions

19
camera/PersonalUI.gd Normal file
View File

@ -0,0 +1,19 @@
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

View File

@ -1,6 +1,7 @@
[gd_scene load_steps=3 format=3 uid="uid://brgqf2ebuyhuy"]
[gd_scene load_steps=4 format=3 uid="uid://brgqf2ebuyhuy"]
[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"]
@ -16,3 +17,26 @@ margin = 0.5
[node name="Camera3D" type="Camera3D" parent="SpringArm3D"]
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)

View File

@ -14,4 +14,6 @@ func spawn_player(owner_id: int):
return player
func despawn_player(owner_id: int):
get_node(spawn_path).get_node(str(owner_id)).queue_free()
var node := get_node(spawn_path).get_node(str(owner_id))
node.queue_free()
await node.tree_exited

View File

@ -9,6 +9,7 @@ enum GameState {
}
var game_state: GameState = GameState.WAITING
var safe_player: Player
var game_tagger: Player
signal state_change(old: GameState, new: GameState)
@ -19,13 +20,18 @@ signal state_leave_tagger_ungrounded
signal state_enter_tagger_change(new_tagger: Player)
signal state_leave_tagger_change
const MIN_PLAYERS := 2
const MIN_PLAYERS := 3
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!"
@rpc("any_peer", "reliable", "call_local")
func push_global_message(msg: String):
%GlobalMessage.text = msg
print(msg)
func set_tagger_grounded(v: bool):
if v and game_state == GameState.TAGGER_CHANGE:
_change_state(GameState.TAGGER_GROUNDED)
@ -40,12 +46,14 @@ func set_tagger_grounded(v: bool):
func not_enough_players() -> bool:
if %Players.get_children().size() < MIN_PLAYERS:
game_tagger = null
_change_state(GameState.WAITING)
%GlobalMessage.text = global_msg_1.format({"min_players": MIN_PLAYERS})
push_global_message.rpc(global_msg_1.format({"min_players": MIN_PLAYERS}))
return true
return false
func change_to_random_tagger():
safe_player = null
game_tagger = %Players.get_children().pick_random()
_change_state(GameState.TAGGER_CHANGE)
@ -55,19 +63,32 @@ func tagger_left_game():
var old_tagger_username := game_tagger.username
change_to_random_tagger()
var tagger_username := game_tagger.username
%GlobalMessage.text = global_msg_5.format({
push_global_message.rpc(global_msg_5.format({
"old_tagger_username": old_tagger_username,
"tagger_username": 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)
safe_player = game_tagger
game_tagger = who
_change_state(GameState.TAGGER_CHANGE)
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:
return
if new_state == GameState.WAITING:
@ -90,21 +111,65 @@ func _change_state(new_state: GameState):
if old_state == GameState.TAGGER_CHANGE:
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():
# Hacky way to start level without going though multiplayer screens
if get_parent() == get_tree().root:
%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
func server_add_player(id: int):
%PlayerSpawner.spawn(id)
if not not_enough_players() and game_state == GameState.WAITING:
start_game()
func server_remove_player(id: int):
%PlayerSpawner.despawn_player(id)
var player := find_player_by_id(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:
while not (node is Level):
node = node.get_parent()
return node
func find_player_by_id(id: int) -> Player:
return %Players.get_node(str(id))

View File

@ -15,9 +15,6 @@ size = Vector2(100, 100)
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")
@ -92,8 +89,12 @@ 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"]

View File

@ -12,12 +12,23 @@ var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
# Set by camera child, switch to signals if becomes too spaghetti
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
# Memory management substantially since nodes are not GC'd
# Connected nodes are the colliding nodes
signal is_bumping(src: Player)
signal check_bumping(src: Player)
var _is_grounded := false
signal is_grounded
signal check_grounded
func _ready():
if username == "":
@ -25,7 +36,7 @@ func _ready():
func is_on_ground() -> bool:
_is_grounded = false
is_grounded.emit(self)
check_grounded.emit(self)
var v := _is_grounded
_is_grounded = false
return v
@ -55,7 +66,7 @@ func _bump_check(src: Player):
func get_first_bumper() -> Player:
_first_bumper = null
is_bumping.emit(self)
check_bumping.emit(self)
var player := _first_bumper
_first_bumper = null
return player
@ -64,26 +75,26 @@ func _on_tag_detection_area_entered(area):
if not (area.get_parent() is Player):
return
var _other_player: Player = area.get_parent()
if is_bumping.is_connected(_bump_check):
if check_bumping.is_connected(_bump_check):
return
is_bumping.connect(_bump_check)
check_bumping.connect(_bump_check)
func _on_tag_detection_area_exited(area):
if not (area.get_parent() is Player):
return
var _other_player: Player = area.get_parent()
if not is_bumping.is_connected(_bump_check):
if not check_bumping.is_connected(_bump_check):
return
is_bumping.disconnect(_bump_check)
check_bumping.disconnect(_bump_check)
func _on_tag_detection_body_entered(body):
if "grounded" in body:
if not is_grounded.is_connected(body.grounded):
is_grounded.connect(body.grounded)
if not check_grounded.is_connected(body.grounded):
check_grounded.connect(body.grounded)
func _on_tag_detection_body_exited(body):
if "grounded" in body:
if is_grounded.is_connected(body.grounded):
is_grounded.disconnect(body.grounded)
if check_grounded.is_connected(body.grounded):
check_grounded.disconnect(body.grounded)