Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[XP] Extended Shop

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [XP] Extended Shop

Mensaje por Wecoc el 2017-10-23, 06:17

Este script es una extensión de la tienda que le asigna una ID concreta a cada una. No reescribe la tienda por defecto sino que va totalmente aparte.
Para usarlo hay que usar esta llamada de script: call_shop(SHOP_ID) cambiando SHOP_ID por la ID de la tienda a cargar.

Usa la interfaz por defecto del maker para la tienda pero añade muchas funciones extras. Algunas de ellas si se usan habría que modificar la inferfaz para que se vean, pero eso lo dejo en vuestras manos a la hora de personalizaros el sistema de tienda para vuestro juego. Si alguien quiere postear sus propias versiones de interfaz del script puede hacerlo sin problema aquí.

Las tiendas ahora se configuran al inicio del script, en el apartado Scene_Title :set_shop_data. Puse una de ejemplo.
Ahí defines los items que contiene por defecto esa tienda y la cantidad de cada uno. También se pueden definir otras propiedades que podréis ver en el apartado de RPG::Shop, como el modo (normal, solo comprar, solo vender), el dinero del mercader, taxa de precios al comprar/vender o items que se pueden vender en esa tienda. En el mismo apartado veréis algunos atajos como uno para hacer una tienda con todos los items posibles.

ATENCIÓN: Los cambios de la tienda son guardados cuando guardas el proyecto así que si se usa este script es probable que las partidas guardadas anteriormente ya no funcionen bien.

En resumen, es un script para gente con cierto conocimiento de scripts, para que lo uséis de base para crearos una tienda como Dios manda en vuestro proyecto. Sé que hay algunos otros scripts de uso de tiendas con ID pero quise hacerlo de modo distinto, en mi opinión algo más amigable que esos.

Código:
#==============================================================================
# ** [XP] Extended Shop v1.0
#------------------------------------------------------------------------------
# Autor: Wecoc (no requiere créditos)
#------------------------------------------------------------------------------
# Este script es una extensión de la tienda que le asigna una ID concreta
# a cada una. No reescribe la tienda por defecto sino que va totalmente aparte.
# Para usarlo hay que usar esta llamada de script:
#     call_shop(SHOP_ID)
#
# Hay que definir los parámetros únicos cada tienda al inicio del script,
# dentro del apartado Scene_Title :set_shop_data.
#
# Los cambios de la tienda son guardados así que si se usa este script es
# probable que las partidas guardadas anteriormente ya no funcionen bien.
#==============================================================================

#==============================================================================
# ** Scene_Title
#==============================================================================

class Scene_Title
  def set_shop_data
    $game_shops = [nil]
    #--------------------------------------------------------------------------
    # Aquí se definen todas las tiendas tal como se hace con la de ejemplo:
    #--------------------------------------------------------------------------
    
    $game_shops[1] = RPG::Shop.new(1) # Tienda de ID 1
    $game_shops[1].shop_goods[[0, 1]] = 5   # Item de id 1 - cantidad 5
    $game_shops[1].shop_goods[[0, 2]] = 1   # Item de id 2 - cantidad 1
    $game_shops[1].shop_goods[[1, 1]] = 2   # Arma de id 1 - cantidad 2
    $game_shops[1].shop_goods[[2, 1]] = 1   # Protector de id 1 - cantidad 1
    
    #--------------------------------------------------------------------------
    for i in 1...$game_shops.size
      shop = $game_shops[i]
      shop.set_current_as_default
    end
  end
  
  alias ext_shop_update update
  def update
    set_shop_data if $game_shops.nil?
    ext_shop_update
  end
end

#==============================================================================
# ** Scene_Save
#==============================================================================

class Scene_Save < Scene_File
  alias ext_shop_write_data write_save_data
  def write_save_data(file)
    ext_shop_write_data(file)
    Marshal.dump($game_shops, file)
  end
end

#==============================================================================
# ** Scene_Load
#==============================================================================

