From 598835c885ed1346a93ab519af29f0cd18ebc269 Mon Sep 17 00:00:00 2001 From: Tomasz Boruc Date: Fri, 9 Oct 2026 14:51:58 +0200 Subject: [PATCH] Startowe przedmioty i sloty i magazyn --- resources/items/beam_laser.tres | 13 +++ resources/items/compact_generator.tres | 13 +++ resources/items/engine_extension.tres | 13 +++ resources/items/hull_plating.tres | 13 +++ resources/items/plasma_cannon.tres | 13 +++ resources/items/reinforced_shield.tres | 13 +++ scenes/game/game.tscn | 5 +- scenes/game/player_ship.tscn | 6 +- scenes/ui/inventory_slot_view.tscn | 16 ++++ scenes/ui/ship_equipment_panel.tscn | 101 +++++++--------------- scenes/ui/ship_inventory_panel.tscn | 44 ++++++++++ scripts/game/flight_hud.gd | 6 ++ scripts/game/ship_controller.gd | 15 ++++ scripts/items/item_definition.gd | 12 +++ scripts/items/item_definition.gd.uid | 1 + scripts/items/item_instance.gd | 15 ++++ scripts/items/item_instance.gd.uid | 1 + scripts/items/item_stat_modifier.gd | 5 ++ scripts/items/item_stat_modifier.gd.uid | 1 + scripts/items/ship_inventory.gd | 108 ++++++++++++++++++++++++ scripts/items/ship_inventory.gd.uid | 1 + scripts/ui/equipment_slot_view.gd | 94 +++++++++++++++++++++ scripts/ui/equipment_slot_view.gd.uid | 1 + scripts/ui/ship_inventory_panel.gd | 26 ++++++ scripts/ui/ship_inventory_panel.gd.uid | 1 + 25 files changed, 464 insertions(+), 73 deletions(-) create mode 100644 resources/items/beam_laser.tres create mode 100644 resources/items/compact_generator.tres create mode 100644 resources/items/engine_extension.tres create mode 100644 resources/items/hull_plating.tres create mode 100644 resources/items/plasma_cannon.tres create mode 100644 resources/items/reinforced_shield.tres create mode 100644 scenes/ui/inventory_slot_view.tscn create mode 100644 scenes/ui/ship_inventory_panel.tscn create mode 100644 scripts/items/item_definition.gd create mode 100644 scripts/items/item_definition.gd.uid create mode 100644 scripts/items/item_instance.gd create mode 100644 scripts/items/item_instance.gd.uid create mode 100644 scripts/items/item_stat_modifier.gd create mode 100644 scripts/items/item_stat_modifier.gd.uid create mode 100644 scripts/items/ship_inventory.gd create mode 100644 scripts/items/ship_inventory.gd.uid create mode 100644 scripts/ui/equipment_slot_view.gd create mode 100644 scripts/ui/equipment_slot_view.gd.uid create mode 100644 scripts/ui/ship_inventory_panel.gd create mode 100644 scripts/ui/ship_inventory_panel.gd.uid diff --git a/resources/items/beam_laser.tres b/resources/items/beam_laser.tres new file mode 100644 index 0000000..4050a99 --- /dev/null +++ b/resources/items/beam_laser.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "beam_laser" +display_name = "Laser wiązkowy" +category = 0 +description = "Precyzyjna broń o dużym zasięgu." +primary_stat = "damage" +primary_value = 8.0 +stat_suffix = " DMG" diff --git a/resources/items/compact_generator.tres b/resources/items/compact_generator.tres new file mode 100644 index 0000000..f527801 --- /dev/null +++ b/resources/items/compact_generator.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "compact_generator" +display_name = "Kompaktowy generator" +category = 3 +description = "Zwiększa maksymalną pojemność energii." +primary_stat = "max_energy" +primary_value = 20.0 +stat_suffix = " energii" diff --git a/resources/items/engine_extension.tres b/resources/items/engine_extension.tres new file mode 100644 index 0000000..a16f8c0 --- /dev/null +++ b/resources/items/engine_extension.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "engine_extension" +display_name = "Rozszerzenie silnika" +category = 4 +description = "Pasywne rozszerzenie zwiększające prędkość maksymalną." +primary_stat = "max_speed" +primary_value = 40.0 +stat_suffix = " px/s" diff --git a/resources/items/hull_plating.tres b/resources/items/hull_plating.tres new file mode 100644 index 0000000..b13d6ff --- /dev/null +++ b/resources/items/hull_plating.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "hull_plating" +display_name = "Płyty kadłubowe" +category = 2 +description = "Zwiększa maksymalną wytrzymałość kadłuba." +primary_stat = "max_hull" +primary_value = 25.0 +stat_suffix = " kadłuba" diff --git a/resources/items/plasma_cannon.tres b/resources/items/plasma_cannon.tres new file mode 100644 index 0000000..b8449b2 --- /dev/null +++ b/resources/items/plasma_cannon.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "plasma_cannon" +display_name = "Działko plazmowe" +category = 0 +description = "Szybkostrzelna broń krótkiego zasięgu." +primary_stat = "damage" +primary_value = 15.0 +stat_suffix = " DMG" diff --git a/resources/items/reinforced_shield.tres b/resources/items/reinforced_shield.tres new file mode 100644 index 0000000..84ae7db --- /dev/null +++ b/resources/items/reinforced_shield.tres @@ -0,0 +1,13 @@ +[gd_resource type="Resource" script_class="ItemDefinition" load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/items/item_definition.gd" id="1_definition"] + +[resource] +script = ExtResource("1_definition") +item_id = "reinforced_shield" +display_name = "Wzmocniony emiter" +category = 1 +description = "Zwiększa maksymalną pojemność tarcz." +primary_stat = "max_shields" +primary_value = 30.0 +stat_suffix = " tarcz" diff --git a/scenes/game/game.tscn b/scenes/game/game.tscn index 8df01d7..73faa15 100644 --- a/scenes/game/game.tscn +++ b/scenes/game/game.tscn @@ -1,10 +1,11 @@ -[gd_scene load_steps=10 format=3] +[gd_scene load_steps=11 format=3] [ext_resource type="Script" path="res://scripts/game/game.gd" id="1_game"] [ext_resource type="Script" path="res://scripts/game/space_level_background.gd" id="2_background"] [ext_resource type="PackedScene" path="res://scenes/game/player_ship.tscn" id="3_player"] [ext_resource type="Script" path="res://scripts/game/flight_hud.gd" id="4_hud"] [ext_resource type="PackedScene" path="res://scenes/ui/ship_equipment_panel.tscn" id="5_equipment"] +[ext_resource type="PackedScene" path="res://scenes/ui/ship_inventory_panel.tscn" id="6_inventory"] [sub_resource type="RectangleShape2D" id="TopWall"] size = Vector2(5200, 40) @@ -77,3 +78,5 @@ theme_override_font_sizes/font_size = 15 text = "STATEK\nKADŁUB: 100 / 100\nTARCZE: 100 / 100\nENERGIA: 100 / 100" [node name="ShipEquipmentPanel" parent="HUD/HUDRoot" instance=ExtResource("5_equipment")] + +[node name="ShipInventoryPanel" parent="HUD/HUDRoot" instance=ExtResource("6_inventory")] diff --git a/scenes/game/player_ship.tscn b/scenes/game/player_ship.tscn index 348ce18..2743f8c 100644 --- a/scenes/game/player_ship.tscn +++ b/scenes/game/player_ship.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=3 format=3] +[gd_scene load_steps=4 format=3] [ext_resource type="Script" path="res://scripts/game/ship_controller.gd" id="1_controller"] +[ext_resource type="Script" path="res://scripts/items/ship_inventory.gd" id="2_inventory"] [sub_resource type="CircleShape2D" id="ShipCollision"] radius = 24.0 @@ -19,3 +20,6 @@ shape = SubResource("ShipCollision") [node name="Camera2D" type="Camera2D" parent="."] position_smoothing_enabled = true position_smoothing_speed = 4.0 + +[node name="ShipInventory" type="Node" parent="."] +script = ExtResource("2_inventory") diff --git a/scenes/ui/inventory_slot_view.tscn b/scenes/ui/inventory_slot_view.tscn new file mode 100644 index 0000000..aa8f91d --- /dev/null +++ b/scenes/ui/inventory_slot_view.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/ui/equipment_slot_view.gd" id="1_slot"] + +[node name="InventorySlot" type="PanelContainer"] +custom_minimum_size = Vector2(86, 62) +script = ExtResource("1_slot") + +[node name="SlotLabel" type="Label" parent="."] +layout_mode = 2 +mouse_filter = 2 +theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) +theme_override_font_sizes/font_size = 12 +text = "PUSTY" +horizontal_alignment = 1 +vertical_alignment = 1 diff --git a/scenes/ui/ship_equipment_panel.tscn b/scenes/ui/ship_equipment_panel.tscn index 6ad3014..a628f23 100644 --- a/scenes/ui/ship_equipment_panel.tscn +++ b/scenes/ui/ship_equipment_panel.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=3 format=3] +[gd_scene load_steps=4 format=3] [ext_resource type="Script" path="res://scripts/ui/ship_schematic.gd" id="1_schematic"] +[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) @@ -48,27 +49,17 @@ horizontal_alignment = 1 layout_mode = 2 theme_override_constants/separation = 8 -[node name="Weapon1" type="PanelContainer" parent="Contents/WeaponSlots"] -custom_minimum_size = Vector2(0, 40) +[node name="Weapon1" parent="Contents/WeaponSlots" instance=ExtResource("2_slot")] layout_mode = 2 +custom_minimum_size = Vector2(118, 48) +slot_kind = "weapon" +slot_index = 0 -[node name="Label" type="Label" parent="Contents/WeaponSlots/Weapon1"] +[node name="Weapon2" parent="Contents/WeaponSlots" instance=ExtResource("2_slot")] layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "BROŃ 1 [LPM]\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="Weapon2" type="PanelContainer" parent="Contents/WeaponSlots"] -custom_minimum_size = Vector2(0, 40) -layout_mode = 2 - -[node name="Label" type="Label" parent="Contents/WeaponSlots/Weapon2"] -layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "BROŃ 2 [PPM]\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 +custom_minimum_size = Vector2(118, 48) +slot_kind = "weapon" +slot_index = 1 [node name="Schematic" type="Control" parent="Contents"] custom_minimum_size = Vector2(0, 136) @@ -88,68 +79,36 @@ columns = 2 theme_override_constants/h_separation = 8 theme_override_constants/v_separation = 6 -[node name="Module1" type="PanelContainer" parent="Contents/ModuleSlots"] -custom_minimum_size = Vector2(0, 54) +[node name="Module1" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 +slot_kind = "module" +slot_index = 0 -[node name="Label" type="Label" parent="Contents/ModuleSlots/Module1"] +[node name="Module2" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "MODUŁ 1\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 +slot_kind = "module" +slot_index = 1 -[node name="Module2" type="PanelContainer" parent="Contents/ModuleSlots"] -custom_minimum_size = Vector2(0, 54) +[node name="Module3" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 +slot_kind = "module" +slot_index = 2 -[node name="Label" type="Label" parent="Contents/ModuleSlots/Module2"] +[node name="Module4" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "MODUŁ 2\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 +slot_kind = "module" +slot_index = 3 -[node name="Module3" type="PanelContainer" parent="Contents/ModuleSlots"] -custom_minimum_size = Vector2(0, 54) +[node name="Module5" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 +slot_kind = "module" +slot_index = 4 -[node name="Label" type="Label" parent="Contents/ModuleSlots/Module3"] +[node name="Module6" parent="Contents/ModuleSlots" instance=ExtResource("2_slot")] layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "MODUŁ 3\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 +slot_kind = "module" +slot_index = 5 -[node name="Module4" type="PanelContainer" parent="Contents/ModuleSlots"] -custom_minimum_size = Vector2(0, 54) +[node name="InventoryButton" type="Button" parent="Contents"] layout_mode = 2 - -[node name="Label" type="Label" parent="Contents/ModuleSlots/Module4"] -layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "MODUŁ 4\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="Module5" type="PanelContainer" parent="Contents/ModuleSlots"] -custom_minimum_size = Vector2(0, 54) -layout_mode = 2 - -[node name="Label" type="Label" parent="Contents/ModuleSlots/Module5"] -layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "MODUŁ 5\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 - -[node name="Module6" type="PanelContainer" parent="Contents/ModuleSlots"] -custom_minimum_size = Vector2(0, 54) -layout_mode = 2 - -[node name="Label" type="Label" parent="Contents/ModuleSlots/Module6"] -layout_mode = 2 -theme_override_colors/font_color = Color(0.82, 0.86, 0.9, 1) -text = "MODUŁ 6\nPUSTY" -horizontal_alignment = 1 -vertical_alignment = 1 +text = "OTWÓRZ MAGAZYN" diff --git a/scenes/ui/ship_inventory_panel.tscn b/scenes/ui/ship_inventory_panel.tscn new file mode 100644 index 0000000..372e388 --- /dev/null +++ b/scenes/ui/ship_inventory_panel.tscn @@ -0,0 +1,44 @@ +[gd_scene load_steps=2 format=3] + +[ext_resource type="Script" path="res://scripts/ui/ship_inventory_panel.gd" id="1_inventory"] + +[node name="ShipInventoryPanel" type="PanelContainer"] +visible = false +anchors_preset = 8 +anchor_left = 0.5 +anchor_top = 0.5 +anchor_right = 0.5 +anchor_bottom = 0.5 +offset_left = -245.0 +offset_top = -208.0 +offset_right = 245.0 +offset_bottom = 208.0 +grow_horizontal = 2 +grow_vertical = 2 +script = ExtResource("1_inventory") + +[node name="Contents" type="VBoxContainer" parent="."] +layout_mode = 2 +theme_override_constants/separation = 8 + +[node name="Header" type="HBoxContainer" parent="Contents"] +layout_mode = 2 + +[node name="Title" type="Label" parent="Contents/Header"] +layout_mode = 2 +size_flags_horizontal = 3 +theme_override_colors/font_color = Color(0.72, 0.88, 0.98, 1) +theme_override_font_sizes/font_size = 16 +text = "MAGAZYN (0 / 20)" + +[node name="CloseButton" type="Button" parent="Contents/Header"] +layout_mode = 2 +text = "ZAMKNIJ" + +[node name="CargoGrid" type="GridContainer" parent="Contents"] +layout_mode = 2 +size_flags_horizontal = 4 +size_flags_vertical = 4 +columns = 4 +theme_override_constants/h_separation = 6 +theme_override_constants/v_separation = 6 diff --git a/scripts/game/flight_hud.gd b/scripts/game/flight_hud.gd index 363df57..442b19a 100644 --- a/scripts/game/flight_hud.gd +++ b/scripts/game/flight_hud.gd @@ -3,11 +3,14 @@ extends CanvasLayer @onready var debug_toggle: Button = $HUDRoot/DebugToggle @onready var debug_info: Label = $HUDRoot/DebugInfo @onready var player: CharacterBody2D = get_parent().get_node("PlayerShip") +@onready var inventory_button: Button = $HUDRoot/ShipEquipmentPanel/Contents/InventoryButton +@onready var inventory_panel: Control = $HUDRoot/ShipInventoryPanel var _debug_expanded := true func _ready() -> void: debug_toggle.pressed.connect(_toggle_debug) + inventory_button.pressed.connect(_toggle_inventory) _update_debug_toggle() func _process(_delta: float) -> void: @@ -48,3 +51,6 @@ func _toggle_debug() -> void: 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 diff --git a/scripts/game/ship_controller.gd b/scripts/game/ship_controller.gd index a2c965e..bac4258 100644 --- a/scripts/game/ship_controller.gd +++ b/scripts/game/ship_controller.gd @@ -12,6 +12,10 @@ const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" @export var turn_acceleration := 7.0 @export var turn_damping := 4.0 +@export var base_max_hull := 100.0 +@export var base_max_shields := 100.0 +@export var base_max_energy := 100.0 +@export var base_max_speed := 420.0 @export var max_hull := 100.0 @export var max_shields := 100.0 @export var max_energy := 100.0 @@ -22,6 +26,17 @@ var energy := 100.0 var angular_velocity := 0.0 var _sprite: Sprite2D +func apply_equipment_bonuses(bonuses: Dictionary) -> void: + max_hull = base_max_hull + float(bonuses.get("max_hull", 0.0)) + max_shields = base_max_shields + float(bonuses.get("max_shields", 0.0)) + max_energy = base_max_energy + float(bonuses.get("max_energy", 0.0)) + max_speed = base_max_speed + float(bonuses.get("max_speed", 0.0)) + reverse_max_speed = max_speed * 0.5 + max_strafe_speed = max_speed * 0.5 + hull = minf(hull, max_hull) + shields = minf(shields, max_shields) + energy = minf(energy, max_energy) + func _ready() -> void: _ensure_input_action(&"ship_thrust", KEY_W) _ensure_input_action(&"ship_brake", KEY_S) diff --git a/scripts/items/item_definition.gd b/scripts/items/item_definition.gd new file mode 100644 index 0000000..4af3b0e --- /dev/null +++ b/scripts/items/item_definition.gd @@ -0,0 +1,12 @@ +extends Resource +class_name ItemDefinition + +enum Category { WEAPON, SHIELD, HULL, GENERATOR, EXTENSION } + +@export var item_id: String = "" +@export var display_name: String = "" +@export var category: Category = Category.EXTENSION +@export_multiline var description: String = "" +@export var primary_stat: String = "" +@export var primary_value: float = 0.0 +@export var stat_suffix: String = "" diff --git a/scripts/items/item_definition.gd.uid b/scripts/items/item_definition.gd.uid new file mode 100644 index 0000000..5b29c54 --- /dev/null +++ b/scripts/items/item_definition.gd.uid @@ -0,0 +1 @@ +uid://d2fdtd4wjk7d diff --git a/scripts/items/item_instance.gd b/scripts/items/item_instance.gd new file mode 100644 index 0000000..afdfe12 --- /dev/null +++ b/scripts/items/item_instance.gd @@ -0,0 +1,15 @@ +extends Resource +class_name ItemInstance + +@export var definition: ItemDefinition +@export_range(1, 1000, 1) var item_level: int = 1 +@export var additional_modifiers: Array[ItemStatModifier] = [] + +func get_stat_total(stat_key: String) -> float: + var total := 0.0 + if definition and definition.primary_stat == stat_key: + total += definition.primary_value + for modifier in additional_modifiers: + if modifier and modifier.stat_key == stat_key: + total += modifier.value + return total diff --git a/scripts/items/item_instance.gd.uid b/scripts/items/item_instance.gd.uid new file mode 100644 index 0000000..c0eebb8 --- /dev/null +++ b/scripts/items/item_instance.gd.uid @@ -0,0 +1 @@ +uid://cgt3ycqmujx4i diff --git a/scripts/items/item_stat_modifier.gd b/scripts/items/item_stat_modifier.gd new file mode 100644 index 0000000..b145dbc --- /dev/null +++ b/scripts/items/item_stat_modifier.gd @@ -0,0 +1,5 @@ +extends Resource +class_name ItemStatModifier + +@export var stat_key: String = "" +@export var value: float = 0.0 diff --git a/scripts/items/item_stat_modifier.gd.uid b/scripts/items/item_stat_modifier.gd.uid new file mode 100644 index 0000000..db06741 --- /dev/null +++ b/scripts/items/item_stat_modifier.gd.uid @@ -0,0 +1 @@ +uid://ddoc7cnp8w1in diff --git a/scripts/items/ship_inventory.gd b/scripts/items/ship_inventory.gd new file mode 100644 index 0000000..44024a4 --- /dev/null +++ b/scripts/items/ship_inventory.gd @@ -0,0 +1,108 @@ +extends Node +class_name ShipInventory + +signal inventory_changed + +const CARGO_SIZE := 20 +const WEAPON_SLOT_COUNT := 2 +const MODULE_SLOT_COUNT := 6 + +var cargo: Array[ItemInstance] = [] +var weapon_slots: Array[ItemInstance] = [] +var module_slots: Array[ItemInstance] = [] + +@onready var ship: CharacterBody2D = get_parent() + +func _ready() -> void: + add_to_group("ship_inventory") + cargo.resize(CARGO_SIZE) + weapon_slots.resize(WEAPON_SLOT_COUNT) + module_slots.resize(MODULE_SLOT_COUNT) + _add_starter_items() + _recalculate_ship_stats() + inventory_changed.emit() + +func get_cargo_used() -> int: + var used := 0 + for item in cargo: + if item != null: + used += 1 + return used + +func get_item(slot_kind: String, index: int) -> ItemInstance: + var slots := _get_slots(slot_kind) + if index < 0 or index >= slots.size(): + return null + return slots[index] + +func can_move_item(from_kind: String, from_index: int, to_kind: String, to_index: int) -> bool: + var source := _get_slots(from_kind) + var destination := _get_slots(to_kind) + if from_index < 0 or from_index >= source.size() or to_index < 0 or to_index >= destination.size(): + return false + if from_kind == to_kind and from_index == to_index: + return false + var item := source[from_index] + if item == null or item.definition == null: + return false + if to_kind == "weapon" and item.definition.category != ItemDefinition.Category.WEAPON: + return false + if to_kind == "module" and item.definition.category == ItemDefinition.Category.WEAPON: + return false + var displaced := destination[to_index] + if displaced != null and displaced.definition != null: + if from_kind == "weapon" and displaced.definition.category != ItemDefinition.Category.WEAPON: + return false + if from_kind == "module" and displaced.definition.category == ItemDefinition.Category.WEAPON: + return false + return true + +func move_item(from_kind: String, from_index: int, to_kind: String, to_index: int) -> bool: + if not can_move_item(from_kind, from_index, to_kind, to_index): + return false + var source := _get_slots(from_kind) + var destination := _get_slots(to_kind) + var displaced := destination[to_index] + destination[to_index] = source[from_index] + source[from_index] = displaced + _recalculate_ship_stats() + inventory_changed.emit() + return true + +func _get_slots(slot_kind: String) -> Array[ItemInstance]: + match slot_kind: + "cargo": + return cargo + "weapon": + return weapon_slots + "module": + return module_slots + return [] + +func _recalculate_ship_stats() -> void: + var bonuses := {} + for item in weapon_slots + module_slots: + if item == null or item.definition == null: + continue + for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed"]: + bonuses[stat_key] = float(bonuses.get(stat_key, 0.0)) + item.get_stat_total(stat_key) + ship.call("apply_equipment_bonuses", bonuses) + +func _add_starter_items() -> void: + var starter_items := [ + "res://resources/items/plasma_cannon.tres", + "res://resources/items/beam_laser.tres", + "res://resources/items/reinforced_shield.tres", + "res://resources/items/hull_plating.tres", + "res://resources/items/compact_generator.tres", + "res://resources/items/engine_extension.tres", + ] + for index in starter_items.size(): + var definition := load(starter_items[index]) as ItemDefinition + if definition == null: + push_warning("Could not load starter item: %s" % starter_items[index]) + continue + var item := ItemInstance.new() + item.definition = definition + item.item_level = 1 + cargo[index] = item diff --git a/scripts/items/ship_inventory.gd.uid b/scripts/items/ship_inventory.gd.uid new file mode 100644 index 0000000..fba83f1 --- /dev/null +++ b/scripts/items/ship_inventory.gd.uid @@ -0,0 +1 @@ +uid://cg5fgh83r2ftu diff --git a/scripts/ui/equipment_slot_view.gd b/scripts/ui/equipment_slot_view.gd new file mode 100644 index 0000000..0a8adb3 --- /dev/null +++ b/scripts/ui/equipment_slot_view.gd @@ -0,0 +1,94 @@ +extends PanelContainer + +@export var slot_kind: String = "cargo" +@export var slot_index: int = 0 + +@onready var slot_label: Label = $SlotLabel + +var _inventory: ShipInventory + +func _ready() -> void: + _inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory + if _inventory: + _inventory.inventory_changed.connect(_refresh) + custom_minimum_size = Vector2(108, 52) if slot_kind != "cargo" else Vector2(86, 62) + _refresh() + +func _refresh() -> void: + if not is_node_ready() or not _inventory: + return + var item: ItemInstance = _inventory.get_item(slot_kind, slot_index) + if item == null or item.definition == null: + slot_label.text = _empty_slot_text() + return + var definition := item.definition + var category_name := _category_name(definition.category) + var value_text := _stat_text(item) + var slot_title := category_name + if slot_kind == "weapon": + var weapon_binding := "LPM" if slot_index == 0 else "PPM" + slot_title = "BROŃ %d [%s]" % [slot_index + 1, weapon_binding] + elif slot_kind == "module": + slot_title = "MODUŁ %d [%d]" % [slot_index + 1, slot_index + 1] + slot_label.text = "%s\n%s\n%s" % [slot_title, definition.display_name, value_text] + +func _get_drag_data(_at_position: Vector2) -> Variant: + if not _inventory: + return null + var item: ItemInstance = _inventory.get_item(slot_kind, slot_index) + if item == null: + return null + var preview := Label.new() + preview.text = item.definition.display_name + preview.add_theme_color_override("font_color", Color(0.85, 0.94, 1.0)) + set_drag_preview(preview) + return {"from_kind": slot_kind, "from_index": slot_index} + +func _can_drop_data(_at_position: Vector2, data: Variant) -> bool: + return ( + _inventory != null + and data is Dictionary + and _inventory.can_move_item( + str(data.get("from_kind", "")), + int(data.get("from_index", -1)), + slot_kind, + slot_index + ) + ) + +func _drop_data(_at_position: Vector2, data: Variant) -> void: + _inventory.move_item( + str(data.get("from_kind", "")), + int(data.get("from_index", -1)), + slot_kind, + slot_index + ) + +func _empty_slot_text() -> String: + if slot_kind == "weapon": + var weapon_binding := "LPM" if slot_index == 0 else "PPM" + return "BROŃ %d [%s]\nPUSTY" % [slot_index + 1, weapon_binding] + if slot_kind == "module": + return "MODUŁ %d [%d]\nPUSTY" % [slot_index + 1, slot_index + 1] + return "PUSTY" + +func _category_name(category: int) -> String: + match category: + ItemDefinition.Category.WEAPON: + return "BROŃ" + ItemDefinition.Category.SHIELD: + return "TARCZA" + ItemDefinition.Category.HULL: + return "KADŁUB" + ItemDefinition.Category.GENERATOR: + return "GENERATOR" + ItemDefinition.Category.EXTENSION: + return "ROZSZERZENIE" + return "PRZEDMIOT" + +func _stat_text(item: ItemInstance) -> String: + var definition := item.definition + if definition.primary_stat.is_empty(): + return "Poz. %d" % item.item_level + var sign_text := "+" if definition.primary_value >= 0.0 else "" + return "%s%.0f%s · Poz. %d" % [sign_text, definition.primary_value, definition.stat_suffix, item.item_level] diff --git a/scripts/ui/equipment_slot_view.gd.uid b/scripts/ui/equipment_slot_view.gd.uid new file mode 100644 index 0000000..5f2b1c5 --- /dev/null +++ b/scripts/ui/equipment_slot_view.gd.uid @@ -0,0 +1 @@ +uid://cywkgu712lk13 diff --git a/scripts/ui/ship_inventory_panel.gd b/scripts/ui/ship_inventory_panel.gd new file mode 100644 index 0000000..ea594ef --- /dev/null +++ b/scripts/ui/ship_inventory_panel.gd @@ -0,0 +1,26 @@ +extends PanelContainer + +const SLOT_SCENE := preload("res://scenes/ui/inventory_slot_view.tscn") +const CARGO_SIZE := 20 + +@onready var cargo_grid: GridContainer = $Contents/CargoGrid +@onready var close_button: Button = $Contents/Header/CloseButton +@onready var title_label: Label = $Contents/Header/Title + +var _inventory: ShipInventory + +func _ready() -> void: + close_button.pressed.connect(func() -> void: hide()) + _inventory = get_tree().get_first_node_in_group("ship_inventory") as ShipInventory + if _inventory: + _inventory.inventory_changed.connect(_refresh_title) + for index in CARGO_SIZE: + var slot := SLOT_SCENE.instantiate() + slot.set("slot_kind", "cargo") + slot.set("slot_index", index) + cargo_grid.add_child(slot) + _refresh_title() + +func _refresh_title() -> void: + if _inventory: + title_label.text = "MAGAZYN (%d / %d)" % [_inventory.get_cargo_used(), CARGO_SIZE] diff --git a/scripts/ui/ship_inventory_panel.gd.uid b/scripts/ui/ship_inventory_panel.gd.uid new file mode 100644 index 0000000..d30e95c --- /dev/null +++ b/scripts/ui/ship_inventory_panel.gd.uid @@ -0,0 +1 @@ +uid://cqt8v17lwfqhr