added new track editor ui

This commit is contained in:
2025-10-20 18:30:21 +11:00
parent a105c2a5c1
commit d4cf1d91e8
12 changed files with 319 additions and 28 deletions

Binary file not shown.

View File

@@ -588,6 +588,18 @@ msgstr "%Interact% Buy {Card_Name} for ${Card_Cost}"
msgid "LABEL_WAVE" msgid "LABEL_WAVE"
msgstr "Wave {Wave_Number}:" msgstr "Wave {Wave_Number}:"
msgid "LABEL_CASSETTE_SELECTOR"
msgstr "Cassette"
msgid "FEATURE_NAME_RADAR"
msgstr "Radar"
msgid "FEATURE_NAME_HEAVY_ROUNDS"
msgstr "Heavy Rounds"
msgid "FEATURE_NAME_EXTENDED_BARREL"
msgstr "Extended Barrel"
#, fuzzy #, fuzzy
#~| msgid "LABEL_DISPLAY_NAME" #~| msgid "LABEL_DISPLAY_NAME"
#~ msgid "LABEL_CARD_NAME" #~ msgid "LABEL_CARD_NAME"

View File

@@ -551,3 +551,15 @@ msgstr ""
#: UI/enemybox.gd #: UI/enemybox.gd
msgid "LABEL_WAVE" msgid "LABEL_WAVE"
msgstr "" msgstr ""
msgid "LABEL_CASSETTE_SELECTOR"
msgstr ""
msgid "FEATURE_NAME_RADAR"
msgstr ""
msgid "FEATURE_NAME_HEAVY_ROUNDS"
msgstr ""
msgid "FEATURE_NAME_EXTENDED_BARREL"
msgstr ""

View File