class Scene_Load < Scene_File
  alias ext_shop_read_data read_save_data
  def read_save_data(file)
    ext_shop_read_data(file)
    $game_shops = Marshal.load(file)
  end
end

#==============================================================================
# ** RPG::Shop
#==============================================================================

module RPG
  class Shop
    #------------------------------------------------------------------------
    attr_accessor :shop_id          # ID de la tienda
    attr_accessor :mode             # 0 - Default, 1 - Comprar, 2 - Vender
    attr_accessor :shop_goods       # Hash de items que se pueden comprar
    attr_accessor :gold             # Dinero disponible
    attr_accessor :buy_tax          # Taxa de precios al comprar
    attr_accessor :sell_tax         # Taxa de precios al vender
    attr_accessor :sellable_goods   # Array de items que se pueden vender
    attr_accessor :sold_list        # Añadir vendidos en su lista a vender
    #------------------------------------------------------------------------
    # * Initialize
    #------------------------------------------------------------------------
    def initialize(shop_id)
      @shop_id = shop_id
      @mode = 0
      @shop_goods = {}
      @shop_goods.default = 0
      @gold = 9999999
      @buy_tax = 1.0
      @sell_tax = 0.5
      @sellable_goods = []
      set_sellable_to_all
      @sold_list = true
    end
    #------------------------------------------------------------------------
    # * Obtener ID de la tienda
    #------------------------------------------------------------------------
    def id
      @shop_id
    end
    #------------------------------------------------------------------------
    # * Obtener si se puede comprar
    #------------------------------------------------------------------------
    def can_buy?
      return (@mode != 2)
    end
    #------------------------------------------------------------------------
    # * Obtener si se puede vender
    #------------------------------------------------------------------------
    def can_sell?
      return (@mode != 1)
    end
    #------------------------------------------------------------------------
    # * Definir una tienda como modo Dios (todos los items disponibles)
    #------------------------------------------------------------------------
    def set_god_shop
      for i in 1...$data_items.size
        @shop_goods[[0, i]] = 99
      end
      for i in 1...$data_weapons.size
        @shop_goods[[1, i]] = 99
      end
      for i in 1...$data_armors.size
        @shop_goods[[2, i]] = 99
      end
    end
    #------------------------------------------------------------------------
    # * Definir tienda en la que se puede vender cualquier item (default)
    #------------------------------------------------------------------------
    def set_sellable_to_all
      for i in 1...$data_items.size
        next if $data_items[i].price == 0
        @sellable_goods << [0, i]
      end
      for i in 1...$data_weapons.size
        next if $data_weapons[i].price == 0
        @sellable_goods << [1, i]
      end
      for i in 1...$data_armors.size
        next if $data_armors[i].price == 0
        @sellable_goods << [2, i]
      end
    end
    #------------------------------------------------------------------------
    attr_accessor :default_shop_goods, :default_gold
    #------------------------------------------------------------------------
    # * Definir valores por defecto
    #------------------------------------------------------------------------
    def set_current_as_default
      @default_shop_goods = @shop_goods.clone
      @default_gold = @gold
    end
    #------------------------------------------------------------------------
    # * Volver a los valores por defecto
    #------------------------------------------------------------------------
    def reset_default
      for i in @default_shop_goods.keys
        value = @default_shop_goods[i]
        if @shop_goods.keys.include?(i)
          @shop_goods[i] = [@shop_goods[i], value].max
        else
          @shop_goods[i] = value
        end
      end
      @gold = [@gold, @default_gold].max
    end
  end
end

#==============================================================================
# ** Window_ExtShopCommand
#==============================================================================

class Window_ExtShopCommand < Window_Selectable
  #--------------------------------------------------------------------------
  # * Object Initialization
  #--------------------------------------------------------------------------
  def initialize(shop_id)
    super(0, 64, 480, 64)
    self.contents = Bitmap.new(width - 32, height - 32)
    @shop_id = shop_id
    @item_max = 3
    @column_max = 3
    @commands = ["Comprar", "Vender", "Salir"]
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    shop = $game_shops[@shop_id]
    draw_item(0, shop.can_buy?)
    draw_item(1, shop.can_sell?)
    draw_item(2, true)
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #--------------------------------------------------------------------------
  def draw_item(index, enabled_mode = false)
    x = 4 + index * 160
    if enabled_mode
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    self.contents.draw_text(x, 0, 128, 32, @commands[index])
  end
