From 6658adf3894d1545daa2437e1141ba8f0b581794 Mon Sep 17 00:00:00 2001 From: Tomasz Boruc Date: Sat, 10 Oct 2026 23:40:48 +0200 Subject: [PATCH] Poprawka --- resources/ui/ship_silhouette.gdshader | 7 + resources/ui/ship_silhouette.gdshader.uid | 1 + scenes/ui/ship_equipment_panel.tscn | 148 +++++++++++++--------- scripts/game/flight_hud.gd | 27 ++-- scripts/game/game.gd | 2 +- scripts/game/weapon_controller.gd | 16 +++ scripts/ui/equipment_slot_view.gd | 20 +++ scripts/ui/ship_inventory_panel.gd | 30 ++++- scripts/ui/ship_schematic.gd | 66 ++++------ 9 files changed, 206 insertions(+), 111 deletions(-) create mode 100644 resources/ui/ship_silhouette.gdshader create mode 100644 resources/ui/ship_silhouette.gdshader.uid diff --git a/resources/ui/ship_silhouette.gdshader b/resources/ui/ship_silhouette.gdshader new file mode 100644 index 0000000..eeed4c3 --- /dev/null +++ b/resources/ui/ship_silhouette.gdshader @@ -0,0 +1,7 @@ +shader_type canvas_item; + +void fragment() { + vec4 pixel = texture(TEXTURE, UV); + float gray = dot(pixel.rgb, vec3(0.299, 0.587, 0.114)); + COLOR *= vec4(mix(pixel.rgb, vec3(gray), 0.8), pixel.a); +} diff --git a/resources/ui/ship_silhouette.gdshader.uid b/resources/ui/ship_silhouette.gdshader.uid new file mode 100644 index 0000000..9d480a4 --- /dev/null +++ b/resources/ui/ship_silhouette.gdshader.uid @@ -0,0 +1 @@ +uid://dtuw26qesw8ia diff --git a/scenes/ui/ship_equipment_panel.tscn b/scenes/ui/ship_equipment_panel.tscn index ccd4984..ce7d425 100644 --- a/scenes/ui/ship_equipment_panel.tscn +++ b/scenes/ui/ship_equipment_panel.tscn @@ -4,113 +4,141 @@ [ext_resource type="PackedScene" path="res://scenes/ui/inventory_slot_view.tscn" id="2_slot"] [sub_resource type="StyleBoxFlat" id="EquipmentPanelStyle"] -bg_color = Color(0.018, 0.045, 0.085, 0.88) +bg_color = Color(0.018, 0.028, 0.043, 0.96) border_width_left = 1 border_width_top = 1 border_width_right = 1 border_width_bottom = 1 -border_color = Color(0.12, 0.32, 0.4, 0.9) +border_color = Color(0.38, 0.42, 0.46, 0.9) content_margin_left = 7.0 -content_margin_top = 6.0 +content_margin_top = 7.0 content_margin_right = 7.0 -content_margin_bottom = 6.0 +content_margin_bottom = 7.0 +corner_radius_top_left = 3 +corner_radius_top_right = 3 +corner_radius_bottom_left = 3 +corner_radius_bottom_right = 3 [node name="ShipEquipmentPanel" type="PanelContainer"] anchors_preset = 1 anchor_left = 1.0 anchor_right = 1.0 -offset_left = -248.0 -offset_top = 14.0 -offset_right = -14.0 -offset_bottom = 454.0 +offset_left = -330.0 +offset_top = 244.0 +offset_right = -10.0 +offset_bottom = 634.0 grow_horizontal = 0 -grow_vertical = 0 +grow_vertical = 1 theme_override_styles/panel = SubResource("EquipmentPanelStyle") [node name="Contents" type="VBoxContainer" parent="."] layout_mode = 2 -theme_override_constants/separation = 3 +theme_override_constants/separation = 6 [node name="Title" type="Label" parent="Contents"] layout_mode = 2 -theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) -theme_override_font_sizes/font_size = 11 +theme_override_colors/font_color = Color(0.8, 0.84, 0.88, 1) +theme_override_font_sizes/font_size = 12 text = "WYPOSAŻENIE STATKU" horizontal_alignment = 1 -[node name="WeaponLabel" type="Label" parent="Contents"] -visible = false +[node name="EquipmentLayout" type="Control" parent="Contents"] +custom_minimum_size = Vector2(306, 318) layout_mode = 2 -theme_override_colors/font_color = Color(0.98, 0.72, 0.38, 1) -theme_override_font_sizes/font_size = 10 -text = "BROŃ PRZEDNIA" -horizontal_alignment = 1 +mouse_filter = 2 -[node name="WeaponSlots" type="HBoxContainer" parent="Contents"] -layout_mode = 2 -theme_override_constants/separation = 8 - -[node name="Weapon1" parent="Contents/WeaponSlots" instance=ExtResource("2_slot")] -layout_mode = 2 -custom_minimum_size = Vector2(90, 38) -slot_kind = "weapon" -slot_index = 0 - -[node name="Weapon2" parent="Contents/WeaponSlots" instance=ExtResource("2_slot")] -layout_mode = 2 -custom_minimum_size = Vector2(90, 38) -slot_kind = "weapon" -slot_index = 1 - -[node name="Schematic" type="Control" parent="Contents"] -custom_minimum_size = Vector2(0, 64) -layout_mode = 2 +[node name="Schematic" type="Control" parent="Contents/EquipmentLayout"] +layout_mode = 1 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 +grow_vertical = 2 +mouse_filter = 2 script = ExtResource("1_schematic") -[node name="ModuleLabel" type="Label" parent="Contents"] -layout_mode = 2 -theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) -theme_override_font_sizes/font_size = 10 -text = "MODUŁY (1–6)" -horizontal_alignment = 1 +[node name="Weapon1" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 44.0 +offset_top = 22.0 +offset_right = 134.0 +offset_bottom = 66.0 +slot_kind = "weapon" +slot_index = 0 +overlay_slot = true -[node name="ModuleSlots" type="GridContainer" parent="Contents"] -layout_mode = 2 -columns = 2 -theme_override_constants/h_separation = 6 -theme_override_constants/v_separation = 3 +[node name="Weapon2" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 172.0 +offset_top = 22.0 +offset_right = 262.0 +offset_bottom = 66.0 +slot_kind = "weapon" +slot_index = 1 +overlay_slot = true -[node name="Module1" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] -layout_mode = 2 +[node name="Module1" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 0.0 +offset_top = 100.0 +offset_right = 104.0 +offset_bottom = 144.0 slot_kind = "module" slot_index = 0 +overlay_slot = true -[node name="Module2" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] -layout_mode = 2 +[node name="Module2" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 202.0 +offset_top = 100.0 +offset_right = 306.0 +offset_bottom = 144.0 slot_kind = "module" slot_index = 1 +overlay_slot = true -[node name="Module3" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] -layout_mode = 2 +[node name="Module3" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 0.0 +offset_top = 180.0 +offset_right = 104.0 +offset_bottom = 224.0 slot_kind = "module" slot_index = 2 +overlay_slot = true -[node name="Module4" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] -layout_mode = 2 +[node name="Module4" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 202.0 +offset_top = 180.0 +offset_right = 306.0 +offset_bottom = 224.0 slot_kind = "module" slot_index = 3 +overlay_slot = true -[node name="Module5" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] -layout_mode = 2 +[node name="Module5" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 0.0 +offset_top = 260.0 +offset_right = 104.0 +offset_bottom = 304.0 slot_kind = "module" slot_index = 4 +overlay_slot = true -[node name="Module6" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] -layout_mode = 2 +[node name="Module6" parent="Contents/EquipmentLayout" instance=ExtResource("2_slot")] +layout_mode = 0 +offset_left = 202.0 +offset_top = 260.0 +offset_right = 306.0 +offset_bottom = 304.0 slot_kind = "module" slot_index = 5 +overlay_slot = true [node name="InventoryButton" type="Button" parent="Contents"] layout_mode = 2 +custom_minimum_size = Vector2(0, 28) theme_override_font_sizes/font_size = 12 text = "MAGAZYN" diff --git a/scripts/game/flight_hud.gd b/scripts/game/flight_hud.gd index dd928a6..c8019ae 100644 --- a/scripts/game/flight_hud.gd +++ b/scripts/game/flight_hud.gd @@ -11,6 +11,7 @@ var _ability_buttons: Dictionary = {} var _ability_bar: HBoxContainer var _ability_ready_style: StyleBoxFlat var _ability_blocked_style: StyleBoxFlat +var _inventory_clip: Control func _ready() -> void: var energy_indicator := Node2D.new() @@ -28,15 +29,18 @@ func _ready() -> void: var equipment := $HUDRoot/ShipEquipmentPanel as Control equipment.set("layout_mode", 1) equipment.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT) - equipment.offset_left = -270.0 + equipment.offset_left = -330.0 equipment.offset_right = -10.0 - inventory_panel.set("layout_mode", 1) - inventory_panel.set_anchors_and_offsets_preset(Control.PRESET_CENTER_BOTTOM) - inventory_panel.grow_vertical = Control.GROW_DIRECTION_BEGIN - inventory_panel.offset_left = -390.0 - inventory_panel.offset_right = 390.0 - inventory_panel.offset_top = -330.0 - inventory_panel.offset_bottom = -62.0 + _inventory_clip = Control.new() + _inventory_clip.name = "InventoryDrawer" + _inventory_clip.clip_contents = true + _inventory_clip.mouse_filter = Control.MOUSE_FILTER_IGNORE + $HUDRoot.add_child(_inventory_clip) + inventory_panel.reparent(_inventory_clip, false) + inventory_panel.set("layout_mode", 0) + inventory_panel.set_anchors_and_offsets_preset(Control.PRESET_TOP_LEFT) + inventory_panel.size = Vector2(780, inventory_panel.get_combined_minimum_size().y) + $HUDRoot.resized.connect(func() -> void: _layout_sidebar.call_deferred()) _create_ability_bar() debug_toggle.pressed.connect(_toggle_debug) inventory_button.pressed.connect(_toggle_inventory) @@ -51,6 +55,8 @@ func _layout_sidebar() -> void: equipment_panel.grow_vertical = Control.GROW_DIRECTION_END equipment_panel.position.y = captain_panel.position.y + captain_panel.size.y + 6.0 equipment_panel.size.y = equipment_panel.get_combined_minimum_size().y + _inventory_clip.size = inventory_panel.size + _inventory_clip.position = Vector2(equipment_panel.position.x - _inventory_clip.size.x - 8, equipment_panel.position.y) func _process(_delta: float) -> void: _update_ability_bar() @@ -109,7 +115,10 @@ func _update_debug_toggle() -> void: debug_toggle.text = "DEBUG [−]" if _debug_expanded else "DEBUG [+]" func _toggle_inventory() -> void: - inventory_panel.visible = not inventory_panel.visible + inventory_panel.call("toggle_drawer") + +func close_inventory() -> void: + inventory_panel.call("close_drawer", true) func _get_bonus_summary() -> String: # Read final ship values so gear and captain multipliers match actual combat. diff --git a/scripts/game/game.gd b/scripts/game/game.gd index f4d2534..d8544a9 100644 --- a/scripts/game/game.gd +++ b/scripts/game/game.gd @@ -120,7 +120,7 @@ func _physics_process(_delta: float) -> void: player.velocity = Vector2.ZERO player.set("angular_velocity", 0.0) player.set("is_docked", true) - $HUD/HUDRoot/ShipInventoryPanel.hide() + $HUD.call("close_inventory") services_menu.call("show_services", GameState.system_level >= LEVEL_BALANCE.MAX_LEVEL) func is_near_protected_planet() -> bool: diff --git a/scripts/game/weapon_controller.gd b/scripts/game/weapon_controller.gd index 12e2bdf..da26b84 100644 --- a/scripts/game/weapon_controller.gd +++ b/scripts/game/weapon_controller.gd @@ -13,6 +13,7 @@ var _laser_pulse_timers := [0.0, 0.0] var _laser_lines: Array[Line2D] = [] var _fire_buttons_down := [false, false] var _fire_just_pressed := [false, false] +var _drag_fire_blocked := false func _ready() -> void: _ensure_input_action(&"ship_fire_primary", MOUSE_BUTTON_LEFT) @@ -37,6 +38,8 @@ func _ensure_input_action(action_name: StringName, button: MouseButton) -> void: func _unhandled_input(event: InputEvent) -> void: if not event is InputEventMouseButton: return + if ship.get_viewport().gui_is_dragging() or _drag_fire_blocked: + return var slot_index := -1 if event.button_index == MOUSE_BUTTON_LEFT: slot_index = 0 @@ -49,6 +52,19 @@ func _unhandled_input(event: InputEvent) -> void: _fire_just_pressed[slot_index] = true func _physics_process(delta: float) -> void: + if ship.get_viewport().gui_is_dragging(): + _drag_fire_blocked = true + if _drag_fire_blocked: + for index in 2: + _fire_buttons_down[index] = false + _fire_just_pressed[index] = false + _laser_pulse_timers[index] = 0.0 + _laser_lines[index].visible = false + _shot_timers[index] = maxf(0.0, _shot_timers[index] - delta) + # Require release after dropping, so the drag gesture cannot become a shot. + if not ship.get_viewport().gui_is_dragging() and not Input.is_mouse_button_pressed(MOUSE_BUTTON_LEFT) and not Input.is_mouse_button_pressed(MOUSE_BUTTON_RIGHT): + _drag_fire_blocked = false + return if bool(ship.get("_is_destroyed")) or bool(ship.get("is_docked")): for line in _laser_lines: line.visible = false diff --git a/scripts/ui/equipment_slot_view.gd b/scripts/ui/equipment_slot_view.gd index dfb54d0..cac39ac 100644 --- a/scripts/ui/equipment_slot_view.gd +++ b/scripts/ui/equipment_slot_view.gd @@ -2,6 +2,7 @@ extends PanelContainer @export var slot_kind: String = "cargo" @export var slot_index: int = 0 +@export var overlay_slot: bool = false @onready var slot_label: Label = $SlotLabel @@ -43,6 +44,23 @@ func _ready() -> void: slot_label.size_flags_vertical = Control.SIZE_EXPAND_FILL slot_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART slot_label.text_overrun_behavior = TextServer.OVERRUN_NO_TRIMMING + if overlay_slot: + custom_minimum_size.y = 44 + slot_label.custom_minimum_size.y = 32 + slot_label.size_flags_vertical = Control.SIZE_EXPAND_FILL + slot_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART + slot_label.text_overrun_behavior = TextServer.OVERRUN_NO_TRIMMING + var binding := Label.new() + binding.mouse_filter = Control.MOUSE_FILTER_IGNORE + binding.text = ("LPM" if slot_index == 0 else "PPM") if slot_kind == "weapon" else str(slot_index + 1) + binding.position = Vector2(2, -14) + binding.add_theme_font_size_override("font_size", 9) + binding.add_theme_color_override("font_color", Color("a0b2c4")) + # Use a plain overlay to keep the binding outside the slot's content layout. + var marker := Control.new() + marker.mouse_filter = Control.MOUSE_FILTER_IGNORE + add_child(marker) + marker.add_child(binding) _refresh() func _refresh() -> void: @@ -73,6 +91,8 @@ func _apply_slot_style(item: ItemInstance) -> void: style.border_color = item.get_type_color() style.bg_color = item.get_background_color() style.set_border_width_all(2) + if overlay_slot: + style.bg_color.a = 0.86 if item != null else 0.48 add_theme_stylebox_override("panel", style) func _delete_item() -> void: diff --git a/scripts/ui/ship_inventory_panel.gd b/scripts/ui/ship_inventory_panel.gd index 9a09245..ebda3c6 100644 --- a/scripts/ui/ship_inventory_panel.gd +++ b/scripts/ui/ship_inventory_panel.gd @@ -8,9 +8,12 @@ const CARGO_SIZE := 20 @onready var title_label: Label = $Contents/Header/Title var _inventory: ShipInventory +var _drawer_open := false +var _slide_tween: Tween +var drawer_width := 780.0 func _ready() -> void: - close_button.pressed.connect(func() -> void: hide()) + close_button.pressed.connect(close_drawer) _inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory if _inventory: _inventory.inventory_changed.connect(_refresh_title) @@ -25,3 +28,28 @@ func _ready() -> void: func _refresh_title() -> void: if _inventory: title_label.text = "MAGAZYN (%d/%d) · Części: %.1f" % [_inventory.get_cargo_used(), CARGO_SIZE, GameState.captain.parts] + +func toggle_drawer() -> void: + _set_drawer_open(not _drawer_open) + +func close_drawer(immediately: bool = false) -> void: + if immediately: + if _slide_tween != null and _slide_tween.is_running(): + _slide_tween.kill() + _drawer_open = false + position.x = drawer_width + hide() + return + _set_drawer_open(false) + +func _set_drawer_open(value: bool) -> void: + if _slide_tween != null and _slide_tween.is_running(): + _slide_tween.kill() + _drawer_open = value + if value and not visible: + position = Vector2(drawer_width, 0) + show() + _slide_tween = create_tween() + _slide_tween.tween_property(self, "position:x", 0.0 if value else drawer_width, 0.25).set_trans(Tween.TRANS_CUBIC).set_ease(Tween.EASE_OUT if value else Tween.EASE_IN) + if not value: + _slide_tween.tween_callback(hide) diff --git a/scripts/ui/ship_schematic.gd b/scripts/ui/ship_schematic.gd index b8a74cb..2393264 100644 --- a/scripts/ui/ship_schematic.gd +++ b/scripts/ui/ship_schematic.gd @@ -1,43 +1,29 @@ extends Control +const CATALOG := preload("res://scripts/game/ship_catalog.gd") +const SILHOUETTE_SHADER := preload("res://resources/ui/ship_silhouette.gdshader") +var _portrait: TextureRect + +func _ready() -> void: + mouse_filter = Control.MOUSE_FILTER_IGNORE + _portrait = TextureRect.new() + _portrait.texture = load(CATALOG.texture_path(CATALOG.for_path(GameState.selected_ship_path))) as Texture2D + _portrait.expand_mode = TextureRect.EXPAND_IGNORE_SIZE + _portrait.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED + _portrait.mouse_filter = Control.MOUSE_FILTER_IGNORE + var material := ShaderMaterial.new() + material.shader = SILHOUETTE_SHADER + _portrait.material = material + add_child(_portrait) + _portrait.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) + _portrait.offset_left = 26 + _portrait.offset_right = -26 + _portrait.offset_top = 12 + _portrait.offset_bottom = -12 + _portrait.modulate = Color(0.78, 0.86, 0.92, 0.56) + func _draw() -> void: - var center := 0.0 - var diagram_scale := minf(size.y / 140.0, size.x / 140.0) - draw_set_transform(Vector2(size.x * 0.5, 0.0), 0.0, Vector2.ONE * diagram_scale) - var hull_color := Color(0.35, 0.72, 0.85, 1.0) - var hull_highlight := Color(0.72, 0.9, 0.96, 1.0) - var weapon_color := Color(0.98, 0.65, 0.28, 1.0) - - var fuselage := PackedVector2Array([ - Vector2(center, 8), - Vector2(center + 13, 44), - Vector2(center + 25, 100), - Vector2(center, 132), - Vector2(center - 25, 100), - Vector2(center - 13, 44), - ]) - var left_wing := PackedVector2Array([ - Vector2(center - 11, 49), - Vector2(center - 62, 82), - Vector2(center - 46, 108), - Vector2(center - 23, 96), - ]) - var right_wing := PackedVector2Array([ - Vector2(center + 11, 49), - Vector2(center + 62, 82), - Vector2(center + 46, 108), - Vector2(center + 23, 96), - ]) - - draw_colored_polygon(left_wing, hull_color) - draw_colored_polygon(right_wing, hull_color) - draw_colored_polygon(fuselage, hull_highlight) - draw_polyline(PackedVector2Array([Vector2(center, 17), Vector2(center, 116)]), hull_color, 2.0) - draw_colored_polygon(PackedVector2Array([ - Vector2(center - 18, 32), Vector2(center - 8, 36), - Vector2(center - 10, 48), Vector2(center - 20, 44), - ]), weapon_color) - draw_colored_polygon(PackedVector2Array([ - Vector2(center + 18, 32), Vector2(center + 8, 36), - Vector2(center + 10, 48), Vector2(center + 20, 44), - ]), weapon_color) + var center := size * Vector2(0.5, 0.52) + draw_circle(center, 105, Color(0.07, 0.12, 0.17, 0.45)) + draw_arc(center, 106, 0, TAU, 80, Color(0.33, 0.43, 0.48, 0.28), 1, true) + draw_line(Vector2(center.x, 12), Vector2(center.x, size.y - 12), Color(0.33, 0.43, 0.48, 0.18), 1, true)