Adds a modifier system allowing dynamic modification of weapon stats and behavior. This includes: - Creating ModifierLibrary to manage available modifiers. - Adds ModifierManager to handle equipping and unequipping modifiers - Adds a new RangedWeaponComponent to handle firing projectiles and managing modifiers. - Introduces a DebugUI for in-game modifier management. - Introduces an "Unlimited Power" modifier that changes the projectile scene. - Modifies stats components to work with the new modifier system. This system allows for more flexible and customizable weapon functionality.
116 lines
3.3 KiB
GDScript
116 lines
3.3 KiB
GDScript
class_name RangedWeapon extends Node2D
|
|
|
|
signal projectile_spawned(projectile)
|
|
|
|
@export var projectile_scene: PackedScene
|
|
|
|
# Base stats - will be modified by modifiers
|
|
var base_stats = {
|
|
"damage": 10.0,
|
|
"fire_rate": 3.0,
|
|
"projectile_speed": 500.0,
|
|
"projectile_size": 1.0,
|
|
"projectile_lifetime": 1.0,
|
|
"projectile_quantity": 1,
|
|
"projectile_spread": 33,
|
|
"max_pierce": 0
|
|
}
|
|
|
|
# Components
|
|
#var stats: ModifierManager
|
|
var can_fire: bool = true
|
|
var fire_timer: Timer
|
|
|
|
func _init() -> void:
|
|
#stats = ModifierManager.new(base_stats)
|
|
#Log.pr(stats)
|
|
#add_child(stats)
|
|
# Setup fire timer
|
|
fire_timer = Timer.new()
|
|
add_child(fire_timer)
|
|
fire_timer.one_shot = true
|
|
|
|
projectile_scene = preload("res://assets/projectiles/projectile_lightning.tscn")
|
|
|
|
func _ready():
|
|
#stats.connect("stats_updated", _on_stats_updated)
|
|
fire_timer.connect("timeout", _on_fire_timer_timeout)
|
|
|
|
# Initial update
|
|
_on_stats_updated()
|
|
|
|
func fire(direction: Vector2, target_position: Vector2):
|
|
if !can_fire:
|
|
return
|
|
|
|
Log.pr("Firing weapon")
|
|
_spawn_projectile(global_position, direction, target_position)
|
|
|
|
can_fire = false
|
|
#Log.pr("Cooldown", stats.get_stat("fire_rate"))
|
|
#fire_timer.start(stats.get_stat("fire_rate"))
|
|
|
|
func _spawn_projectile(spawn_position: Vector2, spawn_direction: Vector2, target_position: Vector2):
|
|
# Get projectile quantity and spread from stats
|
|
var quantity = 1 # stats.get_stat("projectile_quantity")
|
|
var spread_angle = 0 # stats.get_stat("projectile_spread")
|
|
|
|
# Calculate the angle between each projectile
|
|
var angle_step = 0.0
|
|
if quantity > 1 and spread_angle > 0:
|
|
angle_step = spread_angle / (quantity - 1)
|
|
|
|
# Calculate starting angle (to center the spread)
|
|
var start_angle = - spread_angle / 2
|
|
|
|
# Spawn each projectile
|
|
for i in range(quantity):
|
|
var projectile = projectile_scene.instantiate()
|
|
projectile.global_position = spawn_position
|
|
projectile.target_position = target_position
|
|
|
|
# Calculate the direction with spread
|
|
var direction = spawn_direction
|
|
if quantity > 1:
|
|
var current_angle = start_angle + (i * angle_step)
|
|
direction = spawn_direction.rotated(deg_to_rad(current_angle))
|
|
|
|
projectile.direction = direction
|
|
|
|
# Apply stats to projectile
|
|
projectile.speed = 200 # stats.get_stat("projectile_speed")
|
|
projectile.damage = 10 # stats.get_stat("damage")
|
|
projectile.lifetime = 200 # stats.get_stat("projectile_lifetime")
|
|
projectile.source_weapon = self
|
|
|
|
# Set base size
|
|
var size = 1 # stats.get_stat("projectile_size")
|
|
projectile.set_projectile_scale(Vector2(size, size))
|
|
|
|
# Allow modifiers to directly modify the projectile
|
|
#for modifier in stats.modifiers:
|
|
# modifier.modify_projectile(projectile)
|
|
|
|
# Add to scene tree
|
|
if get_tree() and get_tree().get_root():
|
|
get_tree().get_root().add_child(projectile)
|
|
|
|
# Emit the spawn signal
|
|
if projectile.has_signal("on_spawned"):
|
|
projectile.emit_signal("on_spawned", projectile)
|
|
|
|
func add_modifier(modifier: Modifier):
|
|
Log.pr("Adding modifier: ", modifier)
|
|
#stats.add_modifier(modifier)
|
|
|
|
func remove_modifier(modifier_id: String):
|
|
pass
|
|
#stats.remove_modifier(modifier_id)
|
|
func _on_stats_updated():
|
|
# Update any visual components based on new stats
|
|
# For example, if weapon appearance changes based on damage/fire rate
|
|
pass
|
|
|
|
func _on_fire_timer_timeout():
|
|
Log.pr("Fire timer timeout")
|
|
can_fire = true
|