diff --git a/scenes/player.gd b/scenes/player.gd index 148618c..95bcd7a 100644 --- a/scenes/player.gd +++ b/scenes/player.gd @@ -1139,8 +1139,10 @@ func start_movement_along_path(path: Array, clear_visual: bool = true): has_moved_this_turn = path.size() <= movement_range - if main: - if not (is_bot or is_in_group("Bots")): + if not (is_bot or is_in_group("Bots")): + # Only reset to NONE if we were in MOVING state (voluntary movement). + # If we were TARGETING/GRABBING and got pushed, preserve that state. + if main.ui_manager.current_action_state == main.ui_manager.ActionState.MOVING: main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE if TurnManager.turn_based_mode: diff --git a/scripts/managers/player_input_manager.gd b/scripts/managers/player_input_manager.gd index 1d7216d..2673c29 100644 --- a/scripts/managers/player_input_manager.gd +++ b/scripts/managers/player_input_manager.gd @@ -46,7 +46,42 @@ func _process(delta): if target_position != player.current_position: movement_manager.simple_move_to(target_position) - # Targeting Inputs (1, 2, 3, 4) + # === KEYBOARD SHORTCUTS (User Request) === + + # Numpad 1: Speed (Enum 0) + if Input.is_key_pressed(KEY_KP_1): + player.attempt_target_action(0) # FASTER_SPEED + + # Numpad 2: Wall (Enum 2) + elif Input.is_key_pressed(KEY_KP_2): + player.attempt_target_action(2) # BLOCK_FLOOR + + # Numpad 3: Freeze (Enum 1) + elif Input.is_key_pressed(KEY_KP_3): + player.attempt_target_action(1) # AREA_FREEZE + + # Numpad 4: Ghost (Enum 3) + elif Input.is_key_pressed(KEY_KP_4): + player.attempt_target_action(3) # INVISIBLE_MODE + + # C: Special Attack (Attack Mode) - Boost + elif Input.is_key_pressed(KEY_C): + if player.powerup_manager: + player.powerup_manager.use_special_effect() + + # V: Spawn Boost Item + elif Input.is_key_pressed(KEY_V): + if player.powerup_manager: + # Verify the method exists first (it was added recently/confirmed available) + if player.powerup_manager.has_method("spawn_boost_reward"): + player.powerup_manager.spawn_boost_reward() + else: + # Fallback if method missing + player.powerup_manager.use_special_effect() + + # Original 1-4 keys (Succession order 0-3) - Keeping as fallback? + # User didn't ask to remove them, but new Numpad bindings are specific. + # We can leave them for now unless they conflict. if Input.is_key_pressed(KEY_1): player.attempt_target_action(0) elif Input.is_key_pressed(KEY_2): @@ -82,7 +117,7 @@ func _process(delta): player.highlight_cells_if_authorized(area, highlight_id) func handle_unhandled_input(event): - # Early return if not authorized human player + # 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 diff --git a/scripts/managers/special_tiles_manager.gd b/scripts/managers/special_tiles_manager.gd index 43de432..601583d 100644 --- a/scripts/managers/special_tiles_manager.gd +++ b/scripts/managers/special_tiles_manager.gd @@ -81,10 +81,11 @@ func execute_targeted_effect(effect: int, target_pos: Vector2i): # Animation / Shake if player.is_multiplayer_authority(): player.rpc("trigger_screen_shake", "light") - # Also reset action loop? - var main = player.get_tree().get_root().get_node_or_null("Main") - if main and main.ui_manager: - main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE + # Also reset action loop? (ONLY for human players) + if not (player.is_bot or player.is_in_group("Bots")): + var main = player.get_tree().get_root().get_node_or_null("Main") + if main and main.ui_manager: + main.ui_manager.current_action_state = main.ui_manager.ActionState.NONE # Random shape patterns for 3x3 area (relative offsets from center) @@ -221,18 +222,19 @@ func activate_effect(effect: int, target_player: Node3D = null): SpecialEffect.FASTER_SPEED: _execute_faster_speed() SpecialEffect.AREA_FREEZE, SpecialEffect.BLOCK_FLOOR: - # Enter Targeting Mode instead of executing immediately - var main = player.get_tree().get_root().get_node_or_null("Main") - if main and main.ui_manager: - main.ui_manager.current_action_state = main.ui_manager.ActionState.TARGETING - main.ui_manager.pending_skill_id = effect - NotificationManager.send_message(player, "Select a target area...", NotificationManager.MessageType.NORMAL) - # Do NOT set cooldown yet. Cooldown sets on execution. - # Revert the cooldown set above (hacky but handles the split flow) - powerup_cooldowns[effect] = 0.0 - emit_signal("cooldown_updated", effect, 0.0, 0.0) - print("[SpecialTiles] Entered Targeting Mode for %s" % SpecialEffect.keys()[effect]) - return # Exit, wait for input + # Enter Targeting Mode instead of executing immediately (ONLY for human players) + if not (player.is_bot or player.is_in_group("Bots")): + var main = player.get_tree().get_root().get_node_or_null("Main") + if main and main.ui_manager: + main.ui_manager.current_action_state = main.ui_manager.ActionState.TARGETING + main.ui_manager.pending_skill_id = effect + NotificationManager.send_message(player, "Select a target area...", NotificationManager.MessageType.NORMAL) + # Do NOT set cooldown yet. Cooldown sets on execution. + # Revert the cooldown set above (hacky but handles the split flow) + powerup_cooldowns[effect] = 0.0 + emit_signal("cooldown_updated", effect, 0.0, 0.0) + print("[SpecialTiles] Entered Targeting Mode for %s" % SpecialEffect.keys()[effect]) + return # Exit, wait for input SpecialEffect.INVISIBLE_MODE: _execute_invisible_mode(player)