RPG-Maker Quartier

Hier dreht sich alles um die RPG-Maker-Reihe von ASCII/Enterbrain. Der RPG-Maker ist ein Tool, mit dem du dir dein eigenes kleines Rollenspiel erstellen kannst. Du findest hier alles, was du dazu brauchst. Aber natürlich umfasst die Community noch mehr!
Aktuelle Zeit: Di Mär 03, 2020 3:02

Alle Zeiten sind UTC + 1 Stunde



Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast



Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 
Autor Nachricht
Offline
Sayjaman
Sayjaman
Benutzeravatar
Beiträge: 50
Alter: 31
Wohnort: Frauenfeld (CH)
BeitragVerfasst: Di Feb 15, 2011 16:06 
Hallo Leute,

Ich bin etwas verwirrt. Beim Versuch eine Grafik für einen Schatten von einem anderen Projekt einzubinden, bin ich ständig gescheitert.

Also habe ich die Befehle Stück für Stück auskommentiert um so zu überprüfen, wo mein Fehler liegt.
Doch jetzt das Problem:
Das Bild wird zuerst geladen, ist aber noch unsichtbar. Sobald der Kampf beginnt fügt sich das Bild an die richtige Stelle und wird sichtbar gemacht (In dem Skript heisst die Methode: visible=true)

Tja, soweit schön und gut, aber wenn ich die erste Zeile wo es heisst:
@sprites["monster"].visible=false
in
@sprites["monster"].visible=true
ändere, bleibt das Bild trotzdem unsichtbar!

Dann habe ich alle Codezeilen, die von dieser Grafik handelt, auskommentiert, aber das Bild wird trotzdem verschoben und angezeigt, obwohl ich das Bild in der ersten Zeile mit visible=false unsichtbar gemacht habe...

Kann es sein, dass bestimmte Änderungen gar nicht übernommen werden, selbst beim Speichern und Neustart des Makers? Auch wenn ich lediglich die Koordinaten ändere, werden diese nicht übernommen.

Aber es gibt für mich keinen Sinn, wieso der Maker eine solche Änderung nicht übernehmen sollte.
Oder kann ein Anti-Viren Programm solche Änderungen blockieren? Klingt nicht logischer, aber mir gehen langsam die Ideen aus...


Wäre gut, wenn wir jemand helfen könnte, so habe ich extreme Mühe mit Arbeiten^^'


Nach oben
 Profil ICQ  
Mit Zitat antworten  
Offline
Official Oldschool
Official Oldschool
Benutzeravatar
Beiträge: 8917
Alter: 31
Wohnort: BRD, Thüringen
BeitragVerfasst: Di Feb 15, 2011 16:10 
Du musst schon das Script + deine Änderungen + was du eigentlich haben willst posten (bitte in CODE Tags). Sonst kann man dir schlecht helfen.

_________________


Nach oben
 Profil ICQ  
Mit Zitat antworten  
Offline
Sayjaman
Sayjaman
Benutzeravatar
Beiträge: 50
Alter: 31
Wohnort: Frauenfeld (CH)
BeitragVerfasst: Di Feb 15, 2011 16:30 
Das es viel bringt bezweifle ich aber, das Problem tritt auch an anderen Stellen auf.
Es scheint wirklich so, als würden die meisten Änderungen gar nicht übernommen werden.
Soll heissen, ich ändere den Code ab (z.B. die Koordinaten für eine Grafik), speichere es dann und starte mit F12 oder vom Projektordner aus das Spiel, aber es wird immer noch die Unveränderte Version abgespielt.
Und das obwohl im Skript etwas geändert wurde...



Kann den Maker hier leider nicht starten, lade es später hoch.
Hier trotzdem mal das Skript als Download im Projektordner:

http://www.megaupload.com/?d=EAN6L8BQ

Im Skript "PokeBattle_ActualScene" in der Zeile 1447 wird die Grafik geladen und bei 1448 unsichtbar gemacht.
Zwischen den Zeile 1513 und 1517 wird sie verschoben und wieder sichtbar gemacht.

Ich kann da ändern was ich will, solange der Aufruf in Zeile 1447 bleibt, kann ich die restlichen oben erwähnten Zeile ändern oder löschen wie ich will, es bleibt so wie es ursprünglich war.



So, hier ist der Code. Die Zeile, die die Grafik einbindet heisst "pbAddSprite("shadow1",0,0+@yoffset,"Graphics/Pictures/enemyshadow",@viewport)"
Code:
=begin

-  def pbChooseNewEnemy(index,party)
Use this method to choose a new Pokémon for the enemy
The enemy's party is guaranteed to have at least one
choosable member.
index - Index to the battler to be replaced (use e.g. @battle.battlers[index] to
access the battler)
party - Enemy's party

- def pbWildBattleSuccess
This method is called when the player wins a wild Pokémon battle.
This method can change the battle's music for example.

- def pbTrainerBattleSuccess
This method is called when the player wins a Trainer battle.
This method can change the battle's music for example.

- def pbFainted(pkmn)
This method is called whenever a Pokémon faints.
pkmn - PokeBattle_Battler object indicating the Pokémon that fainted

- def pbChooseEnemyCommand(index)
Use this method to choose a command for the enemy.
index - Index of enemy battler (use e.g. @battle.battlers[index] to
access the battler)

- def pbCommandMenu(index)
Use this method to display the list of commands and choose
a command for the player.
index - Index of battler (use e.g. @battle.battlers[index] to
access the battler)
Return values:
0 - Fight
1 - Pokémon
2 - Bag
3 - Run


=end


################################################



class CommandMenuDisplay
 def initialize(viewport=nil)
  @display=nil
  if PokeBattle_Scene::USECOMMANDBOX
   @display=IconSprite.new(0,Graphics.height-96,viewport)
   @display.setBitmap("Graphics/Pictures/commandbox")
  end
  @window=Window_CommandPokemon.newWithSize([],
    Graphics.width-240,Graphics.height-96,240,96);
  @window.columns=2
  @window.columnSpacing=4
  @window.viewport=viewport
  @msgbox=Window_UnformattedTextPokemon.newWithSize(
   "",4,Graphics.height-96,
   Graphics.width-@window.width-4,
   96,viewport)
  @msgbox.baseColor=PokeBattle_Scene::MESSAGEBASECOLOR
  @msgbox.shadowColor=PokeBattle_Scene::MESSAGESHADOWCOLOR
  @msgbox.windowskin=nil
  if PokeBattle_Scene::USECOMMANDBOX
   @window.opacity=0
  end
  @title=""
 end
 def index; @window.index; end
 def index=(value); @window.index=value; end
 def setTexts(value)
  @msgbox.text=value[0]
  # Note 2 and 3 were intentionally switched
  commands=[]
  [1,3,2,4].each{|i|
   commands.push(value[i]) if value[i] && value[i]!=nil
  }
  @window.commands=commands
 end
 def visible; @window.visible; end
 def visible=(value)
  @window.visible=value
  @msgbox.visible=value
  @display.visible=value if @display
 end
 def x; @window.x; end
 def x=(value)
  @window.x=value
  @msgbox.x=value
  @display.x=value if @display
 end
 def y; @window.y; end
 def y=(value)
  @window.y=value
  @msgbox.y=value
  @display.y=value if @display
 end
 def oy; @window.oy; end
 def oy=(value)
  @window.oy=value
  @msgbox.oy=value
  @display.oy=value if @display
 end
 def color; @window.color; end
 def color=(value)
  @window.color=value
  @msgbox.color=value
  @display.color=value if @display
 end
 def ox; @window.ox; end
 def ox=(value)
  @window.ox=value
  @msgbox.ox=value
  @display.ox=value if @display
 end
 def z; @window.z; end
 def z=(value)
  @window.z=value
  @msgbox.z=value
  @display.z=value if @display
 end
 def disposed?
  return @msgbox.disposed? || @window.disposed?
 end
 def dispose
  return if disposed?
  @msgbox.dispose
  @window.dispose
  @display.dispose if @display
 end
 def update
  @msgbox.update
  @window.update
  @display.update if @display
 end
 def refresh
  @msgbox.refresh
  @window.refresh
 end
end

class FightMenuDisplay
 attr_reader :battler
 attr_reader :index
 def battler=(value)
  @battler=value
  refresh
 end
 def setIndex(value)
  if @battler && @battler.moves[value].id!=0
   @index=value
   @window.index=value
   refresh
  end
 end
 def visible; @window.visible; end
 def visible=(value)
  @window.visible=value
  @info.visible=value
  @display.visible=value if @display
 end
 def x; @window.x; end
 def x=(value)
  @window.x=value
  @info.x=value
  @display.x=value if @display
 end
 def y; @window.y; end
 def y=(value)
  @window.y=value
  @info.y=value
  @display.y=value if @display
 end
 def oy; @window.oy; end
 def oy=(value)
  @window.oy=value
  @info.oy=value
  @display.oy=value if @display
 end
 def color; @window.color; end
 def color=(value)
  @window.color=value
  @info.color=value
  @display.color=value if @display
 end
 def ox; @window.ox; end
 def ox=(value)
  @window.ox=value
  @info.ox=value
  @display.ox=value if @display
 end
 def z; @window.z; end
 def z=(value)
  @window.z=value
  @info.z=value
  @display.z=value if @display
 end
 def disposed?
  return @info.disposed? || @window.disposed?
 end
 def dispose
  return if disposed?
  @info.dispose
  @display.dispose if @display
  @window.dispose
 end
 def update
  @info.update
  @window.update
  @display.update if @display
 end
 def initialize(battler,viewport=nil)
  @display=nil
  if PokeBattle_Scene::USEFIGHTBOX
   @display=IconSprite.new(0,Graphics.height-96,viewport)
   @display.setBitmap("Graphics/Pictures/fightbox")
  end
  @window=Window_CommandPokemon.newWithSize([],
    0,Graphics.height-96,320,96,viewport)
  @window.columns=2
  @window.columnSpacing=4
  @info=Window_AdvancedTextPokemon.newWithSize(
   "",320,Graphics.height-96,Graphics.width-320,96,viewport)
  @ctag=shadowctag(PokeBattle_Scene::MENUBASECOLOR,
    PokeBattle_Scene::MENUSHADOWCOLOR)
  if PokeBattle_Scene::USEFIGHTBOX
   @window.opacity=0
   @info.opacity=0
  end
  @battler=battler
  @index=0
  refresh
 end
 def refresh
  return if !@battler
  pbSetNarrowFont(@window.contents)
  commands=[]
  for i in 0...4
   if @battler.moves[i].id!=0
    commands.push(@battler.moves[i].name)
   else
    break
   end
  end
  @window.commands=commands
  selmove=@battler.moves[@index]
  movetype=PBTypes.getName(selmove.type)
  pbSetNarrowFont(@info.contents)
  @info.text=_ISPRINTF("{1:s}PP: {2: 2d}/{3: 2d}<br>TYPE/{4:s}",
    @ctag,selmove.pp,selmove.totalpp,movetype)
 end
end

