Feat/2 weapons foundation #6
@@ -70,7 +70,7 @@ class_name MovementParams
|
|||||||
@export var rocket_jump_falloff: float = 1.5
|
@export var rocket_jump_falloff: float = 1.5
|
||||||
|
|
||||||
# ── Shotgun Jump ──────────────────────────────────────────────────────────────
|
# ── Shotgun Jump ──────────────────────────────────────────────────────────────
|
||||||
@export var shotgun_jump_impulse: float = 20.0
|
@export var shotgun_jump_impulse: float = 10.0
|
||||||
|
|
||||||
# ── Double Jump ───────────────────────────────────────────────────────────────
|
# ── Double Jump ───────────────────────────────────────────────────────────────
|
||||||
@export var double_jump_velocity: float = 8.0
|
@export var double_jump_velocity: float = 8.0
|
||||||
|
|||||||
@@ -4,24 +4,36 @@ class_name HomingProjectile
|
|||||||
var weapon_source: Node
|
var weapon_source: Node
|
||||||
var turn_speed: float = 5.0
|
var turn_speed: float = 5.0
|
||||||
|
|
||||||
|
var initial_aim_dir: Vector3 = Vector3.ZERO
|
||||||
|
var cruise_speed: float = 60.0
|
||||||
|
var ignition_timer: float = 0.5
|
||||||
|
var ignited: bool = false
|
||||||
|
|
||||||
func _physics_process(delta: float) -> void:
|
func _physics_process(delta: float) -> void:
|
||||||
if is_instance_valid(weapon_source) and weapon_source.get("homing_target_pos") != null:
|
if not ignited:
|
||||||
|
ignition_timer -= delta
|
||||||
|
if ignition_timer <= 0.0:
|
||||||
|
ignited = true
|
||||||
|
drop_gravity = 0.0
|
||||||
|
|
||||||
|
if ignited and is_instance_valid(weapon_source):
|
||||||
|
var target_dir: Vector3 = initial_aim_dir
|
||||||
var is_painting = weapon_source.get("is_targeting")
|
var is_painting = weapon_source.get("is_targeting")
|
||||||
if is_painting != null and not is_painting:
|
|
||||||
# Not painting target, just fly straight
|
if is_painting != null and is_painting:
|
||||||
pass
|
var target: Vector3 = weapon_source.get("homing_target_pos")
|
||||||
else:
|
if target != null and target != Vector3.ZERO:
|
||||||
var target: Vector3 = weapon_source.homing_target_pos
|
target_dir = (target - global_position).normalized()
|
||||||
if target != Vector3.ZERO:
|
|
||||||
# Steer towards target
|
if target_dir != Vector3.ZERO:
|
||||||
var speed = velocity.length()
|
|
||||||
var desired_dir = (target - global_position).normalized()
|
|
||||||
var current_dir = velocity.normalized()
|
var current_dir = velocity.normalized()
|
||||||
|
var new_dir = current_dir.lerp(target_dir, turn_speed * delta).normalized()
|
||||||
|
|
||||||
var new_dir = current_dir.lerp(desired_dir, turn_speed * delta).normalized()
|
# Accelerate to cruise speed
|
||||||
velocity = new_dir * speed
|
var current_speed = velocity.length()
|
||||||
|
var new_speed = move_toward(current_speed, cruise_speed, 80.0 * delta)
|
||||||
|
velocity = new_dir * new_speed
|
||||||
|
|
||||||
# Also rotate visually to match new direction
|
|
||||||
var up_vec = Vector3.UP
|
var up_vec = Vector3.UP
|
||||||
if abs(new_dir.dot(up_vec)) > 0.99:
|
if abs(new_dir.dot(up_vec)) > 0.99:
|
||||||
up_vec = Vector3.RIGHT
|
up_vec = Vector3.RIGHT
|
||||||
|
|||||||
+30
-8
@@ -109,19 +109,34 @@ func _fire() -> void:
|
|||||||
var tween = create_tween()
|
var tween = create_tween()
|
||||||
tween.tween_property(muzzle_flash, "light_energy", 0.0, 0.1)
|
tween.tween_property(muzzle_flash, "light_energy", 0.0, 0.1)
|
||||||
|
|
||||||
var origin = camera.global_position
|
var origin = camera.global_position + camera.global_transform.basis * Vector3(0.4, -0.2, -0.6)
|
||||||
var base_dir = -camera.global_transform.basis.z
|
var base_dir = -camera.global_transform.basis.z
|
||||||
|
|
||||||
|
_current_aim_dir = base_dir
|
||||||
|
|
||||||
for i in range(8):
|
for i in range(8):
|
||||||
# Calculate spread
|
|
||||||
var right = camera.global_transform.basis.x
|
var right = camera.global_transform.basis.x
|
||||||
var up = camera.global_transform.basis.y
|
var up = camera.global_transform.basis.y
|
||||||
|
|
||||||
var x_spread = randf_range(-1.0, 1.0) * spread_angle
|
var fraction = float(i) / 7.0 # 0.0 to 1.0 (left to right)
|
||||||
var y_spread = randf_range(-1.0, 1.0) * spread_angle
|
|
||||||
|
|
||||||
var fire_dir = (base_dir + right * x_spread + up * y_spread).normalized()
|
# Offset from left (-0.1) to right (0.1) on the top edge of the launcher
|
||||||
_spawn_custom_projectile(origin, fire_dir)
|
var local_x = lerpf(-0.1, 0.1, fraction)
|
||||||
|
var local_offset = Vector3(local_x, 0.1, 0.0)
|
||||||
|
|
||||||
|
var launcher_center_local = Vector3(0.4, -0.4, -0.6)
|
||||||
|
var proj_origin = camera.global_position + camera.global_transform.basis * (launcher_center_local + local_offset)
|
||||||
|
|
||||||
|
# Fire direction: radial fan out
|
||||||
|
# They shoot mostly forward, but fan out horizontally, and slightly arch upwards radially
|
||||||
|
var angle = lerpf(-PI/3.0, PI/3.0, fraction) # -60 deg to +60 deg fan
|
||||||
|
var x_dir = sin(angle) * 0.6
|
||||||
|
var y_dir = cos(angle) * 0.8 # Reduced upward angle so it's not mostly straight up
|
||||||
|
|
||||||
|
var fire_dir = (base_dir + right * x_dir + up * y_dir).normalized()
|
||||||
|
_spawn_custom_projectile(proj_origin, fire_dir)
|
||||||
|
|
||||||
|
var _current_aim_dir: Vector3 = Vector3.ZERO
|
||||||
|
|
||||||
func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
||||||
var proj = load("res://weapons/homing_projectile.gd").new()
|
var proj = load("res://weapons/homing_projectile.gd").new()
|
||||||
@@ -151,14 +166,21 @@ func _spawn_custom_projectile(origin: Vector3, fire_dir: Vector3) -> void:
|
|||||||
|
|
||||||
proj.position = origin # Start at origin to spread outward around camera
|
proj.position = origin # Start at origin to spread outward around camera
|
||||||
proj.logical_source = origin
|
proj.logical_source = origin
|
||||||
proj.velocity = fire_dir * projectile_speed
|
|
||||||
|
# Initial pop-up speed
|
||||||
|
proj.velocity = fire_dir * 5.0
|
||||||
if player:
|
if player:
|
||||||
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
proj.velocity += fire_dir * player.velocity.dot(fire_dir)
|
||||||
|
|
||||||
|
proj.initial_aim_dir = _current_aim_dir
|
||||||
|
proj.cruise_speed = 65.0
|
||||||
|
proj.ignition_timer = randf_range(0.3, 0.6) # Staggered ignition
|
||||||
|
|
||||||
proj.damage = base_damage
|
proj.damage = base_damage
|
||||||
proj.min_damage = min_damage
|
proj.min_damage = min_damage
|
||||||
proj.falloff_start = falloff_start
|
proj.falloff_start = falloff_start
|
||||||
proj.max_range = max_range
|
proj.max_range = max_range
|
||||||
proj.drop_gravity = 0.0
|
proj.drop_gravity = 5.0 # Slight arc before ignition
|
||||||
proj.owner_player = player
|
proj.owner_player = player
|
||||||
|
|
||||||
# Explosive stats
|
# Explosive stats
|
||||||
|
|||||||
Reference in New Issue
Block a user