Prevent move selection
Principle
A move can be non-selectable for two distinct reasons:
- From the move itself: the move checks its own conditions and decides it cannot be chosen.
- From an external effect: an active effect on the Pokémon prevents the move from being selected.
In both cases, the prevention is signaled by returning a Proc. This return must be accompanied by a message clearly indicating the reason to the player.
Difference with failure (guide 001): selection prevention happens before the turn, in the battle menu. Failure happens during the turn, at move execution.
From the move
Some moves can be non-selectable based on their own rules. For example, the move Stuff Cheeks cannot be selected if the user is not holding a Berry.
To handle this behavior, override the disable_reason method in the move's class.
Example: Stuff Cheeks
# Get the reason why the move is disabled
# @param user [PFM::PokemonBattler] user of the move
# @return [#call] Block that should be called when the move is disabled
def disable_reason(user)
reason_message = @scene.display_message_and_wait(parse_text_with_pokemon(60, 508, user))
return proc { reason_message } unless user.hold_berry?(user.battle_item_db_symbol)
return super
end
- The call to
superis mandatory to preserve default checks. - If the condition is not met, a
Proccontaining the message is returned to signal that the move is disabled. - If the condition is met (the user holds a Berry),
supertakes over.
From an effect
Some moves can be non-selectable because of an active effect on the user. For example, the Gravity effect prevents selection of gravity-affected moves.
To handle this behavior, use the on_move_disabled_check method in the effect's class.
Example: Gravity
# Function called when we try to check if the user cannot use a move
# @param user [PFM::PokemonBattler]
# @param move [Battle::Move]
# @return [Proc, nil]
def on_move_disabled_check(user, move)
return unless move.gravity_affected?
reason_message = move.scene.display_message_and_wait(parse_text_with_pokemon(19, 1092, user, PFM::Text::MOVE[1] => move.name))
return proc { reason_message }
end
- The first line checks that the move is affected by gravity.
- If it is, a
Proccontaining the message is returned. - If it is not,
nilis implicitly returned (no block).
Special case: coupling with prevention
When using disable_reason to disable a move, you must also implement move_usable_by_user (guide 001). Indeed, a disabled move can still be launched through effects like Metronome that bypass selection.
Similarly, for effects, on_move_disabled_check must be coupled with on_move_prevention_user to cover the case where the move is launched without going through the menu.
Conclusion
- Use
disable_reasonandmove_usable_by_userif the logic depends on the move itself. - Use
on_move_disabled_checkandon_move_prevention_userif the logic depends on an external effect. - Return a
Procto signal that the move is non-selectable. - Always display a clear message to the player indicating the reason.
- Always cover the case where the move is launched without going through the selection menu.