The RPG Maker Resource Kit

RMRK RPG Maker Creation => VX => VX Scripts Database => Topic started by: modern algebra on August 31, 2009, 02:15:21 PM

Title: Item Drop Ranks 1.0b
Post by: modern algebra on August 31, 2009, 02:15:21 PM
Item Drop Ranks
Version: 1.0b
Author: modern algebra
Date: October 8, 2009

Version History



Description


This script allows you to set up a dummy item that, when added to the inventory, randomly dispenses one item of a specified rank instead. This can have many uses, from increasing the number of items a monster can drop to changing potential drops based on the difficulty level the player is at.

Basically, you can give any item, weapon or armor an integer rank, and you can also setup items that dispense a random item by rank rather than just itself. For instance, you can set Potion, Magic Water, and Antidote to be rank 1, and you can then make a dummy item that dispenses items of rank 1. Whenever the party gets that dummy item, whether through a monster drop or an event, it will instead randomly pick either a Potion, Magic Water, or Antidote and give that instead.

Features


Instructions

Please see the header of the script for detailed instructions.

Script


Code: [Select]
#==============================================================================
#    Item Drop Ranks
#    Version: 1.0b
#    Author: modern algebra (rmrk.net)
#    Date: October 8, 2009
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Description:
#
#    This script allows you to set up a dummy item that, when added to the
#   inventory, randomly dispenses one item of a specified rank instead. This
#   can have many uses, from increasing the number of items a monster can drop
#   to changing potential drops based on the difficulty level the player is at.
#
#    Basically, you can give any item, weapon or armor an integer rank, and you
#   can also setup items that dispense a random item by rank rather than just
#   itself. For instance, you can set Potion, Magic Water, and Antidote to be
#   rank 1, and you can then make a dummy item that dispenses items of rank 1.
#   Whenever the party gets that dummy item, whether through a monster drop or
#   an event, it will instead randomly pick either a Potion, Magic Water, or
#   Antidote and give that instead.
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Instructions:
#
#    Place script above Main and below Materials in the Script Editor (F11).
#
#    To use this script, you must:
#      a) give ranks to items, weapons, and armors
#      b) specify dummy items that dispense other items based on rank.
#
#    a) To give a rank to an item, all that you need to do is place the
#      following code in its notebox:
#
#        \DROP_RANK[rank]
#          rank : the rank you wish to assign this item.
#
#      Rank assignments are arbitrary, but it is recommended that you create a
#      system that is easy for you to organize. For instance, you could make
#      the ranks go from weakest to strongest items. Note that if you do not
#      set a rank to an item, than it has no rank and can only be obtained
#      through a direct item gain event, not through a dummy item.
#
#    b) The dummy items are the items that dispense other items based on the
#      rank you give items in (a). To specify an item as a dummy item, you need
#      to use one or more of the following codes in the item's notebox:
#
#        \RANK_DROP_PERCENT[rank, percent]
#           rank    : the rank this item can drop. It can be either an integer
#             or a variable. If it is an integer between quotes (ex: "2"),
#             then the rank it drops is the value of the variable with ID 2.
#             If it is just an integer (ex: 2), then it drops rank 2 items.
#           percent : the chance it will drop an item of this rank. Defaults to
#                    100
#
#      You can have as many of these in the dummy item as you like, which is
#      why there is a percent option. For instance, a notebox with these codes:
#        \RANK_DROP_PERCENT[4, 70]
#        \RANK_DROP_PERCENT[5, 30]
#
#      would drop an item of rank 4 70% of the time and an item of rank 5 30%
#      of the time. Note that if the percentages do not add up to 100, they are
#      scaled, so something like this:
#        \RANK_DROP_PERCENT[1, 120]
#        \RANK_DROP_PERCENT["3", 80]
#
#      would actually be a 60% chance of dropping items with rank 1 and 40%
#      chance of dropping an item with rank of whatever the value of variable 3
#      is. And you can make as many of these as you like, so a dummy item can
#      drop more than a single rank of item.
#
#    Please note that items, weapons, and armors are completely distinct in the
#   ranking system. A dummy weapon that drops rank 1 will only drop rank 1
#   weapons, not items or armors. The same is true of dummy items and armors.
#
#    Last but not least, there are some message codes included in this script
#   for printing out the names of the items in a message box. These are:
#      \NI[item_id]
#        item_id : ID of Item whose name should be printed
#      \NW[weapon_id]
#        weapon_id : ID of Weapon whose name should be printed
#      \NA[armor_id]
#        armor_id : ID of Armor whose name should be printed
#==============================================================================