end

#==============================================================================
# ** Window_ExtShopBuy
#==============================================================================

class Window_ExtShopBuy < Window_Selectable
  #--------------------------------------------------------------------------
  attr_reader :item_max
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(shop_id)
    super(0, 128, 368, 352)
    @shop_id = shop_id
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * Item Acquisition
  #--------------------------------------------------------------------------
  def item
    return @data[self.index][0] rescue nil
  end
  #--------------------------------------------------------------------------
  # * Count Acquisition
  #--------------------------------------------------------------------------
  def count
    return @data[self.index][1] rescue nil
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    shop = $game_shops[@shop_id]
    for k in shop.shop_goods.keys.reverse
      item_id = k[1]
      count = shop.shop_goods[k]
      item = case k[0]
        when 0 then $data_items[item_id]
        when 1 then $data_weapons[item_id]
        when 2 then $data_armors[item_id]
      end
      if item != nil
        @data.push([item, count])
      end
    end
    @item_max = @data.size
    if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #--------------------------------------------------------------------------
  def draw_item(index)
    item, count = *@data[index]
    shop = $game_shops[@shop_id]
    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
    price = (item.price.to_f * shop.buy_tax).to_i
    if price <= $game_party.gold and number < 99
      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, 212, 32, item.name, 0)
    self.contents.draw_text(x + 240, y, 88, 32, item.price.to_s, 2)
  end
  #--------------------------------------------------------------------------
  # * Help Text Update
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(self.item == nil ? "" : self.item.description)
  end
end

#==============================================================================
# ** Window_ExtShopSell
#==============================================================================

class Window_ExtShopSell < Window_Selectable
  #--------------------------------------------------------------------------
  attr_reader :item_max
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(shop_id)
    super(0, 128, 640, 352)
    @shop_id = shop_id
    @column_max = 2
    refresh
    self.index = 0
  end
  #--------------------------------------------------------------------------
  # * Getting Items
  #--------------------------------------------------------------------------
  def item
    return @data[self.index]
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  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)
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
  #--------------------------------------------------------------------------
  # * Draw Item
  #--------------------------------------------------------------------------
  def draw_item(index)
    item = @data[index]
    shop = $game_shops[@shop_id]
    case item
    when RPG::Item
      number = $game_party.item_number(item.id)
      enabled = shop.sellable_goods.include?([0, item.id])
    when RPG::Weapon
      number = $game_party.weapon_number(item.id)
      enabled = shop.sellable_goods.include?([1, item.id])
    when RPG::Armor
      number = $game_party.armor_number(item.id)
      enabled = shop.sellable_goods.include?([2, item.id])
    end
    if enabled
      self.contents.font.color = normal_color
    else
      self.contents.font.color = disabled_color
    end
    x = 4 + index % 2 * (288 + 32)
    y = index / 2 * 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, 212, 32, item.name, 0)
    self.contents.draw_text(x + 240, y, 16, 32, ":", 1)
    self.contents.draw_text(x + 256, y, 24, 32, number.to_s, 2)
  end
  #--------------------------------------------------------------------------
  # * Help Text Update
  #--------------------------------------------------------------------------
  def update_help
    @help_window.set_text(self.item == nil ? "" : self.item.description)
  end
end

#==============================================================================
# ** Window_ExtShopNumber
#==============================================================================

