Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

Chest System

MarkR

Member

Chest system
Version: 2.0
By: Mark Redeman (or MarkR)


Introduction
With this script you can create chests where the player can store or take items, weapons and armors from.

Features
A chest has two properties. The amount of slots it has and whether the items are stackable or not.
  • Stackable.
    Stackable means that the chest can contain more than one of the same type of items on one slot. For example:
    An chest which is stackable can contain 99 Potions on one slot, but a chest which isn’t stackable must have 99 open slots to contain the potions.
    Slots.
    The amount of slots determines how many items a chest can have. A chest which is stackable and has 20 slots can contain 20 different items.

Demo
You can download the demo here.

Script
Code:
#==============================================================================

# ** Game_Chest

#------------------------------------------------------------------------------

# Author: Mark Redeman

# Version: 2.0

# Date: 13-01-2011

# Description:

#  This class handles chests, wich can be used to store items.

#  You can choose the amount of slots a chest contains and wheter an chest is

#   stackable or not. If the chest isn't stackable, 1 slot can only contain 1

#   item. If it's stackable all of the slots can contain an infinite amount

#   of items.

# Instructions: 

#  To create a chest, create a call script wich uses the following lines:

#-------------------------------------------------------------------------------

#            id = 0

#            if $game_map.chests[id] == nil

#              chest = $game_map.chests

#              chest[id] = Game_Chest.new(slots, stackable)

#            end

#-------------------------------------------------------------------------------

#  To open a chest, use the following line (in a call script):

#   $scene = Scene_Chest.new(chest_id)

#  Where chest_id is the ID of the chest.

#-------------------------------------------------------------------------------

#        To add items, weapons or armors to the chest use the following

#         lines:

#            chest = $game_map.chests[id]

#            chest.gain_item(item_id, quantity)

#            chest.gain_weapon(weapon_id, quantity)

#            chest.gain_item(armor_id, quantity)

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

 

class Game_Chest

  attr_reader :max_slots

  attr_reader :stackable

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(max_slots = 60, stackable = false)

    @max_slots = [[max_slots, 2997].min, 0].max

    @stackable = stackable

    # Create amount in possession hash for items, weapons, and armor

    @items   = {}

    @weapons = {}

    @armors  = {}

  end

  #--------------------------------------------------------------------------

  # * Get Number of Items Possessed

  #     item_id : item ID

  #--------------------------------------------------------------------------

  def item_number(item_id)

    # If quantity data is in the hash, use it. If not, return 0

    return @items.include?(item_id) ? @items[item_id] : 0

  end

  #--------------------------------------------------------------------------

  # * Get Number of Weapons Possessed

  #     weapon_id : weapon ID

  #--------------------------------------------------------------------------

  def weapon_number(weapon_id)

    # If quantity data is in the hash, use it. If not, return 0

    return @weapons.include?(weapon_id) ? @weapons[weapon_id] : 0

  end

  #--------------------------------------------------------------------------

  # * Get Amount of Armor Possessed

  #     armor_id : armor ID

  #--------------------------------------------------------------------------

  def armor_number(armor_id)

    # If quantity data is in the hash, use it. If not, return 0

    return @armors.include?(armor_id) ? @armors[armor_id] : 0

  end

  #--------------------------------------------------------------------------

  # * Gain Items (or lose)

  #     item_id : item ID

  #     n       : quantity

  #--------------------------------------------------------------------------

  def gain_item(item_id, n)

    # Update quantity data in the hash.

    if item_id > 0 && (n < 0 || gain_item?($data_items[item_id], n))

      @items[item_id] = [item_number(item_id) + n, 0].max

      return true

    end

    return false

  end

  #--------------------------------------------------------------------------

  # * Gain Weapons (or lose)

  #     weapon_id : weapon ID

  #     n         : quantity

  #--------------------------------------------------------------------------

  def gain_weapon(weapon_id, n)

    # Update quantity data in the hash.

    if weapon_id > 0 && (n < 0 || gain_item?($data_weapons[weapon_id], n))

      @weapons[weapon_id] = [weapon_number(weapon_id) + n, 0].max

      return true

    end

    return false

  end

  #--------------------------------------------------------------------------

  # * Gain Armor (or lose)

  #     armor_id : armor ID

  #     n        : quantity

  #--------------------------------------------------------------------------

  def gain_armor(armor_id, n)

    # Update quantity data in the hash.

    if armor_id > 0 && (n < 0 || gain_item?($data_armors[armor_id], n))

      @armors[armor_id] = [armor_number(armor_id) + n, 0].max

      return true

    end

    return false

  end

  #--------------------------------------------------------------------------

  # * Lose Items

  #     item_id : item ID

  #     n       : quantity

  #--------------------------------------------------------------------------

  def lose_item(item_id, n)

    # Reverse the numerical value and call it gain_item

    gain_item(item_id, -n)

  end

  #--------------------------------------------------------------------------

  # * Lose Weapons

  #     weapon_id : weapon ID

  #     n         : quantity

  #--------------------------------------------------------------------------

  def lose_weapon(weapon_id, n)

    # Reverse the numerical value and call it gain_weapon

    gain_weapon(weapon_id, -n)

  end

  #--------------------------------------------------------------------------

  # * Lose Armor

  #     armor_id : armor ID

  #     n        : quantity

  #--------------------------------------------------------------------------

  def lose_armor(armor_id, n)

    # Reverse the numerical value and call it gain_armor

    gain_armor(armor_id, -n)

  end

  #--------------------------------------------------------------------------

  # * Amount of items

  #--------------------------------------------------------------------------

  def amount_of_items

    number = 0

    (1...$data_items.size).each   {|item|   number += item_number(item)    }

    (1...$data_weapons.size).each {|weapon| number += weapon_number(weapon)}

    (1...$data_armors.size).each  {|armor|  number += armor_number(armor)  }

    return number

  end

  #--------------------------------------------------------------------------

  # * Amount of types

  #--------------------------------------------------------------------------

  def amount_of_types

    number = 0

    $data_items.each  {|item| number += 1 if item_number(item.id)   > 0 }

    $data_weapons.each{|item| number += 1 if weapon_number(item.id) > 0 }

    $data_armors.each {|item| number += 1 if armor_number(item.id)  > 0 }

    return number

  end

  #--------------------------------------------------------------------------

  # * Gain item

  #    item : item

  #    n    : amount of items

  #--------------------------------------------------------------------------

  def gain_item?(item, n = 1)

    if @stackable

      # Check to see if item is allready in chest

      case item

      when RPG::Item

        return true if item_number(item.id) > 0

      when RPG::Weapon

        return true if weapon_number(item.id) > 0

      when RPG::Armor

        return true if armor_number(item.id) > 0

      end

      # If it isn't in the chest, check if there is an open slot

      return @max_slots >= (amount_of_types + 1)

    else

      return @max_slots >= (amount_of_items + n)

    end

  end

