- Pokémon Essentials Version
- v20.1 ➖
This is a guide on how to create a method that gets a random ID from game data. (items, Pokémon, etc.) This is most commonly used for events that give the player a random item out of a set, like the tree in the default maps that gives the player a random Apricorn.
Note - This was written in v20, but it's compatible with v19 as well.
You can see all the kinds of GameData in this section of the scripts -
Looking at the script in question will also let you look at the different attributes of the data - broad stuff like name or ID, or class-specific stuff like the base power of moves or weaknesses of a type.
Sometimes you won't have a special method for what you want, though, so you'll just have to write it out by hand. This can be pretty much anything, so I'm not going to go into too much detail, but a few points to remember -
You'll want to create another array, this one containing every ID you don't want.
Then you'd just check to make sure that the blacklist didn't include the ID -
A random Berry
A random fossil, including the Gen 8 half fossils.
This one is a little tricky! The Gen 8 fossils aren't given the fossil flag, because you need two of them to receive a Pokémon. But we can't just check for "Fossil" in the name, because then we'd leave out the Old Amber - so we need to check for either/or.
A random TM that the player doesn't have
You can run checks that aren't just about the game data!
(If you're playtesting this and getting errors, remember that default Essentials doesn't have any TMs, they're all TRs)
A random Fire-type TM
Since the item data only has the move ID, we have to do a little work to get the move's data.
A random Water-type Pokémon that isn't a starter from Gens 1-4, and isn't a Legendary or Mythical.
A little harder than it sounds! Manaphy actually isn't in the Undiscovered egg group, so we have to add it to the blacklist. You also need to remember that the starter evolutions are a different species from their prevos, so you need to add them to the blacklist as well. (Technically, you could check if a Pokémon evolved from a species in the blacklist, but that's overcomplicating things a bit when we've already got so many checks)
If you're using this just for one event, you can actually run the whole thing as a script command, and do whatever you want with the variable. Here's an example of that with the default map's Apricorn tree -
If you plan on using this in multiple different locations, you may find it easier to create a new method in the script editor.
You can also make a method return the generated ID, so you could do something else with it. (Maybe an NPC who asks for a random item?)
Note - This was written in v20, but it's compatible with v19 as well.
Pool
The basic idea here is pretty simple -- Create an empty array
- Add the ID of each entry in the data to the array
- Sample the array
Ruby:
pool = []
GameData::Item.each { |item|
pool.push(item.id)
}
item= pool.sample
You can see all the kinds of GameData in this section of the scripts -
Looking at the script in question will also let you look at the different attributes of the data - broad stuff like name or ID, or class-specific stuff like the base power of moves or weaknesses of a type.
Conditions
It's not super helpful to just get every ID that exists out there, so you'll want to include a check to see if the entry matches whatever criteria you have for it. This can be pretty much anything - any attribute of the data can be checked against whatever you'd like. Some checks have custom methods for them - for example, while you could checkitem.has_flag?("Berry")
, you could also check item.is_berry?
. These checks can be found in the script sections mentioned above, and are sometimes listed on the wiki as well. (For example, the item checks are on the Manipulating items article)Sometimes you won't have a special method for what you want, though, so you'll just have to write it out by hand. This can be pretty much anything, so I'm not going to go into too much detail, but a few points to remember -
==
is to check one value against another,=
is to set it. You want to use==
, not=
.- You can check if a string of text includes another string with
.include?("")
- For example, say I want an NPC who loves red, and gives me items with "red" in their name - Red Shards, Red Nectar, Red Flutes, Red Cards, etc. I could do
item.name.include?("Red")
.- This can get tricky, though, because you might not always think of all the items this could call. This is case-sensitive, but if it wasn't, then Sacred Ash could have also been pulled. Make sure to check your PBS with Ctrl+F, and try to use capitalization and spacing to make sure you're only getting what you want. (Or just create the array directly, honestly)
- For example, say I want an NPC who loves red, and gives me items with "red" in their name - Red Shards, Red Nectar, Red Flutes, Red Cards, etc. I could do
||
means "or",&&
means "and". You can have parenthesis around two conditions to make them into one condition.- For example, say I want a berry or Apricorn that costs less than 500. I would write this as
(item.is_berry? || is_apricorn?) && item.price < 500
- For example, say I want a berry or Apricorn that costs less than 500. I would write this as
!
is put in front of a check to see if it's false.- For example, say I want to give a random Pokémon, but I don't want it to be in the Undiscovered egg group. (which includes most Legendaries) I could write
!species.egg_groups.include?(:Undiscovered)
- For example, say I want to give a random Pokémon, but I don't want it to be in the Undiscovered egg group. (which includes most Legendaries) I could write
Blacklist
You might have cases where you want to make sure specific IDs aren't in the pool. (For example, with my red item NPC, they would also be giving out the Red Chain and Red Orb - too story-important to be given by a random NPC)You'll want to create another array, this one containing every ID you don't want.
Ruby:
blacklist = [:MASTERBALL,:BEASTBALL]
!blacklist.include?(item.id)
Examples
Try writing these out on your own, then compare them to the answer given.A random Berry
Ruby:
GameData::Item.each { |item|
pool.push(item.id) if GameData::Item.get(item).is_berry?
}
item = pool.sample
Ruby:
pool = []
GameData::Item.each { |item|
pool.push(item.id) if (item.name.include?("Fossil") || item.is_fossil?)
}
item = pool.sample
Ruby:
pool = []
GameData::Item.each { |item|
pool.push(item.id) if (item.is_TM? && !$bag.has?(item.id))
}
item = pool.sample
(If you're playtesting this and getting errors, remember that default Essentials doesn't have any TMs, they're all TRs)
Ruby:
pool = []
GameData::Item.each { |item|
pool.push(item.id) if (item.is_TM? && GameData::Move.get(item.move).type == :FIRE)
}
item = pool.sample
Ruby:
blacklist = [
:SQUIRTLE,:WARTORTLE,:BLASTOISE,
:TOTODILE,:CROCONAW,:FERALIGATR,
:MUDKIP,:MARSHTOMP,:SWAMPERT,
:PIPLUP,:PRINPLUP,:EMPOLEON,
:MANAPHY]
GameData::Species.each { |species|
pool.push(species.id) if (species.types.include?(:WATER) && !species.egg_groups.include?(:Undiscovered) && !blacklist.include?(species))
}
species = pool.sample
Using this code
So, that's how to write this, but where do we put it?If you're using this just for one event, you can actually run the whole thing as a script command, and do whatever you want with the variable. Here's an example of that with the default map's Apricorn tree -
Ruby:
pool = []
GameData::Item.each { |item|
pool.push(item.id) if (item.is_apricorn?)
}
item = pool.sample
pbItemBall(item)
If you plan on using this in multiple different locations, you may find it easier to create a new method in the script editor.
Ruby:
def pbRandomApricorn
pool = []
GameData::Item.each { |item|
pool.push(item.id) if (item.is_apricorn?)
}
item = pool.sample
pbItemBall(item)
end
Ruby:
def pbRandomApricorn
pool = []
GameData::Item.each { |item|
pool.push(item.id) if (item.is_apricorn?)
}
item = pool.sample
return item
end
Similar Resources
- Credits
- This is largely based on Luka's Randomizer EX code, so credit should go to him.