Yesterday, 08:20 AM
(This post was last modified: 22 minutes ago by kyonides.
Edit Reason: Updated Script & 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. [Temporarily Disabled in v0.11.0]
- 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.
Leaving the shop without doing anything will decrease the shop's friendship points by 1 (default value).
Purchases and sales will increase those points in no time!
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.)Change Custom Price Shop's Friendship Points - Number stands for any number, either positive or negative.
Code:
price_shop_friend_points(Number)Set Minimum Friendship Level for Certain Items, Weapons or Armors - Types: 0 - Item, 1 - Weapon, 2 - Armor
Code:
price_shop_friendship_min(Mininum, Type, ItemID1, etc.)Change Custom Price Shop's No Transaction Penalty - Number stands for 0 or any positive number. Default Value: 1.
Code:
price_shop_set_no_action_penalty(Number)The Script
Code:
# * KustomPriceShop XP * #
# Scripter : Kyonides
# v0.11.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.
# Leaving the shop without doing anything will decrease the shop's friendship
# points by 1 (default value).
# * 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.)
# - Change Custom Price Shop's Friendship Points:
# Number stands for any number, either positive or negative.
# price_shop_friend_points(Number)
# - Set Minimum Friendship Level for Certain Items, Weapons or Armors:
# Types: 0 - Item, 1 - Weapon, 2 - Armor
# price_shop_friendship_min(Mininum, Type, ItemID1, etc.)
# - Change Custom Price Shop's No Transaction Penalty:
# Number stands for 0 or any positive number. Default Value: 1.
# price_shop_set_no_action_penalty(n)
module KustomPrice
ITEM_MAX = 99
BUY_ONLY_SWITCH = 8
SELL_ONLY_SWITCH = 9
SHOP_ID_VAR = 10
DEFAULT_BACKDROP = "012-PortTown02"
FRIENDSHIP_LEVEL = "Friendship Level: %s"
class Shop
def initialize
@friendship = 0
@no_action_penalty = 1
@friendship_min = {}
@buy_prices = {}
@sell_prices = {}
@buy_item_max = {}
@sell_item_max = {}
@friendship_min.default = {}
@buy_prices.default = {}
@sell_prices.default = {}
@buy_item_max.default = ITEM_MAX
@sell_item_max.default = ITEM_MAX
end
def friendship=(n)
@friendship = [@friendship + n, 0].max
end
def no_action_penalty!
self.friendship -= @no_action_penalty
end
def frienship_min(mininum, type, *items)
fmin = @friendship_min[type]
items.flatten.each {|n| fmin[n] = mininum }
mininum
end
def set_buy_prices(type, data={})
@buy_prices[type].merge!(data)
end
def set_sell_prices(type, data={})
@sell_prices[type].merge!(data)
end
attr_reader :friendship, :friendship_min
attr_reader :buy_prices, :sell_prices
attr_reader :buy_item_max, :sell_item_max
attr_accessor :goods, :no_action_penalty
end
end
class Game_System
alias :kyon_kp_shop_gm_sys_init :initialize
def initialize
kyon_kp_shop_gm_sys_init
reset_price_shop_id!
@custom_price_shops = {}
end
def reset_price_shop_id!
@price_shop_id = 0
end
def init_price_shop(shop_id)
@price_shop_id = shop_id
@custom_price_shops[shop_id] ||= KustomPrice::Shop.new
end
def setup_price_shop(shop_id, new_goods)
shop = @custom_price_shops[shop_id]
shop.goods = new_goods
end
def this_price_shop
@custom_price_shops[@price_shop_id]
end
attr_reader :custom_price_shops
end
class Game_Party
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
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_accessor :shop_goods
def initialize(shop, shop_goods)
w = 368
@tw = w - 64
super(0, 288, w, 192)
sp = shop.buy_prices
@item_prices = sp[0]
@weapon_prices = sp[1]
@armor_prices = sp[2]
@shop_goods = shop_goods.dup
@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 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(shop)
super(0, 128, 640, 352)
@column_max = 2
@no_item = RPG::Item.new
sp = shop.sell_prices
@item_prices = sp[0]
@weapon_prices = sp[1]
@armor_prices = sp[2]
refresh
self.index = 0
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
alias :kyon_kp_shop_int_chng_vars :command_122
def command_122
kyon_kp_shop_int_chng_vars
var_id = @parameters[0]
return unless KustomPrice::SHOP_ID_VAR == var_id
var_id = @parameters[4]
@price_shop = $game_system.init_price_shop(var_id)
end
def price_shop_friend_points(n)
@price_shop.friendship += n
end
def price_shop_friendship_min(min, type, *items)
@price_shop.frienship_min(min, type, *items)
end
def price_shop_set_no_action_penalty(n)
@price_shop.no_action_penalty = n
end
def buy_price_items(data={})
@price_shop.set_buy_prices(0, data)
end
def buy_price_weapons(data={})
@price_shop.set_buy_prices(1, data)
end
def buy_price_armors(data={})
@price_shop.set_buy_prices(2, data)
end
def sell_price_items(data={})
@price_shop.set_sell_prices(0, data)
end
def sell_price_weapons(data={})
@price_shop.set_sell_prices(1, data)
end
def sell_price_armors(data={})
@price_shop.set_sell_prices(2, data)
end
end
class Scene_Map
def call_shop
$game_temp.shop_calling = false
$game_player.straighten
shop_var = KustomPrice::SHOP_ID_VAR
if $game_variables[shop_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!
@transactions = 0
@shop_id = find_shop_id
@shop = $game_system.this_price_shop
@fp = @shop.friendship
@fp_min = @shop.friendship_min
@goods = @shop.goods || $game_temp.shop_goods
setup_friendly_goods
end
def setup_friendly_goods
@shop_goods = []
@goods.each do |type, obj_id|
group = @fp_min[type]
level = group[obj_id] || 0
@shop_goods << [type, obj_id] if level == 0 or level <= @fp
end
@exclude_goods = @shop_goods.size != @goods.size
end
def make_backdrop
@backdrop = Sprite.new
@backdrop.bitmap = RPG::Cache.battleback(DEFAULT_BACKDROP)
end
def make_windows
@help_window = Window_Help.new
show_friendship_level
@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(@shop, @shop_goods)
@buy_window.active = false
@buy_window.visible = false
@buy_window.help_window = @help_window
@sell_window = ShopSellWindow.new(@shop)
@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 show_friendship_level
points = @shop.friendship.to_s
points = sprintf(FRIENDSHIP_LEVEL, points)
@help_window.set_text(points)
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
show_friendship_level
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
show_friendship_level
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
@transactions += @number_window.number
@shop.friendship += @transactions
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
if @shop.friendship != @fp
@fp = @shop.friendship
setup_friendly_goods
@buy_window.shop_goods = @shop_goods
end
@buy_window.refresh
@status_window.refresh
@buy_window.active = true
@buy_window.visible = true
return
when 1 # sell
@transactions += @number_window.number
@shop.friendship += @transactions
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
$game_variables[SHOP_ID_VAR] = 0
$game_switches[BUY_ONLY_SWITCH] = false
$game_switches[SELL_ONLY_SWITCH] = false
$game_party.compact_bag_items!
@shop.no_action_penalty! if @transactions == 0
list = @buy_window.shop_goods
if !@exclude_goods and list.size != @shop_goods.size
$game_system.setup_price_shop(@shop_id, list)
end
$game_system.reset_price_shop_id!
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/MHmxDfpt/kustompriceshop-xp001.jpg)
Purchases and sales will certainly increase those points in no time!
