diff --git a/scripts/Player.gd b/scripts/Player.gd index 2672aa6..6ccc194 100644 --- a/scripts/Player.gd +++ b/scripts/Player.gd @@ -136,9 +136,9 @@ func _do_kick() -> void: forward.y = 0.0 forward = forward.normalized() if forward.length() > 0.01 else Vector3(0.0, 0.0, -1.0) var half_cos: float = cos(deg_to_rad(kick_angle * 0.5)) - var targets := get_tree().get_nodes_in_group("enemies") + get_tree().get_nodes_in_group("kickable") - var kicked_any := false - for e in targets: + var candidates: Array[Node3D] = [] + var candidate_dists: Array[float] = [] + for e in get_tree().get_nodes_in_group("enemies") + get_tree().get_nodes_in_group("kickable"): if not is_instance_valid(e): continue var en := e as Node3D @@ -150,21 +150,34 @@ func _do_kick() -> void: if dist < 0.1 or dist > kick_range: continue if (diff / dist).dot(forward) >= half_cos: - var obj_tier: int = en.get("tier") if en.get("tier") != null else 0 - var diff_tier := tier - obj_tier - var force: float - if diff_tier < 0: - force = 15.0 - elif diff_tier == 0: - force = 50.0 - elif diff_tier == 1: - force = 70.0 - else: - force = 80.0 - en.call("receive_kick", diff / dist, force) - kicked_any = true - if kicked_any: - _squish_effect() + candidates.append(en) + candidate_dists.append(dist) + + if candidates.is_empty(): + return + + var nearest_idx := 0 + for i in range(1, candidates.size()): + if candidate_dists[i] < candidate_dists[nearest_idx]: + nearest_idx = i + + var best := candidates[nearest_idx] + var best_diff := best.global_position - global_position + best_diff.y = 0.0 + var best_dir := best_diff.normalized() + var obj_tier: int = best.get("tier") if best.get("tier") != null else 0 + var diff_tier := tier - obj_tier + var force: float + if diff_tier < 0: + force = 15.0 + elif diff_tier == 0: + force = 50.0 + elif diff_tier == 1: + force = 70.0 + else: + force = 80.0 + best.call("receive_kick", best_dir, force) + _squish_effect() func _try_interact() -> void: var best: Node3D = null