#=============================================================================== # Evolution animation metafiles and related methods #=============================================================================== class SpriteMetafile VIEWPORT = 0 TONE = 1 SRC_RECT = 2 VISIBLE = 3 X = 4 Y = 5 Z = 6 OX = 7 OY = 8 ZOOM_X = 9 ZOOM_Y = 10 ANGLE = 11 MIRROR = 12 BUSH_DEPTH = 13 OPACITY = 14 BLEND_TYPE = 15 COLOR = 16 FLASHCOLOR = 17 FLASHDURATION = 18 BITMAP = 19 def length return @metafile.length end def [](i) return @metafile[i] end def initialize(viewport=nil) @metafile=[] @values=[ viewport, Tone.new(0,0,0,0),Rect.new(0,0,0,0), true, 0,0,0,0,0,100,100, 0,false,0,255,0, Color.new(0,0,0,0),Color.new(0,0,0,0), 0 ] end def disposed? return false end def dispose; end def flash(color,duration) if duration>0 @values[FLASHCOLOR]=color.clone @values[FLASHDURATION]=duration @metafile.push([FLASHCOLOR,color]) @metafile.push([FLASHDURATION,duration]) end end def x return @values[X] end def x=(value) @values[X]=value @metafile.push([X,value]) end def y return @values[Y] end def y=(value) @values[Y]=value @metafile.push([Y,value]) end def bitmap return nil end def bitmap=(value) if value && !value.disposed? @values[SRC_RECT].set(0,0,value.width,value.height) @metafile.push([SRC_RECT,@values[SRC_RECT].clone]) end end def src_rect return @values[SRC_RECT] end def src_rect=(value) @values[SRC_RECT]=value @metafile.push([SRC_RECT,value]) end def visible return @values[VISIBLE] end def visible=(value) @values[VISIBLE]=value @metafile.push([VISIBLE,value]) end def z return @values[Z] end def z=(value) @values[Z]=value @metafile.push([Z,value]) end def ox return @values[OX] end def ox=(value) @values[OX]=value @metafile.push([OX,value]) end def oy return @values[OY] end def oy=(value) @values[OY]=value @metafile.push([OY,value]) end def zoom_x return @values[ZOOM_X] end def zoom_x=(value) @values[ZOOM_X]=value @metafile.push([ZOOM_X,value]) end def zoom_y return @values[ZOOM_Y] end def zoom_y=(value) @values[ZOOM_Y]=value @metafile.push([ZOOM_Y,value]) end def zoom=(value) @values[ZOOM_X]=value @metafile.push([ZOOM_X,value]) @values[ZOOM_Y]=value @metafile.push([ZOOM_Y,value]) end def angle return @values[ANGLE] end def angle=(value) @values[ANGLE]=value @metafile.push([ANGLE,value]) end def mirror return @values[MIRROR] end def mirror=(value) @values[MIRROR]=value @metafile.push([MIRROR,value]) end def bush_depth return @values[BUSH_DEPTH] end def bush_depth=(value) @values[BUSH_DEPTH]=value @metafile.push([BUSH_DEPTH,value]) end def opacity return @values[OPACITY] end def opacity=(value) @values[OPACITY]=value @metafile.push([OPACITY,value]) end def blend_type return @values[BLEND_TYPE] end def blend_type=(value) @values[BLEND_TYPE]=value @metafile.push([BLEND_TYPE,value]) end def color return @values[COLOR] end def color=(value) @values[COLOR]=value.clone @metafile.push([COLOR,@values[COLOR]]) end def tone return @values[TONE] end def tone=(value) @values[TONE]=value.clone @metafile.push([TONE,@values[TONE]]) end def update @metafile.push([-1,nil]) end end class SpriteMetafilePlayer def initialize(metafile,sprite=nil) @metafile=metafile @sprites=[] @playing=false @index=0 @sprites.push(sprite) if sprite end def add(sprite) @sprites.push(sprite) end def playing? return @playing end def play @playing=true @index=0 end def update if @playing for j in @index...@metafile.length @index=j+1 break if @metafile[j][0]<0 code=@metafile[j][0] value=@metafile[j][1] for sprite in @sprites case code when SpriteMetafile::X; sprite.x=value when SpriteMetafile::Y; sprite.y=value when SpriteMetafile::OX; sprite.ox=value when SpriteMetafile::OY; sprite.oy=value when SpriteMetafile::ZOOM_X; sprite.zoom_x=value when SpriteMetafile::ZOOM_Y; sprite.zoom_y=value when SpriteMetafile::SRC_RECT; sprite.src_rect=value when SpriteMetafile::VISIBLE; sprite.visible=value when SpriteMetafile::Z; sprite.z=value # prevent crashes when SpriteMetafile::ANGLE; sprite.angle=(value==180) ? 179.9 : value when SpriteMetafile::MIRROR; sprite.mirror=value when SpriteMetafile::BUSH_DEPTH; sprite.bush_depth=value when SpriteMetafile::OPACITY; sprite.opacity=value when SpriteMetafile::BLEND_TYPE; sprite.blend_type=value when SpriteMetafile::COLOR; sprite.color=value when SpriteMetafile::TONE; sprite.tone=value end end end @playing=false if @index==@metafile.length end end end def pbSaveSpriteState(sprite) state=[] return state if !sprite || sprite.disposed? state[SpriteMetafile::BITMAP] = sprite.x state[SpriteMetafile::X] = sprite.x state[SpriteMetafile::Y] = sprite.y state[SpriteMetafile::SRC_RECT] = sprite.src_rect.clone state[SpriteMetafile::VISIBLE] = sprite.visible state[SpriteMetafile::Z] = sprite.z state[SpriteMetafile::OX] = sprite.ox state[SpriteMetafile::OY] = sprite.oy state[SpriteMetafile::ZOOM_X] = sprite.zoom_x state[SpriteMetafile::ZOOM_Y] = sprite.zoom_y state[SpriteMetafile::ANGLE] = sprite.angle state[SpriteMetafile::MIRROR] = sprite.mirror state[SpriteMetafile::BUSH_DEPTH] = sprite.bush_depth state[SpriteMetafile::OPACITY] = sprite.opacity state[SpriteMetafile::BLEND_TYPE] = sprite.blend_type state[SpriteMetafile::COLOR] = sprite.color.clone state[SpriteMetafile::TONE] = sprite.tone.clone return state end def pbRestoreSpriteState(sprite,state) return if !state || !sprite || sprite.disposed? sprite.x = state[SpriteMetafile::X] sprite.y = state[SpriteMetafile::Y] sprite.src_rect = state[SpriteMetafile::SRC_RECT] sprite.visible = state[SpriteMetafile::VISIBLE] sprite.z = state[SpriteMetafile::Z] sprite.ox = state[SpriteMetafile::OX] sprite.oy = state[SpriteMetafile::OY] sprite.zoom_x = state[SpriteMetafile::ZOOM_X] sprite.zoom_y = state[SpriteMetafile::ZOOM_Y] sprite.angle = state[SpriteMetafile::ANGLE] sprite.mirror = state[SpriteMetafile::MIRROR] sprite.bush_depth = state[SpriteMetafile::BUSH_DEPTH] sprite.opacity = state[SpriteMetafile::OPACITY] sprite.blend_type = state[SpriteMetafile::BLEND_TYPE] sprite.color = state[SpriteMetafile::COLOR] sprite.tone = state[SpriteMetafile::TONE] end def pbSaveSpriteStateAndBitmap(sprite) return [] if !sprite || sprite.disposed? state=pbSaveSpriteState(sprite) state[SpriteMetafile::BITMAP]=sprite.bitmap return state end def pbRestoreSpriteStateAndBitmap(sprite,state) return if !state || !sprite || sprite.disposed? sprite.bitmap=state[SpriteMetafile::BITMAP] pbRestoreSpriteState(sprite,state) return state end #=============================================================================== # Evolution screen #=============================================================================== class PokemonEvolutionScene private def pbGenerateMetafiles(s1x,s1y,s2x,s2y) sprite = SpriteMetafile.new sprite.ox = s1x sprite.oy = s1y sprite.opacity = 255 sprite2 = SpriteMetafile.new sprite2.ox = s2x sprite2.oy = s2y sprite2.zoom = 0.0 sprite2.opacity = 255 alpha = 0 alphaDiff = 10*20/Graphics.frame_rate loop do sprite.color.red = 255 sprite.color.green = 255 sprite.color.blue = 255 sprite.color.alpha = alpha sprite.color = sprite.color sprite2.color = sprite.color sprite2.color.alpha = 255 sprite.update sprite2.update break if alpha>=255 alpha += alphaDiff end totaltempo = 0 currenttempo = 25 maxtempo = 7*Graphics.frame_rate while totaltempo0 @bgviewport.rect.y -= halfResizeDiff @sprites["background"].oy = @bgviewport.rect.y end if @bgviewport.rect.height=255 end @bgviewport.rect.y = 0 @bgviewport.rect.height = Graphics.height @sprites["background"].oy = 0 if canceled pbRestoreSpriteState(@sprites["rsprite1"],oldstate) pbRestoreSpriteState(@sprites["rsprite2"],oldstate2) @sprites["rsprite1"].zoom_x = 1.0 @sprites["rsprite1"].zoom_y = 1.0 @sprites["rsprite1"].color.alpha = 0 @sprites["rsprite1"].visible = true @sprites["rsprite2"].visible = false else @sprites["rsprite1"].visible = false @sprites["rsprite2"].visible = true @sprites["rsprite2"].zoom_x = 1.0 @sprites["rsprite2"].zoom_y = 1.0 @sprites["rsprite2"].color.alpha = 0 end (Graphics.frame_rate/4).times do Graphics.update pbUpdate(true) end tone = 255 toneDiff = 40*20/Graphics.frame_rate loop do Graphics.update pbUpdate tone -= toneDiff @viewport.tone.set(tone,tone,tone,0) break if tone<=0 end end def pbStartScreen(pokemon,newspecies) @pokemon = pokemon @newspecies = 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 addBackgroundOrColoredPlane(@sprites,"background","evolutionbg", Color.new(248,248,248),@bgviewport) rsprite1 = PokemonSprite.new(@viewport) rsprite1.setOffset(PictureOrigin::Center) rsprite1.setPokemonBitmap(@pokemon,false) rsprite1.x = Graphics.width/2 rsprite1.y = (Graphics.height-64)/2 rsprite2 = PokemonSprite.new(@viewport) rsprite2.setOffset(PictureOrigin::Center) rsprite2.setPokemonBitmapSpecies(@pokemon,@newspecies,false) 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"] = pbCreateMessageWindow(@msgviewport) pbFadeInAndShow(@sprites) { pbUpdate } end # Closes the evolution screen. def pbEndScreen pbDisposeMessageWindow(@sprites["msgwindow"]) pbFadeOutAndHide(@sprites) { pbUpdate } pbDisposeSpriteHash(@sprites) @viewport.dispose @bgviewport.dispose @msgviewport.dispose end # Opens the evolution screen def pbEvolution(cancancel=true) metaplayer1 = SpriteMetafilePlayer.new(@metafile1,@sprites["rsprite1"]) metaplayer2 = SpriteMetafilePlayer.new(@metafile2,@sprites["rsprite2"]) metaplayer1.play metaplayer2.play pbBGMStop pbPlayCry(@pokemon) pbMessageDisplay(@sprites["msgwindow"], _INTL("\\se[]What? {1} is evolving!\\^",@pokemon.name)) { pbUpdate } pbMessageWaitForInput(@sprites["msgwindow"],50,true) { pbUpdate } pbPlayDecisionSE oldstate = pbSaveSpriteState(@sprites["rsprite1"]) oldstate2 = pbSaveSpriteState(@sprites["rsprite2"]) pbMEPlay("Evolution start") pbBGMPlay("Evolution") canceled = false begin pbUpdateNarrowScreen metaplayer1.update metaplayer2.update Graphics.update Input.update pbUpdate(true) if Input.trigger?(Input::B) && cancancel pbBGMStop pbPlayCancelSE canceled = true break end end while metaplayer1.playing? && metaplayer2.playing? pbFlashInOut(canceled,oldstate,oldstate2) if canceled pbMessageDisplay(@sprites["msgwindow"], _INTL("Huh? {1} stopped evolving!",@pokemon.name)) { pbUpdate } else pbEvolutionSuccess end end def pbEvolutionSuccess # Play cry of evolved species frames = pbCryFrameLength(@newspecies,@pokemon.form) pbBGMStop pbPlayCrySpecies(@newspecies,@pokemon.form) frames.times do Graphics.update pbUpdate end # Success jingle/message pbMEPlay("Evolution success") newspeciesname = PBSpecies.getName(@newspecies) oldspeciesname = PBSpecies.getName(@pokemon.species) pbMessageDisplay(@sprites["msgwindow"], _INTL("\\se[]Congratulations! Your {1} evolved into {2}!\\wt[80]", @pokemon.name,newspeciesname)) { pbUpdate } @sprites["msgwindow"].text = "" # Check for consumed item and check if Pokémon should be duplicated createSpecies = pbRemoveItemAfterEvolution # Modify Pokémon to make it evolved @pokemon.species = @newspecies @pokemon.name = newspeciesname if @pokemon.name==oldspeciesname @pokemon.form = 0 if @pokemon.isSpecies?(:MOTHIM) @pokemon.calcStats # See and own evolved species $Trainer.seen[@newspecies] = true $Trainer.owned[@newspecies] = true pbSeenForm(@pokemon) # Learn moves upon evolution for evolved species movelist = @pokemon.getMoveList for i in movelist next if i[0]!=0 && i[0]!=@pokemon.level # 0 is "learn upon evolution" pbLearnMove(@pokemon,i[1],true) { pbUpdate } end # Duplicate Pokémon (i.e. Shedinja) if createSpecies>0 && $Trainer.party.length<6 pbDuplicatePokemon(createSpecies) # Consume Poké Ball $PokemonBag.pbDeleteItem(getConst(PBItems,:POKEBALL)) end end def pbRemoveItemAfterEvolution removeItem = false createSpecies = pbCheckEvolutionEx(@pokemon) { |_pokemon,evonib,_level,pkmn| case evonib when PBEvolution::Shedinja next pkmn if $PokemonBag.pbHasItem?(getConst(PBItems,:POKEBALL)) when PBEvolution::TradeItem,PBEvolution::DayHoldItem,PBEvolution::NightHoldItem removeItem = true if pkmn==@newspecies # Item is now consumed end next -1 } @pokemon.setItem(0) if removeItem return createSpecies end def pbDuplicatePokemon(createSpecies) newpokemon = @pokemon.clone newpokemon.species = createSpecies newpokemon.name = PBSpecies.getName(createSpecies) newpokemon.iv = @pokemon.iv.clone newpokemon.ev = @pokemon.ev.clone newpokemon.markings = 0 newpokemon.ballused = 0 newpokemon.setItem(0) newpokemon.clearAllRibbons newpokemon.calcStats newpokemon.heal # Add duplicate Pokémon to party $Trainer.party.push(newpokemon) # See and own duplicate Pokémon $Trainer.seen[createSpecies] = true $Trainer.owned[createSpecies] = true pbSeenForm(newpokemon) end end