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":
|
"ring", "spread", "aimed", "spiral":
|
||||||
_fire_ranged(boss_id, st, kind, p, pos)
|
_fire_ranged(boss_id, st, kind, p, pos)
|
||||||
st["cooldown"] = float(p.get("cooldown", 2.0))
|
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))
|
st["cooldown"] = float(p.get("cooldown", 2.0))
|
||||||
|
|
||||||
@@ -164,9 +180,67 @@ 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:
|
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)
|
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:
|
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["action"] = {}
|
||||||
|
st["cooldown"] = float(p.get("cooldown", 2.0))
|
||||||
|
|
||||||
func _on_enemy_killed(payload: Dictionary) -> void:
|
func _on_enemy_killed(payload: Dictionary) -> void:
|
||||||
var id: int = int(payload.get("entity_id", -1))
|
var id: int = int(payload.get("entity_id", -1))
|
||||||
|
|||||||
Reference in New Issue
Block a user