Inital project

This commit is contained in:
2026-05-22 23:28:18 -05:00
commit 605bfff1d1
250 changed files with 5930 additions and 0 deletions

View File

@@ -0,0 +1,13 @@
extends RigidBody3D
@onready var area_3d: Area3D = %Area3D
func _ready() -> void:
area_3d.body_entered.connect(_on_area_3d_body_entered)
get_tree().create_timer(60).timeout.connect(func(): queue_free())
func _on_area_3d_body_entered(body: Node3D) -> void:
if body.is_in_group("goal"):
queue_free()

View File

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

View File

@@ -0,0 +1,48 @@
[gd_scene format=3 uid="uid://dpcnrigmslqkt"]
[ext_resource type="Script" uid="uid://crvfs5rlkh3qt" path="res://scenes/entities/ball.gd" id="1_1pamd"]
[ext_resource type="Texture2D" uid="uid://cvopdw2yahdp8" path="res://addons/kenney_prototype_textures/red/texture_01.png" id="1_u0o5v"]
[sub_resource type="PhysicsMaterial" id="PhysicsMaterial_u0o5v"]
bounce = 5.0
[sub_resource type="SphereShape3D" id="SphereShape3D_1pamd"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_rlpj1"]
albedo_texture = ExtResource("1_u0o5v")
uv1_triplanar = true
[sub_resource type="SphereMesh" id="SphereMesh_wha2l"]
material = SubResource("StandardMaterial3D_rlpj1")
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_u0o5v"]
properties/0/path = NodePath(".:rotation")
properties/0/spawn = true
properties/0/replication_mode = 1
properties/1/path = NodePath(".:position")
properties/1/spawn = true
properties/1/replication_mode = 1
[sub_resource type="SphereShape3D" id="SphereShape3D_u0o5v"]
radius = 0.6
[node name="Ball" type="RigidBody3D" unique_id=799966824]
collision_layer = 2
collision_mask = 3
physics_material_override = SubResource("PhysicsMaterial_u0o5v")
script = ExtResource("1_1pamd")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=1633801294]
shape = SubResource("SphereShape3D_1pamd")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=1029757699]
mesh = SubResource("SphereMesh_wha2l")
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=223233635]
replication_config = SubResource("SceneReplicationConfig_u0o5v")
[node name="Area3D" type="Area3D" parent="." unique_id=1926680041]
unique_name_in_owner = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="Area3D" unique_id=1533869654]
shape = SubResource("SphereShape3D_u0o5v")

View File

@@ -0,0 +1,5 @@
esc - (cancel/return)
e - spawn ball
v - push to talk
n - toggle open mic
t - open chat

View File

@@ -0,0 +1,11 @@
[gd_scene format=3 uid="uid://ibtqgabhcw6p"]
[ext_resource type="PackedScene" uid="uid://vrgbtswm2ko5" path="res://scenes/ui/main_menu.tscn" id="1_o5qli"]
[ext_resource type="PackedScene" uid="uid://bg2q2emiroavd" path="res://scenes/ui/chat.tscn" id="2_0wfyh"]
[node name="Main" type="Node" unique_id=829705955]
[node name="MainMenu" parent="." unique_id=1371882812 instance=ExtResource("1_o5qli")]
[node name="Chat" parent="." unique_id=1028379683 instance=ExtResource("2_0wfyh")]
visible = false

View File

@@ -0,0 +1,83 @@
class_name Player
extends CharacterBody2D
@onready var player_menu: CanvasLayer = %PlayerMenu
@onready var username_label: Label = %UsernameLabel
@onready var sprite: Sprite2D = %Sprite
@onready var camera: Camera2D = %Camera
@export var walk_speed = 500.0
var player_info := PlayerInfoResource.new()
var menu_open: bool = false
var chat: Chat
func _enter_tree() -> void:
set_multiplayer_authority(int(name))
func _ready() -> void:
add_to_group("Players")
player_menu.hide()
if is_multiplayer_authority():
chat = GameManager.chat_node
chat.chat_input.text_submitted.connect(_on_text_submitted)
camera.make_current()
else:
set_process(false)
set_physics_process(false)
#voice_chat.set_multiplayer_authority(name.to_int())
func set_player_info_steam(steam_id: int):
player_info.init_steam(name.to_int(), Steam.getFriendPersonaName(steam_id), await Steamworks.get_player_avatar(steam_id), steam_id)
username_label.text = player_info.username
sprite.texture = player_info.avatar
func set_player_info_ip(username: String, avatar_bytes: PackedByteArray):
player_info.init_enet(name.to_int(), username, avatar_bytes)
username_label.text = player_info.username
sprite.texture = player_info.avatar
func _physics_process(delta: float) -> void:
if !menu_open:
var direction := Input.get_vector("left", "right", "forward", "backwards")
if direction:
velocity = direction * walk_speed
else:
velocity.x = move_toward(velocity.x, 0, walk_speed)
velocity.y = move_toward(velocity.y, 0, walk_speed)
move_and_slide()
func _on_text_submitted(text: String):
if is_multiplayer_authority():
chat.send_message(player_info.username, player_info.avatar_modulated_color)
func _process(delta: float) -> void:
if Input.is_action_just_pressed("menu") and !player_menu.visible and !chat.visible:
player_menu.show()
menu_open = true
elif Input.is_action_just_pressed("menu") and player_menu.visible:
player_menu.hide()
menu_open = false
if is_multiplayer_authority():
if Input.is_action_just_pressed("toggle_chat") and !chat.visible and !player_menu.visible:
menu_open = true
chat.update_visiblity(true, menu_open)
elif Input.is_action_just_pressed("menu") and chat.visible:
menu_open = false
chat.update_visiblity(false, menu_open)
elif Input.is_action_just_pressed("toggle_chat") and chat.visible and chat.new_message_timer.time_left > 0:
chat.new_message_timer.stop()
chat.chat_input.grab_focus()
menu_open = true

View File

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

View File

