From cc737f22cf8680fc05d50b1a813df61c97c772f8 Mon Sep 17 00:00:00 2001 From: Gabriel Kaszewski Date: Thu, 5 Jun 2025 22:50:45 +0200 Subject: [PATCH] Add marketplace button functionality and skill unlocker integration --- objects/ui/marketplace_button.tscn | 21 +++++++- resources/skills/brick_throw.tres | 3 ++ resources/skills/explosive_brick.tres | 3 ++ resources/skills/fire_brick.tres | 3 ++ resources/skills/ice_brick.tres | 3 ++ .../components/skill_unlocker_component.gd | 4 +- scripts/game_manager.gd | 9 +++- scripts/resources/skill_data.gd | 5 +- scripts/ui/marketplace.gd | 3 +- scripts/ui/marketplace_button.gd | 48 ++++++++++++++++++ scripts/ui/marketplace_button.gd.uid | 1 + scripts/ui/pause_menu.gd | 3 +- sprites/locked_skill.png | Bin 0 -> 124 bytes sprites/locked_skill.png.import | 34 +++++++++++++ sprites/unlocked_skill.png | Bin 0 -> 124 bytes sprites/unlocked_skill.png.import | 34 +++++++++++++ 16 files changed, 167 insertions(+), 7 deletions(-) create mode 100644 scripts/ui/marketplace_button.gd create mode 100644 scripts/ui/marketplace_button.gd.uid create mode 100644 sprites/locked_skill.png create mode 100644 sprites/locked_skill.png.import create mode 100644 sprites/unlocked_skill.png create mode 100644 sprites/unlocked_skill.png.import diff --git a/objects/ui/marketplace_button.tscn b/objects/ui/marketplace_button.tscn index 70a6d66..c045013 100644 --- a/objects/ui/marketplace_button.tscn +++ b/objects/ui/marketplace_button.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=2 format=3 uid="uid://dtl03rod7l2t0"] +[gd_scene load_steps=5 format=3 uid="uid://dtl03rod7l2t0"] [ext_resource type="Texture2D" uid="uid://cvhoq7aubxlmq" path="res://sprites/ui/magnetic_skill_icon.png" id="1_5kqfg"] +[ext_resource type="Script" uid="uid://dx8lex40lotr5" path="res://scripts/ui/marketplace_button.gd" id="2_ulgvb"] +[ext_resource type="Texture2D" uid="uid://52adghxscdgy" path="res://sprites/locked_skill.png" id="2_vb2qn"] +[ext_resource type="Texture2D" uid="uid://rucyqmgrdld3" path="res://sprites/unlocked_skill.png" id="3_guyun"] -[node name="MarketplaceButton" type="Button"] +[node name="MarketplaceButton" type="Button" node_paths=PackedStringArray("skill_level_container")] offset_right = 8.0 offset_bottom = 8.0 size_flags_horizontal = 3 @@ -12,3 +15,17 @@ text = "Fire brick 100" icon = ExtResource("1_5kqfg") flat = true autowrap_mode = 2 +script = ExtResource("2_ulgvb") +unlocked_skill_icon = ExtResource("3_guyun") +locked_skill_icon = ExtResource("2_vb2qn") +skill_level_container = NodePath("HBoxContainer") + +[node name="HBoxContainer" type="HBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 12 +anchor_top = 1.0 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_top = -8.0 +grow_horizontal = 2 +grow_vertical = 0 diff --git a/resources/skills/brick_throw.tres b/resources/skills/brick_throw.tres index 492ddf6..661a69e 100644 --- a/resources/skills/brick_throw.tres +++ b/resources/skills/brick_throw.tres @@ -19,3 +19,6 @@ config = { cost = 50 icon = ExtResource("2_yimbq") type = 1 +is_active = false +level = 0 +max_level = 3 diff --git a/resources/skills/explosive_brick.tres b/resources/skills/explosive_brick.tres index f3f3e5d..d7d00de 100644 --- a/resources/skills/explosive_brick.tres +++ b/resources/skills/explosive_brick.tres @@ -20,3 +20,6 @@ config = { cost = 180 icon = ExtResource("3_wkqmb") type = 1 +is_active = false +level = 0 +max_level = 1 diff --git a/resources/skills/fire_brick.tres b/resources/skills/fire_brick.tres index fb74ccb..eef73dd 100644 --- a/resources/skills/fire_brick.tres +++ b/resources/skills/fire_brick.tres @@ -20,3 +20,6 @@ config = { cost = 150 icon = ExtResource("3_w87qb") type = 1 +is_active = false +level = 0 +max_level = 3 diff --git a/resources/skills/ice_brick.tres b/resources/skills/ice_brick.tres index 65914ef..2e37114 100644 --- a/resources/skills/ice_brick.tres +++ b/resources/skills/ice_brick.tres @@ -20,3 +20,6 @@ config = { cost = 150 icon = ExtResource("3_6btth") type = 1 +is_active = false +level = 0 +max_level = 3 diff --git a/scripts/components/skill_unlocker_component.gd b/scripts/components/skill_unlocker_component.gd index 807d8bf..a4f4006 100644 --- a/scripts/components/skill_unlocker_component.gd +++ b/scripts/components/skill_unlocker_component.gd @@ -4,7 +4,7 @@ extends Node @export var skill_manager: SkillManager @onready var game_manager: GM = $"/root/GameManager" - +signal skill_unlocked(skill_data: SkillData) func has_enough_coins(amount: int) -> bool: @@ -24,6 +24,7 @@ func try_unlock_skill(skill_data: SkillData) -> bool: game_manager.remove_coins(skill_data.cost) game_manager.current_session_state["skills_unlocked"].append(skill_data.name) skill_manager.add_skill(skill_data) + skill_unlocked.emit(skill_data) return true @@ -33,6 +34,7 @@ func unlock_all_skills() -> void: for skill in available_skills: skills.append(skill.name) + skill_unlocked.emit(skill) game_manager.unlock_skills(skills) skill_manager.apply_unlocked_skills() diff --git a/scripts/game_manager.gd b/scripts/game_manager.gd index 1292bbe..06dc732 100644 --- a/scripts/game_manager.gd +++ b/scripts/game_manager.gd @@ -68,6 +68,14 @@ func get_kid_nodes() -> Array[CollectableComponent]: return kid_nodes + +func get_player_node() -> Node: + for node in nodes_in_scene: + if node is PlayerController: + return node + return null + + func add_coins(amount: int) -> void: player_state["coins"] += amount player_state["coins"] = max(0, player_state["coins"]) @@ -213,7 +221,6 @@ func on_level_complete() -> void: SaveSystem.save_game() - func get_unlocked_skills() -> Array: var skills_unlocked = player_state.get("unlocked_skills", []) var skills_current_session = current_session_state.get("skills_unlocked", []) diff --git a/scripts/resources/skill_data.gd b/scripts/resources/skill_data.gd index d41275c..bed8dd9 100644 --- a/scripts/resources/skill_data.gd +++ b/scripts/resources/skill_data.gd @@ -12,4 +12,7 @@ enum SkillType { @export var config: Dictionary = {} @export var cost: int = 0 @export var icon: Texture2D -@export var type: SkillType = SkillType.ATTACK \ No newline at end of file +@export var type: SkillType = SkillType.ATTACK +@export var is_active: bool = false +@export var level: int = 1 +@export var max_level: int = 1 \ No newline at end of file diff --git a/scripts/ui/marketplace.gd b/scripts/ui/marketplace.gd index c4c9a61..2729314 100644 --- a/scripts/ui/marketplace.gd +++ b/scripts/ui/marketplace.gd @@ -46,9 +46,10 @@ func get_button_text(skill: SkillData) -> String: func create_upgrade_button(skill: SkillData): - var button := marketplace_button.instantiate() as Button + var button := marketplace_button.instantiate() as MarketplaceButton button.text = get_button_text(skill) button.icon = skill.icon + button.skill_data = skill button.pressed.connect(func () -> void: _on_button_pressed(skill)) diff --git a/scripts/ui/marketplace_button.gd b/scripts/ui/marketplace_button.gd new file mode 100644 index 0000000..17defb5 --- /dev/null +++ b/scripts/ui/marketplace_button.gd @@ -0,0 +1,48 @@ +class_name MarketplaceButton +extends Button + +@export var skill_data: SkillData +@export var unlocked_skill_icon: Texture2D +@export var locked_skill_icon: Texture2D +@export var skill_level_container: Container + +@onready var gm: GM = $"/root/GameManager" + + +func _ready() -> void: + if not skill_data: + printerr("MarketplaceButton: skill_data is not set.") + if not unlocked_skill_icon or not locked_skill_icon: + printerr("MarketplaceButton: unlocked_skill_icon or locked_skill_icon is not set.") + return + if not skill_level_container: + printerr("MarketplaceButton: skill_level_container is not set.") + return + + setup() + + var player := gm.get_player_node() + var skill_unlocker_component := player.get_node_or_null("SkillUnlockerComponent") as SkillUnlockerComponent + if skill_unlocker_component: + skill_unlocker_component.skill_unlocked.connect(_on_skill_unlock) + + +func setup() -> void: + if not skill_data: + return + + for i in range(skill_data.max_level): + var _icon := TextureRect.new() + _icon.texture = unlocked_skill_icon if i < skill_data.level else locked_skill_icon + skill_level_container.add_child(_icon) + + +func _on_skill_unlock(skill: SkillData) -> void: + if skill.name == skill_data.name: + for i in range(skill_data.max_level): + var icon := skill_level_container.get_child(i) as TextureRect + if i < skill.level: + icon.texture = unlocked_skill_icon + else: + icon.texture = locked_skill_icon + disabled = skill.level >= skill_data.max_level \ No newline at end of file diff --git a/scripts/ui/marketplace_button.gd.uid b/scripts/ui/marketplace_button.gd.uid new file mode 100644 index 0000000..5616e41 --- /dev/null +++ b/scripts/ui/marketplace_button.gd.uid @@ -0,0 +1 @@ +uid://dx8lex40lotr5 diff --git a/scripts/ui/pause_menu.gd b/scripts/ui/pause_menu.gd index 1426e65..0cbf772 100644 --- a/scripts/ui/pause_menu.gd +++ b/scripts/ui/pause_menu.gd @@ -45,7 +45,6 @@ func _ready() -> void: Console.console_closed.connect(_on_console_close) - func _unhandled_input(event: InputEvent) -> void: if event.is_action_pressed("pause") and not is_console_open: if UiManager.is_visible_on_stack(pause_menu_control): @@ -78,6 +77,8 @@ func _on_exit_to_menu_button_pressed() -> void: printerr("PauseMenu: Exit to menu scene not set.") return + gm.resume_game() + gm.reset_current_session_state() get_tree().change_scene_to_packed(exit_to_menu_scene) diff --git a/sprites/locked_skill.png b/sprites/locked_skill.png new file mode 100644 index 0000000000000000000000000000000000000000..a40bf5eea7ad38a370d56360f239ea491bf09790 GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|%sgEjLnNjq zCpa)oojUcuwzl?vrU}Y{3}*RE3`f7p VNNIaLoB}j~!PC{xWt~$(698ifBS8QF literal 0 HcmV?d00001 diff --git a/sprites/locked_skill.png.import b/sprites/locked_skill.png.import new file mode 100644 index 0000000..d7bff02 --- /dev/null +++ b/sprites/locked_skill.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://52adghxscdgy" +path="res://.godot/imported/locked_skill.png-48fa9e93aa2c711c18fd9edb5233eb69.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://sprites/locked_skill.png" +dest_files=["res://.godot/imported/locked_skill.png-48fa9e93aa2c711c18fd9edb5233eb69.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/sprites/unlocked_skill.png b/sprites/unlocked_skill.png new file mode 100644 index 0000000000000000000000000000000000000000..754cbfbb505caf0b326d311458f4b43c50a6178e GIT binary patch literal 124 zcmeAS@N?(olHy`uVBq!ia0vp^93afW1|*O0@9PFqjKx9jP7LeL$-D$|%sgEjLnNjq zCpa+8Hp~6BKlAdk|0j}qPE0x>R99EmQ^5LS(uppKLeE1C!gijI)+jvj5NS9&o8eTJ WeBq7VGRZ&_7(8A5T-G@yGywopkSNCh literal 0 HcmV?d00001 diff --git a/sprites/unlocked_skill.png.import b/sprites/unlocked_skill.png.import new file mode 100644 index 0000000..c602b9a --- /dev/null +++ b/sprites/unlocked_skill.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://rucyqmgrdld3" +path="res://.godot/imported/unlocked_skill.png-be1990df98d42600170074fac52ea327.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://sprites/unlocked_skill.png" +dest_files=["res://.godot/imported/unlocked_skill.png-be1990df98d42600170074fac52ea327.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1