Refactors projectile spawning to allow for customized spawn locations and stat assignment. Applies modifiers to projectiles at the time of spawning, enabling dynamic adjustments to projectile behavior.
84 lines
2.7 KiB
GDScript
84 lines
2.7 KiB
GDScript
@icon("res://assets/editor/64x64/fc1515.png")
|
|
extends Node2D
|
|
class_name RangedWeaponComponent
|
|
|
|
@export var stats: StatsComponent
|
|
@export var basic_projectile: PackedScene = preload("res://assets/projectiles/basic_projectile.tscn")
|
|
|
|
@onready var modifier_manager = $ModifierManager
|
|
@onready var projectile_scene: PackedScene = basic_projectile
|
|
|
|
var can_fire: bool = true
|
|
var cooldown: Timer
|
|
|
|
var projectile_spawn_location: Vector2
|
|
|
|
func _init() -> void:
|
|
cooldown = Timer.new()
|
|
add_child(cooldown)
|
|
cooldown.one_shot = true
|
|
|
|
func _ready() -> void:
|
|
Log.pr("RangedWeaponComponent initialized")
|
|
modifier_manager.set_stats(stats)
|
|
modifier_manager.connect("modifier_added", _on_modifier_added)
|
|
modifier_manager.connect("modifier_removed", _on_modifier_removed)
|
|
cooldown.connect("timeout", _on_fire_timer_timeout)
|
|
|
|
func add_modifier(modifier: Modifier) -> void:
|
|
modifier_manager.add_modifier(modifier)
|
|
|
|
func remove_modifier(modifier_id: String) -> void:
|
|
modifier_manager.remove_modifier(modifier_id)
|
|
|
|
func fire(direction: Vector2, target_position: Vector2) -> void:
|
|
if !can_fire:
|
|
return
|
|
|
|
spawn_projectile(direction, target_position)
|
|
|
|
can_fire = false
|
|
cooldown.start(1 / stats.get_stat("ranged.attack_rate"))
|
|
|
|
func set_projectile_scene() -> void:
|
|
projectile_scene = basic_projectile
|
|
modifier_manager.check_and_call("set_projectile_scene", [self])
|
|
|
|
## Get the projectile spawn location
|
|
## This defaults to the global position of the player
|
|
## but can be overridden by modifiers
|
|
func get_projectile_spawn_location() -> Vector2:
|
|
projectile_spawn_location = global_position
|
|
modifier_manager.check_and_call("get_projectile_spawn_location", [self])
|
|
return projectile_spawn_location
|
|
|
|
func spawn_projectile(spawn_direction: Vector2, target_position: Vector2) -> void:
|
|
Log.pr("Spawning projectile")
|
|
modifier_manager.check_and_call("spawn_projectile", [self])
|
|
|
|
## TODO: Handle multiple shots per fire
|
|
|
|
var projectile = projectile_scene.instantiate()
|
|
projectile.global_position = get_projectile_spawn_location()
|
|
projectile.target_position = target_position
|
|
projectile.set_stats(stats.duplicate())
|
|
projectile.source_weapon = self
|
|
var size = stats.get_stat("ranged.projectile_size")
|
|
projectile.set_projectile_scale(Vector2(size, size))
|
|
|
|
for modifier in modifier_manager.modifiers:
|
|
Log.pr("Adding modifier to projectile: ", modifier)
|
|
if projectile.has_method("add_modifier"):
|
|
projectile.add_modifier(modifier)
|
|
|
|
if get_tree() and get_tree().get_root():
|
|
get_tree().get_root().add_child(projectile)
|
|
|
|
func _on_modifier_added(_modifier: Modifier) -> void:
|
|
set_projectile_scene()
|
|
|
|
func _on_modifier_removed(_modifier: Modifier) -> void:
|
|
set_projectile_scene()
|
|
|
|
func _on_fire_timer_timeout() -> void:
|
|
can_fire = true
|