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

@@ -565,12 +565,13 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
elsif @textchars[@curchar] == "\1"
@pausing = true if @curchar < @numtextchars - 1
self.startPause
refresh
end
refresh
end
end
end
# TODO: Why is this called 4 times per loop in pbMessageDisplay?
def update
super
@pausesprite.update if @pausesprite&.visible
@@ -602,8 +603,8 @@ class Window_AdvancedTextPokemon < SpriteWindow_Base
ret = true
@curchar += 1
break if @textchars[@curchar] == "\n" || # newline
@textchars[@curchar] == "\1" || # pause
@textchars[@curchar] == "\2" || # letter-by-letter break
@textchars[@curchar] == "\1" || # pause: "\!"
@textchars[@curchar] == "\2" || # letter-by-letter break: "\wt[]", "\wtnp[]", "\.", "\|"
@textchars[@curchar].nil?
end
return ret

View File

@@ -163,7 +163,7 @@ class Battle::Scene
commands[:send_to_boxes] = _INTL("Send to Boxes") if mode == 1
commands[:summary] = _INTL("Summary")
commands[:cancel] = _INTL("Cancel")
choice = screen.show_choice_message(_INTL("Do what with {1}?", pkmn.name), commands)
choice = screen.show_menu(_INTL("Do what with {1}?", pkmn.name), commands)
next canCancel if choice.nil?
case choice
when :switch_in, :send_to_boxes
@@ -220,7 +220,7 @@ class Battle::Scene
commands = []
commands[cmdUse = commands.length] = _INTL("Use") if useType && useType != 0
commands[commands.length] = _INTL("Cancel")
command = bag_screen.show_choice_message(_INTL("{1} is selected.", itemName), commands)
command = bag_screen.show_menu(_INTL("{1} is selected.", itemName), commands)
next unless cmdUse >= 0 && command == cmdUse # Use
# Use types:
# 0 = not usable in battle

View File

@@ -24,7 +24,7 @@ class Battle::Peer
end
def pbGetStorageCreatorName
return pbGetStorageCreator if $player.seen_storage_creator
return UI::PC.pbGetStorageCreator if $player.seen_storage_creator
return nil
end

View File