end

 

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

# ** Game_Map

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

 

class Game_Map

  attr_accessor :chests

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  alias game_map_chest_initialize_mark initialize

  def initialize

    # Create an array of chests

    @chests = []

    # Call old method

    game_map_chest_initialize_mark

  end

end

 

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

# ** Scene_Chest

#------------------------------------------------------------------------------

# Author: Mark Redeman

# Version: 2.0

# Date: 13-01-2011

# Description: This scene creates a menu where you can store or take items

#               from a chest.

# Instructions: To open the chest menu, call:

#                      $scene = Scene_Chest.new(chest_id)

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

 

class Scene_Chest

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(id)

    # Get an error message, if chest doesn't exist

    if $game_map.chests.size <= id || id < 0

      p 'Wrong chest id'

    end

    @chest_id = id

  end

  #--------------------------------------------------------------------------

  # * Main Processing

  #--------------------------------------------------------------------------

  def main

    # Make sprite set

    @spriteset             = Spriteset_Map.new

    # Make container windows

    @party_window          = Window_Container.new($game_party)

    @chest_window          = Window_Container.new($game_map.chests[@chest_id])

    @chest_window.visible  = false

    # Make command window

    @command_window        = Window_Horizontal_Command.new(['Inventory', 'Chest'])

    @command_window.active = true

    # Make help window

    @help_window = Window_Container_Help.new($game_map.chests[@chest_id])

    # Associate help window

    @party_window.help_window  = @help_window

    @chest_window.help_window = @help_window

    # Execute transition

    Graphics.transition

    # Main loop

    loop do

      # Update game screen

      Graphics.update

      # Update input information

      Input.update

      # Frame update

      update

      # Abort loop if screen is changed

      if $scene != self

        break

      end

    end

    # Prepare for transition

    Graphics.freeze

    # Dispose of windows

    @party_window.dispose

    @chest_window.dispose

    @command_window.dispose

    @help_window.dispose

    @spriteset.dispose

  end

  #--------------------------------------------------------------------------

  # * Frame Update

  #--------------------------------------------------------------------------

  def update

    # Update windows

    @party_window.update

    @chest_window.update

    @command_window.update

    @help_window.update

    # Update command window, if it's active

    if @command_window.active

      update_command

      return

    end

    # Update item window, if it's active

    if @party_window.active

      update_item

      return

    end

    # Update chest window, if it's active

    if @chest_window.active

      update_chest

      return

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update (when item window is active)

  #--------------------------------------------------------------------------

  def update_command

    # Set help text

    @help_window.set_text("Select either the party's or the chest's possessions")

    if Input.trigger?(Input::B)

      # Play cancel SE

      $game_system.se_play($data_system.cancel_se)

      # Switch to map screen

      $scene = Scene_Map.new

      return

    end

    case @command_window.index

    # Display selected container

    when 0 # Inventory

      @party_window.visible  = true

      @chest_window.visible  = false

    when 1 # Chest

      @party_window.visible  = false

      @chest_window.visible  = true

    end

    # If C button was pressed

    if Input.trigger?(Input::C)

      case @command_window.index

      when 0 # Inventory

        # Play decision SE

        $game_system.se_play($data_system.decision_se)

        # Activate item window

        @party_window.active   = true

        # Deactivate command window

        @command_window.active = false

      when 1 # Chest

        # Play decision SE

        $game_system.se_play($data_system.decision_se)

        @chest_window.active  = true

        # Deactivate command window

        @command_window.active = false

      end

      return

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update (when item window is active)

  #--------------------------------------------------------------------------

  def update_item

    # If B button was pressed

    if Input.trigger?(Input::B)

      # Play cancel SE

      $game_system.se_play($data_system.cancel_se)

      @party_window.active   = false

      @command_window.active = true

      return

    end

    # If C button was pressed

    if Input.trigger?(Input::C) || Input.repeat?(Input::C)

      # Get chest 

      chest = $game_map.chests[@chest_id]

      # Get currently selected data on the item window

      item = @party_window.item

      unless  chest.gain_item?(item)

        # Play buzzer SE

        $game_system.se_play($data_system.buzzer_se)

        return

      end

      # Check item type

      case item

      when RPG::Item

        # Check if item number is enough

        if $game_party.item_number(item.id) > 0

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          # Store item in chest

          $game_party.lose_item(item.id, 1)

          chest.gain_item(item.id, 1)

          # Redraw items

          @party_window.lose_item(item)

          @chest_window.add_item(item)

          return

        else

          # Play buzzer SE

          $game_system.se_play($data_system.buzzer_se)

          return

        end

      when RPG::Weapon

        # Check if item number is enough

        if $game_party.weapon_number(item.id) > 0

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          # Store item in chest

          $game_party.lose_weapon(item.id, 1)

          chest.gain_weapon(item.id, 1)

          # Redraw items

          @party_window.lose_item(item)

          @chest_window.add_item(item)

          return

        else

          # Play buzzer SE

          $game_system.se_play($data_system.buzzer_se)

          return

        end

      when RPG::Armor

        # Check if item number is enough

        if $game_party.armor_number(item.id) > 0

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          # Store item in chest

          $game_party.lose_armor(item.id, 1)

          chest.gain_armor(item.id, 1)

          # Redraw items

          @party_window.lose_item(item)

          @chest_window.add_item(item)

          return

        else

          # Play buzzer SE

          $game_system.se_play($data_system.buzzer_se)

          return

        end

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Frame Update (when chest window is active)

  #--------------------------------------------------------------------------

  def update_chest

    # If B button was pressed

    if Input.trigger?(Input::B)

      # Play cancel SE

      $game_system.se_play($data_system.cancel_se)

      @chest_window.active   = false

      @command_window.active = true

      return

    end

    # If C button was pressed

    if Input.trigger?(Input::C) or Input.repeat?(Input::C)

      # Get chest 

      chest = $game_map.chests[@chest_id]

      # Get currently selected data on the item window

      item = @chest_window.item

      case item

      when RPG::Item

        # Check if item number is enough

        if chest.item_number(item.id) > 0 && $game_party.item_number(item.id) < 99

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          # Store item in chest

          chest.lose_item(item.id, 1)

          $game_party.gain_item(item.id, 1)

          # Redraw items

          @party_window.add_item(item)

          @chest_window.lose_item(item)

          return

        else

          # Play buzzer SE

          $game_system.se_play($data_system.buzzer_se)

          return

        end

      when RPG::Weapon

        # Check if item number is enough

        if chest.weapon_number(item.id) > 0 && $game_party.weapon_number(item.id) < 99

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          # Store item in chest

          chest.lose_weapon(item.id, 1)

          $game_party.gain_weapon(item.id, 1)

          # Redraw items

          @party_window.add_item(item)

          @chest_window.lose_item(item)

          return

        else

          # Play buzzer SE

          $game_system.se_play($data_system.buzzer_se)

          return

        end

      when RPG::Armor

        # Check if item number is enough

        if chest.armor_number(item.id) > 0 && $game_party.armor_number(item.id) < 99

          # Play decision SE

          $game_system.se_play($data_system.decision_se)

          # Store item in chest

          chest.lose_armor(item.id, 1)

          $game_party.gain_armor(item.id, 1)

          # Redraw items

          @party_window.add_item(item)

          @chest_window.lose_item(item)

          return

        else

          # Play buzzer SE

          $game_system.se_play($data_system.buzzer_se)

          return

        end

      else # Player selected an empty slot

        # Play buzzer SE

        $game_system.se_play($data_system.buzzer_se)

        return

      end

    end

  end

