Save-Point
KSingleItemShop ACE - Printable Version

+- Save-Point (https://www.save-point.org)
+-- Forum: Material Development (https://www.save-point.org/forum-8.html)
+--- Forum: Scripts Database (https://www.save-point.org/forum-39.html)
+---- Forum: RPGMaker VX/VXAce (RGSS2/3) Engines (https://www.save-point.org/forum-117.html)
+---- Thread: KSingleItemShop ACE (/thread-11564.html)



KSingleItemShop ACE - kyonides - 04-28-2025

KSingleItemShop ACE

by Kyonides

Introduction

Normally, you would open the store menu and buy n amount of potions or rings, etc.
Thinking What would happen if some items were so unique that you could not ever find more than a single potion or ring there?
This script lets you setup such a custom shop with ease! Grinning

Setup Steps:
  • Turn on a specific switch.
  • Set the shop's ID via a game variable.
  • Use a custom backdrop instead of a snapshot of the current map.
  • Add items to the list of goods as usual.
The scriptlet will take care of deactivating it after exiting the custom menu.

The Script

Code:
# * KSingleItemShop ACE * #
#   Scripter : Kyonides
#   v0.6.0 - 2025-04-27

# Create a special shop that only offers single items on its shelves.
# To keep them separate from normal shops, turn on a specific switch and set
# the shop's ID via a specific variable. The rest is taken care by the script.
# It also allows you to set a backdrop as well instead of the current map.

module KSingleItem
  SHOP_SWITCH = 10
  SHOP_ID_VAR = 10
  DEFAULT_BACKDROPS = ["Wood2", "Room2"]

  class Shop
    attr_accessor :goods
  end
end

class Game_Party
  alias :kyon_single_item_gm_pty_init :initialize
  def initialize
    kyon_single_item_gm_pty_init
    @single_shops = {}
  end

  def setup_single_shop(shop_id, new_goods)
    shop = @single_shops[shop_id] || KSingleItem::Shop.new
    shop.goods = new_goods
  end
  attr_reader :single_shops
end

class Game_Interpreter
  def command_302
    return if $game_party.in_battle
    goods = [@params]
    while next_event_code == 605
      @index += 1
      goods.push(@list[@index].parameters)
    end
    if $game_switches[KSingleItem::SHOP_SWITCH]
      SceneManager.call(SingleShopScene)
    else
      SceneManager.call(Scene_Shop)
    end
    SceneManager.scene.prepare(goods, @params[4])
    Fiber.yield
  end
end

class Window_ShopBuy
  alias :kyon_single_item_win_shopbuy_draw_item :draw_item
  attr_reader :shop_goods
  def initialize(x, y, height, shop_goods, stretch=nil)
    @stretch = stretch
    super(x, y, window_width, height)
    @shop_goods = shop_goods.dup
    @money = 0
    @no_item = RPG::Item.new
    @symbol_color = Color.new(255, 255, 80)
    @symbol = $data_system.currency_unit
    refresh
    select(0)
  end

  def window_width
    @stretch ? 384 : 304
  end

  def item
    @data[@index] || @no_item
  end

  def money=(money)
    @money = money
    refresh
  end

  def price(item)
    @price[item.id]
  end

  def enable?(item)
    item && price(item) <= @money && !$game_party.item_max?(item)
  end

  def set_goods(type, gid)
    case type
    when 0
      $data_items[gid]
    when 1
      $data_weapons[gid]
    when 2
      $data_armors[gid]
    end
  end

  def make_item_list
    @data = []
    @price = {}
    @shop_goods.each do |goods|
      item = set_goods(goods[0], goods[1])
      next unless item
      @data << item
      @price[item.id] = goods[2] == 0 ? item.price : goods[3]
    end
  end

  def draw_item_data(item, rx, ry, enabled=true, w=240)
    return unless item
    draw_icon(item.icon_index, 28, ry, enabled)
    change_color(normal_color, enabled)
    draw_text(56, ry, w - 56, 24, item.name)
    draw_text(w, ry, 100, 24, price(item), 2)
    change_color(@symbol_color, enabled)
    draw_text(w + 100, ry, 16, 24, @symbol, 2)
  end

  def draw_item(n)
    unless @stretch
      kyon_single_item_win_shopbuy_draw_item(n)
    else
      item = @data[n]
      rect = item_rect(n)
      draw_item_data(item, rect.x, rect.y, enable?(item))
    end
  end

  def delete_item
    @shop_goods.delete(@index)
    item = @data.delete(@index)
    @price.delete(item.id)
    create_contents
    draw_all_items
  end
end

class SingleShopScene < Scene_Shop
  def find_shop_id
    $game_variables[KSingleItem::SHOP_ID_VAR]
  end

  def prepare(goods, purchase_only)
    shop_id = find_shop_id
    shop = $game_party.single_shops[shop_id]
    @goods = shop ? shop.goods : goods
    @purchase_only = purchase_only
  end

  def start
    create_main_viewport
    create_background
    @actor = $game_party.menu_actor
    create_help_window
    create_gold_window
    create_command_window
    create_buy_window
    create_status_window
    create_category_window
    create_sell_window
  end

  def create_background
    drop1, drop2 = KSingleItem::DEFAULT_BACKDROPS
    @backdrops = [Sprite.new, Sprite.new]
    @backdrops[0].bitmap = Cache.battleback1(drop1)
    @backdrops[1].bitmap = Cache.battleback2(drop2)
  end

  def create_buy_window
    @buy_window = Window_ShopBuy.new(0, 252, 24 * 7, @goods, true)
    @buy_window.viewport = @viewport
    @buy_window.help_window = @help_window
    @buy_window.hide
    @buy_window.set_handler(:ok,     method(:on_buy_ok))
    @buy_window.set_handler(:cancel, method(:on_buy_cancel))
  end

  def create_status_window
    wx = @buy_window.width
    wy = @buy_window.y
    ww = Graphics.width - wx
    @status_window = Window_ShopStatus.new(wx, wy, ww, @buy_window.height)
    @status_window.viewport = @viewport
    @status_window.hide
    @buy_window.status_window = @status_window
  end

  def create_category_window
    @category_window = Window_ItemCategory.new
    @category_window.viewport = @viewport
    @category_window.help_window = @help_window
    @category_window.hide.deactivate
    @category_window.set_handler(:ok,     method(:on_category_ok))
    @category_window.set_handler(:cancel, method(:on_category_cancel))
  end

  def command_buy
    activate_buy_window
  end

  def command_sell
    @category_window.show.activate
    @sell_window.show
    @sell_window.unselect
    @sell_window.refresh
  end

  def on_buy_ok
    @item = @buy_window.item
    @buy_window.hide
    Sound.play_shop
    do_buy(1)
    @gold_window.refresh
    @status_window.refresh
    @buy_window.delete_item
  end

  def on_buy_cancel
    @command_window.activate
    @buy_window.hide
    @status_window.hide
    @status_window.item = nil
    @help_window.clear
  end

  def dispose_background
    @backdrops.each do |sprite|
      sprite.bitmap.dispose
      sprite.dispose
    end
  end

  def terminate
    super
    reset_single_shop
  end

  def reset_single_shop
    list = @buy_window.shop_goods
    return list.size == @goods.size
    shop_id = find_shop_id
    return if shop_id == 0
    $game_party.setup_single_shop(shop_id, @buy_window.shop_goods)
    $game_variables[KSingleItem::SHOP_ID_VAR] = 0
    $game_switches[KSingleItem::SHOP_SWITCH] = false
  end
end

Terms & Conditions

Free as in Beer beer.
Mention me in your game credits.
That's it! Tongue sticking out