feat(boss): 位移/蓄力/近战招式 dash/charge_up/melee(三段式+前摇预警+接管移动)
This commit is contained in:
@@ -130,6 +130,22 @@ func _start_pattern(boss_id: int, st: Dictionary, p: Dictionary) -> void:
|
||||
"ring", "spread", "aimed", "spiral":
|
||||
_fire_ranged(boss_id, st, kind, p, pos)
|
||||
st["cooldown"] = float(p.get("cooldown", 2.0))
|
||||
"dash":
|
||||
_telegraph(p, pos)
|
||||
st["action"] = {
|
||||
"kind": "dash", "stage": "windup", "timer": float(p.get("windup", 0.8)),
|
||||
"controls_move": true, "p": p,
|
||||
"target": PlayerManager.get_position(), "dir": Vector2.RIGHT, "hit_cd": 0.0}
|
||||
"charge_up":
|
||||
_telegraph(p, pos)
|
||||
st["action"] = {
|
||||
"kind": "charge_up", "stage": "windup", "timer": float(p.get("windup", 1.0)),
|
||||
"controls_move": true, "p": p}
|
||||
"melee":
|
||||
_telegraph(p, pos)
|
||||
st["action"] = {
|
||||
"kind": "melee", "stage": "windup", "timer": float(p.get("windup", 0.6)),
|
||||
"controls_move": true, "p": p}
|
||||
_:
|
||||
st["cooldown"] = float(p.get("cooldown", 2.0))
|
||||
|
||||
@@ -164,10 +180,68 @@ func _fire_ranged(boss_id: int, st: Dictionary, kind: String, p: Dictionary, pos
|
||||
func _spawn_dir(pos: Vector2, angle: float, speed: float, life: float, r: float, dmg: float) -> void:
|
||||
EnemyBulletManager.spawn_bullet(pos, Vector2(cos(angle), sin(angle)) * speed, life, r, dmg)
|
||||
|
||||
# 招式推进(Task 8 补齐三段式);骨架版直接结束
|
||||
## 前摇预警 VFX
|
||||
func _telegraph(p: Dictionary, pos: Vector2) -> void:
|
||||
var vfx: String = String(p.get("telegraph_vfx", ""))
|
||||
if vfx != "":
|
||||
VFXManager.play(vfx, pos, 1.5)
|
||||
|
||||
## 招式推进:三段式 windup → active → recover;结束还原并置冷却
|
||||
func _advance_action(boss_id: int, st: Dictionary, action: Dictionary, delta: float) -> void:
|
||||
action["timer"] = float(action["timer"]) - delta
|
||||
var p: Dictionary = action["p"]
|
||||
var pos: Vector2 = EnemyManager.get_pos_by_id(boss_id)
|
||||
match String(action["kind"]):
|
||||
"dash":
|
||||
match String(action["stage"]):
|
||||
"windup":
|
||||
if float(action["timer"]) <= 0.0:
|
||||
var dir: Vector2 = Vector2(action["target"]) - pos
|
||||
action["dir"] = dir.normalized() if dir.length() > 0.01 else Vector2.RIGHT
|
||||
action["stage"] = "active"
|
||||
action["timer"] = float(p.get("dash_time", 0.5))
|
||||
"active":
|
||||
pos += Vector2(action["dir"]) * float(p.get("dash_speed", 600.0)) * delta
|
||||
EnemyManager.set_entity_pos(boss_id, pos)
|
||||
action["hit_cd"] = maxf(0.0, float(action["hit_cd"]) - delta)
|
||||
if pos.distance_to(PlayerManager.get_position()) <= float(p.get("contact_radius", 40.0)) and float(action["hit_cd"]) <= 0.0:
|
||||
PlayerStats.take_damage(float(p.get("contact_damage", 15.0)))
|
||||
action["hit_cd"] = float(p.get("contact_hit_cd", 0.4))
|
||||
if float(action["timer"]) <= 0.0:
|
||||
action["stage"] = "recover"
|
||||
action["timer"] = float(p.get("recover", 0.8))
|
||||
"recover":
|
||||
if float(action["timer"]) <= 0.0:
|
||||
_end_action(st, p)
|
||||
"charge_up":
|
||||
match String(action["stage"]):
|
||||
"windup":
|
||||
if float(action["timer"]) <= 0.0:
|
||||
_fire_ranged(boss_id, st, String(p.get("release_kind", "ring")), p, pos)
|
||||
action["stage"] = "recover"
|
||||
action["timer"] = float(p.get("recover", 0.8))
|
||||
"recover":
|
||||
if float(action["timer"]) <= 0.0:
|
||||
_end_action(st, p)
|
||||
"melee":
|
||||
match String(action["stage"]):
|
||||
"windup":
|
||||
if float(action["timer"]) <= 0.0:
|
||||
if pos.distance_to(PlayerManager.get_position()) <= float(p.get("melee_radius", 90.0)):
|
||||
PlayerStats.take_damage(float(p.get("melee_damage", 20.0)))
|
||||
VFXManager.play("hit_spark", pos, 2.0)
|
||||
action["stage"] = "recover"
|
||||
action["timer"] = float(p.get("recover", 0.5))
|
||||
"recover":
|
||||
if float(action["timer"]) <= 0.0:
|
||||
_end_action(st, p)
|
||||
_:
|
||||
st["action"] = {}
|
||||
|
||||
func _end_action(st: Dictionary, p: Dictionary) -> void:
|
||||
st["action"] = {}
|
||||
st["cooldown"] = float(p.get("cooldown", 2.0))
|
||||
|
||||
func _on_enemy_killed(payload: Dictionary) -> void:
|
||||
var id: int = int(payload.get("entity_id", -1))
|
||||
if not _active.has(id):
|
||||
|
||||
Reference in New Issue
Block a user