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.
		
		
		
		
		
			
		
			
				
	
	
		
			74 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			GDScript
		
	
			
		
		
	
	
			74 lines
		
	
	
		
			2.5 KiB
		
	
	
	
		
			GDScript
		
	
| 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)
 | |
| 
 | |
| 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()
 | |
| 
 | |
| 
 | |
| 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
 | |
|     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)
 | |
| 
 | |
| 
 | |
| 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)
 |