extends Node3D class_name Combo @onready var character = (get_owner() as Character) @onready var status = (%Status as Status) @onready var skill = (%Skill as Skill) @onready var move = (%Move as Move) class InputData: var action:String var alive_time:float var skill_map = {} #input -> skill[] var input_list = [] #指令缓存 func _ready(): # test add_weapon(load("res://config/weapon/long.tres")) add_weapon(load("res://config/weapon/short.tres")) add_weapon(load("res://config/weapon/fist.tres")) #add_weapon(load("res://config/weapon/chain.tres")) func _process(delta): update_input_alive(delta) update_break() update_move() func update_input_alive(delta): var input_list_new = [] for input in input_list: input.alive_time -= delta if input.alive_time > 0: input_list_new.append(input) input_list = input_list_new func update_break(): for break_level_name in Enum.EBreakLevel: var break_level = Enum.EBreakLevel[break_level_name] if break_level <= status.break_level: var is_break = false match break_level: Enum.EBreakLevel.None: pass Enum.EBreakLevel.Cancel: is_break = update_break_cancel() Enum.EBreakLevel.Jump: is_break = update_break_jump() Enum.EBreakLevel.Break: is_break = update_break_break() Enum.EBreakLevel.Walk: is_break = update_break_walk() if is_break: break func update_break_cancel(): return update_break_by_level(Enum.EBreakLevel.Cancel) func update_break_jump(): for i in range(0,len(input_list)): var input = input_list[i] if input.action == "jump" and not status.is_jumped: refresh_input(i) skill.cancel_skill() move.jump() return true return false func update_break_break(): return update_break_by_level(Enum.EBreakLevel.Break) func update_break_walk(): if status.is_skill_running and status.input_dir.length() > 0: refresh_input(len(input_list)) skill.cancel_skill() return true return false func update_break_by_level(break_level:Enum.EBreakLevel): for i in range(0,len(input_list)): var input = input_list[i] if not input.action in skill_map: continue for skill_cfg in skill_map[input.action]: var skill_player_weapon_cfg = skill_cfg as SkillPlayerCfg if skill_player_weapon_cfg.break_level != break_level: continue var stance_from = skill_player_weapon_cfg.stance_from if stance_from != status.stance and stance_from != Enum.EStance.Any: continue if skill_player_weapon_cfg.weapon: if skill_player_weapon_cfg.weapon != status.weapon_list[status.weapon_index]: continue skill.cast_skill(skill_cfg,status.input_dir) status.stance = skill_player_weapon_cfg.stance_to refresh_input(i) return true return false func refresh_input(index:int): if index >= len(input_list)-1: input_list = [] else: input_list = input_list.slice(index+1) func update_move(): status.move_dir = status.input_dir if status.is_skill_running: pass else: if not status.is_on_floor or status.is_jumping: status.stance = Enum.EStance.AirIdle else: status.stance = Enum.EStance.Idle status.break_level = Enum.EBreakLevel.Walk func add_input_action(action:String): var new_input = InputData.new() new_input.action = action new_input.alive_time = Setting.input_alive_time input_list.append(new_input) func add_skill(action:String,skillCfg:SkillPlayerCfg): if not action in skill_map: skill_map[action] = [] skill_map[action].append(skillCfg) func remove_skill(action:String,skillCfg:SkillPlayerCfg): if not action in skill_map: return skill_map[action].filter(func(cfg): return cfg != skillCfg) func add_weapon(weapon:WeaponCfg): status.weapon_list.append(weapon) for skill_player_weapon_res in Util.get_skill_player_weapon_by_weapon(weapon): var skill_player_weapon = skill_player_weapon_res as SkillPlayerCfg add_skill(skill_player_weapon.action,skill_player_weapon_res) status.emit_status("weapon_list") status.set_status("weapon_index",0) func weapon_index_change(dir:int): if not status.weapon_list: return if status.weapon_index_change_dir: return if abs(dir) != 1: return status.set_status("weapon_index_change_dir",dir) character.add_buff("weapon_index_change",Setting.weapon_anime_duration)