diff --git a/Data/Scripts/010_Data/001_GameData.rb b/Data/Scripts/010_Data/001_GameData.rb index 74d55f981..7b356a567 100644 --- a/Data/Scripts/010_Data/001_GameData.rb +++ b/Data/Scripts/010_Data/001_GameData.rb @@ -219,6 +219,15 @@ module GameData end return false end + + def get_property_for_PBS(key) + ret = nil + if self.class::SCHEMA.include?(key) + ret = self.send(self.class::SCHEMA[key][0]) + ret = nil if ret == false || (ret.is_a?(Array) && ret.length == 0) + end + return ret + end end #============================================================================= diff --git a/Data/Scripts/010_Data/002_PBS data/002_Type.rb b/Data/Scripts/010_Data/002_PBS data/002_Type.rb index 5b2f620d7..0270b9c16 100644 --- a/Data/Scripts/010_Data/002_PBS data/002_Type.rb +++ b/Data/Scripts/010_Data/002_PBS data/002_Type.rb @@ -2,13 +2,13 @@ module GameData class Type attr_reader :id attr_reader :real_name + attr_reader :icon_position # Where this type's icon is within types.png attr_reader :special_type attr_reader :pseudo_type - attr_reader :flags attr_reader :weaknesses attr_reader :resistances attr_reader :immunities - attr_reader :icon_position # Where this type's icon is within types.png + attr_reader :flags DATA = {} DATA_FILENAME = "types.dat" @@ -16,13 +16,13 @@ module GameData SCHEMA = { "SectionName" => [:id, "m"], "Name" => [:real_name, "s"], + "IconPosition" => [:icon_position, "u"], "IsSpecialType" => [:special_type, "b"], "IsPseudoType" => [:pseudo_type, "b"], - "Flags" => [:flags, "*s"], "Weaknesses" => [:weaknesses, "*m"], "Resistances" => [:resistances, "*m"], "Immunities" => [:immunities, "*m"], - "IconPosition" => [:icon_position, "u"] + "Flags" => [:flags, "*s"] } extend ClassMethodsSymbols @@ -31,16 +31,16 @@ module GameData def initialize(hash) @id = hash[:id] @real_name = hash[:real_name] || "Unnamed" + @icon_position = hash[:icon_position] || 0 @special_type = hash[:special_type] || false @pseudo_type = hash[:pseudo_type] || false - @flags = hash[:flags] || [] @weaknesses = hash[:weaknesses] || [] @weaknesses = [@weaknesses] if !@weaknesses.is_a?(Array) @resistances = hash[:resistances] || [] @resistances = [@resistances] if !@resistances.is_a?(Array) @immunities = hash[:immunities] || [] @immunities = [@immunities] if !@immunities.is_a?(Array) - @icon_position = hash[:icon_position] || 0 + @flags = hash[:flags] || [] end # @return [String] the translated name of this item diff --git a/Data/Scripts/010_Data/002_PBS data/004_Move.rb b/Data/Scripts/010_Data/002_PBS data/004_Move.rb index d28494deb..1d37c03b2 100644 --- a/Data/Scripts/010_Data/002_PBS data/004_Move.rb +++ b/Data/Scripts/010_Data/002_PBS data/004_Move.rb @@ -811,5 +811,12 @@ module GameData data[:function_code] = new_code return data end + + alias __orig__get_property_for_PBS get_property_for_PBS + def get_property_for_PBS(key) + ret = __orig__get_property_for_PBS(key) + ret = nil if ["Power", "Priority", "EffectChance"].include?(key) && ret == 0 + return ret + end end end diff --git a/Data/Scripts/010_Data/002_PBS data/005_Item.rb b/Data/Scripts/010_Data/002_PBS data/005_Item.rb index 6c2b74d71..c7b21da67 100644 --- a/Data/Scripts/010_Data/002_PBS data/005_Item.rb +++ b/Data/Scripts/010_Data/002_PBS data/005_Item.rb @@ -6,12 +6,12 @@ module GameData attr_reader :pocket attr_reader :price attr_reader :sell_price - attr_reader :real_description attr_reader :field_use attr_reader :battle_use attr_reader :flags attr_reader :consumable attr_reader :move + attr_reader :real_description DATA = {} DATA_FILENAME = "items.dat" @@ -23,14 +23,14 @@ module GameData "Pocket" => [:pocket, "v"], "Price" => [:price, "u"], "SellPrice" => [:sell_price, "u"], - "Description" => [:real_description, "q"], "FieldUse" => [:field_use, "e", { "OnPokemon" => 1, "Direct" => 2, "TM" => 3, "HM" => 4, "TR" => 5 }], "BattleUse" => [:battle_use, "e", { "OnPokemon" => 1, "OnMove" => 2, "OnBattler" => 3, "OnFoe" => 4, "Direct" => 5 }], "Flags" => [:flags, "*s"], "Consumable" => [:consumable, "b"], - "Move" => [:move, "e", :Move] + "Move" => [:move, "e", :Move], + "Description" => [:real_description, "q"] } extend ClassMethodsSymbols @@ -88,13 +88,13 @@ module GameData @pocket = hash[:pocket] || 1 @price = hash[:price] || 0 @sell_price = hash[:sell_price] || (@price / 2) - @real_description = hash[:real_description] || "???" @field_use = hash[:field_use] || 0 @battle_use = hash[:battle_use] || 0 @flags = hash[:flags] || [] @consumable = hash[:consumable] @consumable = !is_important? if @consumable.nil? @move = hash[:move] + @real_description = hash[:real_description] || "???" end # @return [String] the translated name of this item @@ -192,5 +192,20 @@ module GameData } return combos[species]&.include?(@id) end + + alias __orig__get_property_for_PBS get_property_for_PBS + def get_property_for_PBS(key) + ret = __orig__get_property_for_PBS(key) + case key + when "SellPrice" + ret = nil if ret == @price / 2 + when "FieldUse", "BattleUse" + ret = nil if ret == 0 + when "Consumable" + ret = @consumable + ret = nil if ret || is_important? # Only return false, only for non-important items + end + return ret + end end end diff --git a/Data/Scripts/010_Data/002_PBS data/007_Species.rb b/Data/Scripts/010_Data/002_PBS data/007_Species.rb index 91f02de10..8f0439b38 100644 --- a/Data/Scripts/010_Data/002_PBS data/007_Species.rb +++ b/Data/Scripts/010_Data/002_PBS data/007_Species.rb @@ -72,51 +72,60 @@ module GameData end def self.schema(compiling_forms = false) - ret = { - "FormName" => [:real_form_name, "q"], - "Category" => [:real_category, "s"], - "Pokedex" => [:real_pokedex_entry, "q"], - "Types" => [:types, "eE", :Type, :Type], - "BaseStats" => [:base_stats, "vvvvvv"], - "EVs" => [:evs, "*ev", :Stat], - "BaseExp" => [:base_exp, "v"], - "CatchRate" => [:catch_rate, "u"], - "Happiness" => [:happiness, "u"], - "Moves" => [:moves, "*ue", nil, :Move], - "TutorMoves" => [:tutor_moves, "*e", :Move], - "EggMoves" => [:egg_moves, "*e", :Move], - "Abilities" => [:abilities, "*e", :Ability], - "HiddenAbilities" => [:hidden_abilities, "*e", :Ability], - "WildItemCommon" => [:wild_item_common, "*e", :Item], - "WildItemUncommon" => [:wild_item_uncommon, "*e", :Item], - "WildItemRare" => [:wild_item_rare, "*e", :Item], - "EggGroups" => [:egg_groups, "*e", :EggGroup], - "HatchSteps" => [:hatch_steps, "v"], - "Height" => [:height, "f"], - "Weight" => [:weight, "f"], - "Color" => [:color, "e", :BodyColor], - "Shape" => [:shape, "e", :BodyShape], - "Habitat" => [:habitat, "e", :Habitat], - "Generation" => [:generation, "i"], - "Flags" => [:flags, "*s"] - } + ret = {} if compiling_forms - ret["SectionName"] = [:id, "ev", :Species] - ret["PokedexForm"] = [:pokedex_form, "u"] - ret["Offspring"] = [:offspring, "*e", :Species] - ret["Evolutions"] = [:evolutions, "*ees", :Species, :Evolution, nil] - ret["MegaStone"] = [:mega_stone, "e", :Item] - ret["MegaMove"] = [:mega_move, "e", :Move] - ret["UnmegaForm"] = [:unmega_form, "u"] - ret["MegaMessage"] = [:mega_message, "u"] + ret["SectionName"] = [:id, "ev", :Species] else - ret["SectionName"] = [:id, "m"] - ret["Name"] = [:real_name, "s"] - ret["GrowthRate"] = [:growth_rate, "e", :GrowthRate] - ret["GenderRatio"] = [:gender_ratio, "e", :GenderRatio] - ret["Incense"] = [:incense, "e", :Item] - ret["Offspring"] = [:offspring, "*s"] - ret["Evolutions"] = [:evolutions, "*ses", nil, :Evolution, nil] + ret["SectionName"] = [:id, "m"] + ret["Name"] = [:real_name, "s"] + end + ret["FormName"] = [:real_form_name, "q"] + if compiling_forms + ret["PokedexForm"] = [:pokedex_form, "u"] + ret["MegaStone"] = [:mega_stone, "e", :Item] + ret["MegaMove"] = [:mega_move, "e", :Move] + ret["UnmegaForm"] = [:unmega_form, "u"] + ret["MegaMessage"] = [:mega_message, "u"] + end + ret["Types"] = [:types, "eE", :Type, :Type] + ret["BaseStats"] = [:base_stats, "vvvvvv"] + if !compiling_forms + ret["GenderRatio"] = [:gender_ratio, "e", :GenderRatio] + ret["GrowthRate"] = [:growth_rate, "e", :GrowthRate] + end + ret["BaseExp"] = [:base_exp, "v"] + ret["EVs"] = [:evs, "*ev", :Stat] + ret["CatchRate"] = [:catch_rate, "u"] + ret["Happiness"] = [:happiness, "u"] + ret["Abilities"] = [:abilities, "*e", :Ability] + ret["HiddenAbilities"] = [:hidden_abilities, "*e", :Ability] + ret["Moves"] = [:moves, "*ue", nil, :Move] + ret["TutorMoves"] = [:tutor_moves, "*e", :Move] + ret["EggMoves"] = [:egg_moves, "*e", :Move] + ret["EggGroups"] = [:egg_groups, "*e", :EggGroup] + ret["HatchSteps"] = [:hatch_steps, "v"] + if compiling_forms + ret["Offspring"] = [:offspring, "*e", :Species] + else + ret["Incense"] = [:incense, "e", :Item] + ret["Offspring"] = [:offspring, "*s"] + end + ret["Height"] = [:height, "f"] + ret["Weight"] = [:weight, "f"] + ret["Color"] = [:color, "e", :BodyColor] + ret["Shape"] = [:shape, "e", :BodyShape] + ret["Habitat"] = [:habitat, "e", :Habitat] + ret["Category"] = [:real_category, "s"] + ret["Pokedex"] = [:real_pokedex_entry, "q"] + ret["Generation"] = [:generation, "i"] + ret["Flags"] = [:flags, "*s"] + ret["WildItemCommon"] = [:wild_item_common, "*e", :Item] + ret["WildItemUncommon"] = [:wild_item_uncommon, "*e", :Item] + ret["WildItemRare"] = [:wild_item_rare, "*e", :Item] + if compiling_forms + ret["Evolutions"] = [:evolutions, "*ees", :Species, :Evolution, nil] + else + ret["Evolutions"] = [:evolutions, "*ses", nil, :Evolution, nil] end return ret end @@ -332,5 +341,66 @@ module GameData end return 1 end + + alias __orig__get_property_for_PBS get_property_for_PBS + def get_property_for_PBS(key, writing_form = false) + ret = nil + if self.class.schema(writing_form).include?(key) + ret = self.send(self.class.schema(writing_form)[key][0]) + ret = nil if ret == false || (ret.is_a?(Array) && ret.length == 0) + end + case key + when "SectionName" + ret = [@species, @form] if writing_form + when "FormName" + ret = nil if nil_or_empty?(ret) + when "PokedexForm" + ret = nil if ret == @form + when "UnmegaForm", "MegaMessage", "Generation" + ret = nil if ret == 0 + when "BaseStats" + new_ret = [] + GameData::Stat.each_main do |s| + new_ret[s.pbs_order] = ret[s.id] if s.pbs_order >= 0 + end + ret = new_ret + when "EVs" + new_ret = [] + GameData::Stat.each_main do |s| + new_ret.push([s.id, ret[s.id]]) if ret[s.id] > 0 && s.pbs_order >= 0 + end + ret = new_ret + when "Height", "Weight" + ret = ret.to_f / 10 + when "Habitat" + ret = nil if ret == :None + when "Evolutions" + if ret + ret = ret.select { |evo| !evo[3] } # Remove prevolutions + ret.each do |evo| + param_type = GameData::Evolution.get(evo[1]).parameter + if !param_type.nil? + if param_type.is_a?(Symbol) && !GameData.const_defined?(param_type) + evo[2] = getConstantName(param_type, evo[2]) + else + evo[2] = evo[2].to_s + end + end + end + ret.each_with_index { |evo, i| ret[i] = evo[0, 3] } + ret = nil if ret.length == 0 + end + end + if writing_form && !ret.nil? + base_form = GameData::Species.get(@species) + if !["WildItemCommon", "WildItemUncommon", "WildItemRare"].include?(key) || + (base_form.wild_item_common == @wild_item_common && + base_form.wild_item_uncommon == @wild_item_uncommon && + base_form.wild_item_rare == @wild_item_rare) + ret = nil if base_form.get_property_for_PBS(key) == ret + end + end + return ret + end end end diff --git a/Data/Scripts/010_Data/002_PBS data/009_SpeciesMetrics.rb b/Data/Scripts/010_Data/002_PBS data/009_SpeciesMetrics.rb index 910f5a043..b4ac39e60 100644 --- a/Data/Scripts/010_Data/002_PBS data/009_SpeciesMetrics.rb +++ b/Data/Scripts/010_Data/002_PBS data/009_SpeciesMetrics.rb @@ -84,5 +84,17 @@ module GameData return true # return @front_sprite_altitude > 0 end + + alias __orig__get_property_for_PBS get_property_for_PBS + def get_property_for_PBS(key) + ret = __orig__get_property_for_PBS(key) + case key + when "SectionName" + ret = [@species, (@form > 0) ? @form : nil] + when "FrontSpriteAltitude" + ret = nil if ret == 0 + end + return ret + end end end diff --git a/Data/Scripts/010_Data/002_PBS data/013_TrainerType.rb b/Data/Scripts/010_Data/002_PBS data/013_TrainerType.rb index 1fec8d4e8..df630e740 100644 --- a/Data/Scripts/010_Data/002_PBS data/013_TrainerType.rb +++ b/Data/Scripts/010_Data/002_PBS data/013_TrainerType.rb @@ -103,5 +103,12 @@ module GameData def has_flag?(flag) return @flags.any? { |f| f.downcase == flag.downcase } end + + alias __orig__get_property_for_PBS get_property_for_PBS + def get_property_for_PBS(key) + ret = __orig__get_property_for_PBS(key) + ret = nil if key == "SkillLevel" && ret == @base_money + return ret + end end end diff --git a/Data/Scripts/010_Data/002_PBS data/020_DungeonParameters.rb b/Data/Scripts/010_Data/002_PBS data/020_DungeonParameters.rb index 44285c04f..df0d4663e 100644 --- a/Data/Scripts/010_Data/002_PBS data/020_DungeonParameters.rb +++ b/Data/Scripts/010_Data/002_PBS data/020_DungeonParameters.rb @@ -37,8 +37,8 @@ module GameData "MaxRoomSize" => [:max_room_size, "vv"], "CorridorWidth" => [:corridor_width, "v"], "ShiftCorridors" => [:random_corridor_shift, "b"], - "NodeLayout" => [:node_layout, "s"], - "RoomLayout" => [:room_layout, "s"], + "NodeLayout" => [:node_layout, "m"], + "RoomLayout" => [:room_layout, "m"], "RoomChance" => [:room_chance, "v"], "ExtraConnections" => [:extra_connections_count, "u"], "FloorPatches" => [:floor_patches, "vvu"], @@ -78,8 +78,8 @@ module GameData @room_max_height = (hash[:max_room_size]) ? hash[:max_room_size][1] : @cell_height - 1 @corridor_width = hash[:corridor_width] || 2 @random_corridor_shift = hash[:random_corridor_shift] - @node_layout = hash[:node_layout]&.downcase&.to_sym || :full - @room_layout = hash[:room_layout]&.downcase&.to_sym || :full + @node_layout = hash[:node_layout] || :full + @room_layout = hash[:room_layout] || :full @room_chance = hash[:room_chance] || 70 @extra_connections_count = hash[:extra_connections_count] || 2 @floor_patch_radius = (hash[:floor_patches]) ? hash[:floor_patches][0] : 3 @@ -115,25 +115,19 @@ module GameData return width, height end - def property_from_string(str) - case str + alias __orig__get_property_for_PBS get_property_for_PBS + def get_property_for_PBS(key) + case key + when "SectionName" then return [@area, (@version > 0) ? @version : nil] when "DungeonSize" then return [@cell_count_x, @cell_count_y] when "CellSize" then return [@cell_width, @cell_height] when "MinRoomSize" then return [@room_min_width, @room_min_height] when "MaxRoomSize" then return [@room_max_width, @room_max_height] - when "CorridorWidth" then return @corridor_width - when "ShiftCorridors" then return @random_corridor_shift - when "NodeLayout" then return @node_layout - when "RoomLayout" then return @room_layout - when "RoomChance" then return @room_chance - when "ExtraConnections" then return @extra_connections_count when "FloorPatches" then return [@floor_patch_radius, @floor_patch_chance, @floor_patch_smooth_rate] when "FloorDecorations" then return [@floor_decoration_density, @floor_decoration_large_density] when "VoidDecorations" then return [@void_decoration_density, @void_decoration_large_density] - when "RNGSeed" then return @rng_seed - when "Flags" then return @flags end - return nil + return __orig__get_property_for_PBS(key) end end end diff --git a/Data/Scripts/021_Compiler/001_Compiler.rb b/Data/Scripts/021_Compiler/001_Compiler.rb index d0c1c4c3f..72f74a5da 100644 --- a/Data/Scripts/021_Compiler/001_Compiler.rb +++ b/Data/Scripts/021_Compiler/001_Compiler.rb @@ -573,12 +573,18 @@ module Compiler loop do (start...schema[1].length).each do |i| index += 1 - file.write(",") if index > 0 value = rec[index] + if schema[1][i, 1].upcase != schema[1][i, 1] || !value.nil? + file.write(",") if index > 0 + end if value.nil? # do nothing elsif value.is_a?(String) - file.write(csvQuote(value)) + if schema[1][i, 1].downcase == "q" + file.write(value) + else + file.write(csvQuote(value)) + end elsif value.is_a?(Symbol) file.write(csvQuote(value.to_s)) elsif value == true diff --git a/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb b/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb index 4f5ce6cc8..ec31f3d51 100644 --- a/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb +++ b/Data/Scripts/021_Compiler/003_Compiler_WritePBS.rb @@ -8,6 +8,34 @@ module Compiler file.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") end + def write_PBS_file_generic(game_data, path) + write_pbs_file_message_start(path) + schema = game_data::SCHEMA + File.open(path, "wb") { |f| + add_PBS_header_to_file(f) + # Write each element in turn + game_data.each do |element| + f.write("\#-------------------------------\r\n") + if schema["SectionName"] + f.write("[") + pbWriteCsvRecord(element.get_property_for_PBS("SectionName"), f, schema["SectionName"]) + f.write("]\r\n") + else + f.write("[#{element.id}]\r\n") + end + schema.each_key do |key| + next if key == "SectionName" + val = element.get_property_for_PBS(key) + next if val.nil? + f.write(sprintf("%s = ", key)) + pbWriteCsvRecord(val, f, schema[key]) + f.write("\r\n") + end + end + } + process_pbs_file_message_end + end + #============================================================================= # Save Town Map data to PBS file #============================================================================= @@ -131,126 +159,35 @@ module Compiler # Save type data to PBS file #============================================================================= def write_types(path = "PBS/types.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - add_PBS_header_to_file(f) - # Write each type in turn - GameData::Type.each do |type| - f.write("\#-------------------------------\r\n") - f.write("[#{type.id}]\r\n") - f.write("Name = #{type.real_name}\r\n") - f.write("IconPosition = #{type.icon_position}\r\n") - f.write("IsSpecialType = true\r\n") if type.special? - f.write("IsPseudoType = true\r\n") if type.pseudo_type - f.write(sprintf("Flags = %s\r\n", type.flags.join(","))) if type.flags.length > 0 - f.write("Weaknesses = #{type.weaknesses.join(',')}\r\n") if type.weaknesses.length > 0 - f.write("Resistances = #{type.resistances.join(',')}\r\n") if type.resistances.length > 0 - f.write("Immunities = #{type.immunities.join(',')}\r\n") if type.immunities.length > 0 - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::Type, path) end #============================================================================= # Save ability data to PBS file #============================================================================= def write_abilities(path = "PBS/abilities.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - add_PBS_header_to_file(f) - # Write each ability in turn - GameData::Ability.each do |ability| - f.write("\#-------------------------------\r\n") - f.write("[#{ability.id}]\r\n") - f.write("Name = #{ability.real_name}\r\n") - f.write("Description = #{ability.real_description}\r\n") - f.write(sprintf("Flags = %s\r\n", ability.flags.join(","))) if ability.flags.length > 0 - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::Ability, path) end #============================================================================= # Save move data to PBS file #============================================================================= def write_moves(path = "PBS/moves.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - idx = 0 - add_PBS_header_to_file(f) - # Write each move in turn - GameData::Move.each do |move| - echo "." if idx % 50 == 0 - idx += 1 - Graphics.update if idx % 250 == 0 - f.write("\#-------------------------------\r\n") - f.write("[#{move.id}]\r\n") - f.write("Name = #{move.real_name}\r\n") - f.write("Type = #{move.type}\r\n") - category = GameData::Move::SCHEMA["Category"][2][move.category] - f.write("Category = #{category}\r\n") - f.write("Power = #{move.base_damage}\r\n") if move.base_damage > 0 - f.write("Accuracy = #{move.accuracy}\r\n") - f.write("TotalPP = #{move.total_pp}\r\n") - f.write("Target = #{move.target}\r\n") - f.write("Priority = #{move.priority}\r\n") if move.priority != 0 - f.write("FunctionCode = #{move.function_code}\r\n") - f.write("Flags = #{move.flags.join(',')}\r\n") if move.flags.length > 0 - f.write("EffectChance = #{move.effect_chance}\r\n") if move.effect_chance > 0 - f.write("Description = #{move.real_description}\r\n") - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::Move, path) end #============================================================================= # Save item data to PBS file #============================================================================= def write_items(path = "PBS/items.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - idx = 0 - add_PBS_header_to_file(f) - GameData::Item.each do |item| - echo "." if idx % 50 == 0 - idx += 1 - Graphics.update if idx % 250 == 0 - f.write("\#-------------------------------\r\n") - f.write(sprintf("[%s]\r\n", item.id)) - f.write(sprintf("Name = %s\r\n", item.real_name)) - f.write(sprintf("NamePlural = %s\r\n", item.real_name_plural)) - f.write(sprintf("Pocket = %d\r\n", item.pocket)) - f.write(sprintf("Price = %d\r\n", item.price)) - f.write(sprintf("SellPrice = %d\r\n", item.sell_price)) if item.sell_price != item.price / 2 - field_use = GameData::Item::SCHEMA["FieldUse"][2].key(item.field_use) - f.write(sprintf("FieldUse = %s\r\n", field_use)) if field_use - battle_use = GameData::Item::SCHEMA["BattleUse"][2].key(item.battle_use) - f.write(sprintf("BattleUse = %s\r\n", battle_use)) if battle_use - f.write(sprintf("Consumable = false\r\n")) if !item.is_important? && !item.consumable - f.write(sprintf("Flags = %s\r\n", item.flags.join(","))) if item.flags.length > 0 - f.write(sprintf("Move = %s\r\n", item.move)) if item.move - f.write(sprintf("Description = %s\r\n", item.real_description)) - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::Item, path) end #============================================================================= # Save berry plant data to PBS file #============================================================================= def write_berry_plants(path = "PBS/berry_plants.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - add_PBS_header_to_file(f) - GameData::BerryPlant.each do |bp| - f.write("\#-------------------------------\r\n") - f.write(sprintf("[%s]\r\n", bp.id)) - f.write(sprintf("HoursPerStage = %d\r\n", bp.hours_per_stage)) - f.write(sprintf("DryingPerHour = %d\r\n", bp.drying_per_hour)) - f.write(sprintf("Yield = %s\r\n", bp.yield.join(","))) - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::BerryPlant, path) end #============================================================================= @@ -258,85 +195,25 @@ module Compiler #============================================================================= def write_pokemon(path = "PBS/pokemon.txt") write_pbs_file_message_start(path) + schema = GameData::Species.schema File.open(path, "wb") { |f| - idx = 0 add_PBS_header_to_file(f) - GameData::Species.each_species do |species| - echo "." if idx % 50 == 0 - idx += 1 - Graphics.update if idx % 250 == 0 + # Write each element in turn + GameData::Species.each_species do |element| f.write("\#-------------------------------\r\n") - f.write(sprintf("[%s]\r\n", species.id)) - f.write(sprintf("Name = %s\r\n", species.real_name)) - f.write(sprintf("Types = %s\r\n", species.types.uniq.compact.join(","))) - stats_array = [] - evs_array = [] - GameData::Stat.each_main do |s| - next if s.pbs_order < 0 - stats_array[s.pbs_order] = species.base_stats[s.id] - evs_array.concat([s.id.to_s, species.evs[s.id]]) if species.evs[s.id] > 0 + if schema["SectionName"] + f.write("[") + pbWriteCsvRecord(element.get_property_for_PBS("SectionName"), f, schema["SectionName"]) + f.write("]\r\n") + else + f.write("[#{element.id}]\r\n") end - f.write(sprintf("BaseStats = %s\r\n", stats_array.join(","))) - f.write(sprintf("GenderRatio = %s\r\n", species.gender_ratio)) - f.write(sprintf("GrowthRate = %s\r\n", species.growth_rate)) - f.write(sprintf("BaseExp = %d\r\n", species.base_exp)) - f.write(sprintf("EVs = %s\r\n", evs_array.join(","))) - f.write(sprintf("CatchRate = %d\r\n", species.catch_rate)) - f.write(sprintf("Happiness = %d\r\n", species.happiness)) - if species.abilities.length > 0 - f.write(sprintf("Abilities = %s\r\n", species.abilities.join(","))) - end - if species.hidden_abilities.length > 0 - f.write(sprintf("HiddenAbilities = %s\r\n", species.hidden_abilities.join(","))) - end - if species.moves.length > 0 - f.write(sprintf("Moves = %s\r\n", species.moves.join(","))) - end - if species.tutor_moves.length > 0 - f.write(sprintf("TutorMoves = %s\r\n", species.tutor_moves.join(","))) - end - if species.egg_moves.length > 0 - f.write(sprintf("EggMoves = %s\r\n", species.egg_moves.join(","))) - end - if species.egg_groups.length > 0 - f.write(sprintf("EggGroups = %s\r\n", species.egg_groups.join(","))) - end - f.write(sprintf("HatchSteps = %d\r\n", species.hatch_steps)) - f.write(sprintf("Incense = %s\r\n", species.incense)) if species.incense - if species.offspring.length > 0 - f.write(sprintf("Offspring = %s\r\n", species.offspring.join(","))) - end - f.write(sprintf("Height = %.1f\r\n", species.height / 10.0)) - f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0)) - f.write(sprintf("Color = %s\r\n", species.color)) - f.write(sprintf("Shape = %s\r\n", species.shape)) - f.write(sprintf("Habitat = %s\r\n", species.habitat)) if species.habitat != :None - f.write(sprintf("Category = %s\r\n", species.real_category)) - f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry)) - f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty? - f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != 0 - f.write(sprintf("Flags = %s\r\n", species.flags.join(","))) if species.flags.length > 0 - f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common.join(","))) if species.wild_item_common.length > 0 - f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon.join(","))) if species.wild_item_uncommon.length > 0 - f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare.join(","))) if species.wild_item_rare.length > 0 - if species.evolutions.any? { |evo| !evo[3] } - f.write("Evolutions = ") - need_comma = false - species.evolutions.each do |evo| - next if evo[3] # Skip prevolution entries - f.write(",") if need_comma - need_comma = true - evo_type_data = GameData::Evolution.get(evo[1]) - param_type = evo_type_data.parameter - f.write(sprintf("%s,%s,", evo[0], evo_type_data.id.to_s)) - if !param_type.nil? - if param_type.is_a?(Symbol) && !GameData.const_defined?(param_type) - f.write(getConstantName(param_type, evo[2])) - else - f.write(evo[2].to_s) - end - end - end + schema.each_key do |key| + next if key == "SectionName" + val = element.get_property_for_PBS(key) + next if val.nil? + f.write(sprintf("%s = ", key)) + pbWriteCsvRecord(val, f, schema[key]) f.write("\r\n") end end @@ -349,96 +226,26 @@ module Compiler #============================================================================= def write_pokemon_forms(path = "PBS/pokemon_forms.txt") write_pbs_file_message_start(path) + schema = GameData::Species.schema(true) File.open(path, "wb") { |f| - idx = 0 add_PBS_header_to_file(f) - GameData::Species.each do |species| - echo "." if idx % 50 == 0 - idx += 1 - Graphics.update if idx % 250 == 0 - next if species.form == 0 - base_species = GameData::Species.get(species.species) + # Write each element in turn + GameData::Species.each do |element| + next if element.form == 0 f.write("\#-------------------------------\r\n") - f.write(sprintf("[%s,%d]\r\n", species.species, species.form)) - f.write(sprintf("FormName = %s\r\n", species.real_form_name)) if species.real_form_name && !species.real_form_name.empty? - f.write(sprintf("PokedexForm = %d\r\n", species.pokedex_form)) if species.pokedex_form != species.form - f.write(sprintf("MegaStone = %s\r\n", species.mega_stone)) if species.mega_stone - f.write(sprintf("MegaMove = %s\r\n", species.mega_move)) if species.mega_move - f.write(sprintf("UnmegaForm = %d\r\n", species.unmega_form)) if species.unmega_form != 0 - f.write(sprintf("MegaMessage = %d\r\n", species.mega_message)) if species.mega_message != 0 - if species.types.uniq.compact != base_species.types.uniq.compact - f.write(sprintf("Types = %s\r\n", species.types.uniq.compact.join(","))) + if schema["SectionName"] + f.write("[") + pbWriteCsvRecord(element.get_property_for_PBS("SectionName", true), f, schema["SectionName"]) + f.write("]\r\n") + else + f.write("[#{element.id}]\r\n") end - stats_array = [] - evs_array = [] - GameData::Stat.each_main do |s| - next if s.pbs_order < 0 - stats_array[s.pbs_order] = species.base_stats[s.id] - evs_array.concat([s.id.to_s, species.evs[s.id]]) if species.evs[s.id] > 0 - end - f.write(sprintf("BaseStats = %s\r\n", stats_array.join(","))) if species.base_stats != base_species.base_stats - f.write(sprintf("BaseExp = %d\r\n", species.base_exp)) if species.base_exp != base_species.base_exp - f.write(sprintf("EVs = %s\r\n", evs_array.join(","))) if species.evs != base_species.evs - f.write(sprintf("CatchRate = %d\r\n", species.catch_rate)) if species.catch_rate != base_species.catch_rate - f.write(sprintf("Happiness = %d\r\n", species.happiness)) if species.happiness != base_species.happiness - if species.abilities.length > 0 && species.abilities != base_species.abilities - f.write(sprintf("Abilities = %s\r\n", species.abilities.join(","))) - end - if species.hidden_abilities.length > 0 && species.hidden_abilities != base_species.hidden_abilities - f.write(sprintf("HiddenAbilities = %s\r\n", species.hidden_abilities.join(","))) - end - if species.moves.length > 0 && species.moves != base_species.moves - f.write(sprintf("Moves = %s\r\n", species.moves.join(","))) - end - if species.tutor_moves.length > 0 && species.tutor_moves != base_species.tutor_moves - f.write(sprintf("TutorMoves = %s\r\n", species.tutor_moves.join(","))) - end - if species.egg_moves.length > 0 && species.egg_moves != base_species.egg_moves - f.write(sprintf("EggMoves = %s\r\n", species.egg_moves.join(","))) - end - if species.egg_groups.length > 0 && species.egg_groups != base_species.egg_groups - f.write(sprintf("EggGroups = %s\r\n", species.egg_groups.join(","))) - end - f.write(sprintf("HatchSteps = %d\r\n", species.hatch_steps)) if species.hatch_steps != base_species.hatch_steps - if species.offspring.length > 0 && species.offspring != base_species.offspring - f.write(sprintf("Offspring = %s\r\n", species.offspring.join(","))) - end - f.write(sprintf("Height = %.1f\r\n", species.height / 10.0)) if species.height != base_species.height - f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0)) if species.weight != base_species.weight - f.write(sprintf("Color = %s\r\n", species.color)) if species.color != base_species.color - f.write(sprintf("Shape = %s\r\n", species.shape)) if species.shape != base_species.shape - if species.habitat != :None && species.habitat != base_species.habitat - f.write(sprintf("Habitat = %s\r\n", species.habitat)) - end - f.write(sprintf("Category = %s\r\n", species.real_category)) if species.real_category != base_species.real_category - f.write(sprintf("Pokedex = %s\r\n", species.real_pokedex_entry)) if species.real_pokedex_entry != base_species.real_pokedex_entry - f.write(sprintf("Generation = %d\r\n", species.generation)) if species.generation != base_species.generation - f.write(sprintf("Flags = %s\r\n", species.flags.join(","))) if species.flags.length > 0 && species.flags != base_species.flags - if species.wild_item_common != base_species.wild_item_common || - species.wild_item_uncommon != base_species.wild_item_uncommon || - species.wild_item_rare != base_species.wild_item_rare - f.write(sprintf("WildItemCommon = %s\r\n", species.wild_item_common.join(","))) if species.wild_item_common.length > 0 - f.write(sprintf("WildItemUncommon = %s\r\n", species.wild_item_uncommon.join(","))) if species.wild_item_uncommon.length > 0 - f.write(sprintf("WildItemRare = %s\r\n", species.wild_item_rare.join(","))) if species.wild_item_rare.length > 0 - end - if species.evolutions != base_species.evolutions && species.evolutions.any? { |evo| !evo[3] } - f.write("Evolutions = ") - need_comma = false - species.evolutions.each do |evo| - next if evo[3] # Skip prevolution entries - f.write(",") if need_comma - need_comma = true - evo_type_data = GameData::Evolution.get(evo[1]) - param_type = evo_type_data.parameter - f.write(sprintf("%s,%s,", evo[0], evo_type_data.id.to_s)) - if !param_type.nil? - if param_type.is_a?(Symbol) && !GameData.const_defined?(param_type) - f.write(getConstantName(param_type, evo[2])) - else - f.write(evo[2].to_s) - end - end - end + schema.each_key do |key| + next if key == "SectionName" + val = element.get_property_for_PBS(key, true) + next if val.nil? + f.write(sprintf("%s = ", key)) + pbWriteCsvRecord(val, f, schema[key]) f.write("\r\n") end end @@ -451,48 +258,39 @@ module Compiler #============================================================================= def write_pokemon_metrics(path = "PBS/pokemon_metrics.txt") write_pbs_file_message_start(path) - # Get in species order then in form order - sort_array = [] - dex_numbers = {} - i = 0 - GameData::SpeciesMetrics.each do |metrics| - dex_numbers[metrics.species] = i if !dex_numbers[metrics.species] - sort_array.push([dex_numbers[metrics.species], metrics.id, metrics.species, metrics.form]) - i += 1 - end - sort_array.sort! { |a, b| (a[0] == b[0]) ? a[3] <=> b[3] : a[0] <=> b[0] } - # Write file + schema = GameData::SpeciesMetrics::SCHEMA File.open(path, "wb") { |f| - idx = 0 add_PBS_header_to_file(f) - sort_array.each do |val| - echo "." if idx % 50 == 0 - idx += 1 - Graphics.update if idx % 250 == 0 - species = GameData::SpeciesMetrics.get(val[1]) - if species.form > 0 - base_species = GameData::SpeciesMetrics.get(val[2]) - next if species.back_sprite == base_species.back_sprite && - species.front_sprite == base_species.front_sprite && - species.front_sprite_altitude == base_species.front_sprite_altitude && - species.shadow_x == base_species.shadow_x && - species.shadow_size == base_species.shadow_size + # Write each element in turn + GameData::SpeciesMetrics.each do |element| + if element.form > 0 + base_element = GameData::SpeciesMetrics.get(element.species) + next if element.back_sprite == base_element.back_sprite && + element.front_sprite == base_element.front_sprite && + element.front_sprite_altitude == base_element.front_sprite_altitude && + element.shadow_x == base_element.shadow_x && + element.shadow_size == base_element.shadow_size else - next if species.back_sprite == [0, 0] && species.front_sprite == [0, 0] && - species.front_sprite_altitude == 0 && - species.shadow_x == 0 && species.shadow_size == 2 + next if element.back_sprite == [0, 0] && element.front_sprite == [0, 0] && + element.front_sprite_altitude == 0 && + element.shadow_x == 0 && element.shadow_size == 2 end f.write("\#-------------------------------\r\n") - if species.form > 0 - f.write(sprintf("[%s,%d]\r\n", species.species, species.form)) + if schema["SectionName"] + f.write("[") + pbWriteCsvRecord(element.get_property_for_PBS("SectionName"), f, schema["SectionName"]) + f.write("]\r\n") else - f.write(sprintf("[%s]\r\n", species.species)) + f.write("[#{element.id}]\r\n") + end + schema.each_key do |key| + next if key == "SectionName" + val = element.get_property_for_PBS(key) + next if val.nil? + f.write(sprintf("%s = ", key)) + pbWriteCsvRecord(val, f, schema[key]) + f.write("\r\n") end - f.write(sprintf("BackSprite = %s\r\n", species.back_sprite.join(","))) - f.write(sprintf("FrontSprite = %s\r\n", species.front_sprite.join(","))) - f.write(sprintf("FrontSpriteAltitude = %d\r\n", species.front_sprite_altitude)) if species.front_sprite_altitude != 0 - f.write(sprintf("ShadowX = %d\r\n", species.shadow_x)) - f.write(sprintf("ShadowSize = %d\r\n", species.shadow_size)) end } process_pbs_file_message_end @@ -502,21 +300,7 @@ module Compiler # Save Shadow Pokémon data to PBS file #============================================================================= def write_shadow_pokemon(path = "PBS/shadow_pokemon.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - idx = 0 - add_PBS_header_to_file(f) - GameData::ShadowPokemon.each do |shadow| - echo "." if idx % 150 == 0 - idx += 1 - f.write("\#-------------------------------\r\n") - f.write(sprintf("[%s]\r\n", shadow.id)) - f.write(sprintf("GaugeSize = %d\r\n", shadow.gauge_size)) - f.write(sprintf("Moves = %s\r\n", shadow.moves.join(","))) if shadow.moves.length > 0 - f.write(sprintf("Flags = %s\r\n", shadow.flags.join(","))) if shadow.flags.length > 0 - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::ShadowPokemon, path) end #============================================================================= @@ -555,20 +339,7 @@ module Compiler # Save ability data to PBS file #============================================================================= def write_ribbons(path = "PBS/ribbons.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - add_PBS_header_to_file(f) - # Write each ability in turn - GameData::Ribbon.each do |ribbon| - f.write("\#-------------------------------\r\n") - f.write("[#{ribbon.id}]\r\n") - f.write("Name = #{ribbon.real_name}\r\n") - f.write("IconPosition = #{ribbon.icon_position}\r\n") - f.write("Description = #{ribbon.real_description}\r\n") - f.write(sprintf("Flags = %s\r\n", ribbon.flags.join(","))) if ribbon.flags.length > 0 - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::Ribbon, path) end #============================================================================= @@ -615,24 +386,7 @@ module Compiler # Save trainer type data to PBS file #============================================================================= def write_trainer_types(path = "PBS/trainer_types.txt") - write_pbs_file_message_start(path) - File.open(path, "wb") { |f| - add_PBS_header_to_file(f) - GameData::TrainerType.each do |t| - f.write("\#-------------------------------\r\n") - f.write(sprintf("[%s]\r\n", t.id)) - f.write(sprintf("Name = %s\r\n", t.real_name)) - gender = GameData::TrainerType::SCHEMA["Gender"][2].key(t.gender) - f.write(sprintf("Gender = %s\r\n", gender)) - f.write(sprintf("BaseMoney = %d\r\n", t.base_money)) - f.write(sprintf("SkillLevel = %d\r\n", t.skill_level)) if t.skill_level != t.base_money - f.write(sprintf("Flags = %s\r\n", t.flags.join(","))) if t.flags.length > 0 - f.write(sprintf("IntroBGM = %s\r\n", t.intro_BGM)) if !nil_or_empty?(t.intro_BGM) - f.write(sprintf("BattleBGM = %s\r\n", t.battle_BGM)) if !nil_or_empty?(t.battle_BGM) - f.write(sprintf("VictoryBGM = %s\r\n", t.victory_BGM)) if !nil_or_empty?(t.victory_BGM) - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::TrainerType, path) end #============================================================================= @@ -805,31 +559,31 @@ module Compiler #============================================================================= def write_metadata(path = "PBS/metadata.txt") write_pbs_file_message_start(path) + global_schema = GameData::Metadata::SCHEMA + player_schema = GameData::PlayerMetadata::SCHEMA File.open(path, "wb") { |f| add_PBS_header_to_file(f) - # Write metadata - f.write("\#-------------------------------\r\n") - f.write("[0]\r\n") - metadata = GameData::Metadata.get - schema = GameData::Metadata::SCHEMA - schema.keys.each do |key| - record = metadata.property_from_string(key) - next if record.nil? || (record.is_a?(Array) && record.empty?) - f.write(sprintf("%s = ", key)) - pbWriteCsvRecord(record, f, schema[key]) - f.write("\r\n") - end - # Write player metadata - schema = GameData::PlayerMetadata::SCHEMA - GameData::PlayerMetadata.each do |player_data| - f.write("\#-------------------------------\r\n") - f.write(sprintf("[%d]\r\n", player_data.id)) - schema.keys.each do |key| - record = player_data.property_from_string(key) - next if record.nil? || (record.is_a?(Array) && record.empty?) - f.write(sprintf("%s = ", key)) - pbWriteCsvRecord(record, f, schema[key]) - f.write("\r\n") + # Write each element in turn + [GameData::Metadata, GameData::PlayerMetadata].each do |game_data| + schema = global_schema if game_data == GameData::Metadata + schema = player_schema if game_data == GameData::PlayerMetadata + game_data.each do |element| + f.write("\#-------------------------------\r\n") + if schema["SectionName"] + f.write("[") + pbWriteCsvRecord(element.get_property_for_PBS("SectionName"), f, schema["SectionName"]) + f.write("]\r\n") + else + f.write("[#{element.id}]\r\n") + end + schema.each_key do |key| + next if key == "SectionName" + val = element.get_property_for_PBS(key) + next if val.nil? + f.write(sprintf("%s = ", key)) + pbWriteCsvRecord(val, f, schema[key]) + f.write("\r\n") + end end end } @@ -846,23 +600,21 @@ module Compiler File.open(path, "wb") { |f| idx = 0 add_PBS_header_to_file(f) - GameData::MapMetadata.each do |map_data| + GameData::MapMetadata.each do |element| echo "." if idx % 50 == 0 idx += 1 Graphics.update if idx % 250 == 0 f.write("\#-------------------------------\r\n") - map_name = (map_infos && map_infos[map_data.id]) ? map_infos[map_data.id].name : nil - if map_name - f.write(sprintf("[%03d] # %s\r\n", map_data.id, map_name)) - f.write("Name = #{map_name}\r\n") if nil_or_empty?(map_data.real_name) - else - f.write(sprintf("[%03d]\r\n", map_data.id)) - end - schema.keys.each do |key| - record = map_data.property_from_string(key) - next if record.nil? || (record.is_a?(Array) && record.empty?) + map_name = (map_infos && map_infos[element.id]) ? map_infos[element.id].name : nil + f.write(sprintf("[%03d]", element.id)) + f.write(sprintf(" # %s", map_name)) if map_name + f.write("\r\n") + schema.each_key do |key| + next if key == "SectionName" + val = element.get_property_for_PBS(key) + next if val.nil? f.write(sprintf("%s = ", key)) - pbWriteCsvRecord(record, f, schema[key]) + pbWriteCsvRecord(val, f, schema[key]) f.write("\r\n") end end @@ -926,33 +678,7 @@ module Compiler # Save dungeon parameters to PBS file #============================================================================= def write_dungeon_parameters(path = "PBS/dungeon_parameters.txt") - write_pbs_file_message_start(path) - schema = GameData::DungeonParameters::SCHEMA - keys = schema.keys - # Write file - File.open(path, "wb") { |f| - idx = 0 - add_PBS_header_to_file(f) - GameData::DungeonParameters.each do |parameters_data| - echo "." if idx % 50 == 0 - idx += 1 - Graphics.update if idx % 250 == 0 - f.write("\#-------------------------------\r\n") - if parameters_data.version > 0 - f.write(sprintf("[%s,%d]\r\n", parameters_data.area, parameters_data.version)) - else - f.write(sprintf("[%s]\r\n", parameters_data.area)) - end - keys.each do |key| - value = parameters_data.property_from_string(key) - next if !value || (value.is_a?(Array) && value.length == 0) - f.write(sprintf("%s = ", key)) - pbWriteCsvRecord(value, f, schema[key]) - f.write("\r\n") - end - end - } - process_pbs_file_message_end + write_PBS_file_generic(GameData::DungeonParameters, path) end #============================================================================= diff --git a/PBS/abilities.txt b/PBS/abilities.txt index 5af587cb2..d18729217 100644 --- a/PBS/abilities.txt +++ b/PBS/abilities.txt @@ -158,8 +158,8 @@ Description = The Pokémon is protected from flinching. #------------------------------- [MAGMAARMOR] Name = Magma Armor -Flags = FasterEggHatching Description = Prevents the Pokémon from becoming frozen. +Flags = FasterEggHatching #------------------------------- [WATERVEIL] Name = Water Veil @@ -195,8 +195,8 @@ Description = The Pokémon awakens quickly from sleep. #------------------------------- [FLAMEBODY] Name = Flame Body -Flags = FasterEggHatching Description = Contact with the Pokémon may burn the attacker. +Flags = FasterEggHatching #------------------------------- [RUNAWAY] Name = Run Away @@ -972,8 +972,8 @@ Description = This Pokémon's moves cannot be redirected. #------------------------------- [STEAMENGINE] Name = Steam Engine -Flags = FasterEggHatching Description = Boosts Speed drastically if hit by a Fire or Water move. +Flags = FasterEggHatching #------------------------------- [PUNKROCK] Name = Punk Rock @@ -1069,4 +1069,4 @@ Description = Combines Unnerve and Chilling Neigh Abilities. #------------------------------- [ASONEGRIMNEIGH] Name = As One -Description = Combines Unnerve and Grim Neigh Abilities. \ No newline at end of file +Description = Combines Unnerve and Grim Neigh Abilities. diff --git a/PBS/items.txt b/PBS/items.txt index e1459fa97..a1cdb6091 100644 --- a/PBS/items.txt +++ b/PBS/items.txt @@ -33,8 +33,8 @@ NamePlural = Black Flutes Pocket = 1 Price = 20 FieldUse = Direct -Consumable = false Flags = Fling_30 +Consumable = false Description = A black flute made from blown glass. Its melody makes wild Pokémon less likely to appear. #------------------------------- [WHITEFLUTE] @@ -43,8 +43,8 @@ NamePlural = White Flutes Pocket = 1 Price = 20 FieldUse = Direct -Consumable = false Flags = Fling_30 +Consumable = false Description = A white flute made from blown glass. Its melody makes wild Pokémon more likely to appear. #------------------------------- [HONEY] @@ -5695,8 +5695,8 @@ Pocket = 7 Price = 20 FieldUse = OnPokemon BattleUse = OnPokemon -Consumable = false Flags = Fling_30 +Consumable = false Description = A blue flute made from blown glass. Its melody awakens a single Pokémon from sleep. #------------------------------- [YELLOWFLUTE] @@ -5705,8 +5705,8 @@ NamePlural = Yellow Flutes Pocket = 7 Price = 20 BattleUse = OnBattler -Consumable = false Flags = Fling_30 +Consumable = false Description = A yellow flute made from blown glass. Its melody snaps a single Pokémon out of confusion. #------------------------------- [REDFLUTE] @@ -5715,8 +5715,8 @@ NamePlural = Red Flutes Pocket = 7 Price = 20 BattleUse = OnBattler -Consumable = false Flags = Fling_30 +Consumable = false Description = A red flute made from blown glass. Its melody snaps a single Pokémon out of infatuation. #------------------------------- [POKEDOLL] diff --git a/PBS/metadata.txt b/PBS/metadata.txt index 90ee730a1..5647de8c0 100644 --- a/PBS/metadata.txt +++ b/PBS/metadata.txt @@ -18,7 +18,9 @@ WalkCharset = trainer_POKEMONTRAINER_Red RunCharset = boy_run CycleCharset = boy_bike SurfCharset = boy_surf +DiveCharset = boy_surf FishCharset = boy_fish_offset +SurfFishCharset = boy_fish_offset #------------------------------- [2] TrainerType = POKEMONTRAINER_Leaf @@ -26,4 +28,6 @@ WalkCharset = trainer_POKEMONTRAINER_Leaf RunCharset = girl_run CycleCharset = girl_bike SurfCharset = girl_surf +DiveCharset = girl_surf FishCharset = girl_fish_offset +SurfFishCharset = girl_fish_offset diff --git a/PBS/pokemon.txt b/PBS/pokemon.txt index 28c1ab2b5..43012e95f 100644 --- a/PBS/pokemon.txt +++ b/PBS/pokemon.txt @@ -5279,6 +5279,7 @@ Evolutions = MISMAGIUS,Item,DUSKSTONE #------------------------------- [UNOWN] Name = Unown +FormName = A Types = PSYCHIC BaseStats = 48,72,48,48,72,48 GenderRatio = Genderless @@ -5299,7 +5300,6 @@ Shape = Head Habitat = Rare Category = Symbol Pokedex = This Pokémon is shaped like ancient text characters. Although research is ongoing, it is a mystery as to which came first, the ancient writings or the various Unown. -FormName = A Generation = 2 #------------------------------- [WOBBUFFET] @@ -9238,6 +9238,7 @@ Generation = 3 #------------------------------- [CASTFORM] Name = Castform +FormName = Normal Form Types = NORMAL BaseStats = 70,70,70,70,70,70 GenderRatio = Female50Percent @@ -9259,7 +9260,6 @@ Shape = Head Habitat = Grassland Category = Weather Pokedex = It alters its form depending on the weather. Changes in the climate such as the temperature and humidity appear to affect its cellular structure. -FormName = Normal Form Generation = 3 WildItemCommon = MYSTICWATER WildItemUncommon = MYSTICWATER @@ -10156,6 +10156,7 @@ WildItemRare = STARPIECE #------------------------------- [DEOXYS] Name = Deoxys +FormName = Normal Forme Types = PSYCHIC BaseStats = 50,150,50,150,150,50 GenderRatio = Genderless @@ -10176,7 +10177,6 @@ Shape = Bipedal Habitat = Rare Category = DNA Pokedex = A Pokémon that mutated from an extraterrestrial virus exposed to a laser beam. Its body is configured for superior agility and speed. -FormName = Normal Forme Generation = 3 #------------------------------- [TURTWIG] @@ -10810,6 +10810,7 @@ Generation = 4 #------------------------------- [BURMY] Name = Burmy +FormName = Plant Cloak Types = BUG BaseStats = 40,29,45,36,29,45 GenderRatio = Female50Percent @@ -10830,13 +10831,13 @@ Color = Green Shape = HeadBase Category = Bagworm Pokedex = To shelter itself from cold, wintry winds, it covers itself with a cloak made of twigs and leaves. -FormName = Plant Cloak Generation = 4 Flags = InheritFormFromMother Evolutions = WORMADAM,LevelFemale,20,MOTHIM,LevelMale,20 #------------------------------- [WORMADAM] Name = Wormadam +FormName = Plant Cloak Types = BUG,GRASS BaseStats = 60,59,85,36,79,105 GenderRatio = AlwaysFemale @@ -10857,7 +10858,6 @@ Color = Green Shape = HeadBase Category = Bagworm Pokedex = When Burmy evolved, its cloak became a part of this Pokémon's body. The cloak is never shed. -FormName = Plant Cloak Generation = 4 Flags = InheritFormFromMother WildItemUncommon = SILVERPOWDER @@ -11042,6 +11042,7 @@ Evolutions = CHERRIM,Level,25 #------------------------------- [CHERRIM] Name = Cherrim +FormName = Overcast Form Types = GRASS BaseStats = 70,60,70,85,87,78 GenderRatio = Female50Percent @@ -11061,12 +11062,12 @@ Color = Purple Shape = HeadLegs Category = Blossom Pokedex = Its folded petals are pretty tough. Bird Pokémon can peck at them all they want, and Cherrim won't be bothered at all. -FormName = Overcast Form Generation = 4 WildItemUncommon = MIRACLESEED #------------------------------- [SHELLOS] Name = Shellos +FormName = West Sea Types = WATER BaseStats = 76,48,48,34,57,62 GenderRatio = Female50Percent @@ -11088,13 +11089,13 @@ Color = Purple Shape = Serpentine Category = Sea Slug Pokedex = This Pokémon's habitat shapes its physique. According to some theories, life in warm ocean waters causes this variation to develop. -FormName = West Sea Generation = 4 Flags = InheritFormFromMother Evolutions = GASTRODON,Level,30 #------------------------------- [GASTRODON] Name = Gastrodon +FormName = West Sea Types = WATER,GROUND BaseStats = 111,83,68,39,92,82 GenderRatio = Female50Percent @@ -11115,7 +11116,6 @@ Color = Purple Shape = Serpentine Category = Sea Slug Pokedex = Its search for food sometimes leads it onto land, where it leaves behind a sticky trail of slime as it passes through. -FormName = West Sea Generation = 4 Flags = InheritFormFromMother #------------------------------- @@ -12505,6 +12505,7 @@ Generation = 4 #------------------------------- [ROTOM] Name = Rotom +FormName = Rotom Types = ELECTRIC,GHOST BaseStats = 50,50,77,91,95,77 GenderRatio = Genderless @@ -12524,7 +12525,6 @@ Color = Red Shape = Head Category = Plasma Pokedex = Its body is composed of plasma. It is known to infiltrate electronic devices and wreak havoc. -FormName = Rotom Generation = 4 #------------------------------- [UXIE] @@ -12693,6 +12693,7 @@ Generation = 4 #------------------------------- [GIRATINA] Name = Giratina +FormName = Altered Forme Types = GHOST,DRAGON BaseStats = 150,100,120,90,100,120 GenderRatio = Genderless @@ -12713,7 +12714,6 @@ Color = Black Shape = Multiped Category = Renegade Pokedex = A Pokémon that is said to live in a world on the reverse side of ours. It appears in an ancient cemetery. -FormName = Altered Forme Generation = 4 #------------------------------- [CRESSELIA] @@ -12811,6 +12811,7 @@ Generation = 4 #------------------------------- [SHAYMIN] Name = Shaymin +FormName = Land Forme Types = GRASS BaseStats = 100,100,100,100,100,100 GenderRatio = Genderless @@ -12830,7 +12831,6 @@ Color = Green Shape = Quadruped Category = Gratitude Pokedex = It lives in flower patches and avoids detection by curling up to look like a flowering plant. -FormName = Land Forme Generation = 4 WildItemCommon = LUMBERRY WildItemUncommon = LUMBERRY @@ -12838,6 +12838,7 @@ WildItemRare = LUMBERRY #------------------------------- [ARCEUS] Name = Arceus +FormName = Normal Type Types = NORMAL BaseStats = 120,120,120,120,120,120 GenderRatio = Genderless @@ -12857,7 +12858,6 @@ Color = White Shape = Quadruped Category = Alpha Pokedex = It is described in mythology as the Pokémon that shaped the universe with its 1,000 arms. -FormName = Normal Type Generation = 4 #------------------------------- [VICTINI] @@ -14278,6 +14278,7 @@ WildItemUncommon = ABSORBBULB #------------------------------- [BASCULIN] Name = Basculin +FormName = Red-Striped Types = WATER BaseStats = 70,92,65,98,80,55 GenderRatio = Female50Percent @@ -14299,7 +14300,6 @@ Color = Green Shape = Finned Category = Hostile Pokedex = Savage, violent Pokémon, red and blue Basculin are always fighting each other over territory. -FormName = Red-Striped Generation = 5 Flags = InheritFormFromMother WildItemUncommon = DEEPSEATOOTH @@ -14410,6 +14410,7 @@ Evolutions = DARMANITAN,Level,35 #------------------------------- [DARMANITAN] Name = Darmanitan +FormName = Standard Mode Types = FIRE BaseStats = 105,140,55,95,30,55 GenderRatio = Female50Percent @@ -14430,7 +14431,6 @@ Color = Red Shape = Quadruped Category = Blazing Pokedex = When weakened in battle, it transforms into a stone statue. Then it sharpens its mind and fights on mentally. -FormName = Standard Mode Generation = 5 #------------------------------- [MARACTUS] @@ -15167,6 +15167,7 @@ WildItemCommon = NEVERMELTICE #------------------------------- [DEERLING] Name = Deerling +FormName = Spring Form Types = NORMAL,GRASS BaseStats = 60,60,50,75,40,50 GenderRatio = Female50Percent @@ -15188,12 +15189,12 @@ Color = Pink Shape = Quadruped Category = Season Pokedex = The turning of the seasons changes the color and scent of this Pokémon's fur. People use it to mark the seasons. -FormName = Spring Form Generation = 5 Evolutions = SAWSBUCK,Level,34 #------------------------------- [SAWSBUCK] Name = Sawsbuck +FormName = Spring Form Types = NORMAL,GRASS BaseStats = 80,100,70,95,60,70 GenderRatio = Female50Percent @@ -15214,7 +15215,6 @@ Color = Brown Shape = Quadruped Category = Season Pokedex = The plants growing on its horns change according to the season. The leaders of the herd possess magnificent horns. -FormName = Spring Form Generation = 5 #------------------------------- [EMOLGA] @@ -16564,6 +16564,7 @@ Generation = 5 #------------------------------- [TORNADUS] Name = Tornadus +FormName = Incarnate Forme Types = FLYING BaseStats = 79,115,70,111,125,80 GenderRatio = AlwaysMale @@ -16584,11 +16585,11 @@ Color = Green Shape = HeadArms Category = Cyclone Pokedex = Tornadus expels massive energy from its tail, causing severe storms. Its power is great enough to blow houses away. -FormName = Incarnate Forme Generation = 5 #------------------------------- [THUNDURUS] Name = Thundurus +FormName = Incarnate Forme Types = ELECTRIC,FLYING BaseStats = 79,115,70,111,125,80 GenderRatio = AlwaysMale @@ -16609,7 +16610,6 @@ Color = Blue Shape = HeadArms Category = Bolt Strike Pokedex = The spikes on its tail discharge immense bolts of lightning. It flies around the Unova region firing off lightning bolts. -FormName = Incarnate Forme Generation = 5 #------------------------------- [RESHIRAM] @@ -16660,6 +16660,7 @@ Generation = 5 #------------------------------- [LANDORUS] Name = Landorus +FormName = Incarnate Forme Types = GROUND,FLYING BaseStats = 89,125,90,101,115,80 GenderRatio = AlwaysMale @@ -16680,7 +16681,6 @@ Color = Brown Shape = HeadArms Category = Abundance Pokedex = The energy that comes pouring from its tail increases the nutrition in the soil, making crops grow to great size. -FormName = Incarnate Forme Generation = 5 #------------------------------- [KYUREM] @@ -16708,6 +16708,7 @@ Generation = 5 #------------------------------- [KELDEO] Name = Keldeo +FormName = Ordinary Form Types = WATER,FIGHTING BaseStats = 91,72,90,108,129,90 GenderRatio = Genderless @@ -16727,11 +16728,11 @@ Color = Yellow Shape = Quadruped Category = Colt Pokedex = It crosses the world, running over the surfaces of oceans and rivers. It appears at scenic waterfronts. -FormName = Ordinary Form Generation = 5 #------------------------------- [MELOETTA] Name = Meloetta +FormName = Aria Forme Types = NORMAL,PSYCHIC BaseStats = 100,77,77,90,128,128 GenderRatio = Genderless @@ -16751,7 +16752,6 @@ Color = White Shape = Bipedal Category = Melody Pokedex = Many famous songs have been inspired by the melodies that Meloetta plays. -FormName = Aria Forme Generation = 5 WildItemCommon = STARPIECE WildItemUncommon = STARPIECE @@ -16759,6 +16759,7 @@ WildItemRare = STARPIECE #------------------------------- [GENESECT] Name = Genesect +FormName = Normal Types = BUG,STEEL BaseStats = 71,120,95,99,120,95 GenderRatio = Genderless @@ -16778,7 +16779,6 @@ Color = Purple Shape = Bipedal Category = Paleozoic Pokedex = This ancient bug Pokémon was altered by Team Plasma. They upgraded the cannon on its back. -FormName = Normal Generation = 5 #------------------------------- [CHESPIN] @@ -17184,6 +17184,7 @@ Evolutions = VIVILLON,Level,12 #------------------------------- [VIVILLON] Name = Vivillon +FormName = Archipelago Pattern Types = BUG,FLYING BaseStats = 80,52,50,89,90,50 GenderRatio = Female50Percent @@ -17204,7 +17205,6 @@ Color = White Shape = MultiWinged Category = Scale Pokedex = Vivillon with many different patterns are found all over the world. These patterns are affected by the climate of their habitat. -FormName = Archipelago Pattern Generation = 6 #------------------------------- [LITLEO] @@ -17259,6 +17259,7 @@ Generation = 6 #------------------------------- [FLABEBE] Name = Flabébé +FormName = Red Flower Types = FAIRY BaseStats = 44,38,39,42,61,79 GenderRatio = AlwaysFemale @@ -17280,13 +17281,13 @@ Color = White Shape = HeadArms Category = Single Bloom Pokedex = When it finds a flower it likes, it dwells on that flower its whole life long. It floats in the wind's embrace with an untroubled heart. -FormName = Red Flower Generation = 6 Flags = InheritFormFromMother Evolutions = FLOETTE,Level,19 #------------------------------- [FLOETTE] Name = Floette +FormName = Red Flower Types = FAIRY BaseStats = 54,45,47,52,75,98 GenderRatio = AlwaysFemale @@ -17307,13 +17308,13 @@ Color = White Shape = HeadArms Category = Single Bloom Pokedex = It flutters around fields of flowers and cares for flowers that are starting to wilt. It draws out the power of flowers to battle. -FormName = Red Flower Generation = 6 Flags = InheritFormFromMother Evolutions = FLORGES,Item,SHINYSTONE #------------------------------- [FLORGES] Name = Florges +FormName = Red Flower Types = FAIRY BaseStats = 78,65,68,75,112,154 GenderRatio = AlwaysFemale @@ -17334,7 +17335,6 @@ Color = White Shape = HeadArms Category = Garden Pokedex = It claims exquisite flower gardens as its territory, and it obtains power from basking in the energy emitted by flowering plants. -FormName = Red Flower Generation = 6 Flags = InheritFormFromMother #------------------------------- @@ -17442,6 +17442,7 @@ WildItemUncommon = MENTALHERB #------------------------------- [FURFROU] Name = Furfrou +FormName = Natural Form Types = NORMAL BaseStats = 75,80,60,102,65,90 GenderRatio = Female50Percent @@ -17462,7 +17463,6 @@ Color = White Shape = Quadruped Category = Poodle Pokedex = Trimming its fluffy fur not only makes it more elegant but also increases the swiftness of its movements. -FormName = Natural Form Generation = 6 #------------------------------- [ESPURR] @@ -17493,6 +17493,7 @@ Evolutions = MEOWSTIC,Level,25 #------------------------------- [MEOWSTIC] Name = Meowstic +FormName = Male Types = PSYCHIC BaseStats = 74,48,76,104,83,81 GenderRatio = Female50Percent @@ -17513,7 +17514,6 @@ Color = Blue Shape = BipedalTail Category = Constraint Pokedex = Revealing the eyelike patterns on the insides of its ears will unleash its psychic powers. It normally keeps the patterns hidden, however. -FormName = Male Generation = 6 #------------------------------- [HONEDGE] @@ -17567,6 +17567,7 @@ Evolutions = AEGISLASH,Item,DUSKSTONE #------------------------------- [AEGISLASH] Name = Aegislash +FormName = Shield Forme Types = STEEL,GHOST BaseStats = 60,50,140,60,50,140 GenderRatio = Female50Percent @@ -17586,7 +17587,6 @@ Color = Brown Shape = HeadBase Category = Royal Sword Pokedex = In this defensive stance, Aegislash uses its steel body and a force field of spectral power to reduce the damage of any attack. -FormName = Shield Forme Generation = 6 #------------------------------- [SPRITZEE] @@ -18290,6 +18290,7 @@ Generation = 6 #------------------------------- [PUMPKABOO] Name = Pumpkaboo +FormName = Small Size Types = GHOST,GRASS BaseStats = 44,66,70,56,44,55 GenderRatio = Female50Percent @@ -18310,13 +18311,13 @@ Color = Brown Shape = Head Category = Pumpkin Pokedex = When taking spirits to the afterlife, small Pumpkaboo prefer the spirits of children to those of adults. -FormName = Small Size Generation = 6 Flags = InheritFormFromMother Evolutions = GOURGEIST,Trade, #------------------------------- [GOURGEIST] Name = Gourgeist +FormName = Small Size Types = GHOST,GRASS BaseStats = 55,85,122,99,58,75 GenderRatio = Female50Percent @@ -18336,7 +18337,6 @@ Color = Brown Shape = HeadBase Category = Pumpkin Pokedex = Small Gourgeist pretend to be children to fool adults. Anyone who falls for the act gets carried away to the hereafter. -FormName = Small Size Generation = 6 Flags = InheritFormFromMother #------------------------------- @@ -18442,6 +18442,7 @@ Generation = 6 #------------------------------- [XERNEAS] Name = Xerneas +FormName = Neutral Mode Types = FAIRY BaseStats = 126,131,95,99,131,98 GenderRatio = Genderless @@ -18461,7 +18462,6 @@ Color = Blue Shape = Quadruped Category = Life Pokedex = Legends say it can share eternal life. It slept for a thousand years in the form of a tree before its revival. -FormName = Neutral Mode Generation = 6 #------------------------------- [YVELTAL] @@ -18489,6 +18489,7 @@ Generation = 6 #------------------------------- [ZYGARDE] Name = Zygarde +FormName = 50% Forme Types = DRAGON,GROUND BaseStats = 108,100,121,95,81,95 GenderRatio = Genderless @@ -18508,7 +18509,6 @@ Color = Green Shape = Serpentine Category = Order Pokedex = It's thought to be monitoring the ecosystem. There are rumors that even greater power lies hidden within it. -FormName = 50% Forme Generation = 6 #------------------------------- [DIANCIE] @@ -18536,6 +18536,7 @@ Generation = 6 #------------------------------- [HOOPA] Name = Hoopa +FormName = Hoopa Confined Types = PSYCHIC,GHOST BaseStats = 80,110,60,70,150,130 GenderRatio = Genderless @@ -18555,7 +18556,6 @@ Color = Purple Shape = HeadArms Category = Mischief Pokedex = This troublemaker sends anything and everything to faraway places using its loop, which can warp space. -FormName = Hoopa Confined Generation = 6 #------------------------------- [VOLCANION] @@ -19063,6 +19063,7 @@ WildItemUncommon = CHERIBERRY #------------------------------- [ORICORIO] Name = Oricorio +FormName = Baile Style Types = FIRE,FLYING BaseStats = 75,70,70,93,98,70 GenderRatio = Female75Percent @@ -19083,7 +19084,6 @@ Color = Red Shape = Winged Category = Dancing Pokedex = It beats its wings together to create fire. As it moves in the steps of its beautiful dance, it bathes opponents in intense flames. -FormName = Baile Style Generation = 7 Flags = InheritFormFromMother WildItemUncommon = HONEY @@ -19168,6 +19168,7 @@ Evolutions = LYCANROC,Level,25 #------------------------------- [LYCANROC] Name = Lycanroc +FormName = Midday Form Types = ROCK BaseStats = 75,115,65,112,55,65 GenderRatio = Female50Percent @@ -19188,11 +19189,11 @@ Color = Brown Shape = Quadruped Category = Wolf Pokedex = Its quick movements confuse its enemies. Well equipped with claws and fangs, it also uses the sharp rocks in its mane as weapons. -FormName = Midday Form Generation = 7 #------------------------------- [WISHIWASHI] Name = Wishiwashi +FormName = Solo Form Types = WATER BaseStats = 45,20,20,40,25,25 GenderRatio = Female50Percent @@ -19213,7 +19214,6 @@ Color = Blue Shape = Finned Category = Small Fry Pokedex = It's awfully weak and notably tasty, so everyone is always out to get it. As it happens, anyone trying to bully it receives a painful lesson. -FormName = Solo Form Generation = 7 #------------------------------- [MAREANIE] @@ -19885,6 +19885,7 @@ Evolutions = SILVALLY,Happiness, #------------------------------- [SILVALLY] Name = Silvally +FormName = Type: Normal Types = NORMAL BaseStats = 95,95,95,95,95,95 GenderRatio = Genderless @@ -19904,11 +19905,11 @@ Color = Gray Shape = Quadruped Category = Synthetic Pokedex = Its trust in its partner is what awakens it. This Pokémon is capable of changing its type, a flexibility that is well displayed in battle. -FormName = Type: Normal Generation = 7 #------------------------------- [MINIOR] Name = Minior +FormName = Meteor Form Types = ROCK,FLYING BaseStats = 60,60,100,60,60,100 GenderRatio = Genderless @@ -19928,7 +19929,6 @@ Color = Brown Shape = Head Category = Meteor Pokedex = Originally making its home in the ozone layer, it hurtles to the ground when the shell enclosing its body grows too heavy. -FormName = Meteor Form Generation = 7 WildItemUncommon = STARPIECE #------------------------------- @@ -20009,6 +20009,7 @@ WildItemUncommon = ELECTRICSEED #------------------------------- [MIMIKYU] Name = Mimikyu +FormName = Disguised Form Types = GHOST,FAIRY BaseStats = 55,90,80,96,50,105 GenderRatio = Female50Percent @@ -20029,7 +20030,6 @@ Color = Yellow Shape = Serpentine Category = Disguise Pokedex = A lonely Pokémon, it conceals its terrifying appearance beneath an old rag so it can get closer to people and other Pokémon. -FormName = Disguised Form Generation = 7 WildItemUncommon = CHESTOBERRY #------------------------------- @@ -21758,6 +21758,7 @@ Evolutions = TOXTRICITY,Level,30 #------------------------------- [TOXTRICITY] Name = Toxtricity +FormName = Amped Form Types = ELECTRIC,POISON BaseStats = 75,98,70,75,114,70 GenderRatio = Female50Percent @@ -21778,7 +21779,6 @@ Color = Purple Shape = BipedalTail Category = Punk Pokedex = When this Pokémon sounds as if it's strumming a guitar, it's actually clawing at the protrusions on its chest to generate electricity. -FormName = Amped Form Generation = 8 #------------------------------- [SIZZLIPEDE] @@ -21883,6 +21883,7 @@ Generation = 8 #------------------------------- [SINISTEA] Name = Sinistea +FormName = Phony Form Types = GHOST BaseStats = 40,45,45,50,74,54 GenderRatio = Genderless @@ -21903,12 +21904,12 @@ Color = Purple Shape = Head Category = Black Tea Pokedex = The teacup in which this Pokémon makes its home is a famous piece of antique tableware. Many forgeries are in circulation. -FormName = Phony Form Generation = 8 Evolutions = POLTEAGEIST,Item,CRACKEDPOT #------------------------------- [POLTEAGEIST] Name = Polteageist +FormName = Phony Form Types = GHOST BaseStats = 60,65,65,70,134,114 GenderRatio = Genderless @@ -21929,7 +21930,6 @@ Color = Purple Shape = Head Category = Black Tea Pokedex = This species lives in antique teapots. Most pots are forgeries, but on rare occasions, an authentic work is found. -FormName = Phony Form Generation = 8 #------------------------------- [HATENNA] @@ -22265,6 +22265,7 @@ Evolutions = ALCREMIE,HoldItem,STRAWBERRYSWEET,ALCREMIE,HoldItem,BERRYSWEET,ALCR #------------------------------- [ALCREMIE] Name = Alcremie +FormName = Vanilla Cream Types = FAIRY BaseStats = 65,60,75,64,110,121 GenderRatio = AlwaysFemale @@ -22285,7 +22286,6 @@ Color = White Shape = HeadBase Category = Cream Pokedex = When Alcremie is content, the cream it secretes from its hands becomes sweeter and richer. -FormName = Vanilla Cream Generation = 8 #------------------------------- [FALINKS] @@ -22414,6 +22414,7 @@ Generation = 8 #------------------------------- [EISCUE] Name = Eiscue +FormName = Ice Face Types = ICE BaseStats = 75,80,110,50,65,90 GenderRatio = Female50Percent @@ -22434,11 +22435,11 @@ Color = Blue Shape = BipedalTail Category = Penguin Pokedex = It drifted in on the flow of ocean waters from a frigid place. It keeps its head iced constantly to make sure it stays nice and cold. -FormName = Ice Face Generation = 8 #------------------------------- [INDEEDEE] Name = Indeedee +FormName = Male Types = PSYCHIC,NORMAL BaseStats = 60,65,55,95,105,95 GenderRatio = Female50Percent @@ -22460,11 +22461,11 @@ Color = Purple Shape = BipedalTail Category = Emotion Pokedex = It uses the horns on its head to sense the emotions of others. Males will act as valets for those they serve, looking after their every need. -FormName = Male Generation = 8 #------------------------------- [MORPEKO] Name = Morpeko +FormName = Full Belly Mode Types = ELECTRIC,DARK BaseStats = 58,95,58,97,70,58 GenderRatio = Female50Percent @@ -22485,7 +22486,6 @@ Color = Yellow Shape = Bipedal Category = Two-Sided Pokedex = As it eats the seeds stored up in its pocket-like pouches, this Pokémon is not just satisfying its constant hunger. It's also generating electricity. -FormName = Full Belly Mode Generation = 8 #------------------------------- [CUFANT] @@ -22738,6 +22738,7 @@ Generation = 8 #------------------------------- [ZACIAN] Name = Zacian +FormName = Hero of Many Battles Types = FAIRY BaseStats = 92,130,115,138,80,115 GenderRatio = Genderless @@ -22757,7 +22758,6 @@ Color = Blue Shape = Quadruped Category = Warrior Pokedex = Known as a legendary hero, this Pokémon absorbs metal particles, transforming them into a weapon it uses to battle. -FormName = Hero of Many Battles Generation = 8 WildItemCommon = RUSTEDSWORD WildItemUncommon = RUSTEDSWORD @@ -22765,6 +22765,7 @@ WildItemRare = RUSTEDSWORD #------------------------------- [ZAMAZENTA] Name = Zamazenta +FormName = Hero of Many Battles Types = FIGHTING BaseStats = 92,130,115,138,80,115 GenderRatio = Genderless @@ -22784,7 +22785,6 @@ Color = Red Shape = Quadruped Category = Warrior Pokedex = This Pokémon slept for aeons while in the form of a statue. It was asleep for so long, people forgot that it ever existed. -FormName = Hero of Many Battles Generation = 8 WildItemCommon = RUSTEDSHIELD WildItemUncommon = RUSTEDSHIELD @@ -22839,6 +22839,7 @@ Evolutions = URSHIFU,Event,1 #------------------------------- [URSHIFU] Name = Urshifu +FormName = Single Strike Style Types = FIGHTING,DARK BaseStats = 100,130,100,97,63,60 GenderRatio = FemaleOneEighth @@ -22858,7 +22859,6 @@ Color = Gray Shape = Bipedal Category = Wushu Pokedex = Inhabiting the mountains of a distant region, this Pokémon races across sheer cliffs, training its legs and refining its moves. -FormName = Single Strike Style Generation = 8 #------------------------------- [ZARUDE]