From d046e04027f5b2003b77e340093ce468764c162c Mon Sep 17 00:00:00 2001 From: Lexi Quinn Date: Wed, 20 Aug 2025 16:58:09 +1000 Subject: [PATCH] added radio and new blank cassette system --- Classes/Engineer/class.tres | 5 +- PCs/FSM/fighting_state.gd | 3 +- PCs/hero.gd | 33 +++++- PCs/hero.tscn | 21 ++-- PCs/hud.gd | 7 ++ Scenes/CardPrinter/card_printer.gd | 30 +++++- Scenes/CardPrinter/card_printer.tscn | 63 ++++++++++-- Scenes/ShopStand/shop_stand.gd | 26 ++++- Scenes/ShopStand/shop_stand.tscn | 50 ++++++++- Scenes/TowerBase/tower_base.gd | 7 +- Scripts/data.gd | 1 - Scripts/game.gd | 15 ++- UI/CardSelectionBox/card_selection_box.gd | 2 + UI/CardSelectionBox/card_selection_box.tscn | 1 - card_placing_tool.gd | 32 +++--- choose_card_screen.gd | 39 +++++++ choose_card_screen.gd.uid | 1 + choose_card_screen.tscn | 108 ++++++++++++++++++++ export_presets.cfg | 8 +- project.godot | 2 +- 20 files changed, 392 insertions(+), 62 deletions(-) create mode 100644 choose_card_screen.gd create mode 100644 choose_card_screen.gd.uid create mode 100644 choose_card_screen.tscn diff --git a/Classes/Engineer/class.tres b/Classes/Engineer/class.tres index 2f347ed..bda4a34 100644 --- a/Classes/Engineer/class.tres +++ b/Classes/Engineer/class.tres @@ -1,9 +1,8 @@ -[gd_resource type="Resource" script_class="HeroClass" load_steps=9 format=3 uid="uid://b5pc3frhx467q"] +[gd_resource type="Resource" script_class="HeroClass" load_steps=8 format=3 uid="uid://b5pc3frhx467q"] [ext_resource type="PackedScene" uid="uid://dq8v5e11rvyi6" path="res://Classes/Engineer/plan.tscn" id="1_2m5d7"] [ext_resource type="Script" uid="uid://d40isem6w5d8" path="res://Scripts/Resources/card.gd" id="1_t4fvj"] [ext_resource type="Resource" uid="uid://deer0awg4d18o" path="res://Cards/assault.tres" id="2_62g46"] -[ext_resource type="Resource" uid="uid://b37r54q84vqoi" path="res://Cards/rocket_launcher.tres" id="4_o2u8f"] [ext_resource type="Texture2D" uid="uid://ctkixdue3o7ec" path="res://Classes/Engineer/red_hand.png" id="6_a8dvt"] [ext_resource type="Script" uid="uid://dcwtg2gev3uia" path="res://Scripts/Resources/hero_class.gd" id="7_ftkad"] [ext_resource type="PackedScene" uid="uid://ciagj1hfn4gou" path="res://Classes/Engineer/podium.tscn" id="7_nyup7"] @@ -14,7 +13,7 @@ script = ExtResource("7_ftkad") hero_name = "Engineer" texture = ExtResource("8_0o0bw") hand_texture = ExtResource("6_a8dvt") -deck = Array[ExtResource("1_t4fvj")]([ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("4_o2u8f"), ExtResource("4_o2u8f"), ExtResource("4_o2u8f")]) +deck = Array[ExtResource("1_t4fvj")]([ExtResource("2_62g46"), ExtResource("2_62g46"), ExtResource("2_62g46")]) faction = 1 podium = ExtResource("7_nyup7") card_item = ExtResource("1_2m5d7") diff --git a/PCs/FSM/fighting_state.gd b/PCs/FSM/fighting_state.gd index 643422e..e6e2b8e 100644 --- a/PCs/FSM/fighting_state.gd +++ b/PCs/FSM/fighting_state.gd @@ -29,7 +29,8 @@ func exit_state() -> void: hero.hud.grow_wave_start_label() #hero.hud.primary_duration.visible = true #hero.hud.secondary_duration.visible = true - hero.hud.energy_label.visible = true + if hero.game_manager.card_gameplay: + hero.hud.energy_label.visible = true func process_state(_delta: float) -> void: diff --git a/PCs/hero.gd b/PCs/hero.gd index 8cbb48a..a45e3b8 100644 --- a/PCs/hero.gd +++ b/PCs/hero.gd @@ -65,6 +65,12 @@ var currency: int = 0 : hud.set_currency_count(value) get: return currency +var blank_cassettes: int = 0 : + set(value): + blank_cassettes = value + hud.set_blank_cassette_count(value) + get(): + return blank_cassettes var energy: int = 0 : set(value): energy = value @@ -75,7 +81,7 @@ var selected_card: Card : set(_value): pass get(): - return unique_cards[hand_selected_index] + return unique_cards[hand_selected_index] if unique_cards.size() > 0 else null func set_zoom_factor(value: float) -> void: @@ -89,7 +95,11 @@ func _ready() -> void: sprite.queue_free() player_name_tag.queue_free() for card: Card in hero_class.deck: - draw_pile.add(card) + if game_manager.card_gameplay: + draw_pile.add(card) + else: + add_card(card) + update_selected_box() else: camera.set_visible(false) gun_camera.set_visible(false) @@ -128,8 +138,15 @@ func add_selection(card: Card) -> void: var box: CardSelectionBox = card_select_scene.instantiate() box.set_card(card) box.set_key(unique_cards.size() - 1) + box.set_amount(1) selection_boxes.append(box) $HUD/selection_boxes.add_child(box) + else: + var box: CardSelectionBox + for existing_box: CardSelectionBox in selection_boxes: + if existing_box.card == card: + box = existing_box + box.set_amount(hand.contents.count(card)) func check_removal() -> void: @@ -346,17 +363,21 @@ func equip_weapon(slot: int = 0) -> void: if hand.size == 0: return var energy_cost: int = selected_card.cost - if energy < energy_cost: + if game_manager.card_gameplay and energy < energy_cost: return if weapons[slot] != null: unequip_weapon(slot) + if !game_manager.card_gameplay: + return if hand.size > 0: - energy -= energy_cost + if game_manager.card_gameplay: + energy -= energy_cost place_card_audio.play() cards[slot] = hand.remove_at(hand.contents.find(selected_card)) #card_sprites[hand_selected_index].queue_free() #card_sprites.remove_at(hand_selected_index) - discard_pile.add(cards[slot]) + if game_manager.card_gameplay: + discard_pile.add(cards[slot]) #TODO: Alternate thing to do with the hand i guess #if !inventory.contents.has(cards[slot]): #decrement_selected() @@ -454,6 +475,8 @@ func unequip_weapon(slot: int = 0) -> void: hud.new_energy_bar.disable_secondary_energy() weapons[slot].queue_free() weapons[slot] = null + if !game_manager.card_gameplay: + add_card(cards[slot]) cards[slot] = null place_card_audio.play() diff --git a/PCs/hero.tscn b/PCs/hero.tscn index a09c393..46ffccc 100644 --- a/PCs/hero.tscn +++ b/PCs/hero.tscn @@ -300,15 +300,15 @@ no_depth_test = true fixed_size = true texture = SubResource("ViewportTexture_m3ots") -[node name="DrawPile" type="Node" parent="."] -script = ExtResource("6_cf5ap") - [node name="Hand" type="Node" parent="."] script = ExtResource("6_cf5ap") [node name="DiscardPile" type="Node" parent="."] script = ExtResource("6_cf5ap") +[node name="DrawPile" type="Node" parent="."] +script = ExtResource("6_cf5ap") + [node name="PlayerMovement" type="Node" parent="." node_paths=PackedStringArray("player", "head", "weapon_holder")] script = ExtResource("20_cfhw8") player = NodePath("..") @@ -319,7 +319,7 @@ max_look_up_angle = 80.0 enable_jumping = true weapon_holder = NodePath("../FirstPersonViewport/Head2/RightHand") -[node name="HUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("player", "wave_count", "lives_count", "currency_count", "minimap_outline", "minimap", "minimap_cam", "minimap_viewport", "fps_label", "hover_text", "enemy_sprites", "enemy_counts", "wave_start_label", "place_icon", "swap_icon", "place_text", "swap_text", "new_energy_bar", "energy_label", "primary_duration", "secondary_duration")] +[node name="HUD" type="CanvasLayer" parent="." node_paths=PackedStringArray("player", "wave_count", "lives_count", "currency_count", "minimap_outline", "minimap", "minimap_cam", "minimap_viewport", "fps_label", "hover_text", "enemy_sprites", "enemy_counts", "wave_start_label", "place_icon", "swap_icon", "place_text", "swap_text", "new_energy_bar", "energy_label", "primary_duration", "secondary_duration", "blank_cassette_label")] script = ExtResource("8_yl6ka") player = NodePath("..") wave_count = NodePath("EnemyTracker/WaveCount") @@ -344,6 +344,7 @@ new_energy_bar = NodePath("EnergyBar") energy_label = NodePath("Currencies/HBoxContainer/EnergyLabel") primary_duration = NodePath("weapon_duration") secondary_duration = NodePath("weapon_duration2") +blank_cassette_label = NodePath("Currencies/BlankCassetteLabel") [node name="FirstPersonCam" type="TextureRect" parent="HUD"] anchors_preset = 15 @@ -775,11 +776,13 @@ texture = SubResource("ViewportTexture_w13oc") [node name="CurrencyCount" type="Label" parent="HUD/Currencies/CoinCounter"] layout_mode = 2 +size_flags_horizontal = 3 text = "20" -horizontal_alignment = 1 +horizontal_alignment = 2 vertical_alignment = 1 [node name="HBoxContainer" type="HBoxContainer" parent="HUD/Currencies"] +visible = false layout_mode = 2 [node name="TextureRect" type="TextureRect" parent="HUD/Currencies/HBoxContainer"] @@ -790,8 +793,14 @@ stretch_mode = 5 [node name="EnergyLabel" type="Label" parent="HUD/Currencies/HBoxContainer"] layout_mode = 2 +size_flags_horizontal = 3 text = "0" -horizontal_alignment = 1 +horizontal_alignment = 2 +vertical_alignment = 1 + +[node name="BlankCassetteLabel" type="Label" parent="HUD/Currencies"] +layout_mode = 2 +horizontal_alignment = 2 vertical_alignment = 1 [node name="WeaponSwapTimer" type="Timer" parent="."] diff --git a/PCs/hud.gd b/PCs/hud.gd index 2a791b4..79452c1 100644 --- a/PCs/hud.gd +++ b/PCs/hud.gd @@ -25,6 +25,7 @@ extends CanvasLayer @export var energy_label: Label @export var primary_duration: Label @export var secondary_duration: Label +@export var blank_cassette_label: Label var last_lives_count: int = 120 var enemy_names: Array[String] @@ -35,6 +36,12 @@ var cards: Array[EnemyCardUI] = [] func _ready() -> void: $StartWaveLabel.theme_type_variation = "WaveStartLabel" $InteractLabel.theme_type_variation = "InteractLabel" + if player.game_manager.card_gameplay: + energy_label.visible = true + + +func set_blank_cassette_count(value: int) -> void: + blank_cassette_label.text = str(value) func show_wave_generation_anim(wave: Wave) -> void: diff --git a/Scenes/CardPrinter/card_printer.gd b/Scenes/CardPrinter/card_printer.gd index 719e729..2b7c7bc 100644 --- a/Scenes/CardPrinter/card_printer.gd +++ b/Scenes/CardPrinter/card_printer.gd @@ -1,6 +1,7 @@ class_name CardPrinter extends StaticBody3D @export var button_collider: CollisionShape3D +@export var card_selection_menu: PackedScene #TODO: use faction enum var base_faction: int = 1 @@ -64,7 +65,20 @@ func randomize_cards(faction: Card.Faction) -> void: pos_x += 1.25 item.pressed.connect(card_picked_up) spawned_cards.append(item) - add_child(item) + + +func find_cards(faction: Card.Faction) -> void: + var decided_rarity: int = generate_rarity() + var card_choices: Array[Card] = get_faction_cards(faction) + var cards: Array[Card] = [] + for card: Card in card_choices: + if card.rarity == decided_rarity: + cards.append(card) + var menu: ChooseCardScreen = card_selection_menu.instantiate() as ChooseCardScreen + menu.add_cards(cards) + menu.card_chosen.connect(output_card) + reply_player.pause() + reply_player.hud.add_child(menu) func card_picked_up(card_item: CardItem) -> void: @@ -77,12 +91,20 @@ func card_picked_up(card_item: CardItem) -> void: $StaticBody3D/AudioStreamPlayer3D.play() +func output_card(card: Card) -> void: + reply_player.add_card(card) + reply_player.unpause() + reply_player = null + button_collider.disabled = false + $StaticBody3D/AudioStreamPlayer3D.play() + + func _on_static_body_3d_button_interacted(_value: int, reply: Hero) -> void: reply_player = reply - if reply.energy >= 8: - reply.energy -= 8 + if reply.blank_cassettes >= 1: + reply.blank_cassettes -= 1 else: return button_collider.disabled = true $StaticBody3D/AudioStreamPlayer3D.play() - randomize_cards(reply.hero_class.faction) + find_cards(reply.hero_class.faction) diff --git a/Scenes/CardPrinter/card_printer.tscn b/Scenes/CardPrinter/card_printer.tscn index a641fed..3745d82 100644 --- a/Scenes/CardPrinter/card_printer.tscn +++ b/Scenes/CardPrinter/card_printer.tscn @@ -1,27 +1,31 @@ -[gd_scene load_steps=8 format=3 uid="uid://1b2ikdanl66b"] +[gd_scene load_steps=9 format=3 uid="uid://1b2ikdanl66b"] [ext_resource type="Script" uid="uid://bivtfdl3p1brv" path="res://Scenes/CardPrinter/card_printer.gd" id="1_qft15"] +[ext_resource type="PackedScene" uid="uid://bcvjgl0s1wp8y" path="res://choose_card_screen.tscn" id="2_kpujb"] [ext_resource type="Script" uid="uid://dkfswql8ui0bt" path="res://Scripts/interact_button.gd" id="4_eavi1"] -[ext_resource type="PackedScene" uid="uid://b6i5w3mowcfcs" path="res://Scenes/DraftingTable/drafting_table.glb" id="4_kpujb"] [ext_resource type="AudioStream" uid="uid://dknygn5eyuhxt" path="res://Audio/shot1.wav" id="5_m033a"] [sub_resource type="BoxShape3D" id="BoxShape3D_0ebt5"] -size = Vector3(2.17, 1.55307, 1.12) +size = Vector3(3.00441, 1.21416, 2.14176) [sub_resource type="BoxShape3D" id="BoxShape3D_ikdwj"] -size = Vector3(2.20033, 0.260753, 1.27008) +size = Vector3(0.57883, 0.375308, 0.190803) [sub_resource type="AudioStreamRandomizer" id="AudioStreamRandomizer_73g2w"] random_pitch = 1.1 streams_count = 1 stream_0/stream = ExtResource("5_m033a") +[sub_resource type="BoxShape3D" id="BoxShape3D_21y4o"] +size = Vector3(2.11176, 1.16345, 0.664978) + [node name="CardPrinter" type="StaticBody3D" node_paths=PackedStringArray("button_collider")] script = ExtResource("1_qft15") button_collider = NodePath("StaticBody3D/CollisionShape3D2") +card_selection_menu = ExtResource("2_kpujb") [node name="CollisionShape3D" type="CollisionShape3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.776539, 0.0332634) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.000722647, 0.607083, -0.000626981) shape = SubResource("BoxShape3D_0ebt5") [node name="StaticBody3D" type="StaticBody3D" parent="."] @@ -29,11 +33,11 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.847404, 0.610684) collision_layer = 16 collision_mask = 0 script = ExtResource("4_eavi1") -press_cost = 8 -hover_text = "[center]#Interact# draft a card for 8 Energy" +press_cost = 1 +hover_text = "[center]#Interact# Record to blank cassette" [node name="CollisionShape3D2" type="CollisionShape3D" parent="StaticBody3D"] -transform = Transform3D(1, 0, 0, 0, 0.866025, -0.5, 0, 0.5, 0.866025, -6.55949e-05, 0.349496, -0.579584) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00542301, 0.653175, 0.254328) shape = SubResource("BoxShape3D_ikdwj") [node name="AudioStreamPlayer3D" type="AudioStreamPlayer3D" parent="StaticBody3D"] @@ -41,7 +45,46 @@ transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.578748, -0.587001) stream = SubResource("AudioStreamRandomizer_73g2w") bus = &"SFX" -[node name="drafting_table" parent="." instance=ExtResource("4_kpujb")] -transform = Transform3D(0.06, 0, 0, 0, 0.06, 0, 0, 0, 0.06, 0, 0.385809, 0) +[node name="CSGBox3D" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.76287, 0.437195) +size = Vector3(2.1, 1.21, 0.66) + +[node name="CSGBox3D2" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.50532, 0.844074) +size = Vector3(0.57, 0.365, 0.22) + +[node name="CSGBox3D3" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.07889, 0) +size = Vector3(3.01, 0.275, 2.145) + +[node name="CSGBox3D4" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.17866, 0.464503, 0.722973) +size = Vector3(0.355, 1, 0.37) + +[node name="CSGBox3D5" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.20564, 0.464503, 0.744042) +size = Vector3(0.355, 1, 0.37) + +[node name="CSGBox3D6" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.21651, 0.464503, -0.703903) +size = Vector3(0.355, 1, 0.37) + +[node name="CSGBox3D7" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.20425, 0.464503, -0.796043) +size = Vector3(0.355, 1, 0.37) + +[node name="CSGCylinder3D" type="CSGCylinder3D" parent="."] +transform = Transform3D(0.791895, -0.610657, 0, 0.610657, 0.791895, 0, 0, 0, 1, -0.894404, 2.86265, 0.47663) +radius = 0.131 +height = 1.627 + +[node name="CSGCylinder3D2" type="CSGCylinder3D" parent="."] +transform = Transform3D(0.74906, 0.662502, 0, -0.662502, 0.74906, 0, 0, 0, 1, 1.08608, 2.86265, 0.47663) +radius = 0.131 +height = 1.627 + +[node name="CollisionShape3D2" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.00228882, 1.78986, 0.431061) +shape = SubResource("BoxShape3D_21y4o") [connection signal="button_interacted" from="StaticBody3D" to="." method="_on_static_body_3d_button_interacted"] diff --git a/Scenes/ShopStand/shop_stand.gd b/Scenes/ShopStand/shop_stand.gd index 61df008..74438cf 100644 --- a/Scenes/ShopStand/shop_stand.gd +++ b/Scenes/ShopStand/shop_stand.gd @@ -5,6 +5,9 @@ class_name ShopStand extends Node3D @export var choice_buttons: Array[InteractButton] @export var choice_sprites: Array[Sprite3D] @export var item_card_scene: PackedScene +@export var blank_button: InteractButton +@export var blank_button_collider: CollisionShape3D +@export var blank_models: Array[CSGBox3D] var price_dict: Dictionary = { Data.Rarity.UNCOMMON : 25, @@ -14,13 +17,18 @@ var price_dict: Dictionary = { } var cards_generated: int = 0 +var blanks_available: int = 5 +var blank_cost: int = 20 func close() -> void: for x: CollisionShape3D in choice_colliders: x.disabled = true for x: Sprite3D in choice_sprites: - x.set_visible(false) + x.visible = false + for x: CSGBox3D in blank_models: + x.visible = false + blank_button_collider.disabled = true func randomize_cards() -> void: @@ -82,7 +90,11 @@ func randomize_cards() -> void: for x: CollisionShape3D in choice_colliders: x.set_deferred("disabled", false) for x: Sprite3D in choice_sprites: - x.set_visible(true) + x.visible = true + for x: CSGBox3D in blank_models: + x.visible = true + blank_button_collider.disabled = false + blank_button.hover_text = "#Interact# Spend $" + str(blank_cost) + " to acquire a blank cassette" func retrieve_card(i: int, callback: Hero) -> void: @@ -101,3 +113,13 @@ func retrieve_card(i: int, callback: Hero) -> void: #add_child(item) #button_collider.disabled = false #button_box.position = Vector3(0,0,0) + + +func retrieve_blank(i: int, callback: Hero) -> void: + if callback.currency >= blank_cost: + blank_models[5 - blanks_available].visible = false + blanks_available -= 1 + callback.currency -= blank_cost + callback.blank_cassettes += 1 + if blanks_available == 0: + blank_button_collider.disabled = true diff --git a/Scenes/ShopStand/shop_stand.tscn b/Scenes/ShopStand/shop_stand.tscn index fd9ae7f..e7062af 100644 --- a/Scenes/ShopStand/shop_stand.tscn +++ b/Scenes/ShopStand/shop_stand.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=16 format=3 uid="uid://7g3jev3v6d3l"] +[gd_scene load_steps=17 format=3 uid="uid://7g3jev3v6d3l"] [ext_resource type="Script" uid="uid://colk6js4wet11" path="res://Scenes/ShopStand/shop_stand.gd" id="1_4in53"] [ext_resource type="Script" uid="uid://dkfswql8ui0bt" path="res://Scripts/interact_button.gd" id="1_x8sts"] @@ -17,6 +17,9 @@ albedo_color = Color(0.313726, 0.180392, 0.00392157, 1) [sub_resource type="BoxShape3D" id="BoxShape3D_3a288"] size = Vector3(2.95542, 2.01704, 1.92446) +[sub_resource type="BoxShape3D" id="BoxShape3D_txjtg"] +size = Vector3(0.427765, 0.430664, 0.898926) + [sub_resource type="BoxShape3D" id="BoxShape3D_3r1g8"] size = Vector3(0.69, 0.665, 0.34) @@ -38,16 +41,20 @@ viewport_path = NodePath("SubViewport5") [sub_resource type="ViewportTexture" id="ViewportTexture_rnm0u"] viewport_path = NodePath("SubViewport6") -[node name="ShopStand" type="Node3D" node_paths=PackedStringArray("cards", "choice_colliders", "choice_buttons", "choice_sprites")] +[node name="ShopStand" type="Node3D" node_paths=PackedStringArray("cards", "choice_colliders", "choice_buttons", "choice_sprites", "blank_button", "blank_button_collider", "blank_models")] script = ExtResource("1_4in53") cards = [NodePath("SubViewport/Node2D"), NodePath("SubViewport2/Node2D"), NodePath("SubViewport3/Node2D"), NodePath("SubViewport4/Node2D"), NodePath("SubViewport5/Node2D"), NodePath("SubViewport6/Node2D")] choice_colliders = [NodePath("InteractButton/CollisionShape3D"), NodePath("InteractButton2/CollisionShape3D2"), NodePath("InteractButton3/CollisionShape3D3"), NodePath("InteractButton6/CollisionShape3D6"), NodePath("InteractButton5/CollisionShape3D5"), NodePath("InteractButton4/CollisionShape3D4")] choice_buttons = [NodePath("InteractButton"), NodePath("InteractButton2"), NodePath("InteractButton3"), NodePath("InteractButton6"), NodePath("InteractButton5"), NodePath("InteractButton4")] choice_sprites = [NodePath("Sprites/Sprite3D"), NodePath("Sprites/Sprite3D2"), NodePath("Sprites/Sprite3D3"), NodePath("Sprites/Sprite3D4"), NodePath("Sprites/Sprite3D5"), NodePath("Sprites/Sprite3D6")] item_card_scene = ExtResource("2_qh00w") +blank_button = NodePath("InteractButton7") +blank_button_collider = NodePath("InteractButton7/CollisionShape3D") +blank_models = [NodePath("CSGBox3D4"), NodePath("CSGBox3D5"), NodePath("CSGBox3D6"), NodePath("CSGBox3D7"), NodePath("CSGBox3D8")] [node name="CSGBox3D" type="CSGBox3D" parent="."] -size = Vector3(2.95902, 1, 1) +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.294425, 0, 0) +size = Vector3(3.54787, 1, 1) material = SubResource("StandardMaterial3D_lhc2g") [node name="CSGBox3D2" type="CSGBox3D" parent="."] @@ -66,6 +73,17 @@ material = SubResource("StandardMaterial3D_4tjcf") transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.502094, -0.465026) shape = SubResource("BoxShape3D_3a288") +[node name="InteractButton7" type="StaticBody3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.73285, 0.835364, 0.235621) +collision_layer = 16 +collision_mask = 0 +script = ExtResource("1_x8sts") + +[node name="CollisionShape3D" type="CollisionShape3D" parent="InteractButton7"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -0.0624237, -0.101074, -0.214111) +shape = SubResource("BoxShape3D_txjtg") +disabled = true + [node name="InteractButton" type="StaticBody3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.08327, 0.835364, 0.235621) collision_layer = 16 @@ -211,6 +229,32 @@ pixel_size = 0.0015 texture_filter = 0 texture = SubResource("ViewportTexture_rnm0u") +[node name="CSGBox3D4" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.79147, 0.620414, 0.236721) +visible = false +size = Vector3(0.367981, 0.236755, 0.0673828) + +[node name="CSGBox3D5" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.79147, 0.620414, 0.14049) +visible = false +size = Vector3(0.367981, 0.236755, 0.0673828) + +[node name="CSGBox3D6" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.79147, 0.620414, 0.0426871) +visible = false +size = Vector3(0.367981, 0.236755, 0.0673828) + +[node name="CSGBox3D7" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.79147, 0.620414, -0.0568752) +visible = false +size = Vector3(0.367981, 0.236755, 0.0673828) + +[node name="CSGBox3D8" type="CSGBox3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, -1.79147, 0.620414, -0.151894) +visible = false +size = Vector3(0.367981, 0.236755, 0.0673828) + +[connection signal="button_interacted" from="InteractButton7" to="." method="retrieve_blank"] [connection signal="button_interacted" from="InteractButton" to="." method="retrieve_card"] [connection signal="button_interacted" from="InteractButton2" to="." method="retrieve_card"] [connection signal="button_interacted" from="InteractButton3" to="." method="retrieve_card"] diff --git a/Scenes/TowerBase/tower_base.gd b/Scenes/TowerBase/tower_base.gd index 5583df6..428f6f3 100644 --- a/Scenes/TowerBase/tower_base.gd +++ b/Scenes/TowerBase/tower_base.gd @@ -78,9 +78,10 @@ func networked_spawn_tower(card_index: int, caller_id: int) -> void: @rpc("reliable", "call_local", "any_peer") func networked_remove_tower() -> void: - inventory.remove_at(0) - #game_manager.connected_players_nodes[tower.owner_id].add_card(inventory.remove_at(0)) - #game_manager.connected_players_nodes[tower.owner_id].unready_self() + var card: Card = inventory.remove_at(0) + if !game_manager.card_gameplay: + game_manager.connected_players_nodes[tower.owner_id].add_card(card) + game_manager.connected_players_nodes[tower.owner_id].unready_self() tower.queue_free() #disable_duration_sprites() tower = null diff --git a/Scripts/data.gd b/Scripts/data.gd index 4acb8ac..36f2b66 100644 --- a/Scripts/data.gd +++ b/Scripts/data.gd @@ -23,7 +23,6 @@ static var weapon_recharge_delay: float = 0.5 static var starting_cash: int = 10 static var player_energy: int = 6 static var wall_cost: int = 1 -static var printer_cost: int = 15 static var rarity_weights: Dictionary = { "COMMON" = 50, "UNCOMMON" = 30, diff --git a/Scripts/game.gd b/Scripts/game.gd index 42981f3..611c9be 100644 --- a/Scripts/game.gd +++ b/Scripts/game.gd @@ -29,6 +29,7 @@ var chatbox: Chatbox var wave_limit: int = 20 var shop_chance: float = 0.0 var stats: RoundStats +var card_gameplay: bool = false #TODO: Create a reference to some generic Lobby object that wraps the multiplayer players list stuff @@ -125,6 +126,7 @@ func spawn_players() -> void: player.game_manager = self player.edit_tool.level = level player.hud.map_anchor = level + player.blank_cassettes += 1 player.player_name_tag.text = connected_player_profiles[peer_id].display_name player.position = level.player_spawns[p_i].global_position player.profile = connected_player_profiles[peer_id] @@ -242,8 +244,10 @@ func end_wave() -> void: player.hud.set_wave_count(wave) player.currency += ceili(pot / connected_players_nodes.size()) player.energy = Data.player_energy - player.iterate_duration() - player.draw_to_hand_size() + player.blank_cassettes += 1 + if card_gameplay: + player.iterate_duration() + player.draw_to_hand_size() player.unready_self() for spawn: EnemySpawner in level.enemy_spawns: spawn.visible = true @@ -309,9 +313,10 @@ func start() -> void: spawn_players() for peer_id: int in connected_players_nodes: connected_players_nodes[peer_id].currency = ceili(float(Data.starting_cash) / float(connected_players_nodes.size())) - connected_players_nodes[peer_id].energy = Data.player_energy - connected_players_nodes[peer_id].draw_pile.shuffle() - connected_players_nodes[peer_id].draw_to_hand_size() + if card_gameplay: + connected_players_nodes[peer_id].energy = Data.player_energy + connected_players_nodes[peer_id].draw_pile.shuffle() + connected_players_nodes[peer_id].draw_to_hand_size() #Relies on rng having been seeded set_upcoming_wave() diff --git a/UI/CardSelectionBox/card_selection_box.gd b/UI/CardSelectionBox/card_selection_box.gd index 155f039..7202fd6 100644 --- a/UI/CardSelectionBox/card_selection_box.gd +++ b/UI/CardSelectionBox/card_selection_box.gd @@ -1,6 +1,7 @@ class_name CardSelectionBox extends Control +var card: Card @export var icon: TextureRect @export var tags: VBoxContainer @export var cost_label: Label @@ -14,6 +15,7 @@ func set_amount(num: int) -> void: func set_card(card: Card) -> void: + self.card = card icon.texture = card.icon cost_label.text = str(card.cost) for i: int in tags.get_child_count(): diff --git a/UI/CardSelectionBox/card_selection_box.tscn b/UI/CardSelectionBox/card_selection_box.tscn index adcc674..25e8d3d 100644 --- a/UI/CardSelectionBox/card_selection_box.tscn +++ b/UI/CardSelectionBox/card_selection_box.tscn @@ -77,6 +77,5 @@ offset_top = 100.0 offset_right = 25.0 offset_bottom = 150.0 bbcode_enabled = true -text = "[img=top,50]/home/lexi/godot/multiplayer_tower_defense/UI/Keybinding/XeluController&KeyPrompts/Keyboard & Mouse/Light/1_Key_Light.png[/img]" fit_content = true vertical_alignment = 2 diff --git a/card_placing_tool.gd b/card_placing_tool.gd index f08149a..07c47c1 100644 --- a/card_placing_tool.gd +++ b/card_placing_tool.gd @@ -35,28 +35,34 @@ func _process(_delta: float) -> void: func interact() -> void: if ray.is_colliding() and ray.get_collider() is TowerBase: var tower_base: TowerBase = ray.get_collider() as TowerBase - put_card_in_tower_base(tower_base) + if hero.game_manager.card_gameplay: + if hero.hand.size > 0: + place_card(tower_base) + else: + if tower_base.has_card: + remove_card(tower_base) + elif hero.hand.size > 0: + place_card(tower_base) -func put_card_in_tower_base(tower_base: TowerBase) -> void: - if hero.hand.size <= 0: - return +func place_card(tower_base: TowerBase) -> void: var card: Card = hero.selected_card var energy_cost: int = card.cost - if hero.energy < energy_cost: + if hero.game_manager.card_gameplay and hero.energy < energy_cost: return - if tower_base.has_card: - tower_base.remove_card() + remove_card(tower_base) hero.hand.remove_at(hero.hand.contents.find(card)) hero.check_removal() - #hero.card_sprites[hero.hand_selected_index].queue_free() - #hero.card_sprites.remove_at(hero.hand_selected_index) - #if !hero.hand.contents.has(card): - #hero.decrement_selected() tower_base.add_card(card, multiplayer.get_unique_id()) - hero.discard_pile.add(card) hero.place_card_audio.play() - hero.energy -= energy_cost + if hero.game_manager.card_gameplay: + hero.discard_pile.add(card) + hero.energy -= energy_cost + + +func remove_card(tower_base: TowerBase) -> void: + if tower_base.has_card: + tower_base.remove_card() func spawn_tower_preview() -> void: diff --git a/choose_card_screen.gd b/choose_card_screen.gd new file mode 100644 index 0000000..e7f792c --- /dev/null +++ b/choose_card_screen.gd @@ -0,0 +1,39 @@ +class_name ChooseCardScreen extends Control + +signal card_chosen(card: Card) + +@export var choice_buttons: VBoxContainer +@export var card_name_label: Label +@export var card_description_label: RichTextLabel + +var choices: Array[Card] = [] +var chosen_card: Card = null +var side_a: bool = true + + +func add_cards(cards: Array[Card]) -> void: + var x: int = 0 + for card: Card in cards: + var button: Button = Button.new() + button.text = card.display_name + button.pressed.connect(choose_card.bind(x)) + choices.append(card) + choice_buttons.add_child(button) + x += 1 + choose_card(0) + + +func choose_card(choice: int) -> void: + chosen_card = choices[choice] + card_name_label.text = chosen_card.display_name + choose_side(side_a) + + +func choose_side(side_a_chosen: bool) -> void: + side_a = side_a_chosen + card_description_label.text = chosen_card.tower_stats.text if side_a else chosen_card.weapon_stats.text + + +func _on_confirm_button_pressed() -> void: + card_chosen.emit(chosen_card) + queue_free() diff --git a/choose_card_screen.gd.uid b/choose_card_screen.gd.uid new file mode 100644 index 0000000..1cadfbf --- /dev/null +++ b/choose_card_screen.gd.uid @@ -0,0 +1 @@ +uid://nc0df5y8tll7 diff --git a/choose_card_screen.tscn b/choose_card_screen.tscn new file mode 100644 index 0000000..c96ee2b --- /dev/null +++ b/choose_card_screen.tscn @@ -0,0 +1,108 @@ +[gd_scene load_steps=2 format=3 uid="uid://bcvjgl0s1wp8y"] + +[ext_resource type="Script" uid="uid://nc0df5y8tll7" path="res://choose_card_screen.gd" id="1_y4oar"] + +[node name="ChooseCardScreen" type="Control" node_paths=PackedStringArray("choice_buttons", "card_name_label", "card_description_label")] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_y4oar") +choice_buttons = NodePath("PanelContainer/Content/HBoxContainer/ChoicesVBox") +card_name_label = NodePath("PanelContainer/Content/HBoxContainer/VBoxContainer/NameLabel") +card_description_label = NodePath("PanelContainer/Content/HBoxContainer/DescriptionVBox/RichTextLabel") + +[node name="PanelContainer" type="PanelContainer" parent="."] +layout_mode = 1 +anchors_preset = -1 +anchor_left = 0.03 +anchor_top = 0.03 +anchor_right = 0.97 +anchor_bottom = 0.97 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Content" type="VBoxContainer" parent="PanelContainer"] +layout_mode = 2 + +[node name="ScreenTitleLabel" type="Label" parent="PanelContainer/Content"] +layout_mode = 2 +text = "LABEL_CHOOSE_CARD" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/Content"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="ChoicesVBox" type="VBoxContainer" parent="PanelContainer/Content/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="VBoxContainer" type="VBoxContainer" parent="PanelContainer/Content/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_stretch_ratio = 2.0 + +[node name="NameLabel" type="Label" parent="PanelContainer/Content/HBoxContainer/VBoxContainer"] +layout_mode = 2 +text = "LABEL_CARD_NAME" +horizontal_alignment = 1 +vertical_alignment = 1 + +[node name="HBoxContainer" type="HBoxContainer" parent="PanelContainer/Content/HBoxContainer/VBoxContainer"] +layout_mode = 2 +alignment = 1 + +[node name="TowerButton" type="Button" parent="PanelContainer/Content/HBoxContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "BUTTON_VIEW_TOWER" + +[node name="WeaponButton" type="Button" parent="PanelContainer/Content/HBoxContainer/VBoxContainer/HBoxContainer"] +layout_mode = 2 +text = "BUTTON_VIEW_WEAPON" + +[node name="TextureRect" type="TextureRect" parent="PanelContainer/Content/HBoxContainer/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +size_flags_vertical = 3 + +[node name="ConfirmButton" type="Button" parent="PanelContainer/Content/HBoxContainer/VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +text = "BUTTON_FINALIZE_CARD_CHOICE" + +[node name="DescriptionVBox" type="VBoxContainer" parent="PanelContainer/Content/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="DescriptionLabel" type="Label" parent="PanelContainer/Content/HBoxContainer/DescriptionVBox"] +layout_mode = 2 +text = "LABEL_CARD_DESCRIPTION" + +[node name="RichTextLabel" type="RichTextLabel" parent="PanelContainer/Content/HBoxContainer/DescriptionVBox"] +layout_mode = 2 +size_flags_vertical = 3 +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="FeaturesLabel" type="Label" parent="PanelContainer/Content/HBoxContainer/DescriptionVBox"] +layout_mode = 2 +text = "LABEL_CARD_FEATURES" + +[node name="FeaturesVBox" type="VBoxContainer" parent="PanelContainer/Content/HBoxContainer/DescriptionVBox"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="TargettingLabel" type="Label" parent="PanelContainer/Content/HBoxContainer/DescriptionVBox"] +layout_mode = 2 +text = "LABEL_TARGET_LIST" + +[node name="TargetVBox" type="VBoxContainer" parent="PanelContainer/Content/HBoxContainer/DescriptionVBox"] +layout_mode = 2 +size_flags_vertical = 3 + +[connection signal="pressed" from="PanelContainer/Content/HBoxContainer/VBoxContainer/HBoxContainer/TowerButton" to="." method="choose_side" binds= [true]] +[connection signal="pressed" from="PanelContainer/Content/HBoxContainer/VBoxContainer/HBoxContainer/WeaponButton" to="." method="choose_side" binds= [false]] +[connection signal="pressed" from="PanelContainer/Content/HBoxContainer/VBoxContainer/ConfirmButton" to="." method="_on_confirm_button_pressed"] diff --git a/export_presets.cfg b/export_presets.cfg index 64f8257..a99e7f1 100644 --- a/export_presets.cfg +++ b/export_presets.cfg @@ -9,7 +9,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="../../tower_defense/Linux/Decked Out Defense" +export_path="../../Decked Out Defense/DeckedOutDefense" patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" @@ -23,7 +23,7 @@ script_export_mode=2 custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 -binary_format/embed_pck=true +binary_format/embed_pck=false texture_format/s3tc_bptc=true texture_format/etc2_astc=false binary_format/architecture="x86_64" @@ -55,7 +55,7 @@ custom_features="" export_filter="all_resources" include_filter="" exclude_filter="" -export_path="../../tower_defense/Windows/Decked Out Defense.exe" +export_path="../../Decked Out Defense/DeckedOutDefense.exe" patches=PackedStringArray() encryption_include_filters="" encryption_exclude_filters="" @@ -69,7 +69,7 @@ script_export_mode=2 custom_template/debug="" custom_template/release="" debug/export_console_wrapper=1 -binary_format/embed_pck=true +binary_format/embed_pck=false texture_format/s3tc_bptc=true texture_format/etc2_astc=false binary_format/architecture="x86_64" diff --git a/project.godot b/project.godot index 04e8341..d844c6c 100644 --- a/project.godot +++ b/project.godot @@ -11,7 +11,7 @@ config_version=5 [application] config/name="Decked Out Defense" -config/version="0.2.0" +config/version="0.3.0" run/main_scene="uid://d2k8y13qfvch0" config/features=PackedStringArray("4.4", "Forward Plus") boot_splash/show_image=false