KSingleItemShop ACE
#1
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
"For God has not destined us for wrath, but for obtaining salvation through our Lord Jesus Christ," 1 Thessalonians 5:9

Maranatha!

The Internet might be either your friend or enemy. It just depends on whether or not she has a bad hair day.

[Image: SP1-Scripter.png]
[Image: SP1-Writer.png]
[Image: SP1-Poet.png]
[Image: SP1-PixelArtist.png]
[Image: SP1-Reporter.png]

My Original Stories (available in English and Spanish)

List of Compiled Binary Executables I have published...
HiddenChest & Roole

Give me a free copy of your completed game if you include at least 3 of my scripts! Laughing + Tongue sticking out

Just some scripts I've already published on the board...
KyoGemBoost XP VX & ACE, RandomEnkounters XP, KSkillShop XP, Kolloseum States XP, KEvents XP, KScenario XP & Gosu, KyoPrizeShop XP Mangostan, Kuests XP, KyoDiscounts XP VX, ACE & MV, KChest XP VX & ACE 2016, KTelePort XP, KSkillMax XP & VX & ACE, Gem Roulette XP VX & VX Ace, KRespawnPoint XP, VX & VX Ace, GiveAway XP VX & ACE, Klearance XP VX & ACE, KUnits XP VX, ACE & Gosu 2017, KLevel XP, KRumors XP & ACE, KMonsterPals XP VX & ACE, KStatsRefill XP VX & ACE, KLotto XP VX & ACE, KItemDesc XP & VX, KPocket XP & VX, OpenChest XP VX & ACE
Reply




Users browsing this thread: 1 Guest(s)