TheoAllen

Theo - Limited Inventory

Aug 18th, 2013
221
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 18.49 KB | None | 0 0
  1. # =============================================================================
  2. # TheoAllen - Limited Inventory
  3. # Version : 1.2d
  4. # Contact : www.rpgmakerid.com (or) http://theolized.blogspot.com
  5. # (English Documentation)
  6. # =============================================================================
  7. ($imported ||= {})[:Theo_LimInventory] = true
  8. # =============================================================================
  9. # CHANGE LOGS:
  10. # -----------------------------------------------------------------------------
  11. # 2014.02.11 - Bugfix. Unequip item causes lose the item if inventory is full
  12. # 2013.10.07 - Bugfix. Item doesn't removed when discarded
  13. #            - Bugfix. Inventory amount not refreshed when item is discarded
  14. # 2013.10.04 - Compatibility fix with chest system
  15. # 2013.08.30 - Now unable to discard key item
  16. # 2013.08.22 - Bugfix. Item size notetag isn't working
  17. # 2013.08.19 - Bugfix when gained item
  18. #            - Bugfix when disable display item size in shop menu
  19. # 2013.08.18 - Finished script
  20. # =============================================================================
  21. =begin
  22.  
  23.   ---------------------------------------------------------------------------
  24.   Introduction :
  25.   This script allow you to limit your inventory by overall possesed items
  26.   instead of individual items
  27.  
  28.   ---------------------------------------------------------------------------
  29.   How to Use :
  30.   Put this script below material but above main
  31.   If you're using YEA - Shop Option, put it below that script
  32.   Edit configurations and the notetags as described below
  33.  
  34.   ---------------------------------------------------------------------------
  35.   Notetags :
  36.   write down these notetags to the notebox in your database
  37.  
  38.   <inv size: n>
  39.   Use this notetag where the n is a numeric value which is determine the size
  40.   of item. Use 0 for unlimited item. Only works for item and equipment such as
  41.   weapon or armor.
  42.  
  43.   <inv plus: n>
  44.   Use this notetag to determine the additional avalaible free inventory slot.
  45.   This notetag avalaible for Actor, Class, Equip, and States. If it's for
  46.   actor, avalaible inventory slot will increase when a new actor entered party.
  47.   If it's for equip, the avalaible slot will be increase if the certain equip
  48.   is equipped. And so do states
  49.  
  50.   <inv minus: n>
  51.   Inverse of <inv plus>. It will decrease the avalaible inventory slot. Pretty
  52.   clear I think.
  53.  
  54.   ---------------------------------------------------------------------------
  55.   Script call :
  56.   If you want to force gain an item even the inventory is full, you can do it
  57.   by script call. Just write this following line
  58.  
  59.   force_gain_item($data_items[id],amount)
  60.  
  61.   id is an item id in your database
  62.  
  63.   ---------------------------------------------------------------------------
  64.   Terms of use :
  65.   Credit me, TheoAllen. You are free to edit this script by your own. As long
  66.   as you don't claim it yours. For commercial purpose, don't forget to give me
  67.   a free copy of the game.
  68.  
  69. =end
  70. # =============================================================================
  71. # Configurations :
  72. # =============================================================================
  73. module THEO
  74.   module LimInv
  75.  
  76.   # --------------------------------------------------------------------------
  77.   # General Settings (just put true / false)
  78.   # --------------------------------------------------------------------------
  79.  
  80.     DynamicSlot       = true
  81.   # Total avalaible inventory slot depends on actor, states, total party
  82.   # members, etc ...
  83.  
  84.     Display_ItemSize  = true
  85.   # Diplay item size in item menu
  86.  
  87.     Include_Equip     = false
  88.   # Total used inventory slot will also include actor equipment.
  89.  
  90.     DrawTotal_Size    = true
  91.   # If true, item size window will show total weight of specified item. For
  92.   # example, you have 10 potions. And each potion has 3 size/weight. The window
  93.   # will show 30 instead of 3
  94.  
  95.   # --------------------------------------------------------------------------
  96.   # Numeric Settings
  97.   # --------------------------------------------------------------------------
  98.  
  99.     Default_FreeSlot  = 100
  100.   # Default free slot which is provided each actor. Of course, you may change
  101.   # it by notetag. If DynamicSlot is set to false, it will be the the total
  102.   # avalaible slot
  103.  
  104.     NearMaxed_Percent = 25
  105.   # Percentage to determine if the inventory is almost maxed out or not
  106.  
  107.     NearMaxed_Color   = 21
  108.   # If inventory is almost maxed out, the inventory window will be drawn in
  109.   # different color. The color code is same as \C[n] in message
  110.  
  111.     UseCommand_Size   = 200    
  112.   # The width of use item command window
  113.  
  114.   # --------------------------------------------------------------------------
  115.   # Vocab Settings (Self-explanatory I think)
  116.   # --------------------------------------------------------------------------
  117.  
  118.     InvSlotVocab    = "Inventory: "   # Inventory Vocab
  119.     InvSizeVocab    = "Item Size: "   # Item size / weight
  120.     SlotVocabShort  = "Inv:"          # Abbreviation for Inventory
  121.     UseVocab        = "Use item"      # Use item
  122.     DiscardVocab    = "Discard item"  # Discard Item
  123.     CancelVocab     = "Cancel"        # Cancel
  124.    
  125.   end
  126. end
  127. # ============================================================================
  128. # Do not touch anything pass this line.
  129. # ============================================================================
  130.  
  131. # I told you ...
  132.  
  133. # ============================================================================
  134. # Altered built in modules and classes
  135. # ============================================================================
  136. class << DataManager
  137.  
  138.   alias theo_limited_item_load_db load_database
  139.   def load_database
  140.     theo_limited_item_load_db
  141.     load_limited_slot
  142.   end
  143.  
  144.   def load_limited_slot
  145.     database = $data_actors + $data_classes + $data_weapons + $data_armors +
  146.       $data_states + $data_items
  147.     database.compact.each do |db|
  148.       db.load_limited_inv
  149.     end
  150.   end
  151. end
  152.  
  153. class RPG::BaseItem
  154.   attr_accessor :inv_size # Item inventory size
  155.   attr_accessor :inv_mod  # Inventory slot modifier
  156.  
  157.   def load_limited_inv
  158.     @inv_size = 1
  159.     @inv_mod = self.is_a?(RPG::Actor) ? THEO::LimInv::Default_FreeSlot : 0
  160.     self.note.split(/[\r\n]+/).each do |line|
  161.       case line
  162.       when /<(?:INV_SIZE|inv size): [ ]*(\d+)>/i
  163.         @inv_size = $1.to_i
  164.       when /<(?:INV_PLUS|inv plus): [ ]*(\d+)>/i
  165.         @inv_mod = $1.to_i
  166.       when /<(?:INV_MINUS|inv minus): [ ]*(\d+)>/i
  167.         @inv_mod = -$1.to_i
  168.       end
  169.     end
  170.   end
  171.  
  172. end
  173. # ============================================================================
  174. # Data structures and workflows goes here
  175. # ============================================================================
  176. class Game_Actor < Game_Battler
  177.  
  178.   def equip_size
  179.     return 0 unless THEO::LimInv::Include_Equip
  180.     equips.compact.inject(0) {|total,equip| total + equip.inv_size}
  181.   end
  182.  
  183.   def inv_max
  184.     result = $data_actors[id].inv_mod
  185.     result += $data_classes[class_id].inv_mod
  186.     result += states.inject(0) {|total,db| total + db.inv_mod}
  187.     result += equips.compact.inject(0) {|total,db| total + db.inv_mod}
  188.     result
  189.   end
  190.   # --------------------------------------------------------------------------
  191.   # Overwrite : Trade item with party
  192.   # --------------------------------------------------------------------------
  193.   def trade_item_with_party(new_item, old_item)
  194.     return false if new_item && !$game_party.has_item?(new_item)
  195.     $game_party.force_gain_item(old_item, 1)
  196.     $game_party.force_gain_item(new_item, -1)
  197.     return true
  198.   end
  199.  
  200. end
  201.  
  202. class Game_Party < Game_Unit
  203.  
  204.   def inv_max
  205.     return THEO::LimInv::Default_FreeSlot unless THEO::LimInv::DynamicSlot
  206.     return members.inject(0) {|total,member| total + member.inv_max}
  207.   end
  208.  
  209.   def inv_maxed?
  210.     inv_max <= total_inv_size
  211.   end
  212.  
  213.   def total_inv_size(print = false)
  214.     result = all_items.inject(0) {|total,item| total +
  215.       (item_number(item) * item.inv_size)}
  216.     puts result if print
  217.     result += members.inject(0) {|total,member| total + member.equip_size}
  218.     puts result if print
  219.     result
  220.   end
  221.  
  222.   alias theo_liminv_max_item max_item_number
  223.   def max_item_number(item)
  224.     $BTEST ? theo_liminv_max_item(item) : inv_max_item(item) + item_number(item)
  225.   end
  226.  
  227.   def inv_max_item(item)
  228.     return 9999999 if item.nil? || item.inv_size == 0
  229.     free_slot / item.inv_size
  230.   end
  231.  
  232.   def free_slot
  233.     inv_max - total_inv_size
  234.   end
  235.  
  236.   alias theo_liminv_item_max? item_max?
  237.   def item_max?(item)
  238.     $BTEST ? theo_liminv_item_max?(item) : inv_maxed?
  239.   end
  240.  
  241.   def near_maxed?
  242.     free_slot.to_f / inv_max <= THEO::LimInv::NearMaxed_Percent/100.0
  243.   end
  244.  
  245.   def item_size(item)
  246.     return 0 unless item
  247.     item.inv_size * item_number(item)
  248.   end
  249.  
  250.   def force_gain_item(item, amount)
  251.     container = item_container(item.class)
  252.     return unless container
  253.     last_number = item_number(item)
  254.     new_number = last_number + amount
  255.     container[item.id] = [new_number, 0].max
  256.     container.delete(item.id) if container[item.id] == 0
  257.     $game_map.need_refresh = true
  258.   end
  259.  
  260. end
  261.  
  262. class Game_Interpreter
  263.   def force_gain_item(item, amount)
  264.     $game_party.force_gain_item(item, amount)
  265.   end
  266. end
  267. # ============================================================================
  268. # Window related class goes here
  269. # ============================================================================
  270. class Window_Base < Window
  271.   def draw_inv_slot(x,y,width = contents.width,align = 2)
  272.     txt = sprintf("%d/%d",$game_party.total_inv_size, $game_party.inv_max)
  273.     color = THEO::LimInv::NearMaxed_Color
  274.     if $game_party.near_maxed?
  275.       change_color(text_color(color))
  276.     else
  277.       change_color(normal_color)
  278.     end
  279.     draw_text(x,y,width,line_height,txt,align)
  280.     change_color(normal_color)
  281.   end
  282.  
  283.   def draw_inv_info(x,y,width = contents.width)
  284.     change_color(system_color)
  285.     draw_text(x,y,width,line_height,THEO::LimInv::InvSlotVocab)
  286.     change_color(normal_color)
  287.     draw_inv_slot(x,y,width)
  288.   end
  289.  
  290.   def draw_item_size(item,x,y,total = true,width = contents.width)
  291.     rect = Rect.new(x,y,width,line_height)
  292.     change_color(system_color)
  293.     draw_text(rect,THEO::LimInv::InvSizeVocab)
  294.     change_color(normal_color)
  295.     number = (THEO::LimInv::DrawTotal_Size && total) ?
  296.       $game_party.item_size(item) : item.nil? ? 0 : item.inv_size
  297.     draw_text(rect,number,2)
  298.   end
  299. end
  300.  
  301. class Window_MenuLimInv < Window_Base
  302.  
  303.   def initialize(width)
  304.     super(0,0,width,fitting_height(1))
  305.     refresh
  306.   end
  307.  
  308.   def refresh
  309.     contents.clear
  310.     change_color(system_color)
  311.     txt = THEO::LimInv::SlotVocabShort
  312.     draw_text(0,0,contents.width,line_height,txt)
  313.     draw_inv_slot(0,0)
  314.   end
  315.  
  316. end
  317.  
  318. class Window_ItemSize < Window_Base
  319.  
  320.   def initialize(x,y,width)
  321.     super(x,y,width,fitting_height(1))
  322.   end
  323.  
  324.   def set_item(item)
  325.     @item = item
  326.     refresh
  327.   end
  328.  
  329.   def refresh
  330.     contents.clear
  331.     draw_item_size(@item,0,0)
  332.   end
  333.  
  334. end
  335.  
  336. class Window_FreeSlot < Window_Base
  337.   def initialize(x,y,width)
  338.     super(x,y,width,fitting_height(1))
  339.     refresh
  340.   end
  341.  
  342.   def refresh
  343.     contents.clear
  344.     draw_inv_info(0,0)
  345.   end
  346. end
  347.  
  348. class Window_ItemUseCommand < Window_Command
  349.   include THEO::LimInv
  350.  
  351.   def initialize
  352.     super(0,0)
  353.     self.openness = 0
  354.   end
  355.  
  356.   def set_item(item)
  357.     @item = item
  358.     refresh
  359.   end
  360.  
  361.   def window_width
  362.     UseCommand_Size
  363.   end
  364.  
  365.   def make_command_list
  366.     add_command(UseVocab, :use, $game_party.usable?(@item))
  367.     add_command(DiscardVocab, :discard, discardable?(@item))
  368.     add_command(CancelVocab, :cancel)
  369.   end
  370.  
  371.   def to_center
  372.     self.x = Graphics.width/2 - width/2
  373.     self.y = Graphics.height/2 - height/2
  374.   end
  375.  
  376.   def discardable?(item)
  377.     return false if item.nil?
  378.     !(item.is_a?(RPG::Item) && item.itype_id == 2)
  379.   end
  380.  
  381. end
  382.  
  383. class Window_DiscardAmount < Window_Base
  384.   attr_accessor :cmn_window
  385.   attr_accessor :itemlist
  386.   attr_accessor :freeslot
  387.  
  388.   def initialize(x,y,width)
  389.     super(x,y,width,fitting_height(1))
  390.     self.openness = 0
  391.     @amount = 0
  392.   end
  393.  
  394.   def set_item(item)
  395.     @item = item
  396.     @amount = 0
  397.     refresh
  398.   end
  399.  
  400.   def refresh
  401.     contents.clear
  402.     return unless @item
  403.     draw_item_name(@item,0,0,true,contents.width)
  404.     txt = sprintf("%d/%d",@amount, $game_party.item_number(@item))
  405.     draw_text(0,0,contents.width,line_height,txt,2)
  406.   end
  407.  
  408.   def draw_item_name(item, x, y, enabled = true, width = 172)
  409.     return unless item
  410.     draw_icon(item.icon_index, x, y, enabled)
  411.     change_color(normal_color, enabled)
  412.     draw_text(x + 24, y, width, line_height, item.name + ":")
  413.   end
  414.  
  415.   def update
  416.     super
  417.     return unless open?
  418.     change_amount(1) if Input.repeat?(:RIGHT)
  419.     change_amount(-1) if Input.repeat?(:LEFT)
  420.     change_amount(10) if Input.repeat?(:UP)
  421.     change_amount(-10) if Input.repeat?(:DOWN)
  422.     lose_item if Input.trigger?(:C)
  423.     close_window if Input.trigger?(:B)
  424.   end
  425.  
  426.   def change_amount(num)
  427.     @amount = [[@amount+num,0].max,$game_party.item_number(@item)].min
  428.     Sound.play_cursor
  429.     refresh
  430.   end
  431.  
  432.   def lose_item
  433.     $game_party.lose_item(@item,@amount)
  434.     @itemlist.redraw_current_item
  435.     @freeslot.refresh
  436.     if $game_party.item_number(@item) == 0
  437.       @itemlist.refresh
  438.     end
  439.     close_window
  440.   end
  441.  
  442.   def close_window
  443.     close
  444.     @cmn_window.activate
  445.     Sound.play_ok
  446.   end
  447.  
  448. end
  449.  
  450. class Window_ItemList < Window_Selectable
  451.   attr_reader :item_size_window
  452.  
  453.   def item_size_window=(window)
  454.     @item_size_window = window
  455.     update_help
  456.   end
  457.  
  458.   alias theo_liminv_update_help update_help
  459.   def update_help
  460.     theo_liminv_update_help
  461.     @item_size_window.set_item(item) if @item_size_window
  462.   end
  463.  
  464.   alias theo_liminv_height= height=
  465.   def height=(height)
  466.     self.theo_liminv_height = height
  467.     refresh
  468.   end
  469.  
  470.   def enable?(item)
  471.     return !item.nil?
  472.   end
  473.  
  474. end
  475.  
  476. class Window_ShopNumber < Window_Selectable
  477.   attr_accessor :mode
  478.  
  479.   alias theo_liminv_init initialize
  480.   def initialize(x, y, height)
  481.     theo_liminv_init(x, y, height)
  482.     @mode = :buy
  483.   end
  484.  
  485.   alias theo_liminv_refresh refresh
  486.   def refresh
  487.     theo_liminv_refresh
  488.     draw_itemsize
  489.   end
  490.  
  491.   def draw_itemsize
  492.     item_size = @number * @item.inv_size
  493.     total_size = $game_party.total_inv_size +
  494.       (@mode == :buy ? item_size : -item_size)
  495.     txt = sprintf("%d/%d",total_size,$game_party.inv_max)
  496.     ypos = item_y + line_height * ($imported["YEA-ShopOptions"] ? 5 : 4)
  497.     rect = Rect.new(4,ypos,contents.width-8,line_height)
  498.     change_color(system_color)
  499.     draw_text(rect,THEO::LimInv::InvSlotVocab)
  500.     change_color(normal_color)
  501.     draw_text(rect,txt,2)
  502.   end
  503.  
  504. end
  505.  
  506. class Window_ShopStatus < Window_Base
  507.  
  508.   if THEO::LimInv::Display_ItemSize
  509.   alias theo_liminv_draw_posses draw_possession
  510.   def draw_possession(x, y)
  511.     theo_liminv_draw_posses(x,y)
  512.     y += line_height
  513.     draw_item_size(@item,x,y,false, contents.width-(x*2))
  514.   end
  515.  
  516.   if $imported["YEA-ShopOptions"]
  517.   def draw_actor_equip_info(dx, dy, actor)
  518.     dy += line_height
  519.     enabled = actor.equippable?(@item)
  520.     change_color(normal_color, enabled)
  521.     draw_text(dx, dy, contents.width, line_height, actor.name)
  522.     item1 = current_equipped_item(actor, @item.etype_id)
  523.     draw_actor_param_change(dx, dy, actor, item1) if enabled
  524.   end
  525.   end # $imported["YEA-ShopOption"]
  526.   end # Display item size
  527.  
  528. end
  529. # ============================================================================
  530. # Scene classes goes here
  531. # ============================================================================
  532. class Scene_Menu < Scene_MenuBase
  533.  
  534.   alias theo_liminv_start start
  535.   def start
  536.     theo_liminv_start
  537.     create_liminv_window
  538.   end
  539.  
  540.   def create_liminv_window
  541.     @lim_inv = Window_MenuLimInv.new(@gold_window.width)
  542.     @lim_inv.x = @command_window.x
  543.     @lim_inv.y = @command_window.height
  544.   end
  545.  
  546. end
  547.  
  548. class Scene_Item < Scene_ItemBase
  549.  
  550.   alias theo_liminv_start start
  551.   def start
  552.     theo_liminv_start
  553.     resize_item_window
  554.     create_freeslot_window
  555.     create_itemsize_window
  556.     create_usecommand_window
  557.     create_discard_amount
  558.   end
  559.  
  560.   def resize_item_window
  561.     @item_window.height -= @item_window.line_height * 2
  562.   end
  563.  
  564.   def create_freeslot_window
  565.     wy = @item_window.y + @item_window.height
  566.     wh = THEO::LimInv::Display_ItemSize ? Graphics.width/2 : Graphics.width
  567.     @freeslot = Window_FreeSlot.new(0,wy,wh)
  568.     @freeslot.viewport = @viewport
  569.   end
  570.  
  571.   def create_itemsize_window
  572.     return unless THEO::LimInv::Display_ItemSize
  573.     wx = @freeslot.width
  574.     wy = @freeslot.y
  575.     ww = wx
  576.     @itemsize = Window_ItemSize.new(wx,wy,ww)
  577.     @itemsize.viewport = @viewport
  578.     @item_window.item_size_window = @itemsize
  579.   end
  580.  
  581.   def create_usecommand_window
  582.     @use_command = Window_ItemUseCommand.new
  583.     @use_command.to_center
  584.     @use_command.set_handler(:use, method(:use_command_ok))
  585.     @use_command.set_handler(:discard, method(:on_discard_ok))
  586.     @use_command.set_handler(:cancel, method(:on_usecmd_cancel))
  587.     @use_command.viewport = @viewport
  588.   end
  589.  
  590.   def create_discard_amount
  591.     wx = @use_command.x
  592.     wy = @use_command.y + @use_command.height
  593.     ww = @use_command.width
  594.     @discard_window = Window_DiscardAmount.new(wx,wy,ww)
  595.     @discard_window.cmn_window = @use_command
  596.     @discard_window.itemlist = @item_window
  597.     @discard_window.freeslot = @freeslot
  598.     @discard_window.viewport = @viewport
  599.   end
  600.  
  601.   alias theo_liminv_item_ok on_item_ok
  602.   def on_item_ok
  603.     @use_command.set_item(item)
  604.     @use_command.open
  605.     @use_command.activate
  606.     @use_command.select(0)
  607.   end
  608.  
  609.   alias theo_liminv_use_item use_item
  610.   def use_item
  611.     @use_command.close
  612.     theo_liminv_use_item
  613.     @freeslot.refresh
  614.   end
  615.  
  616.   def use_command_ok
  617.     theo_liminv_item_ok
  618.     @use_command.close
  619.   end
  620.  
  621.   def on_discard_ok
  622.     @discard_window.set_item(item)
  623.     @discard_window.open
  624.   end
  625.  
  626.   def on_usecmd_cancel
  627.     @item_window.activate
  628.     @use_command.close
  629.     @use_command.deactivate
  630.   end
  631.  
  632. end
  633.  
  634. class Scene_Shop < Scene_MenuBase
  635.   alias theo_liminv_buy_ok on_buy_ok
  636.   def on_buy_ok
  637.     @number_window.mode = :buy
  638.     theo_liminv_buy_ok
  639.   end
  640.  
  641.   alias theo_liminv_sell_ok on_sell_ok
  642.   def on_sell_ok
  643.     @number_window.mode = :sell
  644.     theo_liminv_sell_ok
  645.   end
  646. end
Advertisement
Add Comment
Please, Sign In to add comment