|
|
|
@ -2,6 +2,7 @@ extends Node3D
|
|
|
|
class_name Battle
|
|
|
|
class_name Battle
|
|
|
|
|
|
|
|
|
|
|
|
@export var hit_back_limit_curve: Curve
|
|
|
|
@export var hit_back_limit_curve: Curve
|
|
|
|
|
|
|
|
@export var pause_time_limit_curve: Curve
|
|
|
|
|
|
|
|
|
|
|
|
@onready var character: Character = (get_owner() as Character)
|
|
|
|
@onready var character: Character = (get_owner() as Character)
|
|
|
|
@onready var status: Status = (%Status as Status)
|
|
|
|
@onready var status: Status = (%Status as Status)
|
|
|
|
@ -64,9 +65,16 @@ func add_attack(attack: AttackCfg, attack_box: AttackBoxCfg, hit_self: bool = fa
|
|
|
|
var offset: Vector3 = Vector3(offset_xz.x, offset_y, offset_xz.y)
|
|
|
|
var offset: Vector3 = Vector3(offset_xz.x, offset_y, offset_xz.y)
|
|
|
|
var shape: Shape3D = attack_box.shape
|
|
|
|
var shape: Shape3D = attack_box.shape
|
|
|
|
if not shape:
|
|
|
|
if not shape:
|
|
|
|
print("无效形状:",attack_box.get_res_name())
|
|
|
|
print("无效形状:", attack_box.get_res_name())
|
|
|
|
_debug_draw_attack_box(shape, offset)
|
|
|
|
_debug_draw_attack_box(shape, offset)
|
|
|
|
result = Util.raycast_character(shape, pos+offset, attack_dir)
|
|
|
|
result = Util.raycast_character(shape, pos+offset, attack_dir)
|
|
|
|
|
|
|
|
#result按break_level_def排序 确保硬直最高的最后结算
|
|
|
|
|
|
|
|
result.sort_custom(
|
|
|
|
|
|
|
|
func(a: Character, b: Character):
|
|
|
|
|
|
|
|
if a == null: return true
|
|
|
|
|
|
|
|
if b == null: return false
|
|
|
|
|
|
|
|
return a.get_break_level_def() < b.get_break_level_def()
|
|
|
|
|
|
|
|
)
|
|
|
|
var is_hit: bool = false
|
|
|
|
var is_hit: bool = false
|
|
|
|
for target: Character in result:
|
|
|
|
for target: Character in result:
|
|
|
|
if target == null:
|
|
|
|
if target == null:
|
|
|
|
@ -105,14 +113,18 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
var cfg_from: CharacterCfg = character_from.cfg()
|
|
|
|
var cfg_from: CharacterCfg = character_from.cfg()
|
|
|
|
var cfg_to: CharacterCfg = character_to.cfg()
|
|
|
|
var cfg_to: CharacterCfg = character_to.cfg()
|
|
|
|
|
|
|
|
|
|
|
|
var is_dead = character_to.get_status("is_dead")
|
|
|
|
var is_dead = character_to.get_status("is_dead")
|
|
|
|
var is_stun = character_to.get_status("is_stun")
|
|
|
|
var is_stun = character_to.get_status("is_stun")
|
|
|
|
var hp = character_to.get_status("hp")
|
|
|
|
var hp = character_to.get_status("hp")
|
|
|
|
var shield = character_to.get_status("shield")
|
|
|
|
var shield = character_to.get_status("shield")
|
|
|
|
var has_shield = shield > 0
|
|
|
|
var has_shield: bool = shield > 0
|
|
|
|
|
|
|
|
var is_stagger: bool = character_to.has_buff("stagger")
|
|
|
|
|
|
|
|
var is_on_floor: bool = character_to.get_status("is_on_floor")
|
|
|
|
|
|
|
|
var is_self_on_floor: bool = character_from.get_status("is_on_floor")
|
|
|
|
|
|
|
|
|
|
|
|
var is_floating: bool = attack.is_floating or not character_to.get_status("is_on_floor")
|
|
|
|
var is_floating: bool = attack.is_floating or not is_on_floor
|
|
|
|
var is_rebound: bool = attack.is_rebound and (character_from == character_to)
|
|
|
|
var is_rebound: bool = attack.is_rebound and (character_from == character_to)
|
|
|
|
|
|
|
|
var is_bullet: bool = int(character_from.cfg().type) == Enum.ECharacterType.Bullet
|
|
|
|
|
|
|
|
|
|
|
|
var is_break_shield: bool = false
|
|
|
|
var is_break_shield: bool = false
|
|
|
|
var is_break_stun: bool = false
|
|
|
|
var is_break_stun: bool = false
|
|
|
|
@ -120,18 +132,15 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
var is_kill: bool = false
|
|
|
|
var is_kill: bool = false
|
|
|
|
var is_break_skill: bool = false
|
|
|
|
var is_break_skill: bool = false
|
|
|
|
var is_break_skill_real: 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 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
|
|
|
|
var break_level_def: int = character_to.get_break_level_def()
|
|
|
|
break_level_def += character_to.get_status("skill_break_level_add")
|
|
|
|
|
|
|
|
var break_level_sub: int = clampi(attack.break_level - break_level_def, -1, 3)
|
|
|
|
var break_level_sub: int = clampi(attack.break_level - break_level_def, -1, 3)
|
|
|
|
is_break_skill_real = break_level_sub > 0
|
|
|
|
is_break_skill_real = break_level_sub > 0
|
|
|
|
is_break_skill = is_break_skill_real or not character_to.get_status("is_on_floor")
|
|
|
|
is_break_skill = is_break_skill_real or not is_on_floor
|
|
|
|
#硬直等级伤害修正
|
|
|
|
#硬直等级伤害修正
|
|
|
|
if break_level_sub == -1:
|
|
|
|
if break_level_sub == -1:
|
|
|
|
damage = 0
|
|
|
|
damage = 0
|
|
|
|
@ -139,6 +148,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
damage *= 0.5
|
|
|
|
damage *= 0.5
|
|
|
|
|
|
|
|
|
|
|
|
is_floating = is_break_skill and is_floating
|
|
|
|
is_floating = is_break_skill and is_floating
|
|
|
|
|
|
|
|
is_block = not is_break_skill
|
|
|
|
|
|
|
|
|
|
|
|
#造成伤害
|
|
|
|
#造成伤害
|
|
|
|
if has_shield:
|
|
|
|
if has_shield:
|
|
|
|
@ -159,13 +169,21 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
if is_kill:
|
|
|
|
if is_kill:
|
|
|
|
character_to.add_buff("die", 1)
|
|
|
|
character_to.add_buff("die", 1)
|
|
|
|
|
|
|
|
|
|
|
|
#破盾、格挡、击杀修正
|
|
|
|
#卡帧时间计算
|
|
|
|
if break_level_sub < 0:
|
|
|
|
var pause_time: float
|
|
|
|
pause_time = 0.1
|
|
|
|
if is_break_skill:
|
|
|
|
break_level_sub = 0
|
|
|
|
var break_level_sum_rate: float
|
|
|
|
elif break_level_sub == 0:
|
|
|
|
if is_stagger:
|
|
|
|
|
|
|
|
break_level_sum_rate = attack.break_level / 4.0
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
break_level_sum_rate = (attack.break_level + break_level_def) / 4.0
|
|
|
|
|
|
|
|
pause_time = pause_time_limit_curve.sample(break_level_sum_rate)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#格挡 破盾以及击杀具有固定值
|
|
|
|
|
|
|
|
if is_block:
|
|
|
|
pause_time = 0.05
|
|
|
|
pause_time = 0.05
|
|
|
|
if is_break_shield:
|
|
|
|
break_level_sub = 0
|
|
|
|
|
|
|
|
elif is_break_shield:
|
|
|
|
pause_time = 0.2
|
|
|
|
pause_time = 0.2
|
|
|
|
break_level_sub = 2
|
|
|
|
break_level_sub = 2
|
|
|
|
elif is_kill:
|
|
|
|
elif is_kill:
|
|
|
|
@ -213,6 +231,12 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
character_to.set_status("is_be_throw", false)
|
|
|
|
character_to.set_status("is_be_throw", false)
|
|
|
|
status.throw_target = 0
|
|
|
|
status.throw_target = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#碰撞距离计算
|
|
|
|
|
|
|
|
var character_dir: Vector2 = character_to.pos2D() - character_from.pos2D()
|
|
|
|
|
|
|
|
var dist: float = character_dir.length()
|
|
|
|
|
|
|
|
var radius_sum: float = character_from.radius() + character_to.radius()
|
|
|
|
|
|
|
|
var dist_rate: float = clamp(dist / radius_sum, 0, 1)
|
|
|
|
|
|
|
|
|
|
|
|
if is_break_skill:
|
|
|
|
if is_break_skill:
|
|
|
|
#取消技能
|
|
|
|
#取消技能
|
|
|
|
if character_to.get_status("is_skill_running"):
|
|
|
|
if character_to.get_status("is_skill_running"):
|
|
|
|
@ -231,9 +255,10 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
elif break_level_sub == 1: trigger_hit="hit"
|
|
|
|
elif break_level_sub == 1: trigger_hit="hit"
|
|
|
|
character_to.set_view_trigger(trigger_hit)
|
|
|
|
character_to.set_view_trigger(trigger_hit)
|
|
|
|
|
|
|
|
|
|
|
|
#浮空 击落 强制位移
|
|
|
|
|
|
|
|
var hit_up_speed: float = attack.hit_up_speed
|
|
|
|
var hit_up_speed: float = attack.hit_up_speed
|
|
|
|
var hit_back_speed: float = attack.hit_back_speed
|
|
|
|
var hit_back_speed: float = attack.hit_back_speed
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#浮空 击落 强制位移
|
|
|
|
if is_floating:
|
|
|
|
if is_floating:
|
|
|
|
character_to.add_buff("stagger", -1)
|
|
|
|
character_to.add_buff("stagger", -1)
|
|
|
|
character_to.add_buff("floating", -1)
|
|
|
|
character_to.add_buff("floating", -1)
|
|
|
|
@ -246,9 +271,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
3: character_to.add_buff("stagger", 0.9)
|
|
|
|
3: character_to.add_buff("stagger", 0.9)
|
|
|
|
hit_up_speed = 0
|
|
|
|
hit_up_speed = 0
|
|
|
|
if hit_back_limit_curve:
|
|
|
|
if hit_back_limit_curve:
|
|
|
|
var character_dir: Vector2 = character_from.pos2D() - character_to.pos2D()
|
|
|
|
hit_back_speed = max(hit_back_limit_curve.sample(dist_rate), hit_back_speed)
|
|
|
|
var dist = clamp(character_dir.length(), 0, 1)
|
|
|
|
|
|
|
|
hit_back_speed = max(hit_back_limit_curve.sample(dist), hit_back_speed)
|
|
|
|
|
|
|
|
if not is_break_skill_real:
|
|
|
|
if not is_break_skill_real:
|
|
|
|
hit_up_speed *= 0.75
|
|
|
|
hit_up_speed *= 0.75
|
|
|
|
|
|
|
|
|
|
|
|
@ -261,6 +284,15 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
character_from.move_stop()
|
|
|
|
character_from.move_stop()
|
|
|
|
character_from.set_status("skill_move_stop", true)
|
|
|
|
character_from.set_status("skill_move_stop", true)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#攻击到不可移动的物体 造成自身后退
|
|
|
|
|
|
|
|
var is_against_wall: bool = character_to.move_tick(pause_time)
|
|
|
|
|
|
|
|
if is_self_on_floor and not is_bullet and (is_against_wall or not is_break_skill):
|
|
|
|
|
|
|
|
var self_hit_back_speed = max(hit_back_limit_curve.sample(dist_rate), 2)
|
|
|
|
|
|
|
|
character_from.move_stop()
|
|
|
|
|
|
|
|
character_from.set_status("skill_move_stop", true)
|
|
|
|
|
|
|
|
character_from.set_hit_move(-dir, self_hit_back_speed, 0)
|
|
|
|
|
|
|
|
character_from.add_buff("hit_back", attack.hit_up_duration)
|
|
|
|
|
|
|
|
|
|
|
|
#受击pt掉落
|
|
|
|
#受击pt掉落
|
|
|
|
if damage>0:
|
|
|
|
if damage>0:
|
|
|
|
if is_kill || is_break_shield:
|
|
|
|
if is_kill || is_break_shield:
|
|
|
|
@ -300,17 +332,18 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult:
|
|
|
|
_: pass
|
|
|
|
_: pass
|
|
|
|
|
|
|
|
|
|
|
|
#抖动
|
|
|
|
#抖动
|
|
|
|
character_to.add_buff("shake_x", 0.2, true)
|
|
|
|
if is_block:
|
|
|
|
|
|
|
|
character_from.add_buff("shake_x", 0.2, true)
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
character_to.add_buff("shake_x", 0.2, true)
|
|
|
|
|
|
|
|
|
|
|
|
#闪白
|
|
|
|
#闪白
|
|
|
|
character_to.add_buff("flash_white", 0.04)
|
|
|
|
character_to.add_buff("flash_white", 0.04)
|
|
|
|
|
|
|
|
|
|
|
|
#卡帧
|
|
|
|
#卡帧
|
|
|
|
pause_time *= 0.6
|
|
|
|
|
|
|
|
if not is_bullet:
|
|
|
|
if not is_bullet:
|
|
|
|
character_from.set_pause_time(pause_time)
|
|
|
|
character_from.set_pause_time(pause_time)
|
|
|
|
character_to.set_pause_time(pause_time)
|
|
|
|
character_to.set_pause_time(pause_time)
|
|
|
|
character_to.move_tick(pause_time)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#全局特效
|
|
|
|
#全局特效
|
|
|
|
var has_global_effect: bool = character_from.is_player() or character_to.is_player()
|
|
|
|
var has_global_effect: bool = character_from.is_player() or character_to.is_player()
|
|
|
|
@ -375,11 +408,13 @@ func cost_mp(value: int):
|
|
|
|
character.remove_buff("mp_recover")
|
|
|
|
character.remove_buff("mp_recover")
|
|
|
|
character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd)
|
|
|
|
character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func cost_mp_sub():
|
|
|
|
func cost_mp_sub():
|
|
|
|
character.set_status("mp_sub", 0)
|
|
|
|
character.set_status("mp_sub", 0)
|
|
|
|
character.remove_buff("mp_recover")
|
|
|
|
character.remove_buff("mp_recover")
|
|
|
|
character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd)
|
|
|
|
character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func check_ground(): skill.on_check_ground(0)
|
|
|
|
func check_ground(): skill.on_check_ground(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -403,6 +438,7 @@ func cast_sub_character(): skill.on_cast_sub_character()
|
|
|
|
|
|
|
|
|
|
|
|
func hold(): skill.on_hold()
|
|
|
|
func hold(): skill.on_hold()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
func stop():
|
|
|
|
func stop():
|
|
|
|
move.stop()
|
|
|
|
move.stop()
|
|
|
|
|
|
|
|
|
|
|
|
|