• 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