diff --git a/assets/UI/energy_orb.png.import b/assets/UI/energy_orb.png.import new file mode 100644 index 0000000..c61b1c5 --- /dev/null +++ b/assets/UI/energy_orb.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dyx76tn885md3" +path="res://.godot/imported/energy_orb.png-2cbe75b8af4388a02af2b14d7f4c3fa2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/UI/energy_orb.png" +dest_files=["res://.godot/imported/energy_orb.png-2cbe75b8af4388a02af2b14d7f4c3fa2.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/assets/UI/scroll_base.png.import b/assets/UI/scroll_base.png.import new file mode 100644 index 0000000..9e486d7 --- /dev/null +++ b/assets/UI/scroll_base.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://df58t5bfmj70a" +path="res://.godot/imported/scroll_base.png-693a0b068424563664384c6eb0209196.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/UI/scroll_base.png" +dest_files=["res://.godot/imported/scroll_base.png-693a0b068424563664384c6eb0209196.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/assets/UI/tilemap.png.import b/assets/UI/tilemap.png.import new file mode 100644 index 0000000..ac09591 --- /dev/null +++ b/assets/UI/tilemap.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://dmvsmadpgt07f" +path="res://.godot/imported/tilemap.png-083a8bbebe37cff77c4a1b9df77bc47f.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/UI/tilemap.png" +dest_files=["res://.godot/imported/tilemap.png-083a8bbebe37cff77c4a1b9df77bc47f.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/assets/UI/tilemap_packed.png.import b/assets/UI/tilemap_packed.png.import new file mode 100644 index 0000000..450a71e --- /dev/null +++ b/assets/UI/tilemap_packed.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://b27cwck0oyrc" +path="res://.godot/imported/tilemap_packed.png-42b0b930e1378971414a5562b18c2f23.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/UI/tilemap_packed.png" +dest_files=["res://.godot/imported/tilemap_packed.png-42b0b930e1378971414a5562b18c2f23.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/assets/backgrounds/scroll_shop.png b/assets/backgrounds/scroll_shop.png new file mode 100644 index 0000000..0fd346d Binary files /dev/null and b/assets/backgrounds/scroll_shop.png differ diff --git a/assets/backgrounds/scroll_shop.png.import b/assets/backgrounds/scroll_shop.png.import new file mode 100644 index 0000000..1ffa54f --- /dev/null +++ b/assets/backgrounds/scroll_shop.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://d0e0habrx3lmx" +path="res://.godot/imported/scroll_shop.png-6c62852703f1bf6b927ce6a799fdfcdf.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/backgrounds/scroll_shop.png" +dest_files=["res://.godot/imported/scroll_shop.png-6c62852703f1bf6b927ce6a799fdfcdf.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/resources/shaders/card_glow.gdshader b/resources/shaders/card_glow.gdshader new file mode 100644 index 0000000..5038c41 --- /dev/null +++ b/resources/shaders/card_glow.gdshader @@ -0,0 +1,28 @@ +shader_type canvas_item; + +uniform vec4 glow_color : source_color = vec4(1.0, 0.85, 0.4, 1.0); // Warm yellow glow +uniform float glow_strength : hint_range(0.0, 1.0) = 0.0; +uniform float outline_width : hint_range(0.0, 10.0) = 1.2; + +void fragment() { + vec4 texture_color = texture(TEXTURE, UV); + + // Calculate outline + float outline = 0.0; + for(float x = -outline_width; x <= outline_width; x++) { + for(float y = -outline_width; y <= outline_width; y++) { + vec2 offset = vec2(x, y) * TEXTURE_PIXEL_SIZE; + if(texture(TEXTURE, UV + offset).a > 0.0) { + outline = 1.0; + break; + } + } + } + + // Only show outline on the edges (where the original texture is transparent) + outline *= (1.0 - texture_color.a); + + // Add glow to the original color + vec4 glow = glow_color * outline * glow_strength; + COLOR = texture_color + glow; +} \ No newline at end of file diff --git a/scenes/home_base.tscn b/scenes/home_base.tscn index 8d622a1..97b7f0c 100644 --- a/scenes/home_base.tscn +++ b/scenes/home_base.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=3 format=3 uid="uid://bnk32gyp3bsir"] +[gd_scene load_steps=3 format=3 uid="uid://bavbb08gmox7b"] [ext_resource type="Script" path="res://scripts/scenes/home_base.gd" id="1_07xob"] [ext_resource type="Script" path="res://scripts/managers/pause_manager.gd" id="2_5cg8f"] diff --git a/scenes/shop.tscn b/scenes/shop.tscn new file mode 100644 index 0000000..d1932fd --- /dev/null +++ b/scenes/shop.tscn @@ -0,0 +1,52 @@ +[gd_scene load_steps=4 format=3 uid="uid://cndnjigot1as7"] + +[ext_resource type="Script" path="res://scripts/decipher_shop.gd" id="1_10ejr"] +[ext_resource type="Texture2D" uid="uid://d0e0habrx3lmx" path="res://assets/backgrounds/scroll_shop.png" id="1_56d1j"] +[ext_resource type="Script" path="res://scripts/managers/decoder_manager.gd" id="3_bo20c"] + +[node name="DecipherUI" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_10ejr") + +[node name="ScrollShop" type="Sprite2D" parent="."] +position = Vector2(780, 613) +scale = Vector2(1.89022, 1.49542) +texture = ExtResource("1_56d1j") + +[node name="ScrollContainer" type="ScrollContainer" parent="ScrollShop"] +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +offset_left = -370.0 +offset_top = -316.0 +offset_right = -1021.0 +offset_bottom = -464.0 +grow_horizontal = 2 +grow_vertical = 2 +size_flags_horizontal = 3 +horizontal_scroll_mode = 0 +vertical_scroll_mode = 3 + +[node name="GridContainer" type="GridContainer" parent="ScrollShop/ScrollContainer"] +clip_contents = true +layout_mode = 2 +columns = 3 + +[node name="DecipherPointsLabel" type="Label" parent="."] +layout_mode = 1 +anchors_preset = 1 +anchor_left = 1.0 +anchor_right = 1.0 +offset_left = -170.0 +offset_top = 50.0 +offset_right = -111.0 +offset_bottom = 86.0 +grow_horizontal = 0 + +[node name="DecoderManager" type="Node" parent="."] +script = ExtResource("3_bo20c") diff --git a/scripts/decipher_shop.gd b/scripts/decipher_shop.gd new file mode 100644 index 0000000..cebfd62 --- /dev/null +++ b/scripts/decipher_shop.gd @@ -0,0 +1,85 @@ +extends Control + +# First, move the shop card script to a constant reference +const ShopCardScript = preload("res://scripts/scenes/decipher_shop_card.gd") + +@onready var grid_container = $ScrollShop/ScrollContainer/GridContainer +@onready var scroll_container = $ScrollShop/ScrollContainer +@onready var card_scene = preload("res://scenes/card.tscn") +@onready var points_label = $DecipherPointsLabel +@onready var decoder_manager = $DecoderManager + +# Cards available for deciphering +var available_cards = GameState.current_deck + +var card_size: Vector2 + +func _ready() -> void: + setup_grid_container() + populate_shop_cards() + update_points_display() + + # Connect to decoder manager signals + decoder_manager.points_changed.connect(_on_points_changed) + decoder_manager.aspect_decoded.connect(_on_aspect_decoded) + +func setup_grid_container() -> void: + # Configure grid layout + grid_container.columns = 3 + grid_container.add_theme_constant_override("h_separation", 20) + grid_container.add_theme_constant_override("v_separation", 20) + + # Make GridContainer take full width + grid_container.size_flags_horizontal = Control.SIZE_EXPAND | Control.SIZE_FILL + + # Calculate card sizes based on scroll container width + var available_width = scroll_container.size.x + var card_width = (available_width - (grid_container.columns - 1) * grid_container.get_theme_constant("h_separation")) / grid_container.columns + card_size = Vector2(card_width, card_width * 1.5) + + # Calculate total height needed + var rows = ceil(float(available_cards.size()) / grid_container.columns) + var total_height = (card_size.y * rows) + ((rows - 1) * grid_container.get_theme_constant("v_separation")) + + # Set GridContainer size + grid_container.custom_minimum_size = Vector2(available_width, total_height) + +func populate_shop_cards() -> void: + # Clear existing cards + for child in grid_container.get_children(): + child.queue_free() + + # Add available cards to the shop + for card_path in available_cards: + var card_resource = load(card_path) + if card_resource: + var card_instance = card_scene.instantiate() + + # Set the script before setup + card_instance.set_script(ShopCardScript) + + grid_container.add_child(card_instance) + + # Set the card's custom minimum size + card_instance.custom_minimum_size = card_size - Vector2(-10, -30) + + # Make the card expand to fill its cell + card_instance.size_flags_horizontal = Control.SIZE_SHRINK_CENTER + card_instance.size_flags_vertical = Control.SIZE_SHRINK_CENTER + + # Get decoded aspects for this card from GameState + var decoded_aspects = GameState.decoded_aspects.get(card_path, {}) + + # Set up the card with both resource and decoder manager + if card_instance.has_method("setup_shop_card"): + card_instance.setup_shop_card(card_resource, decoded_aspects, decoder_manager) + +func update_points_display() -> void: + points_label.text = "Decipher Points: " + str(decoder_manager.available_points) + +func _on_points_changed(new_amount: int) -> void: + update_points_display() + +func _on_aspect_decoded(_card_id: String, _aspect: String) -> void: + # Refresh the cards to show updated decode status + populate_shop_cards() diff --git a/scripts/managers/decoder_manager.gd b/scripts/managers/decoder_manager.gd index cae87a2..97091b2 100644 --- a/scripts/managers/decoder_manager.gd +++ b/scripts/managers/decoder_manager.gd @@ -39,8 +39,8 @@ func decode_aspect(card: Node, aspect: String) -> void: aspect_decoded.emit(card_id, aspect) # Update decode UI if it's visible - var decode_ui = get_node("/root/Main/Combat/UI/DecodeUI") - if decode_ui and decode_ui.visible: + var decode_ui = get_node_or_null("/root/Main/Combat/UI/DecodeUI") + if decode_ui and decode_ui.visible and decode_ui.has_method("update_points"): decode_ui.update_points() func add_points(amount: int) -> void: diff --git a/scripts/scenes/card.gd b/scripts/scenes/card.gd index b010cc0..2b68ce8 100644 --- a/scripts/scenes/card.gd +++ b/scripts/scenes/card.gd @@ -7,6 +7,7 @@ signal effect_executed(effect_type: String, value: int, target: Node) var card_data: CardData var decoded_aspects: Dictionary = {} +@onready var sprite: Sprite2D = $Sprite2D @onready var cost_label: Label = $MarginContainer/VBoxContainer/TopBar/CostLabel @onready var name_label: Label = $MarginContainer/VBoxContainer/TopBar/NameLabel @onready var effect_label: Label = $MarginContainer/VBoxContainer/EffectLabel @@ -27,6 +28,18 @@ func _ready() -> void: $MarginContainer.offset_right = 0 $MarginContainer.offset_bottom = 0 + # Setup shader + var material = ShaderMaterial.new() + material.shader = preload("res://resources/shaders/card_glow.gdshader") + sprite.material = material + # Start with no glow + set_selected(false) + mouse_entered.connect(_on_mouse_entered) + mouse_exited.connect(_on_mouse_exited) + + # Important: Enable mouse processing + mouse_filter = Control.MOUSE_FILTER_STOP + # Update card display update_display() @@ -151,9 +164,18 @@ func _on_decode_option_selected(id: int) -> void: 1: decoder.decode_aspect(self, "type") 2: decoder.decode_aspect(self, "value") 3: decoder.decode_aspect(self, "description") - -func _on_mouse_entered() -> void: + +func set_selected(is_selected: bool): + if not sprite.material: + return + sprite.material.set_shader_parameter("glow_strength", 1.0 if is_selected else 0.0) + +func _on_mouse_entered(): SoundEffectsSystem.play_sound("ui", "card_hover", -15.0) + set_selected(true) + +func _on_mouse_exited(): + set_selected(false) func corrupt_knowledge() -> void: var aspects_list = decoded_aspects.keys() @@ -162,4 +184,4 @@ func corrupt_knowledge() -> void: var aspect = aspects_list[randi() % aspects_list.size()] decoded_aspects.erase(aspect) GameState.decode_aspects[card_data.resource_path].erase(aspect) - update_display() + update_display() \ No newline at end of file diff --git a/scripts/scenes/decipher_shop_card.gd b/scripts/scenes/decipher_shop_card.gd new file mode 100644 index 0000000..64e8deb --- /dev/null +++ b/scripts/scenes/decipher_shop_card.gd @@ -0,0 +1,79 @@ +# shop_card.gd +extends "res://scripts/scenes/card.gd" + +var decoder_manager: Node = null +var card_resource_path: String = "" + +func setup_shop_card(card_res: Resource, shop_decoded_aspects: Dictionary, decoder_ref: Node) -> void: + decoder_manager = decoder_ref + setup(card_res, shop_decoded_aspects) + card_resource_path = card_res.resource_path + +func get_card_path() -> String: + return card_resource_path + +# Override _gui_input to only handle decoding +func _gui_input(event: InputEvent) -> void: + if event is InputEventMouseButton: + if event.button_index == MOUSE_BUTTON_RIGHT and event.pressed: + show_decode_menu() + +# Override play_card to do nothing +func play_card() -> void: + pass + +# Override execute_effect to do nothing +func execute_effect() -> void: + pass + +# Helper function to check if aspect is decoded +func is_aspect_decoded(aspect: String) -> bool: + if not card_resource_path: + return false + var decoded = GameState.decoded_aspects.get(card_resource_path, {}) + return decoded.get(aspect, false) + +# Modified show_decode_menu for shop context +func show_decode_menu() -> void: + if not decoder_manager: + push_error("Decoder manager not initialized") + return + + var popup = PopupMenu.new() + add_child(popup) + var points_available = decoder_manager.available_points + + popup.add_item("Available Points: " + str(points_available)) + popup.set_item_disabled(0, true) + popup.add_separator() + + # Add available decipher options + var aspects = ["cost", "type", "value", "description"] + var id = 0 + + for aspect in aspects: + if not is_aspect_decoded(aspect): + var cost = decoder_manager.DECODE_COSTS[aspect] + popup.add_item("Decipher %s (%d points)" % [aspect.capitalize(), cost], id) + popup.set_item_disabled(popup.item_count - 1, not decoder_manager.can_decode_aspect(aspect)) + id += 1 + + if popup.item_count == 2: # Only the points display and separator + popup.add_item("Fully Deciphered", -1) + popup.set_item_disabled(popup.item_count - 1, true) + + popup.id_pressed.connect(_on_decode_option_selected) + popup.position = get_global_mouse_position() + popup.popup() + +# Modified decode option handling to use decoder_manager +func _on_decode_option_selected(id: int) -> void: + if not decoder_manager: + push_error("Decoder manager not initialized") + return + + var aspects = ["cost", "type", "value", "description"] + if id >= 0 and id < aspects.size(): + var aspect = aspects[id] + if decoder_manager.can_decode_aspect(aspect): + decoder_manager.decode_aspect(self, aspect) diff --git a/scripts/scenes/home_base.gd b/scripts/scenes/home_base.gd index 0906f7d..4960faa 100644 --- a/scripts/scenes/home_base.gd +++ b/scripts/scenes/home_base.gd @@ -20,7 +20,7 @@ func _on_adventure_button_pressed() -> void: AdventureSystem.start_adventure(adventure) func _on_decoder_button_pressed() -> void: - pass # Go to decoder + get_node("/root/Main").start_decode_shop() func _on_stone_button_pressed() -> void: pass # Go to stone powers and progress diff --git a/scripts/scenes/home_base.tscn b/scripts/scenes/home_base.tscn new file mode 100644 index 0000000..e204e95 --- /dev/null +++ b/scripts/scenes/home_base.tscn @@ -0,0 +1,67 @@ +[gd_scene load_steps=3 format=3 uid="uid://bndtxmsha2gam"] + +[ext_resource type="Script" path="res://scripts/scenes/home_base.gd" id="1_4udhq"] +[ext_resource type="Script" path="res://scripts/managers/pause_manager.gd" id="2_4gf2c"] + +[node name="HomeBase" type="Control"] +layout_mode = 3 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_4udhq") + +[node name="VBoxContainer" type="VBoxContainer" parent="."] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 + +[node name="Label" type="Label" parent="VBoxContainer"] +layout_mode = 2 +theme_override_font_sizes/font_size = 105 +text = "Home base" +horizontal_alignment = 1 + +[node name="GridContainer" type="GridContainer" parent="VBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +theme_override_constants/h_separation = 40 +theme_override_constants/v_separation = 40 +columns = 2 + +[node name="AdventureButton" type="Button" parent="VBoxContainer/GridContainer"] +custom_minimum_size = Vector2(400, 400) +layout_mode = 2 +theme_override_font_sizes/font_size = 87 +text = "Go on an adventure" + +[node name="DecoderButton" type="Button" parent="VBoxContainer/GridContainer"] +custom_minimum_size = Vector2(400, 400) +layout_mode = 2 +theme_override_font_sizes/font_size = 87 +text = "Decode cards" + +[node name="StoneButton" type="Button" parent="VBoxContainer/GridContainer"] +custom_minimum_size = Vector2(400, 400) +layout_mode = 2 +theme_override_font_sizes/font_size = 87 +text = "Magical stone" + +[node name="LoadoutButton" type="Button" parent="VBoxContainer/GridContainer"] +custom_minimum_size = Vector2(400, 400) +layout_mode = 2 +theme_override_font_sizes/font_size = 87 +text = "Deck and inventory" + +[node name="PauseManager" type="Node" parent="."] +script = ExtResource("2_4gf2c") + +[connection signal="pressed" from="VBoxContainer/GridContainer/AdventureButton" to="." method="_on_adventure_button_pressed"] +[connection signal="pressed" from="VBoxContainer/GridContainer/DecoderButton" to="." method="_on_decoder_button_pressed"] +[connection signal="pressed" from="VBoxContainer/GridContainer/StoneButton" to="." method="_on_stone_button_pressed"] +[connection signal="pressed" from="VBoxContainer/GridContainer/LoadoutButton" to="." method="_on_loadout_button_pressed"] diff --git a/scripts/scenes/main.gd b/scripts/scenes/main.gd index a35d77b..0bafe03 100644 --- a/scripts/scenes/main.gd +++ b/scripts/scenes/main.gd @@ -3,6 +3,7 @@ extends Node @onready var combat_scene = preload("res://scenes/combat.tscn") @onready var menu_scene = preload("res://scenes/menus/main_menu.tscn") @onready var home_base_scene = preload("res://scenes/home_base.tscn") +@onready var decode_shop_scene = preload("res://scenes/shop.tscn") var current_scene: Node = null @@ -42,6 +43,10 @@ func start_combat() -> void: var new_combat = combat_scene.instantiate() call_deferred("transition_to_scene", new_combat) +func start_decode_shop() -> void: + var new_decode_shop = decode_shop_scene.instantiate() + call_deferred("transition_to_scene", new_decode_shop) + func start_home_base() -> void: var new_home = home_base_scene.instantiate() call_deferred("transition_to_scene", new_home)