@@ -73,7 +73,7 @@ function = 15
[resource] [resource]
code = "shader_type spatial; code = "shader_type spatial;
render_mode blend_mix, depth_draw_always, cull_back, diffuse_lambert, specular_schlick_ggx, depth_prepass_alpha; render_mode blend_mix, depth_draw_always, depth_test_default, cull_back, diffuse_lambert, specular_schlick_ggx, depth_prepass_alpha;
uniform sampler2D Texture2DParameter : source_color, filter_nearest; uniform sampler2D Texture2DParameter : source_color, filter_nearest;
uniform sampler2D tex_frg_7; uniform sampler2D tex_frg_7;
@@ -147,7 +147,7 @@ void fragment() {
" "
modes/depth_draw = 1 modes/depth_draw = 1
flags/depth_prepass_alpha = true flags/depth_prepass_alpha = true
preview_params/Texture2DParameter = "Resource(\"res://Scenes/TowerBase/funboxtex.png\")" preview_params/Texture2DParameter = "Resource(\"uid://bmor4v4j7krgh\", \"res://Scenes/TowerBase/funboxtex.png\")"
preview_params/Float = "1.0" preview_params/Float = "1.0"
nodes/fragment/0/position = Vector2(1220, 280) nodes/fragment/0/position = Vector2(1220, 280)
nodes/fragment/2/node = SubResource("VisualShaderNodeInput_nxokf") nodes/fragment/2/node = SubResource("VisualShaderNodeInput_nxokf")

View File

@@ -7,7 +7,6 @@
[resource] [resource]
script = ExtResource("2_7wr4x") script = ExtResource("2_7wr4x")
target_type = Array[int]([1]) target_type = Array[int]([1])
energy_type = 0
attributes = Dictionary[String, float]({ attributes = Dictionary[String, float]({
"Damage": 2.0, "Damage": 2.0,
"Fire Delay": 0.5, "Fire Delay": 0.5,

View File

@@ -4,7 +4,10 @@ extends VBoxContainer
@export var icon: TextureRect @export var icon: TextureRect
@export var name_label: Label @export var name_label: Label
var feature: Feature
func set_feature(feature: Feature) -> void:
func set_feature(new_feature: Feature) -> void:
feature = new_feature
icon.texture = feature.icon icon.texture = feature.icon
name_label.text = tr(feature.display_name) name_label.text = tr(feature.display_name)

View File

@@ -9,12 +9,14 @@ anchor_right = 1.0
anchor_bottom = 1.0 anchor_bottom = 1.0
grow_horizontal = 2 grow_horizontal = 2
grow_vertical = 2 grow_vertical = 2
alignment = 1
script = ExtResource("1_tms0v") script = ExtResource("1_tms0v")
icon = NodePath("TextureRect") icon = NodePath("TextureRect")
name_label = NodePath("Label") name_label = NodePath("Label")
[node name="TextureRect" type="TextureRect" parent="."] [node name="TextureRect" type="TextureRect" parent="."]
layout_mode = 2 layout_mode = 2
mouse_filter = 2
texture = ExtResource("2_w6jf0") texture = ExtResource("2_w6jf0")
stretch_mode = 5 stretch_mode = 5

View File

@@ -13,7 +13,7 @@ config_version=5
config/name="Decked Out Defense" config/name="Decked Out Defense"
config/version="0.3.0" config/version="0.3.0"
run/main_scene="uid://d2k8y13qfvch0" run/main_scene="uid://d2k8y13qfvch0"
config/features=PackedStringArray("4.4", "Forward Plus") config/features=PackedStringArray("4.5", "Forward Plus")
boot_splash/show_image=false boot_splash/show_image=false
config/icon="res://Assets/Textures/icon.svg" config/icon="res://Assets/Textures/icon.svg"
@@ -56,8 +56,8 @@ import/blender/enabled=false
[gui] [gui]
theme/custom="uid://b6a0ip4p72tgx"
theme/default_font_antialiasing=0 theme/default_font_antialiasing=0
theme/custom="uid://b6a0ip4p72tgx"
[input] [input]

View File

@@ -44,33 +44,17 @@ func set_card_two(option: int) -> void:
func remix() -> void: func remix() -> void:
temp_card_one = Card.new() temp_card_one = card_one.duplicate(true)
temp_card_one.cost = card_one.cost temp_card_one.tower_stats = temp_card_one.tower_stats.duplicate_deep()
temp_card_one.faction = card_one.faction temp_card_one.weapon_stats = temp_card_one.weapon_stats.duplicate_deep()
temp_card_one.rarity = card_one.rarity
temp_card_one.tags = card_one.tags
temp_card_one.icon = card_one.icon
temp_card_one.display_name = card_one.display_name
temp_card_one.turret_scene = card_one.turret_scene
temp_card_one.weapon_scene = card_one.weapon_scene
temp_card_one.tower_stats = card_one.tower_stats.duplicate()
temp_card_one.weapon_stats = card_one.weapon_stats.duplicate()
for feature: Feature in card_two.tower_stats.features: for feature: Feature in card_two.tower_stats.features:
temp_card_one.tower_stats.features.append(feature) temp_card_one.tower_stats.features.append(feature)
for feature: Feature in card_two.weapon_stats.features: for feature: Feature in card_two.weapon_stats.features:
temp_card_one.weapon_stats.features.append(feature) temp_card_one.weapon_stats.features.append(feature)
temp_card_two = Card.new() temp_card_two = card_two.duplicate(true)
temp_card_two.cost = card_two.cost temp_card_two.tower_stats = temp_card_two.tower_stats.duplicate_deep()
temp_card_two.faction = card_two.faction temp_card_two.weapon_stats = temp_card_two.weapon_stats.duplicate_deep()
temp_card_two.rarity = card_two.rarity
temp_card_two.tags = card_two.tags
temp_card_two.icon = card_two.icon
temp_card_two.display_name = card_two.display_name
temp_card_two.turret_scene = card_two.turret_scene
temp_card_two.weapon_scene = card_two.weapon_scene
temp_card_two.tower_stats = card_two.tower_stats.duplicate()
temp_card_two.weapon_stats = card_two.weapon_stats.duplicate()
for feature: Feature in card_one.tower_stats.features: for feature: Feature in card_one.tower_stats.features:
temp_card_two.tower_stats.features.append(feature) temp_card_two.tower_stats.features.append(feature)
for feature: Feature in card_one.weapon_stats.features: for feature: Feature in card_one.weapon_stats.features:

124
track_editor.gd Normal file
View File

@@ -0,0 +1,124 @@
class_name TrackEditor
extends Control
@export var drag_feature: FeatureUI
@export var sample_library: VBoxContainer
@export var feature_scene: PackedScene
@export var features_list: Array[Feature]
@export var parts: HBoxContainer
var dragging: bool = false
var hovered_feature: Feature
var hovered_drop_slot: int = -2
var feature_uis: Array[FeatureUI]
var slots: Array[VBoxContainer]
const FEATURE_SLOTS: int = 6
func _ready() -> void:
populate_sample_library()
populate_feature_slots()
parts.mouse_entered.connect(set_hovered_drop_slot.bind(-1))
parts.mouse_exited.connect(unset_hovered_drop_slot)
func _process(_delta: float) -> void:
drag_feature.position = get_viewport().get_mouse_position()
func _input(event: InputEvent) -> void:
if event is InputEventMouseButton:
if event.pressed == true and event.button_index == 1:
if hovered_feature != null:
attach_feat_to_mouse(hovered_feature)
if event.pressed == false and event.button_index == 1:
detach_feat_from_mouse()
func populate_sample_library() -> void:
for x: int in 3:
var hbox: HBoxContainer = HBoxContainer.new()
hbox.size_flags_vertical = Control.SIZE_EXPAND_FILL
for y: int in 3:
var feat: FeatureUI = feature_scene.instantiate() as FeatureUI
feat.set_feature(features_list[x])
feat.mouse_filter = Control.MOUSE_FILTER_PASS
feat.size_flags_horizontal = Control.SIZE_EXPAND_FILL
feat.mouse_entered.connect(set_hovered_feature.bind(feat.feature))
hbox.add_child(feat)
sample_library.add_child(hbox)
sample_library.mouse_exited.connect(unset_hovered_feature)
func populate_feature_slots() -> void:
for x: int in FEATURE_SLOTS:
var vbox: VBoxContainer = VBoxContainer.new()
var label: Label = Label.new()
match slots.size():
0: label.text = tr("SLOT_FIRST")
1: label.text = tr("SLOT_SECOND")
2: label.text = tr("SLOT_THIRD")
3: label.text = tr("SLOT_FOURTH")
4: label.text = tr("SLOT_FIFTH")
5: label.text = tr("SLOT_SIXTH")
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.vertical_alignment = VERTICAL_ALIGNMENT_CENTER
vbox.add_child(label)
vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL
vbox.mouse_filter = Control.MOUSE_FILTER_STOP
vbox.mouse_entered.connect(set_hovered_drop_slot.bind(slots.size()))
vbox.mouse_exited.connect(unset_hovered_drop_slot)
parts.add_child(vbox)
slots.append(vbox)
func add_feature(feature: Feature) -> void:
if hovered_drop_slot >= 0 and hovered_drop_slot < feature_uis.size():
change_feature(feature_uis[hovered_drop_slot], feature)
elif feature_uis.size() < FEATURE_SLOTS:
var feature_visual: FeatureUI = feature_scene.instantiate()
feature_visual.set_feature(feature)
slots[feature_uis.size()].add_child(feature_visual)
feature_uis.append(feature_visual)
func change_feature(existing_feature: FeatureUI, new_feature: Feature) -> void:
existing_feature.set_feature(new_feature)
func attach_feat_to_mouse(feature: Feature) -> void:
drag_feature.set_feature(feature)
drag_feature.visible = true
dragging = true
func detach_feat_from_mouse() -> void:
drag_feature.visible = false
if hovered_drop_slot >= -1 and dragging == true:
add_feature(drag_feature.feature)
dragging = false
func set_hovered_feature(feature: Feature) -> void:
hovered_feature = feature
func unset_hovered_feature() -> void:
hovered_feature = null
func set_hovered_drop_slot(slot: int = -2) -> void:
hovered_drop_slot = slot
func unset_hovered_drop_slot() -> void:
hovered_drop_slot = -2
func _on_cancel_button_pressed() -> void:
queue_free()
func _on_confirm_button_pressed() -> void:
pass # Replace with function body.

1
track_editor.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://mrv5vrlxfc13

154
track_editor.tscn Normal file
View File

@@ -0,0 +1,154 @@
[gd_scene load_steps=7 format=3 uid="uid://bajli4d3nqwll"]
[ext_resource type="PackedScene" uid="uid://c8xdsg6gtwvh3" path="res://feature_ui.tscn" id="1_y6tpq"]
[ext_resource type="Script" uid="uid://mrv5vrlxfc13" path="res://track_editor.gd" id="1_yrnbk"]
[ext_resource type="Script" uid="uid://bsuinotkvh7eu" path="res://Scripts/Resources/feature.gd" id="3_dya4i"]
[ext_resource type="Resource" uid="uid://nh7g23b3rnvr" path="res://Scripts/Features/Radar/radar_feature.tres" id="4_4gmyw"]
[ext_resource type="Resource" uid="uid://dfup264h2pun7" path="res://Scripts/Features/HeavyRounds/heavy_rounds_feature.tres" id="5_dxngn"]
[ext_resource type="Resource" uid="uid://bij61ul87ka0r" path="res://Scripts/Features/ExtendedBarrel/extended_barrel_feature.tres" id="6_1rakx"]
[node name="Control" type="Control" node_paths=PackedStringArray("drag_feature", "sample_library", "parts")]
layout_mode = 3
anchors_preset = 15
anchor_right = 1.0
anchor_bottom = 1.0
grow_horizontal = 2
grow_vertical = 2
script = ExtResource("1_yrnbk")
drag_feature = NodePath("FeatureUI")
sample_library = NodePath("PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/SamplePanel/SampleLibrary")
feature_scene = ExtResource("1_y6tpq")
features_list = Array[ExtResource("3_dya4i")]([ExtResource("4_4gmyw"), ExtResource("5_dxngn"), ExtResource("6_1rakx")])
parts = NodePath("PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge/Parts")
[node name="PanelContainer" type="PanelContainer" parent="."]
layout_mode = 1
anchors_preset = -1
anchor_left = 0.175
anchor_top = 0.05
anchor_right = 0.825
anchor_bottom = 0.95
grow_horizontal = 2
grow_vertical = 2
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer"]
layout_mode = 2
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
text = "TITLE_REMIX"
horizontal_alignment = 1
vertical_alignment = 1
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="SourceCartridge" type="HBoxContainer" parent="PanelContainer/VBoxContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="CassetteSelector" type="VBoxContainer" parent="PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge/CassetteSelector"]
layout_mode = 2
text = "LABEL_CASSETTE_SELECTOR"
horizontal_alignment = 1
vertical_alignment = 1
[node name="OptionButton" type="OptionButton" parent="PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge/CassetteSelector"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Parts" type="HBoxContainer" parent="PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 3.0
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
size_flags_stretch_ratio = 0.1
[node name="InfoPanel" type="HBoxContainer" parent="PanelContainer/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
size_flags_stretch_ratio = 5.0
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/VBoxContainer/InfoPanel"]
layout_mode = 2
size_flags_horizontal = 3
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer"]
layout_mode = 2
text = "LABEL_CARD_DESCRIPTION"
horizontal_alignment = 1
vertical_alignment = 1
[node name="RichTextLabel" type="RichTextLabel" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
bbcode_enabled = true
text = "a long ass example description of a card that goes into honestly way too much detail but at least if we can support a lot of text at a good size then we dont have to worry about really complicated cards fucking up our UI later in developement if we end up needing to explain a lot"
[node name="Label2" type="Label" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer"]
layout_mode = 2
text = "LABEL_TARGET_LIST"
horizontal_alignment = 1
vertical_alignment = 1
[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer"]
layout_mode = 2
size_flags_vertical = 3
[node name="MarginContainer" type="MarginContainer" parent="PanelContainer/VBoxContainer/InfoPanel"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_stretch_ratio = 0.1
[node name="VBoxContainer2" type="VBoxContainer" parent="PanelContainer/VBoxContainer/InfoPanel"]
layout_mode = 2
size_flags_horizontal = 3
[node name="SamplePanel" type="VBoxContainer" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2"]
layout_mode = 2
size_flags_vertical = 3
[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/SamplePanel"]
layout_mode = 2
text = "TITLE_SAMPLES"
horizontal_alignment = 1
vertical_alignment = 1
[node name="SampleLibrary" type="VBoxContainer" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/SamplePanel"]
layout_mode = 2
size_flags_horizontal = 3
size_flags_vertical = 3
[node name="Controls" type="HBoxContainer" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2"]
layout_mode = 2
alignment = 2
[node name="CancelButton" type="Button" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/Controls"]
layout_mode = 2
text = "BUTTON_CANCEL"
[node name="ConfirmButton" type="Button" parent="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/Controls"]
layout_mode = 2
text = "BUTTON_CONFIRM_REMIX"
[node name="FeatureUI" parent="." instance=ExtResource("1_y6tpq")]
visible = false
layout_mode = 0
anchors_preset = 0
anchor_right = 0.0
anchor_bottom = 0.0
grow_horizontal = 1
grow_vertical = 1
mouse_filter = 2
[connection signal="pressed" from="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/Controls/CancelButton" to="." method="_on_cancel_button_pressed"]
[connection signal="pressed" from="PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/Controls/ConfirmButton" to="." method="_on_confirm_button_pressed"]