@@ -128,6 +128,26 @@ module ItemHandlers
end
end
#===============================================================================
#
#===============================================================================
def pbTopRightWindow(text, scene = nil)
window = Window_AdvancedTextPokemon.new(text)
window.width = 198
window.x = Graphics.width - window.width
window.y = 0
window.z = 99999
pbPlayDecisionSE
loop do
Graphics.update
Input.update
window.update
scene&.pbUpdate
break if Input.trigger?(Input::USE)
end
window.dispose
end
#===============================================================================
#
#===============================================================================
@@ -135,12 +155,273 @@ def pbCanRegisterItem?(item)
return ItemHandlers.hasUseInFieldHandler(item)
end
def pbCanUseOnPokemon?(item)
# Returns whether pkmn is able to have an item used on it.
def pbCanPokemonHaveItemUsedOnIt?(pkmn, item)
return pkmn && !pkmn.egg? && (!pkmn.hyper_mode || GameData::Item.get(item)&.is_scent?)
end
# Used to filter the Bag when choosing an item to use on a party Pokémon.
# Also used in the Bag to indicate which party Pokémon the selected item is
# usable on.
def pbCanUseItemOnPokemon?(item)
return ItemHandlers.hasUseOnPokemon(item) ||
ItemHandlers.hasUsableOnPokemon(item) ||
GameData::Item.get(item).is_machine?
end
# This method assumes the item is usable on a Pokémon. It returns whether the
# item will have an effect when used on pkmn, i.e. it won't have no effect.
# Used in the Bag to indicate which party Pokémon the selected item is usable
# on.
def pbItemHasEffectOnPokemon?(item, pkmn)
return false if !pbCanPokemonHaveItemUsedOnIt?(pkmn, item)
ret = ItemHandlers.triggerUsableOnPokemon(item, pkmn)
return ret
end
#===============================================================================
# Use an item from the Bag and/or on a Pokémon.
#===============================================================================
# Called from the Bag screen and also when prompted to use a Repel when one runs
# out (bag_screen will be nil for the latter).
# @return [Integer] 0 = item wasn't used; 1 = item used; 2 = close Bag to use in field
def pbUseItem(bag, item, bag_screen = nil)
item_data = GameData::Item.get(item)
useType = item_data.field_use
if useType == 1 # Item is usable on a Pokémon
if $player.pokemon_count == 0
pbMessage(_INTL("There is no Pokémon."))
return 0
end
ret = false
annot = nil
if item_data.is_evolution_stone?
annot = []
$player.party.each do |pkmn|
elig = pkmn.check_evolution_on_use_item(item)
annot.push((elig) ? _INTL("ABLE") : _INTL("NOT ABLE"))
end
end
pbFadeOutIn do
screen = UI::Party.new($player.party, mode: :use_item)
if item_data.is_evolution_stone?
screen.set_able_annotation_proc(proc { |pkmn| next pkmn.check_evolution_on_use_item(item) })
end
screen.choose_pokemon do |pkmn, party_index|
next true if party_index < 0
next false if !pbCanPokemonHaveItemUsedOnIt?(pkmn, item)
qty = 1
max_at_once = ItemHandlers.triggerUseOnPokemonMaximum(item, pkmn)
max_at_once = [max_at_once, bag.quantity(item)].min
if max_at_once > 1
pbPlayDecisionSE
qty = screen.choose_number(
_INTL("How many {1} do you want to use?", GameData::Item.get(item).portion_name_plural), max_at_once
)
screen.set_help_text("")
end
next false if qty <= 0
ret = ItemHandlers.triggerUseOnPokemon(item, qty, pkmn, screen)
if ret && item_data.consumed_after_use?
bag.remove(item, qty)
if !bag.has?(item)
screen.show_message(_INTL("You used your last {1}.", item_data.portion_name))
next true
end
end
next false
end
bag_screen&.pbRefresh
end
return (ret) ? 1 : 0
elsif useType == 2 || item_data.is_machine? # Item is usable from Bag or teaches a move
intret = ItemHandlers.triggerUseFromBag(item, bag_screen)
if intret >= 0
bag.remove(item) if intret == 1 && item_data.consumed_after_use?
return intret
end
pbMessage(_INTL("Can't use that here."))
return 0
end
pbMessage(_INTL("Can't use that here."))
return 0
end
# Only called when in the party screen and having chosen an item to be used on
# the selected Pokémon.
# TODO: Replace all pbMessage and so on in here. scene is the party screen.
def pbUseItemOnPokemon(item, pkmn, scene)
item_data = GameData::Item.get(item)
# TM or HM
if item_data.is_machine?
machine = item_data.move
return false if !machine
movename = GameData::Move.get(machine).name
if pkmn.shadowPokemon?
pbMessage(_INTL("Shadow Pokémon can't be taught any moves.")) { scene.pbUpdate }
elsif !pkmn.compatible_with_move?(machine)
pbMessage(_INTL("{1} can't learn {2}.", pkmn.name, movename)) { scene.pbUpdate }
else
pbMessage("\\se[PC access]" + _INTL("You booted up the {1}.", item_data.portion_name) + "\1") { scene.pbUpdate }
if pbConfirmMessage(_INTL("Do you want to teach {1} to {2}?", movename, pkmn.name)) { scene.pbUpdate }
if pbLearnMove(pkmn, machine, false, true) { scene.pbUpdate }
$bag.remove(item) if item_data.consumed_after_use?
return true
end
end
end
return false
end
# Other item
qty = 1
max_at_once = ItemHandlers.triggerUseOnPokemonMaximum(item, pkmn)
max_at_once = [max_at_once, $bag.quantity(item)].min
if max_at_once > 1
qty = scene.scene.pbChooseNumber(
_INTL("How many {1} do you want to use?", item_data.portion_name_plural), max_at_once
)
scene.set_help_text("") if scene.is_a?(UI::Party)
end
return false if qty <= 0
ret = ItemHandlers.triggerUseOnPokemon(item, qty, pkmn, scene)
scene.clear_annotations
scene.refresh
if ret && item_data.consumed_after_use?
$bag.remove(item, qty)
if !$bag.has?(item)
pbMessage(_INTL("You used your last {1}.", item_data.portion_name)) { scene.pbUpdate }
end
end
return ret
end
def pbUseKeyItemInField(item)
ret = ItemHandlers.triggerUseInField(item)
if ret == -1 # Item effect not found
pbMessage(_INTL("Can't use that here."))
elsif ret > 0 && GameData::Item.get(item).consumed_after_use?
$bag.remove(item)
end
return ret > 0
end
def pbUseItemMessage(item)
itemname = GameData::Item.get(item).portion_name
if itemname.starts_with_vowel?
pbMessage(_INTL("You used an {1}.", itemname))
else
pbMessage(_INTL("You used a {1}.", itemname))
end
end
#===============================================================================
# Give an item to a Pokémon to hold, and take a held item from a Pokémon.
#===============================================================================
# TODO: Replace all pbDisplay and so on in here.
def pbGiveItemToPokemon(item, pkmn, scene, pkmnid = 0)
return false if item.nil?
newitemname = GameData::Item.get(item).portion_name
if pkmn.egg?
scene.pbDisplay(_INTL("Eggs can't hold items."))
return false
elsif pkmn.mail
scene.pbDisplay(_INTL("{1}'s mail must be removed before giving it an item.", pkmn.name))
return false if !pbTakeItemFromPokemon(pkmn, scene)
end
if pkmn.hasItem?
olditemname = pkmn.item.portion_name
if olditemname.starts_with_vowel?
scene.pbDisplay(_INTL("{1} is already holding an {2}.", pkmn.name, olditemname) + "\1")
else
scene.pbDisplay(_INTL("{1} is already holding a {2}.", pkmn.name, olditemname) + "\1")
end
if scene.pbConfirm(_INTL("Would you like to switch the two items?"))
$bag.remove(item)
if !$bag.add(pkmn.item)
raise _INTL("Couldn't re-store deleted item in Bag somehow") if !$bag.add(item)
scene.pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed."))
elsif GameData::Item.get(item).is_mail?
if pbWriteMail(item, pkmn, pkmnid, scene)
pkmn.item = item
scene.pbDisplay(_INTL("Took the {1} from {2} and gave it the {3}.", olditemname, pkmn.name, newitemname))
return true
elsif !$bag.add(item)
raise _INTL("Couldn't re-store deleted item in Bag somehow")
end
else
pkmn.item = item
scene.pbDisplay(_INTL("Took the {1} from {2} and gave it the {3}.", olditemname, pkmn.name, newitemname))
return true
end
end
elsif !GameData::Item.get(item).is_mail? || pbWriteMail(item, pkmn, pkmnid, scene)
$bag.remove(item)
pkmn.item = item
scene.pbDisplay(_INTL("{1} is now holding the {2}.", pkmn.name, newitemname))
return true
end
return false
end
# TODO: Replace all pbDisplay and so on in here.
def pbTakeItemFromPokemon(pkmn, scene)
ret = false
if !pkmn.hasItem?
scene.pbDisplay(_INTL("{1} isn't holding anything.", pkmn.name))
elsif !$bag.can_add?(pkmn.item)
scene.pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed."))
elsif pkmn.mail
if scene.pbConfirm(_INTL("Save the removed mail in your PC?"))
if pbMoveToMailbox(pkmn)
pkmn.item = nil
scene.pbDisplay(_INTL("The mail was saved in your PC."))
ret = true
else
scene.pbDisplay(_INTL("Your PC's Mailbox is full."))
end
elsif scene.pbConfirm(_INTL("If the mail is removed, its message will be lost. OK?"))
item_name = pkmn.item.portion_name
$bag.add(pkmn.item)
pkmn.item = nil
scene.pbDisplay(_INTL("Received the {1} from {2}.", item_name, pkmn.name))
ret = true
end
else
item_name = pkmn.item.portion_name
$bag.add(pkmn.item)
pkmn.item = nil
scene.pbDisplay(_INTL("Received the {1} from {2}.", item_name, pkmn.name))
ret = true
end
return ret
end
#===============================================================================
# Choose an item from a given list. Only lets you choose an item you have at
# least 1 of in the Bag. The chosen item's ID is stored in the given Game
# Variable.
#===============================================================================
def pbChooseItemFromList(message, variable, *args)
commands = {}
args.each do |item|
item_data = GameData::Item.try_get(item)
next if !item_data || !$bag.has?(item_data.id)
commands[item_data.id] = item_data.name
end
if commands.length == 0
$game_variables[variable] = :NONE
return nil
end
commands[:NONE] = _INTL("Cancel")
ret = pbMessage(message, commands.values, -1)
if ret < 0 || ret >= commands.length - 1
$game_variables[variable] = :NONE
return nil
end
$game_variables[variable] = commands.keys[ret] || :NONE
return commands.keys[ret]
end
#===============================================================================
# Change a Pokémon's level.
#===============================================================================
@@ -218,23 +499,9 @@ def pbChangeLevel(pkmn, new_level, scene)
end
end
def pbTopRightWindow(text, scene = nil)
window = Window_AdvancedTextPokemon.new(text)
window.width = 198
window.x = Graphics.width - window.width
window.y = 0
window.z = 99999
pbPlayDecisionSE
loop do
Graphics.update
Input.update
window.update
scene&.pbUpdate
break if Input.trigger?(Input::USE)
end
window.dispose
end
#===============================================================================
# Change a Pokémon's Experience amount.
#===============================================================================
def pbChangeExp(pkmn, new_exp, scene)
new_exp = new_exp.clamp(0, pkmn.growth_rate.maximum_exp)
if pkmn.exp == new_exp
@@ -631,9 +898,6 @@ def pbLearnMove(pkmn, move, ignore_if_known = false, by_machine = false, screen
if by_machine && Settings::TAUGHT_MACHINES_KEEP_OLD_PP
pkmn.moves[move_index].pp = [old_move_pp, pkmn.moves[move_index].total_pp].min
end
# TODO: The last \\wt[16] is skipped in instant text speed. Or rather,
# the text after it is shown at the same time as the text before
# it, but the SE waits for that duration and then plays.
pbMessage(_INTL("1, 2, and...\\wt[16] ...\\wt[16] ...\\wt[16] Ta-da!") + "\\se[Battle ball drop]\1", &block)
pbMessage(_INTL("{1} forgot how to use {2}.\nAnd...", pkmn_name, old_move_name) + "\1", &block)
pbMessage("\\se[]" + _INTL("{1} learned {2}!", pkmn_name, move_name) + "\\se[Pkmn move learnt]", &block)
@@ -658,296 +922,3 @@ def pbForgetMove(pkmn, move_to_learn, screen = nil)
end
return ret
end
#===============================================================================
# Use an item from the Bag and/or on a Pokémon.
#===============================================================================
# Called from the Bag screen and also when prompted to use a Repel when one runs
# out (bag_scene will be nil for the latter).
# @return [Integer] 0 = item wasn't used; 1 = item used; 2 = close Bag to use in field
def pbUseItem(bag, item, bag_scene = nil)
itm = GameData::Item.get(item)
useType = itm.field_use
if useType == 1 # Item is usable on a Pokémon
if $player.pokemon_count == 0
pbMessage(_INTL("There is no Pokémon."))
return 0
end
ret = false
annot = nil
if itm.is_evolution_stone?
annot = []
$player.party.each do |pkmn|
elig = pkmn.check_evolution_on_use_item(item)
annot.push((elig) ? _INTL("ABLE") : _INTL("NOT ABLE"))
end
end
pbFadeOutIn do
screen = UI::Party.new($player.party, mode: :use_item)
if itm.is_evolution_stone?
screen.set_able_annotation_proc(proc { |pkmn| next pkmn.check_evolution_on_use_item(item) })
end
screen.choose_pokemon do |pkmn, party_index|
next true if party_index < 0
next false if !pbCheckUseOnPokemon(item, pkmn)
qty = 1
max_at_once = ItemHandlers.triggerUseOnPokemonMaximum(item, pkmn)
max_at_once = [max_at_once, bag.quantity(item)].min
if max_at_once > 1
pbPlayDecisionSE
qty = screen.choose_number(
_INTL("How many {1} do you want to use?", GameData::Item.get(item).portion_name_plural), max_at_once
)
screen.set_help_text("")
end
next false if qty <= 0
ret = ItemHandlers.triggerUseOnPokemon(item, qty, pkmn, screen)
if ret && itm.consumed_after_use?
bag.remove(item, qty)
if !bag.has?(item)
screen.show_message(_INTL("You used your last {1}.", itm.portion_name))
next true
end
end
next false
end
bag_scene&.pbRefresh
end
return (ret) ? 1 : 0
elsif useType == 2 || itm.is_machine? # Item is usable from Bag or teaches a move
intret = ItemHandlers.triggerUseFromBag(item, bag_scene)
if intret >= 0
bag.remove(item) if intret == 1 && itm.consumed_after_use?
return intret
end
pbMessage(_INTL("Can't use that here."))
return 0
end
pbMessage(_INTL("Can't use that here."))
return 0
end
# Only called when in the party screen and having chosen an item to be used on
# the selected Pokémon.
# TODO: Replace all pbMessage and so on in here. scene is the party screen.
def pbUseItemOnPokemon(item, pkmn, scene)
itm = GameData::Item.get(item)
# TM or HM
if itm.is_machine?
machine = itm.move
return false if !machine
movename = GameData::Move.get(machine).name
if pkmn.shadowPokemon?
pbMessage(_INTL("Shadow Pokémon can't be taught any moves.")) { scene.pbUpdate }
elsif !pkmn.compatible_with_move?(machine)
pbMessage(_INTL("{1} can't learn {2}.", pkmn.name, movename)) { scene.pbUpdate }
else
pbMessage("\\se[PC access]" + _INTL("You booted up the {1}.", itm.portion_name) + "\1") { scene.pbUpdate }
if pbConfirmMessage(_INTL("Do you want to teach {1} to {2}?", movename, pkmn.name)) { scene.pbUpdate }
if pbLearnMove(pkmn, machine, false, true) { scene.pbUpdate }
$bag.remove(item) if itm.consumed_after_use?
return true
end
end
end
return false
end
# Other item
qty = 1
max_at_once = ItemHandlers.triggerUseOnPokemonMaximum(item, pkmn)
max_at_once = [max_at_once, $bag.quantity(item)].min
if max_at_once > 1
qty = scene.scene.pbChooseNumber(
_INTL("How many {1} do you want to use?", itm.portion_name_plural), max_at_once
)
scene.set_help_text("") if scene.is_a?(UI::Party)
end
return false if qty <= 0
ret = ItemHandlers.triggerUseOnPokemon(item, qty, pkmn, scene)
scene.clear_annotations
scene.refresh
if ret && itm.consumed_after_use?
$bag.remove(item, qty)
if !$bag.has?(item)
pbMessage(_INTL("You used your last {1}.", itm.portion_name)) { scene.pbUpdate }
end
end
return ret
end
def pbUseKeyItemInField(item)
ret = ItemHandlers.triggerUseInField(item)
if ret == -1 # Item effect not found
pbMessage(_INTL("Can't use that here."))
elsif ret > 0 && GameData::Item.get(item).consumed_after_use?
$bag.remove(item)
end
return ret > 0
end
def pbUseItemMessage(item)
itemname = GameData::Item.get(item).portion_name
if itemname.starts_with_vowel?
pbMessage(_INTL("You used an {1}.", itemname))
else
pbMessage(_INTL("You used a {1}.", itemname))
end
end
# Returns whether pkmn is able to have an item used on it.
def pbCheckUseOnPokemon(item, pkmn)
return pkmn && !pkmn.egg? && (!pkmn.hyper_mode || GameData::Item.get(item)&.is_scent?)
end
# This method assumes the item is usable on a Pokémon. It returns whether the
# item will have an effect when used on pkmn.
def pbItemHasEffectOnPokemon?(item, pkmn)
return false if !pbCheckUseOnPokemon(item, pkmn)
ret = ItemHandlers.triggerUsableOnPokemon(item, pkmn)
return ret
end
#===============================================================================
# Give an item to a Pokémon to hold, and take a held item from a Pokémon.
#===============================================================================
# TODO: Replace all pbDisplay and so on in here.
def pbGiveItemToPokemon(item, pkmn, scene, pkmnid = 0)
return false if item.nil?
newitemname = GameData::Item.get(item).portion_name
if pkmn.egg?
scene.pbDisplay(_INTL("Eggs can't hold items."))
return false
elsif pkmn.mail
scene.pbDisplay(_INTL("{1}'s mail must be removed before giving it an item.", pkmn.name))
return false if !pbTakeItemFromPokemon(pkmn, scene)
end
if pkmn.hasItem?
olditemname = pkmn.item.portion_name
if olditemname.starts_with_vowel?
scene.pbDisplay(_INTL("{1} is already holding an {2}.", pkmn.name, olditemname) + "\1")
else
scene.pbDisplay(_INTL("{1} is already holding a {2}.", pkmn.name, olditemname) + "\1")
end
if scene.pbConfirm(_INTL("Would you like to switch the two items?"))
$bag.remove(item)
if !$bag.add(pkmn.item)
raise _INTL("Couldn't re-store deleted item in Bag somehow") if !$bag.add(item)
scene.pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed."))
elsif GameData::Item.get(item).is_mail?
if pbWriteMail(item, pkmn, pkmnid, scene)
pkmn.item = item
scene.pbDisplay(_INTL("Took the {1} from {2} and gave it the {3}.", olditemname, pkmn.name, newitemname))
return true
elsif !$bag.add(item)
raise _INTL("Couldn't re-store deleted item in Bag somehow")
end
else
pkmn.item = item
scene.pbDisplay(_INTL("Took the {1} from {2} and gave it the {3}.", olditemname, pkmn.name, newitemname))
return true
end
end
elsif !GameData::Item.get(item).is_mail? || pbWriteMail(item, pkmn, pkmnid, scene)
$bag.remove(item)
pkmn.item = item
scene.pbDisplay(_INTL("{1} is now holding the {2}.", pkmn.name, newitemname))
return true
end
return false
end
# TODO: Replace all pbDisplay and so on in here.
def pbTakeItemFromPokemon(pkmn, scene)
ret = false
if !pkmn.hasItem?
scene.pbDisplay(_INTL("{1} isn't holding anything.", pkmn.name))
elsif !$bag.can_add?(pkmn.item)
scene.pbDisplay(_INTL("The Bag is full. The Pokémon's item could not be removed."))
elsif pkmn.mail
if scene.pbConfirm(_INTL("Save the removed mail in your PC?"))
if pbMoveToMailbox(pkmn)
pkmn.item = nil
scene.pbDisplay(_INTL("The mail was saved in your PC."))
ret = true
else
scene.pbDisplay(_INTL("Your PC's Mailbox is full."))
end
elsif scene.pbConfirm(_INTL("If the mail is removed, its message will be lost. OK?"))
item_name = pkmn.item.portion_name
$bag.add(pkmn.item)
pkmn.item = nil
pkmn.mail = nil
scene.pbDisplay(_INTL("Received the {1} from {2}.", item_name, pkmn.name))
ret = true
end
else
item_name = pkmn.item.portion_name
$bag.add(pkmn.item)
pkmn.item = nil
scene.pbDisplay(_INTL("Received the {1} from {2}.", item_name, pkmn.name))
ret = true
end
return ret
end
#===============================================================================
# Choose an item from the Bag.
#===============================================================================
def pbChooseItem(var = 0, *args)
ret = nil
pbFadeOutIn do
bag_screen = UI::Bag.new($bag, mode: :choose_item)
ret = bag_screen.choose_item
end
$game_variables[var] = ret || :NONE if var > 0
return ret
end
def pbChooseApricorn(var = 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[var] = ret || :NONE if var > 0
return ret
end
def pbChooseFossil(var = 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[var] = ret || :NONE if var > 0
return ret
end
# Shows a list of items to choose from, with the chosen item's ID being stored
# in the given Game Variable. Only items which the player has are listed.
def pbChooseItemFromList(message, variable, *args)
commands = []
itemid = []
args.each do |item|
next if !GameData::Item.exists?(item)
itm = GameData::Item.get(item)
next if !$bag.has?(itm)
commands.push(itm.name)
itemid.push(itm.id)
end
if commands.length == 0
$game_variables[variable] = :NONE
return nil
end
commands.push(_INTL("Cancel"))
itemid.push(nil)
ret = pbMessage(message, commands, -1)
if ret < 0 || ret >= commands.length - 1
$game_variables[variable] = :NONE
return nil
end
$game_variables[variable] = itemid[ret] || :NONE
return itemid[ret]
end

View File

@@ -575,6 +575,7 @@ class Pokemon
def item=(value)
return if value && !GameData::Item.exists?(value)
@item = (value) ? GameData::Item.get(value).id : value
@mail = nil if @item.nil?
end
# Returns whether this Pokémon is holding an item. If an item id is passed,
@@ -608,6 +609,7 @@ class Pokemon
raise ArgumentError, _INTL("Invalid value {1} given", mail.inspect)
end
@mail = mail
@item = mail&.item
end
#-----------------------------------------------------------------------------

View File

@@ -91,7 +91,7 @@ class ItemStorage_Scene
@sprites["pocketwindow"].y = 16
pbSetNarrowFont(@sprites["pocketwindow"].bitmap)
# Item description
@sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize("", 76, 272, Graphics.width - 98, 128, @viewport)
@sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize("", 80, 272, Graphics.width - 98, 128, @viewport)
@sprites["itemtextwindow"].baseColor = ITEMTEXTBASECOLOR
@sprites["itemtextwindow"].shadowColor = ITEMTEXTSHADOWCOLOR
@sprites["itemtextwindow"].windowskin = nil

View File

@@ -1,268 +0,0 @@
#===============================================================================
#
#===============================================================================
def pbPCItemStorage
command = 0
loop do
command = pbShowCommandsWithHelp(nil,
[_INTL("Withdraw Item"),
_INTL("Deposit Item"),
_INTL("Toss Item"),
_INTL("Exit")],
[_INTL("Take out items from the PC."),
_INTL("Store items in the PC."),
_INTL("Throw away items stored in the PC."),
_INTL("Go back to the previous menu.")], -1, command)
case command
when 0 # Withdraw Item
$PokemonGlobal.pcItemStorage ||= PCItemStorage.new
if $PokemonGlobal.pcItemStorage.empty?
pbMessage(_INTL("There are no items."))
else
pbFadeOutIn do
scene = WithdrawItemScene.new
screen = ItemStorageScreen.new(scene, $bag)
screen.pbWithdrawItemScreen
end
end
when 1 # Deposit Item
$PokemonGlobal.pcItemStorage ||= PCItemStorage.new
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
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
end
next false
end
end
when 2 # Toss Item
$PokemonGlobal.pcItemStorage ||= PCItemStorage.new
if $PokemonGlobal.pcItemStorage.empty?
pbMessage(_INTL("There are no items."))
else
pbFadeOutIn do
scene = TossItemScene.new
screen = ItemStorageScreen.new(scene, $bag)
screen.pbTossItemScreen
end
end
else
break
end
end
end
#===============================================================================
#
#===============================================================================
def pbPCMailbox
if !$PokemonGlobal.mailbox || $PokemonGlobal.mailbox.length == 0
pbMessage(_INTL("There's no Mail here."))
else
loop do
command = 0
commands = []
$PokemonGlobal.mailbox.each do |mail|
commands.push(mail.sender)
end
commands.push(_INTL("Cancel"))
command = pbShowCommands(nil, commands, -1, command)
if command >= 0 && command < $PokemonGlobal.mailbox.length
mail_index = command
commandMail = pbMessage(
_INTL("What do you want to do with {1}'s Mail?", $PokemonGlobal.mailbox[mail_index].sender),
[_INTL("Read"),
_INTL("Move to Bag"),
_INTL("Give"),
_INTL("Cancel")], -1
)
case commandMail
when 0 # Read
pbFadeOutIn do
pbDisplayMail($PokemonGlobal.mailbox[mail_index])
end
when 1 # 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 2 # Give
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]
pkmn.item = pkmn.mail.item
$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
end
else
break
end
end
end
end
#===============================================================================
#
#===============================================================================
def pbTrainerPC
pbMessage("\\se[PC open]" + _INTL("{1} booted up the PC.", $player.name))
pbTrainerPCMenu
pbSEPlay("PC close")
end
def pbTrainerPCMenu
command = 0
loop do
command = pbMessage(_INTL("What do you want to do?"),
[_INTL("Item Storage"),
_INTL("Mailbox"),
_INTL("Turn Off")], -1, nil, command)
case command
when 0 then pbPCItemStorage
when 1 then pbPCMailbox
else break
end
end
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 pbGetStorageCreator
return GameData::Metadata.get.storage_creator
end
#===============================================================================
#
#===============================================================================
MenuHandlers.add(:pc_menu, :pokemon_storage, {
"name" => proc {
next ($player.seen_storage_creator) ? _INTL("{1}'s PC", pbGetStorageCreator) : _INTL("Someone's PC")
},
"order" => 10,
"effect" => proc { |menu|
pbMessage("\\se[PC access]" + _INTL("The Pokémon Storage System was opened."))
command = 0
loop do
command = pbShowCommandsWithHelp(nil,
[_INTL("Organize Boxes"),
_INTL("Withdraw Pokémon"),
_INTL("Deposit Pokémon"),
_INTL("See ya!")],
[_INTL("Organize the Pokémon in Boxes and in your party."),
_INTL("Move Pokémon stored in Boxes to your party."),
_INTL("Store Pokémon in your party in Boxes."),
_INTL("Return to the previous menu.")], -1, command)
break if command < 0
case command
when 0 # Organize
pbFadeOutIn do
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.pbStartScreen(0)
end
when 1 # Withdraw
if $PokemonStorage.party_full?
pbMessage(_INTL("Your party is full!"))
next
end
pbFadeOutIn do
scene = PokemonStorageScene.new
screen = PokemonStorageScreen.new(scene, $PokemonStorage)
screen.pbStartScreen(1)
end
when 2 # Deposit
count = 0
$PokemonStorage.party.each do |p|
count += 1 if p && !p.egg? && p.hp > 0
end
if count <= 1
pbMessage(_INTL("Can't deposit the last Pokémon!"))
next
end
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))
pbTrainerPCMenu
next false
}
})
MenuHandlers.add(:pc_menu, :close, {
"name" => _INTL("Log off"),
"order" => 100,
"effect" => proc { |menu|
next true
}
})

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