@@ -0,0 +1,51 @@
[gd_scene format=3 uid="uid://coomlq1nbp7aw"]
[ext_resource type="Script" uid="uid://b0f6yhfyjsqs" path="res://scenes/player/player.gd" id="1_8afob"]
[ext_resource type="PackedScene" uid="uid://dg55eimlsqgp7" path="res://scenes/ui/player_menu.tscn" id="2_dovo2"]
[ext_resource type="Texture2D" uid="uid://blpnie21uplx7" path="res://icon.svg" id="3_gmlin"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_8afob"]
size = Vector2(100, 100)
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_gmlin"]
properties/0/path = NodePath(".:position")
properties/0/spawn = true
properties/0/replication_mode = 1
[node name="Player" type="CharacterBody2D" unique_id=2081549557]
script = ExtResource("1_8afob")
[node name="Sprite" type="Sprite2D" parent="." unique_id=1634085200]
unique_name_in_owner = true
texture = ExtResource("3_gmlin")
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=206749953]
shape = SubResource("RectangleShape2D_8afob")
[node name="UsernameLabel" type="Label" parent="." unique_id=613634768]
unique_name_in_owner = true
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -176.0
offset_top = -93.425
offset_right = 176.0
offset_bottom = -70.425
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 4
text = "username"
horizontal_alignment = 1
[node name="PlayerMenu" parent="." unique_id=1711189995 instance=ExtResource("2_dovo2")]
unique_name_in_owner = true
visible = false
[node name="Camera" type="Camera2D" parent="." unique_id=2093624054]
unique_name_in_owner = true
zoom = Vector2(0.8, 0.8)
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1516753759]
replication_config = SubResource("SceneReplicationConfig_gmlin")

View File

@@ -0,0 +1,121 @@
extends CharacterBody3D
@onready var camera: Camera3D = %Camera
@onready var head: Node3D = %Head
@onready var player_menu: CanvasLayer = %PlayerMenu
@onready var username_label: Label3D = %UsernameLabel
@onready var avatar_image: Sprite3D = %AvatarImage
@onready var spawn_point: Marker3D = %SpawnPoint
@onready var voice_chat = %VoiceChat
@export var sensitivity: float = 0.002
@export var SPEED := 5.0
@export var JUMP_VELOCITY := 4.5
var player_info := PlayerInfoResource.new()
var menu_open: bool = false
var chat: Chat
func _enter_tree() -> void:
set_multiplayer_authority(int(name))
func _ready() -> void:
add_to_group("Players")
player_menu.hide()
if is_multiplayer_authority():
camera.current = true
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
chat = GameManager.chat_node
chat.chat_input.text_submitted.connect(_on_text_submitted)
else:
set_process(false)
set_physics_process(false)
voice_chat.set_multiplayer_authority(name.to_int())
func set_player_info_steam(steam_id: int):
player_info.init_steam(name.to_int(), Steam.getFriendPersonaName(steam_id), await Steamworks.get_player_avatar(steam_id), steam_id)
username_label.text = player_info.username
avatar_image.texture = player_info.avatar
func set_player_info_ip(username: String, avatar_bytes: PackedByteArray):
player_info.init_enet(name.to_int(), username, avatar_bytes)
username_label.text = player_info.username
avatar_image.texture = player_info.avatar
func _physics_process(delta: float) -> void:
if not is_on_floor():
velocity += get_gravity() * delta
var input_dir
var direction
if !menu_open:
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
input_dir = Input.get_vector("left", "right", "forward", "backwards")
direction = (head.transform.basis * Vector3(input_dir.x, 0, input_dir.y)).normalized()
if direction:
velocity.x = direction.x * SPEED
velocity.z = direction.z * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
velocity.z = move_toward(velocity.z, 0, SPEED)
move_and_slide()
func _process(delta: float) -> void:
if Input.is_action_just_pressed("menu") and !player_menu.visible and !chat.visible:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
player_menu.show()
menu_open = true
elif Input.is_action_just_pressed("menu") and player_menu.visible:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
player_menu.hide()
menu_open = false
if Input.is_action_just_released("interact") and !menu_open:
if multiplayer.is_server():
GameManager._spawn_ball(spawn_point.global_position, 1)
else:
GameManager.request_spawn_ball.rpc(spawn_point.global_position)
if is_multiplayer_authority():
if Input.is_action_just_pressed("toggle_chat") and !chat.visible and !player_menu.visible:
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
menu_open = true
chat.update_visiblity(true, menu_open)
elif Input.is_action_just_pressed("menu") and chat.visible:
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
menu_open = false
chat.update_visiblity(false, menu_open)
elif Input.is_action_just_pressed("toggle_chat") and chat.visible and chat.new_message_timer.time_left > 0:
chat.new_message_timer.stop()
Input.set_mouse_mode(Input.MOUSE_MODE_VISIBLE)
chat.chat_input.grab_focus()
menu_open = true
func _unhandled_input(event: InputEvent) -> void:
if !is_multiplayer_authority(): return
if event is InputEventMouseMotion:
head.rotate_y(-event.relative.x * sensitivity)
camera.rotate_x(-event.relative.y * sensitivity)
camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-90), deg_to_rad(90))
func _on_text_submitted(text: String):
if is_multiplayer_authority():
chat.send_message(player_info.username, player_info.avatar_modulated_color)

View File

@@ -0,0 +1 @@
uid://01x0fo4llt5v

View File

@@ -0,0 +1,68 @@
[gd_scene format=3 uid="uid://cq6ovfsdvnt40"]
[ext_resource type="Script" uid="uid://01x0fo4llt5v" path="res://scenes/player/player3d.gd" id="1_qd3o8"]
[ext_resource type="PackedScene" uid="uid://dg55eimlsqgp7" path="res://scenes/ui/player_menu.tscn" id="2_4sc7w"]
[ext_resource type="Texture2D" uid="uid://blpnie21uplx7" path="res://icon.svg" id="3_bjl6v"]
[ext_resource type="PackedScene" uid="uid://brnbhj2m3shio" path="res://scenes/voice_chat/voice_chat.tscn" id="4_jvty1"]
[sub_resource type="CapsuleMesh" id="CapsuleMesh_dovo2"]
[sub_resource type="CapsuleShape3D" id="CapsuleShape3D_8afob"]
[sub_resource type="BoxMesh" id="BoxMesh_8afob"]
[sub_resource type="SceneReplicationConfig" id="SceneReplicationConfig_dovo2"]
properties/0/path = NodePath(".:position")
properties/0/spawn = true
properties/0/replication_mode = 1
properties/1/path = NodePath("Head:rotation")
properties/1/spawn = true
properties/1/replication_mode = 1
[node name="Player" type="CharacterBody3D" unique_id=2050060387]
script = ExtResource("1_qd3o8")
[node name="MeshInstance3D" type="MeshInstance3D" parent="." unique_id=768435836]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
mesh = SubResource("CapsuleMesh_dovo2")
[node name="CollisionShape3D" type="CollisionShape3D" parent="." unique_id=587703821]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0)
shape = SubResource("CapsuleShape3D_8afob")
[node name="Head" type="Node3D" parent="." unique_id=719581770]
unique_name_in_owner = true
[node name="MeshInstance3D" type="MeshInstance3D" parent="Head" unique_id=943825045]
transform = Transform3D(0.5631333, 0, 0, 0, 0.17207867, 0, 0, 0, 0.6267885, 0, 1.5652028, -0.2335369)
mesh = SubResource("BoxMesh_8afob")
[node name="Camera" type="Camera3D" parent="Head" unique_id=1626643721]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5604866, -0.2544498)
[node name="SpawnPoint" type="Marker3D" parent="Head" unique_id=102541278]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.354382, -1.436083)
[node name="PlayerMenu" parent="." unique_id=1711189995 instance=ExtResource("2_4sc7w")]
unique_name_in_owner = true
[node name="MultiplayerSynchronizer" type="MultiplayerSynchronizer" parent="." unique_id=1968705201]
replication_config = SubResource("SceneReplicationConfig_dovo2")
[node name="UsernameLabel" type="Label3D" parent="." unique_id=1985946962]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 2.226443, 0)
billboard = 2
text = "Player ID"
[node name="AvatarImage" type="Sprite3D" parent="." unique_id=1019124351]
unique_name_in_owner = true
transform = Transform3D(0.5, 0, 0, 0, 0.5, 0, 0, 0, 0.5, 0, 2.5678127, 0)
billboard = 2
texture = ExtResource("3_bjl6v")
[node name="VoiceChat" parent="." unique_id=2044163417 instance=ExtResource("4_jvty1")]
unique_name_in_owner = true
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5744768, 0)