end

 

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

# ** Window_Container

#------------------------------------------------------------------------------

# Author: Mark Redeman

# Version: 2.0

# Date: 13-01-2011

# Description:

#  This window displays items in the party's or chest's possession

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

 

class Window_Container < Window_Selectable

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(container = $game_player)

    @container = container

    @x_offset  = 12

    super(128, 112, 384, 256)

    @column_max = 8

    refresh

    self.index = 0

    self.opacity = 155

    self.active  = false

  end

  #--------------------------------------------------------------------------

  # * Get Item

  #--------------------------------------------------------------------------

  def item

    return @data[self.index]

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    if self.contents != nil

      self.contents.dispose

      self.contents = nil

    end

    @data = []

    # Add items

    for i in 1...$data_items.size

      if @container.item_number(i) > 0

        if @container.is_a?(Game_Chest) && !@container.stackable

          (0...@container.item_number(i)).each{ |data| @data.push($data_items[i]) }

        else

          @data.push($data_items[i])

        end

      end

    end

    # Add weapons

    for i in 1...$data_weapons.size

      if @container.weapon_number(i) > 0

        if @container.is_a?(Game_Chest) && !@container.stackable

          (0...@container.weapon_number(i)).each{ @data.push($data_weapons[i]) }

        else

          @data.push($data_weapons[i])

        end

      end

    end

    # Add armors

    for i in 1...$data_armors.size

      if @container.armor_number(i) > 0

        if @container.is_a?(Game_Chest) && !@container.stackable

          (0...@container.armor_number(i)).each{ @data.push($data_armors[i]) }

        else

          @data.push($data_armors[i])

        end

      end

    end

    # If item count is not 0, make a bitmap and draw all items

    @item_max = @data.size

    if @container.is_a?(Game_Chest) && !@container.stackable

      rows   = (@container.max_slots / @column_max) + 1

    else

      rows   = (($data_items.size + $data_weapons.size + $data_armors.size) /

       @column_max + 1)

    end

    height = rows * (32)

    # Recalculate height via 

    self.contents = Bitmap.new(width - 32, height)

    self.contents.font.size = 15

    if @item_max > 0

      for i in 0...@item_max

        draw_item(i)

      end

    end

  end

  #--------------------------------------------------------------------------

  # * Draw Item

  #     index : item index

  #--------------------------------------------------------------------------

  def draw_item(index, opacity = nil)

    x = (index % @column_max) * (32 + @x_offset)

    y = (index / @column_max) * (32)

    item = @data[index]

    case item

    when RPG::Item

      number = @container.item_number(item.id)

    when RPG::Weapon

      number = @container.weapon_number(item.id)

    when RPG::Armor

      number = @container.armor_number(item.id)

    end   

    # Set opacity

    opacity = number > 0 ? 255 : 125 if opacity == nil

    # Clear 

    rect = Rect.new(x, y, 32, 32)

    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))

    # Load icon graphic

    bitmap = RPG::Cache.icon(item.icon_name)

    # Set icon position in the middle of the slot

    x += (32 - bitmap.width) / 2

    y += (32 - bitmap.height) / 2

    # Draw icon

    self.contents.blt(x, y, bitmap, Rect.new(0, 0, 24, 24), opacity)

    # Draw amount of items if container is stackable

    if number > 0 && ((@container.is_a?(Game_Chest) && @container.stackable) || !@container.is_a?(Game_Chest))

      # Draw shadow of the amount of items in possession

      self.contents.font.color = Color.new(0, 0, 0)

      self.contents.draw_text(x - (32 - bitmap.width) / 2 + 1 , y + 7, 32-2, 32, number.to_s, 2)

      # Draw amount of items in possession

      self.contents.font.color = Color.new(255, 255, 255)

      self.contents.draw_text(x - (32 - bitmap.width) / 2 , y + 6, 32 - 2, 32, number.to_s, 2)

    end

  end

  #--------------------------------------------------------------------------

  # * Add Item

  #     item : item

  #--------------------------------------------------------------------------

  def add_item(item)

    if @data.include?(item) && !(@container.is_a?(Game_Chest) && !@container.stackable)

      # Redraw amount of items

      draw_item(@data.index(item))

    else

      # Check if there is an empty slot

      (0..@data.size).each { |i|

      if @data[i] == nil

        # Place a new item in the empty slot

        @data[i] = item

        # Get new item max

        @item_max = @data.size

        # Draw new item

        draw_item(i)

        return

      end                  }

      # Push new item in @data

      @data.push(item)

      # Get new item max

      @item_max = @data.size

      # Draw new item

      draw_item(@data.size - 1)

    end

  end

  #--------------------------------------------------------------------------

  # * Lose Item

  #     item : item

  #--------------------------------------------------------------------------

  def lose_item(item)

    if (@container.is_a?(Game_Chest) && !@container.stackable)

      # Redraw item with half opacity

      draw_item(@index, 125)

      # Set data to nil

      @data[@index] = nil

    else

      # Redraw amount of items

      draw_item(@data.index(item))

    end

  end

  #--------------------------------------------------------------------------

  # * Update Cursor Rectangle

  #--------------------------------------------------------------------------

  def update_cursor_rect

    # If cursor position is less than 0

    if @index < 0

      self.cursor_rect.empty

      return

    end

    # Get current row

    row = @index / @column_max

    # If current row is before top row

    if row < self.top_row

      # Scroll so that current row becomes top row

      self.top_row = row

    end

    # If current row is more to back than back row

    if row > self.top_row + (self.page_row_max - 1)

      # Scroll so that current row becomes back row

      self.top_row = row - (self.page_row_max - 1)

    end

    # Calculate cursor width

    cursor_width = 32#self.width / @column_max - 32

    # Calculate cursor coordinates

    x = @index % @column_max * (cursor_width + @x_offset)

    y = @index / @column_max * (32) - self.oy

    # Update cursor rectangle

    self.cursor_rect.set(x, y, cursor_width, 32)

  end

  #--------------------------------------------------------------------------

  # * Help Text Update

  #--------------------------------------------------------------------------

  def update_help

    if self.item == nil

      @help_window.set_text('This is an empty slot')

      return

    end

    # Check if container is a chest or a party

    if @container.is_a?(Game_Chest)

      # Show amount of items in party's possession

      @help_window.set_party(self.item)

    else

      # Show amount of items in the chest's possession

      @help_window.set_container(self.item)

    end    

  end

