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.
		
		
		
		
		
			
		
			
				
	
	
		
			106 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			GDScript
		
	
			
		
		
	
	
			106 lines
		
	
	
		
			3.4 KiB
		
	
	
	
		
			GDScript
		
	
| 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)
 |