class Window_ExtShopNumber < Window_Base
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(shop_id)
    super(0, 128, 368, 352)
    self.contents = Bitmap.new(width - 32, height - 32)
    @shop_id = shop_id
    @item = nil
    @max = 1
    @price = 0
    @number = 1
  end
  #--------------------------------------------------------------------------
  # * Set Items, Max Quantity, and Price
  #--------------------------------------------------------------------------
  def set(item, max, price)
    @item = item
    @max = max
    @price = price
    @number = 1
    refresh
  end
  #--------------------------------------------------------------------------
  # * Set Inputted Quantity
  #--------------------------------------------------------------------------
  def number
    return @number
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  def refresh
    self.contents.clear
    draw_item_name(@item, 4, 96)
    self.contents.font.color = normal_color
    self.contents.draw_text(272, 96, 32, 32, "×")
    self.contents.draw_text(308, 96, 24, 32, @number.to_s, 2)
    self.cursor_rect.set(304, 96, 32, 32)
    domination = $data_system.words.gold
    cx = contents.text_size(domination).width
    total_price = @price * @number
    self.contents.font.color = normal_color
    self.contents.draw_text(4, 160, 328-cx-2, 32, total_price.to_s, 2)
    self.contents.font.color = system_color
    self.contents.draw_text(332-cx, 160, cx, 32, domination, 2)
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    super
    if self.active
      if Input.repeat?(Input::RIGHT) and @number < @max
        $game_system.se_play($data_system.cursor_se)
        @number += 1
        refresh
      end
      if Input.repeat?(Input::LEFT) and @number > 1
        $game_system.se_play($data_system.cursor_se)
        @number -= 1
        refresh
      end
      if Input.repeat?(Input::UP) and @number < @max
        $game_system.se_play($data_system.cursor_se)
        @number = [@number + 10, @max].min
        refresh
      end
      if Input.repeat?(Input::DOWN) and @number > 1
        $game_system.se_play($data_system.cursor_se)
        @number = [@number - 10, 1].max
        refresh
      end
    end
  end
end

#==============================================================================
# ** Window_ExtShopStatus
#==============================================================================

