Mundo Maker
¡Bienvenid@ a Mundo Maker!

¿Quieres aprender todo sobre el RPG Maker?



Regístrate y forma parte de Mundo Maker.

[Colectivo] Independent Inventory System

Ver el tema anterior Ver el tema siguiente Ir abajo

RPG Maker XP [Colectivo] Independent Inventory System

Mensaje por silvanash el 2018-07-19, 15:29

Basado en la idea de Wecoc del post de aportar ideas y joder, qué mal funciona el puto foro con todos los putos smilies animados.

Código:
#==============================================================================#
# Independent Inventory system
# silvanash and whatever

# Makes actors use independent inventory lists instead of sharing items
# among the party. Actors can only hold onto "items"; the system won't
# work on weapons/protectors, but a scripter can code that in.
# This means that only the actor that is holding a certain item can use it
# during a battle.
# The script comes with a config module where you can set up how many items
# an actor can carry; feel free to make pack-mule characters whose only
# function is the game is to carry as many items as possible to fights.

# WARNING: this script doesn't change the game's default menu. I only edited
# Scene_Battle, so the game may break on other situations. Not that I care.

#==============================================================================#

module SLV_Config
  
  MAX_ACTOR_INVENTORY_SIZE = {
    #database_id => amount,
    1 => 10,
  }
  MAX_ACTOR_INVENTORY_SIZE.default = 10

end

class Game_Actor < Game_Battler

  attr_reader :slv_inventory
  
  alias independent_inventory_init initialize unless $@
  
  def initialize(actor_id)
    independent_inventory_init(actor_id)
    @slv_inventory = {}
  end
  
  def slv_max_gainable_items
    v = 0
    self.slv_inventory.each_value {|i| v += i if i > 0}
    return [SLV_Config::MAX_ACTOR_INVENTORY_SIZE[@actor_id] - v, 0].max
  end
  
  def slv_gain_item(id, n = 1)
    self.slv_inventory[id] = 0 if self.slv_inventory[id].nil?
    self.slv_inventory[id] += [n, slv_max_gainable_items].min
  end
  
  def slv_lose_item(id, n = 1)
    return if self.slv_inventory[id].nil? or self.slv_inventory[id] <= 0
    self.slv_inventory[id] = [0, self.slv_inventory[id] - n].max
  end
  
  def item_can_use?(item_id)
    if self.slv_inventory[item_id].nil? or self.slv_inventory[item_id] <= 0
      return false
    end
    occasion = $data_items[item_id].occasion
    # If in battle
    if $game_temp.in_battle
      return (occasion == 0 or occasion == 1)
    end
    return (occasion == 0 or occasion == 2)
  end
  
end

