Files
tekton/scripts/managers/player_input_manager.gd
T

217 lines
8.3 KiB
GDScript

extends Node
var player: Node3D
var movement_manager: Node
var race_manager: Node
@onready var SettingsManager = get_node_or_null("/root/SettingsManager")
func initialize(p_player: Node3D, p_movement_manager: Node, p_race_manager: Node):
player = p_player
movement_manager = p_movement_manager
race_manager = p_race_manager
func _process(delta):
# Early return conditions
if not is_instance_valid(player) or not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots") or player.is_frozen or player.is_stop_frozen:
return
if TurnManager.turn_based_mode:
return
# Continuous movement input
var move_vec = Vector2i.ZERO
if Input.is_action_pressed("move_north"): move_vec.y -= 1
if Input.is_action_pressed("move_south"): move_vec.y += 1
if Input.is_action_pressed("move_east"): move_vec.x += 1
if Input.is_action_pressed("move_west"): move_vec.x -= 1
# Fallback for explicit diagonal actions (if mapped)
if move_vec == Vector2i.ZERO:
if Input.is_action_pressed("move_northeast"): move_vec = Vector2i(1, -1)
elif Input.is_action_pressed("move_southeast"): move_vec = Vector2i(1, 1)
elif Input.is_action_pressed("move_southwest"): move_vec = Vector2i(-1, 1)
elif Input.is_action_pressed("move_northwest"): move_vec = Vector2i(-1, -1)
# Action inputs (still momentary)
if Input.is_action_just_pressed("action_grab"):
player.grab_item(player.current_position)
elif Input.is_action_just_pressed("action_put"):
player.auto_put_item()
if move_vec != Vector2i.ZERO:
var target_position = player.current_position + move_vec
movement_manager.simple_move_to(target_position)
# Targeting Mode Preview
var main = player.get_node_or_null("/root/Main")
if main and main.ui_manager and main.ui_manager.current_action_state == main.ui_manager.ActionState.TARGETING:
# Use mouse position raycast to determine hover
var viewport = player.get_viewport()
var mouse_pos = viewport.get_mouse_position()
var camera = viewport.get_camera_3d()
var from = camera.project_ray_origin(mouse_pos)
var to = from + camera.project_ray_normal(mouse_pos) * 1000
var hover_grid = player.raycast_to_grid(from, to)
# print("Targeting Hover: %s, Skill: %d" % [hover_grid, main.ui_manager.pending_skill_id]) # Debug
# Only update if valid position
if hover_grid != Vector2i(-1, -1):
var st_manager = player.get_node_or_null("SpecialTilesManager")
if st_manager:
var area = st_manager.get_skill_affected_area(main.ui_manager.pending_skill_id, hover_grid)
# Choose highlight color/mesh based on skill
# User Request: Use default hover item (1)
var highlight_id = 1
player.highlight_cells_if_authorized(area, highlight_id)
func handle_unhandled_input(event):
# Early return if not authorized human playersa
if not player.is_multiplayer_authority() or player.is_bot or player.is_in_group("Bots"):
player.set_process_unhandled_input(false)
return
var main = player.get_node("/root/Main")
if not main:
return
# Turn-based mouse input (handled in unhandled_input)
if not player.is_multiplayer_authority() or player.is_frozen or player.is_stop_frozen or (TurnManager.turn_based_mode and (not player.is_my_turn or movement_manager.is_moving)):
return
# --- Keyboard Shortcuts (Event-based) ---
if event is InputEventKey and event.pressed and not event.echo:
var mode = LobbyManager.get_game_mode()
var is_sng = mode == GameMode.Mode.STOP_N_GO
# Get dynamic keybinds
var key_p1 = SettingsManager.get_control_keycode("powerup_1")
var key_p2 = SettingsManager.get_control_keycode("powerup_2")
var key_p3 = SettingsManager.get_control_keycode("powerup_3")
var key_p4 = SettingsManager.get_control_keycode("powerup_4")
var ek = event.keycode
# Unified check for PowerUp keys
if ek == key_p1:
player.activate_powerup(0) # FASTER_SPEED
elif ek == key_p2:
if is_sng:
player.activate_powerup(3) # Ghost for SNG P2
else:
player.activate_powerup(2) # Wall for Normal P2
elif ek == key_p3 and not is_sng:
player.activate_powerup(1) # AREA_FREEZE
elif ek == key_p4 and not is_sng:
player.activate_powerup(3) # INVISIBLE_MODE
# Non-Remappable variants (Numpad) - Optional fallback
elif ek == KEY_KP_1:
player.activate_powerup(0)
elif ek == KEY_KP_2:
player.activate_powerup(3 if is_sng else 2)
# Action Buttons (Remappable)
elif ek == SettingsManager.get_control_keycode("attack_mode"):
if player.powerup_manager:
player.powerup_manager.use_special_effect()
if player.is_attack_mode and player.has_method("enter_attack_mode"):
player.enter_attack_mode()
elif ek == SettingsManager.get_control_keycode("spawn_boost"):
if player.is_carrying_tekton and player.powerup_manager:
if player.powerup_manager.has_method("spawn_boost_reward"):
player.powerup_manager.spawn_boost_reward()
elif ek == SettingsManager.get_control_keycode("tekton_grab"):
if not player.is_carrying_tekton and player.powerup_manager:
if player.powerup_manager.can_use_special():
player.grab_tekton()
# Handle spawn point selection if not yet selected
# Handle spawn point selection if not yet selected
if not player.spawn_point_selected and player.highlighted_spawn_points.size() > 0:
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
var camera = player.get_viewport().get_camera_3d()
var from = camera.project_ray_origin(event.position)
var to = from + camera.project_ray_normal(event.position) * 1000
var click_position = player.raycast_to_grid(from, to)
if click_position in player.highlighted_spawn_points:
if player.select_spawn_point(click_position):
return
# Turn-based mouse input
if not player.is_multiplayer_authority() or (TurnManager.turn_based_mode and (not player.is_my_turn or movement_manager.is_moving)):
return
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
if player.is_bot == true or player.is_in_group("Bots"):
player.set_process_unhandled_input(false)
player.set_process_input(false)
return
var camera = player.get_viewport().get_camera_3d()
var from = camera.project_ray_origin(event.position)
var to = from + camera.project_ray_normal(event.position) * 1000
var click_position = player.raycast_to_grid(from, to)
if click_position != Vector2i(-1, -1):
handle_grid_click(click_position)
func handle_grid_click(grid_position: Vector2i):
if player.is_frozen or player.is_stop_frozen or player.is_bot == true or player.is_in_group("Bots"):
return
var main = player.get_node("/root/Main")
if not main:
return
match main.ui_manager.current_action_state:
main.ui_manager.ActionState.MOVING:
if grid_position in player.highlighted_cells:
movement_manager.move_to_clicked_position(grid_position)
main.ui_manager.ActionState.GRABBING:
if grid_position in player.highlighted_cells or grid_position == player.current_position:
player.grab_item(grid_position)
main.ui_manager.ActionState.RANDOMIZING:
if grid_position in player.highlighted_cells:
main.randomize_item_at_position(grid_position)
# Add TARGETING State
main.ui_manager.ActionState.TARGETING:
var skill_id = main.ui_manager.pending_skill_id
if skill_id != -1:
var st_manager = player.get_node_or_null("SpecialTilesManager")
if st_manager:
# Clear Highlights FIRST to avoid overwriting the newly placed tiles
player.clear_highlights()
st_manager.execute_targeted_effect(skill_id, grid_position)
# Reset state
main.ui_manager.pending_skill_id = -1
main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE
func handle_slot_gui_input(event, slot_index, slot_ui) -> int:
if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT:
var main = player.get_tree().get_root().get_node_or_null("Main")
if main.ui_manager.current_action_state == main.ui_manager.ActionState.ARRANGING:
if player.selected_playerboard_slot == -1:
player.select_playerboard_slot(slot_index)
return slot_index
else:
if player.selected_playerboard_slot == slot_index:
player.deselect_playerboard_slot()
return slot_index
elif player.can_move_to_target_playerboard_slot():
player.target_playerboard_slot(slot_index)
main.emit_signal("can_move_item", true)
return slot_index
else:
return -1
return -1