This commit is contained in:
Tomasz Boruc 2026-10-10 23:40:48 +02:00
parent d0c79cafe9
commit 6658adf389
9 changed files with 206 additions and 111 deletions

View File

@ -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);
}

View File

@ -0,0 +1 @@
uid://dtuw26qesw8ia

View File

@ -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"

View File

@ -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.

View File

@ -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:

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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)