end

 

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

# ** Window_Container

#------------------------------------------------------------------------------

# Author: Mark Redeman

# Version: 2.0

# Date: 13-01-2011

# Description:

#  This is an horizontal Window_Command window.

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

 

class Window_Horizontal_Command < Window_Selectable

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(commands)

    super(128, 368, 384, 64)

    self.contents = Bitmap.new(width - 32, height - 32)

    @commands   = commands

    @column_max = @commands.size

    @item_max   = @commands.size

    refresh

    self.index = 0

    self.opacity = 155

    self.active  = true

  end

  #--------------------------------------------------------------------------

  # * Refresh

  #--------------------------------------------------------------------------

  def refresh

    # Calculate cursor coordinates

    self.contents.clear

    for i in 0...@item_max

      draw_item(i, normal_color)

    end

  end

  #--------------------------------------------------------------------------

  # * Draw Item

  #     index : item number

  #     color : text color

  #--------------------------------------------------------------------------

  def draw_item(index, color)

    self.contents.font.color = color

    # Calculate cursor width

    cursor_width = self.width / @column_max - 32

    # Calculate x

    x = index % @column_max * (cursor_width + 32) + 2

    rect = Rect.new(x, 0, self.contents.width - x, 32)

    # Clear drawn area

    self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))

    # Draw command

    self.contents.draw_text(rect, @commands[index])

  end

