KustomPriceShop XP - kyonides - 05-17-2026
KustomPriceShop XP
by Kyonides
Introduction
This script allows you to open a special shop on a given map that offers:
- Single items on its shelves.
- Setting custom (buy or sale) prices for specific items.
- Creating buy-only or sell-only shops.
To keep it separate from normal shops, set the shop's ID via a game variable.
You can change the maximum number of units per item allowed in your game.
It also lets you to set a backdrop as well instead of the current map.
Optional Script Calls For The Active Shop
NOTE: ItemID stands for an actual positive number, starting from 1 onwards.
Add Items with Custom Prices:
Code: buy_price_items(ItemID1 => Price1, etc.)
sell_price_items(ItemID1 => Price1, etc.)
Add Weapons with Custom Prices:
Code: buy_price_weapons(WeaponID1 => Price1, etc.)
sell_price_weapons(WeaponID1 => Price1, etc.)
Add Armors with Custom Prices:
Code: buy_price_armors(ArmorID1 => Price1, etc.)
sell_price_armors(ArmorID1 => Price1, etc.)
The Script
Code: # * KustomPriceShop XP * #
# Scripter : Kyonides
# v0.9.0 - 2026-05-17
# Create a special shop that offers:
# - Single items on its shelves.
# - Setting custom prices for specific items.
# - Creating purchase-only or sell-only shops.
# To keep it separate from normal shops, set the shop's ID via a game variable.
# You can change the maximum number of units per item allowed in your game.
# It also allows you to set a backdrop as well instead of the current map.
# * Optional Script Calls For The Active Shop * #
# - Add Items with Custom Prices:
# buy_price_items(ItemID1 => Price1, etc.)
# sell_price_items(ItemID1 => Price1, etc.)
# - Add Weapons with Custom Prices:
# buy_price_weapons(WeaponID1 => Price1, etc.)
# sell_price_weapons(WeaponID1 => Price1, etc.)
# - Add Armors with Custom Prices:
# buy_price_armors(ArmorID1 => Price1, etc.)
# sell_price_armors(ArmorID1 => Price1, etc.)
module KustomPrice
ITEM_MAX = 99
BUY_ONLY_SWITCH = 8
SELL_ONLY_SWITCH = 9
SHOP_ID_VAR = 10
DEFAULT_BACKDROP = "012-PortTown02"
class Shop
attr_accessor :goods
end
extend self
attr_reader :buy_item_prices, :buy_weapon_prices, :buy_armor_prices
attr_reader :sell_item_prices, :sell_weapon_prices, :sell_armor_prices
def buy_items(data={})
@buy_item_prices = data
end
def buy_weapons(data={})
@buy_weapon_prices = data
end
def buy_armors(data={})
@buy_armor_prices = data
end
def sell_items(data={})
@sell_item_prices = data
end
def sell_weapons(data={})
@sell_weapon_prices = data
end
def sell_armors(data={})
@sell_armor_prices = data
end
def clear_prices!
@buy_item_prices = {}
@buy_weapon_prices = {}
@buy_armor_prices = {}
@sell_item_prices = {}
@sell_weapon_prices = {}
@sell_armor_prices = {}
end
clear_prices!
end
class Game_Party
alias :kyon_single_item_gm_pty_init :initialize
def initialize
kyon_single_item_gm_pty_init
@custom_price_shops = {}
end
def setup_price_shop(shop_id, new_goods)
shop = @custom_price_shops[shop_id] || KustomPrice::Shop.new
shop.goods = new_goods
end
def bag_items
@items
end
def bag_weapons
@weapons
end
def bag_armors
@armors
end
def compact_bag_items!
@items.delete_if {|k,v| v == 0 }
@weapons.delete_if {|k,v| v == 0 }
@armors.delete_if {|k,v| v == 0 }
end
attr_reader :custom_price_shops
end
class Window_ShopCommand
def reset_disabled_items
@disabled = []
end
def disable_current_item?
@disabled[@index]
end
end
module KustomPrice
module AddMethods
def item
@data[@index] || @no_item
end
def price
@prices[@index] || 0
end
def get_price(n, item_id, price)
case @types[n]
when 0
@item_prices[item_id] || price
when 1
@weapon_prices[item_id] || price
when 2
@armor_prices[item_id] || price
end
end
end
class ShopBuyWindow < Window_Selectable
include AddMethods
attr_reader :shop_goods
def initialize(shop_goods)
w = 368
@tw = w - 64
super(0, 288, w, 192)
setup_prices
@shop_goods = shop_goods.dup
@disabled = []
@no_item = RPG::Item.new
@transparent = Color.new(0, 0, 0, 0)
@symbol_color = Color.new(255, 255, 80)
@symbol = $data_system.words.gold
refresh
self.index = 0
end
def setup_prices
@item_prices = KustomPrice.buy_item_prices
@weapon_prices = KustomPrice.buy_weapon_prices
@armor_prices = KustomPrice.buy_armor_prices
end
def item_name
self.item.name
end
def set_goods(goods_item)
type, goods_id = goods_item
case type
when 0
[type, $data_items[goods_id]]
when 1
[type, $data_weapons[goods_id]]
when 2
[type, $data_armors[goods_id]]
end
end
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@types = []
@data = []
@prices = []
for goods_item in @shop_goods
type, item = set_goods(goods_item)
next unless item
n = @types.size
@types << type
@data << item
@prices << get_price(n, item.id, item.price)
end
draw_items
end
def draw_items
@item_max = @data.size
self.contents = Bitmap.new(width - 32, row_max * 32) if @item_max > 0
@item_max.times {|i| draw_item(i) }
end
def clear_line(rx, ry)
rect = Rect.new(rx, ry, self.width - 32, 32)
self.contents.fill_rect(rect, @transparent)
end
def draw_item(n)
item = @data[n]
font = self.contents.font
price = @prices[n]
if $game_party.gold >= price
font.color = normal_color
alpha = 255
else
font.color = disabled_color
alpha = 128
end
ry = n * 32
clear_line(4, ry)
bitmap = RPG::Cache.icon(item.icon_name)
self.contents.blt(28, ry + 4, bitmap, Rect.new(0, 0, 24, 24), alpha)
self.contents.draw_text(56, ry, @tw - 100, 32, item.name)
self.contents.draw_text(@tw - 92, ry, 100, 32, price.to_s, 2)
@symbol_color.alpha = alpha
font.color = @symbol_color
self.contents.draw_text(@tw, ry, 24, 32, @symbol, 2)
end
def update_help
@help_window.set_text(self.item.description)
end
def delete_item
@shop_goods.delete(@index)
item = @data.delete(@index)
self.contents.dispose if self.contents != nil
self.contents = nil
draw_items
end
def disable_item(n)
draw_item(n, disabled_color)
@disabled[n] = true
end
end
class ShopSellWindow < Window_Selectable
include AddMethods
def initialize
super(0, 128, 640, 352)
@column_max = 2
@no_item = RPG::Item.new
setup_prices
refresh
self.index = 0
end
def setup_prices
@item_prices = KustomPrice.sell_item_prices
@weapon_prices = KustomPrice.sell_weapon_prices
@armor_prices = KustomPrice.sell_armor_prices
end
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@types = []
@data = []
@prices = []
n = 0
$game_party.bag_items.sort.each do |k,v|
next if $game_party.item_number(k) == 0
@types << 0
@data << obj = $data_items[k]
@prices << get_price(n, k, obj.price / 2)
n += 1
end
$game_party.bag_weapons.sort.each do |k,v|
next if $game_party.weapon_number(i) == 0
@types << 1
@data << obj = $data_weapons[k]
@prices << get_price(n, k, obj.price / 2)
n += 1
end
$game_party.bag_armors.sort.each do |k,v|
next if $game_party.armor_number(i) == 0
@types << 2
@data << obj = $data_armors[k]
@prices << get_price(n, k, obj.price / 2)
n += 1
end
@item_max = @data.size
return if @item_max == 0
self.contents = Bitmap.new(width - 32, row_max * 32)
@item_max.times {|n| draw_item(n) }
end
def draw_item(n)
item = @data[n]
case item
when RPG::Item
number = $game_party.item_number(item.id)
when RPG::Weapon
number = $game_party.weapon_number(item.id)
when RPG::Armor
number = $game_party.armor_number(item.id)
end
price = @prices[n]
if price > 0
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
x = 4 + n % 2 * (288 + 32)
y = n / 2 * 32
rect = Rect.new(x, y, self.width / @column_max - 32, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
bitmap = RPG::Cache.icon(item.icon_name)
opacity = self.contents.font.color == normal_color ? 255 : 128
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
end
def update_help
@help_window.set_text(self.item.description)
end
end
end
class Interpreter
def buy_price_items(data={})
KustomPrice.buy_items(data)
end
def buy_price_weapons(data={})
KustomPrice.buy_weapons(data)
end
def buy_price_armors(data={})
KustomPrice.buy_armors(data)
end
def sell_price_items(data={})
KustomPrice.sell_items(data)
end
def sell_price_weapons(data={})
KustomPrice.sell_weapons(data)
end
def sell_price_armors(data={})
KustomPrice.sell_armors(data)
end
end
class Scene_Map
def call_shop
$game_temp.shop_calling = false
$game_player.straighten
@custom_shop_id_var ||= KustomPrice::SHOP_ID_VAR
if $game_variables[@custom_shop_id_var] != 0
$scene = PriceShopScene.new
else
$scene = Scene_Shop.new
end
end
end
class PriceShopScene < Scene_Shop
include KustomPrice
def find_shop_id
$game_variables[SHOP_ID_VAR]
end
def main
prepare_goods
make_backdrop
make_windows
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
dispose_windows
reset_price_shop
end
def prepare_goods
$game_party.compact_bag_items!
shop_id = find_shop_id
shop = $game_party.custom_price_shops[shop_id]
@goods = shop ? shop.goods : $game_temp.shop_goods
end
def make_backdrop
@backdrop = Sprite.new
@backdrop.bitmap = RPG::Cache.battleback(DEFAULT_BACKDROP)
end
def make_windows
@help_window = Window_Help.new
@command_window = Window_ShopCommand.new
@command_window.reset_disabled_items
@command_window.disable_item(0) if $game_switches[SELL_ONLY_SWITCH]
@command_window.disable_item(1) if $game_switches[BUY_ONLY_SWITCH]
@gold_window = Window_Gold.new
@gold_window.x = 480
@gold_window.y = 64
@dummy_window = Window_Base.new(0, 288, 640, 192)
@buy_window = ShopBuyWindow.new(@goods)
@buy_window.active = false
@buy_window.visible = false
@buy_window.help_window = @help_window
@sell_window = ShopSellWindow.new
@sell_window.active = false
@sell_window.visible = false
@sell_window.help_window = @help_window
@number_window = Window_ShopNumber.new
@number_window.active = false
@number_window.visible = false
@status_window = Window_ShopStatus.new
@status_window.visible = false
end
def update_command
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Map.new
return
elsif Input.trigger?(Input::C)
if @command_window.disable_current_item?
$game_system.se_play($data_system.buzzer_se)
return
end
case @command_window.index
when 0
open_purchase
when 1
open_sale
when 2
$game_system.se_play($data_system.decision_se)
$scene = Scene_Map.new
end
end
end
def open_purchase
$game_system.se_play($data_system.decision_se)
@command_window.active = false
@dummy_window.visible = false
@buy_window.active = true
@buy_window.visible = true
@buy_window.refresh
@status_window.visible = true
end
def open_sale
$game_system.se_play($data_system.decision_se)
@command_window.active = false
@dummy_window.visible = false
@sell_window.active = true
@sell_window.visible = true
@sell_window.refresh
end
def update_buy
@status_window.item = @buy_window.item
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
@command_window.active = true
@dummy_window.visible = true
@buy_window.active = false
@buy_window.visible = false
@status_window.visible = false
@status_window.item = nil
@help_window.set_text("")
return
elsif Input.trigger?(Input::C)
@item = @buy_window.item
price = @buy_window.price
if @item == nil or $game_party.gold < price
$game_system.se_play($data_system.buzzer_se)
return
end
case @item
when RPG::Item
number = $game_party.item_number(@item.id)
when RPG::Weapon
number = $game_party.weapon_number(@item.id)
when RPG::Armor
number = $game_party.armor_number(@item.id)
end
if ITEM_MAX == number
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.decision_se)
max = price == 0 ? ITEM_MAX : $game_party.gold / price
max = [max, ITEM_MAX - number].min
@buy_window.active = false
@buy_window.visible = false
@number_window.set(@item, max, price)
@number_window.active = true
@number_window.visible = true
end
end
def update_sell
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
@command_window.active = true
@dummy_window.visible = true
@sell_window.active = false
@sell_window.visible = false
@status_window.item = nil
@help_window.set_text("")
return
elsif Input.trigger?(Input::C)
@item = @sell_window.item
@status_window.item = @item
price = @sell_window.price
if @item == nil or price == 0
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.decision_se)
case @item
when RPG::Item
number = $game_party.item_number(@item.id)
when RPG::Weapon
number = $game_party.weapon_number(@item.id)
when RPG::Armor
number = $game_party.armor_number(@item.id)
end
total = number
@sell_window.active = false
@sell_window.visible = false
@number_window.set(@item, total, price)
@number_window.active = true
@number_window.visible = true
@status_window.visible = true
end
end
def update_number
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
@number_window.active = false
@number_window.visible = false
case @command_window.index
when 0 # buy
@buy_window.active = true
@buy_window.visible = true
when 1 # sell
@sell_window.active = true
@sell_window.visible = true
@status_window.visible = false
end
return
elsif Input.trigger?(Input::C)
$game_system.se_play($data_system.shop_se)
@number_window.active = false
@number_window.visible = false
case @command_window.index
when 0 # buy
price = @buy_window.price
$game_party.lose_gold(@number_window.number * price)
case @item
when RPG::Item
$game_party.gain_item(@item.id, @number_window.number)
when RPG::Weapon
$game_party.gain_weapon(@item.id, @number_window.number)
when RPG::Armor
$game_party.gain_armor(@item.id, @number_window.number)
end
@gold_window.refresh
@buy_window.refresh
@status_window.refresh
@buy_window.active = true
@buy_window.visible = true
return
when 1 # sell
price = @sell_window.price
$game_party.gain_gold(@number_window.number * price)
case @item
when RPG::Item
$game_party.lose_item(@item.id, @number_window.number)
when RPG::Weapon
$game_party.lose_weapon(@item.id, @number_window.number)
when RPG::Armor
$game_party.lose_armor(@item.id, @number_window.number)
end
@gold_window.refresh
@sell_window.refresh
@status_window.refresh
@sell_window.active = true
@sell_window.visible = true
@status_window.visible = false
end
end
end
def dispose_windows
@backdrop.bitmap.dispose
@backdrop.dispose
@help_window.dispose
@command_window.dispose
@gold_window.dispose
@dummy_window.dispose
@buy_window.dispose
@sell_window.dispose
@number_window.dispose
@status_window.dispose
end
def reset_price_shop
KustomPrice.clear_prices!
$game_party.compact_bag_items!
list = @buy_window.shop_goods
return list.size == @goods.size
shop_id = find_shop_id
return if shop_id == 0
$game_party.setup_price_shop(shop_id, @buy_window.shop_goods)
$game_variables[SHOP_ID_VAR] = 0
$game_switches[BUY_ONLY_SWITCH] = false
$game_switches[SELL_ONLY_SWITCH] = false
end
end
Terms & Conditions
Free as in beer.
Mention me in your game credits.
You may also add the forum's name and URL there.
That's it!
|