diff --git a/Data/Scripts/011_Data/001_Game data.rb b/Data/Scripts/011_Data/001_Game data.rb index 915eb5091..941f59c6b 100644 --- a/Data/Scripts/011_Data/001_Game data.rb +++ b/Data/Scripts/011_Data/001_Game data.rb @@ -1,8 +1,10 @@ module GameData + #============================================================================= # A mixin module for data classes which provides common class methods (called # by GameData::Thing.method) that provide access to data held within. # Assumes the data class's data is stored in a class constant hash called DATA. # For data that is known by a symbol or an ID number. + #============================================================================= module ClassMethods def register(hash) self::DATA[hash[:id]] = self::DATA[hash[:id_number]] = self.new(hash) @@ -59,10 +61,68 @@ module GameData end end + #============================================================================= + # A mixin module for data classes which provides common class methods (called + # by GameData::Thing.method) that provide access to data held within. + # Assumes the data class's data is stored in a class constant hash called DATA. + # For data that is only known by a symbol. + #============================================================================= + module ClassMethodsSymbols + def register(hash) + self::DATA[hash[:id]] = self.new(hash) + end + + # @param other [Symbol, self, String] + # @return [Boolean] whether the given other is defined as a self + def exists?(other) + return false if other.nil? + validate other => [Symbol, self, String] + other = other.id if other.is_a?(self) + other = other.to_sym if other.is_a?(String) + return !self::DATA[other].nil? + end + + # @param other [Symbol, self, String] + # @return [self] + def get(other) + validate other => [Symbol, self, String] + return other if other.is_a?(self) + other = other.to_sym if other.is_a?(String) + raise "Unknown ID #{other}." unless self::DATA.has_key?(other) + return self::DATA[other] + end + + # @param other [Symbol, self, String] + # @return [self, nil] + def try_get(other) + return nil if other.nil? + validate other => [Symbol, self, String] + return other if other.is_a?(self) + other = other.to_sym if other.is_a?(String) + return (self::DATA.has_key?(other)) ? self::DATA[other] : nil + end + + # Yields all data in alphabetical order. + def each + keys = self::DATA.keys.sort { |a, b| self::DATA[a].real_name <=> self::DATA[b].real_name } + keys.each { |key| yield self::DATA[key] } + end + + def load + const_set(:DATA, load_data("Data/#{self::DATA_FILENAME}")) + end + + def save + save_data(self::DATA, "Data/#{self::DATA_FILENAME}") + end + end + + #============================================================================= # A mixin module for data classes which provides common class methods (called # by GameData::Thing.method) that provide access to data held within. # Assumes the data class's data is stored in a class constant hash called DATA. # For data that is only known by an ID number. + #============================================================================= module ClassMethodsIDNumbers def register(hash) self::DATA[hash[:id]] = self.new(hash) @@ -93,6 +153,7 @@ module GameData return (self::DATA.has_key?(other)) ? self::DATA[other] : nil end + # Yields all data in numberical order. def each keys = self::DATA.keys.sort keys.each { |key| yield self::DATA[key] } @@ -107,9 +168,11 @@ module GameData end end + #============================================================================= # A mixin module for data classes which provides common instance methods # (called by thing.method) that analyse the data of a particular thing which # the instance represents. + #============================================================================= module InstanceMethods # @param other [Symbol, self.class, String, Integer] # @return [Boolean] whether other represents the same thing as this thing @@ -128,6 +191,9 @@ module GameData end end + #============================================================================= + # A bulk loader method for all data stored in .dat files in the Data folder. + #============================================================================= def self.load_all Ability.load Item.load diff --git a/Data/Scripts/011_Data/001_PBS data/010_Species.rb b/Data/Scripts/011_Data/001_PBS data/010_Species.rb index 07672350f..e08c89ed2 100644 --- a/Data/Scripts/011_Data/001_PBS data/010_Species.rb +++ b/Data/Scripts/011_Data/001_PBS data/010_Species.rb @@ -98,7 +98,7 @@ module GameData "Weight" => [0, "f"], "Color" => [0, "e", :PBColors], "Shape" => [0, "u"], - "Habitat" => [0, "e", :PBHabitats], + "Habitat" => [0, "e", :Habitat], "Generation" => [0, "i"], "BattlerPlayerX" => [0, "i"], "BattlerPlayerY" => [0, "i"], @@ -161,7 +161,7 @@ module GameData @weight = hash[:weight] || 1 @color = hash[:color] || PBColors::Red @shape = hash[:shape] || 1 - @habitat = hash[:habitat] || PBHabitats::None + @habitat = hash[:habitat] || :None @generation = hash[:generation] || 0 @mega_stone = hash[:mega_stone] @mega_move = hash[:mega_move] diff --git a/Data/Scripts/011_Data/002_Hardcoded data/005_EggGroup.rb b/Data/Scripts/011_Data/002_Hardcoded data/005_EggGroup.rb index 04bb50375..417be0bd2 100644 --- a/Data/Scripts/011_Data/002_Hardcoded data/005_EggGroup.rb +++ b/Data/Scripts/011_Data/002_Hardcoded data/005_EggGroup.rb @@ -5,19 +5,9 @@ module GameData DATA = {} - extend ClassMethods + extend ClassMethodsSymbols include InstanceMethods - def register(hash) - self::DATA[hash[:id]] = self.new(hash) - end - - # Yields all data in alphabetical order. - def each - keys = self::DATA.keys.sort { |a, b| self::DATA[a].real_name <=> self::DATA[b].real_name } - keys.each { |key| yield self::DATA[key] } - end - def self.load; end def self.save; end diff --git a/Data/Scripts/011_Data/002_Hardcoded data/007_Habitat.rb b/Data/Scripts/011_Data/002_Hardcoded data/007_Habitat.rb new file mode 100644 index 000000000..cf5ade000 --- /dev/null +++ b/Data/Scripts/011_Data/002_Hardcoded data/007_Habitat.rb @@ -0,0 +1,74 @@ +module GameData + class Habitat + attr_reader :id + attr_reader :real_name + + DATA = {} + + extend ClassMethodsSymbols + include InstanceMethods + + def self.load; end + def self.save; end + + def initialize(hash) + @id = hash[:id] + @real_name = hash[:name] || "Unnamed" + end + + # @return [String] the translated name of this egg group + def name + return _INTL(@real_name) + end + end +end + +GameData::Habitat.register({ + :id => :None, + :name => _INTL("None") +}) + +GameData::Habitat.register({ + :id => :Grassland, + :name => _INTL("Grassland") +}) + +GameData::Habitat.register({ + :id => :Forest, + :name => _INTL("Forest") +}) + +GameData::Habitat.register({ + :id => :WatersEdge, + :name => _INTL("Water's Edge") +}) + +GameData::Habitat.register({ + :id => :Sea, + :name => _INTL("Sea") +}) + +GameData::Habitat.register({ + :id => :Cave, + :name => _INTL("Cave") +}) + +GameData::Habitat.register({ + :id => :Mountain, + :name => _INTL("Mountain") +}) + +GameData::Habitat.register({ + :id => :RoughTerrain, + :name => _INTL("Rough Terrain") +}) + +GameData::Habitat.register({ + :id => :Urban, + :name => _INTL("Urban") +}) + +GameData::Habitat.register({ + :id => :Rare, + :name => _INTL("Rare") +}) diff --git a/Data/Scripts/011_Data/002_Hardcoded data/007_PBHabitats.rb b/Data/Scripts/011_Data/002_Hardcoded data/007_PBHabitats.rb deleted file mode 100644 index 166fa66f9..000000000 --- a/Data/Scripts/011_Data/002_Hardcoded data/007_PBHabitats.rb +++ /dev/null @@ -1,31 +0,0 @@ -module PBHabitats - None = 0 - Grassland = 1 - Forest = 2 - WatersEdge = 3 - Sea = 4 - Cave = 5 - Mountain = 6 - RoughTerrain = 7 - Urban = 8 - Rare = 9 - - def self.maxValue; 9; end - - def self.getName(id) - id = getID(PBHabitats,id) - names = [ - _INTL("None"), - _INTL("Grassland"), - _INTL("Forest"), - _INTL("Water's Edge"), - _INTL("Sea"), - _INTL("Cave"), - _INTL("Mountain"), - _INTL("Rough Terrain"), - _INTL("Urban"), - _INTL("Rare") - ] - return names[id] - end -end diff --git a/Data/Scripts/021_Debug/004_Editor_Screens.rb b/Data/Scripts/021_Debug/004_Editor_Screens.rb index 71c9cb0b4..4caa446e7 100644 --- a/Data/Scripts/021_Debug/004_Editor_Screens.rb +++ b/Data/Scripts/021_Debug/004_Editor_Screens.rb @@ -667,7 +667,7 @@ module TrainerPokemonProperty pkmn_properties.concat([ [_INTL("Ability"), LimitProperty2.new(99), _INTL("Ability flag. 0=first ability, 1=second ability, 2-5=hidden ability.")], [_INTL("Held item"), ItemProperty, _INTL("Item held by the Pokémon.")], - [_INTL("Nature"), NatureProperty, _INTL("Nature of the Pokémon.")], + [_INTL("Nature"), GameDataProperty.new(:Nature), _INTL("Nature of the Pokémon.")], [_INTL("IVs"), IVsProperty.new(Pokemon::IV_STAT_LIMIT), _INTL("Individual values for each of the Pokémon's stats.")], [_INTL("EVs"), EVsProperty.new(Pokemon::EV_STAT_LIMIT), _INTL("Effort values for each of the Pokémon's stats.")], [_INTL("Happiness"), LimitProperty2.new(255), _INTL("Happiness of the Pokémon (0-255).")], @@ -974,8 +974,8 @@ def pbPokemonEditor [_INTL("WildItemCommon"), ItemProperty, _INTL("Item commonly held by wild Pokémon of this species.")], [_INTL("WildItemUncommon"), ItemProperty, _INTL("Item uncommonly held by wild Pokémon of this species.")], [_INTL("WildItemRare"), ItemProperty, _INTL("Item rarely held by wild Pokémon of this species.")], - [_INTL("Compat1"), EggGroupProperty, _INTL("Compatibility group (egg group) for breeding purposes.")], - [_INTL("Compat2"), EggGroupProperty, _INTL("Compatibility group (egg group) for breeding purposes.")], + [_INTL("Compat1"), GameDataProperty.new(:EggGroup), _INTL("Compatibility group (egg group) for breeding purposes.")], + [_INTL("Compat2"), GameDataProperty.new(:EggGroup), _INTL("Compatibility group (egg group) for breeding purposes.")], [_INTL("StepsToHatch"), LimitProperty.new(99999), _INTL("Number of steps until an egg of this species hatches.")], [_INTL("Incense"), ItemProperty, _INTL("Item needed to be held by a parent to produce an egg of this species.")], [_INTL("Evolutions"), EvolutionsProperty.new, _INTL("Evolution paths of this species.")], @@ -983,7 +983,7 @@ def pbPokemonEditor [_INTL("Weight"), NonzeroLimitProperty.new(9999), _INTL("Weight of the Pokémon in 0.1 kilograms (e.g. 42 = 4.2kg).")], [_INTL("Color"), EnumProperty2.new(PBColors), _INTL("Pokémon's body color.")], [_INTL("Shape"), LimitProperty.new(14), _INTL("Body shape of this species (0-14).")], - [_INTL("Habitat"), EnumProperty2.new(PBHabitats), _INTL("The habitat of this species.")], + [_INTL("Habitat"), GameDataProperty.new(:Habitat), _INTL("The habitat of this species.")], [_INTL("Generation"), LimitProperty.new(99999), _INTL("The number of the generation the Pokémon debuted in.")], [_INTL("BattlerPlayerX"), ReadOnlyProperty, _INTL("Affects positioning of the Pokémon in battle. This is edited elsewhere.")], [_INTL("BattlerPlayerY"), ReadOnlyProperty, _INTL("Affects positioning of the Pokémon in battle. This is edited elsewhere.")], diff --git a/Data/Scripts/021_Debug/007_Editor_DataTypes.rb b/Data/Scripts/021_Debug/007_Editor_DataTypes.rb index a7cfb6781..f40cca83c 100644 --- a/Data/Scripts/021_Debug/007_Editor_DataTypes.rb +++ b/Data/Scripts/021_Debug/007_Editor_DataTypes.rb @@ -235,6 +235,37 @@ end +class GameDataProperty + def initialize(value) + raise _INTL("Couldn't find class {1} in module GameData.", value.to_s) if !GameData.const_defined?(value.to_sym) + @module = GameData.const_get(value.to_sym) + end + + def set(settingname, oldsetting) + commands = [] + i = 0 + @module.each do |data| + if data.respond_to?("id_number") + commands.push([data.id_number, data.name, data.id]) + else + commands.push([i, data.name, data.id]) + end + i += 1 + end + return pbChooseList(commands, oldsetting, nil, -1) + end + + def defaultValue + return nil + end + + def format(value) + return (value && @module.exists?(value)) ? @module.get(value).real_name : "-" + end +end + + + module BGMProperty def self.set(settingname,oldsetting) chosenmap = pbListScreen(settingname,MusicFileLister.new(true,oldsetting)) @@ -402,23 +433,6 @@ end -module NatureProperty - def self.set(_settingname, oldsetting) - ret = pbChooseNatureList((oldsetting) ? oldsetting : nil) - return ret || oldsetting - end - - def self.defaultValue - return nil - end - - def self.format(value) - return (value && GameData::Nature.exists?(value)) ? GameData::Nature.get(value).real_name : "-" - end -end - - - module ItemProperty def self.set(_settingname, oldsetting) ret = pbChooseItemList((oldsetting) ? oldsetting : nil) @@ -436,23 +450,6 @@ end -module EggGroupProperty - def self.set(_settingname, oldsetting) - ret = pbChooseEggGroupList((oldsetting) ? oldsetting : nil) - return ret || oldsetting - end - - def self.defaultValue - return nil - end - - def self.format(value) - return (value && GameData::EggGroup.exists?(value)) ? GameData::EggGroup.get(value).real_name : "-" - end -end - - - class IVsProperty def initialize(limit) @limit = limit @@ -614,8 +611,8 @@ module MapSizeProperty def self.set(settingname,oldsetting) oldsetting = [0,""] if !oldsetting properties = [ - [_INTL("Width"),NonzeroLimitProperty.new(30),_INTL("The width of this map in Region Map squares.")], - [_INTL("Valid Squares"),StringProperty,_INTL("A series of 1s and 0s marking which squares are part of this map (1=part, 0=not part).")], + [_INTL("Width"), NonzeroLimitProperty.new(30), _INTL("The width of this map in Region Map squares.")], + [_INTL("Valid Squares"), StringProperty, _INTL("A series of 1s and 0s marking which squares are part of this map (1=part, 0=not part).")], ] pbPropertyList(settingname,oldsetting,properties,false) return oldsetting diff --git a/Data/Scripts/021_Debug/009_Editor_Utilities.rb b/Data/Scripts/021_Debug/009_Editor_Utilities.rb index 97237fe49..ab5423bb3 100644 --- a/Data/Scripts/021_Debug/009_Editor_Utilities.rb +++ b/Data/Scripts/021_Debug/009_Editor_Utilities.rb @@ -206,22 +206,6 @@ def pbChooseAbilityList(default = nil) return pbChooseList(commands, default, nil, -1) end -def pbChooseNatureList(default = nil) - commands = [] - GameData::Nature.each { |n| commands.push([n.id_number, n.name, n.id]) } - return pbChooseList(commands, default, nil, -1) -end - -def pbChooseEggGroupList(default = nil) - commands = [] - i = 0 - GameData::EggGroup.each do |g| - commands.push([i, g.name, g.id]) - i += 1 - end - return pbChooseList(commands, default, nil, -1) -end - def pbChooseBallList(defaultMoveID = -1) cmdwin = pbListWindow([], 200) commands = [] diff --git a/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb b/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb index 342977e7a..76920f978 100644 --- a/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb +++ b/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb @@ -302,7 +302,7 @@ module Compiler f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0)) f.write(sprintf("Color = %s\r\n", getConstantName(PBColors, species.color))) f.write(sprintf("Shape = %d\r\n", species.shape)) - f.write(sprintf("Habitat = %s\r\n", getConstantName(PBHabitats, species.habitat))) if species.habitat != PBHabitats::None + f.write(sprintf("Habitat = %s\r\n", species.habitat)) if species.habitat != :None f.write(sprintf("Kind = %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? @@ -397,8 +397,8 @@ module Compiler f.write(sprintf("Weight = %.1f\r\n", species.weight / 10.0)) if species.weight != base_species.weight f.write(sprintf("Color = %s\r\n", getConstantName(PBColors, species.color))) if species.color != base_species.color f.write(sprintf("Shape = %d\r\n", species.shape)) if species.shape != base_species.shape - if species.habitat != PBHabitats::None && species.habitat != base_species.habitat - f.write(sprintf("Habitat = %s\r\n", getConstantName(PBHabitats, species.habitat))) + if species.habitat != :None && species.habitat != base_species.habitat + f.write(sprintf("Habitat = %s\r\n", species.habitat)) end f.write(sprintf("Kind = %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