add predefined buildings

This commit is contained in:
Dmitriy Pleshevskiy 2024-01-08 01:07:56 +03:00
parent a811ec65f0
commit 8023498fa7
Signed by: pleshevskiy
GPG Key ID: 79C4487B44403985
14 changed files with 350 additions and 235 deletions

View File

@ -89,8 +89,8 @@
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
# godot4 --headless --export-release "Linux/X11" mindustry-tools
godot4 --headless --export-debug "Linux/X11" mindustry-tools
'';
installPhase = ''

View File

@ -12,7 +12,7 @@ config_version=5
config/name="MindustryTools"
config/version="0.0.1"
run/main_scene="res://src/energy/EnergyTable.tscn"
run/main_scene="res://src/EnergyTable.tscn"
config/features=PackedStringArray("4.2", "GL Compatibility")
boot_splash/show_image=false
boot_splash/fullsize=false

40
src/BuildingOption.gd Normal file
View File

@ -0,0 +1,40 @@
extends Control
const BuildingOptionItem = preload("res://src/BuildingOptionItem.gd")
const buildings_json = preload("res://src/Buildings.tres")
signal selected(item: BuildingOptionItem)
@onready var option_button: OptionButton = $OptionButton;
var selected_option: BuildingOptionItem = null
var options: Array[BuildingOptionItem] = []
func select(selected_id: int):
option_button.selected = option_button.get_item_index(selected_id)
for option in options:
if option.id == selected_id:
selected_option = option
selected.emit(option)
func _ready():
for building_group in buildings_json.data:
option_button.add_separator(building_group.group)
for building in building_group.children:
options.append(BuildingOptionItem.new(building))
option_button.add_item("{label} ({energy} ⚡)".format(building), building.id)
option_button.selected = -1
func _on_option_button_item_selected(index):
var selected_id = option_button.get_item_id(index)
for option in options:
if option.id == selected_id:
print("selected item: %s (id: %s, energy: %s)" % [option.label, option.id, option.energy])
selected_option = option
selected.emit(option)
break

13
src/BuildingOption.tscn Normal file
View File

@ -0,0 +1,13 @@
[gd_scene load_steps=2 format=3 uid="uid://bedenbuamujfg"]
[ext_resource type="Script" path="res://src/BuildingOption.gd" id="1_m7cva"]
[node name="BuildingOption" type="HBoxContainer"]
size_flags_horizontal = 3
script = ExtResource("1_m7cva")
[node name="OptionButton" type="OptionButton" parent="."]
layout_mode = 2
size_flags_horizontal = 3
[connection signal="item_selected" from="OptionButton" to="." method="_on_option_button_item_selected"]

View File

@ -0,0 +1,8 @@
var id: int
var label: String
var energy: int
func _init(data: Dictionary):
id = data["id"]
label = data["label"]
energy = data["energy"]

83
src/Buildings.tres Normal file
View File

@ -0,0 +1,83 @@
[gd_resource type="JSON" format=3 uid="uid://demufg6yeo1b6"]
[resource]
data = [{
"children": [{
"energy": 180.0,
"id": 1.0,
"label": "Турбинный конденсатор"
}],
"group": "Электричество"
}, {
"children": [{
"energy": -30.0,
"id": 101.0,
"label": "Жерловой конденсатор"
}, {
"energy": -11.0,
"id": 102.0,
"label": "Дробитель скал"
}, {
"energy": -9.0,
"id": 103.0,
"label": "Плазменный бур"
}, {
"energy": -160.0,
"id": 104.0,
"label": "Ударная дрель"
}],
"group": "Добыча"
}, {
"children": [{
"energy": -360.0,
"id": 201.0,
"label": "Кремнивая дуговая печь"
}, {
"energy": -60.0,
"id": 202.0,
"label": "Электролизер"
}],
"group": "Заводы"
}, {
"children": [{
"energy": -30.0,
"id": 301.0,
"label": "Грузовая катапульта"
}, {
"energy": -120.0,
"id": 302.0,
"label": "Грузовой разгрузчик"
}, {
"energy": -120.0,
"id": 303.0,
"label": "Конструктор"
}, {
"energy": -120.0,
"id": 304.0,
"label": "Конструктор танков"
}, {
"energy": -180.0,
"id": 305.0,
"label": "Рефабрикатор танков"
}, {
"energy": -120.0,
"id": 306.0,
"label": "Конструктор кораблей"
}, {
"energy": -120.0,
"id": 307.0,
"label": "Конструктор мехов"
}, {
"energy": -150.0,
"id": 308.0,
"label": "Рефабрикатор мехов"
}],
"group": "Техника"
}, {
"children": [{
"energy": -36.0,
"id": 401.0,
"label": "Радар"
}],
"group": "Разное"
}]

103
src/EnergyTable.gd Normal file
View File

