- Pokémon Essentials Version
- v19.1 ➖
While giving TMs their own dedicated pocket was definitely more convenient in the long run, the TM case did have its own little uses in being able to show a move's stats at a glance, and I thought its UI was fun! So, here it is!
This script also lets you sort by move properties! Power, type, name, accuracy, category, or PP!
There's a few steps to putting this together, because I wanted to allow for different possible ways to implement it, so be sure to read through all the instructions!
Part 1: Setting up the UI
This is the easy stuff!Download the files in the download link, and find the folder that's just labelled "TM Case". Put that folder (the folder itself, not just the contents!) in Graphics/Pictures.
(Please note- this pack only has graphics for the eighteen canon types. If your game is adding any custom types with their own TMs, be sure to put in a file named tm_(type)!)
Paste this in a script section above Main:
Ruby:
ItemHandlers::UseInField .add(:TMCASE,proc { |item|
TMCase.new
next 1
})
class Window_TMCase < Window_DrawableCommand
attr_reader :pocket
def initialize(bag,filterlist,pocket,x,y,width,height)
@bag = bag
@filterlist = filterlist
@pocket = pocket
@adapter = PokemonMartAdapter.new
super(x,y,width,height)
@selarrow = AnimatedBitmap.new("Graphics/Pictures/selarrow")
self.windowskin = nil
end
def dispose
super
end
def pocket=(value)
@pocket = value
@item_max = (@filterlist) ? @filterlist[@pocket].length+1 : @bag.pockets[@pocket].length+1
self.index = @bag.getChoice(@pocket)
end
def page_row_max; return 5; end
def page_item_max; return 5; end
def item
return 0 if @filterlist && !@filterlist[@pocket][self.index]
thispocket = @bag.pockets[@pocket]
item = (@filterlist) ? thispocket[@filterlist[@pocket][self.index]] : thispocket[self.index]
return (item) ? item[0] : 0
end
def itemCount
return (@filterlist) ? @filterlist[@pocket].length+1 : @bag.pockets[@pocket].length+1
end
def itemRect(item)
if item<0 || item>=@item_max || item<self.top_item ||
item>self.top_item+self.page_item_max
return Rect.new(0,0,0,0)
else
cursor_width = (self.width-self.borderX-(@column_max-1)*@column_spacing) / @column_max
x = item % @column_max * (cursor_width + @column_spacing)
y = item / @column_max * @row_height - @virtualOy
return Rect.new(x, y, cursor_width, @row_height)
end
end
def drawCursor(index,rect)
if self.index==index
bmp = @selarrow.bitmap
pbCopyBitmap(self.contents,bmp,rect.x,rect.y+24)
end
end
def drawItem(index,_count,rect)
textpos = []
rect = Rect.new(rect.x+16,rect.y+16,rect.width-16,rect.height)
ypos = rect.y+4
thispocket = @bag.pockets[@pocket]
if index==self.itemCount-1
textpos.push([_INTL("CLOSE"),rect.x,ypos,false,self.baseColor,self.shadowColor])
else
item = (@filterlist) ? thispocket[@filterlist[@pocket][index]][0] : thispocket[index][0]
baseColor = self.baseColor
shadowColor = self.shadowColor
textpos.push(
[@adapter.getDisplayName(item),rect.x,ypos,false,baseColor,shadowColor]
)
if !GameData::Item.get(item).is_important? # Not an HM (or infinite TM)
qty = (@filterlist) ? thispocket[@filterlist[@pocket][index]][1] : thispocket[index][1]
qtytext = _ISPRINTF("x{1: 3d}",qty)
xQty = rect.x+rect.width-self.contents.text_size(qtytext).width-16
textpos.push([qtytext,xQty,ypos,false,baseColor,shadowColor])
end
end
pbDrawTextPositions(self.contents,textpos)
end
def refresh
@item_max = itemCount()
self.update_cursor_rect
dwidth = self.width-self.borderX
dheight = self.height-self.borderY
self.contents = pbDoEnsureBitmap(self.contents,dwidth,dheight)
self.contents.clear
for i in 0...@item_max
next if i<self.top_item || i>self.top_item+self.page_item_max
drawItem(i,@item_max,itemRect(i))
end
drawCursor(self.index,itemRect(self.index))
end
def update
super
@uparrow.visible = false
@downarrow.visible = false
end
end
class TMCase
BASE=Color.new(248,248,248)
SHADOW=Color.new(96,96,96)
STATBASE=Color.new(64,64,64)
STATSHADOW=Color.new(216,216,192)
MOVE = true #set to false if you don't want the position of the disc to move
def initialize
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@sprites = {}
@sprites["bg"] = Sprite.new(@viewport)
@sprites["bg"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/bg")
@sprites["overlay"] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
@sprites["doverlay"] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
pbSetSystemFont(@sprites["overlay"].bitmap)
pbSetSystemFont(@sprites["bg"].bitmap)
pbSetSystemFont(@sprites["doverlay"].bitmap)
@power="---"
@accuracy="---"
@pp="---"
@description="---"
@type="normal"
@category=0
@sprites["case"] = Sprite.new(@viewport)
@sprites["case"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/TM Case")
@sprites["case"].x = 24
@sprites["case"].y = 112
@sprites["case"].z = 3
@sprites["disc"] = Sprite.new(@viewport)
@sprites["disc"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/tm_#{@type}")
@sprites["disc"].x = 58
@sprites["disc"].y = 76
@sprites["disc"].z = 1
@sprites["disc"].visible = false
@sprites["sticker"] = Sprite.new(@viewport)
@sprites["sticker"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/hmsticker")
@sprites["sticker"].x = @sprites["disc"].x
@sprites["sticker"].y = @sprites["disc"].y
@sprites["sticker"].z = 2
@sprites["sticker"].visible = false
@sprites["itemlist"] = Window_TMCase.new($PokemonBag,nil,4,188,-22,344,40+32+7*32)
@sprites["itemlist"].viewport = @viewport
@sprites["itemlist"].pocket = 4
@sprites["itemlist"].index = 0
@sprites["itemlist"].baseColor = Color.new(96,96,96)
@sprites["itemlist"].shadowColor = Color.new(208,208,200)
@typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
@catbitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/category"))
overlay = @sprites["overlay"].bitmap
pbDrawTextPositions(@sprites["bg"].bitmap,[[_INTL("TM CASE"),86,6,2,BASE,SHADOW]])
overlay.font.size=26
itemlist=@sprites["itemlist"]
if itemlist.index<itemlist.itemCount-1
movestats
@sprites["disc"].visible = true
else
@power = "---"
@accuracy= "---"
@pp = "---"
@description = "---"
end
textpos = [
[_INTL("#{@power} "),154,292,2,STATBASE,STATSHADOW],
[_INTL("#{@accuracy}% "),154,317,2,STATBASE,STATSHADOW],
[_INTL("#{@pp} PP"),154,343,2,STATBASE,STATSHADOW]
]
drawTextEx(@sprites["doverlay"].bitmap,192,244,320,4,@description,BASE,SHADOW)
pbDrawTextPositions(overlay,textpos)
pbFadeInAndShow(@sprites)
main
end
def movestats
overlay=@sprites["overlay"].bitmap
itemlist=@sprites["itemlist"]
move = GameData::Item.get(itemlist.item).move
# Get data for selected move
if move
moveData = GameData::Move.try_get(move)
@power = moveData.base_damage
@power = "---" if @power == 0 || @power == 1
@category = moveData.category
@accuracy = moveData.accuracy
@accuracy = "---" if @accuracy == 0
@pp = moveData.total_pp
@pp = "---" if @pp == 0
@description = moveData.description
type = moveData.type
type = 0 if type == nil
@category = 0 if @category == nil
@description = "" if @description == nil
type = GameData::Type.try_get(type)
@type = type.real_name.downcase
typerect = Rect.new(0,type.id_number*28,64,28)
overlay.blt(114,244,@typebitmap.bitmap,typerect)
catrect = Rect.new(0,@category*28,64,28)
overlay.blt(114,272,@catbitmap.bitmap,catrect)
@sprites["disc"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/tm_#{@type}")
else
@power = "---"
@accuracy= "---"
@pp = "---"
@category = 0
@description = ""
end
end
def main
loop do
@sprites["doverlay"].bitmap.clear
overlay=@sprites["overlay"].bitmap
overlay.clear
itemlist=@sprites["itemlist"]
@sprites["disc"].visible=(itemlist.index<itemlist.itemCount-1)
if itemlist.index<itemlist.itemCount-1
movestats
else
@power = ""
@accuracy= ""
@pp = ""
@description = ""
end
@sprites["sticker"].visible = (GameData::Item.get(itemlist.item).is_HM?) if itemlist.index<itemlist.itemCount-1
@sprites["sticker"].x = @sprites["disc"].x
@sprites["sticker"].y = @sprites["disc"].y
textpos = [
[_INTL("#{@power} "),154,292,2,STATBASE,STATSHADOW],
[_INTL("#{@accuracy}% "),154,317,2,STATBASE,STATSHADOW],
[_INTL("#{@pp} PP"),154,343,2,STATBASE,STATSHADOW]
]
pbDrawTextPositions(overlay,textpos)
drawTextEx(@sprites["doverlay"].bitmap,192,244,320,4,@description,BASE,SHADOW)
Graphics.update
Input.update
if Input.trigger?(Input::RIGHT) && $game_variables[1]==8
$game_variables[1]=1
break
elsif Input.trigger?(Input::LEFT) && $game_variables[1]==8
$game_variables[1]=0
break
elsif Input.trigger?(Input::DOWN) || Input.repeat?(Input::DOWN)
if itemlist.itemCount>1
pbPlayCursorSE
if itemlist.index<itemlist.itemCount-1
itemlist.index+=1
else
itemlist.index=0
@sprites["disc"].x = 58
@sprites["disc"].y = 76
end
end
if itemlist.index<itemlist.itemCount-1 && itemlist.index>0 &&
MOVE==true && @sprites["disc"].x > 24
@sprites["disc"].x -= 1
@sprites["disc"].y += 1
end
elsif Input.trigger?(Input::UP) || Input.repeat?(Input::UP)
if itemlist.itemCount>1
pbPlayCursorSE
if itemlist.index>0
itemlist.index-=1
if @sprites["disc"].x < 58 && MOVE==true && itemlist.index < 35
@sprites["disc"].x += 1
@sprites["disc"].y -= 1
end
else
itemlist.index=itemlist.itemCount-1
if MOVE==true
@sprites["disc"].x = (58-[itemlist.itemCount,34].min)
@sprites["disc"].y = (76+[itemlist.itemCount,34].min)
end
end
end
elsif Input.trigger?(Input::C)
if itemlist.index<itemlist.itemCount-1
pbUseItem($PokemonBag,itemlist.item)
itemlist.refresh
else
break
end
elsif Input.trigger?(Input::A)
choice = pbMessage(_INTL("Sort by"),
[_INTL("Number"),
_INTL("Type"),
_INTL("Category"),
_INTL("Base Power"),
_INTL("Accuracy"),
_INTL("Name"),
_INTL("Cancel")
])
sortarray = []
for i in 0...$PokemonBag.pockets[4].length
item = $PokemonBag.pockets[4][i][0]
move = GameData::Item.get(item).move
moveData = GameData::Move.try_get(move)
type = moveData.type
cat = moveData.category
power = moveData.base_damage
accuracy = moveData.accuracy
name = moveData.real_name
sortarray.push [item,type,cat,power,accuracy,name]
end
if choice == 0
$PokemonBag.pockets[4].sort!
else
sortarray.sort! { |a,b| (a[choice]==b[choice]) ? a[0]<=>b[0] : a[choice]<=>b[choice] }
for i in 0...$PokemonBag.pockets[4].length
$PokemonBag.pockets[4][i][0]=sortarray[i][0]
end
itemlist.refresh
end
elsif Input.trigger?(Input::B)
break
end
end
pbSEPlay("GUI menu close",80)
pbFadeOutAndHide(@sprites)
$PokemonBag.pockets[4].sort!
dispose
end
def dispose
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
end
Ruby:
ItemHandlers::UseInField .add(:TMCASE,proc { |item|
TMCase.new
next 1
})
class Window_TMCase < Window_DrawableCommand
attr_reader :pocket
def initialize(bag,filterlist,pocket,x,y,width,height)
@bag = bag
@filterlist = filterlist
@pocket = pocket
@adapter = PokemonMartAdapter.new
super(x,y,width,height)
@selarrow = AnimatedBitmap.new("Graphics/Pictures/selarrow")
self.windowskin = nil
end
def dispose
super
end
def pocket=(value)
@pocket = value
@item_max = (@filterlist) ? @filterlist[@pocket].length+1 : @bag.pockets[@pocket].length+1
self.index = @bag.getChoice(@pocket)
end
def page_row_max; return 5; end
def page_item_max; return 5; end
def item
return 0 if @filterlist && !@filterlist[@pocket][self.index]
thispocket = @bag.pockets[@pocket]
item = (@filterlist) ? thispocket[@filterlist[@pocket][self.index]] : thispocket[self.index]
return (item) ? item[0] : 0
end
def itemCount
return (@filterlist) ? @filterlist[@pocket].length+1 : @bag.pockets[@pocket].length+1
end
def itemRect(item)
if item<0 || item>=@item_max || item<self.top_item ||
item>self.top_item+self.page_item_max
return Rect.new(0,0,0,0)
else
cursor_width = (self.width-self.borderX-(@column_max-1)*@column_spacing) / @column_max
x = item % @column_max * (cursor_width + @column_spacing)
y = item / @column_max * @row_height - @virtualOy
return Rect.new(x, y, cursor_width, @row_height)
end
end
def drawCursor(index,rect)
if self.index==index
bmp = @selarrow.bitmap
pbCopyBitmap(self.contents,bmp,rect.x,rect.y+20)
end
end
def drawItem(index,_count,rect)
textpos = []
rect = Rect.new(rect.x+16,rect.y+16,rect.width-16,rect.height)
ypos = rect.y+4
thispocket = @bag.pockets[@pocket]
if index==self.itemCount-1
textpos.push([_INTL("CLOSE"),rect.x,ypos,false,self.baseColor,self.shadowColor])
else
item = (@filterlist) ? thispocket[@filterlist[@pocket][index]][0] : thispocket[index][0]
baseColor = self.baseColor
shadowColor = self.shadowColor
textpos.push(
[@adapter.getDisplayName(item),rect.x,ypos,false,baseColor,shadowColor]
)
if !pbIsImportantItem?(item) # Not an HM (or infinite TM)
qty = (@filterlist) ? thispocket[@filterlist[@pocket][index]][1] : thispocket[index][1]
qtytext = _ISPRINTF("x{1: 3d}",qty)
xQty = rect.x+rect.width-self.contents.text_size(qtytext).width-16
textpos.push([qtytext,xQty,ypos,false,baseColor,shadowColor])
end
end
pbDrawTextPositions(self.contents,textpos)
end
def refresh
@item_max = itemCount()
self.update_cursor_rect
dwidth = self.width-self.borderX
dheight = self.height-self.borderY
self.contents = pbDoEnsureBitmap(self.contents,dwidth,dheight)
self.contents.clear
for i in 0...@item_max
next if i<self.top_item || i>self.top_item+self.page_item_max
drawItem(i,@item_max,itemRect(i))
end
drawCursor(self.index,itemRect(self.index))
end
def update
super
@uparrow.visible = false
@downarrow.visible = false
end
end
class TMCase
BASE=Color.new(248,248,248)
SHADOW=Color.new(96,96,96)
STATBASE=Color.new(64,64,64)
STATSHADOW=Color.new(216,216,192)
def initialize
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@move = true #set to false if you don't want the position of the disc to move
@sprites = {}
@sprites["bg"] = Sprite.new(@viewport)
@sprites["bg"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/bg")
@sprites["overlay"] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
@sprites["doverlay"] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
pbSetSystemFont(@sprites["overlay"].bitmap)
pbSetSystemFont(@sprites["bg"].bitmap)
pbSetSystemFont(@sprites["doverlay"].bitmap)
@power="---"
@accuracy="---"
@pp="---"
@description="---"
@type="normal"
@category=0
@sprites["case"] = Sprite.new(@viewport)
@sprites["case"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/TM Case")
@sprites["case"].x = 24
@sprites["case"].y = 112
@sprites["case"].z = 3
@sprites["disc"] = Sprite.new(@viewport)
@sprites["disc"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/tm_#{@type}")
@sprites["disc"].x = 58
@sprites["disc"].y = 76
@sprites["disc"].z = 1
@sprites["disc"].visible = false
@sprites["sticker"] = Sprite.new(@viewport)
@sprites["sticker"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/hmsticker")
@sprites["sticker"].x = @sprites["disc"].x
@sprites["sticker"].y = @sprites["disc"].y
@sprites["sticker"].z = 2
@sprites["sticker"].visible = false
@sprites["itemlist"] = Window_TMCase.new($PokemonBag,nil,4,188,-17,344,40+32+7*32)
@sprites["itemlist"].viewport = @viewport
@sprites["itemlist"].pocket = 4
@sprites["itemlist"].index = 0
@sprites["itemlist"].baseColor = Color.new(96,96,96)
@sprites["itemlist"].shadowColor = Color.new(208,208,200)
@typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
@catbitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/category"))
overlay = @sprites["overlay"].bitmap
pbDrawTextPositions(@sprites["bg"].bitmap,[[_INTL("TM CASE"),86,15,2,BASE,SHADOW]])
overlay.font.size=24
itemlist=@sprites["itemlist"]
if itemlist.index<itemlist.itemCount-1
movestats
@sprites["disc"].visible = true
else
@power = "---"
@accuracy= "---"
@pp = "---"
@description = "---"
end
textpos = [
[_INTL("#{@power} "),154,297,2,STATBASE,STATSHADOW],
[_INTL("#{@accuracy}% "),154,322,2,STATBASE,STATSHADOW],
[_INTL("#{@pp} PP"),154,348,2,STATBASE,STATSHADOW]
]
drawTextEx(@sprites["doverlay"].bitmap,192,244,320,4,@description,BASE,SHADOW)
pbDrawTextPositions(overlay,textpos)
pbFadeInAndShow(@sprites)
main
end
def movestats
overlay=@sprites["overlay"].bitmap
itemlist=@sprites["itemlist"]
moveid = pbGetMachine(itemlist.item)
# Get data for selected move
moveData = pbGetMoveData(moveid)
@power = moveData[MOVE_BASE_DAMAGE]
if @power == 0
@power = "---"
end
@category = moveData[MOVE_CATEGORY]
@accuracy = moveData[MOVE_ACCURACY]
if @accuracy == 0
@accuracy= "---"
end
@pp = moveData[MOVE_TOTAL_PP]
if @pp == 0
@pp = "---"
end
@description = moveData[MOVE_DESCRIPTION]
type = moveData[MOVE_TYPE]
if type == nil
type = 0
end
if @category == nil
@category = 0
end
if @description == nil
@description = "---"
end
@type = PBTypes.getName(type).downcase
typerect = Rect.new(0,type*28,64,28)
overlay.blt(114,244,@typebitmap.bitmap,typerect)
catrect = Rect.new(0,@category*28,64,28)
overlay.blt(114,272,@catbitmap.bitmap,catrect)
@sprites["disc"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/tm_#{@type}")
end
def main
loop do
@sprites["doverlay"].bitmap.clear
overlay=@sprites["overlay"].bitmap
overlay.clear
itemlist=@sprites["itemlist"]
@sprites["disc"].visible=(itemlist.index<itemlist.itemCount-1)
if itemlist.index<itemlist.itemCount-1
movestats
else
@power = "---"
@accuracy= "---"
@pp = "---"
@description = "---"
end
@sprites["sticker"].visible = (pbIsHiddenMachine?(itemlist.item))
@sprites["sticker"].x = @sprites["disc"].x
@sprites["sticker"].y = @sprites["disc"].y
pbDrawTextPositions(@sprites["bg"].bitmap,[[_INTL("TM CASE"),86,15,2,BASE,SHADOW]])
overlay.font.size=24
textpos = [
[_INTL("#{@power} "),154,297,2,STATBASE,STATSHADOW],
[_INTL("#{@accuracy}% "),154,322,2,STATBASE,STATSHADOW],
[_INTL("#{@pp} PP"),154,348,2,STATBASE,STATSHADOW]
]
pbDrawTextPositions(overlay,textpos)
drawTextEx(@sprites["doverlay"].bitmap,192,244,320,4,@description,BASE,SHADOW)
Graphics.update
Input.update
if Input.trigger?(Input::RIGHT) && $game_variables[1]==8
$game_variables[1]=1
break
elsif Input.trigger?(Input::LEFT) && $game_variables[1]==8
$game_variables[1]=0
break
elsif Input.trigger?(Input::DOWN) || Input.repeat?(Input::DOWN)
if @sprites["disc"].x > 24 && @move==true
if itemlist.itemCount>1
pbPlayCursorSE
if itemlist.index<itemlist.itemCount-1
itemlist.index+=1
else
itemlist.index=0
@sprites["disc"].x = 58
@sprites["disc"].y = 76
end
end
if itemlist.index<itemlist.itemCount-1 && itemlist.index>0 && @move==true
@sprites["disc"].x -= 1
@sprites["disc"].y += 1
end
end
elsif Input.trigger?(Input::UP) || Input.repeat?(Input::UP)
if itemlist.itemCount>1
pbPlayCursorSE
if itemlist.index>0
itemlist.index-=1
if @sprites["disc"].x < 58 && @move==true
@sprites["disc"].x += 1
@sprites["disc"].y -= 1
end
else
itemlist.index=itemlist.itemCount-1
if @move==true
@sprites["disc"].x = (58-itemlist.itemCount)
@sprites["disc"].y = (76+itemlist.itemCount)
end
end
end
elsif Input.trigger?(Input::C)
if itemlist.index<itemlist.itemCount-1
pbUseItem($PokemonBag,itemlist.item)
itemlist.refresh
else
break
end
elsif Input.trigger?(Input::A)
choice = pbMessage(_INTL("Sort by"),
[_INTL("Number"),
_INTL("Type"),
_INTL("Category"),
_INTL("Base Power"),
_INTL("Accuracy"),
_INTL("Name"),
_INTL("Cancel")
])
sortarray = []
for i in 0...$PokemonBag.pockets[4].length
item = $PokemonBag.pockets[4][i][0]
moveid = pbGetMachine(item)
moveData = pbGetMoveData(moveid)
type = moveData[MOVE_TYPE]
cat = moveData[MOVE_CATEGORY]
power = moveData[MOVE_BASE_DAMAGE]
accuracy = moveData[MOVE_ACCURACY]
name = PBMoves.getName(moveid)
sortarray.push [item,type,cat,power,accuracy,name]
end
if choice == 0
$PokemonBag.pockets[4].sort!
else
sortarray.sort! { |a,b| (a[choice]==b[choice]) ? a[0]<=>b[0] : a[choice]<=>b[choice] }
for i in 0...$PokemonBag.pockets[4].length
$PokemonBag.pockets[4][i][0]=sortarray[i][0]
end
itemlist.refresh
end
elsif Input.trigger?(Input::B)
break
end
end
pbSEPlay("GUI menu close",80)
pbFadeOutAndHide(@sprites)
$PokemonBag.pockets[4].sort!
dispose
end
def dispose
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
end
In the games, the TMs would move back as you flipped through them, but if you don't want that, you can just change
MOVE = true
to MOVE = false
! (It's @move
in the v18 version because I made a dumb choice)Now, maybe you really crave that FRLG authenticity and don't want to display the category of the moves. I disagree with your life choices, but here's alternate code for that anyways! (Currently only works for v18, I'll make a v19 version if someone requests it)
Ruby:
ItemHandlers::UseInField .add(:TMCASE,proc { |item|
TMCase.new
next 1
})
class Window_TMCase < Window_DrawableCommand
attr_reader :pocket
def initialize(bag,filterlist,pocket,x,y,width,height)
@bag = bag
@filterlist = filterlist
@pocket = pocket
@adapter = PokemonMartAdapter.new
super(x,y,width,height)
@selarrow = AnimatedBitmap.new("Graphics/Pictures/selarrow")
self.windowskin = nil
end
def dispose
super
end
def pocket=(value)
@pocket = value
@item_max = (@filterlist) ? @filterlist[@pocket].length+1 : @bag.pockets[@pocket].length+1
self.index = @bag.getChoice(@pocket)
end
def page_row_max; return 6; end
def page_item_max; return 6; end
def item
return 0 if @filterlist && !@filterlist[@pocket][self.index]
thispocket = @bag.pockets[@pocket]
item = (@filterlist) ? thispocket[@filterlist[@pocket][self.index]] : thispocket[self.index]
return (item) ? item[0] : 0
end
def itemCount
return (@filterlist) ? @filterlist[@pocket].length+1 : @bag.pockets[@pocket].length+1
end
def itemRect(item)
if item<0 || item>=@item_max || item<self.top_item ||
item>self.top_item+self.page_item_max
return Rect.new(0,0,0,0)
else
cursor_width = (self.width-self.borderX-(@column_max-1)*@column_spacing) / @column_max
x = item % @column_max * (cursor_width + @column_spacing)
y = item / @column_max * @row_height - @virtualOy
return Rect.new(x, y, cursor_width, @row_height)
end
end
def drawCursor(index,rect)
if self.index==index
bmp = @selarrow.bitmap
pbCopyBitmap(self.contents,bmp,rect.x,rect.y+20)
end
end
def drawItem(index,_count,rect)
textpos = []
rect = Rect.new(rect.x+16,rect.y+16,rect.width-16,rect.height)
ypos = rect.y+4
thispocket = @bag.pockets[@pocket]
if index==self.itemCount-1
textpos.push([_INTL("CLOSE"),rect.x,ypos,false,self.baseColor,self.shadowColor])
else
item = (@filterlist) ? thispocket[@filterlist[@pocket][index]][0] : thispocket[index][0]
baseColor = self.baseColor
shadowColor = self.shadowColor
textpos.push(
[@adapter.getDisplayName(item),rect.x,ypos,false,baseColor,shadowColor]
)
if !pbIsImportantItem?(item) # Not an HM (or infinite TM)
qty = (@filterlist) ? thispocket[@filterlist[@pocket][index]][1] : thispocket[index][1]
qtytext = _ISPRINTF("x{1: 3d}",qty)
xQty = rect.x+rect.width-self.contents.text_size(qtytext).width-16
textpos.push([qtytext,xQty,ypos,false,baseColor,shadowColor])
end
end
pbDrawTextPositions(self.contents,textpos)
end
def refresh
@item_max = itemCount()
self.update_cursor_rect
dwidth = self.width-self.borderX
dheight = self.height-self.borderY
self.contents = pbDoEnsureBitmap(self.contents,dwidth,dheight)
self.contents.clear
for i in 0...@item_max
next if i<self.top_item || i>self.top_item+self.page_item_max
drawItem(i,@item_max,itemRect(i))
end
drawCursor(self.index,itemRect(self.index))
end
def update
super
@uparrow.visible = false
@downarrow.visible = false
end
end
class TMCase
BASE=Color.new(248,248,248)
SHADOW=Color.new(96,96,96)
STATBASE=Color.new(64,64,64)
STATSHADOW=Color.new(216,216,192)
def initialize
@viewport = Viewport.new(0, 0, Graphics.width, Graphics.height)
@viewport.z = 99999
@move = true #set to false if you don't want the position of the disc to move
@sprites = {}
@sprites["bg"] = Sprite.new(@viewport)
@sprites["bg"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/bg")
@sprites["overlay"] = BitmapSprite.new(Graphics.width,Graphics.height,@viewport)
pbSetSystemFont(@sprites["overlay"].bitmap)
pbSetSystemFont(@sprites["bg"].bitmap)
@power="---"
@accuracy="---"
@pp="---"
@description="---"
@type="normal"
@sprites["case"] = Sprite.new(@viewport)
@sprites["case"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/TM Case")
@sprites["case"].x = 24
@sprites["case"].y = 112
@sprites["case"].z = 3
@sprites["disc"] = Sprite.new(@viewport)
@sprites["disc"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/tm_#{@type}")
@sprites["disc"].x = 58
@sprites["disc"].y = 76
@sprites["disc"].z = 1
@sprites["disc"].visible = false
@sprites["sticker"] = Sprite.new(@viewport)
@sprites["sticker"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/hmsticker")
@sprites["sticker"].x = @sprites["disc"].x
@sprites["sticker"].y = @sprites["disc"].y
@sprites["sticker"].z = 2
@sprites["sticker"].visible = false
@sprites["itemlist"] = Window_TMCase.new($PokemonBag,nil,4,188,-17,344,40+32+7*32)
@sprites["itemlist"].viewport = @viewport
@sprites["itemlist"].pocket = 4
@sprites["itemlist"].index = 0
@sprites["itemlist"].baseColor = Color.new(96,96,96)
@sprites["itemlist"].shadowColor = Color.new(208,208,200)
@typebitmap = AnimatedBitmap.new(_INTL("Graphics/Pictures/types"))
overlay = @sprites["overlay"].bitmap
pbDrawTextPositions(@sprites["bg"].bitmap,[[_INTL("TM CASE"),86,15,2,BASE,SHADOW]])
overlay.font.size=24
itemlist=@sprites["itemlist"]
if itemlist.index<itemlist.itemCount-1
movestats
@sprites["disc"].visible = true
else
@power = "---"
@accuracy= "---"
@pp = "---"
@description = "---"
end
textpos = [
[_INTL("#{@power} "),154,297,2,STATBASE,STATSHADOW],
[_INTL("#{@accuracy}% "),154,322,2,STATBASE,STATSHADOW],
[_INTL("#{@pp} PP"),154,348,2,STATBASE,STATSHADOW]
]
drawTextEx(overlay,192,268,320,4,@description,BASE,SHADOW)
pbDrawTextPositions(overlay,textpos)
pbFadeInAndShow(@sprites)
main
end
def movestats
overlay=@sprites["overlay"].bitmap
itemlist=@sprites["itemlist"]
moveid = pbGetMachine(itemlist.item)
# Get data for selected move
moveData = pbGetMoveData(moveid)
@power = moveData[MOVE_BASE_DAMAGE]
if @power == 0
@power = "---"
end
@accuracy = moveData[MOVE_ACCURACY]
if @accuracy == 0
@accuracy= "---"
end
@pp = moveData[MOVE_TOTAL_PP]
if @pp == 0
@pp = "---"
end
@description = moveData[MOVE_DESCRIPTION]
type = moveData[MOVE_TYPE]
if type == nil
type = 0
end
if @description == nil
@description = "---"
end
@type = PBTypes.getName(type).downcase
typerect = Rect.new(0,type*28,64,28)
overlay.blt(114,268,@typebitmap.bitmap,typerect)
@sprites["disc"].bitmap = Bitmap.new("Graphics/Pictures/TM Case/tm_#{@type}")
end
def main
loop do
overlay=@sprites["overlay"].bitmap
overlay.clear
itemlist=@sprites["itemlist"]
@sprites["disc"].visible=(itemlist.index<itemlist.itemCount-1)
if itemlist.index<itemlist.itemCount-1
movestats
else
@power = "---"
@accuracy= "---"
@pp = "---"
@description = "---"
end
@sprites["sticker"].visible = (pbIsHiddenMachine?(itemlist.item))
@sprites["sticker"].x = @sprites["disc"].x
@sprites["sticker"].y = @sprites["disc"].y
pbDrawTextPositions(@sprites["bg"].bitmap,[[_INTL("TM CASE"),86,15,2,BASE,SHADOW]])
overlay.font.size=24
textpos = [
[_INTL("#{@power} "),154,297,2,STATBASE,STATSHADOW],
[_INTL("#{@accuracy}% "),154,322,2,STATBASE,STATSHADOW],
[_INTL("#{@pp} PP"),154,348,2,STATBASE,STATSHADOW]
]
pbDrawTextPositions(overlay,textpos)
drawTextEx(overlay,192,268,320,4,@description,BASE,SHADOW)
Graphics.update
Input.update
if Input.trigger?(Input::RIGHT) && $game_variables[1]==8
$game_variables[1]=1
break
elsif Input.trigger?(Input::LEFT) && $game_variables[1]==8
$game_variables[1]=0
break
elsif Input.trigger?(Input::DOWN) || Input.repeat?(Input::DOWN)
if @sprites["disc"].x > 24 && @move==true
if itemlist.itemCount>1
pbPlayCursorSE
if itemlist.index<itemlist.itemCount-1
itemlist.index+=1
else
itemlist.index=0
@sprites["disc"].x = 58
@sprites["disc"].y = 76
end
end
if itemlist.index<itemlist.itemCount-1 && itemlist.index>0 && @move==true
@sprites["disc"].x -= 1
@sprites["disc"].y += 1
end
end
elsif Input.trigger?(Input::UP) || Input.repeat?(Input::UP)
if itemlist.itemCount>1
pbPlayCursorSE
if itemlist.index>0
itemlist.index-=1
if @sprites["disc"].x < 58 && @move==true
@sprites["disc"].x += 1
@sprites["disc"].y -= 1
end
else
itemlist.index=itemlist.itemCount-1
if @move==true
@sprites["disc"].x = (58-itemlist.itemCount)
@sprites["disc"].y = (76+itemlist.itemCount)
end
end
end
elsif Input.trigger?(Input::C)
if itemlist.index<itemlist.itemCount-1
pbUseItem($PokemonBag,itemlist.item)
itemlist.refresh
else
break
end
elsif Input.trigger?(Input::A)
choice = pbMessage(_INTL("Sort by"),
[_INTL("Number"),
_INTL("Type"),
_INTL("Base Power"),
_INTL("Accuracy"),
_INTL("Name"),
_INTL("Cancel")
])
sortarray = []
for i in 0...$PokemonBag.pockets[4].length
item = $PokemonBag.pockets[4][i][0]
moveid = pbGetMachine(item)
moveData = pbGetMoveData(moveid)
type = moveData[MOVE_TYPE]
power = moveData[MOVE_BASE_DAMAGE]
accuracy = moveData[MOVE_ACCURACY]
name = PBMoves.getName(moveid)
sortarray.push [item,type,power,accuracy,name]
end
if choice == 0
$PokemonBag.pockets[4].sort!
else
sortarray.sort! { |a,b| (a[choice]==b[choice]) ? a[0]<=>b[0] : a[choice]<=>b[choice] }
for i in 0...$PokemonBag.pockets[4].length
$PokemonBag.pockets[4][i][0]=sortarray[i][0]
end
itemlist.refresh
end
elsif Input.trigger?(Input::B)
break
end
end
pbSEPlay("GUI menu close",80)
pbFadeOutAndHide(@sprites)
$PokemonBag.pockets[4].sort!
dispose
end
def dispose
pbDisposeSpriteHash(@sprites)
@viewport.dispose
end
end
Part 2: Where to access the TM case?
The TM case can be called from anywhere with TMCase.new, but we're going to have to work around our UI a bit, since it displays the TM pocket, so we'll need to go to PScreen_Bag.If we want to just replace the TM pocket's usual display with this, then we'll just find this section:
Ruby:
# Change pockets
if Input.trigger?(Input::LEFT)
newpocket = itemwindow.pocket
loop do
newpocket = (newpocket==1) ? PokemonBag.numPockets : newpocket-1
break if !@choosing || newpocket==itemwindow.pocket
if @filterlist; break if @filterlist[newpocket].length>0
else; break if @bag.pockets[newpocket].length>0
end
end
if itemwindow.pocket!=newpocket
itemwindow.pocket = newpocket
@bag.lastpocket = itemwindow.pocket
thispocket = @bag.pockets[itemwindow.pocket]
pbPlayCursorSE
pbRefresh
end
elsif Input.trigger?(Input::RIGHT)
newpocket = itemwindow.pocket
loop do
newpocket = (newpocket==PokemonBag.numPockets) ? 1 : newpocket+1
break if !@choosing || newpocket==itemwindow.pocket
if @filterlist; break if @filterlist[newpocket].length>0
else; break if @bag.pockets[newpocket].length>0
end
end
if itemwindow.pocket!=newpocket
itemwindow.pocket = newpocket
@bag.lastpocket = itemwindow.pocket
thispocket = @bag.pockets[itemwindow.pocket]
pbPlayCursorSE
pbRefresh
end
Ruby:
if newpocket == 4
$game_variables[1]=8
TMCase.new
case $game_variables[1]
when 1
newpocket = 5
when 0
newpocket = 3
else
return 0
end
end
But you might be uninterested in that- maybe you want the player to access TMs through the case as an item, or through the PC, or a dedicated event.
In that case, we'll go to the same section and make a similar change, but instead of pasting that bit of code, we'll paste this in the LEFT section:
Ruby:
if newpocket == 4
newpocket = 3
end
Ruby:
if newpocket == 4
newpocket = 5
end
Further up in the script, find def pbRefresh, and replace it with this:
Ruby:
def pbRefresh
# Set the background image
@sprites["background"].setBitmap(sprintf("Graphics/Pictures/Bag/bg_#{@bag.lastpocket}"))
# Set the bag sprite
fbagexists = pbResolveBitmap(sprintf("Graphics/Pictures/Bag/bag_#{@bag.lastpocket}_f"))
if $Trainer.female? && fbagexists
@sprites["bagsprite"].setBitmap("Graphics/Pictures/Bag/bag_#{@bag.lastpocket}_f")
else
@sprites["bagsprite"].setBitmap("Graphics/Pictures/Bag/bag_#{@bag.lastpocket}")
end
# Draw the pocket icons
@sprites["pocketicon"].bitmap.clear
if @choosing && @filterlist
for i in 1...@bag.pockets.length
if @filterlist[i].length==0
if i<4
@sprites["pocketicon"].bitmap.blt(6+(i-1)*26,6,
@pocketbitmap.bitmap,Rect.new((i-1)*20,28,20,20))
else
@sprites["pocketicon"].bitmap.blt(6+(i-2)*26,6,
@pocketbitmap.bitmap,Rect.new((i-1)*20,28,20,20))
end
end
end
end
if @sprites["itemlist"].pocket <4
@sprites["pocketicon"].bitmap.blt((@sprites["itemlist"].pocket-1)*26,2,
@pocketbitmap.bitmap,Rect.new((@sprites["itemlist"].pocket-1)*28,0,28,28))
else
@sprites["pocketicon"].bitmap.blt((@sprites["itemlist"].pocket-2)*26,2,
@pocketbitmap.bitmap,Rect.new((@sprites["itemlist"].pocket-1)*28,0,28,28))
end
# Refresh the item window
@sprites["itemlist"].refresh
# Refresh more things
pbRefreshIndexChanged
end
Finally, take the files in the folder "No TM Pocket" and paste them into Pictures/Bag, erasing the BGs already there.
It should come out looking like this!
So, now that that's out of the way, let's set up a new way to use the TM case!
Like I said before, you can call it from pretty much anywhere via TMCase.new, but I'll just be showing the item as an example here. The script has the item handler coded at the top-
Ruby:
ItemHandlers::UseInField .add(:TMCASE,proc { |item|
TMCase.new
next 1
})
So all we need to do is add the TM Case to the items PBS! Here's a little line set up for that!
XXX,TMCASE,TM Case,TM Cases,8,0,"A case that holds TMs and HMs. It is attached to the bag's compartment for important items.",2,0,6
Just replace XXX with an unused item ID! Make the itemXXX file match, and move that file to Graphics/Icons, and you're all set to use the TM Case as an item! Personally, it's my favorite way of doing so, because you can register it to the F key, but there's plenty of other interesting/useful ways to do it!
Future Goals
- Smooth out the transitions a bit more
- The original script had slightly different text appear-
- Credits
- Credit to TechSkylander1518, please!