Compatibility Issue with Instance Items and Storage Box

● ARCHIVED · READ-ONLY
Started by Otto 2 posts View original ↗
  1. howdy :)
    As my game progresses and I started saving mid test I came across a super evil bug, which has to do with the two scripts in the title:

    Hime Instance Items and Bravo 2 Kilo Item Storage Box

    Wile the two scripts work fine with one another during the regular playtrough, I just found out that, when loading a saved game, every stored item which was an "Istance Item" disappear from the storage box :o
    Furthermore, this causes a bug in the storage box in which some items disappear completely as I try to put them in the box, and some items that were never in the box (and wern't even supposed to be there in the first place, since they are tagged as non-storable) have appeared inside.

    Here are the two scripts (unfortunately I have to post the full scripts because they contain edits, they are not in their original forms):

    Instance Items:
    Spoiler
    Code:
    =begin
    #===============================================================================
     Title: Instance Items
     Author: Hime
     Date: Jan 29, 2015
     URL: http://himeworks.com/2014/01/07/instance-items/
    --------------------------------------------------------------------------------
     ** Change log
     Jan 29, 2015
       - requests for weapons, armors, or items will return a clone of the original
         arrays in case you try to operate on it
     Dec 1, 2014
       - moved instance database reloading into "load_game_without_rescue" instead
         of "load_game"
     Aug 30, 2014
       - fixed issue where removing items, including equips, crashed
     May 4, 2014
       - rather than reloading template database completely, simply drop the
         instance objects
     Mar 21, 2014
       - fixed issue where conditional branch for equip checking doesn't work
     Jan 23, 2014
       - added support for refreshing note, description, and icon index
     Jan 16, 2014
       - added support for refreshing price and features
     Jan 14, 2014
       - added support for "refreshing" names and params
     Jan 12, 2014
       - disabling instance mode properly works for equips
       - fixed issue with equipping
     Jan 9, 2014
       - instance counts do not explicitly "gain/lose" a template item
       - fixed issue where changing equips forcibly was not working correctly
       - fixed issue with battle test when item instances were enabled
     Jan 7, 2014
       - added several setup methods to the Instance Manager
     Dec 10, 2013
       - compatibility with Core Equip Slots
       - Initial release
    --------------------------------------------------------------------------------
     ** Terms of Use
     * Free to use in non-commercial projects
     * Contact me for commercial use
     * No real support. The script is provided as-is
     * Will do bug fixes, but no compatibility patches
     * Features may be requested but no guarantees, especially if it is non-trivial
     * Credits to Hime Works in your project
     * Preserve this header
    --------------------------------------------------------------------------------
     ** Description
    
     This script introduces the concept of "instance items". In order to understand
     what an instance item is, you need to first understand what a "template item"
     is.
    
     All of your database items, weapons, and armors are called "template items".
     That is, they serve as templates for in-game items.
    
     An instance item is simply an instance of a template. For example, you design
     weapon ID 1 in your database and call it a "Short Sword". This is a template
     of a Short Sword; everytime you receive a Short Sword in-game, you receive
     a unique "instance" of this template. Two Short Swords in your inventory are
     treated as two individual entities that have nothing to do with each other
     besides both being based on the Short Sword template.
    
     It is important to note that this script simply provides instance item
     functionality. Additional add-ons are required to provide various features
     such as equip levels, equip affixes, and so on.
    
    --------------------------------------------------------------------------------
     ** Installation
    
     In the script editor, place this script below Materials and above Main
    
     You should place this below any equip-related scripts, such as my
     Core Equip Slots or Yanfly's Ace Equip Engine.
    
    --------------------------------------------------------------------------------
     ** Usage
    
     This script is plug and play.
    
     -- Instance Mode --
    
     You can determine what type of objects allow instances or not in the
     configuration by changing its "instance mode". For example, you can disable
     instances for items so that they stack as normal.
    
     These are the default values I have picked:
    
       Items   - false
       Weapons - true
       Armors  - true
    
     Currently, if instance mode is ON for that category of items, all items will
     be treated as instances.
    
     -- Event Changes --
    
     The following event commands behave differently if instance mode is on.
     When I say "item" I refer to weapons, armors, and items.
    
     - When you gain an item using events, new instances will be added to the
     inventory.
    
     - When you lose an item using events, it follows "template discard" rules.
     For example, if your event says to "lose 1 short sword", then the engine will
     simply look for ANY instance item that is based on the short sword. The same
     applies to equips if you include equips.
    
     - When you use the "change equipment" event command, the engine looks for the
     first instance of the specified equip.
    
    --------------------------------------------------------------------------------
     ** Developers
    
     This script serves as a framework for all instance items. Currently, it only
     supports item, weapon, and armor instances.
    
     The goal is to allow developers to write their own scripts that require
     "unique" items very easily without having to worry about how to actually
     implement it.
    
     This script is designed so that you only need to focus on two things
    
     1. The RPG module, which contains the template weapons, armors, and items.
     2. the InstanceManager module, which handles everything related to instances.
    
     A simple script would first load note-tags from the RPG objects and store them
     with the templates. For example, suppose we want to give all instance weapons
     a random attack bonus. We start by defining the max possible bonus a weapon
     could receive.
    
       class RPG::Weapon < RPG::EquipItem
         def attack_bonus
           50
         end
       end
    
     Now, we make it so that whenever an instance weapon is created, a random bonus
     will be applied to its attack. The InstanceManager provides several "setup"
     methods available for you, depending on what kind of object you're working
     with:
    
       setup_equip_instance(obj)  - use this for any equips (weapons or armors)
       setup_weapon_instance(obj) - use this only for weapons
       setup_armor_instance(obj)  - use this only for armors
       setup_item_instance(obj)   - use this only for items
    
     Since our example is applying a random flat bonus to an instance weapon, we
     would alias the weapon setup method.
    
       module InstanceManager
         class << self
           alias :th_random_weapon_bonus_setup_weapon_instance :setup_weapon_instance
         end
    
         def self.setup_weapon_instance(obj)
           template_obj = get_template(obj)
           th_random_weapon_bonus_setup_weapon_instance(obj)
           obj.params[2] += rand(template_obj.attack_bonus)
         end
       end
    
     Note the use of the `get_template` method in the setup. `obj` is an instance
     weapon that we are creating.Our data is stored with the template weapon, so we
     need to get it first before we can use it. After you have your template, you
     can easily get the data you need to apply to your instance object.
    
     And that's it! Your instance weapon now has a random attack bonus. You can
     verify this by adding the same weapon to your inventory multiple times and
     checking their parameters in the equip menu.
    
     This is a very simple example, but its goal is to demonstrate how to modify
     your instance objects. The rest of the game will just see it as another item
     or equip.
    
     -- Shared Data Compatibility --
    
     Because many scripts may modify item information, it is important to write
     compatible code.
    
     All RPG items, weapons, and armors support a `refresh` method that will
     re-compute a number of variables such as the name or parameters.
    
     For example, to modify the name of an object, you should alias the
     `make_name` method, which takes a name and returns a new name.
    
     The order in which the modifications are applied is important, and therefore
     you should make it clear what order users should place your script in.
    
    #===============================================================================
    =end
    $imported = {} if $imported.nil?
    $imported["TH_InstanceItems"] = true
    #===============================================================================
    # ** Configuration
    #===============================================================================
    module TH
      module Instance_Items
    
        # Enables instance mode for each type of object. When instance mode is
        # enabled, all objects of that type will be treated as instances
        Enable_Items = true
        Enable_Weapons = false
        Enable_Armors = false
      end
    end
    #===============================================================================
    # ** Rest of script
    #===============================================================================
    
    #-------------------------------------------------------------------------------
    # This module manages all instance and template items.
    #-------------------------------------------------------------------------------
    module InstanceManager
    
      class << self
        attr_accessor :weapons
        attr_accessor :armors
        attr_accessor :items
        attr_reader :template_counts
      end
    
      def self.setup
        @template_counts = {}
        @template_counts[:weapon] = $data_weapons.size
        @template_counts[:armor] = $data_armors.size
        @template_counts[:item] = $data_items.size
      end
    
      #-----------------------------------------------------------------------------
      # Stores the instance objects for game saving purpose
      #-----------------------------------------------------------------------------
      def self.create_game_objects
        @weapons = {}
        @armors = {}
        @items = {}
      end
    
      #-----------------------------------------------------------------------------
      # Full copy of the template object so we don't have any reference issues
      #-----------------------------------------------------------------------------
      def self.make_full_copy(obj)
        return Marshal.load(Marshal.dump(obj))
      end
    
      def self.instance_enabled?(obj)
        return TH::Instance_Items::Enable_Items && obj::has_instance() if obj.is_a?(RPG::Item)
        return TH::Instance_Items::Enable_Weapons if obj.is_a?(RPG::Weapon)
        return TH::Instance_Items::Enable_Armors if obj.is_a?(RPG::Armor)
        return false
      end
    
      def self.is_template?(obj)
        return obj.id >= @template_counts[:item] if obj.is_a?(RPG::Item)
        return obj.id >= @template_counts[:weapon] if obj.is_a?(RPG::Weapon)
        return obj.id >= @template_counts[:armor] if obj.is_a?(RPG::Armor)
      end
    
      #-----------------------------------------------------------------------------
      # create an instance from the template. Basically just a full copy.
      #-----------------------------------------------------------------------------
      def self.make_instance(obj)
        new_obj = make_full_copy(obj)
        new_obj.template_id = new_obj.id
        return new_obj
      end
    
      #-----------------------------------------------------------------------------
      # Return the database table that the obj belongs in
      #-----------------------------------------------------------------------------
      def self.get_tables(obj)
        return @items, $data_items if obj.is_a?(RPG::Item)
        return @weapons, $data_weapons if obj.is_a?(RPG::Weapon)
        return @armors, $data_armors if obj.is_a?(RPG::Armor)
      end
    
      def self.get_template(obj)
        return $data_items[obj.template_id] if obj.is_a?(RPG::Item)
        return $data_weapons[obj.template_id] if obj.is_a?(RPG::Weapon)
        return $data_armors[obj.template_id] if obj.is_a?(RPG::Armor)
      end
    
      #-----------------------------------------------------------------------------
      # Returns an instance of the object, assuming it is a valid object, it
      # supports instances, and it's not a template
      #-----------------------------------------------------------------------------
      def self.get_instance(obj)
        return obj if obj.nil? || !instance_enabled?(obj) || !obj.is_template?
        new_obj = make_instance(obj)
        container, table = get_tables(obj)
        id = table.size
    
        new_obj.id = id
        # Setup the instance object as required
        setup_instance(new_obj)
    
        # Add to database and container
        container[id] = new_obj
        table[id] = new_obj
        return new_obj
      end
    
      #-----------------------------------------------------------------------------
      # Set up our new instance object. This is meant to be aliased
      #-----------------------------------------------------------------------------
      def self.setup_instance(obj)
        setup_equip_instance(obj) if obj.is_a?(RPG::EquipItem)
        setup_item_instance(obj) if obj.is_a?(RPG::Item)
      end
    
      #-----------------------------------------------------------------------------
      # Apply any equip-specific logic. This is meant to be aliased.
      # Note the same object is passed to the appropriate setup method depending
      # on whether it's a weapon or armor, so be careful not to apply the same
      # changes multiple times.
      #-----------------------------------------------------------------------------
      def self.setup_equip_instance(obj)
        setup_weapon_instance(obj) if obj.is_a?(RPG::Weapon)
        setup_armor_instance(obj) if obj.is_a?(RPG::Armor)
      end
    
      #-----------------------------------------------------------------------------
      # Apply any weapon-specific logic. This is meant to be aliased.
      #-----------------------------------------------------------------------------
      def self.setup_weapon_instance(obj)
      end
    
      #-----------------------------------------------------------------------------
      # Apply any armor-specific logic. This is meant to be aliased.
      #-----------------------------------------------------------------------------
      def self.setup_armor_instance(obj)
      end
    
      #-----------------------------------------------------------------------------
      # Apply any item-specific logic. This is meant to be aliased.
      #-----------------------------------------------------------------------------
      def self.setup_item_instance(obj)
      end
    end
    
    module RPG
    
      class BaseItem
    
        # List of all attributes that are shared instance variable
        _instance_attr = [:name, :params, :price, :features, :note, :icon_index,
                          :description]
    
        #---------------------------------------------------------------------------
        # Define methods for all shared variables
        #---------------------------------------------------------------------------
        _instance_refresh = "def refresh"
        _instance_attr.each do |ivar|
          _instance_refresh << ";refresh_#{ivar}"
    
          eval(
            "def refresh_#{ivar}
              var = InstanceManager.get_template(self).#{ivar}
              @#{ivar} = make_#{ivar}(InstanceManager.make_full_copy(var))
            end
     
            def make_#{ivar}(#{ivar})
              #{ivar}
            end
            "
          )
        end
        _instance_refresh << ";end"
        eval(_instance_refresh)
    
      end
    
      class Item < UsableItem
        attr_accessor :template_id
    
        def is_template?
          return self.template_id == self.id
        end
    
        def template_id
          @template_id = @id unless @template_id
          return @template_id
        end
      end
    
      class EquipItem < BaseItem
        attr_accessor :template_id
    
        def is_template?
          self.template_id == self.id
        end
    
        def template_id
          @template_id = @id unless @template_id
          return @template_id
        end
      end
    end
    
    module DataManager
    
      class << self
        alias :th_instance_items_load_game_without_rescue :load_game_without_rescue
        alias :th_instance_items_create_game_objects :create_game_objects
        alias :th_instance_items_make_save_contents :make_save_contents
        alias :th_instance_items_extract_save_contents :extract_save_contents
      end
    
      def self.create_game_objects
        th_instance_items_create_game_objects
        InstanceManager.create_game_objects
        load_instance_database
      end
    
      def self.make_save_contents
        contents = th_instance_items_make_save_contents
        contents[:instance_weapons] = InstanceManager.weapons
        contents[:instance_armors] = InstanceManager.armors
        contents[:instance_items] = InstanceManager.items
        contents
      end
    
      def self.extract_save_contents(contents)
        th_instance_items_extract_save_contents(contents)
        InstanceManager.weapons = contents[:instance_weapons] || []
        InstanceManager.armors = contents[:instance_armors] || []
        InstanceManager.items = contents[:instance_items] || []
      end
    
      def self.load_game_without_rescue(index)
        res = th_instance_items_load_game_without_rescue(index)
        reload_instance_database
        return res
      end
    
      #-----------------------------------------------------------------------------
      # Merges the instance items into the database
      #-----------------------------------------------------------------------------
      def self.load_instance_database
        InstanceManager.setup
        merge_array_data($data_weapons, InstanceManager.weapons)
        merge_array_data($data_armors, InstanceManager.armors)
        merge_array_data($data_items, InstanceManager.items)
      end
    
      def self.reload_instance_database
        $data_weapons = $data_weapons[0..InstanceManager.template_counts[:weapon]]
        $data_armors = $data_armors[0..InstanceManager.template_counts[:armor]]
        $data_items = $data_items[0..InstanceManager.template_counts[:item]]
        load_instance_database
      end
    
      def self.merge_array_data(arr, hash)
        hash.each {|i, val|
          arr[i] = val
        }
      end
    end
    
    class Game_Interpreter
    
      alias :th_instance_items_command_111 :command_111
      def command_111
        result = false
        case @params[0]
        when 4
          actor = $game_actors[@params[1]]
          if actor
            case @params[2]
            when 0  # in party
              result = ($game_party.members.include?(actor))
            when 1  # name
              result = (actor.name == @params[3])
            when 2  # Class
              result = (actor.class_id == @params[3])
            when 3  # Skills
              result = (actor.skill_learn?($data_skills[@params[3]]))
            when 4  # Weapons
              result = (actor.instance_weapons_include?(@params[3]))
            when 5  # Armors
              result = (actor.instance_armors_include?(@params[3]))
            when 6  # States
              result = (actor.state?(@params[3]))
            end
          end
        end
        @branch[@indent] = result
    
        # none of them passed, so let's check the other conditions
        th_instance_items_command_111 if !result
      end
    end
    
    class Game_Actor < Game_Battler
    
      alias :th_instance_items_init_equips :init_equips
      def init_equips(equips)
        @equips = Array.new(equip_slots.size) { Game_BaseItem.new }
        instance_equips = check_instance_equips(equips)
        th_instance_items_init_equips(instance_equips)
      end
    
      #-----------------------------------------------------------------------------
      # Replace all initial equips with instances
      #-----------------------------------------------------------------------------
      def check_instance_equips(equips)
        new_equips = []
        equips.each_with_index do |item_id, i|
          etype_id = index_to_etype_id(i)
          slot_id = empty_slot(etype_id)
          if etype_id == 0
            equip = $data_weapons[item_id]
          else
            equip = $data_armors[item_id]
          end
          new_equips << InstanceManager.get_instance(equip)
        end
        return new_equips.collect {|obj| obj ? obj.id : 0}
      end
    
      alias :th_instance_items_change_equip :change_equip
      def change_equip(slot_id, item)
        new_item = item
        if item && InstanceManager.instance_enabled?(item) && $game_party.has_item?(item) && item.is_template?
          new_item = $game_party.find_instance_item(item)
        end
        th_instance_items_change_equip(slot_id, new_item)
      end
    
      alias :th_instance_items_trade_item_with_party :trade_item_with_party
      def trade_item_with_party(new_item, old_item)
        if new_item && InstanceManager.instance_enabled?(new_item) && $game_party.has_item?(new_item) && new_item.is_template?
          new_item = $game_party.find_instance_item(new_item)
        end
        th_instance_items_trade_item_with_party(new_item, old_item)
      end
    
      #-----------------------------------------------------------------------------
      # New.
      #-----------------------------------------------------------------------------
      def instance_weapons_include?(id)
        weapons.any? {|obj| obj.template_id == id }
      end
    
      #-----------------------------------------------------------------------------
      # New.
      #-----------------------------------------------------------------------------
      def instance_armors_include?(id)
        armors.any? {|obj| obj.template_id == id }
      end
    end
    
    class Game_Party < Game_Unit
    
      alias :th_instance_items_init_all_items :init_all_items
      def init_all_items
        th_instance_items_init_all_items
        @item_list = []
        @weapon_list = []
        @armor_list = []
      end
    
      #-----------------------------------------------------------------------------
      # Overwrite. We already keep a list of weapons
      #-----------------------------------------------------------------------------
      alias :th_instance_items_weapons :weapons
      def weapons
        TH::Instance_Items::Enable_Weapons ? @weapon_list.clone : th_instance_items_weapons
      end
    
      #-----------------------------------------------------------------------------
      # Overwrite.
      #-----------------------------------------------------------------------------
      alias :th_instance_items_items :items
      def items
        TH::Instance_Items::Enable_Items ? th_instance_items_items.select{ |item| if item then !item.has_instance() end} + @item_list.clone : th_instance_items_items
      end
    
      #-----------------------------------------------------------------------------
      # Overwrite.
      #-----------------------------------------------------------------------------
      alias :th_instance_items_armors :armors
      def armors
        TH::Instance_Items::Enable_Armors ? @armor_list.clone : th_instance_items_armors
      end
    
      #-----------------------------------------------------------------------------
      # Returns true if the item type supports instances
      #-----------------------------------------------------------------------------
      def instance_enabled?(item)
        return InstanceManager.instance_enabled?(item)
      end
    
      #-----------------------------------------------------------------------------
      # Returns an instance for the given item. If it is already an instance, then
      # we just return that. If it's a template, we create a new instance.
      #-----------------------------------------------------------------------------
      def get_instance(item)
        return InstanceManager.get_instance(item)
      end
    
      #-----------------------------------------------------------------------------
      # Returns the template for the given item
      #-----------------------------------------------------------------------------
      def get_template(item)
        return InstanceManager.get_template(item)
      end
    
      #-----------------------------------------------------------------------------
      # The gain item method performs various checks on the item that you want to
      # add to the inventory. Namely, it checks whether it is a template item or
      # an instance item, updates the item counts, and so on.
      #-----------------------------------------------------------------------------
      alias :th_instance_items_gain_item :gain_item
      def gain_item(item, amount, include_equip = false)
        # special check for normal items
        if !instance_enabled?(item)
          th_instance_items_gain_item(item, amount, include_equip)
        else
          if item
            if amount > 0
              amount.times do |i|
                new_item = get_instance(item)
                add_instance_item(new_item)
              end
            else
              amount.abs.times do |i|
                item_template = get_template(item)
                if item.is_template?
                  # remove using template rules. If an item was lost, then decrease
                  # template count by 1.
                  lose_template_item(item, include_equip)
                else
                  # remove the instance item, and decrease template count by 1
                  lose_instance_item(item)
                end
              end
            end
          else
            th_instance_items_gain_item(item, amount, include_equip)
          end
        end
      end
    
      #-----------------------------------------------------------------------------
      # New. Returns the appropriate container list
      #-----------------------------------------------------------------------------
      def item_container_list(item)
        return @item_list if item.is_a?(RPG::Item)
        return @weapon_list if item.is_a?(RPG::Weapon)
        return @armor_list if item.is_a?(RPG::Armor)
      end
    
      #-----------------------------------------------------------------------------
      # New. Adds the instance item to the appropriate list
      #-----------------------------------------------------------------------------
      def add_instance_item(item)
        container = item_container(item.class)
        container[item.template_id] ||= 0
        container[item.template_id] += 1
        container[item.id] = 1
        container_list = item_container_list(item)
        container_list.push(item)
      end
    
      #-----------------------------------------------------------------------------
      # New. Returns an instance item that matches the template. If it doesn't
      # exist, returns nil
      #-----------------------------------------------------------------------------
      def find_instance_item(template_item)
        container_list = item_container_list(template_item)
        return container_list.find {|obj| obj.template_id == template_item.template_id }
      end
    
      #-----------------------------------------------------------------------------
      # New. Lose an instance item. Simply delete it from the appropriate container
      # list
      #-----------------------------------------------------------------------------
      def lose_instance_item(item)
        container = item_container(item.class)
        container[item.template_id] ||= 0
        container[item.template_id] -= 1
        container[item.id] = 0
        container_list = item_container_list(item)
        container_list.delete(item)
      end
    
      #-----------------------------------------------------------------------------
      # New. Lose a template item. This looks for a
      #-----------------------------------------------------------------------------
      def lose_template_item(item, include_equip)
        container_list = item_container_list(item)
        item_lost = container_list.find {|obj| obj.template_id == item.template_id }
        if item_lost
          container = item_container(item.class)
          container[item.template_id] ||= 0
          container[item.template_id] -= 1
          container_list.delete(item_lost)
        elsif include_equip
          discard_members_template_equip(item, 1)
        end
        return item_lost
      end
    
      #-----------------------------------------------------------------------------
      # New. Same as discarding equips, except we follow template discard rules
      #-----------------------------------------------------------------------------
      def discard_members_template_equip(item, amount)
        n = amount
        members.each do |actor|
          item = actor.equips.find {|obj| obj && obj.template_id == item.template_id }
          while n > 0 && item
            actor.discard_equip(item)
            n -= 1
          end
        end
      end
    end
    
    class Window_ItemList < Window_Selectable
    
      alias :th_instance_items_draw_item_number :draw_item_number
      def draw_item_number(rect, item)
        th_instance_items_draw_item_number(rect, item) if item.is_template?
      end
    end
    
    #===============================================================================
    # RPG::Item
    #===============================================================================
    
    class RPG::Item
      def has_instance
          return false if @note =~ /<Not_Instance>/i
          return true
      end
    end
    
    #===============================================================================
    # Compatibility with Core Equip Slots
    #===============================================================================
    if $imported["TH_CoreEquipSlots"]
      class Game_Actor < Game_Battler
    
        def init_equips(equips)
          @equips = Array.new(initial_slots.size) {|i| Game_EquipSlot.new(initial_slots[i]) }
          instance_equips = check_instance_equips(equips)
          th_instance_items_init_equips(instance_equips)
        end
      end
    end
  2. Storage Box
    Spoiler
    Code:
    #==============================================================================
    # Bravo Storage System
    #------------------------------------------------------------------------------
    # Author: Bravo2Kilo
    # Version: 2.0
    #
    # Version History:
    #   v1.0 = Initial Release
    #   v1.1 = Fixed a bug and added some commands.
    #   v2.0 = Added the ability to have multiple storage containers.
    #==============================================================================
    # Notes
    #   If category and gold are both set to false, you can only exchange items,
    #   if category is set to false and gold is set to true, you can only exchange
    #   gold.
    #==============================================================================
    # To open the storage scene use this command in a script call.
    #   open_storage(name, name_window, category, gold)
    #     name = the name of the storage
    #     name_window = (true or false)true to show the name window
    #     category = (true or false)true to show the category window
    #     gold = (true or false)true to show gold in the category window
    #
    # To add or remove items from a certain storage use this command in a script call
    #   storage_add_item(name, type, id, amount)
    #   storage_remove_item(name, type, id, amount)
    #     name = the name of the storage
    #     type = the type of item, can be(:item, :weapon, :armor)
    #     id = the database id of the item
    #     amount = the amount to add or remove
    #
    # To remove all items and gold in a certain storage use this command in a script call
    #   clear_storage(name)
    #     name = the name of the storage
    #
    # To check the amount of an item in a certain storage use this command in a script call
    #   storage_item_number(name, type, id)
    #     name = the name of the storage
    #     type = the type of item, can be(:item, :weapon, :armor)
    #     id = the database id of the item
    #
    # To add or remove gold from a certain storage use this command in a script call
    #   storage_add_gold(name, amount)
    #   storage_remove_gold(name, amount)
    #     name = the name of the storage
    #     amount = the amount to add or remove
    #
    # To check the amount of gold in a certain storage use this command in a script call
    #   storage_gold_number(name)
    #     name = the name of the storage
    #
    # If you want to set the max ammount of each item that can be in the storage,
    # use this notetag, if a notetage isn't used it will use the default max that
    # is defined below.
    #   <storagemax: X> were X = the max.
    #==============================================================================
    module BRAVO_STORAGE
      # The default max of an item that can be in storage.
      ITEM_MAX = 99
      # The max amount of gold that can be stored.
      GOLD_MAX = 99999999
      # The command name for removing items from storage.
      WITHDRAW_TEXT = "Take Item"
      # The command name for putting items into storage.
      STORE_TEXT = "Store Item"
      # The command name for leaving the storage scene.
      CANCEL_TEXT = "Exit"
      # The storage name window width
      NAME_WIDTH = 0
    #==============================================================================
    # End of Configuration
    #==============================================================================
    end
    $imported ||= {}
    $imported[:Bravo_Storage] = true
    #==============================================================================
    # ** RPG::BaseItem
    #==============================================================================
    class RPG::BaseItem
      #--------------------------------------------------------------------------
      # * Item Storage Max
      #--------------------------------------------------------------------------
      def storage_max
        if @note =~ /<storagemax: (.*)>/i
          return $1.to_i
        else
          return BRAVO_STORAGE::ITEM_MAX
        end
      end
    end
    
    #==============================================================================
    # ** Game_Temp
    #==============================================================================
    
    class Game_Temp
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_accessor :storage_gold
      attr_accessor :storage_category
      attr_accessor :storage_name_window
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      alias bravo_storage_initialize initialize
      def initialize
        bravo_storage_initialize
        @storage_gold = false
        @storage_category = false
        @storage_name_window = false
      end
    end
    
    #==============================================================================
    # ** Game_Party
    #==============================================================================
    
    class Game_Party < Game_Unit
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_reader   :storage_name
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      alias bravo_storage_initialize initialize
      def initialize
        bravo_storage_initialize
        @storage_gold = {}
        @storage_items = {}
        @storage_weapons = {}
        @storage_armors = {}
        @storage_name = nil
      end
      #--------------------------------------------------------------------------
      # * Initialize Storage
      #--------------------------------------------------------------------------
      def init_storage(name)
        @storage_gold[name] ||= 0
        @storage_items[name] ||= {}
        @storage_weapons[name] ||= {}
        @storage_armors[name] ||= {}
      end
      #--------------------------------------------------------------------------
      # * Storage Name =
      #--------------------------------------------------------------------------
      def storage_name=(name)
        return if @storage_name == name
        @storage_name = name
        init_storage(name)
      end
      #--------------------------------------------------------------------------
      # * Clear Storage
      #--------------------------------------------------------------------------
      def clear_storage
        @storage_gold[name] = 0
        @storage_items[name] = {}
        @storage_weapons[name] = {}
        @storage_armors[name] = {}
      end
      #--------------------------------------------------------------------------
      # * Get Item Object Array
      #--------------------------------------------------------------------------
      def storage_items
        @storage_items[@storage_name].keys.sort.collect {|id| $data_items[id] }
      end
      #--------------------------------------------------------------------------
      # * Get Weapon Object Array
      #--------------------------------------------------------------------------
      def storage_weapons
        @storage_weapons[@storage_name].keys.sort.collect {|id| $data_weapons[id] }
      end
      #--------------------------------------------------------------------------
      # * Get Armor Object Array
      #--------------------------------------------------------------------------
      def storage_armors
        @storage_armors[@storage_name].keys.sort.collect {|id| $data_armors[id] }
      end
      #--------------------------------------------------------------------------
      # * Get Array of All Equipment Objects
      #--------------------------------------------------------------------------
      def storage_equip_items
        storage_weapons + storage_armors
      end
      #--------------------------------------------------------------------------
      # * Get Array of All Item Objects
      #--------------------------------------------------------------------------
      def storage_all_items
        storage_items + storage_equip_items
      end
      #--------------------------------------------------------------------------
      # * Get Container Object Corresponding to Item Class
      #--------------------------------------------------------------------------
      def storage_item_container(item_class)
        return @storage_items[@storage_name]   if item_class == RPG::Item
        return @storage_weapons[@storage_name] if item_class == RPG::Weapon
        return @storage_armors[@storage_name]  if item_class == RPG::Armor
        return nil
      end
      #--------------------------------------------------------------------------
      # * Storage Gold
      #--------------------------------------------------------------------------
      def storage_gold
        @storage_gold[@storage_name]
      end
      #--------------------------------------------------------------------------
      # * Increase Storage Gold
      #--------------------------------------------------------------------------
      def storage_gain_gold(amount)
        @storage_gold[@storage_name] = [[@storage_gold[@storage_name] + amount, 0].max, BRAVO_STORAGE::GOLD_MAX].min
      end
      #--------------------------------------------------------------------------
      # * Decrease Storage Gold
      #--------------------------------------------------------------------------
      def storage_lose_gold(amount)
        storage_gain_gold(-amount)
      end
      #--------------------------------------------------------------------------
      # * Get Maximum Number of Items in Storage
      #--------------------------------------------------------------------------
      def storage_max_item_number(item)
        return item.storage_max
      end
      #--------------------------------------------------------------------------
      # * Determine if Maximum Number of Items Are Possessed
      #--------------------------------------------------------------------------
      def storage_item_max?(item)
        storage_item_number(item) >= storage_max_item_number(item)
      end
      #--------------------------------------------------------------------------
      # * Get Number of Items Possessed
      #--------------------------------------------------------------------------
      def storage_item_number(item)
        container = storage_item_container(item.class)
        container ? container[item.id] || 0 : 0
      end
      #--------------------------------------------------------------------------
      # * Increase/Decrease Storage Items
      #--------------------------------------------------------------------------
      def storage_gain_item(item, amount)
        container = storage_item_container(item.class)
        return unless container
        last_number = storage_item_number(item)
        new_number = last_number + amount
        container[item.id] = [[new_number, 0].max, storage_max_item_number(item)].min
        container.delete(item.id) if container[item.id] == 0
      end
      #--------------------------------------------------------------------------
      # * Remove Storage Items
      #--------------------------------------------------------------------------
      def storage_lose_item(item, amount)
        storage_gain_item(item, -amount)
      end
    end
    
    #==============================================================================
    # ** Game_Interpreter
    #==============================================================================
    
    class Game_Interpreter
      #--------------------------------------------------------------------------
      # * Open Storage Scene
      #--------------------------------------------------------------------------
      def open_storage(name, name_window = true, category = true, gold = true)
        $game_party.storage_name = name
        $game_temp.storage_name_window = name_window
        $game_temp.storage_category = category
        $game_temp.storage_gold = gold
        SceneManager.call(Scene_Storage)
      end
      #--------------------------------------------------------------------------
      # * Clear Storage
      #--------------------------------------------------------------------------
      def clear_storage(name)
        $game_party.clear_storage(name)
      end
      #--------------------------------------------------------------------------
      # * Storage Add Item
      #--------------------------------------------------------------------------
      def storage_add_item(name, type, id, amount)
        $game_party.storage_name = name
        case type
        when :item
          item = $data_items[id]
        when :weapon
          item = $data_weapons[id]
        when :armor
          item = $data_armors[id]
        end
        $game_party.storage_gain_item(item, amount)
      end
      #--------------------------------------------------------------------------
      # * Storage Remove Item
      #--------------------------------------------------------------------------
      def storage_remove_item(name, type, id, amount)
        $game_party.storage_name = name
        case type
        when :item
          item = $data_items[id]
        when :weapon
          item = $data_weapons[id]
        when :armor
          item = $data_armors[id]
        end
        $game_party.storage_lose_item(item, amount)
      end
      #--------------------------------------------------------------------------
      # * Storage Item Number
      #--------------------------------------------------------------------------
      def storage_item_number(name, type, id)
        $game_party.storage_name = name
        case type
        when :item
          item = $data_items[id]
        when :weapon
          item = $data_weapons[id]
        when :armor
          item = $data_armors[id]
        end
        $game_party.storage_item_number(item)
      end
      #--------------------------------------------------------------------------
      # * Storage Add Gold
      #--------------------------------------------------------------------------
      def storage_add_gold(name, amount)
        $game_party.storage_name = name
        $game_party.storage_gain_gold(amount)
      end
      #--------------------------------------------------------------------------
      # * Storage Remove Gold
      #--------------------------------------------------------------------------
      def storage_remove_gold(name, amount)
        $game_party.storage_name = name
        $game_party.storage_lose_gold(amount)
      end
      #--------------------------------------------------------------------------
      # * Storage Gold Number
      #--------------------------------------------------------------------------
      def storage_gold_number(name)
        $game_party.storage_name = name
        $game_party.storage_gold
      end
    end
    
    #==============================================================================
    # ** Window_StorageCategory
    #==============================================================================
    
    class Window_StorageCategory < Window_ItemCategory
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize(gold)
        @gold = gold
        super()
      end
      #--------------------------------------------------------------------------
      # * Get Digit Count
      #--------------------------------------------------------------------------
      def col_max
        if @gold == true
          return 4
        else
          return 3
        end
      end
      #--------------------------------------------------------------------------
      # * Create Command List
      #--------------------------------------------------------------------------
      def make_command_list
        add_command(Vocab::item, :item)
        add_command(Vocab::weapon, :weapon)
        add_command(Vocab::armor, :armor)
        add_command(Vocab::currency_unit, :gold) if @gold == true
      end
    end
    
    #==============================================================================
    # ** Window_ItemList
    #------------------------------------------------------------------------------
    #  This window displays a list of party items on the item screen.
    #==============================================================================
    
    class Window_StorageItemList < Window_ItemList
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize(x, y, width, height)
        super(x, y, width, height)
        @storage = :none
      end
      #--------------------------------------------------------------------------
      # * Set Storage Flag
      #--------------------------------------------------------------------------
      def storage=(storage)
        return if @storage == storage
        @storage = storage
        refresh
        self.oy = 0
      end
      #--------------------------------------------------------------------------
      # * Include in Item List?
      #--------------------------------------------------------------------------
      def include?(item)
        case @category
        when :item
          item.is_a?(RPG::Item)
        when :weapon
          item.is_a?(RPG::Weapon)
        when :armor
          item.is_a?(RPG::Armor)
        when :all
          item
        else
          false
        end
      end
      #--------------------------------------------------------------------------
      # * Display in Enabled State?
      #--------------------------------------------------------------------------
      def enable?(item)
        if item.is_a?(RPG::Item)
          return true if !item.key_item?
        elsif item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor)
          return true
        else
          return false
        end
      end
      #--------------------------------------------------------------------------
      # * Create Item List
      #--------------------------------------------------------------------------
      def make_item_list
        case @storage
        when :store
          @data = $game_party.all_items.select {|item| include?(item)}
          @data.push(nil) if include?(nil)
        when :withdraw
          @data = $game_party.storage_all_items.select {|item| include?(item)}
          @data.push(nil) if include?(nil)
        end
      end
      #--------------------------------------------------------------------------
      # * Draw Number of Items
      #--------------------------------------------------------------------------
      def draw_item_number(rect, item)
        case @storage
        when :store
          if $game_party.item_number(item) > 1 #OTTO -> draw item quantity only if > 1
          contents.font.size = YEA::LIMIT::EQUIP_FONT #OTTO -> Font fix hopefully
          draw_text(rect, sprintf("%2d", $game_party.item_number(item)), 2)
          end #End of OTTO draw item if >1
        when :withdraw
    #~       draw_text(rect, sprintf(":%2d", $game_party.storage_item_number(item)), 2)
        end
      end
    end
    
    #==============================================================================
    # ** Window_StorageCommand
    #==============================================================================
    
    class Window_StorageCommand < Window_HorzCommand
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize
        super(0, 0)
    #~     self.windowskin = Cache.system("Window-2")
      end
      #--------------------------------------------------------------------------
      # * Get Window Width
      #--------------------------------------------------------------------------
      def window_width
        if $game_temp.storage_name_window == false
          return 544
        else
          Graphics.width - BRAVO_STORAGE::NAME_WIDTH
        end
      end
      #--------------------------------------------------------------------------
      # * Get Digit Count
      #--------------------------------------------------------------------------
      def col_max
        return 3
      end
      #--------------------------------------------------------------------------
      # * Create Command List
      #--------------------------------------------------------------------------
      def make_command_list
        add_command(BRAVO_STORAGE::WITHDRAW_TEXT, :withdraw)
        add_command(BRAVO_STORAGE::STORE_TEXT, :store)
        add_command(BRAVO_STORAGE::CANCEL_TEXT, :cancel)
      end
    end
    
    #==============================================================================
    # ** Window_StorageName
    #==============================================================================
    class Window_StorageName < Window_Base
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize
        super(0, 0, window_width, fitting_height(1))
        refresh
      end
      #--------------------------------------------------------------------------
      # * Get Window Width
      #--------------------------------------------------------------------------
      def window_width
        return BRAVO_STORAGE::NAME_WIDTH
      end
      #--------------------------------------------------------------------------
      # * Refresh
      #--------------------------------------------------------------------------
      def refresh
        contents.clear
        name = $game_party.storage_name
        draw_text(0, 0, window_width, line_height, name)
      end
      #--------------------------------------------------------------------------
      # * Open Window
      #--------------------------------------------------------------------------
      def open
        refresh
        super
      end
    end
    
    #==============================================================================
    # ** Window_StorageNumber
    #==============================================================================
    
    class Window_StorageNumber < Window_Selectable
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_reader   :number                   # quantity entered
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize
        super(0, 0, window_width, window_height)
        self.windowskin = Cache.system("Window_C")
        @item = nil
        @max = 1
        @number = 1
      end
      #--------------------------------------------------------------------------
      # * Get Window Width
      #--------------------------------------------------------------------------
      def window_width
        return 366
      end
      #--------------------------------------------------------------------------
      # * Get Window Height
      #--------------------------------------------------------------------------
      def window_height
        return 48
      end
      #--------------------------------------------------------------------------
      # * Set Item, Max Quantity
      #--------------------------------------------------------------------------
      def set(item, max)
        @item = item
        @max = max
        @number = 1
        refresh
      end
      #--------------------------------------------------------------------------
      # * Refresh
      #--------------------------------------------------------------------------
      def refresh
        contents.clear
        draw_item_name(@item, 0, 0)
        draw_number
      end
      #--------------------------------------------------------------------------
      # * Draw Quantity
      #--------------------------------------------------------------------------
      def draw_number
        change_color(normal_color)
        draw_text(cursor_x - 28, 0, 22, line_height, "×")
        draw_text(cursor_x, 0, cursor_width - 4, line_height, @number, 2)
      end
      #--------------------------------------------------------------------------
      # * Get Cursor Width
      #--------------------------------------------------------------------------
      def cursor_width
        figures * 10 + 12
      end
      #--------------------------------------------------------------------------
      # * Get X Coordinate of Cursor
      #--------------------------------------------------------------------------
      def cursor_x
        contents_width - cursor_width - 4
      end
      #--------------------------------------------------------------------------
      # * Get Maximum Number of Digits for Quantity Display
      #--------------------------------------------------------------------------
      def figures
        return 2
      end
      #--------------------------------------------------------------------------
      # * Frame Update
      #--------------------------------------------------------------------------
      def update
        super
        if active
          last_number = @number
          update_number
          if @number != last_number
            Sound.play_cursor
            refresh
          end
        end
      end
      #--------------------------------------------------------------------------
      # * Update Quantity
      #--------------------------------------------------------------------------
      def update_number
        change_number(1)   if Input.repeat?(:RIGHT)
        change_number(-1)  if Input.repeat?(:LEFT)
        change_number(10)  if Input.repeat?(:UP)
        change_number(-10) if Input.repeat?(:DOWN)
      end
      #--------------------------------------------------------------------------
      # * Change Quantity
      #--------------------------------------------------------------------------
      def change_number(amount)
        @number = [[@number + amount, @max].min, 1].max
      end
      #--------------------------------------------------------------------------
      # * Update Cursor
      #--------------------------------------------------------------------------
      def update_cursor
        cursor_rect.set(cursor_x, 0, cursor_width, line_height)
      end
    end
    
    #==============================================================================
    # ** Window_GoldTransfer
    #==============================================================================
    
    class Window_GoldTransfer < Window_Selectable
      #--------------------------------------------------------------------------
      # * Public Instance Variables
      #--------------------------------------------------------------------------
      attr_reader   :number                   # quantity entered
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize
        super(0, 0, window_width, window_height)
        @item = nil
        @max = 1
        @number = 1
        @cursor_y = 0
      end
      #--------------------------------------------------------------------------
      # * Get Window Width
      #--------------------------------------------------------------------------
      def window_width
        return 330
      end
      #--------------------------------------------------------------------------
      # * Get Window Height
      #--------------------------------------------------------------------------
      def window_height
        return 72
      end
      #--------------------------------------------------------------------------
      # * Set Item, Max Quantity
      #--------------------------------------------------------------------------
      def set(max, position)
        @max = max
        @number = 1
        @cursor_y = position
        refresh
      end
      #--------------------------------------------------------------------------
      # * Refresh
      #--------------------------------------------------------------------------
      def refresh
        contents.clear
        draw_gold_info
        draw_number
      end
      #--------------------------------------------------------------------------
      # * Display in Enabled State?
      #--------------------------------------------------------------------------
      def enabled?
        if @cursor_y == 0
          return true if $game_party.gold > 0
        else
          return true if $game_party.storage_gold > 0
        end
        return false
      end
      #--------------------------------------------------------------------------
      # * Processing When OK Button Is Pressed
      #--------------------------------------------------------------------------
      def process_ok
        if enabled?
          Sound.play_ok
          Input.update
          deactivate
          call_ok_handler
        else
          Sound.play_buzzer
        end
      end
      #--------------------------------------------------------------------------
      # * Draw Gold Info
      #--------------------------------------------------------------------------
      def draw_gold_info
        party = "Party " + Vocab::currency_unit + " :"
        storage = "Storage " + Vocab::currency_unit + " :"
        draw_text(0, 0, 280, line_height, party)
        draw_text(0, 24, 280, line_height, storage)
        draw_text(0, 0, 225, line_height, $game_party.gold, 2)
        draw_text(0, 24, 225, line_height, $game_party.storage_gold, 2)
      end
      #--------------------------------------------------------------------------
      # * Draw Quantity
      #--------------------------------------------------------------------------
      def draw_number
        change_color(normal_color)
        draw_text(cursor_x - 28, @cursor_y, 22, line_height, "×")
        draw_text(cursor_x, @cursor_y, cursor_width - 4, line_height, @number, 2)
      end
      #--------------------------------------------------------------------------
      # * Get Cursor Width
      #--------------------------------------------------------------------------
      def cursor_width
        figures * 10 + 12
      end
      #--------------------------------------------------------------------------
      # * Get X Coordinate of Cursor
      #--------------------------------------------------------------------------
      def cursor_x
        contents_width - cursor_width - 4
      end
      #--------------------------------------------------------------------------
      # * Get Maximum Number of Digits for Quantity Display
      #--------------------------------------------------------------------------
      def figures
        return 3
      end
      #--------------------------------------------------------------------------
      # * Frame Update
      #--------------------------------------------------------------------------
      def update
        super
        if active
          last_number = @number
          update_number
          if @number != last_number
            Sound.play_cursor
            refresh
          end
        end
      end
      #--------------------------------------------------------------------------
      # * Update Quantity
      #--------------------------------------------------------------------------
      def update_number
        change_number(1)   if Input.repeat?(:RIGHT)
        change_number(-1)  if Input.repeat?(:LEFT)
        change_number(10)  if Input.repeat?(:UP)
        change_number(-10) if Input.repeat?(:DOWN)
      end
      #--------------------------------------------------------------------------
      # * Change Quantity
      #--------------------------------------------------------------------------
      def change_number(amount)
        @number = [[@number + amount, @max].min, 1].max
      end
      #--------------------------------------------------------------------------
      # * Update Cursor
      #--------------------------------------------------------------------------
      def update_cursor
        @cursor_y ||= 0
        cursor_rect.set(cursor_x, @cursor_y, cursor_width, line_height)
      end
    end
    
    #==============================================================================
    # ** Scene_Storage
    #==============================================================================
    
    class Scene_Storage < Scene_MenuBase
      #--------------------------------------------------------------------------
      # * Start Processing
      #--------------------------------------------------------------------------
      def start
        super
        @storage_gold = $game_temp.storage_gold
        @storage_category = $game_temp.storage_category
        @storage_name_window = $game_temp.storage_name_window
        create_help_window
        create_command_window
        create_name_window
    #~     create_dummy_window
        create_category_window
        create_item_window
        create_number_window
        create_gold_window
        create_status_window #OTTO
        create_equip_window #OTTO
        create_background_image #OTTO
      end
    
      #--------------------------------------------------------------------------
      # * Create Command Window
      #--------------------------------------------------------------------------
      def create_command_window
        @command_window = Window_StorageCommand.new
        @command_window.viewport = @viewport
        @command_window.width = @help_window.width #gottino
        @command_window.y = @help_window.height
        @command_window.set_handler(:withdraw, method(:command_withdraw))
        @command_window.set_handler(:store, method(:command_store))
        @command_window.set_handler(:cancel, method(:return_scene))
      end
    
      #-------------------------------------------------------------------------
      # Create Status Window #by OTTO copy/pasted from the menu script
      #-------------------------------------------------------------------------
      def create_status_window
        @Status_window = Window_Base.new(475,120,165,84)
        @Status_window.contents.clear
        @Status_window.change_color(@Status_window.normal_color)
        @Status_window.draw_text(1, -10 , 120, 48, @actor.name)
        @Status_window.draw_actor_hp(@actor, 0, 40, 120)
      end
    
      #-------------------------------------------------------------------------
      # Create Equip Window #by OTTO copy/pasted from the menu script
      #-------------------------------------------------------------------------
    
      def create_equip_window
        @equip_window = Window_Base.new(475,183,165,48)
        @equip_window.contents.clear
        if @actor.equips[0] != nil
          @equip_window.draw_icon(@actor.equips[0].icon_index, 36, 0, true)
          @equip_window.draw_text(0, -12 , 120, 48, RE_MENU::Equip)
          #INSERT CURRENT / REMAINING AMMO HERE # OTTO
          if $game_player.equipped_weapon != nil
           @ammo = $game_player.equipped_weapon.bullets
           @mags = $game_party.item_number($game_player.equipped_weapon.magazine)
          end
          if $game_switches[16] == true #OTTO for Infinite Ammo
           @equip_window.contents.font.name =["VL Gothic"] #<- Font with Infinite character
           @equip_window.draw_text(72, -12, 120, 48, "∞") # <- Show Infinte symbol
          else    #<- added for infinite Ammo too
           @equip_window.draw_text(72, -12 , 120, 48, $game_player.equipped_weapon.bullets)
         end #End of OTTO for Infinite Ammo
        else
          @equip_window.draw_text(0, -12 , 120, 48, RE_MENU::Equip)
        end
      end
    
      #OTTO
      def create_background_image
        @sfondo = Sprite.new
        @sfondo.bitmap = Cache.system("Storage_"+$game_variables[9].to_s)
      
        @sfondo.x = 0
        @sfondo.y = 0
        #@sfondo.z =
        @sfondo.opacity = 255
      
      end
    
      def terminate
          super
          dispose_background
       end
    
       def dispose_background
          @sfondo.bitmap.dispose
          @sfondo.dispose
       end
    
      #--------------------------------------------------------------------------
      # * Create Storage Name Window
      #--------------------------------------------------------------------------
      def create_name_window
        @name_window = Window_StorageName.new
        @name_window.viewport = @viewport
        @name_window.x = @command_window.width
        @name_window.y = @help_window.height
        if @storage_name_window == true
          @name_window.show
        end
      end
      #--------------------------------------------------------------------------
      # * Create Dummy Window
      #--------------------------------------------------------------------------
      def create_dummy_window
        wy = @command_window.y + @command_window.height
        wh = Graphics.height - wy
        @dummy_window = Window_Base.new(0, wy, Graphics.width, wh)
        @dummy_window.viewport = @viewport
      end
      #--------------------------------------------------------------------------
      # * Create Quantity Input Window
      #--------------------------------------------------------------------------
      def create_number_window
        @number_window = Window_StorageNumber.new
        @number_window.viewport = @viewport
        @number_window.x = (274) #((Graphics.width / 2) - (@number_window.width / 2))
        @number_window.y = (262) #((Graphics.height / 2) - (@number_window.height / 2))
        @number_window.hide
        @number_window.set_handler(:ok,     method(:on_number_ok))
        @number_window.set_handler(:cancel, method(:on_number_cancel))
      end
      #--------------------------------------------------------------------------
      # * Create Category Window
      #--------------------------------------------------------------------------
      def create_category_window
        @category_window = Window_StorageCategory.new(@storage_gold)
        @category_window.viewport = @viewport
        @category_window.help_window = @help_window
    #~     @category_window.y = @dummy_window.y
        @category_window.hide.deactivate
        @category_window.set_handler(:ok,     method(:on_category_ok))
        @category_window.set_handler(:cancel, method(:on_category_cancel))
      end
      #--------------------------------------------------------------------------
      # * Create Item Window
      #--------------------------------------------------------------------------
      def create_item_window
        if @storage_category == false
          wy = @command_window.y + @command_window.height
        else
          wy = @category_window.y + @category_window.height
        end
        wh = Graphics.height - wy
        @item_window = Window_StorageItemList.new(0, wy, Graphics.width, wh)
        @item_window.viewport = @viewport
        @item_window.help_window = @help_window
        @item_window.hide
        @item_window.set_handler(:ok,     method(:on_item_ok))
        @item_window.set_handler(:cancel, method(:on_item_cancel))
        if @storage_category == false
          @item_window.category = :item
        else
          @category_window.item_window = @item_window
        end
      end
      #--------------------------------------------------------------------------
      # * Create Item Window
      #--------------------------------------------------------------------------
      def create_gold_window
        @gold_window = Window_GoldTransfer.new
        @gold_window.viewport = @viewport
        @gold_window.x = ((Graphics.width / 2) - (@gold_window.width / 2))
        @gold_window.y = ((Graphics.height / 2) - (@gold_window.height / 2))
        @gold_window.hide
        @gold_window.set_handler(:ok,     method(:on_gold_ok))
        @gold_window.set_handler(:cancel, method(:on_gold_cancel))
      end
      #--------------------------------------------------------------------------
      # * Start Category Selection
      #--------------------------------------------------------------------------
      def start_category_selection
        @dummy_window.hide
        @item_window.show
        @item_window.unselect
        @item_window.refresh
        @item_window.storage = @command_window.current_symbol
        @category_window.show.activate
      end
      #--------------------------------------------------------------------------
      # * [Withdraw] Command
      #--------------------------------------------------------------------------
      def command_withdraw
        if @storage_category == false and @storage_gold == true
          case @command_window.current_symbol
          when :withdraw
            @gold_window.set(max_withdraw, 24)
          when :store
            @gold_window.set(max_store, 0)
          end
          @gold_window.show.activate
        elsif @storage_category == false
    #~       @dummy_window.hide
          @item_window.show.activate
          @item_window.storage = @command_window.current_symbol
          @item_window.select_last
        else
          start_category_selection
        end
      end
      #--------------------------------------------------------------------------
      # * [Store] Command
      #--------------------------------------------------------------------------
      def command_store
        if @storage_category == false and @storage_gold == true
          case @command_window.current_symbol
          when :withdraw
            @gold_window.set(max_withdraw, 24)
          when :store
            @gold_window.set(max_store, 0)
          end
          @gold_window.show.activate
        elsif @storage_category == false
    #~       @dummy_window.hide
          @item_window.show.activate
          @item_window.storage = @command_window.current_symbol
          @item_window.select_last
        else
          start_category_selection
        end
      end
      #--------------------------------------------------------------------------
      # * Category [OK]
      #--------------------------------------------------------------------------
      def on_category_ok
        case @category_window.current_symbol
        when :item, :weapon, :armor
          @item_window.activate
          @item_window.select_last
        when :gold
          case @command_window.current_symbol
          when :withdraw
            @gold_window.set(max_withdraw, 24)
          when :store
            @gold_window.set(max_store, 0)
          end
          @gold_window.show.activate
        end
      end
      #--------------------------------------------------------------------------
      # * Category [Cancel]
      #--------------------------------------------------------------------------
      def on_category_cancel
        @command_window.activate
        @dummy_window.show
        @item_window.hide
        @category_window.hide
      end
      #--------------------------------------------------------------------------
      # * Item [OK]
      #--------------------------------------------------------------------------
      def on_item_ok
        @item = @item_window.item
        case @command_window.current_symbol
        when :withdraw
          @number_window.set(@item, max_withdraw)
        when :store
          @number_window.set(@item, max_store)
        end
        @number_window.show.activate
      end
      #--------------------------------------------------------------------------
      # * Item [Cancel]
      #--------------------------------------------------------------------------
      def on_item_cancel
        @item_window.unselect
        if @storage_category == false
          @item_window.hide
    #~       @dummy_window.show
          @command_window.activate
        else
          @category_window.activate
        end
      end
      #--------------------------------------------------------------------------
      # * Quantity Input [OK]
      #--------------------------------------------------------------------------
      def on_number_ok
        Sound.play_ok
        case @command_window.current_symbol
        when :withdraw
          do_withdraw(@number_window.number)
        when :store
          do_store(@number_window.number)
        end
        @number_window.hide
        @item_window.refresh
        @item_window.activate
        @item_window.select_last
      end
      #--------------------------------------------------------------------------
      # * Quantity Input [Cancel]
      #--------------------------------------------------------------------------
      def on_number_cancel
        Sound.play_cancel
        @number_window.hide
        @item_window.activate
      end
      #--------------------------------------------------------------------------
      # * Gold Quantity Input [OK]
      #--------------------------------------------------------------------------
      def on_gold_ok
        case @command_window.current_symbol
        when :withdraw
          gold_withdraw(@gold_window.number)
          @gold_window.set(max_withdraw, 24)
        when :store
          gold_store(@gold_window.number)
          @gold_window.set(max_store, 0)
        end
        @gold_window.show.activate
        @gold_window.refresh
        Sound.play_ok
      end
      #--------------------------------------------------------------------------
      # * Gold Quantity Input [Cancel]
      #--------------------------------------------------------------------------
      def on_gold_cancel
        Sound.play_cancel
        if @storage_category == false && @storage_gold == true
          @command_window.activate
        else
          start_category_selection
        end
        @gold_window.hide
      end
      #--------------------------------------------------------------------------
      # * Execute Withdraw
      #--------------------------------------------------------------------------
      def do_withdraw(number)
        $game_party.storage_lose_item(@item, number)
        $game_party.gain_item(@item, number)
      end
      #--------------------------------------------------------------------------
      # * Execute Store
      #--------------------------------------------------------------------------
      def do_store(number)
        $game_party.storage_gain_item(@item, number)
        $game_party.lose_item(@item, number)
      end
      #--------------------------------------------------------------------------
      # * Gold Withdraw
      #--------------------------------------------------------------------------
      def gold_withdraw(number)
        $game_party.storage_lose_gold(number)
        $game_party.gain_gold(number)
      end
      #--------------------------------------------------------------------------
      # * Gold Store
      #--------------------------------------------------------------------------
      def gold_store(number)
        $game_party.lose_gold(number)
        $game_party.storage_gain_gold(number)
      end
      #--------------------------------------------------------------------------
      # * Get Maximum Quantity Withdrawable
      #--------------------------------------------------------------------------
      def max_withdraw
        case @category_window.current_symbol
        when :item, :weapon, :armor
          if $game_party.storage_item_number(@item) > 99
            return 99
          else
            $game_party.storage_item_number(@item)
          end
        when :gold
          if $game_party.storage_gold > 999
            return 999
          else
            $game_party.storage_gold
          end
        end
      end
      #--------------------------------------------------------------------------
      # * Get Maximum Quantity Storable
      #--------------------------------------------------------------------------
      def max_store
        case @category_window.current_symbol
        when :item, :weapon, :armor
          if $game_party.item_number(@item) > 99
            return 99
          else
            $game_party.item_number(@item)
          end
        when :gold
          if $game_party.gold > 999
            return 999
          else
            $game_party.gold
          end
        end
      end
    end

    Addon for Storage Box:
    Spoiler
    Code:
    =begin
    #==============================================================================#
    #   AMN Bravo Item Storage addon
    #   Version 1.00
    #   Author: AMoonlessNight
    #   Date: 15 Aug 2018
    #   Latest: 15 Aug 2018
    #==============================================================================#
    #   UPDATE LOG
    #------------------------------------------------------------------------------#
    # 15 Aug 2018 - created the script
    #==============================================================================#
    #   TERMS OF USE
    #------------------------------------------------------------------------------#
    # - Please credit AMoonlessNight or A-Moonless-Night
    # - Free for non-commercial use
    # - See Bravo2Kilo's terms and conditions regarding commercial usage
    # - I'd love to see your game if you end up using one of my scripts
    #==============================================================================#
    
    This script changes the Storage Scene from Bravo2Kilo's Storage System script.
    You can also set certain items to not be able to be stored.
    
    Use the following in an item's notes to set it as unstorable:
    
    <do not store>
    
    =end
    
    #==============================================================================
    #  Please do not edit below this point unless you know what you are doing.
    #==============================================================================
    
    module DataManager
      class <<self; alias amn_storage_datamanager_loaddb load_database; end
      def self.load_database
        amn_storage_datamanager_loaddb
        load_notetags_unstorable_items
      end
    
      def self.load_notetags_unstorable_items
        groups = [$data_items, $data_weapons, $data_armors]
        for group in groups
          for obj in group
            next if obj.nil?
            obj.load_notetags_unstorable
          end
        end
      end
    end
    
    class RPG::BaseItem
      attr_accessor :unstorable_item
      def load_notetags_unstorable
        @unstorable_item = false
        self.note.split(/[\r\n]+/).each { |line|
          case line
          when /<do[ -_]*not[ -_]*store>/i
            @unstorable_item = true
          end
        }
      end
    
    end
    #==============================================================================
    # ** Window_OGItemList
    #------------------------------------------------------------------------------
    #  This window displays a list of party items on the item screen. It is a copy
    #  of the default Window_ItemList, since the original has been overwritten by
    #  the Resident Evil Menu.
    #==============================================================================
    class Window_OGItemList < Window_Selectable
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize(x, y, width, height)
        super
        @category = :none
        @data = []
      end
      #--------------------------------------------------------------------------
      # * Set Category
      #--------------------------------------------------------------------------
      def category=(category)
        return if @category == category
        @category = category
        refresh
        self.oy = 0
      end
      #--------------------------------------------------------------------------
      # * Get Digit Count
      #--------------------------------------------------------------------------
      def col_max
        return 2
      end
      #--------------------------------------------------------------------------
      # * Get Number of Items
      #--------------------------------------------------------------------------
      def item_max
        @data ? @data.size : 1
      end
      #--------------------------------------------------------------------------
      # * Get Item
      #--------------------------------------------------------------------------
      def item
        @data && index >= 0 ? @data[index] : nil
      end
      #--------------------------------------------------------------------------
      # * Get Activation State of Selection Item
      #--------------------------------------------------------------------------
      def current_item_enabled?
        enable?(@data[index])
      end
      #--------------------------------------------------------------------------
      # * Include in Item List?
      #--------------------------------------------------------------------------
      def include?(item)
        case @category
        when :item
          item.is_a?(RPG::Item) && !item.key_item?
        when :weapon
          item.is_a?(RPG::Weapon)
        when :armor
          item.is_a?(RPG::Armor)
        when :key_item
          item.is_a?(RPG::Item) && item.key_item?
        else
          false
        end
      end
      #--------------------------------------------------------------------------
      # * Display in Enabled State?
      #--------------------------------------------------------------------------
      def enable?(item)
        $game_party.usable?(item)
      end
      #--------------------------------------------------------------------------
      # * Create Item List
      #--------------------------------------------------------------------------
      def make_item_list
        @data = $game_party.all_items.select {|item| include?(item)}
        @data.push(nil) if include?(nil)
      end
      #--------------------------------------------------------------------------
      # * Restore Previous Selection Position
      #--------------------------------------------------------------------------
      def select_last
        select(@data.index($game_party.last_item.object) || 0)
      end
      #--------------------------------------------------------------------------
      # * Draw Item
      #--------------------------------------------------------------------------
      def draw_item(index)
        item = @data[index]
        if item
          rect = item_rect(index)
          rect.width -= 4
          draw_item_name(item, rect.x + 4, rect.y, enable?(item))
          draw_item_number(rect, item)
        end
      end
      #--------------------------------------------------------------------------
      # * Draw Number of Items
      #--------------------------------------------------------------------------
      def draw_item_number(rect, item)
        draw_text(rect, sprintf(":%2d", $game_party.item_number(item)), 2)
      end
      #--------------------------------------------------------------------------
      # * Update Help Text
      #--------------------------------------------------------------------------
      def update_help
        @help_window.set_item(item)
      end
      #--------------------------------------------------------------------------
      # * Refresh
      #--------------------------------------------------------------------------
      def refresh
        make_item_list
        create_contents
        draw_all_items
      end
    end
    #==============================================================================
    # ** Window_ItemList
    #------------------------------------------------------------------------------
    #  This window displays a list of party items on the item screen.
    #==============================================================================
    class Window_StorageItemList < Window_ItemList
      def item_max
        @data ? @data.size : 1
    #~     8  + $game_variables[14]
      end
    
      def include?(item)
        case @category
        when :item
          item.is_a?(RPG::Item) && !item.key_item? #!item.unstorable_item
        when :weapon
          item.is_a?(RPG::Weapon) && !item.key_item? #!item.unstorable_item
        when :armor
          item.is_a?(RPG::Armor) && !item.key_item? #!item.unstorable_item
        when :all
          item && !item.key_item? #!item.unstorable_item
        else
          false
        end
      end
    
      #--------------------------------------------------------------------------
      # * Display in Enabled State?
      #--------------------------------------------------------------------------
      def enable?(item)
        if item.is_a?(RPG::Item)
          return true if !item.unstorable_item
        elsif item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor)
          return true
        else
          return false
        end
      end
     
     
    end
    #==============================================================================
    # ** Window_WithdrawItemList
    #------------------------------------------------------------------------------
    #  This window displays a list of party items that are currently in storage.
    #==============================================================================
    class Window_WithdrawItemList < Window_OGItemList
      #--------------------------------------------------------------------------
      # * Object Initialization
      #--------------------------------------------------------------------------
      def initialize(x, y, width, height)
        super(x + 10, y + 9, width, height - 24)
      end
      #--------------------------------------------------------------------------
      # * Get Digit Count
      #--------------------------------------------------------------------------
      def col_max
        return 1
      end
      #--------------------------------------------------------------------------
      # * Include in Item List?
      #--------------------------------------------------------------------------
      def include?(item)
        case @category
        when :item
          item.is_a?(RPG::Item) && !item.key_item?
        when :weapon
          item.is_a?(RPG::Weapon)
        when :armor
          item.is_a?(RPG::Armor)
        when :all
          item
        else
          false
        end
      end
      #--------------------------------------------------------------------------
      # * Display in Enabled State?
      #--------------------------------------------------------------------------
      def enable?(item)
        if item.is_a?(RPG::Item)
          return true if !item.key_item?
        elsif item.is_a?(RPG::Weapon) || item.is_a?(RPG::Armor)
          return true
        else
          return false
        end
      end
      #--------------------------------------------------------------------------
      # * Create Item List
      #--------------------------------------------------------------------------
      def make_item_list
        @data = $game_party.storage_all_items.select {|item| include?(item) }
        @data.push(nil) if include?(nil)
      end
      #--------------------------------------------------------------------------
      # * Draw Number of Items
      #--------------------------------------------------------------------------
      def draw_item_number(rect, item)
        draw_text(rect, sprintf(":%2d", $game_party.storage_item_number(item)), 2)
      end
    end
    
    class Window_StorageCategory < Window_ItemCategory
      attr_reader   :wd_item_window
      #--------------------------------------------------------------------------
      # * Frame Update
      #--------------------------------------------------------------------------
      def update
        super
        @wd_item_window.category = current_symbol if @wd_item_window
      end
      #--------------------------------------------------------------------------
      # * Set Item Window
      #--------------------------------------------------------------------------
      def wd_item_window=(item_window)
        @wd_item_window = item_window
        update
      end
    end
    
    class Scene_Storage < Scene_MenuBase
    
      alias amn_storage_scenestorage_createitemwind create_item_window
      def create_item_window
        amn_storage_scenestorage_createitemwind
        @item_window.show
        @item_window.storage = :store
        create_wditem_window
      end
    
      alias amn_storage_scenestorage_createdummywind create_dummy_window
      def create_dummy_window
        amn_storage_scenestorage_createdummywind
        @dummy_window.hide
      end
    
      def create_wditem_window
        if @storage_category == false
          wy = @command_window.y + @command_window.height
        else
          wy = @category_window.y + @category_window.height
        end
        wh = Graphics.height - wy
        ww = @item_window.x
        @wd_item_window = Window_WithdrawItemList.new(0, wy, ww, wh)
        @wd_item_window.viewport = @viewport
        @wd_item_window.help_window = @help_window
        @wd_item_window.set_handler(:ok,     method(:on_withdraw_ok))
        @wd_item_window.set_handler(:cancel, method(:on_withdraw_cancel))
        if @storage_category == false
          @wd_item_window.category = :item #Category for Store Window
        else
          @category_window.wd_item_window = @wd_item_window
        end
        @wd_item_window.refresh
      end
    
      def start_category_selection
        @item_window.unselect
        @item_window.refresh
        @wd_item_window.unselect
        @wd_item_window.refresh
        @category_window.show.activate
      end
      #--------------------------------------------------------------------------
      # * [Withdraw] Command
      #--------------------------------------------------------------------------
      def command_withdraw
        if @storage_category == false and @storage_gold == true
          case @command_window.current_symbol
          when :withdraw
            @gold_window.set(max_withdraw, 24)
          when :store
            @gold_window.set(max_store, 0)
          end
          @gold_window.show.activate
        elsif @storage_category == false
          @wd_item_window.refresh
          @wd_item_window.activate
          @wd_item_window.select_last
        else
          start_category_selection
        end
      end
      #--------------------------------------------------------------------------
      # * [Store] Command
      #--------------------------------------------------------------------------
      def command_store
        if @storage_category == false and @storage_gold == true
          case @command_window.current_symbol
          when :withdraw
            @gold_window.set(max_withdraw, 24)
          when :store
            @gold_window.set(max_store, 0)
          end
          @gold_window.show.activate
        elsif @storage_category == false
          @item_window.refresh
          @item_window.activate
          @item_window.select_last
        else
          start_category_selection
        end
      end
      #--------------------------------------------------------------------------
      # * Category [OK]
      #--------------------------------------------------------------------------
      def on_category_ok
        case @category_window.current_symbol
        when :item, :weapon, :armor
          case @command_window.current_symbol
          when :withdraw
            @wd_item_window.refresh
            @wd_item_window.activate
            @wd_item_window.select_last
          when :store
            @item_window.refresh
            @item_window.activate
            @item_window.select_last
          end
        when :gold
          case @command_window.current_symbol
          when :withdraw
            @gold_window.set(max_withdraw, 24)
          when :store
            @gold_window.set(max_store, 0)
          end
          @gold_window.show.activate
        end
      end
      #--------------------------------------------------------------------------
      # * Category [Cancel]
      #--------------------------------------------------------------------------
      def on_category_cancel
        @command_window.activate
        @category_window.hide
      end
    
      def on_withdraw_ok
        @item = @wd_item_window.item
        @number_window.set(@item, max_withdraw)
        @number_window.show.activate
      end
    
      def on_withdraw_cancel
        @wd_item_window.unselect
        if @storage_category == false
          @command_window.activate
        else
          @category_window.activate
        end
      end
    
      #--------------------------------------------------------------------------
      # * Item [OK]
      #--------------------------------------------------------------------------
      def on_item_ok
        @item = @item_window.item
        @number_window.set(@item, max_store)
        @number_window.show.activate
      end
      #--------------------------------------------------------------------------
      # * Item [Cancel]
      #--------------------------------------------------------------------------
      def on_item_cancel
        @item_window.unselect
        if @storage_category == false
          @command_window.activate
        else
          @category_window.activate
        end
      end
      #--------------------------------------------------------------------------
      # * Quantity Input [OK]
      #--------------------------------------------------------------------------
      def on_number_ok
        Sound.play_ok
        case @command_window.current_symbol
        when :withdraw
          do_withdraw(@number_window.number)
          @wd_item_window.activate
          @wd_item_window.select_last
        when :store
          do_store(@number_window.number)
          @item_window.activate
          @item_window.select_last
        end
        @item_window.refresh
        @wd_item_window.refresh
        @number_window.hide
      end
      #--------------------------------------------------------------------------
      # * Quantity Input [Cancel]
      #--------------------------------------------------------------------------
      def on_number_cancel
        Sound.play_cancel
        @number_window.hide
        case @command_window.current_symbol
        when :withdraw
          @wd_item_window.activate
        when :store
          @item_window.activate
        end
        @item_window.refresh
        @wd_item_window.refresh
      end
    end

    I'm really sorry for double posting, but I coudn't fit all into one post, and like I said, these were edited scripts so there probably was no use in linking to the official scripts.

    Hopefully some mod can merge the two posts into one :(