end

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

# ** Window_Container_Help

#------------------------------------------------------------------------------

# Author: Mark Redeman

# Version: 2.0

# Date: 13-01-2011

# Description:

#  This window shows amount of items in the party's or container's possession

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

 

class Window_Container_Help < Window_Base

  #--------------------------------------------------------------------------

  # * Object Initialization

  #--------------------------------------------------------------------------

  def initialize(container)

    super(128, 48, 384, 64)

    @container = container

    self.opacity  = 155

    self.contents = Bitmap.new(width - 32, height - 32)

  end

  #--------------------------------------------------------------------------

  # * Set Text

  #  text  : text string displayed in window

  #  align : alignment (0..flush left, 1..center, 2..flush right)

  #--------------------------------------------------------------------------

  def set_text(text, align = 0)

    # If at least one part of text and alignment differ from last time

    if text != @text or align != @align

      # Redraw text

      self.contents.clear

      self.contents.font.color = normal_color

      self.contents.draw_text(0, 0, self.contents.width, 32, text, align)

      @text = text

      @align = align

    end

    self.visible = true

  end

  #--------------------------------------------------------------------------

  # * Set party

  #   Shows the amount of items in the party's possession

  #  item  : selected item

  #--------------------------------------------------------------------------

  def set_party(item)

    unless item.nil?

      text = item.name + " in party's possession: "

      # Get the number of items in the party's possession

      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

      # Clear contents

      self.contents.clear

      # Set normal color

      self.contents.font.color = normal_color

      # Draw item name

      self.contents.draw_text(0, 0, self.contents.width - 32, 32, text)

      # Set system color

      self.contents.font.color = number > 0 ? system_color : disabled_color

      # Draw amount of items

      self.contents.draw_text(self.contents.width - 32, 0, 32, 32, number.to_s, 2)

    else

      # The slot is empty

      set_text('This slot is an empty slot.')

    end

  end

  #--------------------------------------------------------------------------

  # * Set container

  #   Shows the amount of items in the container's possession

  #  item  : selected item

  #--------------------------------------------------------------------------

  def set_container(item)

    text = item.name + " in chest's possession: "

    # Get the number of items in the container's possession

    case item

    when RPG::Item

      number = @container.item_number(item.id)

    when RPG::Weapon

      number = @container.weapon_number(item.id)

    when RPG::Armor

      number = @container.armor_number(item.id)

    end

    # Clear contents

    self.contents.clear

    # Set normal color

    self.contents.font.color = normal_color

    # Draw item name

    self.contents.draw_text(0, 0, self.contents.width - 32, 32, text)

    # Set system color

    self.contents.font.color = number > 0 ? system_color : disabled_color

    # Draw amount of items

    self.contents.draw_text(self.contents.width - 32, 0, 32, 32, number.to_s, 2)

  end

