diff --git a/combat/modifiers/_scripts/modifier_manager.gd b/combat/modifiers/_scripts/modifier_manager.gd index 4d5ca30..f1937c7 100644 --- a/combat/modifiers/_scripts/modifier_manager.gd +++ b/combat/modifiers/_scripts/modifier_manager.gd @@ -1,28 +1,22 @@ @icon("res://assets/editor/64x64/fc1098.png") extends Node2D -class_name ModifierManagerTwo +class_name ModifierManager signal modifier_added(modifier) signal modifier_removed(modifier) signal stats_updated() -var stats: StatsComponent +var stats_component: 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) + Log.pr("StatsComponent: ", stats_component) -func set_stats(stats_component: StatsComponent) -> void: - self.stats = stats_component +func set_stats(stats: StatsComponent) -> void: + self.stats_component = stats func add_modifier(modifier: Modifier) -> void: modifiers.append(modifier) @@ -42,7 +36,7 @@ func remove_modifier(modifier_id: String) -> void: func recalculate_stats() -> void: # Reset stats to base values - final_stats = base_stats.duplicate() + stats_component.reset_stats() # Sort modifiers by priority modifiers.sort_custom(func(a, b): return a.priority > b.priority) @@ -67,26 +61,8 @@ func recalculate_stats() -> void: 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) + modifier.apply_stats_modification(stats_component) diff --git a/combat/modifiers/modifiers/fire_rate_additive.gd b/combat/modifiers/modifiers/fire_rate_additive.gd new file mode 100644 index 0000000..125538e --- /dev/null +++ b/combat/modifiers/modifiers/fire_rate_additive.gd @@ -0,0 +1,12 @@ +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(stats: StatsComponent) -> void: + stats.update_stat("ranged.attack_rate", stats.get_stat("ranged.attack_rate") + fire_rate_bonus) diff --git a/player/modifiers/fire_rate_additive.gd.uid b/combat/modifiers/modifiers/fire_rate_additive.gd.uid similarity index 100% rename from player/modifiers/fire_rate_additive.gd.uid rename to combat/modifiers/modifiers/fire_rate_additive.gd.uid diff --git a/player/modifiers/fire_rate_multiplicative.gd b/combat/modifiers/modifiers/fire_rate_multiplicative.gd similarity index 100% rename from player/modifiers/fire_rate_multiplicative.gd rename to combat/modifiers/modifiers/fire_rate_multiplicative.gd diff --git a/player/modifiers/fire_rate_multiplicative.gd.uid b/combat/modifiers/modifiers/fire_rate_multiplicative.gd.uid similarity index 100% rename from player/modifiers/fire_rate_multiplicative.gd.uid rename to combat/modifiers/modifiers/fire_rate_multiplicative.gd.uid diff --git a/player/modifiers/modifier.gd b/combat/modifiers/modifiers/modifier.gd similarity index 100% rename from player/modifiers/modifier.gd rename to combat/modifiers/modifiers/modifier.gd diff --git a/player/modifiers/modifier.gd.uid b/combat/modifiers/modifiers/modifier.gd.uid similarity index 100% rename from player/modifiers/modifier.gd.uid rename to combat/modifiers/modifiers/modifier.gd.uid diff --git a/player/modifiers/piercing.gd b/combat/modifiers/modifiers/piercing.gd similarity index 100% rename from player/modifiers/piercing.gd rename to combat/modifiers/modifiers/piercing.gd diff --git a/player/modifiers/piercing.gd.uid b/combat/modifiers/modifiers/piercing.gd.uid similarity index 100% rename from player/modifiers/piercing.gd.uid rename to combat/modifiers/modifiers/piercing.gd.uid diff --git a/combat/modifiers/modifiers/projectile_size_additive.gd b/combat/modifiers/modifiers/projectile_size_additive.gd new file mode 100644 index 0000000..0dcddca --- /dev/null +++ b/combat/modifiers/modifiers/projectile_size_additive.gd @@ -0,0 +1,21 @@ +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(stats: StatsComponent) -> void: + stats.update_stat("ranged.projectile_size", stats.get_stat("ranged.projectile_size") + size_increase) + +func modify_projectile(_projectile) -> void: + pass + # 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) -> void: + pass diff --git a/player/modifiers/projectile_size_additive.gd.uid b/combat/modifiers/modifiers/projectile_size_additive.gd.uid similarity index 100% rename from player/modifiers/projectile_size_additive.gd.uid rename to combat/modifiers/modifiers/projectile_size_additive.gd.uid diff --git a/player/modifiers/projectile_size_multiplicative.gd b/combat/modifiers/modifiers/projectile_size_multiplicative.gd similarity index 100% rename from player/modifiers/projectile_size_multiplicative.gd rename to combat/modifiers/modifiers/projectile_size_multiplicative.gd diff --git a/player/modifiers/projectile_size_multiplicative.gd.uid b/combat/modifiers/modifiers/projectile_size_multiplicative.gd.uid similarity index 100% rename from player/modifiers/projectile_size_multiplicative.gd.uid rename to combat/modifiers/modifiers/projectile_size_multiplicative.gd.uid diff --git a/combat/weapons/_scripts/ranged_weapon_component.gd b/combat/weapons/_scripts/ranged_weapon_component.gd index 892a5ca..a1504c5 100644 --- a/combat/weapons/_scripts/ranged_weapon_component.gd +++ b/combat/weapons/_scripts/ranged_weapon_component.gd @@ -9,3 +9,9 @@ class_name RangedWeaponComponent func _ready() -> void: Log.pr("RangedWeaponComponent initialized") modifier_manager.set_stats(stats) + +func add_modifier(modifier: Modifier) -> void: + modifier_manager.add_modifier(modifier) + +func remove_modifier(modifier_id: String) -> void: + modifier_manager.remove_modifier(modifier_id) \ No newline at end of file diff --git a/entities/scripts/stats_component.gd b/entities/scripts/stats_component.gd index f202eda..e32d430 100644 --- a/entities/scripts/stats_component.gd +++ b/entities/scripts/stats_component.gd @@ -2,7 +2,7 @@ extends Node2D class_name StatsComponent -var stats: Dictionary[String, Variant] = { +var base_stats: Dictionary[String, Variant] = { "base": { "health": 100, "max_health": 100, @@ -30,3 +30,66 @@ var stats: Dictionary[String, Variant] = { "pierce_count": 0 } } + +var stats: Dictionary + +func _init() -> void: + if not stats: + reset_stats() + +func reset_stats() -> void: + stats = base_stats.duplicate() + Log.pr("StatsComponent reset to base stats") + +func get_stat(stat_name: String) -> Variant: + var stat = get_nested_stat(stat_name) + if stat: + return stat + else: + Log.pr("Stat not found: ", stat_name) + return null + +func update_stat(stat_name: String, value: Variant) -> void: + var updating_stat = get_nested_stat(stat_name) + if updating_stat: + set_nested_stat(stat_name, value) + Log.pr("Updated stat: ", stat_name, " to ", value) + else: + Log.pr("Stat not found: ", stat_name) + +func get_nested_stat(path: String) -> Variant: + var keys = path.split(".") + var current = stats + + for key in keys: + if current is Dictionary and current.has(key): + current = current[key] + else: + return null # Path doesn't exist + + return current + +func set_nested_stat(path: String, value) -> bool: + var keys = path.split(".") + var current = stats + + # Navigate to the parent of the final key + for i in range(keys.size() - 1): + var key = keys[i] + + # Check if key exists and is a dictionary + if not current.has(key) or not current[key] is Dictionary: + Log.error("Invalid stat path: " + path + " (key '" + key + "' doesn't exist or isn't a dictionary)") + return false + + current = current[key] + + # Check if final key exists + var final_key = keys[keys.size() - 1] + if not current.has(final_key): + Log.error("Invalid stat path: " + path + " (key '" + final_key + "' doesn't exist)") + return false + + # Set the value at the final key + current[final_key] = value + return true \ No newline at end of file diff --git a/player/modifiers/fire_rate_additive.gd b/player/modifiers/fire_rate_additive.gd deleted file mode 100644 index aa62830..0000000 --- a/player/modifiers/fire_rate_additive.gd +++ /dev/null @@ -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 \ No newline at end of file diff --git a/player/modifiers/projectile_size_additive.gd b/player/modifiers/projectile_size_additive.gd deleted file mode 100644 index cac295b..0000000 --- a/player/modifiers/projectile_size_additive.gd +++ /dev/null @@ -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) \ No newline at end of file diff --git a/player/scripts/modifier_management.gd b/player/scripts/modifier_management.gd index 173547d..c1df5db 100644 --- a/player/scripts/modifier_management.gd +++ b/player/scripts/modifier_management.gd @@ -1,4 +1,4 @@ -class_name ModifierManager extends Node +class_name ModifierManagerOLD extends Node signal modifier_added(modifier) signal modifier_removed(modifier) diff --git a/player/scripts/player.gd b/player/scripts/player.gd index bcd6739..3c50a14 100644 --- a/player/scripts/player.gd +++ b/player/scripts/player.gd @@ -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): diff --git a/player/scripts/player_combat.gd b/player/scripts/player_combat.gd index 06b283f..7b5658a 100644 --- a/player/scripts/player_combat.gd +++ b/player/scripts/player_combat.gd @@ -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() diff --git a/player/weapons/ranged_weapon.gd b/player/weapons/ranged_weapon.gd index fb9e5ee..6db4862 100644 --- a/player/weapons/ranged_weapon.gd +++ b/player/weapons/ranged_weapon.gd @@ -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