From 3a5f46998a7fce410046a37e9f1134dbdc35fe8e Mon Sep 17 00:00:00 2001 From: Tomasz Boruc Date: Fri, 9 Oct 2026 15:35:21 +0200 Subject: [PATCH] =?UTF-8?q?Update=20systemu=20strza=C5=82u?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- concept_game.txt | 10 +- project.godot | 8 ++ resources/items/beam_laser.tres | 7 +- resources/items/compact_generator.tres | 1 + resources/items/machine_gun.tres | 18 +++ resources/items/missile_launcher.tres | 19 ++++ resources/items/plasma_cannon.tres | 5 + scenes/game/game.tscn | 1 + scenes/game/player_ship.tscn | 6 +- scenes/game/weapon_projectile.tscn | 16 +++ scripts/game/flight_hud.gd | 3 + scripts/game/ship_controller.gd | 4 + scripts/game/weapon_controller.gd | 148 +++++++++++++++++++++++++ scripts/game/weapon_controller.gd.uid | 1 + scripts/game/weapon_projectile.gd | 82 ++++++++++++++ scripts/game/weapon_projectile.gd.uid | 1 + scripts/items/item_definition.gd | 9 ++ scripts/items/item_instance.gd | 2 + scripts/items/ship_inventory.gd | 19 +++- scripts/ui/equipment_slot_view.gd | 5 +- 20 files changed, 351 insertions(+), 14 deletions(-) create mode 100644 resources/items/machine_gun.tres create mode 100644 resources/items/missile_launcher.tres create mode 100644 scenes/game/weapon_projectile.tscn create mode 100644 scripts/game/weapon_controller.gd create mode 100644 scripts/game/weapon_controller.gd.uid create mode 100644 scripts/game/weapon_projectile.gd create mode 100644 scripts/game/weapon_projectile.gd.uid diff --git a/concept_game.txt b/concept_game.txt index 5eda5f6..f85cec1 100644 --- a/concept_game.txt +++ b/concept_game.txt @@ -219,16 +219,16 @@ X. RODZAJE BRONI I ICH PARAMETRY BAZOWE (POZIOM 1) * Prędkość Pocisku: Natychmiastowa (Hitscan) 3. Wyrzutnia Rakiet (Homing Missile Launcher) - - Wystrzeliwuje wolno lecące rakiety, które automatycznie namierzają najbliższego wroga. + - Wystrzeliwuje wolno lecące rakiety w kierunku wskazanym kursorem. - Po trafieniu wywołują eksplozję obszarową (AOE), raniąc grupy wrogów. - Parametry (Poziom 1): * Obrażenia (DMG): 45 - 70 (Obrażenia obszarowe w promieniu 120 px) - * Szybkostrzelność: Bardzo Niska (0.8 strzału / sec) + * Cooldown: 5 sekund między rakietami * Zasięg: Bardzo Duży (1000 px) * Koszt Energii: Wysoki (25 energy / strzał) * Prędkość Pocisku: Wolna (z systemem śledzenia celu) -4. Działko Obrotowe (Gatling Gun / Rotary Cannon) +4. Działko Maszynowe (Machine Gun / Gatling Gun) - Posiada ekstremalnie wysoką szybkostrzelność ("ściana ołowiu"). - Potrzebuje ułamka sekundy na rozkręcenie luf, zużywa masę energii, ale szybko czyści wrogów. - Parametry (Poziom 1): @@ -245,8 +245,8 @@ PODSUMOWANIE MOCOWE BRONI (POZIOM 1) |-----------------|-----------|-----------------|---------|---------------|--------------------------| | Działko Plazmowe | 12 - 18 | 3.5 / sec | 350 px | 4 / strzał | Krótki dystans, ciągły ostrzał| | Laser | 6 - 9 | 5.0 / sec | 800 px | 6 / tick | Natychmiastowy hitscan | -| Rakiety | 45 - 70 | 0.8 / sec | 1000 px | 25 / strzał | Naprowadzanie + AOE | -| Działko Obrotowe| 3 - 5 | 10.0 / sec | 550 px | 3 / strzał | Wysoka szybkostrzelność i duże zużycie energii | +| Rakiety | 45 - 70 | 1 / 5 sec | 1000 px | 25 / strzał | Wolna, celowana + AOE | +| Działko Maszynowe| 3 - 5 | 10.0 / sec | 550 px | 3 / strzał | Wysoka szybkostrzelność i duże zużycie energii | -------------------------------------------------------------------------------- diff --git a/project.godot b/project.godot index 7bc1275..08bd29c 100644 --- a/project.godot +++ b/project.godot @@ -55,6 +55,14 @@ ship_strafe_right={ "deadzone": 0.5, "events": [Object(InputEventKey,"physical_keycode":69)] } +ship_fire_primary={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"button_index":1)] +} +ship_fire_secondary={ +"deadzone": 0.5, +"events": [Object(InputEventMouseButton,"button_index":2)] +} [editor_plugins] diff --git a/resources/items/beam_laser.tres b/resources/items/beam_laser.tres index 4050a99..79df894 100644 --- a/resources/items/beam_laser.tres +++ b/resources/items/beam_laser.tres @@ -7,7 +7,12 @@ script = ExtResource("1_definition") item_id = "beam_laser" display_name = "Laser wiązkowy" category = 0 -description = "Precyzyjna broń o dużym zasięgu." +description = "Laser pulsacyjny. Każdy impuls zadaje obrażenia i zużywa 6 energii." primary_stat = "damage" primary_value = 8.0 stat_suffix = " DMG" +weapon_kind = 2 +fire_interval = 0.2 +weapon_range = 800.0 +energy_cost = 6.0 +laser_pulse_duration = 0.08 diff --git a/resources/items/compact_generator.tres b/resources/items/compact_generator.tres index f527801..814b00b 100644 --- a/resources/items/compact_generator.tres +++ b/resources/items/compact_generator.tres @@ -11,3 +11,4 @@ description = "Zwiększa maksymalną pojemność energii." primary_stat = "max_energy" primary_value = 20.0 stat_suffix = " energii" +energy_regeneration_bonus = 12.0 diff --git a/resources/items/machine_gun.tres b/resources/items/machine_gun.tres new file mode 100644 index 0000000..231332d --- /dev/null +++ b/resources/items/machine_gun.tres @@ -0,0 +1,18 @@ +[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 = "machine_gun" +display_name = "Działko maszynowe" +category = 0 +description = "Bardzo szybkostrzelna broń kinetyczna." +primary_stat = "damage" +primary_value = 4.0 +stat_suffix = " DMG" +weapon_kind = 1 +fire_interval = 0.1 +projectile_speed = 1150.0 +weapon_range = 550.0 +energy_cost = 3.0 diff --git a/resources/items/missile_launcher.tres b/resources/items/missile_launcher.tres new file mode 100644 index 0000000..303aead --- /dev/null +++ b/resources/items/missile_launcher.tres @@ -0,0 +1,19 @@ +[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 = "missile_launcher" +display_name = "Wyrzutnia rakiet" +category = 0 +description = "Wystrzeliwuje wolną rakietę z eksplozją obszarową. Cooldown: 5 s." +primary_stat = "damage" +primary_value = 60.0 +stat_suffix = " DMG" +weapon_kind = 3 +fire_interval = 5.0 +weapon_cooldown = 5.0 +projectile_speed = 220.0 +weapon_range = 1000.0 +energy_cost = 25.0 diff --git a/resources/items/plasma_cannon.tres b/resources/items/plasma_cannon.tres index b8449b2..14d01a5 100644 --- a/resources/items/plasma_cannon.tres +++ b/resources/items/plasma_cannon.tres @@ -11,3 +11,8 @@ description = "Szybkostrzelna broń krótkiego zasięgu." primary_stat = "damage" primary_value = 15.0 stat_suffix = " DMG" +weapon_kind = 0 +fire_interval = 0.2857 +projectile_speed = 720.0 +weapon_range = 350.0 +energy_cost = 4.0 diff --git a/scenes/game/game.tscn b/scenes/game/game.tscn index 73faa15..d85121f 100644 --- a/scenes/game/game.tscn +++ b/scenes/game/game.tscn @@ -58,6 +58,7 @@ anchor_right = 1.0 anchor_bottom = 1.0 grow_horizontal = 2 grow_vertical = 2 +mouse_filter = 2 [node name="DebugToggle" type="Button" parent="HUD/HUDRoot"] offset_left = 18.0 diff --git a/scenes/game/player_ship.tscn b/scenes/game/player_ship.tscn index 2743f8c..e28d2bd 100644 --- a/scenes/game/player_ship.tscn +++ b/scenes/game/player_ship.tscn @@ -1,7 +1,8 @@ -[gd_scene load_steps=4 format=3] +[gd_scene load_steps=5 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"] +[ext_resource type="Script" path="res://scripts/game/weapon_controller.gd" id="3_weapons"] [sub_resource type="CircleShape2D" id="ShipCollision"] radius = 24.0 @@ -23,3 +24,6 @@ position_smoothing_speed = 4.0 [node name="ShipInventory" type="Node" parent="."] script = ExtResource("2_inventory") + +[node name="WeaponController" type="Node" parent="."] +script = ExtResource("3_weapons") diff --git a/scenes/game/weapon_projectile.tscn b/scenes/game/weapon_projectile.tscn new file mode 100644 index 0000000..d14d3c4 --- /dev/null +++ b/scenes/game/weapon_projectile.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=3 format=3] + +[ext_resource type="Script" path="res://scripts/game/weapon_projectile.gd" id="1_projectile"] + +[sub_resource type="CircleShape2D" id="ProjectileShape"] +radius = 6.0 + +[node name="WeaponProjectile" type="Area2D"] +collision_layer = 0 +collision_mask = 5 +monitoring = true +monitorable = false +script = ExtResource("1_projectile") + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource("ProjectileShape") diff --git a/scripts/game/flight_hud.gd b/scripts/game/flight_hud.gd index 442b19a..d8ca5cf 100644 --- a/scripts/game/flight_hud.gd +++ b/scripts/game/flight_hud.gd @@ -23,11 +23,13 @@ func _process(_delta: float) -> void: debug_info.text = """STEROWANIE W: ciąg S: hamulec / wsteczny Q / E: strafe A / D: obrót +LPM / PPM: broń 1 / broń 2 STATEK KADŁUB: %d / %d TARCZE: %d / %d ENERGIA: %d / %d +ENERGIA REGEN: %.1f /s RUCH PRĘDKOŚĆ: %.1f px/s @@ -40,6 +42,7 @@ OBRÓT: %.2f rad/s""" % [ roundi(float(player.get("hull"))), roundi(float(player.get("max_hull"))), roundi(float(player.get("shields"))), roundi(float(player.get("max_shields"))), roundi(float(player.get("energy"))), roundi(float(player.get("max_energy"))), + float(player.get("energy_regeneration")), ship_velocity.length(), ship_velocity.x, ship_velocity.y, ship_position.x, ship_position.y, rad_to_deg(player.rotation), angular_speed, ] diff --git a/scripts/game/ship_controller.gd b/scripts/game/ship_controller.gd index bac4258..6dcb7c0 100644 --- a/scripts/game/ship_controller.gd +++ b/scripts/game/ship_controller.gd @@ -16,12 +16,14 @@ const DEFAULT_SHIP_TEXTURE := "res://assets/Ships/Spaceship_0.png" @export var base_max_shields := 100.0 @export var base_max_energy := 100.0 @export var base_max_speed := 420.0 +@export var base_energy_regeneration := 12.0 @export var max_hull := 100.0 @export var max_shields := 100.0 @export var max_energy := 100.0 var hull := 100.0 var shields := 100.0 var energy := 100.0 +var energy_regeneration := 12.0 var angular_velocity := 0.0 var _sprite: Sprite2D @@ -31,6 +33,7 @@ func apply_equipment_bonuses(bonuses: Dictionary) -> void: 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)) + energy_regeneration = base_energy_regeneration + float(bonuses.get("energy_regeneration", 0.0)) reverse_max_speed = max_speed * 0.5 max_strafe_speed = max_speed * 0.5 hull = minf(hull, max_hull) @@ -65,6 +68,7 @@ func _ensure_input_action(action_name: StringName, physical_key: Key) -> void: InputMap.action_add_event(action_name, event) func _physics_process(delta: float) -> void: + energy = minf(max_energy, energy + energy_regeneration * delta) var turn_input := Input.get_axis("ship_turn_left", "ship_turn_right") if not is_zero_approx(turn_input): angular_velocity = move_toward( diff --git a/scripts/game/weapon_controller.gd b/scripts/game/weapon_controller.gd new file mode 100644 index 0000000..b824ccc --- /dev/null +++ b/scripts/game/weapon_controller.gd @@ -0,0 +1,148 @@ +extends Node + +const PROJECTILE_SCENE := preload("res://scenes/game/weapon_projectile.tscn") +const RAY_COLLISION_MASK := 5 # World geometry and enemies on physics layer 3. + +@onready var ship: CharacterBody2D = get_parent() +@onready var inventory: ShipInventory = ship.get_node("ShipInventory") + +var _shot_timers := [0.0, 0.0] +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] + +func _ready() -> void: + _ensure_input_action(&"ship_fire_primary", MOUSE_BUTTON_LEFT) + _ensure_input_action(&"ship_fire_secondary", MOUSE_BUTTON_RIGHT) + for slot_index in 2: + var beam := Line2D.new() + beam.width = 4.0 + beam.default_color = Color(0.35, 0.9, 1.0, 0.92) + beam.z_index = 20 + beam.visible = false + ship.get_parent().call_deferred("add_child", beam) + _laser_lines.append(beam) + +func _ensure_input_action(action_name: StringName, button: MouseButton) -> void: + if not InputMap.has_action(action_name): + InputMap.add_action(action_name, 0.5) + var event := InputEventMouseButton.new() + event.button_index = button + if not InputMap.action_has_event(action_name, event): + InputMap.action_add_event(action_name, event) + +func _unhandled_input(event: InputEvent) -> void: + if not event is InputEventMouseButton: + return + var slot_index := -1 + if event.button_index == MOUSE_BUTTON_LEFT: + slot_index = 0 + elif event.button_index == MOUSE_BUTTON_RIGHT: + slot_index = 1 + if slot_index < 0: + return + _fire_buttons_down[slot_index] = event.pressed + if event.pressed: + _fire_just_pressed[slot_index] = true + +func _physics_process(delta: float) -> void: + var mouse_over_ui := ship.get_viewport().gui_get_hovered_control() != null + for slot_index in 2: + _shot_timers[slot_index] = maxf(0.0, _shot_timers[slot_index] - delta) + _laser_pulse_timers[slot_index] = maxf(0.0, _laser_pulse_timers[slot_index] - delta) + var action_name := "ship_fire_primary" if slot_index == 0 else "ship_fire_secondary" + var is_pressed: bool = not mouse_over_ui and ( + Input.is_action_pressed(action_name) or _fire_buttons_down[slot_index] + ) + var is_just_pressed: bool = not mouse_over_ui and ( + Input.is_action_just_pressed(action_name) or _fire_just_pressed[slot_index] + ) + var item: ItemInstance = inventory.weapon_slots[slot_index] + if not is_pressed or item == null or item.definition == null: + _laser_lines[slot_index].visible = ( + item != null + and item.definition != null + and item.definition.weapon_kind == ItemDefinition.WeaponKind.LASER + and _laser_pulse_timers[slot_index] > 0.0 + ) + continue + + var definition := item.definition + if definition.weapon_kind != ItemDefinition.WeaponKind.LASER: + _laser_pulse_timers[slot_index] = 0.0 + _laser_lines[slot_index].visible = false + match definition.weapon_kind: + ItemDefinition.WeaponKind.LASER: + _laser_lines[slot_index].visible = _laser_pulse_timers[slot_index] > 0.0 + _fire_laser(slot_index, definition, item.get_stat_total("damage")) + ItemDefinition.WeaponKind.MISSILE: + if ( + is_just_pressed + and _shot_timers[slot_index] <= 0.0 + and _consume_energy(definition.energy_cost) + ): + _fire_projectile(definition, item.get_stat_total("damage")) + _shot_timers[slot_index] = definition.weapon_cooldown + _: + if _shot_timers[slot_index] <= 0.0 and _consume_energy(definition.energy_cost): + _fire_projectile(definition, item.get_stat_total("damage")) + _shot_timers[slot_index] = definition.fire_interval + for slot_index in 2: + _fire_just_pressed[slot_index] = false + +func _fire_projectile(definition: ItemDefinition, projectile_damage: float) -> void: + var direction := _aim_direction() + var projectile := PROJECTILE_SCENE.instantiate() + projectile.call( + "configure", + ship.global_position + direction * 30.0, + direction, + definition.weapon_kind, + definition.projectile_speed, + projectile_damage, + definition.weapon_range + ) + ship.get_parent().add_child(projectile) + +func _fire_laser(slot_index: int, definition: ItemDefinition, beam_damage: float) -> void: + var line := _laser_lines[slot_index] + if _shot_timers[slot_index] > 0.0 or float(ship.get("energy")) < definition.energy_cost: + return + var direction := _aim_direction() + var endpoint := ship.global_position + direction * definition.weapon_range + var query := PhysicsRayQueryParameters2D.create( + ship.global_position, + endpoint, + RAY_COLLISION_MASK, + [ship.get_rid()] + ) + var result := ship.get_world_2d().direct_space_state.intersect_ray(query) + if not result.is_empty(): + endpoint = result["position"] + line.clear_points() + line.add_point(ship.global_position) + line.add_point(endpoint) + line.visible = true + if not _consume_energy(definition.energy_cost): + line.visible = false + return + if not result.is_empty(): + _apply_damage(result.get("collider"), beam_damage) + _laser_pulse_timers[slot_index] = definition.laser_pulse_duration + _shot_timers[slot_index] = definition.fire_interval + +func _aim_direction() -> Vector2: + var offset := ship.get_global_mouse_position() - ship.global_position + return offset.normalized() if offset.length_squared() > 0.001 else Vector2.UP.rotated(ship.rotation) + +func _consume_energy(amount: float) -> bool: + var current_energy := float(ship.get("energy")) + if current_energy < amount: + return false + ship.set("energy", current_energy - amount) + return true + +func _apply_damage(target: Variant, damage: float) -> void: + if target is Node and target.has_method("take_damage"): + target.call("take_damage", damage) diff --git a/scripts/game/weapon_controller.gd.uid b/scripts/game/weapon_controller.gd.uid new file mode 100644 index 0000000..381bc18 --- /dev/null +++ b/scripts/game/weapon_controller.gd.uid @@ -0,0 +1 @@ +uid://c1506hvftf1fe diff --git a/scripts/game/weapon_projectile.gd b/scripts/game/weapon_projectile.gd new file mode 100644 index 0000000..7ef2b40 --- /dev/null +++ b/scripts/game/weapon_projectile.gd @@ -0,0 +1,82 @@ +extends Area2D + +var direction := Vector2.UP +var projectile_speed := 600.0 +var damage := 1.0 +var max_range := 800.0 +var weapon_kind := ItemDefinition.WeaponKind.PLASMA +var _distance_travelled := 0.0 +var _already_hit: Dictionary = {} + +func _ready() -> void: + body_entered.connect(_on_body_entered) + area_entered.connect(_on_area_entered) + rotation = direction.angle() + +func configure( + start_position: Vector2, + travel_direction: Vector2, + kind: int, + speed: float, + projectile_damage: float, + projectile_range: float +) -> void: + global_position = start_position + direction = travel_direction.normalized() + weapon_kind = kind + projectile_speed = speed + damage = projectile_damage + max_range = projectile_range + +func _physics_process(delta: float) -> void: + var step := projectile_speed * delta + global_position += direction * step + _distance_travelled += step + if _distance_travelled >= max_range: + queue_free() + +func _draw() -> void: + match weapon_kind: + ItemDefinition.WeaponKind.PLASMA: + draw_circle(Vector2.ZERO, 6.0, Color(0.3, 0.85, 1.0, 0.95)) + draw_circle(Vector2.ZERO, 3.0, Color(0.85, 0.98, 1.0, 1.0)) + ItemDefinition.WeaponKind.MACHINE_GUN: + draw_rect(Rect2(-7.0, -2.0, 14.0, 4.0), Color(1.0, 0.82, 0.38, 1.0)) + ItemDefinition.WeaponKind.MISSILE: + draw_colored_polygon(PackedVector2Array([ + Vector2(10, 0), Vector2(-7, -4), Vector2(-4, 0), Vector2(-7, 4), + ]), Color(1.0, 0.42, 0.2, 1.0)) + +func _on_body_entered(body: Node2D) -> void: + _hit_target(body) + +func _on_area_entered(area: Area2D) -> void: + _hit_target(area) + +func _hit_target(target: Node) -> void: + if weapon_kind == ItemDefinition.WeaponKind.MISSILE: + _explode_at_target(target) + else: + _apply_damage_once(target) + queue_free() + +func _explode_at_target(impact_target: Node) -> void: + _apply_damage_once(impact_target) + var explosion_shape := CircleShape2D.new() + explosion_shape.radius = 120.0 + var query := PhysicsShapeQueryParameters2D.new() + query.shape = explosion_shape + query.transform = Transform2D(0.0, global_position) + query.collision_mask = 4 # Enemy physics layer 3. + for result in get_world_2d().direct_space_state.intersect_shape(query, 32): + _apply_damage_once(result.get("collider")) + +func _apply_damage_once(target: Variant) -> void: + if not (target is Node): + return + var instance_id: int = target.get_instance_id() + if _already_hit.has(instance_id): + return + _already_hit[instance_id] = true + if target.has_method("take_damage"): + target.call("take_damage", damage) diff --git a/scripts/game/weapon_projectile.gd.uid b/scripts/game/weapon_projectile.gd.uid new file mode 100644 index 0000000..dba9770 --- /dev/null +++ b/scripts/game/weapon_projectile.gd.uid @@ -0,0 +1 @@ +uid://4pf7qyhqy6c6 diff --git a/scripts/items/item_definition.gd b/scripts/items/item_definition.gd index 4af3b0e..d35b63a 100644 --- a/scripts/items/item_definition.gd +++ b/scripts/items/item_definition.gd @@ -2,6 +2,7 @@ extends Resource class_name ItemDefinition enum Category { WEAPON, SHIELD, HULL, GENERATOR, EXTENSION } +enum WeaponKind { PLASMA, MACHINE_GUN, LASER, MISSILE } @export var item_id: String = "" @export var display_name: String = "" @@ -10,3 +11,11 @@ enum Category { WEAPON, SHIELD, HULL, GENERATOR, EXTENSION } @export var primary_stat: String = "" @export var primary_value: float = 0.0 @export var stat_suffix: String = "" +@export var energy_regeneration_bonus: float = 0.0 +@export var weapon_kind: WeaponKind = WeaponKind.PLASMA +@export var fire_interval: float = 0.25 +@export var weapon_cooldown: float = 0.0 +@export var laser_pulse_duration: float = 0.08 +@export var projectile_speed: float = 0.0 +@export var weapon_range: float = 0.0 +@export var energy_cost: float = 0.0 diff --git a/scripts/items/item_instance.gd b/scripts/items/item_instance.gd index afdfe12..04bfcec 100644 --- a/scripts/items/item_instance.gd +++ b/scripts/items/item_instance.gd @@ -9,6 +9,8 @@ func get_stat_total(stat_key: String) -> float: var total := 0.0 if definition and definition.primary_stat == stat_key: total += definition.primary_value + if definition and stat_key == "energy_regeneration": + total += definition.energy_regeneration_bonus for modifier in additional_modifiers: if modifier and modifier.stat_key == stat_key: total += modifier.value diff --git a/scripts/items/ship_inventory.gd b/scripts/items/ship_inventory.gd index 44024a4..2797f17 100644 --- a/scripts/items/ship_inventory.gd +++ b/scripts/items/ship_inventory.gd @@ -84,7 +84,7 @@ func _recalculate_ship_stats() -> void: 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"]: + for stat_key in ["max_hull", "max_shields", "max_energy", "max_speed", "energy_regeneration"]: bonuses[stat_key] = float(bonuses.get(stat_key, 0.0)) + item.get_stat_total(stat_key) ship.call("apply_equipment_bonuses", bonuses) @@ -92,17 +92,26 @@ func _add_starter_items() -> void: var starter_items := [ "res://resources/items/plasma_cannon.tres", "res://resources/items/beam_laser.tres", + "res://resources/items/machine_gun.tres", + "res://resources/items/missile_launcher.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 + var cargo_index := 0 + var weapon_index := 0 + for path in starter_items: + var definition := load(path) as ItemDefinition if definition == null: - push_warning("Could not load starter item: %s" % starter_items[index]) + push_warning("Could not load starter item: %s" % path) continue var item := ItemInstance.new() item.definition = definition item.item_level = 1 - cargo[index] = item + if definition.category == ItemDefinition.Category.WEAPON and weapon_index < WEAPON_SLOT_COUNT: + weapon_slots[weapon_index] = item + weapon_index += 1 + else: + cargo[cargo_index] = item + cargo_index += 1 diff --git a/scripts/ui/equipment_slot_view.gd b/scripts/ui/equipment_slot_view.gd index 0a8adb3..f085e51 100644 --- a/scripts/ui/equipment_slot_view.gd +++ b/scripts/ui/equipment_slot_view.gd @@ -90,5 +90,6 @@ 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] + var total_value := item.get_stat_total(definition.primary_stat) + var sign_text := "+" if total_value >= 0.0 else "" + return "%s%.0f%s · Poz. %d" % [sign_text, total_value, definition.stat_suffix, item.item_level]