diff --git a/assets/fonts/Supercell-Magic Regular.ttf b/assets/fonts/Supercell-Magic Regular.ttf new file mode 100644 index 0000000..241c49d Binary files /dev/null and b/assets/fonts/Supercell-Magic Regular.ttf differ diff --git a/assets/fonts/Supercell-Magic Regular.ttf.import b/assets/fonts/Supercell-Magic Regular.ttf.import new file mode 100644 index 0000000..fdb6490 --- /dev/null +++ b/assets/fonts/Supercell-Magic Regular.ttf.import @@ -0,0 +1,36 @@ +[remap] + +importer="font_data_dynamic" +type="FontFile" +uid="uid://c2tryhyhlyb1u" +path="res://.godot/imported/Supercell-Magic Regular.ttf-470d998e73788b4db06bc80514578b9e.fontdata" + +[deps] + +source_file="res://assets/fonts/Supercell-Magic Regular.ttf" +dest_files=["res://.godot/imported/Supercell-Magic Regular.ttf-470d998e73788b4db06bc80514578b9e.fontdata"] + +[params] + +Rendering=null +antialiasing=1 +generate_mipmaps=false +disable_embedded_bitmaps=true +multichannel_signed_distance_field=false +msdf_pixel_range=8 +msdf_size=48 +allow_system_fallback=true +force_autohinter=false +modulate_color_glyphs=false +hinting=1 +subpixel_positioning=4 +keep_rounding_remainders=true +oversampling=0.0 +Fallbacks=null +fallbacks=[] +Compress=null +compress=true +preload=[] +language_support={} +script_support={} +opentype_features={} diff --git a/assets/graphics/game_setting/setting_theme.tres b/assets/graphics/game_setting/setting_theme.tres index 34663cc..6b323f6 100644 --- a/assets/graphics/game_setting/setting_theme.tres +++ b/assets/graphics/game_setting/setting_theme.tres @@ -1,8 +1,8 @@ -[gd_resource type="Theme" load_steps=14 format=3 uid="uid://0dhxl4ohyxh8"] +[gd_resource type="Theme" format=3 uid="uid://0dhxl4ohyxh8"] [ext_resource type="Texture2D" uid="uid://bc4h3o4wjjhc7" path="res://assets/graphics/game_setting/checkbox_on.png" id="1_36vy5"] -[ext_resource type="FontFile" uid="uid://c5t0o1yflhrg6" path="res://fonts/Supercell-Magic Regular.ttf" id="1_ofq5d"] -[ext_resource type="FontFile" uid="uid://bkg2jgfslxukn" path="res://fonts/TektonDash2.ttf" id="2_1r1ma"] +[ext_resource type="FontFile" uid="uid://c2tryhyhlyb1u" path="res://assets/fonts/Supercell-Magic Regular.ttf" id="1_ofq5d"] +[ext_resource type="FontFile" uid="uid://dsqg0x5lnosou" path="res://assets/fonts/TektonDash2.ttf" id="2_1r1ma"] [ext_resource type="Texture2D" uid="uid://cwayis8vcdrne" path="res://assets/graphics/game_setting/arrow_down.png" id="2_ucrj8"] [ext_resource type="Texture2D" uid="uid://djtnarduvxu5i" path="res://assets/graphics/game_setting/checkbox_off.png" id="2_w7n4t"] [ext_resource type="Texture2D" uid="uid://dpcrm3nenf3vy" path="res://assets/graphics/game_setting/check_tex.png" id="3_w7n4t"] @@ -99,6 +99,7 @@ HSlider/styles/grabber_area_highlight = SubResource("StyleBoxFlat_dvgdt") HSlider/styles/slider = SubResource("StyleBoxFlat_w4ep3") Label/colors/font_outline_color = Color(0.46666667, 0.32941177, 0.24313726, 1) Label/constants/outline_size = 13 +Label/fonts/font = ExtResource("1_ofq5d") OptionButton/font_sizes/font_size = 24 OptionButton/fonts/font = ExtResource("1_ofq5d") OptionButton/icons/arrow = ExtResource("2_ucrj8") diff --git a/scenes/main.tscn b/scenes/main.tscn index 41d0661..06c1e08 100644 --- a/scenes/main.tscn +++ b/scenes/main.tscn @@ -14,13 +14,11 @@ [ext_resource type="Texture2D" uid="uid://68x88jj25yxg" path="res://assets/textures/Adjacent.png" id="9_6gcb6"] [ext_resource type="Texture2D" uid="uid://dasaeaytvhll0" path="res://assets/models/pboard/AdjacentRect.tres" id="9_aspsw"] [ext_resource type="FontFile" uid="uid://xnjx058n4tsw" path="res://assets/fonts/Nougat-ExtraBlack.ttf" id="13_j8jky"] +[ext_resource type="Theme" uid="uid://0dhxl4ohyxh8" path="res://assets/graphics/game_setting/setting_theme.tres" id="18_pm3ni"] [ext_resource type="Texture2D" uid="uid://ba80xnybpixw2" path="res://assets/graphics/touch_control/take_tile.png" id="25_qkpxi"] [ext_resource type="Texture2D" uid="uid://bsgqrjx2ity4c" path="res://assets/graphics/touch_control/speed.png" id="26_2f3dj"] [ext_resource type="Texture2D" uid="uid://pwxo4lb87yi" path="res://assets/graphics/touch_control/put_tile.png" id="26_5q0nq"] [ext_resource type="Texture2D" uid="uid://umw3e8nfe3vr" path="res://assets/graphics/touch_control/attack_mode.png" id="27_dgi5k"] -[ext_resource type="Texture2D" uid="uid://cupfmb5m15kmf" path="res://assets/graphics/touch_control/wall.png" id="27_yq6so"] -[ext_resource type="Texture2D" uid="uid://dcwdbeqla0ooi" path="res://assets/graphics/touch_control/freeze_area.png" id="28_fv21b"] -[ext_resource type="Texture2D" uid="uid://b2vhatfmufn3d" path="res://assets/graphics/touch_control/ghost.png" id="33_5q0nq"] [ext_resource type="Texture2D" uid="uid://biun2yvglxgij" path="res://assets/graphics/touch_control/grab_tekton.png" id="36_pibwh"] [ext_resource type="Script" uid="uid://86ikh0wuqk7v" path="res://scripts/ui/powerup_inventory_ui.gd" id="powerup_ui_script"] [ext_resource type="Script" uid="uid://b54tfa0n6kogi" path="res://scripts/managers/touch_controls.gd" id="touch_manager"] @@ -1175,29 +1173,20 @@ anchor_left = 1.0 anchor_top = 1.0 anchor_right = 1.0 anchor_bottom = 1.0 -offset_left = -94.0 -offset_top = -432.0 -offset_right = -94.0 -offset_bottom = -432.0 +offset_left = -1252.0 +offset_top = -140.00006 +offset_right = -1252.0 +offset_bottom = -140.00006 grow_horizontal = 0 grow_vertical = 0 +rotation = -0.10297442 +theme = ExtResource("18_pm3ni") script = ExtResource("powerup_ui_script") -[node name="Container" type="VBoxContainer" parent="PowerUpInventoryUI" unique_id=1100906843] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = -31.999996 -offset_right = 41.00098 -offset_bottom = 350.0 -grow_horizontal = 2 -grow_vertical = 2 -rotation = 0.10297442 -theme_override_constants/separation = 10 - -[node name="SpeedBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=1549270030] -layout_mode = 2 +[node name="PowerUpBtn" type="Button" parent="PowerUpInventoryUI" unique_id=1549270030] +layout_mode = 0 +offset_right = 74.28728 +offset_bottom = 78.35126 size_flags_horizontal = 3 size_flags_vertical = 3 focus_mode = 0 @@ -1206,36 +1195,6 @@ flat = true icon_alignment = 1 expand_icon = true -[node name="WallBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=863365575] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -focus_mode = 0 -icon = ExtResource("27_yq6so") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="FreezeAreaBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=1087493560] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -focus_mode = 0 -icon = ExtResource("28_fv21b") -flat = true -icon_alignment = 1 -expand_icon = true - -[node name="GhostBtn" type="Button" parent="PowerUpInventoryUI/Container" unique_id=2041811828] -layout_mode = 2 -size_flags_horizontal = 3 -size_flags_vertical = 3 -focus_mode = 0 -icon = ExtResource("33_5q0nq") -flat = true -icon_alignment = 1 -expand_icon = true - [node name="LeaderboardPanel" type="PanelContainer" parent="." unique_id=364209533] anchors_preset = 1 anchor_left = 1.0 @@ -1419,6 +1378,7 @@ offset_top = 318.0 grow_horizontal = 2 grow_vertical = 2 mouse_filter = 2 +theme = ExtResource("18_pm3ni") [node name="VirtualJoystick" type="Control" parent="TouchControls/TouchControls" unique_id=1983608919] visible = false @@ -1440,6 +1400,7 @@ offset_top = 98.014656 offset_right = 129.85825 offset_bottom = 265.01465 rotation = -0.10297442 +theme_override_constants/separation = 10 [node name="AttackModeBtn" type="Button" parent="TouchControls/TouchControls/PowerBarBtn" unique_id=1380511463] layout_mode = 2 @@ -1462,11 +1423,12 @@ expand_icon = true [node name="InteractionBtn" type="VBoxContainer" parent="TouchControls/TouchControls" unique_id=1738242916] layout_mode = 0 -offset_left = 134.0 +offset_left = 131.0 offset_top = 86.999985 -offset_right = 216.0 +offset_right = 213.0 offset_bottom = 254.0 rotation = -0.10297442 +theme_override_constants/separation = 10 [node name="GrabBtn" type="Button" parent="TouchControls/TouchControls/InteractionBtn" unique_id=914810452] layout_mode = 2 diff --git a/scripts/ui/powerup_inventory_ui.gd b/scripts/ui/powerup_inventory_ui.gd index a5625ad..c21b4d7 100644 --- a/scripts/ui/powerup_inventory_ui.gd +++ b/scripts/ui/powerup_inventory_ui.gd @@ -5,10 +5,17 @@ extends Control # PowerUpInventoryUI - Displays stored powerups and handles selection # UI References -var icon_containers: Dictionary = {} # { EffectEnum: Button } +# UI References +var power_up_button: Button +var effect_textures: Dictionary = { + 0: preload("res://assets/graphics/touch_control/speed.png"), + 1: preload("res://assets/graphics/touch_control/freeze_area.png"), + 2: preload("res://assets/graphics/touch_control/wall.png"), + 3: preload("res://assets/graphics/touch_control/ghost.png") +} # Local State -var selected_effect: int = -1 +var current_effect: int = -1 var special_manager_ref: Node = null # Reference to SpecialTilesManager @onready var SettingsManager = get_node_or_null("/root/SettingsManager") @@ -20,78 +27,44 @@ func _ready(): # Connect to SettingsManager to update labels if SettingsManager and not SettingsManager.control_remapped.is_connected(_on_control_remapped): SettingsManager.control_remapped.connect(_on_control_remapped) - # Map Effect Enum to UI Nodes (Assumes specific names in main.tscn) - # We try to get them immediately. If they are children, they should be accessible. - var container = get_node_or_null("Container") - if not container: - print("[PowerUpUI] ERROR: Container not found in ", get_path()) - return - - # Center buttons in the container instead of spreading them out - container.alignment = BoxContainer.ALIGNMENT_CENTER - # Mapping based on User Request - # 11: FASTER_SPEED (0) -> SpeedBtn - # 12: AREA_FREEZE (1) -> FreezeAreaBtn - # 13: BLOCK_FLOOR (2) -> WallBtn - # 14: INVISIBLE_MODE (3) -> GhostBtn - - # We use 0, 1, 2, 3 to match SpecialTilesManager.SpecialEffect enum - var speed_btn = container.get_node_or_null("SpeedBtn") - var freeze_btn = container.get_node_or_null("FreezeAreaBtn") - var wall_btn = container.get_node_or_null("WallBtn") - var ghost_btn = container.get_node_or_null("GhostBtn") - - var mode = LobbyManager.get_game_mode() - var is_restricted = GameMode.is_restricted(mode) - - _setup_btn(0, speed_btn) - _setup_btn(1, freeze_btn) - _setup_btn(2, wall_btn) - _setup_btn(3, ghost_btn) + # New Single Button UI + power_up_button = get_node_or_null("PowerUpBtn") + if not power_up_button: + # Fallback to Container/PowerUpBtn just in case + power_up_button = get_node_or_null("Container/PowerUpBtn") + + if not power_up_button: + print("[PowerUpUI] ERROR: PowerUpBtn not found") + return - # Remove mode-based restrictions on visibility for now, as ownership controls visibility - if wall_btn: wall_btn.visible = false - if freeze_btn: freeze_btn.visible = false - if speed_btn: speed_btn.visible = false - if ghost_btn: ghost_btn.visible = false + # Helper to setup the single button + _setup_powerup_btn(power_up_button) - _update_shortcuts_for_mode(is_restricted) + # Start hidden until player has a powerup + power_up_button.visible = false - - print("[PowerUpUI] UI Initialization Complete. Mapped %d buttons." % icon_containers.size()) + print("[PowerUpUI] UI Initialization Complete (Single Button Mode).") + func _on_control_remapped(_action: String, _key: int): # Refresh all labels _update_shortcuts_for_mode(LobbyManager.is_game_mode(GameMode.Mode.STOP_N_GO)) -func _setup_btn(effect_id: int, btn: Button): - if not btn: - print("[PowerUpUI] Warning: Button for effect %d is null" % effect_id) - return - - icon_containers[effect_id] = btn - +func _setup_powerup_btn(btn: Button): # Start DISABLED btn.disabled = true - btn.modulate = Color(0.5, 0.5, 0.5, 0.5) # Grayed out + btn.modulate = Color(0.5, 0.5, 0.5, 0.5) btn.focus_mode = Control.FOCUS_NONE - # Fix "Floating" issue: don't expand button to fill whole container height - # This keeps the buttons grouped tightly together - btn.size_flags_vertical = Control.SIZE_SHRINK_CENTER - btn.custom_minimum_size.y = 80 # Consistent height - - - # Add Cooldown Overlay if not btn.has_node("CooldownOverlay"): var overlay = ColorRect.new() overlay.name = "CooldownOverlay" overlay.mouse_filter = Control.MOUSE_FILTER_IGNORE - overlay.color = Color(0, 0, 0, 0.6) # Semi-transparent black + overlay.color = Color(0, 0, 0, 0.6) overlay.set_anchors_preset(Control.PRESET_FULL_RECT) - overlay.anchor_top = 1.0 # Start empty at bottom + overlay.anchor_top = 1.0 overlay.grow_vertical = Control.GROW_DIRECTION_BEGIN btn.add_child(overlay) @@ -100,29 +73,30 @@ func _setup_btn(effect_id: int, btn: Button): var sc_lbl = Label.new() sc_lbl.name = "ShortcutLabel" sc_lbl.mouse_filter = Control.MOUSE_FILTER_IGNORE - sc_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_LEFT + sc_lbl.horizontal_alignment = HORIZONTAL_ALIGNMENT_RIGHT sc_lbl.vertical_alignment = VERTICAL_ALIGNMENT_TOP - sc_lbl.set_anchors_preset(Control.PRESET_FULL_RECT) - sc_lbl.offset_left = 5 - sc_lbl.offset_top = -4 # Lowered slightly from -12 + sc_lbl.set_anchors_preset(Control.PRESET_TOP_RIGHT) + sc_lbl.offset_left = -60 # Width of label roughly + sc_lbl.offset_right = 6 + sc_lbl.offset_top = -4 + sc_lbl.offset_bottom = 12 sc_lbl.add_theme_font_size_override("font_size", 16) sc_lbl.add_theme_color_override("font_outline_color", Color.BLACK) sc_lbl.add_theme_constant_override("outline_size", 4) sc_lbl.add_theme_color_override("font_color", Color(0.9, 0.9, 0.9)) btn.add_child(sc_lbl) - _update_btn_shortcut(effect_id, btn) + _update_btn_shortcut(btn) # Connect click if not btn.pressed.is_connected(_on_btn_pressed): - btn.pressed.connect(_on_btn_pressed.bind(effect_id)) + btn.pressed.connect(_on_btn_pressed) -func _update_shortcuts_for_mode(is_restricted: bool): - for effect_id in icon_containers: - var btn = icon_containers[effect_id] - _update_btn_shortcut(effect_id, btn) +func _update_shortcuts_for_mode(_is_restricted: bool): + if power_up_button: + _update_btn_shortcut(power_up_button) -func _update_btn_shortcut(_effect_id: int, btn: Button): +func _update_btn_shortcut(btn: Button): var sc_lbl = btn.get_node_or_null("ShortcutLabel") if not sc_lbl: return @@ -130,15 +104,16 @@ func _update_btn_shortcut(_effect_id: int, btn: Button): sc_lbl.text = "" return - # Show only Shortcut 1 as per single-slot request + # Show universal powerup shortcut sc_lbl.text = " %s " % SettingsManager.get_control_text("use_powerup") -func _on_btn_pressed(effect_id: int): - print("[PowerUpUI] Clicked Button %d" % effect_id) +func _on_btn_pressed(effect_id: int = -1): + var target_effect = effect_id if effect_id != -1 else current_effect + if target_effect == -1: return + + print("[PowerUpUI] Activating effect: %d" % target_effect) if special_manager_ref: - special_manager_ref.activate_effect(effect_id) - else: - print("[PowerUpUI] ERROR: special_manager_ref is null during click") + special_manager_ref.activate_effect(target_effect) func setup(player_node): print("[PowerUpUI] Setup called for player: ", player_node.name) @@ -160,28 +135,25 @@ func _on_player_child_entered(node: Node, player_node: Node): player_node.child_entered_tree.disconnect(_on_player_child_entered) func _on_global_cooldown_updated(time_left: float, max_time: float): - for effect in icon_containers: - var btn = icon_containers[effect] - var overlay = btn.get_node_or_null("CooldownOverlay") - if overlay: - if time_left > 0: - overlay.visible = true - overlay.anchor_top = 1.0 - (time_left / max_time) - btn.disabled = true - else: - overlay.visible = false - overlay.anchor_top = 1.0 - if special_manager_ref and special_manager_ref.inventory.get(effect, false): - btn.disabled = false + if not power_up_button: return + + var overlay = power_up_button.get_node_or_null("CooldownOverlay") + if overlay: + if time_left > 0: + overlay.visible = true + overlay.anchor_top = 1.0 - (time_left / max_time) + power_up_button.disabled = true + else: + overlay.visible = false + overlay.anchor_top = 1.0 + if current_effect != -1: + power_up_button.disabled = false func _connect_special_manager(special_manager): special_manager_ref = special_manager print("[PowerUpUI] Connected to SpecialTilesManager") # Connect signals if not already connected - if not special_manager.is_connected("powerup_unlocked", _on_powerup_unlocked): - special_manager.connect("powerup_unlocked", _on_powerup_unlocked) - if not special_manager.is_connected("inventory_updated", _on_inventory_updated): special_manager.connect("inventory_updated", _on_inventory_updated) @@ -189,56 +161,36 @@ func _connect_special_manager(special_manager): special_manager.connect("global_cooldown_updated", _on_global_cooldown_updated) # Initial State Sync - if icon_containers.is_empty(): - print("[PowerUpUI] Warning: Icon containers empty during setup. Attempting _ready logic now...") - var container = get_node_or_null("Container") - if container: - _setup_btn(0, container.get_node_or_null("SpeedBtn")) - _setup_btn(1, container.get_node_or_null("FreezeAreaBtn")) - _setup_btn(2, container.get_node_or_null("WallBtn")) - _setup_btn(3, container.get_node_or_null("GhostBtn")) + if not power_up_button: + _ready() # Sync Inventory _on_inventory_updated(special_manager.inventory) - - # Sync Levels for owned items - for effect in special_manager.inventory: - if special_manager.inventory[effect]: - var lvl = special_manager.powerup_levels.get(effect, 1) - _on_powerup_unlocked(effect, lvl) - -func _on_powerup_unlocked(effect: int, level: int): - # Enable button and set level - if icon_containers.has(effect): - var btn = icon_containers[effect] - print("[PowerUpUI] Enabling button for Effect %d (Node: %s)" % [effect, btn.name]) - btn.disabled = false - btn.modulate = Color.WHITE # Restore color - btn.visible = true # Ensure visible - - - # Enforce 1-slot rule by hiding others - if special_manager_ref: - _on_inventory_updated(special_manager_ref.inventory) - else: - print("[PowerUpUI] ERROR: Unlocked Effect %d but no UI button found! Keys: %s" % [effect, icon_containers.keys()]) - func _on_inventory_updated(inventory: Dictionary): - # Update UI icons (Only show ONE active slot as per user request) - print("[PowerUpUI] Inventory Updated Signal Received! Data: ", inventory) - for effect in icon_containers: - var has_item = inventory.get(effect, false) - var btn = icon_containers[effect] + if not power_up_button: return + + # Update UI icon (Single slot logic) + var active_effect: int = -1 + for effect in inventory: + if inventory[effect] == true: + active_effect = effect + break + + current_effect = active_effect + + if active_effect != -1: + power_up_button.visible = true + power_up_button.icon = effect_textures.get(active_effect) - # Single slot logic: Only the owned one is visible - btn.visible = has_item - if has_item: - # Check global cooldown before enabling - var is_cooling = false - if special_manager_ref and special_manager_ref.global_cooldown_timer > 0: - is_cooling = true - - btn.disabled = is_cooling - btn.modulate = Color.WHITE - _update_btn_shortcut(effect, btn) + # Check global cooldown + var is_cooling = false + if special_manager_ref and special_manager_ref.global_cooldown_timer > 0: + is_cooling = true + + power_up_button.disabled = is_cooling + power_up_button.modulate = Color.WHITE + _update_btn_shortcut(power_up_button) + else: + power_up_button.visible = false + power_up_button.disabled = true