mirror of
https://github.com/infinitefusion/infinitefusion-e18.git
synced 2025-12-07 13:15:01 +00:00
2275 lines
69 KiB
Ruby
2275 lines
69 KiB
Ruby
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisualsSidePane < UI::SpriteContainer
|
|
attr_reader :pokemon
|
|
|
|
GRAPHICS_FOLDER = "Storage/"
|
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
|
:default => [Color.new(88, 88, 80), Color.new(168, 184, 184)], # Base and shadow colour
|
|
:no_item => [Color.new(192, 200, 208), Color.new(212, 216, 220)],
|
|
:male => [Color.new(24, 112, 216), Color.new(136, 168, 208)],
|
|
:female => [Color.new(248, 56, 32), Color.new(224, 152, 144)]
|
|
}
|
|
MARK_WIDTH = 16
|
|
MARK_HEIGHT = 16
|
|
|
|
def initialize_bitmaps
|
|
@bitmaps[:types] = AnimatedBitmap.new(UI_FOLDER + _INTL("types"))
|
|
@bitmaps[:markings] = AnimatedBitmap.new(graphics_folder + "markings")
|
|
@bitmaps[:numbers] = AnimatedBitmap.new(graphics_folder + "numbers")
|
|
end
|
|
|
|
def initialize_sprites
|
|
initialize_pane_bg
|
|
initialize_overlay
|
|
initialize_pokemon_sprite
|
|
end
|
|
|
|
def initialize_pane_bg
|
|
add_icon_sprite(:pane_bg, 0, 0, graphics_folder + "overlay_side_pane")
|
|
record_values(:pane_bg)
|
|
end
|
|
|
|
def initialize_overlay
|
|
add_overlay(:overlay, @sprites[:pane_bg].bitmap.width, @sprites[:pane_bg].bitmap.height)
|
|
@sprites[:overlay].z = 10
|
|
record_values(:overlay)
|
|
end
|
|
|
|
def initialize_pokemon_sprite
|
|
# TODO: The Pokémon sprite probably needs its own viewport, to avoid
|
|
# spillover of overly large sprites. Also put it beneath the main
|
|
# background sprite and put another sprite beneath it?
|
|
@sprites[:pokemon] = UI::PokemonStorageVisualsMosaicPokemonSprite.new(@viewport)
|
|
@sprites[:pokemon].setOffset(PictureOrigin::CENTER)
|
|
@sprites[:pokemon].x = 90
|
|
@sprites[:pokemon].y = 164
|
|
@sprites[:pokemon].z = 1
|
|
record_values(:pokemon)
|
|
mosaic_pokemon_sprite
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def width
|
|
return @sprites[:pane_bg].width
|
|
end
|
|
|
|
def pokemon=(value)
|
|
@pokemon = value
|
|
@sprites[:pokemon].setPokemonBitmap(@pokemon) if @sprites[:pokemon] && !@sprites[:pokemon].disposed?
|
|
refresh
|
|
end
|
|
|
|
def mosaic_pokemon_sprite
|
|
@sprites[:pokemon].mosaic_duration = 0.25 # In seconds
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def refresh_overlay
|
|
super
|
|
return if @pokemon.nil?
|
|
draw_name
|
|
draw_level
|
|
draw_shiny_icon
|
|
draw_gender
|
|
draw_markings
|
|
draw_type
|
|
draw_item
|
|
end
|
|
|
|
def draw_name
|
|
pokemon_name = @pokemon.name
|
|
pokemon_name = crop_text(pokemon_name, 158)
|
|
draw_text(pokemon_name, 8, 14)
|
|
end
|
|
|
|
def draw_level
|
|
return if @pokemon.egg?
|
|
draw_image(graphics_folder + _INTL("overlay_lv"), 8, 48)
|
|
draw_number_from_image(@bitmaps[:numbers], @pokemon.level, 30, 48)
|
|
end
|
|
|
|
def draw_shiny_icon
|
|
return if @pokemon.egg?
|
|
draw_image(UI_FOLDER + "shiny", 106, 46) if @pokemon.shiny?
|
|
end
|
|
|
|
def draw_gender
|
|
return if @pokemon.egg?
|
|
if @pokemon.male?
|
|
draw_text(_INTL("♂"), 150, 44, theme: :male)
|
|
elsif @pokemon.female?
|
|
draw_text(_INTL("♀"), 150, 44, theme: :female)
|
|
end
|
|
end
|
|
|
|
def draw_markings
|
|
mark_variants = @bitmaps[:markings].bitmap.height / MARK_HEIGHT
|
|
(@bitmaps[:markings].bitmap.width / MARK_WIDTH).times do |i|
|
|
draw_image(@bitmaps[:markings], 38 + (i * MARK_WIDTH), 262,
|
|
i * MARK_WIDTH, [(@pokemon.markings[i] || 0), mark_variants - 1].min * MARK_HEIGHT,
|
|
MARK_WIDTH, MARK_HEIGHT)
|
|
end
|
|
end
|
|
|
|
def draw_type
|
|
return if @pokemon.egg?
|
|
@pokemon.types.each_with_index do |type, i|
|
|
type_number = GameData::Type.get(type).icon_position
|
|
type_x = (@pokemon.types.length == 1) ? 52 : 18 + ((GameData::Type::ICON_SIZE[0] + 6) * i)
|
|
draw_image(@bitmaps[:types], type_x, 282,
|
|
0, type_number * GameData::Type::ICON_SIZE[1], *GameData::Type::ICON_SIZE)
|
|
end
|
|
end
|
|
|
|
def draw_item
|
|
return if @pokemon.egg?
|
|
if @pokemon.hasItem?
|
|
item_name = @pokemon.item.name
|
|
item_name = crop_text(item_name, 166)
|
|
draw_text(item_name, 86, 316, align: :center)
|
|
else
|
|
draw_text(_INTL("No item"), 86, 316, align: :center, theme: :no_item)
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
# Pokémon sprite.
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisualsMosaicPokemonSprite < PokemonSprite
|
|
attr_reader :mosaic
|
|
|
|
INITIAL_MOSAIC = 10 # Pixellation factor
|
|
|
|
def initialize(*args)
|
|
super(*args)
|
|
@mosaic = 0
|
|
@in_refresh = false
|
|
@mosaic_bitmap = nil
|
|
@mosaic_bitmap2 = nil
|
|
@old_bitmap = self.bitmap
|
|
end
|
|
|
|
def dispose
|
|
super
|
|
@mosaic_bitmap&.dispose
|
|
@mosaic_bitmap = nil
|
|
@mosaic_bitmap2&.dispose
|
|
@mosaic_bitmap2 = nil
|
|
end
|
|
|
|
def bitmap=(value)
|
|
super
|
|
refresh_mosaic(value)
|
|
end
|
|
|
|
def mosaic=(value)
|
|
@mosaic = value
|
|
@mosaic = 0 if @mosaic < 0
|
|
@start_mosaic = @mosaic if !@start_mosaic
|
|
end
|
|
|
|
def mosaic_duration=(val)
|
|
@mosaic_duration = val
|
|
@mosaic_duration = 0 if @mosaic_duration < 0
|
|
@mosaic_timer_start = System.uptime if @mosaic_duration > 0
|
|
end
|
|
|
|
def refresh_mosaic(bitmap)
|
|
return if @in_refresh
|
|
@in_refresh = true
|
|
@old_bitmap = bitmap
|
|
if @mosaic <= 0 || !@old_bitmap
|
|
@mosaic_bitmap&.dispose
|
|
@mosaic_bitmap = nil
|
|
@mosaic_bitmap2&.dispose
|
|
@mosaic_bitmap2 = nil
|
|
self.bitmap = @old_bitmap
|
|
else
|
|
newWidth = [(@old_bitmap.width / @mosaic), 1].max
|
|
newHeight = [(@old_bitmap.height / @mosaic), 1].max
|
|
@mosaic_bitmap2&.dispose
|
|
@mosaic_bitmap = pbDoEnsureBitmap(@mosaic_bitmap, newWidth, newHeight)
|
|
@mosaic_bitmap.clear
|
|
@mosaic_bitmap2 = pbDoEnsureBitmap(@mosaic_bitmap2, @old_bitmap.width, @old_bitmap.height)
|
|
@mosaic_bitmap2.clear
|
|
@mosaic_bitmap.stretch_blt(Rect.new(0, 0, newWidth, newHeight), @old_bitmap, @old_bitmap.rect)
|
|
@mosaic_bitmap2.stretch_blt(
|
|
Rect.new((-@mosaic / 2) + 1, (-@mosaic / 2) + 1, @mosaic_bitmap2.width, @mosaic_bitmap2.height),
|
|
@mosaic_bitmap, Rect.new(0, 0, newWidth, newHeight)
|
|
)
|
|
self.bitmap = @mosaic_bitmap2
|
|
end
|
|
@in_refresh = false
|
|
end
|
|
|
|
def update
|
|
super
|
|
if @mosaic_timer_start
|
|
@start_mosaic = INITIAL_MOSAIC if !@start_mosaic || @start_mosaic == 0
|
|
new_mosaic = lerp(@start_mosaic, 0, @mosaic_duration, @mosaic_timer_start, System.uptime).to_i
|
|
self.mosaic = new_mosaic
|
|
refresh_mosaic(@old_bitmap)
|
|
if new_mosaic == 0
|
|
@mosaic_timer_start = nil
|
|
@start_mosaic = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisualsPokemonIcon < PokemonIconSprite
|
|
OUTLINE_COLOR = Color.new(248, 0, 0)
|
|
FULL_BORDER = true # true = draws the corners
|
|
|
|
def create_outline_bitmap
|
|
@selected_bitmap = Bitmap.new(@animBitmap.height + 4, @animBitmap.height + 4)
|
|
# Copy the icon's bitmap to the new bitmap
|
|
@selected_bitmap.blt(2, 2, @animBitmap.bitmap, Rect.new(0, 0, @animBitmap.height, @animBitmap.height))
|
|
# Determine where the outline's pixels go
|
|
pixels = []
|
|
size = @animBitmap.height / 2
|
|
size.times do |j|
|
|
size.times do |i|
|
|
pixel = @animBitmap.bitmap.get_pixel(i * 2, j * 2)
|
|
this_coord = ((j + 1) * (size + 2)) + i + 1
|
|
pixels[this_coord] = 1 if pixel.alpha == 255 # Visible pixel
|
|
next if pixels[this_coord] != 1
|
|
pixels[this_coord - 1] ||= 2
|
|
pixels[this_coord + 1] = 2
|
|
pixels[this_coord - size - 2] ||= 2
|
|
pixels[this_coord + size + 2] = 2
|
|
if FULL_BORDER
|
|
pixels[this_coord - size - 2 - 1] ||= 2
|
|
pixels[this_coord - size - 2 + 1] ||= 2
|
|
pixels[this_coord + size + 2 - 1] = 2
|
|
pixels[this_coord + size + 2 + 1] = 2
|
|
end
|
|
end
|
|
end
|
|
# Draw the outline
|
|
(size + 2).times do |j|
|
|
(size + 2).times do |i|
|
|
if pixels[(j * (size + 2)) + i] == 3
|
|
@selected_bitmap.fill_rect(i * 2, j * 2, 2, 2, Color.new(255,255,0))
|
|
end
|
|
next if pixels[(j * (size + 2)) + i] != 2
|
|
@selected_bitmap.fill_rect(i * 2, j * 2, 2, 2, OUTLINE_COLOR)
|
|
end
|
|
end
|
|
end
|
|
|
|
def pokemon=(value)
|
|
super
|
|
# NOTE: This only matters when refreshing the screen after giving an item to
|
|
# a Pokémon (a selected Pokémon). It should remain selected.
|
|
if @selected_bitmap
|
|
self.bitmap = @selected_bitmap
|
|
self.src_rect.width = @selected_bitmap.width
|
|
self.src_rect.height = @selected_bitmap.height
|
|
changeOrigin
|
|
end
|
|
end
|
|
|
|
def make_selected
|
|
return if @selected_bitmap
|
|
create_outline_bitmap
|
|
self.bitmap = @selected_bitmap
|
|
self.src_rect.width = @selected_bitmap.width
|
|
self.src_rect.height = @selected_bitmap.height
|
|
changeOrigin
|
|
self.z += 1
|
|
end
|
|
|
|
def make_not_selected
|
|
return if !@selected_bitmap
|
|
@selected_bitmap.dispose
|
|
@selected_bitmap = nil
|
|
if @animBitmap
|
|
self.bitmap = @animBitmap.bitmap
|
|
self.src_rect.width = @animBitmap.height
|
|
self.src_rect.height = @animBitmap.height
|
|
changeOrigin
|
|
end
|
|
self.z -= 1
|
|
end
|
|
|
|
def update; end # Don't animate it
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisualsBox < UI::SpriteContainer
|
|
attr_reader :sprites
|
|
|
|
GRAPHICS_FOLDER = "Storage/"
|
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
|
:default => [Color.new(248, 248, 240), Color.new(40, 48, 48)], # Base and shadow colour
|
|
}
|
|
|
|
def initialize(storage, box_number, viewport)
|
|
@storage = storage
|
|
@box_number = box_number
|
|
super(viewport)
|
|
end
|
|
|
|
def initialize_sprites
|
|
initialize_box_background
|
|
initialize_overlay
|
|
initialize_pokemon_icons
|
|
end
|
|
|
|
def initialize_box_background
|
|
set_box_background
|
|
record_values(:background)
|
|
end
|
|
|
|
def initialize_overlay
|
|
add_overlay(:overlay, @sprites[:background].bitmap.width, @sprites[:background].bitmap.height)
|
|
@sprites[:overlay].z = 10
|
|
record_values(:overlay)
|
|
end
|
|
|
|
def initialize_pokemon_icons
|
|
PokemonBox::BOX_SIZE.times do |i|
|
|
@sprites["pokemon_#{i}"] = UI::PokemonStorageVisualsPokemonIcon.new(@storage[@box_number, i], @viewport)
|
|
@sprites["pokemon_#{i}"].x, @sprites["pokemon_#{i}"].y = pokemon_coords(i)
|
|
@sprites["pokemon_#{i}"].z = 1
|
|
@sprites["pokemon_#{i}"].setOffset
|
|
record_values("pokemon_#{i}")
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def width
|
|
return @sprites[:background].width
|
|
end
|
|
|
|
def pokemon_coords(index)
|
|
return 42 + (48 * (index % PokemonBox::BOX_WIDTH)),
|
|
70 + (48 * (index / PokemonBox::BOX_WIDTH))
|
|
end
|
|
|
|
def pokemon_icon(index)
|
|
return @sprites["pokemon_#{index}"]
|
|
end
|
|
|
|
def reset_pokemon_icon_position(index)
|
|
new_coords = pokemon_coords(index)
|
|
@sprites["pokemon_#{index}"].x = self.x + new_coords[0]
|
|
@sprites["pokemon_#{index}"].y = self.y + new_coords[1]
|
|
end
|
|
|
|
def set_box_background(wallpaper_number = -1)
|
|
@sprites[:background]&.dispose
|
|
add_icon_sprite(:background, self.x, self.y, graphics_folder + box_bitmap(wallpaper_number))
|
|
end
|
|
|
|
def box_bitmap(wallpaper_number = -1)
|
|
return "box_#{wallpaper_number}" if wallpaper_number >= 0
|
|
ret = @storage[@box_number].background
|
|
if !ret.is_a?(Integer) || !@storage.isAvailableWallpaper?(ret)
|
|
ret = @box_number % PokemonStorage::BASIC_WALLPAPER_COUNT
|
|
@storage[@box_number].background = ret
|
|
end
|
|
return "box_#{ret}"
|
|
end
|
|
|
|
def set_visible_proc(this_proc)
|
|
@visible_proc = this_proc
|
|
apply_visible_proc
|
|
end
|
|
|
|
def apply_visible_proc
|
|
PokemonBox::BOX_SIZE.times do |i|
|
|
if @visible_proc && !@visible_proc.call(@sprites["pokemon_#{i}"].pokemon)
|
|
@sprites["pokemon_#{i}"].opacity = 96
|
|
else
|
|
@sprites["pokemon_#{i}"].opacity = 255
|
|
end
|
|
end
|
|
end
|
|
|
|
def fade_all_pokemon
|
|
PokemonBox::BOX_SIZE.times { |i| @sprites["pokemon_#{i}"].opacity = 96 }
|
|
end
|
|
|
|
def unfade_all_pokemon
|
|
apply_visible_proc
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def refresh
|
|
super
|
|
set_box_background
|
|
draw_box_name
|
|
refresh_existing_pokemon
|
|
end
|
|
|
|
def refresh_box_name
|
|
draw_box_name
|
|
end
|
|
|
|
def draw_box_name
|
|
box_name = @storage[@box_number].name
|
|
box_name = crop_text(box_name, 216)
|
|
draw_text(box_name, 162, 14, align: :center)
|
|
end
|
|
|
|
def refresh_existing_pokemon
|
|
PokemonBox::BOX_SIZE.times do |i|
|
|
@sprites["pokemon_#{i}"].pokemon = @storage[@box_number, i]
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisualsPartyPanel < UI::SpriteContainer
|
|
attr_reader :sprites
|
|
|
|
GRAPHICS_FOLDER = "Storage/"
|
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
|
:default => [Color.new(248, 248, 240), Color.new(40, 48, 48)], # Base and shadow colour
|
|
}
|
|
|
|
def initialize(party, mode, viewport)
|
|
@party = party
|
|
@mode = mode
|
|
super(viewport)
|
|
refresh
|
|
end
|
|
|
|
def initialize_sprites
|
|
initialize_panel_background
|
|
initialize_overlay
|
|
initialize_pokemon_icons
|
|
end
|
|
|
|
def initialize_panel_background
|
|
add_icon_sprite(:background, 0, 0, graphics_folder + "overlay_party")
|
|
record_values(:background)
|
|
end
|
|
|
|
def initialize_overlay
|
|
add_overlay(:overlay, @sprites[:background].bitmap.width, @sprites[:background].bitmap.height)
|
|
@sprites[:overlay].z = 10
|
|
record_values(:overlay)
|
|
end
|
|
|
|
def initialize_pokemon_icons
|
|
Settings::MAX_PARTY_SIZE.times do |i|
|
|
@sprites["pokemon_#{i}"] = UI::PokemonStorageVisualsPokemonIcon.new(@party[i], @viewport)
|
|
@sprites["pokemon_#{i}"].x, @sprites["pokemon_#{i}"].y = pokemon_coords(i)
|
|
@sprites["pokemon_#{i}"].z = 1
|
|
@sprites["pokemon_#{i}"].setOffset
|
|
record_values("pokemon_#{i}")
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def height
|
|
return @sprites[:background].bitmap.height
|
|
end
|
|
|
|
def pokemon_coords(index)
|
|
return 50 + (72 * (index % 2)),
|
|
42 + (16 * (index % 2)) + (64 * (index / 2))
|
|
end
|
|
|
|
def pokemon_icon(index)
|
|
return @sprites["pokemon_#{index}"]
|
|
end
|
|
|
|
def reset_pokemon_icon_position(index)
|
|
new_coords = pokemon_coords(index)
|
|
@sprites["pokemon_#{index}"].x = self.x + new_coords[0]
|
|
@sprites["pokemon_#{index}"].y = self.y + new_coords[1]
|
|
end
|
|
|
|
def set_visible_proc(this_proc)
|
|
@visible_proc = this_proc
|
|
apply_visible_proc
|
|
end
|
|
|
|
def apply_visible_proc
|
|
Settings::MAX_PARTY_SIZE.times do |i|
|
|
if @visible_proc && !@visible_proc.call(@sprites["pokemon_#{i}"].pokemon)
|
|
@sprites["pokemon_#{i}"].opacity = 96
|
|
else
|
|
@sprites["pokemon_#{i}"].opacity = 255
|
|
end
|
|
end
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def refresh
|
|
super
|
|
draw_button_text
|
|
refresh_existing_pokemon
|
|
end
|
|
|
|
def draw_button_text
|
|
text = (@mode == :deposit) ? _INTL("Exit") : _INTL("Back")
|
|
draw_text(text, 86, 248, align: :center, outline: :outline)
|
|
end
|
|
|
|
def refresh_existing_pokemon
|
|
Settings::MAX_PARTY_SIZE.times do |i|
|
|
@sprites["pokemon_#{i}"].pokemon = @party[i]
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisualsCursor < UI::SpriteContainer
|
|
attr_reader :quick_swap_mode
|
|
|
|
GRAPHICS_FOLDER = "Storage/"
|
|
BITMAPS = {
|
|
:point1 => ["cursor_point_1"],
|
|
:point2 => ["cursor_point_2"],
|
|
:grab => ["cursor_grab"],
|
|
:fist => ["cursor_fist"],
|
|
:point1q => ["cursor_point_1_q"],
|
|
:point2q => ["cursor_point_2_q"],
|
|
:grabq => ["cursor_grab_q"],
|
|
:fistq => ["cursor_fist_q"]
|
|
}
|
|
# Time in seconds for the cursor to move down or back up to grab/drop a
|
|
# Pokémon.
|
|
GRAB_TIME = 0.2
|
|
|
|
def initialize_sprites
|
|
initialize_cursor
|
|
initialize_pokemon_icon
|
|
initialize_item_icon
|
|
end
|
|
|
|
def initialize_cursor
|
|
@sprites[:cursor] = ChangelingSprite.new(0, 0, @viewport)
|
|
BITMAPS.each_pair do |key, data|
|
|
@sprites[:cursor].add_bitmap(key, graphics_folder + data[0])
|
|
end
|
|
@sprites[:cursor].change_bitmap(:fist)
|
|
record_values(:cursor)
|
|
end
|
|
|
|
def initialize_pokemon_icon
|
|
@sprites[:pokemon] = UI::PokemonStorageVisualsPokemonIcon.new(nil, @viewport)
|
|
@sprites[:pokemon].x = 32
|
|
@sprites[:pokemon].y = 48
|
|
@sprites[:pokemon].z = -1
|
|
@sprites[:pokemon].setOffset
|
|
record_values(:pokemon)
|
|
end
|
|
|
|
def initialize_item_icon
|
|
@sprites[:item] = ItemIconSprite.new(32, 48, nil, @viewport)
|
|
@sprites[:item].z = -1
|
|
@sprites[:item].setOffset
|
|
@sprites[:item].blankzero = true
|
|
record_values(:item)
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def held_pokemon
|
|
return @sprites[:pokemon].pokemon
|
|
end
|
|
|
|
def held_pokemon=(value)
|
|
@sprites[:pokemon].pokemon = value
|
|
end
|
|
|
|
def holding_pokemon?
|
|
return !held_pokemon.nil?
|
|
end
|
|
|
|
def held_item
|
|
return @sprites[:item].item
|
|
end
|
|
|
|
def held_item=(value)
|
|
@sprites[:item].item = value
|
|
end
|
|
|
|
def holding_item?
|
|
return !held_item.nil?
|
|
end
|
|
|
|
def pokemon_icon
|
|
return @sprites[:pokemon]
|
|
end
|
|
|
|
def quick_swap_mode=(value)
|
|
return if @quick_swap_mode == value
|
|
@quick_swap_mode = value
|
|
refresh_cursor
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def animating?
|
|
return @pick_up_timer_1_start || @pick_up_timer_2_start ||
|
|
@put_down_timer_1_start || @put_down_timer_2_start
|
|
end
|
|
|
|
def pick_up_animation_1
|
|
@pick_up_timer_1_start = System.uptime
|
|
@start_y = self.y
|
|
@sprites[:cursor].change_bitmap((@quick_swap_mode) ? :grabq : :grab)
|
|
end
|
|
|
|
def pick_up_animation_2
|
|
@pick_up_timer_2_start = System.uptime
|
|
@start_y = self.y
|
|
@sprites[:cursor].change_bitmap((@quick_swap_mode) ? :fistq : :fist)
|
|
end
|
|
|
|
def put_down_animation_1
|
|
@put_down_timer_1_start = System.uptime
|
|
@start_y = self.y
|
|
@sprites[:cursor].change_bitmap((@quick_swap_mode) ? :fistq : :fist)
|
|
end
|
|
|
|
def put_down_animation_2
|
|
@put_down_timer_2_start = System.uptime
|
|
@start_y = self.y
|
|
@sprites[:cursor].change_bitmap((@quick_swap_mode) ? :grabq : :grab)
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def refresh_cursor
|
|
if (System.uptime / 0.5).to_i.even? # Changes every 0.5 seconds
|
|
@sprites[:cursor].change_bitmap((@quick_swap_mode) ? :point1q : :point1)
|
|
else
|
|
@sprites[:cursor].change_bitmap((@quick_swap_mode) ? :point2q : :point2)
|
|
end
|
|
end
|
|
|
|
def update
|
|
super
|
|
if @pick_up_timer_1_start
|
|
y_offset = lerp(0, 16, GRAB_TIME, @pick_up_timer_1_start, System.uptime)
|
|
self.y = @start_y + y_offset
|
|
@pick_up_timer_1_start = nil if y_offset == 16
|
|
elsif @pick_up_timer_2_start
|
|
y_offset = lerp(0, -16, GRAB_TIME, @pick_up_timer_2_start, System.uptime)
|
|
self.y = @start_y + y_offset
|
|
@pick_up_timer_2_start = nil if y_offset == -16
|
|
elsif @put_down_timer_1_start
|
|
y_offset = lerp(0, 16, GRAB_TIME, @put_down_timer_1_start, System.uptime)
|
|
self.y = @start_y + y_offset
|
|
@put_down_timer_1_start = nil if y_offset == 16
|
|
elsif @put_down_timer_2_start
|
|
y_offset = lerp(0, -16, GRAB_TIME, @put_down_timer_2_start, System.uptime)
|
|
self.y = @start_y + y_offset
|
|
@put_down_timer_2_start = nil if y_offset == -16
|
|
elsif !holding_pokemon? && !holding_item? # Idling animation
|
|
refresh_cursor
|
|
end
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorageVisuals < UI::BaseVisuals
|
|
# -3 = Exit button
|
|
# -2 = Party button, or Back button in party panel
|
|
# -1 = Box name
|
|
# 0+ = index in box/party
|
|
attr_reader :index
|
|
# -1 = party
|
|
# 0+ = box number
|
|
attr_reader :box
|
|
attr_reader :sub_mode
|
|
attr_reader :sprites
|
|
|
|
GRAPHICS_FOLDER = "Storage/" # Subfolder in Graphics/UI
|
|
TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay]
|
|
:default => [Color.new(248, 248, 240), Color.new(40, 48, 48)], # Base and shadow colour
|
|
}
|
|
MARKING_WIDTH = 16
|
|
MARKING_HEIGHT = 16
|
|
|
|
def initialize(storage, mode = :normal)
|
|
@storage = storage
|
|
@mode = mode
|
|
@index = 0
|
|
@box = (@mode == :deposit) ? -1 : @storage.currentBox
|
|
super()
|
|
set_index(@index)
|
|
end
|
|
|
|
def initialize_bitmaps
|
|
@bitmaps[:markings] = AnimatedBitmap.new(graphics_folder + "markings")
|
|
end
|
|
|
|
def initialize_message_box
|
|
super
|
|
@sprites[:speech_box].width = Graphics.width - 180
|
|
end
|
|
|
|
def initialize_sprites
|
|
initialize_side_pane
|
|
initialize_box
|
|
initialize_party_panel
|
|
initialize_marking_sprites
|
|
initialize_cursor
|
|
initialize_buttons
|
|
end
|
|
|
|
def initialize_side_pane
|
|
@sprites[:side_pane] = UI::PokemonStorageVisualsSidePane.new(@viewport)
|
|
@sprites[:side_pane].y = 16
|
|
@sprites[:side_pane].z = 100
|
|
end
|
|
|
|
def initialize_box
|
|
@sprites[:box] = create_box_sprite(@storage.currentBox)
|
|
end
|
|
|
|
def create_box_sprite(box_index)
|
|
ret = UI::PokemonStorageVisualsBox.new(@storage, box_index, @viewport)
|
|
ret.x = 184
|
|
ret.y = 18
|
|
ret.refresh
|
|
return ret
|
|
end
|
|
|
|
def initialize_party_panel
|
|
@sprites[:party_panel] = UI::PokemonStorageVisualsPartyPanel.new(@storage.party, @mode, @viewport)
|
|
@sprites[:party_panel].x = 184
|
|
@sprites[:party_panel].y = (showing_party_panel?) ? Graphics.height - 352 : Graphics.height
|
|
@sprites[:party_panel].z = 1100
|
|
end
|
|
|
|
def initialize_marking_sprites
|
|
# Background image of marking panel
|
|
add_icon_sprite(:marking_bg, 290, 68, graphics_folder + "overlay_marking")
|
|
@sprites[:marking_bg].z = 1900
|
|
@sprites[:marking_bg].visible = false
|
|
# Overlay for marking panel
|
|
add_overlay(:marking_overlay)
|
|
@sprites[:marking_overlay].z = 1901
|
|
@sprites[:marking_overlay].visible = false
|
|
# Cursor to highlight the currently selected marking option
|
|
add_icon_sprite(:marking_cursor, 0, 0, graphics_folder + "cursor_marking")
|
|
@sprites[:marking_cursor].z = 1902
|
|
@sprites[:marking_cursor].visible = false
|
|
@sprites[:marking_cursor].src_rect.height = @sprites[:marking_cursor].bitmap.height / 2
|
|
end
|
|
|
|
def initialize_cursor
|
|
@sprites[:cursor] = UI::PokemonStorageVisualsCursor.new(@viewport)
|
|
@sprites[:cursor].z = 1500
|
|
end
|
|
|
|
def initialize_buttons
|
|
@sprites[:party_button] = IconSprite.new(188, 320, @viewport)
|
|
@sprites[:party_button].setBitmap(graphics_folder + "overlay_buttons")
|
|
@sprites[:party_button].src_rect.height = @sprites[:party_button].height / 2
|
|
@sprites[:party_button].visible = ([:organize, :choose_pokemon].include?(@mode))
|
|
@sprites[:exit_button] = IconSprite.new(386, 320, @viewport)
|
|
@sprites[:exit_button].setBitmap(graphics_folder + "overlay_buttons")
|
|
@sprites[:exit_button].src_rect.y = @sprites[:exit_button].height / 2
|
|
@sprites[:exit_button].src_rect.height = @sprites[:exit_button].height / 2
|
|
@sprites[:exit_button].visible = (@mode != :deposit)
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def can_access_screen_menu?
|
|
return @mode == :organize
|
|
end
|
|
|
|
def pokemon
|
|
return @sprites[:cursor].held_pokemon if holding_pokemon?
|
|
return slot_pokemon
|
|
end
|
|
|
|
# Returns the Pokémon in the storage space the cursor is over.
|
|
def slot_pokemon
|
|
return nil if @index < 0
|
|
return @storage.party[@index] if @box < 0
|
|
return @storage[@box][@index]
|
|
end
|
|
|
|
def holding_pokemon?
|
|
return @sprites[:cursor].holding_pokemon?
|
|
end
|
|
|
|
def pokemon_icon
|
|
return @sprites[:cursor].pokemon_icon if holding_pokemon?
|
|
return @sprites[:box].pokemon_icon(@index) if @box >= 0
|
|
return @sprites[:party_panel].pokemon_icon(@index)
|
|
end
|
|
|
|
def item
|
|
return @sprites[:cursor].held_item
|
|
end
|
|
|
|
def holding_item?
|
|
return @sprites[:cursor].holding_item?
|
|
end
|
|
|
|
def showing_party_panel?
|
|
return @box == -1
|
|
end
|
|
|
|
def set_index(new_index)
|
|
mosaic_pokemon_sprite
|
|
@index = new_index
|
|
refresh_on_index_changed(@index)
|
|
end
|
|
|
|
def set_sub_mode(sub_mode = :normal)
|
|
@sub_mode = sub_mode
|
|
@sprites[:cursor].quick_swap_mode = (@sub_mode != :normal)
|
|
@visible_proc = nil
|
|
if @sub_mode == :rearrange_items
|
|
@visible_proc = proc { |pkmn| pkmn.hasItem? }
|
|
end
|
|
@sprites[:box].set_visible_proc(@visible_proc)
|
|
@sprites[:party_panel].set_visible_proc(@visible_proc)
|
|
end
|
|
|
|
def select_pokemon
|
|
pokemon_icon&.make_selected if !holding_pokemon?
|
|
end
|
|
|
|
def deselect_pokemon
|
|
pokemon_icon&.make_not_selected if !holding_pokemon?
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def go_to_next_box(new_box_number = -1)
|
|
@sprites[:side_pane].pokemon = nil if !holding_pokemon?
|
|
new_box_number = (@storage.currentBox + 1) % @storage.maxBoxes if new_box_number < 0
|
|
@sprites[:cursor].visible = false
|
|
# Animate the boxes moving
|
|
offset_x = @sprites[:box].width + 12
|
|
start_x = @sprites[:box].x
|
|
new_box = create_box_sprite(new_box_number)
|
|
new_box.x = start_x + offset_x
|
|
timer_start = System.uptime
|
|
loop do
|
|
@sprites[:box].x = lerp(start_x, start_x - offset_x, 0.25, timer_start, System.uptime)
|
|
new_box.x = @sprites[:box].x + offset_x
|
|
update
|
|
Graphics.update
|
|
break if new_box.x == start_x
|
|
end
|
|
@sprites[:box].dispose
|
|
@sprites[:box] = new_box
|
|
Input.update
|
|
# Tidy up
|
|
@sprites[:cursor].visible = true
|
|
@storage.currentBox = new_box_number
|
|
@box = new_box_number
|
|
refresh_side_pane
|
|
mosaic_pokemon_sprite
|
|
end
|
|
|
|
def go_to_previous_box(new_box_number = -1)
|
|
@sprites[:side_pane].pokemon = nil if !holding_pokemon?
|
|
new_box_number = (@storage.currentBox + @storage.maxBoxes - 1) % @storage.maxBoxes if new_box_number < 0
|
|
@sprites[:cursor].visible = false
|
|
# Animate the boxes moving
|
|
offset_x = @sprites[:box].width + 12
|
|
start_x = @sprites[:box].x
|
|
new_box = create_box_sprite(new_box_number)
|
|
new_box.x = start_x - offset_x
|
|
timer_start = System.uptime
|
|
loop do
|
|
@sprites[:box].x = lerp(start_x, start_x + offset_x, 0.25, timer_start, System.uptime)
|
|
new_box.x = @sprites[:box].x - offset_x
|
|
update
|
|
Graphics.update
|
|
break if new_box.x == start_x
|
|
end
|
|
@sprites[:box].dispose
|
|
@sprites[:box] = new_box
|
|
Input.update
|
|
# Tidy up
|
|
@sprites[:cursor].visible = true
|
|
@storage.currentBox = new_box_number
|
|
@box = new_box_number
|
|
refresh_side_pane
|
|
mosaic_pokemon_sprite
|
|
end
|
|
|
|
def show_party_panel
|
|
pbSEPlay("GUI storage show party panel")
|
|
@sprites[:cursor].visible = false
|
|
@sprites[:side_pane].pokemon = nil if !holding_pokemon?
|
|
start_y = @sprites[:party_panel].y # Graphics.height
|
|
timer_start = System.uptime
|
|
loop do
|
|
@sprites[:party_panel].y = lerp(start_y, start_y - @sprites[:party_panel].height,
|
|
0.4, timer_start, System.uptime)
|
|
update
|
|
Graphics.update
|
|
break if @sprites[:party_panel].y == start_y - @sprites[:party_panel].height
|
|
end
|
|
Input.update
|
|
@box = -1
|
|
set_index(0)
|
|
mosaic_pokemon_sprite
|
|
@sprites[:cursor].visible = true
|
|
end
|
|
|
|
def hide_party_panel
|
|
pbSEPlay("GUI storage hide party panel")
|
|
@sprites[:cursor].visible = false
|
|
@sprites[:side_pane].pokemon = nil if !holding_pokemon?
|
|
start_y = @sprites[:party_panel].y # Graphics.height - @sprites[:party_panel].height
|
|
timer_start = System.uptime
|
|
loop do
|
|
@sprites[:party_panel].y = lerp(start_y, start_y + @sprites[:party_panel].height,
|
|
0.4, timer_start, System.uptime)
|
|
self.update
|
|
Graphics.update
|
|
break if @sprites[:party_panel].y == start_y + @sprites[:party_panel].height
|
|
end
|
|
Input.update
|
|
@box = @storage.currentBox
|
|
set_index(-2) # Party button
|
|
mosaic_pokemon_sprite
|
|
@sprites[:cursor].visible = true
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def animate_cursor(anim_method)
|
|
@sprites[:cursor].send(anim_method)
|
|
loop do
|
|
Graphics.update
|
|
update_visuals
|
|
break if !@sprites[:cursor].animating?
|
|
end
|
|
end
|
|
|
|
def pick_up_pokemon
|
|
pbSEPlay("GUI storage pick up")
|
|
deselect_pokemon
|
|
# Animate cursor moving down to grab the Pokémon
|
|
animate_cursor(:pick_up_animation_1)
|
|
# Move Pokémon to cursor
|
|
sprite_key = (@box >= 0) ? :box : :party_panel
|
|
spr = @sprites[sprite_key].pokemon_icon(@index)
|
|
@sprites[:cursor].held_pokemon = spr.pokemon
|
|
spr.pokemon = nil
|
|
@sprites[sprite_key].reset_pokemon_icon_position(@index)
|
|
# Animate cursor moving back up holding the picked-up Pokémon
|
|
animate_cursor(:pick_up_animation_2)
|
|
Input.update
|
|
end
|
|
|
|
def swap_pokemon
|
|
pbSEPlay("GUI storage pick up")
|
|
# Move Pokémon between cursor and slot
|
|
held_pkmn = pokemon
|
|
slot_pkmn = slot_pokemon
|
|
sprite_key = (@box >= 0) ? :box : :party_panel
|
|
spr = @sprites[sprite_key].pokemon_icon(@index)
|
|
@sprites[:cursor].held_pokemon = slot_pkmn
|
|
spr.pokemon = held_pkmn
|
|
@sprites[sprite_key].reset_pokemon_icon_position(@index)
|
|
mosaic_pokemon_sprite(true)
|
|
end
|
|
|
|
def put_down_pokemon
|
|
pbSEPlay("GUI storage put down")
|
|
# Animate cursor moving down to put down the held Pokémon
|
|
animate_cursor(:put_down_animation_1)
|
|
# Move Pokémon to slot
|
|
sprite_key = (@box >= 0) ? :box : :party_panel
|
|
spr = @sprites[sprite_key].pokemon_icon(@index)
|
|
spr.pokemon = @sprites[:cursor].held_pokemon
|
|
@sprites[:cursor].held_pokemon = nil
|
|
# Animate cursor moving back up after putting down the held Pokémon
|
|
animate_cursor(:put_down_animation_2)
|
|
Input.update
|
|
end
|
|
|
|
# Called when interacting with a Pokémon in the box. Automatically puts that
|
|
# Pokemon into the party.
|
|
def withdraw_pokemon
|
|
old_index = @index
|
|
pick_up_pokemon if !holding_pokemon?
|
|
show_party_panel
|
|
set_index(@storage.party.length)
|
|
put_down_pokemon
|
|
hide_party_panel
|
|
set_index(old_index)
|
|
end
|
|
|
|
# Called when interacting with a Pokémon in the party. Automatically puts that
|
|
# Pokemon into the box.
|
|
def store_pokemon(new_box, new_index)
|
|
pick_up_pokemon if !holding_pokemon?
|
|
hide_party_panel
|
|
old_index = @index
|
|
if new_box != @box
|
|
pbPlayCursorSE
|
|
(new_box > @box) ? go_to_next_box(new_box) : go_to_previous_box(new_box)
|
|
end
|
|
set_index(new_index)
|
|
put_down_pokemon
|
|
yield if block_given?
|
|
refresh_party_panel
|
|
show_party_panel
|
|
end
|
|
|
|
def release_pokemon(skip_anim = false)
|
|
deselect_pokemon
|
|
sprite = pokemon_icon
|
|
if !skip_anim
|
|
timer_start = System.uptime
|
|
loop do
|
|
Graphics.update
|
|
update_visuals
|
|
sprite.zoom_x = lerp(1.0, 0.0, 1.5, timer_start, System.uptime)
|
|
sprite.zoom_y = sprite.zoom_x
|
|
sprite.opacity = lerp(255, 0, 1.5, timer_start, System.uptime)
|
|
break if sprite.opacity == 0
|
|
end
|
|
Input.update
|
|
sprite.zoom_x = 1.0
|
|
sprite.zoom_y = 1.0
|
|
sprite.opacity = 255
|
|
end
|
|
sprite.pokemon = nil
|
|
end
|
|
|
|
def mosaic_pokemon_sprite(forced = false)
|
|
return if !forced && holding_pokemon?
|
|
@sprites[:side_pane].mosaic_pokemon_sprite if pokemon
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def pick_up_item
|
|
pbSEPlay("GUI storage pick up")
|
|
# Animate cursor moving down to grab the item
|
|
animate_cursor(:pick_up_animation_1)
|
|
# Move item to cursor
|
|
@sprites[:cursor].held_item = pokemon.item
|
|
pokemon.item = nil
|
|
refresh_side_pane
|
|
@sprites[:box].set_visible_proc(@visible_proc)
|
|
@sprites[:party_panel].set_visible_proc(@visible_proc)
|
|
# Animate cursor moving back up holding the picked-up item
|
|
animate_cursor(:pick_up_animation_2)
|
|
Input.update
|
|
end
|
|
|
|
def swap_items
|
|
pbSEPlay("GUI storage pick up")
|
|
# Move item from slot Pokémon to cursor
|
|
@sprites[:cursor].held_item = pokemon.item
|
|
end
|
|
|
|
def put_down_item
|
|
pbSEPlay("GUI storage put down")
|
|
# Animate cursor moving down to put down the held item
|
|
animate_cursor(:put_down_animation_1)
|
|
# Move item to slot Pokémon
|
|
pokemon.item = @sprites[:cursor].held_item
|
|
@sprites[:cursor].held_item = nil
|
|
refresh_side_pane
|
|
@sprites[:box].set_visible_proc(@visible_proc)
|
|
@sprites[:party_panel].set_visible_proc(@visible_proc)
|
|
# Animate cursor moving back up after putting down the held item
|
|
animate_cursor(:put_down_animation_2)
|
|
Input.update
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def choose_box(message, start_box = -1)
|
|
start_box = @storage.currentBox if start_box < 0
|
|
commands = {}
|
|
@storage.maxBoxes.times do |i|
|
|
box = @storage[i]
|
|
commands[i] = _INTL("{1} ({2}/{3})", box.name, box.nitems, box.length) if box
|
|
end
|
|
return show_menu(message, commands, commands.keys.index(start_box) || 0)
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def position_speech_box(text)
|
|
@sprites[:speech_box].resizeHeightToFit(text, Graphics.width - @sprites[:side_pane].width)
|
|
pbBottomRight(@sprites[:speech_box])
|
|
end
|
|
|
|
# Replaces the version in class UI::BaseVisuals because the speech box needs
|
|
# to be positioned differently.
|
|
def show_choice_message(text, options, index = 0, align: :vertical, cmd_side: :right)
|
|
ret = -1
|
|
commands = options
|
|
commands = options.values if options.is_a?(Hash)
|
|
@sprites[:speech_box].visible = true
|
|
@sprites[:speech_box].text = text
|
|
using(cmd_window = Window_AdvancedCommandPokemon.new(commands)) do
|
|
position_speech_box(text)
|
|
cmd_window.viewport = @viewport
|
|
cmd_window.z = @sprites[:speech_box].z + 1
|
|
pbBottomRight(cmd_window)
|
|
cmd_window.height = [cmd_window.height, Graphics.height - @sprites[:speech_box].height].min
|
|
cmd_window.y = Graphics.height - @sprites[:speech_box].height - cmd_window.height
|
|
cmd_window.visible = !@sprites[:speech_box].busy?
|
|
cmd_window.index = index
|
|
loop do
|
|
Graphics.update
|
|
Input.update
|
|
update_visuals
|
|
cmd_window.visible = true if !@sprites[:speech_box].busy?
|
|
cmd_window.update
|
|
if !@sprites[:speech_box].busy?
|
|
if Input.trigger?(Input::BACK)
|
|
pbPlayCancelSE
|
|
ret = -1
|
|
break
|
|
elsif Input.trigger?(Input::USE) && @sprites[:speech_box].resume
|
|
pbPlayDecisionSE
|
|
ret = cmd_window.index
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
@sprites[:speech_box].visible = false
|
|
if options.is_a?(Hash)
|
|
ret = (ret < 0) ? nil : options.keys[ret]
|
|
end
|
|
return ret
|
|
end
|
|
|
|
def choose_box_wallpaper(text, options, index = 0)
|
|
original_index = index
|
|
ret = -1
|
|
commands = options
|
|
commands = options.values if options.is_a?(Hash)
|
|
old_letter_by_letter = @sprites[:speech_box].letterbyletter
|
|
@sprites[:speech_box].letterbyletter = false
|
|
@sprites[:speech_box].visible = true
|
|
@sprites[:speech_box].text = text
|
|
@sprites[:box].fade_all_pokemon
|
|
using(cmd_window = Window_AdvancedCommandPokemon.new(commands)) do
|
|
position_speech_box(text)
|
|
cmd_window.viewport = @viewport
|
|
cmd_window.z = @sprites[:speech_box].z + 1
|
|
pbBottomLeft(cmd_window)
|
|
cmd_window.width = @sprites[:side_pane].width
|
|
cmd_window.height = [cmd_window.height, Graphics.height].min
|
|
cmd_window.y = Graphics.height - cmd_window.height
|
|
cmd_window.visible = !@sprites[:speech_box].busy?
|
|
cmd_window.index = index
|
|
loop do
|
|
Graphics.update
|
|
Input.update
|
|
update_visuals
|
|
cmd_window.visible = true if !@sprites[:speech_box].busy?
|
|
old_index = cmd_window.index
|
|
cmd_window.update
|
|
if cmd_window.index != old_index
|
|
paper_num = (options.is_a?(Hash)) ? options.keys[cmd_window.index] : cmd_window.index
|
|
@sprites[:box].set_box_background(paper_num)
|
|
end
|
|
if !@sprites[:speech_box].busy?
|
|
if Input.trigger?(Input::BACK)
|
|
pbPlayCancelSE
|
|
ret = -1
|
|
break
|
|
elsif Input.trigger?(Input::USE) && @sprites[:speech_box].resume
|
|
pbPlayDecisionSE
|
|
ret = cmd_window.index
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if options.is_a?(Hash)
|
|
ret = (ret < 0) ? nil : options.keys[ret]
|
|
end
|
|
@sprites[:speech_box].letterbyletter = old_letter_by_letter
|
|
@sprites[:speech_box].visible = false
|
|
@sprites[:box].unfade_all_pokemon
|
|
@sprites[:box].set_box_background(options.keys[original_index]) if ret.nil?
|
|
return ret
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def refresh
|
|
super
|
|
refresh_box
|
|
refresh_side_pane
|
|
refresh_party_panel
|
|
refresh_buttons
|
|
refresh_cursor_position
|
|
end
|
|
|
|
def refresh_box
|
|
@sprites[:box].refresh
|
|
end
|
|
|
|
def refresh_side_pane
|
|
return if holding_pokemon? # Selected Pokémon is always the held one
|
|
refresh_selected_pokemon
|
|
end
|
|
|
|
def refresh_party_panel
|
|
@sprites[:party_panel].refresh
|
|
end
|
|
|
|
def refresh_selected_pokemon
|
|
@sprites[:side_pane].pokemon = pokemon
|
|
end
|
|
|
|
def refresh_buttons
|
|
if [:organize, :choose_pokemon].include?(@mode)
|
|
draw_text(_INTL("Party: {1}", @storage.party.length), 270, 334, align: :center, outline: :outline)
|
|
end
|
|
if @mode != :deposit
|
|
draw_text(_INTL("Exit"), 446, 334, align: :center, outline: :outline)
|
|
end
|
|
end
|
|
|
|
def refresh_cursor_position
|
|
if showing_party_panel?
|
|
if @index < 0 # Back button
|
|
@sprites[:cursor].x = 236
|
|
@sprites[:cursor].y = 220
|
|
else
|
|
coords = @sprites[:party_panel].pokemon_coords(@index)
|
|
@sprites[:cursor].x = @sprites[:party_panel].x + coords[0] - 32
|
|
@sprites[:cursor].y = @sprites[:party_panel].y + coords[1] - 64
|
|
end
|
|
return
|
|
end
|
|
case @index
|
|
when -1 # Box name
|
|
@sprites[:cursor].x = 314
|
|
@sprites[:cursor].y = -24
|
|
when -2 # Party Pokémon button
|
|
@sprites[:cursor].x = 238
|
|
@sprites[:cursor].y = 278
|
|
when -3 # Close Box button
|
|
@sprites[:cursor].x = 414
|
|
@sprites[:cursor].y = 278
|
|
else # Box space
|
|
coords = @sprites[:box].pokemon_coords(@index)
|
|
@sprites[:cursor].x = @sprites[:box].x + coords[0] - 32
|
|
@sprites[:cursor].y = @sprites[:box].y + coords[1] - 64
|
|
end
|
|
end
|
|
|
|
def refresh_on_index_changed(old_index)
|
|
refresh_cursor_position
|
|
refresh_side_pane
|
|
end
|
|
|
|
def refresh_markings_cursor
|
|
case @marking_index
|
|
when 6 # OK
|
|
@sprites[:marking_cursor].x = 318
|
|
@sprites[:marking_cursor].y = 196
|
|
@sprites[:marking_cursor].src_rect.y = @sprites[:marking_cursor].bitmap.height / 2
|
|
when 7 # Cancel
|
|
@sprites[:marking_cursor].x = 318
|
|
@sprites[:marking_cursor].y = 260
|
|
@sprites[:marking_cursor].src_rect.y = @sprites[:marking_cursor].bitmap.height / 2
|
|
else
|
|
@sprites[:marking_cursor].x = 318 + (58 * (@marking_index % 3))
|
|
@sprites[:marking_cursor].y = 96 + (50 * (@marking_index / 3))
|
|
@sprites[:marking_cursor].src_rect.y = 0
|
|
end
|
|
end
|
|
|
|
def refresh_markings_panel
|
|
# Set values to use when drawing the markings panel
|
|
marking_x = 334
|
|
marking_y = 106
|
|
marking_spacing_x = 42 + MARKING_WIDTH
|
|
marking_spacing_y = 34 + MARKING_HEIGHT
|
|
markings_per_row = 3
|
|
mark_variants = @bitmaps[:markings].bitmap.height / MARKING_HEIGHT
|
|
# Clear the bitmap
|
|
@sprites[:marking_overlay].bitmap.clear
|
|
# Draw marking icons
|
|
(@bitmaps[:markings].bitmap.width / MARKING_WIDTH).times do |i|
|
|
src_x = i * MARKING_WIDTH
|
|
src_y = [(@markings[i] || 0), mark_variants - 1].min * MARKING_HEIGHT
|
|
draw_image(@bitmaps[:markings],
|
|
marking_x + (marking_spacing_x * (i % markings_per_row)),
|
|
marking_y + (marking_spacing_y * (i / markings_per_row)),
|
|
src_x, src_y, MARKING_WIDTH, MARKING_HEIGHT,
|
|
overlay: :marking_overlay)
|
|
end
|
|
# Draw text
|
|
draw_text(_INTL("OK"), 400, 216, align: :center, outline: :outline, overlay: :marking_overlay)
|
|
draw_text(_INTL("Cancel"), 400, 280, align: :center, outline: :outline, overlay: :marking_overlay)
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def update_input
|
|
deselect_pokemon
|
|
# Check for movement to a new Pokémon/button
|
|
old_index = @index
|
|
update_cursor_movement
|
|
if @index != old_index
|
|
pbPlayCursorSE
|
|
set_index(@index)
|
|
end
|
|
# Check for interaction
|
|
if Input.trigger?(Input::USE)
|
|
return update_interaction(Input::USE)
|
|
elsif Input.trigger?(Input::BACK)
|
|
return update_interaction(Input::BACK)
|
|
elsif Input.trigger?(Input::ACTION)
|
|
return update_interaction(Input::ACTION)
|
|
elsif Input.trigger?(Input::JUMPUP)
|
|
return update_interaction(Input::JUMPUP)
|
|
elsif Input.trigger?(Input::JUMPDOWN)
|
|
return update_interaction(Input::JUMPDOWN)
|
|
end
|
|
return nil
|
|
end
|
|
|
|
def update_cursor_movement
|
|
if showing_party_panel?
|
|
update_cursor_movement_party
|
|
return
|
|
end
|
|
if Input.repeat?(Input::UP)
|
|
case @index
|
|
when -1 # Box name
|
|
@index = (@mode == :withdraw) ? -3 : -2 # Exit button : Party button
|
|
when -2 # Party button
|
|
@index = PokemonBox::BOX_SIZE - 1 - (PokemonBox::BOX_WIDTH * 2 / 3) # 25
|
|
when -3 # Exit button
|
|
@index = PokemonBox::BOX_SIZE - (PokemonBox::BOX_WIDTH / 3) # 28
|
|
else
|
|
@index -= PokemonBox::BOX_WIDTH
|
|
@index = -1 if @index < 0 # Box name
|
|
end
|
|
elsif Input.repeat?(Input::DOWN)
|
|
case @index
|
|
when -1 # Box name
|
|
@index = PokemonBox::BOX_WIDTH / 3 # 2
|
|
when -2, -3 # Party button, Exit button
|
|
@index = -1 # Box name
|
|
else
|
|
@index += PokemonBox::BOX_WIDTH
|
|
if @index >= PokemonBox::BOX_SIZE
|
|
if @index < PokemonBox::BOX_SIZE + (PokemonBox::BOX_WIDTH / 2) && @mode != :withdraw
|
|
@index = -2 # Party button
|
|
else
|
|
@index = -3 # Exit button
|
|
end
|
|
end
|
|
end
|
|
end
|
|
if Input.repeat?(Input::LEFT)
|
|
if @index == -1 # Box name
|
|
pbPlayCursorSE
|
|
go_to_previous_box
|
|
elsif @index == -2 # Party button
|
|
@index = -3 # Exit button
|
|
elsif @index == -3 # Exit button
|
|
@index = -2 if @mode != :withdraw # Party button
|
|
elsif (@index % PokemonBox::BOX_WIDTH) == 0 # Wrap around
|
|
@index += PokemonBox::BOX_WIDTH - 1
|
|
else
|
|
@index -= 1
|
|
end
|
|
elsif Input.repeat?(Input::RIGHT)
|
|
if @index == -1 # Box name
|
|
pbPlayCursorSE
|
|
go_to_next_box
|
|
elsif @index == -2 # Party button
|
|
@index = -3 # Exit button
|
|
elsif @index == -3 # Exit button
|
|
@index = -2 if @mode != :withdraw # Party button
|
|
elsif (@index % PokemonBox::BOX_WIDTH) == PokemonBox::BOX_WIDTH - 1 # Wrap around
|
|
@index -= PokemonBox::BOX_WIDTH - 1
|
|
else
|
|
@index += 1
|
|
end
|
|
end
|
|
end
|
|
|
|
# The Back button is at @index -2.
|
|
def update_cursor_movement_party
|
|
if Input.repeat?(Input::UP)
|
|
if @index == -2 # Back button
|
|
@index = Settings::MAX_PARTY_SIZE - 1
|
|
else
|
|
@index -= 2
|
|
@index = -2 if @index < 0 # Back button
|
|
end
|
|
elsif Input.repeat?(Input::DOWN)
|
|
if @index == -2 # Back button
|
|
@index = 0
|
|
else
|
|
@index += 2
|
|
@index = -2 if @index >= Settings::MAX_PARTY_SIZE # Back button
|
|
end
|
|
end
|
|
if Input.repeat?(Input::LEFT)
|
|
@index -= 1
|
|
@index = Settings::MAX_PARTY_SIZE - 1 if @index < -2
|
|
@index = -2 if @index < 0 # Back button
|
|
elsif Input.repeat?(Input::RIGHT)
|
|
@index += 1
|
|
@index = 0 if @index < 0
|
|
@index = -2 if @index >= Settings::MAX_PARTY_SIZE # Back button
|
|
end
|
|
end
|
|
|
|
def update_interaction(input)
|
|
case input
|
|
when Input::USE
|
|
if @index == -1 # Box name
|
|
pbPlayDecisionSE
|
|
return :interact_box_name_menu
|
|
elsif @index == -2 # Party button, or Back button in party panel
|
|
pbPlayDecisionSE
|
|
return :exit_screen if @mode == :deposit
|
|
return (showing_party_panel?) ? :hide_party_panel : :show_party_panel
|
|
elsif @index == -3 # Exit button
|
|
pbPlayDecisionSE
|
|
return :exit_screen
|
|
else
|
|
if pokemon
|
|
return :rearrange_pokemon if @sub_mode == :rearrange_pokemon
|
|
return :rearrange_items if @sub_mode == :rearrange_items
|
|
pbPlayDecisionSE
|
|
select_pokemon
|
|
return :interact_menu
|
|
end
|
|
end
|
|
when Input::ACTION
|
|
if can_access_screen_menu?
|
|
pbPlayDecisionSE
|
|
return :screen_menu
|
|
end
|
|
when Input::BACK
|
|
pbPlayCancelSE
|
|
if showing_party_panel?
|
|
return (@mode == :deposit) ? :exit_screen : :hide_party_panel
|
|
end
|
|
return :clear_sub_mode if (@sub_mode || :normal) != :normal
|
|
return :exit_screen
|
|
when Input::JUMPUP
|
|
pbPlayCursorSE
|
|
go_to_previous_box
|
|
when Input::JUMPDOWN
|
|
pbPlayCursorSE
|
|
go_to_next_box
|
|
end
|
|
return nil
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# NOTE: This is hardcoded to assume there are 6 marks, arranged in a 3x2 grid,
|
|
# with an OK and Cancel button below.
|
|
def update_input_marking
|
|
# Check for movement to a new option
|
|
if Input.repeat?(Input::UP)
|
|
if @marking_index == 7 # Cancel
|
|
@marking_index = 6
|
|
elsif @marking_index == 6 # OK
|
|
@marking_index = 4
|
|
elsif @marking_index < 3
|
|
@marking_index = 7
|
|
else
|
|
@marking_index -= 3
|
|
end
|
|
elsif Input.repeat?(Input::DOWN)
|
|
if @marking_index == 7 # Cancel
|
|
@marking_index = 1
|
|
elsif @marking_index == 6 # OK
|
|
@marking_index = 7
|
|
elsif @marking_index >= 3
|
|
@marking_index = 6
|
|
else
|
|
@marking_index += 3
|
|
end
|
|
elsif Input.repeat?(Input::LEFT)
|
|
if @marking_index < 6
|
|
@marking_index -= 1
|
|
@marking_index += 3 if (@marking_index % 3) == 2
|
|
end
|
|
elsif Input.repeat?(Input::RIGHT)
|
|
if @marking_index < 6
|
|
@marking_index += 1
|
|
@marking_index -= 3 if (@marking_index % 3) == 0
|
|
end
|
|
end
|
|
# Check for interaction
|
|
if Input.trigger?(Input::USE)
|
|
pbPlayDecisionSE
|
|
case @marking_index
|
|
when 6 # OK
|
|
return true
|
|
when 7 # Cancel
|
|
@marking_index = -1
|
|
return true
|
|
else # Change marking
|
|
mark_variants = @bitmaps[:markings].bitmap.height / MARKING_HEIGHT
|
|
@markings[@marking_index] = ((@markings[@marking_index] || 0) + 1) % mark_variants
|
|
refresh_markings_panel
|
|
end
|
|
elsif Input.trigger?(Input::BACK)
|
|
pbPlayCloseMenuSE
|
|
@marking_index = -1
|
|
return true
|
|
elsif Input.trigger?(Input::ACTION)
|
|
if @marking_index < 6 && @markings[@marking_index] > 0
|
|
pbPlayDecisionSE
|
|
@markings[@marking_index] = 0
|
|
refresh_markings_panel
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
def navigate_markings
|
|
help_text = _INTL("Mark your Pokémon.")
|
|
help_window = Window_AdvancedTextPokemon.newWithSize(
|
|
help_text, 180, 0, Graphics.width - 180, 32, @viewport
|
|
)
|
|
help_window.z = 2000
|
|
help_window.setSkin(MessageConfig.pbGetSpeechFrame)
|
|
help_window.letterbyletter = false
|
|
help_window.resizeHeightToFit(help_text, Graphics.width - 180)
|
|
pbBottomRight(help_window)
|
|
# Setup
|
|
@sprites[:marking_bg].visible = true
|
|
@sprites[:marking_overlay].visible = true
|
|
@sprites[:marking_cursor].visible = true
|
|
@markings = pokemon.markings.clone
|
|
@marking_index = 0
|
|
refresh_markings_panel
|
|
refresh_markings_cursor
|
|
# Navigate loop
|
|
loop do
|
|
Graphics.update
|
|
Input.update
|
|
update_visuals
|
|
old_marking_index = @marking_index
|
|
break if update_input_marking
|
|
if @marking_index != old_marking_index
|
|
pbPlayCursorSE
|
|
refresh_markings_panel
|
|
refresh_markings_cursor
|
|
end
|
|
end
|
|
# Clean up
|
|
@sprites[:marking_bg].visible = false
|
|
@sprites[:marking_overlay].visible = false
|
|
@sprites[:marking_cursor].visible = false
|
|
pokemon.markings = @markings if @marking_index >= 0
|
|
@marking_index = nil
|
|
help_window.dispose
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
#
|
|
#===============================================================================
|
|
class UI::PokemonStorage < UI::BaseScreen
|
|
attr_reader :storage, :mode
|
|
|
|
SCREEN_ID = :pokemon_storage_screen
|
|
|
|
# mode is one of:
|
|
# :withdraw
|
|
# :deposit
|
|
# :organize
|
|
# :choose_pokemon
|
|
def initialize(storage, mode: :organize)
|
|
@storage = storage
|
|
@mode = mode
|
|
super()
|
|
end
|
|
|
|
def initialize_visuals
|
|
@visuals = UI::PokemonStorageVisuals.new(@storage, @mode)
|
|
end
|
|
|
|
def start_screen
|
|
pbSEPlay("PC access")
|
|
super
|
|
end
|
|
|
|
def end_screen
|
|
pbSEPlay("PC close")
|
|
super
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
# Returns the "active" Pokémon, i.e. the one that gets interacted with and is
|
|
# shown in the side pane.
|
|
def pokemon
|
|
return @visuals.pokemon
|
|
end
|
|
|
|
def slot_pokemon
|
|
return @visuals.slot_pokemon
|
|
end
|
|
|
|
# Returns whether the cursor is holding a Pokémon.
|
|
def holding_pokemon?
|
|
return @visuals.holding_pokemon?
|
|
end
|
|
|
|
def item
|
|
return @visuals.item
|
|
end
|
|
|
|
def holding_item?
|
|
return @visuals.holding_item?
|
|
end
|
|
|
|
# -1 is the party, 0+ is a box.
|
|
def box
|
|
return @visuals.box
|
|
end
|
|
|
|
def choose_box(message, start_box = -1)
|
|
return @visuals.choose_box(message, start_box)
|
|
end
|
|
|
|
def set_index(new_index)
|
|
@visuals.set_index(new_index)
|
|
end
|
|
|
|
def set_sub_mode(sub_mode = :normal)
|
|
@visuals.set_sub_mode(sub_mode)
|
|
end
|
|
|
|
def party_able_count
|
|
return @storage.party.count { |pkmn| pkmn.able? }
|
|
end
|
|
|
|
def deselect_pokemon
|
|
@visuals.deselect_pokemon
|
|
end
|
|
|
|
#-----------------------------------------------------------------------------
|
|
|
|
def refresh_selected_pokemon
|
|
@visuals.refresh_selected_pokemon
|
|
end
|
|
|
|
def refresh_box
|
|
@visuals.refresh_box
|
|
end
|
|
end
|
|
|
|
#===============================================================================
|
|
# Actions that can be triggered in the Pokémon storage screen.
|
|
#===============================================================================
|
|
# Shows a choice menu using the MenuHandlers options below.
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :screen_menu, {
|
|
:menu => :storage_screen_menu,
|
|
:menu_message => proc { |screen| _INTL("What do you want to do?") }
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :rearrange_pokemon_mode, {
|
|
:effect => proc { |screen|
|
|
if screen.holding_item?
|
|
screen.show_message(_INTL("You're holding an item!"))
|
|
next
|
|
end
|
|
screen.set_sub_mode(:rearrange_pokemon)
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :rearrange_items_mode, {
|
|
:effect => proc { |screen|
|
|
if screen.holding_pokemon?
|
|
screen.show_message(_INTL("You're holding a Pokémon!"))
|
|
next
|
|
end
|
|
screen.set_sub_mode(:rearrange_items)
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :clear_sub_mode, {
|
|
:effect => proc { |screen|
|
|
if screen.holding_pokemon?
|
|
screen.show_message(_INTL("You're holding a Pokémon!"))
|
|
next
|
|
elsif screen.holding_item?
|
|
item_name = GameData::Item.get(screen.item).name
|
|
if screen.show_confirm_message(_INTL("Put the {1} in your Bag?", item_name))
|
|
$bag.add(screen.item)
|
|
screen.visuals.sprites[:cursor].held_item = nil
|
|
end
|
|
next
|
|
end
|
|
screen.set_sub_mode(:normal)
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :rearrange_pokemon, {
|
|
:effect => proc { |screen|
|
|
if screen.holding_pokemon?
|
|
if screen.slot_pokemon
|
|
screen.perform_action(:swap_pokemon)
|
|
else
|
|
screen.perform_action(:put_down_pokemon)
|
|
end
|
|
else
|
|
screen.perform_action(:pick_up_pokemon)
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :rearrange_items, {
|
|
:effect => proc { |screen|
|
|
next if !screen.slot_pokemon
|
|
if screen.holding_item?
|
|
if screen.slot_pokemon && screen.slot_pokemon.hasItem?
|
|
screen.perform_action(:swap_items)
|
|
else
|
|
screen.perform_action(:put_down_item)
|
|
end
|
|
elsif screen.slot_pokemon && screen.slot_pokemon.hasItem?
|
|
screen.perform_action(:pick_up_item)
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :pick_up_item, {
|
|
:effect => proc { |screen|
|
|
next if screen.holding_item? || !screen.slot_pokemon || !screen.slot_pokemon.hasItem?
|
|
if screen.slot_pokemon.mail
|
|
screen.show_message("You can't move mail.")
|
|
next
|
|
end
|
|
screen.visuals.pick_up_item
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :swap_items, {
|
|
:effect => proc { |screen|
|
|
next if !screen.holding_item? || !screen.slot_pokemon || !screen.slot_pokemon.hasItem?
|
|
held_item = screen.item
|
|
slot_pkmn = screen.slot_pokemon
|
|
if slot_pkmn.mail
|
|
screen.show_message("You can't move mail.")
|
|
next
|
|
end
|
|
screen.visuals.swap_items
|
|
slot_pkmn.item = held_item
|
|
screen.refresh_selected_pokemon
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :put_down_item, {
|
|
:effect => proc { |screen|
|
|
next if !screen.holding_item? || !screen.slot_pokemon || screen.slot_pokemon.hasItem?
|
|
pkmn = screen.slot_pokemon
|
|
screen.visuals.put_down_item
|
|
}
|
|
})
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Shows a choice menu using the MenuHandlers options below.
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :interact_menu, {
|
|
:menu => :storage_pokemon_interact,
|
|
:menu_message => proc { |screen| _INTL("Do what with {1}?", screen.pokemon.name) }
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :select_pokemon, {
|
|
:returns_value => true,
|
|
:effect => proc { |screen|
|
|
if screen.slot_pokemon
|
|
screen.result = [screen.box, screen.index]
|
|
next :quit
|
|
end
|
|
next nil
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :pick_up_pokemon, {
|
|
:effect => proc { |screen|
|
|
raise _INTL("Tried picking up a Pokémon when holding one.") if screen.holding_pokemon?
|
|
raise _INTL("Position {1},{2} is empty...", screen.box, screen.index) if !screen.slot_pokemon
|
|
if screen.box < 0 && screen.slot_pokemon.able? && screen.party_able_count <= 1
|
|
pbPlayBuzzerSE
|
|
screen.show_message(_INTL("That's your last Pokémon!"))
|
|
next
|
|
end
|
|
screen.visuals.pick_up_pokemon
|
|
screen.storage.pbDelete(screen.box, screen.index)
|
|
screen.refresh
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :swap_pokemon, {
|
|
:effect => proc { |screen|
|
|
raise _INTL("Tried swapping a Pokémon when not holding one.") if !screen.holding_pokemon?
|
|
raise _INTL("Position {1},{2} is empty...", screen.box, screen.index) if !screen.slot_pokemon
|
|
held_pkmn = screen.pokemon
|
|
slot_pkmn = screen.slot_pokemon
|
|
if screen.box >= 0
|
|
if screen.index >= @storage.maxPokemon(screen.box)
|
|
screen.show_message("Can't place that there.")
|
|
next
|
|
elsif held_pkmn.mail
|
|
screen.show_message("Please remove the mail.")
|
|
next
|
|
elsif held_pkmn.cannot_store
|
|
screen.show_message(_INTL("{1} refuses to go into storage!", held_pkmn.name))
|
|
next
|
|
end
|
|
elsif screen.box < 0 && slot_pkmn.able? && screen.party_able_count <= 1 && !held_pkmn.able?
|
|
pbPlayBuzzerSE
|
|
screen.show_message(_INTL("That's your last Pokémon!"))
|
|
next
|
|
end
|
|
screen.visuals.swap_pokemon
|
|
screen.storage[screen.box, screen.index] = held_pkmn
|
|
if Settings::HEAL_STORED_POKEMON && screen.box >= 0
|
|
old_ready_evo = held_pkmn.ready_to_evolve
|
|
held_pkmn.heal
|
|
held_pkmn.ready_to_evolve = old_ready_evo
|
|
end
|
|
screen.refresh
|
|
screen.refresh_selected_pokemon
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :put_down_pokemon, {
|
|
:effect => proc { |screen|
|
|
raise _INTL("Tried placing a Pokémon when not holding one.") if !screen.holding_pokemon?
|
|
raise _INTL("Position {1},{2} is not empty...", screen.box, screen.index) if screen.slot_pokemon
|
|
pkmn = screen.pokemon # The held Pokémon
|
|
if screen.box >= 0
|
|
if screen.index >= screen.storage.maxPokemon(screen.box)
|
|
screen.show_message("Can't place that there.")
|
|
next
|
|
elsif pkmn.mail
|
|
screen.show_message("Please remove the mail.")
|
|
next
|
|
elsif pkmn.cannot_store
|
|
screen.show_message(_INTL("{1} refuses to go into storage!", pkmn.name))
|
|
next
|
|
end
|
|
end
|
|
screen.visuals.put_down_pokemon
|
|
screen.storage[screen.box, screen.index] = pkmn
|
|
screen.storage.party.compact! if screen.box < 0
|
|
if Settings::HEAL_STORED_POKEMON && screen.box >= 0
|
|
old_ready_evo = pkmn.ready_to_evolve
|
|
pkmn.heal
|
|
pkmn.ready_to_evolve = old_ready_evo
|
|
end
|
|
screen.refresh
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :summary, {
|
|
:effect => proc { |screen|
|
|
pbFadeOutInWithUpdate(screen.sprites) do
|
|
screen.deselect_pokemon
|
|
if screen.holding_pokemon?
|
|
UI::PokemonSummary.new(screen.pokemon, 0).main
|
|
else
|
|
party = (screen.box >= 0) ? screen.storage[screen.box].pokemon : screen.storage[screen.box]
|
|
new_index = UI::PokemonSummary.new(party, screen.index).main
|
|
screen.set_index(new_index)
|
|
end
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :withdraw, {
|
|
:effect => proc { |screen|
|
|
screen.perform_action(:withdraw_pokemon)
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :withdraw_pokemon, {
|
|
:effect => proc { |screen|
|
|
raise _INTL("Can't withdraw from party...") if screen.box < 0
|
|
if screen.storage.party_full?
|
|
screen.show_message(_INTL("Your party's full!"))
|
|
next
|
|
end
|
|
was_holding = screen.holding_pokemon?
|
|
pkmn = screen.pokemon
|
|
screen.visuals.withdraw_pokemon
|
|
if was_holding
|
|
screen.storage.pbMoveCaughtToParty(pkmn)
|
|
else
|
|
screen.storage.pbMove(-1, -1, screen.box, screen.index)
|
|
end
|
|
screen.refresh
|
|
screen.refresh_selected_pokemon
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :store, {
|
|
:effect => proc { |screen|
|
|
screen.perform_action(:store_pokemon)
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :store_pokemon, {
|
|
:effect => proc { |screen|
|
|
raise _INTL("Can't deposit from box...") if screen.box >= 0
|
|
was_holding = screen.holding_pokemon?
|
|
pkmn = screen.pokemon
|
|
if pkmn.able? && screen.party_able_count <= 1 && !screen.holding_pokemon?
|
|
pbPlayBuzzerSE
|
|
screen.show_message(_INTL("That's your last Pokémon!"))
|
|
next
|
|
elsif pkmn.mail
|
|
screen.show_message("Please remove the mail.")
|
|
next
|
|
elsif pkmn.cannot_store
|
|
screen.show_message(_INTL("{1} refuses to go into storage!", pkmn.name))
|
|
next
|
|
end
|
|
old_box = screen.box
|
|
old_index = screen.index
|
|
loop do
|
|
new_box = screen.choose_box(_INTL("Deposit in which Box?"), old_box)
|
|
break if !new_box
|
|
new_index = screen.storage.pbFirstFreePos(new_box)
|
|
if new_index < 0
|
|
screen.show_message(_INTL("The Box is full."))
|
|
next
|
|
end
|
|
screen.visuals.store_pokemon(new_box, new_index) {
|
|
if was_holding
|
|
screen.storage.pbMoveCaughtToBox(pkmn, new_box)
|
|
else
|
|
screen.storage.pbMove(new_box, new_index, old_box, old_index)
|
|
end
|
|
}
|
|
screen.refresh
|
|
screen.refresh_selected_pokemon
|
|
break
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :give_or_take_item, {
|
|
:effect => proc { |screen|
|
|
pkmn = screen.pokemon
|
|
if pkmn.egg?
|
|
screen.show_message(_INTL("Eggs can't hold items."))
|
|
next
|
|
elsif pkmn.mail
|
|
screen.show_message(_INTL("Please remove the mail."))
|
|
next
|
|
end
|
|
# Take an item
|
|
if pkmn.hasItem?
|
|
item_name = pkmn.item.portion_name
|
|
if screen.show_confirm_message(_INTL("Take the {1}?", item_name))
|
|
if $bag.add(pkmn.item)
|
|
pkmn.item = nil
|
|
screen.refresh
|
|
screen.show_message(_INTL("Took the {1}.", item_name))
|
|
else
|
|
screen.show_message(_INTL("Can't store the {1}.", item_name))
|
|
end
|
|
end
|
|
screen.deselect_pokemon
|
|
next
|
|
end
|
|
# Give an item
|
|
new_item = nil
|
|
pbFadeOutInWithUpdate(screen.sprites) do
|
|
bag_screen = UI::Bag.new($bag, mode: :choose_item)
|
|
bag_screen.set_filter_proc(proc { |itm| GameData::Item.get(itm).can_hold? })
|
|
new_item = bag_screen.choose_item
|
|
screen.deselect_pokemon if !new_item
|
|
end
|
|
if new_item
|
|
item_name = GameData::Item.get(new_item).name
|
|
pkmn.item = new_item
|
|
$bag.remove(new_item)
|
|
screen.refresh
|
|
screen.show_message(_INTL("{1} is now being held.", item_name))
|
|
screen.deselect_pokemon
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :mark_pokemon, {
|
|
:effect => proc { |screen|
|
|
screen.visuals.navigate_markings
|
|
screen.deselect_pokemon
|
|
screen.refresh
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :release_pokemon, {
|
|
:effect => proc { |screen|
|
|
raise _INTL("Tried releasing a Pokémon when not selecting or holding one.", screen.box, screen.index) if !screen.pokemon
|
|
pkmn = screen.pokemon
|
|
if pkmn.egg?
|
|
screen.show_message(_INTL("You can't release an Egg."))
|
|
next
|
|
elsif pkmn.mail
|
|
screen.show_message(_INTL("Please remove the mail."))
|
|
next
|
|
elsif pkmn.cannot_release
|
|
screen.show_message(_INTL("{1} refuses to leave you!", pkmn.name))
|
|
next
|
|
elsif screen.box < 0 && pkmn.able? && screen.party_able_count <= 1 && !screen.holding_pokemon?
|
|
pbPlayBuzzerSE
|
|
screen.show_message(_INTL("That's your last Pokémon!"))
|
|
next
|
|
end
|
|
if screen.show_confirm_serious_message(_INTL("Release this Pokémon?"))
|
|
$bag.add(pkmn.item_id) if pkmn.hasItem?
|
|
pkmn_name = pkmn.name
|
|
screen.visuals.release_pokemon
|
|
screen.storage.pbDelete(screen.box, screen.index) if !screen.holding_pokemon?
|
|
screen.refresh
|
|
screen.show_message(_INTL("{1} was released.", pkmn_name))
|
|
screen.show_message(_INTL("Bye-bye, {1}!", pkmn_name))
|
|
$stats.pokemon_release_count += 1
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :debug, {
|
|
:effect => proc { |screen|
|
|
screen.pokemon_debug_menu(screen.pokemon, [screen.box, screen.index])
|
|
}
|
|
})
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# Shows a choice menu using the MenuHandlers options below.
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :interact_box_name_menu, {
|
|
:menu => :storage_box_interact,
|
|
:menu_message => proc { |screen| _INTL("Choose an option.") }
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :jump_to_box, {
|
|
:effect => proc { |screen|
|
|
new_box = screen.choose_box(_INTL("Jump to which Box?"))
|
|
next if !new_box || new_box == box
|
|
(new_box > box) ? screen.visuals.go_to_next_box(new_box) : screen.visuals.go_to_previous_box(new_box)
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :rename_box, {
|
|
:effect => proc { |screen|
|
|
pbFadeOutInWithUpdate(screen.sprites) do
|
|
ret = pbEnterBoxName(_INTL("Box name?"), 0, 16)
|
|
if ret.length > 0
|
|
screen.storage[screen.storage.currentBox].name = ret
|
|
screen.refresh_box
|
|
end
|
|
end
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :change_box_wallpaper, {
|
|
:effect => proc { |screen|
|
|
papers = screen.storage.availableWallpapers
|
|
old_paper = screen.storage[screen.storage.currentBox].background
|
|
index = papers.keys.index(old_paper) || 0
|
|
new_paper = screen.visuals.choose_box_wallpaper(_INTL("Pick the wallpaper."), papers, index)
|
|
if new_paper && new_paper != old_paper
|
|
screen.storage[screen.storage.currentBox].background = new_paper
|
|
screen.refresh_box
|
|
end
|
|
}
|
|
})
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :show_party_panel, {
|
|
:effect => proc { |screen|
|
|
screen.visuals.show_party_panel
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :hide_party_panel, {
|
|
:effect => proc { |screen|
|
|
screen.visuals.hide_party_panel
|
|
}
|
|
})
|
|
|
|
UIActionHandlers.add(UI::PokemonStorage::SCREEN_ID, :exit_screen, {
|
|
:returns_value => true,
|
|
:effect => proc { |screen|
|
|
if screen.holding_pokemon?
|
|
screen.show_message(_INTL("You're holding a Pokémon!"))
|
|
next nil
|
|
elsif screen.holding_item?
|
|
screen.show_message(_INTL("You're holding an item!"))
|
|
next nil
|
|
end
|
|
next :quit if screen.show_confirm_message(_INTL("Exit from the Box?"))
|
|
next nil
|
|
}
|
|
})
|
|
|
|
#===============================================================================
|
|
# Menu options for choice menus that exist in the Pokémon storage screen.
|
|
#===============================================================================
|
|
MenuHandlers.add(:storage_screen_menu, :rearrange_pokemon_mode, {
|
|
"name" => _INTL("Mode: Switch Pokémon"),
|
|
"order" => 10
|
|
})
|
|
|
|
MenuHandlers.add(:storage_screen_menu, :rearrange_items_mode, {
|
|
"name" => _INTL("Mode: Switch items"),
|
|
"order" => 20
|
|
})
|
|
|
|
MenuHandlers.add(:storage_screen_menu, :cancel, {
|
|
"name" => _INTL("Cancel"),
|
|
"order" => 9999
|
|
})
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
# NOTE: This option is first in withdraw mode.
|
|
MenuHandlers.add(:storage_pokemon_interact, :withdraw, {
|
|
"name" => _INTL("Withdraw"),
|
|
"order" => 10,
|
|
"condition" => proc { |screen| next screen.mode == :withdraw && screen.box >= 0 }
|
|
})
|
|
|
|
# NOTE: This option is first in store mode.
|
|
MenuHandlers.add(:storage_pokemon_interact, :store, {
|
|
"name" => _INTL("Store"),
|
|
"order" => 10,
|
|
"condition" => proc { |screen| next screen.mode == :deposit && screen.box < 0 }
|
|
})
|
|
|
|
# NOTE: This option is for when in "choose a Pokémon" mode.
|
|
MenuHandlers.add(:storage_pokemon_interact, :select_pokemon, {
|
|
"name" => _INTL("Select"),
|
|
"order" => 10,
|
|
"condition" => proc { |screen| next screen.mode == :choose_pokemon }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :pick_up_pokemon, {
|
|
"name" => _INTL("Move"),
|
|
"order" => 20,
|
|
"condition" => proc { |screen| next screen.mode == :organize && !screen.holding_pokemon? }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :swap_pokemon, {
|
|
"name" => _INTL("Shift"),
|
|
"order" => 20,
|
|
"condition" => proc { |screen| next screen.mode == :organize && screen.holding_pokemon? && screen.slot_pokemon }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :put_down_pokemon, {
|
|
"name" => _INTL("Place"),
|
|
"order" => 20,
|
|
"condition" => proc { |screen| next screen.mode == :organize && screen.holding_pokemon? && !screen.slot_pokemon }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :summary, {
|
|
"name" => _INTL("Summary"),
|
|
"order" => 30
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :withdraw_pokemon, {
|
|
"name" => _INTL("Withdraw"),
|
|
"order" => 40,
|
|
"condition" => proc { |screen| next screen.mode == :organize && screen.box >= 0 }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :store_pokemon, {
|
|
"name" => _INTL("Store"),
|
|
"order" => 40,
|
|
"condition" => proc { |screen| next screen.mode == :organize && screen.box < 0 }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :give_or_take_item, {
|
|
"name" => _INTL("Item"),
|
|
"order" => 50,
|
|
"condition" => proc { |screen| next screen.mode == :organize }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :mark_pokemon, {
|
|
"name" => _INTL("Mark"),
|
|
"order" => 60
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :release_pokemon, {
|
|
"name" => _INTL("Release"),
|
|
"order" => 70,
|
|
"condition" => proc { |screen| next screen.mode != :choose_pokemon }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :debug, {
|
|
"name" => _INTL("Debug"),
|
|
"order" => 80,
|
|
"condition" => proc { |screen| next $DEBUG }
|
|
})
|
|
|
|
MenuHandlers.add(:storage_pokemon_interact, :cancel, {
|
|
"name" => _INTL("Cancel"),
|
|
"order" => 9999
|
|
})
|
|
|
|
#-------------------------------------------------------------------------------
|
|
|
|
MenuHandlers.add(:storage_box_interact, :jump_to_box, {
|
|
"name" => _INTL("Jump to box"),
|
|
"order" => 10
|
|
})
|
|
|
|
MenuHandlers.add(:storage_box_interact, :rename_box, {
|
|
"name" => _INTL("Rename box"),
|
|
"order" => 20
|
|
})
|
|
|
|
MenuHandlers.add(:storage_box_interact, :change_box_wallpaper, {
|
|
"name" => _INTL("Change wallpaper"),
|
|
"order" => 30
|
|
})
|
|
|
|
MenuHandlers.add(:storage_box_interact, :cancel, {
|
|
"name" => _INTL("Cancel"),
|
|
"order" => 9999
|
|
})
|