module GameData
class Evolution
attr_reader :id
attr_reader :real_name
attr_reader :parameter
attr_reader :minimum_level # 0 means parameter is the minimum level
attr_reader :level_up_proc
attr_reader :level_up_proc_first
attr_reader :use_item_proc
attr_reader :on_trade_proc
attr_reader :after_battle_proc
attr_reader :event_proc
attr_reader :after_evolution_proc
#DATA = {}
extend ClassMethodsSymbols
include InstanceMethods
def self.load; end
def self.save; end
def initialize(hash)
@id = hash[:id]
@real_name = hash[:id].to_s || "Unnamed"
@parameter = hash[:parameter]
@minimum_level = hash[:minimum_level] || 0
@level_up_proc = hash[:level_up_proc]
@level_up_proc_first = hash[:level_up_proc_first]
@use_item_proc = hash[:use_item_proc]
@on_trade_proc = hash[:on_trade_proc]
@after_battle_proc = hash[:after_battle_proc]
@event_proc = hash[:event_proc]
@after_evolution_proc = hash[:after_evolution_proc]
end
def call_level_up(*args)
return (@level_up_proc) ? @level_up_proc.call(*args) : nil
end
def call_level_up_firsttime(*args)
return (@level_up_proc_first) ? @level_up_proc_first.call(*args) : nil
end
def call_use_item(*args)
return (@use_item_proc) ? @use_item_proc.call(*args) : nil
end
def call_on_trade(*args)
return (@on_trade_proc) ? @on_trade_proc.call(*args) : nil
end
def call_after_battle(*args)
return (@after_battle_proc) ? @after_battle_proc.call(*args) : nil
end
def call_event(*args)
return (@event_proc) ? @event_proc.call(*args) : nil
end
def call_after_evolution(*args)
@after_evolution_proc&.call(*args)
end
end
end
GameData::Evolution.register({
:id => :Level,
:parameter => Integer,
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter
},
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter
}
})
GameData::Evolution.register({
:id => :LevelMale,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && pkmn.male?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && pkmn.male?
}
})
GameData::Evolution.register({
:id => :LevelFemale,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && pkmn.female?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && pkmn.female?
}
})
GameData::Evolution.register({
:id => :LevelDay,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && PBDayNight.isDay?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && PBDayNight.isDay?
}
})
GameData::Evolution.register({
:id => :LevelNight,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && PBDayNight.isNight?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && PBDayNight.isNight?
}
})
GameData::Evolution.register({
:id => :LevelMorning,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && PBDayNight.isMorning?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && PBDayNight.isMorning?
}
})
GameData::Evolution.register({
:id => :LevelAfternoon,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && PBDayNight.isAfternoon?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && PBDayNight.isAfternoon?
}
})
GameData::Evolution.register({
:id => :LevelEvening,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && PBDayNight.isEvening?
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && PBDayNight.isEvening?
}
})
GameData::Evolution.register({
:id => :LevelNoWeather,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $game_screen && $game_screen.weather_type == :None
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $game_screen && $game_screen.weather_type == :None
}
})
GameData::Evolution.register({
:id => :LevelSun,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $game_screen &&
GameData::Weather.get($game_screen.weather_type).category == :Sun
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $game_screen &&
GameData::Weather.get($game_screen.weather_type).category == :Sun
}
})
GameData::Evolution.register({
:id => :LevelRain,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $game_screen &&
[:Rain, :Fog].include?(GameData::Weather.get($game_screen.weather_type).category)
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $game_screen &&
[:Rain, :Fog].include?(GameData::Weather.get($game_screen.weather_type).category)
}
})
GameData::Evolution.register({
:id => :LevelSnow,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $game_screen &&
GameData::Weather.get($game_screen.weather_type).category == :Hail
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $game_screen &&
GameData::Weather.get($game_screen.weather_type).category == :Hail
}
})
GameData::Evolution.register({
:id => :LevelSandstorm,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $game_screen &&
GameData::Weather.get($game_screen.weather_type).category == :Sandstorm
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $game_screen &&
GameData::Weather.get($game_screen.weather_type).category == :Sandstorm
}
})
GameData::Evolution.register({
:id => :LevelCycling,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $PokemonGlobal && $PokemonGlobal.bicycle
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $PokemonGlobal && $PokemonGlobal.bicycle
}
})
GameData::Evolution.register({
:id => :LevelSurfing,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $PokemonGlobal && $PokemonGlobal.surfing
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $PokemonGlobal && $PokemonGlobal.surfing
}
})
GameData::Evolution.register({
:id => :LevelDiving,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $PokemonGlobal && $PokemonGlobal.diving
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $PokemonGlobal && $PokemonGlobal.diving
}
})
GameData::Evolution.register({
:id => :LevelDarkness,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $game_map.metadata&.dark_map
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $game_map.metadata&.dark_map
}
})
GameData::Evolution.register({
:id => :LevelDarkInParty,
:parameter => Integer,
:level_up_proc => proc { |pkmn, parameter|
next pkmn.level >= parameter && $player.has_pokemon_of_type?(:DARK)
},
:level_up_proc_first => proc { |pkmn, parameter|
next pkmn.level == parameter && $player.has_pokemon_of_type?(:DARK)
}
})
#===============================================================================
# Instances of this class are individual Pokémon.
# The player's party Pokémon are stored in the array $player.party.
#===============================================================================
class Pokemon
#=============================================================================
# Evolution checks
#=============================================================================
# Checks whether this Pokemon can evolve because of levelling up.
# @return [Symbol, nil] the ID of the species to evolve into
def check_evolution_on_level_up
return check_evolution_internal { |pkmn, new_species, method, parameter|
success = GameData::Evolution.get(method).call_level_up_firsttime(pkmn, parameter)
next (success) ? new_species : nil
}
end
def check_evolution_on_level_up_first_time
return check_evolution_internal { |pkmn, new_species, method, parameter|
success = GameData::Evolution.get(method).call_level_up_firsttime(pkmn, parameter)
next (success) ? new_species : nil
}
end
def trigger_event_evolution(number)
new_species = check_evolution_by_event(number)
if new_species
#pbFadeOutInWithMusic {
# evo = PokemonEvolutionScene.new
# evo.pbStartScreen(self, new_species)
# evo.pbEvolution
# evo.pbEndScreen
#}
#return true
msgWindow = pbCreateMessageWindow
pbSEPlay("Pkmn move learnt")
pbMessageDisplay(msgWindow, _INTL("\\c[1]{1} can now evolve!", speciesName))
pbDisposeMessageWindow(msgwindow)
end
return false
end
end
#put here by Gardenette - for evolving after battle
def pbEvolutionCheck
$player.party.each_with_index do |pkmn, i|
next if !pkmn || pkmn.egg?
next if pkmn.fainted? && !Settings::CHECK_EVOLUTION_FOR_FAINTED_POKEMON
# Find an evolution
new_species = nil
if new_species.nil? && $game_temp.party_levels_before_battle &&
$game_temp.party_levels_before_battle[i] &&
$game_temp.party_levels_before_battle[i] < pkmn.level
new_species = pkmn.check_evolution_on_level_up
end
new_species = pkmn.check_evolution_after_battle(i) if new_species.nil?
next if new_species.nil?
# Evolve Pokémon if possible
#evo = PokemonEvolutionScene.new
#evo.pbStartScreen(pkmn, new_species)
#evo.pbEvolution
#evo.pbEndScreen
pbSEPlay("Pkmn move learnt")
pbMessage(_INTL("\\c[1]{1} can now evolve!", pkmn.name))
end
end
#put here by Gardenette
def pbChangeExp(pkmn, new_exp, scene)
new_exp = new_exp.clamp(0, pkmn.growth_rate.maximum_exp)
if pkmn.exp == new_exp
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1}'s Exp. Points remained unchanged.", pkmn.name))
else
pbMessage(_INTL("{1}'s Exp. Points remained unchanged.", pkmn.name))
end
return
end
old_level = pkmn.level
old_total_hp = pkmn.totalhp
old_attack = pkmn.attack
old_defense = pkmn.defense
old_special_attack = pkmn.spatk
old_special_defense = pkmn.spdef
old_speed = pkmn.speed
if pkmn.exp > new_exp # Loses Exp
difference = pkmn.exp - new_exp
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} lost {2} Exp. Points!", pkmn.name, difference))
else
pbMessage(_INTL("{1} lost {2} Exp. Points!", pkmn.name, difference))
end
pkmn.exp = new_exp
pkmn.calc_stats
scene.pbRefresh
return if pkmn.level == old_level
# Level changed
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} dropped to Lv. {2}!", pkmn.name, pkmn.level))
else
pbMessage(_INTL("{1} dropped to Lv. {2}!", pkmn.name, pkmn.level))
end
total_hp_diff = pkmn.totalhp - old_total_hp
attack_diff = pkmn.attack - old_attack
defense_diff = pkmn.defense - old_defense
special_attack_diff = pkmn.spatk - old_special_attack
special_defense_diff = pkmn.spdef - old_special_defense
speed_diff = pkmn.speed - old_speed
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
total_hp_diff, attack_diff, defense_diff, special_attack_diff, special_defense_diff, speed_diff), scene)
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
pkmn.totalhp, pkmn.attack, pkmn.defense, pkmn.spatk, pkmn.spdef, pkmn.speed), scene)
else # Gains Exp
difference = new_exp - pkmn.exp
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} gained {2} Exp. Points!", pkmn.name, difference))
else
pbMessage(_INTL("{1} gained {2} Exp. Points!", pkmn.name, difference))
end
pkmn.exp = new_exp
pkmn.changeHappiness("vitamin")
pkmn.calc_stats
scene.pbRefresh
return if pkmn.level == old_level
# Level changed
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} grew to Lv. {2}!", pkmn.name, pkmn.level))
else
pbMessage(_INTL("{1} grew to Lv. {2}!", pkmn.name, pkmn.level))
end
total_hp_diff = pkmn.totalhp - old_total_hp
attack_diff = pkmn.attack - old_attack
defense_diff = pkmn.defense - old_defense
special_attack_diff = pkmn.spatk - old_special_attack
special_defense_diff = pkmn.spdef - old_special_defense
speed_diff = pkmn.speed - old_speed
pbTopRightWindow(_INTL("Max. HP<r>+{1}\r\nAttack<r>+{2}\r\nDefense<r>+{3}\r\nSp. Atk<r>+{4}\r\nSp. Def<r>+{5}\r\nSpeed<r>+{6}",
total_hp_diff, attack_diff, defense_diff, special_attack_diff, special_defense_diff, speed_diff), scene)
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
pkmn.totalhp, pkmn.attack, pkmn.defense, pkmn.spatk, pkmn.spdef, pkmn.speed), scene)
# Learn new moves upon level up
movelist = pkmn.getMoveList
movelist.each do |i|
next if i[0] <= old_level || i[0] > pkmn.level
pbLearnMove(pkmn, i[1], true) { scene.pbUpdate }
end
# Check for evolution
new_species = pkmn.check_evolution_on_level_up
if new_species
#pbFadeOutInWithMusic {
# evo = PokemonEvolutionScene.new
# evo.pbStartScreen(pkmn, new_species)
# evo.pbEvolution
# evo.pbEndScreen
# scene.pbRefresh if scene.is_a?(PokemonPartyScreen)
#}
pbSEPlay("Pkmn move learnt")
pbMessage(_INTL("\\c[1]{1} can now evolve!", pkmn.name))
end
end
end
#put here by Gardenette - for evolving after trade
class PokemonTrade_Scene
def pbEndScreen(need_fade_out = true)
pbDisposeMessageWindow(@sprites["msgwindow"]) if @sprites["msgwindow"]
pbFadeOutAndHide(@sprites) if need_fade_out
pbDisposeSpriteHash(@sprites)
@viewport.dispose
newspecies = @pokemon2.check_evolution_on_trade(@pokemon)
if newspecies
#evo = PokemonEvolutionScene.new
#evo.pbStartScreen(@pokemon2, newspecies)
#evo.pbEvolution(false)
#evo.pbEndScreen
pbSEPlay("Pkmn move learnt")
pbMessage(_INTL("\\c[1]{1} can now evolve!", @pokemon2.name))
end
end
end
ItemHandlers::UseOnPokemon.add(:RARECANDY, proc { |item, qty, pkmn, scene|
if pkmn.shadowPokemon?
scene.pbDisplay(_INTL("It won't have any effect."))
next false
end
if pkmn.level >= GameData::GrowthRate.max_level
new_species = pkmn.check_evolution_on_level_up_first_time
if !Settings::RARE_CANDY_USABLE_AT_MAX_LEVEL || !new_species
scene.pbDisplay(_INTL("It won't have any effect."))
next false
end
# Check for evolution
pbSEPlay("Pkmn move learnt")
pbMessage(_INTL("\\c[1]{1} can now evolve!", pkmn.name))
next true
end
# Level up
pbChangeLevelNoAutoEvolve(pkmn, pkmn.level + qty, scene)
scene.pbHardRefresh
next true
})
#renamed by Gardenette so it does not conflict with Misc Bug Fixes from Hotfixes
def pbChangeLevelNoAutoEvolve(pkmn, new_level, scene)
new_level = new_level.clamp(1, GameData::GrowthRate.max_level)
if pkmn.level == new_level
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1}'s level remained unchanged.", pkmn.name))
else
pbMessage(_INTL("{1}'s level remained unchanged.", pkmn.name))
end
return
end
old_level = pkmn.level
old_total_hp = pkmn.totalhp
old_attack = pkmn.attack
old_defense = pkmn.defense
old_special_attack = pkmn.spatk
old_special_defense = pkmn.spdef
old_speed = pkmn.speed
pkmn.level = new_level
pkmn.calc_stats
scene.pbRefresh
if old_level > new_level
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} dropped to Lv. {2}!", pkmn.name, pkmn.level))
else
pbMessage(_INTL("{1} dropped to Lv. {2}!", pkmn.name, pkmn.level))
end
total_hp_diff = pkmn.totalhp - old_total_hp
attack_diff = pkmn.attack - old_attack
defense_diff = pkmn.defense - old_defense
special_attack_diff = pkmn.spatk - old_special_attack
special_defense_diff = pkmn.spdef - old_special_defense
speed_diff = pkmn.speed - old_speed
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
total_hp_diff, attack_diff, defense_diff, special_attack_diff, special_defense_diff, speed_diff), scene)
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
pkmn.totalhp, pkmn.attack, pkmn.defense, pkmn.spatk, pkmn.spdef, pkmn.speed), scene)
else
pkmn.changeHappiness("vitamin")
if scene.is_a?(PokemonPartyScreen)
scene.pbDisplay(_INTL("{1} grew to Lv. {2}!", pkmn.name, pkmn.level))
else
pbMessage(_INTL("{1} grew to Lv. {2}!", pkmn.name, pkmn.level))
end
total_hp_diff = pkmn.totalhp - old_total_hp
attack_diff = pkmn.attack - old_attack
defense_diff = pkmn.defense - old_defense
special_attack_diff = pkmn.spatk - old_special_attack
special_defense_diff = pkmn.spdef - old_special_defense
speed_diff = pkmn.speed - old_speed
pbTopRightWindow(_INTL("Max. HP<r>+{1}\r\nAttack<r>+{2}\r\nDefense<r>+{3}\r\nSp. Atk<r>+{4}\r\nSp. Def<r>+{5}\r\nSpeed<r>+{6}",
total_hp_diff, attack_diff, defense_diff, special_attack_diff, special_defense_diff, speed_diff), scene)
pbTopRightWindow(_INTL("Max. HP<r>{1}\r\nAttack<r>{2}\r\nDefense<r>{3}\r\nSp. Atk<r>{4}\r\nSp. Def<r>{5}\r\nSpeed<r>{6}",
pkmn.totalhp, pkmn.attack, pkmn.defense, pkmn.spatk, pkmn.spdef, pkmn.speed), scene)
# Learn new moves upon level up
movelist = pkmn.getMoveList
movelist.each do |i|
next if i[0] <= old_level || i[0] > pkmn.level
pbLearnMove(pkmn, i[1], true) { scene.pbUpdate }
end
# Check for evolution
new_species = pkmn.check_evolution_on_level_up_first_time
if new_species
#msgWindow = pbCreateMessageWindow
pbSEPlay("Pkmn move learnt")
pbMessage(_INTL("\\c[1]{1} can now evolve!", pkmn.name))
#pbDisposeMessageWindow(msgwindow)
scene.pbRefresh if scene.is_a?(PokemonPartyScreen)
end
end
end