class Window_ExtShopStatus < Window_Base
  #--------------------------------------------------------------------------
  # * Initialize
  #--------------------------------------------------------------------------
  def initialize(shop_id)
    super(368, 128, 272, 352)
    self.contents = Bitmap.new(width - 32, height - 32)
    @shop_id = shop_id
    @item = nil
    refresh
  end
  #--------------------------------------------------------------------------
  # * Refresh
  #--------------------------------------------------------------------------
  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, "Num. en posesión")
    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
        c = sprintf("%+d", change)
        self.contents.draw_text(124, 64 + 64 * i, 112, 32, c, 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
  #--------------------------------------------------------------------------
  # * Set Item
  #--------------------------------------------------------------------------
  def item=(item)
    if @item != item
      @item = item
      refresh
    end
  end
end

#==============================================================================
# ** Scene_ExtShop
#==============================================================================

class Scene_ExtShop
  def initialize(shop_id)
    @shop_id = shop_id
  end
  #--------------------------------------------------------------------------
  # * Main
  #--------------------------------------------------------------------------
  def main
    @shop = $game_shops[@shop_id]
    @help_window = Window_Help.new
    @command_window = Window_ExtShopCommand.new(@shop_id)
    @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_ExtShopBuy.new(@shop_id)
    @buy_window.active = false
    @buy_window.visible = false
    @buy_window.help_window = @help_window
    @sell_window = Window_ExtShopSell.new(@shop_id)
    @sell_window.active = false
    @sell_window.visible = false
    @sell_window.help_window = @help_window
    @number_window = Window_ExtShopNumber.new(@shop_id)
    @number_window.active = false
    @number_window.visible = false
    @status_window = Window_ExtShopStatus.new(@shop_id)
    @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
    @number_window.dispose
    @status_window.dispose
  end
  #--------------------------------------------------------------------------
  # * Update
  #--------------------------------------------------------------------------
  def update
    @help_window.update
    @command_window.update
    @gold_window.update
    @dummy_window.update
    @buy_window.update
    @sell_window.update
    @number_window.update
    @status_window.update
    if @command_window.active
      update_command
      return
    end
    if @buy_window.active
      update_buy
      return
    end
    if @sell_window.active
      update_sell
      return
    end
    if @number_window.active
      update_number
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Update Command
  #--------------------------------------------------------------------------
  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  # Comprar
        if !@shop.can_buy?
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        $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  # Vender
        if !@shop.can_sell?
          $game_system.se_play($data_system.buzzer_se)
          return
        end
        $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
      when 2  # Salir
        $game_system.se_play($data_system.decision_se)
        $scene = Scene_Map.new
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Update Buy
  #--------------------------------------------------------------------------
  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
      @status_window.visible = false
      @status_window.item = nil
      @help_window.set_text("")
      return
    end
    if Input.trigger?(Input::C)
      @item = @buy_window.item
      if @item == nil or @item.price > $game_party.gold
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      case @item
      when RPG::Item
        number = $game_party.item_number(@item.id)
        count = @shop.shop_goods[[0, @item.id]]
      when RPG::Weapon
        number = $game_party.weapon_number(@item.id)
        count = @shop.shop_goods[[1, @item.id]]
      when RPG::Armor
        number = $game_party.armor_number(@item.id)
        count = @shop.shop_goods[[2, @item.id]]
      end
      if number == 99 or count == 0
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      price = (@item.price.to_f * @shop.buy_tax).to_i
      max = @item.price == 0 ? 99 : $game_party.gold / price
      max = [max, 99 - number].min
      max = [count, max].min
      @buy_window.active = false
      @buy_window.visible = false
      @number_window.set(@item, max, price)
      @number_window.active = true
      @number_window.visible = true
    end
  end
  #--------------------------------------------------------------------------
  # * Update Sell
  #--------------------------------------------------------------------------
  def update_sell
    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
      @status_window.item = nil
      @help_window.set_text("")
      return
    end
    if Input.trigger?(Input::C)
      @item = @sell_window.item
      @status_window.item = @item
      if @item == nil
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      case @item
      when RPG::Item
        number = $game_party.item_number(@item.id)
        sellable = @shop.sellable_goods.include?([0, @item.id])
      when RPG::Weapon
        number = $game_party.weapon_number(@item.id)
        sellable = @shop.sellable_goods.include?([1, @item.id])
      when RPG::Armor
        number = $game_party.armor_number(@item.id)
        sellable = @shop.sellable_goods.include?([2, @item.id])
      end
      if !sellable
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      max = number
      @sell_window.active = false
      @sell_window.visible = false
      price = (@item.price.to_f * @shop.sell_tax).to_i
      count = (@shop.gold.to_f / price).floor
      max = [count, max].min
      @number_window.set(@item, max, price)
      @number_window.active = true
      @number_window.visible = true
      @status_window.visible = true
    end
  end
  #--------------------------------------------------------------------------
  # * Update Number
  #--------------------------------------------------------------------------
  def update_number
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      @number_window.active = false
      @number_window.visible = false
      case @command_window.index
      when 0  # buy
        @buy_window.active = true
        @buy_window.visible = true
      when 1  # sell
        @sell_window.active = true
        @sell_window.visible = true
        @status_window.visible = false
      end
      return
    end
    if Input.trigger?(Input::C)
      $game_system.se_play($data_system.shop_se)
      @number_window.active = false
      @number_window.visible = false
      case @command_window.index
      when 0  # Comprar
        buy_process
      when 1  # Vender
        sell_process
      end
      return
    end
  end
  #--------------------------------------------------------------------------
  # * Proceso: Comprar
  #--------------------------------------------------------------------------
  def buy_process
    price = (@item.price.to_f * @shop.buy_tax).to_i
    number = @number_window.number
    $game_party.lose_gold(number * price)
    @shop.gold += number * price
    case @item
    when RPG::Item
      $game_party.gain_item(@item.id, number)
      array = [0, @item.id]
    when RPG::Weapon
      $game_party.gain_weapon(@item.id, number)
      array = [1, @item.id]
    when RPG::Armor
      $game_party.gain_armor(@item.id, number)
      array = [2, @item.id]
    end
    @shop.shop_goods[array] -= number
    if @shop.shop_goods[array] <= 0
      @shop.shop_goods.except!(array)
    end
    @gold_window.refresh
    @buy_window.refresh
    @buy_window.index = [@buy_window.index, @buy_window.item_max - 1].min
    @status_window.refresh
    @buy_window.active = true
    @buy_window.visible = true
  end
  #--------------------------------------------------------------------------
  # * Proceso: Vender
  #--------------------------------------------------------------------------
  def sell_process
    price = (@item.price.to_f * @shop.sell_tax).to_i
    number = @number_window.number
    $game_party.gain_gold(number * price)
    @shop.gold -= number * price
    case @item
    when RPG::Item
      $game_party.lose_item(@item.id, number)
      array = [0, @item.id]
    when RPG::Weapon
      $game_party.lose_weapon(@item.id, number)
      array = [1, @item.id]
    when RPG::Armor
      $game_party.lose_armor(@item.id, number)
      array = [2, @item.id]
    end
    if @shop.shop_goods.keys.include?(array)
      @shop.shop_goods[array] += number
    elsif @shop.sold_list == true
      @shop.shop_goods[array] = number
    end
    @gold_window.refresh
    @sell_window.refresh
    @status_window.refresh
    @sell_window.active = true
    @sell_window.visible = true
    @status_window.visible = false
  end
end

#==============================================================================
# ** Hash
#==============================================================================

class Hash
  def except(*keys)
    dup.except!(*keys)
  end
  def except!(*keys)
    keys.each { |key| delete(key) }
    self
  end
end

#==============================================================================
# ** Interpreter
#==============================================================================

class Interpreter
  def call_shop(shop_id)
    $scene = Scene_ExtShop.new(shop_id)
  end
end

Cualquier duda me la comentáis aquí.


Última edición por Wecoc el 2017-11-06, 13:00, editado 1 vez
avatar
Wecoc
Administrador
Administrador



Créditos 12205

Gracias : 632

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Extended Shop

Mensaje por xXIsrael0499Xx el 2017-10-23, 09:53

Oh valla muy interesante, habría que probar a ver que tal, me gusta la idea de personalizar de esta forma la tienda y eso, esta muy bien, así que gracias por compartirnos este pedazo de script.
avatar
xXIsrael0499Xx
Veterano
Veterano

0/3

Créditos 2036

Gracias : 112

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Extended Shop

Mensaje por Wecoc el 2017-11-01, 06:04

De nada, gracias por tu interés.

____________________________

Voy a mostraros lo que se puede hacer con este script con más detalle, a modo de tutorial. Ya lo comenté por encima pero supongo que no viene mal poner un ejemplo de cada cosa.

Tal como expliqué las tiendas se definen al inicio, con un formato así:

$game_shops[ID] = RPG::Shop.new(ID)

Cambiando ID por su índice de tienda. Luego justo debajo se definen los cambios usando igualmente $game_shops[ID], tal como se ve en el propio ejemplo que ofrece el script. Esa misma llamada de script se puede hacer desde cualquier otra parte para modificar cosas de la tienda en cualquier lado.

Recordado esto, respondo qué se puede cambiar. Hay que tener en cuenta que para usar debidamente algunas de estas opciones habrá que plantear también cambios en la UI de la tienda para que se muestre todo como debe, como ya comenté.

- ¿Cómo añadir un objeto, arma o protector a la tienda?

$game_shops[ID].shop_goods[[TYPE, Item ID]] = VALUE

Parámetros:
TYPE - 0: Objeto, 1: Arma, 2: Protector
Item ID - Índice en la base de datos de ese item
VALUE - Número de objetos de ese tipo que posee la tienda

Igualar el valor a 0 vendría a ser lo mismo que quitar el objeto de la lista.

- ¿Cómo hacer que en esa tienda solo se pueda comprar o vender?

$game_shops[ID].mode = MODE

Parámetros:
MODE - 0: Normal, 1: Solo comprar, 2: Solo vender

- ¿Cómo definir de cuanto dinero dispone el comerciante?

$game_shops[ID].gold = VALUE

Parámetros:
VALUE - Dinero del comerciante

Por defecto es 9999999, lo cual a efectos prácticos vendría a ser como si fuera ilimitado.

- ¿Cómo definir las taxas de compra y venta?

$game_shops[ID].buy_tax = BUY_TAX
$game_shops[ID].sell_tax = SELL_TAX

Parámetros:
BUY_TAX - Multiplicador al precio de los items al comprarlos de esa tienda. Por defecto 1.0
SELL_TAX - Multiplicador al precio de los items al venderlos en esa tienda. Por defecto 0.5

Propuesta: Esto es ampliable de modo que haya Buy tax y Sell tax concretos para un determinado item (a parte del valor global aquí definido). Para hacer eso habría que definirlo como nuevo parámetro del item, con Data File Save. No solo eso sino que se podría ir más allá y hacer equipos que afectaran al ratio de compra o venta (también con un parámetro mediante Data File Save) o ya casos complicados combinando ambas propiedades, es decir equipo que afecta a la taxa de compra o venta de otros items concretos. Hay todo un mundo de posibilidades ahí.

- ¿Cómo hacer que cierto item, arma o protector no se pueda vender en esa tienda?

Modo 1: Definir los que se pueden vender

Por defecto todos se pueden vender así que primero hay que limpiar la array que los contiene de modo que ninguno se pueda vender.

$game_shops[ID].sellable_goods.clear

Luego se puede añadir uno por uno los que sí se pueden vender.

$game_shops[ID].sellable_goods.push([TYPE, Item ID])

Modo 2: Definir los que NO se pueden vender

En el caso de que todos se puedan vender como siempre menos unos pocos simplemente se pueden quitar esos de la lista.

$game_shops[ID].sellable_goods.delete([TYPE, Item ID])

Parámetros:
TYPE - 0: Objeto, 1: Arma, 2: Protector
Item ID - Índice en la base de datos de ese item

- ¿Cómo configurar si al venderle un item este se le añade a su lista de items para vender o no?

$game_shops[ID].sold_list = VALUE

Parámetros:
VALUE - true: Se añaden a la lista, false: No se añaden. Por defecto vale true.

- ¿Cómo hacer una tienda modo Dios? (con todos los items/armas/protectores disponibles)

$game_shops[ID].set_god_shop

- ¿Cómo recuperar el 'estado inicial' de una tienda?

$game_shops[ID].reset_default

Con esto se recuperarán los datos tal como se han definido inicialmente: lista de items con sus valores, dinero... todo.

Propuesta: Un posible engine que podéis hacer usando este es resetear las tiendas según la hora virtual del juego (si tiene ciclo día/noche), de modo que en cierta hora del día todas las tiendas recuperen su estado normal.

- ¿Cómo definir el estado actual de la tienda como 'estado inicial'?

$game_shops[ID].set_current_as_default

____________________________

Esa es la configuración que ofrece el script. Eso es ampliable, ahora que cada tienda va por ID definirles parámetros no es complicado.
De hecho como propuesta para quien quiera practicar script (o para quien quiera implementarlo en su juego) os dejo algunas cosas que se pueden definir como parámetro nuevo en el script, a ver si alguien se anima a intentarlo ;)