#==============================================================================
# ** RPG::BaseItem
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    attr_writer - idr_drop_name, idr_drop_icon, idr_drop_desc
#    aliased method - name, icon_index, description
#    new methods - drop_rank, rankdrop_item?, rank_percents
#==============================================================================

class RPG::BaseItem
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_writer :idr_drop_name # The name of the item set as dropped
  attr_writer :idr_drop_icon # The icon of the item set as dropped
  attr_writer :idr_drop_desc # The description of the item set as dropped
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Name
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias monabra_drp_ranks_name_1jb1 name unless self.method_defined? (:monabra_drp_ranks_name_1jb1)
  def name (*args)
    return @idr_drop_name if self.rankdrop_item? && !@idr_drop_name.nil?
    # Return Original Method if not a rank item
    return monabra_drp_ranks_name_1jb1 (*args)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Icon Index
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias algmod_icndrop_idr_6df2 icon_index unless self.method_defined? (:algmod_icndrop_idr_6df2)
  def icon_index (*args)
    return @idr_drop_icon if self.rankdrop_item? && !@idr_drop_icon.nil?
    # Return original method if not a rank item
    return algmod_icndrop_idr_6df2 (*args)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Description
  #``````````````````````````````````````````````````````````````````````````
  #  Not necessary for anything I know of, but included in case there is a
  # drop item script that takes the description of the item asked for
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias malgbr_desc_drop_idr_5gv2 description unless self.method_defined? (:malgbr_desc_drop_idr_5gv2)
  def description (*args)
    return @idr_drop_desc if self.rankdrop_item? && !@idr_drop_desc.nil?
    # Return original method if not a rank item
    return malgbr_desc_drop_idr_5gv2 (*args)
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Drop Rank
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def drop_rank
    return $1.to_i if self.note[/\\DROP_RANK\[(\d+)\]/i] != nil
    return -1
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Check if rank item
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def rankdrop_item?
    return self.note[/\\RANK_DROP_PERCENT\[("?\d+"?),?\s*(\d*)\]/i] != nil
  end
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Rank Percents
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  def rank_percents
    rank_drops = []
    text = self.note.dup
    while text.sub! (/\\RANK_DROP_PERCENT\[("?\d+"?),?\s*(\d*)\]/i) { "" } != nil
      rank = $1.include? ('"') ? $game_variables[$1[/(\d+)/].to_i] : $1.to_i
      percent = $2.nil? ? 100 : $2.to_i
      rank_drops.push ([rank, percent])
    end
    # Even out percentages
    count = 0
    rank_drops.each { |a| count += a[1] }
    percent_mod = 100.0 / count.to_f
    rank_drops.each { |a| a[1] *= percent_mod }
    return rank_drops
  end
end

#==============================================================================
# ** Game Temp
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    new attr_reader - idr_item_drop_ranks, idr_weapon_drop_ranks,
#      idr_armor_drop_ranks
#    aliased method - initialize
#==============================================================================

class Game_Temp
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Public Instance Variables
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  attr_reader :idr_item_drop_ranks # 2D array holding items at each drop rank
  attr_reader :idr_weapon_drop_ranks # 2D array holding weapons at each drop rank
  attr_reader :idr_armor_drop_ranks # 2D array holding armors at each drop rank
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Object Initialization
  #``````````````````````````````````````````````````````````````````````````
  #  Initialize drop rank arrays. This is done in Game_Temp so that it will
  # be renewed upon each play in case items have been added or ranks changed.
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias monrba_itmdroprnk_init_9bv2 initialize
  def initialize (*args)
    # Run Original Method
    monrba_itmdroprnk_init_9bv2 (*args)
    # Create Drop Rank arrays
    @idr_item_drop_ranks = []
    @idr_weapon_drop_ranks = []
    @idr_armor_drop_ranks = []
    # Get Item Ranks
    for i in 1...$data_items.size
      item_rank = $data_items[i].drop_rank
      next if item_rank == -1
      @idr_item_drop_ranks[item_rank] = [] if @idr_item_drop_ranks[item_rank].nil?
      @idr_item_drop_ranks[item_rank].push (i)
    end
    # Fill in nil drop ranks
    @idr_item_drop_ranks.each { |array| array = [] if array.nil? }
    # Do the same for weapons and armors
    for i in 1...$data_weapons.size
      item_rank = $data_weapons[i].drop_rank
      next if item_rank == -1
      @idr_weapon_drop_ranks[item_rank] = [] if @idr_weapon_drop_ranks[item_rank].nil?
      @idr_weapon_drop_ranks[item_rank].push (i)
    end
    @idr_weapon_drop_ranks.each { |array| array = [] if array.nil? }
    for i in 1...$data_armors.size
      item_rank = $data_armors[i].drop_rank
      next if item_rank == -1
      @idr_armor_drop_ranks[item_rank] = [] if @idr_armor_drop_ranks[item_rank].nil?
      @idr_armor_drop_ranks[item_rank].push (i)
    end
    @idr_armor_drop_ranks.each { |array| array = [] if array.nil? }
  end
