Refactors modifier system to use StatsComponent
Moves modifier logic to utilize a central StatsComponent for managing and applying stat modifications. This change centralizes stat management and simplifies the application of modifiers, enhancing code maintainability and reducing redundancy. It also moves modifier files to the correct directory.
This commit is contained in:
parent
19cc8cb573
commit
9f66ab0a73
21 changed files with 135 additions and 97 deletions
|
|
@ -1,13 +0,0 @@
|
|||
class_name FireRateAdditive extends Modifier
|
||||
|
||||
@export var fire_rate_bonus: float = 1.0 # +1 shot per second
|
||||
|
||||
func _init():
|
||||
id = "fire_rate_additive"
|
||||
display_name = "Rapid Fire"
|
||||
description = "Increases fire rate by %0.1f shots per second" % fire_rate_bonus
|
||||
modifier_type = ModifierType.ADDITIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, _base_stats: Dictionary) -> void:
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate += fire_rate_bonus
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://cqamoc42g8sam
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
class_name FireRateMultiplicative extends Modifier
|
||||
|
||||
@export var fire_rate_multiplier: float = 1.2 # 20% faster firing
|
||||
|
||||
func _init():
|
||||
id = "fire_rate_multiplicative"
|
||||
display_name = "Frenzy"
|
||||
description = "Increases fire rate by %d%%" % ((fire_rate_multiplier - 1.0) * 100)
|
||||
modifier_type = ModifierType.MULTIPLICATIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, _base_stats: Dictionary) -> void:
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate *= fire_rate_multiplier
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bbqp2rhogkicu
|
||||
|
|
@ -1,31 +0,0 @@
|
|||
class_name Modifier extends Resource
|
||||
|
||||
enum ModifierType {
|
||||
ADDITIVE, # Simply adds values (e.g., +5 damage)
|
||||
MULTIPLICATIVE, # Multiplies by a percentage (e.g., 20% more damage)
|
||||
OVERRIDE, # Completely replaces the value
|
||||
CONDITIONAL # Applies under certain conditions
|
||||
}
|
||||
|
||||
@export var id: String
|
||||
@export var display_name: String
|
||||
@export var description: String
|
||||
@export var icon: Texture
|
||||
@export var rarity: int
|
||||
@export var modifier_type: ModifierType = ModifierType.ADDITIVE
|
||||
@export var priority: int = 0 # Higher priority modifiers apply first
|
||||
|
||||
# Called when the modifier is added to a weapon or ability
|
||||
func on_equip(_owner) -> void:
|
||||
pass
|
||||
|
||||
# Called when the modifier is removed
|
||||
func on_unequip(_owner) -> void:
|
||||
pass
|
||||
|
||||
# Override in child classes for specific modification logic
|
||||
func modify_projectile(_projectile) -> void:
|
||||
pass
|
||||
|
||||
func modify_ability(_ability) -> void:
|
||||
pass
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://c2vpdeqk0vvrg
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
class_name PiercingModifier extends Modifier
|
||||
|
||||
@export var pierce_count: int = 2
|
||||
|
||||
func _init():
|
||||
id = "piercing"
|
||||
display_name = "Piercing Shot"
|
||||
description = "Projectiles pass through %d enemies" % pierce_count
|
||||
|
||||
func modify_projectile(projectile):
|
||||
projectile.pierce_count = pierce_count
|
||||
projectile.connect("on_hit", _on_projectile_hit)
|
||||
|
||||
func _on_projectile_hit(projectile, _target):
|
||||
projectile.pierce_count -= 1
|
||||
if projectile.pierce_count <= 0:
|
||||
projectile.pierce_count = 0
|
||||
projectile.set_piercing(false)
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://b60nonvh7ml2o
|
||||
|
|
@ -1,25 +0,0 @@
|
|||
class_name ProjectileSizeAdditive extends Modifier
|
||||
|
||||
@export var size_increase: float = 0.5 # +50% bigger
|
||||
|
||||
func _init():
|
||||
id = "size_additive"
|
||||
display_name = "Enlarged Projectiles"
|
||||
description = "Increases projectile size by %d%%" % (size_increase * 100)
|
||||
modifier_type = ModifierType.ADDITIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
if final_stats.has("projectile_size"):
|
||||
final_stats.projectile_size += size_increase
|
||||
|
||||
func modify_projectile(projectile) -> void:
|
||||
# This will be called when the projectile is created
|
||||
# Scale is often handled in the recalculate_stats method, but we can also add visual effects here
|
||||
projectile.connect("on_spawned", _on_projectile_spawned)
|
||||
|
||||
func _on_projectile_spawned(projectile):
|
||||
# Add a trail effect for larger projectiles
|
||||
if projectile.scale.x > 1.2:
|
||||
pass
|
||||
#var trail = preload("res://scenes/projectile_trail.tscn").instantiate()
|
||||
#projectile.add_child(trail)
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://hsl3es4bcvqf
|
||||
|
|
@ -1,14 +0,0 @@
|
|||
class_name ProjectileSizeMultiplicative extends Modifier
|
||||
|
||||
@export var size_multiplier: float = 1.5 # 50% bigger
|
||||
|
||||
func _init():
|
||||
id = "size_multiplicative"
|
||||
display_name = "Giant Projectiles"
|
||||
description = "Multiplies projectile size by %0.1fx" % size_multiplier
|
||||
modifier_type = ModifierType.MULTIPLICATIVE
|
||||
priority = 10 # Higher priority than the additive version
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
if final_stats.has("projectile_size"):
|
||||
final_stats.projectile_size *= size_multiplier
|
||||
|
|
@ -1 +0,0 @@
|
|||
uid://bvfir8srnaraa
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
class_name ModifierManager extends Node
|
||||
class_name ModifierManagerOLD extends Node
|
||||
|
||||
signal modifier_added(modifier)
|
||||
signal modifier_removed(modifier)
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@ extends CharacterBody2D
|
|||
@export var ranged: RangedWeaponComponent
|
||||
@export var melee: MeleeWeaponComponent
|
||||
|
||||
var weapon: RangedWeapon
|
||||
var movement: PlayerMovement
|
||||
var combat: PlayerCombat
|
||||
|
||||
|
|
@ -15,7 +14,6 @@ var last_direction = Vector2.DOWN
|
|||
@onready var animated_sprite = $PlayerSprite
|
||||
|
||||
func _ready():
|
||||
weapon = $RangedWeapon
|
||||
combat = PlayerCombat.new()
|
||||
|
||||
movement = PlayerMovement.new()
|
||||
|
|
@ -27,14 +25,14 @@ func _ready():
|
|||
combat.animated_sprite = animated_sprite
|
||||
|
||||
Log.pr("Adding projectile size additive modifier")
|
||||
#weapon.add_modifier(ProjectileSizeAdditive.new())
|
||||
Log.pr(weapon.stats.get_stat("projectile_size")) # Size is now 1.0 + 0.5 = 1.5
|
||||
ranged.add_modifier(ProjectileSizeAdditive.new())
|
||||
#Log.pr(weapon.stats.get_stat("projectile_size")) # Size is now 1.0 + 0.5 = 1.5
|
||||
# Size is now 1.0 + 0.5 = 1.5
|
||||
|
||||
# Add the multiplicative size modifier (1.5x multiplier)
|
||||
Log.pr("Adding projectile size multiplicative modifier")
|
||||
#weapon.add_modifier(ProjectileSizeMultiplicative.new())
|
||||
Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
#Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
# Size is now 1.5 * 1.5 = 2.25
|
||||
|
||||
# Add another additive size modifier (+0.7 or 70% increase)
|
||||
|
|
@ -42,9 +40,9 @@ func _ready():
|
|||
var another_size_mod = ProjectileSizeAdditive.new()
|
||||
another_size_mod.size_increase = 0.7
|
||||
#weapon.add_modifier(another_size_mod)
|
||||
Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
#Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
|
||||
#weapon.add_modifier(FireRateAdditive.new())
|
||||
ranged.add_modifier(FireRateAdditive.new())
|
||||
|
||||
|
||||
func _physics_process(delta):
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ func process(_delta):
|
|||
var direction = mouse_position - player_position
|
||||
var normalized_direction = direction.normalized()
|
||||
|
||||
player.weapon.fire(normalized_direction, mouse_position)
|
||||
player.ranged.fire(normalized_direction, mouse_position)
|
||||
# Update animation
|
||||
#update_animation()
|
||||
|
||||
|
|
|
|||
|
|
@ -17,15 +17,14 @@ var base_stats = {
|
|||
}
|
||||
|
||||
# Components
|
||||
var stats: ModifierManager
|
||||
#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)
|
||||
|
||||
#stats = ModifierManager.new(base_stats)
|
||||
#Log.pr(stats)
|
||||
#add_child(stats)
|
||||
# Setup fire timer
|
||||
fire_timer = Timer.new()
|
||||
add_child(fire_timer)
|
||||
|
|
@ -34,7 +33,7 @@ func _init() -> void:
|
|||
projectile_scene = preload("res://assets/projectiles/projectile_lightning.tscn")
|
||||
|
||||
func _ready():
|
||||
stats.connect("stats_updated", _on_stats_updated)
|
||||
#stats.connect("stats_updated", _on_stats_updated)
|
||||
fire_timer.connect("timeout", _on_fire_timer_timeout)
|
||||
|
||||
# Initial update
|
||||
|
|
@ -48,13 +47,13 @@ func fire(direction: Vector2, target_position: Vector2):
|
|||
_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"))
|
||||
#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 = stats.get_stat("projectile_quantity")
|
||||
var spread_angle = stats.get_stat("projectile_spread")
|
||||
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
|
||||
|
|
@ -79,18 +78,18 @@ func _spawn_projectile(spawn_position: Vector2, spawn_direction: Vector2, target
|
|||
projectile.direction = direction
|
||||
|
||||
# Apply stats to projectile
|
||||
projectile.speed = stats.get_stat("projectile_speed")
|
||||
projectile.damage = stats.get_stat("damage")
|
||||
projectile.lifetime = stats.get_stat("projectile_lifetime")
|
||||
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 = stats.get_stat("projectile_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)
|
||||
#for modifier in stats.modifiers:
|
||||
# modifier.modify_projectile(projectile)
|
||||
|
||||
# Add to scene tree
|
||||
if get_tree() and get_tree().get_root():
|
||||
|
|
@ -102,10 +101,11 @@ func _spawn_projectile(spawn_position: Vector2, spawn_direction: Vector2, target
|
|||
|
||||
func add_modifier(modifier: Modifier):
|
||||
Log.pr("Adding modifier: ", modifier)
|
||||
stats.add_modifier(modifier)
|
||||
#stats.add_modifier(modifier)
|
||||
|
||||
func remove_modifier(modifier_id: String):
|
||||
stats.remove_modifier(modifier_id)
|
||||
pass
|
||||
#stats.remove_modifier(modifier_id)
|
||||
|
||||
func _on_stats_updated():
|
||||
# Update any visual components based on new stats
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue