XP 스크립트

이 스크립트로 호출한 상점은 물건을 사면 재고량이 줄어들면서 물건의 가격이 올라갑니다.  반대로 물건을 팔면 재고량이 늘면서 개당 가격은 떨어지고, 상점에 기본적으로 비치된 물건 외 다른 물건을 팔 경우 해당 물건은 상점의 판매 리스트에 추가되어 역시 구입이 가능합니다(단, 이런 물건들은 재고가 모두 떨어졌을 경우 그냥 판매리스트에서 사라집니다).  재고가 떨어진 물건은 상점의 설정에 따라 일정시간이 지나면 재고량이 올라가게 됩니다.

**주의: 이 스크립트 적용시 이벤트로 상점호출을 할 수 없습니다. (이벤트로 상점처리해 보면 뭐시기 no method 에러가 뜹니다)

**Syvkal씨가 약간 편집한 스크립트입니다:
#==============================================================================
# ■ Game_Stores by Astro_mech
# Special thanks to Phylomortis.com for the advanced shop display window!
#==============================================================================

class Game_Stores
#--------------------------------------------------------------------------
def initialize
@stores = {}
end
#--------------------------------------------------------------------------
def [](id)
return @stores[id]
end
#--------------------------------------------------------------------------
def create!(items, id, rate)
@stores[id] = Store.new(items, id, rate)
end

#==============================================================================

class Store
#--------------------------------------------------------------------------
def initialize(items, id, rate)
#[id, max_stock, now_stock, price_min, price_factor, original_stock?, stock_increase?]
@items = items[0]
@weapons = items[1]
@armors = items[2]
@id = id
@restock_rate = rate
@last_time = Graphics.frame_count / Graphics.frame_rate
end
#--------------------------------------------------------------------------
def get_stock_max(kind, id)
stock = eval("@" + kind + "s[id][1]")
return stock
end
#--------------------------------------------------------------------------
def get_stock_now(kind, id)
stock = eval("@" + kind + "s[id][2]")
return stock
end
#--------------------------------------------------------------------------
def get_price_min(kind, id)
factor = eval("@" + kind + "s[id][3]")
return factor
end
#--------------------------------------------------------------------------
def get_price_factor(kind, id)
factor = eval("@" + kind + "s[id][4]")
return factor
end
#--------------------------------------------------------------------------
def get_price_now(kind, id)
factor = get_price_factor(kind, id).to_f
price = get_price_min(kind, id).to_f
times = get_stock_max(kind, id) - get_stock_now(kind, id)
if times > 0
times.times do
price *= (1.0 + factor/100.0)
end
elsif times < 0
times.abs.times do
price = price - price*(factor/100.0)
end
end
return [[price, 9999999.0].min, 0.0].max.round
end
#--------------------------------------------------------------------------
def update_stock
if @last_time + @restock_rate < Graphics.frame_count / Graphics.frame_rate
times = (Graphics.frame_count/Graphics.frame_rate)-(@last_time + @restock_rate)
times = (times.to_f/@restock_rate.to_f).floor
@last_time = Graphics.frame_count / Graphics.frame_rate
for i in 0..times
self.all_items.each do |item|
if item[2] < item[1]
item[2] += 1 if item[6]
elsif item[2] > item[1]
item[2] -= 1 if item[6]
end
end
end
for item in @items.values
if item[2] <= 0
item[2] = 0
@items.delete(item[0]) unless item[5]
end
end
for item in @weapons.values
if item[2] <= 0
item[2] = 0
@weapons.delete(item[0]) unless item[5]
end
end
for item in @armors.values
if item[2] <= 0
item[2] = 0
@armors.delete(item[0]) unless item[5]
end
end
return true
end
return false
end
#--------------------------------------------------------------------------
def all_items
return @items.values+@weapons.values+@armors.values
end
#--------------------------------------------------------------------------
def stock_items
return [@items.keys, @weapons.keys, @armors.keys]
end
#--------------------------------------------------------------------------
def increment_stock(kind, id, n)
if eval("@" + kind + "s[id] != nil")
eval("@" + kind + "s[id][2] += #{n}")
else
add_item(kind, id, n)
end
end
#--------------------------------------------------------------------------
def decrement_stock(kind, id, n)
if eval("@" + kind + "s[id] != nil")
a = eval("@" + kind + "s[id]")
a[2] = [a[2] - n, 0].max
if a[2] == 0 and not a[5]
hash = eval("@" + kind + "s")
hash.delete(a[0])
end
end
end
#--------------------------------------------------------------------------
def add_item(kind, id, n)
eval("@" + kind + "s[#{id}] = [#{id}, 0, #{n}, $data_#{kind}s[#{id}].price, 10, false, true]")
end
#--------------------------------------------------------------------------
def has_item?(kind, id)
return eval("@" + kind + "s.key?(id)")
end
end