end

#==============================================================================
# ** Game_Party
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - gain_item
#==============================================================================

class Game_Party
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Gain Item
  #    item : the item being gained
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias mornba_gn_itm_drpranks_3hn4 gain_item
  def gain_item (item, *args)
    # If the item is a drop rank dummy item
    if !item.nil? && item.rankdrop_item?
      percent = 0.0
      random = rand (100)
      # Randomly determine which rank the drop is from
      for rank_percent in item.rank_percents
        rank = rank_percent[0]
        percent += rank_percent[1]
        break if random < percent
      end
      # Get rank types and items array
      case item
      when RPG::Item
        rank_array = $game_temp.idr_item_drop_ranks[rank]
        items_array = $data_items
      when RPG::Weapon
        rank_array = $game_temp.idr_weapon_drop_ranks[rank]
        items_array = $data_weapons
      when RPG::Armor
        rank_array = $game_temp.idr_armor_drop_ranks[rank]
        items_array = $data_armors
      end
      # If invalid
      if !rank_array.nil? && !rank_array.empty?
        # Randomize item and retrieve it
        new_item = items_array[rank_array[rand (rank_array.size)]]
        # Recursively call method in case new_item is also a rankdrop item
        gain_item (new_item, *args)
        item.idr_drop_name = new_item.name
        item.idr_drop_icon = new_item.icon_index
        item.idr_drop_desc = new_item.description
        return
      end
    end
    # Run Original Method
    mornba_gn_itm_drpranks_3hn4 (item, *args)
  end
end

#==============================================================================
# ** Window_Message
#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
#  Summary of Changes:
#    aliased method - convert_special_characters
#==============================================================================

class Window_Message < Window_Selectable
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  # * Convert Special Characters
  #~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  alias monalgbra_idr_names_cnvrtspecchar_7kj1 convert_special_characters
  def convert_special_characters (*args)
    # Run Original Method
    monalgbra_idr_names_cnvrtspecchar_7kj1 (*args)
    # Message codes for printing the names of items, weapons, and armors
    @text.gsub! (/\\NI\[(\d+)\]/i) { $1.to_i > 0 ? $data_items[$1.to_i].name : "" }   # Item Name
    @text.gsub! (/\\NW\[(\d+)\]/i) { $1.to_i > 0 ? $data_weapons[$1.to_i].name : "" } # Weapon Name
    @text.gsub! (/\\NA\[(\d+)\]/i) { $1.to_i > 0 ? $data_armors[$1.to_i].name : "" } # Armor Name
  end
end

Credit



Thanks


Support


Please post in this topic for bug reports or suggestions.

Known Compatibility Issues

No currently known compatibility issues.

Author's Notes


Yay! RMVX Scripts Database is now 4 pages. My goal for August has been reached :P

Also, I am happy to make a demo for this script if anyone is confused.


Creative Commons License
This script by modern algebra is licensed under a Creative Commons Attribution-Non-Commercial-Share Alike 2.5 Canada License.
Title: Re: Item Drop Ranks 1.0
Post by: Cascading Dragon on August 31, 2009, 04:12:23 PM
Interesting...So the player would never actually get the dummy item? They would instead get whatever is randomally picked?  Or they use the dummy item and gain the random item?
Title: Re: Item Drop Ranks 1.0
Post by: modern algebra on August 31, 2009, 04:20:33 PM
They never get the dummy item at all. They get whatever is randomly picked.

EDIT::


If you wanted to have it where you got an item and once it was used you got the random selection, then that could be done too. All you'd need to do is have an item (for instance bag), and let that be the item gotten from the drop. Then, you could attach a common event to the item when it is used and have the common event give the dummy item.
Title: Re: Item Drop Ranks 1.0
Post by: modern algebra on October 08, 2009, 01:21:13 PM
Updated to 1.0b - fixing a bug with unequipping.
Title: Re: Item Drop Ranks 1.0b
Post by: EvilM00s on March 07, 2014, 04:50:28 PM
Very good, sir. Another addition to Astralis ROTDA.