Describe Item

In PSDK all item are a kind of GameData::Item, this kind of object only holds the data about the item. It doesn't tell how PSDK should use this item. In order to do this we have a module in PFM called ItemDescriptor.

This module takes an item (item_id / db_symbol) in parameter of action and returns a Wrapper telling what PSDK has to do. This wrapper is refered as extend_data in many UI.

Properties and function of PFM::ItemDescriptor::Wrapper

You can read several properties from the wrapper:

  • no_effect If this property is set to true, the UI has to display the message telling this item has no effect.
  • chen If this property is set to true, the UI has to display the message telling it's not time to use this item.
  • open_party If this property is set to true, the UI has to open the party in order to let the player choose a Pokemon / Skill in order to use this item.
  • open_skill If this property is set to true, the UI has to open the Skill selection UI in order to let the item perform something on a choosen skill.
  • open_skill_learn If this property is set to a move ID, the Party UI should open the MoveTeaching UI on the choosen Pokémon (if it can learn the move).
  • stone_evolve If this property is set to true, the UI should show if the Pokémon is able to evolve or not with this item.
  • use_before_telling If this property is set to true, the item will be used before the message (allowing to cancel usage) from bag.
  • skill_message_id This property should contain the ID of the message to show in the Summary UI when we choose a skill.

Depending on the properties you'll have, you can call several function that will process the item or tell if the item can be used:

  • on_pokemon_choice(pokemon, scene) This function returns true or false if the Item can be used on the Pokemon.
  • on_pokemon_use(pokemon, scene) This function use the item on the Pokemon.
  • on_skill_choice(skill, scene) This function returns true or false if the Item can be used on the specific Move of the Pokémon.
  • on_skill_use(pokemon, skill, scene) This function apply the item on the choosen move.
  • on_use(scene) This function is called if none of the proprety tells to do anything. (From bag usually.)
  • execute_battle_action This function is called from battle engine, the item should be bound to a Pokemon, the Battle Scene and optionally the move in order to process the item during the battle phase.
  • bind(scene, pokemon, skill = nil) This function binds information to the wrapper so the battle engine can use it without knowing the parameters.

How to define the condition that allows EventItem to be used

EventItem are calling common events (outside of the map), by default they will always be called. If you want to put conditions over the possibility to call the common event call the following method:

PFM::ItemDescriptor.define_event_condition(event_id) do
  # return true or false here
end

Example:

PFM::ItemDescriptor.define_event_condition(11) do
  next false if $game_player.surfing?

  next $game_switches[Yuki::Sw::EV_Bicycle] ||
         $game_switches[Yuki::Sw::Env_CanFly] ||
         $game_switches[Yuki::Sw::Env_CanDig]
end

How to define condition preventing certain item of being use (It's not time)

Some item like sacred ash can only be used if any Pokemon of the party is dead. In order to prevent the item from being used if the condition are not meet you can use the following function:

PFM::ItemDescriptor.define_chen_prevention(klass_or_symbol) do |item|
  # return true if chen tells it's not time
end

Example:

PFM::ItemDescriptor.define_chen_prevention(:sacred_ash) do
  next $actors.none? { |pokemon| pokemon.dead? && !pokemon.egg? }
end

How to define an action that is performed from bag

Some item just do something from the bag (:on_use) to define them use the following function:

PFM::ItemDescriptor.define_bag_use(klass_or_symbol, use_before_telling) do |item, scene|
  # Code executed when item is actually used
end

Note: use_before_telling is set to true if you want to make the item act before the message "this item is used". Setting use_before_telling allows you to return :unused from the block in case the item could not be used.

Example:

PFM::ItemDescriptor.define_bag_use(GameData::RepelItem, true) do |item, scene|
  next $pokemon_party.set_repel_count(item.repel_count) if $pokemon_party.get_repel_count <= 0

  scene.display_message(parse_text(22, 47))
  next :unused
end

How to define an action that is performed on a Pokemon

This kind of action is a bit more complex because you need to define two thing:

  • If the item can be used on the choosen Pokémon
  • What happen if the item is applied on the Pokemon
  • If the game is in battle, what should be done during battle

For that we have 3 methods:

Define the usability of item on a Pokemon

To define if the item can be used on a Pokemon, use the following function:

PFM::ItemDescriptor.define_on_pokemon_usability(klass) do |item, pokemon|
  # Return true if it can be used on this Pokemon
end

Example:

PFM::ItemDescriptor.define_on_pokemon_usability(GameData::StoneItem) do |item, pokemon|
  next false if pokemon.egg?

  next pokemon.evolve_check(:stone, item.id)
end

Define the action that is done on a Pokemon on Map

To define the item action when used on a Pokemon on map, use the following function:

PFM::ItemDescriptor.define_on_pokemon_use(klass) do |item, pokemon, scene|
  # Perform the action
end

Example:

PFM::ItemDescriptor.define_on_pokemon_use(GameData::StoneItem) do |item, pokemon, scene|
  id, form = pokemon.evolve_check(:stone, item.id)
  scene.call_scene(GamePlay::Evolve, pokemon, id, form, true) do |evolve_scene|
    scene.running = false
    $bag.add_item(item.id, 1) unless GamePlay::Evolve.from(evolve_scene).evolved
  end
end

Define the action that is done on a Pokemon in Battle

To define the item action when used in Battle, use the following function:

PFM::ItemDescriptor.define_on_pokemon_battler_use(klass) do |item, pokemon, scene|
  # Perform the action
end

How to define an action performed over a move of a Pokemon

This one is even harder than defining actions performed over a Pokemon because first of all you have to define the usability over a Pokemon and then the usability over the move.

We then also have 3 methods:

Define the usability of the item over a Move

To define if an item can act over a move, use the following function:

PFM::ItemDescriptor.define_on_move_usability(klass, skill_message_id = 34) do |item, skill|
  # Return true if the item can be used
end

Note: skill_message_id defines the ID of the message shown in the Summary UI when testing the moves.

Example:

PFM::ItemDescriptor.define_on_move_usability(GameData::PPIncreaseItem, 35) do |_, skill|
  next (skill.data.pp_max * 8 / 5) > skill.ppmax
end

Define the action that is done on a Move on Map

To define the action performed by the item on a move, use the following function:

PFM::ItemDescriptor.define_on_move_use(klass) do |item, pokemon, skill, scene|
  # Do your stuff
end

Example:

PFM::ItemDescriptor.define_on_move_use(GameData::PPIncreaseItem) do |item, pokemon, skill, scene|
  pokemon.loyalty -= GameData::HealingItem.from(item).loyalty_malus
  if GameData::PPIncreaseItem.from(item).max
    skill.ppmax = skill.data.pp_max * 8 / 5
  else
    skill.ppmax += skill.data.pp_max * 1 / 5
  end
  skill.pp += 99
  scene.display_message_and_wait(parse_text(22, 117, PFM::Text::MOVE[0] => skill.name))
end

Define the action that is done on a Move in Battle

To define the action performed by the item on a move in battle, use the following function:

PFM::ItemDescriptor.define_on_battle_move_use(klass) do |item, pokemon, skill, scene|
  # Do your stuff
end