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.

214 lines
6.8 KiB
GDScript

2 years ago
extends Node3D
class_name Battle
@export var hit_back_limit_curve : Curve
2 years ago
@onready var character = (get_owner() as Character)
@onready var status = (%Status as Status)
@onready var skill = (%Skill as Skill)
2 years ago
class HitInfo:
var from : int
2 years ago
var to : int
var dir : Vector2
var attack : AttackCfg
func attack1():
var attack = status.skill_cfg.get_attack1()
var attack_box = status.skill_cfg.get_attack1_box()
call_deferred("_attack",attack,attack_box)
func attack2():
var attack = status.skill_cfg.get_attack2()
var attack_box = status.skill_cfg.get_attack2_box()
call_deferred("_attack",attack,attack_box)
func _attack(attack:AttackCfg,attack_box:AttackBoxCfg):
var pos = character.pos()
var attack_dir = status.skill_dir.normalized()
var offset_xz = attack_dir * attack_box.offset.x
var offset_y = attack_box.offset.y
pos += Vector3(offset_xz.x,offset_y,offset_xz.y)
var result = Util.raycast_character(attack_box.shape,pos,attack_dir)
var is_stuck = false
for target:Character in result:
if target.team() == character.team():
continue
target.add_attack(character.id(),attack_dir,attack)
is_stuck = true
if !is_stuck and !attack.is_force_pause:
skill.on_attack_miss()
2 years ago
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
settle(hit_info)
2 years ago
func settle(hit_info:HitInfo) -> bool:
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 false
2 years ago
var cfg_from = character_from.cfg()
var cfg_to = character_to.cfg()
2 years ago
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
2 years ago
var attack = hit_info.attack
2 years ago
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
2 years ago
2 years ago
var is_break_shield = false
var is_break_stun = false
2 years ago
var is_block = false
2 years ago
var is_kill = false
2 years ago
var is_break_skill = false
2 years ago
var pause_time = attack.pause_time
2 years ago
2 years ago
#造成伤害
2 years ago
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")
2 years ago
has_shield = false
2 years ago
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
2 years ago
if is_kill:
character_to.add_buff("die",1)
2 years ago
#眩晕值累加
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:
2 years ago
is_stun = true
2 years ago
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)
2 years ago
2 years ago
#mp累加
character_from.add_mp(damage * cfg_from.mp.add_rate_attack)
2 years ago
character_from.remove_buff("mp_recover")
character_from.add_buff("mp_recover_cd",status.cfg.mp.recover_cd)
2 years ago
character_to.add_mp(damage * cfg_to.mp.add_rate_hit)
2 years ago
character_to.remove_buff("mp_recover")
character_to.add_buff("mp_recover_cd",status.cfg.mp.recover_cd)
2 years ago
2 years ago
#硬直等级
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()
2 years ago
#停止移动
character_to.move_stop()
2 years ago
#受击动画
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)
2 years ago
#浮空 击落 强制位移
var hit_up_speed = attack.hit_up_speed
var hit_back_speed = attack.hit_back_speed
2 years ago
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)
if hit_back_limit_curve:
var dir = character_from.pos2D() - character_to.pos2D()
var dist = clamp(dir.length(),0,1)
hit_back_speed = max(hit_back_limit_curve.sample(dist),hit_back_speed)
character_to.set_hit_move(hit_info.dir,hit_back_speed,hit_up_speed)
2 years ago
character_to.add_buff("hit_back",attack.hit_back_duration)
character_to.add_buff("hit_up",attack.hit_up_duration)
2 years ago
2 years ago
#受击特效
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)
2 years ago
2 years ago
#抖动
2 years ago
character_to.add_buff("shake_x",0.2,true)
#闪白
character_to.add_buff("flash_white",0.1)
2 years ago
#卡帧
2 years ago
character_from.set_pause_time(pause_time)
character_to.set_pause_time(pause_time)
2 years ago
#全局特效
2 years ago
Global.camera_mgr.effect(pause_time)
2 years ago
#伤害跳字
character_to.show_hit_damage(damage)
2 years ago
2 years ago
#状态跳字
2 years ago
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")
return true
2 years ago
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)
2 years ago
else:
character.set_status("mp_sub",mp_sub_max)
2 years ago
character.remove_buff("mp_recover_cd")
character.remove_buff("mp_recover")
2 years ago
else:
character.set_status("mp_sub",mp_sub+value)
func check_ground():
skill.on_check_ground()