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 6153
94 기타 복권 스크립트 6 백호 2009.02.21 1258
93 기타 Etude87_Bone_Animation_Character ver.1.2 4 습작 2012.07.06 1255
92 기타 무기 개조 스크립트 file 백호 2009.02.21 1248
91 기타 무기 회피율, 방어구 공격력 지정 스크립트 6 백호 2009.02.22 1244
90 기타 제작한 게임의 파일을 모두 exe파일 하나에 쓸어담기 by sheefo@Creation Asylum 1 file 백호 2009.02.22 1239
89 기타 멋진...제작자 정보를 그림으로 1 백호 2009.02.22 1233
88 기타 액터 선택 스크립트 2 백호 2009.02.21 1228
87 기타 NPC Details Window by SephirothSpawn (SDK호환) 1 file 백호 2009.02.22 1209
86 기타 경험치 퍼센트 수정 백호 2009.02.22 1208
85 기타 창고 스크립트 2 백호 2009.02.21 1203
84 기타 Defining Encounter Areas by RPG Advocate (사용법 첨부) file 백호 2009.02.22 1201
83 기타 [신기술 체험] 빠른 애니매이션 1 file 백호 2009.02.22 1201
82 기타 Steal Script (SDK Required) file 백호 2009.02.21 1182
81 기타 현재 맵BGM을 그대로 전투 BGM으로 연결 from phylomortis.com 백호 2009.02.22 1180
80 기타 Shift Puzzles v2 by SephirothSpawn (SDK호환) 3 file 백호 2009.02.22 1170
79 기타 메세지를 분출해 표시 백호 2009.02.22 1169
78 기타 마우스로 길찾기 스크립트 예제 file 백호 2009.02.21 1168
77 기타 상점 변동시세 적용 스크립트 3 file 백호 2009.02.21 1162
76 기타 Resolution Changer Ultimate by Zeus81 7 file 습작 2013.05.05 1162
75 기타 전투 승리 BGM+페이드아웃 스크립트 1 file 백호 2009.02.21 1159
Board Pagination Prev 1 2 3 4 5 6 7 8 9 10 11 12 13 Next
/ 13