Compare commits
11 Commits
Author | SHA1 | Date |
---|---|---|
Spencer Killen | c38c9cbb4b | |
Spencer Killen | df09636af9 | |
EvanGee | aaee834a61 | |
EvanGee | 6668bff3dd | |
Spencer Killen | c7283297ab | |
Spencer Killen | 00ff4fd9c5 | |
Spencer Killen | c3e5073011 | |
EvanGee | c9edb73c50 | |
Spencer Killen | a88607a316 | |
Spencer Killen | 79df0710c0 | |
EvanGee | 8fbd8c86f3 |
|
@ -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
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
[gd_scene load_steps=2 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/camera.gd" id="1_veqr4"]
|
||||||
|
[ext_resource type="Script" path="res://camera/PersonalUI.gd" id="2_u54jc"]
|
||||||
|
|
||||||
|
[sub_resource type="SphereShape3D" id="SphereShape3D_5lewf"]
|
||||||
|
|
||||||
[node name="Camera" type="Node3D"]
|
[node name="Camera" type="Node3D"]
|
||||||
script = ExtResource("1_veqr4")
|
script = ExtResource("1_veqr4")
|
||||||
|
@ -8,8 +11,32 @@ script = ExtResource("1_veqr4")
|
||||||
[node name="SpringArm3D" type="SpringArm3D" parent="."]
|
[node name="SpringArm3D" type="SpringArm3D" parent="."]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 2)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 2)
|
||||||
|
shape = SubResource("SphereShape3D_5lewf")
|
||||||
spring_length = 2.0
|
spring_length = 2.0
|
||||||
margin = 0.5
|
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)
|
||||||
|
|
|
@ -6,9 +6,14 @@ func _ready():
|
||||||
|
|
||||||
func spawn_player(owner_id: int):
|
func spawn_player(owner_id: int):
|
||||||
var player := preload("res://player/player.tscn").instantiate()
|
var player := preload("res://player/player.tscn").instantiate()
|
||||||
|
player.name = str(owner_id)
|
||||||
player.set_multiplayer_authority(owner_id)
|
player.set_multiplayer_authority(owner_id)
|
||||||
if multiplayer.get_unique_id() == owner_id:
|
if multiplayer.get_unique_id() == owner_id:
|
||||||
var camera := preload("res://camera/camera.tscn").instantiate()
|
var camera := preload("res://camera/camera.tscn").instantiate()
|
||||||
player.add_child(camera)
|
player.add_child(camera)
|
||||||
return player
|
return player
|
||||||
|
|
||||||
|
func despawn_player(owner_id: int):
|
||||||
|
var node := get_node(spawn_path).get_node(str(owner_id))
|
||||||
|
node.queue_free()
|
||||||
|
await node.tree_exited
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
extends StaticBody3D
|
|
||||||
|
|
||||||
func grounded(src: Player):
|
|
||||||
src._is_grounded = true
|
|
103
level/level.gd
103
level/level.gd
|
@ -19,6 +19,18 @@ 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 := 2
|
||||||
|
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):
|
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)
|
||||||
|
@ -30,13 +42,44 @@ func set_tagger_grounded(v: bool):
|
||||||
if v and game_state == GameState.TAGGER_UNGROUNDED:
|
if v and game_state == GameState.TAGGER_UNGROUNDED:
|
||||||
_change_state(GameState.TAGGER_GROUNDED)
|
_change_state(GameState.TAGGER_GROUNDED)
|
||||||
|
|
||||||
func set_tagger(who: Player):
|
|
||||||
if game_state == GameState.WAITING:
|
func not_enough_players() -> bool:
|
||||||
|
if %Players.get_children().size() < MIN_PLAYERS:
|
||||||
|
game_tagger = null
|
||||||
|
_change_state(GameState.WAITING)
|
||||||
|
push_global_message.rpc(global_msg_1.format({"min_players": MIN_PLAYERS}))
|
||||||
|
return true
|
||||||
|
return false
|
||||||
|
|
||||||
|
func change_to_random_tagger():
|
||||||
|
game_tagger = %Players.get_children().pick_random()
|
||||||
|
_change_state(GameState.TAGGER_CHANGE)
|
||||||
|
|
||||||
|
func tagger_left_game():
|
||||||
|
if not_enough_players():
|
||||||
return
|
return
|
||||||
|
var old_tagger_username := game_tagger.username
|
||||||
|
change_to_random_tagger()
|
||||||
|
var tagger_username := game_tagger.username
|
||||||
|
push_global_message.rpc(global_msg_5.format({
|
||||||
|
"old_tagger_username": old_tagger_username,
|
||||||
|
"tagger_username": tagger_username}))
|
||||||
|
|
||||||
|
func set_tagger(who: Player):
|
||||||
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()
|
||||||
|
_change_state_full.rpc(new_state, id)
|
||||||
|
|
||||||
|
@rpc("any_peer", "reliable", "call_local")
|
||||||
|
func _change_state_full(new_state: GameState, new_tagger_id: int):
|
||||||
|
game_tagger = null
|
||||||
|
if new_tagger_id != -1:
|
||||||
|
game_tagger = find_player_by_id(new_tagger_id)
|
||||||
if game_state == new_state:
|
if game_state == new_state:
|
||||||
return
|
return
|
||||||
if new_state == GameState.WAITING:
|
if new_state == GameState.WAITING:
|
||||||
|
@ -59,18 +102,72 @@ func _change_state(new_state: GameState):
|
||||||
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 true
|
||||||
|
|
||||||
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 teleport(who: Player):
|
||||||
|
if not who.is_multiplayer_authority():
|
||||||
|
push_error("Don't have the authority to teleport")
|
||||||
|
return
|
||||||
|
who.position = Vector3.ZERO
|
||||||
|
|
||||||
|
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}))
|
||||||
|
teleport(player)
|
||||||
|
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):
|
||||||
|
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:
|
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))
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
[gd_scene load_steps=12 format=3 uid="uid://b00brfkibo5cj"]
|
[gd_scene load_steps=13 format=3 uid="uid://b00brfkibo5cj"]
|
||||||
|
|
||||||
[ext_resource type="PackedScene" uid="uid://bq654gwim6col" path="res://level/level.glb" id="1_s37in"]
|
[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="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/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://addons/smoother/smoother.gd" id="5_2tyle"]
|
||||||
[ext_resource type="Script" path="res://level/PlayerSpawner.gd" id="6_7ww0m"]
|
[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"]
|
[ext_resource type="MeshLibrary" uid="uid://cgh6y5j8wgi36" path="res://level/mesh_library/level_mesh_library.glb" id="6_d34iv"]
|
||||||
|
@ -18,6 +17,11 @@ size = Vector3(2, 0.1, 2)
|
||||||
size = Vector2(100, 100)
|
size = Vector2(100, 100)
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_m3lo5"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_m3lo5"]
|
||||||
|
size = Vector3(100, 100, 1)
|
||||||
|
|
||||||
|
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_285vp"]
|
||||||
|
|
||||||
|
[sub_resource type="BoxShape3D" id="BoxShape3D_0y3ka"]
|
||||||
|
|
||||||
[node name="level" instance=ExtResource("1_s37in")]
|
[node name="level" instance=ExtResource("1_s37in")]
|
||||||
script = ExtResource("2_s1bx6")
|
script = ExtResource("2_s1bx6")
|
||||||
|
@ -33,7 +37,6 @@ transform = Transform3D(25.5862, 0, 0, 0, 25.5862, 0, 0, 0, 25.5862, 0.00464344,
|
||||||
visible = false
|
visible = false
|
||||||
|
|
||||||
[node name="StaticBody3D" type="StaticBody3D" parent="Plane" index="0" groups=["ground"]]
|
[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"]
|
[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)
|
transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0, 0)
|
||||||
|
@ -48,7 +51,7 @@ visible = false
|
||||||
|
|
||||||
[node name="Players" type="Node3D" parent="." index="3"]
|
[node name="Players" type="Node3D" parent="." index="3"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 11.4823, 12, 16.4239)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.78702, 68.686, -4.61699)
|
||||||
|
|
||||||
[node name="PlayerSpawner" type="MultiplayerSpawner" parent="." index="4"]
|
[node name="PlayerSpawner" type="MultiplayerSpawner" parent="." index="4"]
|
||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
|
@ -78,7 +81,7 @@ data = {
|
||||||
}
|
}
|
||||||
metadata/_editor_floor_ = Vector3(0, 2, 0)
|
metadata/_editor_floor_ = Vector3(0, 2, 0)
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="." index="8"]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="." index="8" groups=["ground"]]
|
||||||
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.001, 0, 0)
|
transform = Transform3D(1, 0, 0, 0, -4.37114e-08, 1, 0, -1, -4.37114e-08, 0.001, 0, 0)
|
||||||
mesh = SubResource("QuadMesh_8lqeb")
|
mesh = SubResource("QuadMesh_8lqeb")
|
||||||
skeleton = NodePath("../Cube")
|
skeleton = NodePath("../Cube")
|
||||||
|
@ -86,5 +89,29 @@ skeleton = NodePath("../Cube")
|
||||||
[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D" index="0"]
|
[node name="StaticBody3D" type="StaticBody3D" parent="MeshInstance3D" index="0"]
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D" index="0"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="MeshInstance3D/StaticBody3D" index="0"]
|
||||||
transform = Transform3D(100, 0, 0, 0, 100, 0, 0, 0, 1, 0, 0, -0.5)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.5)
|
||||||
shape = SubResource("BoxShape3D_m3lo5")
|
shape = SubResource("BoxShape3D_m3lo5")
|
||||||
|
|
||||||
|
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." index="9"]
|
||||||
|
replication_config = SubResource("SceneReplicationConfig_285vp")
|
||||||
|
|
||||||
|
[node name="SharedUI" type="Control" parent="." index="10"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 40.0
|
||||||
|
|
||||||
|
[node name="GlobalMessage" type="Label" parent="SharedUI" index="0"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 0
|
||||||
|
offset_right = 40.0
|
||||||
|
offset_bottom = 23.0
|
||||||
|
|
||||||
|
[node name="Ground" type="Area3D" parent="." index="11" groups=["ground"]]
|
||||||
|
transform = Transform3D(9, 0, 0, 0, 9, 0, 0, 0, 9, 4.85232, 7.93442, -4.42363)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Ground" index="0"]
|
||||||
|
shape = SubResource("BoxShape3D_0y3ka")
|
||||||
|
|
||||||
|
[connection signal="despawned" from="PlayerSpawner" to="." method="client_remove_player"]
|
||||||
|
[connection signal="spawned" from="PlayerSpawner" to="." method="client_add_player"]
|
||||||
|
|
|
@ -5,29 +5,40 @@ class_name Player
|
||||||
|
|
||||||
@export var SPEED = 5.0
|
@export var SPEED = 5.0
|
||||||
@export var JUMP_VELOCITY = 4.5
|
@export var JUMP_VELOCITY = 4.5
|
||||||
|
var username: String = ""
|
||||||
|
|
||||||
var gravity = ProjectSettings.get_setting("physics/3d/default_gravity")
|
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
|
||||||
|
|
||||||
# Using signals to maintain a list of currently colliding players because it simplifies
|
|
||||||
# Memory management substantially since nodes are not GC'd
|
# Signals fire continously every frame they're true
|
||||||
# Connected nodes are the colliding nodes
|
signal tag(player: Player)
|
||||||
signal is_bumping(src: Player)
|
signal ground(v: bool)
|
||||||
var _is_grounded := false
|
|
||||||
signal is_grounded
|
func _process(_delta):
|
||||||
|
ground.emit(is_on_ground())
|
||||||
|
var player := get_first_tagging()
|
||||||
|
if player != null:
|
||||||
|
print("tag")
|
||||||
|
tag.emit(player)
|
||||||
|
|
||||||
|
# Signals being abused as weak hashsets
|
||||||
|
# Never emit
|
||||||
|
signal player_tagging_hashset
|
||||||
|
signal ground_touching_hashset
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
if username == "":
|
||||||
|
username = "Player " + name
|
||||||
|
$Sphere.set_instance_shader_parameter("color", Color.DARK_ORANGE)
|
||||||
|
|
||||||
func is_on_ground() -> bool:
|
func is_on_ground() -> bool:
|
||||||
_is_grounded = false
|
return player_tagging_hashset.get_connections().size() > 0
|
||||||
is_grounded.emit()
|
|
||||||
var v := _is_grounded
|
|
||||||
_is_grounded = false
|
|
||||||
return v
|
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta):
|
func _physics_process(delta):
|
||||||
print(is_on_ground())
|
|
||||||
if not is_on_floor():
|
if not is_on_floor():
|
||||||
velocity.y -= gravity * delta
|
velocity.y -= gravity * delta
|
||||||
|
|
||||||
|
@ -43,44 +54,39 @@ func _physics_process(delta):
|
||||||
|
|
||||||
move_and_slide()
|
move_and_slide()
|
||||||
|
|
||||||
var _first_bumper: Player = null
|
func id():
|
||||||
|
return self
|
||||||
|
|
||||||
func _bump_check(src: Player):
|
func get_first_tagging() -> Player:
|
||||||
if src._first_bumper == null:
|
var connections := player_tagging_hashset.get_connections()
|
||||||
src._first_bumper = self
|
if connections.size() == 0:
|
||||||
|
return null
|
||||||
func get_first_bumper() -> Player:
|
return connections[0]["callable"].call()
|
||||||
_first_bumper = null
|
|
||||||
is_bumping.emit(self)
|
|
||||||
var player := _first_bumper
|
|
||||||
_first_bumper = null
|
|
||||||
return player
|
|
||||||
|
|
||||||
func _on_tag_detection_area_entered(area):
|
func _on_tag_detection_area_entered(area):
|
||||||
if not (area.get_parent() is Player):
|
if not (area.get_parent() is Player) or area.get_parent() == self:
|
||||||
return
|
return
|
||||||
var _other_player: Player = area.get_parent()
|
var other_player: Player = area.get_parent()
|
||||||
if is_bumping.is_connected(_bump_check):
|
if player_tagging_hashset.is_connected(other_player.id):
|
||||||
return
|
return
|
||||||
is_bumping.connect(_bump_check)
|
player_tagging_hashset.connect(other_player.id)
|
||||||
|
|
||||||
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) or area.get_parent() == self:
|
||||||
return
|
return
|
||||||
var _other_player: Player = area.get_parent()
|
var other_player: Player = area.get_parent()
|
||||||
if not is_bumping.is_connected(_bump_check):
|
if not player_tagging_hashset.is_connected(other_player.id):
|
||||||
return
|
return
|
||||||
is_bumping.disconnect(_bump_check)
|
player_tagging_hashset.disconnect(other_player.id)
|
||||||
|
|
||||||
|
|
||||||
func _on_tag_detection_body_entered(body):
|
func _on_ground_detection_node_entered(node: Node):
|
||||||
if body.is_in_group("ground"):
|
if node.is_in_group("ground"):
|
||||||
print("fuck")
|
if not ground_touching_hashset.is_connected(node.get_tree):
|
||||||
if not is_grounded.is_connected(body.grounded):
|
ground_touching_hashset.connect(node.get_tree)
|
||||||
is_grounded.connect(body.grounded)
|
|
||||||
|
|
||||||
|
|
||||||
func _on_tag_detection_body_exited(body):
|
func _on_ground_detection_node_exited(node: Node):
|
||||||
if body.is_in_group("ground"):
|
if node.is_in_group("ground"):
|
||||||
if is_grounded.is_connected(body.grounded):
|
if ground_touching_hashset.is_connected(node.get_tree):
|
||||||
is_grounded.disconnect(body.grounded)
|
ground_touching_hashset.disconnect(node.get_tree)
|
||||||
|
|
|
@ -29,6 +29,13 @@ animation/fps=30
|
||||||
animation/trimming=false
|
animation/trimming=false
|
||||||
animation/remove_immutable_tracks=true
|
animation/remove_immutable_tracks=true
|
||||||
import_script/path=""
|
import_script/path=""
|
||||||
_subresources={}
|
_subresources={
|
||||||
|
"materials": {
|
||||||
|
"skin": {
|
||||||
|
"use_external/enabled": true,
|
||||||
|
"use_external/path": "res://player/player_color.tres"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
gltf/naming_version=1
|
gltf/naming_version=1
|
||||||
gltf/embedded_image_handling=1
|
gltf/embedded_image_handling=1
|
||||||
|
|
|
@ -26,13 +26,20 @@ replication_config = SubResource("SceneReplicationConfig_u4bmc")
|
||||||
shape = SubResource("SphereShape3D_t1htn")
|
shape = SubResource("SphereShape3D_t1htn")
|
||||||
|
|
||||||
[node name="TagDetection" type="Area3D" parent="." index="3"]
|
[node name="TagDetection" type="Area3D" parent="." index="3"]
|
||||||
collision_layer = 8388608
|
collision_layer = 8388609
|
||||||
collision_mask = 8388608
|
collision_mask = 8388609
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="TagDetection" index="0"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="TagDetection" index="0"]
|
||||||
shape = SubResource("SphereShape3D_ylark")
|
shape = SubResource("SphereShape3D_ylark")
|
||||||
|
|
||||||
|
[node name="GroundDetection" type="Area3D" parent="." index="4"]
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="GroundDetection" index="0"]
|
||||||
|
shape = SubResource("SphereShape3D_ylark")
|
||||||
|
|
||||||
[connection signal="area_entered" from="TagDetection" to="." method="_on_tag_detection_area_entered"]
|
[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="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="area_entered" from="GroundDetection" to="." method="_on_ground_detection_node_entered"]
|
||||||
[connection signal="body_exited" from="TagDetection" to="." method="_on_tag_detection_body_exited"]
|
[connection signal="area_exited" from="GroundDetection" to="." method="_on_ground_detection_node_exited"]
|
||||||
|
[connection signal="body_entered" from="GroundDetection" to="." method="_on_ground_detection_node_entered"]
|
||||||
|
[connection signal="body_exited" from="GroundDetection" to="." method="_on_ground_detection_node_exited"]
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
shader_type spatial;
|
||||||
|
|
||||||
|
instance uniform vec3 color : source_color;
|
||||||
|
|
||||||
|
void fragment() {
|
||||||
|
ALBEDO = color;
|
||||||
|
// Called for every pixel the material is visible on.
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
[gd_resource type="ShaderMaterial" load_steps=2 format=3 uid="uid://k5oba64lxvnw"]
|
||||||
|
|
||||||
|
[ext_resource type="Shader" path="res://player/player_color.gdshader" id="1_mfu2j"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
render_priority = 0
|
||||||
|
shader = ExtResource("1_mfu2j")
|
|
@ -39,7 +39,11 @@ FmodManager="*res://addons/fmod/FmodManager.gd"
|
||||||
|
|
||||||
[editor_plugins]
|
[editor_plugins]
|
||||||
|
|
||||||
enabled=PackedStringArray("res://addons/fmod/plugin.cfg", "res://addons/godot_gltf2meshlib-6391ec247cc04f5fe89243b24fad68bc2ed2a96b/addons/gltf2meshlib/plugin.cfg")
|
enabled=PackedStringArray("res://addons/godot_gltf2meshlib-6391ec247cc04f5fe89243b24fad68bc2ed2a96b/addons/gltf2meshlib/plugin.cfg")
|
||||||
|
|
||||||
|
[filesystem]
|
||||||
|
|
||||||
|
import/fbx/enabled=false
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
# Runs server side per game
|
||||||
|
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
var port: int
|
var port: int
|
||||||
|
@ -10,7 +12,12 @@ func _ready():
|
||||||
peer.create_server(port, MAX_CLIENTS)
|
peer.create_server(port, MAX_CLIENTS)
|
||||||
m.multiplayer_peer = peer
|
m.multiplayer_peer = peer
|
||||||
m.peer_connected.connect(peer_connected)
|
m.peer_connected.connect(peer_connected)
|
||||||
|
m.peer_disconnected.connect(peer_disconnected)
|
||||||
|
|
||||||
func peer_connected(id: int):
|
func peer_connected(id: int):
|
||||||
print("Client " + str(id) + "connected to lobby " + str(get_path()))
|
print("Client " + str(id) + "connected to lobby " + str(get_path()))
|
||||||
$level.server_add_player(id)
|
$level.server_add_player(id)
|
||||||
|
|
||||||
|
func peer_disconnected(id: int):
|
||||||
|
print("Client " + str(id) + "disconnected to lobby " + str(get_path()))
|
||||||
|
$level.server_remove_player(id)
|
||||||
|
|
|
@ -6,8 +6,8 @@ signal join_lobby(addr: String, port: int)
|
||||||
func add(port: int):
|
func add(port: int):
|
||||||
var lobby_button := preload("res://server/lobby_list_entry.tscn").instantiate()
|
var lobby_button := preload("res://server/lobby_list_entry.tscn").instantiate()
|
||||||
var addr := "127.0.0.1"
|
var addr := "127.0.0.1"
|
||||||
|
if not multiplayer.is_server():
|
||||||
var peer := (multiplayer.multiplayer_peer as ENetMultiplayerPeer).get_peer(1)
|
var peer := (multiplayer.multiplayer_peer as ENetMultiplayerPeer).get_peer(1)
|
||||||
if peer != null:
|
|
||||||
addr = peer.get_remote_address()
|
addr = peer.get_remote_address()
|
||||||
lobby_button.address = addr
|
lobby_button.address = addr
|
||||||
lobby_button.port = port
|
lobby_button.port = port
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
Two types of servers / clients
|
Two types of servers / clients
|
||||||
One for lobby management and one for actual game
|
server.gd and client_lobbies.gd handle lobby management
|
||||||
server.gd and client_lobbies.gd handle the former
|
and lobby.gd and client.gd handle the actual game
|
||||||
and lobby.gd and client.gd handle the latter
|
|
||||||
|
|
|
@ -1,8 +1,30 @@
|
||||||
[gd_scene load_steps=2 format=3 uid="uid://3ksclx7iiepo"]
|
[gd_scene load_steps=3 format=3 uid="uid://3ksclx7iiepo"]
|
||||||
|
|
||||||
|
[sub_resource type="GDScript" id="GDScript_tqnee"]
|
||||||
|
script/source = "extends Node3D
|
||||||
|
|
||||||
|
var stuff := Dictionary()
|
||||||
|
signal more_stuff
|
||||||
|
|
||||||
|
func _ready():
|
||||||
|
var v := Node.new()
|
||||||
|
stuff[v] = null
|
||||||
|
more_stuff.connect(v.get_tree)
|
||||||
|
v.free()
|
||||||
|
await Engine.get_main_loop().process_frame
|
||||||
|
print(stuff.keys())
|
||||||
|
print(more_stuff.get_connections())
|
||||||
|
|
||||||
|
|
||||||
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
|
func _process(delta):
|
||||||
|
pass
|
||||||
|
"
|
||||||
|
|
||||||
[sub_resource type="MeshLibrary" id="MeshLibrary_8y7oa"]
|
[sub_resource type="MeshLibrary" id="MeshLibrary_8y7oa"]
|
||||||
|
|
||||||
[node name="Foo" type="Node3D"]
|
[node name="Foo" type="Node3D"]
|
||||||
|
script = SubResource("GDScript_tqnee")
|
||||||
|
|
||||||
[node name="GridMap" type="GridMap" parent="."]
|
[node name="GridMap" type="GridMap" parent="."]
|
||||||
mesh_library = SubResource("MeshLibrary_8y7oa")
|
mesh_library = SubResource("MeshLibrary_8y7oa")
|
||||||
|
|
Loading…
Reference in New Issue