end

#==============================================================================
# ■ Scene_Shop
#==============================================================================

class Scene_Shop
#--------------------------------------------------------------------------
def main
@store = $game_temp.shop_goods
@store.update_stock
@fake_window = Fake.new
@fake_window.active = false
@fake_window.visible = false
@help_window = Window_Help.new
@command_window = Window_ShopCommand.new
@gold_window = Window_Gold.new
@gold_window.x = 480
@gold_window.y = 64
@dummy_window = Window_Base.new(0, 128, 640, 352)
@buy_window = Window_ShopBuy.new(@store)
@buy_window.active = false
@buy_window.visible = false
@buy_window.opacity = 0
@buy_window.help_window = @help_window
@sell_window = Window_ShopSell.new(@store)
@sell_window.active = false
@sell_window.visible = false
@sell_window.opacity = 0
@sell_window.help_window = @help_window
@status_window = Window_ShopStatus.new
@status_window.visible = false
@objects = [@fake_window, @help_window, @command_window, @gold_window, @dummy_window, @buy_window, @sell_window, @status_window]
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@objects.each {|x| x.dispose}
end
#--------------------------------------------------------------------------
def update
@objects.each {|x| x.update}
if @store.update_stock
@buy_window.refresh
@sell_window.refresh
end
if @command_window.active
update_command
return
end
if @buy_window.active
update_buy
return
end
if @sell_window.active
update_sell
return
end
end
#--------------------------------------------------------------------------
def update_command
if Input.trigger?(Input::B)
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Map.new
return
end
if Input.trigger?(Input::C)
case @command_window.index
when 0
$game_system.se_play($data_system.decision_se)
@command_window.active = false
@dummy_window.visible = false
@buy_window.active = true
@buy_window.visible = true
@fake_window.active = true
@fake_window.visible = true
@status_window.visible = true
when 1
$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
@fake_window.active = true
@fake_window.visible = true
@status_window.visible = true
when 2
$game_system.se_play($data_system.decision_se)
$scene = Scene_Map.new
end
return
end
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
@buy_window.index = 0
@fake_window.active = false
@fake_window.visible = false
@status_window.visible = false
@status_window.item = nil
@help_window.set_text("")
return
end
if Input.trigger?(Input::C)
@item = @buy_window.item
case @item
when RPG::Item
number = $game_party.item_number(@item.id)
string = "item"
when RPG::Weapon
number = $game_party.weapon_number(@item.id)
string = "weapon"
when RPG::Armor
number = $game_party.armor_number(@item.id)
string = "armor"
end
stock = @store.get_stock_now(string, @item.id)
price = @store.get_price_now(string, @item.id)
gold = $game_party.gold
if @item == nil or price > gold or stock == 0 or number == 99
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.shop_se)
$game_party.lose_gold(price)
case @item
when RPG::Item
$game_party.gain_item(@item.id, 1)
when RPG::Weapon
$game_party.gain_weapon(@item.id, 1)
when RPG::Armor
$game_party.gain_armor(@item.id, 1)
end
@store.decrement_stock(string, @item.id, 1)
@gold_window.refresh
@buy_window.refresh
@status_window.refresh
end
end
#--------------------------------------------------------------------------
def update_sell
@status_window.item = @sell_window.item
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
@sell_window.index = 0
@fake_window.active = false
@fake_window.visible = false
@status_window.visible = false
@status_window.item = nil
@help_window.set_text("")
return
end
if Input.trigger?(Input::C)
@item = @sell_window.item
if @item == nil or @item.price == 0
$game_system.se_play($data_system.buzzer_se)
return
end
$game_system.se_play($data_system.shop_se)
case @item
when RPG::Item
$game_party.lose_item(@item.id, 1)
string = "item"
when RPG::Weapon
$game_party.lose_weapon(@item.id, 1)
string = "weapon"
when RPG::Armor
$game_party.lose_armor(@item.id, 1)
string = "armor"
end
if @store.has_item?(string, @item.id)
$game_party.gain_gold((@store.get_price_now(string, @item.id).to_f*0.75).round)
else
$game_party.gain_gold((eval("$data_#{string}s[#{@item.id}].price").to_f*0.75).round)
end
@store.increment_stock(string, @item.id, 1)
@gold_window.refresh
@sell_window.refresh
@status_window.refresh
end
end
end