class PokemonBattlerSprite < RPG::Sprite
 attr_accessor :selected
 def initialize(doublebattle,index,viewport=nil)
  super(viewport)
  @selected=0
  @frame=0
  @index=index
  @updating=false
  @doublebattle=doublebattle
  @index=index
  @spriteX=0
  @spriteY=0
  @spriteXExtra=0
  @spriteYExtra=0
  @spriteVisible=false
  @_iconbitmap=nil
  self.visible=false
 end
 def selected=(value)
  if @selected==1 && value!=1 && @spriteYExtra>0
   @spriteYExtra=0
   self.y=@spriteY
  end
  @selected=value
 end
 def visible=(value)
  @spriteVisible=value if !@updating
  super
 end
 def x
  return @spriteX
 end
 def y
  return @spriteY
 end
 def x=(value)
  @spriteX=value
  super(value+@spriteXExtra)
 end
 def y=(value)
  @spriteY=value
  super(value+@spriteYExtra)
 end
 def update
  @frame+=1
  @updating=true
  if ((@frame/9).floor&1)==1 && @selected==1 # When choosing commands for this Pokémon
   @spriteYExtra=2
  else
   @spriteYExtra=0
  end
  if ((@frame/9).floor&1)==1 && @selected==1 # When choosing commands for this Pokémon
   self.x=@spriteX
   self.y=@spriteY
   self.visible=@spriteVisible
  elsif @selected==2 # When targeted or damaged
   self.x=@spriteX
   self.y=@spriteY
   self.visible=(@frame%10<7)
  elsif
   self.x=@spriteX
   self.y=@spriteY
   self.visible=@spriteVisible
  end
  if @_iconbitmap
   @_iconbitmap.update
   self.bitmap=@_iconbitmap.bitmap
  end
  @updating=false
 end
 def dispose
  @_iconbitmap.dispose if @_iconbitmap
  @_iconbitmap=nil
  self.bitmap=nil if !self.disposed?
  super
 end
 def setPokemonBitmap(pokemon,back=false)
  @_iconbitmap.dispose if @_iconbitmap
  @_iconbitmap=pbLoadPokemonBitmap(pokemon,back)
  self.bitmap=@_iconbitmap ? @_iconbitmap.bitmap : nil
 end
 def setPokemonBitmapSpecies(pokemon,species,back=false)
  @_iconbitmap.dispose if @_iconbitmap
  @_iconbitmap=pbLoadPokemonBitmapSpecies(pokemon,species,back)
  self.bitmap=@_iconbitmap ? @_iconbitmap.bitmap : nil
 end
end

class SafariDataBox < SpriteWrapper
 attr_accessor :selected
 attr_reader :appearing
 def initialize(battle,viewport=nil)
  super(viewport)
  @selected=0
  @battle=battle
  @databox=AnimatedBitmap.new("Graphics/Pictures/safariPlayerBox")
  @spriteX=254
  @spriteY=148+(Graphics.height-320)
  @spritebaseY=0
  @spritebaseX=16
  @appearing=false
  @contents=BitmapWrapper.new(@databox.width,@databox.height)
  self.bitmap=@contents
  self.visible=false
  self.z=2
  refresh
 end
 def appear
  refresh
  self.visible=true
  self.opacity=255
  self.x=@spriteX+320
  self.y=@spriteY
  @appearing=true
 end
 def refresh
  self.bitmap.clear
  self.bitmap.blt(0,0,@databox.bitmap,Rect.new(0,0,@databox.width,@databox.height))
  pbSetSmallFont(self.bitmap)
  textpos=[]
  base=PokeBattle_Scene::BOXTEXTBASECOLOR
  shadow=PokeBattle_Scene::BOXTEXTSHADOWCOLOR
  textpos.push([_INTL("SAFARI BALLS"),@spritebaseX+14,@spritebaseY+6,false,base,shadow])
  textpos.push([_INTL("Left: {1}",@battle.ballcount),@spritebaseX+170,@spritebaseY+40,
    true,base,shadow])
  pbDrawTextPositions(self.bitmap,textpos)
 end
 def update
  super
  if @appearing
   self.x-=8
   @appearing=false if self.x<=@spriteX
   self.y=@spriteY
   return
  end
  self.x=@spriteX
  self.y=@spriteY
 end
end

class PokemonDataBox < SpriteWrapper
 attr_reader :battler
 attr_accessor :selected
 attr_accessor :appearing
 attr_reader :animatingHP
 attr_reader :animatingEXP
 def initialize(battler,doublebattle,viewport=nil)
  super(viewport)
  @explevel=0
  @battler=battler
  @spritebaseY=0
  @selected=0
  @frame=0
  @showhp=false
  @showexp=false
  @appearing=false
  @animatingHP=false
  @currenthp=0
  @endhp=0
  @expflash=0
  @statusCX=64
  @statusY=28
  if (@battler.index&1)==0 # if player's Pokémon
   @spritebaseX=16
  else
   @spritebaseX=0
  end
  yoffset=(Graphics.height-320)
  if doublebattle
   case @battler.index
    when 0
     @databox=AnimatedBitmap.new("Graphics/Pictures/doublePlayerBox")
     @spriteX=256
     @spriteY=124+yoffset
    when 1
     @databox=AnimatedBitmap.new("Graphics/Pictures/doubleEnemyBox")
     @spriteX=26
     @spriteY=10+yoffset
     @spritebaseX=0
     @spritebaseY=0
    when 2
     @databox=AnimatedBitmap.new("Graphics/Pictures/doublePlayerBox")
     @spriteX=280
     @spriteY=174+yoffset
    when 3
     @databox=AnimatedBitmap.new("Graphics/Pictures/doubleEnemyBox")
     @spriteX=2
     @spriteY=60+yoffset
   end
  else
   case @battler.index
    when 0
     @databox=AnimatedBitmap.new("Graphics/Pictures/singlePlayerBox")
     @spriteX=254
     @spriteY=148+yoffset
     @showhp=true
     @showexp=true
     @statusCX=40
     @statusY=44
    when 1
     @databox=AnimatedBitmap.new("Graphics/Pictures/singleEnemyBox")
     @spriteX=26
     @spriteY=32+yoffset
   end
  end
  @statuses=AnimatedBitmap.new(_INTL("Graphics/Pictures/boxstatuses"))
  @contents=BitmapWrapper.new(@databox.width,@databox.height)
  self.bitmap=@contents
  self.visible=false
  self.z=2
  refreshExpLevel
  refresh
 end
 def dispose
  @statuses.dispose
  @databox.dispose
  @contents.dispose
  super
 end
 def refreshExpLevel
   if !@battler.pokemon
     @explevel=0
   else
     growthrate=@battler.pokemon.growthrate
     startexp=PBExperience.pbGetStartExperience(@battler.pokemon.level,growthrate)
     endexp=PBExperience.pbGetStartExperience(@battler.pokemon.level+1,growthrate)
     if startexp==endexp
       @explevel=0
     else
       @explevel=(@battler.pokemon.exp-startexp)*PokeBattle_Scene::EXPGAUGESIZE/(endexp-startexp)
     end
   end
 end
 def exp
  return @animatingEXP ? @currentexp : @explevel
 end
 def hp
  return @animatingHP ? @currenthp : @battler.hp
 end
 def animateHP(oldhp,newhp)
  @currenthp=oldhp
  @endhp=newhp
  @animatingHP=true
 end
 def animateEXP(oldexp,newexp)
  @currentexp=oldexp
  @endexp=newexp
  @animatingEXP=true
 end
 def appear
  refreshExpLevel
  refresh
  self.visible=true
  self.opacity=255
  if (@battler.index&1)==0 # if player's Pokémon
   self.x=@spriteX+320
  else
   self.x=@spriteX-320
  end
  self.y=@spriteY
  @appearing=true
 end
 def refresh
  self.bitmap.clear
  return if !@battler.pokemon
  self.bitmap.blt(0,0,@databox.bitmap,Rect.new(0,0,@databox.width,@databox.height))
  pbSetSmallFont(self.bitmap)
  hpstring=_ISPRINTF("{1: 2d}/{2: 2d}",self.hp,@battler.totalhp)
  textpos=[]
  base=PokeBattle_Scene::BOXTEXTBASECOLOR
  shadow=PokeBattle_Scene::BOXTEXTSHADOWCOLOR
  genderX=self.bitmap.text_size(@battler.name).width
  genderX+=@spritebaseX+14
  textpos.push([@battler.name,@spritebaseX+14,@spritebaseY+6,false,base,shadow])
  if @battler.gender==0 # Male
   textpos.push([_INTL("♂"),genderX,@spritebaseY+6,false,Color.new(8*8,25*8,31*8),shadow])
  elsif @battler.gender==1 # Female
   textpos.push([_INTL("♀"),genderX,@spritebaseY+6,false,Color.new(31*8,19*8,18*8),shadow])
  end
  textpos.push([_INTL("Lv{1}",@battler.level),@spritebaseX+170,@spritebaseY+6,true,base,shadow])
  if @showhp
   textpos.push([hpstring,@spritebaseX+170,@spritebaseY+40,true,base,shadow])
  end
  pbDrawTextPositions(self.bitmap,textpos)
  if @battler.status>0
   self.bitmap.blt(@spritebaseX+14,@spritebaseY+@statusY,@statuses.bitmap,
      Rect.new(0,(@battler.status-1)*16,@statusCX,16))
  end
  hpGaugeSize=PokeBattle_Scene::HPGAUGESIZE
  hpgauge=@battler.totalhp==0 ? 0 : (self.hp*hpGaugeSize/@battler.totalhp)
  hpgauge=1 if hpgauge==0 && self.hp>0
  hpzone=0
  hpzone=1 if self.hp<=(@battler.totalhp/2).floor
  hpzone=2 if self.hp<=(@battler.totalhp/4).floor
  hpcolors=[
   PokeBattle_Scene::HPCOLORSHADOW1,
   PokeBattle_Scene::HPCOLORBASE1,
   PokeBattle_Scene::HPCOLORSHADOW2,
   PokeBattle_Scene::HPCOLORBASE2,
   PokeBattle_Scene::HPCOLORSHADOW3,
   PokeBattle_Scene::HPCOLORBASE3
  ]
  # fill with HP color
  hpGaugeX=PokeBattle_Scene::HPGAUGE_X
  hpGaugeY=PokeBattle_Scene::HPGAUGE_Y
  expGaugeX=PokeBattle_Scene::EXPGAUGE_X
  expGaugeY=PokeBattle_Scene::EXPGAUGE_Y
  self.bitmap.fill_rect(@spritebaseX+hpGaugeX,@spritebaseY+hpGaugeY,hpgauge,2,hpcolors[hpzone*2])
  self.bitmap.fill_rect(@spritebaseX+hpGaugeX,@spritebaseY+hpGaugeY+2,hpgauge,2,hpcolors[hpzone*2+1])
  # fill with black
  self.bitmap.fill_rect(@spritebaseX+hpGaugeX+hpgauge,@spritebaseY+hpGaugeY,hpGaugeSize-hpgauge,2,PokeBattle_Scene::HPCOLORSHADOW4)
  self.bitmap.fill_rect(@spritebaseX+hpGaugeX+hpgauge,@spritebaseY+hpGaugeY+2,hpGaugeSize-hpgauge,2,PokeBattle_Scene::HPCOLORBASE4)
  if @showexp
   # fill with EXP color
   self.bitmap.fill_rect(@spritebaseX+expGaugeX,@spritebaseY+expGaugeY,self.exp,4,PokeBattle_Scene::EXPCOLOR)
  end
 end
 def update
  super
  @frame+=1
  if @animatingHP
   if @currenthp<@endhp
    @currenthp+=1
   elsif @currenthp>@endhp
    @currenthp-=1
   end
   refresh
   @animatingHP=false if @currenthp==@endhp
  end
  if @animatingEXP
   if !@showexp
    @currentexp=@endexp
   elsif @currentexp<@endexp
    @currentexp+=1
   elsif @currentexp>@endexp
    @currentexp-=1
   end
   refresh
   if @currentexp==@endexp
    if @currentexp==PokeBattle_Scene::EXPGAUGESIZE
     if @expflash==0
      pbSEPlay("expfull")
      self.flash(Color.new(64,200,248),8)
      @expflash=8
     else
      @expflash-=1
      if @expflash==0
       @animatingEXP=false
       refreshExpLevel
      end
     end
    else
     @animatingEXP=false
    end
   end
  end
  if @appearing
   if (@battler.index&1)==0 # if player's Pokémon
    self.x-=8
    @appearing=false if self.x<=@spriteX
   else
    self.x+=8
    @appearing=false if self.x>=@spriteX
   end
   self.y=@spriteY
   return
  end
  if ((@frame/10).floor&1)==1 && @selected==1 # When choosing commands for this Pokémon
   self.x=@spriteX
   self.y=@spriteY+2
  elsif ((@frame/5).floor&1)==1 && @selected==2 # When targeted or damaged
   self.x=@spriteX
   self.y=@spriteY+2
  else
   self.x=@spriteX
   self.y=@spriteY
  end
 end
