partial tagging system

This commit is contained in:
Spencer Killen 2024-05-31 11:59:57 -06:00
parent 55d26874bd
commit a9dad02fb9
Signed by: sjkillen
GPG Key ID: 3AF3117BA6FBB75B
7 changed files with 148 additions and 6 deletions

4
level/StaticBody3D.gd Normal file
View File

@ -0,0 +1,4 @@
extends StaticBody3D
func grounded(src: Player):
src._is_grounded = true

View File

@ -1,4 +1,65 @@
extends Node3D
class_name Level
enum GameState {
WAITING, # Stop state to be used by default, nothing should react to this
TAGGER_GROUNDED, # Tagger is on the ground
TAGGER_UNGROUNDED, # Tagger is off the ground
TAGGER_CHANGE, # Tagger has caught someone, and new person must go to ground
}
var game_state: GameState = GameState.WAITING
var game_tagger: Player
signal state_change(old: GameState, new: GameState)
signal state_enter_tagger_grounded
signal state_leave_tagger_grounded
signal state_enter_tagger_ungrounded
signal state_leave_tagger_ungrounded
signal state_enter_tagger_change(new_tagger: Player)
signal state_leave_tagger_change
func set_tagger_grounded(v: bool):
if v and game_state == GameState.TAGGER_CHANGE:
_change_state(GameState.TAGGER_GROUNDED)
return
if not (game_state == GameState.TAGGER_GROUNDED or game_state == GameState.TAGGER_UNGROUNDED):
return
if (not v) and game_state == GameState.TAGGER_GROUNDED:
_change_state(GameState.TAGGER_UNGROUNDED)
if v and game_state == GameState.TAGGER_UNGROUNDED:
_change_state(GameState.TAGGER_GROUNDED)
func set_tagger(who: Player):
if game_state == GameState.WAITING:
return
game_tagger = who
_change_state(GameState.TAGGER_CHANGE)
func _change_state(new_state: GameState):
if game_state == new_state:
return
if new_state == GameState.WAITING:
game_tagger = null
state_change.emit(game_state, new_state)
if new_state == GameState.TAGGER_GROUNDED:
state_enter_tagger_grounded.emit()
if new_state == GameState.TAGGER_UNGROUNDED:
state_enter_tagger_ungrounded.emit()
if new_state == GameState.TAGGER_CHANGE:
state_enter_tagger_change.emit(game_tagger)
var old_state = game_state
game_state = new_state
if old_state == GameState.TAGGER_GROUNDED:
state_leave_tagger_grounded.emit()
if old_state == GameState.TAGGER_UNGROUNDED:
state_leave_tagger_ungrounded.emit()
if old_state == GameState.TAGGER_CHANGE:
state_leave_tagger_change.emit()
func _ready():
# Hacky way to start level without going though multiplayer screens
@ -8,3 +69,9 @@ func _ready():
# Called from the server
func server_add_player(id: int):
%PlayerSpawner.spawn(id)
static func find_level(node: Node) -> Level:
var parent := node
while not (node is Level):
node = node.get_parent()
return node

View File

@ -1,8 +1,9 @@
[gd_scene load_steps=9 format=3 uid="uid://b00brfkibo5cj"]
[gd_scene load_steps=10 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"]
@ -22,7 +23,8 @@ environment = ExtResource("2_ptkl6")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="WorldEnvironment" index="0"]
transform = Transform3D(1, 0, 0, 0, 0.566018, 0.824393, 0, -0.824393, 0.566018, 0, 13.4573, 0)
[node name="StaticBody3D" type="StaticBody3D" parent="Plane" index="0"]
[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)

View File

@ -1,6 +1,7 @@
# Automatically Generated From Builtin CharacterBody Template
extends CharacterBody3D
class_name Player
@export var SPEED = 5.0
@export var JUMP_VELOCITY = 4.5
@ -10,6 +11,21 @@ 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
# 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)
var _is_grounded := false
signal is_grounded
func is_on_ground() -> bool:
_is_grounded = false
is_grounded.emit()
var v := _is_grounded
_is_grounded = false
return v
func _physics_process(delta):
if not is_on_floor():
velocity.y -= gravity * delta
@ -25,3 +41,44 @@ func _physics_process(delta):
velocity.z = move_toward(velocity.z, 0, SPEED)
move_and_slide()
var _first_bumper: Player = null
func _bump_check(src: Player):
if src._first_bumper == null:
src._first_bumper = self
func get_first_bumper() -> Player:
_first_bumper = null
is_bumping.emit(self)
var player := _first_bumper
_first_bumper = null
return player
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):
return
is_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):
return
is_bumping.disconnect(_bump_check)
func _on_tag_detection_body_entered(body):
if body.is_in_group("ground"):
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 is_grounded.is_connected(body.grounded):
is_grounded.disconnect(body.grounded)

View File

@ -1,4 +1,4 @@
[gd_scene load_steps=5 format=3 uid="uid://do25xvpy80iio"]
[gd_scene load_steps=6 format=3 uid="uid://do25xvpy80iio"]
[ext_resource type="PackedScene" uid="uid://bwg2jkbq7gada" path="res://player/player.glb" id="1_0u2un"]
[ext_resource type="Script" path="res://player/player.gd" id="1_gh340"]
@ -11,6 +11,9 @@ properties/0/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_t1htn"]
radius = 0.986757
[sub_resource type="SphereShape3D" id="SphereShape3D_ylark"]
radius = 1.0605
[node name="player" instance=ExtResource("1_0u2un")]
floor_max_angle = 1.32121
script = ExtResource("1_gh340")
@ -21,3 +24,15 @@ replication_config = SubResource("SceneReplicationConfig_u4bmc")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." index="2"]
shape = SubResource("SphereShape3D_t1htn")
[node name="TagDetection" type="Area3D" parent="." index="3"]
collision_layer = 8388608
collision_mask = 8388608
[node name="CollisionShape3D" type="CollisionShape3D" parent="TagDetection" index="0"]
shape = SubResource("SphereShape3D_ylark")
[connection signal="area_entered" from="TagDetection" to="." method="_on_tag_detection_area_entered"]
[connection signal="area_exited" from="TagDetection" to="." method="_on_tag_detection_area_exited"]
[connection signal="body_entered" from="TagDetection" to="." method="_on_tag_detection_body_entered"]
[connection signal="body_exited" from="TagDetection" to="." method="_on_tag_detection_body_exited"]

View File

@ -35,7 +35,6 @@ config/icon="res://icon.svg"
[autoload]
MultiplayerEvents="*res://server/MultiplayerEvents.gd"
FmodManager="*res://addons/fmod/FmodManager.gd"
[editor_plugins]

View File

@ -1,2 +0,0 @@
extends Node