Huge changes
Implemented spawn points correctly. Added saving & loading (currently only implemented with the spawn_index). You can now set spawn indicies in the DynamicAreaLoader to automatically load when the game is set to that value (on ready). Added configuration warnings to DynamicAreaLoader & PlayerSpawnPoint Added some generic translation (pot) files. Added AudioManager autoload to play, stop, fade audio streams (and set the bus directly). Added SceneFader autoload. Added SaveManager autoload. Added OptionsMenu with currently only volume sliders and a fullscreen toggle button. Added PauseMenu
This commit is contained in:
parent
7bd8e95c0d
commit
c7f96c78c4
@ -18,20 +18,21 @@ func _ready() -> void:
|
|||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
|
# Don't process if it isn't necessary.
|
||||||
if not is_instance_valid(character):
|
if not is_instance_valid(character):
|
||||||
return
|
return
|
||||||
|
|
||||||
if audio_player.is_empty():
|
if audio_player.is_empty():
|
||||||
# Don't process if it isn't necessary.
|
|
||||||
return
|
return
|
||||||
|
|
||||||
var on_floor: bool = character.is_on_floor()
|
var on_floor: bool = character.is_on_floor()
|
||||||
if on_floor:
|
if on_floor:
|
||||||
if _was_in_air:
|
if _was_in_air:
|
||||||
|
# We landed. Play a footstep.
|
||||||
play_footstep()
|
play_footstep()
|
||||||
_distance_traveled = 0.0
|
_distance_traveled = 0.0
|
||||||
|
|
||||||
var velocity: Vector3 = abs(character.velocity) #+ (abs(character.get_platform_velocity()) if not character.velocity.is_zero_approx() else Vector3.ZERO)
|
var velocity: Vector3 = abs(character.velocity)
|
||||||
velocity.y = 0.0
|
velocity.y = 0.0
|
||||||
|
|
||||||
if velocity.is_zero_approx():
|
if velocity.is_zero_approx():
|
||||||
|
|||||||
@ -17,6 +17,15 @@ var has_control: bool = true
|
|||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
GameGlobals.player = self
|
GameGlobals.player = self
|
||||||
|
|
||||||
|
if not get_tree().root.is_node_ready():
|
||||||
|
await get_tree().root.ready
|
||||||
|
|
||||||
|
var spawn_point := PlayerSpawnPoint.get_spawn_point_by_index(GameGlobals.spawn_index)
|
||||||
|
|
||||||
|
if is_instance_valid(spawn_point):
|
||||||
|
global_position = spawn_point.global_position
|
||||||
|
head.global_rotation = spawn_point.global_rotation
|
||||||
|
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
# Add the gravity.
|
# Add the gravity.
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
@tool
|
||||||
@icon("dynamic_area_loader.svg")
|
@icon("dynamic_area_loader.svg")
|
||||||
class_name DynamicAreaLoader3D
|
class_name DynamicAreaLoader3D
|
||||||
extends Area3D
|
extends Area3D
|
||||||
@ -16,7 +17,10 @@ signal load_finished(loaded_node: Node)
|
|||||||
## The node to load and add.[br][br]
|
## The node to load and add.[br][br]
|
||||||
## [b]IMPORTANT:[/b] The node needs to be marked as [b]Load as Placeholder[/b], otherwise nothing
|
## [b]IMPORTANT:[/b] The node needs to be marked as [b]Load as Placeholder[/b], otherwise nothing
|
||||||
## happens when loading (see [InstancePlaceholder]).
|
## happens when loading (see [InstancePlaceholder]).
|
||||||
@export var placeholder_node: Node
|
@export var placeholder_node: Node:
|
||||||
|
set(value):
|
||||||
|
placeholder_node = value
|
||||||
|
update_configuration_warnings()
|
||||||
## If [code]true[/code], the actual loading will be done separately in a thread.[br]
|
## If [code]true[/code], the actual loading will be done separately in a thread.[br]
|
||||||
## This prevents the game from freezing for a moment when loading a large scene.[br]
|
## This prevents the game from freezing for a moment when loading a large scene.[br]
|
||||||
## However, loading can be slower on lower-end hardware.
|
## However, loading can be slower on lower-end hardware.
|
||||||
@ -25,37 +29,47 @@ signal load_finished(loaded_node: Node)
|
|||||||
## when the [PlayerCharacter] exits this area.[br]This is to prevent the [PlayerCharacter]
|
## when the [PlayerCharacter] exits this area.[br]This is to prevent the [PlayerCharacter]
|
||||||
## from keep re-loading the area by just walking back and fourth through the load zones.
|
## from keep re-loading the area by just walking back and fourth through the load zones.
|
||||||
@export_range(0.0, 10.0, 0.01, "or_greater", "suffix:s") var keep_loaded_duration: float = 3.0
|
@export_range(0.0, 10.0, 0.01, "or_greater", "suffix:s") var keep_loaded_duration: float = 3.0
|
||||||
|
## Automatically load the area when entering the scene tree, if the [member GameGlobals.spawn_point]
|
||||||
|
## is set to any of these values.
|
||||||
|
@export var loaded_if_spawnpoint: Array[int] = []
|
||||||
|
|
||||||
## The reference to the currently loaded node that was loaded.
|
## The reference to the currently loaded node that was loaded.
|
||||||
var loaded_node: Node
|
var loaded_node: Node
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
|
if Engine.is_editor_hint():
|
||||||
|
return
|
||||||
|
|
||||||
|
if loaded_if_spawnpoint.has(GameGlobals.spawn_index):
|
||||||
|
load_area(null, true)
|
||||||
|
|
||||||
body_entered.connect(_on_body_entered)
|
body_entered.connect(_on_body_entered)
|
||||||
body_exited.connect(_on_body_exited)
|
body_exited.connect(_on_body_exited)
|
||||||
|
|
||||||
|
|
||||||
## Instances the area defined by [member placeholder_node].[br]
|
## Instances the area defined by [member placeholder_node].[br]
|
||||||
## See [method load_area_threaded] if you want to load the area in a thread instead
|
## See [method load_area_threaded] if you want to load the area in a thread instead
|
||||||
## of having a freeze during load.
|
## of having a freeze during load.[br][br]
|
||||||
func load_area(custom_scene: PackedScene = null) -> void:
|
## If [param forced] is [code]true[/code], don't check if the player is colliding when calling this function.
|
||||||
if is_instance_valid(placeholder_node) and placeholder_node is InstancePlaceholder:
|
func load_area(custom_scene: PackedScene = null, forced: bool = false) -> void:
|
||||||
if is_instance_valid(loaded_node) or not overlaps_body(GameGlobals.get_player()):
|
assert(is_instance_valid(placeholder_node), "[placeholder_node] needs to be set.")
|
||||||
return
|
assert(placeholder_node is InstancePlaceholder, "[placeholder_node] needs to be marked as 'Load As Placeholder'.")
|
||||||
|
|
||||||
loaded_node = placeholder_node.create_instance(false, custom_scene)
|
if is_instance_valid(loaded_node) or (not forced and not overlaps_body(GameGlobals.get_player())):
|
||||||
load_finished.emit(loaded_node)
|
return
|
||||||
|
|
||||||
|
loaded_node = placeholder_node.create_instance(false, custom_scene)
|
||||||
|
load_finished.emit(loaded_node)
|
||||||
|
|
||||||
|
|
||||||
## Loads the scene defined in
|
## Loads the scene defined in
|
||||||
## [member placeholder_node] ([member InstancePlaceholder.get_instance_path]) threaded.[br]
|
## [member placeholder_node] ([member InstancePlaceholder.get_instance_path]) threaded.[br]
|
||||||
## Calls [method load_area] with the [param custom_scene] set to the loaded scene.
|
## Calls [method load_area] with the [param custom_scene] set to the loaded scene.[br][br]
|
||||||
func load_area_threaded() -> void:
|
## [param forced] does the same thing as in [method load_area].
|
||||||
if is_instance_valid(loaded_node):
|
func load_area_threaded(forced: bool = false) -> void:
|
||||||
return
|
assert(is_instance_valid(placeholder_node), "[placeholder_node] needs to be set.")
|
||||||
|
assert(placeholder_node is InstancePlaceholder, "[placeholder_node] needs to be marked as 'Load As Placeholder'.")
|
||||||
if not is_instance_valid(placeholder_node) or placeholder_node is not InstancePlaceholder:
|
|
||||||
return
|
|
||||||
|
|
||||||
placeholder_node = placeholder_node as InstancePlaceholder
|
placeholder_node = placeholder_node as InstancePlaceholder
|
||||||
|
|
||||||
@ -70,7 +84,7 @@ func load_area_threaded() -> void:
|
|||||||
|
|
||||||
var scene: PackedScene = ResourceLoader.load_threaded_get(path)
|
var scene: PackedScene = ResourceLoader.load_threaded_get(path)
|
||||||
|
|
||||||
load_area(scene)
|
load_area(scene, forced)
|
||||||
|
|
||||||
|
|
||||||
## Unloads ([method Node.queue_free]) the [member loaded_node].[br]
|
## Unloads ([method Node.queue_free]) the [member loaded_node].[br]
|
||||||
@ -104,3 +118,14 @@ func _on_body_entered(body: Node3D) -> void:
|
|||||||
func _on_body_exited(body: Node3D) -> void:
|
func _on_body_exited(body: Node3D) -> void:
|
||||||
if body == GameGlobals.get_player():
|
if body == GameGlobals.get_player():
|
||||||
unload_area()
|
unload_area()
|
||||||
|
|
||||||
|
|
||||||
|
func _get_configuration_warnings() -> PackedStringArray:
|
||||||
|
if not is_instance_valid(placeholder_node):
|
||||||
|
return ["'placeholder_node' is not set."]
|
||||||
|
|
||||||
|
# TODO: Find a way to detect that in the editor.
|
||||||
|
if placeholder_node is not InstancePlaceholder and false:
|
||||||
|
return ["'placeholder_node' needs to be marked as 'Load As Placeholder'"]
|
||||||
|
|
||||||
|
return []
|
||||||
|
|||||||
@ -1,6 +1,8 @@
|
|||||||
class_name InteractiveLoader
|
class_name InteractiveLoader
|
||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
var load_progress: Array = []
|
||||||
|
|
||||||
|
|
||||||
func load_threaded(path: String) -> Resource:
|
func load_threaded(path: String) -> Resource:
|
||||||
if not is_inside_tree():
|
if not is_inside_tree():
|
||||||
@ -14,7 +16,7 @@ func load_threaded(path: String) -> Resource:
|
|||||||
ResourceLoader.load_threaded_request(path, "", false, ResourceLoader.CACHE_MODE_REUSE)
|
ResourceLoader.load_threaded_request(path, "", false, ResourceLoader.CACHE_MODE_REUSE)
|
||||||
|
|
||||||
while ResourceLoader.load_threaded_get_status(path) != ResourceLoader.THREAD_LOAD_LOADED:
|
while ResourceLoader.load_threaded_get_status(path) != ResourceLoader.THREAD_LOAD_LOADED:
|
||||||
match ResourceLoader.load_threaded_get_status(path):
|
match ResourceLoader.load_threaded_get_status(path, load_progress):
|
||||||
ResourceLoader.THREAD_LOAD_FAILED || ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
|
ResourceLoader.THREAD_LOAD_FAILED || ResourceLoader.THREAD_LOAD_INVALID_RESOURCE:
|
||||||
Logger.print_msg("[Interactive Loader] load failed.", -1.0, Logger.ErrTypes.WARNING)
|
Logger.print_msg("[Interactive Loader] load failed.", -1.0, Logger.ErrTypes.WARNING)
|
||||||
return null
|
return null
|
||||||
|
|||||||
@ -3,8 +3,22 @@ class_name PlayerSpawnPoint
|
|||||||
extends Marker3D
|
extends Marker3D
|
||||||
|
|
||||||
@export var spawn_index: int = 0: set = set_spawn_index
|
@export var spawn_index: int = 0: set = set_spawn_index
|
||||||
|
@export_tool_button("Set unique index") var set_unique_index: Callable = func() -> void:
|
||||||
|
for spawn_point: PlayerSpawnPoint in spawn_points:
|
||||||
|
if spawn_point == self:
|
||||||
|
continue
|
||||||
|
|
||||||
|
if spawn_point.spawn_index == spawn_index:
|
||||||
|
set_spawn_index(spawn_index + 1)
|
||||||
|
set_unique_index.call()
|
||||||
|
return
|
||||||
|
|
||||||
|
update_configuration_warnings()
|
||||||
|
@export var editor_auto_assign_unique_id: bool = true
|
||||||
|
|
||||||
|
static var spawn_points: Array[PlayerSpawnPoint] = []
|
||||||
var idx_label: Label3D
|
var idx_label: Label3D
|
||||||
|
var config_warnings_hint: Label3D
|
||||||
|
|
||||||
|
|
||||||
func _init() -> void:
|
func _init() -> void:
|
||||||
@ -12,17 +26,78 @@ func _init() -> void:
|
|||||||
var player_scene: PackedScene = load("res://components/characters/player/player_character.tscn")
|
var player_scene: PackedScene = load("res://components/characters/player/player_character.tscn")
|
||||||
add_child(player_scene.instantiate(), false, Node.INTERNAL_MODE_FRONT)
|
add_child(player_scene.instantiate(), false, Node.INTERNAL_MODE_FRONT)
|
||||||
|
|
||||||
# Setup label.
|
# Setup labels.
|
||||||
idx_label = Label3D.new()
|
idx_label = Label3D.new()
|
||||||
idx_label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
idx_label.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
||||||
idx_label.shaded = false
|
idx_label.shaded = false
|
||||||
|
idx_label.font_size = 64
|
||||||
add_child(idx_label, false, Node.INTERNAL_MODE_FRONT)
|
add_child(idx_label, false, Node.INTERNAL_MODE_FRONT)
|
||||||
idx_label.position.y = 1.8
|
idx_label.position.y = 1.8
|
||||||
set_spawn_index(spawn_index)
|
set_spawn_index(spawn_index)
|
||||||
|
|
||||||
|
config_warnings_hint = Label3D.new()
|
||||||
|
config_warnings_hint.billboard = BaseMaterial3D.BILLBOARD_ENABLED
|
||||||
|
config_warnings_hint.shaded = false
|
||||||
|
config_warnings_hint.no_depth_test = true
|
||||||
|
config_warnings_hint.fixed_size = true
|
||||||
|
config_warnings_hint.text = "!"
|
||||||
|
config_warnings_hint.modulate = Color.RED
|
||||||
|
add_child(config_warnings_hint, false, Node.INTERNAL_MODE_FRONT)
|
||||||
|
config_warnings_hint.position.y = 1.0
|
||||||
|
|
||||||
|
var tween: Tween = create_tween().set_loops()
|
||||||
|
tween.tween_property(config_warnings_hint, ^"scale", Vector3.ONE * 1.5, 0.075)
|
||||||
|
tween.tween_property(config_warnings_hint, ^"scale", Vector3.ONE * 1.0, 0.075)
|
||||||
|
|
||||||
|
update_configuration_warnings()
|
||||||
|
|
||||||
|
|
||||||
|
func _enter_tree() -> void:
|
||||||
|
if not spawn_points.has(self):
|
||||||
|
spawn_points.append(self)
|
||||||
|
|
||||||
|
if editor_auto_assign_unique_id and Engine.is_editor_hint():
|
||||||
|
set_unique_index.call_deferred()
|
||||||
|
|
||||||
|
|
||||||
|
func _exit_tree() -> void:
|
||||||
|
spawn_points.erase(self)
|
||||||
|
|
||||||
|
|
||||||
func set_spawn_index(index: int) -> void:
|
func set_spawn_index(index: int) -> void:
|
||||||
spawn_index = index
|
spawn_index = index
|
||||||
|
update_configuration_warnings()
|
||||||
|
|
||||||
if is_instance_valid(idx_label):
|
if is_instance_valid(idx_label):
|
||||||
idx_label.text = str(spawn_index)
|
idx_label.text = str(spawn_index)
|
||||||
|
|
||||||
|
|
||||||
|
func make_current(do_autosave: bool = true) -> void:
|
||||||
|
GameGlobals.spawn_index = spawn_index
|
||||||
|
|
||||||
|
if do_autosave:
|
||||||
|
SaveManager.save_game()
|
||||||
|
|
||||||
|
|
||||||
|
static func get_spawn_point_by_index(index: int) -> PlayerSpawnPoint:
|
||||||
|
for spawn_point: PlayerSpawnPoint in PlayerSpawnPoint.spawn_points:
|
||||||
|
if spawn_point.spawn_index == index:
|
||||||
|
return spawn_point
|
||||||
|
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
func _get_configuration_warnings() -> PackedStringArray:
|
||||||
|
var warnings: PackedStringArray = []
|
||||||
|
|
||||||
|
for spawn_point: PlayerSpawnPoint in spawn_points:
|
||||||
|
if spawn_point.spawn_index == spawn_index and spawn_point != self:
|
||||||
|
warnings.append(str(spawn_point, " has the same spawn index as us."))
|
||||||
|
spawn_point.config_warnings_hint.show()
|
||||||
|
|
||||||
|
spawn_point.update_configuration_warnings()
|
||||||
|
|
||||||
|
if warnings.is_empty():
|
||||||
|
config_warnings_hint.hide()
|
||||||
|
|
||||||
|
return warnings
|
||||||
|
|||||||
@ -5,6 +5,10 @@ extends Node3D
|
|||||||
@onready var saw_skin: Node3D = $SawSkin
|
@onready var saw_skin: Node3D = $SawSkin
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
saw_skin.rotation.z = randf() * TAU
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
saw_skin.rotate_z(spin_speed * delta)
|
saw_skin.rotate_z(spin_speed * delta)
|
||||||
|
|||||||
@ -3,5 +3,15 @@ extends Control
|
|||||||
@onready var shader_precompiler: Node = $ShaderPrecompiler
|
@onready var shader_precompiler: Node = $ShaderPrecompiler
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
if SettingsManager.get_setting(&"game", &"has_compiled_shaders"):
|
||||||
|
shader_precompiler.canvas_layer.hide()
|
||||||
|
_on_shader_precompiler_finished_compilation()
|
||||||
|
else:
|
||||||
|
await get_tree().create_timer(1.0).timeout
|
||||||
|
shader_precompiler.precompile_shaders()
|
||||||
|
|
||||||
|
|
||||||
func _on_shader_precompiler_finished_compilation() -> void:
|
func _on_shader_precompiler_finished_compilation() -> void:
|
||||||
get_tree().quit()
|
SettingsManager.set_setting(&"game", &"has_compiled_shaders", true)
|
||||||
|
SceneFader.load_to_path(GameGlobals.MAIN_MENU_PATH)
|
||||||
|
|||||||
@ -4,18 +4,13 @@ signal finished_compilation
|
|||||||
|
|
||||||
const EXCLUDED_DIRECTORIES: Array[String] = [
|
const EXCLUDED_DIRECTORIES: Array[String] = [
|
||||||
"res://addons",
|
"res://addons",
|
||||||
"res://.godot"
|
"res://.godot",
|
||||||
]
|
]
|
||||||
|
|
||||||
#const SIMUTANEOUS_SCENES: int = 5
|
#const SIMUTANEOUS_SCENES: int = 5
|
||||||
|
|
||||||
@onready var progress_bar: ProgressBar = %ProgressBar
|
@onready var progress_bar: ProgressBar = %ProgressBar
|
||||||
|
@onready var canvas_layer: CanvasLayer = $CanvasLayer
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
|
||||||
func _ready() -> void:
|
|
||||||
await get_tree().create_timer(1.0).timeout
|
|
||||||
precompile_shaders()
|
|
||||||
|
|
||||||
|
|
||||||
func precompile_shaders() -> void:
|
func precompile_shaders() -> void:
|
||||||
|
|||||||
19
source/components/ui/menus/loading_screen/loading_screen.gd
Normal file
19
source/components/ui/menus/loading_screen/loading_screen.gd
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
class_name LoadingScreen
|
||||||
|
extends MenuBase
|
||||||
|
|
||||||
|
var _interactive_loader: InteractiveLoader
|
||||||
|
|
||||||
|
@onready var progress_bar: ProgressBar = %ProgressBar
|
||||||
|
|
||||||
|
|
||||||
|
func _process(_delta: float) -> void:
|
||||||
|
if is_instance_valid(_interactive_loader) and not _interactive_loader.load_progress.is_empty():
|
||||||
|
progress_bar.value = _interactive_loader.load_progress.front()
|
||||||
|
|
||||||
|
|
||||||
|
func load_scene(path: String) -> PackedScene:
|
||||||
|
_interactive_loader = InteractiveLoader.new()
|
||||||
|
add_child(_interactive_loader)
|
||||||
|
var resource: Object = await _interactive_loader.load_threaded(path)
|
||||||
|
_interactive_loader.queue_free()
|
||||||
|
return resource
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://tmo4wscguj62
|
||||||
@ -0,0 +1,30 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://buvus4ym83wa8"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://tmo4wscguj62" path="res://components/ui/menus/loading_screen/loading_screen.gd" id="1_1gk3q"]
|
||||||
|
|
||||||
|
[node name="LoadingScreen" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_1gk3q")
|
||||||
|
metadata/_custom_type_script = "uid://crdgxvb8i0cif"
|
||||||
|
|
||||||
|
[node name="ProgressBar" type="ProgressBar" parent="."]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
custom_minimum_size = Vector2(512, 0)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -2.0
|
||||||
|
offset_top = -13.5
|
||||||
|
offset_right = 2.0
|
||||||
|
offset_bottom = 13.5
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
max_value = 1.0
|
||||||
@ -1,10 +1,61 @@
|
|||||||
extends MenuBase
|
class_name MainMenu
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const AMBIENCE_STREAM: AudioStream = preload("res://Dark House.wav")
|
||||||
|
|
||||||
|
@onready var continue_button: Button = %ContinueButton
|
||||||
|
@onready var new_game_button: Button = %NewGameButton
|
||||||
|
@onready var quit_button: Button = %QuitButton
|
||||||
|
@onready var options_menu: Control = $OptionsMenu
|
||||||
|
@onready var main_menu_ui: Control = $MainMenuUI
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
continue_button.disabled = not SaveManager.save_exists()
|
||||||
|
|
||||||
func _on_play_button_pressed() -> void:
|
AudioManager.play_audio(AMBIENCE_STREAM, AudioManager.MUSIC)
|
||||||
pass # Replace with function body.
|
|
||||||
|
|
||||||
|
func _unhandled_input(event: InputEvent) -> void:
|
||||||
|
if options_menu.is_visible_in_tree() and event.is_action_pressed(&"pause"):
|
||||||
|
main_menu_ui.show()
|
||||||
|
options_menu.hide()
|
||||||
|
|
||||||
|
|
||||||
|
func load_game() -> void:
|
||||||
|
AudioManager.fade_audio(AMBIENCE_STREAM, -80.0, SceneFader.fade_in_duration, AudioManager.MUSIC, true)
|
||||||
|
SceneFader.load_to_path(GameGlobals.GAME_PATH)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_new_game_button_pressed() -> void:
|
||||||
|
if SceneFader.is_fading:
|
||||||
|
return
|
||||||
|
|
||||||
|
GameGlobals.reset_game()
|
||||||
|
SaveManager.delete_save()
|
||||||
|
SaveManager.save_game()
|
||||||
|
load_game()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_continue_button_pressed() -> void:
|
||||||
|
if SceneFader.is_fading:
|
||||||
|
return
|
||||||
|
|
||||||
|
GameGlobals.reset_game()
|
||||||
|
SaveManager.load_game()
|
||||||
|
load_game()
|
||||||
|
|
||||||
|
|
||||||
func _on_quit_button_pressed() -> void:
|
func _on_quit_button_pressed() -> void:
|
||||||
|
if SceneFader.is_fading:
|
||||||
|
return
|
||||||
|
|
||||||
get_tree().quit()
|
get_tree().quit()
|
||||||
|
|
||||||
|
|
||||||
|
func _on_settings_button_pressed() -> void:
|
||||||
|
if SceneFader.is_fading:
|
||||||
|
return
|
||||||
|
|
||||||
|
main_menu_ui.hide()
|
||||||
|
options_menu.show()
|
||||||
|
|||||||
@ -1,27 +1,34 @@
|
|||||||
[gd_scene load_steps=2 format=3 uid="uid://dwd8wf02j2epn"]
|
[gd_scene load_steps=4 format=3 uid="uid://dwd8wf02j2epn"]
|
||||||
|
|
||||||
[ext_resource type="Script" uid="uid://bmsx3h2kunhb0" path="res://components/ui/menus/main_menu/main_menu.gd" id="1_6xfbl"]
|
[ext_resource type="Script" uid="uid://bmsx3h2kunhb0" path="res://components/ui/menus/main_menu/main_menu.gd" id="1_6xfbl"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://4s2nskkco0a2" path="res://components/ui/menus/options_menu/options_menu.tscn" id="2_i2wwg"]
|
||||||
|
|
||||||
[node name="MainMenu" type="Control"]
|
[sub_resource type="Environment" id="Environment_6xfbl"]
|
||||||
|
ambient_light_source = 2
|
||||||
|
ambient_light_color = Color(0.177136, 0.177136, 0.177136, 1)
|
||||||
|
|
||||||
|
[node name="MainMenu" type="Node"]
|
||||||
|
script = ExtResource("1_6xfbl")
|
||||||
|
|
||||||
|
[node name="MainMenuUI" type="Control" parent="."]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
anchor_bottom = 1.0
|
anchor_bottom = 1.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
script = ExtResource("1_6xfbl")
|
|
||||||
|
|
||||||
[node name="Label" type="Label" parent="."]
|
[node name="TitleLabel" type="Label" parent="MainMenuUI"]
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 10
|
anchors_preset = 10
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
offset_bottom = 23.0
|
offset_bottom = 88.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
theme_override_font_sizes/font_size = 64
|
theme_override_font_sizes/font_size = 64
|
||||||
text = "Untitled Maskot Horror Game"
|
text = "Magic N' Stuff"
|
||||||
horizontal_alignment = 1
|
horizontal_alignment = 1
|
||||||
|
|
||||||
[node name="ButtonContainer" type="VBoxContainer" parent="."]
|
[node name="ButtonContainer" type="VBoxContainer" parent="MainMenuUI"]
|
||||||
custom_minimum_size = Vector2(128, 0)
|
custom_minimum_size = Vector2(128, 0)
|
||||||
layout_mode = 1
|
layout_mode = 1
|
||||||
anchors_preset = 8
|
anchors_preset = 8
|
||||||
@ -29,21 +36,64 @@ anchor_left = 0.5
|
|||||||
anchor_top = 0.5
|
anchor_top = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
anchor_bottom = 0.5
|
anchor_bottom = 0.5
|
||||||
offset_left = -21.0
|
offset_left = -64.0
|
||||||
offset_top = -33.0
|
offset_top = -68.0
|
||||||
offset_right = 21.0
|
offset_right = 64.0
|
||||||
offset_bottom = 33.0
|
offset_bottom = 68.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
alignment = 1
|
alignment = 1
|
||||||
|
|
||||||
[node name="PlayButton" type="Button" parent="ButtonContainer"]
|
[node name="ContinueButton" type="Button" parent="MainMenuUI/ButtonContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Play"
|
text = "CONTINUE"
|
||||||
|
|
||||||
[node name="QuitButton" type="Button" parent="ButtonContainer"]
|
[node name="NewGameButton" type="Button" parent="MainMenuUI/ButtonContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Quit"
|
text = "NEW_GAME"
|
||||||
|
|
||||||
[connection signal="pressed" from="ButtonContainer/PlayButton" to="." method="_on_play_button_pressed"]
|
[node name="SettingsButton" type="Button" parent="MainMenuUI/ButtonContainer"]
|
||||||
[connection signal="pressed" from="ButtonContainer/QuitButton" to="." method="_on_quit_button_pressed"]
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "SETTINGS"
|
||||||
|
|
||||||
|
[node name="QuitButton" type="Button" parent="MainMenuUI/ButtonContainer"]
|
||||||
|
unique_name_in_owner = true
|
||||||
|
layout_mode = 2
|
||||||
|
text = "QUIT"
|
||||||
|
|
||||||
|
[node name="OptionsMenu" parent="." instance=ExtResource("2_i2wwg")]
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[node name="Background" type="Node3D" parent="."]
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="Background"]
|
||||||
|
environment = SubResource("Environment_6xfbl")
|
||||||
|
|
||||||
|
[node name="TVLight" type="OmniLight3D" parent="Background"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.6, -1)
|
||||||
|
light_energy = 0.135
|
||||||
|
omni_range = 3.0
|
||||||
|
omni_attenuation = 2.15
|
||||||
|
|
||||||
|
[node name="CSGGeometry" type="CSGCombiner3D" parent="Background"]
|
||||||
|
|
||||||
|
[node name="CSGBox3D" type="CSGBox3D" parent="Background/CSGGeometry"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, 0)
|
||||||
|
size = Vector3(10, 4, 7)
|
||||||
|
|
||||||
|
[node name="CSGBox3D2" type="CSGBox3D" parent="Background/CSGGeometry/CSGBox3D"]
|
||||||
|
operation = 2
|
||||||
|
size = Vector3(9, 3, 6)
|
||||||
|
|
||||||
|
[node name="Camera3D" type="Camera3D" parent="Background"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 0.996195, -0.0871557, 0, 0.0871557, 0.996195, 0, 0.4, 1)
|
||||||
|
current = true
|
||||||
|
fov = 55.0
|
||||||
|
|
||||||
|
[connection signal="pressed" from="MainMenuUI/ButtonContainer/ContinueButton" to="." method="_on_continue_button_pressed"]
|
||||||
|
[connection signal="pressed" from="MainMenuUI/ButtonContainer/NewGameButton" to="." method="_on_new_game_button_pressed"]
|
||||||
|
[connection signal="pressed" from="MainMenuUI/ButtonContainer/SettingsButton" to="." method="_on_settings_button_pressed"]
|
||||||
|
[connection signal="pressed" from="MainMenuUI/ButtonContainer/QuitButton" to="." method="_on_quit_button_pressed"]
|
||||||
|
|||||||
@ -12,6 +12,7 @@ func open_menu(last_menu: MenuBase = previous_menu) -> void:
|
|||||||
|
|
||||||
if is_instance_valid(last_menu):
|
if is_instance_valid(last_menu):
|
||||||
previous_menu = last_menu
|
previous_menu = last_menu
|
||||||
|
last_menu.hide()
|
||||||
menu_opened.emit()
|
menu_opened.emit()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
10
source/components/ui/menus/menu_button_opener.gd
Normal file
10
source/components/ui/menus/menu_button_opener.gd
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
class_name MenuButtonOpener
|
||||||
|
extends Button
|
||||||
|
|
||||||
|
@export var open_menu: MenuBase
|
||||||
|
@export var previous_menu: MenuBase
|
||||||
|
|
||||||
|
|
||||||
|
func _pressed() -> void:
|
||||||
|
if is_instance_valid(open_menu):
|
||||||
|
open_menu.open_menu(previous_menu)
|
||||||
1
source/components/ui/menus/menu_button_opener.gd.uid
Normal file
1
source/components/ui/menus/menu_button_opener.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://dtgap28ru5dt0
|
||||||
@ -0,0 +1,10 @@
|
|||||||
|
extends CheckBox
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
button_pressed = SettingsManager.get_setting(&"video", &"fullscreen")
|
||||||
|
|
||||||
|
|
||||||
|
func _toggled(toggled_on: bool) -> void:
|
||||||
|
SettingsManager.set_fullscreen(toggled_on)
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://dlkewd0xr6ytq
|
||||||
@ -0,0 +1,40 @@
|
|||||||
|
class_name SliderLabel
|
||||||
|
extends Label
|
||||||
|
|
||||||
|
|
||||||
|
@export var slider: Slider: set = set_slider
|
||||||
|
@export var pad_zeros: int = 1
|
||||||
|
@export var pad_decimals: int = 2
|
||||||
|
@export var prefix: String = ""
|
||||||
|
@export var suffix: String = ""
|
||||||
|
@export_group("Remap Value")
|
||||||
|
@export var do_remap: bool = false
|
||||||
|
@export var remap_initial_min: float = 0.0
|
||||||
|
@export var remap_initial_max: float = 1.0
|
||||||
|
@export var remap_output_min: float = 0.0
|
||||||
|
@export var remap_output_max: float = 1.0
|
||||||
|
|
||||||
|
|
||||||
|
func set_slider(new_slider: Slider) -> void:
|
||||||
|
if new_slider == slider:
|
||||||
|
return
|
||||||
|
|
||||||
|
if is_instance_valid(slider):
|
||||||
|
slider.value_changed.disconnect(_on_value_changed)
|
||||||
|
|
||||||
|
if is_instance_valid(new_slider):
|
||||||
|
new_slider.value_changed.connect(_on_value_changed)
|
||||||
|
if not new_slider.is_node_ready():
|
||||||
|
await new_slider.ready
|
||||||
|
_on_value_changed(new_slider.get_value()) # Apply the value of the new slider.
|
||||||
|
|
||||||
|
slider = new_slider
|
||||||
|
|
||||||
|
|
||||||
|
func _on_value_changed(new_value: float) -> void:
|
||||||
|
var value: float = new_value
|
||||||
|
if do_remap:
|
||||||
|
value = remap(value, remap_initial_min, remap_initial_max, remap_output_min, remap_output_max)
|
||||||
|
|
||||||
|
var new_text: String = str(value).pad_zeros(pad_zeros).pad_decimals(pad_decimals)
|
||||||
|
set_text(str(prefix, new_text, suffix))
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://dg2s0gww8q6jh
|
||||||
@ -0,0 +1,51 @@
|
|||||||
|
class_name VolumeSlider
|
||||||
|
extends HSlider
|
||||||
|
|
||||||
|
|
||||||
|
## A normal slider that automatically changes the volume of the given [param bus] in
|
||||||
|
## the given [param bus_layout].
|
||||||
|
## This slider will automatically load and save it's value when it enters the tree
|
||||||
|
## or changes it's value.[br]
|
||||||
|
## INFO: You don't need to change [param min_value] and [param max_value], the calculations
|
||||||
|
## towards [param volume_db] are automatically being done.
|
||||||
|
|
||||||
|
## The bus that get's it's volume changed.
|
||||||
|
@export var bus: StringName = &"Master"
|
||||||
|
@export var auto_set_muted: bool = false
|
||||||
|
@export var min_volume: float = 0.0
|
||||||
|
@export var max_volume: float = 1.0
|
||||||
|
@export var default_volume: float = 1.0
|
||||||
|
## The audio bus layout that get's affected.
|
||||||
|
#@export var bus_layout: AudioBusLayout = preload("res://resources/default_bus_layout.tres")
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
value_changed.connect(func(_value_changed: bool) -> void:
|
||||||
|
SettingsManager.set_setting(&"audio", bus, remap(value, min_value, max_value, 0.0, 1.0), true)
|
||||||
|
)
|
||||||
|
|
||||||
|
if not value_changed.is_connected(set_volume):
|
||||||
|
value_changed.connect(set_volume)
|
||||||
|
|
||||||
|
var err: float = SettingsManager.get_setting(&"audio", bus)
|
||||||
|
|
||||||
|
var new_value: float = remap(err, 0.0, 1.0, min_value, max_value)
|
||||||
|
set_value_no_signal(new_value)
|
||||||
|
set_volume(new_value)
|
||||||
|
value_changed.emit(value)
|
||||||
|
|
||||||
|
|
||||||
|
## Set's the volume on the audio bus given by [param bus] to the volume_range (Range from 0 to 100).[br]
|
||||||
|
## Note that this won't change [param value].
|
||||||
|
func set_volume(volume_range: float) -> void:
|
||||||
|
volume_range = remap(volume_range, min_value, max_value, min_volume, max_volume)
|
||||||
|
var new_volume: float = linear_to_db(volume_range)
|
||||||
|
var bus_idx: int = AudioServer.get_bus_index(bus)
|
||||||
|
|
||||||
|
AudioServer.set_bus_volume_db(bus_idx, new_volume)
|
||||||
|
if auto_set_muted:
|
||||||
|
AudioServer.set_bus_mute(bus_idx, is_zero_approx(volume_range))
|
||||||
|
|
||||||
|
|
||||||
|
#func save_volume(volume_range: float) -> void:
|
||||||
|
#OptionSaver.save_option("audio", bus, (volume_range / max_value))
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://d2j5jmj08o7f5
|
||||||
2
source/components/ui/menus/options_menu/options_menu.gd
Normal file
2
source/components/ui/menus/options_menu/options_menu.gd
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
class_name OptionsMenu
|
||||||
|
extends Control
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://dl8uyh4kcvgl4
|
||||||
177
source/components/ui/menus/options_menu/options_menu.tscn
Normal file
177
source/components/ui/menus/options_menu/options_menu.tscn
Normal file
@ -0,0 +1,177 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://4s2nskkco0a2"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://dg2s0gww8q6jh" path="res://components/ui/menus/options_menu/elements/slider_label.gd" id="2_gjkvu"]
|
||||||
|
[ext_resource type="Script" uid="uid://d2j5jmj08o7f5" path="res://components/ui/menus/options_menu/elements/volume_slider.gd" id="2_hj0r6"]
|
||||||
|
[ext_resource type="Script" uid="uid://dlkewd0xr6ytq" path="res://components/ui/menus/options_menu/elements/fullscreen_button.gd" id="3_hj0r6"]
|
||||||
|
|
||||||
|
[node name="OptionsMenu" type="Control"]
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="TabContainer" type="TabContainer" parent="."]
|
||||||
|
custom_minimum_size = Vector2(256, 256)
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
tab_alignment = 1
|
||||||
|
current_tab = 0
|
||||||
|
|
||||||
|
[node name="Audio" type="Control" parent="TabContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
metadata/_tab_index = 0
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="TabContainer/Audio"]
|
||||||
|
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 = 4
|
||||||
|
theme_override_constants/margin_top = 4
|
||||||
|
theme_override_constants/margin_right = 4
|
||||||
|
theme_override_constants/margin_bottom = 4
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Audio/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="MasterLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Master"
|
||||||
|
|
||||||
|
[node name="MasterContainer" type="HBoxContainer" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="VolumeSlider" type="HSlider" parent="TabContainer/Audio/MarginContainer/VBoxContainer/MasterContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
value = 100.0
|
||||||
|
tick_count = 10
|
||||||
|
ticks_on_borders = true
|
||||||
|
script = ExtResource("2_hj0r6")
|
||||||
|
metadata/_custom_type_script = "uid://d2j5jmj08o7f5"
|
||||||
|
|
||||||
|
[node name="SliderLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer/MasterContainer" node_paths=PackedStringArray("slider")]
|
||||||
|
custom_minimum_size = Vector2(30, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "1.0"
|
||||||
|
script = ExtResource("2_gjkvu")
|
||||||
|
slider = NodePath("../VolumeSlider")
|
||||||
|
pad_decimals = 0
|
||||||
|
metadata/_custom_type_script = "uid://dg2s0gww8q6jh"
|
||||||
|
|
||||||
|
[node name="SFXLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "SFX"
|
||||||
|
|
||||||
|
[node name="SFXContainer" type="HBoxContainer" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="VolumeSlider" type="HSlider" parent="TabContainer/Audio/MarginContainer/VBoxContainer/SFXContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
value = 100.0
|
||||||
|
tick_count = 10
|
||||||
|
ticks_on_borders = true
|
||||||
|
script = ExtResource("2_hj0r6")
|
||||||
|
bus = &"SFX"
|
||||||
|
metadata/_custom_type_script = "uid://d2j5jmj08o7f5"
|
||||||
|
|
||||||
|
[node name="SliderLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer/SFXContainer" node_paths=PackedStringArray("slider")]
|
||||||
|
custom_minimum_size = Vector2(30, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "1.0"
|
||||||
|
script = ExtResource("2_gjkvu")
|
||||||
|
slider = NodePath("../VolumeSlider")
|
||||||
|
pad_decimals = 0
|
||||||
|
metadata/_custom_type_script = "uid://dg2s0gww8q6jh"
|
||||||
|
|
||||||
|
[node name="MusicLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Music"
|
||||||
|
|
||||||
|
[node name="MusicContainer" type="HBoxContainer" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="VolumeSlider" type="HSlider" parent="TabContainer/Audio/MarginContainer/VBoxContainer/MusicContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
value = 100.0
|
||||||
|
tick_count = 10
|
||||||
|
ticks_on_borders = true
|
||||||
|
script = ExtResource("2_hj0r6")
|
||||||
|
bus = &"Music"
|
||||||
|
metadata/_custom_type_script = "uid://d2j5jmj08o7f5"
|
||||||
|
|
||||||
|
[node name="SliderLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer/MusicContainer" node_paths=PackedStringArray("slider")]
|
||||||
|
custom_minimum_size = Vector2(30, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "1.0"
|
||||||
|
script = ExtResource("2_gjkvu")
|
||||||
|
slider = NodePath("../VolumeSlider")
|
||||||
|
pad_decimals = 0
|
||||||
|
metadata/_custom_type_script = "uid://dg2s0gww8q6jh"
|
||||||
|
|
||||||
|
[node name="AmbientLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Ambient"
|
||||||
|
|
||||||
|
[node name="AmbientContainer" type="HBoxContainer" parent="TabContainer/Audio/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="VolumeSlider" type="HSlider" parent="TabContainer/Audio/MarginContainer/VBoxContainer/AmbientContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
value = 100.0
|
||||||
|
tick_count = 10
|
||||||
|
ticks_on_borders = true
|
||||||
|
script = ExtResource("2_hj0r6")
|
||||||
|
bus = &"Ambient"
|
||||||
|
metadata/_custom_type_script = "uid://d2j5jmj08o7f5"
|
||||||
|
|
||||||
|
[node name="SliderLabel" type="Label" parent="TabContainer/Audio/MarginContainer/VBoxContainer/AmbientContainer" node_paths=PackedStringArray("slider")]
|
||||||
|
custom_minimum_size = Vector2(30, 0)
|
||||||
|
layout_mode = 2
|
||||||
|
text = "1.0"
|
||||||
|
script = ExtResource("2_gjkvu")
|
||||||
|
slider = NodePath("../VolumeSlider")
|
||||||
|
pad_decimals = 0
|
||||||
|
metadata/_custom_type_script = "uid://dg2s0gww8q6jh"
|
||||||
|
|
||||||
|
[node name="Graphics" type="Control" parent="TabContainer"]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 2
|
||||||
|
metadata/_tab_index = 1
|
||||||
|
|
||||||
|
[node name="MarginContainer" type="MarginContainer" parent="TabContainer/Graphics"]
|
||||||
|
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 = 4
|
||||||
|
theme_override_constants/margin_top = 4
|
||||||
|
theme_override_constants/margin_right = 4
|
||||||
|
theme_override_constants/margin_bottom = 4
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="TabContainer/Graphics/MarginContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="FullscreenButton" type="CheckBox" parent="TabContainer/Graphics/MarginContainer/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Fullscreen"
|
||||||
|
script = ExtResource("3_hj0r6")
|
||||||
49
source/components/ui/menus/pause_menu/pause_menu.gd
Normal file
49
source/components/ui/menus/pause_menu/pause_menu.gd
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
class_name PauseMenu
|
||||||
|
extends Node
|
||||||
|
|
||||||
|
const ACTION_PAUSE: StringName = &"pause"
|
||||||
|
|
||||||
|
var can_pause: bool = true
|
||||||
|
|
||||||
|
@onready var pause_menu: MenuBase = $PauseMenu
|
||||||
|
@onready var options_menu: Control = $OptionsMenu
|
||||||
|
|
||||||
|
|
||||||
|
func _input(event: InputEvent) -> void:
|
||||||
|
if event.is_action_pressed(ACTION_PAUSE):
|
||||||
|
if options_menu.is_visible_in_tree():
|
||||||
|
options_menu.hide()
|
||||||
|
pause_menu.show()
|
||||||
|
else:
|
||||||
|
toggle_pause()
|
||||||
|
|
||||||
|
|
||||||
|
func set_paused(value: bool) -> void:
|
||||||
|
if SceneFader.is_fading:
|
||||||
|
return
|
||||||
|
|
||||||
|
get_tree().paused = value
|
||||||
|
pause_menu.visible = value
|
||||||
|
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE if value else Input.MOUSE_MODE_CAPTURED
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_pause() -> void:
|
||||||
|
if not can_pause or options_menu.is_visible():
|
||||||
|
return
|
||||||
|
|
||||||
|
set_paused(not get_tree().paused)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_continue_button_pressed() -> void:
|
||||||
|
set_paused(false)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_main_menu_button_pressed() -> void:
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
|
||||||
|
await SceneFader.load_to_path(GameGlobals.MAIN_MENU_PATH, true)
|
||||||
|
|
||||||
|
|
||||||
|
func _on_settings_button_pressed() -> void:
|
||||||
|
pause_menu.hide()
|
||||||
|
options_menu.show()
|
||||||
1
source/components/ui/menus/pause_menu/pause_menu.gd.uid
Normal file
1
source/components/ui/menus/pause_menu/pause_menu.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://cx3lpgmhrra8v
|
||||||
63
source/components/ui/menus/pause_menu/pause_menu.tscn
Normal file
63
source/components/ui/menus/pause_menu/pause_menu.tscn
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
[gd_scene load_steps=4 format=3 uid="uid://dawmen0hlfaaq"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cx3lpgmhrra8v" path="res://components/ui/menus/pause_menu/pause_menu.gd" id="1_43sid"]
|
||||||
|
[ext_resource type="Script" uid="uid://crdgxvb8i0cif" path="res://components/ui/menus/menu_base.gd" id="1_hcnxh"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://4s2nskkco0a2" path="res://components/ui/menus/options_menu/options_menu.tscn" id="3_hcnxh"]
|
||||||
|
|
||||||
|
[node name="PauseMenu" type="Node"]
|
||||||
|
process_mode = 3
|
||||||
|
script = ExtResource("1_43sid")
|
||||||
|
|
||||||
|
[node name="PauseMenu" type="Control" parent="."]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 3
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_hcnxh")
|
||||||
|
metadata/_custom_type_script = "uid://crdgxvb8i0cif"
|
||||||
|
|
||||||
|
[node name="Label" type="Label" parent="PauseMenu"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 10
|
||||||
|
anchor_right = 1.0
|
||||||
|
offset_bottom = 23.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
theme_override_font_sizes/font_size = 128
|
||||||
|
text = "Paused"
|
||||||
|
horizontal_alignment = 1
|
||||||
|
|
||||||
|
[node name="VBoxContainer" type="VBoxContainer" parent="PauseMenu"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 8
|
||||||
|
anchor_left = 0.5
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 0.5
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -20.0
|
||||||
|
offset_top = -20.0
|
||||||
|
offset_right = 20.0
|
||||||
|
offset_bottom = 20.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
|
||||||
|
[node name="ContinueButton" type="Button" parent="PauseMenu/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Continue"
|
||||||
|
|
||||||
|
[node name="SettingsButton" type="Button" parent="PauseMenu/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Settings"
|
||||||
|
|
||||||
|
[node name="MainMenuButton" type="Button" parent="PauseMenu/VBoxContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Main Menu"
|
||||||
|
|
||||||
|
[node name="OptionsMenu" parent="." instance=ExtResource("3_hcnxh")]
|
||||||
|
visible = false
|
||||||
|
|
||||||
|
[connection signal="pressed" from="PauseMenu/VBoxContainer/ContinueButton" to="." method="_on_continue_button_pressed"]
|
||||||
|
[connection signal="pressed" from="PauseMenu/VBoxContainer/SettingsButton" to="." method="_on_settings_button_pressed"]
|
||||||
|
[connection signal="pressed" from="PauseMenu/VBoxContainer/MainMenuButton" to="." method="_on_main_menu_button_pressed"]
|
||||||
8
source/game.gd
Normal file
8
source/game.gd
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
|
||||||
|
# Called when the node enters the scene tree for the first time.
|
||||||
|
func _ready() -> void:
|
||||||
|
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
|
||||||
|
|
||||||
|
AudioManager.play_audio(preload("res://Dark House.wav"), AudioManager.AMBIENCE)
|
||||||
1
source/game.gd.uid
Normal file
1
source/game.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://dbsjg3o61vuji
|
||||||
83
source/game.tscn
Normal file
83
source/game.tscn
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
[gd_scene load_steps=7 format=3 uid="uid://s7cw6ulb7kh7"]
|
||||||
|
|
||||||
|
[ext_resource type="PackedScene" uid="uid://clhy3kiceqf2o" path="res://components/characters/player/player_character.tscn" id="1_80nbo"]
|
||||||
|
[ext_resource type="Script" uid="uid://dbsjg3o61vuji" path="res://game.gd" id="1_fc0e3"]
|
||||||
|
[ext_resource type="Environment" uid="uid://xe70va0pjc6c" path="res://resources/game_environment.tres" id="2_7jktm"]
|
||||||
|
[ext_resource type="Script" uid="uid://3hlvt5k34xva" path="res://components/general/player_spawn_point.gd" id="2_e2o6t"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://dawmen0hlfaaq" path="res://components/ui/menus/pause_menu/pause_menu.tscn" id="3_feb5d"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://c0jearfhlqcvr" path="res://components/hazards/saw/saw.tscn" id="5_ryrav"]
|
||||||
|
|
||||||
|
[node name="Game" type="Node"]
|
||||||
|
script = ExtResource("1_fc0e3")
|
||||||
|
|
||||||
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
|
environment = ExtResource("2_7jktm")
|
||||||
|
|
||||||
|
[node name="PlayerCharacter" parent="." instance=ExtResource("1_80nbo")]
|
||||||
|
|
||||||
|
[node name="Menus" type="CanvasLayer" parent="."]
|
||||||
|
|
||||||
|
[node name="PauseMenu" parent="Menus" instance=ExtResource("3_feb5d")]
|
||||||
|
|
||||||
|
[node name="Areas" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="IntroArea" type="Node3D" parent="Areas"]
|
||||||
|
|
||||||
|
[node name="Blockout" type="CSGCombiner3D" parent="Areas/IntroArea"]
|
||||||
|
use_collision = true
|
||||||
|
|
||||||
|
[node name="CSGBox3D" type="CSGBox3D" parent="Areas/IntroArea/Blockout"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.5, -4.5)
|
||||||
|
size = Vector3(5, 4, 12)
|
||||||
|
|
||||||
|
[node name="CSGBox3D3" type="CSGBox3D" parent="Areas/IntroArea/Blockout/CSGBox3D"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -0.5)
|
||||||
|
operation = 2
|
||||||
|
size = Vector3(4, 3, 12)
|
||||||
|
|
||||||
|
[node name="CSGBox3D2" type="CSGBox3D" parent="Areas/IntroArea/Blockout"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 7, -22)
|
||||||
|
size = Vector3(32, 15, 27)
|
||||||
|
|
||||||
|
[node name="CSGBox3D3" type="CSGBox3D" parent="Areas/IntroArea/Blockout/CSGBox3D2"]
|
||||||
|
operation = 2
|
||||||
|
size = Vector3(31, 14, 25)
|
||||||
|
|
||||||
|
[node name="CSGBox3D4" type="CSGBox3D" parent="Areas/IntroArea/Blockout/CSGBox3D2"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -5.5, 12.25)
|
||||||
|
operation = 2
|
||||||
|
size = Vector3(4, 3, 2.5)
|
||||||
|
|
||||||
|
[node name="OmniLight3D" type="OmniLight3D" parent="Areas/IntroArea"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 6, -24)
|
||||||
|
omni_range = 20.0
|
||||||
|
|
||||||
|
[node name="Saw" parent="Areas/IntroArea" instance=ExtResource("5_ryrav")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0, 0.5, -25)
|
||||||
|
|
||||||
|
[node name="Saw2" parent="Areas/IntroArea" instance=ExtResource("5_ryrav")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.2, 0.5, -25)
|
||||||
|
|
||||||
|
[node name="Saw3" parent="Areas/IntroArea" instance=ExtResource("5_ryrav")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.4, 0.5, -25)
|
||||||
|
|
||||||
|
[node name="Saw4" parent="Areas/IntroArea" instance=ExtResource("5_ryrav")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.6, 0.5, -25)
|
||||||
|
|
||||||
|
[node name="Saw5" parent="Areas/IntroArea" instance=ExtResource("5_ryrav")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 0.8, 0.5, -25)
|
||||||
|
|
||||||
|
[node name="Saw6" parent="Areas/IntroArea" instance=ExtResource("5_ryrav")]
|
||||||
|
transform = Transform3D(-4.37114e-08, 0, 1, 0, 1, 0, -1, 0, -4.37114e-08, 1, 0.5, -25)
|
||||||
|
|
||||||
|
[node name="SpawnPoints" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="PlayerSpawnPoint" type="Marker3D" parent="SpawnPoints"]
|
||||||
|
script = ExtResource("2_e2o6t")
|
||||||
|
metadata/_custom_type_script = "uid://3hlvt5k34xva"
|
||||||
|
|
||||||
|
[node name="PlayerSpawnPoint2" type="Marker3D" parent="SpawnPoints"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, -15)
|
||||||
|
script = ExtResource("2_e2o6t")
|
||||||
|
spawn_index = 1
|
||||||
|
metadata/_custom_type_script = "uid://3hlvt5k34xva"
|
||||||
67
source/globals/autoloads/audio/audio_manager.gd
Normal file
67
source/globals/autoloads/audio/audio_manager.gd
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
const MASTER: StringName = &"Master"
|
||||||
|
const MUSIC: StringName = &"Music"
|
||||||
|
const SFX: StringName = &"SFX"
|
||||||
|
const AMBIENCE: StringName = &"Ambient"
|
||||||
|
|
||||||
|
|
||||||
|
func play_audio(stream: AudioStream, bus: StringName, force_restart: bool = false) -> void:
|
||||||
|
if is_playing_audio(stream, bus):
|
||||||
|
if force_restart:
|
||||||
|
var existing_player: AudioStreamPlayer = get_audio_player_for_stream(stream, bus)
|
||||||
|
existing_player.stop()
|
||||||
|
existing_player.play()
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
|
var player: AudioStreamPlayer = _create_audio_player(stream, bus)
|
||||||
|
player.finished.connect(stop_audio.bind(stream, bus))
|
||||||
|
|
||||||
|
add_child(player)
|
||||||
|
player.play()
|
||||||
|
|
||||||
|
|
||||||
|
func stop_audio(stream: AudioStream, bus: StringName) -> void:
|
||||||
|
var player: AudioStreamPlayer = get_audio_player_for_stream(stream, bus)
|
||||||
|
|
||||||
|
if is_instance_valid(player):
|
||||||
|
player.queue_free()
|
||||||
|
|
||||||
|
|
||||||
|
func fade_audio(stream: AudioStream, volume_db: float, duration: float, bus: StringName, stop_on_finish: bool = false) -> void:
|
||||||
|
var player: AudioStreamPlayer = get_audio_player_for_stream(stream, bus)
|
||||||
|
|
||||||
|
if not is_instance_valid(player):
|
||||||
|
return
|
||||||
|
|
||||||
|
var tween: Tween = create_tween()
|
||||||
|
tween.tween_property(player, ^"volume_db", volume_db, duration)
|
||||||
|
|
||||||
|
await tween.finished
|
||||||
|
|
||||||
|
if stop_on_finish and is_instance_valid(player):
|
||||||
|
stop_audio(stream, bus)
|
||||||
|
|
||||||
|
|
||||||
|
func fade_audio_linear(stream: AudioStream, volume_linear: float, bus: StringName, duration: float, stop_on_finish: bool = false) -> void:
|
||||||
|
await fade_audio(stream, linear_to_db(volume_linear), duration, bus, stop_on_finish)
|
||||||
|
|
||||||
|
|
||||||
|
func get_audio_player_for_stream(stream: AudioStream, bus: StringName) -> AudioStreamPlayer:
|
||||||
|
for player: AudioStreamPlayer in get_children():
|
||||||
|
if player.stream == stream and player.bus == bus:
|
||||||
|
return player
|
||||||
|
|
||||||
|
return null
|
||||||
|
|
||||||
|
|
||||||
|
func is_playing_audio(stream: AudioStream, bus: StringName) -> bool:
|
||||||
|
return is_instance_valid(get_audio_player_for_stream(stream, bus))
|
||||||
|
|
||||||
|
|
||||||
|
func _create_audio_player(stream: AudioStream, bus: StringName) -> AudioStreamPlayer:
|
||||||
|
var player := AudioStreamPlayer.new()
|
||||||
|
player.bus = bus
|
||||||
|
player.stream = stream
|
||||||
|
return player
|
||||||
1
source/globals/autoloads/audio/audio_manager.gd.uid
Normal file
1
source/globals/autoloads/audio/audio_manager.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://chwfg6slvsay8
|
||||||
6
source/globals/autoloads/audio/audio_manager.tscn
Normal file
6
source/globals/autoloads/audio/audio_manager.tscn
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
[gd_scene load_steps=2 format=3 uid="uid://diduaxhewgjwa"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://chwfg6slvsay8" path="res://globals/autoloads/audio/audio_manager.gd" id="1_pjc45"]
|
||||||
|
|
||||||
|
[node name="AudioManager" type="Node"]
|
||||||
|
script = ExtResource("1_pjc45")
|
||||||
@ -1,8 +1,19 @@
|
|||||||
extends Node
|
extends Node
|
||||||
|
|
||||||
|
const MAIN_MENU_PATH: String = "res://components/ui/menus/main_menu/main_menu.tscn"
|
||||||
|
const GAME_PATH: String = "res://game.tscn"
|
||||||
|
|
||||||
var player: PlayerCharacter
|
var player: PlayerCharacter
|
||||||
|
var spawn_index: int = 0
|
||||||
|
|
||||||
|
|
||||||
func get_player() -> PlayerCharacter:
|
func get_player() -> PlayerCharacter:
|
||||||
return player
|
return player
|
||||||
|
|
||||||
|
|
||||||
|
func reset_game() -> void:
|
||||||
|
spawn_index = 0
|
||||||
|
|
||||||
|
|
||||||
|
func set_spawn_index(index: int) -> void:
|
||||||
|
spawn_index = index
|
||||||
|
|||||||
@ -18,8 +18,12 @@ func _input(event: InputEvent) -> void:
|
|||||||
using_controller = true
|
using_controller = true
|
||||||
|
|
||||||
if event.is_action_pressed(TOGGLE_MOUSE_BUTTON):
|
if event.is_action_pressed(TOGGLE_MOUSE_BUTTON):
|
||||||
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE else Input.MOUSE_MODE_VISIBLE)
|
toggle_mouse()
|
||||||
|
|
||||||
|
|
||||||
func window_focused() -> bool:
|
func window_focused() -> bool:
|
||||||
return DisplayServer.window_is_focused()
|
return DisplayServer.window_is_focused()
|
||||||
|
|
||||||
|
|
||||||
|
func toggle_mouse() -> void:
|
||||||
|
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED if Input.mouse_mode == Input.MOUSE_MODE_VISIBLE else Input.MOUSE_MODE_VISIBLE)
|
||||||
|
|||||||
32
source/globals/autoloads/save_manager.gd
Normal file
32
source/globals/autoloads/save_manager.gd
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
const SAVE_PATH: String = "user://saves/"
|
||||||
|
const SAVE_FILENAME: String = "saved_game.dat"
|
||||||
|
|
||||||
|
func save_game() -> void:
|
||||||
|
DirAccess.make_dir_recursive_absolute(SAVE_PATH)
|
||||||
|
|
||||||
|
var file := FileAccess.open(str(SAVE_PATH, SAVE_FILENAME), FileAccess.WRITE)
|
||||||
|
|
||||||
|
# Store the variables.
|
||||||
|
file.store_var(GameGlobals.spawn_index)
|
||||||
|
|
||||||
|
|
||||||
|
func load_game() -> bool:
|
||||||
|
if not save_exists():
|
||||||
|
return false
|
||||||
|
|
||||||
|
var file := FileAccess.open(str(SAVE_PATH, SAVE_FILENAME), FileAccess.READ)
|
||||||
|
|
||||||
|
# Load the variables.
|
||||||
|
GameGlobals.spawn_index = file.get_var()
|
||||||
|
|
||||||
|
return true
|
||||||
|
|
||||||
|
|
||||||
|
func delete_save() -> void:
|
||||||
|
DirAccess.remove_absolute(str(SAVE_PATH, SAVE_FILENAME))
|
||||||
|
|
||||||
|
|
||||||
|
func save_exists() -> bool:
|
||||||
|
return FileAccess.file_exists(str(SAVE_PATH, SAVE_FILENAME))
|
||||||
1
source/globals/autoloads/save_manager.gd.uid
Normal file
1
source/globals/autoloads/save_manager.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://iadl2o6wkphx
|
||||||
67
source/globals/autoloads/scene_fader/scene_fader.gd
Normal file
67
source/globals/autoloads/scene_fader/scene_fader.gd
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
extends CanvasLayer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
var fade_in_duration: float = 2.0
|
||||||
|
var fade_out_duration: float = 2.0
|
||||||
|
var is_fading: bool = false
|
||||||
|
var is_loading: bool = false
|
||||||
|
|
||||||
|
|
||||||
|
@onready var interactive_loader: InteractiveLoader = $InteractiveLoader
|
||||||
|
@onready var color_rect: ColorRect = $ColorRect
|
||||||
|
@onready var loading_hint_animations: AnimationPlayer = $HintMargin/Control/LoadingHint/LoadingHintAnimations
|
||||||
|
@onready var loading_hint: TextureRect = $HintMargin/Control/LoadingHint
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
color_rect.hide()
|
||||||
|
|
||||||
|
|
||||||
|
func load_to_path(path: String, unpause_game: bool = false) -> void:
|
||||||
|
if is_loading:
|
||||||
|
return
|
||||||
|
|
||||||
|
is_loading = true
|
||||||
|
|
||||||
|
await fade_in()
|
||||||
|
|
||||||
|
var scene: PackedScene = await interactive_loader.load_threaded(path)
|
||||||
|
|
||||||
|
assert(is_instance_valid(scene))
|
||||||
|
|
||||||
|
get_tree().change_scene_to_packed(scene)
|
||||||
|
|
||||||
|
if unpause_game:
|
||||||
|
get_tree().paused = false
|
||||||
|
|
||||||
|
fade_out()
|
||||||
|
is_loading = false
|
||||||
|
|
||||||
|
|
||||||
|
func fade_in() -> void:
|
||||||
|
color_rect.show()
|
||||||
|
is_fading = true
|
||||||
|
|
||||||
|
var tween: Tween = create_tween()
|
||||||
|
tween.tween_property(color_rect, ^"color:a", 1.0, fade_in_duration)
|
||||||
|
await tween.finished
|
||||||
|
|
||||||
|
is_fading = false
|
||||||
|
|
||||||
|
loading_hint_animations.play(&"hover")
|
||||||
|
loading_hint.show()
|
||||||
|
|
||||||
|
|
||||||
|
func fade_out() -> void:
|
||||||
|
loading_hint_animations.stop()
|
||||||
|
loading_hint.hide()
|
||||||
|
|
||||||
|
is_fading = true
|
||||||
|
|
||||||
|
var tween: Tween = create_tween()
|
||||||
|
tween.tween_property(color_rect, ^"color:a", 0.0, fade_out_duration)
|
||||||
|
await tween.finished
|
||||||
|
|
||||||
|
color_rect.hide()
|
||||||
|
is_fading = false
|
||||||
1
source/globals/autoloads/scene_fader/scene_fader.gd.uid
Normal file
1
source/globals/autoloads/scene_fader/scene_fader.gd.uid
Normal file
@ -0,0 +1 @@
|
|||||||
|
uid://cynllcoh2smgv
|
||||||
125
source/globals/autoloads/scene_fader/scene_fader.tscn
Normal file
125
source/globals/autoloads/scene_fader/scene_fader.tscn
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
[gd_scene load_steps=7 format=3 uid="uid://dis4efdm5s2fc"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://cynllcoh2smgv" path="res://globals/autoloads/scene_fader/scene_fader.gd" id="1_7tt87"]
|
||||||
|
[ext_resource type="Script" uid="uid://d0k03wk1s7cw0" path="res://components/general/interactive_loader.gd" id="2_dwqb8"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://dhw8y2oqxvgwu" path="res://godot_icon.svg" id="3_dwqb8"]
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_t3447"]
|
||||||
|
length = 0.001
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath(".:rotation")
|
||||||
|
tracks/0/interp = 1
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [-0.261799]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath(".:position")
|
||||||
|
tracks/1/interp = 1
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0),
|
||||||
|
"transitions": PackedFloat32Array(1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector2(1112, 608)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="Animation" id="Animation_dwqb8"]
|
||||||
|
resource_name = "hover"
|
||||||
|
loop_mode = 1
|
||||||
|
tracks/0/type = "value"
|
||||||
|
tracks/0/imported = false
|
||||||
|
tracks/0/enabled = true
|
||||||
|
tracks/0/path = NodePath(".:rotation")
|
||||||
|
tracks/0/interp = 2
|
||||||
|
tracks/0/loop_wrap = true
|
||||||
|
tracks/0/keys = {
|
||||||
|
"times": PackedFloat32Array(0, 0.5),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [0.174533, -0.174533]
|
||||||
|
}
|
||||||
|
tracks/1/type = "value"
|
||||||
|
tracks/1/imported = false
|
||||||
|
tracks/1/enabled = true
|
||||||
|
tracks/1/path = NodePath(".:position")
|
||||||
|
tracks/1/interp = 2
|
||||||
|
tracks/1/loop_wrap = true
|
||||||
|
tracks/1/keys = {
|
||||||
|
"times": PackedFloat32Array(0.25, 0.75),
|
||||||
|
"transitions": PackedFloat32Array(1, 1),
|
||||||
|
"update": 0,
|
||||||
|
"values": [Vector2(0, 0), Vector2(0, 5)]
|
||||||
|
}
|
||||||
|
|
||||||
|
[sub_resource type="AnimationLibrary" id="AnimationLibrary_e571n"]
|
||||||
|
_data = {
|
||||||
|
&"RESET": SubResource("Animation_t3447"),
|
||||||
|
&"hover": SubResource("Animation_dwqb8")
|
||||||
|
}
|
||||||
|
|
||||||
|
[node name="SceneFader" type="CanvasLayer"]
|
||||||
|
process_mode = 3
|
||||||
|
layer = 10
|
||||||
|
script = ExtResource("1_7tt87")
|
||||||
|
|
||||||
|
[node name="InteractiveLoader" type="Node" parent="."]
|
||||||
|
script = ExtResource("2_dwqb8")
|
||||||
|
metadata/_custom_type_script = "uid://d0k03wk1s7cw0"
|
||||||
|
|
||||||
|
[node name="ColorRect" type="ColorRect" parent="."]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
color = Color(0, 0, 0, 1)
|
||||||
|
|
||||||
|
[node name="HintMargin" type="MarginContainer" parent="."]
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
mouse_filter = 2
|
||||||
|
theme_override_constants/margin_left = 16
|
||||||
|
theme_override_constants/margin_top = 16
|
||||||
|
theme_override_constants/margin_right = 16
|
||||||
|
theme_override_constants/margin_bottom = 16
|
||||||
|
|
||||||
|
[node name="Control" type="Control" parent="HintMargin"]
|
||||||
|
custom_minimum_size = Vector2(64, 64)
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 8
|
||||||
|
size_flags_vertical = 8
|
||||||
|
mouse_filter = 2
|
||||||
|
|
||||||
|
[node name="LoadingHint" type="TextureRect" parent="HintMargin/Control"]
|
||||||
|
layout_mode = 1
|
||||||
|
anchors_preset = 15
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 1.0
|
||||||
|
offset_left = 1112.0
|
||||||
|
offset_top = 608.0
|
||||||
|
offset_right = 1112.0
|
||||||
|
offset_bottom = 608.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
rotation = -0.261799
|
||||||
|
pivot_offset = Vector2(20, 32)
|
||||||
|
mouse_filter = 2
|
||||||
|
texture = ExtResource("3_dwqb8")
|
||||||
|
expand_mode = 5
|
||||||
|
|
||||||
|
[node name="LoadingHintAnimations" type="AnimationPlayer" parent="HintMargin/Control/LoadingHint"]
|
||||||
|
libraries = {
|
||||||
|
&"": SubResource("AnimationLibrary_e571n")
|
||||||
|
}
|
||||||
71
source/globals/autoloads/settings/settings_manager.gd
Normal file
71
source/globals/autoloads/settings/settings_manager.gd
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
extends Node
|
||||||
|
|
||||||
|
const SETTINGS_PATH: String = "user://settings.cfg"
|
||||||
|
|
||||||
|
var settings: Dictionary[String, Dictionary] = {
|
||||||
|
&"game": {
|
||||||
|
&"has_compiled_shaders": false,
|
||||||
|
},
|
||||||
|
&"audio": {
|
||||||
|
&"Master": 1.0,
|
||||||
|
&"SFX": 1.0,
|
||||||
|
&"Music": 1.0,
|
||||||
|
&"Ambient": 1.0,
|
||||||
|
},
|
||||||
|
&"video": {
|
||||||
|
&"fullscreen": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
func _ready() -> void:
|
||||||
|
load_settings()
|
||||||
|
|
||||||
|
|
||||||
|
func load_settings() -> void:
|
||||||
|
if not FileAccess.file_exists(SETTINGS_PATH):
|
||||||
|
save_settings()
|
||||||
|
return
|
||||||
|
|
||||||
|
var config := ConfigFile.new()
|
||||||
|
config.load(SETTINGS_PATH)
|
||||||
|
|
||||||
|
for section: String in settings.keys():
|
||||||
|
for key: String in settings[section].keys():
|
||||||
|
var default: Variant = get_setting(section, key)
|
||||||
|
set_setting(section, key, config.get_value(section, key, default), false)
|
||||||
|
|
||||||
|
|
||||||
|
func save_settings() -> void:
|
||||||
|
var config := ConfigFile.new()
|
||||||
|
|
||||||
|
for section: String in settings.keys():
|
||||||
|
for key: String in settings[section].keys():
|
||||||
|
config.set_value(section, key, settings[section][key])
|
||||||
|
|
||||||
|
config.save(SETTINGS_PATH)
|
||||||
|
|
||||||
|
|
||||||
|
func set_setting(section: String, key: String, value: Variant, do_save: bool = true) -> void:
|
||||||
|
settings[section][key] = value
|
||||||
|
|
||||||
|
if do_save:
|
||||||
|
save_settings()
|
||||||
|
|
||||||
|
|
||||||
|
func get_setting(section: String, key: String) -> Variant:
|
||||||
|
return settings[section][key]
|
||||||
|
|
||||||
|
|
||||||
|
func adjust_volume(bus: StringName, volume: float) -> void:
|
||||||
|
set_setting(&"audio", bus, volume, false)
|
||||||
|
return
|
||||||
|
|
||||||
|
var fmod_bus: FmodBus = FmodServer.get_bus(str("res://components/fmod/Build/Desktop/", bus, ".bank"))
|
||||||
|
if is_instance_valid(fmod_bus):
|
||||||
|
fmod_bus.volume = volume
|
||||||
|
|
||||||
|
|
||||||
|
func set_fullscreen(fullscreened: bool) -> void:
|
||||||
|
DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_FULLSCREEN if fullscreened else DisplayServer.WINDOW_MODE_WINDOWED)
|
||||||
|
set_setting(&"video", &"fullscreen", fullscreened)
|
||||||
@ -0,0 +1 @@
|
|||||||
|
uid://py4o5sbsljq4
|
||||||
BIN
source/localization/de.mo
Normal file
BIN
source/localization/de.mo
Normal file
Binary file not shown.
38
source/localization/de.po
Normal file
38
source/localization/de.po
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# LANGUAGE translation for MagicNStuff for the following files:
|
||||||
|
# res://components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
#
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: MagicNStuff\n"
|
||||||
|
"POT-Creation-Date: \n"
|
||||||
|
"PO-Revision-Date: \n"
|
||||||
|
"Last-Translator: \n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"Language: de\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Poedit 3.4.2\n"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "Magic N' Stuff"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "CONTINUE"
|
||||||
|
msgstr "Weiterspielen"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "NEW_GAME"
|
||||||
|
msgstr "Neues Spiel"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "SETTINGS"
|
||||||
|
msgstr "Einstellungen"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "QUIT"
|
||||||
|
msgstr "Beenden"
|
||||||
BIN
source/localization/en.mo
Normal file
BIN
source/localization/en.mo
Normal file
Binary file not shown.
38
source/localization/en.po
Normal file
38
source/localization/en.po
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
# LANGUAGE translation for MagicNStuff for the following files:
|
||||||
|
# res://components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
#
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: MagicNStuff\n"
|
||||||
|
"POT-Creation-Date: \n"
|
||||||
|
"PO-Revision-Date: \n"
|
||||||
|
"Last-Translator: \n"
|
||||||
|
"Language-Team: \n"
|
||||||
|
"Language: en\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
"X-Generator: Poedit 3.4.2\n"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "Magic N' Stuff"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "CONTINUE"
|
||||||
|
msgstr "Continue"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "NEW_GAME"
|
||||||
|
msgstr "New Game"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "SETTINGS"
|
||||||
|
msgstr "Settings"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "QUIT"
|
||||||
|
msgstr "Quit"
|
||||||
32
source/localization/translation.pot
Normal file
32
source/localization/translation.pot
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
# LANGUAGE translation for MagicNStuff for the following files:
|
||||||
|
# res://components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
#
|
||||||
|
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||||
|
#
|
||||||
|
#, fuzzy
|
||||||
|
msgid ""
|
||||||
|
msgstr ""
|
||||||
|
"Project-Id-Version: MagicNStuff\n"
|
||||||
|
"MIME-Version: 1.0\n"
|
||||||
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
|
"Content-Transfer-Encoding: 8-bit\n"
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "Magic N' Stuff"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "CONTINUE"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "NEW_GAME"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "SETTINGS"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: components/ui/menus/main_menu/main_menu.tscn
|
||||||
|
msgid "QUIT"
|
||||||
|
msgstr ""
|
||||||
@ -1,3 +0,0 @@
|
|||||||
[gd_scene format=3 uid="uid://cvj5b6ygk8u02"]
|
|
||||||
|
|
||||||
[node name="Main" type="Node"]
|
|
||||||
@ -18,7 +18,8 @@ sky = SubResource("Sky_yaqeo")
|
|||||||
tonemap_mode = 2
|
tonemap_mode = 2
|
||||||
glow_enabled = true
|
glow_enabled = true
|
||||||
|
|
||||||
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_g60qb"]
|
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_g60qb"]
|
||||||
|
albedo_color = Color(1, 0.426083, 0.0827108, 1)
|
||||||
|
|
||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_g60qb"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_g60qb"]
|
||||||
size = Vector3(9, 4, 9)
|
size = Vector3(9, 4, 9)
|
||||||
@ -44,8 +45,7 @@ size = Vector3(22, 4, 7)
|
|||||||
[sub_resource type="BoxShape3D" id="BoxShape3D_0qpgw"]
|
[sub_resource type="BoxShape3D" id="BoxShape3D_0qpgw"]
|
||||||
size = Vector3(9, 4, 25)
|
size = Vector3(9, 4, 25)
|
||||||
|
|
||||||
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_g60qb"]
|
[sub_resource type="WorldBoundaryShape3D" id="WorldBoundaryShape3D_g60qb"]
|
||||||
albedo_color = Color(1, 0.426083, 0.0827108, 1)
|
|
||||||
|
|
||||||
[sub_resource type="CylinderMesh" id="CylinderMesh_g60qb"]
|
[sub_resource type="CylinderMesh" id="CylinderMesh_g60qb"]
|
||||||
|
|
||||||
@ -61,6 +61,94 @@ shadow_enabled = true
|
|||||||
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
[node name="WorldEnvironment" type="WorldEnvironment" parent="."]
|
||||||
environment = SubResource("Environment_4rgsp")
|
environment = SubResource("Environment_4rgsp")
|
||||||
|
|
||||||
|
[node name="Areas" type="Node" parent="."]
|
||||||
|
|
||||||
|
[node name="AlwaysLoaded" type="CSGCombiner3D" parent="Areas"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9)
|
||||||
|
use_collision = true
|
||||||
|
|
||||||
|
[node name="CSGBox3D" type="CSGBox3D" parent="Areas/AlwaysLoaded"]
|
||||||
|
size = Vector3(8, 1, 7)
|
||||||
|
material = SubResource("StandardMaterial3D_g60qb")
|
||||||
|
|
||||||
|
[node name="PerformanceTestPlatform1" type="Area3D" parent="Areas" node_paths=PackedStringArray("placeholder_node")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 0)
|
||||||
|
script = ExtResource("1_q4yy4")
|
||||||
|
placeholder_node = NodePath("Area1")
|
||||||
|
loaded_if_spawnpoint = Array[int]([0])
|
||||||
|
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
||||||
|
|
||||||
|
[node name="Area1" parent="Areas/PerformanceTestPlatform1" instance_placeholder="res://maps/_dynamic_load_test/area_1.tscn"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -2, 2)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Areas/PerformanceTestPlatform1"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 2)
|
||||||
|
shape = SubResource("BoxShape3D_g60qb")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="PerformanceTestPlatform2" type="Area3D" parent="Areas" node_paths=PackedStringArray("placeholder_node")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, -7)
|
||||||
|
script = ExtResource("1_q4yy4")
|
||||||
|
placeholder_node = NodePath("Area2")
|
||||||
|
loaded_if_spawnpoint = Array[int]([1])
|
||||||
|
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
||||||
|
|
||||||
|
[node name="Area2" parent="Areas/PerformanceTestPlatform2" instance_placeholder="res://maps/_dynamic_load_test/area_2.tscn"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -2, 2)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Areas/PerformanceTestPlatform2"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 2)
|
||||||
|
shape = SubResource("BoxShape3D_yaqeo")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Areas/PerformanceTestPlatform2"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.5, 0.5, 3.67773)
|
||||||
|
shape = SubResource("BoxShape3D_4rgsp")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D3" type="CollisionShape3D" parent="Areas/PerformanceTestPlatform2"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.5, 0.5, 5.67773)
|
||||||
|
shape = SubResource("BoxShape3D_m4fap")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="Hallway1Loader" type="Area3D" parent="Areas" node_paths=PackedStringArray("placeholder_node")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, -7)
|
||||||
|
script = ExtResource("1_q4yy4")
|
||||||
|
placeholder_node = NodePath("Hallway1")
|
||||||
|
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
||||||
|
|
||||||
|
[node name="Hallway1" parent="Areas/Hallway1Loader" instance_placeholder="res://maps/_dynamic_load_test/hallway_1.tscn"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -2, 16)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Areas/Hallway1Loader"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 17.85)
|
||||||
|
shape = SubResource("BoxShape3D_k1ge7")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="Hallway2Loader" type="Area3D" parent="Areas" node_paths=PackedStringArray("placeholder_node")]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, -7)
|
||||||
|
script = ExtResource("1_q4yy4")
|
||||||
|
placeholder_node = NodePath("Hallway2")
|
||||||
|
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
||||||
|
|
||||||
|
[node name="Hallway2" parent="Areas/Hallway2Loader" instance_placeholder="res://maps/_dynamic_load_test/hallway_2.tscn"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -2, 16)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="Areas/Hallway2Loader"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 25.5)
|
||||||
|
shape = SubResource("BoxShape3D_ka7nb")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Areas/Hallway2Loader"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.5, 0.5, 3.67773)
|
||||||
|
shape = SubResource("BoxShape3D_kaxur")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
|
[node name="CollisionShape3D3" type="CollisionShape3D" parent="Areas/Hallway2Loader"]
|
||||||
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14, 0.5, 12.6777)
|
||||||
|
shape = SubResource("BoxShape3D_0qpgw")
|
||||||
|
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
||||||
|
|
||||||
[node name="WorldFloor" type="StaticBody3D" parent="."]
|
[node name="WorldFloor" type="StaticBody3D" parent="."]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.5, 0)
|
||||||
metadata/_edit_lock_ = true
|
metadata/_edit_lock_ = true
|
||||||
@ -69,90 +157,6 @@ metadata/_edit_group_ = true
|
|||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor"]
|
[node name="CollisionShape3D" type="CollisionShape3D" parent="WorldFloor"]
|
||||||
shape = SubResource("WorldBoundaryShape3D_g60qb")
|
shape = SubResource("WorldBoundaryShape3D_g60qb")
|
||||||
|
|
||||||
[node name="DynamicAreaLoader3D" type="Area3D" parent="." node_paths=PackedStringArray("placeholder_node")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, 0)
|
|
||||||
script = ExtResource("1_q4yy4")
|
|
||||||
placeholder_node = NodePath("Area1")
|
|
||||||
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
|
||||||
|
|
||||||
[node name="Area1" parent="DynamicAreaLoader3D" instance_placeholder="res://maps/_dynamic_load_test/area_1.tscn"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -2, 2)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="DynamicAreaLoader3D"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 2)
|
|
||||||
shape = SubResource("BoxShape3D_g60qb")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="DynamicAreaLoader3D2" type="Area3D" parent="." node_paths=PackedStringArray("placeholder_node")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, -7)
|
|
||||||
script = ExtResource("1_q4yy4")
|
|
||||||
placeholder_node = NodePath("Area2")
|
|
||||||
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
|
||||||
|
|
||||||
[node name="Area2" parent="DynamicAreaLoader3D2" instance_placeholder="res://maps/_dynamic_load_test/area_2.tscn"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, -2, 2)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="DynamicAreaLoader3D2"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 2)
|
|
||||||
shape = SubResource("BoxShape3D_yaqeo")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D2" type="CollisionShape3D" parent="DynamicAreaLoader3D2"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -12.5, 0.5, 3.67773)
|
|
||||||
shape = SubResource("BoxShape3D_4rgsp")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D3" type="CollisionShape3D" parent="DynamicAreaLoader3D2"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -16.5, 0.5, 5.67773)
|
|
||||||
shape = SubResource("BoxShape3D_m4fap")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="Hallway1Loader" type="Area3D" parent="." node_paths=PackedStringArray("placeholder_node")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, -7)
|
|
||||||
script = ExtResource("1_q4yy4")
|
|
||||||
placeholder_node = NodePath("Hallway1")
|
|
||||||
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
|
||||||
|
|
||||||
[node name="Hallway1" parent="Hallway1Loader" instance_placeholder="res://maps/_dynamic_load_test/hallway_1.tscn"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -2, 16)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Hallway1Loader"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 17.85)
|
|
||||||
shape = SubResource("BoxShape3D_k1ge7")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="Hallway2Loader" type="Area3D" parent="." node_paths=PackedStringArray("placeholder_node")]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 2, -7)
|
|
||||||
script = ExtResource("1_q4yy4")
|
|
||||||
placeholder_node = NodePath("Hallway2")
|
|
||||||
metadata/_custom_type_script = "uid://bj2bhtdul8xct"
|
|
||||||
|
|
||||||
[node name="Hallway2" parent="Hallway2Loader" instance_placeholder="res://maps/_dynamic_load_test/hallway_2.tscn"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 2, -2, 16)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Hallway2Loader"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -2, 0.5, 25.5)
|
|
||||||
shape = SubResource("BoxShape3D_ka7nb")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D2" type="CollisionShape3D" parent="Hallway2Loader"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -7.5, 0.5, 3.67773)
|
|
||||||
shape = SubResource("BoxShape3D_kaxur")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="CollisionShape3D3" type="CollisionShape3D" parent="Hallway2Loader"]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -14, 0.5, 12.6777)
|
|
||||||
shape = SubResource("BoxShape3D_0qpgw")
|
|
||||||
debug_color = Color(0.678973, 0.504376, 0, 0.42)
|
|
||||||
|
|
||||||
[node name="AlwaysLoaded" type="CSGCombiner3D" parent="."]
|
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 9)
|
|
||||||
use_collision = true
|
|
||||||
|
|
||||||
[node name="CSGBox3D" type="CSGBox3D" parent="AlwaysLoaded"]
|
|
||||||
size = Vector3(8, 1, 7)
|
|
||||||
material = SubResource("StandardMaterial3D_g60qb")
|
|
||||||
|
|
||||||
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
[node name="MeshInstance3D" type="MeshInstance3D" parent="."]
|
||||||
transform = Transform3D(5.58473, 6.33307, 0, -6.33307, 5.58473, 0, 0, 0, 8.44375, -13.6652, 0, -15.4998)
|
transform = Transform3D(5.58473, 6.33307, 0, -6.33307, 5.58473, 0, 0, 0, 8.44375, -13.6652, 0, -15.4998)
|
||||||
mesh = SubResource("CylinderMesh_g60qb")
|
mesh = SubResource("CylinderMesh_g60qb")
|
||||||
@ -162,5 +166,17 @@ transform = Transform3D(0.330597, 0, 0.943772, 0, 1, 0, -0.943772, 0, 0.330597,
|
|||||||
script = ExtResource("3_yaqeo")
|
script = ExtResource("3_yaqeo")
|
||||||
metadata/_custom_type_script = "uid://3hlvt5k34xva"
|
metadata/_custom_type_script = "uid://3hlvt5k34xva"
|
||||||
|
|
||||||
|
[node name="PlayerSpawnPoint2" type="Marker3D" parent="."]
|
||||||
|
transform = Transform3D(0.330597, 0, 0.943772, 0, 1, 0, -0.943772, 0, 0.330597, 2.60837, 0.5, -2.6832)
|
||||||
|
script = ExtResource("3_yaqeo")
|
||||||
|
spawn_index = 1
|
||||||
|
metadata/_custom_type_script = "uid://3hlvt5k34xva"
|
||||||
|
|
||||||
|
[node name="PlayerSpawnPoint3" type="Marker3D" parent="."]
|
||||||
|
transform = Transform3D(0.43358, 0, -0.901115, 0, 1, 0, 0.901115, 0, 0.43358, -14.3916, 0.5, -2.6832)
|
||||||
|
script = ExtResource("3_yaqeo")
|
||||||
|
spawn_index = 2
|
||||||
|
metadata/_custom_type_script = "uid://3hlvt5k34xva"
|
||||||
|
|
||||||
[node name="Saw" parent="." instance=ExtResource("4_4rgsp")]
|
[node name="Saw" parent="." instance=ExtResource("4_4rgsp")]
|
||||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.31477, 1.59362, 6.44809)
|
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.31477, 1.59362, 6.44809)
|
||||||
|
|||||||
@ -11,13 +11,18 @@ config_version=5
|
|||||||
[application]
|
[application]
|
||||||
|
|
||||||
config/name="MagicNStuff"
|
config/name="MagicNStuff"
|
||||||
|
run/main_scene="uid://coga3ke4xw3a0"
|
||||||
config/features=PackedStringArray("4.4", "Forward Plus")
|
config/features=PackedStringArray("4.4", "Forward Plus")
|
||||||
config/icon="uid://bovb32x4x3ps5"
|
config/icon="uid://bovb32x4x3ps5"
|
||||||
|
|
||||||
[autoload]
|
[autoload]
|
||||||
|
|
||||||
|
SettingsManager="*res://globals/autoloads/settings/settings_manager.gd"
|
||||||
|
SceneFader="*res://globals/autoloads/scene_fader/scene_fader.tscn"
|
||||||
GameGlobals="*res://globals/autoloads/game_globals.gd"
|
GameGlobals="*res://globals/autoloads/game_globals.gd"
|
||||||
InputManager="*res://globals/autoloads/input_manager.gd"
|
InputManager="*res://globals/autoloads/input_manager.gd"
|
||||||
|
SaveManager="*res://globals/autoloads/save_manager.gd"
|
||||||
|
AudioManager="*res://globals/autoloads/audio/audio_manager.tscn"
|
||||||
Logger="*res://addons/logger/logger.tscn"
|
Logger="*res://addons/logger/logger.tscn"
|
||||||
RunConfigManager="*res://addons/run-configs/run-config-manager.gd"
|
RunConfigManager="*res://addons/run-configs/run-config-manager.gd"
|
||||||
VersionDisplay="*res://addons/version_display/version_display.tscn"
|
VersionDisplay="*res://addons/version_display/version_display.tscn"
|
||||||
@ -33,7 +38,9 @@ folder_colors={
|
|||||||
"res://addons/": "gray",
|
"res://addons/": "gray",
|
||||||
"res://components/": "green",
|
"res://components/": "green",
|
||||||
"res://globals/": "orange",
|
"res://globals/": "orange",
|
||||||
"res://maps/": "yellow"
|
"res://localization/": "teal",
|
||||||
|
"res://maps/": "yellow",
|
||||||
|
"res://resources/": "purple"
|
||||||
}
|
}
|
||||||
|
|
||||||
[input]
|
[input]
|
||||||
@ -99,6 +106,12 @@ camera_right={
|
|||||||
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null)
|
"events": [Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
pause={
|
||||||
|
"deadzone": 0.2,
|
||||||
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194305,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
|
, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":6,"pressure":0.0,"pressed":false,"script":null)
|
||||||
|
]
|
||||||
|
}
|
||||||
toggle_console={
|
toggle_console={
|
||||||
"deadzone": 0.2,
|
"deadzone": 0.2,
|
||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194341,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194341,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
@ -129,3 +142,8 @@ bbcode_edit/editor/open_current_file_documentation={
|
|||||||
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194332,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":true,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194332,"physical_keycode":0,"key_label":0,"unicode":0,"location":0,"echo":false,"script":null)
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[internationalization]
|
||||||
|
|
||||||
|
locale/translations=PackedStringArray("res://localization/de.mo", "res://localization/de.po", "res://localization/en.mo", "res://localization/en.po")
|
||||||
|
locale/translations_pot_files=PackedStringArray("res://components/ui/menus/main_menu/main_menu.tscn")
|
||||||
|
|||||||
8
source/resources/game_environment.tres
Normal file
8
source/resources/game_environment.tres
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
[gd_resource type="Environment" format=3 uid="uid://xe70va0pjc6c"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
tonemap_mode = 3
|
||||||
|
ssao_enabled = true
|
||||||
|
ssao_radius = 0.7
|
||||||
|
ssao_intensity = 1.0
|
||||||
|
glow_enabled = true
|
||||||
Loading…
Reference in New Issue
Block a user