end

def showShadow?(species)
  metrics=load_data("Data/metrics.dat")
  return metrics[2][species]>0
end

class PokeballSendOutAnimation
 SPRITESTEPS=10
 STARTZOOM=0.125
 def initialize(sprite,spritehash,pkmn,doublebattle)
  @disposed=false
  @ballused=pkmn.pokemon ? pkmn.pokemon.ballused : 0
  @PokemonBattlerSprite=sprite
  @PokemonBattlerSprite.visible=false
  @PokemonBattlerSprite.color=Color.new(31*8,22*8,30*8)
  @pokeballsprite=IconSprite.new(0,0,sprite.viewport)
  @pokeballsprite.setBitmap(sprintf("Graphics/Pictures/ball%02d_0",@ballused))
  if doublebattle
   @spritex=pkmn.index==1 ? 400 : 304
  else
   @spritex=344
  end
  @spritey=120+(Graphics.height-320)
  @spritehash=spritehash
  @pokeballsprite.x=@spritex-8
  @pokeballsprite.y=@spritey-8
  @pkmn=pkmn
  @endspritey=adjustBattleSpriteY(sprite,pkmn.species,pkmn.index)
  @shadowY=@spritey+18 # from top
  @shadowX=@spritex-32 # from left
  @shadowVisible=showShadow?(pkmn.species)
  @shadowY-=16 if doublebattle && pkmn.index==3
  @stepspritey=(@spritey-@endspritey)
  @zoomstep=(1.0-STARTZOOM)/SPRITESTEPS
  @animdone=false
  @frame=0
 end
 def disposed?
  return @disposed
 end
 def animdone?
  return @animdone
 end
 def dispose
  return if disposed?
  @pokeballsprite.dispose
  @disposed=true
 end
 def update
  return if disposed?
  @pokeballsprite.update
  @frame+=1
  if @frame==2
   pbSEPlay("recall")
   @pokeballsprite.setBitmap(sprintf("Graphics/Pictures/ball%02d_1",@ballused))
  end
  if @frame==4
   @PokemonBattlerSprite.visible=true
   @PokemonBattlerSprite.zoom_x=STARTZOOM
   @PokemonBattlerSprite.zoom_y=STARTZOOM
   pbSpriteSetCenter(@PokemonBattlerSprite,@spritex,@spritey)
   pbPlayCry(@pkmn.pokemon ? @pkmn.pokemon : @pkmn.species)
   @pokeballsprite.setBitmap(sprintf("Graphics/Pictures/ball%02d_2",@ballused))
  end
  if @frame==8
   @pokeballsprite.visible=false
  end
  if @frame>8 && @frame<=16
   color=Color.new(248,248,248,256-(16-@frame)*32)
   @spritehash["enemybase"].color=color
   @spritehash["playerbase"].color=color   
   @spritehash["battlebg"].color=color
  end
  if @frame>16 && @frame<=24
   color=Color.new(248,248,248,(24-@frame)*32)
   @PokemonBattlerSprite.color.alpha=(24-@frame)*32
   @spritehash["enemybase"].color=color
   @spritehash["playerbase"].color=color   
   @spritehash["battlebg"].color=color
  end
  if @frame>5 && @PokemonBattlerSprite.zoom_x<1.0
   @PokemonBattlerSprite.zoom_x+=@zoomstep
   @PokemonBattlerSprite.zoom_y+=@zoomstep
   @PokemonBattlerSprite.zoom_x=1.0 if @PokemonBattlerSprite.zoom_x > 1.0
   @PokemonBattlerSprite.zoom_y=1.0 if @PokemonBattlerSprite.zoom_y > 1.0
   currentY=@spritey-(@stepspritey*@PokemonBattlerSprite.zoom_y)
   pbSpriteSetCenter(@PokemonBattlerSprite,@spritex,currentY)
   @PokemonBattlerSprite.y=currentY
  end
  if @PokemonBattlerSprite.color.alpha<=0 &&
     @PokemonBattlerSprite.zoom_x>=1.0
   @animdone=true
   if @spritehash["shadow#{@pkmn.index}"]
    @spritehash["shadow#{@pkmn.index}"].x=@shadowX
    @spritehash["shadow#{@pkmn.index}"].y=@shadowY
    @spritehash["shadow#{@pkmn.index}"].visible=@shadowVisible
   end
  end
 end
end

def pokeballThrow(ball,shakes,targetBattler)
 balltype=@battle.pbGetBallType(ball)
 oldvisible=@sprites["shadow#{targetBattler}"].visible
 @sprites["shadow#{targetBattler}"].visible=false
 ball0=sprintf("Graphics/Pictures/ball%02d_0",balltype)
 ball1=sprintf("Graphics/Pictures/ball%02d_1",balltype)
 ball2=sprintf("Graphics/Pictures/ball%02d_2",balltype)
 # sprites
 spriteBall=IconSprite.new(0,0,@viewport)
 spriteBall.visible=false
 spritePoke=@sprites["pokemon#{targetBattler}"]
 # pictures
 pictureBall=PictureEx.new(0)
 picturePoke=PictureEx.new(0)
 pokeball=[360,32]
 dims=[spritePoke.x,spritePoke.y]
 center=getSpriteCenter(@sprites["pokemon#{targetBattler}"])
 # starting positions
 pictureBall.moveVisible(1,true)
 pictureBall.moveName(1,ball0)
 pictureBall.moveOrigin(1,PictureOrigin::Center)
 pictureBall.moveXY(0,1,83,103)
 picturePoke.moveVisible(1,true)
 picturePoke.moveOrigin(1,PictureOrigin::Center)
 picturePoke.moveXY(0,1,center[0],center[1])
 # directives
 picturePoke.moveSE(1,"Audio/SE/throw")
 pictureBall.moveCurve(20,1,233,47,314,33,360,32)
 delay=pictureBall.totalDuration+2
 picturePoke.moveColor(10,delay,Color.new(31*8,22*8,30*8))
 delay=picturePoke.totalDuration
 picturePoke.moveSE(delay,"Audio/SE/recall")
 pictureBall.moveName(delay,ball1)
 pictureBall.moveName(delay+4,ball2)
 picturePoke.moveZoom(15,delay,0)
 picturePoke.moveXY(15,delay,pokeball[0],pokeball[1])
 picturePoke.moveSE(delay+10,"Audio/SE/jumptoball")
 picturePoke.moveVisible(delay+15,false)
 pictureBall.moveName(picturePoke.totalDuration+2,ball0)
 delay=picturePoke.totalDuration+6
 pictureBall.moveXY(15,delay,pokeball[0],128)
 pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop")
 pictureBall.moveXY(8,pictureBall.totalDuration+2,pokeball[0],80)
 pictureBall.moveXY(7,pictureBall.totalDuration+2,pokeball[0],128)
 pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop")
 pictureBall.moveXY(6,pictureBall.totalDuration+2,pokeball[0],96)
 pictureBall.moveXY(5,pictureBall.totalDuration+2,pokeball[0],128)
 pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop")
 pictureBall.moveXY(4,pictureBall.totalDuration+2,pokeball[0],112)
 pictureBall.moveXY(3,pictureBall.totalDuration+2,pokeball[0],128)
 pictureBall.moveSE(pictureBall.totalDuration,"Audio/SE/balldrop")
 picturePoke.moveXY(0,pictureBall.totalDuration,pokeball[0],128)
 delay=pictureBall.totalDuration+18 if shakes==0
 [shakes,3].min.times do
  delay=pictureBall.totalDuration+18
  pictureBall.moveSE(delay,"Audio/SE/ballshake")
  pictureBall.moveXY(4,delay,pokeball[0]-8,128)
  pictureBall.moveAngle(4,delay,20) # positive means counterclockwise
  delay=pictureBall.totalDuration
  pictureBall.moveXY(8,delay,pokeball[0]+8,128)
  pictureBall.moveAngle(8,delay,-20) # negative means clockwise
  delay=pictureBall.totalDuration
  pictureBall.moveXY(4,delay,pokeball[0],128)
  pictureBall.moveAngle(4,delay,0)
 end
 if shakes<4
  picturePoke.moveSE(delay,"Audio/SE/recall")
  pictureBall.moveName(delay,ball1)
  pictureBall.moveName(delay+4,ball2)
  pictureBall.moveVisible(delay+10,false)
  picturePoke.moveVisible(delay,true)
  picturePoke.moveZoom(15,delay,100)
  picturePoke.moveXY(15,delay,center[0],center[1])
  delay=picturePoke.totalDuration
  picturePoke.moveColor(10,delay,Color.new(31*8,22*8,30*8,0))
 end
 picturePoke.moveOrigin(picturePoke.totalDuration,PictureOrigin::TopLeft)
 picturePoke.moveXY(0,picturePoke.totalDuration,dims[0],dims[1])
 loop do
  pictureBall.update
  picturePoke.update
  setPictureIconSprite(spriteBall,pictureBall)
  setPictureSprite(spritePoke,picturePoke)
  pbGraphicsUpdate
  pbInputUpdate
  break if !pictureBall.running? && !picturePoke.running?
 end
 if shakes<4
  @sprites["shadow#{targetBattler}"].visible=oldvisible
 end
 spriteBall.dispose
end

class PokeballPlayerSendOutAnimation
#  Ball curve: 8,52; 22,44; 52, 96
#  Player: Color.new(16*8,23*8,30*8)
 SPRITESTEPS=10
 STARTZOOM=0.125
 def initialize(sprite,spritehash,pkmn,doublebattle)
  @disposed=false
  @PokemonBattlerSprite=sprite
  @pkmn=pkmn
  @PokemonBattlerSprite.visible=false
  @PokemonBattlerSprite.color=Color.new(16*8,23*8,30*8)
  @spritehash=spritehash
  if doublebattle
   @spritex=pkmn.index==0 ? 64 : 180
  else
   @spritex=128
  end
  @spritey=Graphics.height-64
  @endspritey=adjustBattleSpriteY(@PokemonBattlerSprite,
    pkmn.species,pkmn.index)
  @animdone=false
  @frame=0
 end
 def disposed?
  return @disposed
 end
 def animdone?
  return @animdone
 end
 def dispose
  return if disposed?
  @disposed=true
 end
 def update
  return if disposed?
  @frame+=1
  if @frame==4
   @PokemonBattlerSprite.visible=true
   @PokemonBattlerSprite.zoom_x=STARTZOOM
   @PokemonBattlerSprite.zoom_y=STARTZOOM
   pbSEPlay("recall")
   pbSpriteSetCenter(@PokemonBattlerSprite,@spritex,@spritey)
   pbPlayCry(@pkmn.pokemon ? @pkmn.pokemon : @pkmn.species)
  end
  if @frame>8 && @frame<=16
   color=Color.new(248,248,248,256-(16-@frame)*32)
   @spritehash["enemybase"].color=color
   @spritehash["playerbase"].color=color   
   @spritehash["battlebg"].color=color
  end
  if @frame>16 && @frame<=24
   color=Color.new(248,248,248,(24-@frame)*32)
   @PokemonBattlerSprite.color.alpha=(24-@frame)*32
   @spritehash["enemybase"].color=color
   @spritehash["playerbase"].color=color   
   @spritehash["battlebg"].color=color
  end
  if @frame>5 && @PokemonBattlerSprite.zoom_x<1.0
   @PokemonBattlerSprite.zoom_x+=0.1
   @PokemonBattlerSprite.zoom_y+=0.1
   @PokemonBattlerSprite.zoom_x=1.0 if @PokemonBattlerSprite.zoom_x > 1.0
   @PokemonBattlerSprite.zoom_y=1.0 if @PokemonBattlerSprite.zoom_y > 1.0
   pbSpriteSetCenter(@PokemonBattlerSprite,@spritex,0)
   @PokemonBattlerSprite.y=@spritey+(@endspritey-@spritey)*@PokemonBattlerSprite.zoom_y
  end
  if @PokemonBattlerSprite.color.alpha<=0 &&
     @PokemonBattlerSprite.zoom_x>=1.0
   @animdone=true
  end
 end
