|  |  |  | extends Node3D | 
					
						
							|  |  |  | class_name PlayerAction | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | @onready var test_bullet: CharacterCfg = load("res://config/character/bullet01.tres") as CharacterCfg | 
					
						
							|  |  |  | @onready var character: Character = (get_owner() as Character) | 
					
						
							|  |  |  | @onready var status: Status = (%Status as Status) | 
					
						
							|  |  |  | @onready var combo: Combo = (%Combo as Combo) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | var lock_cd_dict: Dictionary = {} | 
					
						
							|  |  |  | var is_lock: bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func _process(delta) -> void: | 
					
						
							|  |  |  | 	#更新主动锁定目标cd | 
					
						
							|  |  |  | 	for key in lock_cd_dict: | 
					
						
							|  |  |  | 		if lock_cd_dict[key] > 0: | 
					
						
							|  |  |  | 			lock_cd_dict[key] -= delta | 
					
						
							|  |  |  | 		else: | 
					
						
							|  |  |  | 			lock_cd_dict.erase(key) | 
					
						
							|  |  |  | 	#当前锁定目标死亡 | 
					
						
							|  |  |  | 	if status.target and not is_target_lockable(status.target): | 
					
						
							|  |  |  | 		character.set_target(0) | 
					
						
							|  |  |  | 	#没有锁定目标 尝试被动锁定 | 
					
						
							|  |  |  | 	if not status.target and not is_lock: | 
					
						
							|  |  |  | 		var enemy_list: Array[Character] = Global.character_mgr.get_enemy_list(character.id()) | 
					
						
							|  |  |  | 		var pos_player: Vector2          = character.pos2D() | 
					
						
							|  |  |  | 		enemy_list.filter( func(a: Character): return a.pos2D().distance_squared_to(pos_player)<3) | 
					
						
							|  |  |  | 		enemy_list.sort_custom( | 
					
						
							|  |  |  | 			func(a: Character, b: Character): | 
					
						
							|  |  |  | 				return a.pos2D().distance_squared_to(pos_player) < b.pos2D().distance_squared_to(pos_player) | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		if enemy_list: | 
					
						
							|  |  |  | 			character.set_target(enemy_list[0].id()) | 
					
						
							|  |  |  | 			character.set_is_lock(is_lock) | 
					
						
							|  |  |  | 	#锁定状态有变化 尝试主动锁定 | 
					
						
							|  |  |  | 	if status.is_lock == is_lock: | 
					
						
							|  |  |  | 		return | 
					
						
							|  |  |  | 	if is_lock: | 
					
						
							|  |  |  | 		var enemy_list: Array[Character] = Global.character_mgr.get_enemy_list(character.id()) | 
					
						
							|  |  |  | 		var pos_player: Vector2          = character.pos2D() | 
					
						
							|  |  |  | 		enemy_list.filter( func(a: Character): return is_target_lockable(a.id())) | 
					
						
							|  |  |  | 		enemy_list.sort_custom( | 
					
						
							|  |  |  | 			func(a: Character, b: Character): | 
					
						
							|  |  |  | 				var a_lock_cd: bool = a.id() in lock_cd_dict | 
					
						
							|  |  |  | 				var b_lock_cd: bool = b.id() in lock_cd_dict | 
					
						
							|  |  |  | 				if a_lock_cd != b_lock_cd: | 
					
						
							|  |  |  | 					return b_lock_cd | 
					
						
							|  |  |  | 				return a.pos2D().distance_squared_to(pos_player) < b.pos2D().distance_squared_to(pos_player) | 
					
						
							|  |  |  | 		) | 
					
						
							|  |  |  | 		if enemy_list: | 
					
						
							|  |  |  | 			character.set_target(enemy_list[0].id()) | 
					
						
							|  |  |  | 			enemy_list[0].set_effect_lock(true) | 
					
						
							|  |  |  | 	else: | 
					
						
							|  |  |  | 		if status.target: | 
					
						
							|  |  |  | 			var target = Global.character_mgr.get_character(status.target) | 
					
						
							|  |  |  | 			if target: | 
					
						
							|  |  |  | 				target.set_effect_lock(false) | 
					
						
							|  |  |  | 				lock_cd_dict[status.target] = 0.5 #0.5秒内无法再次主动锁定 | 
					
						
							|  |  |  | 	character.set_is_lock(is_lock) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_action(key: String, is_pressed: bool) -> bool: | 
					
						
							|  |  |  | 	if is_pressed and check_action_pressed(key): | 
					
						
							|  |  |  | 		return true | 
					
						
							|  |  |  | 	match key: | 
					
						
							|  |  |  | 		"lock": lock(is_pressed) | 
					
						
							|  |  |  | 		"switch": switch(is_pressed) | 
					
						
							|  |  |  | 		_: return false | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func check_action_pressed(key: String) -> bool: | 
					
						
							|  |  |  | 	match key: | 
					
						
							|  |  |  | 		"weapon_pre": combo.weapon_index_change(-1) | 
					
						
							|  |  |  | 		"weapon_next": combo.weapon_index_change(1) | 
					
						
							|  |  |  | 		"test_1": | 
					
						
							|  |  |  | 			Global.character_mgr.create_character(ResourceManager.cfg_character_monster_test4, Enum.ETeam.Monster, character.pos()) | 
					
						
							|  |  |  | 		"test_2": | 
					
						
							|  |  |  | 			for i in range(50): | 
					
						
							|  |  |  | 				Global.character_mgr.create_character(ResourceManager.cfg_character_monster_test2, Enum.ETeam.Monster, character.pos()) | 
					
						
							|  |  |  | 		"test_3": | 
					
						
							|  |  |  | 			Global.character_mgr.create_character(ResourceManager.cfg_character_monster_test3, Enum.ETeam.Monster, character.pos()) | 
					
						
							|  |  |  | 		_: return false | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func is_target_lockable(target_id: int) -> bool: | 
					
						
							|  |  |  | 	var target: Character = Global.character_mgr.get_character(target_id) | 
					
						
							|  |  |  | 	if not target: | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	if target.cfg().type != Enum.ECharacterType.Monster: | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	if target.team() == character.team(): | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	if target.get_status("is_dead"): | 
					
						
							|  |  |  | 		return false | 
					
						
							|  |  |  | 	return true | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func lock(is_pressed: bool): | 
					
						
							|  |  |  | 	is_lock = is_pressed | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func switch(is_pressed: bool): | 
					
						
							|  |  |  | 	character.set_status("is_switch", is_pressed) |