Files
infinitefusion-e18/Data/Scripts/016_Pokemon/005_Pokemon_Evolution.rb
2020-09-05 22:34:32 +01:00

335 lines
11 KiB
Ruby

module PBEvolution
None = 0 # Do not use
Happiness = 1
HappinessDay = 2
HappinessNight = 3
Level = 4
Trade = 5
TradeItem = 6
Item = 7
AttackGreater = 8
AtkDefEqual = 9
DefenseGreater = 10
Silcoon = 11
Cascoon = 12
Ninjask = 13
Shedinja = 14
Beauty = 15
ItemMale = 16
ItemFemale = 17
DayHoldItem = 18
NightHoldItem = 19
HasMove = 20
HasInParty = 21
LevelMale = 22
LevelFemale = 23
Location = 24
TradeSpecies = 25
LevelDay = 26
LevelNight = 27
LevelDarkInParty = 28
LevelRain = 29
HappinessMoveType = 30
LevelEvening = 31
Custom1 = 32
Custom2 = 33
Custom3 = 34
Custom4 = 35
EVONAMES = ["None",
"Happiness", "HappinessDay", "HappinessNight", "Level", "Trade",
"TradeItem", "Item", "AttackGreater", "AtkDefEqual", "DefenseGreater",
"Silcoon", "Cascoon", "Ninjask", "Shedinja", "Beauty",
"ItemMale", "ItemFemale", "DayHoldItem", "NightHoldItem", "HasMove",
"HasInParty", "LevelMale", "LevelFemale", "Location", "TradeSpecies",
"LevelDay", "LevelNight", "LevelDarkInParty", "LevelRain", "HappinessMoveType",
"LevelEvening", "Custom1", "Custom2", "Custom3", "Custom4",
]
# 0 = no parameter
# 1 = Positive integer
# 2 = Item internal name
# 3 = Move internal name
# 4 = Species internal name
# 5 = Type internal name
# 6 = Ability internal name
EVOPARAM = [0, # None (do not use)
0,0,0,1,0, # Happiness, HappinessDay, HappinessNight, Level, Trade
2,2,1,1,1, # TradeItem, Item, AttackGreater, AtkDefEqual, DefenseGreater
1,1,1,1,1, # Silcoon, Cascoon, Ninjask, Shedinja, Beauty
2,2,2,2,3, # ItemMale, ItemFemale, DayHoldItem, NightHoldItem, HasMove
4,1,1,1,4, # HasInParty, LevelMale, LevelFemale, Location, TradeSpecies
1,1,1,1,5, # LevelDay, LevelNight, LevelDarkInParty, LevelRain, HappinessMoveType
1,1,1,1,1 # LevelEvening, Custom 1-4
]
end
#===============================================================================
# Evolutions data cache
#===============================================================================
class PokemonTemp
attr_accessor :evolutionsData
end
def pbLoadEvolutionsData
$PokemonTemp = PokemonTemp.new if !$PokemonTemp
if !$PokemonTemp.evolutionsData
$PokemonTemp.evolutionsData = load_data("Data/species_evolutions.dat") || []
end
return $PokemonTemp.evolutionsData
end
def pbGetEvolutionData(species)
species = getID(PBSpecies,species)
evosData = pbLoadEvolutionsData
return evosData[species] || nil
end
alias __evolutionsData__pbClearData pbClearData
def pbClearData
$PokemonTemp.evolutionsData = nil if $PokemonTemp
__evolutionsData__pbClearData
end
#===============================================================================
# Evolution helper functions
#===============================================================================
def pbGetEvolvedFormData(species,ignoreNone=false)
ret = []
evoData = pbGetEvolutionData(species)
return ret if !evoData || evoData.length==0
evoData.each do |evo|
next if evo[3] # Is the prevolution
next if evo[1]==PBEvolution::None && ignoreNone
ret.push([evo[1],evo[2],evo[0]]) # [Method, parameter, species]
end
return ret
end
def pbGetPreviousForm(species) # Unused
evoData = pbGetEvolutionData(species)
return species if !evoData || evoData.length==0
evoData.each do |evo|
return evo[0] if evo[3] # Is the prevolution
end
return species
end
def pbGetBabySpecies(species,item1=-1,item2=-1)
ret = species
evoData = pbGetEvolutionData(species)
return ret if !evoData || evoData.length==0
evoData.each do |evo|
next if !evo[3]
if item1>=0 && item2>=0
incense = pbGetSpeciesData(evo[0],0,SpeciesIncense)
ret = evo[0] if item1==incense || item2==incense
else
ret = evo[0] # Species of prevolution
end
break
end
ret = pbGetBabySpecies(ret) if ret!=species
return ret
end
def pbGetMinimumLevel(species)
methodsWithMinLevel = [
PBEvolution::Level, PBEvolution::LevelMale, PBEvolution::LevelFemale,
PBEvolution::AttackGreater, PBEvolution::AtkDefEqual, PBEvolution::DefenseGreater,
PBEvolution::Silcoon, PBEvolution::Cascoon,
PBEvolution::Ninjask, PBEvolution::Shedinja,
PBEvolution::LevelDay, PBEvolution::LevelNight,
PBEvolution::LevelDarkInParty, PBEvolution::LevelRain
]
evoData = pbGetEvolutionData(species)
return 1 if !evoData || evoData.length==0
ret = -1
evoData.each do |evo|
if evo[3] && methodsWithMinLevel.include?(evo[1]) # Is the prevolution
ret = (ret<0) ? evo[2] : [ret,evo[2]].min
break
end
end
return (ret==-1) ? 1 : ret
end
def pbGetEvolutionFamilyData(species)
evos = pbGetEvolvedFormData(species,true)
return nil if evos.length==0
ret = []
for i in 0...evos.length
ret.push([species].concat(evos[i]))
evoData = pbGetEvolutionFamilyData(evos[i][2])
ret.concat(evoData) if evoData && evoData.length>0
end
return ret
end
# Used by the Moon Ball when checking if a Pokémon's evolution family includes
# an evolution that uses the Moon Stone.
def pbCheckEvolutionFamilyForMethod(species,method,param=-1)
species = pbGetBabySpecies(species)
evos = pbGetEvolutionFamilyData(species)
return false if !evos || evos.length==0
for evo in evos
if method.is_a?(Array)
next if !method.include?(evo[1])
elsif method>=0
next if evo[1]!=method
end
next if param>=0 && evo[2]!=param
return true
end
return false
end
def pbEvoDebug # Unused
evosData = pbLoadEvolutionsData
for species in 1..PBSpecies.maxValueF
echo PBSpecies.getName(pbGetSpeciesFromFSpecies(species)[0])+"\n"
next if !evosData[species] || evosData[species].length==0
for evo in evosData[species]
echo sprintf("name=%s, type=%s (%02X), level=%d, evo/prevo=%s",
PBSpecies.getName(evo[0]),getConstantName(PBEvolution,evo[1]),evo[1],evo[2],
(evo[3]) ? "prevolution" : "evolution")+"\n"
end
end
echo "end\n"
end
#===============================================================================
# Evolution methods
#===============================================================================
def pbMiniCheckEvolution(pokemon,evonib,level,poke)
case evonib
when PBEvolution::Happiness
return poke if pokemon.happiness>=220
when PBEvolution::HappinessDay
return poke if pokemon.happiness>=220 && PBDayNight.isDay?
when PBEvolution::HappinessNight
return poke if pokemon.happiness>=220 && PBDayNight.isNight?
when PBEvolution::HappinessMoveType
if pokemon.happiness>=220
for m in pokemon.moves
return poke if m.id>0 && m.type==level
end
end
when PBEvolution::Level
return poke if pokemon.level>=level
when PBEvolution::LevelDay
return poke if pokemon.level>=level && PBDayNight.isDay?
when PBEvolution::LevelNight
return poke if pokemon.level>=level && PBDayNight.isNight?
when PBEvolution::LevelEvening
return poke if pokemon.level>=level && PBDayNight.isEvening?
when PBEvolution::LevelMale
return poke if pokemon.level>=level && pokemon.male?
when PBEvolution::LevelFemale
return poke if pokemon.level>=level && pokemon.female?
when PBEvolution::AttackGreater # Hitmonlee
return poke if pokemon.level>=level && pokemon.attack>pokemon.defense
when PBEvolution::AtkDefEqual # Hitmontop
return poke if pokemon.level>=level && pokemon.attack==pokemon.defense
when PBEvolution::DefenseGreater # Hitmonchan
return poke if pokemon.level>=level && pokemon.attack<pokemon.defense
when PBEvolution::Silcoon
return poke if pokemon.level>=level && (((pokemon.personalID>>16)&0xFFFF)%10)<5
when PBEvolution::Cascoon
return poke if pokemon.level>=level && (((pokemon.personalID>>16)&0xFFFF)%10)>=5
when PBEvolution::Ninjask
return poke if pokemon.level>=level
when PBEvolution::Shedinja
return -1
when PBEvolution::DayHoldItem
return poke if pokemon.item==level && PBDayNight.isDay?
when PBEvolution::NightHoldItem
return poke if pokemon.item==level && PBDayNight.isNight?
when PBEvolution::HasMove
for m in pokemon.moves
return poke if m.id==level
end
when PBEvolution::HasInParty
for i in $Trainer.pokemonParty
return poke if i.species==level
end
when PBEvolution::LevelDarkInParty
if pokemon.level>=level
for i in $Trainer.pokemonParty
return poke if i.hasType?(:DARK)
end
end
when PBEvolution::Location
return poke if $game_map.map_id==level
when PBEvolution::LevelRain
if pokemon.level>=level
if $game_screen && ($game_screen.weather_type==PBFieldWeather::Rain ||
$game_screen.weather_type==PBFieldWeather::HeavyRain ||
$game_screen.weather_type==PBFieldWeather::Storm)
return poke
end
end
when PBEvolution::Beauty # Feebas
return poke if pokemon.beauty>=level
when PBEvolution::Trade, PBEvolution::TradeItem, PBEvolution::TradeSpecies
return -1
when PBEvolution::Custom1
# Add code for custom evolution type 1
when PBEvolution::Custom2
# Add code for custom evolution type 2
when PBEvolution::Custom3
# Add code for custom evolution type 3
when PBEvolution::Custom4
# Add code for custom evolution type 4
end
return -1
end
def pbMiniCheckEvolutionItem(pokemon,evonib,level,poke,item)
# Checks for when an item is used on the Pokémon (e.g. an evolution stone)
case evonib
when PBEvolution::Item
return poke if level==item
when PBEvolution::ItemMale
return poke if level==item && pokemon.male?
when PBEvolution::ItemFemale
return poke if level==item && pokemon.female?
end
return -1
end
# Checks whether a Pokemon can evolve now. If a block is given, calls the block
# with the following parameters:
# Pokemon to check; evolution type; level or other parameter; ID of the new species
def pbCheckEvolutionEx(pokemon)
return -1 if pokemon.species<=0 || pokemon.egg? || pokemon.shadowPokemon?
return -1 if isConst?(pokemon.item,PBItems,:EVERSTONE)
return -1 if isConst?(pokemon.ability,PBAbilities,:BATTLEBOND)
ret = -1
for form in pbGetEvolvedFormData(pbGetFSpeciesFromForm(pokemon.species,pokemon.form),true)
ret = yield pokemon,form[0],form[1],form[2]
break if ret>0
end
return ret
end
# Checks whether a Pokemon can evolve now. If an item is used on the Pokémon,
# checks whether the Pokemon can evolve with the given item.
def pbCheckEvolution(pokemon,item=0)
if item==0
return pbCheckEvolutionEx(pokemon) { |pokemon,evonib,level,poke|
next pbMiniCheckEvolution(pokemon,evonib,level,poke)
}
else
return pbCheckEvolutionEx(pokemon) { |pokemon,evonib,level,poke|
next pbMiniCheckEvolutionItem(pokemon,evonib,level,poke,item)
}
end
end