end



class TrainerFadeAnimation
 def initialize(sprites)
  @frame=0
  @sprites=sprites
  @animdone=false
 end
 def animdone?
  return @animdone
 end
 def update
  return if @animdone
  @frame+=1
  @sprites["trainer"].x+=8
  @sprites["trainer2"].x+=8 if @sprites["trainer2"]
  @sprites["partybase1"].x+=8
  @sprites["partybase1"].opacity-=12
  for i in 0...6
   @sprites["enemy#{i}"].opacity-=12
   @sprites["enemy#{i}"].x+=8 if @frame>=i*4
  end
  @animdone=true if @sprites["trainer"].x>=480 &&
    ( !@sprites["trainer2"]||@sprites["trainer2"].x>=480)
 end
end

class PlayerFadeAnimation
 def initialize(sprites)
  @frame=0
  @sprites=sprites
  @animdone=false
 end
 def animdone?
  return @animdone
 end
 def update
  return if @animdone
  @frame+=1
  @sprites["player"].x-=8
  @sprites["playerB"].x-=8 if @sprites["playerB"]
  @sprites["partybase2"].x-=8
  @sprites["partybase2"].opacity-=12
  for i in 0...6
   if @sprites["player#{i}"]
    @sprites["player#{i}"].opacity-=12
    @sprites["player#{i}"].x-=8 if @frame>=i*4
   end
  end
  pa=@sprites["player"]
  pb=@sprites["playerB"]
  pawidth=128
  pbwidth=128
  if (pa && pa.bitmap && !pa.bitmap.disposed?)
   if pa.bitmap.height<pa.bitmap.width
    numframes=pa.bitmap.width/pa.bitmap.height # Number of frames
    pawidth=pa.bitmap.width/numframes # Width per frame
    @sprites["player"].src_rect.x=pawidth*1 if @frame>0
    @sprites["player"].src_rect.x=pawidth*2 if @frame>8
    @sprites["player"].src_rect.x=pawidth*3 if @frame>11
    @sprites["player"].src_rect.width=pawidth
   else
    pawidth=pa.bitmap.width
    @sprites["player"].src_rect.x=0
    @sprites["player"].src_rect.width=pawidth
   end
  end
  if (pb && pb.bitmap && !pb.bitmap.disposed?)
   if pb.bitmap.height<pb.bitmap.width
    numframes=pb.bitmap.width/pb.bitmap.height # Number of frames
    pbwidth=pb.bitmap.width/numframes # Width per frame
    @sprites["playerB"].src_rect.x=pbwidth*1 if @frame>0
    @sprites["playerB"].src_rect.x=pbwidth*2 if @frame>8
    @sprites["playerB"].src_rect.x=pbwidth*3 if @frame>11
    @sprites["playerB"].src_rect.width=pbwidth
   else
    pbwidth=pb.bitmap.width
    @sprites["playerB"].src_rect.x=0
    @sprites["playerB"].src_rect.width=pbwidth
   end
  end
  if pb
   @animdone=true if pb.x<=-pbwidth
  else
   @animdone=true if pa.x<=-pawidth
  end
 end
end

####################################################

class PokeBattle_Scene

USECOMMANDBOX=false # If true, expects a file named Graphics/Pictures/commandbox.png
USEFIGHTBOX=false # If true, expects a file named Graphics/Pictures/fightbox.png
MESSAGEBASECOLOR=Color.new(248,248,248)
MESSAGESHADOWCOLOR=Color.new(104,88,112)
MENUBASECOLOR=Color.new(72,72,72)
MENUSHADOWCOLOR=Color.new(208,208,208)
BOXTEXTBASECOLOR=Color.new(64,64,64)
BOXTEXTSHADOWCOLOR=Color.new(216,208,176)
EXPCOLOR=Color.new(64,200,248)
# Green HP color
HPCOLORBASE1=Color.new(14*8,31*8,21*8)
HPCOLORSHADOW1=Color.new(11*8,26*8,16*8)
# Orange HP color
HPCOLORBASE2=Color.new(31*8,28*8,7*8)
HPCOLORSHADOW2=Color.new(25*8,21*8,1*8)
# Red HP color
HPCOLORBASE3=Color.new(31*8,11*8,7*8)
HPCOLORSHADOW3=Color.new(21*8,8*8,9*8)
# Blank HP color
HPCOLORBASE4=Color.new(0,0,0)
HPCOLORSHADOW4=Color.new(0,0,0)
# Position of HP gauge
HPGAUGE_X=78
HPGAUGE_Y=34
# Position of EXP gauge
EXPGAUGE_X=46
EXPGAUGE_Y=66
# Size of gauges
EXPGAUGESIZE=128
HPGAUGESIZE=96

BLANK=0
MESSAGEBOX=1
COMMANDBOX=2
FIGHTBOX=3

attr_accessor :abortable

def initialize
 @battle=nil
 @lastcmd=[0,0,0,0]
 @lastmove=[0,0,0,0]
 @pkmnwindows=[nil,nil,nil,nil]
 @sprites={}
 @battlestart=true
 @messagemode=false
 @abortable=false
 @aborted=false
end

def pbUpdate
 partyAnimationUpdate
 @sprites["battlebg"].update if @sprites["battlebg"].respond_to?("update")
end

def pbGraphicsUpdate
 partyAnimationUpdate
 @sprites["battlebg"].update if @sprites["battlebg"].respond_to?("update")
 Graphics.update
end
def pbInputUpdate
 Input.update
 if Input.trigger?(Input::B) && @abortable && !@aborted
  @aborted=true
  @battle.pbAbort
 end
end

def pbShowWindow(windowtype)
 @sprites["messagebox"].visible=(windowtype==MESSAGEBOX||windowtype==COMMANDBOX||windowtype==FIGHTBOX||
    windowtype==BLANK)
 @sprites["messagewindow"].visible=(windowtype==MESSAGEBOX)
 @sprites["commandwindow"].visible=(windowtype==COMMANDBOX)
 @sprites["fightwindow"].visible=(windowtype==FIGHTBOX)
end

def pbSetMessageMode(mode)
 @messagemode=mode
 msgwindow=@sprites["messagewindow"]
 if mode # Within Pokémon command
  msgwindow.baseColor=MENUBASECOLOR
  msgwindow.shadowColor=MENUSHADOWCOLOR
  msgwindow.opacity=255
  msgwindow.x=0
  msgwindow.width=Graphics.width
  msgwindow.height=96
  msgwindow.y=Graphics.height-msgwindow.height
 else
  msgwindow.baseColor=MESSAGEBASECOLOR
  msgwindow.shadowColor=MESSAGESHADOWCOLOR
  msgwindow.opacity=0
  msgwindow.x=16
  msgwindow.width=Graphics.width-32
  msgwindow.height=96
  msgwindow.y=Graphics.height-msgwindow.height
 end
end


def pbWaitMessage
 if @briefmessage
  pbShowWindow(MESSAGEBOX)
  cw=@sprites["messagewindow"]
  60.times do
   pbGraphicsUpdate
   pbInputUpdate
  end
  cw.text=""
  cw.visible=false
  @briefmessage=false
 end
end

def pbDisplayMessage(msg,brief=false)
 pbWaitMessage
 pbRefresh
 pbShowWindow(MESSAGEBOX)
 cw=@sprites["messagewindow"]
 cw.text=msg
 i=0
 loop do
  pbGraphicsUpdate
  pbInputUpdate
  cw.update
  if i==60
   cw.text=""
   cw.visible=false
   return
  end
  if Input.trigger?(Input::C) || @abortable
   if cw.pausing?
    pbPlayDecisionSE() if !@abortable
    cw.resume
   end
  end
  if !cw.busy?
   if brief
    @briefmessage=true
    return
   end
   i+=1
  end
 end
end

def pbDisplayPausedMessage(msg)
 pbWaitMessage
 pbRefresh
 pbShowWindow(MESSAGEBOX)
 if @messagemode
  @switchscreen.pbDisplay(msg)
  return
 end
 cw=@sprites["messagewindow"]
 cw.text=_ISPRINTF("{1:s}\1",msg)
 loop do
  pbGraphicsUpdate
  pbInputUpdate
  if Input.trigger?(Input::C) || @abortable
   if cw.busy?
    pbPlayDecisionSE() if cw.pausing? && !@abortable
    cw.resume
   else
    cw.text=""
    pbPlayDecisionSE()
    cw.visible=false if @messagemode
    return
   end
  end
  cw.update
 end
end

def pbDisplayConfirmMessage(msg)
 return pbShowCommands(msg,[_INTL("YES"),_INTL("NO")],1)==0
end

def pbShowCommands(msg,commands,defaultValue)
 pbWaitMessage
 pbRefresh
 pbShowWindow(MESSAGEBOX)
 dw=@sprites["messagewindow"]
 dw.text=msg
 cw = Window_CommandPokemon.new(commands)
 cw.x=Graphics.width-cw.width
 cw.y=Graphics.height-cw.height-dw.height
 cw.index=0
 cw.viewport=@viewport
 pbRefresh
 loop do
  cw.visible=!dw.busy?
  pbGraphicsUpdate
  pbInputUpdate
  pbFrameUpdate(cw)
  dw.update
  if Input.trigger?(Input::B) && defaultValue>=0
   if dw.busy?
    pbPlayDecisionSE() if dw.pausing?
    dw.resume
   else
    cw.dispose
    dw.text=""
    return defaultValue
   end
  end
  if Input.trigger?(Input::C)
   if dw.busy?
    pbPlayDecisionSE() if dw.pausing?
    dw.resume
   else
    cw.dispose
    dw.text=""
    return cw.index
   end
  end
 end
end

def pbFrameUpdate(cw)
 cw.update if cw
 for i in 0..3
  if @sprites["battler#{i}"]
   @sprites["battler#{i}"].update
  end
  if @sprites["pokemon#{i}"]
   @sprites["pokemon#{i}"].update
  end
 end
end

def pbRefresh
 for i in 0..3
  if @sprites["battler#{i}"]
   @sprites["battler#{i}"].refresh
  end
 end
end


def pbAddSprite(id,x,y,filename,viewport)
 sprite=IconSprite.new(x,y,viewport)
 if filename
  sprite.setBitmap(filename) rescue nil
 end
 @sprites[id]=sprite
 return sprite
end

def pbAddPlane(id,filename,viewport)
 sprite=AnimatedPlane.new(viewport)
 if filename
  sprite.setBitmap(filename)
 end
 @sprites[id]=sprite
 return sprite
end

def pbDisposeSprites
 pbDisposeSpriteHash(@sprites)
end

def pbBeginCommandPhase
# Called whenever a new round begins.
 @battlestart=false
end

def pbShowOpponent(index)
 if @battle.opponent
  if @battle.opponent.is_a?(Array)
   trainerfile=sprintf("Graphics/Characters/trainer%03d",@battle.opponent[index].trainertype)
  else
   trainerfile=sprintf("Graphics/Characters/trainer%03d",@battle.opponent.trainertype)
  end
 else
  trainerfile="Graphics/Pictures/trfront"
 end
 pbAddSprite("trainer",Graphics.width,16+@yoffset,trainerfile,@viewport)
 if @sprites["trainer"].bitmap
  @sprites["trainer"].y-=@sprites["trainer"].bitmap.height-128
 end
 20.times do
  pbGraphicsUpdate
  pbInputUpdate
  @sprites["trainer"].x-=6
 end
end

def pbHideOpponent
 20.times do
  pbGraphicsUpdate
  pbInputUpdate
  @sprites["trainer"].x+=6
 end
end

def pbShowHelp(text)
  @sprites["helpwindow"].resizeToFit(text,Graphics.width)
  @sprites["helpwindow"].y=0
  @sprites["helpwindow"].x=0
  @sprites["helpwindow"].text=text
  @sprites["helpwindow"].visible=true
end

def pbHideHelp
  @sprites["helpwindow"].visible=false
end


