From 9753cac24d7a43ea96d28b40409f5685309ac66e Mon Sep 17 00:00:00 2001 From: chendian <-> Date: Sat, 25 Jan 2025 02:27:40 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=8A=80=E8=83=BD=E5=91=BD?= =?UTF-8?q?=E4=B8=AD=20=E4=BB=8E=E5=8D=95=E5=B8=A7=E6=A3=80=E6=B5=8B?= =?UTF-8?q?=E6=94=B9=E4=B8=BA=E6=8C=81=E7=BB=AD=E6=A3=80=E6=B5=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- addons/beehave/nodes/composites/sequence.gd | 98 +++++----- addons/editor_menu_tools/editor_menu_tools.gd | 49 +++-- config/attack_box/circle_normal_thin.tres | 2 +- config/attack_box/rebound.tres | 15 ++ .../character/bullet_hero01_short_stab01.tres | 29 +++ ...t02.tres => bullet_hero01_soul_hit01.tres} | 0 config/skill_core/hero01_remote01.tres | 4 +- .../hero01_basic_air_flash_back.tres | 25 --- .../hero01_basic_flash_back.tres | 26 --- .../hero01_long_stab01.tres | 19 +- .../hero01_long_stab02.tres | 36 ++++ .../hero01_short_skill01.tres | 32 ++++ .../hero01_short_stab01.tres | 38 ++++ project.godot | 6 + .../character/hero01_long_skill03.aseprite | Bin 5392 -> 9194 bytes .../animation/character/hero01_move.aseprite | Bin 35488 -> 35479 bytes resource/animation/character/hero01_move.png | Bin 24470 -> 24472 bytes .../character/hero01_short_skill01.aseprite | Bin 10969 -> 11316 bytes .../character/hero01_short_skill01.png | Bin 8808 -> 5971 bytes .../character/hero01_short_skill03.aseprite | Bin 0 -> 9196 bytes .../hero01_short_skill03.aseprite.import | 25 +++ .../character/hero01_short_skill03.png | Bin 0 -> 2854 bytes .../character/hero01_short_skill03.png.import | 34 ++++ .../hero01_basic_air_flash.tres | 12 +- .../skill_animation/hero01_long_stab02.tres | 95 ++++++++++ .../hero01_short_attack03.tres | 14 +- .../skill_animation/hero01_short_skill01.tres | 82 +++++++++ .../skill_animation/hero01_short_stab01.tres | 95 ++++++++++ .../animation_library.tres | 8 +- scene/ai/bullet01.tscn | 86 --------- scene/ai/bullet02.tscn | 23 --- scene/ai/bullet_simple.tscn | 24 +++ scene/ai/bullet_simple_penetrat.tscn | 20 +++ scene/character/character.tscn | 42 ++++- .../particle/bullet_hero01_short_stab01.tscn | 12 ++ script/_global/struct.gd | 15 ++ script/_global/util.gd | 2 - script/ai/action/action_attack1.gd | 7 +- script/ai/action/action_attack2.gd | 7 +- script/ai/action/action_destroy.gd | 2 +- script/character/battle.gd | 168 ++++++++---------- script/character/battle_attack_area.gd | 57 ++++++ script/character/battle_attack_area.gd.uid | 1 + script/character/character.gd | 8 +- script/character/move.gd | 10 +- script/character/player/combo.gd | 2 +- script/character/skill.gd | 23 ++- script/character/status.gd | 6 +- script/config/attack_box_cfg.gd | 1 + script/config/character_cfg.gd | 13 +- script/config/skill_cfg.gd | 2 - script/editor_tool/editor_tool.gd | 4 - script/manager/resource_manager.gd | 2 +- 53 files changed, 900 insertions(+), 381 deletions(-) create mode 100644 config/attack_box/rebound.tres create mode 100644 config/character/bullet_hero01_short_stab01.tres rename config/character/{bullet02.tres => bullet_hero01_soul_hit01.tres} (100%) delete mode 100644 config/skill_player_basic/hero01_basic_air_flash_back.tres delete mode 100644 config/skill_player_basic/hero01_basic_flash_back.tres create mode 100644 config/skill_player_weapon/hero01_long_stab02.tres create mode 100644 config/skill_player_weapon/hero01_short_skill01.tres create mode 100644 config/skill_player_weapon/hero01_short_stab01.tres create mode 100644 resource/animation/character/hero01_short_skill03.aseprite create mode 100644 resource/animation/character/hero01_short_skill03.aseprite.import create mode 100644 resource/animation/character/hero01_short_skill03.png create mode 100644 resource/animation/character/hero01_short_skill03.png.import create mode 100644 resource/skill_animation/hero01_long_stab02.tres create mode 100644 resource/skill_animation/hero01_short_skill01.tres create mode 100644 resource/skill_animation/hero01_short_stab01.tres delete mode 100644 scene/ai/bullet01.tscn delete mode 100644 scene/ai/bullet02.tscn create mode 100644 scene/ai/bullet_simple.tscn create mode 100644 scene/ai/bullet_simple_penetrat.tscn create mode 100644 scene/effect/particle/bullet_hero01_short_stab01.tscn create mode 100644 script/_global/struct.gd create mode 100644 script/character/battle_attack_area.gd create mode 100644 script/character/battle_attack_area.gd.uid diff --git a/addons/beehave/nodes/composites/sequence.gd b/addons/beehave/nodes/composites/sequence.gd index ec3ab82..11b5d79 100644 --- a/addons/beehave/nodes/composites/sequence.gd +++ b/addons/beehave/nodes/composites/sequence.gd @@ -12,65 +12,65 @@ var successful_index: int = 0 func tick(actor: Node, blackboard: Blackboard) -> int: - for c in get_children(): - - if c.get_index() < successful_index: - continue - - if c != running_child: - c.before_run(actor, blackboard) - - var response = c.tick(actor, blackboard) - if can_send_message(blackboard): - BeehaveDebuggerMessages.process_tick(c.get_instance_id(), response) - - if c is ConditionLeaf: - blackboard.set_value("last_condition", c, str(actor.get_instance_id())) - blackboard.set_value("last_condition_status", response, str(actor.get_instance_id())) - - match response: - SUCCESS: - _cleanup_running_task(c, actor, blackboard) - successful_index += 1 - c.after_run(actor, blackboard) - FAILURE: - _cleanup_running_task(c, actor, blackboard) - # Interrupt any child that was RUNNING before. - interrupt(actor, blackboard) - c.after_run(actor, blackboard) - return FAILURE - RUNNING: - if c != running_child: - if running_child != null: - running_child.interrupt(actor, blackboard) - running_child = c - if c is ActionLeaf: - blackboard.set_value("running_action", c, str(actor.get_instance_id())) - return RUNNING - - _reset() - return SUCCESS + for c in get_children(): + + if c.get_index() < successful_index: + continue + + if c != running_child: + c.before_run(actor, blackboard) + + var response = c.tick(actor, blackboard) + if can_send_message(blackboard): + BeehaveDebuggerMessages.process_tick(c.get_instance_id(), response) + + if c is ConditionLeaf: + blackboard.set_value("last_condition", c, str(actor.get_instance_id())) + blackboard.set_value("last_condition_status", response, str(actor.get_instance_id())) + + match response: + SUCCESS: + _cleanup_running_task(c, actor, blackboard) + successful_index += 1 + c.after_run(actor, blackboard) + FAILURE: + _cleanup_running_task(c, actor, blackboard) + # Interrupt any child that was RUNNING before. + interrupt(actor, blackboard) + c.after_run(actor, blackboard) + return FAILURE + RUNNING: + if c != running_child: + if running_child != null: + running_child.interrupt(actor, blackboard) + running_child = c + if c is ActionLeaf: + blackboard.set_value("running_action", c, str(actor.get_instance_id())) + return RUNNING + + _reset() + return SUCCESS func interrupt(actor: Node, blackboard: Blackboard) -> void: - _reset() - super(actor, blackboard) + _reset() + super(actor, blackboard) func _reset() -> void: - successful_index = 0 + successful_index = 0 ## Changes `running_action` and `running_child` after the node finishes executing. func _cleanup_running_task(finished_action: Node, actor: Node, blackboard: Blackboard): - var blackboard_name = str(actor.get_instance_id()) - if finished_action == running_child: - running_child = null - if finished_action == blackboard.get_value("running_action", null, blackboard_name): - blackboard.set_value("running_action", null, blackboard_name) + var blackboard_name = str(actor.get_instance_id()) + if finished_action == running_child: + running_child = null + if finished_action == blackboard.get_value("running_action", null, blackboard_name): + blackboard.set_value("running_action", null, blackboard_name) func get_class_name() -> Array[StringName]: - var classes := super() - classes.push_back(&"SequenceComposite") - return classes + var classes := super() + classes.push_back(&"SequenceComposite") + return classes diff --git a/addons/editor_menu_tools/editor_menu_tools.gd b/addons/editor_menu_tools/editor_menu_tools.gd index 1dddb12..a2104f5 100644 --- a/addons/editor_menu_tools/editor_menu_tools.gd +++ b/addons/editor_menu_tools/editor_menu_tools.gd @@ -1,10 +1,12 @@ @tool extends EditorPlugin -var selected_skill_file: String +var menu_parent: Node var skill_popup: PopupMenu +var short_cut_popup: PopupMenu var skill_cfg_list: Array[SkillCfg] -var menu_parent: Node +var short_cut_path_list: Array[String] +var selected_skill_file: String func _enter_tree(): @@ -12,14 +14,32 @@ func _enter_tree(): while root.get_parent() != null: root = root.get_parent() menu_parent = root.get_child(0).get_child(4).get_child(0).get_child(0).get_child(0) - if menu_parent: - skill_popup = PopupMenu.new() - skill_popup.name = "技能配置" - skill_popup.about_to_popup.connect(skill_popup_about_to_popup) - skill_popup.index_pressed.connect(skill_popup_index_pressed) - menu_parent.add_child(skill_popup) - else: + if not menu_parent: print("menu_parent is null") + return + + ## 技能配置 + skill_popup = PopupMenu.new() + skill_popup.name = "技能配置" + menu_parent.add_child(skill_popup) + skill_popup.about_to_popup.connect(skill_popup_about_to_popup) + skill_popup.index_pressed.connect(skill_popup_index_pressed) + + ## 快捷方式 + short_cut_popup = PopupMenu.new() + short_cut_popup.name = "快捷方式" + menu_parent.add_child(short_cut_popup) + short_cut_popup.index_pressed.connect(short_cut_index_pressed) + + add_short_cut("配置-角色", "res://config/character") + add_short_cut("配置-武器技能", "res://config/skill_player_weapon") + add_short_cut("资产-技能特效", "res://scene/effect/particle") + add_short_cut("资产-AI", "res://scene/ai") + + +func add_short_cut(target_name: String, path: String): + short_cut_popup.add_item(target_name) + short_cut_path_list.append(path) func skill_popup_about_to_popup(): @@ -34,6 +54,10 @@ func skill_popup_index_pressed(index: int): EditorInterface.select_file(skill_cfg_list[index].resource_path) +func short_cut_index_pressed(index: int): + EditorInterface.select_file(short_cut_path_list[index]) + + func _process(delta: float) -> void: var selected_paths: PackedStringArray = EditorInterface.get_selected_paths() if len(selected_paths) != 1: @@ -55,12 +79,17 @@ func _process(delta: float) -> void: EditorInterface.open_scene_from_path("res://scene/character/character.tscn") var root: Node = EditorInterface.get_edited_scene_root() var character_skill: AnimationPlayer = root.find_child("Skill") as AnimationPlayer - EditorInterface.edit_node(character_skill) var animation_name: String = "animation_library/%s" % Util.get_resource_name(res) + if not character_skill.has_animation(animation_name): + print("技能动画不存在:", animation_name) + return + character_skill.current_animation = animation_name + EditorInterface.edit_node(character_skill) EditorInterface.edit_resource(res) func _exit_tree(): remove_tool_menu_item("Test") if skill_popup: skill_popup.queue_free() + if short_cut_popup: short_cut_popup.queue_free() diff --git a/config/attack_box/circle_normal_thin.tres b/config/attack_box/circle_normal_thin.tres index dad30f4..87c94c6 100644 --- a/config/attack_box/circle_normal_thin.tres +++ b/config/attack_box/circle_normal_thin.tres @@ -1,6 +1,6 @@ [gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://bhxq1uffxyda8"] -[ext_resource type="Script" path="res://script/config/attack_box_cfg.gd" id="1_gwkwy"] +[ext_resource type="Script" uid="uid://dekrsow0vntqs" path="res://script/config/attack_box_cfg.gd" id="1_gwkwy"] [sub_resource type="CylinderShape3D" id="CylinderShape3D_pmh6g"] height = 0.25 diff --git a/config/attack_box/rebound.tres b/config/attack_box/rebound.tres new file mode 100644 index 0000000..de2fc6a --- /dev/null +++ b/config/attack_box/rebound.tres @@ -0,0 +1,15 @@ +[gd_resource type="Resource" script_class="AttackBoxCfg" load_steps=3 format=3 uid="uid://df807k1y1vequ"] + +[ext_resource type="Script" uid="uid://dekrsow0vntqs" path="res://script/config/attack_box_cfg.gd" id="1_fstin"] + +[sub_resource type="CylinderShape3D" id="CylinderShape3D_pmh6g"] +height = 0.8 +radius = 0.25 + +[resource] +script = ExtResource("1_fstin") +shape = SubResource("CylinderShape3D_pmh6g") +offset = Vector2(0, 0) +is_throw = false +is_direct = false +is_hit_self = true diff --git a/config/character/bullet_hero01_short_stab01.tres b/config/character/bullet_hero01_short_stab01.tres new file mode 100644 index 0000000..82df9a5 --- /dev/null +++ b/config/character/bullet_hero01_short_stab01.tres @@ -0,0 +1,29 @@ +[gd_resource type="Resource" script_class="CharacterCfg" load_steps=9 format=3 uid="uid://cb4q16lmqwbin"] + +[ext_resource type="PackedScene" uid="uid://bei75ysjq2pi4" path="res://scene/ai/bullet_simple.tscn" id="1_3q8i1"] +[ext_resource type="Resource" uid="uid://ckbf40c75bfqf" path="res://config/attack/sharp_normal_hit_up.tres" id="2_m73qf"] +[ext_resource type="Resource" uid="uid://decgfcx2xsj8i" path="res://config/attack_box/circle_mid.tres" id="3_3q8i1"] +[ext_resource type="Resource" uid="uid://iv8g1x3bkxvv" path="res://config/character_move/fast_fly.tres" id="4_2bsgq"] +[ext_resource type="Resource" uid="uid://dpajmgrlaytah" path="res://config/character_mp/normal.tres" id="5_gsbwd"] +[ext_resource type="Script" uid="uid://dt3chi1tgnaef" path="res://script/config/character_cfg.gd" id="6_1ypqo"] +[ext_resource type="Resource" uid="uid://h1curvk64vm3" path="res://config/character_shield/none.tres" id="7_k8icm"] +[ext_resource type="Resource" uid="uid://5jes0p152akr" path="res://config/character_stun/none.tres" id="8_rojoo"] + +[resource] +script = ExtResource("6_1ypqo") +name = "hero01" +type = 2 +sprite_height = 26 +sprite_width = 16 +move = ExtResource("4_2bsgq") +shield = ExtResource("7_k8icm") +stun = ExtResource("8_rojoo") +mp = ExtResource("5_gsbwd") +ai_behavior_tree = ExtResource("1_3q8i1") +hp_max = 100.0 +attack = 1.0 +attack1 = ExtResource("2_m73qf") +attack1_box = ExtResource("3_3q8i1") +sub_character_auto_create = false +material_on = 0 +material_off = 0 diff --git a/config/character/bullet02.tres b/config/character/bullet_hero01_soul_hit01.tres similarity index 100% rename from config/character/bullet02.tres rename to config/character/bullet_hero01_soul_hit01.tres diff --git a/config/skill_core/hero01_remote01.tres b/config/skill_core/hero01_remote01.tres index e2c70c4..d90c5f3 100644 --- a/config/skill_core/hero01_remote01.tres +++ b/config/skill_core/hero01_remote01.tres @@ -1,9 +1,9 @@ [gd_resource type="Resource" script_class="SkillCfg" load_steps=5 format=3 uid="uid://cwvj0xsv61cjk"] -[ext_resource type="Script" path="res://script/config/skill_cfg.gd" id="1_doifq"] +[ext_resource type="Script" uid="uid://ch4gg7uuu2e2t" path="res://script/config/skill_cfg.gd" id="1_doifq"] [ext_resource type="Animation" uid="uid://h8hm3kbecdx8" path="res://resource/skill_animation/hero01_remote01.tres" id="2_h285p"] [ext_resource type="SpriteFrames" uid="uid://ce83cuqwgwwi4" path="res://resource/animation/character/hero01_long_attack.aseprite" id="3_w10pb"] -[ext_resource type="Resource" uid="uid://d3mafsovw1mko" path="res://config/character/bullet02.tres" id="4_3k3a4"] +[ext_resource type="Resource" uid="uid://d3mafsovw1mko" path="res://config/character/bullet_hero01_soul_hit01.tres" id="4_3k3a4"] [resource] script = ExtResource("1_doifq") diff --git a/config/skill_player_basic/hero01_basic_air_flash_back.tres b/config/skill_player_basic/hero01_basic_air_flash_back.tres deleted file mode 100644 index 9003ab4..0000000 --- a/config/skill_player_basic/hero01_basic_air_flash_back.tres +++ /dev/null @@ -1,25 +0,0 @@ -[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=4 format=3 uid="uid://djuch6s4ycecd"] - -[ext_resource type="Script" path="res://script/config/skill_weapon_cfg.gd" id="1_pv5y3"] -[ext_resource type="Animation" uid="uid://5gj6dy1eysha" path="res://resource/skill_animation/hero01_basic_air_flash_back.tres" id="2_o1a71"] -[ext_resource type="SpriteFrames" uid="uid://jpxh0jr8wp8g" path="res://resource/animation/character/hero01_basic.aseprite" id="3_ti2km"] - -[resource] -script = ExtResource("1_pv5y3") -action = "none" -name = "" -skill_animation = ExtResource("2_o1a71") -range = 0.0 -free_lock = true -ignore_push = true -stance_from = 101 -stance_to = 10 -break_level = 1 -is_charging = false -mp_cost = 0 -warn_type = 0 -with_stop = false -is_lock_x = null -refresh_animation = false -sprite_frames = ExtResource("3_ti2km") -animation_name = "basic_air_flash" diff --git a/config/skill_player_basic/hero01_basic_flash_back.tres b/config/skill_player_basic/hero01_basic_flash_back.tres deleted file mode 100644 index a1edfaa..0000000 --- a/config/skill_player_basic/hero01_basic_flash_back.tres +++ /dev/null @@ -1,26 +0,0 @@ -[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=4 format=3 uid="uid://copd3b35mo2vn"] - -[ext_resource type="Script" path="res://script/config/skill_weapon_cfg.gd" id="1_obmuu"] -[ext_resource type="Animation" uid="uid://bl2o7f7akp6if" path="res://resource/skill_animation/hero01_basic_flash_back.tres" id="2_cf3hj"] -[ext_resource type="SpriteFrames" uid="uid://jpxh0jr8wp8g" path="res://resource/animation/character/hero01_basic.aseprite" id="3_yxy1c"] - -[resource] -script = ExtResource("1_obmuu") -action = "none" -name = "" -skill_animation = ExtResource("2_cf3hj") -range = 0.0 -free_lock = true -ignore_push = true -stance_from = 100 -stance_to = 0 -break_level = 1 -is_charging = false -mp_cost = 0 -mp_sub_cost = false -warn_type = 0 -with_stop = false -is_lock_x = true -refresh_animation = false -sprite_frames = ExtResource("3_yxy1c") -animation_name = "basic_flash" diff --git a/config/skill_player_weapon/hero01_long_stab01.tres b/config/skill_player_weapon/hero01_long_stab01.tres index 7d6beb5..dd08815 100644 --- a/config/skill_player_weapon/hero01_long_stab01.tres +++ b/config/skill_player_weapon/hero01_long_stab01.tres @@ -10,28 +10,27 @@ [resource] script = ExtResource("3_0cjr8") weapon = ExtResource("6_un8sq") -action = "attack_heavy" +action = "attack_light" name = "" skill_animation = ExtResource("4_mjivf") -range = 0.0 -free_lock = false -ignore_push = true +stance_from = 30 +stance_to = 30 +break_level = 3 +is_charging = false attack1 = ExtResource("1_orvsj") attack1_box = ExtResource("2_332ws") attack1_with_pause_frame = false attack1_with_stop = false attack2_with_pause_frame = false attack2_with_stop = false -stance_from = 30 -stance_to = 30 -break_level = 3 -is_charging = false mp_cost = 0 mp_sub_cost = false -warn_type = 0 +free_lock = false +ignore_push = true with_stop = false is_lock_x = true is_lock_x_move = true -refresh_animation = false +range = 0.0 +warn_type = 0 sprite_frames = ExtResource("5_j4rp7") animation_name = "long_skill_stab01" diff --git a/config/skill_player_weapon/hero01_long_stab02.tres b/config/skill_player_weapon/hero01_long_stab02.tres new file mode 100644 index 0000000..2d1a303 --- /dev/null +++ b/config/skill_player_weapon/hero01_long_stab02.tres @@ -0,0 +1,36 @@ +[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=7 format=3 uid="uid://fnub06pyo2l8"] + +[ext_resource type="Resource" uid="uid://cw7rb4rlfw33q" path="res://config/attack/sharp_heavy_hit_back.tres" id="1_2k8jp"] +[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_1jdoh"] +[ext_resource type="Script" uid="uid://dgwtu2wj5033u" path="res://script/config/skill_weapon_cfg.gd" id="3_tbh7t"] +[ext_resource type="Animation" uid="uid://nhnwu6uccylr" path="res://resource/skill_animation/hero01_long_stab02.tres" id="4_2k8jp"] +[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="5_ys6gu"] +[ext_resource type="Resource" uid="uid://cy3wwalxeyro0" path="res://config/weapon/long.tres" id="6_3b28o"] + +[resource] +script = ExtResource("3_tbh7t") +weapon = ExtResource("6_3b28o") +action = "none" +name = "" +skill_animation = ExtResource("4_2k8jp") +stance_from = 99 +stance_to = 99 +break_level = 0 +is_charging = false +attack1 = ExtResource("1_2k8jp") +attack1_box = ExtResource("2_1jdoh") +attack1_with_pause_frame = false +attack1_with_stop = false +attack2_with_pause_frame = false +attack2_with_stop = false +mp_cost = 0 +mp_sub_cost = false +free_lock = false +ignore_push = true +with_stop = false +is_lock_x = true +is_lock_x_move = true +range = 0.0 +warn_type = 0 +sprite_frames = ExtResource("5_ys6gu") +animation_name = "long_skill_stab02" diff --git a/config/skill_player_weapon/hero01_short_skill01.tres b/config/skill_player_weapon/hero01_short_skill01.tres new file mode 100644 index 0000000..73d0ebe --- /dev/null +++ b/config/skill_player_weapon/hero01_short_skill01.tres @@ -0,0 +1,32 @@ +[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=5 format=3 uid="uid://cjp4q8uhiryjd"] + +[ext_resource type="Animation" uid="uid://qcmj7d5pg6lw" path="res://resource/skill_animation/hero01_short_skill01.tres" id="2_j0c0j"] +[ext_resource type="Script" uid="uid://dgwtu2wj5033u" path="res://script/config/skill_weapon_cfg.gd" id="3_0dcj8"] +[ext_resource type="SpriteFrames" uid="uid://dlmesk4xyydmd" path="res://resource/animation/character/hero01_short_skill03.aseprite" id="3_j0c0j"] +[ext_resource type="Resource" uid="uid://pnhii1a83axg" path="res://config/weapon/short.tres" id="6_7qlca"] + +[resource] +script = ExtResource("3_0dcj8") +weapon = ExtResource("6_7qlca") +action = "attack_heavy" +name = "" +skill_animation = ExtResource("2_j0c0j") +stance_from = 1 +stance_to = 30 +break_level = 3 +is_charging = false +attack1_with_pause_frame = false +attack1_with_stop = false +attack2_with_pause_frame = false +attack2_with_stop = false +mp_cost = 0 +mp_sub_cost = false +free_lock = false +ignore_push = false +with_stop = false +is_lock_x = true +is_lock_x_move = false +range = 0.0 +warn_type = 0 +sprite_frames = ExtResource("3_j0c0j") +animation_name = "short_skill_stab01" diff --git a/config/skill_player_weapon/hero01_short_stab01.tres b/config/skill_player_weapon/hero01_short_stab01.tres new file mode 100644 index 0000000..201956d --- /dev/null +++ b/config/skill_player_weapon/hero01_short_stab01.tres @@ -0,0 +1,38 @@ +[gd_resource type="Resource" script_class="SkillWeaponCfg" load_steps=8 format=3 uid="uid://ckmsp5bdyk3tx"] + +[ext_resource type="Resource" uid="uid://cuc04svaipss7" path="res://config/attack/sharp_normal_none.tres" id="1_5n6sn"] +[ext_resource type="Resource" uid="uid://diedb7vw7eyxp" path="res://config/attack_box/box_mid.tres" id="2_67ngl"] +[ext_resource type="Script" uid="uid://dgwtu2wj5033u" path="res://script/config/skill_weapon_cfg.gd" id="3_cub6b"] +[ext_resource type="Animation" uid="uid://b3fuombjh57oj" path="res://resource/skill_animation/hero01_short_stab01.tres" id="4_67ngl"] +[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="5_kk2vu"] +[ext_resource type="Resource" uid="uid://pnhii1a83axg" path="res://config/weapon/short.tres" id="6_5n6sn"] +[ext_resource type="Resource" uid="uid://cb4q16lmqwbin" path="res://config/character/bullet_hero01_short_stab01.tres" id="6_cub6b"] + +[resource] +script = ExtResource("3_cub6b") +weapon = ExtResource("6_5n6sn") +action = "attack_light" +name = "" +sub_character = ExtResource("6_cub6b") +skill_animation = ExtResource("4_67ngl") +stance_from = 30 +stance_to = 30 +break_level = 3 +is_charging = false +attack1 = ExtResource("1_5n6sn") +attack1_box = ExtResource("2_67ngl") +attack1_with_pause_frame = false +attack1_with_stop = false +attack2_with_pause_frame = false +attack2_with_stop = false +mp_cost = 0 +mp_sub_cost = false +free_lock = false +ignore_push = true +with_stop = false +is_lock_x = true +is_lock_x_move = true +range = 0.0 +warn_type = 0 +sprite_frames = ExtResource("5_kk2vu") +animation_name = "long_skill_stab01" diff --git a/project.godot b/project.godot index c6740eb..c71264f 100644 --- a/project.godot +++ b/project.godot @@ -235,6 +235,12 @@ test_3={ ] } +[layer_names] + +3d_physics/layer_1="墙体" +3d_physics/layer_2="角色" +3d_physics/layer_3="攻击框" + [memory] limits/message_queue/max_size_mb=2048 diff --git a/resource/animation/character/hero01_long_skill03.aseprite b/resource/animation/character/hero01_long_skill03.aseprite index 7b5b7bac3f886ab3742f177de7e48d515ffa3f72..8b965c9564534b68de459ea9ff0d77413645d464 100644 GIT binary patch delta 132 zcmbQB^~#<7l`;dvgQda~*(-U)I2jmzeUxQLVPIg8-Po(l%pL(`NhmN)-p;IR#K|B8 z(QQ0s)t?0ZAbNtCP_$CzC!a2(x-2hyj1T00005APN9E04f0g0ssI2 z0000002%-k0C=2r(K`~vAP5Fvs-*M)o(W1g0|(A*jVD=9eC*8TPm}P8k`bWC;3dXy z>yZI1)=5I!5UsYz<{1v$uUDiP?n|>f(=XfkrIG+iJ z&=ARv6jeVZB31uk$*qRyRck5bs>-8j3Eof0UDtLwRLCdfLE)1av5XLU(=nV2QV;T$ zeii^m`~!}gfV>wxN?$fqg%Fd)BQ*g~lhF_-ldvravnnJi0e`>%000Fb3II9)D**oj z00000000007XTOlc${s~u@%BF3R`l!d9KNsweEc3ylm@VVU6gHke5 zb`iWy#rRd%t_l%!08e%9Bde-f* zY+j6bg$@~I&_SEQOvK2Ie4N0aqt=6MdzKqf{TkPnJiZG44UX~TM%6F^(}4w zxPFDPr=XYVoBwPH@0HJeIqQGj7Ks0o7A7_UQIpXxFSC3mLIDA-lfNe&f4dRHFbD)t zMR%bJa7`#&YEZ?Fp_1cc*~qs}m^TPnw3d`#ee$aQa!ZR5Qls;h{#TsRhJF79|oO;>$7So9t8nKlhF_-v#>2W0Rgg; z>Mk9Bu@%EG2n0}7NvQ!m6O_jcnm9E~5uYI4(Fjvcf#o0-j?msFa(+<6zb&iJjnjI01N~iy)3cs0 F0$Y;PR;vI2 delta 622 zcmV-!0+Icfl>(rZ0s)}00ZAbNu#*uhFSB|fhyj1Y00005APN9E04f0g0ssI200000 z02%-k0C=2r(Y+PLAP5CutE6-QXTtI_0|V#08YX$D_>&^nCh{qIVoE)lKBD*{7bk}2 zRX1}`<;YQIHVv{io6x6bidZnoM%^1apl6cyGZZd}gTVV3*xQ68z}n~ux5Q0*aX z>1U-xEj~%-BgK=^QThYsbBbA$z#}yQQj^gTC$k+SG64a?lTalce=!z>APfXhs@;+U zcqUQ~XNVWxI-F!DA?o8vZ1g*fsHNms*^S|C!^p4r=wrYP9l)y2J!a7{80PR~QRb;; zb~zvB7ojY_d&0c~y+8d3c3QdH+{Ufph|Y@P$dh-kMf10cN@(z<$fuo!RRyP4#Td*Z zs*qK~*!JG{@l@^~*G`giaqBT4wV`N)DG!G@XKW#k(7Me$KPcjR%hl(N(|q{?Mox&& Ivz0FbTZ1PU*#H0l diff --git a/resource/animation/character/hero01_move.png b/resource/animation/character/hero01_move.png index f95c49d9db2cc26598d8ccd2a9e61533b7efef9b..4ccfcdd06fe73e2b6146dcc42b447386c583384a 100644 GIT binary patch literal 24472 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�w;|Vi4~{2?cdw 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 delta 2903 zcmeH}dpwle8pqdbX3Q9kYa6+YaSve_QB0T&Mk2Rda!GDQlA3+6qlR)xa($@?F`~3l zOiF5Nq;j`iy4mTVbj1#-T(a$Vq|S6cpL6~^f1US_cfD)9>+(F`=eO2+u6hh?#|~%# zFkB{{h5dzq!T~TpB?STj08%w+DkzRTngT%zup{OtcMM=g?LQdki2Rcw2_WyU4+Mn1 zeSR$ofVpS?!Jl_B_lAUpk@fLF?7#gtfJ>wgVS|t^7!nHB6AXmVaE_oWgn{1*QXxTD z9cut#VNa|w>l&f+qq*{8XrJeq`J?D62IfqvJdLg_;1z#2UR>kE1yw}Tl-?eFmi0hMKRg?&{o0A;raLy?zp-65`SiWo*%!(7`Hz@U6zej4 z*1M8@jUvp(==3;g4jzBez0lgHzNn#o>{jDrMdumzf>8IKu?f-LVn?sSDBK3&@@0#K z00pSPSqf(n8*d1!Ayha6LKp!EaE65MKoA~g6I2Ay0Vb}Hv6xmYgzwBAiwroYVKR`#a? zuMcJ#|BM#@^*v@V%G@BR=7aGZgxw_n$KGXMu!#Sg`FtS&QN)++=}iPKX%&hRM6vv0 z^<>Og6WtqQ`K-;ETN!b)zPat1DkB$OMQ3!_qQyL!kDiM~g6E~9+9~r^_P>;Be3ooH zlGVFoTUy7yu)|QqTYa5xtkvNRg+fS*M;f77utJjz$b1&a0xcfRY$uU8GR`t;$>rec zuHa(rDkl}i)X7J+`Yj&flq8&G?R~PZ#(2?<4cnq?15e>1>JHJ{7e$@D{I;J@lP(Vs zDm*$q^>Y4cQHX1??J0V|%LJ~t?ohVqVSnLmeIIb`#2*A&;t0O}rh1Az^{>4|rCARfusqX}tuXkK3F#T|i^$C4NkGlZ2BcfEWcs z4NOWIohom6E}vR?G0f22sc!3(q}%bn`5^_Ek|Dj<^=GRX|JHj;cQB&3AhOjrE;>M$ zr$JlB@}hWzhZ!FcIj{y^OI*`u-~3`v-{CEnNyVp2D`fkk zfu|V;Wa;9qlvW6zTOn)!^!etK`AQh3NpMLx)ZCKxha3kh1g~o-@1+5bj zUY?Ce35+ql zBp`v<+Bvz=v($V?vCTOu%SqZt&V>3G37cE`n(gt|z=AJe))`6kmo8*+#H4jhW|W+l z?Lz@7(B`vG9Z2#N(9?vROSoo>$76p93+eX6Jc%MVt?@uB;m)|?#opDJlHq?ywl};} zYLRjBoNf``FTCM`FvQLOS{vcVC?oX_@Y$j10;x1O+aFuApId2%5HrXGBoR04g5cPa6N z{56aaFa)}MYs!Olh#PgVod|-Neq%{<;}*%MBosw8KPPu~wlvr_HpMAxUASpv#n#Fs zTa&i;lBs=$Dr=pI`b+U;H&Z_LzRn|5-nTdP)#y2T*al0x$#mUXtU5EKG7#BSqg>Z< zT|BWkJ1LMw?`AL)o>@rt*woLzA_qGJm);H-@X}65x;S^e&rbN^ho|Tk>=2<=OkmR>u87o%3e0jh(Xk zrui#4O~5+1K{ErATTv}%xgA0<^Q%?`X!2A6+ez@wg_tFmS8LOEm?xlnvwTK!=@$b= zxl-&Nn{IZQpXlL)nB6)DQe70qsp18($>WPzIY(@~tK&ysUJ5eKRCY_5s7TyfpKH0c zZIdGD&~Gh54;&ZnkF+fbz!!^HtomxQ1jD~w-K*M1B!A1ktMuTysT*$Z3`WM$rT1D- z)cEV_sopvsI9k7laKCV(q8Q_vu{x8y!d4$_;Nv8QT%Ej~YXKD<%T5(pOYV@gmjZ^T z&{?71x$>XBB0yvZ4{T=#flJ1r9LpCQIJb?wbkitc0kDxCG=D~;Ow$}Z{EF^`D+ZW#aVkTHez*AznXE0F6~ zApfXY(z0f&vOSkI`x{TQ{my9|#`=n#trJNQKZQ@zVj1i7ObgWB9;v+ERC;%q zI;<&oX4oeD@J?@cb#3qIg^JiznJ_c0Twh#XS%ZS=%Z}sf@}}eS#EjDp@g_Y7Xe?i+ z%!ZyvwIwa=s%}sCVZZmJo6xY|i5auvBDq_UQ0GU*z9(-K^Q~69f2vQ~)wP+!F!C5# zuj@P^E`}sKyi5bp#(yBKauT_w?Sj!+VJnQy{!P0gz=tPZFFe-*huRdx6kODiyF4`O zS5X`&L+cvPjN4bpK8vyPpqX&pP7occQzkJ66w*UaM+X?S%{sJ-VOV diff --git a/resource/animation/character/hero01_short_skill01.png b/resource/animation/character/hero01_short_skill01.png index 010870515d399f145c12fb59e66f749545a8bce6..ec735642e6b51a9e000ce2d4e9ff1de976350434 100644 GIT binary patch literal 5971 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 literal 8808 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 G8Q9MarpFEd literal 0 HcmV?d00001 diff --git a/resource/animation/character/hero01_short_skill03.aseprite.import b/resource/animation/character/hero01_short_skill03.aseprite.import new file mode 100644 index 0000000..949ae01 --- /dev/null +++ b/resource/animation/character/hero01_short_skill03.aseprite.import @@ -0,0 +1,25 @@ +[remap] + +importer="Aseprite SpriteFrames Import" +type="SpriteFrames" +uid="uid://dlmesk4xyydmd" +path="res://.godot/imported/hero01_short_skill03.aseprite-cf64863bc2c45d75bbeae9d71dcd4217.res" + +[deps] + +source_file="res://resource/animation/character/hero01_short_skill03.aseprite" +dest_files=["res://.godot/imported/hero01_short_skill03.aseprite-cf64863bc2c45d75bbeae9d71dcd4217.res"] + +[params] + +spritesheet/layout=0 +spritesheet/fixed_rows_count=1 +spritesheet/fixed_columns_count=1 +spritesheet/border_type=0 +spritesheet/trim=false +spritesheet/ignore_empty=false +spritesheet/merge_duplicates=false +animation/default/name="default" +animation/default/direction=0 +animation/default/repeat_count=0 +animation/autoplay="" diff --git a/resource/animation/character/hero01_short_skill03.png b/resource/animation/character/hero01_short_skill03.png new file mode 100644 index 0000000000000000000000000000000000000000..1245632b02a2037f80dfd461b17966a45d037f0e GIT binary patch literal 2854 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 Eg6FMhZvX%Q literal 0 HcmV?d00001 diff --git a/resource/animation/character/hero01_short_skill03.png.import b/resource/animation/character/hero01_short_skill03.png.import new file mode 100644 index 0000000..1d6eb87 --- /dev/null +++ b/resource/animation/character/hero01_short_skill03.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="CompressedTexture2D" +uid="uid://cyw16jypnrjt0" +path="res://.godot/imported/hero01_short_skill03.png-8257420af302734e3238b32df28eecd2.ctex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://resource/animation/character/hero01_short_skill03.png" +dest_files=["res://.godot/imported/hero01_short_skill03.png-8257420af302734e3238b32df28eecd2.ctex"] + +[params] + +compress/mode=0 +compress/high_quality=false +compress/lossy_quality=0.7 +compress/hdr_compression=1 +compress/normal_map=0 +compress/channel_pack=0 +mipmaps/generate=false +mipmaps/limit=-1 +roughness/mode=0 +roughness/src_normal="" +process/fix_alpha_border=true +process/premult_alpha=false +process/normal_map_invert_y=false +process/hdr_as_srgb=false +process/hdr_clamp_exposure=false +process/size_limit=0 +detect_3d/compress_to=1 diff --git a/resource/skill_animation/hero01_basic_air_flash.tres b/resource/skill_animation/hero01_basic_air_flash.tres index 96c4f99..78eb33b 100644 --- a/resource/skill_animation/hero01_basic_air_flash.tres +++ b/resource/skill_animation/hero01_basic_air_flash.tres @@ -37,7 +37,7 @@ tracks/2/path = NodePath("Status:break_level") tracks/2/interp = 1 tracks/2/loop_wrap = true tracks/2/keys = { -"times": PackedFloat32Array(0, 0.2), +"times": PackedFloat32Array(0, 0.3), "transitions": PackedFloat32Array(1, 1), "update": 1, "values": [3, 4] @@ -49,10 +49,10 @@ tracks/3/path = NodePath("Status:skill_move_speed") tracks/3/interp = 1 tracks/3/loop_wrap = true tracks/3/keys = { -"times": PackedFloat32Array(0, 0.2), -"transitions": PackedFloat32Array(1, 1), +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), "update": 1, -"values": [7.0, 0.0] +"values": [7.0, 0.0, 1.0] } tracks/4/type = "method" tracks/4/imported = false @@ -75,7 +75,7 @@ tracks/5/path = NodePath("Battle") tracks/5/interp = 1 tracks/5/loop_wrap = true tracks/5/keys = { -"times": PackedFloat32Array(0.2), +"times": PackedFloat32Array(0.3), "transitions": PackedFloat32Array(1), "values": [{ "args": [], @@ -89,7 +89,7 @@ tracks/6/path = NodePath("Status:is_speed_y_freeze") tracks/6/interp = 1 tracks/6/loop_wrap = true tracks/6/keys = { -"times": PackedFloat32Array(0, 0.2), +"times": PackedFloat32Array(0, 0.3), "transitions": PackedFloat32Array(1, 1), "update": 1, "values": [true, false] diff --git a/resource/skill_animation/hero01_long_stab02.tres b/resource/skill_animation/hero01_long_stab02.tres new file mode 100644 index 0000000..c807007 --- /dev/null +++ b/resource/skill_animation/hero01_long_stab02.tres @@ -0,0 +1,95 @@ +[gd_resource type="Animation" load_steps=2 format=3 uid="uid://nhnwu6uccylr"] + +[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="1_yn72v"] + +[resource] +resource_name = "hero01_long_stab02" +step = 0.1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("View:sprite_frames") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [ExtResource("1_yn72v")] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("View:animation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": ["long_skill_stab02"] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Status:break_level") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.4, 0.7), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0, 3, 4] +} +tracks/3/type = "method" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Battle") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0.3), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"attack1" +}] +} +tracks/4/type = "method" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Effect") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0.3), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"cast_attack_particle1" +}] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("View:frame") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Status:skill_move_speed") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.2, 0.3), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [-1.0, 4.0, 0.0] +} diff --git a/resource/skill_animation/hero01_short_attack03.tres b/resource/skill_animation/hero01_short_attack03.tres index 60d89e3..2d4ad4d 100644 --- a/resource/skill_animation/hero01_short_attack03.tres +++ b/resource/skill_animation/hero01_short_attack03.tres @@ -61,7 +61,7 @@ tracks/4/path = NodePath("Status:skill_move_speed") tracks/4/interp = 1 tracks/4/loop_wrap = true tracks/4/keys = { -"times": PackedFloat32Array(0.1, 0.4, 0.6, 0.7), +"times": PackedFloat32Array(0, 0.4, 0.6, 0.7), "transitions": PackedFloat32Array(1, 1, 1, 1), "update": 1, "values": [2.0, 0.0, 4.0, 0.0] @@ -130,3 +130,15 @@ tracks/7/keys = { "update": 1, "values": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] } +tracks/8/type = "value" +tracks/8/imported = false +tracks/8/enabled = true +tracks/8/path = NodePath("Status:skill_float_speed") +tracks/8/interp = 1 +tracks/8/loop_wrap = true +tracks/8/keys = { +"times": PackedFloat32Array(0.1, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [2.0, 0.0] +} diff --git a/resource/skill_animation/hero01_short_skill01.tres b/resource/skill_animation/hero01_short_skill01.tres new file mode 100644 index 0000000..378da60 --- /dev/null +++ b/resource/skill_animation/hero01_short_skill01.tres @@ -0,0 +1,82 @@ +[gd_resource type="Animation" load_steps=2 format=3 uid="uid://qcmj7d5pg6lw"] + +[ext_resource type="SpriteFrames" uid="uid://d1dgtfh3h3c24" path="res://resource/animation/character/hero01_short_skill01.aseprite" id="1_0x0f7"] + +[resource] +resource_name = "hero01_short_skill01" +length = 0.8 +step = 0.1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("View:sprite_frames") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [ExtResource("1_0x0f7")] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("View:animation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": ["short_skill01"] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Status:skill_move_speed") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.2), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [-7.0, 0.0] +} +tracks/3/type = "method" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Battle") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0.2), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"stop" +}] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Status:break_level") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.2, 0.6), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0, 3, 4] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("View:frame") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 3, 4, 5, 6, 7] +} diff --git a/resource/skill_animation/hero01_short_stab01.tres b/resource/skill_animation/hero01_short_stab01.tres new file mode 100644 index 0000000..3dde4aa --- /dev/null +++ b/resource/skill_animation/hero01_short_stab01.tres @@ -0,0 +1,95 @@ +[gd_resource type="Animation" load_steps=2 format=3 uid="uid://b3fuombjh57oj"] + +[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="1_rcy2y"] + +[resource] +resource_name = "hero01_short_stab01" +length = 0.8 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("View:sprite_frames") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [ExtResource("1_rcy2y")] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("View:animation") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": ["long_skill_stab01"] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("View:frame") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7), +"transitions": PackedFloat32Array(1, 1, 1, 1, 1, 1, 1, 1), +"update": 1, +"values": [0, 1, 2, 3, 4, 5, 6, 7] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Status:break_level") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.3, 0.5), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0, 3, 4] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Status:speed_up_rate") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.1), +"transitions": PackedFloat32Array(1, 1), +"update": 1, +"values": [-0.5, -1.0] +} +tracks/5/type = "method" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Battle") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0.1), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"cast_sub_character" +}] +} +tracks/6/type = "method" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Effect") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0.1), +"transitions": PackedFloat32Array(1), +"values": [{ +"args": [], +"method": &"cast_attack_particle1" +}] +} diff --git a/resource/skill_animation_library/animation_library.tres b/resource/skill_animation_library/animation_library.tres index e152604..0916add 100644 --- a/resource/skill_animation_library/animation_library.tres +++ b/resource/skill_animation_library/animation_library.tres @@ -1,4 +1,4 @@ -[gd_resource type="AnimationLibrary" load_steps=53 format=3 uid="uid://croik07a1qko5"] +[gd_resource type="AnimationLibrary" load_steps=56 format=3 uid="uid://croik07a1qko5"] [ext_resource type="Animation" uid="uid://t01a4jvp8srr" path="res://resource/skill_animation/hero01_fist_attack01.tres" id="1_4bwwm"] [ext_resource type="Animation" uid="uid://cfapnjkj5dkws" path="res://resource/skill_animation/hero01_basic_flash.tres" id="1_46f01"] @@ -49,9 +49,12 @@ [ext_resource type="Animation" uid="uid://q7qlw0a7hfjt" path="res://resource/skill_animation/hero01_slash01.tres" id="38_lyels"] [ext_resource type="Animation" uid="uid://b7f0rdven8gdc" path="res://resource/skill_animation/hero01_long_skill03.tres" id="42_d2bqv"] [ext_resource type="Animation" uid="uid://cc086nunelk2q" path="res://resource/skill_animation/hero01_long_stab01.tres" id="43_0kutt"] +[ext_resource type="Animation" uid="uid://nhnwu6uccylr" path="res://resource/skill_animation/hero01_long_stab02.tres" id="44_c7cx4"] [ext_resource type="Animation" uid="uid://2oxeq83bpofb" path="res://resource/skill_animation/monster03_slash02.tres" id="45_1vnur"] [ext_resource type="Animation" uid="uid://dyyt3nsvoye62" path="res://resource/skill_animation/monster03_slash01.tres" id="45_s1ue4"] [ext_resource type="Animation" uid="uid://co8bivpp1fm6g" path="res://resource/skill_animation/monster03_slash03.tres" id="46_litb8"] +[ext_resource type="Animation" uid="uid://qcmj7d5pg6lw" path="res://resource/skill_animation/hero01_short_skill01.tres" id="50_1hav4"] +[ext_resource type="Animation" uid="uid://b3fuombjh57oj" path="res://resource/skill_animation/hero01_short_stab01.tres" id="51_44mwa"] [resource] _data = { @@ -98,11 +101,14 @@ _data = { &"hero01_long_skill02": ExtResource("7_ui68j"), &"hero01_long_skill03": ExtResource("42_d2bqv"), &"hero01_long_stab01": ExtResource("43_0kutt"), +&"hero01_long_stab02": ExtResource("44_c7cx4"), &"hero01_remote01": ExtResource("33_7i37k"), &"hero01_short_attack01": ExtResource("11_n0dhn"), &"hero01_short_attack02": ExtResource("11_h2vlt"), &"hero01_short_attack03": ExtResource("11_kejyu"), &"hero01_short_attack04": ExtResource("11_bxi8a"), +&"hero01_short_skill01": ExtResource("50_1hav4"), +&"hero01_short_stab01": ExtResource("51_44mwa"), &"hero01_slash01": ExtResource("38_lyels"), &"monster03_slash01": ExtResource("45_s1ue4"), &"monster03_slash02": ExtResource("45_1vnur"), diff --git a/scene/ai/bullet01.tscn b/scene/ai/bullet01.tscn deleted file mode 100644 index 78a7824..0000000 --- a/scene/ai/bullet01.tscn +++ /dev/null @@ -1,86 +0,0 @@ -[gd_scene load_steps=12 format=3 uid="uid://bgku27xawscbt"] - -[ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_r673b"] -[ext_resource type="Script" path="res://addons/beehave/nodes/composites/selector.gd" id="2_5ltau"] -[ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="3_yeaa5"] -[ext_resource type="Script" path="res://script/ai/action_blackboard/action_blackboard_check.gd" id="4_vnt1w"] -[ext_resource type="Script" path="res://script/ai/action/action_destroy.gd" id="5_0a0n1"] -[ext_resource type="Script" path="res://script/ai/action/action_wait.gd" id="6_omj7f"] -[ext_resource type="Script" path="res://script/ai/action_blackboard/action_blackboard_set.gd" id="7_gpffp"] -[ext_resource type="Script" path="res://script/ai/action/action_attack1.gd" id="7_wcjhl"] -[ext_resource type="Script" path="res://script/ai/action/action_stop_move.gd" id="8_ntwgo"] -[ext_resource type="Script" path="res://script/ai/action_blackboard/action_blackboard_add.gd" id="8_rm753"] -[ext_resource type="Script" path="res://addons/beehave/nodes/decorators/succeeder.gd" id="9_lh2cr"] - -[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")] -script = ExtResource("1_r673b") -blackboard = NodePath("@Node@19481") - -[node name="SelectorComposite" type="Node" parent="."] -script = ExtResource("2_5ltau") - -[node name="SequenceComposite" type="Node" parent="SelectorComposite"] -script = ExtResource("3_yeaa5") - -[node name="CheckStep0" type="Node" parent="SelectorComposite/SequenceComposite"] -script = ExtResource("4_vnt1w") -key = "step" - -[node name="ActionWait" type="Node" parent="SelectorComposite/SequenceComposite"] -script = ExtResource("6_omj7f") -wait_time = 0.05 - -[node name="ActionAttack1" type="Node" parent="SelectorComposite/SequenceComposite"] -script = ExtResource("7_wcjhl") - -[node name="ActionStopMove" type="Node" parent="SelectorComposite/SequenceComposite"] -script = ExtResource("8_ntwgo") - -[node name="SetStep1" type="Node" parent="SelectorComposite/SequenceComposite"] -script = ExtResource("7_gpffp") -key = "step" -value = 1 - -[node name="SequenceComposite2" type="Node" parent="SelectorComposite"] -script = ExtResource("3_yeaa5") - -[node name="CheckStep1" type="Node" parent="SelectorComposite/SequenceComposite2"] -script = ExtResource("4_vnt1w") -key = "step" -value = 1 - -[node name="ActionWait" type="Node" parent="SelectorComposite/SequenceComposite2"] -script = ExtResource("6_omj7f") -wait_time = 0.3 - -[node name="AlwaysSucceedDecorator" type="Node" parent="SelectorComposite/SequenceComposite2"] -script = ExtResource("9_lh2cr") - -[node name="ActionAttack1" type="Node" parent="SelectorComposite/SequenceComposite2/AlwaysSucceedDecorator"] -script = ExtResource("7_wcjhl") - -[node name="AddHit" type="Node" parent="SelectorComposite/SequenceComposite2"] -script = ExtResource("8_rm753") -key = "hit" -value = 1 - -[node name="CheckHit9" type="Node" parent="SelectorComposite/SequenceComposite2"] -script = ExtResource("4_vnt1w") -key = "hit" -value = 9 - -[node name="SetStep2" type="Node" parent="SelectorComposite/SequenceComposite2"] -script = ExtResource("7_gpffp") -key = "step" -value = 2 - -[node name="SequenceComposite3" type="Node" parent="SelectorComposite"] -script = ExtResource("3_yeaa5") - -[node name="CheckStep2" type="Node" parent="SelectorComposite/SequenceComposite3"] -script = ExtResource("4_vnt1w") -key = "step" -value = 2 - -[node name="ActionDestroy" type="Node" parent="SelectorComposite/SequenceComposite3"] -script = ExtResource("5_0a0n1") diff --git a/scene/ai/bullet02.tscn b/scene/ai/bullet02.tscn deleted file mode 100644 index 61f93b5..0000000 --- a/scene/ai/bullet02.tscn +++ /dev/null @@ -1,23 +0,0 @@ -[gd_scene load_steps=6 format=3 uid="uid://bdwwmat306mff"] - -[ext_resource type="Script" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_go1b5"] -[ext_resource type="Script" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_k8nph"] -[ext_resource type="Script" path="res://script/ai/action/action_stop_move.gd" id="3_aums8"] -[ext_resource type="Script" path="res://script/ai/action/action_attack1.gd" id="4_mhoc5"] -[ext_resource type="Script" path="res://script/ai/action/action_destroy.gd" id="5_ejojh"] - -[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")] -script = ExtResource("1_go1b5") -blackboard = NodePath("@Node@19760") - -[node name="SequenceComposite" type="Node" parent="."] -script = ExtResource("2_k8nph") - -[node name="ActionStopMove" type="Node" parent="SequenceComposite"] -script = ExtResource("3_aums8") - -[node name="ActionAttack1" type="Node" parent="SequenceComposite"] -script = ExtResource("4_mhoc5") - -[node name="ActionDestroy" type="Node" parent="SequenceComposite"] -script = ExtResource("5_ejojh") diff --git a/scene/ai/bullet_simple.tscn b/scene/ai/bullet_simple.tscn new file mode 100644 index 0000000..833d385 --- /dev/null +++ b/scene/ai/bullet_simple.tscn @@ -0,0 +1,24 @@ +[gd_scene load_steps=6 format=3 uid="uid://bei75ysjq2pi4"] + +[ext_resource type="Script" uid="uid://mvwcxqcetiqp" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_7oi2o"] +[ext_resource type="Script" uid="uid://cugftmuc8v30c" path="res://addons/beehave/nodes/composites/sequence.gd" id="3_i33jf"] +[ext_resource type="Script" uid="uid://cnw25wdsd3c76" path="res://script/ai/action/action_wait.gd" id="5_onfb3"] +[ext_resource type="Script" uid="uid://ddcaceywxwt20" path="res://script/ai/action/action_attack1.gd" id="6_oqib4"] +[ext_resource type="Script" uid="uid://ci3tg5fkdn16f" path="res://script/ai/action/action_destroy.gd" id="11_i4mx4"] + +[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")] +script = ExtResource("1_7oi2o") +blackboard = NodePath("@Node@25322") + +[node name="SequenceComposite" type="Node" parent="."] +script = ExtResource("3_i33jf") + +[node name="ActionWait" type="Node" parent="SequenceComposite"] +script = ExtResource("5_onfb3") +wait_time = 0.05 + +[node name="ActionAttack1" type="Node" parent="SequenceComposite"] +script = ExtResource("6_oqib4") + +[node name="ActionDestroy" type="Node" parent="SequenceComposite"] +script = ExtResource("11_i4mx4") diff --git a/scene/ai/bullet_simple_penetrat.tscn b/scene/ai/bullet_simple_penetrat.tscn new file mode 100644 index 0000000..9b4f458 --- /dev/null +++ b/scene/ai/bullet_simple_penetrat.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=5 format=3 uid="uid://tr65aikkpp2e"] + +[ext_resource type="Script" uid="uid://mvwcxqcetiqp" path="res://addons/beehave/nodes/beehave_tree.gd" id="1_6wcp2"] +[ext_resource type="Script" uid="uid://cugftmuc8v30c" path="res://addons/beehave/nodes/composites/sequence.gd" id="2_0p8p1"] +[ext_resource type="Script" uid="uid://cnw25wdsd3c76" path="res://script/ai/action/action_wait.gd" id="3_irjra"] +[ext_resource type="Script" uid="uid://ddcaceywxwt20" path="res://script/ai/action/action_attack1.gd" id="4_klwmg"] + +[node name="BeehaveTree" type="Node" node_paths=PackedStringArray("blackboard")] +script = ExtResource("1_6wcp2") +blackboard = NodePath("@Node@25321") + +[node name="SequenceComposite" type="Node" parent="."] +script = ExtResource("2_0p8p1") + +[node name="ActionWait" type="Node" parent="SequenceComposite"] +script = ExtResource("3_irjra") +wait_time = 0.05 + +[node name="ActionAttack1" type="Node" parent="SequenceComposite"] +script = ExtResource("4_klwmg") diff --git a/scene/character/character.tscn b/scene/character/character.tscn index e9c7e81..1679b1c 100644 --- a/scene/character/character.tscn +++ b/scene/character/character.tscn @@ -1,15 +1,16 @@ -[gd_scene load_steps=24 format=3 uid="uid://8rcvw1vnjcf7"] +[gd_scene load_steps=25 format=3 uid="uid://8rcvw1vnjcf7"] [ext_resource type="Script" uid="uid://cdvtgxvof33j3" path="res://script/character/character.gd" id="1_tonbs"] [ext_resource type="Script" uid="uid://cms637d0jt6sk" path="res://script/character/hitbox.gd" id="2_6xf87"] [ext_resource type="Script" uid="uid://bfi4gneebe3oq" path="res://script/character/status.gd" id="2_txdip"] -[ext_resource type="SpriteFrames" uid="uid://cajgs8smbkjan" path="res://resource/animation/character/hero01_fist_skill01.aseprite" id="4_53b4u"] +[ext_resource type="SpriteFrames" uid="uid://c6w03xigmrd31" path="res://resource/animation/character/hero01_long_skill03.aseprite" id="4_53b4u"] [ext_resource type="Script" uid="uid://cnaqs44siwa45" path="res://script/character/move.gd" id="4_66r53"] [ext_resource type="Script" uid="uid://c247mf44qb3uf" path="res://script/character/view.gd" id="4_vijjv"] [ext_resource type="Script" uid="uid://c24is3uqqcmcn" path="res://script/character/skill.gd" id="6_h4xqy"] [ext_resource type="AnimationLibrary" uid="uid://croik07a1qko5" path="res://resource/skill_animation_library/animation_library.tres" id="6_pakq5"] [ext_resource type="Script" uid="uid://cxklw5xp85wuw" path="res://script/character/battle.gd" id="8_w84sf"] [ext_resource type="Script" uid="uid://bys2rd62nmj2v" path="res://script/character/buff.gd" id="9_jlnhy"] +[ext_resource type="Script" uid="uid://dqsadncw4srh6" path="res://script/character/battle_attack_area.gd" id="11_sox5o"] [ext_resource type="Script" uid="uid://d3lbbulqdp1nu" path="res://script/character/effect.gd" id="12_eyfcd"] [ext_resource type="Script" uid="uid://b2ap8nlbb2717" path="res://script/character/core.gd" id="14_gua01"] [ext_resource type="PackedScene" uid="uid://cq03usrdvv43o" path="res://scene/effect/readiness/readiness_lock.tscn" id="14_gw1pa"] @@ -57,6 +58,30 @@ tracks/1/keys = { "update": 1, "values": [false] } +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Status:skill_move_speed") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [2.0] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Status:skill_float_speed") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0.1] +} [sub_resource type="AnimationLibrary" id="AnimationLibrary_avnjy"] _data = { @@ -100,6 +125,7 @@ shape = SubResource("CylinderShape3D_ehwx5") unique_name_in_owner = true script = ExtResource("2_txdip") speed_up_rate = -0.5 +skill_move_speed = 2.0 skill_float_speed = 0.1 [node name="View" type="AnimatedSprite3D" parent="."] @@ -112,7 +138,7 @@ pixel_size = 0.02 double_sided = false texture_filter = 0 sprite_frames = ExtResource("4_53b4u") -animation = &"fist_skill03" +animation = &"long_skill_stab01" script = ExtResource("4_vijjv") [node name="Move" type="Node3D" parent="."] @@ -138,6 +164,16 @@ script = ExtResource("8_w84sf") hit_back_limit_curve = SubResource("Curve_e7j3f") pause_time_limit_curve = SubResource("Curve_55xfs") +[node name="BattleAttackArea" type="Area3D" parent="Battle"] +unique_name_in_owner = true +collision_layer = 4 +collision_mask = 3 +script = ExtResource("11_sox5o") +metadata/_custom_type_script = ExtResource("11_sox5o") + +[node name="BattleAttackAreaCollision" type="CollisionShape3D" parent="Battle/BattleAttackArea"] +unique_name_in_owner = true + [node name="Effect" type="Node3D" parent="."] unique_name_in_owner = true script = ExtResource("12_eyfcd") diff --git a/scene/effect/particle/bullet_hero01_short_stab01.tscn b/scene/effect/particle/bullet_hero01_short_stab01.tscn new file mode 100644 index 0000000..3767a38 --- /dev/null +++ b/scene/effect/particle/bullet_hero01_short_stab01.tscn @@ -0,0 +1,12 @@ +[gd_scene load_steps=2 format=3 uid="uid://bakftws1caca2"] + +[ext_resource type="PackedScene" uid="uid://b2h4pcmlii7dg" path="res://scene/effect/particle/_particle_slash1.tscn" id="1_bduq8"] + +[node name="Particle" instance=ExtResource("1_bduq8")] +transform = Transform3D(0.5, 0, 0, 0, 1, 0, 0, 0, 0.5, 0, 0, 0) + +[node name="Slash" parent="." index="0"] +emitting = true +lifetime = 600.0 +one_shot = false +seed = 300733846 diff --git a/script/_global/struct.gd b/script/_global/struct.gd new file mode 100644 index 0000000..970d796 --- /dev/null +++ b/script/_global/struct.gd @@ -0,0 +1,15 @@ +extends Node3D +class_name Struct + +class AttackInfo: + var attack: AttackCfg + var attack_box: AttackBoxCfg + var attack_dir: Vector2 = Vector2.ZERO + var with_stop: bool = false + var ignore_push: bool = false + + +class HitResultInfo: + var is_hit: bool + var is_break: bool + diff --git a/script/_global/util.gd b/script/_global/util.gd index 88d59fb..0c7a94a 100644 --- a/script/_global/util.gd +++ b/script/_global/util.gd @@ -68,8 +68,6 @@ func raycast_character(shape: Shape3D, origin: Vector3, dir: Vector2) -> Array[C var result3: Array[Character] for node in result2: result3.append(node as Character) - if result.size() > result3.size(): - result3.append(null) #特殊处理 表示命中非Character物体 例如墙体或地面 return result3 diff --git a/script/ai/action/action_attack1.gd b/script/ai/action/action_attack1.gd index 8493ccd..e44c64f 100644 --- a/script/ai/action/action_attack1.gd +++ b/script/ai/action/action_attack1.gd @@ -2,9 +2,6 @@ extends Action class_name ActionAttack1 func run(character: Character, blackboard: Blackboard) -> int: - var is_hit: bool = character.attack1() - if is_hit: - return SUCCESS - else: - return FAILURE + character.attack1() + return SUCCESS diff --git a/script/ai/action/action_attack2.gd b/script/ai/action/action_attack2.gd index aeab384..8cc4f20 100644 --- a/script/ai/action/action_attack2.gd +++ b/script/ai/action/action_attack2.gd @@ -2,9 +2,6 @@ extends Action class_name ActionAttack2 func run(character: Character, blackboard: Blackboard) -> int: - var is_hit: bool = character.attack2() - if is_hit: - return SUCCESS - else: - return FAILURE + character.attack2() + return SUCCESS diff --git a/script/ai/action/action_destroy.gd b/script/ai/action/action_destroy.gd index fa9a412..c853598 100644 --- a/script/ai/action/action_destroy.gd +++ b/script/ai/action/action_destroy.gd @@ -4,4 +4,4 @@ class_name ActionDestroy func run(character: Character, blackboard: Blackboard) -> int: Global.character_mgr.destroy_character(character.id()) return SUCCESS - + diff --git a/script/character/battle.gd b/script/character/battle.gd index d1ae09b..0cfbe30 100644 --- a/script/character/battle.gd +++ b/script/character/battle.gd @@ -8,105 +8,78 @@ class_name Battle @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 +@onready var battle_attack_area: BattleAttackArea = (%BattleAttackArea as BattleAttackArea) 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() - add_attack(attack, attack_box, false, Vector2.ZERO, - status.skill_cfg.attack1_with_pause_frame, status.skill_cfg.attack1_with_stop, status.skill_cfg.ignore_push) + var attack_info: Struct.AttackInfo = Struct.AttackInfo.new() + attack_info.attack = status.skill_cfg.get_attack1() + attack_info.attack_box = status.skill_cfg.get_attack1_box() + attack_info.attack_dir = status.skill_dir + attack_info.with_stop = status.skill_cfg.attack1_with_stop + attack_info.ignore_push = status.skill_cfg.ignore_push + add_attack(attack_info) 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() - add_attack(attack, attack_box, false, Vector2.ZERO, - status.skill_cfg.attack2_with_pause_frame, status.skill_cfg.attack2_with_stop, status.skill_cfg.ignore_push) - - -func character_attack1() -> bool: - var attack: AttackCfg = status.cfg.get_attack1() - var attack_box: AttackBoxCfg = status.cfg.get_attack1_box() - return add_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 add_attack(attack, attack_box) - - -func add_attack(attack: AttackCfg, attack_box: AttackBoxCfg, hit_self: bool = false, attack_dir: Vector2 = Vector2.ZERO, -with_pause_frame: bool = false, with_stop: bool = false, ignore_push: bool = false) -> bool: - if not attack or not attack_box: - return false - - var pos: Vector3 = character.pos() - if not attack_dir: - attack_dir = status.skill_dir.normalized() - var result: Array[Character] - if attack_box.is_throw: + var attack_info: Struct.AttackInfo = Struct.AttackInfo.new() + attack_info.attack = status.skill_cfg.get_attack2() + attack_info.attack_box = status.skill_cfg.get_attack2_box() + attack_info.attack_dir = status.skill_dir + attack_info.with_stop = status.skill_cfg.attack2_with_stop + attack_info.ignore_push = status.skill_cfg.ignore_push + add_attack(attack_info) + + +func character_attack1() -> void: + var attack_info: Struct.AttackInfo = Struct.AttackInfo.new() + attack_info.attack = status.cfg.get_attack1() + attack_info.attack_box = status.cfg.get_attack1_box() + attack_info.attack_dir = status.move_dir + add_attack(attack_info) + + +func character_attack2() -> void: + var attack_info: Struct.AttackInfo = Struct.AttackInfo.new() + attack_info.attack = status.cfg.get_attack2() + attack_info.attack_box = status.cfg.get_attack2_box() + attack_info.attack_dir = status.move_dir + add_attack(attack_info) + + +func add_attack(attack_info: Struct.AttackInfo) -> void: + var result: Character + if attack_info.attack_box.is_throw: var target: Character = Global.character_mgr.get_character(status.throw_target) if target: - result = [target] - elif attack_box.is_direct: + result = target + elif attack_info.attack_box.is_direct: var target: Character = Global.character_mgr.get_character(status.target) if target: - result = [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 - if not shape: - 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: - is_hit = true - continue - if hit_self != (target.team() == character.team()): - continue - var hit_result: HitResult = settle(character.id(), target.id(), attack_dir, attack, with_stop, ignore_push) - on_attack_hit(hit_result) - is_hit = true - if !is_hit and with_pause_frame: - skill.on_attack_miss() - return is_hit - - -func _debug_draw_attack_box(shape: Shape3D, offset: Vector3) -> void: - if not get_tree().debug_collisions_hint: + battle_attack_area.refresh_attack_area(attack_info) 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 + on_attack_character(result, attack_info) -func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool, ignore_push: bool) -> HitResult: - var hit_result: HitResult = HitResult.new() +func on_attack_character(result: Character, attack_info: Struct.AttackInfo) -> void: + if attack_info.attack_box.is_hit_self != (result.team() == character.team()): + return + var hit_result: Struct.HitResultInfo = settle(character.id(), result.id(), attack_info) + on_attack_hit(hit_result) + + +func settle(from: int, to: int, attack_info: Struct.AttackInfo) -> Struct.HitResultInfo: + var attack: AttackCfg = attack_info.attack + var attack_dir: Vector2 = attack_info.attack_dir + var with_stop: bool = attack_info.with_stop + var ignore_push: bool = attack_info.ignore_push + var hit_result: Struct.HitResultInfo = Struct.HitResultInfo.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 @@ -266,8 +239,8 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool 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) + if attack_dir.x!=0: + character_to.set_status("is_right", attack_dir.x<0) else: match break_level_sub: 1: character_to.add_buff("stagger", 0.3) @@ -280,7 +253,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool if not is_break_skill_real: hit_up_speed *= 0.75 - character_to.set_hit_move(dir, hit_back_speed, hit_up_speed) + character_to.set_hit_move(attack_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) @@ -297,7 +270,7 @@ func settle(from: int, to: int, dir: Vector2, attack: AttackCfg, with_stop: bool 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.set_hit_move(-attack_dir, self_hit_back_speed, 0) character_from.add_buff("hit_back", attack.hit_up_duration) #受击pt掉落 @@ -461,26 +434,35 @@ func change_dir() -> void: status.is_right = cast_dir.x > 0 -func on_attack_hit(hit_result: HitResult) -> void: +func on_attack_hit(hit_result: Struct.HitResultInfo) -> 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") + on_skill_trigger(skill_name, "hit") if hit_result.is_break: - on_attack_hit_trigger(skill_name, "break") + on_skill_trigger(skill_name, "break") + + +func on_skill_release(skill_name: String) -> void: + on_skill_trigger(skill_name, "release") + +func on_skill_cast(skill_name: String) -> void: + on_skill_trigger(skill_name, "cast") -func on_attack_hit_trigger(skill_name: String, trigger_name: String) -> void: + +func on_skill_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) +#====skill_trigger==== + +func on_hero01_long_stab01_cast(): + if status.skill_repeat_count >= 5: + skill.cast_skill_by_name("hero01_long_stab02", status.move_dir) func on_hero01_fist_skill01_break(): diff --git a/script/character/battle_attack_area.gd b/script/character/battle_attack_area.gd new file mode 100644 index 0000000..734ebbc --- /dev/null +++ b/script/character/battle_attack_area.gd @@ -0,0 +1,57 @@ +extends Area3D +class_name BattleAttackArea + +@onready var battle: Battle = (%Battle as Battle) +@onready var collision: CollisionShape3D = (%BattleAttackAreaCollision as CollisionShape3D) + +var is_active: bool +var alive_time: float +var attack_info: Struct.AttackInfo +var attack_id_set: Dictionary = {} + + +func _ready(): + body_entered.connect(on_body_entered) + + +func _process(delta: float) -> void: + if is_active: + alive_time -= delta + if alive_time <= 0: + set_active(false) + + +func refresh_attack_area(attack_info_new: Struct.AttackInfo) -> void: + attack_info = attack_info_new + var offset_xz: Vector2 = attack_info.attack_dir * attack_info.attack_box.offset.x + var offset_y: float = attack_info.attack_box.offset.y + var offset: Vector3 = Vector3(offset_xz.x, offset_y, offset_xz.y) + var shape: Shape3D = attack_info.attack_box.shape + collision.position = offset + collision.shape = shape + + attack_id_set.clear() + alive_time = Setting.animation_frame_rate + set_active(false) + set_active(true) + + +func on_body_entered(body: Node3D): + call_deferred("on_body_entereddeferred", body) + + +func on_body_entereddeferred(body: Node3D): + if body is Character: + if not attack_id_set.has(body.id): + battle.on_attack_character(body, attack_info) + attack_id_set[body.id] = true + + +func set_active(value: bool) -> void: + if value: + alive_time = Setting.animation_frame_rate + else: + alive_time = 0 + + is_active = value + collision.disabled = not value diff --git a/script/character/battle_attack_area.gd.uid b/script/character/battle_attack_area.gd.uid new file mode 100644 index 0000000..5298d7f --- /dev/null +++ b/script/character/battle_attack_area.gd.uid @@ -0,0 +1 @@ +uid://dqsadncw4srh6 diff --git a/script/character/character.gd b/script/character/character.gd index 3c634c0..c03b147 100644 --- a/script/character/character.gd +++ b/script/character/character.gd @@ -236,9 +236,9 @@ func get_character_owner() -> Character: return self -func attack1() -> bool: - return battle.character_attack1() +func attack1() -> void: + battle.character_attack1() -func attack2() -> bool: - return battle.character_attack2() +func attack2() -> void: + battle.character_attack2() diff --git a/script/character/move.gd b/script/character/move.gd index 3b72f36..40dee7b 100644 --- a/script/character/move.gd +++ b/script/character/move.gd @@ -131,10 +131,14 @@ func update_move_check(delta) -> bool: if normal_speed < -6 and normal.y >= 0: #墙体互动 Global.effect_mgr.cast_particle(ResourceManager.particle_hit_ground_heavy, character.pos(), normal) - var velocity_new: Vector3 = velocity - normal * normal_speed * 2 - var attack_dir: Vector2 = Vector2(velocity_new.x, velocity_new.z).normalized() + var velocity_new: Vector3 = velocity - normal * normal_speed * 2 + var attack_dir: Vector2 = Vector2(velocity_new.x, velocity_new.z).normalized() character.velocity = Vector3.ZERO - battle.add_attack(ResourceManager.cfg_attack_rebound, ResourceManager.cfg_attack_box_rebound, true, attack_dir) + var attack_info: Struct.AttackInfo = Struct.AttackInfo.new() + attack_info.attack = ResourceManager.cfg_attack_rebound + attack_info.attack_box = ResourceManager.cfg_attack_box_rebound + attack_info.attack_dir = attack_dir + battle.add_attack(attack_info) elif normal_speed <-3: #反弹 Global.effect_mgr.cast_particle(ResourceManager.particle_hit_ground_normal, character.pos(), normal) diff --git a/script/character/player/combo.gd b/script/character/player/combo.gd index 9a62ee4..35c4bc9 100644 --- a/script/character/player/combo.gd +++ b/script/character/player/combo.gd @@ -51,7 +51,7 @@ func update_charging() -> void: if not input.action == release_key: continue refresh_input(i) - battle.on_skill_release_trigger(status.skill_cfg.get_res_name()) + battle.on_skill_release(status.skill_cfg.get_res_name()) break diff --git a/script/character/skill.gd b/script/character/skill.gd index d0679f0..8a793b9 100644 --- a/script/character/skill.gd +++ b/script/character/skill.gd @@ -7,6 +7,8 @@ class_name Skill @onready var effect: Effect = (%Effect as Effect) @onready var buff: Buff = (%Buff as Buff) @onready var move: Move = (%Move as Move) +@onready var battle: Battle = (%Battle as Battle) +@onready var battle_attack_area: BattleAttackArea = (%BattleAttackArea as BattleAttackArea) var skill_dict: Dictionary = {} #name -> skill var skill_map: Dictionary = {} #input -> skillCfg[] @@ -91,8 +93,8 @@ func cast_skill_mp_cost(cfg: SkillCfg) -> bool: return true -func cast_skill_by_name(name: String, cast_dir: Vector2): - var cfg: SkillCfg = skill_dict.get(name) +func cast_skill_by_name(skill_name: String, cast_dir: Vector2) -> void: + var cfg: SkillCfg = skill_dict.get(skill_name) if not cfg: return if not cast_skill_mp_cost(cfg): @@ -118,13 +120,19 @@ func cast_skill(cfg: SkillCfg, cast_dir: Vector2, action_key: String = ""): if cfg.is_lock_x_move: skill_move_dir = cast_dir + #技能重复次数 + if status.skill_cfg and status.skill_cfg == cfg: + status.skill_repeat_count += 1 + else: + status.skill_repeat_count = 0 + break_skill() status.speed_up_rate = -1 status.is_free_control = false status.is_free_turn = false status.is_skill_running = true status.skill_cfg = cfg - status.skill_dir = cast_dir + status.skill_dir = cast_dir.normalized() status.skill_move_dir = skill_move_dir status.break_level = Enum.EBreakLevel.None status.stance = cfg.stance_to @@ -148,6 +156,8 @@ func cast_skill(cfg: SkillCfg, cast_dir: Vector2, action_key: String = ""): play(animation_name, -1, Setting.animation_speed_scale) seek(0, true, true) + battle.on_skill_cast(cfg.get_res_name()) + func break_skill(): stop() @@ -167,6 +177,7 @@ func break_skill(): status.skill_action_key = "" status.set_skill_break_level_add(0) buff.remove_buff("charging") + battle_attack_area.set_active(false) if status.throw_target != 0: var character_to: Character = Global.character_mgr.get_character(status.throw_target) if character_to: @@ -181,12 +192,6 @@ func cancel_skill(): view.reset() -func on_attack_miss(): - # 攻击未命中时跳帧 - _frame_forward() - status.set_skill_break_level_add(-1)#todo - - func on_hold() -> void: _frame_back(1) diff --git a/script/character/status.gd b/script/character/status.gd index 3fce41f..fb8664d 100644 --- a/script/character/status.gd +++ b/script/character/status.gd @@ -12,6 +12,7 @@ class BulletOrder: var cast_dir: Vector2 var target: int + #实体属性 var id: int #id var owner_id: int #所有者id @@ -80,13 +81,12 @@ var skill_cfg: SkillCfg #当前技能 var is_skill_running: bool #技能是否正在释放 var skill_dir: Vector2 #技能释放方向 var skill_move_dir: Vector2 #技能位移方向 +var skill_action_key: String #技能输入指令 +var skill_repeat_count: int #技能重复释放次数 @export var skill_move_speed: float #技能位移速度 @export var skill_float_speed: float #技能y位移速度 @export var skill_move_stop: bool #技能位移速度是否停止生效 - -var skill_action_key: String #技能输入指令 - @export var skill_break_level_add: int #技能额外打断等级 #核心状态 diff --git a/script/config/attack_box_cfg.gd b/script/config/attack_box_cfg.gd index e793817..9d8707d 100644 --- a/script/config/attack_box_cfg.gd +++ b/script/config/attack_box_cfg.gd @@ -5,3 +5,4 @@ class_name AttackBoxCfg @export var offset: Vector2 #偏移 @export var is_throw: bool #是否投技(只命中投技目标) @export var is_direct: bool #是否直接命中 +@export var is_hit_self: bool #是否命中自己 diff --git a/script/config/character_cfg.gd b/script/config/character_cfg.gd index 6e86c1e..03bb9aa 100644 --- a/script/config/character_cfg.gd +++ b/script/config/character_cfg.gd @@ -4,27 +4,28 @@ class_name CharacterCfg #基本信息 @export var name: String @export var type: Enum.ECharacterType -#动画 +@export_group("动画") @export var sprite_frames: SpriteFrames @export var sprite_height: int @export var sprite_width: int -#基本组件 +@export_group("组件") @export var move: CharacterMoveCfg @export var shield: ShieldCfg @export var stun: StunCfg @export var mp: MpCfg @export var ai: AICfg -#战斗信息 +@export var ai_behavior_tree: PackedScene +@export_group("战斗数值") @export var hp_max: float @export var attack: float -#自带技能参数 +@export_group("自带技能参数") @export var attack1: AttackCfg @export var attack1_box: AttackBoxCfg @export var attack2: AttackCfg @export var attack2_box: AttackBoxCfg @export var sub_character: CharacterCfg @export var sub_character_auto_create: bool -#材质 +@export_group("受击材质") @export var material_on: Enum.EMaterial = Enum.EMaterial.None #有护盾时材质 @export var material_off: Enum.EMaterial = Enum.EMaterial.None #无护盾时材质 @@ -52,6 +53,8 @@ func get_particle()->Resource: func get_ai()->PackedScene: + if ai_behavior_tree: + return ai_behavior_tree var res_name: String = get_res_name() var path_default: String = "res://scene/ai/%s.tscn" % res_name if ResourceLoader.exists(path_default): diff --git a/script/config/skill_cfg.gd b/script/config/skill_cfg.gd index 0915fd4..62d6840 100644 --- a/script/config/skill_cfg.gd +++ b/script/config/skill_cfg.gd @@ -15,11 +15,9 @@ var refresh_animation: Callable = check_animation @export_group("攻击参数") @export var attack1: AttackCfg @export var attack1_box: AttackBoxCfg -@export var attack1_with_pause_frame: bool @export var attack1_with_stop: bool @export var attack2: AttackCfg @export var attack2_box: AttackBoxCfg -@export var attack2_with_pause_frame: bool @export var attack2_with_stop: bool @export_group("数值和标记") @export var mp_cost: int diff --git a/script/editor_tool/editor_tool.gd b/script/editor_tool/editor_tool.gd index 17c0877..77cc6f4 100644 --- a/script/editor_tool/editor_tool.gd +++ b/script/editor_tool/editor_tool.gd @@ -24,10 +24,6 @@ extends Node3D print("done.") -func _process(delta: float) -> void: - pass - - func process_mesh_lib(dir_name: String) -> void: var dir := DirAccess.open(dir_name) if not dir: diff --git a/script/manager/resource_manager.gd b/script/manager/resource_manager.gd index 867ab10..02f70b2 100644 --- a/script/manager/resource_manager.gd +++ b/script/manager/resource_manager.gd @@ -57,4 +57,4 @@ var cfg_character_monster_test4: CharacterCfg = load("res://config/character/mon var cfg_attack_normal: AttackCfg = load("res://config/attack/sharp_normal_hit.tres") as AttackCfg var cfg_attack_box_normal: AttackBoxCfg = load("res://config/attack_box/circle_normal.tres") as AttackBoxCfg var cfg_attack_rebound: AttackCfg = load("res://config/attack/rebound.tres") as AttackCfg -var cfg_attack_box_rebound: AttackBoxCfg = load("res://config/attack_box/circle_normal.tres") as AttackBoxCfg +var cfg_attack_box_rebound: AttackBoxCfg = load("res://config/attack_box/rebound.tres") as AttackBoxCfg