Compatibility Issue with Instance Items and Storage Box

Otto

Veteran
Veteran
Joined
Apr 24, 2015
Messages
119
Reaction score
70
First Language
Engilsh
Primarily Uses
RM2k3
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:
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
 
Last edited:

Otto

Veteran
Veteran
Joined
Apr 24, 2015
Messages
119
Reaction score
70
First Language
Engilsh
Primarily Uses
RM2k3
Storage Box
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:
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 :(
 

Users Who Are Viewing This Thread (Users: 0, Guests: 1)

Latest Threads

Latest Profile Posts

Day 9 of giveaways! 8 prizes today :D
He mad, but he cute :kaopride:

Our latest feature is an interview with... me?!

People4_2 (Capelet off and on) added!

Just beat the last of us 2 last night and starting jedi: fallen order right now, both use unreal engine & when I say i knew 80% of jedi's buttons right away because they were the same buttons as TLOU2 its ridiculous, even the same narrow hallway crawl and barely-made-it jump they do. Unreal Engine is just big budget RPG Maker the way they make games nearly identical at its core lol.

Forum statistics

Threads
106,038
Messages
1,018,466
Members
137,821
Latest member
Capterson
Top