From 48292c2a28b6911de5492abd9f9d14cbf17487f7 Mon Sep 17 00:00:00 2001 From: Maruno17 Date: Thu, 26 Sep 2024 01:00:18 +0100 Subject: [PATCH] Increased max mone amount, rewrote Mart code, redesigned Mart and selling items a little --- Data/Scripts/001_Settings.rb | 2 +- Data/Scripts/016_UI/018_UI_ItemStorage.rb | 7 +- Data/Scripts/016b_UI redesign/000_UI_base.rb | 13 +- .../016b_UI redesign/020_UI_PokeMart.rb | 686 ++++++++++++++++++ .../020_UI_old_PokeMart.rb} | 104 ++- 5 files changed, 741 insertions(+), 71 deletions(-) create mode 100644 Data/Scripts/016b_UI redesign/020_UI_PokeMart.rb rename Data/Scripts/{016_UI/020_UI_PokeMart.rb => 016c_UI_old/020_UI_old_PokeMart.rb} (93%) diff --git a/Data/Scripts/001_Settings.rb b/Data/Scripts/001_Settings.rb index 121cc5295..7fb6b5de9 100644 --- a/Data/Scripts/001_Settings.rb +++ b/Data/Scripts/001_Settings.rb @@ -46,7 +46,7 @@ module Settings #----------------------------------------------------------------------------- # The maximum amount of money the player can have. - MAX_MONEY = 999_999 + MAX_MONEY = 9_999_999 # The maximum number of Game Corner coins the player can have. MAX_COINS = 99_999 # The maximum number of Battle Points the player can have. diff --git a/Data/Scripts/016_UI/018_UI_ItemStorage.rb b/Data/Scripts/016_UI/018_UI_ItemStorage.rb index 10d9ae95f..01dab8af9 100644 --- a/Data/Scripts/016_UI/018_UI_ItemStorage.rb +++ b/Data/Scripts/016_UI/018_UI_ItemStorage.rb @@ -16,7 +16,6 @@ class Window_PokemonItemStorage < Window_DrawableCommand def initialize(bag, x, y, width, height) @bag = bag @sortIndex = -1 - @adapter = PokemonMartAdapter.new super(x, y, width, height) self.windowskin = nil end @@ -37,7 +36,7 @@ class Window_PokemonItemStorage < Window_DrawableCommand textpos.push([_INTL("CANCEL"), rect.x, rect.y, :left, self.baseColor, self.shadowColor]) else item = @bag[index][0] - itemname = @adapter.getDisplayName(item) + itemname = GameData::Item.get(item).display_name baseColor = (index == @sortIndex) ? Color.new(248, 24, 24) : self.baseColor textpos.push([itemname, rect.x, rect.y, :left, self.baseColor, self.shadowColor]) if GameData::Item.get(item).show_quantity? @@ -78,7 +77,7 @@ class ItemStorage_Scene @sprites = {} @sprites["background"] = IconSprite.new(0, 0, @viewport) @sprites["background"].setBitmap("Graphics/UI/itemstorage_bg") - @sprites["icon"] = ItemIconSprite.new(50, 334, nil, @viewport) + @sprites["icon"] = ItemIconSprite.new(48, Graphics.height - 48, nil, @viewport) # Item list @sprites["itemwindow"] = Window_PokemonItemStorage.new(@bag, 98, 14, 334, 32 + (ITEMSVISIBLE * 32)) @sprites["itemwindow"].viewport = @viewport @@ -92,7 +91,7 @@ class ItemStorage_Scene @sprites["pocketwindow"].y = 16 pbSetNarrowFont(@sprites["pocketwindow"].bitmap) # Item description - @sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize("", 84, 272, Graphics.width - 84, 128, @viewport) + @sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize("", 76, 272, Graphics.width - 98, 128, @viewport) @sprites["itemtextwindow"].baseColor = ITEMTEXTBASECOLOR @sprites["itemtextwindow"].shadowColor = ITEMTEXTSHADOWCOLOR @sprites["itemtextwindow"].windowskin = nil diff --git a/Data/Scripts/016b_UI redesign/000_UI_base.rb b/Data/Scripts/016b_UI redesign/000_UI_base.rb index f17a6c56d..08518b771 100644 --- a/Data/Scripts/016b_UI redesign/000_UI_base.rb +++ b/Data/Scripts/016b_UI redesign/000_UI_base.rb @@ -385,6 +385,7 @@ module UI @sprites[:speech_box].visible = true @sprites[:speech_box].text = text pbBottomLeftLines(@sprites[:speech_box], 2) + yielded = false loop do Graphics.update Input.update @@ -394,8 +395,12 @@ module UI pbPlayDecisionSE if @sprites[:speech_box].pausing? @sprites[:speech_box].resume end - elsif Input.trigger?(Input::USE) || Input.trigger?(Input::BACK) - break + else + yield if !yielded && block_given? + yielded = true + if Input.trigger?(Input::USE) || Input.trigger?(Input::BACK) + break + end end end @sprites[:speech_box].visible = false @@ -603,8 +608,8 @@ module UI #----------------------------------------------------------------------------- - def show_message(text) - @visuals.show_message(text) + def show_message(text, &block) + @visuals.show_message(text, &block) end alias pbDisplay show_message diff --git a/Data/Scripts/016b_UI redesign/020_UI_PokeMart.rb b/Data/Scripts/016b_UI redesign/020_UI_PokeMart.rb new file mode 100644 index 000000000..60811c406 --- /dev/null +++ b/Data/Scripts/016b_UI redesign/020_UI_PokeMart.rb @@ -0,0 +1,686 @@ +#=============================================================================== +# +#=============================================================================== +class UI::MartStockWrapper + def initialize(stock) + @stock = stock + refresh + end + + def length + return @stock.length + end + + def [](index) + return @stock[index] + end + + 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).price + end + + def buy_price_string(item) + price = buy_price(item) + return _INTL("${1}", price.to_s_formatted) + end + + def sell_price(item) + return 0 if item.nil? + if $game_temp.mart_prices && $game_temp.mart_prices[item] + return $game_temp.mart_prices[item][1] if $game_temp.mart_prices[item][1] >= 0 + end + return GameData::Item.get(item).sell_price + end + + def refresh + @stock.delete_if { |itm| GameData::Item.get(itm).is_important? && $bag.has?(itm) } + end +end + +#=============================================================================== +# Pokémon Mart. +#=============================================================================== +class UI::MartVisualsList < Window_DrawableCommand + def initialize(stock, x, y, width, height, viewport = nil) + @stock = stock + super(x, y, width, height, viewport) + @selarrow = AnimatedBitmap.new(bag_folder + "cursor") + @baseColor = UI::MartVisuals::TEXT_COLOR_THEMES[:black][0] + @shadowColor = UI::MartVisuals::TEXT_COLOR_THEMES[:black][1] + self.windowskin = nil + end + + #----------------------------------------------------------------------------- + + def itemCount + return @stock.length + 1 # The extra 1 is the Cancel option + end + + def bag_folder + return UI::MartVisuals::UI_FOLDER + UI::MartVisuals::GRAPHICS_FOLDER + end + + def item_id + return (self.index >= @stock.length) ? nil : @stock[self.index] + end + + def expensive_base_color=(value) + @expensive_base_color = value + end + + def expensive_shadow_color=(value) + @expensive_shadow_color = value + end + + #----------------------------------------------------------------------------- + + # This draws all the visible options first, and then draws the cursor. + def refresh + @item_max = itemCount + update_cursor_rect + dwidth = self.width - self.borderX + dheight = self.height - self.borderY + self.contents = pbDoEnsureBitmap(self.contents, dwidth, dheight) + self.contents.clear + @item_max.times do |i| + next if i < self.top_item || i > self.top_item + self.page_item_max + drawItem(i, @item_max, itemRect(i)) + end + drawCursor(self.index, itemRect(self.index)) + end + + def drawItem(index, count, rect) + textpos = [] + rect = drawCursor(index, rect) + ypos = rect.y + this_item = @stock[index] + if this_item + # Draw item name + item_name = GameData::Item.get(this_item).display_name + textpos.push([item_name, rect.x, ypos + 2, :left, self.baseColor, self.shadowColor]) + # Draw item price + 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 + 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]) + else + textpos.push([_INTL("CANCEL"), rect.x, ypos + 2, :left, self.baseColor, self.shadowColor]) + end + pbDrawTextPositions(self.contents, textpos) + end +end + +#=============================================================================== +# +#=============================================================================== +class UI::MartVisuals < UI::BaseVisuals + attr_reader :sprites + attr_reader :pocket + + GRAPHICS_FOLDER = "Mart/" # Subfolder in Graphics/UI + TEXT_COLOR_THEMES = { # These color themes are added to @sprites[:overlay] + :default => [Color.new(248, 248, 248), Color.new(56, 56, 56)], # Base and shadow colour + :white => [Color.new(248, 248, 248), Color.new(56, 56, 56)], + :black => [Color.new(88, 88, 80), Color.new(168, 184, 184)], + :expensive => [Color.new(224, 0, 0), Color.new(248, 144, 144)] + } + ITEMS_VISIBLE = 7 + + def initialize(stock, bag) + @stock = stock + @bag = bag + super() + end + + def initialize_sprites + initialize_item_list + initialize_item_sprites + initialize_money_window + initialize_bag_quantity_window + end + + def initialize_item_list + @sprites[:item_list] = UI::MartVisualsList.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 + + def initialize_item_sprites + # Selected item's icon + @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 + ) + @sprites[:item_description].baseColor = TEXT_COLOR_THEMES[:white][0] + @sprites[:item_description].shadowColor = TEXT_COLOR_THEMES[:white][1] + @sprites[:item_description].visible = true + @sprites[:item_description].windowskin = nil + end + + def initialize_money_window + @sprites[:money_window] = Window_AdvancedTextPokemon.newWithSize("", 0, 0, 162, 96, @viewport) + @sprites[:money_window].setSkin("Graphics/Windowskins/goldskin") + @sprites[:money_window].baseColor = TEXT_COLOR_THEMES[:black][0] + @sprites[:money_window].shadowColor = TEXT_COLOR_THEMES[:black][1] + @sprites[:money_window].letterbyletter = false + @sprites[:money_window].visible = true + end + + def initialize_bag_quantity_window + @sprites[:bag_quantity_window] = Window_AdvancedTextPokemon.newWithSize( + _INTL("In Bag:{1}", @bag.quantity(item)), 0, 0, 162, 64, @viewport + ) + @sprites[:bag_quantity_window].setSkin("Graphics/Windowskins/goldskin") + @sprites[:bag_quantity_window].baseColor = TEXT_COLOR_THEMES[:black][0] + @sprites[:bag_quantity_window].shadowColor = TEXT_COLOR_THEMES[:black][1] + @sprites[:bag_quantity_window].letterbyletter = false + @sprites[:bag_quantity_window].visible = true + @sprites[:bag_quantity_window].y = Graphics.height - 102 - @sprites[:bag_quantity_window].height + end + + #----------------------------------------------------------------------------- + + def index + return @sprites[:item_list].index + end + + def set_index(value) + @sprites[:item_list].index = value + refresh_on_index_changed(nil) + end + + def item + return @sprites[:item_list].item_id + end + + def show_money_window + @sprites[:money_window].visible = true + end + + def hide_money_window + @sprites[:money_window].visible = false + end + + def show_bag_quantity_window + @sprites[:bag_quantity_window].visible = true + end + + def hide_bag_quantity_window + @sprites[:bag_quantity_window].visible = false + 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}${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}${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 + refresh_money_window + end + + def refresh_item_list + @sprites[:item_list].refresh + end + + def refresh_selected_item + selected_item = item + # Set the selected item's icon + @sprites[:item_icon].item = selected_item + # Set the selected item's description + if selected_item + @sprites[:item_description].text = GameData::Item.get(selected_item).description + else + @sprites[:item_description].text = _INTL("Quit shopping.") + end + refresh_bag_quantity_window + end + + def refresh_bag_quantity_window + @sprites[:bag_quantity_window].text = _INTL("In Bag:{1}", @bag.quantity(item)) + (item) ? show_bag_quantity_window : hide_bag_quantity_window + end + + def refresh_money_window + @sprites[:money_window].text = _INTL("Money:\n${1}", $player.money.to_s_formatted) + end + + def refresh_on_index_changed(old_index) + refresh_selected_item + end + + #----------------------------------------------------------------------------- + + def update_input + # Check for interaction + if Input.trigger?(Input::USE) + return update_interaction(Input::USE) + elsif Input.trigger?(Input::BACK) + return update_interaction(Input::BACK) + end + return nil + end + + def update_interaction(input) + case input + when Input::USE + if item + pbPlayDecisionSE + return :interact + end + pbPlayCloseMenuSE + return :quit + when Input::BACK + pbPlayCloseMenuSE + return :quit + end + return nil + end + + def navigate + @sprites[:item_list].active = true + ret = super + @sprites[:item_list].active = false + return ret + end +end + +#=============================================================================== +# +#=============================================================================== +class UI::Mart < UI::BaseScreen + attr_reader :stock, :bag + + SCREEN_ID = :mart_screen + + 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 + super() + end + + def initialize_visuals + @visuals = UI::MartVisuals.new(@stock, @bag) + end + + def start_screen + pbSEPlay("GUI menu open") + end + + def end_screen + return if @disposed + pbPlayCloseMenuSE + silent_end_screen + pbScrollMap(4, 5, 5) # Direction 4 (left), 5 tiles, speed 5 (cycling speed, 10 tiles/second) + end + + #----------------------------------------------------------------------------- + + def item + 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 + +#=============================================================================== +# +#=============================================================================== +UIActionHandlers.add(UI::Mart::SCREEN_ID, :interact, { + :effect => proc { |screen| + item = screen.item + item_price = screen.stock.buy_price(item) + # Check affordability + if $player.money < item_price + screen.show_message(_INTL("You don't have enough money.")) + 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("So you want the {1}?\nIt'll be {2}. All right?", + item.portion_name, screen.stock.buy_price_string(item.id)) + ) + 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 + ) + 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)) + ) + 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)) + ) + end + end + # Check affordability (should always be possible, but just make sure) + if $player.money < item_price + screen.show_message(_INTL("You don't have enough money.")) + 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.money_spent_at_marts += item_price + $stats.mart_items_bought += quantity + $player.money -= item_price + screen.stock.refresh + screen.refresh + screen.show_message(_INTL("Here you are! Thank you!")) { pbSEPlay("Mart buy item") } + # Give bonus Premier Ball(s) + if quantity >= 10 && item.is_poke_ball? && GameData::Item.exists?(:PREMIERBALL) + if Settings::MORE_BONUS_PREMIER_BALLS || item.id == :POKEBALL + premier_balls_earned = (Settings::MORE_BONUS_PREMIER_BALLS) ? (quantity / 10) : 1 + premier_balls_added = 0 + premier_balls_earned.times do + break if !screen.bag.add(:PREMIERBALL) + premier_balls_added += 1 + end + if premier_balls_added > 0 + $stats.premier_balls_earned += premier_balls_added + if premier_balls_added > 1 + ball_name = GameData::Item.get(:PREMIERBALL).portion_name_plural + else + ball_name = GameData::Item.get(:PREMIERBALL).portion_name + end + screen.show_message(_INTL("And have {1} {2} on the house!", premier_balls_added, ball_name)) + end + end + end + } +}) + +#=============================================================================== +# +#=============================================================================== +class UI::BagSellVisuals < UI::BagVisuals + def initialize(bag, stock, mode = :choose_item) + @stock = stock + super(bag, mode: mode) + end + + def initialize_sprites + super + @sprites[:money_window] = Window_AdvancedTextPokemon.newWithSize("", 0, 36, 184, 96, @viewport) + @sprites[:money_window].setSkin("Graphics/Windowskins/goldskin") + @sprites[:money_window].z = 2000 + @sprites[:money_window].baseColor = TEXT_COLOR_THEMES[:black][0] + @sprites[:money_window].shadowColor = TEXT_COLOR_THEMES[:black][1] + @sprites[:money_window].letterbyletter = false + @sprites[:money_window].visible = true + @sprites[:unit_price_window] = Window_AdvancedTextPokemon.newWithSize("", 0, 184, 184, 96, @viewport) + @sprites[:unit_price_window].setSkin("Graphics/Windowskins/goldskin") + @sprites[:unit_price_window].z = 2000 + @sprites[:unit_price_window].baseColor = TEXT_COLOR_THEMES[:black][0] + @sprites[:unit_price_window].shadowColor = TEXT_COLOR_THEMES[:black][1] + @sprites[:unit_price_window].letterbyletter = false + @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}${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}${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${1}", $player.money.to_s_formatted) + refresh_unit_price_window + end + + def refresh_input_indicators; end + + def refresh_unit_price_window + @sprites[:unit_price_window].visible = (!item.nil?) + return if item.nil? + price = @stock.sell_price(item) + if GameData::Item.get(item).is_important? || price == 0 + @sprites[:unit_price_window].text = _INTL("You can't sell this item.") + else + @sprites[:unit_price_window].text = _INTL("Price each:\n${1}", price.to_s_formatted) + end + end + + def refresh_on_index_changed(old_index) + refresh_unit_price_window + end +end + +#=============================================================================== +# +#=============================================================================== +class UI::BagSell < UI::Bag + def initialize(bag, mode: :choose_item) + @stock = UI::MartStockWrapper.new([]) + super(bag, mode: mode) + end + + def initialize_visuals + @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) + item_name = item_data.portion_name + item_name_plural = item_data.portion_name_plural + price = @stock.sell_price(item) + # Ensure item can be sold + if item_data.is_important? || price == 0 + show_message(_INTL("Oh, no. I can't buy {1}.", item_name_plural)) + next + end + # Choose a quantity of the item to sell + quantity = @bag.quantity(item) + if quantity > 1 + quantity = choose_item_quantity( + _INTL("How many {1} would you like to sell?", item_name_plural), price, quantity + ) + end + next if quantity == 0 + # Sell the item(s) + price *= quantity + if show_confirm_message(_INTL("I can pay ${1}.\nWould that be OK?", price.to_s_formatted)) + @bag.remove(item, quantity) + old_money = $player.money + $player.money += price + $stats.money_earned_at_marts += $player.money - old_money + refresh + sold_item_name = (quantity > 1) ? item_name_plural : item_name + show_message(_INTL("You turned over the {1} and got ${2}.", + sold_item_name, price.to_s_formatted)) { pbSEPlay("Mart buy item") } + end + next false + end + end +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) + loop do + if cmdBuy >= 0 && cmd == cmdBuy + UI::Mart.new(stock, $bag).main + elsif cmdSell >= 0 && cmd == cmdSell + 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) + end + $game_temp.clear_mart_prices +end diff --git a/Data/Scripts/016_UI/020_UI_PokeMart.rb b/Data/Scripts/016c_UI_old/020_UI_old_PokeMart.rb similarity index 93% rename from Data/Scripts/016_UI/020_UI_PokeMart.rb rename to Data/Scripts/016c_UI_old/020_UI_old_PokeMart.rb index 2bea5bdfe..54d335712 100644 --- a/Data/Scripts/016_UI/020_UI_PokeMart.rb +++ b/Data/Scripts/016c_UI_old/020_UI_old_PokeMart.rb @@ -1,3 +1,4 @@ +=begin #=============================================================================== # Abstraction layer for Pokemon Essentials. #=============================================================================== @@ -156,11 +157,8 @@ class SellAdapter end def getDisplayPrice(item) - if @adapter.showQuantity?(item) - return sprintf("×%d", @adapter.getQuantity(item)) - else - return "" - end + return sprintf("×%d", @adapter.getQuantity(item)) if @adapter.showQuantity?(item) + return "" end def isSelling? @@ -213,27 +211,6 @@ end # #=============================================================================== class PokemonMart_Scene - def update - pbUpdateSpriteHash(@sprites) - @subscene&.pbUpdate - end - - def pbRefresh - if @subscene - @subscene.pbRefresh - else - itemwindow = @sprites["itemwindow"] - @sprites["icon"].item = itemwindow.item - @sprites["itemtextwindow"].text = - (itemwindow.item) ? @adapter.getDescription(itemwindow.item) : _INTL("Quit shopping.") - @sprites["qtywindow"].visible = !itemwindow.item.nil? - @sprites["qtywindow"].text = _INTL("In Bag:{1}", @adapter.getQuantity(itemwindow.item)) - @sprites["qtywindow"].y = Graphics.height - 102 - @sprites["qtywindow"].height - itemwindow.refresh - end - @sprites["moneywindow"].text = _INTL("Money:\n{1}", @adapter.getMoneyString) - end - def pbStartBuyOrSellScene(buying, stock, adapter) # Scroll right before showing screen pbScrollMap(6, 5, 5) @@ -244,7 +221,7 @@ class PokemonMart_Scene @sprites = {} @sprites["background"] = IconSprite.new(0, 0, @viewport) @sprites["background"].setBitmap("Graphics/UI/Mart/bg") - @sprites["icon"] = ItemIconSprite.new(36, Graphics.height - 50, nil, @viewport) + @sprites["icon"] = ItemIconSprite.new(48, Graphics.height - 48, nil, @viewport) winAdapter = buying ? BuyAdapter.new(adapter) : SellAdapter.new(adapter) @sprites["itemwindow"] = Window_PokemonMart.new( stock, winAdapter, Graphics.width - 316 - 16, 10, 330 + 16, Graphics.height - 124 @@ -253,7 +230,7 @@ class PokemonMart_Scene @sprites["itemwindow"].index = 0 @sprites["itemwindow"].refresh @sprites["itemtextwindow"] = Window_UnformattedTextPokemon.newWithSize( - "", 64, Graphics.height - 96 - 16, Graphics.width - 64, 128, @viewport + "", 76, 272, Graphics.width - 98, 128, @viewport ) pbPrepareWindow(@sprites["itemtextwindow"]) @sprites["itemtextwindow"].baseColor = Color.new(248, 248, 248) @@ -361,6 +338,8 @@ class PokemonMart_Scene pbScrollMap(4, 5, 5) if !@subscene end + #----------------------------------------------------------------------------- + def pbPrepareWindow(window) window.visible = true window.letterbyletter = false @@ -386,6 +365,8 @@ class PokemonMart_Scene @sprites["qtywindow"].visible = false end + #----------------------------------------------------------------------------- + def pbDisplay(msg, brief = false) cw = @sprites["helpwindow"] cw.letterbyletter = true @@ -537,6 +518,31 @@ class PokemonMart_Scene return ret end + #----------------------------------------------------------------------------- + + def pbRefresh + if @subscene + @subscene.pbRefresh + else + itemwindow = @sprites["itemwindow"] + @sprites["icon"].item = itemwindow.item + @sprites["itemtextwindow"].text = + (itemwindow.item) ? @adapter.getDescription(itemwindow.item) : _INTL("Quit shopping.") + @sprites["qtywindow"].visible = !itemwindow.item.nil? + @sprites["qtywindow"].text = _INTL("In Bag:{1}", @adapter.getQuantity(itemwindow.item)) + @sprites["qtywindow"].y = Graphics.height - 102 - @sprites["qtywindow"].height + itemwindow.refresh + end + @sprites["moneywindow"].text = _INTL("Money:\n{1}", @adapter.getMoneyString) + end + + def update + pbUpdateSpriteHash(@sprites) + @subscene&.pbUpdate + end + + #----------------------------------------------------------------------------- + def pbChooseBuyItem itemwindow = @sprites["itemwindow"] @sprites["helpwindow"].visible = false @@ -582,18 +588,22 @@ class PokemonMartScreen @adapter = PokemonMartAdapter.new end - def pbConfirm(msg) - return @scene.pbConfirm(msg) - end + #----------------------------------------------------------------------------- def pbDisplay(msg) return @scene.pbDisplay(msg) end + def pbConfirm(msg) + return @scene.pbConfirm(msg) + end + def pbDisplayPaused(msg, &block) return @scene.pbDisplayPaused(msg, &block) end + #----------------------------------------------------------------------------- + def pbBuyScreen @scene.pbStartBuyScene(@stock, @adapter) item = nil @@ -714,34 +724,4 @@ class PokemonMartScreen @scene.pbEndSellScene end end - -#=============================================================================== -# -#=============================================================================== -def pbPokemonMart(stock, speech = nil, cantsell = false) - stock.delete_if { |item| GameData::Item.get(item).is_important? && $bag.has?(item) } - 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 !cantsell - commands[cmdQuit = commands.length] = _INTL("No, thanks") - cmd = pbMessage(speech || _INTL("Welcome! How may I help you?"), commands, cmdQuit + 1) - loop do - if cmdBuy >= 0 && cmd == cmdBuy - scene = PokemonMart_Scene.new - screen = PokemonMartScreen.new(scene, stock) - screen.pbBuyScreen - elsif cmdSell >= 0 && cmd == cmdSell - scene = PokemonMart_Scene.new - screen = PokemonMartScreen.new(scene, stock) - screen.pbSellScreen - else - pbMessage(_INTL("Do come again!")) - break - end - cmd = pbMessage(_INTL("Is there anything else I can do for you?"), commands, cmdQuit + 1) - end - $game_temp.clear_mart_prices -end +=end