#===============================================================================
# * Character Selection - by FL (Credits will be apreciated)
#===============================================================================
#
# This script is for Pokémon Essentials. It's a character selection screen
# suggested for player selection or partner selection.
#
#== INSTALLATION ===============================================================
#
# To this script works, put it above main OR convert into a plugin. Put a 32x32
# background at "Graphics/UI/character_selection_tile" (may works with other
# sizes).
#
#== HOW TO USE =================================================================
#
# Call 'startCharacterSelection(overworld,battle)' passing two arrays with the
# same size as arguments:
#
# - The first include overworld graphics names (from "Graphics/Characters").
# - The second include battler/front graphics names (from "Graphics/Trainers"
# or "Graphics/Characters").
#
# The return is the player selected index, starting at 0.
#
#== EXAMPLES ===================================================================
#
# A basic example that initialize the player:
#
# overworld = [
# "trainer_POKEMONTRAINER_Red",
# "trainer_POKEMONTRAINER_Leaf"]
# battle = ["POKEMONTRAINER_Red",
# "POKEMONTRAINER_Leaf"]
# r=startCharacterSelection(
# overworld,battle)
# pbChangePlayer(r+1)
#
# Example with 4 characters. This example won't change your character, just
# store the index result at game variable 70.
#
# overworld = [
# "trainer_POKEMONTRAINER_Red", "trainer_POKEMONTRAINER_Leaf",
# "trainer_POKEMONTRAINER_Brendan","trainer_POKEMONTRAINER_May"
# ]
# battle = [
# "POKEMONTRAINER_Red","POKEMONTRAINER_Leaf",
# "POKEMONTRAINER_Brendan","POKEMONTRAINER_May"
# ]
# $game_variables[70] = startCharacterSelection(overworld,battle)
#
#===============================================================================
if defined?(PluginManager) && !PluginManager.installed?("Character Selection")
PluginManager.register({
:name => "Character Selection",
:version => "1.2",
:link => "https://www.pokecommunity.com/showthread.php?t=338481",
:credits => "FL"
})
end
class CharacterSelectionScene
BACKGROUND_SPEED = 3
ANIMATION_FRAME_INTERVAL = 4 # Increase for slower animation.
FRAMES_TO_TURN = 128
def pbStartScene(overworld,battle)
@overworld = overworld
@battle = battle
@sprites={}
@viewport=Viewport.new(0,0,Graphics.width,Graphics.height)
@viewport.z=99999
@sprites["bg"]=CharacterSelectionPlane.new(
BACKGROUND_SPEED,FRAMES_TO_TURN,@viewport)
@sprites["bg"].setBitmap("Graphics/UI/character_selection_tile")
@sprites["arrow"]=IconSprite.new(@viewport)
@sprites["arrow"].setBitmap(arrowBitmapPath)
@sprites["battlerbox"]=Window_AdvancedTextPokemon.new("")
@sprites["battlerbox"].viewport=@viewport
pbBottomLeftLines(@sprites["battlerbox"],5)
@sprites["battlerbox"].width=256
@sprites["battlerbox"].x=Graphics.width-@sprites["battlerbox"].width
@sprites["battlerbox"].z=0
@sprites["battler"]=IconSprite.new(384,284,@viewport)
# Numbers for coordinates calculation
lines = 2
totalWidth = 512
totalHeight = 232
marginX = totalWidth/((@overworld.size/2.0).ceil+1)
marginY = 72
for i in 0...@overworld.size
@sprites["icon#{i}"]=AnimatedChar.new(
"Graphics/Characters/"+@overworld[i],4,
[ANIMATION_FRAME_INTERVAL-1,0].max, FRAMES_TO_TURN, @viewport)
@sprites["icon#{i}"].x = marginX*((i/2).floor+1)
@sprites["icon#{i}"].y = marginY+(totalHeight - marginY*2)*(i%lines)
@sprites["icon#{i}"].start
end
updateCursor
@sprites["messagebox"]=Window_AdvancedTextPokemon.new(
_INTL("Choose your character."))
@sprites["messagebox"].viewport=@viewport
pbBottomLeftLines(@sprites["messagebox"],5)
@sprites["messagebox"].width=256
pbFadeInAndShow(@sprites) { update }
end
def updateCursor(index=nil)
@index=0
if index
pbPlayCursorSE
@index=index
end
@sprites["arrow"].x=@sprites["icon#{@index}"].x-32
@sprites["arrow"].y=@sprites["icon#{@index}"].y-32
bmpPath = trainerBitmapPath(@battle[@index])[1]
if bmpPath
echoln("Path found: #{bmpPath}")
#@sprites["battler"].setBitmap(bmpPath)
@sprites["battler"].setTrainerBitmap(bmpPath)
if @sprites["battler"].bitmap
echoln("Bitmap loaded: #{@sprites["battler"].bitmap.width}x#{@sprites["battler"].bitmap.height}")
@sprites["battler"].ox=@sprites["battler"].bitmap.width/2
@sprites["battler"].oy=@sprites["battler"].bitmap.height/2
else
echoln("Bitmap Path Exists, but it doesnt load!")
end
else
echoln("Sprite not found: #{@battle[@index]}")
end
end
def arrowBitmapPath
ret = pbResolveBitmap("Graphics/UI/sel_arrow")
return ret if ret
ret = pbResolveBitmap("Graphics/Pictures/selarrow")
return ret
end
def trainerBitmapPath(spriteName)
ret = [pbResolveBitmap("Graphics/Trainers/"+spriteName.to_s), spriteName]
return ret if ret
ret = pbResolveBitmap("Graphics/Characters/"+spriteName)
return ret
end
def pbMidScene
loop do
Graphics.update
Input.update
self.update
if Input.trigger?(Input::C)
pbPlayDecisionSE
if pbDisplayConfirm(_INTL("Are you sure?"))
pbPlayDecisionSE
return @index
else
pbPlayCancelSE
end
end
lines=2
if Input.repeat?(Input::LEFT)
updateCursor((@index-lines)>=0 ?
@index-lines : @overworld.size-lines+(@index%lines))
end
if Input.repeat?(Input::RIGHT)
updateCursor((@index+lines)<=(@overworld.size-1) ?
@index+lines : @index%lines)
end
if Input.repeat?(Input::UP)
updateCursor(@index!=0 ? @index-1 : @overworld.size-1)
end
if Input.repeat?(Input::DOWN)
updateCursor(@index!=@overworld.size-1 ? @index+1 : 0)
end
end
end
def update
pbUpdateSpriteHash(@sprites)
@sprites["battler"].play
end
def pbDisplayConfirm(text)
ret=-1
oldtext=@sprites["messagebox"].text
@sprites["messagebox"].text=text
using(cmdwindow=Window_CommandPokemon.new([_INTL("Yes"),_INTL("No")])){
cmdwindow.z=@viewport.z+1
cmdwindow.visible=false
pbBottomRight(cmdwindow)
cmdwindow.y-=@sprites["messagebox"].height
loop do
Graphics.update
Input.update
cmdwindow.visible=true if !@sprites["messagebox"].busy?
cmdwindow.update
self.update
if Input.trigger?(Input::B) && !@sprites["messagebox"].busy?
ret=false
end
if (Input.trigger?(Input::C) &&
@sprites["messagebox"].resume && !@sprites["messagebox"].busy?)
ret=(cmdwindow.index==0)
break
end
end
}
@sprites["messagebox"].text=oldtext
return ret
end
def pbEndScene
pbFadeOutAndHide(@sprites) { update }
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
class CharacterSelectionPlane < AnimatedPlane
LIMIT=16
def initialize(speed, turnTime, viewport)
super(viewport)
@speed = speed
@turnTime = turnTime
end
def update
super
@frame=0 if !@frame
@frame+=1
@direction=0 if !@direction
if @frame==@turnTime
@frame=0
@direction+=1
@direction=0 if @direction==4
end
case @direction
when 0 #down
self.oy+=@speed
when 1 #left
self.ox-=@speed
when 2 #up
self.oy-=@speed
when 3 #right
self.ox+=@speed
end
self.ox=0 if self.ox==-LIMIT || self.ox==LIMIT
self.oy=0 if self.oy==-LIMIT || self.oy==LIMIT
end
end
class AnimatedChar < AnimatedSprite
def initialize(*args)
@realframeschar=0
@direction=0
@turnTime=args[3]
super([args[0],args[1],args[2],args[4]])
@frameheight=@animbitmap.height/4
if @animbitmap.width%framecount!=0
raise _INTL("Bitmap's width ({1}) is not a multiple of frame count ({2}) [Bitmap={3}]",@animbitmap.width,@framewidth,@animname)
end
@playing=false
self.src_rect.height=@frameheight
self.ox=@framewidth/2
self.oy=@frameheight
end
def frame=(value)
@frame=value
@realframes=0
self.src_rect.x=@frame%@framesperrow*@framewidth
end
def update
super
if @playing
@realframeschar+=1
if @realframeschar==@turnTime
@realframeschar=0
@direction+=1
@direction= 0 if @direction==4
#Spin
if @direction==2
dir=3
elsif @direction==3
dir=2
else
dir=@direction
end
self.src_rect.y=@frameheight*dir
end
end
end
end
end
class CharacterSelectionScreen
def initialize(scene)
@scene=scene
end
def pbStartScreen(overworld,battle)
@scene.pbStartScene(overworld,battle)
ret = @scene.pbMidScene
@scene.pbEndScene
return ret
end
end
def startCharacterSelection(overworld,battle)
ret = nil
pbFadeOutIn(99999) {
scene=CharacterSelectionScene.new
screen=CharacterSelectionScreen.new(scene)
ret=screen.pbStartScreen(overworld,battle)
}
return ret
end