View File

@@ -724,7 +724,7 @@ class PokemonParty_Scene
screen = PokemonBagScreen.new(scene, bag)
ret = screen.pbChooseItemScreen(proc { |item|
itm = GameData::Item.get(item)
next false if !pbCanUseOnPokemon?(itm)
next false if !pbCanUseItemOnPokemon?(itm)
next false if pokemon.hyper_mode && !GameData::Item.get(item)&.is_scent?
if itm.is_machine?
move = itm.move

View File

@@ -1,3 +1,4 @@
=begin
#===============================================================================
#
#===============================================================================
@@ -703,3 +704,4 @@ class PokemonBagScreen
@scene.pbEndScene
end
end
=end

View File

@@ -1,3 +1,4 @@
=begin
#===============================================================================
# Abstraction layer for Pokemon Essentials.
#===============================================================================
@@ -504,22 +505,4 @@ class BattlePointShopScreen
@scene.pbEndScene
end
end
#===============================================================================
#
#===============================================================================
def pbBattlePointShop(stock, speech = nil)
stock.delete_if { |item| GameData::Item.get(item).is_important? && $bag.has?(item) }
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
scene = BattlePointShop_Scene.new
screen = BattlePointShopScreen.new(scene, stock)
screen.pbBuyScreen
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
=end

View File

@@ -445,6 +445,9 @@ def pbMoveTutorAnnotations(move, movelist = nil)
return ret
end
# TODO: The Bag screen needs passing into this method (if using a machine). If
# it exists, refresh it before finishing pbFadeOutIn to update the party
# compatibility icons.
def pbMoveTutorChoose(move, movelist = nil, by_machine = false, one_use_machine = false)
ret = false
move = GameData::Move.get(move).id

View File

@@ -632,8 +632,8 @@ MenuHandlers.add(:battle_pokemon_debug_menu, :set_item, {
end
when 1 # Remove item
if pkmn.hasItem?
(battler || pkmn).item = nil
pkmn.mail = nil
pkmn.item = nil
battler.item = nil if battler
end
else
break

View File

@@ -605,7 +605,6 @@ MenuHandlers.add(:pokemon_debug_menu, :set_item, {
when 1 # Remove item
if pkmn.hasItem?
pkmn.item = nil
pkmn.mail = nil
screen.pbRefreshSingle(pkmnid)
end
else