source: branches/active/character_customization/game/parpg/inventory.py @ 766

Revision 736, 6.8 KB checked in by aspidites, 8 years ago (diff)

Patch by Aspidites:

  • renamed scripts package to parpg
  • renamed parpg module to application
  • removed packaging and other related files (kept locally for reference, will reintroduce similar scripts to resolve bug #275
  • updated all import statements to respect changes above
  • Property svn:eol-style set to native
Line 
1# This file is part of PARPG.
2#
3# PARPG is free software: you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation, either version 3 of the License, or
6# (at your option) any later version.
7#
8# PARPG is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
15
16from parpg.objects.base import Container
17from parpg.objects.composed import SingleItemContainer as Slot
18
19import copy
20
21# TODO: many missing function definitions in this code
22
23class Inventory(Container):
24    """The class to represent inventory 'model': allow operations with
25       inventory contents, perform weight/bulk calculations, etc"""
26    def __init__(self, **kwargs):
27        """Initialise instance"""
28        Container.__init__(self,  **kwargs)
29        self.items = {"head": Slot(), "neck": Slot(),
30                      "shoulders": Slot(), "chest": Slot(),
31                      "abdomen": Slot(), "left_arm": Slot(),
32                      "right_arm": Slot(),"groin": Slot(),
33                      "hips": Slot(), "left_leg": Slot(),
34                      "right_leg": Slot(), "left_hand": Slot(),
35                      "right_hand": Slot(), "ready": Container(),
36                      "backpack": Container()}
37        for key, item in self.items.iteritems():
38            item.name = key
39            kwargs = {}
40            kwargs["container"] = item
41            item.setScript("onPlaceItem", self.onChildPlaceItem, kwargs = kwargs)
42        self.item_lookup = {}
43       
44    def onChildPlaceItem(self, container):
45        for item in container.items.itervalues():
46            self.item_lookup[item.ID] = container.name 
47
48    def placeItem(self, item, index=None):
49        self.items["backpack"].placeItem(item, index)
50        #self.item_lookup[item.ID] = "backpack"
51       
52    def takeItem(self, item):
53        if not item.ID in self.item_lookup:
54            raise ValueError ('I do not contain this item: %s' % item)
55        self.items[self.item_lookup[item.ID]].takeItem(item)
56        del self.item_lookup[item.ID]
57
58    def removeItem(self, item):
59        if not item.ID in self.item_lookup:
60            raise ValueError ('I do not contain this item: %s' % item)
61        self.items[self.item_lookup[item.ID]].removeItem(item)
62        del self.item_lookup[item.ID]
63
64    def replaceItem(self, old_item, new_item):
65        """Replaces the old item with the new one
66        @param old_item: Old item which is removed
67        @type old_item: Carryable
68        @param new_item: New item which is added
69        @type new_item: Carryable
70        """
71        if not old_item.ID in self.item_lookup:
72            raise ValueError ('I do not contain this item: %s' % old_item)
73        self.items[self.item_lookup[old_item.ID]]\
74            .replaceItem(old_item, new_item)
75
76    def getWeight(self):
77        """Total weight of all items in container + container's own weight"""
78        return sum((item.weight for item in self.items.values()))
79
80    def setWeightDummy(self, weight):
81        pass
82
83    weight = property(getWeight, setWeightDummy, "Total weight of container")
84
85
86    def count(self, item_type = ""):
87        return sum(item.count(item_type) for item in self.items.values())
88   
89    def takeOff(self, item):
90        return self.moveItemToSlot(item, "backpack")
91
92    def moveItemToSlot(self,item,slot,index=None):
93        if not slot in self.items:
94            raise(ValueError("%s: No such slot" % slot))
95
96        if item.ID in self.item_lookup:
97            self.items[self.item_lookup[item.ID]].takeItem(item)
98        try:
99            self.items[slot].placeItem(item, index)
100        except Container.SlotBusy:
101            if index == None :
102                offending_item = self.items[slot].items[0]
103            else :
104                offending_item = self.items[slot].items[index]
105            self.items[slot].takeItem(offending_item)
106            self.items[slot].placeItem(item, index)
107            self.placeItem(offending_item)
108        self.item_lookup[item.ID] = slot
109     
110    def getItemsInSlot(self, slot, index=None):
111        if not slot in self.items:
112            raise(ValueError("%s: No such slot" % slot))
113        if index != None:
114            return self.items[slot].items.get(index)
115        else:
116            return copy.copy(self.items[slot].items)
117
118    def isSlotEmpty(self, slot, index=None):
119        if not slot in self.items:
120            raise(ValueError("%s: No such slot" % slot))
121        if index == None:
122            return self.items[slot].count() == 0
123        else:
124            return not index in self.items[slot].items
125                 
126
127    def has(self, item_ID):
128        return item_ID in self.item_lookup
129
130    def findItemByID(self, ID):
131        if ID not in self.item_lookup:
132            return None
133        return self.items[self.item_lookup[ID]].findItemByID(ID)
134
135    def findItem(self, **kwargs):
136        """Find an item in inventory by various attributes. All parameters
137           are optional.
138           @type name: String
139           @param name: Object name. If the name is non-unique,
140                        first matching object is returned
141           @type kind: String
142           @param kind: One of the possible object kinds like "openable" or
143                        "weapon" (see base.py)
144           @return: The item matching criteria or None if none was found"""
145        for slot in self.items:
146            item_found = self.items[slot].findItem(**kwargs)
147            if item_found != None:
148                return item_found
149        return None
150
151    def __repr__(self):
152        return "[Inventory contents: " + \
153                            reduce((lambda a,b: str(a) 
154                                    + ', ' + str(b)), 
155                                    self.items.values()) + " ]"
156
157    def serializeInventory(self):
158        """Returns the inventory items as a list"""
159        inventory = []
160        inventory.extend(self.items["backpack"].serializeItems())
161        for key, slot in self.items.iteritems():
162            if key == "ready" or key == "backpack":
163                continue
164            elif len(slot.items) > 0:
165                item = slot.items[0]
166                item_dict = item.getStateForSaving()
167                item_dict["slot"] = key                               
168                item_dict["type"] = type(item).__name__
169                inventory.append(item_dict)
170        return inventory
171           
172    def getStateForSaving(self):
173        """Returns state for saving
174        """
175        state = {}
176        state["Inventory"] = self.serializeInventory()
177        return state
Note: See TracBrowser for help on using the repository browser.