AnvilAbilityControler

 avatar
unknown
python
2 months ago
3.4 kB
3
Indexable
extends Node

const BASE_RANGE = 100
const BASE_DAMAGE = 15
const MAX_TARGET_RANGE = 300

@export var anvil_ability_scene: PackedScene

@onready var mastery_component = $WeaponMasteryComponent
@onready var kill_tracker = $KillTrackerComponent

var number_of_anvils = 1
var last_impact_position: Vector2

func _ready() -> void:
	add_to_group("anvil_controller")
	$Timer.timeout.connect(on_timer_timeout)
	GameEvents.ability_upgrade_added.connect(on_ability_upgrade_added)

func get_last_impact_position() -> Vector2:
	return last_impact_position

func find_closest_enemies(player_pos: Vector2, count: int) -> Array:
	var enemies = get_tree().get_nodes_in_group("enemy")
	var valid_targets = []
	
	# Filter and sort enemies by distance
	for enemy in enemies:
		var distance = player_pos.distance_to(enemy.global_position)
		if distance <= MAX_TARGET_RANGE:
			valid_targets.append({
				"node": enemy,
				"distance": distance
			})
	
	# Sort by distance
	valid_targets.sort_custom(func(a, b): return a.distance < b.distance)
	
	# Return the closest enemies up to the requested count
	var result = []
	for i in min(count, valid_targets.size()):
		result.append(valid_targets[i].node)
	
	return result

func get_spawn_position(player: Node2D, target_enemy = null) -> Vector2:
	if target_enemy != null:
		var direction = (target_enemy.global_position - player.global_position).normalized()
		var random_offset = Vector2(randf_range(-20, 20), randf_range(-20, 20))
		var target_pos = target_enemy.global_position + random_offset
		
		var query_parameters = PhysicsRayQueryParameters2D.create(
			player.global_position, 
			target_pos,
			1
		)
		var result = get_tree().root.world_2d.direct_space_state.intersect_ray(query_parameters)
		
		if result.is_empty():
			return target_pos
		return result["position"]
	
	# Fallback to random position if no target
	var random_direction = Vector2.RIGHT.rotated(randf() * TAU)
	var spawn_position = player.global_position + (random_direction * randf_range(0, BASE_RANGE))
	
	var query_parameters = PhysicsRayQueryParameters2D.create(
		player.global_position,
		spawn_position,
		1
	)
	var result = get_tree().root.world_2d.direct_space_state.intersect_ray(query_parameters)
	
	if not result.is_empty():
		spawn_position = result["position"]
	
	return spawn_position

func on_timer_timeout():
	var player = get_tree().get_first_node_in_group("player") as Node2D
	if player == null:
		return
	
	var target_enemies = find_closest_enemies(player.global_position, number_of_anvils)
	
	for i in number_of_anvils:
		var target_enemy = null
		if i < target_enemies.size():
			target_enemy = target_enemies[i]
		
		var spawn_position = get_spawn_position(player, target_enemy)
		last_impact_position = spawn_position
		
		var anvil_ability = anvil_ability_scene.instantiate() as AnvilAbility
		get_tree().get_first_node_in_group("foreground_layer").add_child(anvil_ability)
		anvil_ability.global_position = spawn_position
		anvil_ability.hitbox_component.damage = BASE_DAMAGE
		
		kill_tracker.register_hitbox(anvil_ability.hitbox_component)

func on_ability_upgrade_added(upgrade: AbilityUpgrade, current_upgrades: Dictionary):
	if upgrade.id == "anvil_count":
		if mastery_component.has_mastery_requirement(WeaponMasteryManager.MasteryLevel.TEST):
			number_of_anvils = current_upgrades["anvil_count"]["quantity"] + 1
Leave a Comment