2 hours ago
(This post was last modified: 2 hours ago by kyonides.
Edit Reason: Added Screenshot
)
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.
EVENT SCREENSHOT
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
endTerms & 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!
"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]](https://www.save-point.org/images/userbars/SP1-Scripter.png)
![[Image: SP1-Writer.png]](https://www.save-point.org/images/userbars/SP1-Writer.png)
![[Image: SP1-Poet.png]](https://www.save-point.org/images/userbars/SP1-Poet.png)
![[Image: SP1-PixelArtist.png]](https://www.save-point.org/images/userbars/SP1-PixelArtist.png)
![[Image: SP1-Reporter.png]](https://i.postimg.cc/GmxWbHyL/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!
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
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]](https://www.save-point.org/images/userbars/SP1-Scripter.png)
![[Image: SP1-Writer.png]](https://www.save-point.org/images/userbars/SP1-Writer.png)
![[Image: SP1-Poet.png]](https://www.save-point.org/images/userbars/SP1-Poet.png)
![[Image: SP1-Reporter.png]](https://i.postimg.cc/GmxWbHyL/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!

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



![[Image: kustompriceshop-xp001.jpg]](https://i.postimg.cc/6qDDyxxG/kustompriceshop-xp001.jpg)