Propuesta: Recrear los parámetros que ofrece el script Shop Upgrade para VX Ace. Estos son fondo de escena, imagen portrait del vendedor (que puede ser dinámica según qué compres, etc.) y textos del vendedor al hacer algunas acciones concretas básicas.

Esto es todo, hasta aquí mi tocho-post. Hay que ver cuanto escribo Sweat xD
avatar
Wecoc
Administrador
Administrador



Créditos 12205

Gracias : 632

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Extended Shop

Mensaje por Wecoc el 2017-11-06, 13:21

He hecho un pequeño añadido para este sistema.

Código:
#==============================================================================
# ** [XP] Shop Hidden Conditions v1.0
#------------------------------------------------------------------------------
# Autor: Wecoc (no requiere créditos)
# Este script requiere el script Extended Shop v1.0
#------------------------------------------------------------------------------
# Este add-on permite definir condiciones de aparición de ciertos items
# en la lista de shop goods (objetos para comprar).
# Para hacerlo hay que ir al script Extended Shop, y dentro de set_shop_data
# donde se configura cada tienda definir ahí las condiciones también.
#
# Para definir una condición hay que usar el formato:
#
#   $game_shops[ID].set_hidden_condition(TYPE, ITEM ID, CONDITION)
#
# ID es la id de tienda, TYPE e ITEM ID son para definir el objeto (igual que
# con shop_goods) y CONDITION es una string que será evaluada.
#
# Ejemplo 1: Mostrar item 1 solo si la party tiene nivel 10 o superior
#   $game_shops[1].set_hidden_condition(0, 1, "$game_party.max_level >= 10")
#
# Ejemplo 2: Mostrar armor 4 solo si el actor 3 está en la party
#   $game_shops[1].set_hidden_condition(2, 4, "$game_party.actors.include?(3)")
#
# Ejemplo 3: Mostrar armor 1 si algún actor tiene equipado el accesorio 15
#   $game_shops[1].set_hidden_condition(2, 1, "$game_party.equipped?(4, 15)")
#
#==============================================================================