end

Instructions
Creating a chest.
Creating a new chest is very easy. Use the following code in a call script:
Code:
if $game_map.chests[ID] == nil

chest = $game_map.chests

chest[ID] = Game_Chest.new(max_slots, stockable)

end
Where the ID is the number which you will be using to call the chest menu.
max_slots is the amount of slots the chest has (Default value is 60).
stockable is a Boolean which determines if the chest is stackable or not (Default value is false).


Example 1:
Creates a chest which can contain 20 different item types.
Code:
if $game_map.chests[0] == nil

chest = $game_map.chests

chest[0] = Game_Chest.new(20, true)

end

 

Example 2:
This chest will have 80 slots. Every item, weapon or armor which is in the chest will use one slot.
Code:
if $game_map.chests[0] == nil

chest = $game_map.chests

chest[0] = Game_Chest.new(80, false)

end 

Adding items to a chest
Adding items, weapons and armors can be done via the following code:
Code:
chest = $game_map.chests[ID]

chest.gain_item(item_id, quantity)

chest.gain_weapon(weapon_id, quantity)

chest.gain_weapon(item_id, quantity)

 
Where ID is the ID number you used to create the chest.

Activating the chest menu
You can activate the menu with the following code:
Code:
$scene = Scene_Chest.new(Chest_ID)

Screenshots
This is the menu from which you can store or take items from the chest.
chestsysteem.png


This is what a typical chest event would look like.
kistsysteem01.png


Compatibility
The script won’t work with old save files.

Author's Notes
I would appreciate it if I could get some criticism on this script as it’s my first script I published on an English community. ;)

Terms and Conditions
You may use this script as long as you give me credits for making the script.
 
Nice script. It remembers grandia one. As a easy addition it can be interesting to set the items types that a chest can hold.

Im going to add feedhback:

# if $game_map.chests[0] == nil
# chest = $game_map.chests
# chest[0] = Game_Chest.new(20, true)
# end

I dont like this. Why use the if here?



Also i like shorter methods in the intepreter that call complex code:

Code:
 

def create_chest(num, type, id)

      # if $game_map.chests[id] == nil

# chest = $game_map.chests

# chest[id] = Game_Chest.new(num, type)

# end

end

 

Thats posible too with the adds or show methods.

