From 9fe14395c09e06d958d9933adebe4a6073888e65 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 31 Jan 2021 22:43:51 +0000 Subject: [PATCH] Implemented GameData::Nature, improved registration of GameData entries --- .../011_Data/001_Game data/001_Game data.rb | 8 + .../011_Data/001_Game data/012_Trainer.rb | 8 +- .../Hardcoded game data/003_Nature.rb | 198 ++++++++++++++++++ .../Hardcoded game data/003_PBNatures.rb | 88 -------- Data/Scripts/012_Battle/006_BattleHandlers.rb | 8 +- .../004_PokeBattle_BattlePalace.rb | 33 +-- .../014_Trainers/002_PTrainer_NPCTrainers.rb | 6 +- Data/Scripts/016_Pokemon/001_Pokemon.rb | 55 +++-- Data/Scripts/017_UI/006_PScreen_Summary.rb | 12 +- .../003_PBattle_OrgBattle.rb | 6 +- .../005_PBattle_OrgBattleGenerator.rb | 23 +- .../004_Debug_PokemonCommands.rb | 36 ++-- Data/Scripts/021_Debug/004_Editor_Screens.rb | 34 +-- .../Scripts/021_Debug/007_Editor_DataTypes.rb | 25 ++- .../Scripts/021_Debug/009_Editor_Utilities.rb | 6 + Data/Scripts/022_Compiler/001_Compiler.rb | 14 +- .../022_Compiler/002_Compiler_CompilePBS.rb | 44 ++-- .../022_Compiler/003_Compiler_WritePBS.rb | 4 +- 18 files changed, 384 insertions(+), 224 deletions(-) create mode 100644 Data/Scripts/011_Data/Hardcoded game data/003_Nature.rb delete mode 100644 Data/Scripts/011_Data/Hardcoded game data/003_PBNatures.rb diff --git a/Data/Scripts/011_Data/001_Game data/001_Game data.rb b/Data/Scripts/011_Data/001_Game data/001_Game data.rb index 5a637757b..8488f8211 100644 --- a/Data/Scripts/011_Data/001_Game data/001_Game data.rb +++ b/Data/Scripts/011_Data/001_Game data/001_Game data.rb @@ -4,6 +4,10 @@ module GameData # 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) + end + # @param other [Symbol, self, String, Integer] # @return [Boolean] whether the given other is defined as a self def exists?(other) @@ -60,6 +64,10 @@ module GameData # 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) + end + # @param other [self, Integer] # @return [Boolean] whether the given other is defined as a self def exists?(other) diff --git a/Data/Scripts/011_Data/001_Game data/012_Trainer.rb b/Data/Scripts/011_Data/001_Game data/012_Trainer.rb index 660545015..94e11d1f3 100644 --- a/Data/Scripts/011_Data/001_Game data/012_Trainer.rb +++ b/Data/Scripts/011_Data/001_Game data/012_Trainer.rb @@ -1,5 +1,6 @@ module GameData class Trainer + attr_reader :id attr_reader :id_number attr_reader :trainer_type attr_reader :real_name @@ -22,7 +23,7 @@ module GameData "Item" => [:item, "e", :Item], "Gender" => [:gender, "e", { "M" => 0, "m" => 0, "Male" => 0, "male" => 0, "0" => 0, "F" => 1, "f" => 1, "Female" => 1, "female" => 1, "1" => 1 }], - "Nature" => [:nature, "e", :PBNatures], + "Nature" => [:nature, "e", :Nature], "IV" => [:iv, "uUUUUU"], "EV" => [:ev, "uUUUUU"], "Happiness" => [:happiness, "u"], @@ -67,7 +68,8 @@ module GameData end def initialize(hash) - @id_number = hash[:id] + @id = hash[:id] + @id_number = hash[:id_number] @trainer_type = hash[:trainer_type] @real_name = hash[:name] || "Unnamed" @version = hash[:version] || 0 @@ -132,7 +134,7 @@ module GameData pkmn.nature = pkmn_data[:nature] else nature = pkmn.species_data.id_number + GameData::TrainerType.get(trainer.trainer_type).id_number - pkmn.nature = nature % (PBNatures.maxValue + 1) + pkmn.nature = nature % (GameData::Nature::DATA.length / 2) end PBStats.eachStat do |s| if pkmn_data[:iv] && pkmn_data[:iv].length > 0 diff --git a/Data/Scripts/011_Data/Hardcoded game data/003_Nature.rb b/Data/Scripts/011_Data/Hardcoded game data/003_Nature.rb new file mode 100644 index 000000000..3cb5a535c --- /dev/null +++ b/Data/Scripts/011_Data/Hardcoded game data/003_Nature.rb @@ -0,0 +1,198 @@ +module GameData + class Nature + attr_reader :id + attr_reader :id_number + attr_reader :real_name + attr_reader :stat_changes + + DATA = {} + + extend ClassMethods + include InstanceMethods + + def self.load; end + def self.save; end + + def initialize(hash) + @id = hash[:id] + @id_number = hash[:id_number] || -1 + @real_name = hash[:name] || "Unnamed" + @stat_changes = hash[:stat_changes] || [] + end + + # @return [String] the translated name of this nature + def name + return _INTL(@real_name) + end + end +end + +GameData::Nature.register({ + :id => :HARDY, + :id_number => 0, + :name => _INTL("Hardy") +}) + +GameData::Nature.register({ + :id => :LONELY, + :id_number => 1, + :name => _INTL("Lonely"), + :stat_changes => [[PBStats::ATTACK, 10], [PBStats::DEFENSE, -10]] +}) + +GameData::Nature.register({ + :id => :BRAVE, + :id_number => 2, + :name => _INTL("Brave"), + :stat_changes => [[PBStats::ATTACK, 10], [PBStats::SPEED, -10]] +}) + +GameData::Nature.register({ + :id => :ADAMANT, + :id_number => 3, + :name => _INTL("Adamant"), + :stat_changes => [[PBStats::ATTACK, 10], [PBStats::SPATK, -10]] +}) + +GameData::Nature.register({ + :id => :NAUGHTY, + :id_number => 4, + :name => _INTL("Naughty"), + :stat_changes => [[PBStats::ATTACK, 10], [PBStats::SPDEF, -10]] +}) + +GameData::Nature.register({ + :id => :BOLD, + :id_number => 5, + :name => _INTL("Bold"), + :stat_changes => [[PBStats::DEFENSE, 10], [PBStats::ATTACK, -10]] +}) + +GameData::Nature.register({ + :id => :DOCILE, + :id_number => 6, + :name => _INTL("Docile") +}) + +GameData::Nature.register({ + :id => :RELAXED, + :id_number => 7, + :name => _INTL("Relaxed"), + :stat_changes => [[PBStats::DEFENSE, 10], [PBStats::SPEED, -10]] +}) + +GameData::Nature.register({ + :id => :IMPISH, + :id_number => 8, + :name => _INTL("Impish"), + :stat_changes => [[PBStats::DEFENSE, 10], [PBStats::SPATK, -10]] +}) + +GameData::Nature.register({ + :id => :LAX, + :id_number => 9, + :name => _INTL("Lax"), + :stat_changes => [[PBStats::DEFENSE, 10], [PBStats::SPDEF, -10]] +}) + +GameData::Nature.register({ + :id => :TIMID, + :id_number => 10, + :name => _INTL("Timid"), + :stat_changes => [[PBStats::SPEED, 10], [PBStats::ATTACK, -10]] +}) + +GameData::Nature.register({ + :id => :HASTY, + :id_number => 11, + :name => _INTL("Hasty"), + :stat_changes => [[PBStats::SPEED, 10], [PBStats::DEFENSE, -10]] +}) + +GameData::Nature.register({ + :id => :SERIOUS, + :id_number => 12, + :name => _INTL("Serious") +}) + +GameData::Nature.register({ + :id => :JOLLY, + :id_number => 13, + :name => _INTL("Jolly"), + :stat_changes => [[PBStats::SPEED, 10], [PBStats::SPATK, -10]] +}) + +GameData::Nature.register({ + :id => :NAIVE, + :id_number => 14, + :name => _INTL("Naive"), + :stat_changes => [[PBStats::SPEED, 10], [PBStats::SPDEF, -10]] +}) + +GameData::Nature.register({ + :id => :MODEST, + :id_number => 15, + :name => _INTL("Modest"), + :stat_changes => [[PBStats::SPATK, 10], [PBStats::ATTACK, -10]] +}) + +GameData::Nature.register({ + :id => :MILD, + :id_number => 16, + :name => _INTL("Mild"), + :stat_changes => [[PBStats::SPATK, 10], [PBStats::DEFENSE, -10]] +}) + +GameData::Nature.register({ + :id => :QUIET, + :id_number => 17, + :name => _INTL("Quiet"), + :stat_changes => [[PBStats::SPATK, 10], [PBStats::SPEED, -10]] +}) + +GameData::Nature.register({ + :id => :BASHFUL, + :id_number => 18, + :name => _INTL("Bashful") +}) + +GameData::Nature.register({ + :id => :RASH, + :id_number => 19, + :name => _INTL("Rash"), + :stat_changes => [[PBStats::SPATK, 10], [PBStats::SPDEF, -10]] +}) + +GameData::Nature.register({ + :id => :CALM, + :id_number => 20, + :name => _INTL("Calm"), + :stat_changes => [[PBStats::SPDEF, 10], [PBStats::ATTACK, -10]] +}) + +GameData::Nature.register({ + :id => :GENTLE, + :id_number => 21, + :name => _INTL("Gentle"), + :stat_changes => [[PBStats::SPDEF, 10], [PBStats::DEFENSE, -10]] +}) + +GameData::Nature.register({ + :id => :SASSY, + :id_number => 22, + :name => _INTL("Sassy"), + :stat_changes => [[PBStats::SPDEF, 10], [PBStats::SPEED, -10]] +}) + +GameData::Nature.register({ + :id => :CAREFUL, + :id_number => 23, + :name => _INTL("Careful"), + :stat_changes => [[PBStats::SPDEF, 10], [PBStats::SPATK, -10]] +}) + +GameData::Nature.register({ + :id => :QUIRKY, + :id_number => 24, + :name => _INTL("Quirky") +}) diff --git a/Data/Scripts/011_Data/Hardcoded game data/003_PBNatures.rb b/Data/Scripts/011_Data/Hardcoded game data/003_PBNatures.rb deleted file mode 100644 index e37e737c2..000000000 --- a/Data/Scripts/011_Data/Hardcoded game data/003_PBNatures.rb +++ /dev/null @@ -1,88 +0,0 @@ -module PBNatures - HARDY = 0 - LONELY = 1 - BRAVE = 2 - ADAMANT = 3 - NAUGHTY = 4 - BOLD = 5 - DOCILE = 6 - RELAXED = 7 - IMPISH = 8 - LAX = 9 - TIMID = 10 - HASTY = 11 - SERIOUS = 12 - JOLLY = 13 - NAIVE = 14 - MODEST = 15 - MILD = 16 - QUIET = 17 - BASHFUL = 18 - RASH = 19 - CALM = 20 - GENTLE = 21 - SASSY = 22 - CAREFUL = 23 - QUIRKY = 24 - - def self.maxValue; 24; end - - def self.getName(id) - id = getID(PBNatures, id) - names = [ - _INTL("Hardy"), - _INTL("Lonely"), - _INTL("Brave"), - _INTL("Adamant"), - _INTL("Naughty"), - _INTL("Bold"), - _INTL("Docile"), - _INTL("Relaxed"), - _INTL("Impish"), - _INTL("Lax"), - _INTL("Timid"), - _INTL("Hasty"), - _INTL("Serious"), - _INTL("Jolly"), - _INTL("Naive"), - _INTL("Modest"), - _INTL("Mild"), - _INTL("Quiet"), - _INTL("Bashful"), - _INTL("Rash"), - _INTL("Calm"), - _INTL("Gentle"), - _INTL("Sassy"), - _INTL("Careful"), - _INTL("Quirky") - ] - return names[id] - end - - def self.getStatRaised(id) - stats = [PBStats::ATTACK, PBStats::DEFENSE, PBStats::SPEED, - PBStats::SPATK, PBStats::SPDEF] - m = (id % (stats.length ** 2)) / stats.length - return stats[m] - end - - def self.getStatLowered(id) - stats = [PBStats::ATTACK, PBStats::DEFENSE, PBStats::SPEED, - PBStats::SPATK, PBStats::SPDEF] - m = id % stats.length - return stats[m] - end - - def self.getStatChanges(id) - id = getID(PBNatures,id) - up = PBNatures.getStatRaised(id) - dn = PBNatures.getStatLowered(id) - ret = [] - PBStats.eachStat do |s| - ret[s] = 100 - ret[s] += 10 if s==up - ret[s] -= 10 if s==dn - end - return ret - end -end diff --git a/Data/Scripts/012_Battle/006_BattleHandlers.rb b/Data/Scripts/012_Battle/006_BattleHandlers.rb index 06ff07aa1..37c05cdf6 100644 --- a/Data/Scripts/012_Battle/006_BattleHandlers.rb +++ b/Data/Scripts/012_Battle/006_BattleHandlers.rb @@ -496,11 +496,13 @@ def pbBattleConfusionBerry(battler,battle,item,forced,flavor,confuseMsg) battle.pbDisplay(_INTL("{1} restored its health using its {2}!",battler.pbThis,itemName)) end end - nUp = PBNatures.getStatRaised(battler.nature) - nDn = PBNatures.getStatLowered(battler.nature) - if nUp!=nDn && nDn-1==flavor + flavor_stat = [PBStats::ATTACK, PBStats::DEFENSE, PBStats::SPEED, + PBStats::SPATK, PBStats::SPDEF][flavor] + battler.nature.stat_changes.each do |change| + next if change[1] > 0 || change[0] != flavor_stat battle.pbDisplay(confuseMsg) battler.pbConfuse if battler.pbCanConfuseSelf?(false) + break end return true end diff --git a/Data/Scripts/012_Battle/006_Other battle types/004_PokeBattle_BattlePalace.rb b/Data/Scripts/012_Battle/006_Other battle types/004_PokeBattle_BattlePalace.rb index 5ad9ddd5b..e38c2e69a 100644 --- a/Data/Scripts/012_Battle/006_Other battle types/004_PokeBattle_BattlePalace.rb +++ b/Data/Scripts/012_Battle/006_Other battle types/004_PokeBattle_BattlePalace.rb @@ -98,37 +98,14 @@ class PokeBattle_BattlePalace < PokeBattle_Battle thispkmn.hp<=thispkmn.totalhp/2 nature = thispkmn.nature thispkmn.effects[PBEffects::Pinch] = true - if nature==PBNatures::QUIET || - nature==PBNatures::BASHFUL || - nature==PBNatures::NAIVE || - nature==PBNatures::QUIRKY || - nature==PBNatures::HARDY || - nature==PBNatures::DOCILE || - nature==PBNatures::SERIOUS + case nature + when :QUIET, :BASHFUL, :NAIVE, :QUIRKY, :HARDY, :DOCILE, :SERIOUS pbDisplay(_INTL("{1} is eager for more!",thispkmn.pbThis)) - end - if nature==PBNatures::CAREFUL || - nature==PBNatures::RASH || - nature==PBNatures::LAX || - nature==PBNatures::SASSY || - nature==PBNatures::MILD || - nature==PBNatures::TIMID + when :CAREFUL, :RASH, :LAX, :SASSY, :MILD, :TIMID pbDisplay(_INTL("{1} began growling deeply!",thispkmn.pbThis)) - end - if nature==PBNatures::GENTLE || - nature==PBNatures::ADAMANT || - nature==PBNatures::HASTY || - nature==PBNatures::LONELY || - nature==PBNatures::RELAXED || - nature==PBNatures::NAUGHTY + when :GENTLE, :ADAMANT, :HASTY, :LONELY, :RELAXED, :NAUGHTY pbDisplay(_INTL("A glint appears in {1}'s eyes!",thispkmn.pbThis(true))) - end - if nature==PBNatures::JOLLY || - nature==PBNatures::BOLD || - nature==PBNatures::BRAVE || - nature==PBNatures::CALM || - nature==PBNatures::IMPISH || - nature==PBNatures::MODEST + when :JOLLY, :BOLD, :BRAVE, :CALM, :IMPISH, :MODEST pbDisplay(_INTL("{1} is getting into position!",thispkmn.pbThis)) end end diff --git a/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb b/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb index 2a36c12fb..01524913a 100644 --- a/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb +++ b/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb @@ -44,7 +44,7 @@ def pbNewTrainer(tr_type, tr_name, tr_version, save_changes = true) trainer = [tr_type, tr_name, [], party, tr_version] if save_changes trainer_hash = { - :id => GameData::Trainer::DATA.keys.length / 2, + :id_number => GameData::Trainer::DATA.keys.length / 2, :trainer_type => tr_type, :name => tr_name, :version => tr_version, @@ -57,8 +57,8 @@ def pbNewTrainer(tr_type, tr_name, tr_version, save_changes = true) }) end # Add trainer's data to records - key = [tr_type, tr_name, tr_version] - GameData::Trainer::DATA[trainer_hash[:id]] = GameData::Trainer::DATA[key] = GameData::Trainer.new(trainer_hash) + trainer_hash[:id] = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] + GameData::Trainer.register(trainer_hash) GameData::Trainer.save pbConvertTrainerData pbMessage(_INTL("The Trainer's data was added to the list of battles and in PBS/trainers.txt.")) diff --git a/Data/Scripts/016_Pokemon/001_Pokemon.rb b/Data/Scripts/016_Pokemon/001_Pokemon.rb index 1fba5018c..40a2ee86c 100644 --- a/Data/Scripts/016_Pokemon/001_Pokemon.rb +++ b/Data/Scripts/016_Pokemon/001_Pokemon.rb @@ -31,9 +31,6 @@ class Pokemon # defined at this index. Is recalculated (as 0 or 1) if made nil. # @param value [Integer, nil] forced ability index (nil if none is set) attr_writer :ability_index - # If defined, this Pokémon's nature is considered to be this when calculating stats. - # @param value [Integer, nil] ID of the nature to use for calculating stats - attr_writer :nature_for_stats # @return [Array] the moves known by this Pokémon attr_accessor :moves # @return [Array] the IDs of moves known by this Pokémon when it was obtained @@ -442,35 +439,52 @@ class Pokemon # Nature #============================================================================= - # @return [Integer] the ID of this Pokémon's nature + # @return [GameData::Nature, nil] a Nature object corresponding to this Pokémon's nature def nature - @nature = (@personalID % 25) if !@nature - return @nature + @nature = GameData::Nature.get(@personalID % 25).id if !@nature + return GameData::Nature.try_get(@nature) end - # Returns the calculated nature, taking into account things that change its - # stat-altering effect (i.e. Gen 8 mints). Only used for calculating stats. - # @return [Integer] this Pokémon's calculated nature - def nature_for_stats - return @nature_for_stats || self.nature + def nature_id + return @nature end # Sets this Pokémon's nature to a particular nature. # @param value [Integer, String, Symbol] nature to change to def nature=(value) - @nature = getID(PBNatures, value) + return if value && !GameData::Nature.exists?(value) + @nature = (value) ? GameData::Nature.get(value).id : value calcStats if !@nature_for_stats end + # Returns the calculated nature, taking into account things that change its + # stat-altering effect (i.e. Gen 8 mints). Only used for calculating stats. + # @return [GameData::Nature, nil] this Pokémon's calculated nature + def nature_for_stats + return GameData::Nature.try_get(@nature_for_stats) if @nature_for_stats + return self.nature + end + + def nature_for_stats_id + return @nature_for_stats + end + + # If defined, this Pokémon's nature is considered to be this when calculating stats. + # @param value [Integer, nil] ID of the nature to use for calculating stats + def nature_for_stats=(value) + return if value && !GameData::Nature.exists?(value) + @nature_for_stats = (value) ? GameData::Nature.get(value).id : value + calcStats + end + # Returns whether this Pokémon has a particular nature. If no value is given, # returns whether this Pokémon has a nature set. # @param nature [Integer] nature ID to check # @return [Boolean] whether this Pokémon has a particular nature or a nature # at all - def hasNature?(check_nature = -1) - current_nature = self.nature - return current_nature >= 0 if check_nature < 0 - return current_nature == getID(PBNatures, check_nature) + def hasNature?(check_nature = nil) + return !@nature_id.nil? if check_nature.nil? + return self.nature == check_nature end #============================================================================= @@ -901,7 +915,14 @@ class Pokemon base_stats = self.baseStats this_level = self.level this_IV = self.calcIV - nature_mod = PBNatures.getStatChanges(self.nature_for_stats) + # Format stat multipliers due to nature + nature_mod = [] + PBStats.eachStat { |s| nature_mod[s] = 100 } + this_nature = self.nature_for_stats + if this_nature + this_nature.stat_changes.each { |change| nature_mod[change[0]] += change[1] } + end + # Calculate stats stats = [] PBStats.eachStat do |s| if s == PBStats::HP diff --git a/Data/Scripts/017_UI/006_PScreen_Summary.rb b/Data/Scripts/017_UI/006_PScreen_Summary.rb index ec63ff917..75ca573fd 100644 --- a/Data/Scripts/017_UI/006_PScreen_Summary.rb +++ b/Data/Scripts/017_UI/006_PScreen_Summary.rb @@ -535,7 +535,7 @@ class PokemonSummary_Scene # Write nature showNature = !@pokemon.shadowPokemon? || @pokemon.heartStage>3 if showNature - natureName = PBNatures.getName(@pokemon.nature) + natureName = @pokemon.nature.name memo += _INTL("{1} nature.\n",natureName) end # Write date received @@ -628,11 +628,11 @@ class PokemonSummary_Scene # Determine which stats are boosted and lowered by the Pokémon's nature statshadows = [] PBStats.eachStat { |s| statshadows[s] = shadow } - if !@pokemon.shadowPokemon? || @pokemon.heartStage>3 - natup = PBNatures.getStatRaised(@pokemon.nature_for_stats) - natdn = PBNatures.getStatLowered(@pokemon.nature_for_stats) - statshadows[natup] = Color.new(136,96,72) if natup!=natdn - statshadows[natdn] = Color.new(64,120,152) if natup!=natdn + if !@pokemon.shadowPokemon? || @pokemon.heartStage > 3 + @pokemon.nature_for_stats.stat_changes.each do |change| + statshadows[change[0]] = Color.new(136,96,72) if change[1] > 0 + statshadows[change[0]] = Color.new(64,120,152) if change[1] < 0 + end end # Write various bits of text textpos = [ diff --git a/Data/Scripts/019_Other battles/003_PBattle_OrgBattle.rb b/Data/Scripts/019_Other battles/003_PBattle_OrgBattle.rb index b319f73f0..5768aed0d 100644 --- a/Data/Scripts/019_Other battles/003_PBattle_OrgBattle.rb +++ b/Data/Scripts/019_Other battles/003_PBattle_OrgBattle.rb @@ -34,7 +34,7 @@ class PBPokemon pieces=insp.split(/\s*;\s*/) species = (GameData::Species.exists?(pieces[0])) ? GameData::Species.get(pieces[0]).id : nil item = (GameData::Item.exists?(pieces[1])) ? GameData::Item.get(pieces[1]).id : nil - nature=PBNatures.const_get(pieces[2]) + nature = (GameData::Nature.exists?(pieces[2])) ? GameData::Nature.get(pieces[2]).id : nil ev=pieces[3].split(/\s*,\s*/) evvalue=0 for i in 0...6 @@ -94,7 +94,7 @@ class PBPokemon s=str.split(/\s*,\s*/) species=GameData::Species.get(s[1]).id item=s[2].to_sym - nature=self.constFromStr(PBNatures,s[3]) + nature=GameData::Nature.get(s[3]).id move1=GameData::Move.get(s[4]).id move2=(s.length>=12) ? GameData::Move.get(s[5]).id : nil move3=(s.length>=13) ? GameData::Move.get(s[6]).id : nil @@ -128,7 +128,7 @@ class PBPokemon def inspect c1=GameData::Species.get(@species).id.to_s c2=(@item) ? GameData::Item.get(@item).id.to_s : "" - c3=getConstantName(PBNatures,@nature) + c3=(@nature) ? GameData::Nature.get(@nature).id.to_s : "" evlist="" for i in 0...@ev if ((@ev&(1<>nd5)&1)==0 # If stat to increase isn't emphasized - next if rand(10)<9 if ((ev>>nm5)&1)!=0 # If stat to decrease is emphasized + raised_emphasis = false + lowered_emphasis = false + nature_data.stat_changes.each do |change| + raised_emphasis = true if change[1] > 0 && ((ev >> change[0]) & 1) != 0 + lowered_emphasis = true if change[1] < 0 && ((ev >> change[0]) & 1) != 0 + end + next if rand(10) < 6 && !raised_emphasis + next if rand(10) < 9 && lowered_emphasis end break end diff --git a/Data/Scripts/021_Debug/001_Debug menus/004_Debug_PokemonCommands.rb b/Data/Scripts/021_Debug/001_Debug menus/004_Debug_PokemonCommands.rb index ed8c22de2..41e0ebb5c 100644 --- a/Data/Scripts/021_Debug/001_Debug menus/004_Debug_PokemonCommands.rb +++ b/Data/Scripts/021_Debug/001_Debug menus/004_Debug_PokemonCommands.rb @@ -637,27 +637,35 @@ PokemonDebugMenuCommands.register("setnature", { "always_show" => true, "effect" => proc { |pkmn, pkmnid, heldpoke, settingUpBattle, screen| commands = [] - (PBNatures.maxValue + 1).times do |i| - statUp = PBNatures.getStatRaised(i) - statDown = PBNatures.getStatLowered(i) - if statUp != statDown - text = _INTL("{1} (+{2}, -{3})", PBNatures.getName(i), - PBStats.getNameBrief(statUp), PBStats.getNameBrief(statDown)) + ids = [] + GameData::Nature.each do |nature| + if nature.stat_changes.length == 0 + commands.push(_INTL("{1} (---)", nature.real_name)) else - text = _INTL("{1} (---)", PBNatures.getName(i)) + plus_text = "" + minus_text = "" + nature.stat_changes.each do |change| + if change[1] > 0 + plus_text += "/" if !plus_text.empty? + plus_text += PBStats.getNameBrief(change[0]) + elsif change[1] < 0 + minus_text += "/" if !minus_text.empty? + minus_text += PBStats.getNameBrief(change[0]) + end + end + commands.push(_INTL("{1} (+{2}, -{3})", nature.real_name, plus_text, minus_text)) end - commands.push(text) + ids.push(nature.id) end commands.push(_INTL("[Reset]")) - cmd = pkmn.nature + cmd = ids.index(pkmn.nature_id || ids[0]) loop do - mag = _INTL("Nature is {1}.", PBNatures.getName(pkmn.nature)) + mag = _INTL("Nature is {1}.", pkmn.nature.name) cmd = screen.pbShowCommands(mag, commands, cmd) break if cmd < 0 - if cmd >= 0 && cmd <= PBNatures.maxValue # Set nature - pkmn.nature = cmd - pkmn.calcStats - elsif cmd == PBNatures.maxValue + 1 # Reset + if cmd >= 0 && cmd < commands.length - 1 # Set nature + pkmn.nature = ids[cmd] + elsif cmd == commands.length - 1 # Reset pkmn.nature = nil end screen.pbRefreshSingle(pkmnid) diff --git a/Data/Scripts/021_Debug/004_Editor_Screens.rb b/Data/Scripts/021_Debug/004_Editor_Screens.rb index 9b3083064..d565f5161 100644 --- a/Data/Scripts/021_Debug/004_Editor_Screens.rb +++ b/Data/Scripts/021_Debug/004_Editor_Screens.rb @@ -51,7 +51,7 @@ def pbEncountersEditor :step_chances => [], :types => [] } - GameData::Encounter::DATA[encounter_hash[:id]] = GameData::Encounter.new(encounter_hash) + GameData::Encounter.register(encounter_hash) maps.push([new_map_ID, new_version]) maps.sort! { |a, b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] } ret = maps.index([new_map_ID, new_version]) + 1 @@ -88,7 +88,7 @@ def pbEncountersEditor :step_chances => GameData::Encounter.get(this_set[0], this_set[1]).step_chances.clone, :types => types } - GameData::Encounter::DATA[encounter_hash[:id]] = GameData::Encounter.new(encounter_hash) + GameData::Encounter.register(encounter_hash) maps.push([new_map_ID, new_version]) maps.sort! { |a, b| (a[0] == b[0]) ? a[1] <=> b[1] : a[0] <=> b[0] } ret = maps.index([new_map_ID, new_version]) + 1 @@ -393,7 +393,7 @@ def pbTrainerTypeEditor :skill_code => line[8] } # Add trainer type's data to records - GameData::TrainerType::DATA[t_data.id_number] = GameData::TrainerType::DATA[t_data.id] = GameData::TrainerType.new(type_hash) + GameData::TrainerType.register(type_hash) GameData::TrainerType.save pbConvertTrainerData end @@ -455,7 +455,7 @@ def pbTrainerTypeEditorNew(default_name) :gender => gender } # Add trainer type's data to records - GameData::TrainerType::DATA[id_number] = GameData::TrainerType::DATA[id.to_sym] = GameData::TrainerType.new(tr_type_hash) + GameData::TrainerType.register(tr_type_hash) GameData::TrainerType.save pbConvertTrainerData pbMessage(_INTL("The trainer type {1} was created (ID: {2}).", name, id.to_s)) @@ -549,7 +549,7 @@ def pbTrainerBattleEditor pbMessage(_INTL("Can't save. The Pokémon list is empty.")) else trainer_hash = { - :id => tr_data.id_number, + :id_number => tr_data.id_number, :trainer_type => data[0], :name => data[1], :version => data[2], @@ -558,8 +558,8 @@ def pbTrainerBattleEditor :items => items } # Add trainer type's data to records - key = [data[0], data[1], data[2]] - GameData::Trainer::DATA[tr_data.id_number] = GameData::Trainer::DATA[key] = GameData::Trainer.new(trainer_hash) + trainer_hash[:id] = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] + GameData::Trainer.register(trainer_hash) if data[0] != old_type || data[1] != old_name || data[2] != old_version GameData::Trainer::DATA.delete([old_type, old_name, old_version]) end @@ -592,7 +592,7 @@ def pbTrainerBattleEditor t = pbNewTrainer(tr_type, tr_name, tr_version, false) if t trainer_hash = { - :id => GameData::Trainer::DATA.keys.length / 2, + :id_number => GameData::Trainer::DATA.keys.length / 2, :trainer_type => tr_type, :name => tr_name, :version => tr_version, @@ -605,8 +605,8 @@ def pbTrainerBattleEditor }) end # Add trainer's data to records - key = [tr_type, tr_name, tr_version] - GameData::Trainer::DATA[trainer_hash[:id]] = GameData::Trainer::DATA[key] = GameData::Trainer.new(trainer_hash) + trainer_hash[:id] = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] + GameData::Trainer.register(trainer_hash) pbMessage(_INTL("The Trainer battle was added.")) modified = true end @@ -657,7 +657,7 @@ module TrainerPokemonProperty [_INTL("Level"), NonzeroLimitProperty.new(max_level), _INTL("Level of the Pokémon (1-{1}).", max_level)], [_INTL("Name"), StringProperty, _INTL("Name of the Pokémon.")], [_INTL("Form"), LimitProperty2.new(999), _INTL("Form of the Pokémon.")], - [_INTL("Gender"), GenderProperty.new, _INTL("Gender of the Pokémon.")], + [_INTL("Gender"), GenderProperty, _INTL("Gender of the Pokémon.")], [_INTL("Shiny"), BooleanProperty2, _INTL("If set to true, the Pokémon is a different-colored Pokémon.")], [_INTL("Shadow"), BooleanProperty2, _INTL("If set to true, the Pokémon is a Shadow Pokémon.")] ] @@ -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"), EnumProperty2.new(PBNatures), _INTL("Nature of the Pokémon.")], + [_INTL("Nature"), NatureProperty, _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).")], @@ -759,7 +759,7 @@ def pbEditMetadata(map_id = 0) :player_H => data[15] } # Add metadata's data to records - GameData::Metadata::DATA[map_id] = GameData::Metadata.new(metadata_hash) + GameData::Metadata.register(metadata_hash) GameData::Metadata.save else # Map metadata # Construct metadata hash @@ -787,7 +787,7 @@ def pbEditMetadata(map_id = 0) :battle_environment => data[19] } # Add metadata's data to records - GameData::MapMetadata::DATA[map_id] = GameData::MapMetadata.new(metadata_hash) + GameData::MapMetadata.register(metadata_hash) GameData::MapMetadata.save end Compiler.write_metadata @@ -869,7 +869,7 @@ def pbItemEditor :move => data[9] } # Add item's data to records - GameData::Item::DATA[itm.id_number] = GameData::Item::DATA[itm.id] = GameData::Item.new(item_hash) + GameData::Item.register(item_hash) GameData::Item.save Compiler.write_items end @@ -933,7 +933,7 @@ def pbItemEditorNew(default_name) :description => description } # Add item's data to records - GameData::Item::DATA[id_number] = GameData::Item::DATA[id.to_sym] = GameData::Item.new(item_hash) + GameData::Item.register(item_hash) GameData::Item.save Compiler.write_items pbMessage(_INTL("The item {1} was created (ID: {2}).", name, id.to_s)) @@ -1114,7 +1114,7 @@ def pbPokemonEditor :shadow_size => data[43] } # Add species' data to records - GameData::Species::DATA[spec.id_number] = GameData::Species::DATA[spec.id] = GameData::Species.new(species_hash) + GameData::Species.register(species_hash) GameData::Species.save Compiler.write_pokemon pbMessage(_INTL("Data saved.")) diff --git a/Data/Scripts/021_Debug/007_Editor_DataTypes.rb b/Data/Scripts/021_Debug/007_Editor_DataTypes.rb index 9f1422a81..c7a00dc0c 100644 --- a/Data/Scripts/021_Debug/007_Editor_DataTypes.rb +++ b/Data/Scripts/021_Debug/007_Editor_DataTypes.rb @@ -384,17 +384,17 @@ end -class GenderProperty - def set(_settingname,_oldsetting) +module GenderProperty + def self.set(_settingname,_oldsetting) ret = pbShowCommands(nil,[_INTL("Male"),_INTL("Female")],-1) return (ret>=0) ? ret : nil end - def defaultValue + def self.defaultValue return nil end - def format(value) + def self.format(value) return _INTL("-") if !value return (value==0) ? _INTL("Male") : (value==1) ? _INTL("Female") : "-" end @@ -402,6 +402,23 @@ 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) diff --git a/Data/Scripts/021_Debug/009_Editor_Utilities.rb b/Data/Scripts/021_Debug/009_Editor_Utilities.rb index ab5423bb3..2da0bc8eb 100644 --- a/Data/Scripts/021_Debug/009_Editor_Utilities.rb +++ b/Data/Scripts/021_Debug/009_Editor_Utilities.rb @@ -206,6 +206,12 @@ 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 pbChooseBallList(defaultMoveID = -1) cmdwin = pbListWindow([], 200) commands = [] diff --git a/Data/Scripts/022_Compiler/001_Compiler.rb b/Data/Scripts/022_Compiler/001_Compiler.rb index ededc8951..6a808cfc0 100644 --- a/Data/Scripts/022_Compiler/001_Compiler.rb +++ b/Data/Scripts/022_Compiler/001_Compiler.rb @@ -649,11 +649,15 @@ module Compiler end # Unused - def parseNature(item) - clonitem = item.upcase - clonitem.sub!(/^\s*/, "") - clonitem.sub!(/\s*$/, "") - return pbGetConst(PBNatures, clonitem, _INTL("Undefined nature constant name: {1}\r\nMake sure the name is defined in the script section PBNatures.\r\n{1}", item, FileLineData.linereport)) + def parseNature(nature) + clonnature = nature.upcase + clonnature.sub!(/^\s*/, "") + clonnature.sub!(/\s*$/, "") + nat = GameData::Nature.try_get(clonnature) + if !nat + raise _INTL("Undefined nature constant name: {1}\r\nMake sure the nature is defined in the scripts.\r\n{2}", nature, FileLineData.linereport) + end + return nat.id end # Unused diff --git a/Data/Scripts/022_Compiler/002_Compiler_CompilePBS.rb b/Data/Scripts/022_Compiler/002_Compiler_CompilePBS.rb index 46a362cdf..8893402c0 100644 --- a/Data/Scripts/022_Compiler/002_Compiler_CompilePBS.rb +++ b/Data/Scripts/022_Compiler/002_Compiler_CompilePBS.rb @@ -180,7 +180,7 @@ module Compiler :immunities => contents["Immunities"] } # Add type's data to records - GameData::Type::DATA[type_number] = GameData::Type::DATA[type_symbol] = GameData::Type.new(type_hash) + GameData::Type.register(type_hash) type_names[type_number] = type_hash[:name] } } @@ -229,7 +229,7 @@ module Compiler :description => line[3] } # Add ability's data to records - GameData::Ability::DATA[ability_number] = GameData::Ability::DATA[ability_symbol] = GameData::Ability.new(ability_hash) + GameData::Ability.register(ability_hash) ability_names[ability_number] = ability_hash[:name] ability_descriptions[ability_number] = ability_hash[:description] } @@ -285,7 +285,7 @@ module Compiler :description => line[13] } # Add move's data to records - GameData::Move::DATA[move_number] = GameData::Move::DATA[move_symbol] = GameData::Move.new(move_hash) + GameData::Move.register(move_hash) move_names[move_number] = move_hash[:name] move_descriptions[move_number] = move_hash[:description] } @@ -329,7 +329,7 @@ module Compiler } item_hash[:move] = parseMove(line[10]) if !nil_or_empty?(line[10]) # Add item's data to records - GameData::Item::DATA[item_number] = GameData::Item::DATA[item_symbol] = GameData::Item.new(item_hash) + GameData::Item.register(item_hash) item_names[item_number] = item_hash[:name] item_names_plural[item_number] = item_hash[:name_plural] item_descriptions[item_number] = item_hash[:description] @@ -364,7 +364,7 @@ module Compiler :maximum_yield => line[3] } # Add berry plant's data to records - GameData::BerryPlant::DATA[item_number] = GameData::BerryPlant::DATA[item_symbol] = GameData::BerryPlant.new(berry_plant_hash) + GameData::BerryPlant.register(berry_plant_hash) end } # Save all data @@ -489,7 +489,7 @@ module Compiler :shadow_size => contents["BattlerShadowSize"] } # Add species' data to records - GameData::Species::DATA[species_number] = GameData::Species::DATA[species_symbol] = GameData::Species.new(species_hash) + GameData::Species.register(species_hash) species_names[species_number] = species_hash[:name] species_form_names[species_number] = species_hash[:form_name] species_categories[species_number] = species_hash[:category] @@ -692,7 +692,7 @@ module Compiler species_hash[:wild_item_rare] = contents["WildItemRare"] end # Add form's data to records - GameData::Species::DATA[form_number] = GameData::Species::DATA[form_symbol] = GameData::Species.new(species_hash) + GameData::Species.register(species_hash) species_names[form_number] = species_hash[:name] species_form_names[form_number] = species_hash[:form_name] species_categories[form_number] = species_hash[:category] @@ -897,7 +897,7 @@ module Compiler encounters.compact! encounters.sort! { |a, b| (a[0] == b[0]) ? a[1].to_s <=> b[1].to_s : b[0] <=> a[0] } end - GameData::Encounter::DATA[encounter_hash[:id]] = GameData::Encounter.new(encounter_hash) + GameData::Encounter.register(encounter_hash) end # Raise an error if a map/version combo is used twice key = sprintf("%s_%d", map_number, map_version).to_sym @@ -938,7 +938,7 @@ module Compiler encounters.compact! encounters.sort! { |a, b| (a[0] == b[0]) ? a[1].to_s <=> b[1].to_s : b[0] <=> a[0] } end - GameData::Encounter::DATA[encounter_hash[:id]] = GameData::Encounter.new(encounter_hash) + GameData::Encounter.register(encounter_hash) end # Raise an error if a map/version combo is used twice key = sprintf("%s_0", map_number).to_sym @@ -1010,7 +1010,7 @@ module Compiler encounters.compact! encounters.sort! { |a, b| (a[0] == b[0]) ? a[1].to_s <=> b[1].to_s : b[0] <=> a[0] } end - GameData::Encounter::DATA[encounter_hash[:id]] = GameData::Encounter.new(encounter_hash) + GameData::Encounter.register(encounter_hash) end # Save all data GameData::Encounter.save @@ -1053,7 +1053,7 @@ module Compiler :skill_code => line[9] } # Add trainer type's data to records - GameData::TrainerType::DATA[type_number] = GameData::TrainerType::DATA[type_symbol] = GameData::TrainerType.new(type_hash) + GameData::TrainerType.register(type_hash) tr_type_names[type_number] = type_hash[:name] } # Save all data @@ -1087,14 +1087,14 @@ module Compiler raise _INTL("Started new trainer while previous trainer has no Pokémon.\r\n{1}", FileLineData.linereport) end # Add trainer's data to records - key = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] - GameData::Trainer::DATA[trainer_id] = GameData::Trainer::DATA[key] = GameData::Trainer.new(trainer_hash) + trainer_hash[:id] = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] + GameData::Trainer.register(trainer_hash) end trainer_id += 1 line_data = pbGetCsvRecord($~[1], line_no, [0, "esU", :TrainerType]) # Construct trainer hash trainer_hash = { - :id => trainer_id, + :id_number => trainer_id, :trainer_type => line_data[0], :name => line_data[1], :version => line_data[2] || 0, @@ -1179,14 +1179,14 @@ module Compiler raise _INTL("Started new trainer while previous trainer has no Pokémon.\r\n{1}", FileLineData.linereport) end # Add trainer's data to records - key = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] - GameData::Trainer::DATA[trainer_id] = GameData::Trainer::DATA[key] = GameData::Trainer.new(trainer_hash) + trainer_hash[:id] = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] + GameData::Trainer.register(trainer_hash) end trainer_id += 1 old_format_expected_lines = 3 # Construct trainer hash trainer_hash = { - :id => trainer_id, + :id_number => trainer_id, :trainer_type => nil, :name => nil, :version => 0, @@ -1219,7 +1219,7 @@ module Compiler [0, "evEEEEEUEUBEUUSBU", :Species, nil, :Item, :Move, :Move, :Move, :Move, nil, {"M" => 0, "m" => 0, "Male" => 0, "male" => 0, "0" => 0, "F" => 1, "f" => 1, "Female" => 1, "female" => 1, "1" => 1}, - nil, nil, :PBNatures, nil, nil, nil, nil, nil]) + nil, nil, :Nature, nil, nil, nil, nil, nil]) current_pkmn = { :species => line_data[0] } @@ -1276,8 +1276,8 @@ module Compiler end # Add last trainer's data to records if trainer_hash - key = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] - GameData::Trainer::DATA[trainer_id] = GameData::Trainer::DATA[key] = GameData::Trainer.new(trainer_hash) + trainer_hash[:id] = [trainer_hash[:trainer_type], trainer_hash[:name], trainer_hash[:version]] + GameData::Trainer.register(trainer_hash) end # Save all data GameData::Trainer.save @@ -1449,7 +1449,7 @@ module Compiler :player_H => contents["PlayerH"] } # Add metadata's data to records - GameData::Metadata::DATA[map_id] = GameData::Metadata.new(metadata_hash) + GameData::Metadata.register(metadata_hash) else # Map metadata # Construct metadata hash metadata_hash = { @@ -1476,7 +1476,7 @@ module Compiler :battle_environment => contents["Environment"] } # Add metadata's data to records - GameData::MapMetadata::DATA[map_id] = GameData::MapMetadata.new(metadata_hash) + GameData::MapMetadata.register(metadata_hash) end } } diff --git a/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb b/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb index f4e1a8f97..75cba228d 100644 --- a/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb +++ b/Data/Scripts/022_Compiler/003_Compiler_WritePBS.rb @@ -592,7 +592,7 @@ module Compiler f.write(sprintf(" Moves = %s\r\n", pkmn[:moves].join(","))) if pkmn[:moves] && pkmn[:moves].length > 0 f.write(sprintf(" Ability = %d\r\n", pkmn[:ability_flag])) if pkmn[:ability_flag] f.write(sprintf(" Item = %s\r\n", pkmn[:item])) if pkmn[:item] - f.write(sprintf(" Nature = %s\r\n", getConstantName(PBNatures, pkmn[:nature]))) if pkmn[:nature] + f.write(sprintf(" Nature = %s\r\n", pkmn[:nature])) if pkmn[:nature] if pkmn[:iv] && pkmn[:iv].length > 0 f.write(sprintf(" IV = %s\r\n", (pkmn[:iv].uniq.length == 1) ? pkmn[:iv][0] : pkmn[:iv].join(","))) end @@ -684,7 +684,7 @@ module Compiler pkmn = btpokemon[i] c1 = (species[pkmn.species]) ? species[pkmn.species] : (species[pkmn.species] = GameData::Species.get(pkmn.species).species.to_s) c2 = (items[pkmn.item]) ? items[pkmn.item] : (items[pkmn.item] = GameData::Item.get(pkmn.item).id.to_s) - c3 = (natures[pkmn.nature]) ? natures[pkmn.nature] : (natures[pkmn.nature] = getConstantName(PBNatures, pkmn.nature)) + c3 = (natures[pkmn.nature]) ? natures[pkmn.nature] : (natures[pkmn.nature] = GameData::Nature.get(pkmn.nature).id.to_s) evlist = "" ev = pkmn.ev for i in 0...ev