extends Resource class_name Ability enum Type { SINGLE, AOE, UTILITY, ULT, PASSIVE } @export var ability_name: String = "" @export var type: Type = Type.SINGLE @export var damage: float = 0.0 @export var ability_range: float = 3.0 @export var icon: String = "" func execute(player: Node, targeting: Node) -> void: var dmg: float = _get_modified_damage(player, damage) match type: Type.SINGLE: _execute_single(player, targeting, dmg) Type.AOE: _execute_aoe(player, dmg) Type.UTILITY: _execute_utility(player) Type.ULT: _execute_ult(player, targeting, dmg) func _get_modified_damage(player: Node, base: float) -> float: var combat: Node = player.get_node("Combat") return combat.apply_passive(base) func _execute_single(player: Node, targeting: Node, dmg: float) -> void: var target: Node3D = targeting.current_target if not target or not is_instance_valid(target): return var dist: float = player.global_position.distance_to(target.global_position) if dist > ability_range: return EventBus.damage_requested.emit(player, target, dmg) EventBus.attack_executed.emit(player, player.global_position, -player.global_transform.basis.z, dmg) func _execute_aoe(player: Node, dmg: float) -> void: var enemies := player.get_tree().get_nodes_in_group("enemies") for enemy in enemies: var dist: float = player.global_position.distance_to(enemy.global_position) if dist <= ability_range: EventBus.damage_requested.emit(player, enemy, dmg) EventBus.attack_executed.emit(player, player.global_position, -player.global_transform.basis.z, dmg) func _execute_utility(player: Node) -> void: var shield: Node = player.get_node_or_null("Shield") if shield: shield.current_shield = shield.max_shield EventBus.shield_changed.emit(player, shield.current_shield, shield.max_shield) func _execute_ult(player: Node, targeting: Node, dmg: float) -> void: var target: Node3D = targeting.current_target if not target or not is_instance_valid(target): return var dist: float = player.global_position.distance_to(target.global_position) if dist > ability_range: return EventBus.damage_requested.emit(player, target, dmg * 4.0) var enemies := player.get_tree().get_nodes_in_group("enemies") for enemy in enemies: if enemy != target: var enemy_dist: float = target.global_position.distance_to(enemy.global_position) if enemy_dist <= ability_range: EventBus.damage_requested.emit(player, enemy, dmg * 2.0) EventBus.attack_executed.emit(player, player.global_position, -player.global_transform.basis.z, dmg * 4.0)