Mercurial > parpg-core
diff src/parpg/inventory.py @ 0:1fd2201f5c36
Initial commit of parpg-core.
author | M. George Hansen <technopolitica@gmail.com> |
---|---|
date | Sat, 14 May 2011 01:12:35 -0700 |
parents | |
children | 7b21d460fc31 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/parpg/inventory.py Sat May 14 01:12:35 2011 -0700 @@ -0,0 +1,177 @@ +# This file is part of PARPG. +# +# PARPG is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# PARPG is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with PARPG. If not, see <http://www.gnu.org/licenses/>. + +from parpg.objects.base import Container +from parpg.objects.composed import SingleItemContainer as Slot + +import copy + +# TODO: many missing function definitions in this code + +class Inventory(Container): + """The class to represent inventory 'model': allow operations with + inventory contents, perform weight/bulk calculations, etc""" + def __init__(self, **kwargs): + """Initialise instance""" + Container.__init__(self, **kwargs) + self.items = {"head": Slot(), "neck": Slot(), + "shoulders": Slot(), "chest": Slot(), + "abdomen": Slot(), "left_arm": Slot(), + "right_arm": Slot(),"groin": Slot(), + "hips": Slot(), "left_leg": Slot(), + "right_leg": Slot(), "left_hand": Slot(), + "right_hand": Slot(), "ready": Container(), + "backpack": Container()} + for key, item in self.items.iteritems(): + item.name = key + kwargs = {} + kwargs["container"] = item + item.setScript("onPlaceItem", self.onChildPlaceItem, kwargs = kwargs) + self.item_lookup = {} + + def onChildPlaceItem(self, container): + for item in container.items.itervalues(): + self.item_lookup[item.ID] = container.name + + def placeItem(self, item, index=None): + self.items["backpack"].placeItem(item, index) + #self.item_lookup[item.ID] = "backpack" + + def takeItem(self, item): + if not item.ID in self.item_lookup: + raise ValueError ('I do not contain this item: %s' % item) + self.items[self.item_lookup[item.ID]].takeItem(item) + del self.item_lookup[item.ID] + + def removeItem(self, item): + if not item.ID in self.item_lookup: + raise ValueError ('I do not contain this item: %s' % item) + self.items[self.item_lookup[item.ID]].removeItem(item) + del self.item_lookup[item.ID] + + def replaceItem(self, old_item, new_item): + """Replaces the old item with the new one + @param old_item: Old item which is removed + @type old_item: Carryable + @param new_item: New item which is added + @type new_item: Carryable + """ + if not old_item.ID in self.item_lookup: + raise ValueError ('I do not contain this item: %s' % old_item) + self.items[self.item_lookup[old_item.ID]]\ + .replaceItem(old_item, new_item) + + def getWeight(self): + """Total weight of all items in container + container's own weight""" + return sum((item.weight for item in self.items.values())) + + def setWeightDummy(self, weight): + pass + + weight = property(getWeight, setWeightDummy, "Total weight of container") + + + def count(self, item_type = ""): + return sum(item.count(item_type) for item in self.items.values()) + + def takeOff(self, item): + return self.moveItemToSlot(item, "backpack") + + def moveItemToSlot(self,item,slot,index=None): + if not slot in self.items: + raise(ValueError("%s: No such slot" % slot)) + + if item.ID in self.item_lookup: + self.items[self.item_lookup[item.ID]].takeItem(item) + try: + self.items[slot].placeItem(item, index) + except Container.SlotBusy: + if index == None : + offending_item = self.items[slot].items[0] + else : + offending_item = self.items[slot].items[index] + self.items[slot].takeItem(offending_item) + self.items[slot].placeItem(item, index) + self.placeItem(offending_item) + self.item_lookup[item.ID] = slot + + def getItemsInSlot(self, slot, index=None): + if not slot in self.items: + raise(ValueError("%s: No such slot" % slot)) + if index != None: + return self.items[slot].items.get(index) + else: + return copy.copy(self.items[slot].items) + + def isSlotEmpty(self, slot, index=None): + if not slot in self.items: + raise(ValueError("%s: No such slot" % slot)) + if index == None: + return self.items[slot].count() == 0 + else: + return not index in self.items[slot].items + + + def has(self, item_ID): + return item_ID in self.item_lookup + + def findItemByID(self, ID): + if ID not in self.item_lookup: + return None + return self.items[self.item_lookup[ID]].findItemByID(ID) + + def findItem(self, **kwargs): + """Find an item in inventory by various attributes. All parameters + are optional. + @type name: String + @param name: Object name. If the name is non-unique, + first matching object is returned + @type kind: String + @param kind: One of the possible object kinds like "openable" or + "weapon" (see base.py) + @return: The item matching criteria or None if none was found""" + for slot in self.items: + item_found = self.items[slot].findItem(**kwargs) + if item_found != None: + return item_found + return None + + def __repr__(self): + return "[Inventory contents: " + \ + reduce((lambda a,b: str(a) + + ', ' + str(b)), + self.items.values()) + " ]" + + def serializeInventory(self): + """Returns the inventory items as a list""" + inventory = [] + inventory.extend(self.items["backpack"].serializeItems()) + for key, slot in self.items.iteritems(): + if key == "ready" or key == "backpack": + continue + elif len(slot.items) > 0: + item = slot.items[0] + item_dict = item.getStateForSaving() + item_dict["slot"] = key + item_dict["type"] = type(item).__name__ + inventory.append(item_dict) + return inventory + + def getStateForSaving(self): + """Returns state for saving + """ + state = {} + state["Inventory"] = self.serializeInventory() + return state