def pbBackdrop
 outdoor=false
 if $game_map && pbGetMetadata($game_map.map_id,MetadataOutdoor)
  outdoor=true
 end
 case @battle.environment
  when PBEnvironment::Grass
   id=1
  when PBEnvironment::TallGrass
   id=2
  when PBEnvironment::MovingWater
   id=3
  when PBEnvironment::StillWater
   id=4
  when PBEnvironment::Underwater
   id=5
  when PBEnvironment::Rock
   id=7
  when PBEnvironment::Cave
   id=8
  when PBEnvironment::Sand
   id=9
  else
   id=(outdoor) ? 0 : 6
 end
 if $PokemonGlobal && $PokemonGlobal.nextBattleBack
  id=$PokemonGlobal.nextBattleBack
 elsif $game_map
  back=pbGetMetadata($game_map.map_id,MetadataBattleBack)
  if back && back!=""
   id=pbGetMetadata($game_map.map_id,MetadataBattleBack)
  end
 end
 battlebg="Graphics/Pictures/battlebg#{id}"
 enemybase="Graphics/Pictures/enemybase#{id}"
 playerbase="Graphics/Pictures/playerbase#{id}"
 pbAddPlane("battlebg",battlebg,@viewport)
 pbAddSprite("enemybase",-256,96+@yoffset,enemybase,@viewport) # ends at (224,96)
 pbAddSprite("playerbase",480,192+@yoffset,playerbase,@viewport) # ends at (0,192)
 @sprites["enemybase"].z=-1 # For compatibility with RGSS2
 @sprites["playerbase"].z=-1 # For compatibility with RGSS2
 @sprites["battlebg"].z=-1 # For compatibility with RGSS2
=begin
 if outdoor
  tone = $HourlyTones[Time.now.hour]
  @sprites["battlebg"].tone=tone
  @sprites["enemybase"].tone=tone
  @sprites["playerbase"].tone=tone
 end
=end
end

def inPartyAnimation?
 return @enablePartyAnim && @partyAnimPhase<4
end

def partyAnimationUpdate
  return if !inPartyAnimation?
  if @partyAnimPhase==0
   @sprites["partybase1"].x+=16
   @sprites["partybase2"].x-=16
   @partyAnimPhase=1 if @sprites["partybase1"].x+@sprites["partybase1"].bitmap.width>=208
   return
  end
  if @partyAnimPhase==1
   @enemyendpos=152
   @playerendpos=312
   @partyAnimPhase=2
   @partyAnimI=0
  end
  if @partyAnimPhase==2
   if @partyAnimI>=6
    @partyAnimPhase=4
    return
   end
   if @partyAnimI>=@battle.party2.length || !@battle.party2[@partyAnimI]
    pbAddSprite("enemy#{@partyAnimI}",-28,64+@yoffset,"Graphics/Pictures/ballempty",@viewport)
   elsif @battle.party2[@partyAnimI].hp<=0 || @battle.party2[@partyAnimI].status>0 || @battle.party2[@partyAnimI].egg?
    pbAddSprite("enemy#{@partyAnimI}",-28,64+@yoffset,"Graphics/Pictures/ballfainted",@viewport)
   else
    pbAddSprite("enemy#{@partyAnimI}",-28,64+@yoffset,"Graphics/Pictures/ballnormal",@viewport)
   end
   if @partyAnimI==@battle.party1.length || !@battle.party1[@partyAnimI]
    pbAddSprite("player#{@partyAnimI}",492,176+@yoffset,"Graphics/Pictures/ballempty",@viewport)
   elsif @battle.party1[@partyAnimI].hp<=0 || @battle.party1[@partyAnimI].status>0 || @battle.party1[@partyAnimI].egg?
    pbAddSprite("player#{@partyAnimI}",492,176+@yoffset,"Graphics/Pictures/ballfainted",@viewport)
   else
    pbAddSprite("player#{@partyAnimI}",492,176+@yoffset,"Graphics/Pictures/ballnormal",@viewport)
   end
   @partyAnimPhase=3
  end
  if @partyAnimPhase==3
    @sprites["enemy#{@partyAnimI}"].x+=20
    @sprites["player#{@partyAnimI}"].x-=20
    if @sprites["enemy#{@partyAnimI}"].x>=@enemyendpos
      @partyAnimPhase=2
      @partyAnimI+=1
      @enemyendpos-=20
      @playerendpos+=20
    end
  end
end

def pbStartBattle(battle)
 # Called whenever the battle begins
 @battle=battle
 @lastcmd=[0,0,0,0]
 @lastmove=[0,0,0,0]
 @sprites.clear
 @sprites.clear
 @viewport=Viewport.new(0,Graphics.height/2,Graphics.width,0)
 @viewport.z=99999
 @battleboxvp=Viewport.new(0,0,Graphics.width,Graphics.height)
 @battleboxvp.z=99999
 @showingplayer=true
 @showingenemy=true
 @yoffset=(Graphics.height-320)
 pbBackdrop
 pbAddSprite("partybase1",-400,80+@yoffset,"Graphics/Pictures/pbarrow",@viewport)
 pbAddSprite("partybase2",480,192+@yoffset,"Graphics/Pictures/pbarrow",@viewport)
 @sprites["partybase2"].mirror=true
 @sprites["partybase1"].visible=false
 @sprites["partybase2"].visible=false
 if @battle.opponent
  if @battle.opponent.is_a?(Array)
   trainerfile=sprintf("Graphics/Characters/trainer%03d",@battle.opponent[0].trainertype)
   pbAddSprite("trainer",-144,16+@yoffset,trainerfile,@viewport)
   trainerfile=sprintf("Graphics/Characters/trainer%03d",@battle.opponent[1].trainertype)
   pbAddSprite("trainer2",-240,16+@yoffset,trainerfile,@viewport)
  else
   trainerfile=sprintf("Graphics/Characters/trainer%03d",@battle.opponent.trainertype)
   pbAddSprite("trainer",-192,16+@yoffset,trainerfile,@viewport)
  end
 else
  trainerfile="Graphics/Pictures/trfront"
  pbAddSprite("trainer",-192,16+@yoffset,trainerfile,@viewport)
 end
 if @sprites["trainer"].bitmap
  @sprites["trainer"].y-=@sprites["trainer"].bitmap.height-128
 end
 if @sprites["trainer2"] && @sprites["trainer2"].bitmap
  @sprites["trainer2"].y-=@sprites["trainer2"].bitmap.height-128
 end
 @sprites["shadow0"]=IconSprite.new(0,0,@viewport)
 pbAddSprite("shadow1",0,0+@yoffset,"Graphics/Pictures/enemyshadow",@viewport)
 @sprites["shadow1"].visible=false
 @sprites["pokemon0"]=PokemonBattlerSprite.new(battle.doublebattle,0,@viewport)
 @sprites["pokemon1"]=PokemonBattlerSprite.new(battle.doublebattle,1,@viewport)
 if battle.doublebattle
  pbAddSprite("shadow3",0,0+@yoffset,"Graphics/Pictures/enemyshadow",@viewport)
  @sprites["shadow3"].visible=false
  @sprites["shadow2"]=IconSprite.new(0,0,@viewport)
  @sprites["pokemon3"]=PokemonBattlerSprite.new(battle.doublebattle,3,@viewport)
  @sprites["pokemon2"]=PokemonBattlerSprite.new(battle.doublebattle,2,@viewport)
 end
 @sprites["battler0"]=PokemonDataBox.new(battle.battlers[0],battle.doublebattle,@viewport)
 @sprites["battler1"]=PokemonDataBox.new(battle.battlers[1],battle.doublebattle,@viewport)
 if battle.doublebattle
  @sprites["battler2"]=PokemonDataBox.new(battle.battlers[2],battle.doublebattle,@viewport)
  @sprites["battler3"]=PokemonDataBox.new(battle.battlers[3],battle.doublebattle,@viewport)
 end
 if @battle.player.is_a?(Array)
   trainerfile=sprintf("Graphics/Pictures/trback%03d",@battle.player[0].trainertype)
   pbAddSprite("player",576-48,96+@yoffset,trainerfile,@viewport)
   trainerfile=sprintf("Graphics/Pictures/trback%03d",@battle.player[1].trainertype)
   pbAddSprite("playerB",576+48,96+@yoffset,trainerfile,@viewport)
   if @sprites["player"].bitmap
    if @sprites["player"].bitmap.width>@sprites["player"].bitmap.height
      @sprites["player"].src_rect.x=0
      @sprites["player"].src_rect.width=@sprites["player"].bitmap.width/4
    end
   end
   if @sprites["playerB"].bitmap
    if @sprites["playerB"].bitmap.width>@sprites["playerB"].bitmap.height
      @sprites["playerB"].src_rect.x=0
      @sprites["playerB"].src_rect.width=@sprites["playerB"].bitmap.width/4
    end
   end
 else
   trainerfile=sprintf("Graphics/Pictures/trback%03d",@battle.player.trainertype)
   pbAddSprite("player",576,96+@yoffset,trainerfile,@viewport)
   if @sprites["player"].bitmap
    if @sprites["player"].bitmap.width>@sprites["player"].bitmap.height
      @sprites["player"].src_rect.x=0
      @sprites["player"].src_rect.width=@sprites["player"].bitmap.width/4
    end
   end
 end
 pbAddSprite("messagebox",0,Graphics.height-96,"Graphics/Pictures/messagebox",@viewport)
 @sprites["helpwindow"]=Window_UnformattedTextPokemon.newWithSize("",0,0,32,32,@viewport)
 @sprites["helpwindow"].visible=false
 @sprites["messagewindow"]=Window_AdvancedTextPokemon.new("")
 @sprites["commandwindow"]=CommandMenuDisplay.new(@viewport)
 @sprites["fightwindow"]=FightMenuDisplay.new(nil,@viewport)
 @sprites["messagewindow"].letterbyletter=true
 @sprites["messagewindow"].viewport=@viewport
 @sprites["messagebox"].z=50
 @sprites["messagewindow"].z=100
 @sprites["commandwindow"].z=100
 @sprites["fightwindow"].z=100
 pbShowWindow(MESSAGEBOX)
 pbSetMessageMode(false)
 trainersprite1=@sprites["trainer"]
 trainersprite2=@sprites["trainer2"]
 if !@battle.opponent
  @sprites["trainer"].visible=false
  if @battle.party2.length>=1
   @sprites["pokemon1"].color=Color.new(0,0,0,128)
   @sprites["pokemon1"].setPokemonBitmap(@battle.party2[0],false)
   @sprites["pokemon1"].x=-192 # ends at 144*2
   @sprites["shadow1"].x=-192+16*2
   @sprites["shadow1"].y=65*2+@yoffset
   species=@battle.party2[0].species
   @sprites["pokemon1"].visible=true
   @sprites["shadow1"].visible=showShadow?(species)
   pbPositionPokemonSprite(
    @sprites["pokemon1"],
    @sprites["pokemon1"].x,
    @sprites["pokemon1"].y
   )
   @sprites["pokemon1"].y=adjustBattleSpriteY(
     @sprites["pokemon1"],species,1)
   trainersprite1=@sprites["pokemon1"]
  end
  if @battle.party2.length==2
   @sprites["pokemon1"].color=Color.new(0,0,0,160)
   @sprites["pokemon3"].color=Color.new(0,0,0,160)
   @sprites["pokemon1"].x=-144
   @sprites["shadow1"].x=-144+16*2
   @sprites["pokemon1"].y+=8
   @sprites["shadow1"].y=65*2+@yoffset+8
   @sprites["pokemon3"].setPokemonBitmap(@battle.party2[1],false)
   @sprites["pokemon3"].x=-240
   @sprites["shadow3"].x=-240+16*2
   @sprites["shadow3"].y=65*2+@yoffset
   species=@battle.party2[1].species
   @sprites["pokemon3"].visible=true
   @sprites["shadow3"].visible=showShadow?(species)
   pbPositionPokemonSprite(
    @sprites["pokemon3"],
    @sprites["pokemon3"].x,
    @sprites["pokemon3"].y
   )
   @sprites["pokemon3"].y=adjustBattleSpriteY(
     @sprites["pokemon3"],species,3)
   trainersprite2=@sprites["pokemon3"]
  end
 end
 loop do
  if @viewport.rect.y>Graphics.height/4
   @viewport.rect.y-=2
   @viewport.rect.height+=4
  elsif @viewport.rect.y>0
   @viewport.rect.y-=4
   @viewport.rect.height+=8
  end
  for i in @sprites
   i[1].ox=@viewport.rect.x
   i[1].oy=@viewport.rect.y
  end
  @sprites["enemybase"].x+=4
  @sprites["playerbase"].x-=4
  @sprites["shadow1"].x+=4
  @sprites["shadow3"].x+=4 if @sprites["shadow3"]
  trainersprite1.x+=4
  trainersprite2.x+=4 if trainersprite2
  @sprites["player"].x-=4
  @sprites["playerB"].x-=4  if @sprites["playerB"]
  pbGraphicsUpdate
  pbInputUpdate
  break if @sprites["enemybase"].x>=224
 end
 # Show shiny animation
 if !@battle.opponent
  pbPlayCry(@battle.party2[0])
  if @battle.party2[0].isShiny?
   pbCommonAnimation("Shiny",@battle.battlers[1],nil)
  end
  if @battle.party2.length==2
   if @battle.party2[1].isShiny?
    pbCommonAnimation("Shiny",@battle.battlers[3],nil)
   end
  end
 end
 if @battle.opponent
  @enablePartyAnim=true
  @partyAnimPhase=0
  @sprites["partybase1"].visible=true
  @sprites["partybase2"].visible=true
 else
  @sprites["battler1"].appear
  @sprites["battler3"].appear if @battle.party2.length==2
  appearing=true
  begin
   pbGraphicsUpdate
   pbInputUpdate
   @sprites["battler1"].update
   appearing=@sprites["battler1"].appearing
   @sprites["pokemon1"].color.alpha-=16
   @sprites["pokemon1"].color=@sprites["pokemon1"].color
   if @battle.party2.length==2
    @sprites["battler3"].update
    @sprites["pokemon3"].color.alpha-=16
    @sprites["pokemon3"].color=@sprites["pokemon3"].color
    appearing=(appearing||@sprites["battler3"].appearing)
   end
  end while appearing
 end
