Added final features for this release. Now only polishing (if needed) remains.
Features: Sacrifice-Node, Maintain-Node, Options for screen type, lightcolor and soundvolume, tied in sound effects, game pause when menu is open, visibly open up gate when opening it.
This commit is contained in:
@@ -0,0 +1,46 @@
|
|||||||
|
[gd_scene format=3 uid="uid://fe7so4543q4x"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/UI/DSL/NodeDisplay.cs" id="1_maintain"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_trash"]
|
||||||
|
|
||||||
|
[node name="Maintain" type="PanelContainer" unique_id=346305609 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
anchors_preset = 14
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_bottom = 31.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
script = ExtResource("1_maintain")
|
||||||
|
editorDisplay = NodePath("EditorDisplay")
|
||||||
|
listDisplay = NodePath("ListDisplay")
|
||||||
|
|
||||||
|
[node name="EditorDisplay" type="PanelContainer" parent="." unique_id=237286109]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="EditorDisplay" unique_id=222639319]
|
||||||
|
layout_mode = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="Flavour" type="RichTextLabel" parent="EditorDisplay/HBoxContainer" unique_id=50532719]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Maintain"
|
||||||
|
fit_content = true
|
||||||
|
autowrap_mode = 0
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="TextureButton" type="TextureButton" parent="EditorDisplay/HBoxContainer" unique_id=1753994239]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_stretch_ratio = 0.2
|
||||||
|
texture_normal = ExtResource("2_trash")
|
||||||
|
|
||||||
|
[node name="ListDisplay" type="Button" parent="." unique_id=991375625]
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Repairs the robot by 10% and consumes one matching gear."
|
||||||
|
text = "Maintain"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="EditorDisplay/HBoxContainer/TextureButton" to="." method="DeleteNodePressed"]
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
[gd_scene format=3 uid="uid://bxph44i8mad1i"]
|
||||||
|
|
||||||
|
[ext_resource type="Script" uid="uid://b6kxwmuhmruul" path="res://Scripts/UI/DSL/NodeDisplay.cs" id="1_sacrifice"]
|
||||||
|
[ext_resource type="Texture2D" uid="uid://wq8yc0u0ee33" path="res://Assets/Images/TrashSymbol.png" id="2_trash"]
|
||||||
|
|
||||||
|
[node name="Sacrifice" type="PanelContainer" unique_id=442348941 node_paths=PackedStringArray("editorDisplay", "listDisplay")]
|
||||||
|
anchors_preset = 14
|
||||||
|
anchor_top = 0.5
|
||||||
|
anchor_right = 1.0
|
||||||
|
anchor_bottom = 0.5
|
||||||
|
offset_bottom = 31.0
|
||||||
|
grow_horizontal = 2
|
||||||
|
grow_vertical = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
script = ExtResource("1_sacrifice")
|
||||||
|
editorDisplay = NodePath("EditorDisplay")
|
||||||
|
listDisplay = NodePath("ListDisplay")
|
||||||
|
|
||||||
|
[node name="EditorDisplay" type="PanelContainer" parent="." unique_id=1064798043]
|
||||||
|
layout_mode = 2
|
||||||
|
|
||||||
|
[node name="HBoxContainer" type="HBoxContainer" parent="EditorDisplay" unique_id=1195324631]
|
||||||
|
layout_mode = 2
|
||||||
|
alignment = 1
|
||||||
|
|
||||||
|
[node name="Flavour" type="RichTextLabel" parent="EditorDisplay/HBoxContainer" unique_id=1628437503]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Sacrifice"
|
||||||
|
fit_content = true
|
||||||
|
autowrap_mode = 0
|
||||||
|
horizontal_alignment = 1
|
||||||
|
vertical_alignment = 1
|
||||||
|
|
||||||
|
[node name="TextureButton" type="TextureButton" parent="EditorDisplay/HBoxContainer" unique_id=1813377435]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
size_flags_stretch_ratio = 0.2
|
||||||
|
texture_normal = ExtResource("2_trash")
|
||||||
|
|
||||||
|
[node name="ListDisplay" type="Button" parent="." unique_id=2140824916]
|
||||||
|
layout_mode = 2
|
||||||
|
tooltip_text = "Sacrifices the robot and makes the resource on this tile endless."
|
||||||
|
text = "Sacrifice"
|
||||||
|
|
||||||
|
[connection signal="pressed" from="EditorDisplay/HBoxContainer/TextureButton" to="." method="DeleteNodePressed"]
|
||||||
@@ -3,7 +3,10 @@
|
|||||||
[ext_resource type="Script" uid="uid://br2udyi6t8yvf" path="res://Scripts/World/World.cs" id="1_7lihs"]
|
[ext_resource type="Script" uid="uid://br2udyi6t8yvf" path="res://Scripts/World/World.cs" id="1_7lihs"]
|
||||||
[ext_resource type="AudioStream" uid="uid://dcb746ldlm6ta" path="res://Assets/Sound/Background.mp3" id="1_rajel"]
|
[ext_resource type="AudioStream" uid="uid://dcb746ldlm6ta" path="res://Assets/Sound/Background.mp3" id="1_rajel"]
|
||||||
[ext_resource type="Script" uid="uid://dqrdb3bvws6b6" path="res://Scripts/Core/SteamworksHandler.cs" id="2_b2bpf"]
|
[ext_resource type="Script" uid="uid://dqrdb3bvws6b6" path="res://Scripts/Core/SteamworksHandler.cs" id="2_b2bpf"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://d001edcgov542" path="res://Assets/Sound/button.wav" id="2_button"]
|
||||||
|
[ext_resource type="AudioStream" uid="uid://bo0jlfldvl3fc" path="res://Assets/Sound/mining.wav" id="2_mining"]
|
||||||
[ext_resource type="Script" uid="uid://c7khr6oist3ku" path="res://Scripts/UI/Common/Camera3d.cs" id="3_7lihs"]
|
[ext_resource type="Script" uid="uid://c7khr6oist3ku" path="res://Scripts/UI/Common/Camera3d.cs" id="3_7lihs"]
|
||||||
|
[ext_resource type="Script" uid="uid://gvy12mefkwax" path="res://Scripts/Core/SoundManager.cs" id="3_sound"]
|
||||||
[ext_resource type="Script" uid="uid://bm7knir4552j5" path="res://Scripts/UI/Common/UIHandler.cs" id="4_fgofq"]
|
[ext_resource type="Script" uid="uid://bm7knir4552j5" path="res://Scripts/UI/Common/UIHandler.cs" id="4_fgofq"]
|
||||||
[ext_resource type="Script" uid="uid://bsd6n6b06a4pe" path="res://Scripts/UI/DSL/CodingWindow.cs" id="6_7lihs"]
|
[ext_resource type="Script" uid="uid://bsd6n6b06a4pe" path="res://Scripts/UI/DSL/CodingWindow.cs" id="6_7lihs"]
|
||||||
[ext_resource type="Script" uid="uid://k6vlo7ulvtep" path="res://Scripts/UI/Robots/RobotList.cs" id="7_2irst"]
|
[ext_resource type="Script" uid="uid://k6vlo7ulvtep" path="res://Scripts/UI/Robots/RobotList.cs" id="7_2irst"]
|
||||||
@@ -59,6 +62,19 @@ volume_db = -25.0
|
|||||||
autoplay = true
|
autoplay = true
|
||||||
parameters/looping = true
|
parameters/looping = true
|
||||||
|
|
||||||
|
[node name="ButtonSound" type="AudioStreamPlayer" parent="." unique_id=696063778]
|
||||||
|
stream = ExtResource("2_button")
|
||||||
|
volume_db = -8.0
|
||||||
|
|
||||||
|
[node name="MiningSound" type="AudioStreamPlayer" parent="." unique_id=1851503354]
|
||||||
|
stream = ExtResource("2_mining")
|
||||||
|
volume_db = -12.0
|
||||||
|
|
||||||
|
[node name="SoundManager" type="Node" parent="." unique_id=1220134706 node_paths=PackedStringArray("buttonSound", "miningSound")]
|
||||||
|
script = ExtResource("3_sound")
|
||||||
|
buttonSound = NodePath("../ButtonSound")
|
||||||
|
miningSound = NodePath("../MiningSound")
|
||||||
|
|
||||||
[node name="World" type="Node3D" parent="." unique_id=770208789]
|
[node name="World" type="Node3D" parent="." unique_id=770208789]
|
||||||
script = ExtResource("1_7lihs")
|
script = ExtResource("1_7lihs")
|
||||||
|
|
||||||
@@ -329,6 +345,11 @@ layout_mode = 2
|
|||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
text = "Save"
|
text = "Save"
|
||||||
|
|
||||||
|
[node name="Delete" type="Button" parent="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Saving" unique_id=1891250978]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
text = "Delete"
|
||||||
|
|
||||||
[node name="Load" type="OptionButton" parent="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow" unique_id=970393437]
|
[node name="Load" type="OptionButton" parent="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow" unique_id=970393437]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
@@ -679,6 +700,7 @@ text = "Next"
|
|||||||
[connection signal="button_up" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Buttons/Clear" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="ClearWindow"]
|
[connection signal="button_up" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Buttons/Clear" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="ClearWindow"]
|
||||||
[connection signal="button_up" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Buttons/Compile" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="CompileProgram"]
|
[connection signal="button_up" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Buttons/Compile" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="CompileProgram"]
|
||||||
[connection signal="pressed" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Saving/Save" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="SaveProgram"]
|
[connection signal="pressed" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Saving/Save" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="SaveProgram"]
|
||||||
|
[connection signal="pressed" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Saving/Delete" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="DeleteProgram"]
|
||||||
[connection signal="item_selected" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Load" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="LoadProgram"]
|
[connection signal="item_selected" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Scripting/EditorWindow/Load" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="LoadProgram"]
|
||||||
[connection signal="pressed" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Close" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="CloseWindow"]
|
[connection signal="pressed" from="CanvasLayer/UIHandler/MainUI/Content/CodingWindow/VBoxContainer/Close" to="CanvasLayer/UIHandler/MainUI/Content/CodingWindow" method="CloseWindow"]
|
||||||
[connection signal="item_selected" from="CanvasLayer/UIHandler/MainUI/Content/RobotList/VBoxContainer/Spawning/OptionButton" to="CanvasLayer/UIHandler/MainUI/Content/RobotList" method="OnRobotSelect"]
|
[connection signal="item_selected" from="CanvasLayer/UIHandler/MainUI/Content/RobotList/VBoxContainer/Spawning/OptionButton" to="CanvasLayer/UIHandler/MainUI/Content/RobotList" method="OnRobotSelect"]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
[ext_resource type="Texture2D" uid="uid://dt84awx33mulb" path="res://Assets/Images/ResearchSymbol.png" id="3_df05h"]
|
[ext_resource type="Texture2D" uid="uid://dt84awx33mulb" path="res://Assets/Images/ResearchSymbol.png" id="3_df05h"]
|
||||||
[ext_resource type="Texture2D" uid="uid://dm0w2gtcsa5l4" path="res://Assets/Images/Items/Batteryv1Symbol.png" id="4_8um5k"]
|
[ext_resource type="Texture2D" uid="uid://dm0w2gtcsa5l4" path="res://Assets/Images/Items/Batteryv1Symbol.png" id="4_8um5k"]
|
||||||
[ext_resource type="Texture2D" uid="uid://qqprre8xl8gv" path="res://Assets/Images/Items/Dynamov2Symbol.png" id="5_xim88"]
|
[ext_resource type="Texture2D" uid="uid://qqprre8xl8gv" path="res://Assets/Images/Items/Dynamov2Symbol.png" id="5_xim88"]
|
||||||
|
[ext_resource type="PackedScene" uid="uid://cpq7ppe8bw2bq" path="res://Scenes/Options.tscn" id="6_options"]
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bnhvo"]
|
[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_bnhvo"]
|
||||||
bg_color = Color(0.24115604, 0.24115607, 0.24115595, 1)
|
bg_color = Color(0.24115604, 0.24115607, 0.24115595, 1)
|
||||||
@@ -27,7 +28,7 @@ corner_radius_top_right = 10
|
|||||||
corner_radius_bottom_right = 10
|
corner_radius_bottom_right = 10
|
||||||
corner_radius_bottom_left = 10
|
corner_radius_bottom_left = 10
|
||||||
|
|
||||||
[node name="MainMenu" type="Control" unique_id=622011874]
|
[node name="MainMenu" type="Control" unique_id=622011874 node_paths=PackedStringArray("options")]
|
||||||
layout_mode = 3
|
layout_mode = 3
|
||||||
anchors_preset = 15
|
anchors_preset = 15
|
||||||
anchor_right = 1.0
|
anchor_right = 1.0
|
||||||
@@ -35,6 +36,7 @@ anchor_bottom = 1.0
|
|||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
script = ExtResource("1_tt5f1")
|
script = ExtResource("1_tt5f1")
|
||||||
|
options = NodePath("Options")
|
||||||
|
|
||||||
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="." unique_id=1984828000]
|
[node name="AudioStreamPlayer" type="AudioStreamPlayer" parent="." unique_id=1984828000]
|
||||||
stream = ExtResource("2_8um5k")
|
stream = ExtResource("2_8um5k")
|
||||||
@@ -152,6 +154,11 @@ theme_override_styles/normal = SubResource("StyleBoxFlat_bnhvo")
|
|||||||
theme_override_styles/hover = SubResource("StyleBoxFlat_tt5f1")
|
theme_override_styles/hover = SubResource("StyleBoxFlat_tt5f1")
|
||||||
text = "Exit Game"
|
text = "Exit Game"
|
||||||
|
|
||||||
|
[node name="Options" parent="." instance=ExtResource("6_options")]
|
||||||
|
visible = false
|
||||||
|
layout_mode = 1
|
||||||
|
|
||||||
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnPlay" to="." method="OnPlayPressed"]
|
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnPlay" to="." method="OnPlayPressed"]
|
||||||
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnLoad" to="." method="OnLoadPressed"]
|
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnLoad" to="." method="OnLoadPressed"]
|
||||||
|
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnOptions" to="." method="OnOptionsPressed"]
|
||||||
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnExit" to="." method="OnQuitPressed"]
|
[connection signal="button_up" from="CenterContainer/VBoxContainer/btnExit" to="." method="OnQuitPressed"]
|
||||||
|
|||||||
+44
-4
@@ -1,16 +1,28 @@
|
|||||||
[gd_scene format=3 uid="uid://cpq7ppe8bw2bq"]
|
[gd_scene format=3 uid="uid://cpq7ppe8bw2bq"]
|
||||||
|
|
||||||
[node name="Options" type="PanelContainer" unique_id=230632848]
|
[ext_resource type="Script" path="res://Scripts/UI/Menus/OptionsMenu.cs" id="1_options"]
|
||||||
|
|
||||||
|
[node name="Options" type="PanelContainer" unique_id=230632848 node_paths=PackedStringArray("screenMode", "soundVolume", "lightColor")]
|
||||||
|
custom_minimum_size = Vector2(420, 260)
|
||||||
anchors_preset = 8
|
anchors_preset = 8
|
||||||
anchor_left = 0.5
|
anchor_left = 0.5
|
||||||
anchor_top = 0.5
|
anchor_top = 0.5
|
||||||
anchor_right = 0.5
|
anchor_right = 0.5
|
||||||
anchor_bottom = 0.5
|
anchor_bottom = 0.5
|
||||||
|
offset_left = -210.0
|
||||||
|
offset_top = -130.0
|
||||||
|
offset_right = 210.0
|
||||||
|
offset_bottom = 130.0
|
||||||
grow_horizontal = 2
|
grow_horizontal = 2
|
||||||
grow_vertical = 2
|
grow_vertical = 2
|
||||||
|
script = ExtResource("1_options")
|
||||||
|
screenMode = NodePath("VBoxContainer/GridContainer/ScreenMode")
|
||||||
|
soundVolume = NodePath("VBoxContainer/GridContainer/SoundVolume")
|
||||||
|
lightColor = NodePath("VBoxContainer/GridContainer/LightColor")
|
||||||
|
|
||||||
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1149639381]
|
[node name="VBoxContainer" type="VBoxContainer" parent="." unique_id=1149639381]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
|
theme_override_constants/separation = 10
|
||||||
|
|
||||||
[node name="Title" type="RichTextLabel" parent="VBoxContainer" unique_id=1694731141]
|
[node name="Title" type="RichTextLabel" parent="VBoxContainer" unique_id=1694731141]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
@@ -24,16 +36,44 @@ horizontal_alignment = 1
|
|||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
columns = 2
|
columns = 2
|
||||||
|
|
||||||
[node name="RichTextLabel" type="RichTextLabel" parent="VBoxContainer/GridContainer" unique_id=189106367]
|
[node name="ScreenModeLabel" type="RichTextLabel" parent="VBoxContainer/GridContainer"]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Light color: "
|
text = "Screen"
|
||||||
fit_content = true
|
fit_content = true
|
||||||
autowrap_mode = 0
|
autowrap_mode = 0
|
||||||
|
|
||||||
[node name="ColorPickerButton" type="ColorPickerButton" parent="VBoxContainer/GridContainer" unique_id=1830638845]
|
[node name="ScreenMode" type="OptionButton" parent="VBoxContainer/GridContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
|
[node name="SoundVolumeLabel" type="RichTextLabel" parent="VBoxContainer/GridContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Sound"
|
||||||
|
fit_content = true
|
||||||
|
autowrap_mode = 0
|
||||||
|
|
||||||
|
[node name="SoundVolume" type="HSlider" parent="VBoxContainer/GridContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
size_flags_horizontal = 3
|
||||||
|
max_value = 100.0
|
||||||
|
step = 1.0
|
||||||
|
value = 80.0
|
||||||
|
|
||||||
|
[node name="LightColorLabel" type="RichTextLabel" parent="VBoxContainer/GridContainer"]
|
||||||
|
layout_mode = 2
|
||||||
|
text = "Light color"
|
||||||
|
fit_content = true
|
||||||
|
autowrap_mode = 0
|
||||||
|
|
||||||
|
[node name="LightColor" type="ColorPickerButton" parent="VBoxContainer/GridContainer" unique_id=1830638845]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
size_flags_horizontal = 3
|
size_flags_horizontal = 3
|
||||||
|
|
||||||
[node name="Button" type="Button" parent="VBoxContainer" unique_id=1183264327]
|
[node name="Button" type="Button" parent="VBoxContainer" unique_id=1183264327]
|
||||||
layout_mode = 2
|
layout_mode = 2
|
||||||
text = "Close"
|
text = "Close"
|
||||||
|
|
||||||
|
[connection signal="item_selected" from="VBoxContainer/GridContainer/ScreenMode" to="." method="OnScreenModeSelected"]
|
||||||
|
[connection signal="value_changed" from="VBoxContainer/GridContainer/SoundVolume" to="." method="OnSoundVolumeChanged"]
|
||||||
|
[connection signal="color_changed" from="VBoxContainer/GridContainer/LightColor" to="." method="OnLightColorChanged"]
|
||||||
|
[connection signal="pressed" from="VBoxContainer/Button" to="." method="CloseOptions"]
|
||||||
|
|||||||
@@ -62,6 +62,25 @@ public class FileHandler
|
|||||||
return file.GetAsText();
|
return file.GetAsText();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool DeleteProgram(string name)
|
||||||
|
{
|
||||||
|
CreateScriptDirectory();
|
||||||
|
string path = GetProgramPath(name);
|
||||||
|
|
||||||
|
if (!FileAccess.FileExists(path))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DirAccess dir = DirAccess.Open(ScriptDirectory);
|
||||||
|
if (dir == null)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return dir.Remove($"{name}{ScriptExtension}") == Error.Ok;
|
||||||
|
}
|
||||||
|
|
||||||
private static string GetProgramPath(string filename)
|
private static string GetProgramPath(string filename)
|
||||||
{
|
{
|
||||||
return $"{ScriptDirectory}/{filename}{ScriptExtension}";
|
return $"{ScriptDirectory}/{filename}{ScriptExtension}";
|
||||||
|
|||||||
@@ -25,9 +25,12 @@ public partial class GameData
|
|||||||
public static Dictionary<int, List<Ingredient>> gateUnlocks;
|
public static Dictionary<int, List<Ingredient>> gateUnlocks;
|
||||||
public static bool loadSaveOnStart = false;
|
public static bool loadSaveOnStart = false;
|
||||||
public static bool showTutorial = true;
|
public static bool showTutorial = true;
|
||||||
|
public static bool isPaused = false;
|
||||||
|
|
||||||
public static Color primaryColor = new Color("#276ac2");
|
public static Color primaryColor = new Color("#276ac2");
|
||||||
public static Color lightColor = new Color("#7efff5");
|
public static Color lightColor = new Color("#7efff5");
|
||||||
|
public static int screenMode = 2;
|
||||||
|
public static float soundVolume = 0.8f;
|
||||||
|
|
||||||
public static int ruinSize = 10;
|
public static int ruinSize = 10;
|
||||||
public static int layerSize = 20;
|
public static int layerSize = 20;
|
||||||
@@ -44,12 +47,14 @@ public partial class GameData
|
|||||||
robotStats = new RobotStats();
|
robotStats = new RobotStats();
|
||||||
inventory = new Inventory();
|
inventory = new Inventory();
|
||||||
availableResearch = ResourceLoader.LoadResearch();
|
availableResearch = ResourceLoader.LoadResearch();
|
||||||
|
map = null;
|
||||||
robots.Clear();
|
robots.Clear();
|
||||||
currentLayer = 0;
|
currentLayer = 0;
|
||||||
visibleLayer = 0;
|
visibleLayer = 0;
|
||||||
lowestLayer = 0;
|
lowestLayer = 0;
|
||||||
maxRobotCount = 10;
|
maxRobotCount = 10;
|
||||||
canMove = true;
|
canMove = true;
|
||||||
|
isPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void RebuildRobotStatsFromResearch()
|
public static void RebuildRobotStatsFromResearch()
|
||||||
@@ -65,4 +70,22 @@ public partial class GameData
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static bool HasSpawnableRobotInInventory()
|
||||||
|
{
|
||||||
|
foreach (Item item in inventory.items)
|
||||||
|
{
|
||||||
|
if (robotStats.RobotTypes.ContainsKey(item.data.Id) && item.currentAmount > 0)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HasNoRobotRecovery()
|
||||||
|
{
|
||||||
|
return robots.Count <= 0 && !HasSpawnableRobotInInventory();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,9 @@ public partial class ResourceLoader
|
|||||||
{ new ElseNode(), GD.Load<PackedScene>("res://Prefabs/DSL/ElseNode.tscn") },
|
{ new ElseNode(), GD.Load<PackedScene>("res://Prefabs/DSL/ElseNode.tscn") },
|
||||||
{ new UntilNode(), GD.Load<PackedScene>("res://Prefabs/DSL/UntilNode.tscn") },
|
{ new UntilNode(), GD.Load<PackedScene>("res://Prefabs/DSL/UntilNode.tscn") },
|
||||||
{ new ForNode(), GD.Load<PackedScene>("res://Prefabs/DSL/ForNode.tscn") },
|
{ new ForNode(), GD.Load<PackedScene>("res://Prefabs/DSL/ForNode.tscn") },
|
||||||
{ new WhileNode(), GD.Load<PackedScene>("res://Prefabs/DSL/WhileNode.tscn") }
|
{ new WhileNode(), GD.Load<PackedScene>("res://Prefabs/DSL/WhileNode.tscn") },
|
||||||
|
{ new MaintainNode(), GD.Load<PackedScene>("res://Prefabs/DSL/MaintainNode.tscn") },
|
||||||
|
{ new SacrificeNode(), GD.Load<PackedScene>("res://Prefabs/DSL/SacrificeNode.tscn") }
|
||||||
};
|
};
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ public class SaveGameData
|
|||||||
public int LowestLayer { get; set; }
|
public int LowestLayer { get; set; }
|
||||||
public int MaxRobotCount { get; set; }
|
public int MaxRobotCount { get; set; }
|
||||||
public bool CanMove { get; set; }
|
public bool CanMove { get; set; }
|
||||||
|
public SettingsSaveData Settings { get; set; }
|
||||||
public SurvivalSaveData Survival { get; set; }
|
public SurvivalSaveData Survival { get; set; }
|
||||||
public List<ItemSaveData> Inventory { get; set; }
|
public List<ItemSaveData> Inventory { get; set; }
|
||||||
public List<ResearchSaveData> Research { get; set; }
|
public List<ResearchSaveData> Research { get; set; }
|
||||||
@@ -15,6 +16,16 @@ public class SaveGameData
|
|||||||
public List<RobotSaveData> Robots { get; set; }
|
public List<RobotSaveData> Robots { get; set; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SettingsSaveData
|
||||||
|
{
|
||||||
|
public int ScreenMode { get; set; }
|
||||||
|
public float SoundVolume { get; set; }
|
||||||
|
public float LightColorR { get; set; }
|
||||||
|
public float LightColorG { get; set; }
|
||||||
|
public float LightColorB { get; set; }
|
||||||
|
public float LightColorA { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
public class SurvivalSaveData
|
public class SurvivalSaveData
|
||||||
{
|
{
|
||||||
public float Hunger { get; set; }
|
public float Hunger { get; set; }
|
||||||
|
|||||||
@@ -61,6 +61,7 @@ public static class SaveGameManager
|
|||||||
LowestLayer = GameData.lowestLayer,
|
LowestLayer = GameData.lowestLayer,
|
||||||
MaxRobotCount = GameData.maxRobotCount,
|
MaxRobotCount = GameData.maxRobotCount,
|
||||||
CanMove = GameData.canMove,
|
CanMove = GameData.canMove,
|
||||||
|
Settings = CreateSettingsSaveData(),
|
||||||
Survival = CreateSurvivalSaveData(),
|
Survival = CreateSurvivalSaveData(),
|
||||||
Inventory = CreateInventorySaveData(),
|
Inventory = CreateInventorySaveData(),
|
||||||
Research = CreateResearchSaveData(),
|
Research = CreateResearchSaveData(),
|
||||||
@@ -80,6 +81,7 @@ public static class SaveGameManager
|
|||||||
GameData.maxRobotCount = saveGame.MaxRobotCount;
|
GameData.maxRobotCount = saveGame.MaxRobotCount;
|
||||||
GameData.canMove = saveGame.CanMove;
|
GameData.canMove = saveGame.CanMove;
|
||||||
|
|
||||||
|
ApplySettingsData(saveGame.Settings);
|
||||||
ApplySurvivalData(saveGame.Survival);
|
ApplySurvivalData(saveGame.Survival);
|
||||||
ApplyInventoryData(saveGame.Inventory);
|
ApplyInventoryData(saveGame.Inventory);
|
||||||
ApplyResearchData(saveGame.Research);
|
ApplyResearchData(saveGame.Research);
|
||||||
@@ -100,6 +102,19 @@ public static class SaveGameManager
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static SettingsSaveData CreateSettingsSaveData()
|
||||||
|
{
|
||||||
|
return new SettingsSaveData
|
||||||
|
{
|
||||||
|
ScreenMode = GameData.screenMode,
|
||||||
|
SoundVolume = GameData.soundVolume,
|
||||||
|
LightColorR = GameData.lightColor.R,
|
||||||
|
LightColorG = GameData.lightColor.G,
|
||||||
|
LightColorB = GameData.lightColor.B,
|
||||||
|
LightColorA = GameData.lightColor.A
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
private static List<ItemSaveData> CreateInventorySaveData()
|
private static List<ItemSaveData> CreateInventorySaveData()
|
||||||
{
|
{
|
||||||
List<ItemSaveData> result = new List<ItemSaveData>();
|
List<ItemSaveData> result = new List<ItemSaveData>();
|
||||||
@@ -201,6 +216,7 @@ public static class SaveGameManager
|
|||||||
LowestLayer = saveGame.LowestLayer,
|
LowestLayer = saveGame.LowestLayer,
|
||||||
MaxRobotCount = saveGame.MaxRobotCount,
|
MaxRobotCount = saveGame.MaxRobotCount,
|
||||||
CanMove = saveGame.CanMove,
|
CanMove = saveGame.CanMove,
|
||||||
|
Settings = saveGame.Settings,
|
||||||
Survival = saveGame.Survival,
|
Survival = saveGame.Survival,
|
||||||
Inventory = saveGame.Inventory,
|
Inventory = saveGame.Inventory,
|
||||||
Research = new List<ResearchSaveData>(),
|
Research = new List<ResearchSaveData>(),
|
||||||
@@ -286,6 +302,43 @@ public static class SaveGameManager
|
|||||||
GameData.survival.elapsedSeconds = survival.ElapsedSeconds;
|
GameData.survival.elapsedSeconds = survival.ElapsedSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ApplySettingsData(SettingsSaveData settings)
|
||||||
|
{
|
||||||
|
if (settings == null) return;
|
||||||
|
|
||||||
|
GameData.screenMode = settings.ScreenMode;
|
||||||
|
GameData.soundVolume = settings.SoundVolume;
|
||||||
|
GameData.lightColor = new Color(
|
||||||
|
settings.LightColorR,
|
||||||
|
settings.LightColorG,
|
||||||
|
settings.LightColorB,
|
||||||
|
settings.LightColorA
|
||||||
|
);
|
||||||
|
|
||||||
|
ApplyScreenMode(settings.ScreenMode);
|
||||||
|
SoundManager.SetMasterVolume(settings.SoundVolume);
|
||||||
|
LightHandler.RedrawLights(GameData.lightColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void ApplyScreenMode(int screenMode)
|
||||||
|
{
|
||||||
|
switch (screenMode)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
|
||||||
|
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, false);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
|
||||||
|
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, false);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
|
||||||
|
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static void ApplyInventoryData(List<ItemSaveData> savedItems)
|
private static void ApplyInventoryData(List<ItemSaveData> savedItems)
|
||||||
{
|
{
|
||||||
GameData.inventory = new Inventory();
|
GameData.inventory = new Inventory();
|
||||||
@@ -353,7 +406,7 @@ public static class SaveGameManager
|
|||||||
tile.containsResource = savedTile.ContainsResource;
|
tile.containsResource = savedTile.ContainsResource;
|
||||||
tile.wasVisited = savedTile.WasVisited;
|
tile.wasVisited = savedTile.WasVisited;
|
||||||
tile.resource = savedTile.Resource == null ? null : GameResource.FromSaveData(savedTile.Resource);
|
tile.resource = savedTile.Resource == null ? null : GameResource.FromSaveData(savedTile.Resource);
|
||||||
tile.ContentNode.Visible = savedTile.WasVisited || tile.collapsedMesh == "gate";
|
tile.ContentNode.Visible = savedTile.WasVisited || (tile.collapsedMesh == "gate" && !layer.isGateOpen);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,44 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public partial class SoundManager : Node
|
||||||
|
{
|
||||||
|
private static SoundManager instance;
|
||||||
|
|
||||||
|
[Export] private AudioStreamPlayer buttonSound;
|
||||||
|
[Export] private AudioStreamPlayer miningSound;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void _ExitTree()
|
||||||
|
{
|
||||||
|
if (instance == this)
|
||||||
|
{
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PlayButton()
|
||||||
|
{
|
||||||
|
if (instance == null || instance.buttonSound == null) return;
|
||||||
|
|
||||||
|
instance.buttonSound.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void PlayMining()
|
||||||
|
{
|
||||||
|
if (instance == null || instance.miningSound == null) return;
|
||||||
|
|
||||||
|
instance.miningSound.Play();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void SetMasterVolume(float percent)
|
||||||
|
{
|
||||||
|
percent = Mathf.Clamp(percent, 0f, 1f);
|
||||||
|
int busIndex = AudioServer.GetBusIndex("Master");
|
||||||
|
AudioServer.SetBusVolumeDb(busIndex, Mathf.LinearToDb(percent));
|
||||||
|
AudioServer.SetBusMute(busIndex, percent <= 0f);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://gvy12mefkwax
|
||||||
@@ -25,6 +25,7 @@ public class HarvestNode : ProgramNode
|
|||||||
|
|
||||||
if (tile.resource.Extract(delta))
|
if (tile.resource.Extract(delta))
|
||||||
{
|
{
|
||||||
|
SoundManager.PlayMining();
|
||||||
if (!GameData.inventory.AddItem(new Item {data = tile.resource.item}, 1))
|
if (!GameData.inventory.AddItem(new Item {data = tile.resource.item}, 1))
|
||||||
{
|
{
|
||||||
lastExecutionMessage = "Not enough space";
|
lastExecutionMessage = "Not enough space";
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public class MaintainNode : ProgramNode
|
||||||
|
{
|
||||||
|
private const float MaintenancePerGear = 10f;
|
||||||
|
|
||||||
|
public MaintainNode()
|
||||||
|
{
|
||||||
|
DisplayText = "Maintain";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override NodeResult Execute(Robot robot, double delta)
|
||||||
|
{
|
||||||
|
string gearId = GetGearId(robot);
|
||||||
|
|
||||||
|
if (!GameData.inventory.TryRemoveItem(gearId, 1))
|
||||||
|
{
|
||||||
|
lastExecutionMessage = $"Missing {ItemData.GetReadableName(gearId)}";
|
||||||
|
return NodeResult.FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
robot.Maintain(MaintenancePerGear);
|
||||||
|
lastExecutionMessage = "";
|
||||||
|
return NodeResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReadParameters(NodeDisplay display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ProgramNode Duplicate()
|
||||||
|
{
|
||||||
|
MaintainNode duplicate = new MaintainNode();
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(NodeDisplay display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Save()
|
||||||
|
{
|
||||||
|
return $"Name: {DisplayText}";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string GetGearId(Robot robot)
|
||||||
|
{
|
||||||
|
string robotType = robot == null ? "stone_robot" : robot.robotType;
|
||||||
|
return robotType.Replace("_robot", "_gear");
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://bmibtsh1iq2x
|
||||||
@@ -0,0 +1,52 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public class SacrificeNode : ProgramNode
|
||||||
|
{
|
||||||
|
public SacrificeNode()
|
||||||
|
{
|
||||||
|
DisplayText = "Sacrifice";
|
||||||
|
}
|
||||||
|
|
||||||
|
public override NodeResult Execute(Robot robot, double delta)
|
||||||
|
{
|
||||||
|
Vector3I mapIndex = Pathfinding.GetClosestStartPoint(robot.Position);
|
||||||
|
Tile tile = GameData.map[mapIndex.Y].tiles[mapIndex.X, mapIndex.Z];
|
||||||
|
|
||||||
|
if (!tile.containsResource || tile.resource == null)
|
||||||
|
{
|
||||||
|
lastExecutionMessage = "No resource on this tile";
|
||||||
|
return NodeResult.FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tile.resource.IsEndless())
|
||||||
|
{
|
||||||
|
lastExecutionMessage = "Resource is already endless";
|
||||||
|
return NodeResult.FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
|
tile.resource.MakeEndless();
|
||||||
|
GameData.robots.Remove(robot);
|
||||||
|
robot.QueueFree();
|
||||||
|
lastExecutionMessage = "";
|
||||||
|
return NodeResult.SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ReadParameters(NodeDisplay display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override ProgramNode Duplicate()
|
||||||
|
{
|
||||||
|
SacrificeNode duplicate = new SacrificeNode();
|
||||||
|
return duplicate;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Setup(NodeDisplay display)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Save()
|
||||||
|
{
|
||||||
|
return $"Name: {DisplayText}";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://dq8e7txyldpew
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
public class GameResource
|
public class GameResource
|
||||||
{
|
{
|
||||||
|
private const float NormalExtractionSpeed = 1f;
|
||||||
|
private const float EndlessExtractionSpeed = 4f;
|
||||||
|
|
||||||
public string name;
|
public string name;
|
||||||
public ItemData item;
|
public ItemData item;
|
||||||
|
|
||||||
@@ -15,17 +18,23 @@ public class GameResource
|
|||||||
maxAmount = GameData.rand.Next(1000, 10000);
|
maxAmount = GameData.rand.Next(1000, 10000);
|
||||||
currentAmount = maxAmount;
|
currentAmount = maxAmount;
|
||||||
isEndless = false;
|
isEndless = false;
|
||||||
extractionSpeed = 1f;
|
extractionSpeed = NormalExtractionSpeed;
|
||||||
item = GameData.availableItems[name];
|
item = GameData.availableItems[name];
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GameResource FromSaveData(ResourceSaveData saveData)
|
public static GameResource FromSaveData(ResourceSaveData saveData)
|
||||||
{
|
{
|
||||||
GameResource resource = new GameResource(saveData.Name);
|
GameResource resource = new GameResource(saveData.Name)
|
||||||
resource.currentAmount = saveData.CurrentAmount;
|
{
|
||||||
resource.maxAmount = saveData.MaxAmount;
|
currentAmount = saveData.CurrentAmount,
|
||||||
resource.isEndless = saveData.IsEndless;
|
maxAmount = saveData.MaxAmount,
|
||||||
resource.extractionSpeed = saveData.ExtractionSpeed;
|
isEndless = saveData.IsEndless,
|
||||||
|
extractionSpeed = saveData.ExtractionSpeed
|
||||||
|
};
|
||||||
|
if (resource.isEndless && resource.extractionSpeed <= NormalExtractionSpeed)
|
||||||
|
{
|
||||||
|
resource.extractionSpeed = EndlessExtractionSpeed;
|
||||||
|
}
|
||||||
resource.timeSinceLastExtraction = saveData.TimeSinceLastExtraction;
|
resource.timeSinceLastExtraction = saveData.TimeSinceLastExtraction;
|
||||||
return resource;
|
return resource;
|
||||||
}
|
}
|
||||||
@@ -64,4 +73,20 @@ public class GameResource
|
|||||||
{
|
{
|
||||||
return (isEndless || currentAmount > 0) && GameData.availableResearch[item.Research].state == ResearchState.RESEARCHED;
|
return (isEndless || currentAmount > 0) && GameData.availableResearch[item.Research].state == ResearchState.RESEARCHED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void MakeEndless()
|
||||||
|
{
|
||||||
|
isEndless = true;
|
||||||
|
extractionSpeed = EndlessExtractionSpeed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsEndless()
|
||||||
|
{
|
||||||
|
return isEndless;
|
||||||
|
}
|
||||||
|
|
||||||
|
public float GetExtractionSpeed()
|
||||||
|
{
|
||||||
|
return extractionSpeed;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ public partial class Robot : Node3D
|
|||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
if (GameData.isPaused) return;
|
||||||
|
|
||||||
if (isExecuting)
|
if (isExecuting)
|
||||||
{
|
{
|
||||||
if (CanExecute(delta))
|
if (CanExecute(delta))
|
||||||
@@ -155,6 +157,16 @@ public partial class Robot : Node3D
|
|||||||
currentMessage = "";
|
currentMessage = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void Maintain(float amount)
|
||||||
|
{
|
||||||
|
maintenance = Math.Clamp(maintenance + amount, 0f, 100f);
|
||||||
|
if (maintenance > 0f)
|
||||||
|
{
|
||||||
|
isBroken = false;
|
||||||
|
}
|
||||||
|
currentMessage = "";
|
||||||
|
}
|
||||||
|
|
||||||
public RobotSaveData CreateSaveData()
|
public RobotSaveData CreateSaveData()
|
||||||
{
|
{
|
||||||
return new RobotSaveData
|
return new RobotSaveData
|
||||||
|
|||||||
@@ -19,8 +19,15 @@ public partial class TestRunner : Node
|
|||||||
Run("Research execution pays resources and finishes", TestResearchExecutionPaysResourcesAndFinishes);
|
Run("Research execution pays resources and finishes", TestResearchExecutionPaysResourcesAndFinishes);
|
||||||
Run("Research cannot start without resources", TestResearchCannotStartWithoutResources);
|
Run("Research cannot start without resources", TestResearchCannotStartWithoutResources);
|
||||||
Run("Inventory add failure keeps inventory unchanged", TestInventoryAddFailureKeepsInventoryUnchanged);
|
Run("Inventory add failure keeps inventory unchanged", TestInventoryAddFailureKeepsInventoryUnchanged);
|
||||||
|
Run("Saved scripts can be deleted", TestSavedScriptsCanBeDeleted);
|
||||||
Run("Resource extraction and save data roundtrip", TestResourceSaveRoundtrip);
|
Run("Resource extraction and save data roundtrip", TestResourceSaveRoundtrip);
|
||||||
|
Run("Endless resources extract slower", TestEndlessResourcesExtractSlower);
|
||||||
Run("Robot save data roundtrip keeps robot state", TestRobotSaveRoundtrip);
|
Run("Robot save data roundtrip keeps robot state", TestRobotSaveRoundtrip);
|
||||||
|
Run("Maintain node consumes matching gear", TestMaintainNodeConsumesMatchingGear);
|
||||||
|
Run("Sacrifice node makes resource endless", TestSacrificeNodeMakesResourceEndless);
|
||||||
|
Run("No robot recovery detects loss", TestNoRobotRecoveryDetectsLoss);
|
||||||
|
Run("Robot item prevents no robot loss", TestRobotItemPreventsNoRobotLoss);
|
||||||
|
Run("Save data captures and restores options", TestSaveDataRestoresOptions);
|
||||||
Run("Save data captures and restores global state", TestSaveDataRestoresGlobalState);
|
Run("Save data captures and restores global state", TestSaveDataRestoresGlobalState);
|
||||||
Run("Save data restores survival timer", TestSaveDataRestoresSurvivalTimer);
|
Run("Save data restores survival timer", TestSaveDataRestoresSurvivalTimer);
|
||||||
Run("Split save files store and load data", TestSplitSaveFilesRoundtrip);
|
Run("Split save files store and load data", TestSplitSaveFilesRoundtrip);
|
||||||
@@ -28,6 +35,8 @@ public partial class TestRunner : Node
|
|||||||
Run("If node evaluates inventory comparisons", TestIfNodeEvaluatesInventoryComparisons);
|
Run("If node evaluates inventory comparisons", TestIfNodeEvaluatesInventoryComparisons);
|
||||||
Run("While node reports false conditions", TestWhileNodeReportsFalseConditions);
|
Run("While node reports false conditions", TestWhileNodeReportsFalseConditions);
|
||||||
Run("For node stops after configured amount", TestForNodeStopsAfterConfiguredAmount);
|
Run("For node stops after configured amount", TestForNodeStopsAfterConfiguredAmount);
|
||||||
|
Run("Paused world does not drain survival", TestPausedWorldDoesNotDrainSurvival);
|
||||||
|
Run("Open gate hides gate content", TestOpenGateHidesGateContent);
|
||||||
Run("Item data readable names are stable", TestItemDataReadableNames);
|
Run("Item data readable names are stable", TestItemDataReadableNames);
|
||||||
Run("Resource files load core game data", TestResourceFilesLoadCoreData);
|
Run("Resource files load core game data", TestResourceFilesLoadCoreData);
|
||||||
|
|
||||||
@@ -173,6 +182,20 @@ public partial class TestRunner : Node
|
|||||||
AssertEqual(saveData.CurrentAmount, loadedResource.CreateSaveData().CurrentAmount, "resource amount");
|
AssertEqual(saveData.CurrentAmount, loadedResource.CreateSaveData().CurrentAmount, "resource amount");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestEndlessResourcesExtractSlower()
|
||||||
|
{
|
||||||
|
GameResource resource = new GameResource("stone");
|
||||||
|
|
||||||
|
AssertTrue(resource.Extract(1.0), "normal resource should extract after one second");
|
||||||
|
|
||||||
|
resource.MakeEndless();
|
||||||
|
|
||||||
|
AssertFalse(resource.Extract(1.0), "endless resource should not extract after one second");
|
||||||
|
AssertTrue(resource.Extract(3.0), "endless resource should extract after four total seconds");
|
||||||
|
AssertTrue(resource.IsEndless(), "resource should be endless");
|
||||||
|
AssertTrue(resource.GetExtractionSpeed() > 1f, "endless extraction speed should be slower");
|
||||||
|
}
|
||||||
|
|
||||||
private void TestRobotSaveRoundtrip()
|
private void TestRobotSaveRoundtrip()
|
||||||
{
|
{
|
||||||
Robot robot = new Robot
|
Robot robot = new Robot
|
||||||
@@ -201,6 +224,59 @@ public partial class TestRunner : Node
|
|||||||
AssertTrue(loadedRobot.isCoolingDown, "robot cooling state");
|
AssertTrue(loadedRobot.isCoolingDown, "robot cooling state");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestMaintainNodeConsumesMatchingGear()
|
||||||
|
{
|
||||||
|
Robot robot = new Robot
|
||||||
|
{
|
||||||
|
robotType = "copper_robot",
|
||||||
|
maintenance = 50f,
|
||||||
|
isBroken = true
|
||||||
|
};
|
||||||
|
|
||||||
|
GameData.inventory.AddItem(new Item { data = GameData.availableItems["copper_gear"] }, 1);
|
||||||
|
MaintainNode node = new MaintainNode();
|
||||||
|
|
||||||
|
AssertEqual(NodeResult.SUCCESS, node.Execute(robot, 0), "maintain should succeed");
|
||||||
|
AssertClose(60f, robot.maintenance, 0.001f, "maintenance repaired by 10");
|
||||||
|
AssertFalse(robot.isBroken, "robot should be usable again");
|
||||||
|
AssertEqual(0, GameData.inventory.GetItemAmount("copper_gear"), "gear should be consumed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestSacrificeNodeMakesResourceEndless()
|
||||||
|
{
|
||||||
|
GameData.ruinSize = 1;
|
||||||
|
GameData.layerSize = 1;
|
||||||
|
GameData.map = new Layer[1];
|
||||||
|
GameData.map[0] = CreateTestLayer(0, "spawn");
|
||||||
|
GameData.map[0].tiles[0, 0].resource = new GameResource("stone");
|
||||||
|
GameData.map[0].tiles[0, 0].containsResource = true;
|
||||||
|
Pathfinding.BuildAStarGraph();
|
||||||
|
|
||||||
|
Robot robot = new Robot
|
||||||
|
{
|
||||||
|
Position = Vector3.Zero
|
||||||
|
};
|
||||||
|
GameData.robots.Add(robot);
|
||||||
|
|
||||||
|
SacrificeNode node = new SacrificeNode();
|
||||||
|
|
||||||
|
AssertEqual(NodeResult.SUCCESS, node.Execute(robot, 0), "sacrifice should succeed");
|
||||||
|
AssertTrue(GameData.map[0].tiles[0, 0].resource.IsEndless(), "resource should become endless");
|
||||||
|
AssertEqual(0, GameData.robots.Count, "robot should be removed");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestNoRobotRecoveryDetectsLoss()
|
||||||
|
{
|
||||||
|
AssertTrue(GameData.HasNoRobotRecovery(), "no robots and no robot items should be a loss");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestRobotItemPreventsNoRobotLoss()
|
||||||
|
{
|
||||||
|
GameData.inventory.AddItem(new Item { data = GameData.availableItems["stone_robot"] }, 1);
|
||||||
|
|
||||||
|
AssertFalse(GameData.HasNoRobotRecovery(), "robot item should prevent loss");
|
||||||
|
}
|
||||||
|
|
||||||
private void TestSaveDataRestoresGlobalState()
|
private void TestSaveDataRestoresGlobalState()
|
||||||
{
|
{
|
||||||
GameData.inventory.AddItem(new Item { data = GameData.availableItems["stone"] }, 12);
|
GameData.inventory.AddItem(new Item { data = GameData.availableItems["stone"] }, 12);
|
||||||
@@ -221,6 +297,27 @@ public partial class TestRunner : Node
|
|||||||
AssertEqual(ResearchState.RESEARCHED, GameData.availableResearch["stoneage"].state, "saved research");
|
AssertEqual(ResearchState.RESEARCHED, GameData.availableResearch["stoneage"].state, "saved research");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestSaveDataRestoresOptions()
|
||||||
|
{
|
||||||
|
GameData.screenMode = 1;
|
||||||
|
GameData.soundVolume = 0.35f;
|
||||||
|
GameData.lightColor = new Color(0.2f, 0.4f, 0.6f, 1f);
|
||||||
|
|
||||||
|
SaveGameData saveData = SaveGameManager.CreateSaveData();
|
||||||
|
|
||||||
|
GameData.screenMode = 2;
|
||||||
|
GameData.soundVolume = 0.8f;
|
||||||
|
GameData.lightColor = Colors.White;
|
||||||
|
|
||||||
|
SaveGameManager.ApplyWorldData(saveData);
|
||||||
|
|
||||||
|
AssertEqual(1, GameData.screenMode, "saved screen mode");
|
||||||
|
AssertClose(0.35f, GameData.soundVolume, 0.001f, "saved sound volume");
|
||||||
|
AssertClose(0.2f, GameData.lightColor.R, 0.001f, "saved light red");
|
||||||
|
AssertClose(0.4f, GameData.lightColor.G, 0.001f, "saved light green");
|
||||||
|
AssertClose(0.6f, GameData.lightColor.B, 0.001f, "saved light blue");
|
||||||
|
}
|
||||||
|
|
||||||
private void TestSaveDataRestoresSurvivalTimer()
|
private void TestSaveDataRestoresSurvivalTimer()
|
||||||
{
|
{
|
||||||
GameData.survival.elapsedSeconds = 321.5;
|
GameData.survival.elapsedSeconds = 321.5;
|
||||||
@@ -270,6 +367,17 @@ public partial class TestRunner : Node
|
|||||||
AssertEqual(0, GameData.inventory.items.Count, "failed add should not create stacks");
|
AssertEqual(0, GameData.inventory.items.Count, "failed add should not create stacks");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestSavedScriptsCanBeDeleted()
|
||||||
|
{
|
||||||
|
string scriptName = "delete_test_script";
|
||||||
|
FileHandler.SaveProgram(scriptName, "Name: Explore;");
|
||||||
|
|
||||||
|
AssertTrue(FileHandler.LoadProgramNames().Contains(scriptName), "script should be listed");
|
||||||
|
AssertTrue(FileHandler.DeleteProgram(scriptName), "delete should succeed");
|
||||||
|
AssertEqual("", FileHandler.LoadProgram(scriptName), "deleted script should be empty");
|
||||||
|
AssertFalse(FileHandler.DeleteProgram(scriptName), "second delete should fail");
|
||||||
|
}
|
||||||
|
|
||||||
private void TestResearchCannotStartWithoutResources()
|
private void TestResearchCannotStartWithoutResources()
|
||||||
{
|
{
|
||||||
ResearchData researchData = new ResearchData
|
ResearchData researchData = new ResearchData
|
||||||
@@ -367,6 +475,33 @@ public partial class TestRunner : Node
|
|||||||
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "loop finished");
|
AssertEqual(NodeResult.CONDITIONFALSE, node.Execute(null, 0), "loop finished");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void TestPausedWorldDoesNotDrainSurvival()
|
||||||
|
{
|
||||||
|
GameData.isPaused = true;
|
||||||
|
GameData.canMove = false;
|
||||||
|
GameData.survival.energy = 100f;
|
||||||
|
|
||||||
|
World world = new World();
|
||||||
|
world.UpdateGameLoop(100.0);
|
||||||
|
|
||||||
|
AssertClose(100f, GameData.survival.energy, 0.001f, "energy should not drain while paused");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void TestOpenGateHidesGateContent()
|
||||||
|
{
|
||||||
|
Layer layer = CreateTestLayer(0, "gate");
|
||||||
|
layer.gateCoordinate = new Vector2I(0, 0);
|
||||||
|
layer.tiles[0, 0].ContentNode = new Node3D
|
||||||
|
{
|
||||||
|
Visible = true
|
||||||
|
};
|
||||||
|
|
||||||
|
layer.OpenGate();
|
||||||
|
|
||||||
|
AssertTrue(layer.isGateOpen, "gate should be open");
|
||||||
|
AssertFalse(layer.tiles[0, 0].ContentNode.Visible, "gate content should be hidden");
|
||||||
|
}
|
||||||
|
|
||||||
private void TestItemDataReadableNames()
|
private void TestItemDataReadableNames()
|
||||||
{
|
{
|
||||||
AssertEqual("Iron gear", ItemData.GetReadableName("iron_gear"), "readable name");
|
AssertEqual("Iron gear", ItemData.GetReadableName("iron_gear"), "readable name");
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public partial class UIHandler : Control
|
|||||||
public void HandleMenuButton()
|
public void HandleMenuButton()
|
||||||
{
|
{
|
||||||
OpenUIElement(menu);
|
OpenUIElement(menu);
|
||||||
|
GameData.isPaused = menu.Visible || options.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleMenu()
|
public void HandleMenu()
|
||||||
@@ -67,7 +68,9 @@ public partial class UIHandler : Control
|
|||||||
|
|
||||||
public void ShowOptions()
|
public void ShowOptions()
|
||||||
{
|
{
|
||||||
|
menu.Hide();
|
||||||
OpenUIElement(options);
|
OpenUIElement(options);
|
||||||
|
GameData.isPaused = options.Visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleMapButton()
|
public void HandleMapButton()
|
||||||
@@ -101,6 +104,7 @@ public partial class UIHandler : Control
|
|||||||
RAM.Text = memoryDisplay;
|
RAM.Text = memoryDisplay;
|
||||||
DisplaySurvivalStats();
|
DisplaySurvivalStats();
|
||||||
DisplayWorldStats();
|
DisplayWorldStats();
|
||||||
|
DisplayLoseCondition();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ExitGame()
|
public void ExitGame()
|
||||||
@@ -123,6 +127,7 @@ public partial class UIHandler : Control
|
|||||||
|
|
||||||
public void OpenUIElement(Control element)
|
public void OpenUIElement(Control element)
|
||||||
{
|
{
|
||||||
|
SoundManager.PlayButton();
|
||||||
if (element.Visible)
|
if (element.Visible)
|
||||||
{
|
{
|
||||||
element.Hide();
|
element.Hide();
|
||||||
@@ -141,6 +146,11 @@ public partial class UIHandler : Control
|
|||||||
if (child == element) continue;
|
if (child == element) continue;
|
||||||
child.Visible = false;
|
child.Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (element != menu && element != options)
|
||||||
|
{
|
||||||
|
GameData.isPaused = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisplayRobotAlarm()
|
private void DisplayRobotAlarm()
|
||||||
@@ -201,15 +211,28 @@ public partial class UIHandler : Control
|
|||||||
unlockLayer.Disabled = !GameData.inventory.CanCraft(GameData.map[GameData.lowestLayer].gateIngredients, 1);
|
unlockLayer.Disabled = !GameData.inventory.CanCraft(GameData.map[GameData.lowestLayer].gateIngredients, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DisplayLoseCondition()
|
||||||
|
{
|
||||||
|
if (!GameData.HasNoRobotRecovery()) return;
|
||||||
|
|
||||||
|
ShowGameOver("No robots remain and no robot can be spawned from inventory.");
|
||||||
|
}
|
||||||
|
|
||||||
public void UnlockLayer()
|
public void UnlockLayer()
|
||||||
{
|
{
|
||||||
if (GameData.inventory.CanCraft(GameData.map[GameData.lowestLayer].gateIngredients, 1))
|
if (GameData.inventory.CanCraft(GameData.map[GameData.lowestLayer].gateIngredients, 1))
|
||||||
{
|
{
|
||||||
|
int openedLayer = GameData.lowestLayer;
|
||||||
foreach (Ingredient ingredient in GameData.map[GameData.lowestLayer].gateIngredients)
|
foreach (Ingredient ingredient in GameData.map[GameData.lowestLayer].gateIngredients)
|
||||||
{
|
{
|
||||||
GameData.inventory.RemoveItem(ingredient.Item, ingredient.Amount);
|
GameData.inventory.RemoveItem(ingredient.Item, ingredient.Amount);
|
||||||
}
|
}
|
||||||
GameData.lowestLayer++;
|
GameData.lowestLayer++;
|
||||||
|
World world = GetNodeOrNull<World>("/root/Main/World");
|
||||||
|
if (world != null)
|
||||||
|
{
|
||||||
|
world.OpenGate(openedLayer);
|
||||||
|
}
|
||||||
if (GameData.lowestLayer == GameData.ruinSize)
|
if (GameData.lowestLayer == GameData.ruinSize)
|
||||||
{
|
{
|
||||||
gameOver.Show();
|
gameOver.Show();
|
||||||
@@ -218,9 +241,14 @@ public partial class UIHandler : Control
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void ShowGameOver()
|
public void ShowGameOver()
|
||||||
|
{
|
||||||
|
ShowGameOver($"You died!\rReason: {GameData.survival.deathReason}\rBetter luck next time.");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ShowGameOver(string message)
|
||||||
{
|
{
|
||||||
if (gameOver.Visible) return;
|
if (gameOver.Visible) return;
|
||||||
gameOver.GetNode<RichTextLabel>("./VBoxContainer/Content").Text = $"[font_size=32]You died!\rReason: {GameData.survival.deathReason}\rBetter luck next time.\r";
|
gameOver.GetNode<RichTextLabel>("./VBoxContainer/Content").Text = $"[font_size=32]{message}\r";
|
||||||
gameOver.Show();
|
gameOver.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ public partial class CodingWindow : PanelContainer
|
|||||||
|
|
||||||
public void LoadProgram(int index)
|
public void LoadProgram(int index)
|
||||||
{
|
{
|
||||||
|
if (index <= 0) return;
|
||||||
|
|
||||||
ClearWindow();
|
ClearWindow();
|
||||||
string scriptContent = FileHandler.LoadProgram(availableScripts.GetItemText(index));
|
string scriptContent = FileHandler.LoadProgram(availableScripts.GetItemText(index));
|
||||||
string[] nodes = scriptContent.Split(";");
|
string[] nodes = scriptContent.Split(";");
|
||||||
@@ -151,6 +153,22 @@ public partial class CodingWindow : PanelContainer
|
|||||||
availableScripts.Select(0);
|
availableScripts.Select(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void DeleteProgram()
|
||||||
|
{
|
||||||
|
string filename = scriptName.Text;
|
||||||
|
int selectedIndex = availableScripts.GetSelectedId();
|
||||||
|
if (selectedIndex > 0)
|
||||||
|
{
|
||||||
|
filename = availableScripts.GetItemText(selectedIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filename.Length <= 0) return;
|
||||||
|
if (!FileHandler.DeleteProgram(filename)) return;
|
||||||
|
|
||||||
|
ClearWindow();
|
||||||
|
SetupScriptOptions();
|
||||||
|
}
|
||||||
|
|
||||||
public void SaveProgram()
|
public void SaveProgram()
|
||||||
{
|
{
|
||||||
string result = "";
|
string result = "";
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ public partial class NodeDisplay : PanelContainer
|
|||||||
result.node = new ElseNode();
|
result.node = new ElseNode();
|
||||||
result.LoadElse(nodeSanitized);
|
result.LoadElse(nodeSanitized);
|
||||||
break;
|
break;
|
||||||
|
case "maintain":
|
||||||
|
result.node = new MaintainNode();
|
||||||
|
result.LoadMaintain(nodeSanitized);
|
||||||
|
break;
|
||||||
|
case "sacrifice":
|
||||||
|
result.node = new SacrificeNode();
|
||||||
|
result.LoadSacrifice(nodeSanitized);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
result.QueueFree();
|
result.QueueFree();
|
||||||
return null;
|
return null;
|
||||||
@@ -99,6 +107,10 @@ public partial class NodeDisplay : PanelContainer
|
|||||||
|
|
||||||
private void LoadElse(string content) { }
|
private void LoadElse(string content) { }
|
||||||
|
|
||||||
|
private void LoadMaintain(string content) { }
|
||||||
|
|
||||||
|
private void LoadSacrifice(string content) { }
|
||||||
|
|
||||||
private void LoadIf(string content)
|
private void LoadIf(string content)
|
||||||
{
|
{
|
||||||
HBoxContainer valueContainer = GetNode<HBoxContainer>("./EditorDisplay/VBoxContainer/Values");
|
HBoxContainer valueContainer = GetNode<HBoxContainer>("./EditorDisplay/VBoxContainer/Values");
|
||||||
|
|||||||
@@ -2,6 +2,8 @@ using Godot;
|
|||||||
|
|
||||||
public partial class MainMenu : Control
|
public partial class MainMenu : Control
|
||||||
{
|
{
|
||||||
|
[Export] private PanelContainer options;
|
||||||
|
|
||||||
public override void _Ready()
|
public override void _Ready()
|
||||||
{
|
{
|
||||||
UIStyle.Apply(this);
|
UIStyle.Apply(this);
|
||||||
@@ -26,4 +28,11 @@ public partial class MainMenu : Control
|
|||||||
{
|
{
|
||||||
GetTree().Quit();
|
GetTree().Quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OnOptionsPressed()
|
||||||
|
{
|
||||||
|
if (options == null) return;
|
||||||
|
|
||||||
|
options.Show();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using Godot;
|
||||||
|
|
||||||
|
public partial class OptionsMenu : PanelContainer
|
||||||
|
{
|
||||||
|
private readonly Vector2 panelSize = new Vector2(420, 260);
|
||||||
|
|
||||||
|
[Export] private OptionButton screenMode;
|
||||||
|
[Export] private HSlider soundVolume;
|
||||||
|
[Export] private ColorPickerButton lightColor;
|
||||||
|
|
||||||
|
public override void _Ready()
|
||||||
|
{
|
||||||
|
CenterPanel();
|
||||||
|
SetupScreenModes();
|
||||||
|
screenMode.Select(GameData.screenMode);
|
||||||
|
soundVolume.Value = GameData.soundVolume * 100f;
|
||||||
|
lightColor.Color = GameData.lightColor;
|
||||||
|
ApplyScreenMode(GameData.screenMode);
|
||||||
|
SoundManager.SetMasterVolume(GameData.soundVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupScreenModes()
|
||||||
|
{
|
||||||
|
screenMode.Clear();
|
||||||
|
screenMode.AddItem("Fullscreen");
|
||||||
|
screenMode.AddItem("Windowed");
|
||||||
|
screenMode.AddItem("Windowed Fullscreen");
|
||||||
|
screenMode.Select(2);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnScreenModeSelected(int index)
|
||||||
|
{
|
||||||
|
GameData.screenMode = index;
|
||||||
|
ApplyScreenMode(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ApplyScreenMode(int index)
|
||||||
|
{
|
||||||
|
switch (index)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
|
||||||
|
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, false);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Windowed);
|
||||||
|
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, false);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
DisplayServer.WindowSetMode(DisplayServer.WindowMode.Fullscreen);
|
||||||
|
DisplayServer.WindowSetFlag(DisplayServer.WindowFlags.Borderless, true);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnSoundVolumeChanged(double value)
|
||||||
|
{
|
||||||
|
GameData.soundVolume = (float)value / 100f;
|
||||||
|
SoundManager.SetMasterVolume(GameData.soundVolume);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnLightColorChanged(Color color)
|
||||||
|
{
|
||||||
|
GameData.lightColor = color;
|
||||||
|
LightHandler.RedrawLights(color);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void CloseOptions()
|
||||||
|
{
|
||||||
|
Hide();
|
||||||
|
GameData.isPaused = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CenterPanel()
|
||||||
|
{
|
||||||
|
CustomMinimumSize = panelSize;
|
||||||
|
SetAnchorsPreset(LayoutPreset.Center);
|
||||||
|
OffsetLeft = -panelSize.X / 2f;
|
||||||
|
OffsetTop = -panelSize.Y / 2f;
|
||||||
|
OffsetRight = panelSize.X / 2f;
|
||||||
|
OffsetBottom = panelSize.Y / 2f;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
uid://ca1rfge0y3y4i
|
||||||
@@ -39,6 +39,16 @@ public partial class Layer : Node3D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void OpenGate()
|
||||||
|
{
|
||||||
|
isGateOpen = true;
|
||||||
|
Tile gateTile = tiles[gateCoordinate.X, gateCoordinate.Y];
|
||||||
|
if (gateTile.ContentNode != null)
|
||||||
|
{
|
||||||
|
gateTile.ContentNode.Visible = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void SetupLayer(int layerSize, int level, Dictionary<string, MeshInstance3D> tileMeshes, Vector2I collapseOrigin)
|
public void SetupLayer(int layerSize, int level, Dictionary<string, MeshInstance3D> tileMeshes, Vector2I collapseOrigin)
|
||||||
{
|
{
|
||||||
this.layerSize = layerSize;
|
this.layerSize = layerSize;
|
||||||
|
|||||||
@@ -98,6 +98,13 @@ public partial class World : Node3D
|
|||||||
|
|
||||||
public override void _Process(double delta)
|
public override void _Process(double delta)
|
||||||
{
|
{
|
||||||
|
UpdateGameLoop(delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateGameLoop(double delta)
|
||||||
|
{
|
||||||
|
if (isPaused) return;
|
||||||
|
|
||||||
survival.Update(delta);
|
survival.Update(delta);
|
||||||
if (!canMove) return;
|
if (!canMove) return;
|
||||||
|
|
||||||
@@ -110,6 +117,25 @@ public partial class World : Node3D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void RefreshVisibleLayer()
|
||||||
|
{
|
||||||
|
ShowLayer(visibleLayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OpenGate(int layerIndex)
|
||||||
|
{
|
||||||
|
if (layerIndex < 0 || layerIndex >= map.Length) return;
|
||||||
|
|
||||||
|
Layer layer = map[layerIndex];
|
||||||
|
layer.OpenGate();
|
||||||
|
Pathfinding.UpdateGatePoint(layerIndex, true);
|
||||||
|
|
||||||
|
if (layerIndex == visibleLayer)
|
||||||
|
{
|
||||||
|
RefreshVisibleLayer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void SpawnDefaultRobot()
|
private void SpawnDefaultRobot()
|
||||||
{
|
{
|
||||||
Robot robot = ResourceLoader.LoadRobotPrefab().Instantiate<Robot>();
|
Robot robot = ResourceLoader.LoadRobotPrefab().Instantiate<Robot>();
|
||||||
@@ -184,6 +210,10 @@ public partial class World : Node3D
|
|||||||
for (int y = 0; y < layerSize; y++)
|
for (int y = 0; y < layerSize; y++)
|
||||||
{
|
{
|
||||||
Tile tile = layer.tiles[x, y];
|
Tile tile = layer.tiles[x, y];
|
||||||
|
if (layer.isGateOpen && tile.collapsedMesh == "gate")
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
result.Add(new TileRenderData
|
result.Add(new TileRenderData
|
||||||
{
|
{
|
||||||
Tile = tile,
|
Tile = tile,
|
||||||
|
|||||||
Reference in New Issue
Block a user