Files
infinitefusion-e18/Data/Scripts/010_Data/002_PBS data/008_Species.rb
2021-07-08 21:19:45 +01:00

334 lines
12 KiB
Ruby

module GameData
class Species
attr_reader :id
attr_reader :species
attr_reader :form
attr_reader :real_name
attr_reader :real_form_name
attr_reader :real_category
attr_reader :real_pokedex_entry
attr_reader :pokedex_form
attr_reader :type1
attr_reader :type2
attr_reader :base_stats
attr_reader :evs
attr_reader :base_exp
attr_reader :growth_rate
attr_reader :gender_ratio
attr_reader :catch_rate
attr_reader :happiness
attr_reader :moves
attr_reader :tutor_moves
attr_reader :egg_moves
attr_reader :abilities
attr_reader :hidden_abilities
attr_reader :wild_item_common
attr_reader :wild_item_uncommon
attr_reader :wild_item_rare
attr_reader :egg_groups
attr_reader :hatch_steps
attr_reader :incense
attr_reader :evolutions
attr_reader :height
attr_reader :weight
attr_reader :color
attr_reader :shape
attr_reader :habitat
attr_reader :generation
attr_reader :mega_stone
attr_reader :mega_move
attr_reader :unmega_form
attr_reader :mega_message
attr_accessor :back_sprite_x
attr_accessor :back_sprite_y
attr_accessor :front_sprite_x
attr_accessor :front_sprite_y
attr_accessor :front_sprite_altitude
attr_accessor :shadow_x
attr_accessor :shadow_size
DATA = {}
DATA_FILENAME = "species.dat"
extend ClassMethodsSymbols
include InstanceMethods
# @param species [Symbol, self, String]
# @param form [Integer]
# @return [self, nil]
def self.get_species_form(species, form)
return nil if !species || !form
validate species => [Symbol, self, String]
validate form => Integer
species = species.species if species.is_a?(self)
species = species.to_sym if species.is_a?(String)
trial = sprintf("%s_%d", species, form).to_sym
species_form = (DATA[trial].nil?) ? species : trial
return (DATA.has_key?(species_form)) ? DATA[species_form] : nil
end
def self.each_species
DATA.each_value { |species| yield species if species.form == 0 }
end
def self.species_count
ret = 0
self.each_species { |species| ret += 1 }
return ret
end
def self.schema(compiling_forms = false)
ret = {
"FormName" => [0, "q"],
"Category" => [0, "s"],
"Pokedex" => [0, "q"],
"Type1" => [0, "e", :Type],
"Type2" => [0, "e", :Type],
"BaseStats" => [0, "vvvvvv"],
"EVs" => [0, "uuuuuu"],
"BaseExp" => [0, "v"],
"CatchRate" => [0, "u"],
"Happiness" => [0, "u"],
"Moves" => [0, "*ue", nil, :Move],
"TutorMoves" => [0, "*e", :Move],
"EggMoves" => [0, "*e", :Move],
"Abilities" => [0, "*e", :Ability],
"HiddenAbilities" => [0, "*e", :Ability],
"WildItemCommon" => [0, "e", :Item],
"WildItemUncommon" => [0, "e", :Item],
"WildItemRare" => [0, "e", :Item],
"EggGroups" => [0, "*e", :EggGroup],
"HatchSteps" => [0, "v"],
"Height" => [0, "f"],
"Weight" => [0, "f"],
"Color" => [0, "e", :BodyColor],
"Shape" => [0, "e", :BodyShape],
"Habitat" => [0, "e", :Habitat],
"Generation" => [0, "i"],
"BattlerPlayerX" => [0, "i"],
"BattlerPlayerY" => [0, "i"],
"BattlerEnemyX" => [0, "i"],
"BattlerEnemyY" => [0, "i"],
"BattlerAltitude" => [0, "i"],
"BattlerShadowX" => [0, "i"],
"BattlerShadowSize" => [0, "u"],
# All properties below here are old names for some properties above.
# They will be removed in v21.
"Rareness" => [0, "u"],
"Compatibility" => [0, "*e", :EggGroup],
"Kind" => [0, "s"],
"BaseEXP" => [0, "v"],
"EffortPoints" => [0, "uuuuuu"],
"HiddenAbility" => [0, "*e", :Ability],
"StepsToHatch" => [0, "v"],
}
if compiling_forms
ret["PokedexForm"] = [0, "u"]
ret["Evolutions"] = [0, "*ees", :Species, :Evolution, nil]
ret["MegaStone"] = [0, "e", :Item]
ret["MegaMove"] = [0, "e", :Move]
ret["UnmegaForm"] = [0, "u"]
ret["MegaMessage"] = [0, "u"]
else
ret["InternalName"] = [0, "n"]
ret["Name"] = [0, "s"]
ret["GrowthRate"] = [0, "e", :GrowthRate]
ret["GenderRatio"] = [0, "e", :GenderRatio]
ret["Incense"] = [0, "e", :Item]
ret["Evolutions"] = [0, "*ses", nil, :Evolution, nil]
# All properties below here are old names for some properties above.
# They will be removed in v21.
ret["GenderRate"] = [0, "e", :GenderRatio]
end
return ret
end
def initialize(hash)
@id = hash[:id]
@species = hash[:species] || @id
@form = hash[:form] || 0
@real_name = hash[:name] || "Unnamed"
@real_form_name = hash[:form_name]
@real_category = hash[:category] || "???"
@real_pokedex_entry = hash[:pokedex_entry] || "???"
@pokedex_form = hash[:pokedex_form] || @form
@type1 = hash[:type1] || :NORMAL
@type2 = hash[:type2] || @type1
@base_stats = hash[:base_stats] || {}
@evs = hash[:evs] || {}
GameData::Stat.each_main do |s|
@base_stats[s.id] = 1 if !@base_stats[s.id] || @base_stats[s.id] <= 0
@evs[s.id] = 0 if !@evs[s.id] || @evs[s.id] < 0
end
@base_exp = hash[:base_exp] || 100
@growth_rate = hash[:growth_rate] || :Medium
@gender_ratio = hash[:gender_ratio] || :Female50Percent
@catch_rate = hash[:catch_rate] || 255
@happiness = hash[:happiness] || 70
@moves = hash[:moves] || []
@tutor_moves = hash[:tutor_moves] || []
@egg_moves = hash[:egg_moves] || []
@abilities = hash[:abilities] || []
@hidden_abilities = hash[:hidden_abilities] || []
@wild_item_common = hash[:wild_item_common]
@wild_item_uncommon = hash[:wild_item_uncommon]
@wild_item_rare = hash[:wild_item_rare]
@egg_groups = hash[:egg_groups] || [:Undiscovered]
@hatch_steps = hash[:hatch_steps] || 1
@incense = hash[:incense]
@evolutions = hash[:evolutions] || []
@height = hash[:height] || 1
@weight = hash[:weight] || 1
@color = hash[:color] || :Red
@shape = hash[:shape] || :Head
@habitat = hash[:habitat] || :None
@generation = hash[:generation] || 0
@mega_stone = hash[:mega_stone]
@mega_move = hash[:mega_move]
@unmega_form = hash[:unmega_form] || 0
@mega_message = hash[:mega_message] || 0
@back_sprite_x = hash[:back_sprite_x] || 0
@back_sprite_y = hash[:back_sprite_y] || 0
@front_sprite_x = hash[:front_sprite_x] || 0
@front_sprite_y = hash[:front_sprite_y] || 0
@front_sprite_altitude = hash[:front_sprite_altitude] || 0
@shadow_x = hash[:shadow_x] || 0
@shadow_size = hash[:shadow_size] || 2
end
# @return [String] the translated name of this species
def name
return pbGetMessageFromHash(MessageTypes::Species, @real_name)
end
# @return [String] the translated name of this form of this species
def form_name
return pbGetMessageFromHash(MessageTypes::FormNames, @real_form_name)
end
# @return [String] the translated Pokédex category of this species
def category
return pbGetMessageFromHash(MessageTypes::Kinds, @real_category)
end
# @return [String] the translated Pokédex entry of this species
def pokedex_entry
return pbGetMessageFromHash(MessageTypes::Entries, @real_pokedex_entry)
end
def apply_metrics_to_sprite(sprite, index, shadow = false)
if shadow
if (index & 1) == 1 # Foe Pokémon
sprite.x += @shadow_x * 2
end
else
if (index & 1) == 0 # Player's Pokémon
sprite.x += @back_sprite_x * 2
sprite.y += @back_sprite_y * 2
else # Foe Pokémon
sprite.x += @front_sprite_x * 2
sprite.y += @front_sprite_y * 2
sprite.y -= @front_sprite_altitude * 2
end
end
end
def shows_shadow?
return true
# return @front_sprite_altitude > 0
end
def get_evolutions(exclude_invalid = false)
ret = []
@evolutions.each do |evo|
next if evo[3] # Is the prevolution
next if evo[1] == :None && exclude_invalid
ret.push([evo[0], evo[1], evo[2]]) # [Species, method, parameter]
end
return ret
end
def get_family_evolutions(exclude_invalid = true)
evos = self.get_evolutions(exclude_invalid)
evos = evos.sort { |a, b| GameData::Species.keys.index(a[0]) <=> GameData::Species.keys.index(b[0]) }
ret = []
evos.each do |evo|
ret.push([@species].concat(evo)) # [Prevo species, evo species, method, parameter]
evo_array = GameData::Species.get(evo[0]).get_family_evolutions(exclude_invalid)
ret.concat(evo_array) if evo_array && evo_array.length > 0
end
return ret
end
def get_previous_species
return @species if @evolutions.length == 0
@evolutions.each { |evo| return evo[0] if evo[3] } # Is the prevolution
return @species
end
def get_baby_species(check_items = false, item1 = nil, item2 = nil)
ret = @species
return ret if @evolutions.length == 0
@evolutions.each do |evo|
next if !evo[3] # Not the prevolution
if check_items
incense = GameData::Species.get(evo[0]).incense
ret = evo[0] if !incense || item1 == incense || item2 == incense
else
ret = evo[0] # Species of prevolution
end
break
end
ret = GameData::Species.get(ret).get_baby_species(check_items, item1, item2) if ret != @species
return ret
end
def get_related_species
sp = self.get_baby_species
evos = GameData::Species.get(sp).get_family_evolutions(false)
return [sp] if evos.length == 0
return [sp].concat(evos.map { |e| e[1] }).uniq
end
def family_evolutions_have_method?(check_method, check_param = nil)
sp = self.get_baby_species
evos = GameData::Species.get(sp).get_family_evolutions
return false if evos.length == 0
evos.each do |evo|
if check_method.is_a?(Array)
next if !check_method.include?(evo[2])
else
next if evo[2] != check_method
end
return true if check_param.nil? || evo[3] == check_param
end
return false
end
# Used by the Moon Ball when checking if a Pokémon's evolution family
# includes an evolution that uses the Moon Stone.
def family_item_evolutions_use_item?(check_item = nil)
sp = self.get_baby_species
evos = GameData::Species.get(sp).get_family_evolutions
return false if !evos || evos.length == 0
evos.each do |evo|
next if GameData::Evolution.get(evo[2]).use_item_proc.nil?
return true if check_item.nil? || evo[3] == check_item
end
return false
end
def minimum_level
return 1 if @evolutions.length == 0
@evolutions.each do |evo|
next if !evo[3] # Not the prevolution
evo_method_data = GameData::Evolution.get(evo[1])
next if evo_method_data.level_up_proc.nil?
min_level = evo_method_data.minimum_level
return (min_level == 0) ? evo[2] : min_level + 1
end
return 1
end
end
end