Adds a modifier and stats system to manage combat-related attributes. Introduces StatsComponent for storing entity statistics and ModifierManager for applying dynamic modifiers. Recalculates stats based on modifier type and priority. Updates projectile and weapon components to utilize the new stats system.
92 lines
2.8 KiB
GDScript
92 lines
2.8 KiB
GDScript
@icon("res://assets/editor/64x64/fc1098.png")
|
|
extends Node2D
|
|
class_name ModifierManagerTwo
|
|
|
|
signal modifier_added(modifier)
|
|
signal modifier_removed(modifier)
|
|
signal stats_updated()
|
|
|
|
var stats: StatsComponent
|
|
|
|
# Stores all active modifiers
|
|
var modifiers: Array[Modifier] = []
|
|
|
|
# Base stats (before modifiers)
|
|
var base_stats: Dictionary = {}
|
|
|
|
# Final calculated stats
|
|
var final_stats: Dictionary = {}
|
|
|
|
func _ready() -> void:
|
|
Log.pr("ModifierManager initialized")
|
|
Log.pr("Stats: ", stats)
|
|
|
|
func set_stats(stats_component: StatsComponent) -> void:
|
|
self.stats = stats_component
|
|
|
|
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:
|
|
pass
|
|
# 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)
|