|
|
|
|
extends Node3D
|
|
|
|
|
class_name Battle
|
|
|
|
|
|
|
|
|
|
@onready var character = (get_owner() as Character)
|
|
|
|
|
@onready var status = (%Status as Status)
|
|
|
|
|
|
|
|
|
|
class HitInfo:
|
|
|
|
|
var from : int
|
|
|
|
|
var to : int
|
|
|
|
|
var dir : Vector2
|
|
|
|
|
var attack : AttackCfg
|
|
|
|
|
|
|
|
|
|
var hit_info_list = [] #命中信息
|
|
|
|
|
|
|
|
|
|
func attack():
|
|
|
|
|
if !status.skill_cfg:
|
|
|
|
|
return
|
|
|
|
|
var attack_list = status.skill_cfg.attack_list
|
|
|
|
|
if !attack_list:
|
|
|
|
|
print("未配置技能攻击",status.skill_cfg)
|
|
|
|
|
return
|
|
|
|
|
var attack_index = status.skill_attack_index
|
|
|
|
|
if attack_index >= len(attack_list):
|
|
|
|
|
attack_index = len(attack_list) - 1
|
|
|
|
|
var attack = attack_list[attack_index] as AttackCfg
|
|
|
|
|
var enemy_list = Global.character_mgr.get_enemy_list(character.id())
|
|
|
|
|
var pos = character.pos()
|
|
|
|
|
var attack_dir = status.skill_dir.normalized()
|
|
|
|
|
var attack_height = attack.height
|
|
|
|
|
var attack_size = Util.grid_vector2(attack.size)
|
|
|
|
|
var attack_radius = attack.radius
|
|
|
|
|
var offset_xz = attack_dir * Util.grid_float(attack.offset.x)
|
|
|
|
|
pos += Vector3(offset_xz.x,Util.grid_float(attack.offset.y),offset_xz.y)
|
|
|
|
|
for enemy in enemy_list:
|
|
|
|
|
var target_pos = enemy.pos()
|
|
|
|
|
var target_radius = enemy.radius()
|
|
|
|
|
var target_height = enemy.height()
|
|
|
|
|
if Util.attack_detection(pos,target_pos,target_radius,target_height,attack_dir,attack_height,attack_size,attack_radius):
|
|
|
|
|
var hit_info = HitInfo.new()
|
|
|
|
|
hit_info.from = character.id()
|
|
|
|
|
hit_info.to = enemy.id()
|
|
|
|
|
hit_info.dir = attack_dir
|
|
|
|
|
hit_info.attack = attack
|
|
|
|
|
hit_info_list.append(hit_info)
|
|
|
|
|
|
|
|
|
|
func add_attack(from:int,dir:Vector2,attack:AttackCfg):
|
|
|
|
|
var hit_info = HitInfo.new()
|
|
|
|
|
hit_info.from = from
|
|
|
|
|
hit_info.to = character.id()
|
|
|
|
|
hit_info.dir = dir
|
|
|
|
|
hit_info.attack = attack
|
|
|
|
|
hit_info_list.append(hit_info)
|
|
|
|
|
|
|
|
|
|
func _process(delta):
|
|
|
|
|
for hit_info in hit_info_list:
|
|
|
|
|
settle(hit_info)
|
|
|
|
|
hit_info_list.clear()
|
|
|
|
|
|
|
|
|
|
func settle(hit_info:HitInfo):
|
|
|
|
|
var character_from = Global.character_mgr.get_character(hit_info.from) as Character
|
|
|
|
|
var character_to = Global.character_mgr.get_character(hit_info.to) as Character
|
|
|
|
|
if !character_from or !character_to:
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
var cfg_from = character_from.cfg()
|
|
|
|
|
var cfg_to = 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 attack = hit_info.attack
|
|
|
|
|
var is_floating = attack.is_floating or not character_to.get_status("is_on_floor")
|
|
|
|
|
var is_hit_down = attack.is_hit_down
|
|
|
|
|
var is_rebound = attack.is_rebound
|
|
|
|
|
|
|
|
|
|
var is_break_shield = false
|
|
|
|
|
var is_break_stun = false
|
|
|
|
|
var is_block = false
|
|
|
|
|
var is_kill = false
|
|
|
|
|
var is_break_skill = false
|
|
|
|
|
|
|
|
|
|
#造成伤害
|
|
|
|
|
var damage = attack.damage_rate * cfg_from.attack
|
|
|
|
|
if has_shield:
|
|
|
|
|
damage = min(shield,damage)
|
|
|
|
|
character_to.set_status("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 = 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累加
|
|
|
|
|
character_from.add_mp(damage * cfg_from.mp.add_rate_attack)
|
|
|
|
|
character_from.remove_buff("mp_recover")
|
|
|
|
|
character_from.add_buff("mp_recover_cd",status.cfg.mp.recover_cd)
|
|
|
|
|
character_to.add_mp(damage * cfg_to.mp.add_rate_hit)
|
|
|
|
|
character_to.remove_buff("mp_recover")
|
|
|
|
|
character_to.add_buff("mp_recover_cd",status.cfg.mp.recover_cd)
|
|
|
|
|
|
|
|
|
|
#硬直等级
|
|
|
|
|
var break_level_def = cfg_to.shield.break_level_on if has_shield else cfg_to.shield.break_level_off
|
|
|
|
|
var break_level_sub = clampi(attack.break_level - break_level_def,0,3)
|
|
|
|
|
is_break_skill = break_level_sub > 0
|
|
|
|
|
if is_break_skill:
|
|
|
|
|
#取消技能
|
|
|
|
|
if character_to.get_status("is_skill_running"):
|
|
|
|
|
character_to.cancel_skill()
|
|
|
|
|
|
|
|
|
|
#停止移动
|
|
|
|
|
character_to.move_stop()
|
|
|
|
|
|
|
|
|
|
#受击动画
|
|
|
|
|
var trigger_hit = ""
|
|
|
|
|
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 = attack.hit_up_speed
|
|
|
|
|
if is_floating:
|
|
|
|
|
character_to.add_buff("stagger",-1)
|
|
|
|
|
character_to.add_buff("floating",-1)
|
|
|
|
|
if hit_info.dir.x!=0:
|
|
|
|
|
character_to.set_status("is_right",hit_info.dir.x<0)
|
|
|
|
|
else:
|
|
|
|
|
character_to.add_buff("stagger",1)
|
|
|
|
|
hit_up_speed = 0
|
|
|
|
|
if is_hit_down:
|
|
|
|
|
character_to.add_buff("hit_down",-1)
|
|
|
|
|
character_to.set_hit_move(hit_info.dir,attack.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)
|
|
|
|
|
|
|
|
|
|
#受击特效
|
|
|
|
|
character_to.cast_particle(ResourceManager.particle_hit_normal)
|
|
|
|
|
|
|
|
|
|
#抖动
|
|
|
|
|
character_to.add_buff("shake_x",0.2,true)
|
|
|
|
|
|
|
|
|
|
#闪白
|
|
|
|
|
character_to.add_buff("flash_white",0.1)
|
|
|
|
|
|
|
|
|
|
#形变
|
|
|
|
|
character_to.add_buff("deformation",0.1)
|
|
|
|
|
|
|
|
|
|
#卡帧
|
|
|
|
|
character_from.add_buff("pause",attack.pause_time)
|
|
|
|
|
character_to.add_buff("pause",attack.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")
|
|
|
|
|
|
|
|
|
|
func add_mp(value:float):
|
|
|
|
|
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)
|
|
|
|
|
if value == mp_sub_max-mp_sub:
|
|
|
|
|
var mp_add = min(mp_max-mp,1)
|
|
|
|
|
if mp_add > 0:
|
|
|
|
|
character.set_status("mp",mp+mp_add)
|
|
|
|
|
character.set_status("mp_sub",0)
|
|
|
|
|
else:
|
|
|
|
|
character.remove_buff("mp_recover_cd")
|
|
|
|
|
character.remove_buff("mp_recover")
|
|
|
|
|
else:
|
|
|
|
|
character.set_status("mp_sub",mp_sub+value)
|