commit a811ec65f0a4c66808ca2e2c3abc93f43a4786df Author: Dmitriy Pleshevskiy Date: Sun Jan 7 17:32:49 2024 +0300 initial commit diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..04a277b --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +# Godot 4+ specific ignores +.godot/ + +# builds +target/ + +# direnv +/.envrc +/.direnv/ diff --git a/export_presets.cfg b/export_presets.cfg new file mode 100644 index 0000000..f1e7386 --- /dev/null +++ b/export_presets.cfg @@ -0,0 +1,39 @@ +[preset.0] + +name="Linux/X11" +platform="Linux/X11" +runnable=true +dedicated_server=false +custom_features="" +export_filter="all_resources" +include_filter="" +exclude_filter="target/*" +export_path="target/MindustryTools.x86_64" +encryption_include_filters="" +encryption_exclude_filters="" +encrypt_pck=false +encrypt_directory=false + +[preset.0.options] + +custom_template/debug="" +custom_template/release="" +debug/export_console_wrapper=0 +binary_format/embed_pck=true +texture_format/bptc=true +texture_format/s3tc=true +texture_format/etc=false +texture_format/etc2=false +binary_format/architecture="x86_64" +ssh_remote_deploy/enabled=false +ssh_remote_deploy/host="user@host_ip" +ssh_remote_deploy/port="22" +ssh_remote_deploy/extra_args_ssh="" +ssh_remote_deploy/extra_args_scp="" +ssh_remote_deploy/run_script="#!/usr/bin/env bash +export DISPLAY=:0 +unzip -o -q \"{temp_dir}/{archive_name}\" -d \"{temp_dir}\" +\"{temp_dir}/{exe_name}\" {cmd_args}" +ssh_remote_deploy/cleanup_script="#!/usr/bin/env bash +kill $(pgrep -x -f \"{temp_dir}/{exe_name} {cmd_args}\") +rm -rf \"{temp_dir}\"" diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f5fedda --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1704161960, + "narHash": "sha256-QGua89Pmq+FBAro8NriTuoO/wNaUtugt29/qqA8zeeM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "63143ac2c9186be6d9da6035fa22620018c85932", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..bf9992e --- /dev/null +++ b/flake.nix @@ -0,0 +1,122 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + }; + + outputs = { self, nixpkgs, flake-utils, ... }: + let + inherit (builtins) substring; + version = "${substring 0 8 self.lastModifiedDate}_${self.shortRev or "dirty"}"; + + mkGodotEmailTemplates = { stdenv, fetchurl, unzip, lib, ... }: + stdenv.mkDerivation rec { + pname = "godot-email-templates"; + version = "4.2.1-stable"; + src = fetchurl { + url = "https://github.com/godotengine/godot/releases/download/${version}/Godot_v${version}_export_templates.tpz"; + hash = "sha256-xfFA61eEY6L6FAfzXjfBeqNKS4R7nTDinDhHuV5t2gc="; + }; + nativeBuildInputs = [ unzip ]; + unpackPhase = '' + mkdir $out + unzip $src + mv templates $out/${lib.replaceStrings ["-"] ["."] version} + ''; + }; + + mkMindustryTools = + { stdenv + , lib + , vulkan-loader + , libGL + , libX11 + , libXcursor + , libXinerama + , libXext + , libXrandr + , libXrender + , libXi + , libXfixes + , libxkbcommon + , alsa-lib + , libpulseaudio + , dbus + , speechd + , fontconfig + , udev + , makeWrapper + , autoPatchelfHook + , godot_4 + , godotEmailTemplates + , ... + }: + stdenv.mkDerivation { + pname = "mindustry-tools"; + inherit version; + + src = ./.; + + nativeBuildInputs = [ + autoPatchelfHook + makeWrapper + godot_4 + ]; + + runtimeDependencies = [ + vulkan-loader + libGL + libX11 + libXcursor + libXinerama + libXext + libXrandr + libXrender + libXi + libXfixes + libxkbcommon + alsa-lib + libpulseaudio + dbus + dbus.lib + speechd + fontconfig + fontconfig.lib + udev + ]; + + buildPhase = '' + export HOME=$(pwd) + mkdir -p .local/share/godot/export_templates/ + cp -r ${godotEmailTemplates}/* .local/share/godot/export_templates + godot4 --headless --export-release "Linux/X11" mindustry-tools + # godot4 --headless --export-debug "Linux/X11" mindustry-tools + ''; + + installPhase = '' + install -m755 -D mindustry-tools $out/bin/mindustry-tools + ''; + }; + in + flake-utils.lib.eachDefaultSystem (system: + let + inherit (builtins) mapAttrs; + pkgs = import nixpkgs { inherit system; }; + + godotEmailTemplates = pkgs.callPackage mkGodotEmailTemplates { }; + mindustryTools = pkgs.callPackage mkMindustryTools { inherit godotEmailTemplates; }; + + mkApp = drv: flake-utils.lib.mkApp { inherit drv; }; + packages = { + default = mindustryTools; + email-templates = godotEmailTemplates; + }; + in + { + check = packages; + + inherit packages; + + apps = mapAttrs (name: mkApp) packages; + }); +} diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..c7f9a2b --- /dev/null +++ b/project.godot @@ -0,0 +1,24 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=5 + +[application] + +config/name="MindustryTools" +config/version="0.0.1" +run/main_scene="res://src/energy/EnergyTable.tscn" +config/features=PackedStringArray("4.2", "GL Compatibility") +boot_splash/show_image=false +boot_splash/fullsize=false +boot_splash/use_filter=false + +[rendering] + +renderer/rendering_method="gl_compatibility" +renderer/rendering_method.mobile="gl_compatibility" diff --git a/src/energy/EnergyTable.gd b/src/energy/EnergyTable.gd new file mode 100644 index 0000000..b100eae --- /dev/null +++ b/src/energy/EnergyTable.gd @@ -0,0 +1,45 @@ +extends Control + +const table_row = preload("res://src/energy/EnergyTableRow.tscn") +@onready var table_body = $VBoxContainer/TableBody/VBoxContainer +@onready var total_energy_label = $VBoxContainer/TableSummary/HBoxContainer/TotalEnergyLabel + +var data = [{ }] + + +func render_total_energy_label(): + var total_energy = 0 + for data_row in data: + total_energy += data_row["instance"].energy + + total_energy_label.text = str(total_energy) + +func _on_energy_changed(_value: int): + render_total_energy_label() + +func _on_table_row_deleted(instance: Node): + table_body.remove_child(instance) + for i in range(0, data.size()): + var data_row = data[i] + if data_row["instance"] == instance: + data.pop_at(i) + break + render_total_energy_label() + +func add_row(data_row: Dictionary): + var instance = table_row.instantiate() + table_body.add_child(instance) + instance.energy_changed.connect(_on_energy_changed) + instance.deleted.connect(_on_table_row_deleted) + data_row["instance"] = instance + +func _ready(): + for data_row in data: + add_row(data_row) + + render_total_energy_label() + +func _on_add_building_button_pressed(): + var new_row = {} + data.append(new_row) + add_row(new_row) diff --git a/src/energy/EnergyTable.tscn b/src/energy/EnergyTable.tscn new file mode 100644 index 0000000..7e43849 --- /dev/null +++ b/src/energy/EnergyTable.tscn @@ -0,0 +1,87 @@ +[gd_scene load_steps=2 format=3 uid="uid://cbegq3jfbfb6t"] + +[ext_resource type="Script" path="res://src/energy/EnergyTable.gd" id="1_k0c5x"] + +[node name="EnergyTable" 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_k0c5x") + +[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="TableHeader" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/TableHeader"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TableHeader/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Название" + +[node name="Label2" type="Label" parent="VBoxContainer/TableHeader/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Энергия/сек за ед." + +[node name="Label3" type="Label" parent="VBoxContainer/TableHeader/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Кол-во ед." + +[node name="Label4" type="Label" parent="VBoxContainer/TableHeader/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "Энергия/сек" + +[node name="TableBody" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="VBoxContainer/TableBody"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="TableSummary" type="PanelContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer/TableSummary"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer/TableSummary/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "ИТОГО" + +[node name="Label2" type="Label" parent="VBoxContainer/TableSummary/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="Label3" type="Label" parent="VBoxContainer/TableSummary/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="TotalEnergyLabel" type="Label" parent="VBoxContainer/TableSummary/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "0" + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 + +[node name="AddBuildingButton" type="Button" parent="VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "Добавить здание" + +[connection signal="pressed" from="VBoxContainer/HBoxContainer/AddBuildingButton" to="." method="_on_add_building_button_pressed"] diff --git a/src/energy/EnergyTableRow.gd b/src/energy/EnergyTableRow.gd new file mode 100644 index 0000000..59a7db2 --- /dev/null +++ b/src/energy/EnergyTableRow.gd @@ -0,0 +1,35 @@ +extends HBoxContainer + +@export var unit_name: String +@export var energy_per_unit: int +@export var unit_count: int = 1 + +signal energy_changed(new_value) +var energy: int: + get: + return energy + set(value): + if value != energy: + energy = value + energy_changed.emit(value) + $EnergyLabel.text = str(energy) + +func render_energy(): + energy = unit_count * energy_per_unit + +func _ready(): + $UnitNameLineEdit.text = unit_name + $EnergyPerUnitLineEdit.text = str(energy_per_unit) + $UnitCountLineEdit.text = str(unit_count) + render_energy() + +func _on_unit_count_line_edit_text_changed(new_text): + unit_count = int(new_text) + render_energy() + +func _on_energy_per_unit_line_edit_text_changed(new_text): + energy_per_unit = int(new_text) + render_energy() + +func _on_unit_name_line_edit_text_changed(new_text): + unit_name = new_text diff --git a/src/energy/EnergyTableRow.tscn b/src/energy/EnergyTableRow.tscn new file mode 100644 index 0000000..6df6a6a --- /dev/null +++ b/src/energy/EnergyTableRow.tscn @@ -0,0 +1,110 @@ +[gd_scene load_steps=2 format=3 uid="uid://cvc75dbbiut78"] + +[sub_resource type="GDScript" id="GDScript_obfag"] +script/source = "extends HBoxContainer + +@export var unit_name: String +@export var energy_per_unit: int +@export var unit_count: int = 1 + +@onready var unit_name_line_edit = $UnitNameLineEdit +@onready var unit_count_line_edit = $UnitCountLineEdit +@onready var energy_per_unit_line_edit = $EnergyPerUnitLineEdit +@onready var energy_label = $HBoxContainer/EnergyLabel + +signal deleted(instance: Node) +signal energy_changed(new_value: int) + + +var energy: int: + get: + return energy + set(value): + if value != energy: + energy = value + energy_changed.emit(value) + energy_label.text = str(energy) + + +func render_energy(): + energy = unit_count * energy_per_unit + +func _ready(): + unit_name_line_edit.text = unit_name + energy_per_unit_line_edit.text = str(energy_per_unit) + unit_count_line_edit.text = str(unit_count) + render_energy() + +func _on_unit_count_line_edit_text_changed(new_text): + unit_count = int(new_text) + render_energy() + +func _on_energy_per_unit_line_edit_text_changed(new_text): + energy_per_unit = int(new_text) + render_energy() + +func _on_unit_name_line_edit_text_changed(new_text): + unit_name = new_text + +func _on_delete_row_button_pressed(): + deleted.emit(self) +" + +[node name="EnergyTableRow" type="HBoxContainer"] +anchors_preset = 10 +anchor_right = 1.0 +offset_bottom = 35.0 +grow_horizontal = 2 +script = SubResource("GDScript_obfag") + +[node name="UnitNameLineEdit" type="LineEdit" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "Турбинный конденсатор" +middle_mouse_paste_enabled = false +drag_and_drop_selection_enabled = false +flat = true +caret_blink = true + +[node name="EnergyPerUnitLineEdit" type="LineEdit" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "180" +virtual_keyboard_type = 2 +middle_mouse_paste_enabled = false +drag_and_drop_selection_enabled = false +flat = true +select_all_on_focus = true +caret_blink = true + +[node name="UnitCountLineEdit" type="LineEdit" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 +placeholder_text = "4" +virtual_keyboard_type = 2 +middle_mouse_paste_enabled = false +drag_and_drop_selection_enabled = false +flat = true +select_all_on_focus = true +caret_blink = true + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="EnergyLabel" type="Label" parent="HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +text = "0" + +[node name="DeleteRowButton" type="Button" parent="HBoxContainer"] +layout_mode = 2 +tooltip_text = "Удалить здание" +theme_override_colors/font_color = Color(1, 0.215686, 0.137255, 1) +text = "✖" +flat = true + +[connection signal="text_changed" from="UnitNameLineEdit" to="." method="_on_unit_name_line_edit_text_changed"] +[connection signal="text_changed" from="EnergyPerUnitLineEdit" to="." method="_on_energy_per_unit_line_edit_text_changed"] +[connection signal="text_changed" from="UnitCountLineEdit" to="." method="_on_unit_count_line_edit_text_changed"] +[connection signal="pressed" from="HBoxContainer/DeleteRowButton" to="." method="_on_delete_row_button_pressed"] diff --git a/src/main.tscn b/src/main.tscn new file mode 100644 index 0000000..ce1b41a --- /dev/null +++ b/src/main.tscn @@ -0,0 +1,32 @@ +[gd_scene format=3 uid="uid://bwvm6y1nt53yk"] + +[node name="Control" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="TabContainer" type="TabContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="VBoxContainer" type="VBoxContainer" parent="TabContainer"] +layout_mode = 2 + +[node name="AddBlockButton" type="Button" parent="TabContainer/VBoxContainer"] +layout_mode = 2 +text = "Добавить блок" + +[node name="VFlowContainer" type="VFlowContainer" parent="TabContainer"] +visible = false +layout_mode = 2 + +[node name="AddBlockButton" type="Button" parent="TabContainer/VFlowContainer"] +layout_mode = 2 +text = "Добавить блок"