Compare commits
33 Commits
bc582efb90
...
stage/mole
| Author | SHA1 | Date | |
|---|---|---|---|
| 01f1b52086 | |||
| a59255d9d6 | |||
| 3c7e1a612d | |||
| df8c8c6c3b | |||
| 8b7a8e014f | |||
| f78ad93191 | |||
| 6df9442b49 | |||
| 1fbc2f6637 | |||
| da15fb77a2 | |||
| 9d9ed22ea8 | |||
| 0e447f80ec | |||
| fd636e2d9a | |||
| 27db6d6d27 | |||
| a11805ad30 | |||
| 241dfb3073 | |||
| 9dd1d45698 | |||
| 6d8e8e3734 | |||
| 2b46fd18f7 | |||
| f83b290f5c | |||
| 51ee5029e9 | |||
| 6b8af22d7a | |||
| ac6549579e | |||
| 99de1fc113 | |||
| 8f1b301ece | |||
| d406fd2e30 | |||
| fc093533fd | |||
| a1e0ec07d7 | |||
| 7bd85cc050 | |||
| 1ff04ff3b3 | |||
| 27540988fd | |||
| cc0a4cb71b | |||
| f2b58d7314 | |||
| 6482dab9b6 |
1
.gitignore
vendored
1
.gitignore
vendored
@@ -49,4 +49,3 @@ export_presets.cfg
|
||||
data_*/
|
||||
mono_crash.*.json
|
||||
|
||||
addons/
|
||||
|
||||
21
evolve-die-repeat/addons/modular-settings-menu/LICENSE
Normal file
21
evolve-die-repeat/addons/modular-settings-menu/LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2024-present Mark Velez
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,7 @@
|
||||
[plugin]
|
||||
|
||||
name="Modular Settings Menu"
|
||||
description="A fully modular settings menu that can be customized with ease."
|
||||
author="Mark Velez"
|
||||
version="1.0.0"
|
||||
script="plugin.gd"
|
||||
13
evolve-die-repeat/addons/modular-settings-menu/plugin.gd
Normal file
13
evolve-die-repeat/addons/modular-settings-menu/plugin.gd
Normal file
@@ -0,0 +1,13 @@
|
||||
@tool
|
||||
extends EditorPlugin
|
||||
|
||||
var pluginPath: String = get_script().resource_path.get_base_dir()
|
||||
const settingsDataManagerPath: String = "/singletons/settings_data_manager.gd"
|
||||
|
||||
|
||||
func _enter_tree():
|
||||
add_autoload_singleton("SettingsDataManager", pluginPath + settingsDataManagerPath)
|
||||
|
||||
|
||||
func _exit_tree():
|
||||
remove_autoload_singleton("SettingsDataManager")
|
||||
@@ -0,0 +1 @@
|
||||
uid://7kssh3jmekkk
|
||||
@@ -0,0 +1,53 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://pir75xaw2g08"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/modular-settings-menu/scripts/settings-elements-scripts/audio_setting.gd" id="1_n7p26"]
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hlot4"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_4i2xw"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hlot4")
|
||||
|
||||
[node name="MasterVolume" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_n7p26")
|
||||
AUDIO_BUS = "Master"
|
||||
STEP_VALUE = 0.01
|
||||
DISPLAY_PERCENT_VALUE = true
|
||||
VALUE_SUFFIX = "%"
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "MasterVolume"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Master"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_4i2xw")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,53 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://y6kuxwyem48c"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/modular-settings-menu/scripts/settings-elements-scripts/audio_setting.gd" id="1_05os8"]
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hlot4"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_4i2xw"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hlot4")
|
||||
|
||||
[node name="MusicVolume" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_05os8")
|
||||
AUDIO_BUS = "Music"
|
||||
STEP_VALUE = 0.01
|
||||
DISPLAY_PERCENT_VALUE = true
|
||||
VALUE_SUFFIX = "%"
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "MusicVolume"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Music"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_4i2xw")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,53 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://jl3iirunm0hq"]
|
||||
|
||||
[ext_resource type="Script" path="res://addons/modular-settings-menu/scripts/settings-elements-scripts/audio_setting.gd" id="1_b0uh7"]
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hlot4"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_4i2xw"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hlot4")
|
||||
|
||||
[node name="SFXVolume" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_b0uh7")
|
||||
AUDIO_BUS = "SFX"
|
||||
STEP_VALUE = 0.01
|
||||
DISPLAY_PERCENT_VALUE = true
|
||||
VALUE_SUFFIX = "%"
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "SFXVolume"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "SFX"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_4i2xw")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,38 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://bbtri7oyxvehi"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_jjel1"]
|
||||
|
||||
[node name="InputButton" type="PanelContainer"]
|
||||
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="MarginContainer" type="MarginContainer" parent="."]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ActionLabel" type="Label" parent="MarginContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 2
|
||||
size_flags_vertical = 1
|
||||
mouse_filter = 1
|
||||
text = "action name"
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="ActionInput" type="Button" parent="MarginContainer/HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
mouse_filter = 1
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_jjel1")
|
||||
text = "input key"
|
||||
@@ -0,0 +1,305 @@
|
||||
[gd_scene format=3 uid="uid://cqqhgk8ufkmqa"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://bbtri7oyxvehi" path="res://addons/modular-settings-menu/scenes/settings-elements/controls-elements/input-settings-panel/input-settings-panel-elements/input_button.tscn" id="1_1y7ch"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_0eq0v"]
|
||||
resource_name = "input_settings_panel"
|
||||
script/source = "extends Control
|
||||
|
||||
# Button scene for actions
|
||||
@export var InputButtonScene: PackedScene
|
||||
|
||||
# Panel node references
|
||||
@onready var ActionListRef: VBoxContainer = %ActionList
|
||||
@onready var ResetButtonRef: Button = %ResetButton
|
||||
@onready var BackButtonRef: Button = $VBoxContainer/HBoxContainer/BackButton
|
||||
@onready var ApplyButtonRef: Button = $VBoxContainer/HBoxContainer/ApplyButton
|
||||
|
||||
# List of events for each action
|
||||
var actionEvents_: Dictionary
|
||||
# Cache for changed actions
|
||||
var panelCache_: Dictionary
|
||||
# Reference list to the button for each action
|
||||
var actionReferenceList_: Dictionary
|
||||
|
||||
# Reference to the element this panel belongs to
|
||||
var PanelOwnerRef: ButtonElement
|
||||
|
||||
# For remapping
|
||||
var isRemapping: bool = false
|
||||
var actionToRemap: String
|
||||
var ActionInputButtonRef: Button
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect necessary signals
|
||||
ResetButtonRef.connect(\"pressed\", on_reset_button_pressed)
|
||||
BackButtonRef.connect(\"pressed\", on_back_button_pressed)
|
||||
ApplyButtonRef.connect(\"pressed\", on_apply_button_pressed)
|
||||
|
||||
|
||||
# Called to populate the action list with actions
|
||||
func create_action_list(reset: bool = false) -> void:
|
||||
# All the remappable actions
|
||||
var INPUT_ACTIONS_: Dictionary = PanelOwnerRef.ACTION_LIST_.duplicate()
|
||||
INPUT_ACTIONS_.make_read_only()
|
||||
|
||||
# Get the events for the actions
|
||||
actionEvents_ = get_events(INPUT_ACTIONS_, reset)
|
||||
|
||||
# Check if the action list is already populated
|
||||
if ActionListRef.get_child_count() > 0:
|
||||
# Remove all the existing actions from the action list
|
||||
for child in ActionListRef.get_children():
|
||||
child.queue_free()
|
||||
|
||||
# Create the actions for the action list
|
||||
for action in INPUT_ACTIONS_:
|
||||
# Instantiate the button scene
|
||||
var ButtonRef: PanelContainer = InputButtonScene.instantiate()
|
||||
# Get references to the elements of the button scene
|
||||
var ActionLabelRef: Label = ButtonRef.find_child(\"ActionLabel\")
|
||||
var ActionInputRef: Button = ButtonRef.find_child(\"ActionInput\")
|
||||
# Get the event for the action
|
||||
var event = actionEvents_[action]
|
||||
|
||||
# Add a reference of the instantiated button to the reference list
|
||||
actionReferenceList_[action] = ButtonRef
|
||||
# Change the label text of the button to the action it corresponds to
|
||||
ActionLabelRef.set_text(INPUT_ACTIONS_[action])
|
||||
ActionInputRef.set_text(event.as_text())
|
||||
|
||||
ActionListRef.add_child(ButtonRef)
|
||||
ActionInputRef.connect(
|
||||
\"pressed\",
|
||||
on_input_button_pressed.bind(action, ActionInputRef)
|
||||
)
|
||||
|
||||
|
||||
func on_input_button_pressed(action: String, ActionInputRef: Button) -> void:
|
||||
# Check if a button is not being remapped currently
|
||||
if not isRemapping:
|
||||
isRemapping = true
|
||||
actionToRemap = action
|
||||
ActionInputButtonRef = ActionInputRef
|
||||
ActionInputRef.set_text(\"Press key to bind...\")
|
||||
|
||||
|
||||
func _input(event: InputEvent):
|
||||
# Check if an action is being remapped currently
|
||||
if isRemapping:
|
||||
# Check if the desired input is either a keyboard or mouse input
|
||||
if (
|
||||
event is InputEventKey
|
||||
or event is InputEventMouseButton
|
||||
and event.pressed
|
||||
):
|
||||
# Check if the event is a mouse event and if it was a double click
|
||||
if event is InputEventMouseButton and event.double_click:
|
||||
# Disable the double click flag
|
||||
event.double_click = false
|
||||
|
||||
# Set the input button's text to the inputted event
|
||||
ActionInputButtonRef.set_text(event.as_text())
|
||||
|
||||
# Check if the inputted event is different compared to the saved one for the action
|
||||
if not check_matching_event(event):
|
||||
var duplicateEvent: String = check_duplicate_event(event)
|
||||
actionEvents_[actionToRemap] = event
|
||||
panelCache_[actionToRemap] = event
|
||||
ApplyButtonRef.set_disabled(false)
|
||||
|
||||
if duplicateEvent:
|
||||
var ActionInputRef: Button =\\
|
||||
actionReferenceList_[duplicateEvent].find_child(
|
||||
\"ActionInput\"
|
||||
)
|
||||
actionEvents_[duplicateEvent] = InputEventKey.new()
|
||||
panelCache_[duplicateEvent] = actionEvents_[duplicateEvent]
|
||||
ActionInputRef.set_text(
|
||||
actionEvents_[duplicateEvent].as_text()
|
||||
)
|
||||
|
||||
isRemapping = false
|
||||
actionToRemap = \"\"
|
||||
ActionInputButtonRef = null
|
||||
|
||||
accept_event()
|
||||
|
||||
|
||||
# Checks if the inputted event matches the one saved for the action
|
||||
func check_matching_event(event: InputEvent) -> bool:
|
||||
var eventType: String = event.get_class()
|
||||
var eventButton: int = get_event_button(event)
|
||||
var currentEvent = actionEvents_[actionToRemap]
|
||||
|
||||
# Check if the event matches the action to be remapped
|
||||
if (
|
||||
currentEvent.is_class(eventType)
|
||||
and get_event_button(currentEvent) == eventButton
|
||||
):
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
|
||||
# Checks if any other action has the inputted event as it's event
|
||||
func check_duplicate_event(event: InputEvent) -> String:
|
||||
var eventType: String = event.get_class()
|
||||
var eventButton: int = get_event_button(event)
|
||||
|
||||
# Check for duplicates in other actions
|
||||
for action in actionEvents_:
|
||||
# Check if the action is not the one being remapped
|
||||
if action != actionToRemap:
|
||||
var storedEvent = actionEvents_[action]
|
||||
|
||||
# Check if the input type and event matches the inputted event
|
||||
if (
|
||||
storedEvent.is_class(eventType)
|
||||
and get_event_button(storedEvent) == eventButton
|
||||
):
|
||||
return action
|
||||
|
||||
return \"\"
|
||||
|
||||
|
||||
# Called to get the physical index for the inputted event depending on the input event's type
|
||||
func get_event_button(event: InputEvent) -> int:
|
||||
# Check for the input event's type
|
||||
match event.get_class():
|
||||
\"InputEventKey\":
|
||||
return event.get_keycode()
|
||||
\"InputEventMouseButton\":
|
||||
return event.get_button_index()
|
||||
|
||||
return -1
|
||||
|
||||
|
||||
# Called to update the action's events to the cached events
|
||||
func update_action_events(actionList_: Dictionary) -> void:
|
||||
# Itterate through all the recieved actions
|
||||
for action in actionList_:
|
||||
# Remove all events for the action
|
||||
InputMap.action_erase_events(action)
|
||||
|
||||
# Check if the action has an event assigned to it
|
||||
if actionList_[action]:
|
||||
# Add the new event to the action
|
||||
InputMap.action_add_event(action, actionList_[action])
|
||||
|
||||
|
||||
# Called to get all the events for the remappable actions
|
||||
func get_events(actions_: Dictionary, reset: bool = false) -> Dictionary:
|
||||
var events_: Dictionary = {}
|
||||
|
||||
if PanelOwnerRef.noSaveFile or PanelOwnerRef.invalidSaveFile or reset:
|
||||
InputMap.load_from_project_settings()
|
||||
for action in actions_:
|
||||
# Retrieve the first event for the action
|
||||
events_[action] = InputMap.action_get_events(action)[0]
|
||||
panelCache_ = events_.duplicate(true)
|
||||
else:
|
||||
# Retrieve the events from the loaded data
|
||||
events_ = PanelOwnerRef.inputSettingsData_.duplicate()
|
||||
|
||||
return events_
|
||||
|
||||
|
||||
func on_reset_button_pressed():
|
||||
panelCache_.clear()
|
||||
create_action_list(true)
|
||||
ApplyButtonRef.set_disabled(false)
|
||||
|
||||
|
||||
func on_back_button_pressed():
|
||||
# Check if there have been any changes made
|
||||
if ApplyButtonRef.is_disabled():
|
||||
# Clear the cache and return normally
|
||||
panelCache_.clear()
|
||||
hide()
|
||||
owner.SettingsPanelRef.show()
|
||||
else:
|
||||
# Display the discard changes popup
|
||||
owner.display_discard_changes(self)
|
||||
|
||||
|
||||
func on_apply_button_pressed():
|
||||
# Update the input map
|
||||
update_action_events(panelCache_)
|
||||
panelCache_.clear()
|
||||
# Send the new data to the parent element
|
||||
PanelOwnerRef.panel_settings_changed(actionEvents_)
|
||||
ApplyButtonRef.set_disabled(true)
|
||||
"
|
||||
|
||||
[node name="InputSettingsPanel" type="Control"]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_0eq0v")
|
||||
InputButtonScene = ExtResource("1_1y7ch")
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -194.0
|
||||
offset_top = -29.0
|
||||
offset_right = 194.0
|
||||
offset_bottom = 30.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 280)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="ActionList" type="VBoxContainer" parent="VBoxContainer/PanelContainer/MarginContainer/VBoxContainer/ScrollContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
|
||||
[node name="ResetButton" type="Button" parent="VBoxContainer/PanelContainer/MarginContainer/VBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
focus_mode = 0
|
||||
text = "Reset to default"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ApplyButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
layout_direction = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
disabled = true
|
||||
text = "Apply"
|
||||
|
||||
[node name="BackButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
layout_direction = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
text = "Back"
|
||||
@@ -0,0 +1,165 @@
|
||||
[gd_scene format=3 uid="uid://i0w5gftb0j16"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://cqqhgk8ufkmqa" path="res://addons/modular-settings-menu/scenes/settings-elements/controls-elements/input-settings-panel/input_settings_panel.tscn" id="1_6pc66"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_te2ja"]
|
||||
resource_name = "input_settings"
|
||||
script/source = "extends ButtonElement
|
||||
|
||||
##List of actions to make remappable and how the name they should display.
|
||||
@export var ACTION_LIST_: Dictionary = {
|
||||
\"ui_up\": \"Up\",
|
||||
\"ui_down\": \"Down\",
|
||||
\"ui_left\": \"Left\",
|
||||
\"ui_right\": \"Right\",
|
||||
}
|
||||
|
||||
# Path to the settings save file
|
||||
var DATA_FOLDER: String = SettingsDataManager.DATA_FOLDER
|
||||
const FILE_NAME: String = \"keybinds\"
|
||||
const FILE_EXTENSION: String = \".json\"
|
||||
var PATH: String = DATA_FOLDER + \"/\" + FILE_NAME + FILE_EXTENSION
|
||||
|
||||
# Currently stored input data
|
||||
var inputSettingsData_: Dictionary
|
||||
|
||||
# Flag for checking if a save file exists for input settings
|
||||
var noSaveFile: bool
|
||||
# Flag for checking if an invalid value was found in the save file
|
||||
var invalidSaveFile: bool = false
|
||||
|
||||
|
||||
func _ready():
|
||||
super._ready()
|
||||
ACTION_LIST_.make_read_only()
|
||||
SettingsDataManager.connect(\"settings_retrieved\", load_settings)
|
||||
# Verify the directory
|
||||
DirAccess.make_dir_absolute(DATA_FOLDER)
|
||||
# Check if a save file exists
|
||||
if not FileAccess.file_exists(PATH):
|
||||
noSaveFile = true
|
||||
|
||||
|
||||
# Loads the saved/default values of the element
|
||||
func load_settings() -> void:
|
||||
# Get the current value for the element
|
||||
if noSaveFile:
|
||||
# Get the events for the remappable actions from the project settings
|
||||
inputSettingsData_ = ElementPanelRef.get_events(ACTION_LIST_)
|
||||
save_input_settings()
|
||||
else:
|
||||
get_input_settings()
|
||||
|
||||
# Check if save file is valid
|
||||
if invalidSaveFile:
|
||||
# Get the events for the remappable actions from the project settings
|
||||
inputSettingsData_ = ElementPanelRef.get_events(ACTION_LIST_)
|
||||
save_input_settings()
|
||||
else:
|
||||
call_deferred(\"apply_settings\")
|
||||
|
||||
|
||||
func pressed() -> void:
|
||||
# Check if a save file exists
|
||||
if not FileAccess.file_exists(PATH):
|
||||
noSaveFile = true
|
||||
|
||||
ElementPanelRef.create_action_list()
|
||||
# Switch panels
|
||||
ParentRef.SettingsMenuRef.SettingsPanelRef.hide()
|
||||
ElementPanelRef.show()
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func apply_settings() -> void:
|
||||
# Assign the events for the remappable actions
|
||||
ElementPanelRef.update_action_events(inputSettingsData_)
|
||||
|
||||
|
||||
# Called to update the input settings data
|
||||
func panel_settings_changed(newValue_: Dictionary) -> void:
|
||||
inputSettingsData_ = newValue_.duplicate()
|
||||
save_input_settings()
|
||||
|
||||
|
||||
# Called to save the input settings
|
||||
func save_input_settings() -> void:
|
||||
var file := FileAccess.open(PATH, FileAccess.WRITE)
|
||||
var data_: Dictionary = {}
|
||||
|
||||
# Itterate through the input settings
|
||||
for input in inputSettingsData_:
|
||||
var inputEvent = inputSettingsData_[input]
|
||||
# Serialize the InputEvent of the action
|
||||
match inputEvent.get_class():
|
||||
\"InputEventKey\":
|
||||
data_[input] = {
|
||||
\"type\": \"keyboard\",
|
||||
\"key\": inputEvent.get_keycode()
|
||||
}
|
||||
\"InputEventMouseButton\":
|
||||
data_[input] = {
|
||||
\"type\": \"mouse\",
|
||||
\"button\": inputEvent.get_button_index()
|
||||
}
|
||||
|
||||
# Save the string to a json file
|
||||
file.store_string(JSON.stringify(data_, \"\\t\", false))
|
||||
file.close()
|
||||
noSaveFile = false
|
||||
|
||||
|
||||
# Called to retrieve the input settings data from the save file
|
||||
func get_input_settings() -> void:
|
||||
var file := FileAccess.open(PATH, FileAccess.READ)
|
||||
# Parse the json string to a dictionary
|
||||
var data_ = JSON.parse_string(file.get_as_text())
|
||||
file.close()
|
||||
|
||||
# Check if there were any errors or if the save file is empty
|
||||
if data_ == null or data_.is_empty():
|
||||
push_error(\"Failed to parse input settings\")
|
||||
invalidSaveFile = true
|
||||
return
|
||||
|
||||
verify_settings_data(data_)
|
||||
|
||||
|
||||
# Used for verifying the integrity of the save file
|
||||
func verify_settings_data(data_: Dictionary) -> void:
|
||||
# Itterate through all the retrieved data
|
||||
for input in data_:
|
||||
# Check if the action exists
|
||||
if not ACTION_LIST_.has(input):
|
||||
push_warning(\"Invalid input settings entry: \", input)
|
||||
invalidSaveFile = true
|
||||
continue
|
||||
|
||||
# Reconstruct the InputEvent for the action
|
||||
match data_[input][\"type\"]:
|
||||
\"keyboard\":
|
||||
var key := InputEventKey.new()
|
||||
key.set_keycode(data_[input][\"key\"])
|
||||
inputSettingsData_[input] = key
|
||||
\"mouse\":
|
||||
var button := InputEventMouseButton.new()
|
||||
button.set_button_index(data_[input][\"button\"])
|
||||
inputSettingsData_[input] = button
|
||||
|
||||
# Itterate through all the expected actions
|
||||
for action in ACTION_LIST_:
|
||||
if not data_.has(action):
|
||||
data_[action] = InputMap.action_get_events(action)[0]
|
||||
invalidSaveFile = true
|
||||
push_warning(\"Input action is missing: \", action)
|
||||
"
|
||||
|
||||
[node name="InputSettings" type="Button"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
text = "Input Settings"
|
||||
script = SubResource("GDScript_te2ja")
|
||||
ElementPanelScene = ExtResource("1_6pc66")
|
||||
@@ -0,0 +1,37 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://c2tgt7fu0n5wp"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_te2ja"]
|
||||
resource_name = "invert_y"
|
||||
script/source = "extends ToggleElement
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="InvertY" type="HBoxContainer" node_paths=PackedStringArray("ToggleRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_te2ja")
|
||||
ToggleRef = NodePath("Toggle")
|
||||
IDENTIFIER = "InvertY"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Invert Y-Axis"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Toggle" type="CheckButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,60 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://cy8n6yalxprb7"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_s1j2c"]
|
||||
resource_name = "sensitivity"
|
||||
script/source = "extends SliderElement
|
||||
|
||||
|
||||
# Element specific script for applying its value to the game
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
"
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hlot4"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_4i2xw"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hlot4")
|
||||
|
||||
[node name="Sensitivity" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_s1j2c")
|
||||
MAX_VALUE = 5.0
|
||||
STEP_VALUE = 0.01
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "Sensitivity"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Mouse Sensitivity"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_4i2xw")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,94 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dvkksl3mrnoto"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_pvp7f"]
|
||||
resource_name = "discard_changes_popup"
|
||||
script/source = "extends PanelContainer
|
||||
|
||||
@onready var YesButtonRef: Button = %YesButton
|
||||
@onready var NoButtonRef: Button = %NoButton
|
||||
|
||||
var CallerRef: Control
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect necessary signals
|
||||
YesButtonRef.connect(\"pressed\", yes_button_pressed)
|
||||
NoButtonRef.connect(\"pressed\", no_button_pressed)
|
||||
connect(\"hidden\", on_hidden)
|
||||
|
||||
|
||||
func yes_button_pressed() -> void:
|
||||
# Check if the panel this belongs to has the \"discard changes\" function
|
||||
if CallerRef.has_method(\"discard_changes\"):
|
||||
CallerRef.discard_changes()
|
||||
|
||||
# Disable the panel's apply button
|
||||
CallerRef.ApplyButtonRef.set_disabled(true)
|
||||
CallerRef.on_back_button_pressed()
|
||||
|
||||
# Reset the changed elements count
|
||||
SettingsDataManager.changedElementsCount = 0
|
||||
|
||||
hide()
|
||||
|
||||
|
||||
func no_button_pressed() -> void:
|
||||
hide()
|
||||
|
||||
|
||||
func on_hidden() -> void:
|
||||
CallerRef = null
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_8kuxy"]
|
||||
bg_color = Color(0.162066, 0.162066, 0.162065, 1)
|
||||
corner_radius_top_left = 4
|
||||
corner_radius_top_right = 4
|
||||
corner_radius_bottom_right = 4
|
||||
corner_radius_bottom_left = 4
|
||||
|
||||
[node name="DiscardChangesPopup" type="PanelContainer"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_pvp7f")
|
||||
|
||||
[node name="PopupWindow" type="PanelContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 4
|
||||
size_flags_vertical = 4
|
||||
theme_override_styles/panel = SubResource("StyleBoxFlat_8kuxy")
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="PopupWindow"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 4
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="PopupWindow/MarginContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="Text" type="Label" parent="PopupWindow/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
text = "Would you like to discard
|
||||
all changes done?"
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="PopupWindow/MarginContainer/VBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/separation = 8
|
||||
|
||||
[node name="YesButton" type="Button" parent="PopupWindow/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "Yes"
|
||||
|
||||
[node name="NoButton" type="Button" parent="PopupWindow/MarginContainer/VBoxContainer/HBoxContainer"]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
text = "No"
|
||||
@@ -0,0 +1,63 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://elu1vc0ox472"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_1rk38"]
|
||||
resource_name = "fov"
|
||||
script/source = "extends SliderElement
|
||||
|
||||
|
||||
# Element specific script for applying its value to the game
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
"
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hlot4"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_4i2xw"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hlot4")
|
||||
|
||||
[node name="FOV" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_1rk38")
|
||||
MIN_VALUE = 30.0
|
||||
MAX_VALUE = 120.0
|
||||
STEP_VALUE = 1.0
|
||||
DEFAULT_VALUE = 75.0
|
||||
VALUE_SUFFIX = "°"
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "FOV"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Field of View"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_4i2xw")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,83 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://csg6c3uuct1ls"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_5w56l"]
|
||||
resource_name = "anti_aliasing"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = [
|
||||
\"Disabled\",
|
||||
\"FXAA\",
|
||||
\"2x MSAA\",
|
||||
\"4x MSAA\",
|
||||
\"8x MSAA\",
|
||||
\"TAA\"
|
||||
]
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
# Enables the selected anti aliasing
|
||||
match currentValue:
|
||||
\"Disabled\":
|
||||
set_anti_aliasing_mode()
|
||||
\"FXAA\":
|
||||
set_anti_aliasing_mode(Viewport.SCREEN_SPACE_AA_FXAA)
|
||||
\"2x MSAA\":
|
||||
set_anti_aliasing_mode(
|
||||
Viewport.SCREEN_SPACE_AA_DISABLED,
|
||||
Viewport.MSAA_2X
|
||||
)
|
||||
\"4x MSAA\":
|
||||
set_anti_aliasing_mode(
|
||||
Viewport.SCREEN_SPACE_AA_DISABLED,
|
||||
Viewport.MSAA_4X
|
||||
)
|
||||
\"8x MSAA\":
|
||||
set_anti_aliasing_mode(
|
||||
Viewport.SCREEN_SPACE_AA_DISABLED,
|
||||
Viewport.MSAA_8X
|
||||
)
|
||||
\"TAA\":
|
||||
set_anti_aliasing_mode(
|
||||
Viewport.SCREEN_SPACE_AA_DISABLED,
|
||||
Viewport.MSAA_DISABLED, true
|
||||
)
|
||||
|
||||
|
||||
# Sets the anti aliasing mode according to the values provided
|
||||
func set_anti_aliasing_mode(
|
||||
fxaaMode: Viewport.ScreenSpaceAA = Viewport.SCREEN_SPACE_AA_DISABLED,
|
||||
msaaMode: Viewport.MSAA = Viewport.MSAA_DISABLED,
|
||||
taaMode: bool = false
|
||||
) -> void:
|
||||
get_viewport().set_screen_space_aa(fxaaMode)
|
||||
get_viewport().set_msaa_3d(msaaMode)
|
||||
get_viewport().set_use_taa(taaMode)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="AntiAliasing" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_5w56l")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "AntiAliasing"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Anti Aliasing"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,53 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://3ckate3v614f"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_mnbyt"]
|
||||
resource_name = "depth_of_field"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": null,
|
||||
\"Low\": RenderingServer.DOF_BLUR_QUALITY_LOW,
|
||||
\"Medium\": RenderingServer.DOF_BLUR_QUALITY_MEDIUM,
|
||||
\"High\": RenderingServer.DOF_BLUR_QUALITY_HIGH
|
||||
}
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
if not apply_in_game_setting(currentValue):
|
||||
if currentValue == \"Disabled\":
|
||||
return
|
||||
|
||||
RenderingServer.camera_attributes_set_dof_blur_quality(
|
||||
OPTION_LIST_[currentValue],
|
||||
true
|
||||
)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="DepthOfField" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_mnbyt")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "DepthOfField"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Depth of Field"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,109 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://byff0jwaicxvr"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_duwn0"]
|
||||
resource_name = "display_mode"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Fullscreen\": DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN,
|
||||
\"Borderless Windowed\": DisplayServer.WINDOW_MODE_WINDOWED,
|
||||
\"Windowed\": DisplayServer.WINDOW_MODE_WINDOWED
|
||||
}
|
||||
|
||||
|
||||
func load_settings() -> void:
|
||||
super.load_settings()
|
||||
# Check if the resolution element should be disabled
|
||||
call_deferred(\"check_resolution\")
|
||||
|
||||
|
||||
func option_selected(index: int) -> void:
|
||||
super.option_selected(index)
|
||||
# Check if the resolution element should be disabled
|
||||
check_resolution()
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
DisplayServer.window_set_mode(OPTION_LIST_[currentValue])
|
||||
|
||||
if currentValue == \"Borderless Windowed\":
|
||||
DisplayServer.window_set_flag(
|
||||
DisplayServer.WINDOW_FLAG_BORDERLESS,
|
||||
true
|
||||
)
|
||||
adjust_resolution()
|
||||
else:
|
||||
DisplayServer.window_set_flag(
|
||||
DisplayServer.WINDOW_FLAG_BORDERLESS,
|
||||
false
|
||||
)
|
||||
|
||||
if currentValue == \"Windowed\":
|
||||
# Set the resolution to 80% if the resolution setting doesnt exist
|
||||
if not ParentRef.ELEMENT_REFERENCE_TABLE_.has(\"Resolution\"):
|
||||
adjust_resolution(0.8)
|
||||
return
|
||||
|
||||
# Apply the selected resolution manually if it has not been changed
|
||||
if not ParentRef.changedElements_.has(\"Resolution\"):
|
||||
# Resolution change has to be delayed by at least 2 frames.
|
||||
# Otherwise height of the window will be off by a bit.
|
||||
await get_tree().process_frame
|
||||
await get_tree().process_frame
|
||||
# Apply the resolution settings manually
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[\"Resolution\"]._apply_settings()
|
||||
|
||||
|
||||
# Called to check if the resolution element should be disabled
|
||||
func check_resolution() -> void:
|
||||
if not ParentRef.ELEMENT_REFERENCE_TABLE_.has(\"Resolution\"):
|
||||
return
|
||||
|
||||
var ResolutionRef: SettingsElement =\\
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[\"Resolution\"]
|
||||
|
||||
if currentValue != \"Windowed\":
|
||||
ResolutionRef.OptionsRef.set_disabled(true)
|
||||
else:
|
||||
ResolutionRef.OptionsRef.set_disabled(false)
|
||||
|
||||
|
||||
# Called to scale the resolution to the provided percentage
|
||||
func adjust_resolution(sizeScale: float = 1.0) -> void:
|
||||
var displaySize: Vector2i =\\
|
||||
DisplayServer.screen_get_size(
|
||||
DisplayServer.window_get_current_screen()
|
||||
) * sizeScale
|
||||
|
||||
get_window().set_size(displaySize)
|
||||
get_viewport().set_size(displaySize)
|
||||
get_window().move_to_center()
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="DisplayMode" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_duwn0")
|
||||
DEFAULT_VALUE = "Fullscreen"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "DisplayMode"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Display Mode"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,55 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://du5urp5d2dyjb"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_7hlvr"]
|
||||
resource_name = "glow_quality"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = [
|
||||
\"Disabled\",
|
||||
\"Low\",
|
||||
\"High\"
|
||||
]
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
|
||||
if currentValue == \"Disabled\":
|
||||
return
|
||||
|
||||
# Toggle bicubic upscaling
|
||||
match currentValue:
|
||||
\"Low\":
|
||||
RenderingServer.environment_glow_set_use_bicubic_upscale(false)
|
||||
\"High\":
|
||||
RenderingServer.environment_glow_set_use_bicubic_upscale(true)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="GlowQuality" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_7hlvr")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "GlowQuality"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Glow Quality"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,85 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://dghfxwcbi5ig"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_eitn6"]
|
||||
resource_name = "max_fps"
|
||||
script/source = "extends SliderElement
|
||||
|
||||
|
||||
func init_element() -> void:
|
||||
super.init_element()
|
||||
# Increase UI max value by one for unlimited fps
|
||||
SliderRef.set_max(MAX_VALUE + 1)
|
||||
if ValueBoxRef is SpinBox:
|
||||
ValueBoxRef.set_max(MAX_VALUE + 1)
|
||||
|
||||
|
||||
func load_settings() -> void:
|
||||
super.load_settings()
|
||||
if currentValue == 0:
|
||||
ValueBoxRef.set_text(\"Unlimited\")
|
||||
SliderRef.set_value(MAX_VALUE + 1)
|
||||
|
||||
|
||||
func value_changed(value: float) -> void:
|
||||
if value > MAX_VALUE:
|
||||
value = 0
|
||||
ValueBoxRef.set_text(\"Unlimited\")
|
||||
|
||||
super.value_changed(value)
|
||||
|
||||
|
||||
|
||||
# Element specific script for applying its value to the game
|
||||
func _apply_settings() -> void:
|
||||
if (
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_.has(\"VSync\")
|
||||
and ParentRef.ELEMENT_REFERENCE_TABLE_[\"VSync\"].currentValue != \"Disabled\"
|
||||
):
|
||||
return
|
||||
|
||||
Engine.set_max_fps(currentValue)
|
||||
"
|
||||
|
||||
[node name="MaxFPS" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_eitn6")
|
||||
MIN_VALUE = 30.0
|
||||
MAX_VALUE = 240.0
|
||||
STEP_VALUE = 1.0
|
||||
DEFAULT_VALUE = 60.0
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "MaxFPS"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Max FPS"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="Label" parent="SliderValue"]
|
||||
custom_minimum_size = Vector2(80, 31)
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 1
|
||||
text = "240"
|
||||
horizontal_alignment = 2
|
||||
vertical_alignment = 1
|
||||
@@ -0,0 +1,64 @@
|
||||
[gd_scene load_steps=2 format=3 uid="uid://cn8r63dmvd55c"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_utf5l"]
|
||||
resource_name = "resolution"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
## Toggle window resizing by the user.
|
||||
@export var RESIZABLE: bool = false
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"3840x2160\": Vector2i(3840, 2160),
|
||||
\"2560x1440\": Vector2i(2560, 1440),
|
||||
\"1920x1080\": Vector2i(1920, 1080),
|
||||
\"1280x720\": Vector2i(1280, 720),
|
||||
\"960x540\": Vector2i(960, 540)
|
||||
}
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
# Toggle window resizing
|
||||
DisplayServer.window_set_flag(
|
||||
DisplayServer.WINDOW_FLAG_RESIZE_DISABLED,
|
||||
!RESIZABLE
|
||||
)
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
if DisplayServer.window_get_mode() == DisplayServer.WINDOW_MODE_EXCLUSIVE_FULLSCREEN:
|
||||
return
|
||||
|
||||
if DisplayServer.window_get_flag(DisplayServer.WINDOW_FLAG_BORDERLESS):
|
||||
return
|
||||
|
||||
# Change the window size to the selected resolution
|
||||
get_window().set_size(OPTION_LIST_[currentValue])
|
||||
get_viewport().set_size(OPTION_LIST_[currentValue])
|
||||
get_window().move_to_center()
|
||||
"
|
||||
|
||||
[node name="Resolution" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_utf5l")
|
||||
DEFAULT_VALUE = "1920x1080"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "Resolution"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Resolution"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
@@ -0,0 +1,41 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://5dydkttc2fww"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_usma2"]
|
||||
resource_name = "fsr_options"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Ultra Quality\": 0.77,
|
||||
\"Quality\": 0.67,
|
||||
\"Balanced\": 0.59,
|
||||
\"Performance\": 0.5
|
||||
}
|
||||
|
||||
|
||||
func _apply_settings() -> void:
|
||||
get_viewport().set_scaling_3d_scale(OPTION_LIST_[currentValue])
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="FSRMode" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
size_flags_vertical = 3
|
||||
script = SubResource("GDScript_usma2")
|
||||
DEFAULT_VALUE = "Balanced"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "FSRMode"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "FSR Mode"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,61 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://bdoaqhvw440eh"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_ng2w8"]
|
||||
resource_name = "fsr_sharpness"
|
||||
script/source = "extends SliderElement
|
||||
|
||||
|
||||
# Element specific script for applying its value to the game
|
||||
func _apply_settings() -> void:
|
||||
get_viewport().set_fsr_sharpness((MAX_VALUE - currentValue) * 2.0)
|
||||
"
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hae3h"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_0xoq4"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hae3h")
|
||||
|
||||
[node name="FSRSharpness" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_ng2w8")
|
||||
STEP_VALUE = 0.01
|
||||
DEFAULT_VALUE = 0.9
|
||||
DISPLAY_PERCENT_VALUE = true
|
||||
VALUE_SUFFIX = "%"
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "FSRSharpness"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "FSR Sharpness"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_0xoq4")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,62 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://ha87l3hl643g"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_7dhl4"]
|
||||
resource_name = "resolution_scale"
|
||||
script/source = "extends SliderElement
|
||||
|
||||
|
||||
# Element specific script for applying its value to the game
|
||||
func _apply_settings() -> void:
|
||||
get_viewport().set_scaling_3d_scale(currentValue)
|
||||
"
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hae3h"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_0xoq4"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hae3h")
|
||||
|
||||
[node name="ResolutionScale" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_7dhl4")
|
||||
MIN_VALUE = 0.5
|
||||
MAX_VALUE = 2.0
|
||||
STEP_VALUE = 0.01
|
||||
DISPLAY_PERCENT_VALUE = true
|
||||
VALUE_SUFFIX = "%"
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "ResolutionScale"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Resolution Scale"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 20
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_0xoq4")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,128 @@
|
||||
[gd_scene format=3 uid="uid://b3w7qpn4nhmu2"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ha87l3hl643g" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/scaler-sub-elements/resolution_scale.tscn" id="1_4irey"]
|
||||
[ext_resource type="PackedScene" uid="uid://5dydkttc2fww" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/scaler-sub-elements/fsr_mode.tscn" id="2_w65g1"]
|
||||
[ext_resource type="PackedScene" uid="uid://bdoaqhvw440eh" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/scaler-sub-elements/fsr_sharpness.tscn" id="3_v8pix"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_bn0b0"]
|
||||
resource_name = "scaler"
|
||||
script/source = "extends MultiElement
|
||||
|
||||
|
||||
func _display_sub_elements() -> void:
|
||||
match currentValue:
|
||||
\"Disabled\":
|
||||
for element in SUB_ELEMENTS_:
|
||||
element.hide()
|
||||
\"Bilinear\":
|
||||
SUB_ELEMENTS_[0].show()
|
||||
SUB_ELEMENTS_[1].hide()
|
||||
SUB_ELEMENTS_[2].hide()
|
||||
\"FSR 2.2\":
|
||||
SUB_ELEMENTS_[0].hide()
|
||||
SUB_ELEMENTS_[1].show()
|
||||
SUB_ELEMENTS_[2].show()
|
||||
"
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_mdyud"]
|
||||
resource_name = "scaling_mode"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": Viewport.SCALING_3D_MODE_BILINEAR,
|
||||
\"Bilinear\": Viewport.SCALING_3D_MODE_BILINEAR,
|
||||
\"FSR 2.2\": Viewport.SCALING_3D_MODE_FSR2
|
||||
}
|
||||
|
||||
|
||||
# Loads the saved/default values of the element
|
||||
func load_settings() -> void:
|
||||
super.load_settings()
|
||||
# Check if TAA is selected
|
||||
call_deferred(\"check_anti_aliasing\")
|
||||
|
||||
|
||||
func option_selected(index: int) -> void:
|
||||
super.option_selected(index)
|
||||
# Check if TAA is selected
|
||||
check_anti_aliasing()
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
get_viewport().set_scaling_3d_mode(OPTION_LIST_[currentValue])
|
||||
if currentValue == \"Disabled\":
|
||||
get_viewport().set_scaling_3d_scale(1.0)
|
||||
|
||||
|
||||
# Checks if TAA is selected while FSR 2.2 is enabled
|
||||
func check_anti_aliasing() -> void:
|
||||
if not ParentRef.ELEMENT_REFERENCE_TABLE_.has(\"AntiAliasing\"):
|
||||
return
|
||||
|
||||
var AntiAliasingRef: SettingsElement =\\
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[\"AntiAliasing\"]
|
||||
var taaIndex: int = AntiAliasingRef.OPTION_LIST_.find(\"TAA\")
|
||||
|
||||
if currentValue != \"FSR 2.2\":
|
||||
AntiAliasingRef.OptionsRef.set_item_disabled(
|
||||
taaIndex,
|
||||
false
|
||||
)
|
||||
return
|
||||
|
||||
AntiAliasingRef.OptionsRef.set_item_disabled(
|
||||
taaIndex,
|
||||
true
|
||||
)
|
||||
if AntiAliasingRef.currentValue == \"TAA\":
|
||||
var disabledIndex: int = AntiAliasingRef.OPTION_LIST_.find(\"Disabled\")
|
||||
# Reselect the anti aliasing mode
|
||||
AntiAliasingRef.OptionsRef.select(disabledIndex)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="Scaler" type="VBoxContainer" node_paths=PackedStringArray("MainElementRef", "SUB_ELEMENTS_")]
|
||||
offset_top = 51.0
|
||||
offset_right = 1152.0
|
||||
offset_bottom = 51.0
|
||||
script = SubResource("GDScript_bn0b0")
|
||||
MainElementRef = NodePath("ScalingMode")
|
||||
SUB_ELEMENTS_ = [NodePath("ResolutionScale"), NodePath("FSRMode"), NodePath("FSRSharpness")]
|
||||
|
||||
[node name="ScalingMode" type="HBoxContainer" parent="." node_paths=PackedStringArray("OptionsRef")]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
script = SubResource("GDScript_mdyud")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "ScalingMode"
|
||||
|
||||
[node name="Label" type="Label" parent="ScalingMode"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Scaling Mode"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="ScalingMode"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
|
||||
[node name="ResolutionScale" parent="." instance=ExtResource("1_4irey")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="FSRMode" parent="." instance=ExtResource("2_w65g1")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FSRSharpness" parent="." instance=ExtResource("3_v8pix")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,53 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://ddykljx6ndodi"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_6k8bu"]
|
||||
resource_name = "sdfgi_quality"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": null,
|
||||
\"Low\": RenderingServer.ENV_SDFGI_RAY_COUNT_8,
|
||||
\"Medium\": RenderingServer.ENV_SDFGI_RAY_COUNT_32,
|
||||
\"High\": RenderingServer.ENV_SDFGI_RAY_COUNT_96
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
|
||||
if currentValue == \"Disabled\":
|
||||
return
|
||||
|
||||
RenderingServer.environment_set_sdfgi_ray_count(OPTION_LIST_[currentValue])
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="SDFGIQuality" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
tooltip_text = "Signed Distance Field Global Illumination"
|
||||
script = SubResource("GDScript_6k8bu")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "SDFGIQuality"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "SDFGI Quality"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,50 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cgqiotob5aaoq"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_v3ktk"]
|
||||
resource_name = "shadow_quality"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Low\": RenderingServer.SHADOW_QUALITY_SOFT_LOW,
|
||||
\"Medium\": RenderingServer.SHADOW_QUALITY_SOFT_MEDIUM,
|
||||
\"High\": RenderingServer.SHADOW_QUALITY_SOFT_HIGH
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
RenderingServer.directional_soft_shadow_filter_set_quality(
|
||||
OPTION_LIST_[currentValue]
|
||||
)
|
||||
RenderingServer.positional_soft_shadow_filter_set_quality(
|
||||
OPTION_LIST_[currentValue]
|
||||
)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="ShadowQuality" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_v3ktk")
|
||||
DEFAULT_VALUE = "Low"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "ShadowQuality"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Shadow Quality"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,78 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bk5ky60jln7ag"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_h10e0"]
|
||||
resource_name = "ssao_quality"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": null,
|
||||
\"Low\": {
|
||||
\"quality\": RenderingServer.ENV_SSAO_QUALITY_LOW,
|
||||
\"halfSize\": true,
|
||||
\"blurPasses\": 1,
|
||||
\"fadeOutFrom\": 25,
|
||||
\"fadeOutTo\": 150
|
||||
},
|
||||
\"Medium\": {
|
||||
\"quality\": RenderingServer.ENV_SSAO_QUALITY_MEDIUM,
|
||||
\"halfSize\": true,
|
||||
\"blurPasses\": 2,
|
||||
\"fadeOutFrom\": 50,
|
||||
\"fadeOutTo\": 300
|
||||
},
|
||||
\"High\": {
|
||||
\"quality\": RenderingServer.ENV_SSAO_QUALITY_HIGH,
|
||||
\"halfSize\": false,
|
||||
\"blurPasses\": 4,
|
||||
\"fadeOutFrom\": 100,
|
||||
\"fadeOutTo\": 600
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
|
||||
if currentValue == \"Disabled\":
|
||||
return
|
||||
|
||||
RenderingServer.environment_set_ssao_quality(
|
||||
OPTION_LIST_[currentValue][\"quality\"],
|
||||
OPTION_LIST_[currentValue][\"halfSize\"],
|
||||
0.5,
|
||||
OPTION_LIST_[currentValue][\"blurPasses\"],
|
||||
OPTION_LIST_[currentValue][\"fadeOutFrom\"],
|
||||
OPTION_LIST_[currentValue][\"fadeOutTo\"]
|
||||
)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="SSAOQuality" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
tooltip_text = "Screen Space Ambient Occlusion"
|
||||
script = SubResource("GDScript_h10e0")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "SSAOQuality"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "SSAO Quality"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,78 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://bmnvig4gfqj0c"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_fwd72"]
|
||||
resource_name = "ssil_quality"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": null,
|
||||
\"Low\": {
|
||||
\"quality\": RenderingServer.ENV_SSIL_QUALITY_LOW,
|
||||
\"halfSize\": true,
|
||||
\"blurPasses\": 2,
|
||||
\"fadeOutFrom\": 25,
|
||||
\"fadeOutTo\": 150
|
||||
},
|
||||
\"Medium\": {
|
||||
\"quality\": RenderingServer.ENV_SSIL_QUALITY_MEDIUM,
|
||||
\"halfSize\": true,
|
||||
\"blurPasses\": 4,
|
||||
\"fadeOutFrom\": 50,
|
||||
\"fadeOutTo\": 300
|
||||
},
|
||||
\"High\": {
|
||||
\"quality\": RenderingServer.ENV_SSIL_QUALITY_HIGH,
|
||||
\"halfSize\": false,
|
||||
\"blurPasses\": 8,
|
||||
\"fadeOutFrom\": 100,
|
||||
\"fadeOutTo\": 600
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(currentValue)
|
||||
|
||||
if currentValue == \"Disabled\":
|
||||
return
|
||||
|
||||
RenderingServer.environment_set_ssil_quality(
|
||||
OPTION_LIST_[currentValue][\"quality\"],
|
||||
OPTION_LIST_[currentValue][\"halfSize\"],
|
||||
0.5,
|
||||
OPTION_LIST_[currentValue][\"blurPasses\"],
|
||||
OPTION_LIST_[currentValue][\"fadeOutFrom\"],
|
||||
OPTION_LIST_[currentValue][\"fadeOutTo\"]
|
||||
)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="SSILQuality" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
tooltip_text = "Screen Space Indirect Lighting"
|
||||
script = SubResource("GDScript_fwd72")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "SSILQuality"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "SSIL Quality"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,70 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cqfr01uk73ce5"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_v8qca"]
|
||||
resource_name = "ssr_quality"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": null,
|
||||
\"Low\": {
|
||||
\"roughnessQuality\": RenderingServer.ENV_SSR_ROUGHNESS_QUALITY_LOW,
|
||||
\"maxSteps\": 32,
|
||||
\"fadeIn\": 0.3,
|
||||
\"fadeOut\": 1.0
|
||||
},
|
||||
\"Medium\": {
|
||||
\"roughnessQuality\": RenderingServer.ENV_SSR_ROUGHNESS_QUALITY_MEDIUM,
|
||||
\"maxSteps\": 64,
|
||||
\"fadeIn\": 0.15,
|
||||
\"fadeOut\": 2.0
|
||||
},
|
||||
\"High\": {
|
||||
\"roughnessQuality\": RenderingServer.ENV_SSR_ROUGHNESS_QUALITY_HIGH,
|
||||
\"maxSteps\": 128,
|
||||
\"fadeIn\": 0.075,
|
||||
\"fadeOut\": 4.0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
apply_in_game_setting(OPTION_LIST_[currentValue])
|
||||
|
||||
if currentValue == \"Disabled\":
|
||||
return
|
||||
|
||||
RenderingServer.environment_set_ssr_roughness_quality(
|
||||
OPTION_LIST_[currentValue][\"roughnessQuality\"]
|
||||
)
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="SSRQuality" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
tooltip_text = "Screen Space Reflection"
|
||||
script = SubResource("GDScript_v8qca")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "SSRQuality"
|
||||
IS_IN_GAME_SETTING = true
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "SSR Quality"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,96 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://idtbqnsqlvb6"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_kwfgn"]
|
||||
resource_name = "vsync"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Disabled\": DisplayServer.VSYNC_DISABLED,
|
||||
\"Enabled\": DisplayServer.VSYNC_ENABLED,
|
||||
\"Adaptive\": DisplayServer.VSYNC_ADAPTIVE
|
||||
}
|
||||
|
||||
|
||||
# Loads the saved/default values of the element
|
||||
func load_settings() -> void:
|
||||
super.load_settings()
|
||||
# Toggle the max fps element
|
||||
call_deferred(\"toggle_max_fps\")
|
||||
|
||||
|
||||
func option_selected(index: int) -> void:
|
||||
super.option_selected(index)
|
||||
# Toggle the max fps element
|
||||
toggle_max_fps()
|
||||
|
||||
|
||||
# Called to apply the settings in the settings cache
|
||||
func _apply_settings() -> void:
|
||||
# Set the vsync mode to the selected option
|
||||
DisplayServer.window_set_vsync_mode(OPTION_LIST_[currentValue])
|
||||
|
||||
# Set the max fps to unlimited if vsync is being enabled
|
||||
if currentValue != \"Disabled\":
|
||||
Engine.set_max_fps(0)
|
||||
|
||||
# Check if the max fps element exists and if vsync is disabled
|
||||
if (
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_.has(\"MaxFPS\")
|
||||
and currentValue == \"Disabled\"
|
||||
):
|
||||
# Check if max fps has been changed
|
||||
if not ParentRef.changedElements_.has(\"MaxFPS\"):
|
||||
# Apply the max fps settings manually
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[\"MaxFPS\"]._apply_settings()
|
||||
elif currentValue == \"Disabled\":
|
||||
# Set the max fps to the max fps read from the project settings
|
||||
Engine.set_max_fps(ProjectSettings.get_setting(\"application/run/max_fps\"))
|
||||
|
||||
|
||||
|
||||
# Disable/Enable the max fps element according to if vsync is on or not
|
||||
func toggle_max_fps() -> void:
|
||||
if not ParentRef.ELEMENT_REFERENCE_TABLE_.has(\"MaxFPS\"):
|
||||
return
|
||||
|
||||
# Reference to the slider value node of the max fps element
|
||||
var MaxFpsRef: SettingsElement =\\
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[\"MaxFPS\"]
|
||||
|
||||
if currentValue == \"Disabled\":
|
||||
# Enable the max fps element
|
||||
MaxFpsRef.SliderRef.set_editable(true)
|
||||
MaxFpsRef.ValueBoxRef.modulate = Color.WHITE
|
||||
else:
|
||||
# Disable the max fps element
|
||||
MaxFpsRef.SliderRef.set_editable(false)
|
||||
MaxFpsRef.ValueBoxRef.modulate = Color.GRAY
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="VSync" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_kwfgn")
|
||||
DEFAULT_VALUE = "Disabled"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "VSync"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "V-Sync"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,14 @@
|
||||
[gd_scene format=3 uid="uid://d0rkws47yf8l2"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d3nlqtnyyndrg" path="res://addons/modular-settings-menu/scripts/base-settings-elements/button_element.gd" id="1_cnjcn"]
|
||||
[ext_resource type="PackedScene" uid="uid://cwhs0kpipkxfv" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/element-panel-template/element_panel_template.tscn" id="2_gbpfn"]
|
||||
|
||||
[node name="ButtonElementTemplate" type="Button"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
text = "Button Element"
|
||||
script = ExtResource("1_cnjcn")
|
||||
ElementPanelScene = ExtResource("2_gbpfn")
|
||||
@@ -0,0 +1,76 @@
|
||||
[gd_scene format=3 uid="uid://cwhs0kpipkxfv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://cyig515shrgnb" path="res://addons/modular-settings-menu/scripts/element_panel.gd" id="1_3f2r5"]
|
||||
[ext_resource type="PackedScene" uid="uid://bjcuw6amean2" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/slider_element_template.tscn" id="2_fpsnu"]
|
||||
|
||||
[node name="ElementPanelTemplate" 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_3f2r5")
|
||||
IDENTIFIER = "PanelTemplate"
|
||||
|
||||
[node name="VBoxContainer" type="VBoxContainer" parent="."]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -194.0
|
||||
offset_top = -29.0
|
||||
offset_right = 194.0
|
||||
offset_bottom = 30.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="PanelContainer" type="PanelContainer" parent="VBoxContainer"]
|
||||
custom_minimum_size = Vector2(0, 280)
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/PanelContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer/PanelContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer/PanelContainer/MarginContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ElementList" type="VBoxContainer" parent="VBoxContainer/PanelContainer/MarginContainer/ScrollContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SliderElementTemplate" parent="VBoxContainer/PanelContainer/MarginContainer/ScrollContainer/MarginContainer/ElementList" instance=ExtResource("2_fpsnu")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ApplyButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
layout_direction = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
disabled = true
|
||||
text = "Apply"
|
||||
|
||||
[node name="BackButton" type="Button" parent="VBoxContainer/HBoxContainer"]
|
||||
layout_direction = 1
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
text = "Back"
|
||||
@@ -0,0 +1,46 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://vlmvkci3ptii"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_sk6j2"]
|
||||
resource_name = "option_element_template"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
# Provide the options for the element
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"None\": null,
|
||||
\"Slider\": null,
|
||||
\"Toggle\": null
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the setting to the game
|
||||
func _apply_settings() -> void:
|
||||
pass
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="MainElement" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_sk6j2")
|
||||
DEFAULT_VALUE = "None"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "MainElement"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Option Element"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,43 @@
|
||||
[gd_scene format=3 uid="uid://csr6kawyf3t3i"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://vlmvkci3ptii" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/multi-element-template/main_element.tscn" id="1_mhqaj"]
|
||||
[ext_resource type="PackedScene" uid="uid://bjcuw6amean2" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/slider_element_template.tscn" id="2_mf8gn"]
|
||||
[ext_resource type="PackedScene" uid="uid://cxaxyqer0af21" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/toggle_element_template.tscn" id="3_gs1f8"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_sk6j2"]
|
||||
resource_name = "multi_element_template"
|
||||
script/source = "extends MultiElement
|
||||
|
||||
|
||||
func _display_sub_elements() -> void:
|
||||
match currentValue:
|
||||
\"None\":
|
||||
for element in SUB_ELEMENTS_:
|
||||
element.hide()
|
||||
\"Slider\":
|
||||
SUB_ELEMENTS_[0].show()
|
||||
SUB_ELEMENTS_[1].hide()
|
||||
\"Toggle\":
|
||||
SUB_ELEMENTS_[0].hide()
|
||||
SUB_ELEMENTS_[1].show()
|
||||
"
|
||||
|
||||
[node name="MultiElementTemplate" type="VBoxContainer" node_paths=PackedStringArray("MainElementRef", "SUB_ELEMENTS_")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
size_flags_horizontal = 3
|
||||
script = SubResource("GDScript_sk6j2")
|
||||
MainElementRef = NodePath("MainElement")
|
||||
SUB_ELEMENTS_ = [NodePath("SliderElementTemplate"), NodePath("ToggleElementTemplate")]
|
||||
|
||||
[node name="MainElement" parent="." instance=ExtResource("1_mhqaj")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SliderElementTemplate" parent="." instance=ExtResource("2_mf8gn")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ToggleElementTemplate" parent="." instance=ExtResource("3_gs1f8")]
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,44 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://dc1yif146sxav"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_sk6j2"]
|
||||
resource_name = "option_element_template"
|
||||
script/source = "extends OptionElement
|
||||
|
||||
|
||||
# Provide the options for the element
|
||||
func _init() -> void:
|
||||
OPTION_LIST_ = {
|
||||
\"Example\": null
|
||||
}
|
||||
|
||||
|
||||
# Called to apply the setting to the game
|
||||
func _apply_settings() -> void:
|
||||
pass
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="OptionElementTemplate" type="HBoxContainer" node_paths=PackedStringArray("OptionsRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_sk6j2")
|
||||
DEFAULT_VALUE = "Example"
|
||||
OptionsRef = NodePath("Options")
|
||||
IDENTIFIER = "OptionTemplate"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Option Element"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Options" type="OptionButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,78 @@
|
||||
[gd_scene format=3 uid="uid://ejplmui1twn4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ssroxjs8wt" path="res://addons/modular-settings-menu/scripts/settings_section.gd" id="1_aglse"]
|
||||
[ext_resource type="PackedScene" uid="uid://dc1yif146sxav" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/option_element_template.tscn" id="2_ws4gk"]
|
||||
[ext_resource type="PackedScene" uid="uid://csr6kawyf3t3i" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/multi-element-template/multi_element_template.tscn" id="2_xre3j"]
|
||||
[ext_resource type="PackedScene" uid="uid://bjcuw6amean2" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/slider_element_template.tscn" id="3_o11e6"]
|
||||
[ext_resource type="PackedScene" uid="uid://cxaxyqer0af21" path="res://addons/modular-settings-menu/scenes/settings-elements/templates/toggle_element_template.tscn" id="4_41mog"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_e0spm"]
|
||||
|
||||
[node name="SectionTemplate" type="TabBar"]
|
||||
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
|
||||
theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_e0spm")
|
||||
script = ExtResource("1_aglse")
|
||||
IDENTIFIER = "ExampleSection"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
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 = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ElementList" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="ParentElementTemplate" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList" instance=ExtResource("2_xre3j")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSection" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/SubSection"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "Sub Section"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/SubSection"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/SubSection"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="OptionElementTemplate" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/SubSection/SubSectionElements" instance=ExtResource("2_ws4gk")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SliderElementTemplate" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/SubSection/SubSectionElements" instance=ExtResource("3_o11e6")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ToggleElementTemplate" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/SubSection/SubSectionElements" instance=ExtResource("4_41mog")]
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,57 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://bjcuw6amean2"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_i57rt"]
|
||||
resource_name = "slider_element_template"
|
||||
script/source = "extends SliderElement
|
||||
|
||||
|
||||
# Called to apply the setting to the game
|
||||
func _apply_settings() -> void:
|
||||
pass
|
||||
"
|
||||
|
||||
[sub_resource type="PlaceholderTexture2D" id="PlaceholderTexture2D_hlot4"]
|
||||
size = Vector2(0, 0)
|
||||
|
||||
[sub_resource type="Theme" id="Theme_4i2xw"]
|
||||
SpinBox/icons/updown = SubResource("PlaceholderTexture2D_hlot4")
|
||||
|
||||
[node name="SliderElementTemplate" type="HBoxContainer" node_paths=PackedStringArray("SliderRef", "ValueBoxRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_i57rt")
|
||||
SliderRef = NodePath("SliderValue/Slider")
|
||||
ValueBoxRef = NodePath("SliderValue/Value")
|
||||
IDENTIFIER = "SliderTemplate"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Slider Element"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="SliderValue" type="HBoxContainer" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_constants/separation = 6
|
||||
|
||||
[node name="Slider" type="HSlider" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
ticks_on_borders = true
|
||||
|
||||
[node name="Value" type="SpinBox" parent="SliderValue"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 8
|
||||
size_flags_vertical = 4
|
||||
theme = SubResource("Theme_4i2xw")
|
||||
max_value = 0.0
|
||||
step = 0.0
|
||||
alignment = 2
|
||||
@@ -0,0 +1,36 @@
|
||||
[gd_scene load_steps=3 format=3 uid="uid://cxaxyqer0af21"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_bpxmf"]
|
||||
resource_name = "toggle_element_template"
|
||||
script/source = "extends ToggleElement
|
||||
|
||||
|
||||
# Called to apply the setting to the game
|
||||
func _apply_settings() -> void:
|
||||
pass
|
||||
"
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_drjjf"]
|
||||
|
||||
[node name="ToggleElementTemplate" type="HBoxContainer" node_paths=PackedStringArray("ToggleRef")]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = SubResource("GDScript_bpxmf")
|
||||
ToggleRef = NodePath("Toggle")
|
||||
IDENTIFIER = "ToggleTemplate"
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 1
|
||||
text = "Toggle Element"
|
||||
vertical_alignment = 1
|
||||
|
||||
[node name="Toggle" type="CheckButton" parent="."]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
focus_mode = 0
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_drjjf")
|
||||
@@ -0,0 +1,74 @@
|
||||
[gd_scene format=3 uid="uid://y5oxvao3aqtb"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ssroxjs8wt" path="res://addons/modular-settings-menu/scripts/settings_section.gd" id="1_e0sxq"]
|
||||
[ext_resource type="PackedScene" uid="uid://pir75xaw2g08" path="res://addons/modular-settings-menu/scenes/settings-elements/audio-elements/master_volume.tscn" id="2_l5q4d"]
|
||||
[ext_resource type="PackedScene" uid="uid://y6kuxwyem48c" path="res://addons/modular-settings-menu/scenes/settings-elements/audio-elements/music_volume.tscn" id="3_v08xa"]
|
||||
[ext_resource type="PackedScene" uid="uid://jl3iirunm0hq" path="res://addons/modular-settings-menu/scenes/settings-elements/audio-elements/sfx_volume.tscn" id="4_j1ron"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_e0spm"]
|
||||
|
||||
[node name="Audio" type="TabBar"]
|
||||
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
|
||||
theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_e0spm")
|
||||
script = ExtResource("1_e0sxq")
|
||||
IDENTIFIER = "Audio"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
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 = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ElementList" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="VolumeSettings" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/VolumeSettings"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "Volume Settings"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/VolumeSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/VolumeSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MasterVolume" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/VolumeSettings/SubSectionElements" instance=ExtResource("2_l5q4d")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="MusicVolume" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/VolumeSettings/SubSectionElements" instance=ExtResource("3_v08xa")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SFXVolume" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/VolumeSettings/SubSectionElements" instance=ExtResource("4_j1ron")]
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,86 @@
|
||||
[gd_scene format=3 uid="uid://dfswr81erouhj"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ssroxjs8wt" path="res://addons/modular-settings-menu/scripts/settings_section.gd" id="1_vmore"]
|
||||
[ext_resource type="PackedScene" uid="uid://cy8n6yalxprb7" path="res://addons/modular-settings-menu/scenes/settings-elements/controls-elements/sensitivity.tscn" id="2_qcqml"]
|
||||
[ext_resource type="PackedScene" uid="uid://c2tgt7fu0n5wp" path="res://addons/modular-settings-menu/scenes/settings-elements/controls-elements/invert_y.tscn" id="3_8np8q"]
|
||||
[ext_resource type="PackedScene" uid="uid://i0w5gftb0j16" path="res://addons/modular-settings-menu/scenes/settings-elements/controls-elements/input_settings.tscn" id="4_bejag"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_e0spm"]
|
||||
|
||||
[node name="Controls" type="TabBar"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_e0spm")
|
||||
script = ExtResource("1_vmore")
|
||||
IDENTIFIER = "Controls"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
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 = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ElementList" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="MouseSettings" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/MouseSettings"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "Mouse Settings"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/MouseSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/MouseSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Sensitivity" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/MouseSettings/SubSectionElements" instance=ExtResource("2_qcqml")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="InvertY" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/MouseSettings/SubSectionElements" instance=ExtResource("3_8np8q")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="KeyboardSettings" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/KeyboardSettings"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "Keyboard Settings"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/KeyboardSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/KeyboardSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="InputSettings" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/KeyboardSettings/SubSectionElements" instance=ExtResource("4_bejag")]
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,66 @@
|
||||
[gd_scene format=3 uid="uid://c66v42g6gs7gr"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ssroxjs8wt" path="res://addons/modular-settings-menu/scripts/settings_section.gd" id="1_i11k5"]
|
||||
[ext_resource type="PackedScene" uid="uid://elu1vc0ox472" path="res://addons/modular-settings-menu/scenes/settings-elements/gameplay-elements/fov.tscn" id="2_c8t76"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_e0spm"]
|
||||
|
||||
[node name="Gameplay" type="TabBar"]
|
||||
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
|
||||
theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_e0spm")
|
||||
script = ExtResource("1_i11k5")
|
||||
IDENTIFIER = "Gameplay"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
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 = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ElementList" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="GeneralSettings" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/GeneralSettings"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "General Settings"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/GeneralSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/GeneralSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="FOV" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/GeneralSettings/SubSectionElements" instance=ExtResource("2_c8t76")]
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,129 @@
|
||||
[gd_scene format=3 uid="uid://buqq0kms2dbb4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://c3ssroxjs8wt" path="res://addons/modular-settings-menu/scripts/settings_section.gd" id="1_704sp"]
|
||||
[ext_resource type="PackedScene" uid="uid://byff0jwaicxvr" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/display_mode.tscn" id="1_mr6e7"]
|
||||
[ext_resource type="PackedScene" uid="uid://cn8r63dmvd55c" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/resolution.tscn" id="2_5bpi0"]
|
||||
[ext_resource type="PackedScene" uid="uid://b3w7qpn4nhmu2" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/scaler.tscn" id="4_g2t2s"]
|
||||
[ext_resource type="PackedScene" uid="uid://dghfxwcbi5ig" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/max_fps.tscn" id="5_82fyi"]
|
||||
[ext_resource type="PackedScene" uid="uid://idtbqnsqlvb6" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/vsync.tscn" id="6_2rh1a"]
|
||||
[ext_resource type="PackedScene" uid="uid://csg6c3uuct1ls" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/anti_aliasing.tscn" id="7_r8hxv"]
|
||||
[ext_resource type="PackedScene" uid="uid://3ckate3v614f" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/depth_of_field.tscn" id="8_28f8l"]
|
||||
[ext_resource type="PackedScene" uid="uid://cgqiotob5aaoq" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/shadow_quality.tscn" id="9_1x78v"]
|
||||
[ext_resource type="PackedScene" uid="uid://cqfr01uk73ce5" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/ssr_quality.tscn" id="10_cfuis"]
|
||||
[ext_resource type="PackedScene" uid="uid://du5urp5d2dyjb" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/glow_quality.tscn" id="10_m0pim"]
|
||||
[ext_resource type="PackedScene" uid="uid://bk5ky60jln7ag" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/ssao_quality.tscn" id="11_xa1gl"]
|
||||
[ext_resource type="PackedScene" uid="uid://bmnvig4gfqj0c" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/ssil_quality.tscn" id="12_jqvyp"]
|
||||
[ext_resource type="PackedScene" uid="uid://ddykljx6ndodi" path="res://addons/modular-settings-menu/scenes/settings-elements/graphics-elements/sdfgi_quality.tscn" id="13_ifeh4"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_v0fou"]
|
||||
|
||||
[node name="Graphics" type="TabBar"]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_v0fou")
|
||||
script = ExtResource("1_704sp")
|
||||
IDENTIFIER = "Graphics"
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="."]
|
||||
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 = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer"]
|
||||
layout_mode = 2
|
||||
horizontal_scroll_mode = 0
|
||||
|
||||
[node name="MarginContainer" type="MarginContainer" parent="MarginContainer/ScrollContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/margin_left = 8
|
||||
theme_override_constants/margin_top = 8
|
||||
theme_override_constants/margin_right = 8
|
||||
theme_override_constants/margin_bottom = 8
|
||||
|
||||
[node name="ElementList" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
size_flags_vertical = 3
|
||||
theme_override_constants/separation = 24
|
||||
|
||||
[node name="BasicSettings" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/BasicSettings"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "Basic Settings"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/BasicSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/BasicSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="DisplayMode" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/BasicSettings/SubSectionElements" instance=ExtResource("1_mr6e7")]
|
||||
layout_mode = 2
|
||||
defaultValue = "Windowed"
|
||||
|
||||
[node name="Resolution" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/BasicSettings/SubSectionElements" instance=ExtResource("2_5bpi0")]
|
||||
layout_mode = 2
|
||||
defaultValue = "1280x720"
|
||||
|
||||
[node name="MaxFPS" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/BasicSettings/SubSectionElements" instance=ExtResource("5_82fyi")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="AdvancedSettings" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionName" type="Label" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 20
|
||||
text = "Advanced Settings
|
||||
"
|
||||
|
||||
[node name="HSeparator" type="HSeparator" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SubSectionElements" type="VBoxContainer" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings"]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="Scaler" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("4_g2t2s")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="AntiAliasing" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("7_r8hxv")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="VSync" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("6_2rh1a")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="DepthOfField" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("8_28f8l")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ShadowQuality" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("9_1x78v")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="GlowQuality" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("10_m0pim")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SSRQuality" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("10_cfuis")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SSAOQuality" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("11_xa1gl")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SSILQuality" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("12_jqvyp")]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="SDFGIQuality" parent="MarginContainer/ScrollContainer/MarginContainer/ElementList/AdvancedSettings/SubSectionElements" instance=ExtResource("13_ifeh4")]
|
||||
layout_mode = 2
|
||||
@@ -0,0 +1,97 @@
|
||||
[gd_scene format=3 uid="uid://px6a2dg8cawb"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://houdhjao14e7" path="res://addons/modular-settings-menu/scripts/settings_menu.gd" id="1_crapp"]
|
||||
[ext_resource type="PackedScene" uid="uid://c66v42g6gs7gr" path="res://addons/modular-settings-menu/scenes/settings-sections/gameplay.tscn" id="2_kjxrg"]
|
||||
[ext_resource type="PackedScene" uid="uid://buqq0kms2dbb4" path="res://addons/modular-settings-menu/scenes/settings-sections/graphics.tscn" id="3_8fcn6"]
|
||||
[ext_resource type="PackedScene" uid="uid://dfswr81erouhj" path="res://addons/modular-settings-menu/scenes/settings-sections/controls.tscn" id="4_3a4pu"]
|
||||
[ext_resource type="PackedScene" uid="uid://dvkksl3mrnoto" path="res://addons/modular-settings-menu/scenes/settings-elements/discard_changes_popup.tscn" id="4_yfemx"]
|
||||
[ext_resource type="PackedScene" uid="uid://y5oxvao3aqtb" path="res://addons/modular-settings-menu/scenes/settings-sections/audio.tscn" id="5_ayxwc"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_kwbsm"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_ntlmy"]
|
||||
|
||||
[sub_resource type="StyleBoxEmpty" id="StyleBoxEmpty_qp71p"]
|
||||
|
||||
[node name="Settings" type="Control" unique_id=1487060885]
|
||||
layout_mode = 3
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 1
|
||||
script = ExtResource("1_crapp")
|
||||
|
||||
[node name="SettingsPanel" type="VBoxContainer" parent="." unique_id=481915833]
|
||||
layout_mode = 1
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -320.0
|
||||
offset_top = -270.0
|
||||
offset_right = 320.0
|
||||
offset_bottom = 270.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="SettingsTabs" type="TabContainer" parent="SettingsPanel" unique_id=1124467818]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 3
|
||||
theme_override_styles/tab_focus = SubResource("StyleBoxEmpty_kwbsm")
|
||||
current_tab = 0
|
||||
|
||||
[node name="Gameplay" parent="SettingsPanel/SettingsTabs" unique_id=354139496 instance=ExtResource("2_kjxrg")]
|
||||
layout_mode = 2
|
||||
metadata/_tab_index = 0
|
||||
|
||||
[node name="Graphics" parent="SettingsPanel/SettingsTabs" unique_id=1265630621 instance=ExtResource("3_8fcn6")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
metadata/_tab_index = 1
|
||||
|
||||
[node name="Controls" parent="SettingsPanel/SettingsTabs" unique_id=1352859195 instance=ExtResource("4_3a4pu")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
metadata/_tab_index = 2
|
||||
|
||||
[node name="Audio" parent="SettingsPanel/SettingsTabs" unique_id=1839468677 instance=ExtResource("5_ayxwc")]
|
||||
visible = false
|
||||
layout_mode = 2
|
||||
metadata/_tab_index = 3
|
||||
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="SettingsPanel" unique_id=1987062525]
|
||||
layout_mode = 2
|
||||
|
||||
[node name="ApplyButton" type="Button" parent="SettingsPanel/HBoxContainer" unique_id=266503706]
|
||||
unique_name_in_owner = true
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_ntlmy")
|
||||
disabled = true
|
||||
text = "Apply"
|
||||
|
||||
[node name="BackButton" type="Button" parent="SettingsPanel/HBoxContainer" unique_id=1620563241]
|
||||
layout_mode = 2
|
||||
size_flags_horizontal = 3
|
||||
theme_override_styles/focus = SubResource("StyleBoxEmpty_qp71p")
|
||||
text = "Back"
|
||||
|
||||
[node name="ElementPanels" type="Control" parent="." unique_id=703442684]
|
||||
layout_mode = 1
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
mouse_filter = 2
|
||||
|
||||
[node name="DiscardChangesPopup" parent="." unique_id=1211622821 instance=ExtResource("4_yfemx")]
|
||||
visible = false
|
||||
layout_mode = 1
|
||||
|
||||
[connection signal="visibility_changed" from="." to="." method="on_visibility_changed"]
|
||||
[connection signal="pressed" from="SettingsPanel/HBoxContainer/ApplyButton" to="." method="on_apply_button_pressed"]
|
||||
[connection signal="pressed" from="SettingsPanel/HBoxContainer/BackButton" to="." method="on_back_button_pressed"]
|
||||
@@ -0,0 +1,40 @@
|
||||
extends Button
|
||||
class_name ButtonElement
|
||||
|
||||
## Reference to the element's panel scene.
|
||||
@export var ElementPanelScene: PackedScene
|
||||
|
||||
## Reference to the node the settings element is under.
|
||||
@onready var ParentRef: Node = owner
|
||||
|
||||
## Reference to the element's panel.
|
||||
var ElementPanelRef: Node
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect necessary signals
|
||||
connect("pressed", pressed)
|
||||
create_element_panel()
|
||||
|
||||
|
||||
func pressed() -> void:
|
||||
# Switch panels
|
||||
ParentRef.SettingsMenuRef.SettingsPanelRef.hide()
|
||||
ElementPanelRef.show()
|
||||
# Populate the settings cache of the panel
|
||||
ElementPanelRef.get_settings()
|
||||
|
||||
|
||||
## Called to create the element's panel.
|
||||
func create_element_panel() -> void:
|
||||
var ElementPanelsRef: Control = ParentRef.SettingsMenuRef.ElementPanelsRef
|
||||
ElementPanelRef = ElementPanelScene.instantiate()
|
||||
|
||||
# Check if the element panel exists
|
||||
if not ElementPanelsRef.find_child(ElementPanelRef.name):
|
||||
# Give a reference of the element
|
||||
ElementPanelRef.PanelOwnerRef = self
|
||||
ElementPanelRef.hide()
|
||||
# Add the panel to the element panels list
|
||||
ElementPanelsRef.add_child(ElementPanelRef)
|
||||
ElementPanelRef.set_owner(ParentRef.SettingsMenuRef)
|
||||
@@ -0,0 +1 @@
|
||||
uid://d3nlqtnyyndrg
|
||||
@@ -0,0 +1,67 @@
|
||||
extends Control
|
||||
class_name MultiElement
|
||||
## A wrapper node for multi elements.
|
||||
|
||||
@export var MainElementRef: SettingsElement
|
||||
@export var SUB_ELEMENTS_: Array[SettingsElement]
|
||||
|
||||
var ParentRef: SettingsSection
|
||||
|
||||
var currentValue :
|
||||
get:
|
||||
return MainElementRef.currentValue
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
ParentRef = owner
|
||||
ParentRef.connect("setting_changed", update_element)
|
||||
ParentRef.connect("apply_button_pressed", apply_settings)
|
||||
ParentRef.SettingsMenuRef.connect("changes_discarded", load_settings)
|
||||
SettingsDataManager.connect("settings_retrieved", load_settings)
|
||||
init_main_element()
|
||||
init_sub_elements()
|
||||
|
||||
|
||||
func init_main_element() -> void:
|
||||
var elementId: String = MainElementRef.IDENTIFIER
|
||||
MainElementRef.IS_MULTI_ELEMENT = true
|
||||
MainElementRef.ParentRef = ParentRef
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[elementId] = MainElementRef
|
||||
|
||||
|
||||
## Used to initialize sub elements of the multi element.
|
||||
func init_sub_elements() -> void:
|
||||
for ElementRef in SUB_ELEMENTS_:
|
||||
ElementRef.IS_MULTI_ELEMENT = true
|
||||
ElementRef.IS_SUB_ELEMENT = true
|
||||
ElementRef.ParentRef = ParentRef
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[ElementRef.IDENTIFIER] = ElementRef
|
||||
|
||||
|
||||
## Called when settings are loaded to display the appropriate elements.
|
||||
func load_settings() -> void:
|
||||
call_deferred("_display_sub_elements")
|
||||
|
||||
|
||||
## Called when the main element's value changes do display the appropriate elements.
|
||||
func update_element(elementId: String) -> void:
|
||||
if elementId == MainElementRef.IDENTIFIER:
|
||||
call_deferred("_display_sub_elements")
|
||||
|
||||
|
||||
## Called to update the visibility of sub elements based on the main elements's current value.
|
||||
## This function is overwritten by the multi element wrapper.
|
||||
func _display_sub_elements() -> void:
|
||||
return
|
||||
|
||||
|
||||
## Called when the apply button is pressed.
|
||||
func apply_settings() -> void:
|
||||
if ParentRef.changedElements_.has(MainElementRef.IDENTIFIER):
|
||||
for SubElementRef in SUB_ELEMENTS_:
|
||||
if (
|
||||
not SubElementRef.is_visible_in_tree()
|
||||
or ParentRef.changedElements_.has(SubElementRef.IDENTIFIER)
|
||||
):
|
||||
continue
|
||||
SubElementRef._apply_settings()
|
||||
@@ -0,0 +1 @@
|
||||
uid://c74spwofs62nw
|
||||
@@ -0,0 +1,72 @@
|
||||
extends SettingsElement
|
||||
class_name OptionElement
|
||||
## A settings element specifically for elements that have option buttons.
|
||||
|
||||
## Default value for the element.
|
||||
## Value has to exist in OPTION_LIST_ otherwise the first option will be used.
|
||||
@export var DEFAULT_VALUE: String
|
||||
|
||||
## Element node references
|
||||
@export var OptionsRef: OptionButton
|
||||
|
||||
## List of options related to the settings element
|
||||
var OPTION_LIST_
|
||||
|
||||
## Index of the currently selected item
|
||||
var selectedIndex: int
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
OPTION_LIST_.make_read_only()
|
||||
OptionsRef.connect("item_selected", option_selected)
|
||||
|
||||
|
||||
func init_element() -> void:
|
||||
fill_options_button()
|
||||
|
||||
|
||||
func get_valid_values() -> Dictionary:
|
||||
if not OPTION_LIST_.has(DEFAULT_VALUE):
|
||||
push_warning("Invalid default value for element '" + IDENTIFIER + "'.")
|
||||
if OPTION_LIST_ is Dictionary:
|
||||
DEFAULT_VALUE = OPTION_LIST_.keys()[0]
|
||||
else:
|
||||
DEFAULT_VALUE = OPTION_LIST_[0]
|
||||
|
||||
return {
|
||||
"defaultValue": DEFAULT_VALUE,
|
||||
"validOptions": OPTION_LIST_
|
||||
}
|
||||
|
||||
|
||||
## Used to initialize the option button element.
|
||||
func fill_options_button() -> void:
|
||||
var index: int = 0
|
||||
# Get the current item count of the option button
|
||||
var itemCount: int = OptionsRef.get_item_count()
|
||||
|
||||
# Add the options from the received option list of the element
|
||||
for option in OPTION_LIST_:
|
||||
# Check if the option button has not been initialized yet
|
||||
if itemCount == 0:
|
||||
OptionsRef.add_item(option, index)
|
||||
# Select the option that was loaded
|
||||
if option == currentValue:
|
||||
OptionsRef.select(index)
|
||||
selectedIndex = index
|
||||
|
||||
index += 1
|
||||
|
||||
|
||||
func option_selected(index: int) -> void:
|
||||
# Check if the settings menu is open
|
||||
if ParentRef.settingsCache_.size() > 0:
|
||||
# Update the settings cache with the selected option
|
||||
ParentRef.settingsCache_[IDENTIFIER] = OptionsRef.get_item_text(index)
|
||||
# Check if the selected value is different than the saved value
|
||||
ParentRef.settings_changed(IDENTIFIER)
|
||||
|
||||
# Update the element's values
|
||||
currentValue = OptionsRef.get_item_text(index)
|
||||
selectedIndex = index
|
||||
@@ -0,0 +1 @@
|
||||
uid://1dxqbc07as1r
|
||||
@@ -0,0 +1,205 @@
|
||||
extends Control
|
||||
class_name SettingsElement
|
||||
## The base script for settings elements.
|
||||
|
||||
## Identifier for the element.
|
||||
## This value is used as the key in the settings data.
|
||||
@export var IDENTIFIER: String = "Element"
|
||||
|
||||
## Toggle based on whether the element handles a setting that requires an in game node to exist.
|
||||
@export var IS_IN_GAME_SETTING: bool
|
||||
|
||||
## The name of the section the element is under.
|
||||
@onready var SECTION: String = ParentRef.IDENTIFIER
|
||||
|
||||
## Reference to the section the settings element is under.
|
||||
var ParentRef: SettingsSection
|
||||
|
||||
# Multi element flags
|
||||
## Flag to turn an element into the main element of a multi element.
|
||||
var IS_MULTI_ELEMENT: bool = false
|
||||
## Flag to turn an element into a sub element of a multi element.
|
||||
var IS_SUB_ELEMENT: bool = false
|
||||
|
||||
## Current value of the element.
|
||||
var currentValue
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
if not IS_MULTI_ELEMENT:
|
||||
ParentRef = owner
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
SettingsDataManager.connect("settings_retrieved", load_settings)
|
||||
# Check if the element is a sub element
|
||||
if not IS_SUB_ELEMENT:
|
||||
ParentRef.connect("apply_button_pressed", _apply_settings)
|
||||
# Add an entry of the settings element to the section's reference table
|
||||
ParentRef.ELEMENT_REFERENCE_TABLE_[IDENTIFIER] = self
|
||||
|
||||
|
||||
## Used to initialize a settings element.
|
||||
## This function is overwritten by each [b]type[/b] of element.
|
||||
func init_element() -> void:
|
||||
return
|
||||
|
||||
|
||||
## Loads the saved or default value of the element.
|
||||
func load_settings() -> void:
|
||||
# List of valid values for the element
|
||||
var VALUES_: Dictionary = get_valid_values()
|
||||
VALUES_.make_read_only()
|
||||
|
||||
# Check if no save file exists
|
||||
if SettingsDataManager.noSaveFile:
|
||||
# Assign default value as current value
|
||||
currentValue = VALUES_["defaultValue"]
|
||||
# Add default value of element to the settings data
|
||||
SettingsDataManager.settingsData_[SECTION][IDENTIFIER] = currentValue
|
||||
else:
|
||||
# Verify the existance and validity of the element in the settings data
|
||||
if verify_settings_data(VALUES_):
|
||||
# Get the current value from the settings data
|
||||
currentValue = SettingsDataManager.settingsData_[SECTION][IDENTIFIER]
|
||||
else:
|
||||
# Assign default value as current value
|
||||
currentValue = VALUES_["defaultValue"]
|
||||
# Add default value of the element to the settings data
|
||||
SettingsDataManager.settingsData_[SECTION][IDENTIFIER] = currentValue
|
||||
SettingsDataManager.invalidSaveFile = true
|
||||
|
||||
init_element()
|
||||
|
||||
# Check if the current element is in an in game menu or if it is a sub element
|
||||
if (
|
||||
ParentRef.SettingsMenuRef.IS_IN_GAME_MENU == IS_IN_GAME_SETTING
|
||||
or not IS_SUB_ELEMENT
|
||||
):
|
||||
# Apply the loaded values to the game
|
||||
call_deferred("_apply_settings")
|
||||
|
||||
|
||||
## Used to get the valid values an element can have for validating settings data.
|
||||
## This function is overwritten by each [b]type[/b] of element.
|
||||
func get_valid_values() -> Dictionary:
|
||||
return {}
|
||||
|
||||
|
||||
## Checks if the loaded values are valid for the element.
|
||||
## If a value is wrong, it will be fixed automatically.
|
||||
func verify_settings_data(VALUES_: Dictionary) -> bool:
|
||||
# Check if an entry exists for the element
|
||||
if not entry_exists():
|
||||
return false
|
||||
|
||||
# Get the value of the element
|
||||
var RETRIEVED_VALUE = SettingsDataManager.settingsData_[SECTION][IDENTIFIER]
|
||||
|
||||
# Check if the retrieved value is the correct type
|
||||
if not is_valid_type(VALUES_, RETRIEVED_VALUE):
|
||||
return false
|
||||
|
||||
# Check if the retrieved value has the expected value
|
||||
if not is_valid_value(VALUES_, RETRIEVED_VALUE):
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
## Used by verify_settings_data() to check if the element
|
||||
## and the section it is under exists in the settings data.
|
||||
func entry_exists() -> bool:
|
||||
# Check if the section exists in settings data
|
||||
if not SettingsDataManager.settingsData_.has(SECTION):
|
||||
push_warning("Settings section missing: ", SECTION)
|
||||
return false
|
||||
|
||||
# Check if the element exists in the settings data
|
||||
if not SettingsDataManager.settingsData_[SECTION].has(IDENTIFIER):
|
||||
push_warning("Settings element is missing: ", IDENTIFIER)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
## Used by verify_settings_data() to check if the retrieved value has the correct type.
|
||||
func is_valid_type(VALUES_: Dictionary, RETRIEVED_VALUE) -> bool:
|
||||
if typeof(RETRIEVED_VALUE) != typeof(VALUES_["defaultValue"]):
|
||||
push_warning(
|
||||
"Invalid value type of '"
|
||||
+ type_string(typeof(RETRIEVED_VALUE))
|
||||
+ "' for element '"
|
||||
+ IDENTIFIER
|
||||
+ "' expected value type of '"
|
||||
+ type_string(typeof(VALUES_["defaultValue"]))
|
||||
+ "'"
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
## Used by verify_settings_data() to check if the retrieved value has a valid value.
|
||||
func is_valid_value(VALUES_: Dictionary, RETRIEVED_VALUE) -> bool:
|
||||
# Get the type of the valid value
|
||||
match typeof(VALUES_["defaultValue"]):
|
||||
# If the type is either string or bool
|
||||
TYPE_STRING, TYPE_BOOL:
|
||||
# Check if the retrieved value is valid
|
||||
if not VALUES_["validOptions"].has(RETRIEVED_VALUE):
|
||||
push_warning(
|
||||
"Invalid value '"
|
||||
+ str(RETRIEVED_VALUE)
|
||||
+ "' for element '"
|
||||
+ IDENTIFIER
|
||||
+ "' expected values: "
|
||||
+ str(VALUES_["validOptions"])
|
||||
)
|
||||
return false
|
||||
# If the type is either int or float
|
||||
TYPE_INT, TYPE_FLOAT:
|
||||
# Check if the retrieved value is valid
|
||||
if (
|
||||
RETRIEVED_VALUE < VALUES_["minValue"]
|
||||
or RETRIEVED_VALUE > VALUES_["maxValue"]
|
||||
):
|
||||
# Special check if max fps is set to 0 (unlimited)
|
||||
if IDENTIFIER == "MaxFPS" and RETRIEVED_VALUE == 0:
|
||||
return true
|
||||
|
||||
push_warning(
|
||||
"Invalid value "
|
||||
+ str(RETRIEVED_VALUE)
|
||||
+ " for element '"
|
||||
+ IDENTIFIER
|
||||
+ "' expected values between "
|
||||
+ str(VALUES_["minValue"])
|
||||
+ " and "
|
||||
+ str(VALUES_["maxValue"])
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
|
||||
|
||||
## Used to apply in game settings that require a node to exist to be applied,
|
||||
## i.e., world environment related settings and or most gameplay settings.
|
||||
func apply_in_game_setting(value = null) -> bool:
|
||||
if ParentRef.SettingsMenuRef.IS_IN_GAME_MENU:
|
||||
SettingsDataManager.call_deferred(
|
||||
"emit_signal",
|
||||
"applied_in_game_setting",
|
||||
SECTION,
|
||||
IDENTIFIER,
|
||||
value
|
||||
)
|
||||
return true
|
||||
|
||||
return false
|
||||
|
||||
|
||||
## Called to apply the setting to the game.
|
||||
## This function is overwritten by each [b]element[/b].
|
||||
func _apply_settings() -> void:
|
||||
return
|
||||
@@ -0,0 +1 @@
|
||||
uid://fv4elvbeqrqg
|
||||
@@ -0,0 +1,96 @@
|
||||
extends SettingsElement
|
||||
class_name SliderElement
|
||||
## A settings element specifically for elements that have a slider.
|
||||
|
||||
# Default values for the element
|
||||
@export var MIN_VALUE: float = 0
|
||||
@export var MAX_VALUE: float = 1
|
||||
@export var STEP_VALUE: float = 0.1
|
||||
@export var DEFAULT_VALUE: float = 1
|
||||
|
||||
## If true, displays 0 to 100 instead of 0 to 1 in the settings,
|
||||
## but the true value remains the same.
|
||||
@export var DISPLAY_PERCENT_VALUE: bool = false
|
||||
|
||||
## An extra suffix for the value (optional).
|
||||
@export var VALUE_SUFFIX: String = ""
|
||||
|
||||
## Reference to the slider of the element.
|
||||
@export var SliderRef: HSlider
|
||||
## Reference to the SpinBox or Label of the element.
|
||||
@export var ValueBoxRef: Control
|
||||
|
||||
|
||||
## Overwrite for SettingsElement.
|
||||
func init_element() -> void:
|
||||
init_slider(100 if DISPLAY_PERCENT_VALUE else 1)
|
||||
|
||||
|
||||
## Called to initialize the slider element.
|
||||
func init_slider(FACTOR: float) -> void:
|
||||
# Apply the min/max/step/current value of the SliderRef
|
||||
SliderRef.set_min(MIN_VALUE * FACTOR)
|
||||
SliderRef.set_max(MAX_VALUE * FACTOR)
|
||||
SliderRef.set_step(STEP_VALUE * FACTOR)
|
||||
SliderRef.set_value(currentValue * FACTOR)
|
||||
|
||||
# Connect the value changed signal for the SliderRef
|
||||
if not SliderRef.is_connected("value_changed", slider_value_changed):
|
||||
SliderRef.connect("value_changed", slider_value_changed.bind(FACTOR))
|
||||
|
||||
# Check if the value box is a spin box or a label
|
||||
if ValueBoxRef is SpinBox:
|
||||
# Apply the min/max/step/current value of the spin box
|
||||
ValueBoxRef.set_min(MIN_VALUE * FACTOR)
|
||||
ValueBoxRef.set_max(MAX_VALUE * FACTOR)
|
||||
ValueBoxRef.set_step(STEP_VALUE * FACTOR)
|
||||
ValueBoxRef.set_value(currentValue * FACTOR)
|
||||
|
||||
# Add caret blink to spin box
|
||||
ValueBoxRef.get_line_edit().set_caret_blink_enabled(true)
|
||||
|
||||
ValueBoxRef.set_suffix(VALUE_SUFFIX)
|
||||
|
||||
# Connect the value changed signal of the spin box
|
||||
if not ValueBoxRef.is_connected("value_changed", value_box_value_changed):
|
||||
ValueBoxRef.connect("value_changed", value_box_value_changed)
|
||||
else:
|
||||
# Set the text as the current value
|
||||
ValueBoxRef.set_text(str(currentValue) + VALUE_SUFFIX)
|
||||
|
||||
|
||||
## Gets the valid values from the element to be used for validating data.
|
||||
func get_valid_values() -> Dictionary:
|
||||
# Check if value is out of bounds
|
||||
if DEFAULT_VALUE > MAX_VALUE or DEFAULT_VALUE < MIN_VALUE:
|
||||
push_warning("Invalid default value for element '" + IDENTIFIER + "'.")
|
||||
DEFAULT_VALUE = clampf(DEFAULT_VALUE, MIN_VALUE, MAX_VALUE)
|
||||
|
||||
return {
|
||||
"defaultValue": DEFAULT_VALUE,
|
||||
"minValue": MIN_VALUE,
|
||||
"maxValue": MAX_VALUE,
|
||||
}
|
||||
|
||||
|
||||
## Used to update values of the section cache the element is under.
|
||||
func value_changed(value: float) -> void:
|
||||
# Check if the settings menu is open
|
||||
if ParentRef.settingsCache_.size() > 0:
|
||||
ParentRef.settingsCache_[IDENTIFIER] = value
|
||||
# Check if the new value is different than the saved value
|
||||
ParentRef.settings_changed(IDENTIFIER)
|
||||
currentValue = value
|
||||
|
||||
|
||||
func slider_value_changed(value: float, FACTOR: float) -> void:
|
||||
if ValueBoxRef is SpinBox:
|
||||
ValueBoxRef.set_value(value)
|
||||
else:
|
||||
ValueBoxRef.set_text(str(value) + VALUE_SUFFIX)
|
||||
|
||||
value_changed(value / FACTOR)
|
||||
|
||||
|
||||
func value_box_value_changed(value: float) -> void:
|
||||
SliderRef.set_value(value)
|
||||
@@ -0,0 +1 @@
|
||||
uid://084wuqxrcn2t
|
||||
@@ -0,0 +1,38 @@
|
||||
extends SettingsElement
|
||||
class_name ToggleElement
|
||||
## A settings element specifically for elements that have a toggle button.
|
||||
|
||||
## Default value for the element
|
||||
@export var DEFAULT_VALUE: bool = false
|
||||
|
||||
## Reference to the toggle button of the element.
|
||||
@export var ToggleRef: Button
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
super._ready()
|
||||
ToggleRef.connect("toggled", toggled)
|
||||
|
||||
|
||||
## Overwrite for SettingsElement.
|
||||
func init_element() -> void:
|
||||
ToggleRef.set_pressed(currentValue)
|
||||
|
||||
|
||||
## Gets the valid values from the element to be used for validating data.
|
||||
func get_valid_values() -> Dictionary:
|
||||
return {
|
||||
"defaultValue": DEFAULT_VALUE,
|
||||
"validOptions": [true, false]
|
||||
}
|
||||
|
||||
|
||||
## Used to update values of the section cache the element is under.
|
||||
func toggled(state: bool) -> void:
|
||||
# Check if the settings menu is open
|
||||
if ParentRef.settingsCache_.size() > 0:
|
||||
# Update the settings cache with the new toggle state
|
||||
ParentRef.settingsCache_[IDENTIFIER] = state
|
||||
# Check if the new state is different than the saved state
|
||||
ParentRef.settings_changed(IDENTIFIER)
|
||||
currentValue = state
|
||||
@@ -0,0 +1 @@
|
||||
uid://djvaswjdtm251
|
||||
@@ -0,0 +1,54 @@
|
||||
extends SettingsSection
|
||||
|
||||
# Panel node references
|
||||
@onready var BackButtonRef: Button = $VBoxContainer/HBoxContainer/BackButton
|
||||
@onready var ApplyButtonRef: Button = $VBoxContainer/HBoxContainer/ApplyButton
|
||||
|
||||
# Reference to the element this panel belongs to
|
||||
var PanelOwnerRef: ButtonElement
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect neccessary signals
|
||||
BackButtonRef.connect("pressed", on_back_pressed)
|
||||
ApplyButtonRef.connect("pressed", on_apply_settings)
|
||||
|
||||
# Add a reference of the section to the reference table
|
||||
SettingsDataManager.ELEMENT_PANEL_REFERENCE_TABLE_[IDENTIFIER] = self
|
||||
|
||||
# Check if a save file exists
|
||||
if SettingsDataManager.noSaveFile:
|
||||
# Add the section to the settings data dictionary
|
||||
SettingsDataManager.settingsData_[IDENTIFIER] = {}
|
||||
|
||||
SettingsMenuRef = owner
|
||||
# Load the settings of the elements inside of the panel
|
||||
call_deferred("init_elements")
|
||||
|
||||
|
||||
# Called to load the settings of the elements inside of the panel
|
||||
func init_elements() -> void:
|
||||
for element in ELEMENT_REFERENCE_TABLE_:
|
||||
ELEMENT_REFERENCE_TABLE_[element].load_settings()
|
||||
|
||||
|
||||
func settings_changed(elementId: String) -> void:
|
||||
ApplyButtonRef.set_disabled(check_for_changes(elementId))
|
||||
|
||||
|
||||
func on_back_pressed():
|
||||
# Check if there have been any changes made
|
||||
if ApplyButtonRef.is_disabled():
|
||||
# Clear the cache and return normally
|
||||
settingsCache_.clear()
|
||||
hide()
|
||||
SettingsMenuRef.SettingsPanelRef.show()
|
||||
else:
|
||||
SettingsMenuRef.display_discard_changes(self)
|
||||
|
||||
|
||||
func on_apply_settings():
|
||||
super.on_apply_settings()
|
||||
# Save the updated settings data
|
||||
SettingsDataManager.call_deferred("save_data")
|
||||
ApplyButtonRef.set_disabled(true)
|
||||
@@ -0,0 +1 @@
|
||||
uid://cyig515shrgnb
|
||||
@@ -0,0 +1,13 @@
|
||||
extends SliderElement
|
||||
|
||||
## Name of the audio bus that the volume slider is assigned to.
|
||||
@export var AUDIO_BUS: String
|
||||
|
||||
|
||||
# Element specific script for applying its value to the game
|
||||
func _apply_settings() -> void:
|
||||
# Get the index of the audio bus
|
||||
var busIndex: int = AudioServer.get_bus_index(AUDIO_BUS)
|
||||
|
||||
# Set the volume of the audio bus
|
||||
AudioServer.set_bus_volume_db(busIndex, linear_to_db(currentValue))
|
||||
@@ -0,0 +1 @@
|
||||
uid://b16tk8008cqdj
|
||||
@@ -0,0 +1,20 @@
|
||||
extends Node
|
||||
|
||||
@export var CameraRef: Camera3D
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect neccessary signal
|
||||
SettingsDataManager.connect("applied_in_game_setting", apply_in_game_settings)
|
||||
|
||||
|
||||
# Called to apply in game settings for the specific node
|
||||
func apply_in_game_settings(section: String, element: String, value) -> void:
|
||||
match element:
|
||||
"FOV":
|
||||
CameraRef.set_fov(value)
|
||||
"DepthOfField":
|
||||
var enabled: bool = false if value == "Disabled" else true
|
||||
# Disable/Enable DOF
|
||||
CameraRef.attributes.set_dof_blur_far_enabled(enabled)
|
||||
CameraRef.attributes.set_dof_blur_near_enabled(enabled)
|
||||
@@ -0,0 +1 @@
|
||||
uid://b52warfwk40xd
|
||||
@@ -0,0 +1,42 @@
|
||||
extends Node
|
||||
|
||||
@export var WorldEnvRef: WorldEnvironment
|
||||
|
||||
@onready var EnvironmentRef: Environment = WorldEnvRef.environment
|
||||
|
||||
|
||||
func _ready():
|
||||
SettingsDataManager.connect("applied_in_game_setting", apply_in_game_settings)
|
||||
|
||||
|
||||
# Called by elements to apply in game settings
|
||||
func apply_in_game_settings(section: String, element: String, value) -> void:
|
||||
match element:
|
||||
"SSRQuality":
|
||||
if SettingsDataManager.settingsData_[section][element] == "Disabled":
|
||||
EnvironmentRef.set_ssr_enabled(false)
|
||||
return
|
||||
EnvironmentRef.set_ssr_enabled(true)
|
||||
EnvironmentRef.set_ssr_max_steps(value["maxSteps"])
|
||||
EnvironmentRef.set_ssr_fade_in(value["fadeIn"])
|
||||
EnvironmentRef.set_ssr_fade_out(value["fadeOut"])
|
||||
|
||||
"SSAOQuality":
|
||||
EnvironmentRef.set_ssao_enabled(
|
||||
false if value == "Disabled" else true
|
||||
)
|
||||
|
||||
"SSILQuality":
|
||||
EnvironmentRef.set_ssil_enabled(
|
||||
false if value == "Disabled" else true
|
||||
)
|
||||
|
||||
"SDFGIQuality":
|
||||
EnvironmentRef.set_sdfgi_enabled(
|
||||
false if value == "Disabled" else true
|
||||
)
|
||||
|
||||
"GlowQuality":
|
||||
EnvironmentRef.set_glow_enabled(
|
||||
false if value == "Disabled" else true
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
uid://dtgajfyolcqno
|
||||
@@ -0,0 +1,83 @@
|
||||
extends Control
|
||||
class_name SettingsMenu
|
||||
|
||||
## Emitted when the settings menu is made visible.
|
||||
signal settings_menu_opened
|
||||
## Emitted when the apply button is pressed.
|
||||
signal apply_button_pressed
|
||||
## Emitted when the settings menu is hidden.
|
||||
signal settings_menu_closed
|
||||
## Emitted when changes are discarded.
|
||||
signal changes_discarded
|
||||
|
||||
## Used to check if gameplay related settings should be applied
|
||||
@export var IS_IN_GAME_MENU: bool = true
|
||||
## Reference to the parent node of the menu UI.
|
||||
## The node this references will get set visible when pressing the back button.
|
||||
@export var MenuPanelRef: Node
|
||||
## List of settings sections that should be left out of the settings menu instance.
|
||||
@export var IGNORED_SECTIONS_: Array[String]
|
||||
|
||||
|
||||
@onready var DiscardChangesRef: PanelContainer = $DiscardChangesPopup
|
||||
@onready var SettingsPanelRef: VBoxContainer = $SettingsPanel
|
||||
@onready var ApplyButtonRef: Button = %ApplyButton
|
||||
|
||||
var ElementPanelsRef: Control
|
||||
var SettingsTabsRef: TabContainer
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
ElementPanelsRef = $ElementPanels
|
||||
SettingsTabsRef = $SettingsPanel/SettingsTabs
|
||||
ignore_sections()
|
||||
|
||||
|
||||
func _ready():
|
||||
# Load the settings menu
|
||||
SettingsDataManager.call_deferred("emit_signal", "settings_retrieved")
|
||||
|
||||
|
||||
func on_back_button_pressed() -> void:
|
||||
# Check if there have been any changes made
|
||||
if ApplyButtonRef.is_disabled():
|
||||
hide()
|
||||
MenuPanelRef.show()
|
||||
# Clear the settings cache
|
||||
emit_signal("settings_menu_closed")
|
||||
else:
|
||||
# Display the discard changes popup
|
||||
display_discard_changes(self)
|
||||
|
||||
|
||||
func on_apply_button_pressed() -> void:
|
||||
ApplyButtonRef.set_disabled(true)
|
||||
# Apply the settings of each section
|
||||
emit_signal("apply_button_pressed")
|
||||
# Save the updated settings data
|
||||
SettingsDataManager.call_deferred("save_data")
|
||||
# Reset the changed elements count
|
||||
SettingsDataManager.changedElementsCount = 0
|
||||
|
||||
|
||||
func on_visibility_changed() -> void:
|
||||
if is_visible_in_tree():
|
||||
emit_signal("settings_menu_opened")
|
||||
|
||||
|
||||
# Called to discard the changes in the settings menu
|
||||
func discard_changes() -> void:
|
||||
emit_signal("changes_discarded")
|
||||
for SectionRef in SettingsTabsRef.get_children():
|
||||
SectionRef.discard_changes()
|
||||
|
||||
|
||||
func display_discard_changes(CallerRef: Control) -> void:
|
||||
DiscardChangesRef.show()
|
||||
DiscardChangesRef.CallerRef = CallerRef
|
||||
|
||||
|
||||
func ignore_sections() -> void:
|
||||
for SectionRef in SettingsTabsRef.get_children():
|
||||
if IGNORED_SECTIONS_.has(SectionRef.IDENTIFIER):
|
||||
SectionRef.queue_free()
|
||||
@@ -0,0 +1 @@
|
||||
uid://houdhjao14e7
|
||||
@@ -0,0 +1,123 @@
|
||||
extends Control
|
||||
class_name SettingsSection
|
||||
## The base script for settings sections.
|
||||
|
||||
## Emitted when the apply button is pressed.
|
||||
signal apply_button_pressed
|
||||
## Emitted when a setting has it's value changed.
|
||||
signal setting_changed(elementId: String)
|
||||
|
||||
## Identifier for the section.
|
||||
## This value is used as the key in the settings data.
|
||||
@export var IDENTIFIER: String
|
||||
|
||||
## Reference to the settings menu node.
|
||||
var SettingsMenuRef: SettingsMenu
|
||||
|
||||
## Reference table of all elements under the section.
|
||||
var ELEMENT_REFERENCE_TABLE_: Dictionary
|
||||
## Cache of all the settings values for the section.
|
||||
var settingsCache_: Dictionary
|
||||
## A list of all the elements that were changed since the settings were last applied.
|
||||
var changedElements_: Array[String]
|
||||
|
||||
|
||||
func _enter_tree() -> void:
|
||||
SettingsMenuRef = owner
|
||||
|
||||
|
||||
func _ready():
|
||||
# Connect neccessary signals from the central root node for the settings
|
||||
SettingsMenuRef.connect("settings_menu_opened", get_settings)
|
||||
SettingsMenuRef.connect("apply_button_pressed", on_apply_settings)
|
||||
SettingsMenuRef.connect("settings_menu_closed", clear_cache)
|
||||
|
||||
# Add a reference of the section to the reference table
|
||||
SettingsDataManager.SECTION_REFERENCE_TABLE_[IDENTIFIER] = self
|
||||
|
||||
# Check if a save file exists
|
||||
if SettingsDataManager.noSaveFile:
|
||||
# Add the section to the settings data dictionary
|
||||
SettingsDataManager.settingsData_[IDENTIFIER] = {}
|
||||
|
||||
|
||||
## Called when opening the settings menu to fill the settings cache.
|
||||
func get_settings() -> void:
|
||||
# Copy the settings data for the section into it's cache
|
||||
settingsCache_ =\
|
||||
SettingsDataManager.settingsData_[IDENTIFIER].duplicate(true)
|
||||
|
||||
# If no save file exists saves the default values retrieved from the section's elements
|
||||
if SettingsDataManager.noSaveFile or SettingsDataManager.invalidSaveFile:
|
||||
SettingsDataManager.call_deferred("save_data")
|
||||
|
||||
# Clear the changed elements array
|
||||
changedElements_.clear()
|
||||
|
||||
|
||||
## Called to clear the section's cache.
|
||||
func clear_cache() -> void:
|
||||
settingsCache_.clear()
|
||||
|
||||
|
||||
## Called when a setting has been changed.
|
||||
func settings_changed(elementId: String) -> void:
|
||||
SettingsMenuRef.ApplyButtonRef.set_disabled(check_for_changes(elementId))
|
||||
emit_signal("setting_changed", elementId)
|
||||
|
||||
|
||||
## Called to check for changes between the cache and the settings data.
|
||||
func check_for_changes(elementId: String) -> bool:
|
||||
var cacheValue = settingsCache_[elementId]
|
||||
var savedValue = SettingsDataManager.settingsData_[IDENTIFIER][elementId]
|
||||
# Check if there are differences between the cache and the settings data
|
||||
if cacheValue == savedValue:
|
||||
# Check if the element is on the changed elements list
|
||||
if changedElements_.has(elementId):
|
||||
# Remove the element from the list
|
||||
changedElements_.erase(elementId)
|
||||
# Decrease the changed elements count
|
||||
SettingsDataManager.changedElementsCount -= 1
|
||||
|
||||
# Check if there are any other changed elements
|
||||
if SettingsDataManager.changedElementsCount == 0:
|
||||
# Disabled the apply button
|
||||
return true
|
||||
|
||||
# Check if the element is not the changed elements list
|
||||
if not changedElements_.has(elementId):
|
||||
# Add the element to the list
|
||||
changedElements_.append(elementId)
|
||||
# Increase the changed elements count
|
||||
SettingsDataManager.changedElementsCount += 1
|
||||
|
||||
# Enable the apply button
|
||||
return false
|
||||
|
||||
|
||||
## Called to saved the data in the section's cache to the settings data
|
||||
## and apply the settings to the game.
|
||||
func on_apply_settings() -> void:
|
||||
# Check if any of the sections elements have been changed
|
||||
if changedElements_.size() > 0:
|
||||
# Copy the section cache into the settings data dictionary
|
||||
SettingsDataManager.settingsData_[IDENTIFIER] = settingsCache_.duplicate(true)
|
||||
|
||||
# Apply the settings for the changed elements
|
||||
for element in changedElements_:
|
||||
ELEMENT_REFERENCE_TABLE_[element]._apply_settings()
|
||||
|
||||
# Clear the changed elements array
|
||||
changedElements_.clear()
|
||||
|
||||
|
||||
## Called to discard changes that have been made since the last save.
|
||||
func discard_changes() -> void:
|
||||
# Check if any of the sections elements have been changed
|
||||
if changedElements_.size() > 0:
|
||||
# Load the saved settings for each element in the section
|
||||
for element in changedElements_:
|
||||
ELEMENT_REFERENCE_TABLE_[element].load_settings()
|
||||
|
||||
# Clear the changed elements array
|
||||
changedElements_.clear()
|
||||
@@ -0,0 +1 @@
|
||||
uid://c3ssroxjs8wt
|
||||
@@ -0,0 +1,212 @@
|
||||
extends Node
|
||||
## Handles the loading and saving of settings data.
|
||||
|
||||
## Emitted when loading the settings data.
|
||||
signal settings_retrieved
|
||||
## Emitted when applying specific settings to in game objects.
|
||||
signal applied_in_game_setting(section: String, setting: String, value)
|
||||
|
||||
## PATH to the settings save file.
|
||||
var DATA_FOLDER: String = OS.get_user_data_dir()
|
||||
## Name of the file that the settings data is saved in.
|
||||
const FILE_NAME: String = "settings"
|
||||
## Extension for the save file.
|
||||
const FILE_EXTENSION: String = ".cfg"
|
||||
## The PATH to the save file on the computer.
|
||||
var PATH: String = DATA_FOLDER + "/" + FILE_NAME + FILE_EXTENSION
|
||||
|
||||
## Dictionary that stores all settings data.
|
||||
var settingsData_: Dictionary
|
||||
## A reference table of all sections.
|
||||
var SECTION_REFERENCE_TABLE_: Dictionary
|
||||
## A reference table of all element panels.
|
||||
var ELEMENT_PANEL_REFERENCE_TABLE_: Dictionary
|
||||
|
||||
## The number of elements that have been changed since the settings have been saved.
|
||||
var changedElementsCount: int = 0
|
||||
|
||||
## Flag for checking if a save file exists.
|
||||
var noSaveFile: bool
|
||||
## Flag for checking if an invalid value was found in the save file.
|
||||
var invalidSaveFile: bool = false
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Verify the directory
|
||||
DirAccess.make_dir_absolute(DATA_FOLDER)
|
||||
|
||||
# Check if a save file exists
|
||||
if FileAccess.file_exists(PATH):
|
||||
# Proceed normally by retrieving data from the save file
|
||||
call_deferred("get_data")
|
||||
else:
|
||||
# Enable the no save file flag
|
||||
noSaveFile = true
|
||||
push_warning("No save file found")
|
||||
|
||||
|
||||
## Called to save the settings data to the save file.
|
||||
func save_data() -> void:
|
||||
# Create a new config instance
|
||||
var config := ConfigFile.new()
|
||||
|
||||
# Add the data from the settings data dictionary
|
||||
for section in settingsData_:
|
||||
for element in settingsData_[section]:
|
||||
config.set_value(section, element, settingsData_[section][element])
|
||||
|
||||
# Save the data to the specified directory
|
||||
var err = config.save(PATH)
|
||||
|
||||
# Check for errors
|
||||
if err != OK:
|
||||
push_error("Failed to save data_: ", err)
|
||||
return
|
||||
|
||||
# Disable the no save file flag if it was enabled
|
||||
if noSaveFile:
|
||||
noSaveFile = false
|
||||
|
||||
# Disable the invalid save file flag if it was enabled
|
||||
if invalidSaveFile:
|
||||
invalidSaveFile = false
|
||||
|
||||
|
||||
## Called to retrieve data from the save file.
|
||||
func get_data() -> void:
|
||||
# Create a new config instance
|
||||
var config := ConfigFile.new()
|
||||
# Load the save data
|
||||
var err := config.load(PATH)
|
||||
# Temporary data dictionary
|
||||
var data_: Dictionary = {}
|
||||
|
||||
# Check for errors
|
||||
if err != OK:
|
||||
push_error("Failed to load settings data_: ", err)
|
||||
return
|
||||
|
||||
# Add the retrieved data to the settings data dictionary
|
||||
for section in config.get_sections():
|
||||
data_[section] = {}
|
||||
for key in config.get_section_keys(section):
|
||||
data_[section][key] = config.get_value(section, key)
|
||||
|
||||
# Verify the validity of the loaded data
|
||||
verify_settings_data_(data_)
|
||||
|
||||
# Copy the retrieved data into the settings data dictionary
|
||||
settingsData_ = data_.duplicate(true)
|
||||
|
||||
|
||||
## Checks if the save file has any invalid entries and removes them or adds missing sections.
|
||||
func verify_settings_data_(data_: Dictionary) -> void:
|
||||
# List of valid entries to compare to
|
||||
var validEntries_: Dictionary = SECTION_REFERENCE_TABLE_.duplicate()
|
||||
# Merge the element panel references into the valid entries
|
||||
validEntries_.merge(ELEMENT_PANEL_REFERENCE_TABLE_)
|
||||
# List of invalid entries to be removed
|
||||
var invalidEntries_: Dictionary = {}
|
||||
|
||||
# Itterate through the loaded settings data
|
||||
for section in data_:
|
||||
if is_valid_section(invalidEntries_, section):
|
||||
verify_elements(data_, invalidEntries_, section)
|
||||
|
||||
# Check if there are any sections missing from the retrieved data
|
||||
check_for_missing_sections(data_, validEntries_)
|
||||
|
||||
# Check if there are any invalid entries
|
||||
if invalidEntries_.size() > 0:
|
||||
# Set the invalid save file flag to true
|
||||
invalidSaveFile = true
|
||||
remove_invalid_entries(data_, invalidEntries_, validEntries_)
|
||||
|
||||
|
||||
## Used by the verify_settings_data() function to verify the retrieved sections.
|
||||
func is_valid_section(invalidEntries_: Dictionary, SECTION: String) -> bool:
|
||||
# Check if the section is in either of the reference tables
|
||||
if (
|
||||
SECTION_REFERENCE_TABLE_.has(SECTION)
|
||||
or ELEMENT_PANEL_REFERENCE_TABLE_.has(SECTION)
|
||||
):
|
||||
return true
|
||||
|
||||
# Add the invalid section to the invalid entries list
|
||||
invalidEntries_[SECTION] = []
|
||||
push_warning("Invalid section '", SECTION, "' found.")
|
||||
return false
|
||||
|
||||
|
||||
## Used by the verify_settings_data() function to verify the elements inside of the retrieved sections.
|
||||
func verify_elements(
|
||||
data_: Dictionary,
|
||||
invalidEntries_: Dictionary,
|
||||
SECTION: String
|
||||
) -> void:
|
||||
# Array of all elements under the section
|
||||
var VALID_SECTION_ELEMENTS: Array = get_valid_elements(SECTION)
|
||||
|
||||
# Itterate through all the elements in the section
|
||||
for element in data_[SECTION]:
|
||||
# Check for invalid elements
|
||||
if not VALID_SECTION_ELEMENTS.has(element):
|
||||
# Check if the element is in a valid section
|
||||
if not invalidEntries_.has(SECTION):
|
||||
# Add the section to the invalid entries list
|
||||
invalidEntries_[SECTION] = []
|
||||
|
||||
# Add the invalid element to the invalid entries list
|
||||
invalidEntries_[SECTION].append(element)
|
||||
push_warning(
|
||||
"Invalid element '"
|
||||
+ element
|
||||
+ "' found in section '"
|
||||
+ SECTION
|
||||
+ "'."
|
||||
)
|
||||
|
||||
|
||||
## Used by the verify_elements() function to retrieve the valid elements for the retrieved section.
|
||||
func get_valid_elements(SECTION: String) -> Array:
|
||||
# Check if the section is a settings section
|
||||
if SECTION_REFERENCE_TABLE_.has(SECTION):
|
||||
return SECTION_REFERENCE_TABLE_[SECTION].ELEMENT_REFERENCE_TABLE_.keys()
|
||||
|
||||
# Check if the section is an element panel
|
||||
if ELEMENT_PANEL_REFERENCE_TABLE_.has(SECTION):
|
||||
return ELEMENT_PANEL_REFERENCE_TABLE_[SECTION].ELEMENT_REFERENCE_TABLE_.keys()
|
||||
|
||||
return []
|
||||
|
||||
|
||||
## Used by the verify_settings_data() function to check if any expected sections are missing.
|
||||
func check_for_missing_sections(data_: Dictionary, validEntries_: Dictionary) -> void:
|
||||
# Itterate through all valid sections
|
||||
for section in validEntries_:
|
||||
# Check if the section is missing from the loaded data_
|
||||
if not data_.has(section):
|
||||
# Add an empty entry for the section
|
||||
data_[section] = {}
|
||||
# Set the invalid save file flag to true
|
||||
invalidSaveFile = true
|
||||
push_warning("Settings section is missing: ", section)
|
||||
|
||||
|
||||
## Used by the verify_settings_data() function to remove invalid entires from the retrieved data.
|
||||
func remove_invalid_entries(
|
||||
data_: Dictionary,
|
||||
invalidEntries_: Dictionary,
|
||||
validEntries_: Dictionary
|
||||
) -> void:
|
||||
# Itterate through the sections in the invalid entries list
|
||||
for section in invalidEntries_:
|
||||
# Check if the section is valid
|
||||
if validEntries_.has(section):
|
||||
# Itterate through the invalid elements
|
||||
for element in invalidEntries_[section]:
|
||||
# Remove the invalid element
|
||||
data_[section].erase(element)
|
||||
else:
|
||||
# Remove the invalid section
|
||||
data_.erase(section)
|
||||
@@ -0,0 +1 @@
|
||||
uid://c70d4w5cws2at
|
||||
@@ -1,24 +1,23 @@
|
||||
extends Node
|
||||
|
||||
# Main scene
|
||||
var mainSceneInstance
|
||||
|
||||
# Screen
|
||||
var screen_size = Vector2(1920.0, 1080.0) # Default screen size (this is a float for some reason)
|
||||
var viewport_size
|
||||
@onready var extent: Rect2 = get_viewport().get_visible_rect()
|
||||
|
||||
# Main menu & game spawning
|
||||
@onready
|
||||
var mainMenuScene = preload("res://main_menu.tscn").instantiate()
|
||||
@onready
|
||||
var gameScene = preload("res://molecular/molecular_stage.tscn").instantiate()
|
||||
var extent: Rect2
|
||||
|
||||
# utils.
|
||||
var rng = RandomNumberGenerator.new()
|
||||
var eps: float = 1e-4
|
||||
var legacy_movement: bool = false
|
||||
|
||||
# managers
|
||||
@onready
|
||||
var foodManager = gameScene.get_node("FoodManager")
|
||||
var foodManager: FoodManager2D
|
||||
|
||||
# A world "current"
|
||||
# TODO: This should be moved to a different "game manager" specific to the molecular stage
|
||||
# polar
|
||||
var flow_dir: float # [0, 2pi)
|
||||
var flow_mag: float # [0, 1]
|
||||
@@ -33,24 +32,26 @@ var t: float = 0.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Start game
|
||||
mainSceneInstance = get_tree().root.get_child(-1)
|
||||
|
||||
# Create viewport
|
||||
viewport_size = get_viewport().get_visible_rect().size
|
||||
|
||||
# Create game (main menu)
|
||||
add_child(mainMenuScene)
|
||||
|
||||
|
||||
# initial world current
|
||||
get_new_flow()
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
t += delta
|
||||
|
||||
# Flow current change
|
||||
if abs(fmod(t, flowT)) < eps:
|
||||
get_new_flow()
|
||||
|
||||
func start_game() -> void:
|
||||
add_child(gameScene)
|
||||
|
||||
func switch_scene(name:String) -> void:
|
||||
if name == "respawn":
|
||||
mainSceneInstance.go_to_respawn_scene()
|
||||
|
||||
# TODO: This needs to be called from a script inheriting a CharacterBody2D (e.g. the player)
|
||||
# Alternative would be to pass the player reference to this script (which might be better?)
|
||||
@@ -58,29 +59,29 @@ func init_screen_size(x:float, y:float) -> void:
|
||||
screen_size.x = x
|
||||
screen_size.y = y
|
||||
|
||||
extent = Rect2(Vector2(-viewport_size.x/2, -viewport_size.y/2), viewport_size + screen_size)
|
||||
|
||||
# This can take a vector of any size (but should be 2d, other components are unused)
|
||||
func get_boundaried_position(position):
|
||||
# clamp
|
||||
#return position.clamp(Vector2.ZERO, screen_size)
|
||||
|
||||
# periodic
|
||||
position.x = wrapf(position.x, 0, screen_size.x)
|
||||
position.y = wrapf(position.y, 0, screen_size.y)
|
||||
position.x = wrapf(position.x, -viewport_size.x/2 , screen_size.x + viewport_size.x/2)
|
||||
position.y = wrapf(position.y, -viewport_size.y/2, screen_size.y + viewport_size.y/2)
|
||||
return position
|
||||
|
||||
|
||||
func get_new_flow():
|
||||
flow_dir = rng.randf()*2*PI
|
||||
flow_mag = rng.randf()
|
||||
|
||||
flow_x = flow_mag * cos(flow_dir)
|
||||
flow_y = flow_mag * sin(flow_dir)
|
||||
|
||||
|
||||
|
||||
|
||||
func calc_distance(one, two) -> float:
|
||||
var candidate = one.distance_to(two)
|
||||
var onedup = one
|
||||
# FIXME: doesnt work-- predators lose track across game boundary
|
||||
if one.x < screen_size.x/2:
|
||||
if one.y < screen_size.y/2:
|
||||
# top left
|
||||
@@ -105,10 +106,16 @@ func calc_distance(one, two) -> float:
|
||||
onedup.x += screen_size.x
|
||||
candidate = min(candidate, onedup.distance_to(two))
|
||||
else:
|
||||
# botom right
|
||||
# bottom right
|
||||
onedup.y += screen_size.y
|
||||
candidate = min(candidate, onedup.distance_to(two))
|
||||
onedup.y -= screen_size.y
|
||||
onedup.x += screen_size.x
|
||||
candidate = min(candidate, onedup.distance_to(two))
|
||||
return candidate
|
||||
|
||||
func change_window_size(width: int, height: int) -> void:
|
||||
# Do NOT remove this Godot, ffs!!!
|
||||
var newSize = Vector2i(width, height)
|
||||
|
||||
|
||||
|
||||
3
evolve-die-repeat/main.tscn
Normal file
3
evolve-die-repeat/main.tscn
Normal file
@@ -0,0 +1,3 @@
|
||||
[gd_scene format=3 uid="uid://bsrxph8oa7uuj"]
|
||||
|
||||
[node name="Main" type="Node" unique_id=1994328839]
|
||||
@@ -1,7 +0,0 @@
|
||||
extends Control
|
||||
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
print("Starting game by pressing button...")
|
||||
GameManager.start_game()
|
||||
self.queue_free()
|
||||
@@ -1 +0,0 @@
|
||||
uid://dxc66bci2ivrj
|
||||
@@ -1,6 +1,16 @@
|
||||
[gd_scene format=3 uid="uid://drgv154ei1vrl"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://dxc66bci2ivrj" path="res://main_menu.gd" id="1_06t4h"]
|
||||
[ext_resource type="PackedScene" uid="uid://px6a2dg8cawb" path="res://addons/modular-settings-menu/scenes/settings.tscn" id="1_06t4h"]
|
||||
|
||||
[sub_resource type="GDScript" id="GDScript_rhts7"]
|
||||
script/source = "extends Control
|
||||
|
||||
|
||||
func _on_play_button_pressed() -> void:
|
||||
print(\"Starting game by pressing button...\")
|
||||
GameManager.start_game()
|
||||
self.queue_free()
|
||||
"
|
||||
|
||||
[sub_resource type="LabelSettings" id="LabelSettings_rhts7"]
|
||||
font_size = 64
|
||||
@@ -12,25 +22,44 @@ anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
script = ExtResource("1_06t4h")
|
||||
script = SubResource("GDScript_rhts7")
|
||||
|
||||
[node name="PlayButton" type="Button" parent="." unique_id=1831335357]
|
||||
layout_mode = 0
|
||||
offset_left = 448.0
|
||||
offset_top = 256.0
|
||||
offset_right = 768.0
|
||||
offset_bottom = 314.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 = -160.0
|
||||
offset_top = -29.0
|
||||
offset_right = 160.0
|
||||
offset_bottom = 29.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
text = "Play"
|
||||
|
||||
[node name="MainMenuText" type="Label" parent="." unique_id=1324657553]
|
||||
layout_mode = 0
|
||||
offset_left = 320.0
|
||||
offset_top = 32.0
|
||||
offset_right = 904.0
|
||||
offset_bottom = 151.0
|
||||
layout_mode = 1
|
||||
anchors_preset = 5
|
||||
anchor_left = 0.5
|
||||
anchor_right = 0.5
|
||||
offset_left = -292.0
|
||||
offset_right = 292.0
|
||||
offset_bottom = 119.0
|
||||
grow_horizontal = 2
|
||||
text = "The Main Menu"
|
||||
label_settings = SubResource("LabelSettings_rhts7")
|
||||
horizontal_alignment = 1
|
||||
vertical_alignment = 1
|
||||
|
||||
[connection signal="pressed" from="PlayButton" to="." method="_on_play_button_pressed"]
|
||||
[node name="Settings" parent="." unique_id=112964493 node_paths=PackedStringArray("MenuPanelRef") instance=ExtResource("1_06t4h")]
|
||||
layout_mode = 1
|
||||
MenuPanelRef = NodePath("../SettingsWheelButton")
|
||||
|
||||
[node name="SettingsWheelButton" type="Button" parent="." unique_id=2147291321]
|
||||
layout_mode = 0
|
||||
offset_left = 898.0
|
||||
offset_top = 46.0
|
||||
offset_right = 954.0
|
||||
offset_bottom = 93.0
|
||||
|
||||
61
evolve-die-repeat/main_scene.gd
Normal file
61
evolve-die-repeat/main_scene.gd
Normal file
@@ -0,0 +1,61 @@
|
||||
extends Node
|
||||
|
||||
# Main menu & game spawning
|
||||
@onready
|
||||
var mainMenuScene = preload("res://main_menu.tscn")
|
||||
var mainMenuSceneInstance: Node
|
||||
@onready
|
||||
var gameScene = preload("res://molecular/molecular_stage.tscn")
|
||||
var gameSceneInstance: Node
|
||||
@onready
|
||||
var respawnScene = preload("res://respawn_menu.tscn")
|
||||
var respawnSceneInstance: Node
|
||||
# Currently active scene (instance)
|
||||
var currentSceneInstance:Node
|
||||
|
||||
# UI effects
|
||||
var fadeEffect: CanvasLayer
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
# Instantiate effects
|
||||
fadeEffect = $UI/Fade
|
||||
fadeEffect.visible = false
|
||||
|
||||
# Create game (main menu)
|
||||
print("Creating Main menu...")
|
||||
mainMenuSceneInstance = mainMenuScene.instantiate()
|
||||
currentSceneInstance = mainMenuSceneInstance
|
||||
add_child(currentSceneInstance)
|
||||
|
||||
# Link MainMenu button to start_game
|
||||
print("Linking Play button...")
|
||||
mainMenuSceneInstance.get_node("PlayButton").connect("pressed", start_game)
|
||||
|
||||
|
||||
func start_game() -> void:
|
||||
print("Starting game...")
|
||||
|
||||
# Instatiate
|
||||
currentSceneInstance.queue_free()
|
||||
gameSceneInstance = gameScene.instantiate()
|
||||
currentSceneInstance = gameSceneInstance
|
||||
add_child(currentSceneInstance)
|
||||
|
||||
# Populate GameManager with game scene
|
||||
GameManager.foodManager = gameSceneInstance.get_node("FoodManager")
|
||||
|
||||
|
||||
func go_to_respawn_scene() -> void:
|
||||
fadeEffect.visible = true
|
||||
await fadeEffect.fade(1.0, 1.5).finished
|
||||
print("Switching to Respawn scene.")
|
||||
currentSceneInstance.queue_free()
|
||||
|
||||
respawnSceneInstance = respawnScene.instantiate()
|
||||
respawnSceneInstance.get_node("RespawnButton").connect("pressed", start_game)
|
||||
currentSceneInstance = respawnSceneInstance
|
||||
|
||||
add_child(currentSceneInstance)
|
||||
await fadeEffect.fade(0.0, 1.5).finished
|
||||
fadeEffect.visible = false
|
||||
1
evolve-die-repeat/main_scene.gd.uid
Normal file
1
evolve-die-repeat/main_scene.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://wiv0plsu04s
|
||||
@@ -1,6 +1,11 @@
|
||||
[gd_scene format=3 uid="uid://b8gt8os2m28lv"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://vsbibc5fanou" path="res://game_manager.gd" id="1_0f027"]
|
||||
[ext_resource type="Script" uid="uid://wiv0plsu04s" path="res://main_scene.gd" id="1_2c62f"]
|
||||
[ext_resource type="PackedScene" uid="uid://3eg3a8ceom4l" path="res://molecular/fade.tscn" id="2_2c62f"]
|
||||
|
||||
[node name="MainScene" type="Node" unique_id=1897047571]
|
||||
script = ExtResource("1_0f027")
|
||||
script = ExtResource("1_2c62f")
|
||||
|
||||
[node name="UI" type="Node2D" parent="." unique_id=1032224503]
|
||||
|
||||
[node name="Fade" parent="UI" unique_id=853660457 instance=ExtResource("2_2c62f")]
|
||||
|
||||
BIN
evolve-die-repeat/molecular/assets/player-sprite-attacking.png
Normal file
BIN
evolve-die-repeat/molecular/assets/player-sprite-attacking.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 281 B |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://du1lb4nr47kvl"
|
||||
path="res://.godot/imported/player-sprite-attacking.png-6189c8275a257517c87cdb65abf5639a.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://molecular/assets/player-sprite-attacking.png"
|
||||
dest_files=["res://.godot/imported/player-sprite-attacking.png-6189c8275a257517c87cdb65abf5639a.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
evolve-die-repeat/molecular/assets/player-sprite-attacking2.png
Normal file
BIN
evolve-die-repeat/molecular/assets/player-sprite-attacking2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 308 B |
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bsd1qtw50esai"
|
||||
path="res://.godot/imported/player-sprite-attacking2.png-3e4e9a47129b5ac21e61c82e331ba03f.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://molecular/assets/player-sprite-attacking2.png"
|
||||
dest_files=["res://.godot/imported/player-sprite-attacking2.png-3e4e9a47129b5ac21e61c82e331ba03f.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
BIN
evolve-die-repeat/molecular/assets/player-sprite.png
Normal file
BIN
evolve-die-repeat/molecular/assets/player-sprite.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 253 B |
40
evolve-die-repeat/molecular/assets/player-sprite.png.import
Normal file
40
evolve-die-repeat/molecular/assets/player-sprite.png.import
Normal file
@@ -0,0 +1,40 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://cd0iv6hsi3fad"
|
||||
path="res://.godot/imported/player-sprite.png-f2c28aefaf4a8e7293c46f17a4267bc1.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://molecular/assets/player-sprite.png"
|
||||
dest_files=["res://.godot/imported/player-sprite.png-f2c28aefaf4a8e7293c46f17a4267bc1.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
11
evolve-die-repeat/molecular/fade.gd
Normal file
11
evolve-die-repeat/molecular/fade.gd
Normal file
@@ -0,0 +1,11 @@
|
||||
extends CanvasLayer
|
||||
|
||||
@onready var color_rect: ColorRect = $ColorRect
|
||||
|
||||
func _ready() -> void:
|
||||
color_rect.color.a = 0
|
||||
|
||||
func fade(target_alpha: float, duration: float):
|
||||
var tween = create_tween()
|
||||
tween.tween_property(color_rect, "color:a", target_alpha, duration)
|
||||
return tween
|
||||
1
evolve-die-repeat/molecular/fade.gd.uid
Normal file
1
evolve-die-repeat/molecular/fade.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bwf56ehqo32gr
|
||||
14
evolve-die-repeat/molecular/fade.tscn
Normal file
14
evolve-die-repeat/molecular/fade.tscn
Normal file
@@ -0,0 +1,14 @@
|
||||
[gd_scene format=3 uid="uid://3eg3a8ceom4l"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bwf56ehqo32gr" path="res://molecular/fade.gd" id="1_rx8rx"]
|
||||
|
||||
[node name="Fade" type="CanvasLayer" unique_id=853660457]
|
||||
script = ExtResource("1_rx8rx")
|
||||
|
||||
[node name="ColorRect" type="ColorRect" parent="." unique_id=1320853444]
|
||||
anchors_preset = 15
|
||||
anchor_right = 1.0
|
||||
anchor_bottom = 1.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 2
|
||||
color = Color(0, 0, 0, 0)
|
||||
@@ -1,21 +1,15 @@
|
||||
@abstract
|
||||
class_name AbstractFood
|
||||
extends Area2D
|
||||
extends Node
|
||||
|
||||
@export var val: int = 1
|
||||
@export var food_name: String = "Food"
|
||||
|
||||
|
||||
@export var flow_carry_speed: float = 10.0
|
||||
|
||||
signal consumed
|
||||
|
||||
func _ready() -> void:
|
||||
pass
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var dpos = Vector2(GameManager.flow_x, GameManager.flow_y) * delta * flow_carry_speed
|
||||
position += dpos
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
pass
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
extends Node
|
||||
class_name FoodManager2D
|
||||
|
||||
var minCount: int = 20
|
||||
var minCount: int = 0
|
||||
var _currentCount: int = 0
|
||||
|
||||
var rng = RandomNumberGenerator.new()
|
||||
@@ -19,10 +19,6 @@ func _ready() -> void:
|
||||
spawnRange = GameManager.extent
|
||||
call_deferred("_spawn_minimum")
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
pass
|
||||
|
||||
func _spawn_minimum() -> void:
|
||||
while _currentCount < minCount:
|
||||
_spawn_random()
|
||||
@@ -38,7 +34,7 @@ func _spawn_random() -> void:
|
||||
func _spawn_food(position: Vector2) -> void:
|
||||
var instance = foodTypes[rng.rand_weighted(foodProbs)].instantiate()
|
||||
instance.position = position
|
||||
add_child(instance)
|
||||
call_deferred("add_child", instance)
|
||||
if instance.has_signal("consumed"):
|
||||
instance.consumed.connect(_on_entity_consumed)
|
||||
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
extends AbstractFood
|
||||
class_name FoodMolecular
|
||||
|
||||
@onready var collision: Area2D = $Collision
|
||||
@onready var sprite: AnimatedSprite2D = $Collision/Sprite
|
||||
@onready var player = get_tree().get_first_node_in_group("player") # FIXME: this is not v efficient; global resource? or at least per Stage.
|
||||
|
||||
func _ready() -> void:
|
||||
$AnimatedSprite2D.play()
|
||||
sprite.play()
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
var dpos = Vector2(GameManager.flow_x, GameManager.flow_y) * delta * flow_carry_speed
|
||||
collision.position = GameManager.get_boundaried_position(collision.position + dpos)
|
||||
|
||||
func _process(delta):
|
||||
collision.position = GameManager.get_boundaried_position(collision.position)
|
||||
|
||||
func _on_body_entered(body: Node2D) -> void:
|
||||
eat(body)
|
||||
@@ -19,3 +31,10 @@ func apply_effect(consumer: Node2D) -> void:
|
||||
if consumer.has_method("collect_resource"): # TODO: Define a "consumer" group instead?
|
||||
consumer.collect_resource(val) # val is from parent (default 1), override if required
|
||||
# TODO: *Some cool effect here*
|
||||
|
||||
|
||||
# FIXME: position tracking inaccurate?
|
||||
func _on_collision_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
if player:
|
||||
player.target = self.collision
|
||||
|
||||
@@ -7,9 +7,6 @@
|
||||
[ext_resource type="Texture2D" uid="uid://dj4lyyloj1ke1" path="res://molecular/assets/food/food-left-bottom-bolt.png" id="5_i3g2v"]
|
||||
[ext_resource type="Texture2D" uid="uid://cbynycukppmup" path="res://molecular/assets/food/food-right-bottom-bolt.png" id="6_07uaq"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0vfbj"]
|
||||
radius = 2.0
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_oo5vd"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
@@ -51,28 +48,31 @@ animations = [{
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[node name="FoodMol" type="Area2D" unique_id=595352294]
|
||||
collision_layer = 8
|
||||
collision_mask = 7
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_0vfbj"]
|
||||
radius = 5.0
|
||||
|
||||
[node name="FoodMol" type="Node2D" unique_id=742430243]
|
||||
script = ExtResource("1_0vfbj")
|
||||
metadata/_custom_type_script = "uid://cayxffay17o0u"
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=762721134]
|
||||
shape = SubResource("CircleShape2D_0vfbj")
|
||||
[node name="Collision" type="Area2D" parent="." unique_id=927700818]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="." unique_id=98693723]
|
||||
[node name="Sprite" type="AnimatedSprite2D" parent="Collision" unique_id=1856148995]
|
||||
texture_filter = 1
|
||||
sprite_frames = SubResource("SpriteFrames_oo5vd")
|
||||
frame_progress = 0.9373464
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="Collision" unique_id=98693723]
|
||||
visible = false
|
||||
scale = Vector2(0.385, 0.385)
|
||||
texture = ExtResource("2_68e2u")
|
||||
|
||||
[node name="WrappingManager" type="Node" parent="." unique_id=1406150436 node_paths=PackedStringArray("sprite", "shape")]
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="Collision" unique_id=762721134]
|
||||
shape = SubResource("CircleShape2D_0vfbj")
|
||||
|
||||
[node name="WrappingManager" type="Node" parent="." unique_id=1406150436]
|
||||
script = ExtResource("3_8lhj0")
|
||||
sprite = NodePath("../AnimatedSprite2D")
|
||||
shape = NodePath("../CollisionShape2D")
|
||||
metadata/_custom_type_script = "uid://bvbc0n0pslq7p"
|
||||
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1856148995]
|
||||
scale = Vector2(0.385, 0.385)
|
||||
sprite_frames = SubResource("SpriteFrames_oo5vd")
|
||||
frame_progress = 0.9373464
|
||||
|
||||
[connection signal="body_entered" from="." to="." method="_on_body_entered"]
|
||||
[connection signal="body_entered" from="Collision" to="." method="_on_body_entered"]
|
||||
[connection signal="input_event" from="Collision" to="." method="_on_collision_input_event"]
|
||||
|
||||
@@ -17,39 +17,56 @@ var desired_rotation: float = 0
|
||||
# Resources / money
|
||||
var resources: int = 0
|
||||
|
||||
# Health
|
||||
var maxHealth: int = 100
|
||||
var healthPoints: int = 100
|
||||
var isAlive: bool = true
|
||||
@onready var invulnerable_cooldown_timer: Timer = $InvulnerableCooldownTimer
|
||||
var hasiframes: bool = false # only used for iframe after collision for now
|
||||
var target = Vector2.ZERO # either vector2 or Node2D
|
||||
|
||||
func _ready() -> void:
|
||||
var screen_size = get_viewport_rect().size
|
||||
GameManager.init_screen_size(screen_size.x, screen_size.y)
|
||||
|
||||
attack_area.monitoring = false # no collision until attacking TODO: Thing about being attacked
|
||||
attack_area.monitoring = false # no collision until attacking TODO: Think about being attacked
|
||||
attack_timer.wait_time = attack_duration
|
||||
attack_cooldown_timer.wait_time = attack_cooldown_duration
|
||||
|
||||
sprite.play("default")
|
||||
|
||||
|
||||
func _input(event):
|
||||
# TODO: only does clicks/taps; accept mouse drags
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
target = get_global_mouse_position()
|
||||
|
||||
func _physics_process(delta):
|
||||
var pos
|
||||
if typeof(target) == TYPE_VECTOR2:
|
||||
pos = target
|
||||
elif "position" in target:
|
||||
pos = target.position
|
||||
else:
|
||||
return
|
||||
var dir: Vector2 = position.direction_to(pos)
|
||||
|
||||
if position.distance_to(pos) > 2:
|
||||
self.desired_rotation = atan2(dir.y, dir.x)
|
||||
move_and_collide(speed * dir * delta)
|
||||
position = GameManager.get_boundaried_position(position)
|
||||
|
||||
|
||||
func _process(delta):
|
||||
velocity = Vector2.ZERO
|
||||
if Input.is_action_pressed("move_right"):
|
||||
velocity.x += 1
|
||||
if Input.is_action_pressed("move_left"):
|
||||
velocity.x -= 1
|
||||
if Input.is_action_pressed("move_down"):
|
||||
velocity.y += 1
|
||||
if Input.is_action_pressed("move_up"):
|
||||
velocity.y -= 1
|
||||
if Input.is_action_pressed("try_attack"):
|
||||
try_attack()
|
||||
if isAlive:
|
||||
if Input.is_action_pressed("try_attack"):
|
||||
try_attack()
|
||||
|
||||
|
||||
if not velocity.is_zero_approx():
|
||||
self.desired_rotation = atan2(velocity.y, velocity.x)
|
||||
|
||||
# smoothly rotate
|
||||
if self.rotation != self.desired_rotation:
|
||||
self.rotation = lerp_angle(self.rotation, self.desired_rotation, clampf(4 * delta, 0, 1))
|
||||
|
||||
move_and_collide(speed * velocity * delta)
|
||||
position = GameManager.get_boundaried_position(position)
|
||||
|
||||
|
||||
func try_attack() -> void:
|
||||
if not can_attack:
|
||||
return
|
||||
@@ -66,7 +83,7 @@ func _on_attack_timeout() -> void:
|
||||
sprite.play("default")
|
||||
attack_cooldown_timer.start()
|
||||
|
||||
func _on_cooldown_timeout() -> void:
|
||||
func _on_attack_cooldown_timeout() -> void:
|
||||
can_attack = true
|
||||
|
||||
func _on_attack_hit(body: Node2D) -> void:
|
||||
@@ -75,17 +92,39 @@ func _on_attack_hit(body: Node2D) -> void:
|
||||
if body.has_method("handle_damage"):
|
||||
body.handle_damage(damage, self)
|
||||
hit_hittable = true
|
||||
elif body.is_in_group("resources"):
|
||||
pass
|
||||
if hit_hittable:
|
||||
await get_tree().create_timer(0.2).timeout
|
||||
sprite.play("default")
|
||||
# TODO: resource handling logic
|
||||
|
||||
func _on_invulnerable_cooldown_timeout() -> void:
|
||||
hasiframes = false
|
||||
|
||||
func handle_damage(dmg: int, src: Node) -> void:
|
||||
# TODO: damage logic
|
||||
pass
|
||||
# TODO: enhanced damage logic (src entity effects?)
|
||||
if not hasiframes:
|
||||
print("Player took %d damage." % dmg)
|
||||
healthPoints -= dmg
|
||||
hasiframes = true
|
||||
invulnerable_cooldown_timer.start()
|
||||
if isAlive and healthPoints <= 0:
|
||||
die()
|
||||
|
||||
func collect_resource(damnt: int) -> void:
|
||||
resources += damnt
|
||||
print("Resource collected! Total: ", resources)
|
||||
|
||||
func die() -> void:
|
||||
print("Player died.")
|
||||
isAlive = false
|
||||
GameManager.switch_scene("respawn")
|
||||
|
||||
# TODO: Is this used or should it be removed? (currently unused)
|
||||
func respawm() -> void:
|
||||
healthPoints = maxHealth
|
||||
isAlive = true
|
||||
hasiframes = true
|
||||
attack_cooldown_timer.start()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,14 +1,21 @@
|
||||
[gd_scene format=3 uid="uid://dxluckxdkpv4f"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://di7eglnrnqm6i" path="res://molecular/molecular_player.gd" id="1_0ix7k"]
|
||||
[ext_resource type="Texture2D" uid="uid://boknmstvkc0a2" path="res://molecular/assets/player-sprite-placeholder-attacking-crop.png" id="2_5hxmy"]
|
||||
[ext_resource type="Texture2D" uid="uid://cxwvga07sm3yl" path="res://molecular/assets/player-sprite-placeholder-crop.png" id="2_en8op"]
|
||||
[ext_resource type="Texture2D" uid="uid://du1lb4nr47kvl" path="res://molecular/assets/player-sprite-attacking.png" id="2_rq1v6"]
|
||||
[ext_resource type="Texture2D" uid="uid://bsd1qtw50esai" path="res://molecular/assets/player-sprite-attacking2.png" id="3_xiwfn"]
|
||||
[ext_resource type="Texture2D" uid="uid://cd0iv6hsi3fad" path="res://molecular/assets/player-sprite.png" id="4_rq1v6"]
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_onrkg"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": ExtResource("2_5hxmy")
|
||||
"duration": 0.5,
|
||||
"texture": ExtResource("2_rq1v6")
|
||||
}, {
|
||||
"duration": 4.0,
|
||||
"texture": ExtResource("3_xiwfn")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": ExtResource("2_rq1v6")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"attacking",
|
||||
@@ -16,19 +23,18 @@ animations = [{
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 5.0,
|
||||
"texture": ExtResource("2_en8op")
|
||||
"texture": ExtResource("4_rq1v6")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"default",
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_5hxmy"]
|
||||
radius = 378.18
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_4flbx"]
|
||||
radius = 191.95984
|
||||
height = 1295.8773
|
||||
radius = 5.999982
|
||||
height = 27.990019
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_5hxmy"]
|
||||
|
||||
[node name="player" type="CharacterBody2D" unique_id=2032508208]
|
||||
collision_mask = 14
|
||||
@@ -36,8 +42,12 @@ script = ExtResource("1_0ix7k")
|
||||
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=1745800698]
|
||||
visibility_layer = 2
|
||||
scale = Vector2(0.5, 0.5)
|
||||
sprite_frames = SubResource("SpriteFrames_onrkg")
|
||||
animation = &"attacking"
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=2137063701 groups=["player"]]
|
||||
rotation = -1.5732701
|
||||
shape = SubResource("CapsuleShape2D_4flbx")
|
||||
|
||||
[node name="AttackArea" type="Area2D" parent="." unique_id=187975387]
|
||||
position = Vector2(0, 56)
|
||||
@@ -45,20 +55,20 @@ rotation = -1.5732701
|
||||
collision_mask = 6
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="AttackArea" unique_id=1968501358]
|
||||
position = Vector2(41.029465, 288.86832)
|
||||
position = Vector2(55.977566, 9.138502)
|
||||
shape = SubResource("CircleShape2D_5hxmy")
|
||||
debug_color = Color(0.80813414, 0.3957308, 0.3356335, 0.41960785)
|
||||
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=2137063701 groups=["player"]]
|
||||
rotation = -1.5732701
|
||||
shape = SubResource("CapsuleShape2D_4flbx")
|
||||
|
||||
[node name="AttackTimer" type="Timer" parent="." unique_id=2057433652]
|
||||
one_shot = true
|
||||
|
||||
[node name="AttackCooldownTimer" type="Timer" parent="." unique_id=1056439284]
|
||||
one_shot = true
|
||||
|
||||
[node name="InvulnerableCooldownTimer" type="Timer" parent="." unique_id=311411582]
|
||||
one_shot = true
|
||||
|
||||
[connection signal="body_entered" from="AttackArea" to="." method="_on_attack_hit"]
|
||||
[connection signal="timeout" from="AttackTimer" to="." method="_on_attack_timeout"]
|
||||
[connection signal="timeout" from="AttackCooldownTimer" to="." method="_on_cooldown_timeout"]
|
||||
[connection signal="timeout" from="AttackCooldownTimer" to="." method="_on_attack_cooldown_timeout"]
|
||||
[connection signal="timeout" from="InvulnerableCooldownTimer" to="." method="_on_invulnerable_cooldown_timeout"]
|
||||
|
||||
File diff suppressed because one or more lines are too long
26
evolve-die-repeat/molecular/predator/collision.gd
Normal file
26
evolve-die-repeat/molecular/predator/collision.gd
Normal file
@@ -0,0 +1,26 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
var desired_rotation: float = self.rotation
|
||||
@export var speed = 0.8
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
# smoothly rotate
|
||||
if self.rotation != self.desired_rotation:
|
||||
self.rotation = lerp_angle(self.rotation, self.desired_rotation, clampf(4 * delta, 0, 1))
|
||||
|
||||
func move(motion: Vector3, mod: float) -> void:
|
||||
self.desired_rotation = atan2(motion.y, motion.x)
|
||||
move_and_collide(Vector2(motion.x, motion.y).normalized() * self.speed * mod) # Moves along the given vector
|
||||
|
||||
# Apply boundary to new position
|
||||
position = GameManager.get_boundaried_position(position)
|
||||
|
||||
func handle_damage(dmg: int, src: Node) -> void:
|
||||
if owner:
|
||||
owner.handle_damage(dmg, src)
|
||||
|
||||
func duplicate_init() -> void:
|
||||
var sight = $Sight
|
||||
remove_child(sight)
|
||||
sight.queue_free()
|
||||
1
evolve-die-repeat/molecular/predator/collision.gd.uid
Normal file
1
evolve-die-repeat/molecular/predator/collision.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cus6ogtwxx4v7
|
||||
@@ -1,40 +1,33 @@
|
||||
extends AbstractPredator2D
|
||||
extends AbstractPredator
|
||||
|
||||
# FIXME: (general) tracking across wrapping boundary
|
||||
|
||||
var starting_pos
|
||||
var can_attack: bool = true
|
||||
var desired_rotation: float = self.rotation
|
||||
@onready var sprite = $AnimatedSprite2D
|
||||
@onready var fsm: StateMachine = $StateMachine
|
||||
@onready var attack_cooldown_timer: Timer = $AttackCooldownTimer
|
||||
@onready var wrapper: WrappingManager = $WrappingManager
|
||||
|
||||
@onready var collision: CharacterBody2D = $Collision
|
||||
@onready var sprite = $Collision/Sprite
|
||||
@export var damage: int = 15
|
||||
@export var attack_range = 20
|
||||
@export var attack_range = 40
|
||||
@export var sight_range = 200
|
||||
@export var speed = 0.8
|
||||
|
||||
func _ready() -> void:
|
||||
health = maxHealth
|
||||
sprite.play("Healthy")
|
||||
play_sprite(idle_sprite)
|
||||
if starting_pos:
|
||||
collision.set_position(starting_pos)
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
# smoothly rotate
|
||||
if self.rotation != self.desired_rotation:
|
||||
self.rotation = lerp_angle(self.rotation, self.desired_rotation, clampf(4 * delta, 0, 1))
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
pass
|
||||
|
||||
# FIXME: (also goes for prey) this is framerate dependent UNLESS called from a _physics function.
|
||||
func move(motion: Vector3, mod: float = 1.0) -> void:
|
||||
move_and_collide(Vector2(motion.x, motion.y).normalized() * self.speed * mod) # Moves along the given vector
|
||||
self.desired_rotation = atan2(motion.y, motion.x)
|
||||
|
||||
# Apply boundary to new position
|
||||
position = GameManager.get_boundaried_position(position)
|
||||
collision.move(motion, mod)
|
||||
|
||||
|
||||
func set_position(pos: Vector2) -> void:
|
||||
if collision:
|
||||
collision.set_position(pos)
|
||||
else:
|
||||
starting_pos = pos
|
||||
|
||||
func try_attack(target: Node) -> void:
|
||||
if not can_attack:
|
||||
@@ -46,11 +39,8 @@ func attack(target: Node) -> void:
|
||||
var hit_hittable = false
|
||||
if target.is_in_group("prey") or target.is_in_group("player"):
|
||||
if target.has_method("handle_damage"):
|
||||
target.handle_damage(damage, self)
|
||||
target.handle_damage(damage, self.collision)
|
||||
hit_hittable = true
|
||||
elif target.is_in_group("resources"):
|
||||
# TODO: resource handling logic
|
||||
pass
|
||||
if hit_hittable:
|
||||
attack_cooldown_timer.start()
|
||||
|
||||
@@ -70,8 +60,8 @@ func die() -> void:
|
||||
super.die()
|
||||
|
||||
func become_injured() -> void:
|
||||
sprite.play("Hurt")
|
||||
wrapper.play_sprite("Hurt")
|
||||
idle_sprite = "Hurt"
|
||||
play_sprite(idle_sprite)
|
||||
|
||||
func _on_sight_body_entered(body: Node2D) -> void:
|
||||
if fsm.map(fsm.state) != fsm.States.HUNTING and body.is_in_group("prey") or (health < maxHealth and body.is_in_group("player")):
|
||||
@@ -79,3 +69,9 @@ func _on_sight_body_entered(body: Node2D) -> void:
|
||||
|
||||
func _on_attack_cooldown_timer_timeout() -> void:
|
||||
can_attack = true
|
||||
|
||||
|
||||
func _on_collision_input_event(viewport: Node, event: InputEvent, shape_idx: int) -> void:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
|
||||
if player:
|
||||
player.target = self.collision
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
[gd_scene format=3 uid="uid://s4s66oaexava"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d07cjelbqbiug" path="res://molecular/predator/hammerhead_predator.gd" id="1_xp037"]
|
||||
[ext_resource type="Script" uid="uid://cus6ogtwxx4v7" path="res://molecular/predator/collision.gd" id="2_7qt2q"]
|
||||
[ext_resource type="Texture2D" uid="uid://ch5rddsumyyhm" path="res://molecular/assets/predator/predator-healthy.png" id="2_34kwa"]
|
||||
[ext_resource type="Texture2D" uid="uid://30uwkdbnuu3h" path="res://molecular/assets/predator/hammerheadRibozyme-hunting.png" id="3_0ts4d"]
|
||||
[ext_resource type="Script" uid="uid://cygrmt03sx0k1" path="res://molecular/predator/state_machine.gd" id="3_xp037"]
|
||||
@@ -91,32 +92,44 @@ animations = [{
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[node name="HammerheadPredator" type="CharacterBody2D" unique_id=678504815 groups=["predator"]]
|
||||
scale = Vector2(0.3, 0.3)
|
||||
collision_layer = 4
|
||||
collision_mask = 3
|
||||
motion_mode = 1
|
||||
[node name="HammerheadPredator" type="Node" unique_id=1312337720]
|
||||
script = ExtResource("1_xp037")
|
||||
maxHealth = 50
|
||||
metadata/_custom_type_script = "uid://dgfimmq53whll"
|
||||
|
||||
[node name="WrappingManager" type="Node" parent="." unique_id=826586678 node_paths=PackedStringArray("sprite", "shape")]
|
||||
script = ExtResource("9_shhro")
|
||||
sprite = NodePath("../AnimatedSprite2D")
|
||||
shape = NodePath("../CollisionPolygon2D")
|
||||
metadata/_custom_type_script = "uid://bvbc0n0pslq7p"
|
||||
[node name="Collision" type="CharacterBody2D" parent="." unique_id=76553184 groups=["predator"]]
|
||||
scale = Vector2(0.8, 0.8)
|
||||
collision_layer = 4
|
||||
collision_mask = 3
|
||||
input_pickable = true
|
||||
script = ExtResource("2_7qt2q")
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="." unique_id=1596156928]
|
||||
[node name="Sprite" type="AnimatedSprite2D" parent="Collision" unique_id=410999609]
|
||||
rotation = -1.5707964
|
||||
sprite_frames = SubResource("SpriteFrames_shhro")
|
||||
animation = &"Healthy"
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Collision" unique_id=1596156928]
|
||||
light_mask = 4
|
||||
visibility_layer = 4
|
||||
position = Vector2(0.111679085, 1.1167793)
|
||||
rotation = -1.5707964
|
||||
polygon = PackedVector2Array(-22.184862, -27.994831, 23.481365, -27.21198, 13.82622, 25.891317, -6.005971, 25.891317)
|
||||
|
||||
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="." unique_id=410999609]
|
||||
rotation = 4.712389
|
||||
sprite_frames = SubResource("SpriteFrames_shhro")
|
||||
animation = &"Hunting"
|
||||
[node name="Sight" type="Area2D" parent="Collision" unique_id=1608385873]
|
||||
collision_layer = 0
|
||||
collision_mask = 7
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Collision/Sight" unique_id=1707240701]
|
||||
light_mask = 4
|
||||
visibility_layer = 4
|
||||
position = Vector2(-1.0900421, 1.6350927)
|
||||
rotation = -1.5707964
|
||||
polygon = PackedVector2Array(14.135091, 27.34004, 56.058624, 148.93633, 22.979004, 163.77974, -19.854843, 161.65926, -53.782654, 143.84715, -5.8649073, 27.34004)
|
||||
|
||||
[node name="WrappingManager" type="Node" parent="." unique_id=826586678]
|
||||
script = ExtResource("9_shhro")
|
||||
metadata/_custom_type_script = "uid://bvbc0n0pslq7p"
|
||||
|
||||
[node name="StateMachine" type="Node" parent="." unique_id=1857729810 node_paths=PackedStringArray("initial_state")]
|
||||
script = ExtResource("3_xp037")
|
||||
@@ -138,22 +151,12 @@ one_shot = true
|
||||
[node name="Hunting" type="Node" parent="StateMachine" unique_id=1569866955]
|
||||
script = ExtResource("8_7qt2q")
|
||||
|
||||
[node name="Sight" type="Area2D" parent="." unique_id=1608385873]
|
||||
collision_layer = 0
|
||||
collision_mask = 7
|
||||
|
||||
[node name="CollisionPolygon2D" type="CollisionPolygon2D" parent="Sight" unique_id=1707240701]
|
||||
light_mask = 4
|
||||
visibility_layer = 4
|
||||
position = Vector2(-1.0900421, 1.6350927)
|
||||
rotation = -1.5707964
|
||||
polygon = PackedVector2Array(-27.769547, -29.426758, 31.88504, -29.184647, 12.700996, 28.7294, 56.058624, 148.93633, 22.979004, 163.77974, -19.854843, 161.65926, -53.782654, 143.84715, -8.333115, 30.157196)
|
||||
|
||||
[node name="AttackCooldownTimer" type="Timer" parent="." unique_id=435253442]
|
||||
wait_time = 0.5
|
||||
one_shot = true
|
||||
|
||||
[connection signal="input_event" from="Collision" to="." method="_on_collision_input_event"]
|
||||
[connection signal="body_entered" from="Collision/Sight" to="." method="_on_sight_body_entered"]
|
||||
[connection signal="timeout" from="StateMachine/Idle/Timer" to="StateMachine/Idle" method="_on_timer_timeout"]
|
||||
[connection signal="timeout" from="StateMachine/RandomMovement/Timer" to="StateMachine/RandomMovement" method="_on_timer_timeout"]
|
||||
[connection signal="body_entered" from="Sight" to="." method="_on_sight_body_entered"]
|
||||
[connection signal="timeout" from="AttackCooldownTimer" to="." method="_on_attack_cooldown_timer_timeout"]
|
||||
|
||||
@@ -5,22 +5,22 @@ var target: Node2D
|
||||
func enter(previous_state_path: String, data := {}) -> void:
|
||||
if data.has("target"):
|
||||
target = data["target"]
|
||||
owner.sprite.play("Hunting")
|
||||
owner.play_sprite("Hunting")
|
||||
else:
|
||||
# default behaviour; do nothing
|
||||
finished.emit(owner.fsm.States.IDLE, {})
|
||||
|
||||
func physics_update(_delta: float) -> void:
|
||||
if target == null or GameManager.calc_distance(owner.position, target.position) > owner.sight_range:
|
||||
if target == null or GameManager.calc_distance(owner.collision.position, target.position) > owner.sight_range:
|
||||
finished.emit(owner.fsm.States.IDLE, {})
|
||||
return
|
||||
|
||||
# alternatively, we could use a collision shape and inbuilt signals, but im not sure if that works better (mixing signals and custom fsm stuff i mean
|
||||
if GameManager.calc_distance(owner.position, target.position) > owner.attack_range:
|
||||
if GameManager.calc_distance(owner.collision.position, target.position) > owner.attack_range:
|
||||
owner.move(move_towards(target.position))
|
||||
else:
|
||||
owner.attack(target)
|
||||
|
||||
func move_towards(pos: Vector2) -> Vector3:
|
||||
var diff = target.position - owner.position
|
||||
var diff = target.position - owner.collision.position
|
||||
return Vector3(diff.x, diff.y ,0)
|
||||
|
||||
28
evolve-die-repeat/molecular/prey/collision.gd
Normal file
28
evolve-die-repeat/molecular/prey/collision.gd
Normal file
@@ -0,0 +1,28 @@
|
||||
extends CharacterBody2D
|
||||
|
||||
var desired_rotation: float = self.rotation
|
||||
@export var speed = 0.5
|
||||
|
||||
|
||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||
func _process(delta: float) -> void:
|
||||
# smoothly rotate
|
||||
if self.rotation != self.desired_rotation:
|
||||
self.rotation = lerp_angle(self.rotation, self.desired_rotation, clampf(4 * delta, 0, 1))
|
||||
|
||||
func move(motion: Vector3, mod: float) -> void:
|
||||
move_and_collide(Vector2(motion.x, motion.y).normalized() * self.speed * mod) # Moves along the given vector
|
||||
self.desired_rotation = atan2(motion.y, motion.x)
|
||||
|
||||
# Apply boundary to new position
|
||||
position = GameManager.get_boundaried_position(position)
|
||||
|
||||
|
||||
func handle_damage(dmg: int, src: Node) -> void:
|
||||
if owner:
|
||||
owner.handle_damage(dmg, src)
|
||||
|
||||
func duplicate_init() -> void:
|
||||
var sight = $Sight
|
||||
remove_child(sight)
|
||||
sight.queue_free()
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user