class Window_slv_Item < Window_Selectable
  
  def initialize(actor = nil)
    super(0, 64, 640, 416)
    @column_max = 2
    refresh(actor)
    self.index = 0
    if $game_temp.in_battle
      self.y = 64
      self.height = 256
      self.back_opacity = 160
    end
  end

  def refresh(actor)
    if self.contents != nil
      self.contents.dispose
      self.contents = nil
    end
    return if actor.nil?
    @data = []
    for i in 1...$data_items.size
      if !actor.slv_inventory[i].nil? and actor.slv_inventory[i] > 0
        @data.push($data_items[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, actor)
      end
    end
  end
  
  def draw_item(index, actor)
    item = @data[index]
    number = actor.slv_inventory[item.id]
    if actor.item_can_use?(item.id)
      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
  
  def item
    return @data[self.index]
  end
  
  def update_help
    @help_window.set_text(self.item == nil ? "" : self.item.description)
  end
  
end

class Scene_Battle
  
  def start_item_select
    @item_window = Window_slv_Item.new if @item_window.nil?
    @item_window.refresh(@active_battler)
    @item_window.help_window = @help_window
    @actor_command_window.active = false
    @actor_command_window.visible = false
  end
  
  def update_phase3_item_select
    @item_window.visible = true
    @item_window.update
    if Input.trigger?(Input::B)
      $game_system.se_play($data_system.cancel_se)
      end_item_select
      return
    end
    if Input.trigger?(Input::C)
      @item = @item_window.item
      if !@active_battler.item_can_use?(@item.id)
        $game_system.se_play($data_system.buzzer_se)
        return
      end
      $game_system.se_play($data_system.decision_se)
      @active_battler.current_action.item_id = @item.id
      @item_window.visible = false
      if @item.scope == 1
        start_enemy_select
      elsif @item.scope == 3 or @item.scope == 5
        start_actor_select
      else
        end_item_select
        phase3_next_actor
      end
      return
    end
  end
  
  def make_item_action_result
    @item = $data_items[@active_battler.current_action.item_id]
    unless @active_battler.item_can_use?(@item.id)
      @phase4_step = 1
      return
    end
    @active_battler.slv_lose_item(@item.id, 1) if @item.consumable
    @help_window.set_text(@item.name, 1)
    @animation1_id = @item.animation1_id
    @animation2_id = @item.animation2_id
    @common_event_id = @item.common_event_id
    index = @active_battler.current_action.target_index
    target = $game_party.smooth_target_actor(index)
    set_target_battlers(@item.scope)
    for target in @target_battlers
      target.item_effect(@item)
    end
  end
  
end

La idea original era que cada actor tuviera un inventario separado, de modo que la poción que tiene Alexis la puede usar él y nadie más, porque es un egoísta de mierda.

Mi apaño gestiona inventarios separados. Los objectos de cada actor se guardan en la misma estructura de datos que Game_Party, tal que:

Código:
actor = $game_party.actors[0]
actor.slv_gain_item(database_id, amount = 1)
actor.slv_lose_item(database_id, amount = 1)

También hay un método can_use_item?, que está copiado de Game_Party pero dentro de Game_Actor para comprobar inventario interno en lugar de toda la party.

He editado la batalla para usar una Window_slv_Item, que dibuja sólo los items de cada actor. La batalla también está editada para que funcione con esa lista.

Lo que falta por hacer:

Editar el menú principal o whatever, para añadir métodos que gestionen el inventario. Los métodos están escritos, pero no se usan en ninguna parte. De momento, la única forma de cambiar inventario es mediante llamada a script. Hacer la interfaz no debería ser difícil, pero es un coñazo y requiere más esfuerzo del que estoy dispuesto a invertir en un script que nadie va a usar.

También hace falta un método para "recoger" los objetos en batalla. La idea es que cuando un actor muere, todo su inventario cae al suelo, y entonces los otros actores pueden usar su turno para recoger/usar uno de los objetos del suelo. Problema: race conditions. No hay nada que impida que varios actores intenten usar la última copia de un objeto del suelo. La otra opción es no tirar los objetos al suelo, de modo que cuando el actor reviva, tenga todo su inventario encima en lugar de tener que recogerlo.

Créditos: borradme de la cabecera del script si queréis.

Compatibilidades: incompatible con todo, incluso con otros scripts que haya hecho yo. Alguien debería programar un sistema de batalla modular, donde sea más fácil añadir/quitar/editar métodos. Hacer apaños y rezar para que el resto de la gente sepa editar scripts para no romper el juego es estúpido.
avatar
silvanash
Aventurero
Aventurero

0/3

Créditos 1666

Gracias : 239

Volver arriba Ir abajo

RPG Maker XP Re: [Colectivo] Independent Inventory System

Mensaje por Alcacho el 2018-07-19, 21:24

Jajajjaj me mataste de risa Very Happy Smile Baile Stop Pirate Cool Colega
avatar
Alcacho
Iniciado
Iniciado

1/3

Créditos 86

Gracias : 8

Volver arriba Ir abajo

RPG Maker XP Re: [Colectivo] Independent Inventory System

Mensaje por Wecoc el 2018-07-20, 16:08

@Alcacho Eso es flood. Ya van varias veces que te saltas las normas y ésta vez de modo muy descarado.
Te he puesto warn. Lee las normas para más información.

Cuando propuse la idea no pensé que fuera necesario crear una Window_Item distinta, más bien solo aplicarle un filtro a la misma para mostrar solo los items del actor seleccionado. Está el tema del target, entiendo que aunque cada actor tenga sus items cuando los selecciona puede aplicarlo a otro actor si lo desea. Eso sí, el target "Usuario" en el menú funciona igual que "Aliado" pero en este caso habría que hacer como en batalla y restringuirlo solo al seleccionado.

Poder indicar desde el menú quien usa el item a parte de a quien se usa (de mismo modo como funcionan las habiliades) puede ser interesante para hacer items más "mágicos", por ejemplo se puede hacer un item que al usarlo gaste cierta magia o cosas así.

Cuando un personaje muere ya no puede usar sus items así que estaría bien añadir la opción de pasarse items entre personajes.

Seguramente probaré a hacerle alguna cosa para ayudar en el colectivo.
avatar
Wecoc
Administrador
Administrador



Créditos 12208

Gracias : 632

Volver arriba Ir abajo

RPG Maker XP Re: [Colectivo] Independent Inventory System

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.