• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Setting IVs and EVs in TRAINER.TXT

SETTING IVs AND EVs IN TRAINER.TXT
This script adds adjustable Trainerpokemon EVs and IVs
by bulbasaurlvl5, drag and drop added by derFischae

This script is for Pokemon Essentials 17.
This Script makes it possible to set EVs and IVs (HP,ATK,... all seperately) in trainer.txt for the pokemon of a trainerBattle
Example: GYARADOS,50,CHOICEBAND,AQUATAIL,EARTHQUAKE,STONEEDGE,BOUNCE,0,F,,,ADAMANT,31,,kogasa,,,0,252,0,252,0,0,31,31,0,4,12,25
0-16th slot as usual, then EVHP,EVATK,EVDEF,EVSPD,EVSATK,EVSDEF,IVHP,IVATK,IVDEF,IVSPD,IVSATK,IVSDEF,
Default value will be used by using empty set "". Default value for EVs equals some equally spread EVs increasing with level by formula
EV = [85,level*3/2].min
Default value for IVs is 10 as usual.
If you set the value of TPIV in trainers.txt then also TPIVHP,TPIVATK,... have the same value unless you also set the value of TPIVHP,... in trainers.txt. In that case the pokemon gains the IVHP,... of that TPIVHP,... value.

Installation: Copy the whole script in a new Script called
"compiling trainer.txt IVs and EVs"
above main and under compiler. Make sure that no script you added manually overrides the same methods we overrided here.

Note that: After starting the game, the original compiler script given in Script "Compiler" already ran and used the original function "pbCompileTrainers" in the Script "Compiler" before this new, second compiler in this Script runs with this new "pbCompileTrainers" in this script.

Code:
#===============================================================================
# SETTING IVs AND EVs IN TRAINER.TXT
#
# by bulbasaurlvl5
# drag and drop added by derFischae
#===============================================================================

#===============================================================================
# Adds adjustable Trainerpokemon EVs and IVs
#
# This Script makes it possible to set EVs and IVs (HP,ATK,... all seperately)
# in trainer.txt for the pokemon of a trainerBattle
# Example: GYARADOS,50,CHOICEBAND,AQUATAIL,EARTHQUAKE,STONEEDGE,BOUNCE,0,F,,,ADAMANT,31,,kogasa,,,0,252,0,252,0,0,31,31,0,4,12,25
#          0-16th slot as usual, then EVHP,EVATK,EVDEF,EVSPD,EVSATK,EVSDEF,IVHP,IVATK,IVDEF,IVSPD,IVSATK,IVSDEF,
# Default value will be used by using empty set "".
# Default value for EVs equals some equally spread EVs increasing with level by formula
#         EV = [85,level*3/2].min
# Default value for IVs is 10 as usual.
# If you set the value of TPIV in trainers.txt then also TPIVHP,TPIVATK,... 
# have the same value unless you also set the value of TPIVHP,... in trainers.txt.
# In that case the pokemon gains the IVHP,... of that TPIVHP,... value.
#
# Installation: Copy the whole script in a new Script called 
#    "compiling trainer.txt IVs and EVs"
# above main and under compiler. Make sure that no script you added manually overrides the same
# methods we overrided here.
#
# Note that: After starting the game,
# the original compiler script given in Script "Compiler" already ran and used
# the original function "pbCompileTrainers" in the Script "Compiler"
# before this new, second compiler in this Script runs with this new 
# "pbCompileTrainers" in this script.
# 
#===============================================================================


#===============================================================================
# adding and replacing new stuff to the script
#       PTrainer_NPCTrainers
#===============================================================================
TPSPECIES   = 0
TPLEVEL     = 1
TPITEM      = 2
TPMOVE1     = 3
TPMOVE2     = 4
TPMOVE3     = 5
TPMOVE4     = 6
TPABILITY   = 7
TPGENDER    = 8
TPFORM      = 9
TPSHINY     = 10
TPNATURE    = 11
TPIV        = 12
TPHAPPINESS = 13
TPNAME      = 14
TPSHADOW    = 15
TPBALL      = 16
TPEVHP      = 17
TPEVATK      = 18
TPEVDEF      = 19
TPEVSPD      = 20
TPEVSATK      = 21
TPEVSDEF      = 22
TPIVHP      = 23
TPIVATK      = 24
TPIVDEF      = 25
TPIVSPD      = 26
TPIVSATK      = 27
TPIVSDEF      = 28

