For the main page about items, see Items.

This page describes how item effects are defined.

Ways to use an item

Most items have an effect. A Potion will restore up to 20HP, for instance. These effects are all written in the scripts, in up to several different places depending on the kind of item and how it is used (e.g. from the Bag, in battle, as a registered item, etc.). This section of the page describes the different ways an item can be actively used, and how to set up general item effects in each case. See below for passive effects (e.g. held items), Poké Ball effects and so forth.

The script sections PItem_ItemEffects and PItem_BattleItemEffects contain all the item effects for items that are actively used. As there are several different ways an item can be used, there are several different handlers, one for each way. There are six such handlers:

Handler Description
UseFromBag For when the item is being used from the Bag, but not on a chosen Pokémon. Typically used for Escape Rope, Repels, all usable Key Items and a few others.

Returns one of the following numbers:

  • 0 - The item was not used.
  • 1 - The item was used, and the Bag screen stays open.
  • 2 - The item was used, and the Bag screen is closed.
  • 3 - The item was used, and it was consumed.
  • 4 - The item was used, it was consumed, and the Bag screen is closed.
UseOnPokemon For when the item is to be used on one particular Pokémon in your party (which the player chooses). This includes Potions, Revives, Ethers, evolution stones, etc.

Returns TRUE if the item was used, and FALSE if it wasn't.

