84 lines
No EOL
2.9 KiB
GDScript
84 lines
No EOL
2.9 KiB
GDScript
class_name ModifierManager extends Node
|
|
|
|
signal modifier_added(modifier)
|
|
signal modifier_removed(modifier)
|
|
signal stats_updated()
|
|
|
|
# Stores all active modifiers
|
|
var modifiers: Array[Modifier] = []
|
|
|
|
# Base stats (before modifiers)
|
|
var base_stats: Dictionary = {}
|
|
|
|
# Final calculated stats
|
|
var final_stats: Dictionary = {}
|
|
|
|
func _init(initial_base_stats: Dictionary = {}):
|
|
base_stats = initial_base_stats.duplicate()
|
|
final_stats = initial_base_stats.duplicate()
|
|
|
|
func add_modifier(modifier: Modifier) -> void:
|
|
modifiers.append(modifier)
|
|
modifier.on_equip(get_parent())
|
|
emit_signal("modifier_added", modifier)
|
|
recalculate_stats()
|
|
|
|
func remove_modifier(modifier_id: String) -> void:
|
|
for i in range(modifiers.size()):
|
|
if modifiers[i].id == modifier_id:
|
|
var modifier = modifiers[i]
|
|
modifier.on_unequip(get_parent())
|
|
modifiers.remove_at(i)
|
|
emit_signal("modifier_removed", modifier)
|
|
recalculate_stats()
|
|
break
|
|
|
|
func recalculate_stats() -> void:
|
|
# Reset stats to base values
|
|
final_stats = base_stats.duplicate()
|
|
|
|
# Sort modifiers by priority
|
|
modifiers.sort_custom(func(a, b): return a.priority > b.priority)
|
|
|
|
# First pass: Apply OVERRIDE modifiers (highest priority first)
|
|
for modifier in modifiers:
|
|
if modifier.modifier_type == Modifier.ModifierType.OVERRIDE:
|
|
_apply_modifier_stats(modifier)
|
|
|
|
# Second pass: Apply ADDITIVE modifiers
|
|
for modifier in modifiers:
|
|
if modifier.modifier_type == Modifier.ModifierType.ADDITIVE:
|
|
_apply_modifier_stats(modifier)
|
|
|
|
# Third pass: Apply MULTIPLICATIVE modifiers
|
|
for modifier in modifiers:
|
|
if modifier.modifier_type == Modifier.ModifierType.MULTIPLICATIVE:
|
|
_apply_modifier_stats(modifier)
|
|
|
|
# Last pass: Apply CONDITIONAL modifiers
|
|
for modifier in modifiers:
|
|
if modifier.modifier_type == Modifier.ModifierType.CONDITIONAL:
|
|
_apply_modifier_stats(modifier)
|
|
|
|
# Apply caps and floors to stats
|
|
_apply_stat_limits()
|
|
|
|
emit_signal("stats_updated")
|
|
|
|
func _apply_modifier_stats(modifier: Modifier) -> void:
|
|
if modifier.has_method("apply_stats_modification"):
|
|
modifier.apply_stats_modification(final_stats, base_stats)
|
|
|
|
func _apply_stat_limits() -> void:
|
|
# Example: Cap fire rate
|
|
if final_stats.has("fire_rate"):
|
|
final_stats.fire_rate = min(final_stats.fire_rate, 20.0) # Max 20 shots per second
|
|
final_stats.fire_rate = max(final_stats.fire_rate, 0.5) # Min 0.5 shots per second
|
|
|
|
# Example: Cap projectile size
|
|
if final_stats.has("projectile_size"):
|
|
final_stats.projectile_size = min(final_stats.projectile_size, 5.0) # Max 5x normal size
|
|
final_stats.projectile_size = max(final_stats.projectile_size, 0.2) # Min 0.2x normal size
|
|
|
|
func get_stat(stat_name: String, default_value = 0):
|
|
return final_stats.get(stat_name, default_value) |