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.
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?
TIPO
, você colocará a natureza do item, 0 para itens, 1 armas e 2 para armadurasID
, você vai colocar a ID do item, que você acha na sua Database do RMXP mesmoESTOQUE
, você vai colocar a quantidade disponível, inicial, pra cada itemPREÇO_MÍNIMO
, você vai definir o preço inicial mínimo, que pode aumentar dependendo de quanto você compre delePORCENTAGEM_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.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.
#============================================================================== # ■ 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 end
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!