diff --git a/Scripts/data.gd b/Scripts/data.gd index 41885b3..3a9abcd 100644 --- a/Scripts/data.gd +++ b/Scripts/data.gd @@ -42,6 +42,13 @@ static var rarity_colors: Array[Color] = [ Color8(181, 36, 204), Color8(225, 112, 30), ] +static var slot_prices: Array[int] = [ + 10, + 15, + 20, + 25, + 30, +] ## Recursively searches a folder for any Card resources and loads them diff --git a/drag_n_drop_container.gd b/drag_n_drop_container.gd new file mode 100644 index 0000000..6f01da8 --- /dev/null +++ b/drag_n_drop_container.gd @@ -0,0 +1,84 @@ +class_name DragNDropContainer +extends MarginContainer + +signal dropped(dropped_node: Control, dropped_from: DragNDropContainer) + +@export var panel: PanelContainer +@export var panel_label: Label +@export var finite_contents: bool = true +@export var contents: Control +@export var drag_parent: Node + +var dragging: bool = false +var drag_node: Control + + +func _ready() -> void: + if contents: + panel.move_to_front() + panel.visible = false + + +func _process(_delta: float) -> void: + if dragging: + drag_node.position = get_viewport().get_mouse_position() + + +func _gui_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + if event.pressed == true and event.button_index == 1: + start_drag() + if event.pressed == false and event.button_index == 1: + end_drag() + + +func set_label(text: String) -> void: + panel_label.text = text + + +func set_immutable_contents(new_contents: Control) -> void: + if contents: + remove_child(contents) + contents = null + finite_contents = false + contents = new_contents.duplicate() + add_child(contents) + panel.move_to_front() + panel.visible = false + + +func add_contents(new_contents: Control) -> void: + if finite_contents: + remove_contents() + contents = new_contents.duplicate() + add_child(contents) + panel.move_to_front() + panel.visible = false + + +func remove_contents() -> void: + if finite_contents: + remove_child(contents) + contents = null + panel.visible = true + + +func start_drag() -> void: + if !contents: + return + drag_node = contents.duplicate() + drag_parent.add_child(drag_node) + drag_node.size = Vector2.ZERO + drag_node.mouse_filter = Control.MOUSE_FILTER_IGNORE + panel.visible = true + panel_label.visible = false + dragging = true + + +func end_drag() -> void: + if !contents: + return + panel.visible = false + dragging = false + dropped.emit(drag_node, self) + drag_node.queue_free() diff --git a/drag_n_drop_container.gd.uid b/drag_n_drop_container.gd.uid new file mode 100644 index 0000000..5fa82e4 --- /dev/null +++ b/drag_n_drop_container.gd.uid @@ -0,0 +1 @@ +uid://c75aw4btsld8n diff --git a/drag_n_drop_container.tscn b/drag_n_drop_container.tscn new file mode 100644 index 0000000..806c654 --- /dev/null +++ b/drag_n_drop_container.tscn @@ -0,0 +1,34 @@ +[gd_scene load_steps=3 format=3 uid="uid://dik1j1w8vrul5"] + +[ext_resource type="Script" uid="uid://c75aw4btsld8n" path="res://drag_n_drop_container.gd" id="1_4pe2q"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_xvy6u"] +bg_color = Color(0, 0, 0, 0.25) + +[node name="DragNDropContainer" type="MarginContainer" node_paths=PackedStringArray("panel", "panel_label", "drag_parent")] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 +mouse_filter = 0 +script = ExtResource("1_4pe2q") +panel = NodePath("PanelContainer") +panel_label = NodePath("PanelContainer/Label") +drag_parent = NodePath("DragParent") + +[node name="PanelContainer" type="PanelContainer" parent="."] +layout_mode = 2 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_xvy6u") + +[node name="Label" type="Label" parent="PanelContainer"] +layout_mode = 2 +size_flags_vertical = 1 +text = "PRICE" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="DragParent" type="Node" parent="."] diff --git a/price_panel.gd b/price_panel.gd new file mode 100644 index 0000000..c1f8a3d --- /dev/null +++ b/price_panel.gd @@ -0,0 +1,8 @@ +class_name PricePanel +extends PanelContainer + +@export var label: Label + + +func set_price(price: int) -> void: + label.text = "$" + str(price) diff --git a/price_panel.gd.uid b/price_panel.gd.uid new file mode 100644 index 0000000..108f5e7 --- /dev/null +++ b/price_panel.gd.uid @@ -0,0 +1 @@ +uid://bs73eocafngiu diff --git a/price_panel.tscn b/price_panel.tscn new file mode 100644 index 0000000..daf854c --- /dev/null +++ b/price_panel.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=3 format=3 uid="uid://dekexkjl37dvh"] + +[ext_resource type="Script" uid="uid://bs73eocafngiu" path="res://price_panel.gd" id="1_sn84y"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_517dt"] +bg_color = Color(0.2702219, 0.27022195, 0.27022177, 0.09019608) +corner_detail = 1 + +[node name="Control" type="PanelContainer" node_paths=PackedStringArray("label")] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 +theme_override_styles/panel = SubResource("StyleBoxFlat_517dt") +script = ExtResource("1_sn84y") +label = NodePath("Label") + +[node name="Label" type="Label" parent="."] +layout_mode = 2 +text = "$15" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/remix_table.gd b/remix_table.gd index d7b7cb8..628bf3e 100644 --- a/remix_table.gd +++ b/remix_table.gd @@ -17,6 +17,7 @@ func _on_static_body_3d_button_interacted(_value: int, callback: Hero) -> void: var card_array: Array[Card] = [] for card: Card in callback.hand.contents: card_array.append(card) + menu.hero = reply_player menu.populate_feature_slots() menu.add_option(card_array) menu.cards_remixed.connect(output) @@ -24,10 +25,11 @@ func _on_static_body_3d_button_interacted(_value: int, callback: Hero) -> void: reply_player.hud.add_child(menu) -func output(cards_to_remove: Array[Card], cards_to_add: Array[Card]) -> void: +func output(cards_to_remove: Array[Card], cards_to_add: Array[Card], amount_spent: int) -> void: for card: Card in cards_to_remove: reply_player.hand.contents.erase(card) reply_player.check_removal() for card: Card in cards_to_add: reply_player.add_card(card) + reply_player.currency -= amount_spent reply_player.unpause() diff --git a/test_ui.gd b/test_ui.gd new file mode 100644 index 0000000..e79e579 --- /dev/null +++ b/test_ui.gd @@ -0,0 +1,39 @@ +extends PanelContainer + + +var hovered_slot: DragNDropContainer + +@export var slots: Array[DragNDropContainer] +@export var other_slots: Array[DragNDropContainer] +@export var features: Array[Feature] +@export var feature_ui: PackedScene + + +func _ready() -> void: + for slot: DragNDropContainer in slots: + slot.mouse_entered.connect(hover_slot.bind(slot)) + slot.mouse_exited.connect(unhover_slot) + slot.dropped.connect(drop_slot) + var x: int = 0 + for slot: DragNDropContainer in other_slots: + var new_feature_ui: FeatureUI = feature_ui.instantiate() as FeatureUI + new_feature_ui.set_feature(features[x]) + slot.set_immutable_contents(new_feature_ui) + slot.mouse_entered.connect(hover_slot.bind(slot)) + slot.mouse_exited.connect(unhover_slot) + slot.dropped.connect(drop_slot) + x += 1 + + +func drop_slot(dropped_ui: Control, from: DragNDropContainer) -> void: + if hovered_slot: + from.remove_contents() + hovered_slot.add_contents(dropped_ui) + + +func hover_slot(slot: DragNDropContainer) -> void: + hovered_slot = slot + + +func unhover_slot() -> void: + hovered_slot = null diff --git a/test_ui.gd.uid b/test_ui.gd.uid new file mode 100644 index 0000000..e2c563c --- /dev/null +++ b/test_ui.gd.uid @@ -0,0 +1 @@ +uid://cdrpqvf37mehj diff --git a/test_ui.tscn b/test_ui.tscn new file mode 100644 index 0000000..f06704d --- /dev/null +++ b/test_ui.tscn @@ -0,0 +1,54 @@ +[gd_scene load_steps=7 format=3 uid="uid://da471yc1kajfo"] + +[ext_resource type="Script" uid="uid://cdrpqvf37mehj" path="res://test_ui.gd" id="1_3tn64"] +[ext_resource type="PackedScene" uid="uid://dik1j1w8vrul5" path="res://drag_n_drop_container.tscn" id="1_w4nob"] +[ext_resource type="PackedScene" uid="uid://c8xdsg6gtwvh3" path="res://feature_ui.tscn" id="2_3tn64"] +[ext_resource type="Script" uid="uid://bsuinotkvh7eu" path="res://Scripts/Resources/feature.gd" id="2_w3nqu"] +[ext_resource type="Resource" uid="uid://dfup264h2pun7" path="res://Scripts/Features/HeavyRounds/heavy_rounds_feature.tres" id="3_55qp5"] +[ext_resource type="Resource" uid="uid://nh7g23b3rnvr" path="res://Scripts/Features/Radar/radar_feature.tres" id="4_mlaor"] + +[node name="Control" type="PanelContainer" node_paths=PackedStringArray("slots", "other_slots")] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = 200.0 +offset_top = 100.0 +offset_right = -200.0 +offset_bottom = -100.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_3tn64") +slots = [NodePath("VBoxContainer/HBoxContainer/DragNDropContainer"), NodePath("VBoxContainer/HBoxContainer/DragNDropContainer2"), NodePath("VBoxContainer/HBoxContainer/DragNDropContainer3")] +other_slots = [NodePath("VBoxContainer/HBoxContainer2/DragNDropContainer"), NodePath("VBoxContainer/HBoxContainer2/DragNDropContainer2")] +features = Array[ExtResource("2_w3nqu")]([ExtResource("3_55qp5"), ExtResource("4_mlaor")]) +feature_ui = ExtResource("2_3tn64") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="DragNDropContainer" parent="VBoxContainer/HBoxContainer" instance=ExtResource("1_w4nob")] +layout_mode = 2 + +[node name="DragNDropContainer2" parent="VBoxContainer/HBoxContainer" instance=ExtResource("1_w4nob")] +layout_mode = 2 + +[node name="DragNDropContainer3" parent="VBoxContainer/HBoxContainer" instance=ExtResource("1_w4nob")] +layout_mode = 2 + +[node name="HBoxContainer2" type="HBoxContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="DragNDropContainer" parent="VBoxContainer/HBoxContainer2" node_paths=PackedStringArray("contents") instance=ExtResource("1_w4nob")] +layout_mode = 2 +finite_contents = false +contents = NodePath("") + +[node name="DragNDropContainer2" parent="VBoxContainer/HBoxContainer2" node_paths=PackedStringArray("contents") instance=ExtResource("1_w4nob")] +layout_mode = 2 +finite_contents = false +contents = NodePath("") diff --git a/track_editor.gd b/track_editor.gd index ac4c8bf..a322760 100644 --- a/track_editor.gd +++ b/track_editor.gd @@ -1,7 +1,7 @@ class_name TrackEditor extends Control -signal cards_remixed(cards_consumed: Array[Card], cards_created: Array[Card]) +signal cards_remixed(cards_consumed: Array[Card], cards_created: Array[Card], amount_spent: int) @export var drag_feature: FeatureUI @export var sample_library: VBoxContainer @@ -11,9 +11,12 @@ signal cards_remixed(cards_consumed: Array[Card], cards_created: Array[Card]) @export var drop_down: OptionButton @export var card_desc: CardDescriptionUI @export var check_button: CheckButton +@export var price_panel_scene: PackedScene +@export var price_label: Label const FEATURE_SLOTS: int = 6 +var hero: Hero var dragging: bool = false var hovered_feature: Feature var hovered_drop_slot: int = -2 @@ -21,11 +24,14 @@ var hovered_drop_track: int = 0 var tower_feature_uis: Array[FeatureUI] var weapon_feature_uis: Array[FeatureUI] var features_list: Array[Feature] -var tower_slots: Array[VBoxContainer] -var weapon_slots: Array[VBoxContainer] +var tower_slots: Array[MarginContainer] +var weapon_slots: Array[MarginContainer] +var tower_prices: Array[PricePanel] +var weapon_prices: Array[PricePanel] var cards: Array[Card] var card_selected: Card var temp_card: Card +var cost: int = 0 func _ready() -> void: @@ -36,6 +42,7 @@ func _ready() -> void: weapon_parts.mouse_entered.connect(set_hovered_drop_slot.bind(-1, 1)) tower_parts.mouse_exited.connect(unset_hovered_drop_slot) weapon_parts.mouse_exited.connect(unset_hovered_drop_slot) + price_label.text = "$" + str(cost) func _process(_delta: float) -> void: @@ -106,26 +113,38 @@ func populate_sample_library() -> void: func populate_feature_slots() -> void: for x: int in FEATURE_SLOTS: - var vbox: VBoxContainer = VBoxContainer.new() + var vbox: MarginContainer = MarginContainer.new() vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL vbox.mouse_filter = Control.MOUSE_FILTER_STOP vbox.mouse_entered.connect(set_hovered_drop_slot.bind(tower_slots.size(), 0)) vbox.mouse_exited.connect(unset_hovered_drop_slot) tower_parts.add_child(vbox) tower_slots.append(vbox) + if x != 0: + var panel: PricePanel = price_panel_scene.instantiate() as PricePanel + panel.set_price(Data.slot_prices[x - 1]) + vbox.add_child(panel) + tower_prices.append(panel) for x: int in FEATURE_SLOTS: - var vbox: VBoxContainer = VBoxContainer.new() + var vbox: MarginContainer = MarginContainer.new() vbox.size_flags_horizontal = Control.SIZE_EXPAND_FILL vbox.mouse_filter = Control.MOUSE_FILTER_STOP vbox.mouse_entered.connect(set_hovered_drop_slot.bind(weapon_slots.size(), 1)) vbox.mouse_exited.connect(unset_hovered_drop_slot) weapon_parts.add_child(vbox) weapon_slots.append(vbox) + if x != 0: + var panel: PricePanel = price_panel_scene.instantiate() as PricePanel + panel.set_price(Data.slot_prices[x - 1]) + vbox.add_child(panel) + weapon_prices.append(panel) func add_feature(feature: Feature, track: int, modify_resource: bool = true) -> void: + if hovered_drop_slot == 0: + return if track == 0: - if hovered_drop_slot >= 0 and hovered_drop_slot < tower_feature_uis.size(): + if hovered_drop_slot > 0 and hovered_drop_slot < tower_feature_uis.size(): change_feature(tower_feature_uis[hovered_drop_slot], feature, 0) elif tower_feature_uis.size() < FEATURE_SLOTS: var feature_visual: FeatureUI = feature_scene.instantiate() @@ -134,9 +153,14 @@ func add_feature(feature: Feature, track: int, modify_resource: bool = true) -> tower_feature_uis.append(feature_visual) if modify_resource: temp_card.tower_stats.features.append(feature) + tower_prices[tower_feature_uis.size() - 2].visible = false + cost += Data.slot_prices[tower_feature_uis.size() - 2] + price_label.text = "$" + str(cost) card_desc.set_card(temp_card, check_button.button_pressed) + if cost > hero.currency: + $PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/Controls/ConfirmButton.disabled = true elif track == 1: - if hovered_drop_slot >= 0 and hovered_drop_slot < weapon_feature_uis.size(): + if hovered_drop_slot > 0 and hovered_drop_slot < weapon_feature_uis.size(): change_feature(weapon_feature_uis[hovered_drop_slot], feature, 1) elif weapon_feature_uis.size() < FEATURE_SLOTS: var feature_visual: FeatureUI = feature_scene.instantiate() @@ -145,7 +169,12 @@ func add_feature(feature: Feature, track: int, modify_resource: bool = true) -> weapon_feature_uis.append(feature_visual) if modify_resource: temp_card.weapon_stats.features.append(feature) + weapon_prices[weapon_feature_uis.size() - 2].visible = false + cost += Data.slot_prices[weapon_feature_uis.size() - 2] + price_label.text = "$" + str(cost) card_desc.set_card(temp_card, check_button.button_pressed) + if cost > hero.currency: + $PanelContainer/VBoxContainer/InfoPanel/VBoxContainer2/Controls/ConfirmButton.disabled = true func change_feature(existing_feature: FeatureUI, new_feature: Feature, track: int) -> void: @@ -193,7 +222,7 @@ func unset_hovered_drop_slot() -> void: func _on_cancel_button_pressed() -> void: var cards_to_remove: Array[Card] = [] var cards_to_add: Array[Card] = [] - cards_remixed.emit(cards_to_remove, cards_to_add) + cards_remixed.emit(cards_to_remove, cards_to_add, 0) queue_free() @@ -202,7 +231,7 @@ func _on_confirm_button_pressed() -> void: var cards_to_add: Array[Card] = [] cards_to_remove.append(card_selected) cards_to_add.append(temp_card) - cards_remixed.emit(cards_to_remove, cards_to_add) + cards_remixed.emit(cards_to_remove, cards_to_add, cost) queue_free() diff --git a/track_editor.tscn b/track_editor.tscn index d24181c..546d88c 100644 --- a/track_editor.tscn +++ b/track_editor.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=4 format=3 uid="uid://bajli4d3nqwll"] +[gd_scene load_steps=5 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="PackedScene" uid="uid://dekexkjl37dvh" path="res://price_panel.tscn" id="3_48m6c"] [ext_resource type="PackedScene" uid="uid://cmlpmr78tmo6p" path="res://card_description_ui.tscn" id="3_q6wwl"] -[node name="Control" type="Control" node_paths=PackedStringArray("drag_feature", "sample_library", "tower_parts", "weapon_parts", "drop_down", "card_desc", "check_button")] +[node name="Control" type="Control" node_paths=PackedStringArray("drag_feature", "sample_library", "tower_parts", "weapon_parts", "drop_down", "card_desc", "check_button", "price_label")] layout_mode = 3 anchors_preset = 15 anchor_right = 1.0 @@ -20,6 +21,8 @@ weapon_parts = NodePath("PanelContainer/VBoxContainer/VBoxContainer/WeaponTrack/ drop_down = NodePath("PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge/CassetteSelector/OptionButton") card_desc = NodePath("PanelContainer/VBoxContainer/InfoPanel/VBoxContainer/DescriptionVBox") check_button = NodePath("PanelContainer/VBoxContainer/InfoPanel/VBoxContainer/CheckButton") +price_panel_scene = ExtResource("3_48m6c") +price_label = NodePath("PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge/MarginContainer/Label") [node name="PanelContainer" type="PanelContainer" parent="."] layout_mode = 1 @@ -72,6 +75,12 @@ alignment = 1 layout_mode = 2 size_flags_horizontal = 3 +[node name="Label" type="Label" parent="PanelContainer/VBoxContainer/VBoxContainer/SourceCartridge/MarginContainer"] +layout_mode = 2 +size_flags_vertical = 1 +horizontal_alignment = 1 +vertical_alignment = 1 + [node name="SourceCartridge2" type="HBoxContainer" parent="PanelContainer/VBoxContainer/VBoxContainer"] layout_mode = 2