#Was sollte der Standardwert fuer IVHP, etc sein?
#Per default sollten wir doch den Wert nehmen, der durch TPIV (12. Stelle)
#bestimmt ist, oder?
#
#Was sollte der Standardwert fuer EVHP,... etc sein?
#lieber sich was ueberlegen, damit EVs bei Default anhand des levels bestimmt werden
#falls kein Wert eingetragen wurde? z.B. (so wie urspruenglich)
#poke[TPEVHP+i] = [85,level*3/2].min
#Dann braucht man auch nicht TPDEFAULTS erweitern. Wir brauchen also nicht sowas
TPDEFAULTS = [0,10,0,0,0,0,0,nil,nil,0,false,nil,10,70,nil,false,0]


#===============================================================================
#replaces method "pbLoadTrainer" in script "PTrainer_NPCTrainers"
#===============================================================================
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)
  end
  success=false
  items=[]
  party=[]
  opponent=nil
  trainers=load_data("Data/trainers.dat")
  for trainer in trainers
    name=trainer[1]
    thistrainerid=trainer[0]
    thispartyid=trainer[4]
    next if trainerid!=thistrainerid || name!=trainername || partyid!=thispartyid
    items=trainer[2].clone
    name=pbGetMessageFromHash(MessageTypes::TrainerNames,name)
    for i in RIVALNAMES
      if isConst?(trainerid,PBTrainers,i[0]) && $game_variables[i[1]]!=0
        name=$game_variables[i[1]]
      end
    end
    opponent=PokeBattle_Trainer.new(name,thistrainerid)
    opponent.setForeignID($Trainer) if $Trainer
    for poke in trainer[3]
      species=poke[TPSPECIES]
      level=poke[TPLEVEL]
      pokemon=PokeBattle_Pokemon.new(species,level,opponent)
      pokemon.forcedForm = true if poke[TPFORM]!=0 && MultipleForms.hasFunction?(pokemon.species,"getForm")
      pokemon.formNoCall=poke[TPFORM]
      pokemon.resetMoves
      pokemon.setItem(poke[TPITEM])
      if poke[TPMOVE1]>0 || poke[TPMOVE2]>0 || poke[TPMOVE3]>0 || poke[TPMOVE4]>0
        k=0
        for move in [TPMOVE1,TPMOVE2,TPMOVE3,TPMOVE4]
          pokemon.moves[k]=PBMove.new(poke[move])
          k+=1
        end
        pokemon.moves.compact!
      end
      pokemon.setAbility(poke[TPABILITY])
      pokemon.setGender(poke[TPGENDER])
      if poke[TPSHINY]   # if this is a shiny Pokémon
        pokemon.makeShiny
      else
        pokemon.makeNotShiny
      end
      pokemon.setNature(poke[TPNATURE])
      #================================
      # original code
      #iv=poke[TPIV]
      #for i in 0...6
      #  pokemon.iv[i]=iv&0x1F
      #  pokemon.ev[i]=[85,level*3/2].min
      #end
      #================================
      #replaced by:
      for i in 0...6
        pokemon.iv[i]=poke[TPIVHP+i]&0x1F
        pokemon.ev[i]=poke[TPEVHP+i].to_i
      end
      #end of changes
      #================================
      pokemon.happiness=poke[TPHAPPINESS]
      pokemon.name=poke[TPNAME] if poke[TPNAME] && poke[TPNAME]!=""
      if poke[TPSHADOW]   # if this is a Shadow Pokémon
        pokemon.makeShadow rescue nil
        pokemon.pbUpdateShadowMoves(true) rescue nil
        pokemon.makeNotShiny
      end
      pokemon.ballused=poke[TPBALL]
      pokemon.calcStats
      party.push(pokemon)
    end
    success=true
    break
  end
  return success ? [opponent,items,party] : nil
