feat(bounce): bullet_manager 命中弹跳分支(优先于pierce)+跳过已访问+_find_nearest_unvisited 寻的
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -73,6 +73,10 @@ func _check_collision(bullet_idx: int, base: int) -> bool:
|
||||
var dist_sq: float = dx * dx + dy * dy
|
||||
if dist_sq > query_r * query_r:
|
||||
continue
|
||||
if _bullet_contexts.has(bullet_idx):
|
||||
var vt = _bullet_contexts[bullet_idx].get("visited_targets", null)
|
||||
if vt != null and entity_id in vt:
|
||||
continue # 弹跳已命中过此敌:跳过,避免密集群内重复命中
|
||||
# 命中:通过 DamageContextPool 发出伤害
|
||||
var ctx_id: int = DamageContextPool.acquire(b_dmg, b_mult, b_type, b_own, false, 0.0)
|
||||
EnemyManager.apply_damage_from_context(entity_id, ctx_id)
|
||||
@@ -99,6 +103,25 @@ func _check_collision(bullet_idx: int, base: int) -> bool:
|
||||
if payload_id >= 0:
|
||||
var parent_depth: int = int(cold.get("trigger_parent_depth", 0))
|
||||
SpellEvaluator.execute_sub(payload_id, hit_pos, b_own, parent_depth + 1)
|
||||
# bounce 处理(优先于 pierce):命中后弹向最近未访问敌人,伤害递减
|
||||
var bounce: int = int(cold.get("bounce_remaining", 0))
|
||||
if bounce > 0:
|
||||
var visited: Array = cold.get("visited_targets", [])
|
||||
visited.append(entity_id)
|
||||
var next_id: int = _find_nearest_unvisited(Vector2(bx, by), float(cold.get("bounce_range", 250.0)), visited)
|
||||
if next_id >= 0:
|
||||
var np: Vector2 = EnemyManager.get_pos_by_id(next_id)
|
||||
var spd: float = Vector2(_data[base + 2], _data[base + 3]).length()
|
||||
var dir: Vector2 = (np - Vector2(bx, by)).normalized()
|
||||
_data[base + 2] = dir.x * spd
|
||||
_data[base + 3] = dir.y * spd
|
||||
_data[base + 7] *= float(cold.get("bounce_decay", 0.9))
|
||||
cold["bounce_remaining"] = bounce - 1
|
||||
cold["visited_targets"] = visited
|
||||
_bullet_contexts[bullet_idx] = cold
|
||||
return false
|
||||
_swap_and_pop(bullet_idx)
|
||||
return true
|
||||
# pierce 处理
|
||||
var pierce: int = int(cold.get("pierce_remaining", 0))
|
||||
if pierce > 0:
|
||||
@@ -174,6 +197,23 @@ func sync_multimesh(mm: MultiMesh) -> void:
|
||||
0.0, Vector2(r * 2.0, r * 2.0), 0.0,
|
||||
Vector2(_data[base + 0], _data[base + 1])))
|
||||
|
||||
## 弹跳寻的:query_circle 半径内滤除已访问/哨兵,取最近 entity_id;无则 -1
|
||||
func _find_nearest_unvisited(origin: Vector2, radius: float, visited: Array) -> int:
|
||||
var hits: PackedInt32Array = SpatialGrid.query_circle(origin, radius)
|
||||
var best_id: int = -1
|
||||
var best_sq: float = radius * radius
|
||||
for eid in hits:
|
||||
if eid in visited:
|
||||
continue
|
||||
var p: Vector2 = EnemyManager.get_pos_by_id(eid)
|
||||
if p == Vector2(-9999.0, -9999.0):
|
||||
continue
|
||||
var d: float = origin.distance_squared_to(p)
|
||||
if d <= best_sq:
|
||||
best_sq = d
|
||||
best_id = eid
|
||||
return best_id
|
||||
|
||||
func get_nearest_enemy_pos(origin: Vector2, max_dist: float = 9999.0) -> Vector2:
|
||||
return EnemyManager.get_nearest_pos(origin, max_dist)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user