You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

101 lines
3.3 KiB
GDScript

1 year ago
extends Node3D
class_name SoulAI
@export var follow_speed_curve: Curve
@export var follow_dist_max: int = 5
@onready var character: Character = (get_owner() as Character)
@onready var status: Status = (%Status as Status)
@onready var skill: Skill = (%Skill as Skill)
1 year ago
var owner_character: Character
func _process(_delta) -> void:
owner_character = Global.character_mgr.get_character(status.owner_id)
if not owner_character:
Global.character_mgr.destroy_character(character.id())
return
update_skill()
update_skill_move()
update_move()
update_bullet()
1 year ago
func update_skill() -> void:
if not status.ai_skill_order:
return
var skill_order: Status.SkillOrder = status.ai_skill_order[0]
if not skill_order:
return
var skill_cfg: SkillCfg = skill_order.skill_cfg
if skill_cfg.sub_character and skill_cfg.sub_character.type == Enum.ECharacterType.Bullet:
8 months ago
for i in range(skill_cfg.sub_character_count):
var bullet_order: Status.BulletOrder = Status.BulletOrder.new()
bullet_order.bullet_cfg = skill_cfg.sub_character
bullet_order.cast_dir = skill_order.cast_dir
bullet_order.target = skill_order.target
status.ai_bullet_order.append(bullet_order)
status.ai_skill_order.remove_at(0)
else:
var cast_dir: Vector2 = skill_order.cast_dir if skill_order.cast_dir else Vector2.RIGHT
status.target = skill_order.target
var target: Character = Global.character_mgr.get_character(status.target)
if target:
cast_dir = character.pos2D().direction_to(target.pos2D()).normalized()
#施放技能条件检查
if not skill.cast_skill_check(skill_cfg, status.break_level):
return
character.move_to(cast_dir)
skill.cast_skill(skill_cfg, cast_dir)
status.ai_skill_order.remove_at(0)
func update_skill_move() -> void:
if not status.is_skill_running:
return
var target: Character = Global.character_mgr.get_character(status.target)
if not target:
return
var dir: Vector2 = target.pos2D() - character.pos2D()
var dist: float = dir.length()
if int(status.break_level) < Enum.EBreakLevel.Break:
if dist < 0.5:
character.move_to(-dir)
elif dist > 2:
character.move_to(dir)
1 year ago
10 months ago
func update_bullet() -> void:
if character.has_buff("bullet_cd"):
return
if not status.ai_bullet_order:
return
var bullet_order: Status.BulletOrder = status.ai_bullet_order[0]
if not bullet_order:
return
var pos: Vector3 = character.pos()
var dir: Vector2 = bullet_order.cast_dir
var sub: Character = Global.character_mgr.create_character(bullet_order.bullet_cfg, status.team, pos, dir, status.id)
if sub:
sub.set_status("target", bullet_order.target)
status.ai_bullet_order.remove_at(0)
character.add_buff("bullet_cd", Setting.bullet_cd)
10 months ago
1 year ago
func update_move() -> void:
if status.is_skill_running:
return
var owner_pos: Vector3 = owner_character.pos()
var radius_add: float = owner_character.radius() + character.radius()
var target_pos: Vector3 = owner_pos + Vector3(-1 if owner_character.is_right() else 1, 0, 0) * radius_add * 1.1
var dir: Vector3 = target_pos - character.pos()
var dir_2d: Vector2 = Vector2(dir.x, dir.z)
var dist: float = dir_2d.length()
if dist > follow_dist_max:
character.set_pos(target_pos)
return
var dist_rate = clamp(dist / follow_dist_max, 0, 1)
status.speed_up_rate = follow_speed_curve.sample(dist_rate)
character.move_to(dir_2d)