For last its better to tell the user the default values or the internal script limits.
 

MarkR

Member

First of all, thanks for the feedback! :biggrin:

I put the if there so it won't replace an old chest with a new chest.
For example: If you want a chest which you can access in every inn in the game, you would have to create the chest at the start of the game, because if you where to put only the chest[id] = Game_Chest.new(num, type) you would overwrite the chest every time you try to open that chest.

gerrtunk":2710hk77 said:
Nice script. It remembers grandia one. As a easy addition it can be interesting to set the items types that a chest can hold.
Also i like shorter methods in the intepreter that call complex code:

Code:
 

def create_chest(num, type, id)

      # if $game_map.chests[id] == nil

# chest = $game_map.chests

# chest[id] = Game_Chest.new(num, type)

# end

end

 
I will look into that. I haven't worked with the interpreter yet so I didn't think of that.

gerrtunk":2710hk77 said:
As a easy addition it can be interesting to set the items types that a chest can hold.
I will be adding that feature as an addon as well as showing both windows (the chest window and the party window) at the same time.

gerrtunk":2710hk77 said:
For last its better to tell the user the default values or the internal script limits.
Do you mean the default values of the amount of slots and whether a chest is stackable or not? I hadn't thought about that. I will add a feature to configure these settings in the next version.
 
First of all... I like the idea of the script... while it's certainly not your idea to pack items in chests for later use, to my knowledge you're the first to make a script for that. You seem to be rather new at scripting, though, and I think I see some typical eventer's habits here and there... but yeah, let me give you some more pointy feedback as well...

First of all, your layout is a bit questionable if you ask me... you're breaking with standart RMXP conventions a few times in your screenshot there (which is all I've seen from your script, as I didn't try the demo). First of all, you decided against item names in favor for a lot of items... the question is, is that a good thing to do, as usually, people use the same icon for multiple things. Also, item names generally help you finding weapons, as the name is what you identify them by usually - the icon is just a supportive feature.
Second, your help and inventory/chest icons seem to be exchanged... the order to me should be 'select where to operate' -> 'operate (as in select item)' -> 'get help for the item if needed'.
Last but not least, your Window_Command instance is a bit off... your items there are supposed to have an x value of 4, which is why yours look so damn stuck to the left side of the selection area, I think... that you should definately fix imo, it doesn't look very good.

Interface-wise, a selection menu for the two different item storages seems like an easy way to go, requires an additional (and unneeded) key press. Now if you take the Bethesda approach, displaying your inventory and the chest next to each other not only let's you select the other window with a single keypress (L/R, for example), but also shows both lists at once. It's a design that proved itself, and with a bit of writing, you can make sure every last person gets it... personally, I think it's one of the most superior scripts handling this, while I won't miss my very own chance to take it on... but more on that later.

Your scripting style is a bit questionable at times (you have Window_Container in your headers twice, for example... as well as your scene before the window definitions, which isn't really what anyone does... and yeah, you once use if Input.trigger?(Input::C) or Input.repeat?(Input::C), and once if Input.trigger?(Input::C) || Input.repeat?(Input::C) ^^ ), however basically solid. Without looking at it too extensively, the fact that it's 900 lines makes me wonder if you don't have anything unneeded in there, as I don't think you'd need that many to get this functionality done.

So yeah... it might seem to you that I teared it pretty much apart, but believe me - you got off the hook easily ^^ I actually think this script has a lot of potential, and it's a nice way of getting you very deep into RGSS ^^ (otherwise I wouldn't invest that much time writing this now, would i?).
That being said - keep up the good work, and I'm looking forward to updates ;)



Last but not least... the promised concept of mine regarding chests - and actually a unique and pretty awesome approach, if I may say so myself. ;)
The thought behind it is that you need several things at once, without loosing time or finger strength pressing too many buttons. Also, the fact that you might at all times see the amount in a chest vs. the amount in your inventory without looking both up individually is a factor. Therefore, I created a concept working with 3 columns:

Code:
[ Chest ] [ Item List ] [ Inventory ]