@ -0,0 +1,103 @@
extends Control
const table_row = preload("res://src/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"].total_energy
total_energy_label.text = str(total_energy)
func add_row(data_row: Dictionary):
data.append(data_row)
var instance = table_row.instantiate()
if data_row["building_id"]:
instance.building_id = data_row["building_id"]
if data_row["building_count"]:
instance.building_count = data_row["building_count"]
table_body.add_child(instance)
instance.add_to_group("Persist")
instance.total_energy_changed.connect(_on_total_energy_changed)
instance.deleted.connect(_on_table_row_deleted)
data_row["instance"] = instance
func del_row(node: Node):
table_body.remove_child(node)
for i in range(0, data.size()):
var data_row = data[i]
if data_row["instance"] == node:
data.pop_at(i)
break
func load_data():
if not FileAccess.file_exists("user://energy_table.save"):
return
var save_nodes = get_tree().get_nodes_in_group("Persist")
for node in save_nodes:
del_row(node)
var save_data_file = FileAccess.open("user://energy_table.save", FileAccess.READ)
while save_data_file.get_position() < save_data_file.get_length():
var json_string = save_data_file.get_line()
var json = JSON.new()
var parse_result = json.parse(json_string)
if not parse_result == OK:
print("JSON Parse Error: ", json.get_error_message(), " in ", json_string, " at line ", json.get_error_line())
continue
var node_data = json.get_data()
add_row(node_data)
func save_data():
var save_data_file = FileAccess.open("user://energy_table.save", FileAccess.WRITE)
var save_nodes = get_tree().get_nodes_in_group("Persist")
for node in save_nodes:
print(node.name)
if node.scene_file_path.is_empty():
print("persistent node '%s' is not an instanced scene, skipped" % node.name)
continue
if !node.has_method("get_save_data"):
print("persistent node '%s' is missing a get_save_data() function, skipped" % node.name)
continue
var node_data = node.call("get_save_data")
var json_string = JSON.stringify(node_data)
save_data_file.store_line(json_string)
func _ready():
# Add initial empty row
load_data()
if data.is_empty():
add_row({})
render_total_energy_label()
func _on_total_energy_changed(_value: int):
render_total_energy_label()
save_data()
func _on_table_row_deleted(instance: Node):
del_row(instance)
render_total_energy_label()
save_data()
func _on_add_building_button_pressed():
add_row({})

View File

@ -1,6 +1,6 @@
[gd_scene load_steps=2 format=3 uid="uid://cbegq3jfbfb6t"]
[ext_resource type="Script" path="res://src/energy/EnergyTable.gd" id="1_k0c5x"]
[ext_resource type="Script" path="res://src/EnergyTable.gd" id="1_k0c5x"]
[node name="EnergyTable" type="Control"]
layout_mode = 3
@ -30,11 +30,6 @@ 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
@ -64,10 +59,6 @@ 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

54
src/EnergyTableRow.gd Normal file
View File

@ -0,0 +1,54 @@
extends HBoxContainer
const BuildingOptionItem = preload("res://src/BuildingOptionItem.gd")
signal deleted(instance: Node)
signal total_energy_changed(new_value: int)
@export var building_id: int
@export var building_count: int = 1
@onready var building_option = $BuildingOption
@onready var building_count_line_edit: LineEdit = $BuildingCountLineEdit
@onready var total_energy_label: Label = $HBoxContainer/EnergyLabel
var building: BuildingOptionItem
var total_energy: int:
get:
return total_energy
set(value):
if value != total_energy:
total_energy = value
total_energy_changed.emit(value)
total_energy_label.text = str(total_energy)
func render_energy():
total_energy = building_count * (building.energy if building else 0)
func _ready():
building_count_line_edit.text = str(building_count)
if building_id:
building_option.select(building_id)
render_energy()
func _on_unit_count_line_edit_text_changed(new_text):
building_count = int(new_text)
render_energy()
func _on_delete_row_button_pressed():
deleted.emit(self)
func _on_building_option_selected(item: BuildingOptionItem):
building = item
render_energy()
func get_save_data() -> Dictionary:
return {
"building_id": building.id if building else null,
"building_count": building_count,
}

45
src/EnergyTableRow.tscn Normal file
View File

@ -0,0 +1,45 @@
[gd_scene load_steps=3 format=3 uid="uid://cvc75dbbiut78"]
[ext_resource type="Script" path="res://src/EnergyTableRow.gd" id="1_ptpv1"]
[ext_resource type="PackedScene" uid="uid://bedenbuamujfg" path="res://src/BuildingOption.tscn" id="2_7rmkk"]
[node name="EnergyTableRow" type="HBoxContainer"]
anchors_preset = 10
anchor_right = 1.0
offset_bottom = 35.0
grow_horizontal = 2
script = ExtResource("1_ptpv1")
[node name="BuildingOption" parent="." instance=ExtResource("2_7rmkk")]
layout_mode = 2
[node name="BuildingCountLineEdit" 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="selected" from="BuildingOption" to="." method="_on_building_option_selected"]
[connection signal="text_changed" from="BuildingCountLineEdit" to="." method="_on_unit_count_line_edit_text_changed"]
[connection signal="pressed" from="HBoxContainer/DeleteRowButton" to="." method="_on_delete_row_button_pressed"]

View File

@ -1,45 +0,0 @@
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)

View File

@ -1,35 +0,0 @@
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

View File

@ -1,110 +0,0 @@
[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"]

View File

@ -1,32 +0,0 @@
[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 = "Добавить блок"