diff --git a/addons/gdLinter/Settings/ignore.gd b/addons/gdLinter/Settings/ignore.gd new file mode 100644 index 0000000..6c763c3 --- /dev/null +++ b/addons/gdLinter/Settings/ignore.gd @@ -0,0 +1,44 @@ +class_name GDLinterIgnore +extends Resource + +@export_group("Name Checks") +@export var _function_name: bool = false +@export var _class_name: bool = false +@export var _sub_class_name: bool = false +@export var _signal_name: bool = false +@export var _class_variable_name: bool = false +@export var _class_load_variable_name: bool = false +@export var _function_variable_name: bool = false +@export var _function_preload_variable_name: bool = false +@export var _function_argument_name: bool = false +@export var _loop_variable_name: bool = false +@export var _enum_name: bool = false +@export var _enum_element_name: bool = false +@export var _constant_name: bool = false +@export var _load_constant_name: bool = false + +@export_group("Basic Checks") +@export var _duplicated_load: bool = false +@export var _expression_not_assigned: bool = false +@export var _unnecessary_pass: bool = false +@export var _unused_argument: bool = false +@export var _comparison_with_itself: bool = false + +@export_group("Class Checks") +@export var _private_method_call: bool = false +@export var _class_definitions_order: bool = false + +@export_group("Design Checks") +@export var _max_public_methods: bool = false +@export var _function_arguments_number: bool = false + +@export_group("Format Checks") +@export var _max_file_lines: bool = false +@export var _trailing_whitespace: bool = false +@export var _max_line_length: bool = false +@export var _mixed_tabs_and_spaces: bool = false + +@export_group("Misc Checks") +@export var _no_elif_return: bool = false +@export var _no_else_return: bool = false + diff --git a/addons/gdLinter/Settings/ignore.tres b/addons/gdLinter/Settings/ignore.tres new file mode 100644 index 0000000..ec32cbf --- /dev/null +++ b/addons/gdLinter/Settings/ignore.tres @@ -0,0 +1,35 @@ +[gd_resource type="Resource" script_class="GDLinterIgnore" load_steps=2 format=3 uid="uid://6ip8eigu30by"] + +[ext_resource type="Script" path="res://addons/gdLinter/Settings/ignore.gd" id="1_8j37n"] + +[resource] +script = ExtResource("1_8j37n") +_function_name = false +_class_name = false +_sub_class_name = false +_signal_name = false +_class_variable_name = false +_class_load_variable_name = false +_function_variable_name = false +_function_preload_variable_name = false +_function_argument_name = false +_loop_variable_name = false +_enum_name = false +_enum_element_name = false +_constant_name = false +_load_constant_name = false +_duplicated_load = false +_expression_not_assigned = false +_unnecessary_pass = false +_unused_argument = false +_comparison_with_itself = false +_private_method_call = false +_class_definitions_order = false +_max_public_methods = false +_function_arguments_number = false +_max_file_lines = false +_trailing_whitespace = false +_max_line_length = false +_mixed_tabs_and_spaces = false +_no_elif_return = false +_no_else_return = false diff --git a/addons/gdLinter/UI/Basic.gd b/addons/gdLinter/UI/Basic.gd new file mode 100644 index 0000000..d3a6cb4 --- /dev/null +++ b/addons/gdLinter/UI/Basic.gd @@ -0,0 +1,39 @@ +@tool +extends MarginContainer + +var _owner: GDLinterIgnoreWindow = owner + +@onready var duplicated_load: CheckBox = %DuplicatedLoad +@onready var expression_not_assigned: CheckBox = %ExpressionNotAssigned +@onready var unnecessary_pass: CheckBox = %UnnecessaryPass +@onready var unused_argument: CheckBox = %UnusedArgument +@onready var comparision_with_itself: CheckBox = %ComparisionWithItself + + +func init() -> void: + _owner = owner + duplicated_load.button_pressed = _owner.ignore.get("_duplicated_load") + expression_not_assigned.button_pressed = _owner.ignore.get("_expression_not_assigned") + unnecessary_pass.button_pressed = _owner.ignore.get("_unnecessary_pass") + unused_argument.button_pressed = _owner.ignore.get("_unused_argument") + comparision_with_itself.button_pressed = _owner.ignore.get("_comparison_with_itself") + + +func _on_duplicated_load_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_duplicated_load", toggled_on) + + +func _on_expression_not_assigned_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_expression_not_assigned", toggled_on) + + +func _on_unnecessary_pass_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_unnecessary_pass", toggled_on) + + +func _on_unused_argument_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_unused_argument", toggled_on) + + +func _on_comparision_with_itself_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_comparison_with_itself", toggled_on) diff --git a/addons/gdLinter/UI/Class.gd b/addons/gdLinter/UI/Class.gd new file mode 100644 index 0000000..c415576 --- /dev/null +++ b/addons/gdLinter/UI/Class.gd @@ -0,0 +1,21 @@ +@tool +extends MarginContainer + +var _owner: GDLinterIgnoreWindow = owner + +@onready var private_method_call: CheckBox = %PrivateMethodCall +@onready var class_definition_order: CheckBox = %ClassDefinitionOrder + + +func init() -> void: + _owner = owner + private_method_call.button_pressed = _owner.ignore.get("_private_method_call") + class_definition_order.button_pressed = _owner.ignore.get("_class_definitions_order") + + +func _on_private_method_call_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_private_method_call", toggled_on) + + +func _on_class_definition_order_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_class_definitions_order", toggled_on) diff --git a/addons/gdLinter/UI/Design.gd b/addons/gdLinter/UI/Design.gd new file mode 100644 index 0000000..9c81347 --- /dev/null +++ b/addons/gdLinter/UI/Design.gd @@ -0,0 +1,21 @@ +@tool +extends MarginContainer + +var _owner: GDLinterIgnoreWindow = owner + +@onready var max_public_methods: CheckBox = %MaxPublicMethods +@onready var function_argument_number: CheckBox = %FunctionArgumentNumber + + +func init() -> void: + _owner = owner + max_public_methods.button_pressed = _owner.ignore.get("_max_public_methods") + function_argument_number.button_pressed = _owner.ignore.get("_function_arguments_number") + + +func _on_max_public_methods_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_max_public_methods", toggled_on) + + +func _on_function_argument_number_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_function_arguments_number", toggled_on) diff --git a/addons/gdLinter/UI/Dock.gd b/addons/gdLinter/UI/Dock.gd new file mode 100644 index 0000000..4f38490 --- /dev/null +++ b/addons/gdLinter/UI/Dock.gd @@ -0,0 +1,101 @@ +@tool +class_name GDLinterDock +extends Control + +var gd_linter: GDLinter +var error_descriptions := preload("res://addons/gdLinter/error_descriptions.gd").new() +var script_text_editor: ScriptEditorBase +var color_error: Color = EditorInterface.get_editor_settings()\ + .get_setting("text_editor/theme/highlighting/comment_markers/critical_color") + +var num_problems: int = 0 +var num_ignored_problems: int = 0 + +var _ignore: GDLinterIgnore = preload("res://addons/gdLinter/Settings/ignore.tres") + +@onready var file: Label = %File +@onready var problems_num: Label = %ProblemsNum +@onready var ignored_problems_num: Label = %IgnoredProblemsNum +@onready var version: Label = %Version +@onready var tree: Tree = %Tree +@onready var gd_linter_ignore_window: GDLinterIgnoreWindow = $GdLinterIgnoreWindow + + +func _ready() -> void: + gd_linter_ignore_window.ignore = _ignore + gd_linter_ignore_window.dock_ui = self + tree.add_theme_color_override("font_color", color_error) + tree.set_column_title(0, "Line") + tree.set_column_title(1, "Error") + tree.set_column_title_alignment(0, HORIZONTAL_ALIGNMENT_LEFT) + tree.set_column_title_alignment(1, HORIZONTAL_ALIGNMENT_LEFT) + tree.set_column_custom_minimum_width(0, 75) + tree.set_column_custom_minimum_width(1, 0) + tree.set_column_expand(0, false) + tree.set_column_expand(1, true) + tree.set_column_clip_content(0, false) + tree.set_column_clip_content(1, true) + tree.set_column_expand_ratio(0, 4) + tree.item_activated.connect(_on_item_activated) + +func reset_problem_num() -> void: + num_problems = 0 + num_ignored_problems = 0 + + +func create_item(line: int, name: String) -> void: + var regex = RegEx.new() + regex.compile("(?<=\\()[^\\)]+") + var result := regex.search_all(name) + var error_type := result[-1].strings[0] + if _ignore.get(str_dash_to_underscore(error_type)): + num_ignored_problems += 1 + return + + var item := tree.create_item() + item.set_text(0, str(line)) + item.set_text(1, name) + item.set_metadata(0, line) + + if error_descriptions.error.has(error_type): + item.set_tooltip_text(1, error_descriptions.error[error_type]) + num_problems += 1 + + +func set_problems_label(number: int) -> void: + problems_num.text = str(number) + + +func set_ignored_problems_label(number: int) -> void: + ignored_problems_num.text = str(number) + +func clear_items() -> void: + reset_problem_num() + tree.clear() + tree.create_item() + + +func _on_item_activated() -> void: + var selected: TreeItem = tree.get_selected() + var line := selected.get_metadata(0) + + EditorInterface.edit_script(load(file.text), line) + + if not EditorInterface.get_editor_settings().get("text_editor/external/use_external_editor"): + EditorInterface.set_main_screen_editor("Script") + + +func str_dash_to_underscore(string: String) -> String: + return "_" + string.replace("-", "_") + + +func is_error_ignored(name: String) -> bool: + var regex = RegEx.new() + regex.compile("(?<=\\()[^\\)]+") + var result := regex.search_all(name) + var error_type := result[-1].strings[0] + return _ignore.get(str_dash_to_underscore(error_type)) + + +func _on_button_pressed() -> void: + gd_linter_ignore_window.popup() diff --git a/addons/gdLinter/UI/Dock.tscn b/addons/gdLinter/UI/Dock.tscn new file mode 100644 index 0000000..9cd6778 --- /dev/null +++ b/addons/gdLinter/UI/Dock.tscn @@ -0,0 +1,111 @@ +[gd_scene load_steps=3 format=3 uid="uid://d1eqlqvotirg1"] + +[ext_resource type="Script" path="res://addons/gdLinter/UI/Dock.gd" id="1_u5r3b"] +[ext_resource type="PackedScene" uid="uid://cgk7hjif0ujw1" path="res://addons/gdLinter/UI/GDLinterIgnoreWindow.tscn" id="3_ib5aw"] + +[node name="Dock" 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_u5r3b") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Header" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="RichTextLabel" type="RichTextLabel" parent="VBoxContainer/Header"] +layout_mode = 2 +bbcode_enabled = true +text = "[center]GDLint Plugin 2.0.2[/center]" +fit_content = true + +[node name="LintedFile" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/LintedFile"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/LintedFile/HBoxContainer"] +layout_mode = 2 +text = "Currently linted file:" + +[node name="File" type="Label" parent="VBoxContainer/LintedFile/HBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 + +[node name="MiddleContainer" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +size_flags_stretch_ratio = 20.0 + +[node name="Tree" type="Tree" parent="VBoxContainer/MiddleContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +focus_mode = 0 +theme_override_colors/font_color = Color(0.77, 0.35, 0.35, 1) +theme_override_constants/v_separation = 0 +columns = 2 +column_titles_visible = true +hide_folding = true +hide_root = true +select_mode = 1 +scroll_horizontal_enabled = false + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/MiddleContainer"] +layout_mode = 2 + +[node name="Button" type="Button" parent="VBoxContainer/MiddleContainer/VBoxContainer"] +layout_mode = 2 +text = "Ignore +Settings" + +[node name="Statusbar" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 10 + +[node name="ProblemsContainer" type="HBoxContainer" parent="VBoxContainer/Statusbar"] +layout_mode = 2 +theme_override_constants/separation = 0 + +[node name="ProblemsNum" type="Label" parent="VBoxContainer/Statusbar/ProblemsContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "0" + +[node name="ProblemsLbl" type="Label" parent="VBoxContainer/Statusbar/ProblemsContainer"] +layout_mode = 2 +text = "problems found" + +[node name="VSeparator" type="VSeparator" parent="VBoxContainer/Statusbar/ProblemsContainer"] +layout_mode = 2 + +[node name="IgnoredProblemsNum" type="Label" parent="VBoxContainer/Statusbar/ProblemsContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "0" + +[node name="IgnoredProblemsLbl" type="Label" parent="VBoxContainer/Statusbar/ProblemsContainer"] +layout_mode = 2 +text = "problems ignored" + +[node name="Version" type="Label" parent="VBoxContainer/Statusbar"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_horizontal = 3 +horizontal_alignment = 2 + +[node name="GdLinterIgnoreWindow" parent="." instance=ExtResource("3_ib5aw")] +dialog_text = "" + +[connection signal="pressed" from="VBoxContainer/MiddleContainer/VBoxContainer/Button" to="." method="_on_button_pressed"] diff --git a/addons/gdLinter/UI/Format.gd b/addons/gdLinter/UI/Format.gd new file mode 100644 index 0000000..f61661e --- /dev/null +++ b/addons/gdLinter/UI/Format.gd @@ -0,0 +1,33 @@ +@tool +extends MarginContainer + +var _owner: GDLinterIgnoreWindow = owner + +@onready var max_file_lines: CheckBox = %MaxFileLines +@onready var trailing_whitespace_check_box: CheckBox = %TrailingWhitespaceCheckBox +@onready var max_line_length: CheckBox = %MaxLineLength +@onready var mixed_tabs_and_spaces: CheckBox = %MixedTabsAndSpaces + + +func init() -> void: + _owner = owner + max_file_lines.button_pressed = _owner.ignore.get("_max_file_lines") + trailing_whitespace_check_box.button_pressed = _owner.ignore.get("_trailing_whitespace") + max_line_length.button_pressed = _owner.ignore.get("_max_line_length") + mixed_tabs_and_spaces.button_pressed = _owner.ignore.get("_mixed_tabs_and_spaces") + + +func _on_max_file_lines_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_max_file_lines", toggled_on) + + +func _on_trailing_whitespace_check_box_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_trailing_whitespace", toggled_on) + + +func _on_max_line_length_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_max_line_length", toggled_on) + + +func _on_mixed_tabs_and_spaces_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_mixed_tabs_and_spaces", toggled_on) diff --git a/addons/gdLinter/UI/GDLinterIgnoreWindow.gd b/addons/gdLinter/UI/GDLinterIgnoreWindow.gd new file mode 100644 index 0000000..7a00b80 --- /dev/null +++ b/addons/gdLinter/UI/GDLinterIgnoreWindow.gd @@ -0,0 +1,31 @@ +@tool +class_name GDLinterIgnoreWindow +extends AcceptDialog + +var ignore: GDLinterIgnore +var dock_ui: GDLinterDock + +@onready var basic: MarginContainer = %Basic +@onready var design: MarginContainer = %Design +@onready var format: MarginContainer = %Format +@onready var misc: MarginContainer = %Misc +@onready var _name: MarginContainer = %Name +@onready var _class: MarginContainer = %Class + + +func reapply_linting() -> void: + var current_script := EditorInterface.get_script_editor().get_current_script() + dock_ui.gd_linter.script_editor.editor_script_changed.emit(current_script) + + +func _on_confirmed() -> void: + reapply_linting() + + +func _on_about_to_popup() -> void: + basic.init() + design.init() + format.init() + misc.init() + _name.init() + _class.init() diff --git a/addons/gdLinter/UI/GDLinterIgnoreWindow.tscn b/addons/gdLinter/UI/GDLinterIgnoreWindow.tscn new file mode 100644 index 0000000..1974c03 --- /dev/null +++ b/addons/gdLinter/UI/GDLinterIgnoreWindow.tscn @@ -0,0 +1,261 @@ +[gd_scene load_steps=8 format=3 uid="uid://cgk7hjif0ujw1"] + +[ext_resource type="Script" path="res://addons/gdLinter/UI/GDLinterIgnoreWindow.gd" id="1_71hhq"] +[ext_resource type="Script" path="res://addons/gdLinter/UI/Name.gd" id="2_35t2j"] +[ext_resource type="Script" path="res://addons/gdLinter/UI/Basic.gd" id="3_ijjp7"] +[ext_resource type="Script" path="res://addons/gdLinter/UI/Class.gd" id="4_s2mg3"] +[ext_resource type="Script" path="res://addons/gdLinter/UI/Design.gd" id="5_2ncqt"] +[ext_resource type="Script" path="res://addons/gdLinter/UI/Format.gd" id="6_5fvrg"] +[ext_resource type="Script" path="res://addons/gdLinter/UI/Misc.gd" id="7_l8gkb"] + +[node name="GdLinterIgnoreWindow" type="AcceptDialog"] +disable_3d = true +title = "GDLinter Ignore Settings" +initial_position = 1 +size = Vector2i(480, 539) +dialog_text = "fghgfdfggfd" +script = ExtResource("1_71hhq") + +[node name="PanelContainer" type="PanelContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 8.0 +offset_top = 8.0 +offset_right = -8.0 +offset_bottom = -34.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="TabContainer" type="TabContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="Name" type="MarginContainer" parent="PanelContainer/TabContainer"] +unique_name_in_owner = true +layout_mode = 2 +script = ExtResource("2_35t2j") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/TabContainer/Name"] +layout_mode = 2 + +[node name="FunctionName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Function Name" + +[node name="ClassName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Class Name" + +[node name="SubClassName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Sub Class Name" + +[node name="SignalName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Signal Name" + +[node name="ClassVariableName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Class Variable Name" + +[node name="ClassLoadVariableName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Class Load Variable Name" + +[node name="FunctionVariableName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Function Variable Name" + +[node name="FunctionPreloadVariableName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Function Preload Variable Name" + +[node name="FunctionArgumentName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Function Argument Name" + +[node name="LoopVariableName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Loop Variable Name" + +[node name="EnumName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Enum Name" + +[node name="EnumElementName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Enum Element Name" + +[node name="ConstantName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Constant Name" + +[node name="LoadConstantName" type="CheckBox" parent="PanelContainer/TabContainer/Name/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Load Constant Name" + +[node name="Basic" type="MarginContainer" parent="PanelContainer/TabContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +script = ExtResource("3_ijjp7") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/TabContainer/Basic"] +layout_mode = 2 + +[node name="DuplicatedLoad" type="CheckBox" parent="PanelContainer/TabContainer/Basic/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Duplicated Load" + +[node name="ExpressionNotAssigned" type="CheckBox" parent="PanelContainer/TabContainer/Basic/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Expression Not Assigned" + +[node name="UnnecessaryPass" type="CheckBox" parent="PanelContainer/TabContainer/Basic/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Unnecessary Pass" + +[node name="UnusedArgument" type="CheckBox" parent="PanelContainer/TabContainer/Basic/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Unused Argument" + +[node name="ComparisionWithItself" type="CheckBox" parent="PanelContainer/TabContainer/Basic/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Comparision With Itself" + +[node name="Class" type="MarginContainer" parent="PanelContainer/TabContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +script = ExtResource("4_s2mg3") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/TabContainer/Class"] +layout_mode = 2 + +[node name="PrivateMethodCall" type="CheckBox" parent="PanelContainer/TabContainer/Class/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Private Method Call" + +[node name="ClassDefinitionOrder" type="CheckBox" parent="PanelContainer/TabContainer/Class/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Class Definition Order" + +[node name="Design" type="MarginContainer" parent="PanelContainer/TabContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +script = ExtResource("5_2ncqt") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/TabContainer/Design"] +layout_mode = 2 + +[node name="MaxPublicMethods" type="CheckBox" parent="PanelContainer/TabContainer/Design/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Max Public Methods" + +[node name="FunctionArgumentNumber" type="CheckBox" parent="PanelContainer/TabContainer/Design/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Function Argument Number" + +[node name="Format" type="MarginContainer" parent="PanelContainer/TabContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +script = ExtResource("6_5fvrg") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/TabContainer/Format"] +layout_mode = 2 + +[node name="MaxFileLines" type="CheckBox" parent="PanelContainer/TabContainer/Format/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Max File Lines" + +[node name="TrailingWhitespaceCheckBox" type="CheckBox" parent="PanelContainer/TabContainer/Format/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Trailing Whitespace" + +[node name="MaxLineLength" type="CheckBox" parent="PanelContainer/TabContainer/Format/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Max Line Length" + +[node name="MixedTabsAndSpaces" type="CheckBox" parent="PanelContainer/TabContainer/Format/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Mixed Tabs And Spaces" + +[node name="Misc" type="MarginContainer" parent="PanelContainer/TabContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +script = ExtResource("7_l8gkb") + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/TabContainer/Misc"] +layout_mode = 2 + +[node name="NoElifReturn" type="CheckBox" parent="PanelContainer/TabContainer/Misc/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "No Elif Return" + +[node name="NoElseReturn" type="CheckBox" parent="PanelContainer/TabContainer/Misc/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "No Else Return" + +[connection signal="about_to_popup" from="." to="." method="_on_about_to_popup"] +[connection signal="confirmed" from="." to="." method="_on_confirmed"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/FunctionName" to="PanelContainer/TabContainer/Name" method="_on_function_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/ClassName" to="PanelContainer/TabContainer/Name" method="_on_class_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/SubClassName" to="PanelContainer/TabContainer/Name" method="_on_sub_class_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/SignalName" to="PanelContainer/TabContainer/Name" method="_on_signal_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/ClassVariableName" to="PanelContainer/TabContainer/Name" method="_on_class_variable_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/ClassLoadVariableName" to="PanelContainer/TabContainer/Name" method="_on_class_load_variable_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/FunctionVariableName" to="PanelContainer/TabContainer/Name" method="_on_function_variable_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/FunctionPreloadVariableName" to="PanelContainer/TabContainer/Name" method="_on_function_preload_variable_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/FunctionArgumentName" to="PanelContainer/TabContainer/Name" method="_on_function_argument_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/LoopVariableName" to="PanelContainer/TabContainer/Name" method="_on_loop_variable_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/EnumName" to="PanelContainer/TabContainer/Name" method="_on_enum_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/EnumElementName" to="PanelContainer/TabContainer/Name" method="_on_enum_element_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/ConstantName" to="PanelContainer/TabContainer/Name" method="_on_constant_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Name/VBoxContainer/LoadConstantName" to="PanelContainer/TabContainer/Name" method="_on_load_constant_name_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Basic/VBoxContainer/DuplicatedLoad" to="PanelContainer/TabContainer/Basic" method="_on_duplicated_load_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Basic/VBoxContainer/ExpressionNotAssigned" to="PanelContainer/TabContainer/Basic" method="_on_expression_not_assigned_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Basic/VBoxContainer/UnnecessaryPass" to="PanelContainer/TabContainer/Basic" method="_on_unnecessary_pass_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Basic/VBoxContainer/UnusedArgument" to="PanelContainer/TabContainer/Basic" method="_on_unused_argument_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Basic/VBoxContainer/ComparisionWithItself" to="PanelContainer/TabContainer/Basic" method="_on_comparision_with_itself_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Class/VBoxContainer/PrivateMethodCall" to="PanelContainer/TabContainer/Class" method="_on_private_method_call_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Class/VBoxContainer/ClassDefinitionOrder" to="PanelContainer/TabContainer/Class" method="_on_class_definition_order_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Design/VBoxContainer/MaxPublicMethods" to="PanelContainer/TabContainer/Design" method="_on_max_public_methods_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Design/VBoxContainer/FunctionArgumentNumber" to="PanelContainer/TabContainer/Design" method="_on_function_argument_number_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Format/VBoxContainer/MaxFileLines" to="PanelContainer/TabContainer/Format" method="_on_max_file_lines_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Format/VBoxContainer/TrailingWhitespaceCheckBox" to="PanelContainer/TabContainer/Format" method="_on_trailing_whitespace_check_box_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Format/VBoxContainer/MaxLineLength" to="PanelContainer/TabContainer/Format" method="_on_max_line_length_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Format/VBoxContainer/MixedTabsAndSpaces" to="PanelContainer/TabContainer/Format" method="_on_mixed_tabs_and_spaces_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Misc/VBoxContainer/NoElifReturn" to="PanelContainer/TabContainer/Misc" method="_on_no_elif_return_toggled"] +[connection signal="toggled" from="PanelContainer/TabContainer/Misc/VBoxContainer/NoElseReturn" to="PanelContainer/TabContainer/Misc" method="_on_no_else_return_toggled"] diff --git a/addons/gdLinter/UI/Misc.gd b/addons/gdLinter/UI/Misc.gd new file mode 100644 index 0000000..6e6bbe5 --- /dev/null +++ b/addons/gdLinter/UI/Misc.gd @@ -0,0 +1,21 @@ +@tool +extends MarginContainer + +var _owner: GDLinterIgnoreWindow = owner + +@onready var no_elif_return: CheckBox = %NoElifReturn +@onready var no_else_return: CheckBox = %NoElseReturn + + +func init() -> void: + _owner = owner + no_elif_return.button_pressed = _owner.ignore.get("_no_elif_return") + no_else_return.button_pressed = _owner.ignore.get("_no_else_return") + + +func _on_no_elif_return_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_no_elif_return", toggled_on) + + +func _on_no_else_return_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_no_else_return", toggled_on) diff --git a/addons/gdLinter/UI/Name.gd b/addons/gdLinter/UI/Name.gd new file mode 100644 index 0000000..6b3920e --- /dev/null +++ b/addons/gdLinter/UI/Name.gd @@ -0,0 +1,93 @@ +@tool +extends MarginContainer + +var _owner: GDLinterIgnoreWindow = owner + +@onready var function_name: CheckBox = %FunctionName +@onready var sub_class_name: CheckBox = %SubClassName +@onready var signal_name: CheckBox = %SignalName +@onready var class_variable_name: CheckBox = %ClassVariableName +@onready var class_load_variable_name: CheckBox = %ClassLoadVariableName +@onready var function_variable_name: CheckBox = %FunctionVariableName +@onready var function_preload_variable_name: CheckBox = %FunctionPreloadVariableName +@onready var function_argument_name: CheckBox = %FunctionArgumentName +@onready var loop_variable_name: CheckBox = %LoopVariableName +@onready var enum_name: CheckBox = %EnumName +@onready var enum_element_name: CheckBox = %EnumElementName +@onready var constant_name: CheckBox = %ConstantName +@onready var load_constant_name: CheckBox = %LoadConstantName +@onready var _class_name: CheckBox = %ClassName + + +func init() -> void: + _owner = owner + function_name.button_pressed = _owner.ignore.get("_function_name") + _class_name.button_pressed = _owner.ignore.get("_class_name") + sub_class_name.button_pressed = _owner.ignore.get("_sub_class_name") + signal_name.button_pressed = _owner.ignore.get("_signal_name") + class_variable_name.button_pressed = _owner.ignore.get("_class_variable_name") + class_load_variable_name.button_pressed = _owner.ignore.get("_class_load_variable_name") + function_variable_name.button_pressed = _owner.ignore.get("_function_variable_name") + function_preload_variable_name.button_pressed = _owner.ignore.get("_function_preload_variable_name") + function_argument_name.button_pressed = _owner.ignore.get("_function_argument_name") + loop_variable_name.button_pressed = _owner.ignore.get("_loop_variable_name") + enum_name.button_pressed = _owner.ignore.get("_enum_name") + enum_element_name.button_pressed = _owner.ignore.get("_enum_element_name") + constant_name.button_pressed = _owner.ignore.get("_constant_name") + load_constant_name.button_pressed = _owner.ignore.get("_load_constant_name") + + +func _on_function_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_function_name", toggled_on) + + +func _on_class_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_class_name", toggled_on) + + +func _on_sub_class_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_sub_class_name", toggled_on) + + +func _on_signal_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_signal_name", toggled_on) + + +func _on_class_variable_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_class_variable_name", toggled_on) + + +func _on_class_load_variable_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_class_load_variable_name", toggled_on) + + +func _on_function_variable_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_function_variable_name", toggled_on) + + +func _on_function_preload_variable_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_function_preload_variable_name", toggled_on) + + +func _on_function_argument_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_function_argument_name", toggled_on) + + +func _on_loop_variable_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_loop_variable_name", toggled_on) + + +func _on_enum_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_enum_name", toggled_on) + + +func _on_enum_element_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_enum_element_name", toggled_on) + + +func _on_constant_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_constant_name", toggled_on) + + +func _on_load_constant_name_toggled(toggled_on: bool) -> void: + _owner.ignore.set("_load_constant_name", toggled_on) diff --git a/addons/gdLinter/error_descriptions.gd b/addons/gdLinter/error_descriptions.gd new file mode 100644 index 0000000..684d888 --- /dev/null +++ b/addons/gdLinter/error_descriptions.gd @@ -0,0 +1,51 @@ +extends Resource + +var error := { + #region Name Checks + "function-name": "Validates if function name conforms to snake_case, _private_snake_case, or _on_PascalCase_snake_case.", + "class-name": "Validates if class name conforms to PascalCase.", + "sub-class-name": "Validates if class name conforms to _PrivatePascalCase.", + "signal-name": "Validates if signal name conforms to PascalCase.", + "class-variable-name": "Validates if class variable name conforms to snake_case or _private_snake_case.", + "class-load-variable-name": "Validates if class load variable (var variable = load(...)) name conforms to PascalCase, snake_case or private_snake_case.", + "function-variable-name": "alidates if function variable name conforms to snake_case.", + "function-preload-variable-name": "Validates if function preload variable (var Variable = preload(...)) name conforms to PascalCase.", + "function-argument-name": "Validates if function argument (formal parameter) name conforms to snake_case or _private_snake_case.", + "loop-variable-name": "Validates if loop variable name conforms to snake_case or _private_snake_case.", + "enum-name": "Validates if enum name conforms to PascalCase.", + "enum-element-name": "Validates if enum element name conforms to UPPER_SNAKE_CASE.", + "constant-name": "Validates if constant name conforms to UPPER_SNAKE_CASE.", + "load-constant-name": "Validates if load constant (const constant = load(...)) name conforms to PascalCase, snake_case or private_snake_case.", + #endregion + + #region Basic Checks + "duplicated-load": "Copy-pasted load(...) for the same path e.g. load('res://asdf.tscn') in multiple places. To fix, simply extract string to constant.", + "expression-not-assigned": "Standalone expression like 1 + 1 which is not used in any way. To fix, simply remove that expression.", + "unnecessary-pass": "Pass which is not the only expression on class or function body. To fix, simple remove that pass statement.", + "unused-argument": "Unused funtion argument. To fix, simply remove it or mark as explicitly unused by prefixing with underscore _ e.g. _unused_arg.", + "comparison-with-itself": "Redundant comparison like e.g. x == x which is always true. To fix, simply remove that expression.", + #endregion + + #region Class Checks + "private-method-call": """private (prefixed with underscore _) function was called. + E.g. player._private_func(). To fix, redesign your approach so that private function is not being called.""", + "class-definitions-order": "Class statements are not in order.", + #endregion + + #region Design Checks + "max-public-methods": "Validates maximum number of public methods (class-level functions).", + "function-arguments-number": "Validates number of function arguments.", + #endregion + + #region Format Checks + "max-file-lines": "Validates maximum number of file lines.", + "trailing-whitespace": "Validates if any trailing whitespaces are present.", + "max-line-length": "Validates maxium line length for each line.", + "mixed-tabs-and-spaces": "Validates if either only tabs or only spaces are used for indentation.", + #endregion + + #region Misc Checks + "no-elif-return": "Validates if unnecessary elif is present in case if body was ended with return.", + "no-else-return": "Validates if unnecessary else is present in case if (and each elif) body was ended with return." + #endregion +} diff --git a/addons/gdLinter/gdLinter.gd b/addons/gdLinter/gdLinter.gd new file mode 100644 index 0000000..ca76314 --- /dev/null +++ b/addons/gdLinter/gdLinter.gd @@ -0,0 +1,188 @@ +@tool +class_name GDLinter +extends EditorPlugin + +const DockScene := preload("res://addons/gdLinter/UI/Dock.tscn") + + +var icon_error := EditorInterface.get_editor_theme().get_icon("Error", "EditorIcons") +var color_error: Color = EditorInterface.get_editor_settings()\ + .get_setting("text_editor/theme/highlighting/comment_markers/critical_color") + +var icon_error_ignore := EditorInterface.get_editor_theme().get_icon("ErrorWarning", "EditorIcons") +var icon_ignore := EditorInterface.get_editor_theme().get_icon("Warning", "EditorIcons") + +var icon_success := EditorInterface.get_editor_theme().get_icon("StatusSuccess", "EditorIcons") +var color_success: Color = EditorInterface.get_editor_settings()\ + .get_setting("text_editor/theme/highlighting/comment_markers/notice_color") + +var bottom_panel_button: Button +var highlight_lines: PackedInt32Array +var item_lists: Array[ItemList] +var script_editor: ScriptEditor + +var _dock_ui: GDLinterDock +var _is_gdlint_installed: bool +var _ignore: Resource +var _gdlint_path: String + + +func _enter_tree() -> void: + # install the GDLint dock + _dock_ui = DockScene.instantiate() + _dock_ui.gd_linter = self + bottom_panel_button = add_control_to_bottom_panel(_dock_ui, "GDLint") + + # connect signal to lint on save + resource_saved.connect(on_resource_saved) + + script_editor = EditorInterface.get_script_editor() + script_editor.editor_script_changed.connect(_on_editor_script_changed) + _gdlint_path = get_gdlint_path() + get_gdlint_version() + prints("Loading GDLint Plugin success") + +# TODO: Reenable again? +# Dunno how highlighting lines in Godot works, since it get removed after a second or so +# So I use this evil workaround straight from hell: +#func _process(_delta: float) -> void: + #if not get_current_editor(): + #return + # + #if not highlight_lines.is_empty(): + #set_line_color(color_error) + + +func _on_editor_script_changed(script: Script) -> void: + _dock_ui.clear_items() + on_resource_saved(script) + + +func get_gdlint_version() -> void: + var output := [] + OS.execute(_gdlint_path, ["--version"], output) + _is_gdlint_installed = true if not output[0].is_empty() else false + if _is_gdlint_installed: + _dock_ui.version.text = "Using %s" % output[0] + else: + _dock_ui.version.text = "gdlint not found!" + + +func _exit_tree() -> void: + if is_instance_valid(_dock_ui): + remove_control_from_bottom_panel(_dock_ui) + _dock_ui.free() + + if Engine.get_version_info().hex >= 0x40201: + prints("Unload GDLint Plugin success") + + +func on_resource_saved(resource: Resource) -> void: + if not resource is GDScript: + return + + _dock_ui.clear_items() + clear_highlights() + + # Show resource path in the GDLint Dock + _dock_ui.file.text = resource.resource_path + + # Execute linting and get its output + var filepath: String = ProjectSettings.globalize_path(resource.resource_path) + var gdlint_output: Array = [] + var output_array: PackedStringArray + var exit_code = OS.execute(_gdlint_path, [filepath], gdlint_output, true) + if not exit_code == -1: + var output_string: String = gdlint_output[0] + output_array = output_string.replace(filepath+":", "Line ").split("\n") + + _dock_ui.set_problems_label(_dock_ui.num_problems) + _dock_ui.set_ignored_problems_label(_dock_ui.num_ignored_problems) + + # Workaround until unique name bug is fixed + # https://github.com/Scony/godot-gdscript-toolkit/issues/284 + # Hope I won't break other stuff with it + if not output_array.size() or output_array[0] == "Line ": + printerr("gdLint Error: ", output_array, "\n File can't be linted!") + return + + # When there is no error + if output_array.size() <= 2: + bottom_panel_button.add_theme_constant_override(&"icon_max_width", 8) + bottom_panel_button.icon = icon_success + return + + # When errors are found create buttons in the dock + for i in output_array.size()-2: + var regex := RegEx.new() + regex.compile("\\d+") + var result := regex.search(output_array[i]) + if result: + var current_line := int(result.strings[0])-1 + var error := output_array[i].rsplit(":", true, 1) + if len(error) > 1: + _dock_ui.create_item(current_line+1, error[1]) + if _dock_ui.is_error_ignored(error[1]): + continue + highlight_lines.append(current_line) + + _dock_ui.set_problems_label(_dock_ui.num_problems) + _dock_ui.set_ignored_problems_label(_dock_ui.num_ignored_problems) + + # Error, no Ignore + if _dock_ui.num_problems > 0 and _dock_ui.num_ignored_problems <= 0: + bottom_panel_button.icon = icon_error + # no Error, Ignore + elif _dock_ui.num_problems <= 0 and _dock_ui.num_ignored_problems > 0: + bottom_panel_button.icon = icon_ignore + # Error, Ignore + elif _dock_ui.num_problems > 0 and _dock_ui.num_ignored_problems > 0: + bottom_panel_button.icon = icon_error_ignore + else: + bottom_panel_button.icon = null + _dock_ui.script_text_editor = EditorInterface.get_script_editor().get_current_editor() + + +func set_line_color(color: Color) -> void: + var current_code_editor := get_current_editor() + if current_code_editor == null: + return + + for line: int in highlight_lines: + # Skip line if this one is from the old code editor + if line > current_code_editor.get_line_count()-1: + continue + current_code_editor.set_line_background_color(line, + color.darkened(0.5)) + + +func clear_highlights() -> void: + set_line_color(Color(0, 0, 0, 0)) + highlight_lines.clear() + + +func get_current_editor() -> CodeEdit: + var current_editor := EditorInterface.get_script_editor().get_current_editor() + if current_editor == null: + return + return current_editor.get_base_editor() as CodeEdit + + +func get_gdlint_path() -> String: + if OS.get_name() == "Windows": + return "gdlint" + + # macOS & Linux + var output := [] + OS.execute("python3", ["-m", "site", "--user-base"], output) + var python_bin_folder := (output[0] as String).strip_edges().path_join("bin") + if FileAccess.file_exists(python_bin_folder.path_join("gdlint")): + return python_bin_folder.path_join("gdlint") + + # Linux dirty hardcoded fallback + if OS.get_name() == "Linux": + if FileAccess.file_exists("/usr/bin/gdlint"): + return "/usr/bin/gdlint" + + # Global fallback + return "gdlint" diff --git a/addons/gdLinter/plugin.cfg b/addons/gdLinter/plugin.cfg new file mode 100644 index 0000000..f9487ba --- /dev/null +++ b/addons/gdLinter/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="gdLinter" +description="Runs `gdlint` on save to automatically lint your GDScript as you code." +author="Falli" +version="2.0.2" +script="gdLinter.gd" diff --git a/assets/SpaceMono-Bold.ttf b/assets/SpaceMono-Bold.ttf new file mode 100644 index 0000000..20e3449 Binary files /dev/null and b/assets/SpaceMono-Bold.ttf differ diff --git a/assets/SpaceMono-Bold.ttf.import b/assets/SpaceMono-Bold.ttf.import new file mode 100644 index 0000000..2096f99 --- /dev/null +++ b/assets/SpaceMono-Bold.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://dmitg6232hytb" +path="res://.godot/imported/SpaceMono-Bold.ttf-a0599d1b2f2dabf2e3ca851caf1baa92.fontdata" + +[deps] + +source_file="res://assets/SpaceMono-Bold.ttf" +dest_files=["res://.godot/imported/SpaceMono-Bold.ttf-a0599d1b2f2dabf2e3ca851caf1baa92.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/SpaceMono-BoldItalic.ttf b/assets/SpaceMono-BoldItalic.ttf new file mode 100644 index 0000000..ff2ea5a Binary files /dev/null and b/assets/SpaceMono-BoldItalic.ttf differ diff --git a/assets/SpaceMono-BoldItalic.ttf.import b/assets/SpaceMono-BoldItalic.ttf.import new file mode 100644 index 0000000..c153b60 --- /dev/null +++ b/assets/SpaceMono-BoldItalic.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://d2edhb701t42t" +path="res://.godot/imported/SpaceMono-BoldItalic.ttf-f7b46e55b1271856b01bb8cddc5a12ab.fontdata" + +[deps] + +source_file="res://assets/SpaceMono-BoldItalic.ttf" +dest_files=["res://.godot/imported/SpaceMono-BoldItalic.ttf-f7b46e55b1271856b01bb8cddc5a12ab.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/SpaceMono-Italic.ttf b/assets/SpaceMono-Italic.ttf new file mode 100644 index 0000000..f36282f Binary files /dev/null and b/assets/SpaceMono-Italic.ttf differ diff --git a/assets/SpaceMono-Italic.ttf.import b/assets/SpaceMono-Italic.ttf.import new file mode 100644 index 0000000..c78cdc3 --- /dev/null +++ b/assets/SpaceMono-Italic.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cjyu63kdviglf" +path="res://.godot/imported/SpaceMono-Italic.ttf-c3b45ba693c1f9c8acc44c6917acf7a0.fontdata" + +[deps] + +source_file="res://assets/SpaceMono-Italic.ttf" +dest_files=["res://.godot/imported/SpaceMono-Italic.ttf-c3b45ba693c1f9c8acc44c6917acf7a0.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/SpaceMono-Regular.ttf b/assets/SpaceMono-Regular.ttf new file mode 100644 index 0000000..04e56b9 Binary files /dev/null and b/assets/SpaceMono-Regular.ttf differ diff --git a/assets/SpaceMono-Regular.ttf.import b/assets/SpaceMono-Regular.ttf.import new file mode 100644 index 0000000..1faaf77 --- /dev/null +++ b/assets/SpaceMono-Regular.ttf.import @@ -0,0 +1,33 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://cuhtrlqg4s5tw" +path="res://.godot/imported/SpaceMono-Regular.ttf-a0e59f506ad76f27d9c5d7797291715d.fontdata" + +[deps] + +source_file="res://assets/SpaceMono-Regular.ttf" +dest_files=["res://.godot/imported/SpaceMono-Regular.ttf-a0e59f506ad76f27d9c5d7797291715d.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +hinting=1 +subpixel_positioning=1 +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/scifi_tilesheet@2.png b/assets/scifi_tilesheet@2.png index c1073a4..bbc1acf 100644 Binary files a/assets/scifi_tilesheet@2.png and b/assets/scifi_tilesheet@2.png differ diff --git a/data/buildings/advanced/advanced_building_group.tres b/data/buildings/advanced/advanced_building_group.tres new file mode 100644 index 0000000..c471109 --- /dev/null +++ b/data/buildings/advanced/advanced_building_group.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="BuildingGroup" load_steps=4 format=3 uid="uid://cfeob1arfvw6p"] + +[ext_resource type="Script" path="res://data/buildings/building_group.gd" id="1_5u0lh"] +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_hpowi"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_24mqt"] +atlas = ExtResource("1_hpowi") +region = Rect2(1088, 576, 64, 64) + +[resource] +script = ExtResource("1_5u0lh") +name = "Advanced" +atlas_texture = SubResource("AtlasTexture_24mqt") +buildings = Array[Resource("res://data/buildings/building.gd")]([]) diff --git a/data/buildings/basic/basic_building_group.tres b/data/buildings/basic/basic_building_group.tres new file mode 100644 index 0000000..df16de8 --- /dev/null +++ b/data/buildings/basic/basic_building_group.tres @@ -0,0 +1,17 @@ +[gd_resource type="Resource" script_class="BuildingGroup" load_steps=7 format=3 uid="uid://dqv53okb3evb7"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_p1crr"] +[ext_resource type="Script" path="res://data/buildings/building_group.gd" id="1_xphre"] +[ext_resource type="Resource" uid="uid://d38xgwstvtcm4" path="res://data/buildings/basic/harvester/harvester_building.tres" id="2_5rd2r"] +[ext_resource type="Resource" uid="uid://cta6ngelbwo8b" path="res://data/buildings/basic/warehouse/warehouse_building.tres" id="3_vxs34"] +[ext_resource type="Resource" uid="uid://bibep1rd0jml2" path="res://data/buildings/basic/researcher/researcher_building.tres" id="4_fxdio"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_nleix"] +atlas = ExtResource("1_p1crr") +region = Rect2(1024, 576, 64, 64) + +[resource] +script = ExtResource("1_xphre") +name = "Basic" +atlas_texture = SubResource("AtlasTexture_nleix") +buildings = Array[Resource("res://data/buildings/building.gd")]([ExtResource("2_5rd2r"), ExtResource("3_vxs34"), ExtResource("4_fxdio")]) diff --git a/data/buildings/basic/harvester/harvester.gd b/data/buildings/basic/harvester/harvester.gd new file mode 100644 index 0000000..a4a76a3 --- /dev/null +++ b/data/buildings/basic/harvester/harvester.gd @@ -0,0 +1,20 @@ +extends Building + +var nearest_res +var _distance +var _direction + +const CARBON_RESOURCE = preload("res://data/game_resources/carbon/carbon_resource.tres") +const HARVESTER_PARTICLES = preload("res://data/buildings/basic/harvester/harvester_particles.tscn") + +func initialize(building: BuildingBase) -> void: + nearest_res = Grid.get_nearest_resource(building.position, CARBON_RESOURCE) + _distance = building.position.distance_to(nearest_res) + _direction = nearest_res.direction_to(building.position) + BuildingManager.add_resource_building(CARBON_RESOURCE, building) + +func ready(building: BuildingBase) -> void: + var particles = HARVESTER_PARTICLES.instantiate() + particles.init(_distance, _direction, CARBON_RESOURCE) + particles.position = nearest_res + building.add_sibling(particles) diff --git a/data/buildings/basic/harvester/harvester_building.tres b/data/buildings/basic/harvester/harvester_building.tres new file mode 100644 index 0000000..5ae2764 --- /dev/null +++ b/data/buildings/basic/harvester/harvester_building.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" load_steps=5 format=3 uid="uid://d38xgwstvtcm4"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_m1sbx"] +[ext_resource type="Script" path="res://data/buildings/basic/harvester/harvester.gd" id="3_fy2m4"] +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="3_xlnq5"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_mgt0w"] +atlas = ExtResource("1_m1sbx") +region = Rect2(1088, 128, 64, 64) + +[resource] +script = ExtResource("3_fy2m4") +atlas_texture = SubResource("AtlasTexture_mgt0w") +name = "Harvester" +description = "Harvests nearby resources" +cost = { +ExtResource("3_xlnq5"): 100 +} diff --git a/data/buildings/basic/harvester/harvester_particles.gd b/data/buildings/basic/harvester/harvester_particles.gd new file mode 100644 index 0000000..b8f5b8a --- /dev/null +++ b/data/buildings/basic/harvester/harvester_particles.gd @@ -0,0 +1,37 @@ +extends Node2D + +var _pickup + +var _distance +var _direction +var _emitters: Array[CPUParticles2D] = [] + +func init(distance: float, direction: Vector2, res: GameResource) -> void: + _distance = distance + _direction = direction + _pickup = res + +func _ready() -> void: + if _emitters.size() < 10: + var particles = CPUParticles2D.new() + particles.amount = 8 + particles.spread = 8 * (_distance / 128) + particles.material = ParticleProcessMaterial.new() + particles.damping_max = _distance * -2.5 + particles.damping_min = _distance * -2.55 + particles.gravity = Vector2.ZERO + particles.direction = _direction + particles.initial_velocity_max = _distance * 2.25 + particles.initial_velocity_min = _distance * 2.2 + particles.lifetime = 1.65 + add_child(particles) + _emitters.append(particles) + else: + for i in range(1, _emitters.size()): + _emitters[i].queue_free() + _emitters.resize(1) + ResourceManager.pickup(_pickup) + + +func _on_particles_timer_timeout() -> void: + _ready() diff --git a/data/buildings/basic/harvester/harvester_particles.tscn b/data/buildings/basic/harvester/harvester_particles.tscn new file mode 100644 index 0000000..e357363 --- /dev/null +++ b/data/buildings/basic/harvester/harvester_particles.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://73dsjfc4imfo"] + +[ext_resource type="Script" path="res://data/buildings/basic/harvester/harvester_particles.gd" id="1_td5fv"] + +[node name="HarvesterParticles" type="Node2D"] +script = ExtResource("1_td5fv") + +[node name="ParticlesTimer" type="Timer" parent="."] +wait_time = 0.5 +autostart = true + +[connection signal="timeout" from="ParticlesTimer" to="." method="_on_particles_timer_timeout"] diff --git a/data/buildings/basic/researcher/researcher.gd b/data/buildings/basic/researcher/researcher.gd new file mode 100644 index 0000000..241b94c --- /dev/null +++ b/data/buildings/basic/researcher/researcher.gd @@ -0,0 +1,10 @@ +extends Node +class_name Researcher + +const RESEARCH_MENU = preload("res://scene/research_menu.tscn") + +func interact(on_interaction_finished: Callable) -> bool: + var build_menu = RESEARCH_MENU.instantiate() + build_menu.research.connect(on_interaction_finished) + add_sibling(build_menu) + return true diff --git a/data/buildings/basic/researcher/researcher.tscn b/data/buildings/basic/researcher/researcher.tscn new file mode 100644 index 0000000..45de94b --- /dev/null +++ b/data/buildings/basic/researcher/researcher.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://bw3j3vxpsfxst"] + +[ext_resource type="Script" path="res://data/buildings/basic/researcher/researcher.gd" id="1_018kr"] + +[node name="Researcher" type="Node"] +script = ExtResource("1_018kr") diff --git a/data/buildings/basic/researcher/researcher_building.tres b/data/buildings/basic/researcher/researcher_building.tres new file mode 100644 index 0000000..8034270 --- /dev/null +++ b/data/buildings/basic/researcher/researcher_building.tres @@ -0,0 +1,20 @@ +[gd_resource type="Resource" script_class="Building" load_steps=6 format=3 uid="uid://bibep1rd0jml2"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_kruad"] +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="2_hybxl"] +[ext_resource type="Script" path="res://data/buildings/building.gd" id="3_pleu3"] +[ext_resource type="PackedScene" uid="uid://bw3j3vxpsfxst" path="res://data/buildings/basic/researcher/researcher.tscn" id="4_sugjm"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_n7l2d"] +atlas = ExtResource("1_kruad") +region = Rect2(1024, 128, 64, 64) + +[resource] +script = ExtResource("3_pleu3") +atlas_texture = SubResource("AtlasTexture_n7l2d") +name = "Researcher" +description = "Research new buildings and technologies" +cost = { +ExtResource("2_hybxl"): 6000 +} +world_scene = ExtResource("4_sugjm") diff --git a/data/buildings/basic/warehouse/warehouse.gd b/data/buildings/basic/warehouse/warehouse.gd new file mode 100644 index 0000000..7be23ef --- /dev/null +++ b/data/buildings/basic/warehouse/warehouse.gd @@ -0,0 +1,9 @@ +extends Building + +const CARBON_RESOURCE = preload("res://data/game_resources/carbon/carbon_resource.tres") + +func initialize(building: BuildingBase) -> void: + BuildingManager.add_storage_building(CARBON_RESOURCE, building) + +func ready(building: BuildingBase) -> void: + pass diff --git a/data/buildings/basic/warehouse/warehouse_building.tres b/data/buildings/basic/warehouse/warehouse_building.tres new file mode 100644 index 0000000..40496cf --- /dev/null +++ b/data/buildings/basic/warehouse/warehouse_building.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" load_steps=5 format=3 uid="uid://cta6ngelbwo8b"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_t8g7q"] +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="2_0uiah"] +[ext_resource type="Script" path="res://data/buildings/basic/warehouse/warehouse.gd" id="3_nvser"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_hcas6"] +atlas = ExtResource("1_t8g7q") +region = Rect2(1024, 64, 64, 64) + +[resource] +script = ExtResource("3_nvser") +atlas_texture = SubResource("AtlasTexture_hcas6") +name = "Warehouse" +description = "Allows storage of more materials" +cost = { +ExtResource("2_0uiah"): 500 +} diff --git a/data/buildings/building.gd b/data/buildings/building.gd new file mode 100644 index 0000000..138bc07 --- /dev/null +++ b/data/buildings/building.gd @@ -0,0 +1,16 @@ +class_name Building +extends Resource + +@export var atlas_texture: AtlasTexture +@export var name: String +@export var description: String +@export var cost: Dictionary +@export var world_scene: PackedScene + + +func initialize(building: BuildingBase) -> void: + pass + + +func ready(building: BuildingBase) -> void: + pass diff --git a/data/buildings/building_base.gd b/data/buildings/building_base.gd new file mode 100644 index 0000000..ab3232b --- /dev/null +++ b/data/buildings/building_base.gd @@ -0,0 +1,18 @@ +class_name BuildingBase +extends Node2D + +var _building_data: Building +var building_data_scene + +@onready var sprite_2d: Sprite2D = $Sprite2D + +func initialize(data: Building, grid_location: Vector2i) -> void: + _building_data = data + position = Grid.grid_to_world_center(grid_location) + sprite_2d.texture = _building_data.atlas_texture + if _building_data.world_scene: + building_data_scene = _building_data.world_scene.instantiate() + add_child(building_data_scene) + +func interact(on_interaction_finished: Callable) -> bool: + return building_data_scene.interact(on_interaction_finished) diff --git a/data/buildings/building_base.tscn b/data/buildings/building_base.tscn new file mode 100644 index 0000000..9448382 --- /dev/null +++ b/data/buildings/building_base.tscn @@ -0,0 +1,8 @@ +[gd_scene load_steps=2 format=3 uid="uid://kij6k2k1rmxb"] + +[ext_resource type="Script" path="res://data/buildings/building_base.gd" id="1_odhat"] + +[node name="BuildingBase" type="Node2D"] +script = ExtResource("1_odhat") + +[node name="Sprite2D" type="Sprite2D" parent="."] diff --git a/data/buildings/building_group.gd b/data/buildings/building_group.gd new file mode 100644 index 0000000..481a5c1 --- /dev/null +++ b/data/buildings/building_group.gd @@ -0,0 +1,7 @@ +extends Resource +class_name BuildingGroup + +@export var name: String +@export var atlas_texture: AtlasTexture + +@export var buildings: Array[Building] diff --git a/data/buildings/building_methods.gd b/data/buildings/building_methods.gd new file mode 100644 index 0000000..7c5e8ac --- /dev/null +++ b/data/buildings/building_methods.gd @@ -0,0 +1,5 @@ +extends Resource +class_name BuildingMethods + +func ready(building: BuildingBase) -> void: + pass diff --git a/data/buildings/building_methods.tscn b/data/buildings/building_methods.tscn new file mode 100644 index 0000000..b5fa279 --- /dev/null +++ b/data/buildings/building_methods.tscn @@ -0,0 +1,6 @@ +[gd_scene load_steps=2 format=3 uid="uid://7threw5x5tw6"] + +[ext_resource type="Script" path="res://data/buildings/building_methods.gd" id="1_ll4rt"] + +[node name="BuildingMethods" type="Node2D"] +script = ExtResource("1_ll4rt") diff --git a/data/buildings/corruptor.tres b/data/buildings/corruptor.tres new file mode 100644 index 0000000..67ac0bd --- /dev/null +++ b/data/buildings/corruptor.tres @@ -0,0 +1,14 @@ +[gd_resource type="Resource" script_class="Building" load_steps=4 format=3 uid="uid://bgwoy0uh2cpvu"] + +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="1_5s38g"] +[ext_resource type="Resource" uid="uid://dr00rd4f42jqe" path="res://data/game_resources/gem/gem_resource.tres" id="2_u1tpw"] +[ext_resource type="Script" path="res://data/buildings/building.gd" id="3_bd7jk"] + +[resource] +script = ExtResource("3_bd7jk") +name = "Corruptor" +description = "A building which only functions to spread corruption, and does it well" +cost = { +ExtResource("1_5s38g"): 40, +ExtResource("2_u1tpw"): 20 +} diff --git a/data/buildings/hub.tres b/data/buildings/hub.tres new file mode 100644 index 0000000..be4574e --- /dev/null +++ b/data/buildings/hub.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="Building" load_steps=3 format=3 uid="uid://c6vv3hyn5sd7o"] + +[ext_resource type="Script" path="res://data/buildings/building.gd" id="1_ssd30"] +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="2_d8jrj"] + +[resource] +script = ExtResource("1_ssd30") +name = "Hub" +description = "Main cheap base that corrupts a square" +cost = { +ExtResource("2_d8jrj"): 50 +} diff --git a/data/game_resources/carbon/carbon_resource.tres b/data/game_resources/carbon/carbon_resource.tres new file mode 100644 index 0000000..417140b --- /dev/null +++ b/data/game_resources/carbon/carbon_resource.tres @@ -0,0 +1,12 @@ +[gd_resource type="Resource" script_class="GameResource" load_steps=3 format=3 uid="uid://bpjj0x7jr1k6u"] + +[ext_resource type="Script" path="res://scripts/game_resource.gd" id="1_4maxk"] +[ext_resource type="Resource" uid="uid://bsrqp68lxf2f" path="res://data/game_resources/carbon/spawn_pattern_close.tres" id="2_eyt7m"] + +[resource] +script = ExtResource("1_4maxk") +atlas_location = Vector2i(5, 3) +pickup_value = 20 +name = "Carbon" +spawn_patterns = Array[Resource("res://scripts/spawn_pattern.gd")]([ExtResource("2_eyt7m")]) +storage_max = 2500 diff --git a/data/game_resources/carbon/spawn_pattern_close.tres b/data/game_resources/carbon/spawn_pattern_close.tres new file mode 100644 index 0000000..110213e --- /dev/null +++ b/data/game_resources/carbon/spawn_pattern_close.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="SpawnPattern" load_steps=2 format=3 uid="uid://bsrqp68lxf2f"] + +[ext_resource type="Script" path="res://scripts/spawn_pattern.gd" id="1_pksks"] + +[resource] +script = ExtResource("1_pksks") +min_distance = 8 +max_distance = 20 +min_spread = 15 +quantity = 4 +cluster_size = 12 diff --git a/data/game_resources/gem/gem_resource.tres b/data/game_resources/gem/gem_resource.tres new file mode 100644 index 0000000..6ca06dc --- /dev/null +++ b/data/game_resources/gem/gem_resource.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="GameResource" load_steps=3 format=3 uid="uid://dr00rd4f42jqe"] + +[ext_resource type="Script" path="res://scripts/game_resource.gd" id="1_tfoa4"] +[ext_resource type="Resource" uid="uid://0crnt5nbhhlv" path="res://data/game_resources/gem/spawn_pattern_close.tres" id="2_n3fuo"] + +[resource] +script = ExtResource("1_tfoa4") +atlas_location = Vector2i(5, 6) +pickup_value = 10 +name = "Gem" +spawn_patterns = Array[Resource("res://scripts/spawn_pattern.gd")]([ExtResource("2_n3fuo")]) +storage_max = 0 +skills_needed = Array[int]([0]) diff --git a/data/game_resources/gem/spawn_pattern_close.tres b/data/game_resources/gem/spawn_pattern_close.tres new file mode 100644 index 0000000..d625b8b --- /dev/null +++ b/data/game_resources/gem/spawn_pattern_close.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="SpawnPattern" load_steps=2 format=3 uid="uid://0crnt5nbhhlv"] + +[ext_resource type="Script" path="res://scripts/spawn_pattern.gd" id="1_bi4rm"] + +[resource] +script = ExtResource("1_bi4rm") +min_distance = 16 +max_distance = 40 +min_spread = 30 +quantity = 4 +cluster_size = 6 diff --git a/data/interactions/build/advanced/build_advanced.tres b/data/interactions/build/advanced/build_advanced.tres new file mode 100644 index 0000000..e93998c --- /dev/null +++ b/data/interactions/build/advanced/build_advanced.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="InteractionBuildBasic" load_steps=4 format=3 uid="uid://kqcdiin4k3jr"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_ce8rd"] +[ext_resource type="Script" path="res://data/interactions/build/basic/interaction_build_basic.gd" id="2_xgp0x"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_fxfd2"] +atlas = ExtResource("1_ce8rd") +region = Rect2(1088, 576, 64, 64) + +[resource] +script = ExtResource("2_xgp0x") +name = "Advanced" +image = SubResource("AtlasTexture_fxfd2") diff --git a/data/interactions/build/advanced/interaction_build_advanced.gd b/data/interactions/build/advanced/interaction_build_advanced.gd new file mode 100644 index 0000000..1f4e8a3 --- /dev/null +++ b/data/interactions/build/advanced/interaction_build_advanced.gd @@ -0,0 +1,6 @@ +extends Interaction +class_name InteractionBuildAdvanced + +func interact_at(pos: Vector2i, root: Node) -> Array[Interaction]: + print("Building at: %s" % pos) + return [] diff --git a/data/interactions/build/basic/build_basic.tres b/data/interactions/build/basic/build_basic.tres new file mode 100644 index 0000000..684bf9c --- /dev/null +++ b/data/interactions/build/basic/build_basic.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="InteractionBuildBasic" load_steps=4 format=3 uid="uid://k4dq7122cnu0"] + +[ext_resource type="Script" path="res://data/interactions/build/basic/interaction_build_basic.gd" id="1_8f33m"] +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_qfmuq"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_w7o8k"] +atlas = ExtResource("1_qfmuq") +region = Rect2(1024, 576, 64, 64) + +[resource] +script = ExtResource("1_8f33m") +name = "Basic" +image = SubResource("AtlasTexture_w7o8k") diff --git a/data/interactions/build/basic/interaction_build_basic.gd b/data/interactions/build/basic/interaction_build_basic.gd new file mode 100644 index 0000000..c487920 --- /dev/null +++ b/data/interactions/build/basic/interaction_build_basic.gd @@ -0,0 +1,6 @@ +extends Interaction +class_name InteractionBuildBasic + +func interact_at(pos: Vector2i, root: Node) -> Array[Interaction]: + print("Building at: %s" % pos) + return [] diff --git a/data/interactions/build/build.tres b/data/interactions/build/build.tres new file mode 100644 index 0000000..c619183 --- /dev/null +++ b/data/interactions/build/build.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="InteractionBuild" load_steps=4 format=3 uid="uid://bo3e2jefukgdy"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_bglkk"] +[ext_resource type="Script" path="res://data/interactions/build/interaction_build.gd" id="2_0g8r2"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_f6dt5"] +atlas = ExtResource("1_bglkk") +region = Rect2(960, 512, 64, 64) + +[resource] +script = ExtResource("2_0g8r2") +name = "Build" +image = SubResource("AtlasTexture_f6dt5") diff --git a/data/interactions/build/interaction_build.gd b/data/interactions/build/interaction_build.gd new file mode 100644 index 0000000..d814a19 --- /dev/null +++ b/data/interactions/build/interaction_build.gd @@ -0,0 +1,8 @@ +extends Interaction +class_name InteractionBuild + +const BUILD_ADVANCED = preload("res://data/interactions/build/advanced/build_advanced.tres") +const BUILD_BASIC = preload("res://data/interactions/build/basic/build_basic.tres") + +func interact_at(pos: Vector2i, root: Node) -> Array[Interaction]: + return [BUILD_BASIC, BUILD_ADVANCED] diff --git a/data/interactions/gather/gather.tres b/data/interactions/gather/gather.tres new file mode 100644 index 0000000..e83bf55 --- /dev/null +++ b/data/interactions/gather/gather.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="InteractionGather" load_steps=4 format=3 uid="uid://r4evto2nkehg"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_cquks"] +[ext_resource type="Script" path="res://data/interactions/gather/interaction_gather.gd" id="2_4amum"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_jjmaq"] +atlas = ExtResource("1_cquks") +region = Rect2(1024, 512, 64, 64) + +[resource] +script = ExtResource("2_4amum") +name = "Gather" +image = SubResource("AtlasTexture_jjmaq") diff --git a/data/interactions/gather/interaction_gather.gd b/data/interactions/gather/interaction_gather.gd new file mode 100644 index 0000000..66b7d80 --- /dev/null +++ b/data/interactions/gather/interaction_gather.gd @@ -0,0 +1,24 @@ +extends Interaction +class_name InteractionGather + +var interaction_display +var _pos + +func interact_at(pos: Vector2i, root: Node) -> Array[Interaction]: + _pos = pos + print("Gathering at: %s" % pos) + + interaction_display = ProgressBar.new() + interaction_display.position = Grid.grid_to_world_center(_pos) - Vector2(30, 10) + interaction_display.size = Vector2(60, 20) + interaction_display.show_percentage = false + var tween = root.create_tween() + tween.tween_property(interaction_display, "value", 100, 3) + tween.tween_callback(_cleanup_gather) + root.add_child(interaction_display) + return [] + +func _cleanup_gather() -> void: + interaction_display.queue_free() + var res: GameResource = Grid.get_location_data(_pos).get_resource() + res.gained_resource.emit(res) diff --git a/data/interactions/interaction.gd b/data/interactions/interaction.gd new file mode 100644 index 0000000..c1ec860 --- /dev/null +++ b/data/interactions/interaction.gd @@ -0,0 +1,8 @@ +extends Resource +class_name Interaction + +@export var name: String +@export var image: AtlasTexture + +func interact_at(pos: Vector2i, root: Node) -> Array[Interaction]: + return [] diff --git a/data/research/gem_research.tres b/data/research/gem_research.tres new file mode 100644 index 0000000..8ad60fb --- /dev/null +++ b/data/research/gem_research.tres @@ -0,0 +1,18 @@ +[gd_resource type="Resource" script_class="Research" load_steps=5 format=3 uid="uid://ddsmk1qmb2ohf"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_i07ie"] +[ext_resource type="Script" path="res://data/research/research.gd" id="1_swmp6"] +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="2_gc3ag"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_1i8g4"] +atlas = ExtResource("1_i07ie") +region = Rect2(320, 384, 64, 64) + +[resource] +script = ExtResource("1_swmp6") +atlas_texture = SubResource("AtlasTexture_1i8g4") +name = "Gems" +description = "Allows the gathering of Gems" +cost = { +ExtResource("2_gc3ag"): 10 +} diff --git a/data/research/research.gd b/data/research/research.gd new file mode 100644 index 0000000..3380227 --- /dev/null +++ b/data/research/research.gd @@ -0,0 +1,8 @@ +class_name Research +extends Resource + +@export var atlas_texture: AtlasTexture +@export var name: String +@export var description: String +@export var cost: Dictionary +@export var world_scene: PackedScene diff --git a/data/scifi_tileset.tres b/data/scifi_tileset.tres index 575130c..cee87b3 100644 --- a/data/scifi_tileset.tres +++ b/data/scifi_tileset.tres @@ -5,146 +5,404 @@ [sub_resource type="TileSetAtlasSource" id="TileSetAtlasSource_yq8ar"] resource_name = "scifi" texture = ExtResource("1_40wcs") -texture_region_size = Vector2i(128, 128) +texture_region_size = Vector2i(64, 64) 0:0/0 = 0 +0:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:0/0/physics_layer_0/angular_velocity = 0.0 1:0/next_alternative_id = 2 1:0/0 = 0 +1:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:0/0/physics_layer_0/angular_velocity = 0.0 2:0/0 = 0 +2:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:0/0/physics_layer_0/angular_velocity = 0.0 3:0/0 = 0 +3:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:0/0/physics_layer_0/angular_velocity = 0.0 4:0/0 = 0 +4:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:0/0/physics_layer_0/angular_velocity = 0.0 5:0/0 = 0 +5:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:0/0/physics_layer_0/angular_velocity = 0.0 6:0/0 = 0 +6:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:0/0/physics_layer_0/angular_velocity = 0.0 7:0/0 = 0 +7:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:0/0/physics_layer_0/angular_velocity = 0.0 8:0/0 = 0 +8:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:0/0/physics_layer_0/angular_velocity = 0.0 9:0/0 = 0 +9:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:0/0/physics_layer_0/angular_velocity = 0.0 10:0/0 = 0 +10:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:0/0/physics_layer_0/angular_velocity = 0.0 11:0/0 = 0 +11:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:0/0/physics_layer_0/angular_velocity = 0.0 12:0/0 = 0 +12:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:0/0/physics_layer_0/angular_velocity = 0.0 13:0/0 = 0 +13:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:0/0/physics_layer_0/angular_velocity = 0.0 14:0/0 = 0 +14:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:0/0/physics_layer_0/angular_velocity = 0.0 15:0/0 = 0 +15:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:0/0/physics_layer_0/angular_velocity = 0.0 16:0/0 = 0 +16:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:0/0/physics_layer_0/angular_velocity = 0.0 17:0/0 = 0 +17:0/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:0/0/physics_layer_0/angular_velocity = 0.0 0:1/0 = 0 +0:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:1/0/physics_layer_0/angular_velocity = 0.0 1:1/0 = 0 +1:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:1/0/physics_layer_0/angular_velocity = 0.0 2:1/0 = 0 +2:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:1/0/physics_layer_0/angular_velocity = 0.0 3:1/0 = 0 +3:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:1/0/physics_layer_0/angular_velocity = 0.0 4:1/0 = 0 +4:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:1/0/physics_layer_0/angular_velocity = 0.0 5:1/0 = 0 +5:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:1/0/physics_layer_0/angular_velocity = 0.0 6:1/0 = 0 +6:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:1/0/physics_layer_0/angular_velocity = 0.0 7:1/0 = 0 +7:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:1/0/physics_layer_0/angular_velocity = 0.0 8:1/0 = 0 +8:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:1/0/physics_layer_0/angular_velocity = 0.0 9:1/0 = 0 +9:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:1/0/physics_layer_0/angular_velocity = 0.0 10:1/0 = 0 +10:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:1/0/physics_layer_0/angular_velocity = 0.0 11:1/0 = 0 +11:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:1/0/physics_layer_0/angular_velocity = 0.0 12:1/0 = 0 +12:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:1/0/physics_layer_0/angular_velocity = 0.0 13:1/0 = 0 +13:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:1/0/physics_layer_0/angular_velocity = 0.0 14:1/0 = 0 +14:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:1/0/physics_layer_0/angular_velocity = 0.0 15:1/0 = 0 +15:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:1/0/physics_layer_0/angular_velocity = 0.0 16:1/0 = 0 +16:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:1/0/physics_layer_0/angular_velocity = 0.0 17:1/0 = 0 +17:1/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:1/0/physics_layer_0/angular_velocity = 0.0 0:2/0 = 0 +0:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:2/0/physics_layer_0/angular_velocity = 0.0 1:2/0 = 0 +1:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:2/0/physics_layer_0/angular_velocity = 0.0 2:2/0 = 0 +2:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:2/0/physics_layer_0/angular_velocity = 0.0 3:2/0 = 0 +3:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:2/0/physics_layer_0/angular_velocity = 0.0 4:2/0 = 0 +4:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:2/0/physics_layer_0/angular_velocity = 0.0 5:2/0 = 0 +5:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:2/0/physics_layer_0/angular_velocity = 0.0 6:2/0 = 0 +6:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:2/0/physics_layer_0/angular_velocity = 0.0 7:2/0 = 0 +7:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:2/0/physics_layer_0/angular_velocity = 0.0 8:2/0 = 0 +8:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:2/0/physics_layer_0/angular_velocity = 0.0 9:2/0 = 0 +9:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:2/0/physics_layer_0/angular_velocity = 0.0 10:2/0 = 0 +10:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:2/0/physics_layer_0/angular_velocity = 0.0 11:2/0 = 0 +11:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:2/0/physics_layer_0/angular_velocity = 0.0 12:2/0 = 0 +12:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:2/0/physics_layer_0/angular_velocity = 0.0 13:2/0 = 0 +13:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:2/0/physics_layer_0/angular_velocity = 0.0 14:2/0 = 0 +14:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:2/0/physics_layer_0/angular_velocity = 0.0 15:2/0 = 0 +15:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:2/0/physics_layer_0/angular_velocity = 0.0 16:2/0 = 0 +16:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:2/0/physics_layer_0/angular_velocity = 0.0 17:2/0 = 0 +17:2/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:2/0/physics_layer_0/angular_velocity = 0.0 0:3/0 = 0 +0:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:3/0/physics_layer_0/angular_velocity = 0.0 1:3/0 = 0 +1:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:3/0/physics_layer_0/angular_velocity = 0.0 2:3/0 = 0 +2:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:3/0/physics_layer_0/angular_velocity = 0.0 3:3/0 = 0 +3:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:3/0/physics_layer_0/angular_velocity = 0.0 4:3/0 = 0 +4:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:3/0/physics_layer_0/angular_velocity = 0.0 5:3/0 = 0 +5:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:3/0/physics_layer_0/angular_velocity = 0.0 +5:3/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16) 6:3/0 = 0 +6:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:3/0/physics_layer_0/angular_velocity = 0.0 7:3/0 = 0 +7:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:3/0/physics_layer_0/angular_velocity = 0.0 8:3/0 = 0 +8:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:3/0/physics_layer_0/angular_velocity = 0.0 9:3/0 = 0 +9:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:3/0/physics_layer_0/angular_velocity = 0.0 10:3/0 = 0 +10:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:3/0/physics_layer_0/angular_velocity = 0.0 11:3/0 = 0 +11:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:3/0/physics_layer_0/angular_velocity = 0.0 12:3/0 = 0 +12:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:3/0/physics_layer_0/angular_velocity = 0.0 13:3/0 = 0 +13:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:3/0/physics_layer_0/angular_velocity = 0.0 14:3/0 = 0 +14:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:3/0/physics_layer_0/angular_velocity = 0.0 15:3/0 = 0 +15:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:3/0/physics_layer_0/angular_velocity = 0.0 16:3/0 = 0 +16:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:3/0/physics_layer_0/angular_velocity = 0.0 17:3/0 = 0 +17:3/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:3/0/physics_layer_0/angular_velocity = 0.0 0:4/0 = 0 +0:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:4/0/physics_layer_0/angular_velocity = 0.0 1:4/0 = 0 +1:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:4/0/physics_layer_0/angular_velocity = 0.0 2:4/0 = 0 +2:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:4/0/physics_layer_0/angular_velocity = 0.0 3:4/0 = 0 +3:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:4/0/physics_layer_0/angular_velocity = 0.0 4:4/0 = 0 +4:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:4/0/physics_layer_0/angular_velocity = 0.0 5:4/0 = 0 +5:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:4/0/physics_layer_0/angular_velocity = 0.0 6:4/0 = 0 +6:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:4/0/physics_layer_0/angular_velocity = 0.0 7:4/0 = 0 +7:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:4/0/physics_layer_0/angular_velocity = 0.0 8:4/0 = 0 +8:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:4/0/physics_layer_0/angular_velocity = 0.0 9:4/0 = 0 +9:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:4/0/physics_layer_0/angular_velocity = 0.0 10:4/0 = 0 +10:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:4/0/physics_layer_0/angular_velocity = 0.0 11:4/0 = 0 +11:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:4/0/physics_layer_0/angular_velocity = 0.0 12:4/0 = 0 +12:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:4/0/physics_layer_0/angular_velocity = 0.0 13:4/0 = 0 +13:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:4/0/physics_layer_0/angular_velocity = 0.0 14:4/0 = 0 +14:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:4/0/physics_layer_0/angular_velocity = 0.0 15:4/0 = 0 +15:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:4/0/physics_layer_0/angular_velocity = 0.0 16:4/0 = 0 +16:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:4/0/physics_layer_0/angular_velocity = 0.0 17:4/0 = 0 +17:4/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:4/0/physics_layer_0/angular_velocity = 0.0 0:5/0 = 0 +0:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:5/0/physics_layer_0/angular_velocity = 0.0 1:5/0 = 0 +1:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:5/0/physics_layer_0/angular_velocity = 0.0 2:5/0 = 0 +2:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:5/0/physics_layer_0/angular_velocity = 0.0 3:5/0 = 0 +3:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:5/0/physics_layer_0/angular_velocity = 0.0 4:5/0 = 0 +4:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:5/0/physics_layer_0/angular_velocity = 0.0 5:5/0 = 0 +5:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:5/0/physics_layer_0/angular_velocity = 0.0 6:5/0 = 0 +6:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:5/0/physics_layer_0/angular_velocity = 0.0 7:5/0 = 0 +7:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:5/0/physics_layer_0/angular_velocity = 0.0 8:5/0 = 0 +8:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:5/0/physics_layer_0/angular_velocity = 0.0 9:5/0 = 0 +9:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:5/0/physics_layer_0/angular_velocity = 0.0 10:5/0 = 0 +10:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:5/0/physics_layer_0/angular_velocity = 0.0 11:5/0 = 0 +11:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:5/0/physics_layer_0/angular_velocity = 0.0 12:5/0 = 0 +12:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:5/0/physics_layer_0/angular_velocity = 0.0 13:5/0 = 0 +13:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:5/0/physics_layer_0/angular_velocity = 0.0 14:5/0 = 0 +14:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:5/0/physics_layer_0/angular_velocity = 0.0 15:5/0 = 0 +15:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:5/0/physics_layer_0/angular_velocity = 0.0 16:5/0 = 0 +16:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:5/0/physics_layer_0/angular_velocity = 0.0 17:5/0 = 0 +17:5/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:5/0/physics_layer_0/angular_velocity = 0.0 0:6/0 = 0 +0:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:6/0/physics_layer_0/angular_velocity = 0.0 1:6/0 = 0 +1:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:6/0/physics_layer_0/angular_velocity = 0.0 2:6/0 = 0 +2:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:6/0/physics_layer_0/angular_velocity = 0.0 3:6/0 = 0 +3:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:6/0/physics_layer_0/angular_velocity = 0.0 4:6/0 = 0 +4:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:6/0/physics_layer_0/angular_velocity = 0.0 5:6/0 = 0 +5:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:6/0/physics_layer_0/angular_velocity = 0.0 +5:6/0/physics_layer_0/polygon_0/points = PackedVector2Array(-16, -16, 16, -16, 16, 16, -16, 16) 6:6/0 = 0 +6:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:6/0/physics_layer_0/angular_velocity = 0.0 7:6/0 = 0 +7:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:6/0/physics_layer_0/angular_velocity = 0.0 10:6/0 = 0 +10:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:6/0/physics_layer_0/angular_velocity = 0.0 11:6/0 = 0 +11:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:6/0/physics_layer_0/angular_velocity = 0.0 12:6/0 = 0 +12:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:6/0/physics_layer_0/angular_velocity = 0.0 13:6/0 = 0 +13:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:6/0/physics_layer_0/angular_velocity = 0.0 14:6/0 = 0 +14:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:6/0/physics_layer_0/angular_velocity = 0.0 15:6/0 = 0 +15:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:6/0/physics_layer_0/angular_velocity = 0.0 16:6/0 = 0 +16:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:6/0/physics_layer_0/angular_velocity = 0.0 17:6/0 = 0 +17:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:6/0/physics_layer_0/angular_velocity = 0.0 0:7/0 = 0 +0:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:7/0/physics_layer_0/angular_velocity = 0.0 4:7/0 = 0 4:7/0/terrain_set = 0 4:7/0/terrain = 0 +4:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:7/0/physics_layer_0/angular_velocity = 0.0 4:7/0/terrains_peering_bit/bottom_side = 0 5:7/0 = 0 5:7/0/terrain_set = 0 5:7/0/terrain = 0 +5:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:7/0/physics_layer_0/angular_velocity = 0.0 5:7/0/terrains_peering_bit/right_side = 0 5:7/0/terrains_peering_bit/bottom_right_corner = 0 5:7/0/terrains_peering_bit/bottom_side = 0 6:7/0 = 0 6:7/0/terrain_set = 0 6:7/0/terrain = 0 +6:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:7/0/physics_layer_0/angular_velocity = 0.0 6:7/0/terrains_peering_bit/right_side = 0 6:7/0/terrains_peering_bit/bottom_right_corner = 0 6:7/0/terrains_peering_bit/bottom_side = 0 @@ -153,12 +411,16 @@ texture_region_size = Vector2i(128, 128) 7:7/0 = 0 7:7/0/terrain_set = 0 7:7/0/terrain = 0 +7:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:7/0/physics_layer_0/angular_velocity = 0.0 7:7/0/terrains_peering_bit/bottom_side = 0 7:7/0/terrains_peering_bit/bottom_left_corner = 0 7:7/0/terrains_peering_bit/left_side = 0 9:7/0 = 0 9:7/0/terrain_set = 0 9:7/0/terrain = 0 +9:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:7/0/physics_layer_0/angular_velocity = 0.0 9:7/0/terrains_peering_bit/right_side = 0 9:7/0/terrains_peering_bit/bottom_side = 0 9:7/0/terrains_peering_bit/left_side = 0 @@ -168,6 +430,8 @@ texture_region_size = Vector2i(128, 128) 10:7/0 = 0 10:7/0/terrain_set = 0 10:7/0/terrain = 0 +10:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:7/0/physics_layer_0/angular_velocity = 0.0 10:7/0/terrains_peering_bit/right_side = 0 10:7/0/terrains_peering_bit/bottom_right_corner = 0 10:7/0/terrains_peering_bit/bottom_side = 0 @@ -176,24 +440,72 @@ texture_region_size = Vector2i(128, 128) 10:7/0/terrains_peering_bit/top_side = 0 10:7/0/terrains_peering_bit/top_right_corner = 0 11:7/0 = 0 +11:7/0/terrain_set = 0 +11:7/0/terrain = 0 +11:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:7/0/physics_layer_0/angular_velocity = 0.0 +11:7/0/terrains_peering_bit/right_side = 0 +11:7/0/terrains_peering_bit/left_side = 0 +11:7/0/terrains_peering_bit/top_left_corner = 0 +11:7/0/terrains_peering_bit/top_side = 0 12:7/0 = 0 +12:7/0/terrain_set = 0 +12:7/0/terrain = 0 +12:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:7/0/physics_layer_0/angular_velocity = 0.0 +12:7/0/terrains_peering_bit/right_side = 0 +12:7/0/terrains_peering_bit/left_side = 0 +12:7/0/terrains_peering_bit/top_side = 0 +12:7/0/terrains_peering_bit/top_right_corner = 0 13:7/0 = 0 +13:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:7/0/physics_layer_0/angular_velocity = 0.0 14:7/0 = 0 +14:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:7/0/physics_layer_0/angular_velocity = 0.0 15:7/0 = 0 +15:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:7/0/physics_layer_0/angular_velocity = 0.0 16:7/0 = 0 +16:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:7/0/physics_layer_0/angular_velocity = 0.0 17:7/0 = 0 +17:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:7/0/physics_layer_0/angular_velocity = 0.0 0:8/0 = 0 +0:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:8/0/physics_layer_0/angular_velocity = 0.0 1:8/0 = 0 +1:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:8/0/physics_layer_0/angular_velocity = 0.0 2:8/0 = 0 +2:8/0/terrain_set = 0 +2:8/0/terrain = 0 +2:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:8/0/physics_layer_0/angular_velocity = 0.0 +2:8/0/terrains_peering_bit/right_side = 0 +2:8/0/terrains_peering_bit/bottom_side = 0 +2:8/0/terrains_peering_bit/top_side = 0 3:8/0 = 0 +3:8/0/terrain_set = 0 +3:8/0/terrain = 0 +3:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:8/0/physics_layer_0/angular_velocity = 0.0 +3:8/0/terrains_peering_bit/bottom_side = 0 +3:8/0/terrains_peering_bit/left_side = 0 +3:8/0/terrains_peering_bit/top_side = 0 4:8/0 = 0 4:8/0/terrain_set = 0 4:8/0/terrain = 0 +4:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:8/0/physics_layer_0/angular_velocity = 0.0 4:8/0/terrains_peering_bit/bottom_side = 0 4:8/0/terrains_peering_bit/top_side = 0 5:8/0 = 0 5:8/0/terrain_set = 0 5:8/0/terrain = 0 +5:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:8/0/physics_layer_0/angular_velocity = 0.0 5:8/0/terrains_peering_bit/right_side = 0 5:8/0/terrains_peering_bit/bottom_right_corner = 0 5:8/0/terrains_peering_bit/bottom_side = 0 @@ -202,6 +514,8 @@ texture_region_size = Vector2i(128, 128) 6:8/0 = 0 6:8/0/terrain_set = 0 6:8/0/terrain = 0 +6:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:8/0/physics_layer_0/angular_velocity = 0.0 6:8/0/terrains_peering_bit/right_side = 0 6:8/0/terrains_peering_bit/bottom_right_corner = 0 6:8/0/terrains_peering_bit/bottom_side = 0 @@ -213,6 +527,8 @@ texture_region_size = Vector2i(128, 128) 7:8/0 = 0 7:8/0/terrain_set = 0 7:8/0/terrain = 0 +7:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:8/0/physics_layer_0/angular_velocity = 0.0 7:8/0/terrains_peering_bit/bottom_side = 0 7:8/0/terrains_peering_bit/bottom_left_corner = 0 7:8/0/terrains_peering_bit/left_side = 0 @@ -221,6 +537,8 @@ texture_region_size = Vector2i(128, 128) 8:8/0 = 0 8:8/0/terrain_set = 0 8:8/0/terrain = 0 +8:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:8/0/physics_layer_0/angular_velocity = 0.0 8:8/0/terrains_peering_bit/right_side = 0 8:8/0/terrains_peering_bit/bottom_side = 0 8:8/0/terrains_peering_bit/bottom_left_corner = 0 @@ -230,6 +548,8 @@ texture_region_size = Vector2i(128, 128) 9:8/0 = 0 9:8/0/terrain_set = 0 9:8/0/terrain = 0 +9:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:8/0/physics_layer_0/angular_velocity = 0.0 9:8/0/terrains_peering_bit/right_side = 0 9:8/0/terrains_peering_bit/bottom_side = 0 9:8/0/terrains_peering_bit/left_side = 0 @@ -237,6 +557,8 @@ texture_region_size = Vector2i(128, 128) 10:8/0 = 0 10:8/0/terrain_set = 0 10:8/0/terrain = 0 +10:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:8/0/physics_layer_0/angular_velocity = 0.0 10:8/0/terrains_peering_bit/right_side = 0 10:8/0/terrains_peering_bit/bottom_right_corner = 0 10:8/0/terrains_peering_bit/bottom_side = 0 @@ -244,29 +566,79 @@ texture_region_size = Vector2i(128, 128) 10:8/0/terrains_peering_bit/top_side = 0 10:8/0/terrains_peering_bit/top_right_corner = 0 11:8/0 = 0 +11:8/0/terrain_set = 0 +11:8/0/terrain = 0 +11:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:8/0/physics_layer_0/angular_velocity = 0.0 +11:8/0/terrains_peering_bit/bottom_side = 0 +11:8/0/terrains_peering_bit/left_side = 0 +11:8/0/terrains_peering_bit/top_left_corner = 0 +11:8/0/terrains_peering_bit/top_side = 0 12:8/0 = 0 +12:8/0/terrain_set = 0 +12:8/0/terrain = 0 +12:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:8/0/physics_layer_0/angular_velocity = 0.0 +12:8/0/terrains_peering_bit/bottom_side = 0 +12:8/0/terrains_peering_bit/bottom_left_corner = 0 +12:8/0/terrains_peering_bit/left_side = 0 +12:8/0/terrains_peering_bit/top_side = 0 13:8/0 = 0 +13:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:8/0/physics_layer_0/angular_velocity = 0.0 14:8/0 = 0 +14:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:8/0/physics_layer_0/angular_velocity = 0.0 15:8/0 = 0 +15:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:8/0/physics_layer_0/angular_velocity = 0.0 16:8/0 = 0 +16:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:8/0/physics_layer_0/angular_velocity = 0.0 17:8/0 = 0 +17:8/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:8/0/physics_layer_0/angular_velocity = 0.0 0:9/0 = 0 +0:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:9/0/physics_layer_0/angular_velocity = 0.0 1:9/0 = 0 +1:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:9/0/physics_layer_0/angular_velocity = 0.0 2:9/0 = 0 +2:9/0/terrain_set = 0 +2:9/0/terrain = 0 +2:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:9/0/physics_layer_0/angular_velocity = 0.0 +2:9/0/terrains_peering_bit/right_side = 0 +2:9/0/terrains_peering_bit/left_side = 0 +2:9/0/terrains_peering_bit/top_side = 0 3:9/0 = 0 +3:9/0/terrain_set = 0 +3:9/0/terrain = 0 +3:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:9/0/physics_layer_0/angular_velocity = 0.0 +3:9/0/terrains_peering_bit/right_side = 0 +3:9/0/terrains_peering_bit/bottom_side = 0 +3:9/0/terrains_peering_bit/left_side = 0 4:9/0 = 0 4:9/0/terrain_set = 0 4:9/0/terrain = 0 +4:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:9/0/physics_layer_0/angular_velocity = 0.0 4:9/0/terrains_peering_bit/top_side = 0 5:9/0 = 0 5:9/0/terrain_set = 0 5:9/0/terrain = 0 +5:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:9/0/physics_layer_0/angular_velocity = 0.0 5:9/0/terrains_peering_bit/right_side = 0 5:9/0/terrains_peering_bit/top_side = 0 5:9/0/terrains_peering_bit/top_right_corner = 0 6:9/0 = 0 6:9/0/terrain_set = 0 6:9/0/terrain = 0 +6:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:9/0/physics_layer_0/angular_velocity = 0.0 6:9/0/terrains_peering_bit/right_side = 0 6:9/0/terrains_peering_bit/left_side = 0 6:9/0/terrains_peering_bit/top_left_corner = 0 @@ -275,12 +647,16 @@ texture_region_size = Vector2i(128, 128) 7:9/0 = 0 7:9/0/terrain_set = 0 7:9/0/terrain = 0 +7:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:9/0/physics_layer_0/angular_velocity = 0.0 7:9/0/terrains_peering_bit/left_side = 0 7:9/0/terrains_peering_bit/top_left_corner = 0 7:9/0/terrains_peering_bit/top_side = 0 8:9/0 = 0 8:9/0/terrain_set = 0 8:9/0/terrain = 0 +8:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:9/0/physics_layer_0/angular_velocity = 0.0 8:9/0/terrains_peering_bit/right_side = 0 8:9/0/terrains_peering_bit/bottom_right_corner = 0 8:9/0/terrains_peering_bit/bottom_side = 0 @@ -291,6 +667,8 @@ texture_region_size = Vector2i(128, 128) 9:9/0 = 0 9:9/0/terrain_set = 0 9:9/0/terrain = 0 +9:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:9/0/physics_layer_0/angular_velocity = 0.0 9:9/0/terrains_peering_bit/right_side = 0 9:9/0/terrains_peering_bit/bottom_right_corner = 0 9:9/0/terrains_peering_bit/bottom_side = 0 @@ -300,6 +678,8 @@ texture_region_size = Vector2i(128, 128) 10:9/0 = 0 10:9/0/terrain_set = 0 10:9/0/terrain = 0 +10:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:9/0/physics_layer_0/angular_velocity = 0.0 10:9/0/terrains_peering_bit/right_side = 0 10:9/0/terrains_peering_bit/bottom_right_corner = 0 10:9/0/terrains_peering_bit/bottom_side = 0 @@ -308,50 +688,136 @@ texture_region_size = Vector2i(128, 128) 10:9/0/terrains_peering_bit/top_side = 0 10:9/0/terrains_peering_bit/top_right_corner = 0 11:9/0 = 0 +11:9/0/terrain_set = 0 +11:9/0/terrain = 0 +11:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:9/0/physics_layer_0/angular_velocity = 0.0 +11:9/0/terrains_peering_bit/right_side = 0 +11:9/0/terrains_peering_bit/bottom_right_corner = 0 +11:9/0/terrains_peering_bit/bottom_side = 0 +11:9/0/terrains_peering_bit/top_side = 0 12:9/0 = 0 +12:9/0/terrain_set = 0 +12:9/0/terrain = 0 +12:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:9/0/physics_layer_0/angular_velocity = 0.0 +12:9/0/terrains_peering_bit/right_side = 0 +12:9/0/terrains_peering_bit/bottom_side = 0 +12:9/0/terrains_peering_bit/top_side = 0 +12:9/0/terrains_peering_bit/top_right_corner = 0 13:9/0 = 0 +13:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:9/0/physics_layer_0/angular_velocity = 0.0 14:9/0 = 0 +14:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:9/0/physics_layer_0/angular_velocity = 0.0 15:9/0 = 0 +15:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:9/0/physics_layer_0/angular_velocity = 0.0 16:9/0 = 0 +16:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:9/0/physics_layer_0/angular_velocity = 0.0 17:9/0 = 0 +17:9/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:9/0/physics_layer_0/angular_velocity = 0.0 0:10/0 = 0 +0:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +0:10/0/physics_layer_0/angular_velocity = 0.0 1:10/0 = 0 +1:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:10/0/physics_layer_0/angular_velocity = 0.0 2:10/0 = 0 +2:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:10/0/physics_layer_0/angular_velocity = 0.0 3:10/0 = 0 +3:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:10/0/physics_layer_0/angular_velocity = 0.0 4:10/0 = 0 4:10/0/terrain_set = 0 4:10/0/terrain = 0 +4:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +4:10/0/physics_layer_0/angular_velocity = 0.0 5:10/0 = 0 5:10/0/terrain_set = 0 5:10/0/terrain = 0 +5:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +5:10/0/physics_layer_0/angular_velocity = 0.0 5:10/0/terrains_peering_bit/right_side = 0 6:10/0 = 0 6:10/0/terrain_set = 0 6:10/0/terrain = 0 +6:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +6:10/0/physics_layer_0/angular_velocity = 0.0 6:10/0/terrains_peering_bit/right_side = 0 6:10/0/terrains_peering_bit/left_side = 0 7:10/0 = 0 7:10/0/terrain_set = 0 7:10/0/terrain = 0 +7:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +7:10/0/physics_layer_0/angular_velocity = 0.0 7:10/0/terrains_peering_bit/left_side = 0 8:10/0 = 0 +8:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:10/0/physics_layer_0/angular_velocity = 0.0 9:10/0 = 0 +9:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:10/0/physics_layer_0/angular_velocity = 0.0 10:10/0 = 0 +10:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +10:10/0/physics_layer_0/angular_velocity = 0.0 11:10/0 = 0 +11:10/0/terrain_set = 0 +11:10/0/terrain = 0 +11:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +11:10/0/physics_layer_0/angular_velocity = 0.0 +11:10/0/terrains_peering_bit/right_side = 0 +11:10/0/terrains_peering_bit/bottom_side = 0 +11:10/0/terrains_peering_bit/bottom_left_corner = 0 +11:10/0/terrains_peering_bit/left_side = 0 12:10/0 = 0 +12:10/0/terrain_set = 0 +12:10/0/terrain = 0 +12:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +12:10/0/physics_layer_0/angular_velocity = 0.0 +12:10/0/terrains_peering_bit/right_side = 0 +12:10/0/terrains_peering_bit/bottom_right_corner = 0 +12:10/0/terrains_peering_bit/bottom_side = 0 +12:10/0/terrains_peering_bit/left_side = 0 13:10/0 = 0 +13:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +13:10/0/physics_layer_0/angular_velocity = 0.0 14:10/0 = 0 +14:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +14:10/0/physics_layer_0/angular_velocity = 0.0 15:10/0 = 0 +15:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +15:10/0/physics_layer_0/angular_velocity = 0.0 16:10/0 = 0 +16:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +16:10/0/physics_layer_0/angular_velocity = 0.0 17:10/0 = 0 +17:10/0/physics_layer_0/linear_velocity = Vector2(0, 0) +17:10/0/physics_layer_0/angular_velocity = 0.0 8:6/0 = 0 +8:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:6/0/physics_layer_0/angular_velocity = 0.0 9:6/0 = 0 +9:6/0/physics_layer_0/linear_velocity = Vector2(0, 0) +9:6/0/physics_layer_0/angular_velocity = 0.0 1:7/0 = 0 +1:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +1:7/0/physics_layer_0/angular_velocity = 0.0 2:7/0 = 0 +2:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +2:7/0/physics_layer_0/angular_velocity = 0.0 3:7/0 = 0 +3:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +3:7/0/physics_layer_0/angular_velocity = 0.0 8:7/0 = 0 8:7/0/terrain_set = 0 8:7/0/terrain = 0 +8:7/0/physics_layer_0/linear_velocity = Vector2(0, 0) +8:7/0/physics_layer_0/angular_velocity = 0.0 8:7/0/terrains_peering_bit/right_side = 0 8:7/0/terrains_peering_bit/bottom_side = 0 8:7/0/terrains_peering_bit/bottom_left_corner = 0 @@ -361,7 +827,9 @@ texture_region_size = Vector2i(128, 128) 8:7/0/terrains_peering_bit/top_right_corner = 0 [resource] -tile_size = Vector2i(128, 128) +tile_size = Vector2i(64, 64) +physics_layer_0/collision_layer = 1 +physics_layer_0/collision_mask = 0 terrain_set_0/mode = 0 terrain_set_0/terrain_0/name = "corruption" terrain_set_0/terrain_0/color = Color(0.368627, 0.411765, 0.129412, 1) diff --git a/data/world_theme.tres b/data/world_theme.tres new file mode 100644 index 0000000..1b3e993 --- /dev/null +++ b/data/world_theme.tres @@ -0,0 +1,6 @@ +[gd_resource type="Theme" load_steps=2 format=3 uid="uid://dcpugcgqnnf17"] + +[ext_resource type="FontFile" uid="uid://cuhtrlqg4s5tw" path="res://assets/SpaceMono-Regular.ttf" id="1_suqxc"] + +[resource] +Label/fonts/font = ExtResource("1_suqxc") diff --git a/project.godot b/project.godot index c96f054..9a066b3 100644 --- a/project.godot +++ b/project.godot @@ -10,7 +10,124 @@ config_version=5 [application] -config/name="Corupture" +config/name="Corrupture" run/main_scene="res://scene/world.tscn" config/features=PackedStringArray("4.2", "Forward Plus") config/icon="res://icon.svg" + +[autoload] + +Grid="*res://scripts/autoloads/grid.gd" +ResourceManager="*res://scripts/autoloads/resource_manager.gd" +BuildingManager="*res://scripts/autoloads/building_manager.gd" + +[debug] + +gdscript/warnings/untyped_declaration=1 + +[editor_plugins] + +enabled=PackedStringArray("res://addons/gdLinter/plugin.cfg") + +[gui] + +theme/custom="res://data/world_theme.tres" + +[input] + +ui_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194319,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) +] +} +ui_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194321,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":0,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) +] +} +ui_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194320,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":11,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":-1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) +] +} +ui_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":4194322,"physical_keycode":0,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":0,"axis":1,"axis_value":1.0,"script":null) +, Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) +] +} +view_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194321,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":1.0,"script":null) +] +} +view_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194319,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":2,"axis_value":-1.0,"script":null) +] +} +view_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194320,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":-1.0,"script":null) +] +} +view_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":4194322,"key_label":0,"unicode":0,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":3,"axis_value":1.0,"script":null) +] +} +move_left={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":65,"key_label":0,"unicode":97,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":-1.0,"script":null) +] +} +move_right={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":68,"key_label":0,"unicode":100,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":0,"axis_value":1.0,"script":null) +] +} +move_up={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":87,"key_label":0,"unicode":119,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":-1.0,"script":null) +] +} +move_down={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":83,"key_label":0,"unicode":115,"echo":false,"script":null) +, Object(InputEventJoypadMotion,"resource_local_to_scene":false,"resource_name":"","device":-1,"axis":1,"axis_value":1.0,"script":null) +] +} +interact={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":69,"key_label":0,"unicode":101,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":0,"pressure":0.0,"pressed":false,"script":null) +] +} +build={ +"deadzone": 0.5, +"events": [Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":-1,"window_id":0,"alt_pressed":false,"shift_pressed":false,"ctrl_pressed":false,"meta_pressed":false,"pressed":false,"keycode":0,"physical_keycode":66,"key_label":0,"unicode":98,"echo":false,"script":null) +, Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":-1,"button_index":3,"pressure":0.0,"pressed":false,"script":null) +] +} + +[rendering] + +textures/canvas_textures/default_texture_filter=0 diff --git a/scene/base.tscn b/scene/base.tscn index 0ddcd33..7234672 100644 --- a/scene/base.tscn +++ b/scene/base.tscn @@ -1,9 +1,9 @@ [gd_scene load_steps=2 format=3 uid="uid://bbsaqy4xm1ldf"] -[ext_resource type="Script" path="res://scripts/Base.gd" id="1_0nxag"] +[ext_resource type="Script" path="res://scripts/base.gd" id="1_5hpho"] [node name="Base" type="Node2D"] -script = ExtResource("1_0nxag") +script = ExtResource("1_5hpho") [node name="ExpandTimer" type="Timer" parent="."] autostart = true diff --git a/scene/build_menu.tscn b/scene/build_menu.tscn new file mode 100644 index 0000000..98b14c2 --- /dev/null +++ b/scene/build_menu.tscn @@ -0,0 +1,90 @@ +[gd_scene load_steps=3 format=3 uid="uid://cym5p3olst2nc"] + +[ext_resource type="Script" path="res://scripts/build_menu.gd" id="1_v2c78"] + +[sub_resource type="Theme" id="Theme_0djom"] + +[node name="BuildMenu" type="CanvasLayer"] +script = ExtResource("1_v2c78") + +[node name="MarginContainer" type="MarginContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 128 +theme_override_constants/margin_top = 128 +theme_override_constants/margin_right = 128 +theme_override_constants/margin_bottom = 128 + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"] +layout_mode = 2 +theme = SubResource("Theme_0djom") + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="BuildingGroups" type="ItemList" parent="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +allow_search = false +auto_height = true + +[node name="ScrollContainer2" type="ScrollContainer" parent="MarginContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer2"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Buildings" type="ItemList" parent="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer2/VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 +auto_height = true + +[node name="DetailsContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 3.0 + +[node name="Title" type="Label" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +layout_mode = 2 +text = "Select a building" +horizontal_alignment = 1 + +[node name="HSeparator" type="HSeparator" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +layout_mode = 2 + +[node name="Description" type="Label" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +visible = false +layout_mode = 2 +text = " " + +[node name="BuildMaterials" type="GridContainer" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +visible = false +layout_mode = 2 +columns = 2 + +[node name="BuildButtonsContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +visible = false +layout_mode = 2 +alignment = 1 + +[node name="BuildButton" type="Button" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/BuildButtonsContainer"] +layout_mode = 2 +text = "Build +" + +[connection signal="item_selected" from="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer/VBoxContainer/BuildingGroups" to="." method="_on_building_groups_item_selected"] +[connection signal="item_selected" from="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer2/VBoxContainer/Buildings" to="." method="_on_buildings_item_selected"] +[connection signal="pressed" from="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/BuildButtonsContainer/BuildButton" to="." method="_on_build_button_pressed"] diff --git a/scene/interaction_bar.tscn b/scene/interaction_bar.tscn new file mode 100644 index 0000000..c00926f --- /dev/null +++ b/scene/interaction_bar.tscn @@ -0,0 +1,9 @@ +[gd_scene load_steps=2 format=3 uid="uid://dfr3hvxqo4fqf"] + +[ext_resource type="Script" path="res://scripts/interaction_bar.gd" id="1_qwnlc"] + +[node name="InteractionBar" type="ProgressBar"] +offset_right = 60.0 +offset_bottom = 20.0 +show_percentage = false +script = ExtResource("1_qwnlc") diff --git a/scene/interaction_wheel.tscn b/scene/interaction_wheel.tscn new file mode 100644 index 0000000..2d26b23 --- /dev/null +++ b/scene/interaction_wheel.tscn @@ -0,0 +1,96 @@ +[gd_scene load_steps=6 format=3 uid="uid://bq0jhdgh104y6"] + +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_1ljdt"] +[ext_resource type="Script" path="res://scripts/interaction_wheel.gd" id="1_gdnx3"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_7xl34"] +atlas = ExtResource("1_1ljdt") +region = Rect2(832, 512, 128, 128) + +[sub_resource type="AtlasTexture" id="AtlasTexture_gdnoe"] +atlas = ExtResource("1_1ljdt") +region = Rect2(1024, 512, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ci5w3"] +atlas = ExtResource("1_1ljdt") +region = Rect2(960, 576, 64, 64) + +[node name="InteractionWheel" type="Node2D"] +script = ExtResource("1_gdnx3") + +[node name="Wheel" type="Sprite2D" parent="."] +texture = SubResource("AtlasTexture_7xl34") + +[node name="Interactions" type="Node2D" parent="."] + +[node name="SpriteNorth" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(0, -96) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteNorthEast" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(68, -68) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteEast" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(96, 0) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteSouthEast" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(68, 68) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteSouth" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(0, 96) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteSouthWest" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(-68, 68) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteWest" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(-96, 0) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="SpriteNorthWest" type="Sprite2D" parent="Interactions"] +visible = false +position = Vector2(-68, -68) +texture = SubResource("AtlasTexture_gdnoe") + +[node name="Cursor" type="Sprite2D" parent="."] +texture = SubResource("AtlasTexture_ci5w3") +centered = false +offset = Vector2(0, -32) + +[node name="InformationPanel" type="Panel" parent="."] +visible = false +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -20.0 +offset_top = -20.0 +offset_right = 20.0 +offset_bottom = 20.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="InteractionLabel" type="Label" parent="InformationPanel"] +layout_mode = 1 +anchors_preset = 5 +anchor_left = 0.5 +anchor_right = 0.5 +offset_left = -20.0 +offset_right = 20.0 +offset_bottom = 24.0 +grow_horizontal = 2 +theme_override_font_sizes/font_size = 8 +text = "Build" +horizontal_alignment = 1 diff --git a/scene/player.tscn b/scene/player.tscn new file mode 100644 index 0000000..4a9c530 --- /dev/null +++ b/scene/player.tscn @@ -0,0 +1,97 @@ +[gd_scene load_steps=12 format=3 uid="uid://dkvcye4mhvshd"] + +[ext_resource type="Script" path="res://scripts/player.gd" id="1_j0htm"] +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="1_vqdy1"] + +[sub_resource type="AtlasTexture" id="AtlasTexture_rbmjr"] +atlas = ExtResource("1_vqdy1") +region = Rect2(832, 640, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_xx5oc"] +atlas = ExtResource("1_vqdy1") +region = Rect2(832, 640, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2ckq3"] +atlas = ExtResource("1_vqdy1") +region = Rect2(896, 704, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_vet2c"] +atlas = ExtResource("1_vqdy1") +region = Rect2(960, 704, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_fqxfq"] +atlas = ExtResource("1_vqdy1") +region = Rect2(832, 640, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_03ery"] +atlas = ExtResource("1_vqdy1") +region = Rect2(896, 640, 64, 64) + +[sub_resource type="AtlasTexture" id="AtlasTexture_ix8o6"] +atlas = ExtResource("1_vqdy1") +region = Rect2(960, 640, 64, 64) + +[sub_resource type="SpriteFrames" id="SpriteFrames_tj1nq"] +animations = [{ +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_rbmjr") +}], +"loop": true, +"name": &"default", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_xx5oc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_2ckq3") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_xx5oc") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_vet2c") +}], +"loop": true, +"name": &"interact", +"speed": 5.0 +}, { +"frames": [{ +"duration": 1.0, +"texture": SubResource("AtlasTexture_fqxfq") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_03ery") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_fqxfq") +}, { +"duration": 1.0, +"texture": SubResource("AtlasTexture_ix8o6") +}], +"loop": true, +"name": &"walk", +"speed": 5.0 +}] + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_jav3v"] +size = Vector2(40, 45) + +[node name="Player" type="CharacterBody2D"] +motion_mode = 1 +script = ExtResource("1_j0htm") + +[node name="Sprite" type="AnimatedSprite2D" parent="."] +sprite_frames = SubResource("SpriteFrames_tj1nq") +frame_progress = 0.850199 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("RectangleShape2D_jav3v") + +[node name="Camera2D" type="Camera2D" parent="."] + +[node name="InteractionTimer" type="Timer" parent="."] +process_callback = 0 +one_shot = true diff --git a/scene/research_menu.tscn b/scene/research_menu.tscn new file mode 100644 index 0000000..2f6215c --- /dev/null +++ b/scene/research_menu.tscn @@ -0,0 +1,80 @@ +[gd_scene load_steps=3 format=3 uid="uid://be35i6l6srg64"] + +[ext_resource type="Script" path="res://scripts/research_menu.gd" id="1_k3x02"] + +[sub_resource type="Theme" id="Theme_0djom"] + +[node name="ResearchMenu" type="CanvasLayer"] +script = ExtResource("1_k3x02") + +[node name="MarginContainer" type="MarginContainer" parent="."] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +theme_override_constants/margin_left = 128 +theme_override_constants/margin_top = 128 +theme_override_constants/margin_right = 128 +theme_override_constants/margin_bottom = 128 + +[node name="PanelContainer" type="PanelContainer" parent="MarginContainer"] +layout_mode = 2 +theme = SubResource("Theme_0djom") + +[node name="HBoxContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer"] +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="MarginContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="ResearchItems" type="ItemList" parent="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer/VBoxContainer"] +unique_name_in_owner = true +layout_mode = 2 +size_flags_vertical = 3 +allow_search = false +auto_height = true + +[node name="DetailsContainer" type="VBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 3.0 + +[node name="Title" type="Label" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +unique_name_in_owner = true +layout_mode = 2 +text = "Select research" +horizontal_alignment = 1 + +[node name="HSeparator" type="HSeparator" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +layout_mode = 2 + +[node name="Description" type="Label" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +text = " " + +[node name="ResearchMaterials" type="GridContainer" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +columns = 2 + +[node name="ResearchButtonsContainer" type="HBoxContainer" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer"] +unique_name_in_owner = true +visible = false +layout_mode = 2 +alignment = 1 + +[node name="StartResearchButton" type="Button" parent="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/ResearchButtonsContainer"] +layout_mode = 2 +text = "Start Research" + +[connection signal="item_selected" from="MarginContainer/PanelContainer/HBoxContainer/ScrollContainer/VBoxContainer/ResearchItems" to="." method="_on_research_selected"] +[connection signal="pressed" from="MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/ResearchButtonsContainer/StartResearchButton" to="." method="_on_build_button_pressed"] diff --git a/scene/world.tscn b/scene/world.tscn index 36d55d0..73489d3 100644 --- a/scene/world.tscn +++ b/scene/world.tscn @@ -1,35 +1,136 @@ -[gd_scene load_steps=7 format=3 uid="uid://m0us5xqa3gnk"] +[gd_scene load_steps=10 format=3 uid="uid://m0us5xqa3gnk"] [ext_resource type="Script" path="res://scripts/world.gd" id="1_yf6q1"] +[ext_resource type="Resource" uid="uid://dr00rd4f42jqe" path="res://data/game_resources/gem/gem_resource.tres" id="2_rn4a2"] [ext_resource type="TileSet" uid="uid://d1sh6dy2w10b0" path="res://data/scifi_tileset.tres" id="2_sa7dm"] -[ext_resource type="Script" path="res://scripts/Window.gd" id="3_bfjot"] -[ext_resource type="Script" path="res://scripts/BuildingManager.gd" id="4_61js3"] +[ext_resource type="Resource" uid="uid://bpjj0x7jr1k6u" path="res://data/game_resources/carbon/carbon_resource.tres" id="3_pq6ic"] +[ext_resource type="Texture2D" uid="uid://n806c03hgaq1" path="res://assets/scifi_tilesheet@2.png" id="5_qhth7"] +[ext_resource type="Script" path="res://scripts/gui.gd" id="6_yuatk"] -[sub_resource type="FastNoiseLite" id="FastNoiseLite_teaou"] +[sub_resource type="AtlasTexture" id="AtlasTexture_rchmc"] +atlas = ExtResource("5_qhth7") +region = Rect2(1920, 896, 128, 128) -[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_8pjar"] -noise = SubResource("FastNoiseLite_teaou") +[sub_resource type="AtlasTexture" id="AtlasTexture_4w4ox"] +atlas = ExtResource("5_qhth7") +region = Rect2(2048, 896, 128, 128) + +[sub_resource type="AtlasTexture" id="AtlasTexture_2smg6"] +atlas = ExtResource("5_qhth7") +region = Rect2(2176, 896, 128, 128) [node name="world" type="Node2D"] script = ExtResource("1_yf6q1") -noise_texture = SubResource("NoiseTexture2D_8pjar") +game_resources = Array[Resource("res://scripts/game_resource.gd")]([ExtResource("2_rn4a2"), ExtResource("3_pq6ic")]) [node name="world_grid" type="TileMap" parent="."] tile_set = ExtResource("2_sa7dm") format = 2 layer_0/name = "ground" -layer_1/name = "Cursor" +layer_1/name = "corruption" layer_1/tile_data = PackedInt32Array() -layer_2/name = "environment" +layer_2/name = "cursor" layer_2/tile_data = PackedInt32Array() -layer_3/name = "buildings" +layer_3/name = "environment" layer_3/tile_data = PackedInt32Array() +layer_4/name = "buildings" +layer_4/tile_data = PackedInt32Array() -[node name="Camera2D" type="Camera2D" parent="."] -zoom = Vector2(0.3, 0.3) -drag_horizontal_enabled = true -drag_vertical_enabled = true -script = ExtResource("3_bfjot") +[node name="CanvasLayer" type="CanvasLayer" parent="."] -[node name="BuildingManager" type="Node2D" parent="."] -script = ExtResource("4_61js3") +[node name="GUI" type="Control" parent="CanvasLayer"] +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("6_yuatk") + +[node name="ResourceContainer" type="PanelContainer" parent="CanvasLayer/GUI"] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -128.0 +offset_bottom = 128.0 +grow_horizontal = 0 + +[node name="MarginContainer" type="MarginContainer" parent="CanvasLayer/GUI/ResourceContainer"] +layout_mode = 2 +theme_override_constants/margin_left = 4 +theme_override_constants/margin_top = 4 +theme_override_constants/margin_right = 4 +theme_override_constants/margin_bottom = 4 + +[node name="VBoxContainer" type="VBoxContainer" parent="CanvasLayer/GUI/ResourceContainer/MarginContainer"] +layout_mode = 2 + +[node name="ResourcesLabel" type="Label" parent="CanvasLayer/GUI/ResourceContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +size_flags_stretch_ratio = 2.0 +text = "Resources:" +horizontal_alignment = 1 + +[node name="GridContainer" type="GridContainer" parent="CanvasLayer/GUI/ResourceContainer/MarginContainer/VBoxContainer"] +layout_mode = 2 +columns = 2 + +[node name="BottomBar" type="PanelContainer" parent="CanvasLayer/GUI"] +visible = false +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 0 + +[node name="HBoxContainer" type="HBoxContainer" parent="CanvasLayer/GUI/BottomBar"] +custom_minimum_size = Vector2(0, 128) +layout_mode = 2 + +[node name="BuildContainer" type="GridContainer" parent="CanvasLayer/GUI/BottomBar/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +columns = 2 + +[node name="TextureButton" type="TextureButton" parent="CanvasLayer/GUI/BottomBar/HBoxContainer/BuildContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +texture_normal = SubResource("AtlasTexture_rchmc") +ignore_texture_size = true +stretch_mode = 5 + +[node name="TextureButton2" type="TextureButton" parent="CanvasLayer/GUI/BottomBar/HBoxContainer/BuildContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +texture_normal = SubResource("AtlasTexture_4w4ox") +ignore_texture_size = true +stretch_mode = 5 + +[node name="TextureButton3" type="TextureButton" parent="CanvasLayer/GUI/BottomBar/HBoxContainer/BuildContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +texture_normal = SubResource("AtlasTexture_2smg6") +ignore_texture_size = true +stretch_mode = 5 + +[node name="DetailsPanel" type="PanelContainer" parent="CanvasLayer/GUI/BottomBar/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 3.0 + +[node name="Label" type="Label" parent="CanvasLayer/GUI/BottomBar/HBoxContainer/DetailsPanel"] +layout_mode = 2 +text = "Item details here: +other info here too" + +[node name="Spacer" type="Control" parent="CanvasLayer/GUI/BottomBar/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 2.0 diff --git a/scripts/Base.gd b/scripts/Base.gd index 3427c88..62c340b 100644 --- a/scripts/Base.gd +++ b/scripts/Base.gd @@ -1,23 +1,25 @@ extends Node2D class_name Base -@export var world_grid: TileMap -var grid_loc -var i = 1 +@export var building_data: Building +@export var world: World -const curruption_directions := [Vector2i.LEFT, Vector2i.RIGHT, Vector2i.UP, Vector2i.DOWN] +@onready var expand_timer: Timer = $ExpandTimer +var grid_loc: Vector2i +#Vector2i(17,7) var corruption_tiles: Array[Vector2i] = [] -func _ready(): - grid_loc = world_grid.local_to_map(position) +func _ready() -> void: + grid_loc = world.grid_location(position) + world.change_location_data(grid_loc, Constants.TilemapLayers.BUILDINGS, building_data.atlas_texture_region) corruption_tiles.append(grid_loc) - world_grid.set_cell(Constants.TilemapLayers.BUILDINGS, grid_loc, 0, Vector2i(17,7)) + world.corrupt_location(grid_loc) + building_data.corruption_pattern.expansion_finished.connect(on_corruption_finished) - -func _on_expand_timer_timeout(): - var corrupt_tile = corruption_tiles.pick_random() + self.curruption_directions.pick_random() - while corruption_tiles.has(corrupt_tile): - corrupt_tile = corruption_tiles.pick_random() + self.curruption_directions.pick_random() +func _on_expand_timer_timeout() -> void: + var corrupt_tile: Vector2i = building_data.corruption_pattern.expand_next_tile() + grid_loc corruption_tiles.append(corrupt_tile) - world_grid.set_cells_terrain_connect(Constants.TilemapLayers.ENVIRONMENT, corruption_tiles, 0, 0) - i += 1 + world.corrupt_location(corrupt_tile) + +func on_corruption_finished() -> void: + expand_timer.stop() diff --git a/scripts/BuildingManager.gd b/scripts/BuildingManager.gd deleted file mode 100644 index 50f2f2c..0000000 --- a/scripts/BuildingManager.gd +++ /dev/null @@ -1,12 +0,0 @@ -extends Node2D - -@onready var world_grid = $"../world_grid" -var base = preload("res://scene/base.tscn") - -func _unhandled_input(event): - if event is InputEventMouseButton and event.is_pressed() and event.button_index == MOUSE_BUTTON_LEFT: - var build = base.instantiate() - build.position = get_global_mouse_position() - build.world_grid = world_grid - add_child(build) - #world_grid.set_cell(2, world_grid.local_to_map(get_global_mouse_position()), 0, Vector2i(16,2)) diff --git a/scripts/autoloads/building_manager.gd b/scripts/autoloads/building_manager.gd new file mode 100644 index 0000000..58095f6 --- /dev/null +++ b/scripts/autoloads/building_manager.gd @@ -0,0 +1,17 @@ +extends Node + +var _resource_buildings = {} +var _storage_buildings = {} + +func add_resource_building(res: GameResource, building: BuildingBase) -> void: + if not _resource_buildings.has(res): + _resource_buildings[res] = [] + _resource_buildings[res].append(building) + +func add_storage_building(res: GameResource, building: BuildingBase) -> void: + if not _storage_buildings.has(res): + _storage_buildings[res] = [] + _storage_buildings[res].append(building) + +func get_storage_count_for_resource(res: GameResource) -> int: + return 0 if not _storage_buildings.has(res) else _storage_buildings[res].size() diff --git a/scripts/autoloads/grid.gd b/scripts/autoloads/grid.gd new file mode 100644 index 0000000..8f4d1be --- /dev/null +++ b/scripts/autoloads/grid.gd @@ -0,0 +1,57 @@ +extends Node + +const GRID_SIZE := 64 +var world_grid: TileMap +var world_data: Dictionary = {} + +var res_locations := {} + +func init(grid: TileMap) -> void: + world_grid = grid + +func world_to_grid(world_loc: Vector2) -> Vector2i: + return Vector2i(floor(world_loc.x / GRID_SIZE), floor(world_loc.y / GRID_SIZE)) + +func grid_to_world_center(grid_loc: Vector2i) -> Vector2: + return Vector2((grid_loc.x + 0.5) * GRID_SIZE, (grid_loc.y + 0.5) * GRID_SIZE) + +func set_selected_tile(tile: Vector2i) -> void: + world_grid.clear_layer(Constants.TilemapLayers.CURSOR) + world_grid.set_cell(Constants.TilemapLayers.CURSOR, tile,0,Vector2i(0,7)) + +func corrupt_location(loc: Vector2i) -> bool: + return world_data[loc].change_layer(Constants.TilemapLayers.CORRUPTION, true) + +func get_corrupted_cells() -> Array[Vector2i]: + return world_data.values().filter(func(cell: CellData): return cell.is_corrupted()).map(func(cell: CellData) -> Vector2i: return cell._pos) + +func change_location_data(pos: Vector2i, layer: int, data: Vector2i) -> void: + if not world_data.has(pos): + world_data[pos] = CellData.new(pos) + world_data[pos].change_layer(layer, data) + world_grid.set_cell(layer, pos, 0, data) + +func get_location_data(pos: Vector2i) -> CellData: + if world_data.has(pos): + return world_data[pos] + return null + +func change_location_resource(pos: Vector2i, data: GameResource) -> void: + world_data[pos].change_resource(data) + world_grid.set_cell(Constants.TilemapLayers.ENVIRONMENT, pos, 0, data.atlas_location) + if not res_locations.has(data): + res_locations[data] = [] + res_locations[data].append(Grid.grid_to_world_center(pos)) + +func get_nearest_resource(pos: Vector2, data: GameResource) -> Vector2: + var distance: float = 9999 + var nearest: Vector2 + for location: Vector2 in res_locations[data]: + var _dist = pos.distance_to(location) + if _dist < distance: + distance = _dist + nearest = location + return nearest + +func change_location_building(pos: Vector2i, data: BuildingBase) -> void: + world_data[pos].change_building(data) diff --git a/scripts/autoloads/resource_manager.gd b/scripts/autoloads/resource_manager.gd new file mode 100644 index 0000000..00f798c --- /dev/null +++ b/scripts/autoloads/resource_manager.gd @@ -0,0 +1,51 @@ +extends Node +signal changed_resource + +@export var resources := {} + +func _on_gained_resource(res: GameResource) -> void: + print("Gained Resource: %s" % res) + var changed_resources := { + res: res.pickup_value + } + changed_resource.emit(ResourceChangedSignal.new(changed_resources)) + +func pickup(resource: GameResource) -> void: + if not resources.has(resource): + resources[resource] = 0 + var pickup_amount = min(resource.pickup_value, get_resource_limit(resource) - resources[resource]) + if pickup_amount > 0: + resources[resource] += pickup_amount + var changed_resources := { + resource: pickup_amount + } + changed_resource.emit(ResourceChangedSignal.new(changed_resources)) + +func has_amount(res: GameResource, amount: int) -> bool: + return resources[res] >= amount if resources.has(res) else false + +func has_resources(cost: Dictionary) -> bool: + return cost.keys().reduce(func(accum, res): return accum and has_amount(res, cost[res]), true) + +func use_resources(cost: Dictionary) -> void: + var changed_resources := { + } + for res in cost.keys(): + resources[res] -= cost[res] + changed_resources[res] = -cost[res] + changed_resource.emit(ResourceChangedSignal.new(changed_resources)) + +func get_resource_limit(resource: GameResource) -> int: + return resource.storage_max * (1 + BuildingManager.get_storage_count_for_resource(resource)) + +#func _on_timer_timeout() -> void: + #var corrupted_resources := Grid.get_corrupted_resources() + #if corrupted_resources.size() > 0: + #var changed_resources := {} + #for corrupted_resource: CellData in corrupted_resources: + #var res: GameResource = corrupted_resource.get_resource() + #if not resources.has(res): + #resources[res] = 0 + #resources[res] += res.pickup_value + #changed_resources[res] = resources[res] + #changed_resource.emit(ResourceChangedSignal.new(changed_resources)) diff --git a/scripts/build_menu.gd b/scripts/build_menu.gd new file mode 100644 index 0000000..a2b4a76 --- /dev/null +++ b/scripts/build_menu.gd @@ -0,0 +1,70 @@ +extends CanvasLayer + +signal build(building: Building) + +var groups_visible: Array[BuildingGroup] = [] +var buildings_visible: Array[Building] = [] +var selected_building: Building + +const ADVANCED_BUILDING_GROUP = preload("res://data/buildings/advanced/advanced_building_group.tres") +const BASIC_BUILDING_GROUP = preload("res://data/buildings/basic/basic_building_group.tres") + +@onready var building_groups: ItemList = $MarginContainer/PanelContainer/HBoxContainer/ScrollContainer/VBoxContainer/BuildingGroups +@onready var buildings: ItemList = $MarginContainer/PanelContainer/HBoxContainer/ScrollContainer2/VBoxContainer/Buildings + +@onready var title: Label = $MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/Title +@onready var description: Label = $MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/Description +@onready var build_materials: GridContainer = $MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/BuildMaterials +@onready var build_buttons_container: HBoxContainer = $MarginContainer/PanelContainer/HBoxContainer/DetailsContainer/BuildButtonsContainer + +func _ready() -> void: + _add_building_group(BASIC_BUILDING_GROUP) + _add_building_group(ADVANCED_BUILDING_GROUP) + building_groups.grab_focus() + +func _add_building_group(group: BuildingGroup) -> void: + building_groups.add_item(group.name, group.atlas_texture) + groups_visible.append(group) + +func _on_building_groups_item_selected(index: int) -> void: + buildings.clear() + buildings_visible.clear() + for building in groups_visible[index].buildings: + buildings_visible.append(building) + buildings.add_item(building.name, building.atlas_texture) + + description.hide() + build_materials.hide() + build_buttons_container.hide() + selected_building = null + + +func _on_buildings_item_selected(index: int) -> void: + selected_building = buildings_visible[index] + title.text = selected_building.name + description.text = selected_building.description + + for child in build_materials.get_children(): + child.queue_free() + for res: GameResource in selected_building.cost.keys(): + var image = TextureRect.new() + var texture = AtlasTexture.new() + texture.atlas = preload("res://assets/scifi_tilesheet@2.png") + texture.region = Rect2(64 * res.atlas_location, Vector2(64, 64)) + image.texture = texture + build_materials.add_child(image) + var label = Label.new() + label.text = str(selected_building.cost[res]) + if not ResourceManager.has_amount(res, selected_building.cost[res]): + label.add_theme_color_override("font_color", Color.RED) + build_materials.add_child(label) + + description.show() + build_materials.show() + build_buttons_container.show() + + +func _on_build_button_pressed() -> void: + if selected_building: + build.emit(selected_building) + queue_free() diff --git a/scripts/cell_data.gd b/scripts/cell_data.gd new file mode 100644 index 0000000..e246cea --- /dev/null +++ b/scripts/cell_data.gd @@ -0,0 +1,61 @@ +class_name CellData +extends Resource + +const BUILD = preload("res://data/interactions/build/build.tres") +const GATHER = preload("res://data/interactions/gather/gather.tres") + +@export var layer_info: Dictionary = { + Constants.TilemapLayers.CORRUPTION: false +} +var _pos: Vector2i +var interaction_display: ProgressBar + +func _to_string() -> String: + return "{%s %s}" % [_pos, layer_info] + +func _init(pos: Vector2i) -> void: + _pos = pos + +func change_layer(layer: int, data: Variant) -> bool: + if layer_info.has(layer) and layer_info[layer] == data: + return false + layer_info[layer] = data + return true + +func change_resource(data: GameResource) -> void: + layer_info[Constants.TilemapLayers.ENVIRONMENT] = data + +func change_building(data: BuildingBase) -> void: + layer_info[Constants.TilemapLayers.BUILDINGS] = data + +func get_resource() -> GameResource: + return layer_info[Constants.TilemapLayers.ENVIRONMENT] as GameResource + +func has_resource() -> bool: + return has_layer(Constants.TilemapLayers.ENVIRONMENT) + +func get_building() -> BuildingBase: + return layer_info[Constants.TilemapLayers.BUILDINGS] as BuildingBase + +func has_building() -> bool: + return has_layer(Constants.TilemapLayers.BUILDINGS) + +func is_corrupted() -> bool: + return layer_info[Constants.TilemapLayers.CORRUPTION] + +func has_layer(layer: int) -> bool: + return layer_info.has(layer) + +func is_interactable() -> bool: + return has_resource() or has_building() + +func is_buildable() -> bool: + return not has_resource() and not has_building() + +func get_interaction_options() -> Array[Interaction]: + var interactions: Array[Interaction] = [] + if has_resource(): + interactions.append(GATHER) + if not has_building(): + interactions.append(BUILD) + return interactions diff --git a/scripts/constants.gd b/scripts/constants.gd index 04c0d01..064787e 100644 --- a/scripts/constants.gd +++ b/scripts/constants.gd @@ -3,7 +3,8 @@ class_name Constants enum TilemapLayers { GROUND = 0, - CURSOR = 1, - ENVIRONMENT = 2, - BUILDINGS = 3, + CORRUPTION = 1, + CURSOR = 2, + ENVIRONMENT = 3, + BUILDINGS = 4, } diff --git a/scripts/expansion_patterns/expansion_base.gd b/scripts/expansion_patterns/expansion_base.gd new file mode 100644 index 0000000..5c25e5a --- /dev/null +++ b/scripts/expansion_patterns/expansion_base.gd @@ -0,0 +1,6 @@ +class_name ExpansionBase extends Resource + +signal expansion_finished + +func expand_next_tile() -> Vector2i: + return Vector2i.ZERO diff --git a/scripts/expansion_patterns/expansion_random_pattern_large.gd b/scripts/expansion_patterns/expansion_random_pattern_large.gd new file mode 100644 index 0000000..7333b25 --- /dev/null +++ b/scripts/expansion_patterns/expansion_random_pattern_large.gd @@ -0,0 +1,18 @@ +class_name ExpansionRandomPatternLarge extends ExpansionBase + +const EXPANSION_DISTANCE: int = 8 + +var expansion_tiles: Array[Vector2i] = [] + +func expand_next_tile() -> Vector2i: + if expansion_tiles.is_empty(): + for i in range(EXPANSION_DISTANCE, 0, -1): + expansion_tiles.append(Vector2i(0, i)) + expansion_tiles.append(Vector2i(0, -i)) + expansion_tiles.append(Vector2i(i, 0)) + expansion_tiles.append(Vector2i(-i, 0)) + for ran in range(1, EXPANSION_DISTANCE): + pass + if expansion_tiles.size() == 1: + expansion_finished.emit() + return expansion_tiles.pop_back() diff --git a/scripts/expansion_patterns/expansion_square_pattern.gd b/scripts/expansion_patterns/expansion_square_pattern.gd new file mode 100644 index 0000000..e40d3cf --- /dev/null +++ b/scripts/expansion_patterns/expansion_square_pattern.gd @@ -0,0 +1,18 @@ +class_name ExpansionSquarePattern extends ExpansionBase + +const EXPANSION_STAGES: int = 3 + +var expansion_stage: int = 0 +var expansion_tiles: Array[Vector2i] = [] + +func expand_next_tile() -> Vector2i: + if expansion_tiles.is_empty(): + if expansion_stage < EXPANSION_STAGES: + expansion_stage += 1 + for x in range(-expansion_stage, expansion_stage + 1): + for y in range(-expansion_stage, expansion_stage + 1): + if abs(x) == expansion_stage or abs(y) == expansion_stage: + expansion_tiles.append(Vector2i(x, y)) + if expansion_stage == EXPANSION_STAGES and expansion_tiles.size() == 1: + expansion_finished.emit() + return expansion_tiles.pop_at(randi_range(0, expansion_tiles.size() - 1)) diff --git a/scripts/game_resource.gd b/scripts/game_resource.gd new file mode 100644 index 0000000..9f26f34 --- /dev/null +++ b/scripts/game_resource.gd @@ -0,0 +1,23 @@ +class_name GameResource +extends Resource + +signal gained_resource(res: GameResource) + +@export var atlas_location: Vector2i +@export var pickup_value: int +@export var name: String +@export var spawn_patterns: Array[SpawnPattern] +@export var storage_max: int +@export var skills_needed: Array[Skills.ABILITIES] = [] + +func _to_string() -> String: + return name + +func get_spawn_locations() -> Array[Vector2i]: + var spawns: Array[Vector2i] = [] + for spawn in spawn_patterns: + spawns.append_array(spawn.get_spawn_locations()) + return spawns + +func can_harvest(skills: Skills) -> bool: + return skills.has_skills(skills_needed) diff --git a/scripts/gui.gd b/scripts/gui.gd new file mode 100644 index 0000000..c00ea77 --- /dev/null +++ b/scripts/gui.gd @@ -0,0 +1,41 @@ +extends Control + +@onready var resource_container: GridContainer = $ResourceContainer/MarginContainer/VBoxContainer/GridContainer +const SCIFI_TILESHEET = preload("res://assets/scifi_tilesheet@2.png") + + +var _resource_displays := {} + +func _ready() -> void: + ResourceManager.changed_resource.connect(_on_resource_manager_changed_resource) + +func _on_resource_manager_changed_resource(changed: ResourceChangedSignal) -> void: + for resource: GameResource in changed.changed_resources.keys(): + if not _resource_displays.has(resource): + var atlas_tex := AtlasTexture.new() + atlas_tex.atlas = SCIFI_TILESHEET + atlas_tex.region = Rect2(Grid.GRID_SIZE * resource.atlas_location.x, Grid.GRID_SIZE * resource.atlas_location.y, Grid.GRID_SIZE, Grid.GRID_SIZE) + var img := TextureRect.new() + img.texture = atlas_tex + img.expand_mode = TextureRect.EXPAND_FIT_WIDTH_PROPORTIONAL + resource_container.add_child(img) + + var label := Label.new() + resource_container.add_child(label) + + var data := ResourceData.new() + data.image = img + data.label = label + data.value = changed.changed_resources[resource] + _resource_displays[resource] = data + + label.text = "%s / %s" % [data.value, ResourceManager.get_resource_limit(resource)] + else: + var data: ResourceData = _resource_displays[resource] + data.value += changed.changed_resources[resource] + data.label.text = "%s / %s" % [data.value, ResourceManager.get_resource_limit(resource)] + +class ResourceData: + var image: TextureRect + var label: Label + var value: int diff --git a/scripts/interaction_bar.gd b/scripts/interaction_bar.gd new file mode 100644 index 0000000..56858f1 --- /dev/null +++ b/scripts/interaction_bar.gd @@ -0,0 +1,20 @@ +extends ProgressBar +class_name InteractionBar + +signal interaction_finished + +var grid_position: Vector2i + +func _ready() -> void: + position = Grid.grid_to_world_center(grid_position) - Vector2(30,10) + + var tween = get_tree().create_tween() + tween.tween_property(self, "value", 100, 3) + tween.tween_callback(_cleanup_gather) + +func _cleanup_gather() -> void: + interaction_finished.emit() + #TODO add the interaction for buildings + var res: GameResource = Grid.get_location_data(grid_position).get_resource() + ResourceManager.pickup(res) + self.queue_free() diff --git a/scripts/interaction_wheel.gd b/scripts/interaction_wheel.gd new file mode 100644 index 0000000..b18814d --- /dev/null +++ b/scripts/interaction_wheel.gd @@ -0,0 +1,49 @@ +extends Node2D +class_name InteractionWheel + +signal closed + +var interactions: Array[Interaction] +var grid_position: Vector2i + +@onready var interaction_icons: Array[Node] = $Interactions.get_children() +@onready var cursor: Sprite2D = $Cursor +@onready var information_panel: Panel = $InformationPanel +@onready var interaction_label: Label = $InformationPanel/InteractionLabel + +func initialize(interaction_location: Vector2i, interactions: Array[Interaction]) -> void: + grid_position = interaction_location + position = Grid.grid_to_world_center(interaction_location) + self.interactions = interactions + +func _ready() -> void: + for i in range(interactions.size()): + interaction_icons[i].texture = interactions[i].image + interaction_icons[i].show() + +func _process(delta: float) -> void: + var selection_direction = Input.get_vector("view_left", "view_right", "view_up", "view_down") + if selection_direction: + cursor.rotation = selection_direction.angle() + cursor.show() + var selection = _get_selection_index(cursor.rotation) + if selection < interactions.size(): + information_panel.show() + interaction_label.text = interactions[selection].name + else: + information_panel.hide() + if Input.is_action_just_pressed("select") and cursor.visible: + var selection = _get_selection_index(cursor.rotation) + print("Selection: %s Rotation: %s" % [selection, cursor.rotation]) + if selection < interactions.size(): + var next_interactions = interactions[selection].interact_at(grid_position, get_tree().root) + if next_interactions.is_empty(): + closed.emit() + queue_free() + else: + interactions = next_interactions + _ready() + +func _get_selection_index(angle: float) -> int: + var adjusted_angle = fposmod(angle + (PI / 2.0), 2.0 * PI) + return floor(((int(floor(adjusted_angle / (PI / 8.0))) + 1) % 16) / 2.0) diff --git a/scripts/player.gd b/scripts/player.gd new file mode 100644 index 0000000..4e5b7ae --- /dev/null +++ b/scripts/player.gd @@ -0,0 +1,97 @@ +extends CharacterBody2D +class_name Player + +@export var SPEED := 4 + +var last_direction = 0 +var interaction_location: Vector2i +var _interaction_options: InteractionWheel +var _interacting := false +var _attempting_build: Building +var _build_placement: Sprite2D +var _in_menu := false + +var _skills := Skills.new() + +@onready var sprite: AnimatedSprite2D = $Sprite +@onready var interaction_timer: Timer = $InteractionTimer +const INTERACTION_BAR = preload("res://scene/interaction_bar.tscn") +const BUILD_MENU = preload("res://scene/build_menu.tscn") +const BUILDING_BASE = preload("res://data/buildings/building_base.tscn") + +func _physics_process(delta: float) -> void: + var input_direction := Input.get_vector("move_left", "move_right", "move_up", "move_down") if not _in_menu else Vector2.ZERO + velocity = input_direction * SPEED / delta + move_and_slide() + + if input_direction: + if _interaction_options: + _interaction_options.queue_free() + _on_interation_options_closed() + sprite.play("walk") + last_direction = input_direction.angle() + PI / 2 + rotation = last_direction + interaction_location = Grid.world_to_grid(position) + Vector2i(input_direction.round()) + Grid.set_selected_tile(interaction_location) + else: + sprite.stop() + + if _build_placement: + _build_placement.position = Grid.grid_to_world_center(interaction_location) + _build_placement.self_modulate = Color(0, 1, 0, 0.5) if Grid.get_location_data(interaction_location).is_buildable() else Color(1, 0, 0, 0.4) + +func _input(event: InputEvent) -> void: + if event.is_action_pressed("interact"): + var interact_data: CellData = Grid.get_location_data(interaction_location) + if _attempting_build and interact_data.is_buildable(): + _build() + elif not _interacting and interact_data.is_interactable(): + if interact_data.has_resource(): + var interaction = INTERACTION_BAR.instantiate() + interaction.interaction_finished.connect(_on_interaction_finished) + interaction.grid_position = interaction_location + _interacting = true + add_sibling(interaction) + elif interact_data.has_building(): + _in_menu = interact_data.get_building().interact(_on_interaction_finished) + if event.is_action_pressed("build"): + var build_menu = BUILD_MENU.instantiate() + build_menu.build.connect(_on_build_menu_build) + add_sibling(build_menu) + _in_menu = true + +func _on_interaction_finished() -> void: + _interacting = false + _in_menu = false + +func _on_build_menu_build(building: Building) -> void: + print("Building: %s" % building.name) + _in_menu = false + _attempting_build = building + _build_placement = Sprite2D.new() + _build_placement.texture = _attempting_build.atlas_texture + _build_placement.self_modulate = Color(1, 0, 0, 0.4) + add_sibling(_build_placement) + +func _build() -> void: + ResourceManager.use_resources(_attempting_build.cost) + var build: BuildingBase = BUILDING_BASE.instantiate() + add_sibling(build) + build.initialize(_attempting_build, interaction_location) + Grid.change_location_building(interaction_location, build) + + if not ResourceManager.has_resources(_attempting_build.cost): + _attempting_build = null + _build_placement.queue_free() + _build_placement = null + +func _on_interation_options_closed() -> void: + _interaction_options = null + +func _unhandled_input(event): + if event is InputEventMouseButton: + match event.button_index: + MOUSE_BUTTON_WHEEL_DOWN: + $Camera2D.zoom -= Vector2(0.01, 0.01) + MOUSE_BUTTON_WHEEL_UP: + $Camera2D.zoom += Vector2(0.01, 0.01) diff --git a/scripts/research_menu.gd b/scripts/research_menu.gd new file mode 100644 index 0000000..a7d9c6e --- /dev/null +++ b/scripts/research_menu.gd @@ -0,0 +1,53 @@ +extends CanvasLayer + +signal research(research: Research) + +var researches: Array[Research] = [] +var selected_research: Research + +const GEM_RESEARCH = preload("res://data/research/gem_research.tres") + +@onready var research_items: ItemList = %ResearchItems + +@onready var title: Label = %Title +@onready var description: Label = %Description +@onready var research_materials: GridContainer = %ResearchMaterials +@onready var research_buttons_container: HBoxContainer = %ResearchButtonsContainer + +func _ready() -> void: + _add_research(GEM_RESEARCH) + research_items.grab_focus() + +func _add_research(group: Research) -> void: + research_items.add_item(group.name, group.atlas_texture) + researches.append(group) + +func _on_research_selected(index: int) -> void: + selected_research = researches[index] + title.text = selected_research.name + description.text = selected_research.description + + for child in research_materials.get_children(): + child.queue_free() + for res: GameResource in selected_research.cost.keys(): + var image = TextureRect.new() + var texture = AtlasTexture.new() + texture.atlas = preload("res://assets/scifi_tilesheet@2.png") + texture.region = Rect2(64 * res.atlas_location, Vector2(64, 64)) + image.texture = texture + research_materials.add_child(image) + var label = Label.new() + label.text = str(selected_research.cost[res]) + if not ResourceManager.has_amount(res, selected_research.cost[res]): + label.add_theme_color_override("font_color", Color.RED) + research_materials.add_child(label) + + description.show() + research_materials.show() + research_buttons_container.show() + + +func _on_build_button_pressed() -> void: + if selected_research: + research.emit(selected_research) + queue_free() diff --git a/scripts/signals/resource_changed_signal.gd b/scripts/signals/resource_changed_signal.gd new file mode 100644 index 0000000..14c8116 --- /dev/null +++ b/scripts/signals/resource_changed_signal.gd @@ -0,0 +1,6 @@ +class_name ResourceChangedSignal extends Node + +var changed_resources := {} + +func _init(changed: Dictionary) -> void: + changed_resources = changed diff --git a/scripts/skills.gd b/scripts/skills.gd new file mode 100644 index 0000000..6e2f26c --- /dev/null +++ b/scripts/skills.gd @@ -0,0 +1,18 @@ +class_name Skills +extends Resource + +enum ABILITIES { HARVEST_GEM, CORRUPT_RESOURCE, CORRUPT_BUILDING } + +var _aquired_skills: Array[ABILITIES] = [] + +func aquire_skill(skill: ABILITIES) -> void: + _aquired_skills.append(skill) + +func has_skill(skill: ABILITIES) -> bool: + return _aquired_skills.has(skill) + +func has_skills(skills: Array[ABILITIES]) -> bool: + var _has_skills = true + for skill: ABILITIES in skills: + _has_skills = _has_skills and has_skill(skill) + return _has_skills diff --git a/scripts/spawn_pattern.gd b/scripts/spawn_pattern.gd new file mode 100644 index 0000000..0c3d587 --- /dev/null +++ b/scripts/spawn_pattern.gd @@ -0,0 +1,34 @@ +extends Resource +class_name SpawnPattern + +@export var min_distance: int +@export var max_distance: int +@export var min_spread: int +@export var quantity: int +@export var cluster_size: int + +func get_spawn_locations() -> Array[Vector2i]: + var spawns: Array[Vector2i] = [] + var clusters: Array[Vector2] = [] + for cluster_i in range(quantity): + var cluster + var is_valid_cluster := false + while not is_valid_cluster: + is_valid_cluster = true + var dist = randf_range(min_distance, max_distance) + var angle = randf_range(0, 2*PI) + cluster = Vector2.RIGHT.rotated(angle) + cluster *= dist + for old_cluster: Vector2 in clusters: + is_valid_cluster = is_valid_cluster and old_cluster.distance_to(cluster) > min_spread + clusters.append(cluster) + + var local_spawns = [Vector2i(cluster)] + for point in range(cluster_size - 1): + var next = local_spawns.pick_random() + while local_spawns.has(next): + var next_change = [Vector2i.LEFT, Vector2i.RIGHT, Vector2i.UP, Vector2i.DOWN].pick_random() + next = next + next_change + local_spawns.append(next) + spawns.append_array(local_spawns) + return spawns diff --git a/scripts/world.gd b/scripts/world.gd index c21d974..7c3431f 100644 --- a/scripts/world.gd +++ b/scripts/world.gd @@ -1,18 +1,30 @@ -extends Node2D +class_name World extends Node2D -@export var noise_texture: NoiseTexture2D -var noise_values -@onready var world_grid = $world_grid +@export var game_resources: Array[GameResource] +const PLAYER = preload("res://scene/player.tscn") + +var terrain_noise := FastNoiseLite.new() +#var resource_noise: Noise = FastNoiseLite.new() var temp_size = 150 var temp_noise_val = [] var temp_noise_reg = [] -var noise_regions = [-999,10,150,200,999] -var atlas_regions = [Vector2i(0,1),Vector2i(0,0),Vector2i(2,0),Vector2i(0,2)] +var noise_regions := [-999,0,999] +var atlas_regions := [Vector2i(0,1),Vector2i(0,0)] + +@onready var world_grid: TileMap = $world_grid func get_noise_value(x: int, y: int): - return noise_values.get_noise_2d(x,y) * 500 + return terrain_noise.get_noise_2d(x,y) * 500 + +#func is_resource_tile(x: int, y: int) -> GameResource: + #var dist = sqrt(x ^ 2 + y ^ 2) + #for res: GameResource in game_resources: + #var noise = resource_noise.get_noise_2d(x, y) + #if res.distance_probability(dist) > (noise + 1.0) / 2.0: + #return res + #return null func get_noise_region(x,y): var noise_val = get_noise_value(x,y) @@ -21,18 +33,35 @@ func get_noise_region(x,y): return i func _ready(): - noise_values = noise_texture.noise + Grid.init(world_grid) + terrain_noise.seed = randi() + #resource_noise.seed = randi() + for x in range(-temp_size, temp_size): for y in range(-temp_size, temp_size): - world_grid.set_cell(0, Vector2i(x,y),0,atlas_regions[get_noise_region(x,y)]) + Grid.change_location_data(Vector2i(x,y), Constants.TilemapLayers.GROUND, atlas_regions[get_noise_region(x,y)]) + #var tile_res := is_resource_tile(x,y) + #if tile_res: + #change_location_resource(Vector2i(x,y), tile_res) + #if not tile_res.gained_resource.is_connected(resource_manager._on_gained_resource): + #tile_res.gained_resource.connect(resource_manager._on_gained_resource) temp_noise_val.append(get_noise_value(x,y)) temp_noise_reg.append(get_noise_region(x,y)) prints(temp_noise_val.min(), temp_noise_val.max()) for region in noise_regions.size(): prints(region, noise_regions[region], temp_noise_reg.count(region)) - #get_tree().quit() - -func _process(delta): - var mouse_pos = world_grid.local_to_map(get_local_mouse_position()) - world_grid.clear_layer(1) - world_grid.set_cell(1, mouse_pos,0,Vector2i(0,7)) + var player = PLAYER.instantiate() + add_child(player) + add_resources_to_map() + +func corrupt_location(loc: Vector2i): + if Grid.corrupt_location(loc): + var corrupted_cells := Grid.get_corrupted_cells() + world_grid.set_cells_terrain_connect(Constants.TilemapLayers.CORRUPTION, corrupted_cells, 0, 0) + +func add_resources_to_map() -> void: + for res: GameResource in game_resources: + #res.gained_resource.connect(ResourceManager._on_gained_resource) + var spawns = res.get_spawn_locations() + for spawn in spawns: + Grid.change_location_resource(spawn, res)