#==============================================================================
# ■ Window_ShopBuy
#==============================================================================

class Window_ShopBuy < Window_Selectable
#--------------------------------------------------------------------------
def initialize(store)
super(0, 160, 368, 320) # super(0, 128, 368, 352) (0, 160, 368, 320)
@store = store
refresh
self.index = 0
end
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
for i in 0...@store.stock_items.size
for j in @store.stock_items[i]
case i
when 0
item = $data_items[j]
when 1
item = $data_weapons[j]
when 2
item = $data_armors[j]
end
if item != nil
@data.push(item)
end
end
end
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
def draw_item(index)
item = @data[index]
case item
when RPG::Item
number = $game_party.item_number(item.id)
string = "item"
when RPG::Weapon
number = $game_party.weapon_number(item.id)
string = "weapon"
when RPG::Armor
number = $game_party.armor_number(item.id)
string = "armor"
end
price = @store.get_price_now(string, item.id)
stock = @store.get_stock_now(string, item.id)
if price <= $game_party.gold and number < 99 and stock != 0
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
x = 4
y = index * 32
rect = Rect.new(x, y, self.width - 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, 180, 32, item.name, 0)
temp_color = self.contents.font.color.clone
self.contents.font.color = system_color
self.contents.font.color.alpha = temp_color.alpha
self.contents.draw_text(x + 208, y, 32, 32, stock.to_s, 0)
self.contents.font.color = temp_color
self.contents.draw_text(x + 240, y, 88, 32, price.to_s, 2)
end
#--------------------------------------------------------------------------
def update_help
@help_window.set_text(self.item == nil ? "" : self.item.description)
end
end

#==============================================================================
# ■ Window_ShopSell
#==============================================================================

class Window_ShopSell < Window_Selectable
#--------------------------------------------------------------------------
def initialize(store)
super(0, 160, 368, 320) # super(0, 128, 368, 352) (0, 160, 368, 320)
@store = store
@column_max = 1
refresh
self.index = 0
end
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
for i in 1...$data_items.size
if $game_party.item_number(i) > 0
@data.push($data_items[i])
end
end
for i in 1...$data_weapons.size
if $game_party.weapon_number(i) > 0
@data.push($data_weapons[i])
end
end
for i in 1...$data_armors.size
if $game_party.armor_number(i) > 0
@data.push($data_armors[i])
end
end
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
def draw_item(index)
item = @data[index]
case item
when RPG::Item
number = $game_party.item_number(item.id)
string = "item"
when RPG::Weapon
number = $game_party.weapon_number(item.id)
string = "weapon"
when RPG::Armor
number = $game_party.armor_number(item.id)
string = "armor"
end
if @store.has_item?(string, item.id)
price = (@store.get_price_now(string, item.id).to_f*0.75).round
stock = @store.get_stock_now(string, item.id)
else
price = (item.price.to_f*0.75).round
stock = 0
end
if price > 0
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
x = 4
y = index * 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, 180, 32, item.name, 0)
temp_color = self.contents.font.color.clone
self.contents.font.color = system_color
self.contents.font.color.alpha = temp_color.alpha
self.contents.draw_text(x + 208, y, 32, 32, stock.to_s, 0)
self.contents.font.color = temp_color
self.contents.draw_text(x + 240, y, 88, 32, price.to_s, 2)
end
#--------------------------------------------------------------------------
def update_help
@help_window.set_text(self.item == nil ? "" : self.item.description)
end
end

#==============================================================================
# ■ Window_ShopStatus
#==============================================================================

