This commit is contained in:
Tomasz Boruc 2026-10-13 19:49:14 +02:00
parent 6ce039021c
commit 24a58b60db
11 changed files with 94 additions and 9 deletions

View File

@ -6,7 +6,7 @@ extends CanvasLayer
@onready var inventory_button: Button = $HUDRoot/ShipEquipmentPanel/Contents/InventoryButton @onready var inventory_button: Button = $HUDRoot/ShipEquipmentPanel/Contents/InventoryButton
@onready var inventory_panel: Control = $HUDRoot/ShipInventoryPanel @onready var inventory_panel: Control = $HUDRoot/ShipInventoryPanel
var _debug_expanded := true var _debug_expanded := false
var _ability_buttons: Dictionary = {} var _ability_buttons: Dictionary = {}
var _ability_bar: HBoxContainer var _ability_bar: HBoxContainer
var _ability_ready_style: StyleBoxFlat var _ability_ready_style: StyleBoxFlat
@ -14,7 +14,7 @@ var _ability_blocked_style: StyleBoxFlat
var _inventory_clip: Control var _inventory_clip: Control
var _sidebar: PanelContainer var _sidebar: PanelContainer
var _sidebar_toggle: Button var _sidebar_toggle: Button
var _sidebar_open := true var _sidebar_open := false
var _sidebar_tween: Tween var _sidebar_tween: Tween
const SIDEBAR_WIDTH := 306.0 const SIDEBAR_WIDTH := 306.0
const EQUIPMENT_UI_SCALE := 0.8 const EQUIPMENT_UI_SCALE := 0.8
@ -23,8 +23,8 @@ var _captain_panel: PanelContainer
var _cockpit: Control var _cockpit: Control
func _ready() -> void: func _ready() -> void:
_sidebar_open = bool(GameState.hud_panel_state.get("ship_open", true)) _sidebar_open = bool(GameState.hud_panel_state.get("ship_open", false))
_debug_expanded = bool(GameState.hud_panel_state.get("debug_expanded", true)) _debug_expanded = bool(GameState.hud_panel_state.get("debug_expanded", false))
debug_info.visible = _debug_expanded debug_info.visible = _debug_expanded
var energy_indicator := Node2D.new() var energy_indicator := Node2D.new()
energy_indicator.name = "EnergyIndicator" energy_indicator.name = "EnergyIndicator"

View File

@ -0,0 +1,28 @@
extends Line2D
var _time := 0.0
func _ready() -> void:
# Draw the beam in layers instead of a flat line. No bloom is required.
default_color = Color.TRANSPARENT
width = 0.0
func _process(delta: float) -> void:
_time += delta
if visible:
queue_redraw()
func _draw() -> void:
if points.size() < 2:
return
var start := points[0]
var end := points[1]
var pulse := 0.88 + sin(_time * 65.0) * 0.12
draw_line(start, end, Color(0.1, 0.65, 1.0, 0.09 * pulse), 16, true)
draw_line(start, end, Color(0.15, 0.8, 1.0, 0.2 * pulse), 9, true)
draw_line(start, end, Color(0.3, 0.92, 1.0, 0.7), 3.8, true)
draw_line(start, end, Color(0.9, 1.0, 1.0, 0.96), 1.4, true)
for point in [start, end]:
draw_circle(point, 9 * pulse, Color(0.1, 0.8, 1.0, 0.12))
draw_circle(point, 4 * pulse, Color(0.35, 0.95, 1.0, 0.6))
draw_circle(point, 1.8, Color(0.9, 1.0, 1.0))

View File

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

View File

@ -0,0 +1,21 @@
extends Node2D
var _age := 0.0
const DURATION := 0.075
func _ready() -> void:
z_index = 25
func _process(delta: float) -> void:
_age += delta
if _age >= DURATION:
queue_free()
else:
queue_redraw()
func _draw() -> void:
var fade := 1.0 - _age / DURATION
draw_circle(Vector2.ZERO, 12 * fade, Color(1.0, 0.48, 0.08, 0.18 * fade))
draw_colored_polygon(PackedVector2Array([Vector2(-2, -3), Vector2(8, -2), Vector2(19, 0), Vector2(8, 2), Vector2(-2, 3)]), Color(1.0, 0.7, 0.18, fade))
draw_line(Vector2(-2, 0), Vector2(13 * fade, 0), Color(1.0, 0.97, 0.8, fade), 2, true)
draw_line(Vector2(1, -7 * fade), Vector2(1, 7 * fade), Color(1.0, 0.78, 0.3, fade * 0.7), 1, true)