View File

@@ -0,0 +1,58 @@
class_name Chat
extends CanvasLayer
@onready var chat_output: RichTextLabel = %ChatOutput
@onready var chat_input: LineEdit = %ChatInput
@onready var scroll_container: ScrollContainer = %ScrollContainer
@onready var new_message_timer: Timer = %NewMessageTimer
var menu_open: bool = false
func _ready():
GameManager.chat_node = self
new_message_timer.timeout.connect(_on_new_message_timer_timeout)
func send_message(username: String, avatar_color: Color = Color.WEB_GRAY):
if chat_input.text.is_empty(): return
if multiplayer.is_server():
add_chat_message(username, chat_input.text, avatar_color)
else:
add_chat_message.rpc_id(1, username, chat_input.text, avatar_color)
chat_input.clear()
@rpc("any_peer", "call_remote")
func add_chat_message(username: String, text: String, avatar_color: Color = Color.WEB_GRAY):
receive_chat_message.rpc(username, text, avatar_color)
@rpc("authority", "call_local")
func receive_chat_message(username: String, text: String, avatar_color: Color = Color.WEB_GRAY):
var os_time = Time.get_time_dict_from_system()
var formatted_os_time = str("%02d:%02d:%02d" % [os_time.hour, os_time.minute, os_time.second])
var new_message = "[%s]: [color=%s]%s[/color]: %s\n" % [formatted_os_time, avatar_color.to_html(false), username, text]
chat_output.append_text(new_message)
new_message_timer.start()
show()
print("DEBUG: receive called on peer: ", multiplayer.get_unique_id(), " | frame: ", Engine.get_process_frames())
func update_visiblity(set_chat_visible: bool, menu_open_init: bool):
if set_chat_visible:
show()
chat_input.grab_focus()
menu_open = menu_open_init
elif !set_chat_visible:
chat_input.release_focus()
hide()
menu_open = menu_open_init
func _on_new_message_timer_timeout():
if !menu_open:
hide()

View File

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

View File

@@ -0,0 +1,66 @@
[gd_scene format=3 uid="uid://bg2q2emiroavd"]
[ext_resource type="Script" uid="uid://m4rcvxjd31mr" path="res://scenes/ui/chat.gd" id="1_6bdm3"]
[node name="Chat" type="CanvasLayer" unique_id=1028379683]
script = ExtResource("1_6bdm3")
[node name="Control" type="Control" parent="." unique_id=524383998]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Panel" type="Panel" parent="Control" unique_id=284178139]
custom_minimum_size = Vector2(300, 400)
layout_mode = 1
anchors_preset = 2
anchor_top = 1.0
anchor_bottom = 1.0
offset_top = -400.0
offset_right = 300.0
grow_vertical = 0
[node name="VBoxContainer" type="VBoxContainer" parent="Control/Panel" unique_id=446822655]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
alignment = 2
[node name="ScrollContainer" type="ScrollContainer" parent="Control/Panel/VBoxContainer" unique_id=1582116754]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 3
[node name="ChatOutput" type="RichTextLabel" parent="Control/Panel/VBoxContainer/ScrollContainer" unique_id=587198232]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
theme_override_constants/outline_size = 8
theme_override_font_sizes/normal_font_size = 13
theme_override_font_sizes/bold_font_size = 13
theme_override_font_sizes/bold_italics_font_size = 13
theme_override_font_sizes/italics_font_size = 13
theme_override_font_sizes/mono_font_size = 13
bbcode_enabled = true
scroll_following = true
[node name="ChatInput" type="LineEdit" parent="Control/Panel/VBoxContainer" unique_id=1416488657]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 8
placeholder_text = "Send message"
max_length = 100
keep_editing_on_text_submit = true
caret_blink = true
[node name="NewMessageTimer" type="Timer" parent="." unique_id=1779987389]
unique_name_in_owner = true
wait_time = 5.0
one_shot = true

View File

@@ -0,0 +1,18 @@
class_name LoadingScreen
extends CanvasLayer
@export var loading_icon: TextureRect
@export var loading_label: Label
@export var cancel_button: Button
signal cancel_pressed
func _ready() -> void:
var offset := loading_icon.size / 2
loading_icon.pivot_offset = offset
cancel_button.pressed.connect(func(): cancel_pressed.emit())
func _process(_delta: float) -> void:
loading_icon.rotation_degrees += 2

View File

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

View File