end


#===============================================================================
# replaces the method "pbCompileTrainers" in Script "Compiler"
# it will be used while compiling with the second, new compiler down
#===============================================================================
def pbCompileTrainers
  # Trainer types
  records = []
  trainernames = []
  count = 0
  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]
    )
    if record[3] && (record[3]<0 || record[3]>255)
      raise _INTL("Bad money amount (must be from 0 through 255)\r\n{1}",FileLineData.linereport)
    end
    record[3] = 30 if !record[3]
    if record[8] && (record[8]<0 || record[8]>255)
      raise _INTL("Bad skill value (must be from 0 through 255)\r\n{1}",FileLineData.linereport)
    end
    record[8] = record[3] if !record[8]
    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)
    end
    trainernames[record[0]] = record[2]
    records[record[0]]      = record
    maxValue = [maxValue,record[0]].max
  }
  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 += "\r\ndef self.getName(id)\r\nreturn pbGetMessage(MessageTypes::TrainerTypes,id)\r\nend"
  code += "\r\ndef self.getCount\r\nreturn #{count}\r\nend"
  code += "\r\ndef self.maxValue\r\nreturn #{maxValue}\r\nend\r\nend"
  eval(code)
  pbAddScript(code,"PBTrainers")
  File.open("Data/trainertypes.dat","wb"){|f|
    Marshal.dump(records,f)
  }
  # Individual trainers
  lines   = []
  linenos = []
  lineno  = 1
  File.open("PBS/trainers.txt","rb"){|f|
    FileLineData.file="PBS/trainers.txt"
    f.each_line {|line|
      if lineno==1 && line[0]==0xEF && line[1]==0xBB && line[2]==0xBF
        line = line[3,line.length-3]
      end
      line = prepline(line)
      if line!=""
        lines.push(line)
        linenos.push(lineno)
      end
      lineno += 1
    }
  }
  nameoffset = 0
  trainers = []
  trainernames.clear
  i = 0; loop do break unless i<lines.length
    FileLineData.setLine(lines[i],linenos[i])
    trainername = parseTrainer(lines[i])
    FileLineData.setLine(lines[i+1],linenos[i+1])
    nameline = strsplit(lines[i+1],/\s*,\s*/)
    name = nameline[0]
    raise _INTL("Trainer name too long\r\n{1}",FileLineData.linereport) if name.length>=0x10000
    trainernames.push(name)
    partyid = 0
    if nameline[1] && nameline[1]!=""
      raise _INTL("Expected a number for the trainer battle ID\r\n{1}",FileLineData.linereport) if !nameline[1][/^\d+$/]
      partyid = nameline[1].to_i
    end
    FileLineData.setLine(lines[i+2],linenos[i+2])
    items = strsplit(lines[i+2],/\s*,\s*/)
    items[0].gsub!(/^\s+/,"")   # Number of Pokémon
    raise _INTL("Expected a number for the number of Pokémon\r\n{1}",FileLineData.linereport) if !items[0][/^\d+$/]
    numpoke = items[0].to_i
    realitems = []
    for j in 1...items.length   # Items held by Trainer
      realitems.push(parseItem(items[j])) if items[j] && items[j]!=""
    end
    pkmn = []
    for j in 0...numpoke
      FileLineData.setLine(lines[i+j+3],linenos[i+j+3])
      poke = strsplit(lines[i+j+3],/\s*,\s*/)
      begin
        # Species
        poke[TPSPECIES] = parseSpecies(poke[TPSPECIES])
      rescue
        raise _INTL("Expected a species name: {1}\r\n{2}",poke[0],FileLineData.linereport)
      end
      # Level
      poke[TPLEVEL] = poke[TPLEVEL].to_i
      if poke[TPLEVEL]<=0 || poke[TPLEVEL]>PBExperience::MAXLEVEL
        raise _INTL("Bad level: {1} (must be from 1-{2})\r\n{3}",poke[TPLEVEL],PBExperience::MAXLEVEL,FileLineData.linereport) 
      end
      # Held item
      if !poke[TPITEM] || poke[TPITEM]==""
        poke[TPITEM] = TPDEFAULTS[TPITEM]
      else
        poke[TPITEM] = parseItem(poke[TPITEM])
      end
      # Moves
      moves = []
      for j in [TPMOVE1,TPMOVE2,TPMOVE3,TPMOVE4]
        moves.push(parseMove(poke[j])) if poke[j] && poke[j]!=""
      end
      for j in 0...4
        index = [TPMOVE1,TPMOVE2,TPMOVE3,TPMOVE4][j]
        if moves[j] && moves[j]!=0
          poke[index] = moves[j]
        else
          poke[index] = TPDEFAULTS[index]
        end
      end
      # Ability
      if !poke[TPABILITY] || poke[TPABILITY]==""
        poke[TPABILITY] = TPDEFAULTS[TPABILITY]
      else
        poke[TPABILITY] = poke[TPABILITY].to_i
        raise _INTL("Bad abilityflag: {1} (must be 0 or 1 or 2-5)\r\n{2}",poke[TPABILITY],FileLineData.linereport) if poke[TPABILITY]<0 || poke[TPABILITY]>5
      end
      # Gender
      if !poke[TPGENDER] || poke[TPGENDER]==""
        poke[TPGENDER] = TPDEFAULTS[TPGENDER]
      else
        if poke[TPGENDER]=="M"
          poke[TPGENDER] = 0
        elsif poke[TPGENDER]=="F"
          poke[TPGENDER] = 1
        else
          poke[TPGENDER] = poke[TPGENDER].to_i
          raise _INTL("Bad genderflag: {1} (must be M or F, or 0 or 1)\r\n{2}",poke[TPGENDER],FileLineData.linereport) if poke[TPGENDER]<0 || poke[TPGENDER]>1
        end
      end
      # Form
      if !poke[TPFORM] || poke[TPFORM]==""
        poke[TPFORM] = TPDEFAULTS[TPFORM]
      else
        poke[TPFORM] = poke[TPFORM].to_i
        raise _INTL("Bad form: {1} (must be 0 or greater)\r\n{2}",poke[TPFORM],FileLineData.linereport) if poke[TPFORM]<0
      end
      # Shiny
      if !poke[TPSHINY] || poke[TPSHINY]==""
        poke[TPSHINY] = TPDEFAULTS[TPSHINY]
      elsif poke[TPSHINY]=="shiny"
        poke[TPSHINY] = true
      else
        poke[TPSHINY] = csvBoolean!(poke[TPSHINY].clone)
      end
      # Nature
      if !poke[TPNATURE] || poke[TPNATURE]==""
        poke[TPNATURE] = TPDEFAULTS[TPNATURE]
      else
        poke[TPNATURE] = parseNature(poke[TPNATURE])
      end
      # IVs
      if !poke[TPIV] || poke[TPIV]==""
        poke[TPIV] = TPDEFAULTS[TPIV]
      else
        poke[TPIV] = poke[TPIV].to_i
        raise _INTL("Bad IV: {1} (must be from 0-31)\r\n{2}",poke[TPIV],FileLineData.linereport) if poke[TPIV]<0 || poke[TPIV]>31
      end
      # Happiness
      if !poke[TPHAPPINESS] || poke[TPHAPPINESS]==""
        poke[TPHAPPINESS] = TPDEFAULTS[TPHAPPINESS]
      else
        poke[TPHAPPINESS] = poke[TPHAPPINESS].to_i
        raise _INTL("Bad happiness: {1} (must be from 0-255)\r\n{2}",poke[TPHAPPINESS],FileLineData.linereport) if poke[TPHAPPINESS]<0 || poke[TPHAPPINESS]>255
      end
      # Nickname
      if !poke[TPNAME] || poke[TPNAME]==""
        poke[TPNAME] = TPDEFAULTS[TPNAME]
      else
        poke[TPNAME] = poke[TPNAME].to_s
        raise _INTL("Bad nickname: {1} (must be 1-20 characters)\r\n{2}",poke[TPNAME],FileLineData.linereport) if (poke[TPNAME].to_s).length>20
      end
      # Shadow
      if !poke[TPSHADOW] || poke[TPSHADOW]==""
        poke[TPSHADOW] = TPDEFAULTS[TPSHADOW]
      else
        poke[TPSHADOW] = csvBoolean!(poke[TPSHADOW].clone)
      end
      # Ball
      if !poke[TPBALL] || poke[TPBALL]==""
        poke[TPBALL] = TPDEFAULTS[TPBALL]
      else
        poke[TPBALL] = poke[TPBALL].to_i
        raise _INTL("Bad form: {1} (must be 0 or greater)\r\n{2}",poke[TPBALL],FileLineData.linereport) if poke[TPBALL]<0
      end
      #================================================
      # added new compiling routine for the IVs and EVs
      evSum = 0
      for k in 0...6
        #IVs
        if !poke[TPIVHP+k] || poke[TPIVHP+k]==""
          poke[TPIVHP+k] = poke[TPIV]
        else
          poke[TPIVHP+k] = poke[TPIVHP+k].to_i
          raise _INTL("Bad IV: {1} (must be from 0-31)\r\n{2}",poke[TPIVHP+i],FileLineData.linereport) if poke[TPIVHP+k]<0 || poke[TPIVHP+k]>31
        end
        #EVs
        if !poke[TPEVHP+k] || poke[TPEVHP+k]==""
          #poke[TPEVHP+k] = TPDEFAULTS[TPEVHP+k]
          #lieber sich was ueberlegen, damit EVs bei Default
          #anhand des levels bestimmt werden? z.B. 
          poke[TPEVHP+k] = [85,poke[TPLEVEL].to_i*3/2].min
        else
          poke[TPEVHP+k] = poke[TPEVHP+k].to_i
          #In welchem Zahlenbereich sollen denn die EVs liegen?
          raise _INTL("Bad EV: {1} (must be from 0-255)\r\n{2}",poke[TPEVHP+k],FileLineData.linereport) if poke[TPEVHP+k]<0 || poke[TPEVHP+k]>255
        end
        evSum+=poke[TPEVHP+k]
      end
      raise _INTL("Bad EV sum: {1} (sum must be from 0-510)\r\n{2}",evSum,FileLineData.linereport) if evSum<0 || evSum>510
      #end of changes (compared to the original)
      #================================================
      pkmn.push(poke)
    end
    i += 3+numpoke
    MessageTypes.setMessagesAsHash(MessageTypes::TrainerNames,trainernames)
    trainers.push([trainername,name,realitems,pkmn,partyid])
    nameoffset += name.length
  end
  save_data(trainers,"Data/trainers.dat")
end


#===============================================================================
# starting to compile?
# the used functions for the compiler have to be written above this 
# compiler, especially the method "pbCompileTrainers"
#
# this compiler only looks for the trainers.txt
#===============================================================================
begin
  if $DEBUG
    datafiles = ["trainers.dat"]
    textfiles = ["trainers.txt"]
    mustcompile = true
    Input.update
    mustcompile = false if Input.press?(Input::SHIFT)
    if mustcompile
      for i in 0...datafiles.length
        begin
          File.delete("Data/#{datafiles[i]}")
        rescue SystemCallError
        end
      end
    end
    pbCompileTrainers
  end
rescue Exception
  e = $!
  raise e if "#{e.class}"=="Reset" || e.is_a?(Reset) || e.is_a?(SystemExit)
  pbPrintException(e)
  for i in 0...datafiles.length
    begin
      File.delete("Data/#{datafiles[i]}")
    rescue SystemCallError
    end
  end
  raise Reset.new if e.is_a?(Hangup)
  loop do
    Graphics.update
  end
end
 
Back
Top