The center column shows you the list of all the items that are either a) in the current chest, or b) in your inventory, or c) in both. You best get this if you iterate through $data_items, and check in exactly the way I said earlier (though you can neglect case c) ).
The left and right columns show the amount of items carried of the specific one... or 0 in disabled color if there are none at the time (because they're only in the other container).

Now, you operate it with your arrow keys solely: Up and down keys scroll through items, left moves the current item from chest to inventory, and right does the opposite. You completely save switching through scenes, as well as gain overview, as you can compare 1:1 which items are where, and how many of 'em.
Obviously, this won't work with the icon bunch style that you chose, so if that's what you want to keep up, well... this beauty of an idea of mine (modest, am I not?) won't work. Seriously though: You don't need a chest system in a game where you can carry 6 billion items. Therefore: I can only vote for the list, and I think my system COULD work out pretty nicely... the idea is yours under one condition: You get rid of the 'mark's in the alias names, and promise to work on your scripting style :p (that's right, no credit needed)
 
I try using this in my game
*thx before

but the same item not add in 1 item.. the result when I input 5 hi-potion..
there 5 hi potion in chest.. not 1 hi-potion with 5 number like the ss above

is there a config to make like SS?
 

MarkR

Member

I’m sorry for this late response. I have been busy with other things and forgot about this script. :X

Thanks a lot for your criticism. I’m certain it will help me make a better script. I didn’t know that the items in a command window are supposed to have an x value of 4, but now that I read you post I can see that it indeed looks strange.

Like you said, I made some stupid mistakes with my scripting style (most likely because I was a bit too eager to publish this script) and will hopefully fix that in the next version.

I like your concept. It’s definitely more user friendly, but I also liked the idea of the chests having slots so I’m not yet sure if I will use your idea. I might make two versions, one for large chests and another one for smaller chests, which will use the slots.

One last thing. You said that I should get rid of the mark’s in my aliases (which is fine by me), but I read in the SDK that I should format my aliases like this:
yourname_scriptname_classname_methodname

So should I still use this format (only if the idea came from me of course) or is it not necessary?

setanbedul":3rk4x1il said:
I try using this in my game
*thx before

but the same item not add in 1 item.. the result when I input 5 hi-potion..
there 5 hi potion in chest.. not 1 hi-potion with 5 number like the ss above

is there a config to make like SS?

Could you be a bit more specific? What script codes did you use?
I normally don't speak English, so it would also help if you improved your spelling and grammar. (A)
 
MarkR":2hvm0lq9 said:
One last thing. You said that I should get rid of the mark’s in my aliases (which is fine by me), but I read in the SDK that I should format my aliases like this:
yourname_scriptname_classname_methodname

So should I still use this format (only if the idea came from me of course) or is it not necessary?
Well, that's something I'm kinda fighting over with everyone... theoretically
, there could be someone creating an equal script to yours, naming their methods the same and therefore have the same alias names... and apparently, what the SDK creators thought was that there's someone who needs two chest scripts in their game... which is something I don't see happening anytime soon.

So basically, naming aliases is about uniqueness, but not on the cost of being precise and as short as possible... as you could also name an alias fdjngondmfoejornownrfonreognerog_update - not doing anyone any good. Personally, I prefer the format [script]_[original method], such as chestsystem_update. I know that the SDK states something else, so I guess it's up to you to decide on this (as you're the scripter ;) )... personally, the author's name doesn't help me while reading the script, so more unique but actually helpful alias names is definately what I prefer over bluescope_aka_the_third_man_aka_mike_update ^^
 
if the img small. just click it
MarkR":2fpkpsjf said:
...
setanbedul":2fpkpsjf said:
I try using this in my game
*thx before

but the same item not add in 1 item.. the result when I input 5 hi-potion..
there 5 hi potion in chest.. not 1 hi-potion with 5 number like the ss above

is there a config to make like SS?

Could you be a bit more specific? What script codes did you use?
I normally don't speak English, so it would also help if you improved your spelling and grammar. (A)
okay
Clipboard01.jpg

this is my basic world.. there 2 event.. a girl that give me some item and chest

I talked to her and receive item (10 for each item)

in my item menu


now the chest

my item before add

my chest before add

I add a few item

when i click on chest I got this?!? the item is not group but separate

when i return some item.. the item that I remove is still in there .. actualy i can't click it.. is there a bug or this is the script fitur??

thx 4 the script
 

MarkR

Member

@BlueScope: Thanks for explaining that to me! I will try to improve the scripting style in the next version of this script.

@setanbedul: That's because the chest you made isn't "stackable", if you don't want the items to be separate, you should use the following code:
Code:
 

if $game_map.chests[chest_id] == nil

chest = $game_map.chests

chest[chest_id] = Game_Chest.new(amount_of_slots, true)

end

 
Don't forget to change the chest_id and amount_of_slots.

This is the code I used for the chest in the first screenshot:
Code:
 

if $game_map.chests[2] == nil

chest = $game_map.chests

chest[2] = Game_Chest.new(99, true)

end

 
This will create a chest which is stackable and has 99 slots, which means that you can store 99 different items in the chest.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top