@@ -0,0 +1,74 @@
[gd_scene format=3 uid="uid://38t27mxycd35"]
[ext_resource type="Script" uid="uid://ddkeq7kl674rl" path="res://scenes/ui/loading_screen.gd" id="1_q4fso"]
[ext_resource type="Texture2D" uid="uid://dygue47bpuvu0" path="res://assets/hourglass-regular.png" id="2_q4fso"]
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_q4fso"]
bg_color = Color(0, 0, 0, 1)
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_5fj0j"]
content_margin_left = 10.0
content_margin_top = 10.0
content_margin_right = 10.0
content_margin_bottom = 10.0
bg_color = Color(0.6790145, 2.815649e-06, 5.7756904e-07, 1)
[node name="LoadingScreen" type="CanvasLayer" unique_id=1615444093 node_paths=PackedStringArray("loading_icon", "loading_label", "cancel_button")]
script = ExtResource("1_q4fso")
loading_icon = NodePath("Control/MarginContainer/LoadingIcon")
loading_label = NodePath("Control/MarginContainer/LoadingLabel")
cancel_button = NodePath("Control/MarginContainer/CancelButton")
[node name="Control" type="Control" parent="." unique_id=1464738685]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="Panel" type="Panel" parent="Control" unique_id=598144043]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_styles/panel = SubResource("StyleBoxFlat_q4fso")
[node name="MarginContainer" type="MarginContainer" parent="Control" unique_id=874650830]
layout_mode = 1
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
theme_override_constants/margin_left = 50
theme_override_constants/margin_top = 50
theme_override_constants/margin_right = 50
theme_override_constants/margin_bottom = 50
[node name="LoadingIcon" type="TextureRect" parent="Control/MarginContainer" unique_id=6862137]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 100)
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 4
texture = ExtResource("2_q4fso")
expand_mode = 1
[node name="LoadingLabel" type="Label" parent="Control/MarginContainer" unique_id=1340572936]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 4
size_flags_vertical = 8
text = "Joining..."
horizontal_alignment = 1
[node name="CancelButton" type="Button" parent="Control/MarginContainer" unique_id=1414424067]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 0
size_flags_vertical = 8
theme_override_styles/normal = SubResource("StyleBoxFlat_5fj0j")
text = "Cancel"

View File

@@ -0,0 +1,141 @@
extends CanvasLayer
@onready var quit_button: Button = %QuitButton
@onready var steam_host_button: Button = %SteamHostButton
@onready var steam_lobby_id_edit: LineEdit = %SteamLobbyIDEdit
@onready var join_steam_button: Button = %JoinSteamButton
@onready var steam_controls: VBoxContainer = %SteamControls
@onready var steam_avatar: TextureRect = %SteamAvatar
@onready var steam_username_label: Label = %SteamUsernameLabel
@onready var ip_host_button: Button = %IPHostButton
@onready var e_net_controls: VBoxContainer = %ENetControls
@onready var username_input: LineEdit = %UsernameInput
@onready var ip_avatar_image: TextureButton = %IPAvatarImage
@onready var ip_edit: LineEdit = %IPEdit
@onready var join_ip_button: Button = %JoinIPButton
const TEST_LEVEL = preload("uid://tnw1q8a7ndio")
const STAGING_LEVEL = preload("uid://bc14d644835pj")
func _ready() -> void:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
check_command_line()
quit_button.pressed.connect(func(): get_tree().quit())
if OS.has_feature("nosteam"):
steam_controls.hide()
e_net_controls.show()
join_ip_button.pressed.connect(_on_ip_join_pressed)
ip_host_button.pressed.connect(_on_host_ip_pressed)
username_input.text_changed.connect(_on_username_input_text_changed)
ip_avatar_image.pressed.connect(_on_ip_avatar_clicked)
return
join_steam_button.pressed.connect(_on_join_steam_pressed)
steam_host_button.pressed.connect(_on_host_steam_pressed)
steam_lobby_id_edit.text_changed.connect(_on_lobby_text_changed)
Steam.join_requested.connect(_on_lobby_join_requested)
steam_username_label.text = Steamworks.steam_username
steam_avatar.texture = await Steamworks.get_player_avatar(Steamworks.steam_id)
func _on_host_steam_pressed():
NetworkManager.start_steam_lobby()
add_world()
hide()
func _on_join_steam_pressed():
NetworkManager.join_steam_lobby(steam_lobby_id_edit.text.to_int())
add_world()
hide()
func _on_lobby_join_requested(this_lobby_id: int, friend_id: int) -> void:
NetworkManager.join_steam_lobby(this_lobby_id)
add_world()
hide()
func add_world():
var new_scene := STAGING_LEVEL.instantiate()
get_tree().current_scene.add_child.call_deferred(new_scene)
func _on_lobby_text_changed(new_text: String):
if new_text == "":
join_steam_button.disabled = true
else:
join_steam_button.disabled = false
func check_command_line() -> void:
var these_arguments: Array = OS.get_cmdline_args()
if these_arguments.size() > 0:
if these_arguments[0] == "+connect_lobby":
if int(these_arguments[1]) > 0:
print("Command line lobby ID: %s" % these_arguments[1])
NetworkManager.join_steam_lobby(these_arguments[1])
add_world()
hide()
#region Non steam
func _on_ip_join_pressed():
var avatar: ImageTexture = ImageTexture.create_from_image(ip_avatar_image.texture_normal.get_image())
NetworkManager.join_server(ip_edit.text, username_input.text, avatar)
add_world()
hide()
func _on_host_ip_pressed():
var avatar: ImageTexture = ImageTexture.create_from_image(ip_avatar_image.texture_normal.get_image())
NetworkManager.start_server(username_input.text, avatar)
add_world()
hide()
func _on_username_input_text_changed(new_text: String) -> void:
if new_text == "":
ip_host_button.hide()
join_ip_button.hide()
else:
ip_host_button.show()
join_ip_button.show()
func _on_ip_avatar_clicked():
var file_dialog := FileDialog.new()
file_dialog.file_mode = FileDialog.FILE_MODE_OPEN_FILE
file_dialog.access = FileDialog.ACCESS_FILESYSTEM
file_dialog.filters = PackedStringArray([
"*.png ; PNG Images",
"*.jpg, *.jpeg ; JPEG Images",
"*.bmp ; BMP Images"
])
file_dialog.file_selected.connect(func(path: String):
var img := Image.new()
var err := img.load(path)
if err != OK:
push_error("Failed to load image from file")
return
img.resize(100, 100, Image.INTERPOLATE_LANCZOS)
var texture := ImageTexture.create_from_image(img)
ip_avatar_image.texture_normal = texture
file_dialog.queue_free()
)
add_child(file_dialog)
file_dialog.popup_centered()
#endregion

View File

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

View File

