|  |  |  | extends Node3D | 
					
						
							|  |  |  | class_name Combo | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var character: Character = (get_owner() as Character) | 
					
						
							|  |  |  | @onready var status: Status = (%Status as Status) | 
					
						
							|  |  |  | @onready var skill: Skill = (%Skill as Skill) | 
					
						
							|  |  |  | @onready var move: Move = (%Move as Move) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class InputData: | 
					
						
							|  |  |  |     var action: String | 
					
						
							|  |  |  |     var alive_time: float | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var skill_map: Dictionary      = {} #input -> skill[]  | 
					
						
							|  |  |  | var input_list: Array[Variant] = [] #指令缓存 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _ready(): | 
					
						
							|  |  |  |     # test | 
					
						
							|  |  |  |     add_weapon(load("res://config/weapon/long.tres") as WeaponCfg) | 
					
						
							|  |  |  |     #add_weapon(load("res://config/weapon/short.tres") as WeaponCfg) | 
					
						
							|  |  |  |     add_weapon(load("res://config/weapon/fist.tres") as WeaponCfg) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _process(delta): | 
					
						
							|  |  |  |     update_input_alive(delta) | 
					
						
							|  |  |  |     update_break() | 
					
						
							|  |  |  |     update_move() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func update_input_alive(delta): | 
					
						
							|  |  |  |     var input_list_new: Array[Variant] = [] | 
					
						
							|  |  |  |     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: bool = 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() -> bool: | 
					
						
							|  |  |  |     return update_break_by_level(Enum.EBreakLevel.Cancel) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func update_break_jump() -> bool: | 
					
						
							|  |  |  |     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() -> bool: | 
					
						
							|  |  |  |     return update_break_by_level(Enum.EBreakLevel.Break) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func update_break_walk() -> bool: | 
					
						
							|  |  |  |     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) -> bool: | 
					
						
							|  |  |  |     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: SkillPlayerCfg = skill_cfg as SkillPlayerCfg | 
					
						
							|  |  |  |             if skill_player_weapon_cfg.break_level != break_level: | 
					
						
							|  |  |  |                 continue | 
					
						
							|  |  |  |             var stance_from: Enum.EStance = skill_player_weapon_cfg.stance_from | 
					
						
							|  |  |  |             if (stance_from != status.stance) and (int(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) -> void: | 
					
						
							|  |  |  |     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: SkillPlayerCfg in Util.get_skill_player_weapon_by_weapon(weapon): | 
					
						
							|  |  |  |         var skill_player_weapon: SkillPlayerCfg = 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) -> void: | 
					
						
							|  |  |  |     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) | 
					
						
							|  |  |  |     return |