Rewrote BP Shop code, tidied PC menu code, fixed message display bug involving instant speed and \wtnp, fixed mail vanishing bug, tweaks to other rewritten UI

This commit is contained in:
Maruno17
2024-09-27 22:10:26 +01:00
parent 48292c2a28
commit b80de83b0d
20 changed files with 967 additions and 797 deletions

View File

@@ -440,9 +440,10 @@ module UI
return ret
end
# Used for dialogue.
# align: Where the command window is in relation to the message window.
# :horizontal is side by side, :vertical is command window above.
def show_choice_message(text, options, index = 0, align: :horizontal, cmd_side: :right)
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)
@@ -493,6 +494,14 @@ module UI
return ret
end
def show_menu(text, options, index = 0, cmd_side: :right)
old_letter_by_letter = @sprites[:speech_box].letterbyletter
@sprites[:speech_box].letterbyletter = false
ret = show_choice_message(text, options, index, align: :horizontal, cmd_side: cmd_side)
@sprites[:speech_box].letterbyletter = old_letter_by_letter
return ret
end
def show_choice(options, index = 0)
ret = -1
commands = options
@@ -529,6 +538,72 @@ module UI
return UIHelper.pbChooseNumber(@sprites[:speech_box], help_text, maximum, init_value) { update_visuals }
end
def choose_number_as_money_multiplier(help_text, money_per_unit, maximum, init_value = 1)
@sprites[:speech_box].visible = true
@sprites[:speech_box].text = help_text
pbBottomLeftLines(@sprites[:speech_box], 2)
# Show the help text
loop do
Graphics.update
Input.update
update_visuals
if @sprites[:speech_box].busy?
if Input.trigger?(Input::USE)
pbPlayDecisionSE if @sprites[:speech_box].pausing?
@sprites[:speech_box].resume
end
else
break
end
end
# Choose a quantity
item_price = money_per_unit
quantity = init_value
using(num_window = Window_AdvancedTextPokemon.newWithSize(
_INTL("×{1}<r>${2}", quantity, (quantity * item_price).to_s_formatted),
0, 0, 224, 64, @viewport)) do
num_window.z = 2000
num_window.visible = true
num_window.letterbyletter = false
pbBottomRight(num_window)
num_window.y -= @sprites[:speech_box].height
loop do
Graphics.update
Input.update
update
num_window.update
# Change quantity
old_quantity = quantity
if Input.repeat?(Input::LEFT)
quantity = [quantity - 10, 1].max
elsif Input.repeat?(Input::RIGHT)
quantity = [quantity + 10, maximum].min
elsif Input.repeat?(Input::UP)
quantity += 1
quantity = 1 if quantity > maximum
elsif Input.repeat?(Input::DOWN)
quantity -= 1
quantity = maximum if quantity < 1
end
if quantity != old_quantity
num_window.text = _INTL("×{1}<r>${2}", quantity, (quantity * item_price).to_s_formatted)
pbPlayCursorSE
end
# Finish choosing a quantity
if Input.trigger?(Input::USE)
pbPlayDecisionSE
break
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
quantity = 0
break
end
end
end
@sprites[:speech_box].visible = false
return quantity
end
#---------------------------------------------------------------------------
def refresh_on_index_changed(old_index)
@@ -626,6 +701,10 @@ module UI
alias pbShowCommands show_choice_message
def show_menu(text, options, initial_index = 0, cmd_side: :right)
return @visuals.show_menu(text, options, initial_index, cmd_side: cmd_side)
end
def show_choice(options, initial_index = 0)
return @visuals.show_choice(options, initial_index)
end
@@ -635,7 +714,7 @@ module UI
MenuHandlers.each_available(menu_handler_id, self) do |option, _hash, name|
commands[option] = name
end
return show_choice_message(message, commands) if message
return show_menu(message, commands) if message
return show_choice(commands)
end
@@ -645,6 +724,10 @@ module UI
alias pbChooseNumber choose_number
def choose_number_as_money_multiplier(help_text, money_per_unit, maximum, init_value = 1)
return @visuals.choose_number_as_money_multiplier(help_text, money_per_unit, maximum, init_value)
end
#-----------------------------------------------------------------------------
def refresh

View File

