diff --git a/config/skill_player_weapon/hero01_long_attack03.tres b/config/skill_player_weapon/hero01_long_attack03.tres index 42f1ea7..6e268f0 100644 --- a/config/skill_player_weapon/hero01_long_attack03.tres +++ b/config/skill_player_weapon/hero01_long_attack03.tres @@ -1,6 +1,5 @@ -[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=8 format=3 uid="uid://5ufjc1dso0y8"] +[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=7 format=3 uid="uid://5ufjc1dso0y8"] -[ext_resource type="Resource" uid="uid://btg40rn2f36c2" path="res://config/attack/sharp_normal_hit_back.tres" id="1_7ai5j"] [ext_resource type="Resource" uid="uid://d3mcp8sf6qbmd" path="res://config/attack/sharp_normal_hit.tres" id="1_rgi7a"] [ext_resource type="Script" path="res://script/config/skill_weapon_cfg.gd" id="1_uaib7"] [ext_resource type="Resource" uid="uid://cy3wwalxeyro0" path="res://config/weapon/long.tres" id="2_8uqiw"] @@ -19,7 +18,7 @@ free_lock = false ignore_push = false attack1 = ExtResource("1_rgi7a") attack1_box = ExtResource("2_j0l20") -attack2 = ExtResource("1_7ai5j") +attack2 = ExtResource("1_rgi7a") attack2_box = ExtResource("2_j0l20") stance_from = 2 stance_to = 3 diff --git a/scene/character/character.tscn b/scene/character/character.tscn index b9111e3..dbd168d 100644 --- a/scene/character/character.tscn +++ b/scene/character/character.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=26 format=3 uid="uid://8rcvw1vnjcf7"] +[gd_scene load_steps=27 format=3 uid="uid://8rcvw1vnjcf7"] [ext_resource type="Script" path="res://script/character/character.gd" id="1_tonbs"] [ext_resource type="Script" path="res://script/character/hitbox.gd" id="2_6xf87"] @@ -74,9 +74,16 @@ _data = { } [sub_resource type="Curve" id="Curve_e7j3f"] -max_value = 6.0 -_data = [Vector2(0, 6), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] +max_value = 4.0 +_data = [Vector2(0, 4), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0] point_count = 2 +metadata/_snap_enabled = true + +[sub_resource type="Curve" id="Curve_55xfs"] +max_value = 0.3 +_data = [Vector2(0, 0), 0.0, 0.0, 0, 0, Vector2(0.5, 0.09), 0.555563, 0.555563, 0, 0, Vector2(1, 0.3), 2.8841e-07, 0.0, 0, 0] +point_count = 3 +metadata/_snap_enabled = true [node name="Character" type="CharacterBody3D"] collision_layer = 2 @@ -138,6 +145,7 @@ script = ExtResource("9_jlnhy") unique_name_in_owner = true script = ExtResource("8_w84sf") hit_back_limit_curve = SubResource("Curve_e7j3f") +pause_time_limit_curve = SubResource("Curve_55xfs") [node name="Effect" type="Node3D" parent="."] unique_name_in_owner = true diff --git a/script/character/battle.gd b/script/character/battle.gd index de878e1..2aec448 100644 --- a/script/character/battle.gd +++ b/script/character/battle.gd @@ -2,6 +2,7 @@ extends Node3D class_name Battle @export var hit_back_limit_curve: Curve +@export var pause_time_limit_curve: Curve @onready var character: Character = (get_owner() as Character) @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 shape: Shape3D = attack_box.shape if not shape: - print("无效形状:",attack_box.get_res_name()) + print("无效形状:", attack_box.get_res_name()) _debug_draw_attack_box(shape, offset) 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 for target: Character in result: 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_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 hp = character_to.get_status("hp") 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_bullet: bool = int(character_from.cfg().type) == Enum.ECharacterType.Bullet var is_break_shield: 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_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_def: int = character_to.get_break_level_def() 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 = 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: damage = 0 @@ -139,6 +148,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult: damage *= 0.5 is_floating = is_break_skill and is_floating + is_block = not is_break_skill #造成伤害 if has_shield: @@ -159,13 +169,21 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult: if is_kill: character_to.add_buff("die", 1) - #破盾、格挡、击杀修正 - if break_level_sub < 0: - pause_time = 0.1 - break_level_sub = 0 - elif break_level_sub == 0: + #卡帧时间计算 + var pause_time: float + if is_break_skill: + var break_level_sum_rate: float + 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 - if is_break_shield: + break_level_sub = 0 + elif is_break_shield: pause_time = 0.2 break_level_sub = 2 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) 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 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" 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) @@ -246,9 +271,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult: 3: character_to.add_buff("stagger", 0.9) 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) + hit_back_speed = max(hit_back_limit_curve.sample(dist_rate), hit_back_speed) if not is_break_skill_real: 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.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掉落 if damage>0: if is_kill || is_break_shield: @@ -300,17 +332,18 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg) -> HitResult: _: 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) #卡帧 - pause_time *= 0.6 if not is_bullet: character_from.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() @@ -375,11 +408,13 @@ func cost_mp(value: int): character.remove_buff("mp_recover") character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd) + func cost_mp_sub(): character.set_status("mp_sub", 0) character.remove_buff("mp_recover") character.add_buff("mp_recover_cd", status.cfg.mp.recover_cd) + 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 stop(): move.stop() diff --git a/script/character/character.gd b/script/character/character.gd index 26adfce..a484a69 100644 --- a/script/character/character.gd +++ b/script/character/character.gd @@ -138,8 +138,8 @@ func move_stop(): set_status("move_dir", Vector2.ZERO) move.stop() -func move_tick(delta): - move.move_tick(delta) +func move_tick(delta) -> bool: + return move.move_tick(delta) func get_face_dir() -> Vector2: if status.move_dir == Vector2.ZERO: @@ -202,6 +202,11 @@ func cost_mp(value: int): func cost_mp_sub(): battle.cost_mp_sub() +func get_break_level_def() -> int: + var shield: float = get_status("shield") + var break_level_def: int = cfg().shield.break_level_on if shield > 0 else cfg().shield.break_level_off + break_level_def += get_status("skill_break_level_add") + return break_level_def func set_effect_lock(value: bool): effect.set_effect_lock(value) diff --git a/script/character/move.gd b/script/character/move.gd index fe480ad..9661c62 100644 --- a/script/character/move.gd +++ b/script/character/move.gd @@ -23,11 +23,11 @@ func _process(delta) -> void: return -func move_tick(delta) -> void: +func move_tick(delta) -> bool: var is_hit_floor: bool = update_on_floor(delta) update_move(delta) update_speed_y(delta) - update_move_check(delta) + var is_against_wall: bool = update_move_check(delta) status.velocity_change = character.velocity.abs() - velocity_cache velocity_cache = character.velocity.abs() if character.velocity: @@ -38,7 +38,7 @@ func move_tick(delta) -> void: SignalManager.character_hit_floor.emit(character.id(), character.pos()) update_deformation(delta) update_move_effect(delta) - return + return is_against_wall func update_on_floor(delta) -> bool: @@ -116,7 +116,7 @@ func update_move_effect(delta): Global.effect_mgr.cast_particle(ResourceManager.particle_move_dash, character.view_pos(), character.velocity.normalized()) -func update_move_check(delta): +func update_move_check(delta) -> bool: var velocity: Vector3 = character.velocity character.move_and_slide() if status.is_stagger: @@ -140,6 +140,9 @@ func update_move_check(delta): Global.effect_mgr.cast_particle(ResourceManager.particle_hit_ground_normal, character.pos(), normal) character.velocity = velocity - normal * normal_speed * 1.5 character.add_buff("floating", -1) + if normal.y == 0: + return true + return false func jump(): diff --git a/script/config/attack_cfg.gd b/script/config/attack_cfg.gd index ac09462..d581bfa 100644 --- a/script/config/attack_cfg.gd +++ b/script/config/attack_cfg.gd @@ -18,5 +18,4 @@ class_name AttackCfg @export var hit_back_duration: float = 0.05 #击退持续时间 @export var hit_up_duration: float = 0.05 #击飞持续时间 @export_group("卡帧") -@export var pause_time: float #卡帧时间 @export var is_force_pause: bool #是否强制卡帧