end

def pbEndBattle(result)
 @abortable=false
 pbShowWindow(BLANK)
 # Fade out all sprites
 pbBGMFade(1.0)
 pbFadeOutAndHide(@sprites)
 pbDisposeSprites
end

def pbRecall(battlerindex)
 @briefmessage=false
 if @battle.pbIsOpposing?(battlerindex)
  @sprites["shadow#{battlerindex}"].visible=false
 else
  spritePoke=@sprites["pokemon#{battlerindex}"]
  picturePoke=PictureEx.new(0)
  dims=[spritePoke.x,spritePoke.y]
  center=getSpriteCenter(spritePoke)
  # starting positions
  picturePoke.moveVisible(1,true)
  picturePoke.moveOrigin(1,PictureOrigin::Center)
  picturePoke.moveXY(0,1,center[0],center[1])
  # directives
  picturePoke.moveColor(10,1,Color.new(16*8,23*8,30*8))
  delay=picturePoke.totalDuration
  picturePoke.moveSE(delay,"Audio/SE/recall")
  picturePoke.moveZoom(15,delay,0)
  picturePoke.moveXY(15,delay,center[0],Graphics.height-80)
  picturePoke.moveVisible(picturePoke.totalDuration,false)
  picturePoke.moveColor(0,picturePoke.totalDuration,Color.new(0,0,0,0))
  picturePoke.moveOrigin(picturePoke.totalDuration,PictureOrigin::TopLeft)
  loop do
   picturePoke.update
   setPictureSprite(spritePoke,picturePoke)
   pbGraphicsUpdate
   pbInputUpdate
   break if !picturePoke.running?
  end
 end
end

def pbTrainerSendOut(battlerindex,pkmn)
  @briefmessage=false
  fadeanim=nil
  while inPartyAnimation?; end
  if @showingenemy
   fadeanim=TrainerFadeAnimation.new(@sprites)
  end
  frame=0
  @sprites["pokemon#{battlerindex}"].setPokemonBitmap(pkmn,false)
  sendout=PokeballSendOutAnimation.new(@sprites["pokemon#{battlerindex}"],
   @sprites,@battle.battlers[battlerindex],@battle.doublebattle)
  loop do
   pbGraphicsUpdate
   pbInputUpdate
   fadeanim.update if fadeanim
   frame+=1   
   if frame==1
    @sprites["battler#{battlerindex}"].appear
   end
   if frame>=10
    sendout.update
   end
   @sprites["battler#{battlerindex}"].update
   break if 
     (!fadeanim || fadeanim.animdone?) &&
     sendout.animdone? &&
     !@sprites["battler#{battlerindex}"].appearing
  end
  if @battle.battlers[battlerindex].pokemon.isShiny?
   pbCommonAnimation("Shiny",@battle.battlers[battlerindex],nil)
  end
  sendout.dispose
  if @showingenemy
   @showingenemy=false
   pbDisposeSprite(@sprites,"trainer")
   pbDisposeSprite(@sprites,"partybase1")
   for i in 0...6
    pbDisposeSprite(@sprites,"enemy#{i}")
   end
  end
  pbRefresh
end

def pbSendOut(battlerindex,pkmn)
while inPartyAnimation?; end
balltype=pkmn.ballused
ballbitmap=sprintf("Graphics/Pictures/ball%02d_0",balltype)
pictureBall=PictureEx.new(0)
delay=1
pictureBall.moveVisible(delay,true)
pictureBall.moveName(delay,ballbitmap)
pictureBall.moveOrigin(delay,PictureOrigin::Center)
# Setting the ball's movement path
path=[[111, 164], [113, 154], [115, 145], [118, 136],
[122, 128], [130, 124], [137, 129], [140, 138],
[142, 147], [143, 156], [144, 166], [145, 175],
[145, 185], [146, 194], [146, 203], [146, 213],
[147, 222], [147, 232], [147, 241], [147, 250]]
spriteBall=IconSprite.new(0,0,@viewport)
spriteBall.visible=false
angle=0
for coord in path
 delay=pictureBall.totalDuration
 pictureBall.moveAngle(0,delay,angle)
 pictureBall.moveXY(1,delay,coord[0],coord[1])
 angle+=80
 angle%=360
end
pictureBall.adjustPosition(0,Graphics.height-320)
  @sprites["battler#{battlerindex}"].visible=false
  @briefmessage=false
  fadeanim=nil
  if @showingplayer
   fadeanim=PlayerFadeAnimation.new(@sprites)
  end
  frame=0
  @sprites["pokemon#{battlerindex}"].setPokemonBitmap(pkmn,true)
  sendout=PokeballPlayerSendOutAnimation.new(@sprites["pokemon#{battlerindex}"],
    @sprites,@battle.battlers[battlerindex],@battle.doublebattle)
  loop do
   fadeanim.update if fadeanim
   frame+=1
   if frame>1 && !pictureBall.running? &&
      !@sprites["battler#{battlerindex}"].appearing
    @sprites["battler#{battlerindex}"].appear
   end
   if frame>=3 && !pictureBall.running?
    sendout.update
   end
   if (frame>=10 || !fadeanim) && pictureBall.running?
    pictureBall.update
    setPictureIconSprite(spriteBall,pictureBall)
   end
   @sprites["battler#{battlerindex}"].update
   pbGraphicsUpdate
   pbInputUpdate
   break if 
     (!fadeanim || fadeanim.animdone?) &&
     sendout.animdone? &&
     !@sprites["battler#{battlerindex}"].appearing
  end
  spriteBall.dispose
  sendout.dispose
  if @battle.battlers[battlerindex].pokemon.isShiny?
   pbCommonAnimation("Shiny",@battle.battlers[battlerindex],nil)
  end
  if @showingplayer
   @showingplayer=false
   pbDisposeSprite(@sprites,"player")
   pbDisposeSprite(@sprites,"partybase2")
   for i in 0...6
    pbDisposeSprite(@sprites,"player#{i}")
   end
  end
  pbRefresh
end

def pbTrainerWithdraw(battle,pkmn)
 pbRefresh
end

def pbWithdraw(battle,pkmn)
 pbRefresh
end

def pbForgetMove(pokemon,moveToLearn)
# Called whenever a Pokémon should forget a move.  It
# should return -1 if the selection is canceled, or 0 to 3
# to indicate the move to forget.  The function should not
# allow HM moves to be forgotten.
 ret=-1
 pbFadeOutIn(99999){
  scene=PokemonSummaryScene.new
  screen=PokemonSummary.new(scene)
  ret=screen.pbStartForgetScreen([pokemon],0,moveToLearn)
 }
 return ret
end

def pbBeginAttackPhase
 pbSelectBattler(-1)
end



def pbSafariStart
  @briefmessage=false
  @sprites["battler0"]=SafariDataBox.new(@battle,@viewport)
  @sprites["battler0"].appear
  loop do
   @sprites["battler0"].update
   pbGraphicsUpdate
   pbInputUpdate
   break if 
     !@sprites["battler0"].appearing
  end
  pbRefresh
end

def pbCommandMenuEx(index,texts)
 pbShowWindow(COMMANDBOX)
 cw2=@sprites["commandwindow"]
 cw2.setTexts(texts)
 cw2.index=[0,2,1,3][@lastcmd[index]]
 pbSelectBattler(index)
 pbRefresh
 loop do
  pbGraphicsUpdate
  pbInputUpdate
  pbFrameUpdate(cw2)
  if Input.trigger?(Input::C)
   ret=[0,2,1,3][cw2.index]
   pbPlayDecisionSE()
   @lastcmd[index]=ret
   return ret
  end
  nextindex=pbNextIndex(cw2.index)
  if cw2.index!=nextindex
   pbPlayCursorSE()
   cw2.index=nextindex
  end
 end
end

def pbSafariCommandMenu(index)
 pbCommandMenuEx(index,[
  _INTL("What will\n{1} throw?",@battle.pbPlayer.name),
  _INTL("BALL"),
  _INTL("ROCK"),
  _INTL("BAIT"),
  _INTL("RUN")
 ])
end

def pbCommandMenu(index)
# Use this method to display the list of commands.
#  Return values:
#  0 - Fight
#  1 - Pokémon
#  2 - Bag
#  3 - Run
 shadowTrainer=(hasConst?(PBTypes,:SHADOW) && @opponent)
 ret=pbCommandMenuEx(index,[
  _INTL("What will\n{1} do?",@battle.battlers[index].name),
  _INTL("FIGHT"),
  _INTL("POKéMON"),
  _INTL("BAG"),
  shadowTrainer ? _INTL("CALL") : _INTL("RUN")
 ])
 if ret==3 && shadowTrainer
  ret=4 # convert "Run" to "Call"
 end
 return ret
end

def pbMoveString(move)
 ret=_INTL("{1}",move.name)
 typename=PBTypes.getName(move.type)
 if move.id>0
  ret+=_INTL(" ({1}) PP: {2}/{3}",typename,move.pp,move.totalpp)
 end
 return ret
end

def pbNameEntry(helptext)
 return pbEnterText(helptext,0,10)
end

def pbFightMenu(index)
# Use this method to display the list of moves for a Pokémon
 pbShowWindow(FIGHTBOX)
 cw = @sprites["fightwindow"]
 battler=@battle.battlers[index]
 cw.battler=battler
 lastIndex=@lastmove[index]
 if battler.moves[lastIndex].id!=0
  cw.setIndex(lastIndex)
 else
  cw.setIndex(0)
 end
 pbSelectBattler(index)
 pbRefresh
 loop do
  pbGraphicsUpdate
  pbInputUpdate
  pbFrameUpdate(cw)
  if Input.trigger?(Input::B) # Cancel fight menu
   @lastmove[index]=cw.index
   pbPlayCancelSE()
   return -1
  end
  if Input.trigger?(Input::C)# Confirm choice
   ret=cw.index
   pbPlayDecisionSE()
   @lastmove[index]=ret
   return ret
  end
  nextindex=pbNextIndex(cw.index)
  if cw.index!=nextindex # Move cursor
   pbPlayCursorSE()
   cw.setIndex(nextindex)
  end
 end