class Window_ShopStatus < Window_Base
#--------------------------------------------------------------------------
def initialize
super(368, 128, 272, 352)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = $fontface
self.contents.font.size = $fontsize
@item = nil
refresh
end
#--------------------------------------------------------------------------
def refresh
self.contents.clear
if @item == nil
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
self.contents.font.color = system_color
self.contents.draw_text(4, 0, 200, 32, "You own:")
self.contents.font.color = normal_color
self.contents.draw_text(204, 0, 32, 32, number.to_s, 2)
if @item.is_a?(RPG::Item)
return
end
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
if actor.equippable?(@item)
self.contents.font.color = normal_color
else
self.contents.font.color = disabled_color
end
self.contents.draw_text(4, 64 + 64 * i, 120, 32, actor.name)
if @item.is_a?(RPG::Weapon)
item1 = $data_weapons[actor.weapon_id]
elsif @item.kind == 0
item1 = $data_armors[actor.armor1_id]
elsif @item.kind == 1
item1 = $data_armors[actor.armor2_id]
elsif @item.kind == 2
item1 = $data_armors[actor.armor3_id]
else
item1 = $data_armors[actor.armor4_id]
end
if actor.equippable?(@item)
if @item.is_a?(RPG::Weapon)
atk1 = item1 != nil ? item1.atk : 0
atk2 = @item != nil ? @item.atk : 0
change = atk2 - atk1
end
if @item.is_a?(RPG::Armor)
pdef1 = item1 != nil ? item1.pdef : 0
mdef1 = item1 != nil ? item1.mdef : 0
pdef2 = @item != nil ? @item.pdef : 0
mdef2 = @item != nil ? @item.mdef : 0
change = pdef2 - pdef1 + mdef2 - mdef1
end
self.contents.draw_text(124, 64 + 64 * i, 112, 32,
sprintf("%+d", change), 2)
end
if item1 != nil
x = 4
y = 64 + 64 * i + 32
bitmap = RPG::Cache.icon(item1.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, item1.name)
end
end
end
#--------------------------------------------------------------------------
def item=(item)
if @item != item
@item = item
refresh
end
end
end

#==============================================================================
# ■ Scene_Title
#==============================================================================

class Scene_Title
alias dynamic_stores_new_game command_new_game
def command_new_game
$game_stores = Game_Stores.new
dynamic_stores_new_game
end
end

#==============================================================================
# ■ Interpreter
#==============================================================================

class Interpreter
#--------------------------------------------------------------------------
def create_store(id)
if $game_stores[id] == nil
rate = 0
items = [Hash.new, Hash.new, Hash.new]
got_rate = false
loop do
@index += 1
if not [108, 408].include?(@list[@index].code)
@index -= 1
break
end
next if @list[@index].parameters[0].include?("#")
if @list[@index].code == 108 and not got_rate
rate = @list[@index].parameters[0].to_i
got_rate = true
next
end
if [108, 408].include?(@list[@index].code) and got_rate
a = @list[@index].parameters[0].split(' ')
for i in 0...a.size
a[i].strip!
a[i] = a[i].to_i
end
kind = a[0]
info = [a[1], a[2], a[2], a[3], a[4], true, (a[5]>=1)]
items[kind][info[0]] = info
end
end
$game_stores.create!(items, id, rate)
end
store = $game_stores[id]
$game_temp.battle_abort = true
$game_temp.shop_calling = true
$game_temp.shop_goods = store
end
end

#==============================================================================
# ■ Scene_Save
#==============================================================================

class Scene_Save
def write_save_data(file)
characters = []
for i in 0...$game_party.actors.size
actor = $game_party.actors[i]
characters.push([actor.character_name, actor.character_hue])
end
Marshal.dump(characters, file)
Marshal.dump(Graphics.frame_count, file)
$game_system.save_count += 1
$game_system.magic_number = $data_system.magic_number
Marshal.dump($game_system, file)
Marshal.dump($game_switches, file)
Marshal.dump($game_variables, file)
Marshal.dump($game_self_switches, file)
Marshal.dump($game_screen, file)
Marshal.dump($game_actors, file)
Marshal.dump($game_party, file)
Marshal.dump($game_troop, file)
Marshal.dump($game_map, file)
Marshal.dump($game_player, file)
Marshal.dump($game_stores, file)
end
end

#==============================================================================
# ■ Scene_Load
#==============================================================================

class Scene_Load
def read_save_data(file)
characters = Marshal.load(file)
Graphics.frame_count = Marshal.load(file)
$game_system = Marshal.load(file)
$game_switches = Marshal.load(file)
$game_variables = Marshal.load(file)
$game_self_switches = Marshal.load(file)
$game_screen = Marshal.load(file)
$game_actors = Marshal.load(file)
$game_party = Marshal.load(file)
$game_troop = Marshal.load(file)
$game_map = Marshal.load(file)
$game_player = Marshal.load(file)
$game_stores = Marshal.load(file)
if $game_system.magic_number != $data_system.magic_number
$game_map.setup($game_map.map_id)
$game_player.center($game_player.x, $game_player.y)
end
$game_party.refresh
end
end


