|  |  |  | extends Node3D | 
					
						
							|  |  |  | class_name Battle | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @export var hit_back_limit_curve: Curve | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var character: Character = (get_owner() as Character) | 
					
						
							|  |  |  | @onready var status: Status = (%Status as Status) | 
					
						
							|  |  |  | @onready var skill: Skill = (%Skill as Skill) | 
					
						
							|  |  |  | @onready var move: Move = (%Move as Move) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class HitResult: | 
					
						
							|  |  |  |     var is_hit: bool | 
					
						
							|  |  |  |     var is_break: bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func attack1() -> void: | 
					
						
							|  |  |  |     if not status.skill_cfg: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     var attack: AttackCfg        = status.skill_cfg.get_attack1() | 
					
						
							|  |  |  |     var attack_box: AttackBoxCfg = status.skill_cfg.get_attack1_box() | 
					
						
							|  |  |  |     _attack(attack, attack_box) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func attack2() -> void: | 
					
						
							|  |  |  |     if not status.skill_cfg: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     var attack: AttackCfg        = status.skill_cfg.get_attack2() | 
					
						
							|  |  |  |     var attack_box: AttackBoxCfg = status.skill_cfg.get_attack2_box() | 
					
						
							|  |  |  |     _attack(attack, attack_box) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func character_attack1() -> bool: | 
					
						
							|  |  |  |     var attack: AttackCfg        = status.cfg.get_attack1() | 
					
						
							|  |  |  |     var attack_box: AttackBoxCfg = status.cfg.get_attack1_box() | 
					
						
							|  |  |  |     return _attack(attack, attack_box) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func character_attack2() -> bool: | 
					
						
							|  |  |  |     var attack: AttackCfg        = status.cfg.get_attack2() | 
					
						
							|  |  |  |     var attack_box: AttackBoxCfg = status.cfg.get_attack2_box() | 
					
						
							|  |  |  |     return _attack(attack, attack_box) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _attack(attack: AttackCfg, attack_box: AttackBoxCfg) -> bool: | 
					
						
							|  |  |  |     if not attack or not attack_box: | 
					
						
							|  |  |  |         return false | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var pos: Vector3        = character.pos() | 
					
						
							|  |  |  |     var attack_dir: Vector2 = status.skill_dir.normalized() | 
					
						
							|  |  |  |     var result: Array[Character] | 
					
						
							|  |  |  |     if attack_box.is_throw: | 
					
						
							|  |  |  |         var target: Character = Global.character_mgr.get_character(status.throw_target) | 
					
						
							|  |  |  |         if target: | 
					
						
							|  |  |  |             result = [target] | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         var offset_xz: Vector2 = attack_dir * attack_box.offset.x | 
					
						
							|  |  |  |         var offset_y: float    = attack_box.offset.y | 
					
						
							|  |  |  |         var offset: Vector3    = Vector3(offset_xz.x, offset_y, offset_xz.y) | 
					
						
							|  |  |  |         var shape: Shape3D     = attack_box.shape | 
					
						
							|  |  |  |         _debug_draw_attack_box(shape, offset) | 
					
						
							|  |  |  |         result = Util.raycast_character(shape, pos+offset, attack_dir) | 
					
						
							|  |  |  |     var is_hit: bool = false | 
					
						
							|  |  |  |     for target: Character in result: | 
					
						
							|  |  |  |         if target == null: | 
					
						
							|  |  |  |             is_hit = true | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         if target.team() == character.team(): | 
					
						
							|  |  |  |             continue | 
					
						
							|  |  |  |         var hit_result: HitResult = add_attack(character.id(), target.id(), attack_dir, attack) | 
					
						
							|  |  |  |         on_attack_hit(hit_result) | 
					
						
							|  |  |  |         is_hit = true | 
					
						
							|  |  |  |     if !is_hit and !attack.is_force_pause: | 
					
						
							|  |  |  |         skill.on_attack_miss() | 
					
						
							|  |  |  |     return is_hit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _debug_draw_attack_box(shape: Shape3D, offset: Vector3) -> void: | 
					
						
							|  |  |  |     if not get_tree().debug_collisions_hint: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     if shape is BoxShape3D: | 
					
						
							|  |  |  |         var scale: Vector3 = shape.size | 
					
						
							|  |  |  |         character.cast_particle(ResourceManager.particle_debug_box, false, offset, scale) | 
					
						
							|  |  |  |     elif shape is CylinderShape3D: | 
					
						
							|  |  |  |         var scale: Vector3 = Vector3(shape.radius, shape.height, shape.radius) | 
					
						
							|  |  |  |         character.cast_particle(ResourceManager.particle_debug_cylinder, false, offset, scale) | 
					
						
							|  |  |  |     return | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func add_attack(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult: | 
					
						
							|  |  |  |     var hit_result: HitResult = HitResult.new() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var character_from: Character = Global.character_mgr.get_character(from) as Character | 
					
						
							|  |  |  |     var character_to: Character   = Global.character_mgr.get_character(to) as Character | 
					
						
							|  |  |  |     if !character_from or !character_to: | 
					
						
							|  |  |  |         return hit_result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var cfg_from: CharacterCfg = character_from.cfg() | 
					
						
							|  |  |  |     var cfg_to: CharacterCfg   = character_to.cfg() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var is_stun    = character_to.get_status("is_stun") | 
					
						
							|  |  |  |     var hp         = character_to.get_status("hp") | 
					
						
							|  |  |  |     var shield     = character_to.get_status("shield") | 
					
						
							|  |  |  |     var has_shield = shield > 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var is_floating: bool = attack.is_floating or not character_to.get_status("is_on_floor") | 
					
						
							|  |  |  |     var is_hit_down: bool = attack.is_hit_down and not character_to.get_status("is_on_floor") | 
					
						
							|  |  |  |     var is_rebound: bool  = attack.is_rebound | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     var is_break_shield: bool     = false | 
					
						
							|  |  |  |     var is_break_stun: bool       = false | 
					
						
							|  |  |  |     var is_block: bool            = false | 
					
						
							|  |  |  |     var is_kill: bool             = false | 
					
						
							|  |  |  |     var is_break_skill: bool      = false | 
					
						
							|  |  |  |     var is_break_skill_real: bool = false | 
					
						
							|  |  |  |     var pause_time: float         = attack.pause_time | 
					
						
							|  |  |  |     var is_bullet: bool           = int(character_from.cfg().type) == Enum.ECharacterType.Bullet | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #基本伤害 | 
					
						
							|  |  |  |     var damage: float = attack.damage_rate * cfg_from.attack | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #硬直等级 | 
					
						
							|  |  |  |     var break_level_def: int = cfg_to.shield.break_level_on if has_shield else cfg_to.shield.break_level_off | 
					
						
							|  |  |  |     break_level_def += character_to.get_status("skill_break_level_add") | 
					
						
							|  |  |  |     var break_level_sub: int = clampi(attack.break_level - break_level_def, 0, 3) | 
					
						
							|  |  |  |     is_break_skill_real = break_level_sub > 0 | 
					
						
							|  |  |  |     is_break_skill = is_break_skill_real or not character_to.get_status("is_on_floor") | 
					
						
							|  |  |  |     if break_level_sub < 0: | 
					
						
							|  |  |  |         damage = 0 | 
					
						
							|  |  |  |         pause_time *= 2 | 
					
						
							|  |  |  |     elif break_level_sub == 0: | 
					
						
							|  |  |  |         damage *= 0.5 | 
					
						
							|  |  |  |         pause_time *= 1.5 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     is_floating = is_break_skill and is_floating | 
					
						
							|  |  |  |     is_hit_down = is_break_skill and is_hit_down | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #造成伤害 | 
					
						
							|  |  |  |     if has_shield: | 
					
						
							|  |  |  |         damage = min(shield, damage) | 
					
						
							|  |  |  |         character_to.set_shield(shield-damage) | 
					
						
							|  |  |  |         is_break_shield = damage == shield | 
					
						
							|  |  |  |         if is_break_shield: | 
					
						
							|  |  |  |             character_to.remove_buff("shield_recover_cd") | 
					
						
							|  |  |  |             character_to.remove_buff("shield_recover") | 
					
						
							|  |  |  |             has_shield = false | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             character_to.remove_buff("shield_recover") | 
					
						
							|  |  |  |             character_to.add_buff("shield_recover_cd", cfg_to.shield.recover_cd) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         damage = min(hp, damage) | 
					
						
							|  |  |  |         character_to.set_status("hp", hp-damage) | 
					
						
							|  |  |  |         is_kill = damage == hp | 
					
						
							|  |  |  |         if is_kill: | 
					
						
							|  |  |  |             character_to.add_buff("die", 1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #眩晕值累加 | 
					
						
							|  |  |  |     if not is_stun: | 
					
						
							|  |  |  |         var stun_damage: float = attack.stun_attack | 
					
						
							|  |  |  |         var stun               = character_to.get_status("stun") | 
					
						
							|  |  |  |         var stun_max           = character_to.get_status("stun_max") | 
					
						
							|  |  |  |         stun_damage = min(stun_max-stun, stun_damage) | 
					
						
							|  |  |  |         character_to.set_status("stun", stun+stun_damage) | 
					
						
							|  |  |  |         is_break_stun = stun_damage == stun_max-stun | 
					
						
							|  |  |  |         if is_break_stun: | 
					
						
							|  |  |  |             is_stun = true | 
					
						
							|  |  |  |             character_to.set_status("is_stun", true) | 
					
						
							|  |  |  |             character_to.remove_buff("stun_recover_cd") | 
					
						
							|  |  |  |             character_to.remove_buff("stun_recover") | 
					
						
							|  |  |  |             character_to.add_buff("stun_recover_break_cd", cfg_to.stun.recover_break_cd) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             character_to.remove_buff("stun_recover") | 
					
						
							|  |  |  |             character_to.add_buff("stun_recover_cd", cfg_to.stun.recover_cd) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #mp累加 | 
					
						
							|  |  |  |     if not is_bullet: | 
					
						
							|  |  |  |         character_from.add_mp_sub(damage * cfg_from.mp.add_rate_attack, true) | 
					
						
							|  |  |  |     character_to.add_mp_sub(damage * cfg_to.mp.add_rate_hit, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #投技检测 | 
					
						
							|  |  |  |     if is_break_skill and attack.is_throw_check and not character_to.get_status("is_be_throw") and status.throw_target == 0: | 
					
						
							|  |  |  |         character_to.set_status("is_be_throw", true) | 
					
						
							|  |  |  |         status.throw_target = character_to.id() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #投技结束 | 
					
						
							|  |  |  |     if attack.is_throw_end: | 
					
						
							|  |  |  |         character_to.set_status("is_be_throw", false) | 
					
						
							|  |  |  |         status.throw_target = 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if is_break_skill: | 
					
						
							|  |  |  |         #取消技能 | 
					
						
							|  |  |  |         if character_to.get_status("is_skill_running"): | 
					
						
							|  |  |  |             character_to.cancel_skill() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #停止移动 | 
					
						
							|  |  |  |         character_to.move_stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #受击动画 | 
					
						
							|  |  |  |         var trigger_hit: String = "" | 
					
						
							|  |  |  |         if is_rebound: trigger_hit="rebound" | 
					
						
							|  |  |  |         elif is_floating: trigger_hit = "air_hit_down" if is_hit_down else "air_hit_up" | 
					
						
							|  |  |  |         elif is_stun: trigger_hit="stun_hit" | 
					
						
							|  |  |  |         elif break_level_sub == 3: trigger_hit="lhit" | 
					
						
							|  |  |  |         elif break_level_sub == 2: trigger_hit="mhit" | 
					
						
							|  |  |  |         elif break_level_sub == 1: trigger_hit="hit" | 
					
						
							|  |  |  |         character_to.set_view_trigger(trigger_hit) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         #浮空 击落 强制位移 | 
					
						
							|  |  |  |         var hit_up_speed: float   = attack.hit_up_speed | 
					
						
							|  |  |  |         var hit_back_speed: float = attack.hit_back_speed | 
					
						
							|  |  |  |         if is_floating: | 
					
						
							|  |  |  |             character_to.add_buff("stagger", -1) | 
					
						
							|  |  |  |             character_to.add_buff("floating", -1) | 
					
						
							|  |  |  |             if dir.x!=0: | 
					
						
							|  |  |  |                 character_to.set_status("is_right", dir.x<0) | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             character_to.add_buff("stagger", 1) | 
					
						
							|  |  |  |             hit_up_speed = 0 | 
					
						
							|  |  |  |             if hit_back_limit_curve: | 
					
						
							|  |  |  |                 var character_dir: Vector2 = character_from.pos2D() - character_to.pos2D() | 
					
						
							|  |  |  |                 var dist                   = clamp(character_dir.length(), 0, 1) | 
					
						
							|  |  |  |                 hit_back_speed = max(hit_back_limit_curve.sample(dist), hit_back_speed) | 
					
						
							|  |  |  |         if is_hit_down: | 
					
						
							|  |  |  |             character_to.add_buff("hit_down", -1) | 
					
						
							|  |  |  |         elif not is_break_skill_real: | 
					
						
							|  |  |  |             hit_up_speed *= 0.75 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         character_to.set_hit_move(dir, hit_back_speed, hit_up_speed) | 
					
						
							|  |  |  |         character_to.add_buff("hit_back", attack.hit_back_duration) | 
					
						
							|  |  |  |         character_to.add_buff("hit_up", attack.hit_up_duration) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #停止自身位移 | 
					
						
							|  |  |  |     if attack.is_stop_self and not is_bullet: | 
					
						
							|  |  |  |         character_from.move_stop() | 
					
						
							|  |  |  |         character_from.set_status("skill_move_stop", true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #受击特效 | 
					
						
							|  |  |  |     match attack.damage_type: | 
					
						
							|  |  |  |         Enum.EDamageType.Sharp: character_to.cast_particle(ResourceManager.particle_hit_sharp, false) | 
					
						
							|  |  |  |         Enum.EDamageType.Blunt: character_to.cast_particle(ResourceManager.particle_hit_blunt, false) | 
					
						
							|  |  |  |         Enum.EDamageType.Ground: character_to.cast_particle(ResourceManager.particle_hit_ground, false) | 
					
						
							|  |  |  |         _: pass | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #抖动 | 
					
						
							|  |  |  |     character_to.add_buff("shake_x", 0.2, true) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #闪白 | 
					
						
							|  |  |  |     character_to.add_buff("flash_white", 0.1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #卡帧 | 
					
						
							|  |  |  |     if not is_bullet: | 
					
						
							|  |  |  |         character_from.set_pause_time(pause_time) | 
					
						
							|  |  |  |     character_to.set_pause_time(pause_time) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #全局特效 | 
					
						
							|  |  |  |     if character_from.is_player() or character_to.is_player(): | 
					
						
							|  |  |  |         Global.camera_mgr.effect(pause_time) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #伤害跳字 | 
					
						
							|  |  |  |     character_to.show_hit_damage(damage) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     #状态跳字 | 
					
						
							|  |  |  |     if is_break_shield: character_to.show_hit_text("Break") | 
					
						
							|  |  |  |     elif is_break_stun: character_to.show_hit_text("Stun") | 
					
						
							|  |  |  |     elif not is_break_skill: character_to.show_hit_text("Block") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hit_result.is_break = is_break_skill | 
					
						
							|  |  |  |     return hit_result | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func add_mp_sub(value: float, from_battle: bool): | 
					
						
							|  |  |  |     var mp         = character.get_status("mp") | 
					
						
							|  |  |  |     var mp_max     = character.get_status("mp_max") | 
					
						
							|  |  |  |     var mp_sub     = character.get_status("mp_sub") | 
					
						
							|  |  |  |     var mp_sub_max = character.get_status("mp_sub_max") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     value = min(mp_sub_max-mp_sub, value) | 
					
						
							|  |  |  |     var mp_sub_full = value == mp_sub_max-mp_sub | 
					
						
							|  |  |  |     var mp_full     = mp == mp_max | 
					
						
							|  |  |  |     if mp_sub_full: | 
					
						
							|  |  |  |         #mp_sub已满 | 
					
						
							|  |  |  |         if mp_full: | 
					
						
							|  |  |  |             #mp已满 | 
					
						
							|  |  |  |             character.set_status("mp_sub", mp_sub_max) | 
					
						
							|  |  |  |             character.remove_buff("mp_recover_cd") | 
					
						
							|  |  |  |             character.remove_buff("mp_recover") | 
					
						
							|  |  |  |         else: | 
					
						
							|  |  |  |             #mp未满 | 
					
						
							|  |  |  |             character.set_status("mp", mp+1) | 
					
						
							|  |  |  |             character.set_status("mp_sub", 0) | 
					
						
							|  |  |  |     else: | 
					
						
							|  |  |  |         character.set_status("mp_sub", max(mp_sub+value, 0)) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if from_battle: | 
					
						
							|  |  |  |         character.remove_buff("mp_recover") | 
					
						
							|  |  |  |         character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func cost_mp(value: int): | 
					
						
							|  |  |  |     var mp     = character.get_status("mp") | 
					
						
							|  |  |  |     var mp_max = character.get_status("mp_max") | 
					
						
							|  |  |  |     var mp_new = mp-value | 
					
						
							|  |  |  |     mp_new = min(mp_new, mp_max) | 
					
						
							|  |  |  |     mp_new = max(mp_new, 0) | 
					
						
							|  |  |  |     character.set_status("mp", mp_new) | 
					
						
							|  |  |  |     character.remove_buff("mp_recover") | 
					
						
							|  |  |  |     character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_ground(): skill.on_check_ground(0) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_ground1(): skill.on_check_ground(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_ground2(): skill.on_check_ground(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_charging1(): skill.on_check_charging(1) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_charging2(): skill.on_check_charging(2) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_charging3(): skill.on_check_charging(3) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func cast_sub_character(): skill.on_cast_sub_character() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func hold(): skill.on_hold() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func stop(): move.stop() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func change_dir() -> void: | 
					
						
							|  |  |  |     var cast_dir: Vector2 = status.move_dir | 
					
						
							|  |  |  |     var target: Character = Global.character_mgr.get_character(status.target) | 
					
						
							|  |  |  |     if target: | 
					
						
							|  |  |  |         cast_dir = target.pos2D() - character.pos2D() | 
					
						
							|  |  |  |     status.skill_dir = cast_dir | 
					
						
							|  |  |  |     status.is_right = cast_dir.x > 0 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_attack_hit(hit_result: HitResult) -> void: | 
					
						
							|  |  |  |     if not status.skill_cfg: | 
					
						
							|  |  |  |         return | 
					
						
							|  |  |  |     var skill_name: String = status.skill_cfg.get_res_name() | 
					
						
							|  |  |  |     if hit_result.is_hit: | 
					
						
							|  |  |  |         on_attack_hit_trigger(skill_name, "hit") | 
					
						
							|  |  |  |     if hit_result.is_break: | 
					
						
							|  |  |  |         on_attack_hit_trigger(skill_name, "break") | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_attack_hit_trigger(skill_name: String, trigger_name: String) -> void: | 
					
						
							|  |  |  |     var func_name: String = "on_%s_%s" % [skill_name, trigger_name] | 
					
						
							|  |  |  |     if has_method(func_name): | 
					
						
							|  |  |  |         call(func_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_skill_release_trigger(skill_name: String) -> void: | 
					
						
							|  |  |  |     var func_name: String = "on_%s_release" % skill_name | 
					
						
							|  |  |  |     if has_method(func_name): | 
					
						
							|  |  |  |         call(func_name) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_hero01_fist_skill01_break(): | 
					
						
							|  |  |  |     var target: int = status.throw_target | 
					
						
							|  |  |  |     skill.cast_skill_by_name("hero01_fist_skill02", status.move_dir) | 
					
						
							|  |  |  |     status.throw_target = target | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func on_hero01_fist_skill_charging_release(): | 
					
						
							|  |  |  |     match status.charging_level: | 
					
						
							|  |  |  |         0: skill.cast_skill_by_name("hero01_fist_skill_charging01", status.move_dir) | 
					
						
							|  |  |  |         _: skill.cast_skill_by_name("hero01_fist_skill_charging02", status.move_dir) |