module RPG
  class Shop
    #------------------------------------------------------------------------
    attr_reader :shop_hidden
    #------------------------------------------------------------------------
    alias shop_hidden_ini initialize unless $@
    def initialize(shop_id)
      shop_hidden_ini(shop_id)
      @shop_hidden = {}
      @shop_hidden.default = "true"
    end
    #------------------------------------------------------------------------
    def get_item(type, item_id)
      case type
      when 0 # Item
        item = $data_items[item_id]
      when 1 # Weapon
        item = $data_weapons[item_id]
      when 2 # Armor
        item = $data_armors[item_id]
      end
      return item
    end
    #------------------------------------------------------------------------
    def set_hidden_condition(type, item_id, condition)
      item = get_item(type, item_id)
      @shop_hidden[item] = condition
    end
    #------------------------------------------------------------------------
    def clear_hidden_condition(type, item_id)
      set_hidden_condition(type, item_id, "true")
    end
  end
end

class Window_ExtShopBuy < Window_Selectable
  def refresh
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    @data = []
    shop = $game_shops[@shop_id]
    for k in shop.shop_goods.keys.reverse
      item_id = k[1]
      count = shop.shop_goods[k]
      item = case k[0]
        when 0 then $data_items[item_id]
        when 1 then $data_weapons[item_id]
        when 2 then $data_armors[item_id]
      end
      next if item.nil?
      next if eval(shop.shop_hidden[item]) != true
      @data.push([item, count])
    end
    @item_max = @data.size
    if @item_max > 0
      self.contents = Bitmap.new(width - 32, row_max * 32)
      for i in 0...@item_max
        draw_item(i)
      end
    end
  end
end

class Game_Party
  def equipped?(slot, id)
    for i in 0...@actors.size
      actor = $game_party.actors[i]
      case slot
      when 0 # Weapon
        return true if actor.weapon_id == id
      when 1 # Shield
        return true if actor.armor1_id == id
      when 2 # Head
        return true if actor.armor2_id == id
      when 3 # Body
        return true if actor.armor3_id == id
      when 4 # Accessory
        return true if actor.armor4_id == id
      end
    end
    return false
  end
end

Este add-on permite definir condiciones de aparición de ciertos items en la lista de shop goods (objetos para comprar). Las instrucciones son simples y estan en el propio script.

Con esto podéis hacer que cierto item/weapon/armor solo aparezca en esa tienda si la party tiene al menos un nivel concreto (se mira el máximo del grupo), o que aparezca solo si algún actor está en la party, o solo si se tiene cierto accesorio equipado... Las condiciones que se os ocurran.

Podéis encadenar varias poniendo and entre ellas en la misma condición.
avatar
Wecoc
Administrador
Administrador



Créditos 12205

Gracias : 632

Volver arriba Ir abajo

RPG Maker XP Re: [XP] Extended Shop

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Permisos de este foro:
No puedes responder a temas en este foro.