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 6203
981 저장 Advanced Save Menu 편집 20101005 Edition (SDK2용) 3 Alkaid 2010.10.05 1299
980 저장 Advanced Save Menu 편집 20101006 Edition (SDK2용) 1 Alkaid 2010.10.06 1222
979 저장 Advanced Save Menu 편집한 것. (SDK2용) Alkaid 2010.09.11 1219
978 저장 Advanced Save System Edit (현재 맵을 보여주지 않음) file 백호 2009.02.22 1558
977 상점 Advanced Shop System by Alexis Hiemis 1 file Alkaid 2010.10.08 1872
976 기타 Advanced Weather System (AWS) 3 file 백호 2009.02.22 1272
975 키입력 AInput Module 3.10 by vgvgf (전체키, 마우스 입력) 6 file Alkaid 2010.09.01 3030
974 키입력 Aleworks Input Module 1.21 by vgvgf (SDK호환) 8 WMN 2008.04.06 2145
973 기타 AMS-Advanced Message Script Edited by Dubleax 3 file 백호 2009.02.21 766
972 기타 AMS___Advanced_Message_Script 1 file 백호 2009.02.22 889
971 장비 Angie's Equipment Sets 2.3 by DerVVulfman 7 Alkaid 2010.12.31 1869
970 메시지 Animated Window Skin by Tana 1 백호 2009.02.22 1338
969 기타 Anti Event Lag Script 3 백호 2009.02.21 1057
968 메뉴 AP 올리기 8 알피지GM 2010.02.15 1491
967 기타 appletree님 요청) 화면 명암 주기 3 file 뮤바보 2013.01.31 2727
966 저장 ASM - Advanced Save Menu 3 file 백호 2009.02.21 1639
965 전투 ATB시스템 입니다. [스샷 첨부] 17 백호 2009.02.22 4182
964 전투 ATB전투 5 백호 2009.02.22 3369
963 전투 ATB전투 형식 스크랩트 [ 어디서 퍼왔는..] 7 WMN 2008.03.17 2545
962 기타 ATS-Advanced Time System 1 file 백호 2009.02.21 964
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