end

def pbItemMenu(index)
# Use this method to display the inventory
# The return value is the item chosen, or 0 if the choice was canceled.
 ret=0
 endscene=true
 oldsprites=pbFadeOutAndHide(@sprites)
 itemscene=PokemonBag_Scene.new
 itemscene.pbStartScene($PokemonBag)
 loop do
  item=itemscene.pbChooseItem
  break if item==0
  usetype=$ItemData[item][ITEMBATTLEUSE]
  cmdUse=-1
  commands=[]
  if usetype==0
   commands[commands.length]=_INTL("CANCEL")
  else
   commands[cmdUse=commands.length]=_INTL("USE")
   commands[commands.length]=_INTL("CANCEL")
  end
  itemname=PBItems.getName(item)
  command=itemscene.pbShowCommands(_INTL("{1} is selected.",itemname),commands)
  if cmdUse>=0 && command==cmdUse
   if usetype==1
    pkmnlist=PokemonScreen_Scene.new
    pkmnscreen=PokemonScreen.new(pkmnlist,@battle.party1)
    itemscene.pbEndScene
    pkmnlist.pbStartScene(@battle.party1,_INTL("Use on which Pokémon?"))
    pkmnid=pkmnlist.pbChoosePokemon
    if pkmnid>=0 && @battle.pbUseItemOnPokemon(item,pkmnid,pkmnscreen)
     pkmnscreen.pbRefresh
     pkmnlist.pbEndScene
     ret=item
     endscene=false
     break
    end
    pkmnlist.pbEndScene
    itemscene.pbStartScene($PokemonBag)
   elsif usetype==2
     if @battle.pbUseItemOnBattler(item,index,itemscene)
      ret=item
      break
     end
   end
  end
 end
 pbConsumeItemInBattle($PokemonBag,ret)
 itemscene.pbEndScene if endscene
 for i in 0..4
  if @sprites["battler#{i}"]
   @sprites["battler#{i}"].refresh
  end
 end
 pbFadeInAndShow(@sprites,oldsprites)
 return ret
end

def pbSelectBattler(index,selectmode=1)
 numwindows=@battle.doublebattle ? 4 : 2
 for i in 0...numwindows
  sprite=@sprites["battler#{i}"]
  sprite.selected=(i==index) ? selectmode : 0
  sprite=@sprites["pokemon#{i}"]
  sprite.selected=(i==index) ? selectmode : 0
 end
end

def pbFirstTarget(index)
 for i in 0..3
  if i!=index && @battle.battlers[i].hp>0 &&
     @battle.battlers[index].pbIsOpposing?(i)
   return i
  end 
 end
 return -1
end

def pbNextIndex(curindex)
 if Input.trigger?(Input::LEFT) && (curindex&1)==1
  return curindex-1
 elsif Input.trigger?(Input::RIGHT) &&  (curindex&1)==0
  return curindex+1
 elsif Input.trigger?(Input::UP) &&  (curindex&2)==2
  return curindex-2
 elsif Input.trigger?(Input::DOWN) &&  (curindex&2)==0
  return curindex+2
 end
 return curindex
end

def pbUpdateSelected(index)
 numwindows=@battle.doublebattle ? 4 : 2
 for i in 0...numwindows
  if i==index
   @sprites["battler#{i}"].selected=2
   @sprites["pokemon#{i}"].selected=2
  else
   @sprites["battler#{i}"].selected=0
   @sprites["pokemon#{i}"].selected=0
  end
  @sprites["battler#{i}"].update
  @sprites["pokemon#{i}"].update
 end
end

def pbChooseTarget(index)
# Use this method to make the player choose a target
# for certain moves in double battles.
 pbShowWindow(FIGHTBOX)
 curwindow=pbFirstTarget(index)
 if curwindow==-1
  raise RuntimeError.new(_INTL("No targets somehow..."))
 end
 loop do
  pbGraphicsUpdate
  pbInputUpdate
  pbUpdateSelected(curwindow)
  if Input.trigger?(Input::C)
   pbUpdateSelected(-1)
   return curwindow
  end
  if Input.trigger?(Input::B)
   pbUpdateSelected(-1)
   return -1
  end
  if curwindow>=0
   if Input.trigger?(Input::RIGHT) || Input.trigger?(Input::DOWN)
    loop do
     newcurwindow=3 if curwindow==0
     newcurwindow=1 if curwindow==3
     newcurwindow=2 if curwindow==1
     newcurwindow=0 if curwindow==2
     curwindow=newcurwindow
     next if curwindow==index
     break if @battle.battlers[curwindow].hp>0
    end
   elsif Input.trigger?(Input::LEFT) || Input.trigger?(Input::UP)
    loop do
     newcurwindow=2 if curwindow==0
     newcurwindow=1 if curwindow==2
     newcurwindow=3 if curwindow==1
     newcurwindow=0 if curwindow==3
     curwindow=newcurwindow
     next if curwindow==index
     break if @battle.battlers[curwindow].hp>0
    end
   end
  end
 end
end

def pbSwitch(index,lax,cancancel)
 party=@battle.pbParty(index)
 inactives=[1,1,1,1,1,1]
 partypos=[]
 switchsprites={}
 activecmd=0
 ret=-1
 numactive=(@doublebattle)?2:1
 pbShowWindow(BLANK)
 pbSetMessageMode(true)
 # Fade out and hide all sprites
 visiblesprites=pbFadeOutAndHide(@sprites)
 battler=@battle.battlers[0]
 activecmd=0 if battler.index==index
 inactives[battler.pokemonIndex]=0
 partypos[0]=battler.pokemonIndex
 if @battle.doublebattle && !@battle.fullparty1
  battler=@battle.battlers[2]
  activecmd=1 if battler.index==index
  inactives[battler.pokemonIndex]=0
  partypos[1]=battler.pokemonIndex
 end
 # Add all non-active Pokémon
 for i in 0...6
  partypos[partypos.length]=i if inactives[i]==1
 end
 modparty=[]
 for i in 0...6
  modparty.push(party[partypos[i]])
 end
 scene=PokemonScreen_Scene.new
 @switchscreen=PokemonScreen.new(scene,modparty)
 @switchscreen.pbStartScene(_INTL("Choose a Pokémon."),
    @battle.doublebattle && !@battle.fullparty1)
 loop do
  scene.pbSetHelpText(_INTL("Choose a Pokémon."))
  activecmd=@switchscreen.pbChoosePokemon
  if cancancel && activecmd==-1
   ret=-1
   break
  end
  if activecmd>=0
   commands=[]
   cmdShift=-1
   cmdSummary=-1
   pkmnindex=partypos[activecmd]
   commands[cmdShift=commands.length]=_INTL("SHIFT") if !party[pkmnindex].egg?
   commands[cmdSummary=commands.length]=_INTL("SUMMARY")
   commands[commands.length]=_INTL("CANCEL")
   command=scene.pbShowCommands(_INTL("Do what with {1}?",party[pkmnindex].name),commands)
   if cmdShift>=0 && command==cmdShift
    canswitch=lax ?
       @battle.pbCanSwitchLax?(index,pkmnindex,true) :
       @battle.pbCanSwitch?(index,pkmnindex,true)
    if canswitch
     ret=pkmnindex
     break
    end
   elsif cmdSummary>=0 && command==cmdSummary
    scene.pbSummary(activecmd)
   end
  end
 end
 @switchscreen.pbEndScene
 @switchscreen=nil
 pbSetMessageMode(false)
 # back to main battle screen
 pbFadeInAndShow(@sprites,visiblesprites)
 return ret
end

def pbDamageAnimation(pkmn,effectiveness)
 pkmnsprite=@sprites["pokemon#{pkmn.index}"]
 shadowsprite=@sprites["shadow#{pkmn.index}"]
 sprite=@sprites["battler#{pkmn.index}"]
 oldshadowvisible=shadowsprite.visible
 oldvisible=sprite.visible
 sprite.selected=2
 @briefmessage=false
 6.times do
  pbGraphicsUpdate
  pbInputUpdate
 end
 case effectiveness
  when 0
   pbSEPlay("normaldamage")
  when 1
   pbSEPlay("notverydamage")
  when 2
   pbSEPlay("superdamage")
 end
 8.times do
  pkmnsprite.visible=!pkmnsprite.visible
  if oldshadowvisible
   shadowsprite.visible=!shadowsprite.visible
  end
  4.times do
   pbGraphicsUpdate
   pbInputUpdate
   sprite.update
  end
 end
 sprite.selected=0
 sprite.visible=oldvisible
end

def pbHPChanged(pkmn,oldhp)
# This method is called whenever a Pokémon's HP changes.
# Used to animate the HP bar.
 @briefmessage=false
 hpchange=pkmn.hp-oldhp
 if hpchange<0
  hpchange=-hpchange
  PBDebug.log("[#{pkmn.pbThis} lost #{hpchange} HP, now has #{pkmn.hp} HP]") if @battle.debug
 else
  PBDebug.log("[#{pkmn.pbThis} gained #{hpchange} HP, now has #{pkmn.hp} HP]") if @battle.debug
 end
 sprite=@sprites["battler#{pkmn.index}"]
 sprite.animateHP(oldhp,pkmn.hp)
 while sprite.animatingHP
  pbGraphicsUpdate
  pbInputUpdate
  sprite.update
 end
end

def pbFainted(pkmn)
# This method is called whenever a Pokémon faints
 frames=pbCryFrameLength(pkmn.pokemon)
 pbPlayCry(pkmn.pokemon)
 frames.times do
  pbGraphicsUpdate
  pbInputUpdate
 end
 @sprites["shadow#{pkmn.index}"].visible=false
 pkmnsprite=@sprites["pokemon#{pkmn.index}"]
 pkmnsprite.visible=false
 if @battle.pbIsOpposing?(pkmn.index)
  tempvp=Viewport.new(0,0,480,144+@yoffset)
 else
  tempvp=Viewport.new(0,0,480,224+@yoffset)
 end
 tempvp.z=@viewport.z
 tempsprite=SpriteWrapper.new(tempvp)
 tempsprite.x=pkmnsprite.x
 tempsprite.y=pkmnsprite.y
 tempsprite.bitmap=pkmnsprite.bitmap
 tempsprite.visible=true
 pbSEPlay("faint")
 16.times do
  tempsprite.y+=8
  pbGraphicsUpdate
  pbInputUpdate
 end
 tempsprite.dispose
 tempvp.dispose
 8.times do
  @sprites["battler#{pkmn.index}"].opacity=32
  pbGraphicsUpdate
  pbInputUpdate
 end
 @sprites["battler#{pkmn.index}"].visible=false
end


def pbChooseEnemyCommand(index)
# Use this method to choose a command for the enemy.
 @battle.pbDefaultChooseEnemyCommand(index)
end

def pbChooseNewEnemy(index,party)
# Use this method to choose a new Pokémon for the enemy
# The enemy's party is guaranteed to have at least one choosable member.
 @battle.pbDefaultChooseNewEnemy(index,party)
end

def pbWildBattleSuccess
# This method is called when the player wins a wild Pokémon battle.
# This method can change the battle's music for example.
 pbBGMPlay(pbGetWildVictoryME())
end

def pbTrainerBattleSuccess
# This method is called when the player wins a Trainer battle.
# This method can change the battle's music for example.
 pbBGMPlay(pbGetTrainerVictoryME(@battle.opponent))
end

def pbEXPBar(pokemon,battler,startexp,endexp,tempexp1,tempexp2)
 if battler
  @sprites["battler#{battler.index}"].refreshExpLevel
  exprange=(endexp-startexp)
  startexplevel=0
  endexplevel=0
  if exprange!=0
   startexplevel=(tempexp1-startexp)*128/exprange
   endexplevel=(tempexp2-startexp)*128/exprange
  end
  @sprites["battler#{battler.index}"].animateEXP(startexplevel,endexplevel)
  while @sprites["battler#{battler.index}"].animatingEXP
   pbGraphicsUpdate
   pbInputUpdate
   @sprites["battler#{battler.index}"].update
  end
 end
