Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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.

#########################################################################
# 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
    [email protected]_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/[email protected]["pokemon"].bitmap.width/2
    @sprites["pokemon"].y=48+([email protected]["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
    @[email protected]*@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 [email protected]
      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"
        [email protected]
      else
        frame=0
      end
    end
    [email protected] 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 (@[email protected])
  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 >[email protected]
      # processes animation speed
      @[email protected]
      @[email protected]_points[0] if @currentIndex >[email protected]_points[1]
      @[email protected]_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
#     [email protected]^@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")
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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".
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Sir_Tman

Overworked game Dev

Non-binary
Australia
Seen March 9th, 2020
Posted December 9th, 2019
201 posts
4.9 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?

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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.

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)
}
})
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Arkadious

Developer of Fragmentum

Age 22
Male
New Zealand
Seen July 18th, 2019
Posted October 9th, 2017
50 posts
4.6 Years
I'm getting this error with the latest update:

Spoiler:
Exception: ArgumentError
Message: wrong number of arguments(3 for 2)
Rot8er_ConeX Delta/Alolan Forms:205:in `pbCheckPokemonIconFiles'
Rot8er_ConeX Delta/Alolan Forms:205:in `pbPokemonIconFile'
Pokemon_Sprites:188:in `pokemon='
Pokemon_Sprites:174:in `initialize'
PScreen_Load:172:in `new'
PScreen_Load:172:in `pbSetParty'
PScreen_Load:171:in `each'
PScreen_Load:171:in `pbSetParty'
PScreen_Load:324:in `pbStartLoadScreen'
Main:6:in `main'

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 Years
I'm getting this error with the latest update:

Spoiler:
Exception: ArgumentError
Message: wrong number of arguments(3 for 2)
Rot8er_ConeX Delta/Alolan Forms:205:in `pbCheckPokemonIconFiles'
Rot8er_ConeX Delta/Alolan Forms:205:in `pbPokemonIconFile'
Pokemon_Sprites:188:in `pokemon='
Pokemon_Sprites:174:in `initialize'
PScreen_Load:172:in `new'
PScreen_Load:172:in `pbSetParty'
PScreen_Load:171:in `each'
PScreen_Load:171:in `pbSetParty'
PScreen_Load:324:in `pbStartLoadScreen'
Main:6:in `main'
OOOOOPS, put a line in the wrong spot.

Thank you for catching that. Fix is now in the main post
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 Years
Edited the first post to include the new Delta/Alola Forms revealed in today's Corocoro
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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:
  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]
    [email protected]
    [email protected][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
    if self.hasWorkingAbility(:SURGESURFER) && @battle.field.effects[PBEffects::ElectricTerrain]>0
      speedmult=speedmult*2
    end
    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) &&
       [email protected][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
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 Years
Can you make it so it's possible to add more the 1 delta form per pokemon?
This is designed to work like how the Gen VII games seem to do this. But you could use a combination of this and the default form code to make multiple deltas.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 Years
I'm getting a syntax error on line 207
Try removing the comma on that line.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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:



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.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Marty152

Male
The Netherlands
Seen April 8th, 2019
Posted November 28th, 2017
16 posts
7.1 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?

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 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.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

BlackOutG5

Male
Seen September 6th, 2019
Posted August 29th, 2019
78 posts
5 Years
Ok, here's my fix to make it work just add or edit the links in red! All of this is in PSystem_Utilities The only problem with this fix is that Shadow Pokemon's Icons and sprites won't load thats the only fix everything else from Delta/Alolan icons and so on will load.

1) Search for # Loads Pokémon/item/trainer graphics

After than Search for def pbLoadPokemonBitmapSpecies(pokemon, species, back=false)

then replace it with this pastebin all the way to def pbPokemonFootprintFile(species) BUT DONT REPLACE THE FOOTPRINT Script just everything from the pbLoadPokemonBitmapSpecies and everything between those 2. Dont forget to copy raw of the pastebin: http://pastebin.com/Q4DPb57W

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 Years
Ok, here's my fix to make it work just add or edit the links in red! All of this is in PSystem_Utilities The only problem with this fix is that Shadow Pokemon's Icons and sprites won't load thats the only fix everything else from Delta/Alolan icons and so on will load.

1) Search for # Loads Pokémon/item/trainer graphics

After than Search for def pbLoadPokemonBitmapSpecies(pokemon, species, back=false)

then replace it with this pastebin all the way to def pbPokemonFootprintFile(species) BUT DONT REPLACE THE FOOTPRINT Script just everything from the pbLoadPokemonBitmapSpecies and everything between those 2. Dont forget to copy raw of the pastebin: http://pastebin.com/Q4DPb57W
So I'm looking at the code for the EBS and even of vanilla Essentials v16.2 And I'm not seeing either of them mention anything about sorting the Pokemon sprites into separate folders based on shininess and gender. That might be something you yourself added.

The issue I noticed, which does coincide with the error message originally posted (4 arguments in a function designed to take in at most 3), is that the EBS has a way to handle the scale of sprites whereas default Essentials doesn't.

Somehow, though (don't ask me how), you reminded me that I need to add compatibility for the Following Pokemon script.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

Rot8er_ConeX

Male
The Dissa Region
Seen February 22nd, 2018
Posted May 8th, 2017
822 posts
5.1 Years
Oh EBS I'm using BW Essentials edited by Klien xD. That's a fix for people who use BW essentials. version 3.1.1
That's good to know. That's the only thing that makes this incompatible with BW Essentials?

I'll have to figure out how to detect if someone is using BW essentials. Detecting the EBS is as simple as checking if the class DynamicPokemonSprite exists, according to other things Luka's made.

Which leads to my next point: the first post now contains code that makes it compatible with the EBS and Following Pokemon.
Features of Pokemon Entropy

The black circular "doodles" in the lower right corner of my avatar are actually my username written in Gallifreyan. Yes I'm a Whovian.

BlackOutG5

Male
Seen September 6th, 2019
Posted August 29th, 2019
78 posts
5 Years
It works now I re-added you script to my game and as well as the EliteBattle_BitmapWrappers but got another issue It won't load the right image like it would still be the regular pokemon instead of the alolan pokemon when I look at it in battle or Party. but the Icon loads perfectly fine. and the type change and moves work too.