@@ -0,0 +1,158 @@
[gd_scene format=3 uid="uid://vrgbtswm2ko5"]
[ext_resource type="Script" uid="uid://crq0b0ygnfbjl" path="res://scenes/ui/main_menu.gd" id="1_sl1te"]
[ext_resource type="Texture2D" uid="uid://blpnie21uplx7" path="res://icon.svg" id="2_fe2o3"]
[ext_resource type="Texture2D" uid="uid://csljnn1ulbh7i" path="res://addons/kenney_prototype_textures/dark/texture_04.png" id="3_1g8jr"]
[node name="MainMenu" type="CanvasLayer" unique_id=1371882812]
script = ExtResource("1_sl1te")
[node name="Control" type="Control" parent="." unique_id=1988941314]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="PanelContainer" type="PanelContainer" parent="Control" unique_id=1538311932]
custom_minimum_size = Vector2(600, 300)
layout_mode = 1
anchors_preset = 8
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
offset_left = -300.0
offset_top = -150.0
offset_right = 300.0
offset_bottom = 150.0
grow_horizontal = 2
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="Control/PanelContainer" unique_id=1446206489]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
[node name="VBoxContainer" type="VBoxContainer" parent="Control/PanelContainer/MarginContainer" unique_id=600731185]
custom_minimum_size = Vector2(300, 0)
layout_mode = 2
size_flags_horizontal = 4
[node name="HBoxContainer2" type="HBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer" unique_id=1127605886]
layout_mode = 2
[node name="Label" type="Label" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer2" unique_id=1776570352]
layout_mode = 2
size_flags_horizontal = 6
text = "Battle Beans"
[node name="HBoxContainer" type="HBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer" unique_id=1028494634]
layout_mode = 2
size_flags_vertical = 3
[node name="SteamControls" type="VBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer" unique_id=614477215]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
theme_override_constants/separation = 20
[node name="SteamAvatar" type="TextureRect" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/SteamControls" unique_id=1524328989]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 100)
layout_mode = 2
size_flags_horizontal = 6
texture = ExtResource("2_fe2o3")
expand_mode = 1
[node name="SteamUsernameLabel" type="Label" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/SteamControls" unique_id=1636629417]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 6
text = "Username"
[node name="SteamHostButton" type="Button" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/SteamControls" unique_id=574367772]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "Host"
[node name="SteamJoinHbox" type="HBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/SteamControls" unique_id=747576334]
visible = false
layout_mode = 2
size_flags_vertical = 3
[node name="SteamLobbyIDEdit" type="LineEdit" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/SteamControls/SteamJoinHbox" unique_id=1021124488]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
placeholder_text = "Lobby ID"
alignment = 1
[node name="JoinSteamButton" type="Button" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/SteamControls/SteamJoinHbox" unique_id=1137964974]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
disabled = true
text = "Join"
[node name="ENetControls" type="VBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer" unique_id=1909532057]
unique_name_in_owner = true
visible = false
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
theme_override_constants/separation = 10
[node name="HBoxContainer" type="HBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls" unique_id=374121199]
layout_mode = 2
theme_override_constants/separation = 20
[node name="IPAvatarImage" type="TextureButton" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls/HBoxContainer" unique_id=966792766]
unique_name_in_owner = true
custom_minimum_size = Vector2(100, 100)
layout_mode = 2
texture_normal = ExtResource("3_1g8jr")
ignore_texture_size = true
stretch_mode = 0
[node name="UsernameInput" type="LineEdit" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls/HBoxContainer" unique_id=53008613]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 4
text = "Username"
placeholder_text = "Username"
[node name="IPHostButton" type="Button" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls" unique_id=388231535]
unique_name_in_owner = true
layout_mode = 2
text = "Host"
[node name="IPJoinHBox" type="HBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls" unique_id=1248428381]
layout_mode = 2
[node name="IPEdit" type="LineEdit" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls/IPJoinHBox" unique_id=1604669433]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "127.0.0.1"
placeholder_text = "IP Address"
alignment = 1
[node name="JoinIPButton" type="Button" parent="Control/PanelContainer/MarginContainer/VBoxContainer/HBoxContainer/ENetControls/IPJoinHBox" unique_id=1995375905]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
text = "Join"
[node name="QuitButton" type="Button" parent="Control/PanelContainer/MarginContainer/VBoxContainer" unique_id=1924907920]
unique_name_in_owner = true
layout_mode = 2
text = "Quit"

View File

@@ -0,0 +1,5 @@
class_name PlayerListItem
extends HBoxContainer
@export var avatar: TextureRect
@export var username: Label

View File

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

View File

@@ -0,0 +1,22 @@
[gd_scene format=3 uid="uid://bv670qe133heb"]
[ext_resource type="Script" uid="uid://dh3xwj2voqo15" path="res://scenes/ui/player_list_item.gd" id="1_lm242"]
[ext_resource type="Texture2D" uid="uid://blpnie21uplx7" path="res://icon.svg" id="1_scu6w"]
[node name="PlayerListItem" type="HBoxContainer" unique_id=775069241 node_paths=PackedStringArray("avatar", "username")]
theme_override_constants/separation = 15
script = ExtResource("1_lm242")
avatar = NodePath("Avatar")
username = NodePath("Username")
[node name="Avatar" type="TextureRect" parent="." unique_id=648912719]
unique_name_in_owner = true
custom_minimum_size = Vector2(60, 60)
layout_mode = 2
texture = ExtResource("1_scu6w")
expand_mode = 1
[node name="Username" type="Label" parent="." unique_id=332583236]
unique_name_in_owner = true
layout_mode = 2
text = "Username"

View File

@@ -0,0 +1,36 @@
extends CanvasLayer
const PLAYER_LIST_ITEM = preload("uid://bv670qe133heb")
@onready var leave_button: Button = %LeaveButton
@onready var player_list: VBoxContainer = %PlayerList
func _ready() -> void:
leave_button.pressed.connect(_on_leave_pressed)
visibility_changed.connect(_on_visibility_changed)
func _on_leave_pressed():
NetworkManager.leave_server()
func _on_visibility_changed():
if visible:
refresh_player_list()
func refresh_player_list():
for child in player_list.get_children():
child.queue_free()
if NetworkManager.is_steam_lobby:
for p in NetworkManager.player_list.values():
var item: PlayerListItem = PLAYER_LIST_ITEM.instantiate()
var player := p as Player
item.username.text = player.player_info.username
if player.player_info.avatar != null:
item.avatar.texture = player.player_info.avatar
player_list.add_child(item)

View File

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

View File

@@ -0,0 +1,50 @@
[gd_scene format=3 uid="uid://dg55eimlsqgp7"]
[ext_resource type="Script" uid="uid://cnn532uwkyl2y" path="res://scenes/ui/player_menu.gd" id="1_2rx5c"]
[node name="PlayerMenu" type="CanvasLayer" unique_id=1711189995]
script = ExtResource("1_2rx5c")
[node name="Control" type="Control" parent="." unique_id=1118512792]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
[node name="PanelContainer" type="PanelContainer" parent="Control" unique_id=1851737141]
layout_mode = 1
anchors_preset = 9
anchor_bottom = 1.0
offset_right = 540.0
grow_vertical = 2
[node name="MarginContainer" type="MarginContainer" parent="Control/PanelContainer" unique_id=1940417879]
layout_mode = 2
theme_override_constants/margin_left = 20
theme_override_constants/margin_top = 20
theme_override_constants/margin_right = 20
theme_override_constants/margin_bottom = 20
[node name="VBoxContainer" type="VBoxContainer" parent="Control/PanelContainer/MarginContainer" unique_id=1499285095]
custom_minimum_size = Vector2(500, 0)
layout_mode = 2
theme_override_constants/separation = 50
alignment = 1
[node name="ScrollContainer" type="ScrollContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer" unique_id=670435526]
layout_mode = 2
size_flags_vertical = 3
[node name="PlayerList" type="VBoxContainer" parent="Control/PanelContainer/MarginContainer/VBoxContainer/ScrollContainer" unique_id=1713092068]
unique_name_in_owner = true
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="LeaveButton" type="Button" parent="Control/PanelContainer/MarginContainer/VBoxContainer" unique_id=1877596038]
unique_name_in_owner = true
layout_mode = 2
size_flags_vertical = 8
text = "Leave"

View File

@@ -0,0 +1,156 @@
class_name VoiceChat
extends Node3D
@onready var open_mic_status_label: Label = %OpenMicStatusLabel
@onready var canvas_layer: CanvasLayer = %CanvasLayer
const SAMPLE_RATE: int = 48000
var current_sample_rate: int = SAMPLE_RATE
var voice_playback: AudioStreamGeneratorPlayback = null
var voice_loopback: AudioStreamGeneratorPlayback = null
var is_open_mic: bool = false
var is_prox: bool = true
var is_in_echo_chamber: bool = false
var is_looping_back: bool = false
var voice_stream_player #can be 3d or non spatial
var loopback_voice_stream_player #can be 3d or non spatial
func _ready():
if !is_multiplayer_authority():
canvas_layer.hide()
setup_stream()
func _process(delta):
check_for_voice()
func setup_stream() -> void:
# Optionally we can get the sample rate from Steam
current_sample_rate = Steam.getVoiceOptimalSampleRate()
if is_prox: #if you want to switch between prox and not prox
# Normal prox chat
voice_stream_player = AudioStreamPlayer3D.new()
voice_stream_player.unit_size = 3.0
voice_stream_player.bus = "VoiceChatBus"
voice_stream_player.attenuation_model = AudioStreamPlayer3D.ATTENUATION_LOGARITHMIC
add_child(voice_stream_player)
# Loopback for echo aslf-hearing
loopback_voice_stream_player = AudioStreamPlayer3D.new()
loopback_voice_stream_player.unit_size = 3.0
loopback_voice_stream_player.bus = "VoiceChatLoopbackBus"
add_child(loopback_voice_stream_player)
else:
# Normal voice chat (NON-PROXIMITY)
voice_stream_player = AudioStreamPlayer.new()
voice_stream_player.bus = "VoiceChatBus"
add_child(voice_stream_player)
# Normal prox chat
voice_stream_player.stream = AudioStreamGenerator.new()
voice_stream_player.stream.mix_rate = current_sample_rate
voice_stream_player.play()
voice_playback = voice_stream_player.get_stream_playback()
# Loopback for echo aslf-hearing
loopback_voice_stream_player.stream = AudioStreamGenerator.new()
loopback_voice_stream_player.stream.mix_rate = current_sample_rate
loopback_voice_stream_player.play()
voice_loopback = loopback_voice_stream_player.get_stream_playback()
func _input(event: InputEvent) -> void:
if !is_multiplayer_authority(): return
if event.is_action_pressed("voice_toggle") and !get_parent().menu_open:
is_open_mic = not is_open_mic
record_voice(is_open_mic)
if is_open_mic:
open_mic_status_label.text = "open mic: true"
elif !is_open_mic:
open_mic_status_label.text = "open mic: false"
if event.is_action_pressed("push_to_talk") and !get_parent().menu_open:
record_voice(true)
if event.is_action_released("push_to_talk") and !get_parent().menu_open:
record_voice(false)
func record_voice(is_recording: bool) -> void:
Steam.setInGameVoiceSpeaking(Steam.getSteamID(), is_recording)
if is_recording:
Steam.startVoiceRecording()
else:
Steam.stopVoiceRecording()
func check_for_voice() -> void:
if !Steamworks.is_initalized: return
if !is_multiplayer_authority(): return
var voice_data: Dictionary = Steam.getVoice()
if voice_data['result'] == Steam.VoiceResult.VOICE_RESULT_OK and voice_data['written']:
# Pass the voice data along
process_voice_data.rpc(voice_data['buffer'])
if is_looping_back:
process_loopback_voice_data(voice_data['buffer'])
# If using MultiplayerPeer, we will add this line
@rpc("any_peer", "call_remote", "unreliable")
func process_voice_data(voice_data: PackedByteArray) -> void:
var decompressed_voice: Dictionary = Steam.decompressVoice(voice_data, current_sample_rate)
if decompressed_voice['result'] == Steam.VoiceResult.VOICE_RESULT_OK and decompressed_voice['size'] > 0:
var frames_to_push: PackedVector2Array = PackedVector2Array()
frames_to_push.resize(decompressed_voice['size'] / 2)
for i in range(0, decompressed_voice['size'], 2):
var sample_int: int = decompressed_voice['uncompressed'].decode_s16(i)
var amplitude: float = float(sample_int) / 32768.0
frames_to_push[i / 2] = Vector2(amplitude, amplitude)
if voice_playback.get_frames_available() >= frames_to_push.size():
voice_playback.push_buffer(frames_to_push)
elif voice_playback.get_frames_available() > 0:
voice_playback.push_buffer(frames_to_push.slice(0, voice_playback.get_frames_available()))
func update_echo_chamber_status(is_in_echo_chamber: bool):
if is_in_echo_chamber and is_prox:
is_looping_back = true
if is_multiplayer_authority():
var new_reverb = AudioEffectReverb.new()
new_reverb.dry = 0.0
new_reverb.wet = 0.25
AudioServer.add_bus_effect(3, new_reverb, 0) # Add reverb with only wet-reverb for loopback to hear your own echo
voice_stream_player.bus = "VoiceChatEchoBus"
else:
is_looping_back = false
if is_multiplayer_authority():
AudioServer.remove_bus_effect(3, 0) # Set loopback back to normal by removing echo effect
voice_stream_player.bus = "VoiceChatBus"
func process_loopback_voice_data(voice_data: PackedByteArray) -> void:
var decompressed_voice: Dictionary = Steam.decompressVoice(voice_data, current_sample_rate)
if decompressed_voice['result'] == Steam.VoiceResult.VOICE_RESULT_OK and decompressed_voice['size'] > 0:
var frames_to_push: PackedVector2Array = PackedVector2Array()
frames_to_push.resize(decompressed_voice['size'] / 2)
for i in range(0, decompressed_voice['size'], 2):
var sample_int: int = decompressed_voice['uncompressed'].decode_s16(i)
var amplitude: float = float(sample_int) / 32768.0
frames_to_push[i / 2] = Vector2(amplitude, amplitude)
if voice_loopback.get_frames_available() >= frames_to_push.size():
voice_loopback.push_buffer(frames_to_push)
elif voice_loopback.get_frames_available() > 0:
voice_loopback.push_buffer(frames_to_push.slice(0, voice_loopback.get_frames_available()))

View File

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

View File

@@ -0,0 +1,15 @@
[gd_scene format=3 uid="uid://brnbhj2m3shio"]
[ext_resource type="Script" uid="uid://xw1ylfth7mdn" path="res://scenes/voice_chat/voice_chat.gd" id="1_tj6ls"]
[node name="VoiceChat" type="Node3D" unique_id=2044163417]
script = ExtResource("1_tj6ls")
[node name="CanvasLayer" type="CanvasLayer" parent="." unique_id=684198300]
unique_name_in_owner = true
[node name="OpenMicStatusLabel" type="Label" parent="CanvasLayer" unique_id=1018064567]
unique_name_in_owner = true
offset_right = 40.0
offset_bottom = 23.0
text = "open mic: false"

View File

@@ -0,0 +1,4 @@
extends Node2D
func _enter_tree() -> void:
GameManager.current_level = self

View File

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

View File

@@ -0,0 +1,21 @@
[gd_scene format=4 uid="uid://bc14d644835pj"]
[ext_resource type="Script" uid="uid://1kxqwsp6ol8v" path="res://scenes/world/staging_level/staging_level.gd" id="1_fcnyv"]
[ext_resource type="Texture2D" uid="uid://ksjjn5wwyodr" path="res://addons/kenney_prototype_textures/dark/texture_01.png" id="1_oij6c"]
[sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_oij6c"]
texture = ExtResource("1_oij6c")
texture_region_size = Vector2i(1024, 1024)
0:0/0 = 0
[sub_resource type="TileSet" id="TileSet_fcnyv"]
tile_size = Vector2i(1024, 1024)
sources/1 = SubResource("TileSetAtlasSource_oij6c")
[node name="StagingLevel" type="Node2D" unique_id=1542925777]
z_index = -1
script = ExtResource("1_fcnyv")
[node name="TileMapLayer" type="TileMapLayer" parent="." unique_id=424677526]
tile_map_data = PackedByteArray("AAAAAAAAAQAAAAAAAAD//wAAAQAAAAAAAAD/////AQAAAAAAAAAAAP//AQAAAAAAAAABAP//AQAAAAAAAAABAAAAAQAAAAAAAAABAAEAAQAAAAAAAAAAAAEAAQAAAAAAAAD//wEAAQAAAAAAAAD+/wEAAQAAAAAAAAD+/wAAAQAAAAAAAAD+////AQAAAAAAAAD+//7/AQAAAAAAAAD///7/AQAAAAAAAAAAAP7/AQAAAAAAAAABAP7/AQAAAAAAAAA=")
tile_set = SubResource("TileSet_fcnyv")

View File

@@ -0,0 +1,21 @@
extends Node3D
#@onready var echo_area_3d = %EchoArea3D
#
#func _enter_tree() -> void:
#GameManager.current_level = self
#
#
#func _ready():
#echo_area_3d.body_entered.connect(_on_body_entered)
#echo_area_3d.body_exited.connect(_on_body_exited)
#
#
#func _on_body_entered(body: Node3D):
#if body is Player:
#body.voice_chat.update_echo_chamber_status(true)
#
#
#func _on_body_exited(body: Node3D):
#if body is Player:
#body.voice_chat.update_echo_chamber_status(false)

View File

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

View File

@@ -0,0 +1,178 @@
[gd_scene format=3 uid="uid://tnw1q8a7ndio"]
[ext_resource type="Texture2D" uid="uid://ksjjn5wwyodr" path="res://addons/kenney_prototype_textures/dark/texture_01.png" id="1_2x7fr"]
[ext_resource type="Script" uid="uid://dn4ibees5bt5j" path="res://scenes/world/test_level.gd" id="1_7gmxp"]
[ext_resource type="Texture2D" uid="uid://d0x8llxd670sv" path="res://addons/kenney_prototype_textures/purple/texture_01.png" id="2_swvrr"]
[sub_resource type="ProceduralSkyMaterial" id="ProceduralSkyMaterial_2x7fr"]
sky_horizon_color = Color(0.66224277, 0.6717428, 0.6867428, 1)
ground_bottom_color = Color(0, 0, 0, 1)
ground_horizon_color = Color(0.18410549, 0.036081314, 0.34570548, 1)
[sub_resource type="Sky" id="Sky_swvrr"]
sky_material = SubResource("ProceduralSkyMaterial_2x7fr")
[sub_resource type="Environment" id="Environment_7lndr"]
background_mode = 2
sky = SubResource("Sky_swvrr")
tonemap_mode = 2
glow_enabled = true
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_mdrfg"]
[sub_resource type="PlaneMesh" id="PlaneMesh_2x7fr"]
size = Vector2(100, 100)
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_swvrr"]
albedo_texture = ExtResource("1_2x7fr")
uv1_triplanar = true
uv1_world_triplanar = true
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_7lndr"]
albedo_texture = ExtResource("2_swvrr")
uv1_triplanar = true
[sub_resource type="CylinderMesh" id="CylinderMesh_2x7fr"]
material = SubResource("StandardMaterial3D_7lndr")
height = 4.0
[sub_resource type="CylinderShape3D" id="CylinderShape3D_swvrr"]
height = 4.0
[sub_resource type="BoxShape3D" id="BoxShape3D_7lndr"]
size = Vector3(100, 20, 0.25878906)
[sub_resource type="BoxMesh" id="BoxMesh_7lndr"]
size = Vector3(0.5, 5, 5)
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_7lndr"]
points = PackedVector3Array(0.25, 2.5, 2.5, -0.25, 2.5, 2.5, 0.25, -2.5, 2.5, 0.25, 2.5, -2.5, -0.25, 2.5, -2.5, -0.25, -2.5, 2.5, 0.25, -2.5, -2.5, -0.25, -2.5, -2.5)
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_7gmxp"]
points = PackedVector3Array(0.25, 2.5, 2.5, -0.25, 2.5, 2.5, 0.25, -2.5, 2.5, 0.25, 2.5, -2.5, -0.25, 2.5, -2.5, -0.25, -2.5, 2.5, 0.25, -2.5, -2.5, -0.25, -2.5, -2.5)
[sub_resource type="ConvexPolygonShape3D" id="ConvexPolygonShape3D_3soa3"]
points = PackedVector3Array(0.25, 2.5, 2.5, -0.25, 2.5, 2.5, 0.25, -2.5, 2.5, 0.25, 2.5, -2.5, -0.25, 2.5, -2.5, -0.25, -2.5, 2.5, 0.25, -2.5, -2.5, -0.25, -2.5, -2.5)
[sub_resource type="BoxShape3D" id="BoxShape3D_32mv2"]
size = Vector3(4.8, 4.926178, 4.4814453)
[node name="TestLevel" type="Node3D" unique_id=196268006]
script = ExtResource("1_7gmxp")
[node name="WorldEnvironment" type="WorldEnvironment" parent="." unique_id=829791786]
environment = SubResource("Environment_7lndr")
[node name="DirectionalLight3D" type="DirectionalLight3D" parent="." unique_id=800450023]
transform = Transform3D(-0.8660254, -0.43301278, 0.25, 0, 0.49999997, 0.86602545, -0.50000006, 0.75, -0.43301266, 0, 0, 0)
shadow_enabled = true
[node name="Camera3D" type="Camera3D" parent="." unique_id=1064079434]
transform = Transform3D(0.7071068, -0.35355338, 0.61237246, 0, 0.8660254, 0.5, -0.7071068, -0.35355338, 0.61237246, 4.6606436, 4.750062, 2.8106136)
[node name="MultiplayerSpawner" type="MultiplayerSpawner" parent="." unique_id=639554418]
_spawnable_scenes = PackedStringArray("uid://dpcnrigmslqkt")
spawn_path = NodePath("..")
[node name="StaticBody3D" type="StaticBody3D" parent="." unique_id=1186260132]
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D" unique_id=2055751647]
shape = SubResource("WorldBoundaryShape3D_mdrfg")
[node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBody3D" unique_id=47604539]
mesh = SubResource("PlaneMesh_2x7fr")
surface_material_override/0 = SubResource("StandardMaterial3D_swvrr")
[node name="StaticBody3D2" type="StaticBody3D" parent="." unique_id=1520600822 groups=["goal"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.4108834, 9.536743e-07, -1.2906597)
[node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBody3D2" unique_id=1159683456]
mesh = SubResource("CylinderMesh_2x7fr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D2" unique_id=1391557602]
shape = SubResource("CylinderShape3D_swvrr")
[node name="StaticBody3D3" type="StaticBody3D" parent="." unique_id=290931779 groups=["goal"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.176176, -0.9479208, -0.94028664)
[node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBody3D3" unique_id=1447471713]
mesh = SubResource("CylinderMesh_2x7fr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D3" unique_id=1798687076]
shape = SubResource("CylinderShape3D_swvrr")
[node name="StaticBody3D4" type="StaticBody3D" parent="." unique_id=163538835 groups=["goal"]]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.8935657, 1.62342, -3.0411158)
[node name="MeshInstance3D" type="MeshInstance3D" parent="StaticBody3D4" unique_id=1029490741]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.6905794, 0)
mesh = SubResource("CylinderMesh_2x7fr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D4" unique_id=1458757496]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -0.6905794, 0)
shape = SubResource("CylinderShape3D_swvrr")
[node name="StaticBody3D5" type="StaticBody3D" parent="." unique_id=355953735]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -37)
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D5" unique_id=63747778]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 9.5, -12.708469)
shape = SubResource("BoxShape3D_7lndr")
[node name="StaticBody3D6" type="StaticBody3D" parent="." unique_id=644460602]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 62.50641)
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D6" unique_id=500155799]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 9.5, -12.708469)
shape = SubResource("BoxShape3D_7lndr")
[node name="StaticBody3D7" type="StaticBody3D" parent="." unique_id=1867921512]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, -36.676903, 1.9073486e-06, 0.7191582)
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D7" unique_id=200079656]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 9.5, -12.708469)
shape = SubResource("BoxShape3D_7lndr")
[node name="StaticBody3D8" type="StaticBody3D" parent="." unique_id=256816272]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 37.323097, 1.9073486e-06, -0.35115814)
[node name="CollisionShape3D" type="CollisionShape3D" parent="StaticBody3D8" unique_id=31312910]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 9.5, -12.708469)
shape = SubResource("BoxShape3D_7lndr")
[node name="EchoChamber" type="Node3D" parent="." unique_id=1336132105]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 7.353159, 0, 9.207022)
[node name="StaticBody3D" type="StaticBody3D" parent="EchoChamber" unique_id=457540061]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2.3000002, 2.5, 0)
[node name="MeshInstance3D" type="MeshInstance3D" parent="EchoChamber/StaticBody3D" unique_id=446628111]
mesh = SubResource("BoxMesh_7lndr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="EchoChamber/StaticBody3D" unique_id=1806946331]
shape = SubResource("ConvexPolygonShape3D_7lndr")
[node name="StaticBody3D2" type="StaticBody3D" parent="EchoChamber" unique_id=1319869867]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2.6999998, 2.5, 0)
[node name="MeshInstance3D" type="MeshInstance3D" parent="EchoChamber/StaticBody3D2" unique_id=1024269247]
mesh = SubResource("BoxMesh_7lndr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="EchoChamber/StaticBody3D2" unique_id=2028901953]
shape = SubResource("ConvexPolygonShape3D_7gmxp")
[node name="StaticBody3D3" type="StaticBody3D" parent="EchoChamber" unique_id=1227565400]
transform = Transform3D(-4.371139e-08, 1, 0, -1, -4.371139e-08, 0, 0, 0, 1, 0.3000002, 5.2, 0)
[node name="MeshInstance3D" type="MeshInstance3D" parent="EchoChamber/StaticBody3D3" unique_id=1869523150]
mesh = SubResource("BoxMesh_7lndr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="EchoChamber/StaticBody3D3" unique_id=274619902]
shape = SubResource("ConvexPolygonShape3D_3soa3")
[node name="EchoArea3D" type="Area3D" parent="EchoChamber" unique_id=958250901]
unique_name_in_owner = true
[node name="CollisionShape3D" type="CollisionShape3D" parent="EchoChamber/EchoArea3D" unique_id=1378357733]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.099999905, 2.4636383, 0)
shape = SubResource("BoxShape3D_32mv2")