#===================================================
# - CLASS Fake Begins
#===================================================

class Fake < Window_Base

#---------------------------------------------------------------------------------

def initialize
super(0, 128, 368, 352)
self.contents = Bitmap.new(width - 32, height - 32)
self.contents.font.name = $defaultfonttype
self.contents.font.size = $defaultfontsize
self.contents.font.color = text_color(0)
self.contents.draw_text(32, 0, 300, 20, "Item")
self.contents.draw_text(202, 0, 300, 20, "Stock")
self.contents.draw_text(292, 0, 300, 20, "Price")
end
end

#===================================================
# - CLASS Fake Ends
#===================================================

**사용법:
  상점은 이벤트에서 스크립트 "create_store(ID)"로 호출합니다.  (ID)에는 숫자나 문자열이 들어갈 수 있고, 상점마다 고유한 값이어야 합니다.  그 다음 주석에 숫자를 쓰는데, 이 숫자는 몇초에 하나씩 재고가 차는가(지정한 최대값까지)를 지정합니다.  그리고 그 다음부터 주석으로
(아이템 종류:0=일반 1=무기 2=방어구) (아이템 ID) (최소가격) (가격상승률) (시간이 지나면 재고가 차는가?:0=재고량 회복되지 않음 1=재고량 회복)
식으로 넣어줘야 합니다.

Who's 백호

?

이상혁입니다.

http://elab.kr

Atachment
첨부 '1'

List of Articles
번호 분류 제목 글쓴이 날짜 조회 수
공지 스크립트 자료 게시물 작성시 주의사항 습작 2012.12.24 6202
981 오디오 WhiteFlute - AudioEX (XP/VX/VXA) file Alkaid 2012.12.26 1257
980 그래픽 WhiteFlute - BitmapEX 4 file JACKY 2012.12.10 2955
979 오디오 Audio Module Rewrite mciSendString 1.1 by DerVVulfman Alkaid 2012.09.18 1371
978 전투 Trickster씨의 전투 시스템 (SDK 필수?) Alkaid 2012.09.18 3261
977 스킬 Trickster's Bag of Skill Effects (SDK 필요) Alkaid 2012.09.17 1291
976 변수/스위치 Switchless Common Events by PK8(XP/VX/VXA) Alkaid 2012.09.15 1202
975 변수/스위치 Initial Switches and Variables by PK8 (XP/VX/VXA) Alkaid 2012.09.14 1298
974 변수/스위치 The Self Data Suite by PK8 (XP/VX/VXA) Alkaid 2012.09.14 1237
973 그래픽 부드럽게 화면이 움직이는 스크립트 입니다. 16 GangSin 2012.09.12 4594
972 맵/타일 Editor Tiles by PK8 (XP/VX/VXA) Alkaid 2012.09.11 1868
971 장비 Auto Equipment Optimization for Guillaume777's Multi Slot Script by DerVVulfman Alkaid 2012.09.09 1498
970 메뉴 Leidy's Ring Command Window 1.2 by DerVVulfman Alkaid 2012.09.09 1433
969 그래픽 Pictures below Characters by PK8 (XP/VXA) Alkaid 2012.09.07 1643
968 그래픽 Event Transparency by DerVVulfman (XP/VX/VXA) Alkaid 2012.09.01 1488
967 전투 Etude87_Custom_Slip_Damage_XP ver.1.0 5 습작 2012.08.26 1857
966 전투 Mr.Mo's ABS Ultimate 7.0 by DerVVulfman 4 Alkaid 2012.08.26 2587
965 그래픽 Composite Window Skins by PK8 (XP/VX/VXA) Alkaid 2012.08.26 1563
964 스킬 Miriam's Handicrafts! 1.3 by DerVVulfman Alkaid 2012.08.26 1207
963 전투 Minkoff's Animated Battlers - Enhanced 13.8 by DerVVulfman 1 Alkaid 2012.08.26 1832
962 메뉴 메뉴를 바꾸는 스크립트 14 №1 2012.08.04 4214
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ... 52 Next
/ 52