How to block a move?

What are the ways to block a move?

Blocking the move is a process that stems from the characteristics of the target. If there is a reason why the target causes a move block, then the functions related to blocking should return true instead of false and indicate the reason for the block with a message before returning true.

From the move code itself

Some moves may fail due to their mechanics. For example, using Bind on a target that is already under the effect of Bind should fail. To accomplish this, there is a method in moves: move_blocked_by_target? which should return true if the target is already under the effect of Bind.

Example with "Octolock"

Code d'Octoprise

Note : If you wish to learn more about move_blocked_by_target?, please visit the Understanding the move_blocked_by_target? function section at the end of the article.

From the code of an effect

Effects expose a function that returns true when move_blocked_by_target? is invoked. This method is called on_move_prevention_target. The functionality is similar to move_blocked_by_target?; if you return true, then the move will dodge. This is useful for creating effects (abilities, items, weather, terrains, etc.) that allow a Pokémon to be immune to certain moves.

Example with the Ability "Good as Gold"

Code de Corps en Or

Understanding the function move_blocked_by_target?

Code de move_blocked_by_target

What particularly interests us in this function:

  • exec_hooks(Move, :move_prevention_target, binding)

exec_hooks: It is a method that is called to execute a series of Hooks. Hooks are functions or procedures that are triggered in response to certain events or conditions in the program. They allow for modifying the standard behavior of a function or adding additional functionalities without changing the original code of the function.

Move: This first argument specifies the context or the application domain of the Hooks to be executed. Here, Move indicates that the Hooks are related to Pokémon's moves. Move represents the class that groups together the Hooks related to moves.

:move_prevention_target: The second argument is a symbol that specifically identifies the Hooks to be executed. In this case, :move_prevention_target refers to a set of Hooks intended to check if the user Pokémon can perform a certain move. These Hooks can include checks for conditions such as status effects, terrain effects, weather conditions, etc., which might prevent the use of the move.

binding: The third argument, binding, is a bit more complex. In Ruby, a binding is an object that encapsulates the execution context of a piece of code, including local variables, available methods, the value of self, etc. Passing binding to exec_hooks thus allows the Hooks to access the context in which exec_hooks was called. This means they can read and modify local variables, call methods, and so on, as if they were part of the original code of the method move_blocked_by_target?.

Understanding the procedure of the function move_blocked_by_target?

Hook Call

When exec_hooks(Move, :move_prevention_target, binding) is executed, it searches for and executes all the Hooks associated with the event or condition :move_prevention_target in the context of moves (Move).

Handling the value returned by the Hook

If none of the executed Hooks raises a Hooks::ForceReturn exception, the move_blocked_by_target? function continues its normal execution and reaches the return false at the end, indicating that the move will not be blocked.

However, if a Hook decides that the move should not be used and returns true (either directly or via an exception like Hooks::ForceReturn with set to true), the execution flow of move_blockedby_target? is interrupted, and it returns true to its caller.

Consequences of a return true

The return of true indicates that something has prevented the use of the move. This can be due to various game-specific reasons, a terrain effect, effects of abilities, etc.

The calling function or method that invoked move_blocked_by_target? must then handle this true to decide on the subsequent actions. For example, this may result in a message being displayed to the user indicating that the move has been blocked.