- Pokémon Essentials Version
- v19.1 ➖
Code
Ruby:
module Settings
# Players can use Pokemon that are not yet the required type,
#but can evolve into it
PREVOS_INCLUDED = true
end
class PokemonGlobalMetadata
attr_accessor :monotype
end
#Sets the given variable to the ID number of the type used in the run
def pbSetMonoVariables(varnum)
$game_variables[varnum] = GameData::Type.get($PokemonGlobal.monotype).id_number
end
#Returns true if a monotype run is active
def pbMonoActive?
return true if $PokemonGlobal.monotype
end
#Turns off monotype run
def pbEndMono
$PokemonGlobal.monotype = nil
end
def pbChooseMono
choices = []
GameData::Type.each do |type|
choices.push(type.real_name) if !type.pseudo_type
end
choices.push(_INTL("Cancel"))
choice = pbMessage(_INTL("Which type would you like to use?"),choices,choices.length)
choice = choices[choice]
if choice != "Cancel"
choice = choice.upcase.to_sym
$PokemonGlobal.monotype = choice
end
end
module GameData
class Species
#Adapted from Pokemon class
# @return [Array<Symbol>] an array of this Pokémon's types
def types
ret = [self.type1]
ret.push(self.type2) if self.type2 && self.type2 != self.type1
return ret
end
# @param type [Symbol, String, Integer] type to check
# @return [Boolean] whether this Pokémon has the specified type
def hasType?(type)
type = GameData::Type.get(type).id
return self.types.include?(type)
end
#New utilities:
def can_evolve_into_usable?(type,exclude_invalid = true)
@evolutions.each do |evo|
next if evo[3] # Is the prevolution
next if evo[1] == :None && exclude_invalid
species = GameData::Species.get(evo[0])
return true if species.usable_monotype?(type)
end
return false
end
def usable_monotype?(type=$PokemonGlobal.monotype)
return true if type==nil
return true if self.hasType?(type)
return true if self.can_evolve_into_usable?(type) && Settings::PREVOS_INCLUDED
return false
end
end
end
class Pokemon
# The core method that performs evolution checks. Needs a block given to it,
# which will provide either a GameData::Species ID (the species to evolve
# into) or nil (keep checking).
# @return [Symbol, nil] the ID of the species to evolve into
def check_evolution_internal
return nil if egg? || shadowPokemon?
return nil if hasItem?(:EVERSTONE)
return nil if hasAbility?(:BATTLEBOND)
species_data.get_evolutions(true).each do |evo| # [new_species, method, parameter, boolean]
next if evo[3] # Prevolution
species = GameData::Species.get(evo[0])
next if !species.usable_monotype?
ret = yield self, evo[0], evo[1], evo[2] # pkmn, new_species, method, parameter
return ret if ret
end
return nil
end
def usable_monotype?(type=$PokemonGlobal.monotype)
return GameData::Species.get_species_form(self.species,self.form).usable_monotype?
end
end
#===============================================================================
# Giving Pokémon to the player (will send to storage if party is full)
#===============================================================================
def pbAddPokemon(pkmn, level = 1, see_form = true)
return false if !pkmn
if pbBoxesFull?
pbMessage(_INTL("There's no more room for Pokémon!\1"))
pbMessage(_INTL("The Pokémon Boxes are full and can't accept any more!"))
return false
end
pkmn = Pokemon.new(pkmn, level) if !pkmn.is_a?(Pokemon)
if !pkmn.usable_monotype?
type = GameData::Type.get($PokemonGlobal.monotype).real_name
pbMessage(_INTL("#{pkmn.speciesName} can't be used in a monotype #{type} challenge."))
return false
end
species_name = pkmn.speciesName
pbMessage(_INTL("{1} obtained {2}!\\me[Pkmn get]\\wtnp[80]\1", $Trainer.name, species_name))
pbNicknameAndStore(pkmn)
$Trainer.pokedex.register(pkmn) if see_form
return true
end
def pbAddPokemonSilent(pkmn, level = 1, see_form = true)
return false if !pkmn || pbBoxesFull?
pkmn = Pokemon.new(pkmn, level) if !pkmn.is_a?(Pokemon)
return false if !pkmn.usable_monotype?
$Trainer.pokedex.register(pkmn) if see_form
$Trainer.pokedex.set_owned(pkmn.species)
pkmn.record_first_moves
if $Trainer.party_full?
$PokemonStorage.pbStoreCaught(pkmn)
else
$Trainer.party[$Trainer.party.length] = pkmn
end
return true
end
#===============================================================================
# Giving Pokémon/eggs to the player (can only add to party)
#===============================================================================
def pbAddToParty(pkmn, level = 1, see_form = true)
return false if !pkmn || $Trainer.party_full?
pkmn = Pokemon.new(pkmn, level) if !pkmn.is_a?(Pokemon)
if !pkmn.usable_monotype?
type = GameData::Type.get($PokemonGlobal.monotype).real_name
pbMessage(_INTL("#{pkmn.speciesName} can't be used in a monotype #{type} challenge."))
return false
end
species_name = pkmn.speciesName
pbMessage(_INTL("{1} obtained {2}!\\me[Pkmn get]\\wtnp[80]\1", $Trainer.name, species_name))
pbNicknameAndStore(pkmn)
$Trainer.pokedex.register(pkmn) if see_form
return true
end
def pbAddToPartySilent(pkmn, level = nil, see_form = true)
return false if !pkmn || $Trainer.party_full?
pkmn = Pokemon.new(pkmn, level) if !pkmn.is_a?(Pokemon)
return false if !pkmn.usable_monotype?
$Trainer.pokedex.register(pkmn) if see_form
$Trainer.pokedex.set_owned(pkmn.species)
pkmn.record_first_moves
$Trainer.party[$Trainer.party.length] = pkmn
return true
end
def pbAddForeignPokemon(pkmn, level = 1, owner_name = nil, nickname = nil, owner_gender = 0, see_form = true)
return false if !pkmn || $Trainer.party_full? || !pkmn.usable_monotype?
pkmn = Pokemon.new(pkmn, level) if !pkmn.is_a?(Pokemon)
if !pkmn.usable_monotype?
type = GameData::Type.get($PokemonGlobal.monotype).real_name
pbMessage(_INTL("#{pkmn.speciesName} can't be used in a monotype #{type} challenge."))
return false
end
# Set original trainer to a foreign one
pkmn.owner = Pokemon::Owner.new_foreign(owner_name || "", owner_gender)
# Set nickname
pkmn.name = nickname[0, Pokemon::MAX_NAME_SIZE] if !nil_or_empty?(nickname)
# Recalculate stats
pkmn.calc_stats
if owner_name
pbMessage(_INTL("\\me[Pkmn get]{1} received a Pokémon from {2}.\1", $Trainer.name, owner_name))
else
pbMessage(_INTL("\\me[Pkmn get]{1} received a Pokémon.\1", $Trainer.name))
end
pbStorePokemon(pkmn)
$Trainer.pokedex.register(pkmn) if see_form
$Trainer.pokedex.set_owned(pkmn.species)
return true
end
def pbGenerateEgg(pkmn, text = "")
return false if !pkmn || $Trainer.party_full?
pkmn = Pokemon.new(pkmn, Settings::EGG_LEVEL) if !pkmn.is_a?(Pokemon)
if !pkmn.usable_monotype?
type = GameData::Type.get($PokemonGlobal.monotype).real_name
pbMessage(_INTL("#{pkmn.speciesName} can't be used in a monotype #{type} challenge."))
return false
end
# Set egg's details
pkmn.name = _INTL("Egg")
pkmn.steps_to_hatch = pkmn.species_data.hatch_steps
pkmn.obtain_text = text
pkmn.calc_stats
# Add egg to party
$Trainer.party[$Trainer.party.length] = pkmn
return true
end
alias pbAddEgg pbGenerateEgg
alias pbGenEgg pbGenerateEgg
def pbStartTrade(pokemonIndex,newpoke,nickname,trainerName,trainerGender=0)
myPokemon = $Trainer.party[pokemonIndex]
opponent = NPCTrainer.new(trainerName,trainerGender)
opponent.id = $Trainer.make_foreign_ID
yourPokemon = nil
resetmoves = true
if newpoke.is_a?(Pokemon)
newpoke.owner = Pokemon::Owner.new_from_trainer(opponent)
yourPokemon = newpoke
resetmoves = false
else
species_data = GameData::Species.try_get(newpoke)
raise _INTL("Species does not exist ({1}).", newpoke) if !species_data
yourPokemon = Pokemon.new(species_data.id, myPokemon.level, opponent)
end
if !yourPokemon.usable_monotype?
pbMessage(_INTL("#{pkmn.speciesName} can't be used in a monotype #{type} challenge."))
return false
end
yourPokemon.name = nickname
yourPokemon.obtain_method = 2 # traded
yourPokemon.reset_moves if resetmoves
yourPokemon.record_first_moves
$Trainer.pokedex.register(yourPokemon)
$Trainer.pokedex.set_owned(yourPokemon.species)
pbFadeOutInWithMusic {
evo = PokemonTrade_Scene.new
evo.pbStartScreen(myPokemon,yourPokemon,$Trainer.name,opponent.name)
evo.pbTrade
evo.pbEndScreen
}
$Trainer.party[pokemonIndex] = yourPokemon
end
There is, unfortunately, one additional step to take- find this section in Item_BattleEffects -
Ruby:
if battler.semiInvulnerable?
scene.pbDisplay(_INTL("It's no good! It's impossible to aim at a Pokémon that's not in sight!")) if showMessages
next false
end
Ruby:
species = GameData::Species.get(battler.species)
if !species.usable_monotype?
type = GameData::Type.get($PokemonGlobal.monotype).real_name
scene.pbDisplay(_INTL("You can't catch this Pokémon in a monotype #{type} challenge!"),) if showMessages
next false
end
Using this Script
The setting PREVOS_INCLUDED at the top is to allow for Pokemon that gain or change types on evolving. For example, in a Fire run, you would still be able to use Eevee, because it can evolve into Flareon.There's a fair number of calls here-
pbChooseMono
has the player choose the type to use, or none at all. (The list is pulled from the Types database, you shouldn't have to do anything to adjust it for new types you add)pbMonoActive?
returns true if monotype rules are in place. You could use this as a global switch by naming a switchs:pbMonoActive?
pbSetMonoVariables(x)
sets game variable x to the ID number of the type being used- 0 for Normal, 1 for Fighting, and so on. (Unfortunately, since variables are 0 by default, you'll have to either combine it with pbMonoActive?- or, if you don't think it'll be too confusing, add 1 to the variable again and just work with the values offset)pbEndMono
removes the challenge rules. It doesn't do anything else- be sure to give any prizes or anything before you take them off!- The script call
$PokemonGlobal.monotype
will return the internal name of the type being used.
While a challenge run is in play:
- If a Pokemon isn't eligible for the run (has the required type or can evolve into the required type), the player can't receive it through gifts (egg or standard), through catching (will get a message like when you try to catch in doubles), or through trading.
- Every script that gives a Pokemon will return false if it can't be used in the monotype challenge. Be sure to avoid any potential softlocks for the player!
- Pokemon can only evolve if their evolution is eligible for the run. This should, to my knowledge, account for all stages in a chain- for example, you can obtain Caterpie in a mono Flying run, because it will evolve into Metapod, which will evolve into Butterfree.
Future Goals
- Get a nicer UI rather than just selecting from text
- Figure out the deal with the Poke Ball handler so I can make this completely plug-n-play
- Credits
- Credits to TechSkylander1518, please!