From c8790bafc970257fb270d30d246708505aceea4c Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Sun, 6 Dec 2020 19:21:18 +0000 Subject: [PATCH] Created and implemented GameData::TrainerType, fixed free text entry text mispositioning --- Data/Scripts/001_Technical/008_Errors.rb | 8 - .../009_Objects and windows/012_TextEntry.rb | 6 +- Data/Scripts/011_Data/001_Data_Cache.rb | 19 -- .../011_Data/001_Game data/001_Game data.rb | 3 +- .../011_Data/001_Game data/005_Metadata.rb | 16 +- .../001_Game data/008_Trainer type.rb | 49 ++++ .../003_Battle/009_Battle_Action_Other.rb | 2 +- .../001_PokeBattle_Animation.rb | 7 +- .../Scripts/013_Overworld/002_PField_Field.rb | 18 +- .../013_Overworld/003_PField_Visuals.rb | 31 ++- .../014_Trainers/001_PokeBattle_Trainer.rb | 180 ++++++------- .../014_Trainers/002_PTrainer_NPCTrainers.rb | 139 +++++----- Data/Scripts/015_Items/004_PItem_Phone.rb | 38 ++- Data/Scripts/017_UI/010_PScreen_Phone.rb | 2 +- .../018_Minigames/001_PMinigame_Duel.rb | 2 +- .../005_PBattle_OrgBattleGenerator.rb | 32 +-- .../003_PSystem_FileUtilities.rb | 82 +++--- .../005_PSystem_Utilities.rb | 13 +- Data/Scripts/021_Debug/004_Editor_Screens.rb | 245 +++++++++--------- Data/Scripts/021_Debug/005_Editor_SaveData.rb | 92 +++---- .../021_Debug/006_Editor_DataFormatting.rb | 14 +- .../Scripts/021_Debug/007_Editor_DataTypes.rb | 8 +- Data/Scripts/021_Debug/008_Editor_Listers.rb | 83 +++--- .../Scripts/021_Debug/009_Editor_Utilities.rb | 19 -- Data/Scripts/022_Compiler/002_Compiler.rb | 28 +- Data/Scripts/022_Compiler/003_Compiler_PBS.rb | 77 +++--- .../004_Compiler_MapsAndEvents.rb | 52 ++-- 27 files changed, 582 insertions(+), 683 deletions(-) create mode 100644 Data/Scripts/011_Data/001_Game data/008_Trainer type.rb diff --git a/Data/Scripts/001_Technical/008_Errors.rb b/Data/Scripts/001_Technical/008_Errors.rb index 3a25f6a8d..8007e1491 100644 --- a/Data/Scripts/001_Technical/008_Errors.rb +++ b/Data/Scripts/001_Technical/008_Errors.rb @@ -13,18 +13,10 @@ def pbGetExceptionMessage(e,_script="") emessage = "File #{filename} not found." end if emessage && !safeExists?("Game.rgssad") && !safeExists?("Game.rgss2a") - emessage = emessage.gsub(/uninitialized constant PBItems\:\:(\S+)/) { - "The item '#{$1}' is not valid. Please add the item\r\nto the PBS/items.txt file. See the wiki for more information." } - emessage = emessage.gsub(/undefined method `(\S+?)' for PBItems\:Module/) { - "The item '#{$1}' is not valid. Please add the item\r\nto the PBS/items.txt file. See the wiki for more information." } emessage = emessage.gsub(/uninitialized constant PBTypes\:\:(\S+)/) { "The type '#{$1}' is not valid. Please add the type\r\nto the PBS/types.txt file." } emessage = emessage.gsub(/undefined method `(\S+?)' for PBTypes\:Module/) { "The type '#{$1}' is not valid. Please add the type\r\nto the PBS/types.txt file." } - emessage = emessage.gsub(/uninitialized constant PBTrainers\:\:(\S+)$/) { - "The trainer type '#{$1}' is not valid. Please add the trainer\r\nto the PBS/trainertypes.txt file. See the wiki for\r\nmore information." } - emessage = emessage.gsub(/undefined method `(\S+?)' for PBTrainers\:Module/) { - "The trainer type '#{$1}' is not valid. Please add the trainer\r\nto the PBS/trainertypes.txt file. See the wiki for\r\nmore information." } emessage = emessage.gsub(/uninitialized constant PBSpecies\:\:(\S+)$/) { "The Pokemon species '#{$1}' is not valid. Please\r\nadd the species to the PBS/pokemon.txt file.\r\nSee the wiki for more information." } emessage = emessage.gsub(/undefined method `(\S+?)' for PBSpecies\:Module/) { diff --git a/Data/Scripts/009_Objects and windows/012_TextEntry.rb b/Data/Scripts/009_Objects and windows/012_TextEntry.rb index 4ef92c0dd..417224182 100644 --- a/Data/Scripts/009_Objects and windows/012_TextEntry.rb +++ b/Data/Scripts/009_Objects and windows/012_TextEntry.rb @@ -249,7 +249,7 @@ class Window_TextEntry < SpriteWindow_Base bitmap=self.contents bitmap.clear x=0 - y=0 + y=6 if @heading textwidth=bitmap.text_size(@heading).width pbDrawShadowText(bitmap,x,y, textwidth+4, 32, @heading,@baseColor,@shadowColor) @@ -278,13 +278,13 @@ class Window_TextEntry < SpriteWindow_Base pbDrawShadowText(bitmap,x,y, textwidth+4, 32, c,@baseColor,@shadowColor) # Draw cursor if necessary if ((@frame/10)&1) == 0 && i==@helper.cursor - bitmap.fill_rect(x,y+4,2,24,cursorcolor) + bitmap.fill_rect(x,y-2,2,24,cursorcolor) end # Add x to drawn text width x += textwidth end if ((@frame/10)&1) == 0 && textscan.length==@helper.cursor - bitmap.fill_rect(x,y+4,2,24,cursorcolor) + bitmap.fill_rect(x,y-2,2,24,cursorcolor) end end end diff --git a/Data/Scripts/011_Data/001_Data_Cache.rb b/Data/Scripts/011_Data/001_Data_Cache.rb index 7460664cc..1c2e344e1 100644 --- a/Data/Scripts/011_Data/001_Data_Cache.rb +++ b/Data/Scripts/011_Data/001_Data_Cache.rb @@ -14,7 +14,6 @@ class PokemonTemp attr_accessor :speciesTMData attr_accessor :speciesShadowMovesets attr_accessor :pokemonFormToSpecies - attr_accessor :trainerTypesData attr_accessor :trainersData attr_accessor :moveToAnim attr_accessor :battleAnims @@ -34,7 +33,6 @@ def pbClearData $PokemonTemp.speciesTMData = nil $PokemonTemp.speciesShadowMovesets = nil $PokemonTemp.pokemonFormToSpecies = nil - $PokemonTemp.trainerTypesData = nil $PokemonTemp.trainersData = nil $PokemonTemp.moveToAnim = nil $PokemonTemp.battleAnims = nil @@ -209,23 +207,6 @@ def pbLoadFormToSpecies return $PokemonTemp.pokemonFormToSpecies end -#=============================================================================== -# Methods to get trainer type data. -#=============================================================================== -def pbLoadTrainerTypesData - $PokemonTemp = PokemonTemp.new if !$PokemonTemp - if !$PokemonTemp.trainerTypesData - $PokemonTemp.trainerTypesData = load_data("Data/trainer_types.dat") || [] - end - return $PokemonTemp.trainerTypesData -end - -def pbGetTrainerTypeData(trainer_type) - trainer_type_data = pbLoadTrainerTypesData - return trainer_type_data[trainer_type] if trainer_type_data - return nil -end - #=============================================================================== # Methods to get data about individual trainers. #=============================================================================== 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 70f0a8220..48439dc15 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 @@ -120,9 +120,10 @@ module GameData def self.load_all Ability.load Item.load - Move.load BerryPlant.load Metadata.load MapMetadata.load + Move.load + TrainerType.load end end diff --git a/Data/Scripts/011_Data/001_Game data/005_Metadata.rb b/Data/Scripts/011_Data/001_Game data/005_Metadata.rb index d420f6a60..185e09e9a 100644 --- a/Data/Scripts/011_Data/001_Game data/005_Metadata.rb +++ b/Data/Scripts/011_Data/001_Game data/005_Metadata.rb @@ -30,14 +30,14 @@ module GameData "WildCaptureME" => [6, "s"], "SurfBGM" => [7, "s"], "BicycleBGM" => [8, "s"], - "PlayerA" => [9, "esssssss", :PBTrainers], - "PlayerB" => [10, "esssssss", :PBTrainers], - "PlayerC" => [11, "esssssss", :PBTrainers], - "PlayerD" => [12, "esssssss", :PBTrainers], - "PlayerE" => [13, "esssssss", :PBTrainers], - "PlayerF" => [14, "esssssss", :PBTrainers], - "PlayerG" => [15, "esssssss", :PBTrainers], - "PlayerH" => [16, "esssssss", :PBTrainers] + "PlayerA" => [9, "esssssss", :TrainerType], + "PlayerB" => [10, "esssssss", :TrainerType], + "PlayerC" => [11, "esssssss", :TrainerType], + "PlayerD" => [12, "esssssss", :TrainerType], + "PlayerE" => [13, "esssssss", :TrainerType], + "PlayerF" => [14, "esssssss", :TrainerType], + "PlayerG" => [15, "esssssss", :TrainerType], + "PlayerH" => [16, "esssssss", :TrainerType] } extend ClassMethodsIDNumbers diff --git a/Data/Scripts/011_Data/001_Game data/008_Trainer type.rb b/Data/Scripts/011_Data/001_Game data/008_Trainer type.rb new file mode 100644 index 000000000..293f7a626 --- /dev/null +++ b/Data/Scripts/011_Data/001_Game data/008_Trainer type.rb @@ -0,0 +1,49 @@ +module GameData + class TrainerType + attr_reader :id + attr_reader :id_number + attr_reader :real_name + attr_reader :base_money + attr_reader :battle_BGM + attr_reader :victory_ME + attr_reader :intro_ME + attr_reader :gender + attr_reader :skill_level + attr_reader :skill_code + + DATA = {} + DATA_FILENAME = "trainer_types.dat" + + extend ClassMethods + include InstanceMethods + + def initialize(hash) + @id = hash[:id] + @id_number = hash[:id_number] || -1 + @real_name = hash[:name] || "Unnamed" + @base_money = hash[:base_money] || 30 + @battle_BGM = hash[:battle_BGM] + @victory_ME = hash[:victory_ME] + @intro_ME = hash[:intro_ME] + @gender = hash[:gender] || 2 + @skill_level = hash[:skill_level] || @base_money + @skill_code = hash[:skill_code] + end + + # @return [String] the translated name of this trainer type + def name + return pbGetMessage(MessageTypes::TrainerTypes, @id_number) + end + + def male?; return @gender == 0; end + def female?; return @gender == 1; end + end +end + +#=============================================================================== +# Deprecated methods +#=============================================================================== +def pbGetTrainerTypeData(trainer_type) + Deprecation.warn_method('pbGetTrainerTypeData', 'v20', 'GameData::TrainerType.get(trainer_type)') + return GameData::TrainerType.get(trainer_type) +end diff --git a/Data/Scripts/012_Battle/003_Battle/009_Battle_Action_Other.rb b/Data/Scripts/012_Battle/003_Battle/009_Battle_Action_Other.rb index 9b0a50086..8b918b2ab 100644 --- a/Data/Scripts/012_Battle/003_Battle/009_Battle_Action_Other.rb +++ b/Data/Scripts/012_Battle/003_Battle/009_Battle_Action_Other.rb @@ -73,7 +73,7 @@ class PokeBattle_Battle end end # NOTE: Add your own Mega objects for particular NPC trainers here. -# if isConst?(pbGetOwnerFromBattlerIndex(idxBattler).trainertype,PBTrainers,:BUGCATCHER) +# if pbGetOwnerFromBattlerIndex(idxBattler).trainertype == :BUGCATCHER # return _INTL("Mega Net") # end return _INTL("Mega Ring") diff --git a/Data/Scripts/012_Battle/005_Battle scene/001_PokeBattle_Animation.rb b/Data/Scripts/012_Battle/005_Battle scene/001_PokeBattle_Animation.rb index cc27fb4bb..f494921e9 100644 --- a/Data/Scripts/012_Battle/005_Battle scene/001_PokeBattle_Animation.rb +++ b/Data/Scripts/012_Battle/005_Battle scene/001_PokeBattle_Animation.rb @@ -106,11 +106,12 @@ module PokeBattle_BallAnimationMixin end # Back sprite is animated, make the Poké Ball track the trainer's hand coordSets = [[traSprite.x-44,traSprite.y-32],[-10,-36],[118,-4]] - if isConst?(@trainer.trainertype,PBTrainers,:POKEMONTRAINER_Leaf) + case @trainer.trainertype + when :POKEMONTRAINER_Leaf coordSets = [[traSprite.x-30,traSprite.y-30],[-18,-36],[118,-6]] - elsif isConst?(@trainer.trainertype,PBTrainers,:POKEMONTRAINER_Brendan) + when :POKEMONTRAINER_Brendan coordSets = [[traSprite.x-46,traSprite.y-40],[-4,-30],[118,-2]] - elsif isConst?(@trainer.trainertype,PBTrainers,:POKEMONTRAINER_May) + when :POKEMONTRAINER_May coordSets = [[traSprite.x-44,traSprite.y-38],[-8,-30],[122,0]] end # Arm stretched out behind player diff --git a/Data/Scripts/013_Overworld/002_PField_Field.rb b/Data/Scripts/013_Overworld/002_PField_Field.rb index 67157337b..b77dff19d 100644 --- a/Data/Scripts/013_Overworld/002_PField_Field.rb +++ b/Data/Scripts/013_Overworld/002_PField_Field.rb @@ -695,10 +695,10 @@ module InterpreterFieldMixin end def pbTrainerIntro(symbol) - return if $DEBUG && !pbTrainerTypeCheck(symbol) - trtype = PBTrainers.const_get(symbol) + return true if $DEBUG && !GameData::TrainerType.exists?(symbol) + tr_type = GameData::TrainerType.get(symbol).id pbGlobalLock - pbPlayTrainerIntroME(trtype) + pbPlayTrainerIntroME(tr_type) return true end @@ -1320,18 +1320,18 @@ end #=============================================================================== # Partner trainer #=============================================================================== -def pbRegisterPartner(trainerid,trainername,partyid=0) - trainerid = getID(PBTrainers,trainerid) +def pbRegisterPartner(tr_type, tr_name, tr_id = 0) + tr_type = GameData::TrainerType.get(tr_type).id pbCancelVehicles - trainer = pbLoadTrainer(trainerid,trainername,partyid) - Events.onTrainerPartyLoad.trigger(nil,trainer) - trainerobject = PokeBattle_Trainer.new(_INTL(trainer[0].name),trainerid) + trainer = pbLoadTrainer(tr_type, tr_name, tr_id) + Events.onTrainerPartyLoad.trigger(nil, trainer) + trainerobject = PokeBattle_Trainer.new(trainer[0].name, tr_type) trainerobject.setForeignID($Trainer) for i in trainer[2] i.owner = Pokemon::Owner.new_from_trainer(trainerobject) i.calcStats end - $PokemonGlobal.partner = [trainerid,trainerobject.name,trainerobject.id,trainer[2]] + $PokemonGlobal.partner = [tr_type, trainerobject.name, trainerobject.id, trainer[2]] end def pbDeregisterPartner diff --git a/Data/Scripts/013_Overworld/003_PField_Visuals.rb b/Data/Scripts/013_Overworld/003_PField_Visuals.rb index e8c848d25..4c21da853 100644 --- a/Data/Scripts/013_Overworld/003_PField_Visuals.rb +++ b/Data/Scripts/013_Overworld/003_PField_Visuals.rb @@ -136,13 +136,16 @@ def pbBattleAnimationOverride(viewport,battletype=0,foe=nil) ##### VS. animation, by Luka S.J. ##### ##### Tweaked by Maruno ##### if (battletype==1 || battletype==3) && foe.length==1 # Against single trainer - trainerid = (foe[0].trainertype rescue -1) - if trainerid>=0 - tbargraphic = sprintf("Graphics/Transitions/vsBar%s",getConstantName(PBTrainers,trainerid)) rescue nil - tbargraphic = sprintf("Graphics/Transitions/vsBar%d",trainerid) if !pbResolveBitmap(tbargraphic) - tgraphic = sprintf("Graphics/Transitions/vsTrainer%s",getConstantName(PBTrainers,trainerid)) rescue nil - tgraphic = sprintf("Graphics/Transitions/vsTrainer%d",trainerid) if !pbResolveBitmap(tgraphic) + tr_type = foe[0].trainertype + tr_type_id = GameData::TrainerType.get(tr_type).id_number + if tr_type + tbargraphic = sprintf("Graphics/Transitions/vsBar%s", tr_type.to_s) rescue nil + tbargraphic = sprintf("Graphics/Transitions/vsBar%d", tr_type_id) if !pbResolveBitmap(tbargraphic) + tgraphic = sprintf("Graphics/Transitions/vsTrainer%s", tr_type.to_s) rescue nil + tgraphic = sprintf("Graphics/Transitions/vsTrainer%d", tr_type_id) if !pbResolveBitmap(tgraphic) if pbResolveBitmap(tbargraphic) && pbResolveBitmap(tgraphic) + player_tr_type = $Trainer.trainertype + player_tr_type_id = GameData::TrainerType.get(player_tr_type).id_number outfit = $Trainer.outfit # Set up viewplayer = Viewport.new(0,Graphics.height/3,Graphics.width/2,128) @@ -158,12 +161,12 @@ def pbBattleAnimationOverride(viewport,battletype=0,foe=nil) overlay = Sprite.new(viewport) overlay.bitmap = Bitmap.new(Graphics.width,Graphics.height) pbSetSystemFont(overlay.bitmap) - pbargraphic = sprintf("Graphics/Transitions/vsBar%s_%d",getConstantName(PBTrainers,$Trainer.trainertype),outfit) rescue nil - pbargraphic = sprintf("Graphics/Transitions/vsBar%d_%d",$Trainer.trainertype,outfit) if !pbResolveBitmap(pbargraphic) + pbargraphic = sprintf("Graphics/Transitions/vsBar%s_%d", player_tr_type.to_s, outfit) rescue nil + pbargraphic = sprintf("Graphics/Transitions/vsBar%d_%d", player_tr_type_id, outfit) if !pbResolveBitmap(pbargraphic) if !pbResolveBitmap(pbargraphic) - pbargraphic = sprintf("Graphics/Transitions/vsBar%s",getConstantName(PBTrainers,$Trainer.trainertype)) rescue nil + pbargraphic = sprintf("Graphics/Transitions/vsBar%s", player_tr_type.to_s) rescue nil + pbargraphic = sprintf("Graphics/Transitions/vsBar%d", player_tr_type_id) if !pbResolveBitmap(pbargraphic) end - pbargraphic = sprintf("Graphics/Transitions/vsBar%d",$Trainer.trainertype) if !pbResolveBitmap(pbargraphic) xoffset = ((Graphics.width/2)/10)*10 bar1 = Sprite.new(viewplayer) bar1.bitmap = BitmapCache.load_bitmap(pbargraphic) @@ -199,12 +202,12 @@ def pbBattleAnimationOverride(viewport,battletype=0,foe=nil) bar1.bitmap = BitmapCache.load_bitmap(pbargraphic) bar2 = AnimatedPlane.new(viewopp) bar2.bitmap = BitmapCache.load_bitmap(tbargraphic) - pgraphic = sprintf("Graphics/Transitions/vsTrainer%s_%d",getConstantName(PBTrainers,$Trainer.trainertype),outfit) rescue nil - pgraphic = sprintf("Graphics/Transitions/vsTrainer%d_%d",$Trainer.trainertype,outfit) if !pbResolveBitmap(pgraphic) + pgraphic = sprintf("Graphics/Transitions/vsTrainer%s_%d", player_tr_type.to_s, outfit) rescue nil + pgraphic = sprintf("Graphics/Transitions/vsTrainer%d_%d", player_tr_type_id, outfit) if !pbResolveBitmap(pgraphic) if !pbResolveBitmap(pgraphic) - pgraphic = sprintf("Graphics/Transitions/vsTrainer%s",getConstantName(PBTrainers,$Trainer.trainertype)) rescue nil + pgraphic = sprintf("Graphics/Transitions/vsTrainer%s", player_tr_type.to_s) rescue nil + pgraphic = sprintf("Graphics/Transitions/vsTrainer%d", player_tr_type_id) if !pbResolveBitmap(pgraphic) end - pgraphic = sprintf("Graphics/Transitions/vsTrainer%d",$Trainer.trainertype) if !pbResolveBitmap(pgraphic) player = Sprite.new(viewplayer) player.bitmap = BitmapCache.load_bitmap(pgraphic) player.x = -xoffset diff --git a/Data/Scripts/014_Trainers/001_PokeBattle_Trainer.rb b/Data/Scripts/014_Trainers/001_PokeBattle_Trainer.rb index 590d5437d..e172e9ff5 100644 --- a/Data/Scripts/014_Trainers/001_PokeBattle_Trainer.rb +++ b/Data/Scripts/014_Trainers/001_PokeBattle_Trainer.rb @@ -16,44 +16,58 @@ class PokeBattle_Trainer attr_accessor :pokegear # Whether the Pokégear was obtained attr_writer :language - def trainerTypeName # Name of this trainer type (localized) - return PBTrainers.getName(@trainertype) rescue _INTL("PkMn Trainer") + def trainerTypeName; return GameData::TrainerType.get(@trainertype).name; end + def moneyEarned; return GameData::TrainerType.get(@trainertype).base_money; end + def gender; return GameData::TrainerType.get(@trainertype).gender; end + def male?; return GameData::TrainerType.get(@trainertype).male?; end + def female?; return GameData::TrainerType.get(@trainertype).female?; end + alias isMale? male? + alias isFemale? female? + def skill; return GameData::TrainerType.get(@trainertype).skill_level; end + def skillCode; return GameData::TrainerType.get(@trainertype).skill_code; end + + def hasSkillCode(code) + c = skillCode + return c && c != "" && c[/#{code}/] end def fullname - return _INTL("{1} {2}",self.trainerTypeName,@name) + return _INTL("{1} {2}", trainerTypeName, @name) end - def publicID(id=nil) # Portion of the ID which is visible on the Trainer Card - return id ? id&0xFFFF : @id&0xFFFF + #============================================================================= + # Unique ID number + #============================================================================= + def publicID(id = nil) # Portion of the ID which is visible on the Trainer Card + return id ? id & 0xFFFF : @id & 0xFFFF end - def secretID(id=nil) # Other portion of the ID - return id ? id>>16 : @id>>16 + def secretID(id = nil) # Other portion of the ID + return id ? id >> 16 : @id >> 16 end def getForeignID # Random ID other than this Trainer's ID - fid=0 + fid = 0 loop do - fid=rand(256) - fid|=rand(256)<<8 - fid|=rand(256)<<16 - fid|=rand(256)<<24 - break if fid!=@id + fid = rand(2 ** 16) | rand(2 ** 16) << 16 + break if fid != @id end return fid end def setForeignID(other) - @id=other.getForeignID + @id = other.getForeignID end def metaID - @metaID=$PokemonGlobal.playerID if !@metaID - @metaID=0 if !@metaID + @metaID = $PokemonGlobal.playerID if !@metaID + @metaID = 0 if !@metaID return @metaID end + #============================================================================= + # Other properties + #============================================================================= def outfit return @outfit || 0 end @@ -63,31 +77,7 @@ class PokeBattle_Trainer end def money=(value) - @money=[[value,MAX_MONEY].min,0].max - end - - def moneyEarned # Money won when trainer is defeated - data = pbGetTrainerTypeData(@trainertype) - return data[3] if data && data[3] - return 30 - end - - def skill # Skill level (for AI) - data = pbGetTrainerTypeData(@trainertype) - return data[8] if data && data[8] - return 30 - end - - def skillCode - data = pbGetTrainerTypeData(@trainertype) - return data[9] if data && data[9] - return "" - end - - def hasSkillCode(code) - c = skillCode - return true if c && c!="" && c[/#{code}/] - return false + @money = [[value, MAX_MONEY].min, 0].max end def numbadges # Number of badges @@ -96,18 +86,9 @@ class PokeBattle_Trainer return ret end - def gender - data = pbGetTrainerTypeData(@trainertype) - return data[7] if data && data[7] - return 2 # Gender unknown - end - - def male?; return self.gender==0; end - alias isMale? male? - - def female?; return self.gender==1; end - alias isFemale? female? - + #============================================================================= + # Party + #============================================================================= def pokemonParty return @party.find_all { |p| p && !p.egg? } end @@ -133,100 +114,103 @@ class PokeBattle_Trainer end def firstParty - return nil if @party.length==0 + return nil if @party.length == 0 return @party[0] end def firstPokemon - p=self.pokemonParty - return nil if p.length==0 + p = self.pokemonParty + return nil if p.length == 0 return p[0] end def firstAblePokemon - p=self.ablePokemonParty - return nil if p.length==0 + p = self.ablePokemonParty + return nil if p.length == 0 return p[0] end def lastParty - return nil if @party.length==0 - return @party[@party.length-1] + return nil if @party.length == 0 + return @party[@party.length - 1] end def lastPokemon - p=self.pokemonParty - return nil if p.length==0 - return p[p.length-1] + p = self.pokemonParty + return nil if p.length == 0 + return p[p.length - 1] end def lastAblePokemon - p=self.ablePokemonParty - return nil if p.length==0 - return p[p.length-1] + p = self.ablePokemonParty + return nil if p.length == 0 + return p[p.length - 1] end - def pokedexSeen(region=-1) # Number of Pokémon seen - ret=0 - if region==-1 + #============================================================================= + # Pokédex + #============================================================================= + def pokedexSeen(region = -1) # Number of Pokémon seen + ret = 0 + if region == -1 for i in 1..PBSpecies.maxValue - ret+=1 if @seen[i] + ret += 1 if @seen[i] end else - regionlist=pbAllRegionalSpecies(region) + regionlist = pbAllRegionalSpecies(region) for i in regionlist - ret+=1 if i > 0 && @seen[i] + ret += 1 if i > 0 && @seen[i] end end return ret end - def pokedexOwned(region=-1) # Number of Pokémon owned - ret=0 - if region==-1 + def pokedexOwned(region = -1) # Number of Pokémon owned + ret = 0 + if region == -1 for i in 0..PBSpecies.maxValue - ret+=1 if @owned[i] + ret += 1 if @owned[i] end else - regionlist=pbAllRegionalSpecies(region) + regionlist = pbAllRegionalSpecies(region) for i in regionlist - ret+=1 if @owned[i] + ret += 1 if @owned[i] end end return ret end def numFormsSeen(species) - species=getID(PBSpecies,species) - return 0 if species<=0 - ret=0 - array=@formseen[species] - for i in 0...[array[0].length,array[1].length].max - ret+=1 if array[0][i] || array[1][i] + species = getID(PBSpecies, species) + return 0 if species <= 0 + ret = 0 + array = @formseen[species] + for i in 0...[array[0].length, array[1].length].max + ret += 1 if array[0][i] || array[1][i] end return ret end def seen?(species) - species=getID(PBSpecies,species) - return species>0 ? @seen[species] : false + species = getID(PBSpecies, species) + return species > 0 ? @seen[species] : false end alias hasSeen? seen? def owned?(species) - species=getID(PBSpecies,species) - return species>0 ? @owned[species] : false + species = getID(PBSpecies, species) + return species > 0 ? @owned[species] : false end alias hasOwned? owned? def setSeen(species) - species=getID(PBSpecies,species) - @seen[species]=true if species>0 + species = getID(PBSpecies, species) + @seen[species] = true if species > 0 end def setOwned(species) - species=getID(PBSpecies,species) - @owned[species]=true if species>0 + species = getID(PBSpecies, species) + @owned[species] = true if species > 0 end def clearPokedex @@ -238,18 +222,18 @@ class PokeBattle_Trainer @seen[i] = false @owned[i] = false @formlastseen[i] = [] - @formseen[i] = [[],[]] + @formseen[i] = [[], []] end end - def initialize(name,trainertype) + #============================================================================= + # Initializing + #============================================================================= + def initialize(name, trainertype) @name = name @language = pbGetLanguage @trainertype = trainertype - @id = rand(256) - @id |= rand(256)<<8 - @id |= rand(256)<<16 - @id |= rand(256)<<24 + @id = rand(2 ** 16) | rand(2 ** 16) << 16 @metaID = 0 @outfit = 0 @pokegear = false diff --git a/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb b/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb index 91c32e10e..51ceb5013 100644 --- a/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb +++ b/Data/Scripts/014_Trainers/002_PTrainer_NPCTrainers.rb @@ -44,33 +44,28 @@ end #=============================================================================== # #=============================================================================== -def pbLoadTrainer(trainerid,trainername,partyid=0) - if trainerid.is_a?(String) || trainerid.is_a?(Symbol) - if !hasConst?(PBTrainers,trainerid) - raise _INTL("Trainer type does not exist ({1}, {2}, ID {3})",trainerid,trainername,partyid) - end - trainerid = getID(PBTrainers,trainerid) +def pbLoadTrainer(tr_type, tr_name, tr_id = 0) + if !GameData::TrainerType.exists?(tr_type) + raise _INTL("Trainer type {1} does not exist.", tr_type) end + tr_type = GameData::TrainerType.get(tr_type).id success = false items = [] party = [] opponent = nil trainers = pbLoadTrainersData for trainer in trainers - thistrainerid = trainer[0] - name = trainer[1] - thispartyid = trainer[4] - next if thistrainerid!=trainerid || name!=trainername || thispartyid!=partyid + next if trainer[0] != tr_type || trainer[1] != tr_name || trainer[4] != tr_id # Found the trainer we want, load it up items = trainer[2].clone - name = pbGetMessageFromHash(MessageTypes::TrainerNames,name) + tr_name = pbGetMessageFromHash(MessageTypes::TrainerNames, tr_name) for i in RIVAL_NAMES - next if !isConst?(trainerid,PBTrainers,i[0]) || !$game_variables[i[1]].is_a?(String) - name = $game_variables[i[1]] + next if i[0] != tr_type || !$game_variables[i[1]].is_a?(String) + tr_name = $game_variables[i[1]] break end loseText = pbGetMessageFromHash(MessageTypes::TrainerLoseText,trainer[5]) - opponent = PokeBattle_Trainer.new(name,thistrainerid) + opponent = PokeBattle_Trainer.new(tr_name, tr_type) opponent.setForeignID($Trainer) # Load up each Pokémon in the trainer's party for poke in trainer[3] @@ -93,7 +88,11 @@ def pbLoadTrainer(trainerid,trainername,partyid=0) g = (poke[TrainerData::GENDER]) ? poke[TrainerData::GENDER] : (opponent.female?) ? 1 : 0 pokemon.setGender(g) (poke[TrainerData::SHINY]) ? pokemon.makeShiny : pokemon.makeNotShiny - n = (poke[TrainerData::NATURE]) ? poke[TrainerData::NATURE] : (pokemon.species+opponent.trainertype)%(PBNatures.maxValue+1) + if poke[TrainerData::NATURE] + n = poke[TrainerData::NATURE] + else + n = (pokemon.species + GameData::TrainerType.get(opponent.trainertype).id_number) % (PBNatures.maxValue + 1) + end pokemon.setNature(n) for i in 0...6 if poke[TrainerData::IV] && poke[TrainerData::IV].length>0 @@ -125,18 +124,16 @@ def pbLoadTrainer(trainerid,trainername,partyid=0) end def pbConvertTrainerData - data = pbLoadTrainerTypesData - trainertypes = [] - for i in 0...data.length - record = data[i] - trainertypes[record[0]] = record[2] if record + tr_type_names = [] + GameData::TrainerType.each do |t| + tr_type_names[t.id_number] = t.real_name end - MessageTypes.setMessages(MessageTypes::TrainerTypes,trainertypes) + MessageTypes.setMessages(MessageTypes::TrainerTypes, tr_type_names) pbSaveTrainerTypes pbSaveTrainerBattles end -def pbNewTrainer(trainerid,trainername,trainerparty,savechanges=true) +def pbNewTrainer(tr_type, tr_name, tr_id, savechanges = true) pokemon = [] for i in 0...6 if i==0 @@ -160,7 +157,7 @@ def pbNewTrainer(trainerid,trainername,trainerparty,savechanges=true) end end end - trainer = [trainerid,trainername,[],pokemon,trainerparty] + trainer = [tr_type,tr_name,[],pokemon,tr_id] if savechanges data = pbLoadTrainersData data.push(trainer) @@ -172,87 +169,67 @@ def pbNewTrainer(trainerid,trainername,trainerparty,savechanges=true) return trainer end -def pbTrainerTypeCheck(symbol) +def pbTrainerTypeCheck(trainer_type) return true if !$DEBUG - ret = false - if hasConst?(PBTrainers,symbol) - trtype = PBTrainers.const_get(symbol) - data = pbGetTrainerTypeData(trtype) - ret = true if data + return true if GameData::TrainerType.exists?(trainer_type) + if pbConfirmMessage(_INTL("Add new trainer type {1}?", trainer_type.to_s)) + pbTrainerTypeEditorNew(trainer_type.to_s) end - if !ret - if pbConfirmMessage(_INTL("Add new trainer type {1}?",symbol)) - pbTrainerTypeEditorNew(symbol.to_s) - end - pbMapInterpreter.command_end if pbMapInterpreter - end - return ret + pbMapInterpreter.command_end if pbMapInterpreter + return false end -def pbGetFreeTrainerParty(trainerid,trainername) - if trainerid.is_a?(String) || trainerid.is_a?(Symbol) - if !hasConst?(PBTrainers,trainerid) - raise _INTL("Trainer type does not exist ({1}, {2}, ID {3})",trainerid,trainername,partyid) - end - trainerid = getID(PBTrainers,trainerid) +def pbGetFreeTrainerParty(tr_type, tr_name) + if !GameData::TrainerType.exists?(tr_type) + raise _INTL("Trainer type {1} does not exist.", tr_type) end + tr_type = GameData::TrainerType.get(tr_type).id trainers = pbLoadTrainersData - usedparties = [] + used_ids = [] for trainer in trainers - thistrainerid = trainer[0] - name = trainer[1] - next if thistrainerid!=trainerid || name!=trainername - usedparties.push(trainer[4]) + next if trainer[0] != tr_type || trainer[1] != tr_name + used_ids.push(trainer[4]) end - ret = -1 for i in 0...256 - next if usedparties.include?(i) - ret = i - break + return i if !used_ids.include?(i) end - return ret + return -1 end -def pbTrainerCheck(trainerid,trainername,maxbattles,startBattleId=0) +# Called from trainer events to ensure the trainer exists +def pbTrainerCheck(tr_type, tr_name, max_battles, tr_id = 0) return true if !$DEBUG - if trainerid.is_a?(String) || trainerid.is_a?(Symbol) - pbTrainerTypeCheck(trainerid) - return false if !hasConst?(PBTrainers,trainerid) - trainerid = PBTrainers.const_get(trainerid) - end - for i in 0...maxbattles - trainer = pbLoadTrainer(trainerid,trainername,i+startBattleId) - next if trainer - traineridstring = "#{trainerid}" - traineridstring = getConstantName(PBTrainers,trainerid) rescue "-" - if pbConfirmMessage(_INTL("Add new battle {1} (of {2}) for ({3}, {4})?", - i+1,maxbattles,traineridstring,trainername)) - pbNewTrainer(trainerid,trainername,i) - end + # Check for existence of trainer type + pbTrainerTypeCheck(tr_type) + return false if !GameData::TrainerType.exists?(tr_type) + tr_type = GameData::TrainerType.get(tr_type).id + # Check for existence of trainer with given ID number + return true if pbLoadTrainer(tr_type, tr_name, tr_id) + # Add new trainer + if pbConfirmMessage(_INTL("Add new trainer variant {1} (of {2}) for {3} {4}?", + tr_id, max_battles, tr_type.to_s, tr_name)) + pbNewTrainer(tr_type, tr_name, tr_id) end return true end -def pbMissingTrainer(trainerid, trainername, trainerparty) - if trainerid.is_a?(String) || trainerid.is_a?(Symbol) - if !hasConst?(PBTrainers,trainerid) - raise _INTL("Trainer type does not exist ({1}, {2}, ID {3})",trainerid,trainername,partyid) - end - trainerid = getID(PBTrainers,trainerid) +def pbMissingTrainer(tr_type, tr_name, tr_id) + if !GameData::TrainerType.exists?(tr_type) + raise _INTL("Trainer type {1} does not exist.", tr_type) end - traineridstring = getConstantName(PBTrainers,trainerid) rescue "#{trainerid}" + tr_type = GameData::TrainerType.get(tr_type).id if !$DEBUG - raise _INTL("Can't find trainer ({1}, {2}, ID {3})",traineridstring,trainername,trainerparty) + raise _INTL("Can't find trainer ({1}, {2}, ID {3})", tr_type.to_s, tr_name, tr_id) end message = "" - if trainerparty!=0 - message = (_INTL("Add new trainer ({1}, {2}, ID {3})?",traineridstring,trainername,trainerparty)) + if tr_id != 0 + message = _INTL("Add new trainer ({1}, {2}, ID {3})?", tr_type.to_s, tr_name, tr_id) else - message = (_INTL("Add new trainer ({1}, {2})?",traineridstring,trainername)) + message = _INTL("Add new trainer ({1}, {2})?", tr_type.to_s, tr_name) end - cmd = pbMessage(message,[_INTL("Yes"),_INTL("No")],2) - if cmd==0 - pbNewTrainer(trainerid,trainername,trainerparty) + cmd = pbMessage(message, [_INTL("Yes"), _INTL("No")], 2) + if cmd == 0 + pbNewTrainer(tr_type, tr_name, tr_id) end return cmd end diff --git a/Data/Scripts/015_Items/004_PItem_Phone.rb b/Data/Scripts/015_Items/004_PItem_Phone.rb index 71f7491fb..f72816052 100644 --- a/Data/Scripts/015_Items/004_PItem_Phone.rb +++ b/Data/Scripts/015_Items/004_PItem_Phone.rb @@ -41,15 +41,13 @@ end def pbPhoneRegisterBattle(message,event,trainertype,trainername,maxbattles) return if !$Trainer.pokegear # Can't register without a Pokégear - if trainertype.is_a?(String) || trainertype.is_a?(Symbol) - return false if !hasConst?(PBTrainers,trainertype) - trainertype = PBTrainers.const_get(trainertype) - end + return false if !GameData::TrainerType.exists?(trainertype) + trainertype = GameData::TrainerType.get(trainertype) contact = pbFindPhoneTrainer(trainertype,trainername) return if contact && contact[0] # Existing contact and is visible message = _INTL("Let me register you.") if !message return if !pbConfirmMessage(message) - displayname = _INTL("{1} {2}",PBTrainers.getName(trainertype), + displayname = _INTL("{1} {2}", GameData::TrainerType.get(trainertype).name, pbGetMessageFromHash(MessageTypes::TrainerNames,trainername)) if contact # Previously registered, just make visible contact[0] = true @@ -80,44 +78,42 @@ def pbRandomPhoneTrainer return temparray[rand(temparray.length)] end -def pbFindPhoneTrainer(trtype,trname) # Ignores whether visible or not +def pbFindPhoneTrainer(tr_type, tr_name) # Ignores whether visible or not return nil if !$PokemonGlobal.phoneNumbers - trtype = getID(PBTrainers,trtype) - return nil if !trtype || trtype<=0 + tr_type = GameData::TrainerType.get(tr_type).id for num in $PokemonGlobal.phoneNumbers - return num if num[1]==trtype && num[2]==trname # If a match + return num if num[1] == tr_type && num[2] == tr_name # If a match end return nil end -def pbHasPhoneTrainer?(trtype,trname) - return pbFindPhoneTrainer(trtype,trname)!=nil +def pbHasPhoneTrainer?(tr_type, tr_name) + return pbFindPhoneTrainer(tr_type, tr_name) != nil end -def pbPhoneBattleCount(trtype,trname) - trainer = pbFindPhoneTrainer(trtype,trname) - return trainer[5] if trainer - return 0 +def pbPhoneBattleCount(tr_type, tr_name) + trainer = pbFindPhoneTrainer(tr_type, tr_name) + return (trainer) ? trainer[5] : 0 end -def pbPhoneReadyToBattle?(trtype,trname) - trainer = pbFindPhoneTrainer(trtype,trname) +def pbPhoneReadyToBattle?(tr_type, tr_name) + trainer = pbFindPhoneTrainer(tr_type, tr_name) return (trainer && trainer[4]>=2) end #=============================================================================== # Contact rematch data modifications #=============================================================================== -def pbPhoneIncrement(trtype,trname,maxbattles) - trainer = pbFindPhoneTrainer(trtype,trname) +def pbPhoneIncrement(tr_type, tr_name, maxbattles) + trainer = pbFindPhoneTrainer(tr_type, tr_name) return if !trainer trainer[5] += 1 if trainer[5]=100 - break + if GameData::TrainerType.exists?(:YOUNGSTER) && rand(30) == 0 + trainerid = :YOUNGSTER + else + tr_type_values = GameData::TrainerType::DATA.values + loop do + tr_type_data = tr_type_values[rand(tr_type_values.length)] + next if tr_type_data.base_money >= 100 + trainerid = tr_type_data.id + end end - gender=(!trainertypes[trainerid] || - !trainertypes[trainerid][7]) ? 2 : trainertypes[trainerid][7] + gender = GameData::TrainerType.get(trainerid).gender randomName=getRandomNameEx(gender,nil,0,12) tr=[trainerid,randomName,_INTL("Here I come!"), _INTL("Yes, I won!"),_INTL("Man, I lost!"),[]] bttrainers.push(tr) end - bttrainers.sort! { |a,b| - money1=(!trainertypes[a[0]] || - !trainertypes[a[0]][3]) ? 30 : trainertypes[a[0]][3] - money2=(!trainertypes[b[0]] || - !trainertypes[b[0]][3]) ? 30 : trainertypes[b[0]][3] - money1==money2 ? a[0]<=>b[0] : money1<=>money2 + bttrainers.sort! { |a, b| + money1 = GameData::TrainerType.get(a[0]).base_money + money2 = GameData::TrainerType.get(b[0]).base_money + (money1 == money2) ? a[0].to_s <=> b[0].to_s : money1 <=> money2 } end yield(nil) if block_given? diff --git a/Data/Scripts/020_System and utilities/003_PSystem_FileUtilities.rb b/Data/Scripts/020_System and utilities/003_PSystem_FileUtilities.rb index 4a2cdac88..e3a967171 100644 --- a/Data/Scripts/020_System and utilities/003_PSystem_FileUtilities.rb +++ b/Data/Scripts/020_System and utilities/003_PSystem_FileUtilities.rb @@ -318,18 +318,20 @@ end #=============================================================================== def pbTrainerCharFile(type) # Used by the phone return nil if !type - bitmapFileName = sprintf("Graphics/Characters/trchar%s",getConstantName(PBTrainers,type)) rescue nil + tr_type_data = GameData::TrainerType.get(type) + bitmapFileName = sprintf("Graphics/Characters/trchar%s", tr_type_data.id.to_s) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Characters/trchar%03d",type) + bitmapFileName = sprintf("Graphics/Characters/trchar%03d", tr_type_data.id_number) end return bitmapFileName end def pbTrainerCharNameFile(type) # Used by Battle Frontier and compiler return nil if !type - bitmapFileName = sprintf("trchar%s",getConstantName(PBTrainers,type)) rescue nil - if !pbResolveBitmap(sprintf("Graphics/Characters/"+bitmapFileName)) - bitmapFileName = sprintf("trchar%03d",type) + tr_type_data = GameData::TrainerType.get(type) + bitmapFileName = sprintf("trchar%s", tr_type_data.id.to_s) rescue nil + if !pbResolveBitmap(sprintf("Graphics/Characters/" + bitmapFileName)) + bitmapFileName = sprintf("trchar%03d", tr_type_data.id_number) end return bitmapFileName end @@ -341,48 +343,44 @@ end #=============================================================================== def pbTrainerSpriteFile(type) return nil if !type - bitmapFileName = sprintf("Graphics/Trainers/trainer%s", - getConstantName(PBTrainers,type)) rescue nil + tr_type_data = GameData::TrainerType.get(type) + bitmapFileName = sprintf("Graphics/Trainers/trainer%s", tr_type_data.id.to_s) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Trainers/trainer%03d",type) + bitmapFileName = sprintf("Graphics/Trainers/trainer%03d", tr_type_data.id_number) end return bitmapFileName end def pbTrainerSpriteBackFile(type) return nil if !type - bitmapFileName = sprintf("Graphics/Trainers/trback%s", - getConstantName(PBTrainers,type)) rescue nil + tr_type_data = GameData::TrainerType.get(type) + bitmapFileName = sprintf("Graphics/Trainers/trback%s", tr_type_data.id.to_s) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Trainers/trback%03d",type) + bitmapFileName = sprintf("Graphics/Trainers/trback%03d", tr_type_data.id_number) end return bitmapFileName end def pbPlayerSpriteFile(type) return nil if !type + tr_type_data = GameData::TrainerType.get(type) outfit = ($Trainer) ? $Trainer.outfit : 0 - bitmapFileName = sprintf("Graphics/Trainers/trainer%s_%d", - getConstantName(PBTrainers,type),outfit) rescue nil + bitmapFileName = sprintf("Graphics/Trainers/trainer%s_%d", tr_type_data.id.to_s, outfit) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Trainers/trainer%03d_%d",type,outfit) - if !pbResolveBitmap(bitmapFileName) - bitmapFileName = pbTrainerSpriteFile(type) - end + bitmapFileName = sprintf("Graphics/Trainers/trainer%03d_%d", tr_type_data.id_number, outfit) + bitmapFileName = pbTrainerSpriteFile(tr_type_data.id) if !pbResolveBitmap(bitmapFileName) end return bitmapFileName end def pbPlayerSpriteBackFile(type) return nil if !type + tr_type_data = GameData::TrainerType.get(type) outfit = ($Trainer) ? $Trainer.outfit : 0 - bitmapFileName = sprintf("Graphics/Trainers/trback%s_%d", - getConstantName(PBTrainers,type),outfit) rescue nil + bitmapFileName = sprintf("Graphics/Trainers/trback%s_%d", tr_type_data.id.to_s, outfit) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Trainers/trback%03d_%d",type,outfit) - if !pbResolveBitmap(bitmapFileName) - bitmapFileName = pbTrainerSpriteBackFile(type) - end + bitmapFileName = sprintf("Graphics/Trainers/trback%03d_%d", tr_type_data.id_number, outfit) + bitmapFileName = pbTrainerSpriteBackFile(tr_type_data.id) if !pbResolveBitmap(bitmapFileName) end return bitmapFileName end @@ -394,23 +392,22 @@ end #=============================================================================== def pbTrainerHeadFile(type) return nil if !type - bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%s",getConstantName(PBTrainers,type)) rescue nil + tr_type_data = GameData::TrainerType.get(type) + bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%s", tr_type_data.id.to_s) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%03d",type) + bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%03d", tr_type_data.id_number) end return bitmapFileName end def pbPlayerHeadFile(type) return nil if !type + tr_type_data = GameData::TrainerType.get(type) outfit = ($Trainer) ? $Trainer.outfit : 0 - bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%s_%d", - getConstantName(PBTrainers,type),outfit) rescue nil + bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%s_%d", tr_type_data.id.to_s, outfit) rescue nil if !pbResolveBitmap(bitmapFileName) - bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%03d_%d",type,outfit) - if !pbResolveBitmap(bitmapFileName) - bitmapFileName = pbTrainerHeadFile(type) - end + bitmapFileName = sprintf("Graphics/Pictures/mapPlayer%03d_%d", tr_type_data.id_number, outfit) + bitmapFileName = pbTrainerHeadFile(tr_type_data.id) if !pbResolveBitmap(bitmapFileName) end return bitmapFileName end @@ -590,12 +587,11 @@ end #=============================================================================== # Load/play various trainer battle music #=============================================================================== -def pbPlayTrainerIntroME(trainerType) - data = pbGetTrainerTypeData(trainerType) - if data && data[6] && data[6]!="" - bgm = pbStringToAudioFile(data[6]) - pbMEPlay(bgm) - end +def pbPlayTrainerIntroME(trainer_type) + trainer_type_data = GameData::TrainerType.get(trainer_type) + return if !trainer_type_data.intro_ME || trainer_type_data.intro_ME == "" + bgm = pbStringToAudioFile(trainer_type_data.intro_ME) + pbMEPlay(bgm) end def pbGetTrainerBattleBGM(trainer) # can be a PokeBattle_Trainer or an array of them @@ -606,8 +602,8 @@ def pbGetTrainerBattleBGM(trainer) # can be a PokeBattle_Trainer or an array o music = nil trainerarray = (trainer.is_a?(Array)) ? trainer : [trainer] trainerarray.each do |t| - data = pbGetTrainerTypeData(t.trainertype) - music = data[4] if data && data[4] + trainer_type_data = GameData::TrainerType.get(t.trainertype) + music = trainer_type_data.battle_BGM if trainer_type_data.battle_BGM end ret = pbStringToAudioFile(music) if music && music!="" if !ret @@ -632,8 +628,8 @@ def pbGetTrainerBattleBGMFromType(trainertype) if $PokemonGlobal.nextBattleBGM return $PokemonGlobal.nextBattleBGM.clone end - data = pbGetTrainerTypeData(trainertype) - ret = pbStringToAudioFile(data[4]) if data && data[4] + trainer_type_data = GameData::TrainerType.get(trainertype) + ret = trainer_type_data.battle_BGM if trainer_type_data.battle_BGM if !ret # Check map metadata music = GameData::MapMetadata.get($game_map.map_id).trainer_battle_BGM @@ -655,8 +651,8 @@ def pbGetTrainerVictoryME(trainer) # can be a PokeBattle_Trainer or an array o music = nil trainerarray = (trainer.is_a?(Array)) ? trainer : [trainer] trainerarray.each do |t| - data = pbGetTrainerTypeData(t.trainertype) - music = data[5] if data && data[5] + trainer_type_data = GameData::TrainerType.get(t.trainertype) + music = trainer_type_data.victory_ME if trainer_type_data.victory_ME end ret = nil if music && music!="" diff --git a/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb b/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb index b6aaec359..0d7cc2a66 100644 --- a/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb +++ b/Data/Scripts/020_System and utilities/005_PSystem_Utilities.rb @@ -685,17 +685,12 @@ def pbGetPlayerGraphic end def pbGetPlayerTrainerType - id = $PokemonGlobal.playerID - return 0 if id<0 || id>=8 - meta = GameData::Metadata.get_player(id) - return 0 if !meta - return meta[0] + meta = GameData::Metadata.get_player($PokemonGlobal.playerID) + return (meta) ? meta[0] : nil end -def pbGetTrainerTypeGender(trainertype) - data = pbGetTrainerTypeData(trainertype) - return data[7] if data && data[7] - return 2 # Gender unknown +def pbGetTrainerTypeGender(trainer_type) + return GameData::TrainerType.get(trainer_type).gender end def pbTrainerName(name=nil,outfit=0) diff --git a/Data/Scripts/021_Debug/004_Editor_Screens.rb b/Data/Scripts/021_Debug/004_Editor_Screens.rb index 02219a00f..8d3a0006f 100644 --- a/Data/Scripts/021_Debug/004_Editor_Screens.rb +++ b/Data/Scripts/021_Debug/004_Editor_Screens.rb @@ -218,135 +218,134 @@ end #=============================================================================== # Trainer type editor #=============================================================================== -def pbTrainerTypeEditorNew(trconst) - data = pbLoadTrainerTypesData - # Get the first unused ID after all existing t-types for the new t-type to use. - maxid = -1 - for rec in data - next if !rec - maxid = rec[0] if rec[0]>maxid - end - trainertype = maxid+1 - trname = pbMessageFreeText(_INTL("Please enter the trainer type's name."), - (trconst) ? trconst.gsub(/_+/," ") : "",false,30) - return -1 if trname=="" && !trconst - # Create an internal name based on the trainer type's name if there is none. - trconst = trname if !trconst - trconst = trconst.gsub(/é/,"e") - trconst = trconst.gsub(/[^A-Za-z0-9_]/,"") - trconst = trconst.upcase - if trconst.length==0 - trconst = sprintf("T_%03d",trainertype) - elsif !trconst[0,1][/[A-Z]/] - trconst = "T_"+trconst - end - # Create a default name if there is none. - trname = trconst if trname=="" - cname = trconst - if hasConst?(PBTrainers,cname) - suffix = 1 - 100.times do - tname = sprintf("%s_%d",cname,suffix) - if !hasConst?(PBTrainers,tname) - cname = tname - break - end - suffix += 1 - end - end - if hasConst?(PBTrainers,cname) - pbMessage(_INTL("Failed to create the trainer type. Choose a different name.")) - return -1 - end - record = [] - record[0] = trainertype - record[1] = cname - record[2] = trname - record[7] = pbMessage(_INTL("Is the Trainer male, female, or mixed gender?"),[ - _INTL("Male"),_INTL("Female"),_INTL("Mixed")],0) - params = ChooseNumberParams.new - params.setRange(0,255) - params.setDefaultValue(30) - record[3] = pbMessageChooseNumber(_INTL("Set the money per level won for defeating the Trainer."),params) - record[8] = record[3] - record[9] = "" - PBTrainers.const_set(cname,record[0]) - data[record[0]] = record - save_data(data,"Data/trainer_types.dat") - $PokemonTemp.trainerTypesData = nil - pbConvertTrainerData - pbMessage(_INTL("The Trainer type was created (ID: {1}).",record[0])) - pbMessage(_ISPRINTF("Put the Trainer's graphic (trainer{1:03d}.png or trainer{2:s}.png) in Graphics/Characters, or it will be blank.", - record[0],getConstantName(PBTrainers,record[0]))) - return record[0] -end - -def pbTrainerTypeEditorSave(trainertype,ttdata) - record = [] - record[0] = trainertype - for i in 0..ttdata.length - record.push(ttdata[i]) - end - setConstantName(PBTrainers,trainertype,ttdata[0]) - data = pbLoadTrainerTypesData - data[record[0]] = record - save_data(data,"Data/trainer_types.dat") - $PokemonTemp.trainerTypesData = nil - pbConvertTrainerData -end - def pbTrainerTypeEditor selection = 0 - trainerTypes = [ - [_INTL("Internal Name"), ReadOnlyProperty, _INTL("Internal name that appears in constructs like PBTrainers::XXX.")], + trainer_types = [ + [_INTL("Internal Name"), ReadOnlyProperty, _INTL("Internal name that is used as a symbol like :XXX.")], [_INTL("Trainer Name"), StringProperty, _INTL("Name of the trainer type as displayed by the game.")], - [_INTL("Money Per Level"), LimitProperty.new(9999), _INTL("Player earns this amount times the highest level among the trainer's Pokémon.")], + [_INTL("Base Money"), LimitProperty.new(9999), _INTL("Player earns this much money times the highest level among the trainer's Pokémon.")], [_INTL("Battle BGM"), BGMProperty, _INTL("BGM played in battles against trainers of this type.")], [_INTL("Battle End ME"), MEProperty, _INTL("ME played when player wins battles against trainers of this type.")], [_INTL("Battle Intro ME"), MEProperty, _INTL("ME played before battles against trainers of this type.")], [_INTL("Gender"), EnumProperty.new([ - _INTL("Male"),_INTL("Female"),_INTL("Mixed gender")]), + _INTL("Male"), _INTL("Female"), _INTL("Undefined")]), _INTL("Gender of this Trainer type.")], - [_INTL("Skill"), LimitProperty.new(9999), _INTL("Skill level of this Trainer type.")], - [_INTL("Skill Codes"), StringProperty, _INTL("Letters/phrases representing AI modifications of trainers of this type.")], + [_INTL("Skill Level"), LimitProperty.new(9999), _INTL("Skill level of this Trainer type.")], + [_INTL("Skill Code"), StringProperty, _INTL("Letters/phrases representing AI modifications of trainers of this type.")], ] - pbListScreenBlock(_INTL("Trainer Types"),TrainerTypeLister.new(selection,true)) { |button,trtype| - if trtype + pbListScreenBlock(_INTL("Trainer Types"), TrainerTypeLister.new(selection, true)) { |button, tr_type| + if tr_type if button==Input::A - if trtype[0]>=0 + if tr_type.is_a?(Symbol) if pbConfirmMessageSerious("Delete this trainer type?") - data = pbLoadTrainerTypesData - removeConstantValue(PBTrainers,trtype[0]) - data[trtype[0]] = nil - save_data(data,"Data/trainer_types.dat") - $PokemonTemp.trainerTypesData = nil + id_number = GameData::TrainerType.get(tr_type).id_number + GameData::TrainerType::DATA.delete(tr_type) + GameData::TrainerType::DATA.delete(id_number) + GameData::TrainerType.save pbConvertTrainerData pbMessage(_INTL("The Trainer type was deleted.")) end end - elsif button==Input::C - selection = trtype[0] - if selection<0 - newid = pbTrainerTypeEditorNew(nil) - if newid>=0 - selection = newid - end - else - data = [] - for i in 1..trtype.length - data.push(trtype[i]) - end - # trtype[2] contains trainer's name to display as title - save = pbPropertyList(trtype[2],data,trainerTypes,true) - if save - pbTrainerTypeEditorSave(selection,data) + elsif button == Input::C + if tr_type.is_a?(Symbol) + t_data = GameData::TrainerType.get(tr_type) + data = [ + t_data.id.to_s, + t_data.real_name, + t_data.base_money, + t_data.battle_BGM, + t_data.victory_ME, + t_data.intro_ME, + t_data.gender, + t_data.skill_level, + t_data.skill_code + ] + if pbPropertyList(t_data.id.to_s, data, trainer_types, true) + # Construct trainer type hash + type_hash = { + :id_number => t_data.id_number, + :id => t_data.id, + :name => line[1], + :base_money => line[2], + :battle_BGM => line[3], + :victory_ME => line[4], + :intro_ME => line[5], + :gender => line[6], + :skill_level => line[7], + :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.save + pbConvertTrainerData end + else # Add a new trainer type + pbTrainerTypeEditorNew(nil) end end end } end +def pbTrainerTypeEditorNew(default_name) + # Get an unused ID number for the new item + max_id = 0 + GameData::TrainerType.each { |t| max_id = t.id_number if max_id < t.id_number } + id_number = max_id + 1 + # Choose a name + name = pbMessageFreeText(_INTL("Please enter the trainer type's name."), + (default_name) ? default_name.gsub(/_+/, " ") : "", false, 30) + if name == "" + return nil if !default_name + name = default_name + end + # Generate an ID based on the item name + id = name.gsub(/é/, "e") + id = id.gsub(/[^A-Za-z0-9_]/, "") + id = id.upcase + if id.length == 0 + id = sprintf("T_%03d", id_number) + elsif !id[0, 1][/[A-Z]/] + id = "T_" + id + end + if GameData::TrainerType.exists?(id) + for i in 1..100 + trial_id = sprintf("%s_%d", id, i) + next if GameData::TrainerType.exists?(trial_id) + id = trial_id + break + end + end + if GameData::TrainerType.exists?(id) + pbMessage(_INTL("Failed to create the trainer type. Choose a different name.")) + return nil + end + # Choose a gender + gender = pbMessage(_INTL("Is the Trainer male, female or undefined?"), [ + _INTL("Male"), _INTL("Female"), _INTL("Undefined")], 0) + # Choose a base money value + params = ChooseNumberParams.new + params.setRange(0, 255) + params.setDefaultValue(30) + base_money = pbMessageChooseNumber(_INTL("Set the money per level won for defeating the Trainer."), params) + # Construct trainer type hash + tr_type_hash = { + :id_number => id_number, + :id => id.to_sym, + :name => name, + :base_money => base_money, + :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.save + pbConvertTrainerData + pbMessage(_INTL("The trainer type {1} was created (ID: {2}).", name, id.to_s)) + pbMessage(_ISPRINTF("Put the Trainer's graphic (trainer{1:s}.png or trainer{2:03d}.png) in Graphics/Trainers, or it will be blank.", + id, id_number)) + return id.to_sym +end + #=============================================================================== @@ -391,13 +390,11 @@ end def pbTrainerBattleEditor selection = 0 - trainertypes = pbLoadTrainerTypesData - trainers = pbLoadTrainersData + trainers = pbLoadTrainersData modified = false for trainer in trainers - trtype = trainer[0] - next if trainertypes && trainertypes[trtype] - trainer[0] = 0 + next if GameData::TrainerType.exists?(trainer[0]) + trainer[0] = nil modified = true end pbListScreenBlock(_INTL("Trainer Battles"),TrainerBattleLister.new(selection,true)) { |button,trtype| @@ -418,22 +415,19 @@ def pbTrainerBattleEditor selection = index if selection<0 # New trainer - trainertype = -1 - ret = pbMessage(_INTL("First, define the type of trainer."),[ + trainertype = nil + ret = pbMessage(_INTL("First, define the new trainer's type."),[ _INTL("Use existing type"), - _INTL("Use new type"), - _INTL("Cancel")],3) + _INTL("Create new type"), + _INTL("Cancel")], 3) if ret==0 trainertype = pbListScreen(_INTL("TRAINER TYPE"),TrainerTypeLister.new(0,false)) - next if !trainertype - trainertype = trainertype[0] - next if trainertype<0 elsif ret==1 trainertype = pbTrainerTypeEditorNew(nil) - next if trainertype<0 else next end + next if !trainertype trainername = pbMessageFreeText(_INTL("Now enter the trainer's name."),"",false,30) next if trainername=="" trainerparty = pbGetFreeTrainerParty(trainertype,trainername) @@ -670,7 +664,7 @@ def pbItemEditor ] pbListScreenBlock(_INTL("Items"), ItemLister.new(selection, true)) { |button, item| if item - if button==Input::A + if button == Input::A if item.is_a?(Symbol) if pbConfirmMessageSerious("Delete this item?") id_number = GameData::Item.get(item).id_number @@ -681,7 +675,7 @@ def pbItemEditor pbMessage(_INTL("The item was deleted.")) end end - elsif button==Input::C + elsif button == Input::C if item.is_a?(Symbol) itm = GameData::Item.get(item) data = [ @@ -740,6 +734,11 @@ def pbItemEditorNew(default_name) id = name.gsub(/é/, "e") id = id.gsub(/[^A-Za-z0-9_]/, "") id = id.upcase + if id.length == 0 + id = sprintf("ITEM_%03d", id_number) + elsif !id[0, 1][/[A-Z]/] + id = "ITEM_" + id + end if GameData::Item.exists?(id) for i in 1..100 trial_id = sprintf("%s_%d", id, i) @@ -776,7 +775,7 @@ def pbItemEditorNew(default_name) pbSaveItems pbMessage(_INTL("The item {1} was created (ID: {2}).", name, id.to_s)) pbMessage(_ISPRINTF("Put the item's graphic (item{1:s}.png or item{2:03d}.png) in Graphics/Icons, or it will be blank.", - id.to_s, id_number)) + id, id_number)) end diff --git a/Data/Scripts/021_Debug/005_Editor_SaveData.rb b/Data/Scripts/021_Debug/005_Editor_SaveData.rb index bb0672638..be12f99e8 100644 --- a/Data/Scripts/021_Debug/005_Editor_SaveData.rb +++ b/Data/Scripts/021_Debug/005_Editor_SaveData.rb @@ -7,8 +7,7 @@ def pbSaveTypes f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") for i in 0..(PBTypes.maxValue rescue 25) name = PBTypes.getName(i) rescue nil next if !name || name=="" @@ -52,8 +51,7 @@ def pbSaveAbilities f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") GameData::Ability.each do |a| f.write(sprintf("%d,%s,%s,%s\r\n", @@ -76,8 +74,7 @@ def pbSaveMoveData f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") current_type = -1 GameData::Move.each do |m| if current_type != m.type @@ -144,8 +141,7 @@ def pbSerializeConnectionData(conndata,mapinfos) f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") for conn in conndata if mapinfos @@ -184,8 +180,7 @@ def pbSaveMetadata f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") # Write global metadata f.write("\#-------------------------------\r\n") f.write("[000]\r\n") @@ -230,8 +225,7 @@ def pbSaveItems f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") current_pocket = 0 GameData::Item.each do |i| if current_pocket != i.pocket @@ -268,8 +262,7 @@ def pbSaveBerryPlants f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") GameData::BerryPlant.each do |bp| f.write(sprintf("%s = %d,%d,%d,%d\r\n", @@ -295,8 +288,7 @@ def pbSaveTrainerLists f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") for tr in trainerlists f.write("\#-------------------------------\r\n") f.write(((tr[5]) ? "[DefaultTrainerList]" : "[TrainerList]")+"\r\n") @@ -321,8 +313,7 @@ def pbSaveMachines f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") keys = machines.keys.sort { |a, b| GameData::Move.get(a).id_number <=> GameData::Move.get(b).id_number } for i in 0...keys.length Graphics.update if i%50==0 @@ -356,8 +347,7 @@ def pbSaveEncounterData f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") sortedkeys = encdata.keys.sort for i in sortedkeys next if !encdata[i] @@ -395,29 +385,25 @@ end # Save trainer type data to PBS file #=============================================================================== def pbSaveTrainerTypes - data = pbLoadTrainerTypesData - return if !data - File.open("PBS/trainertypes.txt","wb") { |f| + File.open("PBS/trainertypes.txt", "wb") { |f| f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") - for i in 0...data.length - record = data[i] - next if !record - dataline = sprintf("%d,%s,%s,%d,%s,%s,%s,%s,%s,%s", - i,record[1],record[2], - record[3], - record[4] ? record[4] : "", - record[5] ? record[5] : "", - record[6] ? record[6] : "", - record[7] ? ["Male","Female","Mixed"][record[7]] : "Mixed", - (record[8]!=record[3]) ? record[8] : "", - record[9] ? record[9] : "") - f.write(dataline) - f.write("\r\n") + GameData::TrainerType.each do |t| + f.write(sprintf("%d,%s,%s,%d,%s,%s,%s,%s,%s,%s\r\n", + t.id_number, + csvQuote(t.id.to_s), + csvQuote(t.real_name), + t.base_money, + csvQuote(t.battle_BGM), + csvQuote(t.victory_ME), + csvQuote(t.intro_ME), + ["Male", "Female", "Mixed"][t.gender], + (t.skill_level == t.base_money) ? "" : t.skill_level.to_s, + csvQuote(t.skill_code) + )) end } end @@ -434,10 +420,9 @@ def pbSaveTrainerBattles f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") for trainer in data - trtypename = getConstantName(PBTrainers,trainer[0]) rescue pbGetTrainerConst(trainer[0]) rescue nil + trtypename = trainer[0].to_s next if !trtypename f.write("\#-------------------------------\r\n") # Section @@ -540,8 +525,7 @@ def pbSaveTownMap f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") for i in 0...mapdata.length map = mapdata[i] next if !map @@ -572,8 +556,7 @@ def pbSavePhoneData f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") f.write("[]\r\n") f.write(data.generics.join("\r\n")+"\r\n") @@ -616,8 +599,7 @@ def pbSavePokemonData pokedata.write(0xEF.chr) pokedata.write(0xBB.chr) pokedata.write(0xBF.chr) - pokedata.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - pokedata.write("\r\n") + pokedata.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") for i in 1..(PBSpecies.maxValue rescue PBSpecies.getCount-1 rescue messages.getCount(MessageTypes::Species)-1) cname = getConstantName(PBSpecies,i) rescue next speciesname = messages.get(MessageTypes::Species,i) @@ -878,8 +860,7 @@ def pbSavePokemonFormsData pokedata.write(0xEF.chr) pokedata.write(0xBB.chr) pokedata.write(0xBF.chr) - pokedata.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - pokedata.write("\r\n") + pokedata.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") m1 = (PBSpecies.maxValue+1 rescue PBSpecies.getCount rescue messages.getCount(MessageTypes::Species)) m2 = (PBSpecies.maxValueF rescue m1) for i in m1..m2 @@ -1335,8 +1316,7 @@ def pbSaveShadowMoves f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") for i in 0...shadow_movesets.length moveset = shadow_movesets[i] @@ -1372,8 +1352,7 @@ def pbSaveBTTrainers(bttrainers,filename) f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") for i in 0...bttrainers.length next if !bttrainers[i] f.write("\#-------------------------------\r\n") @@ -1384,7 +1363,7 @@ def pbSaveBTTrainers(bttrainers,filename) next if record==nil f.write(sprintf("%s = ",key)) if key=="Type" - f.write((getConstantName(PBTrainers,record) rescue pbGetTrainerConst(record))) + f.write(record.to_s) elsif key=="PokemonNos" f.write(record.join(",")) # pbWriteCsvRecord somehow won't work here else @@ -1411,8 +1390,7 @@ def pbSaveBattlePokemon(btpokemon,filename) f.write(0xEF.chr) f.write(0xBB.chr) f.write(0xBF.chr) - f.write("\# "+_INTL("See the documentation on the wiki to learn how to edit this file.")) - f.write("\r\n") + f.write("\# " + _INTL("See the documentation on the wiki to learn how to edit this file.") + "\r\n") f.write("\#-------------------------------\r\n") for i in 0...btpokemon.length Graphics.update if i%500==0 diff --git a/Data/Scripts/021_Debug/006_Editor_DataFormatting.rb b/Data/Scripts/021_Debug/006_Editor_DataFormatting.rb index 56df87b7d..c5c38e68a 100644 --- a/Data/Scripts/021_Debug/006_Editor_DataFormatting.rb +++ b/Data/Scripts/021_Debug/006_Editor_DataFormatting.rb @@ -23,6 +23,8 @@ def pbWriteCsvRecord(record,file,schema) # do nothing elsif rec[i].is_a?(String) file.write(csvQuote(rec[i])) + elsif rec[i].is_a?(Symbol) + file.write(csvQuote(rec[i].to_s)) elsif rec[i]==true file.write("true") elsif rec[i]==false @@ -35,11 +37,7 @@ def pbWriteCsvRecord(record,file,schema) file.write(enumer[rec[i]]) elsif enumer.is_a?(Symbol) || enumer.is_a?(String) mod = Object.const_get(enumer.to_sym) - if enumer.to_s=="PBTrainers" && !mod.respond_to?("getCount") - file.write((getConstantName(mod,rec[i]) rescue pbGetTrainerConst(rec[i]))) - else - file.write(getConstantName(mod,rec[i])) - end + file.write(getConstantName(mod,rec[i])) elsif enumer.is_a?(Module) file.write(getConstantName(enumer,rec[i])) elsif enumer.is_a?(Hash) @@ -60,11 +58,7 @@ def pbWriteCsvRecord(record,file,schema) end elsif enumer.is_a?(Symbol) || enumer.is_a?(String) mod = Object.const_get(enumer.to_sym) - if enumer.to_s=="PBTrainers" && !mod.respond_to?("getCount") - file.write((getConstantNameOrValue(mod,rec[i]) rescue pbGetTrainerConst(rec[i]))) - else - file.write(getConstantNameOrValue(mod,rec[i])) - end + file.write(getConstantNameOrValue(mod,rec[i])) elsif enumer.is_a?(Module) file.write(getConstantNameOrValue(enumer,rec[i])) elsif enumer.is_a?(Hash) diff --git a/Data/Scripts/021_Debug/007_Editor_DataTypes.rb b/Data/Scripts/021_Debug/007_Editor_DataTypes.rb index 62301e35f..69a1acc9b 100644 --- a/Data/Scripts/021_Debug/007_Editor_DataTypes.rb +++ b/Data/Scripts/021_Debug/007_Editor_DataTypes.rb @@ -249,13 +249,13 @@ end module TrainerTypeProperty - def self.set(settingname,oldsetting) - chosenmap = pbListScreen(settingname,TrainerTypeLister.new(oldsetting,false)) - return (chosenmap) ? chosenmap[0] : oldsetting + def self.set(settingname, oldsetting) + chosenmap = pbListScreen(settingname, TrainerTypeLister.new(0, false)) + return chosenmap || oldsetting end def self.format(value) - return (!value) ? value.inspect : PBTrainers.getName(value) + return (value && GameData::TrainerType.exists?(value)) ? GameData::TrainerType.get(value).real_name : "-" end end diff --git a/Data/Scripts/021_Debug/008_Editor_Listers.rb b/Data/Scripts/021_Debug/008_Editor_Listers.rb index aa62071ca..9343ab949 100644 --- a/Data/Scripts/021_Debug/008_Editor_Listers.rb +++ b/Data/Scripts/021_Debug/008_Editor_Listers.rb @@ -376,9 +376,8 @@ end class ItemLister - def initialize(selection=0,includeNew=false) - @sprite = IconSprite.new(0,0) - @sprite = ItemIconSprite.new(Graphics.width*3/4,Graphics.height/2,nil) + def initialize(selection = 0, includeNew = false) + @sprite = ItemIconSprite.new(Graphics.width * 3 / 4, Graphics.height / 2, nil) @sprite.z = 2 @selection = selection @commands = [] @@ -418,13 +417,13 @@ class ItemLister @ids.push(i[1]) end @index = @selection - @index = @commands.length-1 if @index>=@commands.length - @index = 0 if @index<0 + @index = @commands.length - 1 if @index >= @commands.length + @index = 0 if @index < 0 return @commands end def value(index) - return nil if index<0 + return nil if index < 0 return @ids[index] end @@ -436,12 +435,9 @@ end class TrainerTypeLister - def initialize(selection,includeNew) - @sprite = IconSprite.new(0,0) - @sprite.bitmap = nil - @sprite.x = Graphics.width * 3 / 4 - @sprite.y = (Graphics.height - 64) / 2 + 64 - @sprite.z = 2 + def initialize(selection = 0, includeNew = false) + @sprite = IconSprite.new(Graphics.width * 3 / 4, (Graphics.height - 64) / 2 + 64) + @sprite.z = 2 @selection = selection @commands = [] @ids = [] @@ -466,47 +462,41 @@ class TrainerTypeLister def commands @commands.clear @ids.clear - @trainers = pbLoadTrainerTypesData + cmds = [] + GameData::TrainerType.each do |tr_type| + cmds.push([tr_type.id_number, tr_type.id, tr_type.real_name]) + end + cmds.sort! { |a, b| a[2].downcase <=> b[2].downcase } if @includeNew @commands.push(_INTL("[NEW TRAINER TYPE]")) - @ids.push(-1) + @ids.push(true) end - @trainers.length.times do |i| - next if !@trainers[i] - @commands.push(sprintf("%3d: %s",i,@trainers[i][2])) - @ids.push(@trainers[i][0]) - end - @commands.length.times do |i| - @index = i if @ids[i]==@selection + for t in cmds + @commands.push(sprintf("%03d: %s", t[0], t[2])) + @ids.push(t[1]) end + @index = @selection + @index = @commands.length - 1 if @index >= @commands.length + @index = 0 if @index < 0 return @commands end def value(index) - return nil if index<0 - return [-1] if @ids[index]==-1 - return @trainers[@ids[index]] + return nil if index < 0 + return @ids[index] end def refresh(index) @sprite.bitmap.dispose if @sprite.bitmap - return if index<0 + return if index < 0 begin - @sprite.setBitmap(pbTrainerSpriteFile(@ids[index]),0) + @sprite.setBitmap(pbTrainerSpriteFile(@ids[index]), 0) rescue @sprite.setBitmap(nil) end - sprite_width = @sprite.bitmap.width - sprite_height = @sprite.bitmap.height - @sprite.ox = sprite_width/2 - @sprite.oy = sprite_height/2 - scale_x = (Graphics.width/2).to_f/sprite_width - scale_y = (Graphics.height-64).to_f/sprite_height - if scale_x<1.0 || scale_y<1.0 - min_scale = [scale_x, scale_y].min - @sprite.zoom_x = @sprite.zoom_y = min_scale - else - @sprite.zoom_x = @sprite.zoom_y = 1.0 + if @sprite.bitmap + @sprite.ox = @sprite.bitmap.width / 2 + @sprite.oy = @sprite.bitmap.height / 2 end end end @@ -515,11 +505,8 @@ end class TrainerBattleLister def initialize(selection,includeNew) - @sprite = IconSprite.new - @sprite.bitmap = nil - @sprite.x = Graphics.width*3/4 - @sprite.y = (Graphics.height/2)+32 - @sprite.z = 2 + @sprite = IconSprite.new(Graphics.width * 3 / 4, (Graphics.height / 2) + 32) + @sprite.z = 2 @pkmnList = Window_UnformattedTextPokemon.new() @pkmnList.x = Graphics.width/2 @pkmnList.y = Graphics.height-64 @@ -562,12 +549,12 @@ class TrainerBattleLister if @trainers[i][4]>0 # TrainerType TrainerName (version) xPartySize @commands.push(_ISPRINTF("{1:s} {2:s} ({3:d}) x{4:d}", - PBTrainers.getName(@trainers[i][0]),@trainers[i][1],@trainers[i][4], - @trainers[i][3].length)) + GameData::TrainerType.get(@trainers[i][0]).name, @trainers[i][1], + @trainers[i][4], @trainers[i][3].length)) else # TrainerType TrainerName xPartySize @commands.push(_ISPRINTF("{1:s} {2:s} x{3:d}", - PBTrainers.getName(@trainers[i][0]),@trainers[i][1], + GameData::TrainerType.get(@trainers[i][0]).name, @trainers[i][1], @trainers[i][3].length)) end # Trainer type ID @@ -594,8 +581,10 @@ class TrainerBattleLister rescue @sprite.setBitmap(nil) end - @sprite.ox = @sprite.bitmap.width/2 - @sprite.oy = @sprite.bitmap.height + if @sprite.bitmap + @sprite.ox = @sprite.bitmap.width/2 + @sprite.oy = @sprite.bitmap.height + end text = "" if !@includeNew || index>0 @trainers[(@includeNew) ? index-1 : index][3].each_with_index do |p,i| diff --git a/Data/Scripts/021_Debug/009_Editor_Utilities.rb b/Data/Scripts/021_Debug/009_Editor_Utilities.rb index 0fb72537e..3bf1bbc15 100644 --- a/Data/Scripts/021_Debug/009_Editor_Utilities.rb +++ b/Data/Scripts/021_Debug/009_Editor_Utilities.rb @@ -237,29 +237,10 @@ def pbGetHabitatConst(i) return ret end -# Unused -#def pbGetAbilityConst(i) -# return MakeshiftConsts.get(MessageTypes::Abilities,i,PBAbilities) -#end - -# Unused -#def pbGetMoveConst(i) -# return MakeshiftConsts.get(MessageTypes::Moves,i,PBMoves) -#end - -# Unused -#def pbGetItemConst(i) -# return MakeshiftConsts.get(MessageTypes::Items,i,PBItems) -#end - def pbGetSpeciesConst(i) return MakeshiftConsts.get(MessageTypes::Species,i,PBSpecies) end -def pbGetTrainerConst(i) - return MakeshiftConsts.get(MessageTypes::TrainerTypes,i,PBTrainers) -end - #=============================================================================== diff --git a/Data/Scripts/022_Compiler/002_Compiler.rb b/Data/Scripts/022_Compiler/002_Compiler.rb index dd3803733..28cf531ac 100644 --- a/Data/Scripts/022_Compiler/002_Compiler.rb +++ b/Data/Scripts/022_Compiler/002_Compiler.rb @@ -311,7 +311,7 @@ module Compiler end return enumer.const_get(ret.to_sym) elsif enumer.is_a?(Symbol) || enumer.is_a?(String) - if [:Ability, :Item, :Move].include?(enumer) + if [:Ability, :Item, :Move, :TrainerType].include?(enumer) enumer = GameData.const_get(enumer.to_sym) begin if ret == "" || !enumer.exists?(ret.to_sym) @@ -353,7 +353,7 @@ module Compiler return nil if ret=="" || !(enumer.const_defined?(ret) rescue false) return enumer.const_get(ret.to_sym) elsif enumer.is_a?(Symbol) || enumer.is_a?(String) - if [:Ability, :Item, :Move].include?(enumer) + if [:Ability, :Item, :Move, :TrainerType].include?(enumer) enumer = GameData.const_get(enumer.to_sym) return nil if ret == "" || !enumer.exists?(ret.to_sym) return ret.to_sym @@ -568,7 +568,7 @@ module Compiler clonitem.sub!(/\s*$/,"") itm = GameData::Item.try_get(clonitem) if !itm - raise _INTL("Undefined item constant name: %s\r\nName must consist only of letters, numbers and\r\nunderscores, and can't begin with a number.\r\nMake sure the item is defined in\r\nPBS/items.txt.\r\n{1}", item, FileLineData.linereport) + raise _INTL("Undefined item constant name: {1}\r\nName must consist only of letters, numbers and\r\nunderscores, and can't begin with a number.\r\nMake sure the item is defined in\r\nPBS/items.txt.\r\n{2}", item, FileLineData.linereport) end return itm.id.to_s end @@ -589,7 +589,7 @@ module Compiler mov = GameData::Move.try_get(clonmove) if !mov return nil if skip_unknown - raise _INTL("Undefined move constant name: %s\r\nName must consist only of letters, numbers and\r\nunderscores, and can't begin with a number.\r\nMake sure the move is defined in\r\nPBS/moves.txt.\r\n{1}", move, FileLineData.linereport) + raise _INTL("Undefined move constant name: {1}\r\nName must consist only of letters, numbers and\r\nunderscores, and can't begin with a number.\r\nMake sure the move is defined in\r\nPBS/moves.txt.\r\n{2}", move, FileLineData.linereport) end return mov.id.to_s end @@ -603,11 +603,15 @@ module Compiler end # Unused - def parseTrainer(item) - clonitem = item.clone - clonitem.sub!(/^\s*/,"") - clonitem.sub!(/\s*$/,"") - return pbGetConst(PBTrainers,clonitem,_INTL("Undefined Trainer constant name: %s\r\nName must consist only of letters, numbers, and\r\nunderscores and can't begin with a number.\r\nIn addition, the name must be defined\r\nin trainertypes.txt.\r\n{1}",FileLineData.linereport)) + def parseTrainer(type) + clontype = type.clone + clontype.sub!(/^\s*/, "") + clontype.sub!(/\s*$/, "") + typ = GameData::TrainerType.try_get(clontype) + if !typ + raise _INTL("Undefined Trainer type constant name: {1}\r\nName must consist only of letters, numbers and\r\nunderscores, and can't begin with a number.\r\nMake sure the trainer type is defined in\r\ntrainertypes.txt.\r\n{2}", type, FileLineData.linereport) + end + return typ.id.to_s end #============================================================================= @@ -644,11 +648,11 @@ module Compiler yield(_INTL("Compiling Trainer data")) compile_trainers # Depends on PBSpecies, Item, Move yield(_INTL("Compiling phone data")) - compile_phone # Depends on PBTrainers + compile_phone yield(_INTL("Compiling metadata")) - compile_metadata # Depends on PBTrainers + compile_metadata # Depends on TrainerType yield(_INTL("Compiling battle Trainer data")) - compile_trainer_lists # Depends on PBTrainers + compile_trainer_lists # Depends on TrainerType yield(_INTL("Compiling encounter data")) compile_encounters # Depends on PBSpecies yield(_INTL("Compiling shadow moveset data")) diff --git a/Data/Scripts/022_Compiler/003_Compiler_PBS.rb b/Data/Scripts/022_Compiler/003_Compiler_PBS.rb index 0d50bc953..8162ebb91 100644 --- a/Data/Scripts/022_Compiler/003_Compiler_PBS.rb +++ b/Data/Scripts/022_Compiler/003_Compiler_PBS.rb @@ -1,5 +1,3 @@ -class PBTrainers; end - module Compiler module_function @@ -1220,42 +1218,45 @@ module Compiler # Compile trainer types #============================================================================= def compile_trainer_types - records = [] - trainernames = [] - maxValue = 0 - pbCompilerEachPreppedLine("PBS/trainertypes.txt") { |line,lineno| - record=pbGetCsvRecord(line,lineno,[0,"unsUSSSeUS", # ID can be 0 - nil,nil,nil,nil,nil,nil,nil,{ - "" => 2, - "Male" => 0,"M" => 0,"0" => 0, - "Female" => 1,"F" => 1,"1" => 1, - "Mixed" => 2,"X" => 2,"2" => 2 - },nil,nil] + GameData::TrainerType::DATA.clear + tr_type_names = [] + # Read each line of trainertypes.txt at a time and compile it into a trainer type + pbCompilerEachCommentedLine("PBS/trainertypes.txt") { |line, line_no| + line = pbGetCsvRecord(line, line_no, [0, "unsUSSSeUS", + nil, nil, nil, nil, nil, nil, nil, { + "Male" => 0, "M" => 0, "0" => 0, + "Female" => 1, "F" => 1, "1" => 1, + "Mixed" => 2, "X" => 2, "2" => 2, "" => 2 + }, nil, nil] ) - if records[record[0]] - raise _INTL("Two trainer types ({1} and {2}) have the same ID ({3}), which is not allowed.\r\n{4}", - records[record[0]][1],record[1],record[0],FileLineData.linereport) + type_number = line[0] + type_symbol = line[1].to_sym + if GameData::TrainerType::DATA[type_number] + raise _INTL("Trainer type ID number '{1}' is used twice.\r\n{2}", type_number, FileLineData.linereport) + elsif GameData::TrainerType::DATA[type_symbol] + raise _INTL("Trainer type ID '{1}' is used twice.\r\n{2}", type_symbol, FileLineData.linereport) end - trainernames[record[0]] = record[2] - records[record[0]] = record - maxValue = [maxValue,record[0]].max + # Construct trainer type hash + type_hash = { + :id_number => type_number, + :id => type_symbol, + :name => line[2], + :base_money => line[3], + :battle_BGM => line[4], + :victory_ME => line[5], + :intro_ME => line[6], + :gender => line[7], + :skill_level => line[8], + :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) + tr_type_names[type_number] = type_hash[:name] } - count = records.compact.length - MessageTypes.setMessages(MessageTypes::TrainerTypes,trainernames) - code = "class PBTrainers\r\n" - for rec in records - next if !rec - code += "#{rec[1]}=#{rec[0]}\r\n" - end - code += "def self.getName(id)\r\n" - code += "id=getID(PBTrainers,id)\r\n" - code += "return pbGetMessage(MessageTypes::TrainerTypes,id); end\r\n" - code += "def self.getCount; return #{count}; end\r\n" - code += "def self.maxValue; return #{maxValue}; end\r\n" - code += "end\r\n" - eval(code, TOPLEVEL_BINDING) - pbAddScript(code,"PBTrainers") - save_data(records,"Data/trainer_types.dat") + # Save all data + GameData::TrainerType.save + MessageTypes.setMessages(MessageTypes::TrainerTypes, tr_type_names) + Graphics.update end #============================================================================= @@ -1280,7 +1281,7 @@ module Compiler if pokemonindex==-1 raise _INTL("Started new trainer while previous trainer has no Pokémon.\r\n{1}",FileLineData.linereport) end - section = pbGetCsvRecord($~[1],lineno,[0,"esU",PBTrainers]) + section = pbGetCsvRecord($~[1],lineno,[0,"esU",:TrainerType]) trainerindex += 1 trainertype = section[0] trainername = section[1] @@ -1378,7 +1379,7 @@ module Compiler oldcompilerline += 1 case oldcompilerline when 1 # Trainer type - record = pbGetCsvRecord(line,lineno,[0,"e",PBTrainers]) + record = pbGetCsvRecord(line,lineno,[0,"e",:TrainerType]) trainers[trainerindex][0] = record when 2 # Trainer name, version number record = pbGetCsvRecord(line,lineno,[0,"sU"]) @@ -1462,7 +1463,7 @@ module Compiler def compile_battle_tower_trainers(filename) sections = [] requiredtypes = { - "Type" => [0, "e",PBTrainers], + "Type" => [0, "e", :TrainerType], "Name" => [1, "s"], "BeginSpeech" => [2, "s"], "EndSpeechWin" => [3, "s"], diff --git a/Data/Scripts/022_Compiler/004_Compiler_MapsAndEvents.rb b/Data/Scripts/022_Compiler/004_Compiler_MapsAndEvents.rb index d162d8dc0..a39c7d9ba 100644 --- a/Data/Scripts/022_Compiler/004_Compiler_MapsAndEvents.rb +++ b/Data/Scripts/022_Compiler/004_Compiler_MapsAndEvents.rb @@ -385,55 +385,37 @@ module Compiler class TrainerChecker def initialize @trainers = nil - @trainertypes = nil @dontaskagain = false end - def pbTrainerTypeCheck(symbol) - ret = true - if $DEBUG - return if @dontaskagain - if !hasConst?(PBTrainers,symbol) - ret = false - else - trtype = PBTrainers.const_get(symbol) - @trainertypes = load_data("Data/trainer_types.dat") if !@trainertypes - ret = false if !@trainertypes || !@trainertypes[trtype] - end - if !ret - if pbConfirmMessage(_INTL("Add new trainer named {1}?",symbol)) - pbTrainerTypeEditorNew(symbol.to_s) - @trainers = nil - @trainertypes = nil - end -# if pbMapInterpreter -# pbMapInterpreter.command_end rescue nil -# end - end + def pbTrainerTypeCheck(trainer_type) + return if !$DEBUG || @dontaskagain + return if GameData::TrainerType.exists?(trainer_type) + if pbConfirmMessage(_INTL("Add new trainer type {1}?", trainer_type.to_s)) + pbTrainerTypeEditorNew(trainer_type.to_s) end - return ret end - def pbTrainerBattleCheck(trtype,trname,trid) + def pbTrainerBattleCheck(tr_type, tr_name, tr_id) return if !$DEBUG || @dontaskagain - if trtype.is_a?(String) || trtype.is_a?(Symbol) - pbTrainerTypeCheck(trtype) - return if !hasConst?(PBTrainers,trtype) - trtype = PBTrainers.const_get(trtype) - end + # Check for existence of trainer type + pbTrainerTypeCheck(tr_type) + return if !GameData::TrainerType.exists?(tr_type) + tr_type = GameData::TrainerType.get(tr_type).id + # Check for existence of trainer @trainers = load_data("Data/trainers.dat") if !@trainers if @trainers for trainer in @trainers - return if trainer[0]==trtype && trainer[1]==trname && trainer[4]==trid + return if trainer[0]==tr_type && trainer[1]==tr_name && trainer[4]==tr_id end end - cmd = pbMissingTrainer(trtype,trname,trid) + # Add new trainer + cmd = pbMissingTrainer(tr_type,tr_name,tr_id) if cmd==2 @dontaskagain = true Graphics.update end - @trainers = nil - @trainertypes = nil + @trainers = nil end end @@ -539,8 +521,8 @@ module Compiler trainerChecker.pbTrainerBattleCheck(trtype,trname,battleid) if !$INEDITOR # Set the event's charset to one depending on the trainer type if the event # doesn't have a charset - if firstpage.graphic.character_name=="" && hasConst?(PBTrainers,trtype) - trainerid = getConst(PBTrainers,trtype) + if firstpage.graphic.character_name=="" && GameData::TrainerType.exists?(trtype) + trainerid = GameData::TrainerType.get(trtype).id if trainerid filename = pbTrainerCharNameFile(trainerid) if FileTest.image_exist?("Graphics/Characters/"+filename)