• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • 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.

Plug-and-play Delta Pokemon/Alolan Forms script

824
Posts
8
Years
  • This script allows players to make Delta Pokemon (as fans have called them for a while) or Alolan Forms (as they are now officially known) without making them unique species or numbered forms.

    This script includes all of the differences between Alolan Pokemon and their "Kantonian" counterparts Hau uses the word "Kantonian" to describe the player's mother's Meowth, which leads me to believe this is the proper way to refer to the non-Alolan form of a Pokemon that has an Alolan Form. This includes:
    - Types
    - Base stats, if they're different
    - Height and Weight, if they're different
    - Level-up moveset, if they're different
    - TM/Move Tutor compatability
    - Egg Moves
    - Evolution methods, if they're different

    In addition, this script includes the breeding mechanics used in Sun and Moon to enable Kantonian Form parents to birth Kantonian Form children despite the children being born in Alola, just flipped on their end to allow Alolan Form parents to birth Alolan Form children despite the game (presumably) not taking place in Alola.

    I have also included a (logical) method of making the Wormadam-esque Alolan Forms - Raichu, Exeggutor, and Marowak - able to evolve from their non-Alolan pre-evolutions. This does require you to have the Strange Souvenir item in your game.

    The script includes all of the canon Alolan Forms.

    To use, put this code in a script section above Main, but below PSystem_Utilities. If using the EBS and/or Following Pokemon, place it below those scripts but above Main. If using KleinStudio's BW Essentials kit, paste it in a script section directly above Main.

    Code:
    #########################################################################
    # Delta Pokemon/Alolan Form code
    # This is compatible with Essentials v16.2
    # Also compatible with Luka's Elite Battle System (EBS),
    #    Klien's BW Essentials kit,
    #    and mej's Following Pokemon script
    # Note that this code adds the Alolan forms as code within the game
    # It does not automatically create the Alolan forms as possible
    #    encounters.
    # You as the game developer need to decide how you want players to
    #    encounter the Alolan Pokemon.
    #########################################################################
    # To use
    # 1.) place in a new script section below "PSystem_Utilities" but
    #    above "Main"
    #  - if using the EBS or Following Pokemon scripts, place below those
    #      scripts as well as "PSystem_Utilities"
    # 2.) Decide how you want the player to encounter Delta/Alolan Pokemon
    #  - see the bottom of this script for an example that makes Alolan
    #      Exeggutor appear on a certain map
    #########################################################################
    # Please note that the breeding mechanics for Deltaness work under the
    #    assumption that your fangame will NOT be taking place in Alola.
    # Likewise, the evolution mechanics for Pikachu, Cubone, and Exeggcute
    #    work under the assumption that your fangame will NOT be taking
    #    place in Alola, but that you DO wish the players to be able to
    #    obtain Alolan Raichu, Alolan Marowak, and Alolan Exeggutor in
    #    some way.
    #########################################################################
    
    # Battlers
    
    class PokeBattle_Battler
      def isDelta?
        return (@pokemon) ? @pokemon.isDelta? : false
      end
    
      def isAlolan?
        return (@pokemon) ? @pokemon.isDelta? : false
      end
    
      def isEgg?
        return (@pokemon) ? (@pokemon.isEgg? rescue @pokemon.egg? rescue false) : false
      end
    
      def isAlolaForm?
        return (@pokemon) ? @pokemon.isDelta? : false
      end
    end
    
    class PokeBattle_FakeBattler
      def isDelta?; return @pokemon.isDelta?; end
      def isAlolan?; return @pokemon.isDelta?; end
      def isAlolaForm?; return @pokemon.isDelta?; end
    end
    
    # Pokemon
    
    class PokeBattle_Pokemon
      alias ____mf_getAbilityList getAbilityList
      def getAbilityList
        v=MultipleForms.call("getAbilityList",self)
        return v if v!=nil && v.length>0
        return self.____mf_getAbilityList
      end
      
      # generates the list of Egg Moves
      def possibleEggMoves
        v=MultipleForms.call("possibleEggMoves",self)
        return v if v!=nil
        pbRgssOpen("Data/eggEmerald.dat","rb"){|f|
             f.pos=(self.species-1)*8
             offset=f.fgetdw
             length=f.fgetdw
             if length>0
               bob=[]
               f.pos=offset
               i=0; loop do break unless i<length
                 atk=f.fgetw
                 bob.push(atk)
                 i+=1
               end
               return bob
             else
               return []
             end
           }
      end
    
      attr_accessor(:deltaflag)  # Forces the deltaness (true/false)
    
      def isDelta?
        return @deltaflag if @deltaflag != nil
            return false
      end
    
      def isAlolan?
        return isDelta?
      end
    
      def isAlolaForm?
        return isDelta?
      end
      
      def makeDelta
        @deltaflag=true
      end
    
      # provides a fix for forms crashing game
      def spoofForm(val)
        @deltaflag = false
        @form = val
      end
    end
    
    # Breeding
    def pbDayCareGenerateEgg
      if pbDayCareDeposited!=2
        return
      elsif $Trainer.party.length>=6
        raise _INTL("Can't store the egg")
      end
      pokemon0=$PokemonGlobal.daycare[0][0]
      pokemon1=$PokemonGlobal.daycare[1][0]
      mother=nil
      father=nil
      babyspecies=0
      ditto0=pbIsDitto?(pokemon0)
      ditto1=pbIsDitto?(pokemon1)
      if (pokemon0.isFemale? || ditto0)
        babyspecies=(ditto0) ? pokemon1.species : pokemon0.species
        mother=pokemon0
        father=pokemon1
      else
        babyspecies=(ditto1) ? pokemon0.species : pokemon1.species
        mother=pokemon1
        father=pokemon0
      end
      babyspecies=pbGetBabySpecies(babyspecies,mother.item,father.item)
      if isConst?(babyspecies,PBSpecies,:MANAPHY) && hasConst?(PBSpecies,:PHIONE)
        babyspecies=getConst(PBSpecies,:PHIONE)
      elsif (isConst?(babyspecies,PBSpecies,:NIDORANfE) && hasConst?(PBSpecies,:NIDORANmA)) ||
            (isConst?(babyspecies,PBSpecies,:NIDORANmA) && hasConst?(PBSpecies,:NIDORANfE))
        babyspecies=[getConst(PBSpecies,:NIDORANmA),
                     getConst(PBSpecies,:NIDORANfE)][rand(2)]
      elsif (isConst?(babyspecies,PBSpecies,:VOLBEAT) && hasConst?(PBSpecies,:ILLUMISE)) ||
            (isConst?(babyspecies,PBSpecies,:ILLUMISE) && hasConst?(PBSpecies,:VOLBEAT))
        babyspecies=[getConst(PBSpecies,:VOLBEAT),
                     getConst(PBSpecies,:ILLUMISE)][rand(2)]
      end
      # Generate egg
      egg=PokeBattle_Pokemon.new(babyspecies,EGGINITIALLEVEL,$Trainer)
      # Randomise personal ID
      pid=rand(65536)
      pid|=(rand(65536)<<16)
      egg.personalID=pid
      # Inheriting form
      if isConst?(babyspecies,PBSpecies,:BURMY) ||
         isConst?(babyspecies,PBSpecies,:SHELLOS) ||
         isConst?(babyspecies,PBSpecies,:BASCULIN) ||
         isConst?(babyspecies,PBSpecies,:MINIOR) ||
         isConst?(babyspecies,PBSpecies,:ORICORIO)
        egg.form=mother.form
      end
      # Inheriting Delta-ness
      if (mother.isDelta? && isConst?(mother.item,PBItems,:EVERSTONE)) ||
         (mother.isDelta? && isConst?(mother.item,PBItems,:STRANGESOUVENIR)) ||
    	 (father.isDelta? && isConst?(father.item,PBItems,:EVERSTONE)) ||
         (father.isDelta? && isConst?(father.item,PBItems,:STRANGESOUVENIR))
        egg.makeDelta
      end
      # Inheriting Moves
      moves=[]
      othermoves=[] 
      movefather=father; movemother=mother
      if pbIsDitto?(movefather) && !mother.isFemale?
        movefather=mother; movemother=father
      end
      # Initial Moves
      initialmoves=egg.getMoveList
      moop=egg.possibleEggMoves
      for k in initialmoves
        if k[0]<=EGGINITIALLEVEL
          moves.push(k[1])
        else
          othermoves.push(k[1]) if mother.knowsMove?(k[1]) && father.knowsMove?(k[1])
        end
      end
      # Inheriting Natural Moves
      for move in othermoves
        moves.push(move)
      end
      # Inheriting Machine Moves
      if !USENEWBATTLEMECHANICS
        for i in 0...$ItemData.length
          next if !$ItemData[i]
          atk=$ItemData[i][ITEMMACHINE]
          next if !atk || atk==0
          if egg.isCompatibleWithMove?(atk)
            moves.push(atk) if movefather.knowsMove?(atk)
          end
        end
      end
      # Inheriting Egg Moves
      if moop.length>0 && movefather.isMale?
        for i in moop
          moves.push(i) if movefather.knowsMove?(i)
        end
      end
      if USENEWBATTLEMECHANICS && moop.length>0 && movemother.isFemale?
        for i in moop
          moves.push(i) if movemother.knowsMove?(i)
        end
      end
      # Volt Tackle
      lightball=false
      if (isConst?(father.species,PBSpecies,:PIKACHU) || 
          isConst?(father.species,PBSpecies,:RAICHU)) && 
          isConst?(father.item,PBItems,:LIGHTBALL)
        lightball=true
      end
      if (isConst?(mother.species,PBSpecies,:PIKACHU) || 
          isConst?(mother.species,PBSpecies,:RAICHU)) && 
          isConst?(mother.item,PBItems,:LIGHTBALL)
        lightball=true
      end
      if lightball && isConst?(babyspecies,PBSpecies,:PICHU) &&
         hasConst?(PBMoves,:VOLTTACKLE)
        moves.push(getConst(PBMoves,:VOLTTACKLE))
      end
      moves|=[] # remove duplicates
      # Assembling move list
      finalmoves=[]
      listend=moves.length-4
      listend=0 if listend<0
      j=0
      for i in listend..listend+3
        moveid=(i>=moves.length) ? 0 : moves[i]
        finalmoves[j]=PBMove.new(moveid)
        j+=1
      end 
      # Inheriting Individual Values
      ivs=[]
      for i in 0...6
        ivs[i]=rand(32)
      end
      ivinherit=[]
      for i in 0...2
        parent=[mother,father][i]
        ivinherit[i]=PBStats::HP if isConst?(parent.item,PBItems,:POWERWEIGHT)
        ivinherit[i]=PBStats::ATTACK if isConst?(parent.item,PBItems,:POWERBRACER)
        ivinherit[i]=PBStats::DEFENSE if isConst?(parent.item,PBItems,:POWERBELT)
        ivinherit[i]=PBStats::SPEED if isConst?(parent.item,PBItems,:POWERANKLET)
        ivinherit[i]=PBStats::SPATK if isConst?(parent.item,PBItems,:POWERLENS)
        ivinherit[i]=PBStats::SPDEF if isConst?(parent.item,PBItems,:POWERBAND)
      end
      num=0; r=rand(2)
      for i in 0...2
        if ivinherit[r]!=nil
          parent=[mother,father][r]
          ivs[ivinherit[r]]=parent.iv[ivinherit[r]]
          num+=1
          break
        end
        r=(r+1)%2
      end
      stats=[PBStats::HP,PBStats::ATTACK,PBStats::DEFENSE,
             PBStats::SPEED,PBStats::SPATK,PBStats::SPDEF]
      limit=(USENEWBATTLEMECHANICS && (isConst?(mother.item,PBItems,:DESTINYKNOT) ||
             isConst?(father.item,PBItems,:DESTINYKNOT))) ? 5 : 3
      loop do
        freestats=[]
        for i in stats
          freestats.push(i) if !ivinherit.include?(i)
        end
        break if freestats.length==0
        r=freestats[rand(freestats.length)]
        parent=[mother,father][rand(2)]
        ivs[r]=parent.iv[r]
        ivinherit.push(r)
        num+=1
        break if num>=limit
      end
      # Inheriting nature
      newnatures=[]
      newnatures.push(mother.nature) if isConst?(mother.item,PBItems,:EVERSTONE)
      newnatures.push(father.nature) if isConst?(father.item,PBItems,:EVERSTONE)
      if newnatures.length>0
        egg.setNature(newnatures[rand(newnatures.length)])
      end
      # Masuda method and Shiny Charm
      shinyretries=0
      shinyretries+=5 if father.language!=mother.language
      shinyretries+=2 if hasConst?(PBItems,:SHINYCHARM) &&
                         $PokemonBag.pbQuantity(:SHINYCHARM)>0
      if shinyretries>0
        for i in 0...shinyretries
          break if egg.isShiny?
          egg.personalID=rand(65536)|(rand(65536)<<16)
        end
      end
      # Inheriting ability from the mother
      if (!ditto0 && !ditto1)
        if mother.hasHiddenAbility?
          egg.setAbility(mother.abilityIndex) if rand(10)<6
        else
          if rand(10)<8
            egg.setAbility(mother.abilityIndex)
          else
            egg.setAbility((mother.abilityIndex+1)%2)
          end
        end
      elsif ((!ditto0 && ditto1) || (!ditto1 && ditto0)) && USENEWBATTLEMECHANICS
        parent=(!ditto0) ? mother : father
        if parent.hasHiddenAbility?
          egg.setAbility(parent.abilityIndex) if rand(10)<6
        end
      end
      # Inheriting Poké Ball from the mother
      if mother.isFemale? &&
         !isConst?(pbBallTypeToBall(mother.ballused),PBItems,:MASTERBALL) &&
         !isConst?(pbBallTypeToBall(mother.ballused),PBItems,:CHERISHBALL)
        egg.ballused=mother.ballused
      end
      egg.iv[0]=ivs[0]
      egg.iv[1]=ivs[1]
      egg.iv[2]=ivs[2]
      egg.iv[3]=ivs[3]
      egg.iv[4]=ivs[4]
      egg.iv[5]=ivs[5]
      egg.moves[0]=finalmoves[0]
      egg.moves[1]=finalmoves[1]
      egg.moves[2]=finalmoves[2]
      egg.moves[3]=finalmoves[3]
      egg.calcStats
      egg.obtainText=_INTL("Day-Care Couple")
      egg.name=_INTL("Egg")
      dexdata=pbOpenDexData
      pbDexDataOffset(dexdata,babyspecies,21)
      eggsteps=dexdata.fgetw
      dexdata.close
      egg.eggsteps=eggsteps
      if rand(65536)<POKERUSCHANCE
        egg.givePokerus
      end
      $Trainer.party[$Trainer.party.length]=egg
    end
    
    ##############################################################
    # Appearance change
    ##############################################################
    class PokemonSprite < SpriteWrapper
      def setSpeciesBitmap(species,female=false,form=0,shiny=false,shadow=false,back=false,egg=false,delta=false)
        @_iconbitmap.dispose if @_iconbitmap
        @_iconbitmap=species>0 ? pbLoadSpeciesBitmap(species,female,form,shiny,shadow,back,egg,delta) : nil
        self.bitmap=@_iconbitmap ? @_iconbitmap.bitmap : nil
      end
    end
    
    class PokemonEggHatchScene
      def pbStartScene(pokemon)
        @sprites={}
        @pokemon=pokemon
        @nicknamed=false
        @viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
        @viewport.z=99999
        addBackgroundOrColoredPlane(@sprites,"background","hatchbg",
          Color.new(248,248,248),@viewport)
        @sprites["pokemon"]=PokemonSprite.new(@viewport)
        @sprites["pokemon"].setSpeciesBitmap(@pokemon.species,@pokemon.isFemale?,
                                            (@pokemon.form rescue 0),@pokemon.isShiny?,
                                            false,false,true,(@pokemon.isDelta? rescue false)) # Egg sprite
        @sprites["pokemon"].x=Graphics.width/2-@sprites["pokemon"].bitmap.width/2
        @sprites["pokemon"].y=48+(Graphics.height-@sprites["pokemon"].bitmap.height)/2
        @sprites["hatch"]=BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
        @sprites["overlay"]=BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
        @sprites["overlay"].z=200
        @sprites["overlay"].bitmap=Bitmap.new(Graphics.width,Graphics.height)
        @sprites["overlay"].bitmap.fill_rect(0,0,Graphics.width,Graphics.height,
            Color.new(255,255,255))
        @sprites["overlay"].opacity=0
        pbFadeInAndShow(@sprites)
      end
    end
    
    def pbLoadPokemonBitmap(pokemon, back=false, scale=nil)
      return pbLoadPokemonBitmapSpecies(pokemon,pokemon.species,back,scale)
    end
    
    # Note: Returns an AnimatedBitmap, not a Bitmap
    def pbLoadPokemonBitmapSpecies(pokemon, species, back=false, scale=nil)
      ret=nil
      if scale==nil
        scale=1
        if defined?(POKEMONSPRITESCALE)
          scale=POKEMONSPRITESCALE if POKEMONSPRITESCALE != nil
        end
      end
      if pokemon.isEgg?
        bitmapFileName=sprintf("Graphics/Battlers/%segg",getConstantName(PBSpecies,species)) rescue nil
        if !pbResolveBitmap(bitmapFileName)
          bitmapFileName=sprintf("Graphics/Battlers/%03degg",species)
          if !pbResolveBitmap(bitmapFileName)
            bitmapFileName=sprintf("Graphics/Battlers/egg")
          end
        end
        bitmapFileName=pbResolveBitmap(bitmapFileName)
      else
        bitmapFileName=pbCheckPokemonBitmapFiles([species,back,
                                                  (pokemon.isFemale?),
                                                  pokemon.isShiny?,
                                                  (pokemon.form rescue 0),
                                                  (pokemon.isShadow? rescue false),
                                                  (pokemon.isDelta? rescue false)])
        # Alter bitmap if supported
        alterBitmap=(MultipleForms.getFunction(species,"alterBitmap") rescue nil)
      end
      if bitmapFileName && alterBitmap
        animatedBitmap=AnimatedBitmap.new(bitmapFileName)
        copiedBitmap=animatedBitmap.copy
        animatedBitmap.dispose
        copiedBitmap.each {|bitmap|
          alterBitmap.call(pokemon,bitmap)
        }
        ret=copiedBitmap
        if defined?(DynamicPokemonSprite) # if EBS code exists
          animatedBitmap=AnimatedBitmapWrapper.new(bitmapFileName,scale)
          animatedBitmap.prepareStrip
          for i in 0...animatedBitmap.totalFrames
            alterBitmap.call(pokemon,animatedBitmap.alterBitmap(i))
          end
          animatedBitmap.compileStrip
          ret=animatedBitmap
        end
      elsif bitmapFileName
        ret=AnimatedBitmap.new(bitmapFileName)
        ret=AnimatedBitmapWrapper.new(bitmapFileName,scale) if defined?(DynamicPokemonSprite) # if EBS code exists
      end
      return ret
    end
    
    # Note: Returns an AnimatedBitmap, not a Bitmap
    def pbLoadSpeciesBitmap(species,female=false,form=0,shiny=false,shadow=false,back=false,egg=false,delta=false)
      ret=nil
      if egg
        bitmapFileName=sprintf("Graphics/Battlers/%segg",getConstantName(PBSpecies,species)) rescue nil
        if !pbResolveBitmap(bitmapFileName)
          bitmapFileName=sprintf("Graphics/Battlers/%03degg",species)
          if !pbResolveBitmap(bitmapFileName)
            bitmapFileName=sprintf("Graphics/Battlers/egg")
          end
        end
        bitmapFileName=pbResolveBitmap(bitmapFileName)
      else
        bitmapFileName=pbCheckPokemonBitmapFiles([species,back,female,shiny,form,shadow,delta])
      end
      if bitmapFileName
        ret=AnimatedBitmap.new(bitmapFileName)
      end
      return ret
    end
    
    def pbCheckPokemonBitmapFiles(params)
      species=params[0]
      back=params[1]
      factors=[]
      factors.push([5,params[5],false]) if params[5] && params[5]!=false    # shadow
      factors.push([2,params[2],false]) if params[2] && params[2]!=false    # gender
      factors.push([3,params[3],false]) if params[3] && params[3]!=false    # shiny
      factors.push([4,params[4].to_s,""]) if params[4] && params[4].to_s!="" &&
                                                          params[4].to_s!="0" # form
      factors.push([6,params[6],false]) if params[6] && params[6]!=false    # shiny
      tshadow=false
      tgender=false
      tshiny=false
      tdelta=false
      tform=""
      for i in 0...2**factors.length
        for j in 0...factors.length
          case factors[j][0]
          when 2  # gender
            tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 3  # shiny
            tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 4  # form
            tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 5  # shadow
            tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 6  # delta
            tdelta=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          end
        end
        folder=""
        if defined?(DUALSCREENHEIGHT) # if BW data exists
          folder="Front/"
          folder="Back/" if back
          folder="FrontShiny/" if tshiny
          folder="BackShiny/" if back && tshiny
          folder+="Female/" if tgender
        end
        bitmapFileName=sprintf("Graphics/Battlers/%s%s%s%s%s%s%s%s",
          folder,
          getConstantName(PBSpecies,species),
          tgender ? "f" : "",
          tshiny ? "s" : "",
          tdelta ? "d" : "",
          back ? "b" : "",
          (tform!="" ? "_"+tform : ""),
          tshadow ? "_shadow" : "") rescue nil
        ret=pbResolveBitmap(bitmapFileName)
        return ret if ret
        bitmapFileName=sprintf("Graphics/Battlers/%s%03d%s%s%s%s%s%s",
          folder, species,
          tgender ? "f" : "",
          tshiny ? "s" : "",
          tdelta ? "d" : "",
          back ? "b" : "",
          (tform!="" ? "_"+tform : ""),
          tshadow ? "_shadow" : "")
        ret=pbResolveBitmap(bitmapFileName)
        return ret if ret
      end
      return nil
    end
    
    def pbPokemonIconFile(pokemon)
      bitmapFileName=nil
      bitmapFileName=pbCheckPokemonIconFiles([pokemon.species,
                                              (pokemon.isFemale?),
                                              pokemon.isShiny?,
                                              (pokemon.form rescue 0),
                                              (pokemon.isShadow? rescue false),
                                              pokemon.isDelta?],
                                              pokemon.isEgg?)
      return bitmapFileName
    end
    
    def pbCheckPokemonIconFiles(params,egg=false)
      species=params[0]
      if egg
        bitmapFileName=sprintf("Graphics/Icons/icon%segg",getConstantName(PBSpecies,species)) rescue nil
        if !pbResolveBitmap(bitmapFileName)
          bitmapFileName=sprintf("Graphics/Icons/icon%03degg",species)
          if !pbResolveBitmap(bitmapFileName)
            bitmapFileName=sprintf("Graphics/Icons/iconEgg")
          end
        end
        return pbResolveBitmap(bitmapFileName)
      else
        factors=[]
        factors.push([4,params[4],false]) if params[4] && params[4]!=false    # shadow
        factors.push([1,params[1],false]) if params[1] && params[1]!=false    # gender
        factors.push([2,params[2],false]) if params[2] && params[2]!=false    # shiny
        factors.push([5,params[5],false]) if params[5] && params[5]!=false    # delta
        factors.push([3,params[3].to_s,""]) if params[3] && params[3].to_s!="" &&
                                                            params[3].to_s!="0" # form
        tshadow=false
        tgender=false
        tshiny=false
        tdelta=false
        tform=""
        for i in 0...2**factors.length
          for j in 0...factors.length
            case factors[j][0]
            when 1  # gender
              tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
            when 2  # shiny
              tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
            when 3  # form
              tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
            when 4  # shadow
              tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
            when 5  # delta
              tdelta=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
            end
          end
          bitmapFileName=sprintf("Graphics/Icons/icon%s%s%s%s%s%s",
            getConstantName(PBSpecies,species),
            tgender ? "f" : "",
            tshiny ? "s" : "",
            tdelta ? "d" : "",
            (tform!="" ? "_"+tform : ""),
            tshadow ? "_shadow" : "") rescue nil
          ret=pbResolveBitmap(bitmapFileName)
          return ret if ret
          bitmapFileName=sprintf("Graphics/Icons/icon%03d%s%s%s%s%s",
            species,
            tgender ? "f" : "",
            tshiny ? "s" : "",
            tdelta ? "d" : "",
            (tform!="" ? "_"+tform : ""),
            tshadow ? "_shadow" : "")
          ret=pbResolveBitmap(bitmapFileName)
          return ret if ret
        end
      end
      return nil
    end
    
    #########################################################################
    # Following Pokemon compatibility
    #########################################################################
    class DependentEvents
      def change_sprite(id, shiny=nil, animation=nil, form=nil, gender=nil, shadow=false, delta=nil)
        events=$PokemonGlobal.dependentEvents
        for i in 0...events.length
          if events[i] && events[i][8]=="Dependent"
            file=FOLLOWER_FILE_DIR+pbCheckPokemonFollowerFiles([id,gender,shiny,delta,form,shadow])
            events[i][6]=file
            @realEvents[i].character_name=file
            if animation
              $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
            end
            $game_variables[Walking_Time_Variable]=0
          end
        end
      end
    
      def refresh_sprite(animation=true)
        if $game_variables[Current_Following_Variable]!=0
          return unless $game_switches[Toggle_Following_Switch]
          return if $PokemonGlobal.bicycle
          if $Trainer.party[0].isShiny?
            shiny=true
          else
            shiny=false
          end
          if defined?($Trainer.party[0].isDelta?)
            delta = $Trainer.party[0].isDelta?
          else
            delta = false
          end
          if $Trainer.party[0].form>0
            form=$Trainer.party[0].form
          else
            form=nil
          end
          if defined?($Trainer.party[0].isShadow?)
            shadow = $Trainer.party[0].isShadow?
          else
            shadow = false
          end
          if $PokemonGlobal.surfing
            if $Trainer.party[0].hp>0 && !$Trainer.party[0].isEgg? && $Trainer.party[0].hasType?(:WATER)
              events=$PokemonGlobal.dependentEvents
              if animation
                for i in 0...events.length
                  $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
                  pbWait(10)
                end
              end
              change_sprite($Trainer.party[0].species, shiny, false, form, $Trainer.party[0].gender, shadow, delta)
            elsif ALWAYS_ANIMATED_CAN_SURF && ($Trainer.party[0].hasType?(:FLYING) ||
              isConst?($Trainer.party[0].ability,PBAbilities,:LEVITATE) ||
              ALWAYS_ANIMATED_FOLLOWERS.include?($Trainer.party[0].species)) &&
              !(ALWAYS_ANIMATED_EXCEPTION.include?($Trainer.party[0].species)) &&
              $Trainer.party[0].hp>0 && !$Trainer.party[0].isEgg?
              events=$PokemonGlobal.dependentEvents
              if animation
                for i in 0...events.length
                  $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
                  pbWait(10)
                end
              end
              change_sprite($Trainer.party[0].species, shiny, false, form, $Trainer.party[0].gender, shadow, delta)
            else
              remove_sprite(false)
            end
          elsif $PokemonGlobal.diving
            if $Trainer.party[0].hp>0 && !$Trainer.party[0].isEgg? && $Trainer.party[0].hasType?(:WATER) && WATERPOKEMONCANDIVE
              events=$PokemonGlobal.dependentEvents
              if animation
                for i in 0...events.length
                  $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
                  pbWait(10)
                end
              end
              change_sprite($Trainer.party[0].species, shiny, false, form, $Trainer.party[0].gender, shadow, delta)
            else
              remove_sprite(false)
            end
          else
            if $Trainer.party[0].hp>0 && !$Trainer.party[0].isEgg? && $scene.is_a?(Scene_Map)
              events=$PokemonGlobal.dependentEvents
              if animation
                for i in 0...events.length
                  $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
                  pbWait(10)
                end
              end
              change_sprite($Trainer.party[0].species, shiny, false, form, $Trainer.party[0].gender, shadow, delta)
            elsif $Trainer.party[0].hp<=0 || $Trainer.party[0].isEgg?
              remove_sprite(animation)
            end
          end
        else
          check_faint
        end
      end
    
      def Come_back(shiny=nil, animation=nil, delta=nil)
        return if !$game_variables[Following_Activated_Switch]
        return if $Trainer.party.length==0
        $PokemonTemp.dependentEvents.pbMoveDependentEvents
        events=$PokemonGlobal.dependentEvents
        if $game_variables[Current_Following_Variable]==$Trainer.party[0]
          remove_sprite(false)
          if $scene.is_a?(Scene_Map)
            for i in 0...events.length
              $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
            end
          end
        end
        if $Trainer.party[0].hp>0 && !$Trainer.party[0].isEgg?
          $game_variables[Current_Following_Variable]=$Trainer.party[0]
          refresh_sprite(animation)
        end
        for i in 0...events.length
          if events[i] && events[i][8]=="Dependent"
            file=FOLLOWER_FILE_DIR+pbCheckPokemonFollowerFiles([id,gender,shiny,delta,form,shadow])
            events[i][6]=file
            @realEvents[i].character_name=file
            if animation
              $scene.spriteset.addUserAnimation(Animation_Come_Out,@realEvents[i].x,@realEvents[i].y)
            end
          end
        end
      end
    end
    
    # this is an entirely new function, not found in the official release of Following Pokemon
    # it searches for Follower sprites the same way base Essentials searches for battlers and icons
    # rather than a series of "if-than" events
    def pbCheckPokemonFollowerFiles(params)
      species=params[0]
      factors=[]
      factors.push([1,params[1],false]) if params[1] && params[1]!=false    # gender
      factors.push([2,params[2],false]) if params[2] && params[2]!=false    # shiny
      factors.push([3,params[3],false]) if params[3] && params[3]!=false    # delta
      factors.push([4,params[4].to_s,""]) if params[4] && params[4].to_s!="" # form
      factors.push([5,params[5],false]) if params[5] && params[5]!=false    # shadow
      tshadow=false
      tgender=false
      tshiny=false
      tdelta=false
      tform=""
      for i in 0...2**factors.length
        for j in 0...factors.length
          case factors[j][0]
          when 1  # gender
            tgender=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 2  # shiny
            tshiny=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 3  # delta
            tdelta=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 4  # form
            tform=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          when 5  # shadow
            tshadow=((i/(2**j))%2==0) ? factors[j][1] : factors[j][2]
          end
        end
        bitmapFileName=sprintf("%s%s%s%s%s%s",
          getConstantName(PBSpecies,species),
          tgender ? "f" : "",
          tshiny ? "s" : "",
          tdelta ? "d" : "",
          (tform!="" ? "_"+tform : ""),
          tshadow ? "_shadow" : "") rescue nil
        ret=pbResolveBitmap(sprintf("%s%s%s",FOLLOWER_FILE_PATH,FOLLOWER_FILE_DIR,bitmapFileName))
        return bitmapFileName if ret
        bitmapFileName=sprintf("%03d%s%s%s%s%s",
          species,
          tgender ? "f" : "",
          tshiny ? "s" : "",
          tdelta ? "d" : "",
          (tform!="" ? "_"+tform : ""),
          tshadow ? "_shadow" : "")
        ret=pbResolveBitmap(sprintf("%s%s%s",FOLLOWER_FILE_PATH,FOLLOWER_FILE_DIR,bitmapFileName))
        return bitmapFileName if ret
      end
    end
    
    ##############################################################
    # Hybrid AnimatedBitmapWrapper class to encompass both the
    #    EBS version's inputs and the BW version's ones
    ##############################################################
    class AnimatedBitmapWrapper
      attr_reader :width
      attr_reader :height
      attr_reader :totalFrames
      attr_reader :animationFrames
      attr_reader :currentIndex
      attr_accessor :scale
    
      def initialize(file,twoframe_scale=2)
        raise "filename is nil" if file==nil
        if scale.is_a?(Numeric) # EBS version
          @scale = twoframe_scale
          @twoframe = false
        elsif !!scale == scale # BW version
          @scale = 2
          @twoframe = twoframe_scale
        end
        if @scale==nil
          @scale=2
        end
        @width = 0
        @height = 0
        @frame = 0
        @frames = 2
        @direction = +1
        @animationFinish = false
        @totalFrames = 0
        @currentIndex = 0
        @speed = 1
          # 0 - not moving at all
          # 1 - normal speed
          # 2 - medium speed
          # 3 - slow speed
        bmp = BitmapCache.load_bitmap(file)
        #bmp = Bitmap.new(file)
        @bitmapFile=Bitmap.new(bmp.width,bmp.height); @bitmapFile.blt(0,0,bmp,Rect.new(0,0,bmp.width,bmp.height))
        # initializes full Pokemon bitmap
        @bitmap=Bitmap.new(@bitmapFile.width,@bitmapFile.height)
        @bitmap.blt(0,0,@bitmapFile,Rect.new(0,0,@bitmapFile.width,@bitmapFile.height))
        @[email protected]*@scale
        @[email protected]*@scale
    
        @[email protected]/@bitmap.height
        @animationFrames=@totalFrames*@frames
        # calculates total number of frames
        @loop_points=[0,@totalFrames]
        # first value is start, second is end
    
        @actualBitmap=Bitmap.new(@width,@height)
        @actualBitmap.clear
        @actualBitmap.stretch_blt(Rect.new(0,0,@width,@height),@bitmap,Rect.new(@currentIndex*(@width/@scale),0,@width/@scale,@height/@scale))
      end
      alias initialize_elite initialize
    
      def length; @totalFrames; end
      def disposed?; @actualBitmap.disposed?; end
      def dispose; @actualBitmap.dispose; end
      def copy; @actualBitmap.clone; end
      def bitmap; @actualBitmap; end
      def bitmap=(val); @actualBitmap=val; end
      def each; end
      def alterBitmap(index); return @strip[index]; end
    
      def prepareStrip
        @strip=[]
        for i in 0...@totalFrames
          bitmap=Bitmap.new(@width,@height)
          bitmap.stretch_blt(Rect.new(0,0,@width,@height),@bitmapFile,Rect.new((@width/@scale)*i,0,@width/@scale,@height/@scale))
          @strip.push(bitmap)
        end
      end
      def compileStrip
        @bitmap.clear
        for i in [email protected]
          @bitmap.stretch_blt(Rect.new((@width/@scale)*i,0,@width/@scale,@height/@scale),@strip[i],Rect.new(0,0,@width,@height))
        end
      end
    
      def reverse
        if @direction  >  0
          @direction=-1
        elsif @direction < 0
          @direction=+1
        end
      end
    
      def setLoop(start, finish)
        @loop_points=[start,finish]
      end
    
      def setSpeed(value)
        @speed=value
      end
    
      def toFrame(frame)
        if frame.is_a?(String)
          if frame=="last"
            frame=@totalFrames-1
          else
            frame=0
          end
        end
        frame=@totalFrames if frame > @totalFrames
        frame=0 if frame < 0
        @currentIndex=frame
        @actualBitmap.clear
        @actualBitmap.stretch_blt(Rect.new(0,0,@width,@height),@bitmap,Rect.new(@currentIndex*(@width/@scale),0,@width/@scale,@height/@scale))
      end
    
      def play
        return if @currentIndex >= @loop_points[1]-1
        self.update
      end
    
      def finished?
        return (@currentIndex==@totalFrames-1)
      end
    
      def update
        return false if @actualBitmap.disposed?
        return false if @speed < 1
        case @speed
        # frame skip
        when 1
          @frames=2
        when 2
          @frames=4
        when 3
          @frames=5
        end
        @frame+=1
    
        if @frame >=@frames
          # processes animation speed
          @currentIndex+=@direction
          @currentIndex=@loop_points[0] if @currentIndex >=@loop_points[1]
          @currentIndex=@loop_points[1]-1 if @currentIndex < @loop_points[0]
          @frame=0
        end
        @actualBitmap.clear
        @actualBitmap.stretch_blt(Rect.new(0,0,@width,@height),@bitmap,Rect.new(@currentIndex*(@width/@scale),0,@width/@scale,@height/@scale))
        # updates the actual bitmap
      end
      alias update_elite update
    
      # returns bitmap to original state
      def deanimate
        @frame=0
        @currentIndex=0
        @actualBitmap.clear
        @actualBitmap.stretch_blt(Rect.new(0,0,@width,@height),@bitmap,Rect.new(@currentIndex*(@width/@scale),0,@width/@scale,@height/@scale))
      end
    end
    
    ##############################################################
    # Evolution differences
    ##############################################################
    def pbGetEvolvedFormData(species,delta=false)
      ret=[]
      _EVOTYPEMASK=0x3F
      _EVODATAMASK=0xC0
      _EVONEXTFORM=0x00
      pbRgssOpen("Data/evolutions.dat","rb"){|f|
         f.pos=(species-1)*8
         offset=f.fgetdw
         length=f.fgetdw
         if length>0
           f.pos=offset
           i=0; loop do break unless i<length
             evo=f.fgetb
             evonib=evo&_EVOTYPEMASK
             level=f.fgetw
             poke=f.fgetw
             if (evo&_EVODATAMASK)==_EVONEXTFORM
               ret.push([evonib,level,poke])
             end
             i+=5
           end
         end
      }
      if delta
        ret[0][0]=27 if isConst?(species,PBSpecies,:RATTATA) # Alolan Rattata only evolves at night
        ret[0][0]=1 if isConst?(species,PBSpecies,:MEOWTH) # Alolan Meowth evolves via friendship
        # Alolan Vulpix and Alolan Sandshrew evolve via the Ice Stone if it exists
        ret[0][2]=getConst(PBItems,:ICESTONE) if isConst?(species,PBSpecies,:VULPIX) && getConst(PBItems,:ICESTONE)!=nil
        ret[0][0]=7 if isConst?(species,PBSpecies,:SANDSHREW) && getConst(PBItems,:ICESTONE)!=nil
        ret[0][2]=getConst(PBItems,:ICESTONE) if isConst?(species,PBSpecies,:SANDSHREW) && getConst(PBItems,:ICESTONE)!=nil
      end
      return ret
    end
    
    def pbCheckEvolutionEx(pokemon)
      return -1 if pokemon.species<=0 || pokemon.isEgg?
      return -1 if isConst?(pokemon.species,PBSpecies,:PICHU) && pokemon.form==1
      return -1 if isConst?(pokemon.item,PBItems,:EVERSTONE) &&
                   !isConst?(pokemon.species,PBSpecies,:KADABRA)
      ret=-1
      for form in pbGetEvolvedFormData(pokemon.species,pokemon.isDelta?)
        ret=yield pokemon,form[0],form[1],form[2]
        break if ret>0
      end
      return ret
    end
    
    # Pikachu, Cubone (at night), and Exeggcute holding the Strange Souvenir
    #    will evolve into Alolan Raichu, Alolan Marowak, and Alolan Exeggutor
    #    respectively.  (The item will not be consumed.)
    # Remove this function if you wish this not to be the case.
    class PokemonEvolutionScene
      def pbStartScreen(pokemon,newspecies)
        @sprites={}
        @bgviewport=Viewport.new(0,0,Graphics.width,Graphics.height)
        @bgviewport.z=99999
        @viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
        @viewport.z=99999
        @msgviewport=Viewport.new(0,0,Graphics.width,Graphics.height)
        @msgviewport.z=99999
        @pokemon=pokemon
        @newspecies=newspecies
        addBackgroundOrColoredPlane(@sprites,"background","evolutionbg",
           Color.new(248,248,248),@bgviewport)
        rsprite1=PokemonSprite.new(@viewport)
        rsprite2=PokemonSprite.new(@viewport)
        rsprite1.setPokemonBitmap(@pokemon,false)
        if isConst?(pokemon.item,PBItems,:STRANGESOUVENIR)
          if (isConst?(@newspecies,PBSpecies,:MAROWAK) && PBDayNight.isNight?) ||
              isConst?(@newspecies,PBSpecies,:RAICHU) ||
              isConst?(@newspecies,PBSpecies,:EXEGGUTOR)
            @pokemon.makeDelta
          end
        end
        rsprite2.setPokemonBitmapSpecies(@pokemon,@newspecies,false)
        rsprite1.ox=rsprite1.bitmap.width/2
        rsprite1.oy=rsprite1.bitmap.height/2
        rsprite2.ox=rsprite2.bitmap.width/2
        rsprite2.oy=rsprite2.bitmap.height/2
        rsprite1.x=Graphics.width/2
        rsprite1.y=(Graphics.height-64)/2
        rsprite2.x=rsprite1.x
        rsprite2.y=rsprite1.y
        rsprite2.opacity=0
        @sprites["rsprite1"]=rsprite1
        @sprites["rsprite2"]=rsprite2
        pbGenerateMetafiles(rsprite1.ox,rsprite1.oy,rsprite2.ox,rsprite2.oy)
        @sprites["msgwindow"]=Kernel.pbCreateMessageWindow(@msgviewport)
        pbFadeInAndShow(@sprites) { pbUpdate }
      end
    end
    
    ##############################################################
    # Alolan Form differences
    ##############################################################
    
    MultipleForms.register(:RATTATA,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:GLUTTONY),0],
              [getID(PBAbilities,:HUSTLE),1],
              [getID(PBAbilities,:THICKFAT),2]]
      end
      next
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:HIDDENPOWER,:SUNNYDAY,:TAUNT,:ICEBEAM,
                 :BLIZZARD,:PROTECT,:RAINDANCE,:FRUSTRATION,:RETURN,
                 :SHADOWBALL,:DOUBLETEAM,:SLUDGEBOMB,:TORMENT,:FACADE,
                 :REST,:ATTRACT,:THIEF,:ROUND,:QUASH,
                 :EMBARGO,:SHADOWCLAW,:GRASSKNOT,:SWAGGER,:SLEEPTALK,
                 :UTURN,:SUBSTITUTE,:SNARL,:DARKPULSE,:CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:COUNTER,:FINALGAMBIT,:FURYSWIPES,:MEFIRST,:REVENGE,
                 :REVERSAL,:SNATCH,:STOCKPILE,:SWALLOW,:SWITCHEROO,
                 :UPROAR]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:RATICATE,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 25.5 if pokemon.isDelta?
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [75,71,70,77,40,80] if pokemon.isDelta?
       next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:GLUTTONY),0],
              [getID(PBAbilities,:HUSTLE),1],
              [getID(PBAbilities,:THICKFAT),2]]
      end
      next
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:HIDDENPOWER,:SUNNYDAY,:TAUNT,:ICEBEAM,
                 :BLIZZARD,:PROTECT,:RAINDANCE,:FRUSTRATION,:RETURN,
                 :SHADOWBALL,:DOUBLETEAM,:SLUDGEBOMB,:TORMENT,:FACADE,
                 :REST,:ATTRACT,:THIEF,:ROUND,:QUASH,
                 :EMBARGO,:SHADOWCLAW,:GRASSKNOT,:SWAGGER,:SLEEPTALK,
                 :UTURN,:SUBSTITUTE,:SNARL,:DARKPULSE,:CONFIDE,
                 :ROAR,:BULKUP,:VENOSHOCK,:SUNNYDAY,:HYPERBEAM,
                 :SLUDGEWAVE,:GIGAIMPACT,:SWORDSDANCE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:RAICHU,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:PSYCHIC) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 0.7 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 21.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:SURGESURFER),0],
                    [getID(PBAbilities,:SURGESURFER),2]]
      end
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [60,85,50,110,95,85] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[]
       movelist=[[1,:PSYCHIC],[1,:SPEEDSWAP],[1,:THUNDERSHOCK],
                 [1,:TAILWHIP],[1,:QUICKATTACK],[1,:THUNDERBOLT]]
       for i in movelist
         i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :PSYSHOCK,:CALMMIND,:TOXIC,:HIDDENPOWER,:HYPERBEAM,
                 :LIGHTSCREEN,:PROTECT,:RAINDANCE,:SAFEGUARD,:FRUSTRATION,
                 :THUNDERBOLT,:THUNDER,:RETURN,:PSYCHIC,:BRICKBREAK,
                 :DOUBLETEAM,:REFLECT,:FACADE,:REST,:ATTRACT,
                 :THIEF,:ROUND,:ECHOEDVOICE,:FOCUSBLAST,:FLING,
                 :CHARGEBEAM,:GIGAIMPACT,:VOLTSWITCH,:THUNDERWAVE,
                 :GRASSKNOT,:SWAGGER,:SLEEPTALK,:SUBSTITUTE,
                 :WILDCHARGE,:CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:SANDSHREW,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:ICE) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:STEEL) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 0.6 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 40.0 if pokemon.isDelta?
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [50,75,90,40,10,35] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:SCRATCH],[1,:DEFENSECURL],[3,:BIDE],[5,:PODERSNOW],
                  [7,:ICEBALL],[9,:RAPIDSPIN],[11,:FURYCUTTER],[14,:METALCLAW],
                  [17,:SWIFT],[20,:FURYSWIPES],[23,:IRONDEFENSE],[26,:SLASH],
                  [30,:IRONHEAD],[34,:GYROBALL],[38,:SWORDSDANCE],[42,:HAIL],
                  [46,:BLIZZARD]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :WORKUP,:TOXIC,:HAIL,:HIDDENPOWER,:SUNNYDAY,
                 :BLIZZARD,:PROTECT,:SAFEGUARD,:FRUSTRATION,:EARTHQUAKE,
                 :RETURN,:LEECHLIFE,:BRICKBREAK,:DOUBLETEAM,:AERIALACE,
                 :FACADE,:REST,:ATTRACT,:THIEF,:ROUND,
                 :FLING,:SHADOWCLAW,:AURORAVEIL,:GYROBALL,:SWORDSDANCE,
                 :BULLDOZE,:FROSTBREATH,:ROCKSLIDE,:XSCISSOR,
                 :POISONJAB,:SWAGGER,:SLEEPTALK,:SUBSTITUTE,
                 :CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:AMNESIA,:CHIPAWAY,:COUNTER,:CRUSHCLAW,:CURSE,
                 :ENDURE,:FLAIL,:ICICLECRASH,:ICICLESPEAR,:METALCLAW,
                 :NIGHTSLASH]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:SNOWCLOAK),0]] if getID(PBAbilities,:SLUSHRUSH)==nil
        next [[getID(PBAbilities,:SNOWCLOAK),0],
              [getID(PBAbilities,:SLUSHRUSH),2]]
      end
      next
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:SANDSLASH,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:ICE) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:STEEL) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 1.2 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 55.0 if pokemon.isDelta?
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [75,100,120,65,25,65] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:ICICLESPEAR],[1,:METALBURST],[1,:ICICLECRASH],[1,:SLASH],
                  [1,:DEFENSECURL],[1,:ICEBALL],[1,:METALCLAW]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :WORKUP,:TOXIC,:HAIL,:HIDDENPOWER,:SUNNYDAY,
                 :BLIZZARD,:PROTECT,:SAFEGUARD,:FRUSTRATION,:EARTHQUAKE,
                 :RETURN,:LEECHLIFE,:BRICKBREAK,:DOUBLETEAM,:AERIALACE,
                 :FACADE,:REST,:ATTRACT,:THIEF,:ROUND,
                 :FLING,:SHADOWCLAW,:AURORAVEIL,:GYROBALL,:SWORDSDANCE,
                 :BULLDOZE,:FROSTBREATH,:ROCKSLIDE,:XSCISSOR,
                 :POISONJAB,:SWAGGER,:SLEEPTALK,:SUBSTITUTE,
                 :CONFIDE,:HYPERBEAM,:FOCUSBLAST,:GIGAIMPACT]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:SNOWCLOAK),0]] if getID(PBAbilities,:SLUSHRUSH)==nil
        next [[getID(PBAbilities,:SNOWCLOAK),0],
              [getID(PBAbilities,:SLUSHRUSH),2]]
      end
      next
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:VULPIX,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:ICE) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:ICE) if pokemon.isDelta?
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:POWDERSNOW],[4,:TAILWHIP],[7,:ROAR],[9,:BABYDOLLEYES],
                  [10,:ICESHARD],[12,:CONFUSERAY],[15,:ICYWIND],
                  [18,:PAYBACK],[20,:MIST],[23,:FEINTATTACK],[26,:HEX],
                  [28,:AURORABEAM],[31,:EXTRASENSORY],[34,:SAFEGUARD],
                  [36,:ICEBEAM],[39,:IMPRISON],[42,:BLIZZARD],[44,:GRUDGE],
                  [47,:CAPTIVATE],[50,:SHEERCOLD]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :ROAR,:TOXIC,:HAIL,:HIDDENPOWER,:ICEBEAM,
                 :BLIZZARD,:PROTECT,:RAINDANCE,:SAFEGUARD,:FRUSTRATION,
                 :RETURN,:DOUBLETEAM,:FACADE,:REST,:ATTRACT,:ROUND,
                 :PAYBACK,:AURORAVEIL,:PSYCHUP,:FROSTBREATH,
                 :SWAGGER,:SLEEPTALK,:SUBSTITUTE,
                 :CONFIDE,:DARKPULSE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:AGILITY,:CHARM,:DISABLE,:ENCORE,:EXTRASENSORY,
                 :FLAIL,:FREEZEDRY,:HOWL,:HYPNOSIS,:MOONBLAST,
                 :POWERSWAP,:SPITE,:SECRETPOWER,:TAILSLAP]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:SNOWCLOAK),0],
              [getID(PBAbilities,:SNOWWARNING),2]]
      end
      next
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:NINETAILS,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:ICE) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:FAIRY) if pokemon.isDelta?
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [73,67,75,109,81,100] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:DAZZLINGGLEAM],[1,:IMPRISON],[1,:NASTYPLOT],[1,:ICEBEAM],
                  [1,:ICESHARD],[1,:CONFUSERAY],[1,:SAFEGUARD]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :ROAR,:TOXIC,:HAIL,:HIDDENPOWER,:ICEBEAM,
                 :BLIZZARD,:PROTECT,:RAINDANCE,:SAFEGUARD,:FRUSTRATION,
                 :RETURN,:DOUBLETEAM,:FACADE,:REST,:ATTRACT,:ROUND,
                 :PAYBACK,:AURORAVEIL,:PSYCHUP,:FROSTBREATH,
                 :SWAGGER,:SLEEPTALK,:SUBSTITUTE,:CONFIDE,:DARKPULSE,
                 :PSYSHOCK,:CALMMIND,:GIGAIMPACT,:DREAMEATER,:DAZZLINGGLEAM]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:SNOWCLOAK),0],
              [getID(PBAbilities,:SNOWWARNING),2]]
      end
      next
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:DIGLETT,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:STEEL) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 1.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:TANGLINGHAIR)==nil
          next [[getID(PBAbilities,:SANDVEIL),0],
                [getID(PBAbilities,:GOOEY),1],
                [getID(PBAbilities,:SANDFORCE),2]]
        end
        next [[getID(PBAbilities,:SANDVEIL),0],
              [getID(PBAbilities,:TANGLEDHAIR),1],
              [getID(PBAbilities,:SANDFORCE),2]]
      end
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [10,55,30,90,35,45] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:SANDATTACK],[1,:METALCLAW],[4,:GROWL],[7,:ASTONISH],
                  [10,:MUDSLAP],[14,:MAGNITUDE],[18,:BULLDOZE],
                  [22,:SUCKERPUNCH],[25,:MUDBOMB],[28,:EARTHPOWER],[31,:DIG],
                  [35,:IRONHEAD],[39,:EARTHQUAKE],[43,:FISSURE]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :WORKUP,:TOXIC,:HIDDENPOWER,:SUNNYDAY,:PROTECT,
                 :FRUSTRATION,:EARTHQUAKE,:RETURN,:DOUBLETEAM,
                 :SLUDGEBOMB,:SANDSTORM,:ROCKTOMB,:AERIELACE,:FACADE,
                 :REST,:ATTRACT,:THIEF,:ROUND,:ECHOEDVOICE,
                 :SHADOWCLAW,:BULLDOZE,:ROCKSLIDE,:SWAGGER,:SLEEPTALK,
                 :SUBSTITUTE,:FLASHCANNON,:CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:ANCIENTPOWER,:BEATUP,:ENDURE,:FEINTATTACK,
                 :FINALGAMBIT,:HEADBUTT,:MEMENTO,:METALSOUND,
                 :PURSUIT,:REVERSAL,:THRASH]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:DUGTRIO,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:STEEL) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 66.6 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:TANGLINGHAIR)==nil
          next [[getID(PBAbilities,:SANDVEIL),0],
                [getID(PBAbilities,:GOOEY),1],
                [getID(PBAbilities,:SANDFORCE),2]]
        end
        next [[getID(PBAbilities,:SANDVEIL),0],
              [getID(PBAbilities,:TANGLEDHAIR),1],
              [getID(PBAbilities,:SANDFORCE),2]]
      end
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [35,100,60,110,50,70] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:SANDTOMB],[1,:ROTOTILLER],[1,:NIGHTSLASH],
                  [1,:TRIATTACK],[1,:SANDATTACK],[1,:METALCLAW],
                  [1,:GROWL],[4,:GROWL],[7,:ASTONISH],
                  [10,:MUDSLAP],[14,:MAGNITUDE],[18,:BULLDOZE],
                  [22,:SUCKERPUNCH],[25,:MUDBOMB],[30,:EARTHPOWER],[35,:DIG],
                  [41,:IRONHEAD],[47,:EARTHQUAKE],[53,:FISSURE]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :WORKUP,:TOXIC,:HIDDENPOWER,:SUNNYDAY,:PROTECT,
                 :FRUSTRATION,:EARTHQUAKE,:RETURN,:DOUBLETEAM,
                 :SLUDGEBOMB,:SANDSTORM,:ROCKTOMB,:AERIELACE,:FACADE,
                 :REST,:ATTRACT,:THIEF,:ROUND,:ECHOEDVOICE,
                 :SHADOWCLAW,:BULLDOZE,:ROCKSLIDE,:SWAGGER,:SLEEPTALK,
                 :SUBSTITUTE,:FLASHCANNON,:CONFIDE,:HYPERBEAM,
                 :SLUDGEWAVE,:GIGAIMPACT,:STONEEDGE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:MEOWTH,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:PICKUP),0],
              [getID(PBAbilities,:TECHNICIAN),1],
              [getID(PBAbilities,:RATTLED),2]]
      end
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [40,35,34,90,50,40] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:SCRATCH],[1,:GROWL],[6,:BITE],[9,:FAKEOUT],
                  [14,:FURYSWIPES],[17,:SCREECH],[22,:FEINTATTACK],
                  [25,:TAUNT],[30,:PAYDAY],[33,:SLASH],[38,:NASTYPLOT],
                  [41,:ASSURANCE],[46,:CAPTIVATE],[49,:NIGHTSLASH],
                  [50,:FEINT],[55,:DARKPULSE]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :WORKUP,:TOXIC,:HIDDENPOWER,:SUNNYDAY,:TAUNT,:PROTECT,
                 :RAINDANCE,:FRUSTRATION,:THUNDERBOLT,:THUNDER,:RETURN,
                 :SHADOWBALL,:DOUBLETEAM,:AERIELACE,:TORMENT,:FACADE,
                 :REST,:ATTRACT,:THIEF,:ROUND,:ECHOEDVOICE,:QUASH,
                 :EMBARGO,:SHADOWCLAW,:PAYBACK,:PSYCHUP,:DREAMEATER,
                 :SWAGGER,:SLEEPTALK,:UTURN,:SUBSTITUTE,:DARKPULSE,
                 :CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:AMNESIA,:ASSIST,:CHARM,:COVET,:FLAIL,:FLATTER,
                 :FOULPLAY,:HYPNOSIS,:PARTINGSHOT,:PUNISHMENT,
                 :SNATCH,:SPITE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:PERSIAN,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 1.1 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 33.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:FURCOAT),0],
              [getID(PBAbilities,:TECHNICIAN),1],
              [getID(PBAbilities,:RATTLED),2]]
      end
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [65,60,60,115,75,65] if pokemon.isDelta?
       next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:SWIFT],[1,:QUASH],[1,:PLAYROUGH],[1,:SWITCHEROO],
                  [1,:SCRATCH],[1,:GROWL],[1,:BITE],[1,:FAKEOUT],
                  [6,:BITE],[9,:FAKEOUT],[14,:FURYSWIPES],[17,:SCREECH],
                  [22,:FEINTATTACK],[25,:TAUNT],[32,:POWERGEM],[37,:SLASH],
                  [44,:NASTYPLOT],[49,:ASSURANCE],[56,:CAPTIVATE],
                  [61,:NIGHTSLASH],[65,:FEINT],[69,:DARKPULSE]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :WORKUP,:TOXIC,:HIDDENPOWER,:SUNNYDAY,:TAUNT,:PROTECT,
                 :RAINDANCE,:FRUSTRATION,:THUNDERBOLT,:THUNDER,:RETURN,
                 :SHADOWBALL,:DOUBLETEAM,:AERIELACE,:TORMENT,:FACADE,
                 :REST,:ATTRACT,:THIEF,:ROUND,:ECHOEDVOICE,:QUASH,
                 :EMBARGO,:SHADOWCLAW,:PAYBACK,:PSYCHUP,:DREAMEATER,
                 :SWAGGER,:SLEEPTALK,:UTURN,:SUBSTITUTE,:DARKPULSE,
                 :CONFIDE,:ROAR,:HYPERBEAM,:GIGAIMPACT,:SNARL]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:GEODUDE,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:ELECTRIC) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 20.3 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:GALVANIZE)==nil
          next [[getID(PBAbilities,:MAGNETPULL),0],
                [getID(PBAbilities,:STURDY),1]]
        end
        next [[getID(PBAbilities,:MAGNETPULL),0],
              [getID(PBAbilities,:STURDY),1],
              [getID(PBAbilities,:GALVANIZE),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:TACKLE],[1,:DEFENSECURL],[4,:CHARGE],[6,:ROCKPOLISH],
                  [10,:ROLLOUT],[12,:SPARK],[16,:ROCKTHROW],[18,:SMACKDOWN],
                  [22,:THUNDERPUNCH],[24,:SELFDESTRUCT],[28,:STEALTHROCK],
                  [30,:ROCKBLAST],[34,:DISCHARGE],[36,:EXPLOSION],
                  [40,:DOUBLEEDGE],[42,:STONEEDGE]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:HIDDENPOWER,:SUNNYDAY,:PROTECT,:SMACKDOWN,
                 :THUNDERBOLT,:THUNDER,:EARTHQUAKE,:RETURN,:BRICKBREAK,
                 :DOUBLETEAM,:FLAMETHROWER,:SANDSTORM,:FIREBLAST,
                 :ROCKTOMB,:FACADE,:REST,:ATTRACT,:ROUND,
                 :FLING,:CHARGEBEAM,:BRUTALSWING,:EXPLOSION,
                 :ROCKPOLISH,:STONEEDGE,:VOLTSWITCH,:GYROBALL,
                 :BULLDOZE,:ROCKSLIDE,:SWAGGER,:SLEEPTALK,
                 :SUBSTITUTE,:NATUREPOWER,:CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:AUTOTOMIZE,:BLOCK,:COUNTER,:CURSE,:ENDURE,:FLAIL,
                 :MAGNETRISE,:ROCKCLIMB,:SCREECH,:WIDEGUARD]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:GRAVELER,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:ELECTRIC) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 110.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:GALVANIZE)==nil
          next [[getID(PBAbilities,:MAGNETPULL),0],
                [getID(PBAbilities,:STURDY),1]]
        end
        next [[getID(PBAbilities,:MAGNETPULL),0],
              [getID(PBAbilities,:STURDY),1],
              [getID(PBAbilities,:GALVANIZE),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:TACKLE],[1,:DEFENSECURL],[1,:CHARGE],[1,:ROCKPOLISH],
                  [4,:CHARGE],[6,:ROCKPOLISH],[10,:ROLLOUT],[12,:SPARK],
                  [16,:ROCKTHROW],[18,:SMACKDOWN],[22,:THUNDERPUNCH],
                  [24,:SELFDESTRUCT],[30,:STEALTHROCK],[34,:ROCKBLAST],
                  [40,:DISCHARGE],[44,:EXPLOSION],[50,:DOUBLEEDGE],
                  [54,:STONEEDGE]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:HIDDENPOWER,:SUNNYDAY,:PROTECT,:SMACKDOWN,
                 :THUNDERBOLT,:THUNDER,:EARTHQUAKE,:RETURN,:BRICKBREAK,
                 :DOUBLETEAM,:FLAMETHROWER,:SANDSTORM,:FIREBLAST,
                 :ROCKTOMB,:FACADE,:REST,:ATTRACT,:ROUND,
                 :FLING,:CHARGEBEAM,:BRUTALSWING,:EXPLOSION,
                 :ROCKPOLISH,:STONEEDGE,:VOLTSWITCH,:GYROBALL,
                 :BULLDOZE,:ROCKSLIDE,:SWAGGER,:SLEEPTALK,
                 :SUBSTITUTE,:NATUREPOWER,:CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:GOLEM,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:ELECTRIC) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 110.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:GALVANIZE)==nil
          next [[getID(PBAbilities,:MAGNETPULL),0],
                [getID(PBAbilities,:STURDY),1]]
        end
        next [[getID(PBAbilities,:MAGNETPULL),0],
              [getID(PBAbilities,:STURDY),1],
              [getID(PBAbilities,:GALVANIZE),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:HEAVYSLAM],[1,:TACKLE],[1,:DEFENSECURL],[1,:CHARGE],
                  [1,:ROCKPOLISH],[4,:CHARGE],[6,:ROCKPOLISH],
                  [10,:STEAMROLLER],[12,:SPARK],[16,:ROCKTHROW],
                  [18,:SMACKDOWN],[22,:THUNDERPUNCH],[24,:SELFDESTRUCT],
                  [30,:STEALTHROCK],[34,:ROCKBLAST],[40,:DISCHARGE],
                  [44,:EXPLOSION],[50,:DOUBLEEDGE],[54,:STONEEDGE],
                  [60,:HEAVYSLAM]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:HIDDENPOWER,:SUNNYDAY,:PROTECT,:SMACKDOWN,
                 :THUNDERBOLT,:THUNDER,:EARTHQUAKE,:RETURN,:BRICKBREAK,
                 :DOUBLETEAM,:FLAMETHROWER,:SANDSTORM,:FIREBLAST,
                 :ROCKTOMB,:FACADE,:REST,:ATTRACT,:ROUND,
                 :FLING,:CHARGEBEAM,:BRUTALSWING,:EXPLOSION,
                 :ROCKPOLISH,:STONEEDGE,:VOLTSWITCH,:GYROBALL,
                 :BULLDOZE,:ROCKSLIDE,:SWAGGER,:SLEEPTALK,
                 :SUBSTITUTE,:NATUREPOWER,:CONFIDE,:ROAR,:HYPERBEAM,
                 :FRUSTRATION,:ECHOEDVOICE,:FOCUSBLAST,:GIGAIMPACT,
                 :WILDCHARGE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:GRIMER,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 0.7 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 42.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:POWEROFALCHEMY)==nil
          if getID(PBAbilities,:RECEIVER)==nil
            next [[getID(PBAbilities,:POISONTOUCH),0],
                  [getID(PBAbilities,:GLUTTONY),1]]
          end
          next [[getID(PBAbilities,:POISONTOUCH),0],
                [getID(PBAbilities,:GLUTTONY),1],
                [getID(PBAbilities,:RECEIVER),2]]
        end
        next [[getID(PBAbilities,:POISONTOUCH),0],
              [getID(PBAbilities,:GLUTTONY),1],
              [getID(PBAbilities,:POWEROFALCHEMY),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:POUND],[1,:POISONGAS],[4,:HARDEN],[7,:BITE],[12,:DISABLE],
                  [15,:ACIDSPRAY],[18,:POISONFANG],[21,:MINIMIZE],[26,:FLING],
                  [29,:KNOCKOFF],[32,:CRUNCH],[37,:SCREECH],[40,:GUNKSHOT],
                  [43,:ACIDARMOR],[46,:BELCH],[48,:MEMENTO]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:VENOSHOCK,:HIDDENPOWER,:SUNNYDAY,:TAUNT,
                 :PROTECT,:RAINDANCE,:FRUSTRATION,:RETURN,:SHADOWBALL,
                 :DOUBLETEAM,:SLUDGEWAVE,:FLAMETHROWER,:SLUDGEBOMB,
                 :FIREBLAST,:ROCKTOMB,:TORMENT,:FACADE,:REST,:ATTRACT,
                 :THIEF,:ROUND,:FLING,:BRUTALSWING,:QUASH,:EMBARGO,
                 :EXPLOSION,:PAYBACK,:ROCKPOLISH,:STONEEDGE,:INFESTATION,
                 :POISONJAB,:SWAGGER,:SLEEPTALK,:SUBSTITUTE,:SNARL,:CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "possibleEggMoves"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[:ASSURANCE,:CLEARSMOG,:CURSE,:IMPRISION,:MEANLOOK,:PURSUIT,
                 :SCARYFACE,:SHADOWSNEAK,:SPITE,:STOCKPILE,:SPITUP,:SWALLOW]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:MUK,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:DARK) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 1.0 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 52.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        if getID(PBAbilities,:POWEROFALCHEMY)==nil
          if getID(PBAbilities,:RECEIVER)==nil
            next [[getID(PBAbilities,:POISONTOUCH),0],
                  [getID(PBAbilities,:GLUTTONY),1]]
          end
          next [[getID(PBAbilities,:POISONTOUCH),0],
                [getID(PBAbilities,:GLUTTONY),1],
                [getID(PBAbilities,:RECEIVER),2]]
        end
        next [[getID(PBAbilities,:POISONTOUCH),0],
              [getID(PBAbilities,:GLUTTONY),1],
              [getID(PBAbilities,:POWEROFALCHEMY),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:VENOMDRENCH],[1,:POUND],[1,:POISONGAS],[1,:HARDEN],
                  [1,:BITE],[4,:HARDEN],[7,:BITE],[12,:DISABLE],
                  [15,:ACIDSPRAY],[18,:POISONFANG],[21,:MINIMIZE],[26,:FLING],
                  [29,:KNOCKOFF],[32,:CRUNCH],[37,:SCREECH],[40,:GUNKSHOT],
                  [46,:ACIDARMOR],[52,:BELCH],[57,:MEMENTO]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1]) if getConst(PBMoves,movelist[i])!=nil
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:VENOSHOCK,:HIDDENPOWER,:SUNNYDAY,:TAUNT,
                 :PROTECT,:RAINDANCE,:FRUSTRATION,:RETURN,:SHADOWBALL,
                 :DOUBLETEAM,:SLUDGEWAVE,:FLAMETHROWER,:SLUDGEBOMB,
                 :FIREBLAST,:ROCKTOMB,:TORMENT,:FACADE,:REST,:ATTRACT,
                 :THIEF,:ROUND,:FLING,:BRUTALSWING,:QUASH,:EMBARGO,
                 :EXPLOSION,:PAYBACK,:ROCKPOLISH,:STONEEDGE,:INFESTATION,
                 :POISONJAB,:SWAGGER,:SLEEPTALK,:SUBSTITUTE,:SNARL,
                 :CONFIDE,:HYPERBEAM,:BRICKBREAK,:FOCUSBLAST,
                 :GIGAIMPACT,:DARKPULSE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:EXEGGUTOR,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:DRAGON) if pokemon.isDelta?
      next
    },
    "height"=>proc{|pokemon|
      next 10.9 if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 415.6 if pokemon.isDelta?
      next
    },
    "getBaseStats"=>proc{|pokemon|
       next [95,105,85,45,125,75] if pokemon.isDelta?
       next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:FRISK),0],
              [getID(PBAbilities,:HARVEST),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:DRAGONHAMMER],[1,:SEEDBOMB],[1,:BARRAGE],[1,:HYPNOSIS],
                  [1,:CONFUSION],[17,:PSYSHOCK],[27,:EGGBOMB],[37,:WOODHAMMER],
                  [47,:LEAFSTORM]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1])
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :PSYSHOCK,:TOXIC,:HIDDENPOWER,:SUNNYDAY,:HYPERBEAM,
                 :LIGHTSCREEN,:PROTECT,:FRUSTRATION,:SOLARBEAM,:EARTHQUAKE,
                 :RETURN,:PSYCHIC,:BRICKBREAK,:DOUBLETEAM,:REFLECT,
                 :FLAMETHROWER,:SLUDGEBOMB,:FACADE,:REST,:ATTRACT,
                 :THIEF,:ROUND,:ENERGYBALL,:BRUTALSWING,:EXPLOSION,
                 :GIGAIMPACT,:SWORDSDANCE,:PSYCHUP,:BULLDOZE,:DRAGONTAIL,
                 :INFESTATION,:DREAMEATER,:GRASSKNOT,:SWAGGER,:SLEEPTALK,
                 :SUBSTITUTE,:TRICKEROOM,:NATUREPOWER,:CONFIDE,:DRACOMETEOR]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    MultipleForms.register(:MAROWAK,{
    "getFormName"=>proc{|pokemon|
      next _INTL("Alola Form") if pokemon.isDelta?
      next
    },
    "type1"=>proc{|pokemon|
      next getID(PBTypes,:FIRE) if pokemon.isDelta?
      next
    },
    "type2"=>proc{|pokemon|
      next getID(PBTypes,:GHOST) if pokemon.isDelta?
      next
    },
    "weight"=>proc{|pokemon|
      next 34.0 if pokemon.isDelta?
      next
    },
    "getAbilityList"=>proc{|pokemon|
      if pokemon.isDelta?
        next [[getID(PBAbilities,:CURSEDBODY),0],
              [getID(PBAbilities,:LIGHTNINGROD),1],
              [getID(PBAbilities,:ROCKHEAD),2]]
      end
      next
    },
    "getMoveList"=>proc{|pokemon|
      next if !pokemon.isDelta?
      movelist=[]
      if pokemon.isDelta?
        movelist=[[1,:GROWL],[1,:TAILWHIP],[1,:BONECLUB],[1,:FLAMEWHEEL],
                  [3,:TAILWHIP],[7,:BONECLUB],[11,:FLAMEWHEEL],[13,:LEER],
                  [17,:HEX],[21,:BONEMERANG],[23,:WILLOWISP],[27,:SHADOWBONE],
                  [33,:THRASH],[37,:FLING],[43,:STOMPINGTANTRUM],[49,:ENDEAVOR],
                  [53,:FLAREBLITZ],[59,:RETALIATE],[65,:BONERUSH]]
      end
      for i in movelist
        i[1]=getConst(PBMoves,i[1])
      end
      next movelist
    },
    "getMoveCompatibility"=>proc{|pokemon|
       next if !pokemon.isDelta?
       movelist=[# TMs
                 :TOXIC,:HIDDENPOWER,:SUNNYDAY,:ICEBEAM,:BLIZZARD,:HYPERBEAM,
                 :PROTECT,:RAINDANCE,:FRUSTRATION,:SMACKDOWN,:THUNDERBOLT,
                 :THUNDER,:EARTHQUAKE,:RETURN,:SHADOWBALL,:BRICKBREAK,:DOUBLETEAM,
                 :FLAMETHROWER,:SANDSTORM,:FIREBLAST,:ROCKTOMB,:AERIALACE,:FACADE,
                 :FLAMECHARGE,:REST,:ATTRACT,:THIEF,:ROUND,:ECHOEDVOICE,
                 :FOCUSBLAST,:FALSESWIPE,:FLING,:BRUTALSWING,:WILLOWISP,
                 :GIGAIMPACT,:STONEEDGE,:SWORDSDANCE,:BULLDOZE,:ROCKSLIDE,
                 :DREAMEATER,:SWAGGER,:SLEEPTALK,:SUBSTITUTE,:DARKPULSE,
                 :CONFIDE]
       for i in 0...movelist.length
         movelist[i]=getConst(PBMoves,movelist[i]) if getConst(PBMoves,movelist[i])!=nil
       end
       next movelist
    },
    "onSetForm"=>proc{|pokemon,form|
      pbSeenForm(pokemon)
    }
    })
    
    ###################################################################
    # EXAMPLE ENCOUNTER MODIFIER
    # This makes Exeggutor that are created on a particular map
    #    become Alolan Exeggutor automatically.
    # Evolving Exeggcute on this map will not make them become Alolan
    #    Exeggutor.  Only wild Exeggutor.
    # "pokemon.makeDelta" is how to make the Pokemon a Delta/Alolan
    ###################################################################
    # Events.onWildPokemonCreate+=proc {|sender,e|
    #    pokemon=e[0]
    #    if $game_map.map_id==51 && isConst?(pokemon.species,PBSpecies,:EXEGGUTOR)
    #      pokemon.makeDelta
    #    end
    # }
    
    ###################################################################
    # EXAMPLE RANDOM SPAWNER MODIFIER
    # This makes Delta/Alolan Pokemon spawn randomly, at the same rate
    #    as Shiny Pokemon do
    # Note that this method doesn't allow for Shiny Delta/Alolan
    #    Pokemon, as the possible numbers for it don't overlap.
    # Note also that this does not make a Delta for every species.
    #    If a species doesn't have a Delta/Alolan Form defined, than
    #    this function is meaningless.
    ###################################################################
    # class PokeBattle_Pokemon
    #   def isDelta?
    #     return @deltaflag if @deltaflag!=nil
    #     a=@personalID^@trainerID
    #     b=a&0xFFFF
    #     c=(a>>16)&0xFFFF
    #     d=b^c
    #     return (d>65536-SHINYPOKEMONCHANCE)
    #   end
    # end

    In order to make a sprite for an Alolan Pokemon, name the sprite "###d.png", where the ### is replaced with the National Pokedex number of the species. For example, Alolan Ninetales's sprite would be named "038d.png". This can be combined with the existing modifiers - "###sd.png" for a Shiny Alolan Pokemon, "###db.png" for the backsprite of an Alolan Pokemon, "##fd.png" for a female Alolan Pokemon, "###d_1.png" for the (numbered) alternate form of an Alolan Pokemon, etc. (In order to do the backsprite for a female Shiny Alolan Pokemon in a numbered alternate form, the proper syntax is "###fsdb_1.png")
     
    Last edited:
    824
    Posts
    8
    Years
  • I Think this script very awesome!

    It's a very dumbed down version of the way Delta Pokemon work in my game, (dumbed down because I needed to make it plug-and-play). I've previously avoided telling anyone what code changes I made, but now that it appears that Game Freak is going down the same path I did, there's no longer the excuse of "wanting to keep this feature unique to my own game".
     

    Sir_Tman

    Overworked game Dev
    201
    Posts
    8
    Years
  • Dear lord we only just got Alola Forms announced the other day. So how would this work for mega evolutions? Do we need to add a line in to check if its Alola Form?
     
    824
    Posts
    8
    Years
  • Dear lord we only just got Alola Forms announced the other day
    This is a variation of code I was already using in my own game for over a year now. Game Freak's reveal of Alola Forms just prompted me to go public with it.

    So how would this work for mega evolutions? Do we need to add a line in to check if its Alola Form?
    Well, at the moment we don't have any Alolan Forms that can Mega Evolve, so we don't know if they'll have their own Mega Stones or use the basic ones for their species.

    But, in my own game, Steelix has a Mega form and a Delta form, and the Delta form has a different Mega from the non-Delta. Here's my code for Steelix, so you can see how I did it.

    Code:
    MultipleForms.register(:STEELIX,{
    "getMegaForm"=>proc{|pokemon|
       next 1 if isConst?(pokemon.item,PBItems,:STEELIXITE)
       next
    },
    "getUnmegaForm"=>proc{|pokemon|
       next 0
    },
    "getMegaName"=>proc{|pokemon|
       next _INTL("Mega Steelix") if pokemon.form==1
       next
    },
    "getBaseStats"=>proc{|pokemon|
       next [75,135,225,55,65,55] if pokemon.form==1 && pokemon.isDelta?
       next [75,125,230,30,55,95] if pokemon.form==1
       next
    },
    "type1"=>proc{|pokemon|
       next getID(PBTypes,:FIRE) if pokemon.form==1 && pokemon.isDelta?
       next
    },
    "ability"=>proc{|pokemon|
       next getID(PBAbilities,:FOUNDRY) if pokemon.form==1 && pokemon.isDelta?
       next getID(PBAbilities,:SANDFORCE) if pokemon.form==1
       next
    },
    "height"=>proc{|pokemon|
       next 105 if pokemon.form==1
       next
    },
    "weight"=>proc{|pokemon|
       next 740.0 if pokemon.form==1
       next
    },
    "onSetForm"=>proc{|pokemon,form|
       pbSeenForm(pokemon)
    }
    })
     
    824
    Posts
    8
    Years
  • Update to allow icons (on the Party screen and the PC) to change based on whether a Pokemon is Alolan or not. Naming the files follows similar rules to the battlers.
     

    Arkadious

    Developer of Fragmentum
    50
    Posts
    8
    Years
  • I'm getting this error with the latest update:

    Spoiler:
     
    824
    Posts
    8
    Years
  • I'm getting this error with the latest update:

    Spoiler:

    OOOOOPS, put a line in the wrong spot.

    Thank you for catching that. Fix is now in the main post
     
    33
    Posts
    7
    Years
  • Nice work!
    A neat thing a dev could do with this is check if the mother or father of an egg was an Alola/Deta pokémon and make a species-specific list of moves that could be passed down between the two subspecies.
     
    824
    Posts
    8
    Years
  • Added the new information we learned about Alolan Meowth and Marowak in the trailer (their abilities), as well as Alolan Raichu entirely added.

    Note that even though my code references the ability Surge Surfer, it doesn't add it. You need to do that yourself. The relevant bit of code is def pbSpeed(), which can be found on lines 642-701 of the script section PokeBattle_Battler.

    Personally, I'd do it by inserting the red lines:
    Code:
      def pbSpeed()
        stagemul=[10,10,10,10,10,10,10,15,20,25,30,35,40]
        stagediv=[40,35,30,25,20,15,10,10,10,10,10,10,10]
        speed=@speed
        stage=@stages[PBStats::SPEED]+6
        speed=(speed*stagemul[stage]/stagediv[stage]).floor
        speedmult=0x1000
        case @battle.pbWeather
        when PBWeather::RAINDANCE, PBWeather::HEAVYRAIN
          speedmult=speedmult*2 if self.hasWorkingAbility(:SWIFTSWIM)
        when PBWeather::SUNNYDAY, PBWeather::HARSHSUN
          speedmult=speedmult*2 if self.hasWorkingAbility(:CHLOROPHYLL)
        when PBWeather::SANDSTORM
          speedmult=speedmult*2 if self.hasWorkingAbility(:SANDRUSH)
        end
        if self.hasWorkingAbility(:QUICKFEET) && self.status>0
          speedmult=(speedmult*1.5).round
        end[COLOR="Red"]
        if self.hasWorkingAbility(:SURGESURFER) && @battle.field.effects[PBEffects::ElectricTerrain]>0
          speedmult=speedmult*2
        end[/COLOR]
        if self.hasWorkingAbility(:UNBURDEN) && @effects[PBEffects::Unburden] &&
           self.item==0
          speedmult=speedmult*2
        end
        if self.hasWorkingAbility(:SLOWSTART) && self.turncount<=5
          speedmult=(speedmult/2).round
        end
        if self.hasWorkingItem(:MACHOBRACE) ||
           self.hasWorkingItem(:POWERWEIGHT) ||
           self.hasWorkingItem(:POWERBRACER) ||
           self.hasWorkingItem(:POWERBELT) ||
           self.hasWorkingItem(:POWERANKLET) ||
           self.hasWorkingItem(:POWERLENS) ||
           self.hasWorkingItem(:POWERBAND)
          speedmult=(speedmult/2).round
        end
        if self.hasWorkingItem(:CHOICESCARF)
          speedmult=(speedmult*1.5).round
        end
        if isConst?(self.item,PBItems,:IRONBALL)
          speedmult=(speedmult/2).round
        end
        if self.hasWorkingItem(:QUICKPOWDER) && isConst?(self.species,PBSpecies,:DITTO) &&
           !@effects[PBEffects::Transform]
          speedmult=speedmult*2
        end
        if self.pbOwnSide.effects[PBEffects::Tailwind]>0
          speedmult=speedmult*2
        end
        if self.pbOwnSide.effects[PBEffects::Swamp]>0
          speedmult=(speedmult/2).round
        end
        if self.status==PBStatuses::PARALYSIS && !self.hasWorkingAbility(:QUICKFEET)
          speedmult=(speedmult/4).round
        end
        if @battle.internalbattle && @battle.pbOwnedByPlayer?(@index) &&
           @battle.pbPlayer.numbadges>=BADGESBOOSTSPEED
          speedmult=(speedmult*1.1).round
        end
        speed=(speed*speedmult*1.0/0x1000).round
        return [speed,1].max
      end
     
    7
    Posts
    15
    Years
    • Seen Aug 30, 2016
    Can you make it so it's possible to add more the 1 delta form per pokemon?
     
    30
    Posts
    7
    Years
    • Age 31
    • Seen Jan 8, 2023
    Great script!

    But I have some doubts:

    This script is compatible with EliteBattle? Because If i add it above EliteBattle scripts I got this error when entering any battle:

    error.png


    If I put below I don't receive anu error, but the sprite of the Pokémon doens't change...
     
    Last edited:
    824
    Posts
    8
    Years
  • Great script!

    But I have some doubts:

    This script is compatible with EliteBattle? Because If i add it above EliteBattle scripts I got this error when entering any battle:

    error.png


    If I put below I don't receive anu error, but the sprite of the Pokémon doens't change...

    If you're using the Elite Battle System, place this script below the EBS scripts. Both systems overwrite the same functions, and mine are based on the EBS's

    Did you make sprites for a the Delta forms? The code doesn't come with new sprites - you have to find/make them yourself.
     
    16
    Posts
    10
    Years
  • I've got the same error with the number of arguments of the bitmapwrapper, but in my project it appears in any battle when the delta species script is below the elite battle scripts. When it's above, I don't get any error, but also no appearance change. I've only made a sprite for the front just to check if it worked. Do you know what might cause this?
     
    81
    Posts
    8
    Years
    • Age 22
    • Seen Sep 7, 2019
    Guys I fixed the error for people who has Elite Battlers and it still crashed I'll post on this link tomorrow the fix Because I'm tired after trying to fix this mess for ages.
     
    824
    Posts
    8
    Years
  • Okay, so I've figured out the problem in regards to the EBS. Working on a solution that doesn't mess with compatibility for non-EBS systems in the process of fixing it for the EBS.

    The issue has to do with the EBS being able to auto-scale sprites. It's looking for that scale parameter, and not finding it.


    EDIT: the first post has been edited to be compatible with the EBS. the function pbLoadPokemonBitmapSpecies( has been edited, and the function pbLoadPokemonBitmap( has been entirely added to take advantage of the new functionality in the edited function.
     
    Last edited:
    Back
    Top