View File

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

View File

@ -23,6 +23,7 @@ func _ready() -> void:
_ensure_input_action(&"ship_fire_missile", MOUSE_BUTTON_MIDDLE) _ensure_input_action(&"ship_fire_missile", MOUSE_BUTTON_MIDDLE)
for slot_index in ShipInventory.WEAPON_SLOT_COUNT: for slot_index in ShipInventory.WEAPON_SLOT_COUNT:
var beam := Line2D.new() var beam := Line2D.new()
beam.set_script(preload("res://scripts/game/laser_beam_visual.gd"))
beam.width = 4.0 beam.width = 4.0
beam.default_color = Color(0.35, 0.9, 1.0, 0.92) beam.default_color = Color(0.35, 0.9, 1.0, 0.92)
beam.z_index = 20 beam.z_index = 20
@ -148,6 +149,18 @@ func _fire_projectile(item: ItemInstance) -> void:
ship.get_parent().add_child(projectile) ship.get_parent().add_child(projectile)
projectile.set("missile_homing", definition.missile_homing) projectile.set("missile_homing", definition.missile_homing)
WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), muzzle_position, definition.weapon_kind) WEAPON_AUDIO_SCRIPT.play(ship.get_parent(), muzzle_position, definition.weapon_kind)
if definition.weapon_kind == ItemDefinition.WeaponKind.MACHINE_GUN:
var flash := Node2D.new()
flash.set_script(preload("res://scripts/game/muzzle_flash.gd"))
# Keep the short flash attached to the muzzle while the ship moves.
ship.add_child(flash)
flash.global_position = muzzle_position
flash.global_rotation = direction.angle()
func _exit_tree() -> void:
for beam in _laser_lines:
if is_instance_valid(beam):
beam.queue_free()
func _fire_laser(slot_index: int, item: ItemInstance) -> void: func _fire_laser(slot_index: int, item: ItemInstance) -> void:
var definition := item.definition var definition := item.definition

View File

@ -177,7 +177,19 @@ func _draw() -> void:
draw_texture_rect(PLASMA_TEXTURE, Rect2(-texture_size * 0.5, texture_size), false) draw_texture_rect(PLASMA_TEXTURE, Rect2(-texture_size * 0.5, texture_size), false)
draw_set_transform(Vector2.ZERO) draw_set_transform(Vector2.ZERO)
ItemDefinition.WeaponKind.MACHINE_GUN: ItemDefinition.WeaponKind.MACHINE_GUN:
draw_rect(Rect2(-7.0, -2.0, 14.0, 4.0), Color(1.0, 0.82, 0.38, 1.0)) # Tapered tracer, warm halo and a bright metallic projectile core.
for index in 6:
var tail_distance := 5.0 + index * 4.0
if tail_distance >= _distance_travelled:
break
var fade := 1.0 - float(index) / 6.0
var tip := Vector2(-tail_distance, 0)
var tail := Vector2(-minf(tail_distance + 4.0, _distance_travelled), 0)
draw_line(tail, tip, Color(1.0, 0.48, 0.1, fade * 0.55), 1.8 * fade, true)
draw_line(Vector2(-9, 0), Vector2(6, 0), Color(1.0, 0.56, 0.12, 0.18), 7, true)
draw_line(Vector2(-7, 0), Vector2(6, 0), Color(1.0, 0.8, 0.3), 2.5, true)
draw_line(Vector2(-3, 0), Vector2(7, 0), Color(1.0, 0.98, 0.84), 1.2, true)
draw_circle(Vector2(6, 0), 1.5, Color(1.0, 0.94, 0.65))
ItemDefinition.WeaponKind.MISSILE: ItemDefinition.WeaponKind.MISSILE:
_draw_missile() _draw_missile()

View File

@ -55,7 +55,7 @@ func _ready() -> void:
_captain.changed.connect(_refresh) _captain.changed.connect(_refresh)
player.get_node("ShipInventory").connect("inventory_changed", _refresh) player.get_node("ShipInventory").connect("inventory_changed", _refresh)
_refresh() _refresh()
if bool(GameState.hud_panel_state.get("captain_collapsed", false)): if bool(GameState.hud_panel_state.get("captain_collapsed", true)):
_toggle_collapsed() _toggle_collapsed()
func _train(skill: String) -> void: func _train(skill: String) -> void:

View File

@ -40,7 +40,7 @@ func _load_ships() -> void:
var accent: Color = chassis["accent"] var accent: Color = chassis["accent"]
var button := Button.new() var button := Button.new()
button.name = "Ship%d" % int(chassis["number"]) button.name = "Ship%d" % int(chassis["number"])
button.custom_minimum_size = Vector2(250, 258) button.custom_minimum_size = Vector2(240, 238)
button.size_flags_horizontal = Control.SIZE_EXPAND_FILL button.size_flags_horizontal = Control.SIZE_EXPAND_FILL
button.toggle_mode = true button.toggle_mode = true
button.button_group = button_group button.button_group = button_group
@ -56,10 +56,10 @@ func _load_ships() -> void:
contents.offset_top = 12 contents.offset_top = 12
contents.offset_bottom = -12 contents.offset_bottom = -12
contents.add_theme_constant_override("separation", 5) contents.add_theme_constant_override("separation", 5)
contents.add_child(_label(chassis["name"].to_upper(), 22, Color("edf6ff"))) contents.add_child(_label(chassis["name"].to_upper(), 20, Color("edf6ff")))
contents.add_child(_label(chassis["role"], 11, accent)) contents.add_child(_label(chassis["role"], 11, accent))
var preview := TextureRect.new() var preview := TextureRect.new()
preview.custom_minimum_size.y = 128 preview.custom_minimum_size.y = 110
preview.size_flags_vertical = Control.SIZE_EXPAND_FILL preview.size_flags_vertical = Control.SIZE_EXPAND_FILL
preview.texture = texture preview.texture = texture
preview.expand_mode = TextureRect.EXPAND_IGNORE_SIZE preview.expand_mode = TextureRect.EXPAND_IGNORE_SIZE

View File

@ -21,6 +21,13 @@ func _ready() -> void:
var drawer := root.get_node("ShipDrawer") as Control var drawer := root.get_node("ShipDrawer") as Control
var toggle := root.get_node("ShipToggle") as Button var toggle := root.get_node("ShipToggle") as Button
var captain := root.get_node("CaptainPanel") var captain := root.get_node("CaptainPanel")
assert(captain._collapsed and not captain.get_node("Contents/Skills").visible)
assert(not hud._debug_expanded and not hud.debug_info.visible)
assert(not hud._sidebar_open and not drawer.visible)
assert(not hud.inventory_panel.visible)
toggle.pressed.emit()
captain._toggle_collapsed()
await get_tree().create_timer(0.3).timeout
var equipment := drawer.get_node("Scroll/Contents/ShipEquipmentPanel") var equipment := drawer.get_node("Scroll/Contents/ShipEquipmentPanel")
assert(captain.get_parent() != equipment.get_parent()) assert(captain.get_parent() != equipment.get_parent())
assert(drawer.scale.is_equal_approx(Vector2.ONE * 0.8)) assert(drawer.scale.is_equal_approx(Vector2.ONE * 0.8))

View File

@ -23,6 +23,8 @@ func _ready() -> void:
assert(is_equal_approx(panel.position.x + panel.size.x, menu.size.x)) assert(is_equal_approx(panel.position.x + panel.size.x, menu.size.x))
var grid := panel.get_node("Layout/ShipScroll/ShipGrid") as GridContainer var grid := panel.get_node("Layout/ShipScroll/ShipGrid") as GridContainer
assert(grid.columns == 2 and grid.get_child_count() == 4) assert(grid.columns == 2 and grid.get_child_count() == 4)
assert(not panel.get_node("Layout/ShipScroll").get_v_scroll_bar().visible)
assert(not panel.get_node("Layout/ShipScroll").get_h_scroll_bar().visible)
assert(not panel.has_node("Layout/Footer/ContinueButton")) assert(not panel.has_node("Layout/Footer/ContinueButton"))
panel.get_node("Layout/Footer/CloseButton").pressed.emit() panel.get_node("Layout/Footer/CloseButton").pressed.emit()
await get_tree().create_timer(0.25).timeout await get_tree().create_timer(0.25).timeout