close

Вход

Забыли?

вход по аккаунту

?

Inventory Plus

код для вставкиСкачать
=begin
#==============================================================================
** FP Inventory Plus
Author: Tsukihime
Date: Jul 10, 2012
------------------------------------------------------------------------------
** Change log
Jul 10
-fixed logic error where == wasn't returning false if no branches return
Jul 9
-restructured Game_Weapon, Game_Armor, and Game_Item to include a new
BaseItem module
-overwrote == logic to distinguish between RPG objects and custom objects.
Jun 26
-added proper item losing
May 30
-fixed issue where item type check wasn't checked properly
eg: default weapon check assumes class == RPG::Weapon
May 29
-added counting options: count-by-item, count-by-stack
May 27
-added options to enable/disable item/weight limits
-added item limit window
May 26
-added the imported boolean
May 24
-Initialized RPG classes
May 22
-Added "clear inventory" method to clear everything out
-Clears out equips as well
May 15, 2012
- fixed some bugs
May 14, 2012
- Initial release
------------------------------------------------------------------------------ This script extends the default inventory system and all item-handling
throughout the engine. All items will be fetched from the inventory, and
instances of the specific item is stored and retrieved.
You can specify the stack sizes for each item as well as their weights.
You can specify item limits and weight limits for each item.
All equips are treated independently.
This script will act as the basis for all future item-related scripts.
To specify an item/equip stack size, tag it with
<¤чейка: n>
where n is an integer >= 1
To specify the weight of an item/equip, tag it with
<вес: n>
where n is a real number
To specify the the limit for an item/equip, tag it with
<лимит: n>
where n is an integer >= 0
#==============================================================================
=end
$imported = {} if $imported.nil?
$imported["FP_InventoryPlus"] = true
#==============================================================================
# ** Configuration
#==============================================================================
module Feature_Plus
module Inventory_System
Use_Item_Limit = true
Use_Weight_Limit = true
# Item counting method. If "Count_Items" is true, then
# Count_Stacks is not used
Count_By_Stack = true # treat each stack as a single item
Count_By_Item = false # count every item individually
# ячейка по-умолчанию
Default_Item_Stack = 9999
Default_Equip_Stack = 1
# ћасса по-умолчанию
Default_KeyItem_Weight = 0
Default_Item_Weight = 1
Default_Equip_Weight = 10
Weight_Unit = "кг."
# [current weight] / [max weight] [weight unit]
Weight_Display = "%s/%s %s"
# [item_count] / [item_limit]
Item_Display = "¬ещей: %s/%s"
# Inventory limit defaults
Inventory_Limit = 100 #макс.кол-во всех вещей
Weight_Limit = 150 #макс. вес всех вещей
#regex
Item_Limit = /<лимит:?\s*(\d+)/i #макс.кол-во дл¤ предмета Item_Weight = /<вес:?\s*(.*)>/i #вес предмета
Stack_Size = /<¤чейка:?\s*(\d+)>/i #кол-во вещей одной позиции до перехода на другую
end
end
#==============================================================================
# ** Rest of the script
#==============================================================================
module RPG
class Item < UsableItem
include Feature_Plus::Inventory_System
def item_weight
return @item_weight unless @item_weight.nil?
res = Item_Weight.match(self.note)
return @item_weight = res ? res[1].to_f : (key_item? ? Default_KeyItem_Weight : Default_Item_Weight)
end
def item_stack
return @item_stack unless @item_stack.nil?
res = Stack_Size.match(self.note)
return @item_stack = res ? res[1].to_i : Default_Item_Stack
end
def item_limit
return @item_limit unless @item_limit.nil?
res = Item_Limit.match(self.note)
return @item_limit = res ? res[1].to_i : Inventory_Limit
end
end
class EquipItem < BaseItem
include Feature_Plus::Inventory_System
def item_weight
return @item_weight unless @item_weight.nil?
res = Item_Weight.match(self.note)
return @item_weight = res ? res[1].to_f : Default_Equip_Weight
end
def item_stack
return @item_stack unless @item_stack.nil?
res = Stack_Size.match(self.note)
return @item_stack = res ? res[1].to_i : Default_Equip_Stack
end
def item_limit
return @item_limit unless @item_limit.nil?
res = Item_Limit.match(self.note)
return @item_limit = res ? res[1].to_i : Inventory_Limit
end
end
end
# this module is included by Game_Item, Game_Weapon, and Game_Armor
module BaseItem
attr_reader :index # index of item in the inventory slot
attr_reader :count # number of items in this stack
attr_reader :class #
attr_reader :item_stack # max items per stack
attr_reader :item_weight # weight per instance of item
attr_reader :item_limit # max number of items allowed to carry
attr_reader :id # database ID used to reference the type of item
def initialize(item, index)
super()
init_base_attributes(item)
@count = 0
@index = index
@id = item.id
@item_stack = item.item_stack
@item_weight = item.item_weight
@item_limit = item.item_limit
setup(item, index) if needs_setup?(item)
end
def setup(item, index)
end
def init_base_attributes(item)
item.instance_variables.each do |attr|
self.instance_variable_set(attr, item.instance_variable_get(attr))
end
end
def amount_can_add?
@item_stack - @count
end
def add_amount(amt)
@count = [@count + amt, @item_stack].min
end
def lose_amount(amt)
lost = [amt, @count].min
@count = [@count - amt, 0].max
return lost
end
def full?
@count >= @item_stack
end
def can_add?
return false if full?
return true
end
def inspect
"<%s>" % @name
end
end
# This module is included in Game_Weapon and Game_Armor. It contains common
# methods shared by all equip items
module EquipItem
def setup(item, index)
# call anything from BaseItem
super
end
end
#==============================================================================
# ** Game_Item
#------------------------------------------------------------------------------
# This is an extension of RPG::Item. All of the methods defined in
# RPG::Item are inherited. When an item is created, it is wrapped by
# this Game_Item and all of the attributes are cloned
#==============================================================================
class Game_Item < RPG::Item
include BaseItem def setup(item, index)
@class = Game_Item
end
def needs_setup?(item)
item.class == RPG::Item
end
def ==(item)
if item.class == RPG::Item
return $data_items[@id] == item
elsif item.is_a?(Game_Item)
return self.equal?(item)
end
return false
end
end
#==============================================================================
# ** Game_Weapon
#------------------------------------------------------------------------------
# This is an extension of RPG::Weapon. All of the methods defined in
# RPG::Weapon are inherited. When an item is created, it is wrapped by
# this Game_Weapon and all of the attributes are cloned
#==============================================================================
class Game_Weapon < RPG::Weapon
include BaseItem
include EquipItem
alias :th_inventory_setup :setup
def setup(item, index)
@class = Game_Weapon
@params = item.params.clone #we must clone this
@name = item.name
th_inventory_setup(item, index)
end
def needs_setup?(item)
item.class == RPG::Weapon
end
def ==(item)
if item.class == RPG::Weapon
return $data_weapons[@id] == item
elsif item.is_a?(Game_Weapon)
return equal?(item)
end
return false
end
end
#==============================================================================
# ** Game_Armor
#------------------------------------------------------------------------------
# This is an extension of RPG::Armor. All of the methods defined in
# RPG::Armor are inherited. When an item is created, it is wrapped by
# this Game_Armor and all of the attributes are cloned
#==============================================================================
class Game_Armor < RPG::Armor
include BaseItem
include EquipItem
def setup(item, index)
@class = Game_Armor
@params = item.params.clone #we must clone this
@name = item.name
end
def needs_setup?(item)
item.class == RPG::Armor
end
def ==(item)
if item.class == RPG::Armor
return $data_armors[@id] == item
elsif item.is_a?(RPG::Armor)
return self.equal?(item)
end
return false
end
end
#==============================================================================
# ** Game_Inventory
#------------------------------------------------------------------------------
# This is an inventory object. It represents a generic inventory, containing
# a set of items including common items, weapons, armors, and key items.
#
# All inventory related methods are defined and any access to the inventory
# should use the provided methods
#==============================================================================
class Game_Inventory
include Feature_Plus::Inventory_System
attr_reader :weight
attr_reader :item_count
def initialize
@id = 0
@name = ""
@weight = 0
@item_count = 0
@items = {}
@weapons = {}
@armors = {}
@discards = {}
@inventory_limit = Inventory_Limit
@weight_limit = Weight_Limit
end
def max_items
@inventory_limit
end
def max_weight
@weight_limit
end
def weight_exceeded?(item)
return false unless Feature_Plus::Inventory_System::Use_Weight_Limit
@weight + item.item_weight > @weight_limit
end
def items_exceeded?
return false unless Feature_Plus::Inventory_System::Use_Item_Limit
@item_count >= @inventory_limit
end
def limit_reached?(item)
items_exceeded? || weight_exceeded?(item)
end
def can_add_amount?(item)
if item.item_weight > 0
return [[max_items - @item_count, (max_weight - @weight) / item.item_weight].min, 0].max
end
return [max_items - @item_count, 0].max
end
def get_item_type(item)
return @items if item.is_a?(RPG::Item)
return @weapons if item.is_a?(RPG::Weapon)
return @armors if item.is_a?(RPG::Armor)
return nil
end
def is_system_item?(item)
return [RPG::Weapon, RPG::Armor, RPG::Item].include?(item.class)
end
def item_number(item)
container = get_item_type(item)
return 0 unless container && container[item.id]
return container[item.id].count unless item.instance_variable_defined?(:@index)
return container[item.id][item.index].nil? ? 0 : container[item.id][item.index].count
end
def has_item?(item, include_equip=false)
item_number(item) > 0
end
def gain_item(item, amount)
container = get_item_type(item)
return unless container
valid_amount = [can_add_amount?(item), amount].min
discard_amount = amount - valid_amount
unless limit_reached?(item)
container[item.id] = Game_InventorySlot.new(item) unless container[item.id]
amount_avail = [container[item.id].can_add_amount?(item), valid_amount].min
container[item.id].gain_item(item, amount_avail)
update_inventory(container, item, amount_avail)
end
update_discards(item, discard_amount)
end
def lose_item(item, amount)
container = get_item_type(item)
return unless container
return unless container[item.id]
lost = container[item.id].lose_item(item, amount)
update_inventory(container, item, -lost)
end
def update_inventory(container, item, added)
#~ if Count_By_Item
@weight += item.item_weight * added
@item_count += added
#~ elsif Count_By_Stack
#~ mod = container[item.id].stacks.size
#~ @weight += added < 0 ? -mod*item.item_weight : mod*item.item_weight
#~ @item_count += added < 0 ? -mod : mod
#~ end
end
def update_discards(item, remains)
return unless remains > 0
p "Discarded %d %s" %[remains, item.name]
end
def clear_inventory(include_equips=false)
$game_party.all_members.each {|actor| actor.clear_equips} if include_equips
@weapons.clear
@armors.clear
@items.clear
@item_count = 0
@weight = 0
end
#--------------------------------------------------------------------------
# * Accessor methods. Returns the same things that Game_Party used
# to return
#--------------------------------------------------------------------------
#~ def get_weapon(item_id)
slot = @weapons[item_id]
return unless slot
return slot.stacks[0]
end
def get_armor(item_id)
slot = @armors[item_id]
return unless slot
return slot.stacks[0]
end
def items
@items.keys.sort.collect {|id| @items[id].stacks}.flatten
end
def weapons
@weapons.keys.sort.collect {|id| @weapons[id].stacks}.flatten
end
def armors
@armors.keys.sort.collect {|id| @armors[id].stacks}.flatten
end
def equip_items
weapons.concat(armors)
end
def discards
@discards
end
def all_items
items.concat(weapons).concat(armors)
end
end
#==============================================================================
# ** Game_InventorySlot
#------------------------------------------------------------------------------
# This is an inventory slot object. It provides information about this slot
# such as the number of items and total weight. It stores an instance of
# my custom game item in an array
#==============================================================================
class Game_InventorySlot
include Feature_Plus::Inventory_System
attr_reader :item_stack
attr_reader :count
attr_reader :weight
def initialize(item)
@id = item.id
@item = item
@stacks = [] # individual instances of this item
@item_weight = item.item_weight
@count = 0 # number of items across all stacks
@weight = 0 # weight of items across all stacks
@item_stack = item.item_stack # number of items per stack
@item_limit = item.item_limit
end
def [](index)
return unless @stacks[index]
@stacks[index]
end
def max_items
@item_limit
end
def max_weight
Weight_Limit
end
def stack_size
@item_stack
end
#--------------------------------------------------------------------------
# * Return all non-nil stacks
#--------------------------------------------------------------------------
def stacks
@stacks.select {|stack| !stack.nil?}
end
def slot_exceeded?
@count >= max_items
end
def weight_exceeded?(item)
return false unless Feature_Plus::Inventory_System::Use_Weight_Limit
@weight >= max_weight
end
def can_add?(item)
return false if slot_exceeded? || weight_exceeded?(item)
return true
end
def can_add_amount?(item)
if item.item_weight > 0
return [[max_items - @count, (max_weight - @weight) / item.item_weight].min, 0].max
end
return [max_items - @count, 0].max
end
# gets the first available stack to add item to
def get_stack(item)
(0 .. @stacks.size ).find { |k| @stacks[k].nil? || @stacks[k].can_add?}
end
# gets the first non-nil stack
def first_stack
(0 .. @stacks.size ).find { |k| @stacks[k]}
end
def make_item(item, i)
@stacks[i] = Game_Item.new(item, i) if item.is_a?(RPG::Item)
@stacks[i] = Game_Weapon.new(item, i) if item.is_a?(RPG::Weapon)
@stacks[i] = Game_Armor.new(item, i) if item.is_a?(RPG::Armor)
end
def gain_item(item, amount)
return unless can_add?(item)
total = amount
while amount > 0
i = get_stack(item)
make_item(item, i) if @stacks[i].nil?
stack = @stacks[i]
amt = stack.amount_can_add?
@stacks[i].add_amount([amount, amount - amt, 0].max)
amount -= amt
end
update_slot(item, total)
end
def delete_stack(index)
@stacks.delete_at(index) @stacks.insert(index, nil)
end
def lose_item(item, amount)
total_lost = 0
while @count > 0 && amount > 0
i = item.index rescue first_stack
if i
i = first_stack if @stacks[i].count == 0
stack = @stacks[i]
lost_amount = stack.lose_amount(amount)
delete_stack(i) if @stacks[i].count == 0
update_slot(item, -lost_amount)
total_lost += lost_amount
amount -= lost_amount
end
end
return total_lost
end
def update_slot(item, amount)
@count += amount
@weight += item.item_weight * amount end
end
class Game_Actor < Game_Battler
alias fp_inventory_actor_initialize initialize
def initialize(actor_id)
fp_inventory_actor_initialize(actor_id)
@last_skill = Game_CustItem.new
end
def clear_equips
@equips = Array.new(equip_slots.size) { Game_CustItem.new }
end
#need to set up initial equips properly
def init_equips(equips)
@equips = Array.new(equip_slots.size) { Game_CustItem.new }
equips.each_with_index do |item_id, i|
etype_id = index_to_etype_id(i)
slot_id = empty_slot(etype_id)
if item_id > 0
@equips[slot_id].object = get_initial_equip(etype_id == 0, item_id) if slot_id
else
@equips[slot_id].object = nil if slot_id
end
end
refresh
end
def get_initial_equip(is_weapon, item_id)
if is_weapon
return Game_Weapon.new($data_weapons[item_id], 0)
else
return Game_Armor.new($data_armors[item_id], 0)
end
end
def xequips
@equips.collect {|item| item.object }
end
def armors
@equips.select {|item| item.is_armor? }.collect {|item| item.object }
end
def change_equip(slot_id, item)
return unless trade_item_with_party(item, equips[slot_id])
return if item && equip_slots[slot_id] != item.etype_id
@equips[slot_id].object = item
refresh
end
# event command "change equipment"
def change_equip_by_id(slot_id, item_id)
if equip_slots[slot_id] == 0
item = $game_party.get_weapon(item_id)
return unless item
change_equip(slot_id, item)
else
index = $game_party.get_armor(item_id)
return unless item
change_equip(slot_id, Game_Armor.new($data_armors[item_id], index))
end
end
end
#==============================================================================
# ** Game_party
#------------------------------------------------------------------------------
# All inventory access methods are re-written to allow the Inventory object
# to properly handle those requests
#==============================================================================
class Game_Party < Game_Unit
attr_reader :inventory
alias tsuki_inventory_party_initialize initialize
def initialize
tsuki_inventory_party_initialize
@inventory = Game_Inventory.new
@last_item = Game_CustItem.new
end
def clear_inventory(include_equip=false)
@inventory.clear_inventory(include_equip)
end
def weight
@inventory.weight
end
def items
@inventory.items
end
def weapons
@inventory.weapons
end def armors
@inventory.armors
end
def equip_items
@inventory.equip_items
end
def all_items
@inventory.all_items
end
def item_number(item)
@inventory.item_number(item)
end
def has_item?(item, include_equip=false)
@inventory.has_item?(item)
end
def gain_item(item, amount, include_equip = false)
if amount < 0
lose_item(item, -amount, include_equip)
else
@inventory.gain_item(item, amount)
end
end
def lose_item(item, amount, include_equip = false)
@inventory.lose_item(item, amount)
end
def max_item_number(item)
99
end
def max_weight
@inventory.max_weight
end
def item_count
@inventory.item_count
end
def max_items
@inventory.max_items
end
def item_max?(item)
item_number(item) >= max_item_number(item)
end
def get_weapon(item_id)
@inventory.get_weapon(item_id)
end
def get_armor(item_id)
@inventory.get_armor(item_id)
end
end
#==============================================================================
# ** Game_CustItem
#------------------------------------------------------------------------------
# This is a variation of Game_BaseItem that stores the actual instance of
# the object rather than storing references to the database
#==============================================================================
class Game_CustItem < Game_BaseItem
def initialize
super
@object = nil
end
def is_skill?; @object.is_a?(RPG::Skill); end
def is_item?; @object.is_a?(RPG::Item); end
def is_weapon?; @object.is_a?(RPG::Weapon); end
def is_armor?; @object.is_a?(RPG::Armor); end
def object
return nil unless @object
return @object end
def object=(item)
@class = item.class
@item_id = item.id if item
@object = item
end
def set_equip(is_weapon, item_id)
@class = is_weapon ? RPG::Weapon : RPG::Armor
@item_id = item_id
@object = is_weapon ? $data_weapons[item_id] : $data_armors[item_id]
end
end
class Game_Action
alias fp_initialize_clear_action clear
def clear
fp_initialize_clear_action
@item = Game_CustItem.new
end
def set_item(item)
@item.object = item
self
end
end
#==============================================================================
# ** Scenes
#==============================================================================
class Scene_Battle < Scene_Base
def on_item_ok
@item = @item_window.item
BattleManager.actor.input.set_item(@item)
if !@item.need_selection?
@item_window.hide
next_command
elsif @item.for_opponent?
select_enemy_selection
else
select_actor_selection
end
$game_party.last_item.object = @item
end
end
class Scene_Menu < Scene_MenuBase
alias fp_inventory_menu_start start
def start
fp_inventory_menu_start
create_limit_windows
end
def create_limit_windows
y = 48
if Feature_Plus::Inventory_System::Use_Weight_Limit
@weight_window = Window_Weight.new(0, Graphics.height - y - @gold_window.height)
y += 48
end
if Feature_Plus::Inventory_System::Use_Item_Limit
@item_limit_window = Window_ItemLimit.new(0, Graphics.height - y - @gold_window.height)
end
end
end
class Scene_Item < Scene_ItemBase
alias fp_inventory_item_start start
def start
fp_inventory_item_start
create_limit_windows
end
def create_limit_windows
x = 160
if Feature_Plus::Inventory_System::Use_Weight_Limit
@weight_window = Window_Weight.new(Graphics.width - x, 0)
@weight_window.z = 200
@actor_window.z = 300
x += 160
end
if Feature_Plus::Inventory_System::Use_Item_Limit
@item_limit_window = Window_ItemLimit.new(Graphics.width - x, 0)
@item_limit_window.z = 200
x += 160
end
end
alias fp_inventory_use_item use_item
def use_item
fp_inventory_use_item
@weight_window.refresh if Feature_Plus::Inventory_System::Use_Weight_Limit
@item_limit_window.refresh if Feature_Plus::Inventory_System::Use_Item_Limit
end
end
class Window_ItemLimit < Window_Base
include Feature_Plus::Inventory_System
def initialize(x, y)
super(x, y, window_width, fitting_height(1))
refresh
end
def window_width
160
end
def refresh
contents.clear
draw_weight_value(4, 0)
end
def draw_weight_value(x, y)
text = sprintf(Item_Display, item_count, item_limit)
change_color(normal_color) draw_text(x, y, self.contents.width - 4, line_height, text, 1)
end
def item_limit
$game_party.max_items
end
#--------------------------------------------------------------------------
# * Get inventory weight
#--------------------------------------------------------------------------
def item_count
$game_party.item_count
end
#--------------------------------------------------------------------------
# * Open Window
#--------------------------------------------------------------------------
def open
refresh
super
end
end
class Window_Weight < Window_Base
include Feature_Plus::Inventory_System
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize(x, y)
super(x, y, window_width, fitting_height(1))
refresh
end
#--------------------------------------------------------------------------
# * Get Window Width
#--------------------------------------------------------------------------
def window_width
return 160
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
contents.clear
draw_weight_value(4, 0, contents.width - 8)
end
def draw_weight_value(x, y, width)
text = sprintf(Weight_Display, weight, max_weight, weight_unit)
change_color(normal_color) draw_text(x, y, width, line_height, text, 2)
end
def weight_unit
Weight_Unit
end
def max_weight
$game_party.max_weight
end
#--------------------------------------------------------------------------
# * Get inventory weight
#--------------------------------------------------------------------------
def weight
$game_party.weight
end
#--------------------------------------------------------------------------
# * Open Window
#--------------------------------------------------------------------------
def open
refresh
super
end
end
class Game_Interpreter
def can_add_amount?(item)
return false if item.nil?
item = $data_items[item] unless item.is_a?(RPG::BaseItem)
return $game_party.inventory.can_add_amount?(item)
end
def armor(i)
return $data_armors[i]
end
def weapon(i)
return $data_weapons[i]
end
def item(i)
return @data_items[i]
end
end
Автор
suncrash
Документ
Категория
Без категории
Просмотров
198
Размер файла
27 Кб
Теги
plus, inventory
1/--страниц
Пожаловаться на содержимое документа