@@ -519,13 +519,10 @@ class UI::PartyVisuals < UI::BaseVisuals
return ret
end
def show_choice_message(text, options, index = 0)
def show_menu(text, options, index = 0, cmd_side: :right)
@sprites[:help_window].visible = false
old_letter_by_letter = @sprites[:speech_box].letterbyletter
@sprites[:speech_box].letterbyletter = false
cmd_menu_align = :right # (@index.even? ? :right : :left)
ret = super(text, options, index, cmd_side: cmd_menu_align)
@sprites[:speech_box].letterbyletter = old_letter_by_letter
# cmd_side = (@index.even?) ? :right : :left
ret = super(text, options, index, cmd_side: cmd_side)
@sprites[:help_window].visible = true
return ret
end
@@ -853,6 +850,10 @@ class UI::Party < UI::BaseScreen
#-----------------------------------------------------------------------------
alias pbShowCommands show_menu
#-----------------------------------------------------------------------------
def refresh
super
reset_help_text
@@ -1068,7 +1069,7 @@ class UI::Party < UI::BaseScreen
commands[:not_enter] = _INTL("No Entry") if (statuses[index] || 0) > 2 # Already entered
commands[:summary] = _INTL("Summary")
commands[:cancel] = _INTL("Cancel")
chosen_command = show_choice_message(_INTL("Do what with {1}?", pokemon.name), commands)
chosen_command = show_menu(_INTL("Do what with {1}?", pokemon.name), commands)
case chosen_command
when :enter
if real_order.length >= ruleset.number && ruleset.number > 0
@@ -1113,7 +1114,7 @@ class UI::Party < UI::BaseScreen
move_names.push(_INTL("{1} (PP: {2}/{3})", move.name, move.pp, move.total_pp))
end
end
return show_choice_message(message, move_names)
return show_menu(message, move_names)
end
alias pbChooseMove choose_move
@@ -1188,7 +1189,7 @@ UIActionHandlers.add(UI::Party::SCREEN_ID, :item_use, {
bag_screen = UI::Bag.new($bag, mode: :choose_item)
bag_screen.set_filter_proc(proc { |itm|
item_data = GameData::Item.get(itm)
next false if !pbCanUseOnPokemon?(itm)
next false if !pbCanUseItemOnPokemon?(itm)
next false if pkmn.hyper_mode && !item_data&.is_scent?
if item_data.is_machine?
move = item_data.move
@@ -1284,6 +1285,12 @@ UIActionHandlers.add(UI::Party::SCREEN_ID, :item_move, {
}
})
# Shows a choice menu using the MenuHandlers options below.
UIActionHandlers.add(UI::Party::SCREEN_ID, :mail_menu, {
:menu => :party_screen_interact_mail,
:menu_message => proc { |screen| _INTL("Do what with the Mail?") }
})
UIActionHandlers.add(UI::Party::SCREEN_ID, :item_move_mode, {
:effect => proc { |screen|
screen.set_sub_mode(:switch_items)

View File

@@ -1407,7 +1407,7 @@ class UI::PokemonSummary < UI::BaseScreen
end
def choose_move
pbSEPlay("GUI menu open")
pbSEPlay("GUI summary change page")
start_screen
@result = perform_action(:navigate_moves)
end_screen

View File

@@ -544,7 +544,7 @@ class UI::BagVisuals < UI::BaseVisuals
use_type = item_data.field_use
# TODO: If @mode == :choose_item_in_battle, also check for item usage on a
# battler.
return if !pbCanUseOnPokemon?(item)
return if !pbCanUseItemOnPokemon?(item)
icon_x = 0
icon_y = 0
icon_size = [@bitmaps[:party_icons].height, @bitmaps[:party_icons].height]
@@ -710,6 +710,8 @@ class UI::BagVisuals < UI::BaseVisuals
return update_interaction_choose_item(Input::USE)
elsif Input.trigger?(Input::BACK)
return update_interaction_choose_item(Input::BACK)
elsif Input.trigger?(Input::ACTION)
return update_interaction_choose_item(Input::ACTION)
end
return nil
end
@@ -723,6 +725,13 @@ class UI::BagVisuals < UI::BaseVisuals
end
pbPlayDecisionSE
return :chosen
when Input::ACTION
if item && @pocket == :Machines
pbPlayDecisionSE
@show_move_details = !@show_move_details
refresh_move_details
refresh_input_indicators
end
when Input::BACK
pbPlayCloseMenuSE
return :quit
@@ -974,7 +983,7 @@ UIActionHandlers.add(UI::Bag::SCREEN_ID, :debug, {
:effect => proc { |screen|
command = 0
loop do
command = screen.show_choice_message(
command = screen.show_menu(
_INTL("Do what with {1}?", screen.item.name),
[_INTL("Change quantity"), _INTL("Make Mystery Gift"), _INTL("Cancel")], command)
case command
@@ -1076,3 +1085,38 @@ MenuHandlers.add(:bag_screen_interact, :cancel, {
"name" => _INTL("Cancel"),
"order" => 9999
})
#===============================================================================
# Methods for choosing an item from the Bag.
#===============================================================================
def pbChooseItem(game_variable = 0, *args)
ret = nil
pbFadeOutIn do
bag_screen = UI::Bag.new($bag, mode: :choose_item)
ret = bag_screen.choose_item
end
$game_variables[game_variable] = ret || :NONE if game_variable > 0
return ret
end
def pbChooseApricorn(game_variable = 0)
ret = nil
pbFadeOutIn do
bag_screen = UI::Bag.new($bag, mode: :choose_item)
bag_screen.set_filter_proc(proc { |item| GameData::Item.get(item).is_apricorn? })
ret = bag_screen.choose_item
end
$game_variables[game_variable] = ret || :NONE if game_variable > 0
return ret
end
def pbChooseFossil(game_variable = 0)
ret = nil
pbFadeOutIn do
bag_screen = UI::Bag.new($bag, mode: :choose_item)
bag_screen.set_filter_proc(proc { |item| GameData::Item.get(item).is_fossil? })
ret = bag_screen.choose_item
end
$game_variables[game_variable] = ret || :NONE if game_variable > 0
return ret
end

View File

@@ -0,0 +1,280 @@
#===============================================================================
# TODO: Make this code more consistent between having methods in the module and
# code in MenuHandlers.
#===============================================================================
module UI::PC
module_function
def pbGetStorageCreator
return GameData::Metadata.get.storage_creator
end
#-----------------------------------------------------------------------------
def pbPokeCenterPC
pbMessage("\\se[PC open]" + _INTL("{1} booted up the PC.", $player.name))
# Get all commands
command_list = []
commands = []
MenuHandlers.each_available(:pc_menu) do |option, hash, name|
command_list.push(name)
commands.push(hash)
end
# Main loop
command = 0
loop do
choice = pbMessage(_INTL("Which PC should be accessed?"), command_list, -1, nil, command)
if choice < 0
pbPlayCloseMenuSE
break
end
break if commands[choice]["effect"].call
end
pbSEPlay("PC close")
end
def pbTrainerPC
pbMessage("\\se[PC open]" + _INTL("{1} booted up the PC.", $player.name))
pbTrainerPCMenu
pbSEPlay("PC close")
end
def pbTrainerPCMenu
commands = {
:item_storage => _INTL("Item Storage"),
:mailbox => _INTL("Mailbox"),
:turn_off => _INTL("Turn off")
}
command = 0
loop do
command = pbMessage(_INTL("What do you want to do?"), commands.values, -1, nil, command)
case commands.keys[command]
when :item_storage
pbPlayDecisionSE
pbPCItemStorage
when :mailbox
if !$PokemonGlobal.mailbox || $PokemonGlobal.mailbox.length == 0
pbMessage(_INTL("There's no Mail here."))
next
end
pbPlayDecisionSE
pbPCMailbox
else
break
end
end
end
#-----------------------------------------------------------------------------
def pbPCItemStorage
$PokemonGlobal.pcItemStorage ||= PCItemStorage.new
commands = {
:withdraw => [_INTL("Withdraw Item"), _INTL("Take out items from the PC.")],
:deposit => [_INTL("Deposit Item"), _INTL("Store items in the PC.")],
:toss => [_INTL("Toss Item"), _INTL("Throw away items stored in the PC.")],
:exit => [_INTL("Exit"), _INTL("Go back to the previous menu.")]
}
command = 0
loop do
commands.values.map { |val| val[0] }
command = pbShowCommandsWithHelp(nil, commands.values.map { |val| val[0] },
commands.values.map { |val| val[1] }, -1, command)
break if command < 0
case commands.keys[command]
when :withdraw
if $PokemonGlobal.pcItemStorage.empty?
pbMessage(_INTL("There are no items."))
else
pbPlayDecisionSE
pbFadeOutIn do
scene = WithdrawItemScene.new
screen = ItemStorageScreen.new(scene, $bag)
screen.pbWithdrawItemScreen
end
end
when :deposit
pbPlayDecisionSE
item_storage = $PokemonGlobal.pcItemStorage
pbFadeOutIn do
bag_screen = UI::Bag.new($bag, mode: :choose_item)
given_item = bag_screen.choose_item do |item|
item_data = GameData::Item.get(item)
qty = $bag.quantity(item)
if qty > 1 && !item_data.is_important?
qty = bag_screen.choose_number(_INTL("How many do you want to deposit?"), qty)
end
next false if qty == 0
if !item_storage.can_add?(item, qty)
raise "Can't delete items from Bag" if !$bag.remove(item, qty)
raise "Can't deposit items to storage" if !item_storage.add(item, qty)
bag_screen.refresh
disp_qty = (item_data.is_important?) ? 1 : qty
item_name = (disp_qty > 1) ? item_data.portion_name_plural : item_data.portion_name
bag_screen.show_message(_INTL("Deposited {1} {2}.", disp_qty, item_name))
else
bag_screen.show_message(_INTL("There's no room to store items."))
end
next false
end
end
when :toss
if $PokemonGlobal.pcItemStorage.empty?
pbMessage(_INTL("There are no items."))
else
pbPlayDecisionSE
pbFadeOutIn do
scene = TossItemScene.new
screen = ItemStorageScreen.new(scene, $bag)
screen.pbTossItemScreen
end
end
else
break
end
end
end
#-----------------------------------------------------------------------------
def pbPCMailbox
command = 0
loop do
commands = []
$PokemonGlobal.mailbox.each { |mail| commands.push(mail.sender) }
commands.push(_INTL("Cancel"))
mail_index = pbShowCommands(nil, commands, -1, command)
break if mail_index < 0 || mail_index >= $PokemonGlobal.mailbox.length
interact_commands = {
:read => _INTL("Read"),
:move_to_bag => _INTL("Move to Bag"),
:give => _INTL("Give"),
:cancel => _INTL("Cancel")
}
command_mail = pbMessage(
_INTL("What do you want to do with {1}'s Mail?", $PokemonGlobal.mailbox[mail_index].sender),
interact_commands.values, -1
)
case interact_commands.keys[command_mail]
when :read
pbPlayDecisionSE
pbFadeOutIn { pbDisplayMail($PokemonGlobal.mailbox[mail_index]) }
when :move_to_bag
if pbConfirmMessage(_INTL("The message will be lost. Is that OK?"))
if $bag.add($PokemonGlobal.mailbox[mail_index].item)
pbMessage(_INTL("The Mail was returned to the Bag with its message erased."))
$PokemonGlobal.mailbox.delete_at(mail_index)
else
pbMessage(_INTL("The Bag is full."))
end
end
when :give
pbPlayDecisionSE
pbFadeOutIn do
screen = UI::Party.new($player.party, mode: :choose_pokemon)
screen.choose_pokemon do |pkmn, party_index|
next true if party_index < 0
if pkmn.egg?
screen.show_message(_INTL("Eggs can't hold mail."))
elsif pkmn.hasItem? || pkmn.mail
screen.show_message(_INTL("This Pokémon is holding an item. It can't hold mail."))
else
pkmn.mail = $PokemonGlobal.mailbox[mail_index]
$PokemonGlobal.mailbox.delete_at(mail_index)
screen.refresh
screen.show_message(_INTL("Mail was transferred from the Mailbox."))
next true
end
next false
end
end
else
pbPlayDecisionSE
end
end
end
end
#===============================================================================
#
#===============================================================================
MenuHandlers.add(:pc_menu, :pokemon_storage, {
"name" => proc {
next ($player.seen_storage_creator) ? _INTL("{1}'s PC", UI::PC.pbGetStorageCreator) : _INTL("Someone's PC")
},
"order" => 10,
"effect" => proc { |menu|
pbMessage("\\se[PC access]" + _INTL("The Pokémon Storage System was opened."))
commands = {
:organize => [_INTL("Organize Boxes"), _INTL("Organize the Pokémon in Boxes and in your party.")],
:withdraw => [_INTL("Withdraw Pokémon"), _INTL("Move Pokémon stored in Boxes to your party.")],
:deposit => [_INTL("Deposit Pokémon"), _INTL("Store Pokémon in your party in Boxes.")],
:quit => [_INTL("See ya!"), _INTL("Return to the previous menu.")]
}
command = 0
loop do
command = pbShowCommandsWithHelp(nil, commands.values.map { |val| val[0] },
commands.values.map { |val| val[1] }, -1, command)
break if command < 0
case commands.keys[command]
when :organize
pbPlayDecisionSE
pbFadeOutIn do
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.pbStartScreen(0)
end
when :withdraw
if $PokemonStorage.party_full?
pbMessage(_INTL("Your party is full!"))
next
end
pbPlayDecisionSE
pbFadeOutIn do
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.pbStartScreen(1)
end
when :deposit
if $player.able_pokemon_count <= 1
pbMessage(_INTL("Can't deposit the last Pokémon!"))
next
end
pbPlayDecisionSE
pbFadeOutIn do
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.pbStartScreen(2)
end
else
break
end
end
next false
}
})
MenuHandlers.add(:pc_menu, :player_pc, {
"name" => proc { next _INTL("{1}'s PC", $player.name) },
"order" => 20,
"effect" => proc { |menu|
pbMessage("\\se[PC access]" + _INTL("Accessed {1}'s PC.", $player.name))
UI::PC.pbTrainerPCMenu
next false
}
})
MenuHandlers.add(:pc_menu, :close, {
"name" => _INTL("Log off"),
"order" => 999,
"effect" => proc { |menu|
next true
}
})
#===============================================================================
#
#===============================================================================
def pbPokeCenterPC
UI::PC.pbPokeCenterPC
end

View File

@@ -76,6 +76,10 @@ class UI::MartVisualsList < Window_DrawableCommand
@expensive_shadow_color = value
end
def expensive?(this_item)
return @stock.buy_price(this_item) > $player.money
end
#-----------------------------------------------------------------------------
# This draws all the visible options first, and then draws the cursor.
@@ -106,7 +110,7 @@ class UI::MartVisualsList < Window_DrawableCommand
price = @stock.buy_price_string(this_item)
price_width = self.contents.text_size(price).width
price_x = rect.x + rect.width - price_width - 2 - 16
expensive = @stock.buy_price(this_item) > $player.money
expensive = expensive?(this_item)
price_base_color = (expensive) ? @expensive_base_color || self.baseColor : self.baseColor
price_shadow_color = (expensive) ? @expensive_shadow_color || self.shadowColor : self.shadowColor
textpos.push([price, price_x, ypos + 2, :left, price_base_color, price_shadow_color])
@@ -158,7 +162,7 @@ class UI::MartVisuals < UI::BaseVisuals
@sprites[:item_icon] = ItemIconSprite.new(48, Graphics.height - 48, nil, @viewport)
# Selected item's description text box
@sprites[:item_description] = Window_UnformattedTextPokemon.newWithSize(
"", 76 + 4, 272, Graphics.width - 98, 128, @viewport
"", 80, 272, Graphics.width - 98, 128, @viewport
)
@sprites[:item_description].baseColor = TEXT_COLOR_THEMES[:white][0]
@sprites[:item_description].shadowColor = TEXT_COLOR_THEMES[:white][1]
@@ -220,76 +224,6 @@ class UI::MartVisuals < UI::BaseVisuals
#-----------------------------------------------------------------------------
def choose_item_quantity(help_text, price_per_unit, maximum, init_value = 1)
@sprites[:speech_box].visible = true
@sprites[:speech_box].text = help_text
pbBottomLeftLines(@sprites[:speech_box], 2)
# Show the help text
loop do
Graphics.update
Input.update
update_visuals
if @sprites[:speech_box].busy?
if Input.trigger?(Input::USE)
pbPlayDecisionSE if @sprites[:speech_box].pausing?
@sprites[:speech_box].resume
end
else
break
end
end
# Choose a quantity
item_price = price_per_unit
quantity = init_value
using(num_window = Window_AdvancedTextPokemon.newWithSize(
_INTL("×{1}<r>${2}", quantity, (quantity * item_price).to_s_formatted),
0, 0, 224, 64, @viewport)) do
num_window.z = 2000
num_window.visible = true
num_window.letterbyletter = false
num_window.baseColor = TEXT_COLOR_THEMES[:black][0]
num_window.shadowColor = TEXT_COLOR_THEMES[:black][1]
pbBottomRight(num_window)
num_window.y -= @sprites[:speech_box].height
loop do
Graphics.update
Input.update
update
num_window.update
# Change quantity
old_quantity = quantity
if Input.repeat?(Input::LEFT)
quantity = [quantity - 10, 1].max
elsif Input.repeat?(Input::RIGHT)
quantity = [quantity + 10, maximum].min
elsif Input.repeat?(Input::UP)
quantity += 1
quantity = 1 if quantity > maximum
elsif Input.repeat?(Input::DOWN)
quantity -= 1
quantity = maximum if quantity < 1
end
if quantity != old_quantity
num_window.text = _INTL("×{1}<r>${2}", quantity, (quantity * item_price).to_s_formatted)
pbPlayCursorSE
end
# Finish choosing a quantity
if Input.trigger?(Input::USE)
pbPlayDecisionSE
break
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
quantity = 0
break
end
end
end
@sprites[:speech_box].visible = false
return quantity
end
#-----------------------------------------------------------------------------
def refresh
refresh_item_list
refresh_selected_item
@@ -372,11 +306,15 @@ class UI::Mart < UI::BaseScreen
def initialize(stock, bag)
pbScrollMap(6, 5, 5) # Direction 6 (right), 5 tiles, speed 5 (cycling speed, 10 tiles/second)
@stock = UI::MartStockWrapper.new(stock)
@bag = bag
initialize_stock(stock)
super()
end
def initialize_stock(stock)
@stock = UI::MartStockWrapper.new(stock)
end
def initialize_visuals
@visuals = UI::MartVisuals.new(@stock, @bag)
end
@@ -398,12 +336,6 @@ class UI::Mart < UI::BaseScreen
return nil if @visuals.item.nil?
return GameData::Item.get(@visuals.item)
end
#-----------------------------------------------------------------------------
def choose_item_quantity(help_text, price_per_unit, maximum, init_value = 1)
return @visuals.choose_item_quantity(help_text, price_per_unit, maximum, init_value)
end
end
#===============================================================================
@@ -423,26 +355,26 @@ UIActionHandlers.add(UI::Mart::SCREEN_ID, :interact, {
if item.is_important?
quantity = 1
next if !screen.show_confirm_message(
_INTL("So you want the {1}?\nIt'll be {2}. All right?",
item.portion_name, screen.stock.buy_price_string(item.id))
_INTL("So you want the {1}?\nIt'll be ${2}. All right?",
item.portion_name, item_price.to_s_formatted)
)
else
max_quantity = (item_price <= 0) ? PokemonBag::MAX_PER_SLOT : $player.money / item_price
max_quantity = [max_quantity, PokemonBag::MAX_PER_SLOT].min
quantity = screen.choose_item_quantity(
_INTL("So how many {1}?", item.portion_name_plural), item_price, max_quantity
quantity = screen.choose_number_as_money_multiplier(
_INTL("How many {1} would you like?", item.portion_name_plural), item_price, max_quantity
)
next if quantity == 0
item_price *= quantity
if quantity > 1
next if !screen.show_confirm_message(
_INTL("So you want {1} {2}?\nThey'll be {3}. All right?",
quantity, item.portion_name_plural, screen.stock.buy_price_string(item.id))
_INTL("So you want {1} {2}?\nThey'll be ${3}. All right?",
quantity, item.portion_name_plural, item_price.to_s_formatted)
)
elsif quantity > 0
next if !screen.show_confirm_message(
_INTL("So you want {1} {2}?\nIt'll be {3}. All right?",
quantity, item.portion_name, screen.stock.buy_price_string(item.id))
_INTL("So you want {1} {2}?\nIt'll be ${3}. All right?",
quantity, item.portion_name, item_price.to_s_formatted)
)
end
end
@@ -514,74 +446,6 @@ class UI::BagSellVisuals < UI::BagVisuals
@sprites[:unit_price_window].visible = true
end
def choose_item_quantity(help_text, price_per_unit, maximum, init_value = 1)
@sprites[:speech_box].visible = true
@sprites[:speech_box].text = help_text
pbBottomLeftLines(@sprites[:speech_box], 2)
# Show the help text
loop do
Graphics.update
Input.update
update_visuals
if @sprites[:speech_box].busy?
if Input.trigger?(Input::USE)
pbPlayDecisionSE if @sprites[:speech_box].pausing?
@sprites[:speech_box].resume
end
else
break
end
end
# Choose a quantity
item_price = price_per_unit
quantity = init_value
using(num_window = Window_AdvancedTextPokemon.newWithSize(
_INTL("×{1}<r>${2}", quantity, (quantity * item_price).to_s_formatted),
0, 0, 224, 64, @viewport)) do
num_window.z = 2000
num_window.visible = true
num_window.letterbyletter = false
num_window.baseColor = TEXT_COLOR_THEMES[:black][0]
num_window.shadowColor = TEXT_COLOR_THEMES[:black][1]
pbBottomRight(num_window)
num_window.y -= @sprites[:speech_box].height
loop do
Graphics.update
Input.update
update
num_window.update
# Change quantity
old_quantity = quantity
if Input.repeat?(Input::LEFT)
quantity = [quantity - 10, 1].max
elsif Input.repeat?(Input::RIGHT)
quantity = [quantity + 10, maximum].min
elsif Input.repeat?(Input::UP)
quantity += 1
quantity = 1 if quantity > maximum
elsif Input.repeat?(Input::DOWN)
quantity -= 1
quantity = maximum if quantity < 1
end
if quantity != old_quantity
num_window.text = _INTL("×{1}<r>${2}", quantity, (quantity * item_price).to_s_formatted)
pbPlayCursorSE
end
# Finish choosing a quantity
if Input.trigger?(Input::USE)
pbPlayDecisionSE
break
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
quantity = 0
break
end
end
end
@sprites[:speech_box].visible = false
return quantity
end
def refresh
super
@sprites[:money_window].text = _INTL("Money:\n<r>${1}", $player.money.to_s_formatted)
@@ -619,10 +483,6 @@ class UI::BagSell < UI::Bag
@visuals = UI::BagSellVisuals.new(@bag, @stock, mode: @mode)
end
def choose_item_quantity(help_text, price_per_unit, maximum, init_value = 1)
return @visuals.choose_item_quantity(help_text, price_per_unit, maximum, init_value)
end
def sell_items
choose_item do |item|
item_data = GameData::Item.get(item)
@@ -637,7 +497,7 @@ class UI::BagSell < UI::Bag
# Choose a quantity of the item to sell
quantity = @bag.quantity(item)
if quantity > 1
quantity = choose_item_quantity(
quantity = choose_number_as_money_multiplier(
_INTL("How many {1} would you like to sell?", item_name_plural), price, quantity
)
end
@@ -663,24 +523,22 @@ end
#
#===============================================================================
def pbPokemonMart(stock, speech = nil, cannot_sell = false)
commands = []
cmdBuy = -1
cmdSell = -1
cmdQuit = -1
commands[cmdBuy = commands.length] = _INTL("I'm here to buy")
commands[cmdSell = commands.length] = _INTL("I'm here to sell") if !cannot_sell
commands[cmdQuit = commands.length] = _INTL("No, thanks")
cmd = pbMessage(speech || _INTL("Welcome! How may I help you?"), commands, cmdQuit + 1)
commands = {}
commands[:buy] = _INTL("I'm here to buy")
commands[:sell] = _INTL("I'm here to sell") if !cannot_sell
commands[:cancel] = _INTL("No, thanks")
cmd = pbMessage(speech || _INTL("Welcome! How may I help you?"), commands.values, commands.length)
loop do
if cmdBuy >= 0 && cmd == cmdBuy
case commands.keys[cmd]
when :buy
UI::Mart.new(stock, $bag).main
elsif cmdSell >= 0 && cmd == cmdSell
when :sell
pbFadeOutIn { UI::BagSell.new($bag).sell_items }
else
pbMessage(_INTL("Do come again!"))
break
end
cmd = pbMessage(_INTL("Is there anything else I can do for you?"), commands, cmdQuit + 1)
cmd = pbMessage(_INTL("Is there anything else I can do for you?"), commands.values, commands.length, nil, cmd)
end
$game_temp.clear_mart_prices
end

View File

@@ -0,0 +1,205 @@
#===============================================================================
#
#===============================================================================
class UI::BPShopStockWrapper < UI::MartStockWrapper
def buy_price(item)
return 0 if item.nil?
if $game_temp.mart_prices && $game_temp.mart_prices[item]
return $game_temp.mart_prices[item][0] if $game_temp.mart_prices[item][0] > 0
end
return GameData::Item.get(item).bp_price
end
def buy_price_string(item)
price = buy_price(item)
return _INTL("{1} BP", price.to_s_formatted)
end
end
#===============================================================================
# Pokémon Mart.
#===============================================================================
class UI::BPShopVisualsList < UI::MartVisualsList
def expensive?(this_item)
return @stock.buy_price(this_item) > $player.battle_points
end
end
#===============================================================================
#
#===============================================================================
class UI::BPShopVisuals < UI::MartVisuals
def initialize_item_list
@sprites[:item_list] = UI::BPShopVisualsList.new(@stock, 152, 10, 374, 38 + (ITEMS_VISIBLE * 32), @viewport)
@sprites[:item_list].expensive_base_color = TEXT_COLOR_THEMES[:expensive][0]
@sprites[:item_list].expensive_shadow_color = TEXT_COLOR_THEMES[:expensive][1]
@sprites[:item_list].active = false
end
#-----------------------------------------------------------------------------
# Like the one in class BaseVisuals, but shows the money as BP instead of $.
def choose_number_as_money_multiplier(help_text, money_per_unit, maximum, init_value = 1)
@sprites[:speech_box].visible = true
@sprites[:speech_box].text = help_text
pbBottomLeftLines(@sprites[:speech_box], 2)
# Show the help text
loop do
Graphics.update
Input.update
update_visuals
if @sprites[:speech_box].busy?
if Input.trigger?(Input::USE)
pbPlayDecisionSE if @sprites[:speech_box].pausing?
@sprites[:speech_box].resume
end
else
break
end
end
# Choose a quantity
item_price = money_per_unit
quantity = init_value
using(num_window = Window_AdvancedTextPokemon.newWithSize(
_INTL("×{1}<r>{2} BP", quantity, (quantity * item_price).to_s_formatted),
0, 0, 224, 64, @viewport)) do
num_window.z = 2000
num_window.visible = true
num_window.letterbyletter = false
pbBottomRight(num_window)
num_window.y -= @sprites[:speech_box].height
loop do
Graphics.update
Input.update
update
num_window.update
# Change quantity
old_quantity = quantity
if Input.repeat?(Input::LEFT)
quantity = [quantity - 10, 1].max
elsif Input.repeat?(Input::RIGHT)
quantity = [quantity + 10, maximum].min
elsif Input.repeat?(Input::UP)
quantity += 1
quantity = 1 if quantity > maximum
elsif Input.repeat?(Input::DOWN)
quantity -= 1
quantity = maximum if quantity < 1
end
if quantity != old_quantity
num_window.text = _INTL("×{1}<r>{2} BP", quantity, (quantity * item_price).to_s_formatted)
pbPlayCursorSE
end
# Finish choosing a quantity
if Input.trigger?(Input::USE)
pbPlayDecisionSE
break
elsif Input.trigger?(Input::BACK)
pbPlayCancelSE
quantity = 0
break
end
end
end
@sprites[:speech_box].visible = false
return quantity
end
#-----------------------------------------------------------------------------
def refresh_money_window
@sprites[:money_window].text = _INTL("BP:\n<r>{1}", $player.battle_points.to_s_formatted)
end
end
#===============================================================================
#
#===============================================================================
class UI::BPShop < UI::Mart
SCREEN_ID = :bp_shop
def initialize_stock(stock)
@stock = UI::BPShopStockWrapper.new(stock)
end
def initialize_visuals
@visuals = UI::BPShopVisuals.new(@stock, @bag)
end
end
#===============================================================================
#
#===============================================================================
UIActionHandlers.add(UI::BPShop::SCREEN_ID, :interact, {
:effect => proc { |screen|
item = screen.item
item_price = screen.stock.buy_price(item)
# Check affordability
if $player.battle_points < item_price
screen.show_message(_INTL("I'm sorry, you don't have enough BP."))
next
end
# Choose how many of the item to buy
quantity = 0
if item.is_important?
quantity = 1
next if !screen.show_confirm_message(
_INTL("You would like the {1}?\nThat will be {2} BP.",
item.portion_name, item_price.to_s_formatted)
)
else
max_quantity = (item_price <= 0) ? PokemonBag::MAX_PER_SLOT : $player.battle_points / item_price
max_quantity = [max_quantity, PokemonBag::MAX_PER_SLOT].min
quantity = screen.choose_number_as_money_multiplier(
_INTL("How many {1} would you like?", item.portion_name_plural), item_price, max_quantity
)
next if quantity == 0
item_price *= quantity
if quantity > 1
next if !screen.show_confirm_message(
_INTL("You would like {1} {2}?\nThey'll be {3} BP.",
quantity, item.portion_name_plural, item_price.to_s_formatted)
)
elsif quantity > 0
next if !screen.show_confirm_message(
_INTL("You would like {1} {2}?\nThat will be {3} BP.",
quantity, item.portion_name, item_price.to_s_formatted)
)
end
end
# Check affordability (should always be possible, but just make sure)
if $player.battle_points < item_price
screen.show_message(_INTL("I'm sorry, you don't have enough BP."))
next
end
# Check the item can be put in the Bag
if !screen.bag.can_add?(item.id, quantity)
screen.show_message(_INTL("You have no room in your Bag."))
next
end
# Add the bought item(s)
screen.bag.add(item.id, quantity)
$stats.battle_points_spent += item_price
$stats.mart_items_bought += quantity
$player.battle_points -= item_price
screen.stock.refresh
screen.refresh
screen.show_message(_INTL("Here you are! Thank you!")) { pbSEPlay("Mart buy item") }
}
})
#===============================================================================
#
#===============================================================================
def pbBattlePointShop(stock, speech = nil)
if speech.nil?
pbMessage(_INTL("Welcome to the Exchange Service Corner!"))
pbMessage(_INTL("We can exchange your BP for fabulous items."))
else
pbMessage(speech)
end
UI::BPShop.new(stock, $bag).main
pbMessage(_INTL("Thank you for visiting."))
pbMessage(_INTL("Please visit us again when you have saved up more BP."))
$game_temp.clear_mart_prices
end