end

def pbShowPokedex(species)
 pbFadeOutIn(99999){
    scene=PokemonPokedexScene.new
    screen=PokemonPokedex.new(scene)
    screen.pbDexEntry(species)
 }
end

def pbFindAnimation(moveid)
 begin
  move2anim=load_data("Data/move2anim.dat")
  anim=move2anim[0][moveid]
  return anim if anim
  if hasConst?(PBMoves,:TACKLE)
   anim=move2anim[0][getConst(PBMoves,:TACKLE)]
   return anim if anim
  end
 rescue
  return nil
 end
 return nil
end



def pbCommonAnimation(animname,attacker,opponent,side=true)
 animations=load_data("Data/PkmnAnimations.rxdata")
 for i in 0...animations.length
  if animations[i] && animations[i].name=="Common:"+animname
   pbAnimationCore(animations[i],attacker,opponent,side)
   return
  end
 end
end

def pbChangeSpecies(attacker,species)
 pkmn=@sprites["pokemon#{attacker.index}"]
 shadow=@sprites["shadow#{attacker.index}"]
 back=!@battle.pbIsOpposing?(attacker.index)
 pkmn.setPokemonBitmapSpecies(
  attacker.pokemon,species,back
 )
 pkmn.y=adjustBattleSpriteY(pkmn,species,attacker.index)
 if shadow && !back
  shadow.visible=showShadow?(species)
 end
end

def pbChangePokemon(attacker,pokemon)
 pkmn=@sprites["pokemon#{attacker.index}"]
 shadow=@sprites["shadow#{attacker.index}"]
 back=!@battle.pbIsOpposing?(attacker.index)
 pkmn.setPokemonBitmap(pokemon,back
 )
 pkmn.y=adjustBattleSpriteY(pkmn,pokemon.species,attacker.index)
 if shadow && !back
  shadow.visible=showShadow?(pokemon.species)
 end
end

def pbAnimation(moveid,attacker,opponent,side=true)
 animid=pbFindAnimation(moveid)
 return if !animid
 animations=load_data("Data/PkmnAnimations.rxdata")
 pbSaveShadows {
  pbAnimationCore(animations[animid],attacker,opponent,side)
 }
 if isConst?(moveid,PBMoves,:TRANSFORM) && attacker && opponent
  # Change form to transformed version
  pbChangePokemon(attacker,opponent.pokemon)
 end
end

def pbSaveShadows
 shadows=[]
 for i in 0...4
  s=@sprites["shadow#{i}"]
  shadows[i]=s ? s.visible : false
  s.visible=false if s
 end
 yield
 for i in 0...4
  s=@sprites["shadow#{i}"]
  s.visible=shadows[i] if s
 end
end

def pbAnimationCore(animation,attacker,opponent,side=true)
 if !attacker || !animation
  return
 end
 @briefmessage=false
 user=(attacker) ? @sprites["pokemon#{attacker.index}"] : nil
 target=(opponent) ? @sprites["pokemon#{opponent.index}"] : nil
 olduserx=user.x
 oldusery=user.y
 oldtargetx=target ? target.x : 0
 oldtargety=target ? target.y : 0
 if !target
  animplayer=PBAnimationPlayer.new(
    animation,user,user,@viewport
  )
  userwidth=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.width
  userheight=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.height
  animplayer.setLineTransform(
    144,188,352,108,
    user.x+(userwidth/2),
    user.y+(userheight/2),
    user.x+(userwidth/2),
    user.y+(userheight/2)
  )
 else
  animplayer=PBAnimationPlayer.new(
    animation,user,target,@viewport
  )
  userwidth=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.width
  targetwidth=(!target.bitmap || target.bitmap.disposed?) ? 128 : target.bitmap.width
  userheight=(!user.bitmap || user.bitmap.disposed?) ? 128 : user.bitmap.height
  targetheight=(!target.bitmap || target.bitmap.disposed?) ? 128 : target.bitmap.height
  animplayer.setLineTransform(
    144,188,352,108,
    user.x+(userwidth/2),
    user.y+(userheight/2),
    target.x+(targetwidth/2),
    target.y+(targetheight/2)
  )
 end
 animplayer.start
 while animplayer.playing?
  animplayer.update
  pbGraphicsUpdate
  pbInputUpdate
 end
 user.ox=0
 user.oy=0
 target.ox=0 if target
 target.oy=0 if target
 user.x=olduserx
 user.y=oldusery
 target.x=oldtargetx if target
 target.y=oldtargety if target
 animplayer.dispose
end

def pbLevelUp(pokemon,battler,oldtotalhp,oldattack,
            olddefense,oldspeed,oldspatk,oldspdef)
   pbTopRightWindow(_INTL("MaxHP<r>+{1}\r\nATTACK<r>+{2}\r\nDEFENSE<r>+{3}\r\nSP. ATK<r>+{4}\r\nSP. DEF<r>+{5}\r\nSPEED<r>+{6}",
       pokemon.totalhp-oldtotalhp,
       pokemon.attack-oldattack,
       pokemon.defense-olddefense,
       pokemon.spatk-oldspatk,
       pokemon.spdef-oldspdef,
       pokemon.speed-oldspeed
   ))
   pbTopRightWindow(_INTL("MaxHP<r>{1}\r\nATTACK<r>{2}\r\nDEFENSE<r>{3}\r\nSP. ATK<r>{4}\r\nSP. DEF<r>{5}\r\nSPEED<r>{6}",
       pokemon.totalhp,pokemon.attack,pokemon.defense,pokemon.spatk,pokemon.spdef,pokemon.speed))
end

def pbThrowAndDeflect(ball,targetBattler)
end
def pbThrow(ball,shakes,targetBattler)
 @briefmessage=false
 pokeballThrow(ball,shakes,targetBattler)
end
def pbThrowSuccess
 if !@opponent
  @briefmessage=false
  pbBGMPlay("../ME/PkmRS-Caught")
  frames=(3.5*Graphics.frame_rate).to_i
  frames.times do
   pbGraphicsUpdate
   pbInputUpdate
  end
 end
end


end



Nach oben
 Profil ICQ  
Mit Zitat antworten  
Offline
Sayjaman
Sayjaman
Benutzeravatar
Beiträge: 50
Alter: 31
Wohnort: Frauenfeld (CH)
BeitragVerfasst: Mi Feb 16, 2011 15:31 
Sorry für Doppelpost, wollte nur mitteilen, dass es sich erledigt hat^^

Musste mich etwas mehr durch den Code "kämpfen" als erwartet, aber weiss jetzt wie's funktioniert und warum meine Änderungen nichts bewirkt haben (wer rechnet auch damit, dass er die Funktionen mal oben, mal unten und zwischendrin script...)

Trotzdem danke für Eure Bemühungen^^

Eine kleine Frage noch zum Schluss:
Die Funktion "yield" ist mir eben in einer ganz anderen Art und Weise begegnet. Kann ich es auch so verwenden, dass die aktuelle Funktion "pausiert" und währenddessen der Code in den {} ausgeführt wird? Und sobald dieser Code ausgeführt wurde, wird der Code nach dem "yield" weitergeführt?

Sowas wäre echt praktisch für z.B. Berechnungen, die man in einer anderen Funktion mal verwendet hat und immer wieder mal als Übergabewert benötigt. (Sorry für die eher einfache Frage, aber Ruby bzw. RGSS ist mir noch nicht so vertraut wie ich es gerne hätte)


Nach oben
 Profil ICQ  
Mit Zitat antworten  
Offline
Official Oldschool
Official Oldschool
Benutzeravatar
Beiträge: 8917
Alter: 31
Wohnort: BRD, Thüringen
BeitragVerfasst: Mi Feb 16, 2011 16:30 
Im Rubykurs wird yield hier grob (eher für Anfänger) erklärt. Kurzgefasst: Der Code zwischen den {...} ist ein sogenanntes Closure. Das ist eine Funktion, die lokal definiert und in einer Variable gespeichert wird (im Gegensatz zu Methoden, die einen festen Namen haben und an eine Klasse und deren Instanzen gebunden ist). Weiterhin hat ein Closure Zugriff auf den umliegenden Variablenscope.

Solche Closures kann man mit folgender Funktion definieren:
Code:
addition = lambda {|x, y| x + y }
addition[5, 2] #=> 7
addition[1, 2] #=> 3

In dem Beispiel habe ich ein Closure mit der Methode lambda erzeugt und diese lokale Funktion mit der [] Methode aufgerufen (alternativ kannst du auch die Methode #call verwenden).

Wie gesagt haben diese Closures Zugriff auf den umliegenden Variablenscope:
Code:
x = 3
potenz = lambda {|y| x**y}
potenz[2] #=> 9
potenz[3] #=> 27
x = 2
potenz[2] #=> 4
potenz[3] #=> 8


Du kannst also im Closure alles machen was du auch im umliegenden Code schreiben kannst (aber Achtung: Variablen die im Closure erzeugt, also das erste Mal zugewiesen werden, sind auch nur im Closure gültig).

Ich denke das beantwortet deine Frage mit dem "Sowas wäre echt praktisch für z.B. Berechnungen, die man in einer anderen Funktion mal verwendet hat und immer wieder mal als Übergabewert benötigt".

yield ist im Prinzip nur Syntaxzucker. Ruby macht intensiven Gebrauch von funktionaler Programmierung. z.B. könnte man eine Funktion schreiben, die zwischen zwei Zahlen iteriert, wie in Pascal die FOR x UPTO y Schleife. Sowas könnte man folgendermaßen umsetzen:
Code:
def iteriere(von, zu, closure)
  while von <= zu do
    closure[von]
    von += 1
  end
end


iteriere(3, 5, lambda {|i| print(i) } )
#=> 3, 4, 5


Das sieht natürlich recht hässlich aus. Ruby hat daher die Block-Syntax eingeführt. Jede Methode darf einen speziellen Closure-Parameter erhalten. Dieser muss nicht innerhalb der Parameterliste stehen, sondern darf hinter der Funktion in geschweiften Klammern angehangen werden. Damit man in der Parameterliste diesen speziellen Closure-Parameter von anderen unterscheiden kann, wird seinem Namen ein & vorrangestellt:
Code:
def iteriere(von, zu, &closure)
  while von <= zu do
    closure[von]
    von += 1
  end
end

# jetzt darf man schreiben:

iteriere(3, 5) {|i| print(i) }


Und da man in den meisten Fällen den Closure selbst gar nicht braucht, sondern nur seine call Methode aufrufen möchte, gibt es das Schlüsselwort yield. Das tut nichts weiter als die call-Methode des Closureparameters aufzurufen.

Code:
def iteriere(von, zu)
  while von <= zu do
    yield von
    von += 1
  end
end

iteriere(3, 5) {|i| print(i) }


Der Vorteil ist nicht nur der kürzere Code, sondern auch dass der Rubyinterpreter an dieser Stelle weiß, dass der Closure wirklich NUR zum Aufrufen der Call-Methode gebraucht wird. Der Interpreter darf deshalb den Code stärker optimieren (yield ist also schneller als die &closure Schreibweise).

btw. gibt es in Ruby eine ganze Menge Methoden, die Gebrauch von Closures machen. Alle Schleifen in Ruby, bis auf until und while, sind über Closures definiert:
Code:
3.upto(5) {|i| print(i) }
8.downto(6) {|i| print(i) }
["Ein", "Array", "mit", "Wörtern"].find_all {|wort| wort.size == 3} #=> ["Ein", "mit"]
[1, 2, 3, 4, 5].map {|i| i + i} #=> [2, 3, 4, 5, 6]
[1, 3, 5].inject(0) {|summe, summant| summe + summant} #=> 9
[1, 2, 3, 4].each {|i| print(i) }
# ... und viele mehr!

_________________


Nach oben
 Profil ICQ  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 5 Beiträge ] 

Alle Zeiten sind UTC + 1 Stunde


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
cron
Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de