Resolve pending gameplay tickets
This commit is contained in:
parent
ec20778215
commit
c2ebbfaa2d
28 changed files with 618 additions and 188 deletions
|
|
@ -5,7 +5,7 @@
|
|||
script = ExtResource("1")
|
||||
definition_id = "distorder"
|
||||
display_name = "Energy Propulser"
|
||||
description = "Unarmed propulsion hull that burns energy to drive the whole fleet faster. While one flies with you, a fader lets you push cruise speed past its default."
|
||||
description = "Unarmed propulsion hull that burns energy to drive the whole fleet faster. It also grants an aimed fleet dash; each Propulser carries its own recharge."
|
||||
build_cost = 14
|
||||
build_resource_costs = {"ore": 14, "energy": 8}
|
||||
build_time = 16.0
|
||||
|
|
@ -18,7 +18,7 @@ component_scenes = Array[PackedScene]([ExtResource("2")])
|
|||
base_stats = {"max_speed": 645.0, "acceleration": 1845.0, "delivery_speed": 180.0}
|
||||
unlock_id = "unlock_distorder"
|
||||
unlock_name = "Unlock Energy Propulser"
|
||||
unlock_description = "Research a propulsion hull that burns energy to drive the whole fleet faster - while one flies with you, a fader lets you push cruise speed past its default."
|
||||
unlock_description = "Research a propulsion hull that burns energy to drive the whole fleet faster and grants an aimed fleet dash."
|
||||
unlock_cost = 0
|
||||
unlock_resource_costs = {"energy": 50}
|
||||
research_point_cost = 1
|
||||
|
|
|
|||
|
|
@ -33,6 +33,11 @@ var fleet_target: Vector2 = Vector2.ZERO
|
|||
# travelling along. Zero heading means the fleet is not being steered.
|
||||
var anchor: Vector2 = Vector2.ZERO
|
||||
var steer_direction: Vector2 = Vector2.ZERO
|
||||
# An aimed Propulser burst translates the complete formation as one body.
|
||||
var dash_direction: Vector2 = Vector2.ZERO
|
||||
var dash_remaining: float = 0.0
|
||||
|
||||
const DASH_SPEED: float = 1400.0
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
|
|
@ -227,12 +232,29 @@ func move_in_direction(direction: Vector2) -> void:
|
|||
steer_direction = direction.normalized()
|
||||
|
||||
|
||||
func dash(direction: Vector2, distance: float) -> bool:
|
||||
if direction.length() < 0.001 or distance <= 0.0 or ships.is_empty():
|
||||
return false
|
||||
if dash_remaining <= 0.0:
|
||||
anchor = get_formation_origin()
|
||||
dash_direction = direction.normalized()
|
||||
dash_remaining = distance
|
||||
return true
|
||||
|
||||
|
||||
func is_dashing() -> bool:
|
||||
return dash_remaining > 0.0
|
||||
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
# #158: a building may pay a local cost out of the hold when the fleet is
|
||||
# actually standing at it, and the autoload has no other way to know
|
||||
# where that is. Written before the early return below - a parked fleet
|
||||
# is exactly the case that matters.
|
||||
GameState.fleet_position = get_centroid()
|
||||
if is_dashing():
|
||||
_advance_dash(delta)
|
||||
return
|
||||
if steer_direction == Vector2.ZERO:
|
||||
return
|
||||
# The anchor - the fleet's formation centre - travels at cruise_speed.
|
||||
|
|
@ -244,6 +266,29 @@ func _process(delta: float) -> void:
|
|||
_assign_slot_targets()
|
||||
|
||||
|
||||
func _advance_dash(delta: float) -> void:
|
||||
var step: float = minf(DASH_SPEED * delta, dash_remaining)
|
||||
var displacement: Vector2 = dash_direction * step
|
||||
dash_remaining -= step
|
||||
anchor += displacement
|
||||
fleet_target += displacement
|
||||
for ship in ships:
|
||||
if not is_instance_valid(ship):
|
||||
continue
|
||||
# Move the hull and its destination together. That preserves every
|
||||
# formation offset and prevents normal steering from trying to "repair"
|
||||
# the burst by pulling ships back toward their pre-dash targets.
|
||||
ship.position += displacement
|
||||
ship.move_target += displacement
|
||||
ship.velocity = Vector2.ZERO
|
||||
ship.fleet_velocity = Vector2.ZERO
|
||||
ship.rotation = dash_direction.angle() + PI / 2.0
|
||||
if dash_remaining <= 0.001:
|
||||
dash_remaining = 0.0
|
||||
if steer_direction != Vector2.ZERO:
|
||||
_assign_slot_targets()
|
||||
|
||||
|
||||
func _effective_cruise_speed() -> float:
|
||||
return cruise_speed * GameState.fleet_speed_multiplier
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,25 @@
|
|||
class_name VesselDistorderComponent
|
||||
extends Node
|
||||
extends "res://vessels/VesselCooldownFillComponent.gd"
|
||||
|
||||
# Pure presence marker (#59) - no per-shot behaviour, no tick(). Its only
|
||||
# job is to make Ship.has_capability("distorder") true, which is what
|
||||
# SpeedFader.gd/Fleet.gd key off to reveal and apply the speed boost.
|
||||
# Energy drain while boosted is a later ticket (#62).
|
||||
# The presence marker used by the speed fader, plus the Energy Propulser's
|
||||
# independently recharging dash (#179). Keeping both on one component means
|
||||
# a vessel is the source of both propulsion capabilities and carries its own
|
||||
# cooldown just like gas bombers and laser vessels do.
|
||||
|
||||
var capability_id := "distorder"
|
||||
|
||||
const DASH_COOLDOWN: float = 5.0
|
||||
const READY_COLOR := Color(0.85, 0.95, 0.15)
|
||||
const COOLING_COLOR := Color(0.28, 0.31, 0.08)
|
||||
|
||||
|
||||
func _init() -> void:
|
||||
cooldown_duration = DASH_COOLDOWN
|
||||
|
||||
|
||||
func consume_dash() -> bool:
|
||||
return _begin_cooldown(DASH_COOLDOWN)
|
||||
|
||||
|
||||
func _ready_color() -> Color: return READY_COLOR
|
||||
func _cooling_color() -> Color: return COOLING_COLOR
|
||||
|
|
|
|||
|
|
@ -2,5 +2,5 @@
|
|||
|
||||
[ext_resource type="Script" path="res://vessels/VesselDistorderComponent.gd" id="1"]
|
||||
|
||||
[node name="DistorderComponent" type="Node"]
|
||||
[node name="DistorderComponent" type="Node2D"]
|
||||
script = ExtResource("1")
|
||||
|
|
|
|||
Loading…
Reference in a new issue