Game Stores Por Astro_mech [RMXP]
Publicado em 10 de setembro de 2012.Game_Stores é um script desenvolvido por Astro_mech, para ser usado em um jogo ou projeto do RPG Maker XP.
Basicamente, este script permite lojas dinâmicas no seu projeto. É muito interessante: além de estoque nas lojas, o preço dos ítens podem subir ou diminuir, dependendo de quanto você compra ou vende.
O Phylomortis.com criou a janela de loja avançada e a demo por KaotiX.
Instruções
Para instalar o script, basta copiar o código abaixo acima do Main.
Para criar uma loja dinâmica, basta criar um evento e chamar o script create_store("ID"), onde ID é algo que identifique a loja (pode usar o nome da loja, por exemplo), e deve estar entre aspas.
Depois crie um comentário com um número. Este número representa, em segundos, o tempo em que a loja atualiza seu estoque. Se você colocar 60, vai demorar 60 segundos, ou um minuto para isto ocorrer.
Daí você vai ter que colocar um comentário para cada item que você quer que tenha na loja. Cada linha contém 6 números, separados por espaço: TIPO ID ESTOQUE PREÇO_MÍNIMO PORCENTAGEM_PREÇO AUMENTO_ESTOQUE?
- No
TIPO, você colocará a natureza do item, 0 para itens, 1 armas e 2 para armaduras - No
ID, você vai colocar a ID do item, que você acha na sua Database do RMXP mesmo - No
ESTOQUE, você vai colocar a quantidade disponível, inicial, pra cada item - No
PREÇO_MÍNIMO, você vai definir o preço inicial mínimo, que pode aumentar dependendo de quanto você compre dele - Em
PORCENTAGEM_PREÇO, você deve digitar a porcentagem que o preço vai aumentar, cada vez que o item é comprado. Se o preço inicial for 100, e você colocar 1%, vai aumentar 10. - Em
AUMENTO_ESTOQUE?você define se o estoque vai ser reposto (1) ou não (0).
Estas informações estão também (em inglês) em um dos NPCs da demo.
Código
#==============================================================================
# ■ 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
@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.help_window = @help_window
@sell_window = Window_ShopSell.new(@store)
@sell_window.active = false
@sell_window.visible = false
@sell_window.help_window = @help_window
@status_window = Window_ShopStatus.new
@status_window.visible = false
Graphics.transition
loop do
Graphics.update
Input.update
update
if $scene != self
break
end
end
Graphics.freeze
@help_window.dispose
@command_window.dispose
@gold_window.dispose
@dummy_window.dispose
@buy_window.dispose
@sell_window.dispose
@status_window.dispose
end
#--------------------------------------------------------------------------
def update
@help_window.update
@command_window.update
@gold_window.update
@dummy_window.update
@buy_window.update
@sell_window.update
@status_window.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
@buy_window.refresh
@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
@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
@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
@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, 128, 368, 352)
@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, 128, 368, 352)
@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
endDownload e ficha técnica
- Download (clique com o botão esquerdo do mouse ou toque no link)
- Desenvolvedor, publisher e/ou distribuidor: Astro_mech
- Sistema(s): Windows 98/98SE/Me/2000/XP/Vista/7
- Tamanho: 189 KB (pacote de instalação e/ou espaço em disco)
- Licença: Grátis
- Categoria: Programação XP
- Tag: RPG Maker XP
- Adicionado por: LichKing
- Acessos: 42
Observação: se você gostou deste post ou ele lhe foi útil de alguma forma, por favor considere apoiar financeiramente a Gaming Room. Fico feliz só de ajudar, mas a contribuição do visitante é muito importante para que este site continua existindo e para que eu possa continuar provendo este tipo de conteúdo e melhorar cada vez mais. Acesse aqui e saiba como. Obrigado!
