Further refinements in weapone fire helper logic.
This commit is contained in:
parent
9554af183c
commit
a655f9332f
3 changed files with 57 additions and 9 deletions
|
|
@ -14,6 +14,7 @@ speed = 500
|
|||
projectiles = 5
|
||||
horizontal_offset = 8.25
|
||||
stagger_offset = 0.5
|
||||
compensate_spawn_geometry = true
|
||||
stagger_animation = true
|
||||
follow_angle = true
|
||||
groups = Array[ExtResource("2_qeb4b")]([ExtResource("3_qeb4b")])
|
||||
|
|
|
|||
|
|
@ -15,17 +15,34 @@ func compute_standard_props(weapon_data: WeaponShot, projectile_index: int, spaw
|
|||
# Timing: center-first, pairs outward
|
||||
var time_offset: float = abs(index_from_center) * weapon_data.stagger_offset
|
||||
|
||||
# Vertical spacing creates the ^ (inverted-V) geometry: outer projectiles fire lower
|
||||
# (higher Y values, further from the player) than the center projectile, which sits
|
||||
# higher on screen (lower Y values). This creates a ^ pattern relative to the origin.
|
||||
var vertical_offset: float = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
|
||||
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, +vertical_offset)
|
||||
|
||||
# Angle (only when projectiles >= 3, division-by-zero guard)
|
||||
# Moved before vertical offset to support compensation
|
||||
var bullet_angle: float = 0.0
|
||||
if total_projectiles >= 3:
|
||||
bullet_angle = (index_from_center / center_index) * (weapon_data.spread_angle / 2.0)
|
||||
|
||||
# Vertical spacing creates the ^ (inverted-V) geometry: outer projectiles fire lower
|
||||
# (higher Y values, further from the player) than the center projectile, which sits
|
||||
# higher on screen (lower Y values). This creates a ^ pattern relative to the origin.
|
||||
# When compensate_spawn_geometry is enabled and spread_angle > 0, compute vertical
|
||||
# offsets to align the geometric spread with velocity vectors.
|
||||
var vertical_offset: float
|
||||
if weapon_data.compensate_spawn_geometry and weapon_data.spread_angle > 0 and total_projectiles >= 3:
|
||||
var velocity_angle_rad: float = abs(bullet_angle) * PI / 180.0
|
||||
if index_from_center == 0:
|
||||
# Center bullet in compensated mode: use full projectile_vertical_spacing
|
||||
# so the V-shape stays visually smooth (center = 35, outer ≈ 75)
|
||||
# instead of a broken gap (center = 8.75, outer ≈ 75).
|
||||
vertical_offset = weapon_data.projectile_vertical_spacing
|
||||
elif velocity_angle_rad > 0.1: # Guard against division by zero for very small angles
|
||||
vertical_offset = abs(bullet_horizontal_offset) / tan(velocity_angle_rad)
|
||||
else:
|
||||
# Very small angle: fall back to full spacing
|
||||
vertical_offset = weapon_data.projectile_vertical_spacing
|
||||
else:
|
||||
vertical_offset = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
|
||||
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, +vertical_offset)
|
||||
|
||||
# Fire time
|
||||
var fire_time: float = current_time + time_offset
|
||||
|
||||
|
|
@ -61,8 +78,9 @@ func compute_grouped_props(group: WeaponProjectileGroup, weapon_data: WeaponShot
|
|||
bullet_angle = -group.angle_offset
|
||||
|
||||
# Symmetrical spread (guard against < 3 bullets)
|
||||
var spread_contribution: float = 0.0
|
||||
if group.bullet_count >= 3:
|
||||
var spread_contribution = (index_from_center / center_index) * (group.spread_angle / 2.0)
|
||||
spread_contribution = (index_from_center / center_index) * (group.spread_angle / 2.0)
|
||||
if mirror:
|
||||
bullet_angle -= spread_contribution
|
||||
else:
|
||||
|
|
@ -71,7 +89,25 @@ func compute_grouped_props(group: WeaponProjectileGroup, weapon_data: WeaponShot
|
|||
# Vertical spacing creates the ^ (inverted-V) geometry: outer projectiles fire lower
|
||||
# (higher Y values, further from the player) than the center projectile, which sits
|
||||
# higher on screen (lower Y values). This creates a ^ pattern relative to the origin.
|
||||
var vertical_offset: float = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
|
||||
# When compensate_spawn_geometry is enabled and group.spread_angle > 0, compute
|
||||
# vertical offsets to preserve the within-group V-shape independently of
|
||||
# angle_offset, which handles global tilt.
|
||||
#
|
||||
# angle_offset tilts the entire group — mixing it into the compensation formula
|
||||
# breaks the V-shape because the formula assumes velocity vectors converge at the
|
||||
# origin, but with angle_offset > 0 they fan out from an offset line instead.
|
||||
# Solution: calculate compensation using only within-group parameters.
|
||||
var vertical_offset: float
|
||||
if weapon_data.compensate_spawn_geometry and group.spread_angle > 0 and group.bullet_count >= 3 and index_from_center != 0:
|
||||
var within_group_angle: float = abs(spread_contribution) # exclude angle_offset
|
||||
var within_group_angle_rad: float = within_group_angle * PI / 180.0
|
||||
var within_group_horizontal: float = abs(index_from_center * group.horizontal_spacing) # exclude group.horizontal_offset
|
||||
if within_group_angle_rad > 0.1: # Guard against division by zero for very small angles
|
||||
vertical_offset = within_group_horizontal / tan(within_group_angle_rad)
|
||||
else:
|
||||
vertical_offset = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
|
||||
else:
|
||||
vertical_offset = (abs(index_from_center) * weapon_data.projectile_vertical_spacing) / 2.0
|
||||
var position: Vector2 = spawn_position + Vector2(bullet_horizontal_offset, +vertical_offset)
|
||||
|
||||
# Timing: group delay + within-group stagger
|
||||
|
|
|
|||
|
|
@ -8,7 +8,10 @@ extends Resource
|
|||
@export var speed: int = 135
|
||||
@export var projectiles: int = 2
|
||||
# Vertical spacing between projectiles in a burst (used by WeaponFireHelper to compute the ^ pattern).
|
||||
# This controls spatial burst geometry, NOT temporal spacing between continuous fire bursts.
|
||||
# This parameter has a dual role: spatial (computing the ^ burst geometry) and temporal
|
||||
# (serving as the burst-gating threshold in ShootComponent.shoot()). When compensate_spawn_geometry
|
||||
# is enabled, this parameter is overridden by geometric compensation for spatial calculations;
|
||||
# temporal behavior remains unchanged and continues to use this value.
|
||||
@export var projectile_vertical_spacing: float = 35
|
||||
# Vertical offset from the top of the player's sprite where bullets spawn.
|
||||
# Measured in pixels; negative values fire in front of (above) the ship,
|
||||
|
|
@ -23,6 +26,14 @@ extends Resource
|
|||
@export var spread_angle: float = 0.0
|
||||
# Time delay per projectile index
|
||||
@export var stagger_offset: float = 0.25
|
||||
# When enabled, adjusts spawn vertical offsets so the geometric line
|
||||
# from the center bullet to each outer bullet matches their velocity
|
||||
# direction. Eliminates the optical illusion where the spread appears
|
||||
# wider than the actual bullet trajectories (e.g. spread.tres flies at
|
||||
# half the angle it visually appears to fan).
|
||||
|
||||
## WARNING: This flag uses a trigonometric formula (horizontal_offset / tan(angle)) that evaluates independently-tuned horizontal and spread angles in grouped shots ONLY!
|
||||
@export var compensate_spawn_geometry: bool = false
|
||||
|
||||
@export_category("Effects")
|
||||
# Offset animation playback per projectile index
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue