You cannot select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
	
	
		
			161 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			GDScript
		
	
			
		
		
	
	
			161 lines
		
	
	
		
			4.9 KiB
		
	
	
	
		
			GDScript
		
	
| 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
 |