UseInField For when the item needs to close the Bag screen in order to be used, or if it is being used in the field as a registered item. For Repels, Honey, Black/White Flutes, Escape Rope and all appropriate Key Items. Items that do not have this handler cannot be registered.
BattleUseOnPokemon For when the item is to be used on one particular Pokémon in your party (which the player chooses) during battle. Is for nearly all items that also have a UseOnPokemon handler (except ones that can't be used in battle, obviously), and also for items that affect attraction/confusion (which are in-battle-only statuses).

Returns TRUE if the item was used, and FALSE if it wasn't.

BattleUseOnBattler For when the item is to be used on a Pokémon that is currently in battle (which you choose). For X Attack et al and all Poké Balls (to decide if it can be used).

Returns TRUE if the item was used, and FALSE if it wasn't.

UseInBattle For when the item is being used in battle, but not on a Pokémon you choose. For Poké Doll (automatic escape from battle), Poké Flute (affects all battlers) and all Poké Balls (to start the capture process).

Many items can be used in more than one of the situations described above. The new item's effect must be written separately for each handler (e.g. Potion has a defined effect both for UseOnPokemon and BattleUseOnPokemon). Many items will have the exact same effect for each of its handlers, but some do not (e.g. Old Rod, other Key Items). If in doubt, look at existing items that have similar effects to your new item to decide which handlers you need, and what each handler should do.

Notice that whenever an item is referred to, it is preceded by a colon (:). This colon is important.

Examples

ItemHandlers::UseOnPokemon.add(:POTION,proc { |item,pkmn,scene|
  next pbHPItem(pkmn,20,scene)
})

This describes what a Potion does. This particular example is the UseOnPokemon handler; there is also a BattlerUseOnPokemon handler for the Potion, which has an identical effect to this one.

It calls def pbHPItem, which changes the HP of a single Pokémon, and tells it to add 20. That method will add as much HP as possible, up to that value.

ItemHandlers::UseOnPokemon.add(:ANTIDOTE,proc { |item,pkmn,scene|
  if pkmn.fainted? || pkmn.status!=PBStatuses::POISON
    scene.pbDisplay(_INTL("It won't have any effect."))
    next false
  end
  pkmn.healStatus
  scene.pbRefresh
  scene.pbDisplay(_INTL("{1} was cured of its poisoning.",pkmn.name))
  next true
})

This describes what an Antidote does (cures the poison effect). This particular example is the UseOnPokemon handler; there is also a BattleUseOnPokemon handler for the Antidote, which has an identical effect to this one.

ItemHandlers::UseOnPokemon.copy(:ANTIDOTE,:PECHABERRY)

This line copies the UseOnPokemon handler effect of Antidote and gives it to Pecha Berry. The BattleUseOnPokemon handler effect must be copied separately (but in the same way - only the handler's name is different).

ItemHandlers::UseOnPokemon.copy(:AWAKENING,:CHESTOBERRY,:BLUEFLUTE,:POKEFLUTE)

You can copy an item's handler effect to multiple other items at once. Here, Awakening's UseOnPokemon handler effect is copied to three other items at once.

ItemHandlers::UseOnPokemon.addIf(proc { |item| pbIsEvolutionStone?(item)},
  proc { |item,pkmn,scene|
    if pkmn.shadowPokemon?
      scene.pbDisplay(_INTL("It won't have any effect."))
      next false
    end
    newspecies = pbCheckEvolution(pkmn,item)
    if newspecies<=0
      scene.pbDisplay(_INTL("It won't have any effect."))
      next false
    end
    pbFadeOutInWithMusic {
      evo = PokemonEvolutionScene.new
      evo.pbStartScreen(pkmn,newspecies)
      evo.pbEvolution(false)
      evo.pbEndScreen
      if scene.is_a?(PokemonPartyScreen)
        scene.pbRefreshAnnotations(proc { |p| pbCheckEvolution(p,item)>0 })
        scene.pbRefresh
      end
    }
    next true
  }
)

This code describes what an evolution stone does. It only has the UseOnPokemon handler. There is no code difference here depending on which particular evolution stone is being used. This is because the def pbCheckEvolution is what checks whether the stone being used will work on the Pokémon or not, and returns a value for "newSpecies" (either the ID number of the evolved species if it can be used, or 0 if it can't). The effect then carries out depending on this value.

This handler applies to any item which matches the proc given in the first line, rather than matching a specific item. This is done by using UseOnPokemon.addIf rather than UseOnPokemon.add, and by providing a proc into which is passed the item being used.

ItemHandlers::UseFromBag.add(:OLDROD,proc { |item|
  terrain = pbFacingTerrainTag
  notCliff = $game_map.passable?($game_player.x,$game_player.y,$game_player.direction,$game_player)
  if (PBTerrain.isWater?(terrain) && !$PokemonGlobal.surfing && notCliff) ||
     (PBTerrain.isWater?(terrain) && $PokemonGlobal.surfing)
    next 2
  end
  pbMessage(_INTL("Can't use that here."))
  next 0
})

ItemHandlers::UseInField.add(:OLDROD,proc { |item|
  terrain = pbFacingTerrainTag
  notCliff = $game_map.passable?($game_player.x,$game_player.y,$game_player.direction,$game_player)
  if !PBTerrain.isWater?(terrain) || (!notCliff && !$PokemonGlobal.surfing)
    pbMessage(_INTL("Can't use that here."))
    next 0
  end
  encounter = $PokemonEncounters.hasEncounter?(EncounterTypes::OldRod)
  if pbFishing(encounter,1)
    pbEncounter(EncounterTypes::OldRod)
  end
  next 1
})

These are the two handlers for the Old Rod. Note that they are different. The first one does a check for whether it can be used - if successful (i.e. when used while facing water, but not off a clifftop), all it does is "next 2", which means that the Bag screen should be closed and the UseInField handler for that item should then be run. If the Old Rod cannot be used, the Bag screen is not closed in the first place.

If the Old Rod has been registered and is being used that way, it performs the UseInField handler effect immediately instead. The UseInField handler is the one that actually describes what the Old Rod does.


Note that some items which have a UseInField handler counterpart will NOT simply "next 2" in its UseFromBag handler effect (e.g. Town Map, Coin Case), even if it can be used. Those items do not need to close the Bag screen in order to do something. In this case, the two handlers are simply identical.

Poké Balls

Poké Balls can have several different effects, from changing the likelihood of capturing a Pokémon to making the captured Pokémon happier. These effects are not defined in the same place as above, but in the script section PokeBall_CatchEffects.

All effects of Poké Balls are written in one or more handlers. The possible handlers are as follows:

Handler Description
IsUnconditional If present, it will always be called as soon as the wild Pokémon has been absorbed into the Poké Ball. If this handler returns TRUE, then the capture is successful, regardless of anything else.

By default, only the Master Ball has this handler (and it always returns TRUE).

ModifyCatchRate Changes the catch rate of the Poké Ball. This change can depend on any factor of the Pokémon to be captured (e.g. level, weight, type, how it evolves), and/or on any condition of the battle (e.g. turn count, environment, time of day).

Most Poké Balls have one of these handlers.

OnCatch Describes an effect that happens after a successful capture.

The Heal Ball will heal the captured Pokémon, and the Friend Ball sets its happiness to 200.

OnFailCatch Describes an effect that happens after a failed capture attempt.

There is no existing Poké Ball which has this kind of effect, but you could create a Poké Ball that, for example, puts the Pokémon to sleep if it fails to capture it.

Other effects of Poké Balls (e.g. Luxury Ball increases happiness gain) need to be defined separately. There is no standard code for this, as these additional effects could vary wildly.

When defining a new Poké Ball, in addition to defining its effect, it will also need to be listed in the hash $BallTypes at the top of the script section PokeBall_CatchEffects. The number given to a Poké Ball here determines the filename of Poké Ball graphics used in battle and the summary screens.

Examples

BallHandlers::ModifyCatchRate.add(:GREATBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
  next catchRate*1.5
})

A Great Ball is 1.5x as effective as a regular Poké Ball. This code reflects this by multiplying "catchRate" by 1.5.

BallHandlers::ModifyCatchRate.add(:DIVEBALL,proc { |ball,catchRate,battle,battler,ultraBeast|
  catchRate *= 3.5 if battle.environment==PBEnvironment::Underwater
  next catchRate
})

A Dive Ball is 3.5x as effective as a regular Poké Ball, but only if used while underwater. It has the same effectiveness as a regular Poké Ball if it is used above water.

BallHandlers::IsUnconditional.add(:MASTERBALL,proc { |ball,battle,battler|
  next true
})

The Master Ball will always capture a Pokémon. Because an IsUnconditional handler is always called as soon as a Pokémon is absorbed into a Poké Ball, and because this handler always returns TRUE, the capture will always be successful.

BallHandlers::OnCatch.add(:FRIENDBALL,proc { |ball,battle,pkmn|
  pkmn.happiness = 200
})

The Friend Ball doesn't change the capture rate, but it does change the happiness of the captured Pokémon upon capture. This is the code that does so. Any other effects that occur upon successfully capturing a Pokémon (these effects usually only affect the captured Pokémon) can use this handler (e.g. the Heal Ball restoring the captured Pokémon to full health).

TMs and HMs

Main article: Learning moves

TMs and HMs are also used in a different way to the methods mentioned above. All TMs and HMs work in exactly the same way, with the one exception being that a TM will be consumed after use (unless the setting INFINITE_TMS is set to true).

The page Learning moves contains more information about how a move is taught. The only requirement for creating a TM or HM item is to define it as one.

Mail

Mail items cannot be used like other items, but instead can be read. Reading a mail item from the Bag will simply show the blank mail, while reading a mail item being held by a Pokémon will show the mail and its message.

When a mail item is given to a Pokémon to hold, the player can enter a message. It is automatically signed with the player's name. If the mail is defined as one which shows Pokémon on it, then the holder and the next two Pokémon currently in the player's party will appear as icons on the mail, in order of right to left.

A mail's message (and details of the Pokémon to show on it) are saved as a property of the Pokémon holding the mail. See the page Editing a Pokémon for an explanation of how to set the message, sender's name and icons for a held mail item.

The only requirement for creating a mail item is to define it as one.

Held items

Some items have effects if they are held by a Pokémon, such as making certain types of moves stronger in battle, giving more experience or making a particular weather move last longer. There are standard ways to define the more common types of held item effects, all of which are in the script section BattleHandlers_Items.

Each type of effect has its own type of battle handler. These are much the same as the handlers shown above. They will not be described in detail here, and the advice is to look at items with similar effects to a new one you want to add and to see how they work.

Some item battle effects do not have handlers, usually because they are so niche that it isn't worth creating a handler for them.

Held items which have effects outside of battle do not have any standard code or handlers, again because they are so niche. These include the Destiny Knot (for breeding), Cleanse Tag/Pure Incense (for avoiding wild encounters), Everstone (prevents evolution) and Soothe Bell (for happiness gain).

Special item effects

There are some items, usually Key Items, that have unique or significant effects when used. These include:

It is best to look at the scripts directly to see how these items work.

In general, any other Key Items are used passively. That is, an event will check to see if the player has a particular Key Item (e.g. Key Card), rather than the player having to actively use that item. Checks like this are described in the page Manipulating items.

Use by enemy trainers

Main article: Battle AI

Some items can be used by enemy trainers during battle. By default, the AI knows how to use HP-restoring items, status problem-curing items and X items (e.g. X Attack).

The decisions of which item should be used are coded in the script section AI_Item. If you add an item and want the AI to be able to use it, you should add code in here for it.

Community content is available under CC-BY-SA unless otherwise noted.