source: trunk/game/scripts/inventory.py @ 610

Revision 610, 6.7 KB checked in by beliar, 9 years ago (diff)

Patch by Beliar.

  • Added "Open" action to InventoryItems?. This will open a ContainerGui? for now. Should make a gui that can reflect the actual possible size of the container.
  • Split OpenBoxAction? into a generic OpenAction?, for Containers that are not "openable" and a OpenBoxAction? for all Containers that are "openable" (The latter ones have an "open" method)
  • Moved SingleItemContainer? from composed to base and made it derive from the normal Container class.
  • Added a SingleItemCarryableContainer? class
  • MapItems? in the agent files can now have an attributes item.
  • Added container attribute to possible MapItem? attributes
  • MapItems? that have the "Container" attribute will have the "Open" action automatically added on creation.
  • Inventory now uses Container from base instead of CarryableContainer? from composed
  • Gave "Pot" the "Container" attribute
  • Added ItemSelf? exception to Container which will be raised when trying to place a container in itself.
  • ContainerGui? and InventoryGui? now catch exceptions from the Container
  • Removed debug print statements left over in inventory_gui
  • 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 scripts.objects.base import Container, SingleItemContainer as Slot
17
18import copy
19
20# TODO: many missing function definitions in this code
21
22class Inventory(Container):
23    """The class to represent inventory 'model': allow operations with
24       inventory contents, perform weight/bulk calculations, etc"""
25    def __init__(self, **kwargs):
26        """Initialise instance"""
27        Container.__init__(self,  **kwargs)
28        self.items = {"head": Slot(), "neck": Slot(),
29                      "shoulders": Slot(), "chest": Slot(),
30                      "abdomen": Slot(), "left_arm": Slot(),
31                      "right_arm": Slot(),"groin": Slot(),
32                      "hips": Slot(), "left_leg": Slot(),
33                      "right_leg": Slot(), "left_hand": Slot(),
34                      "right_hand": Slot(), "ready": Container(),
35                      "backpack": Container()}
36        for key, item in self.items.iteritems():
37            item.name = key
38            kwargs = {}
39            kwargs["container"] = item
40            item.setScript("onPlaceItem", self.onChildPlaceItem, kwargs = kwargs)
41        self.item_lookup = {}
42       
43    def onChildPlaceItem(self, container):
44        for item in container.items.itervalues():
45            self.item_lookup[item.ID] = container.name 
46
47    def placeItem(self, item, index=None):
48        self.items["backpack"].placeItem(item, index)
49        #self.item_lookup[item.ID] = "backpack"
50       
51    def takeItem(self, item):
52        if not item.ID in self.item_lookup:
53            raise ValueError ('I do not contain this item: %s' % item)
54        self.items[self.item_lookup[item.ID]].takeItem(item)
55        del self.item_lookup[item.ID]
56
57    def removeItem(self, item):
58        if not item.ID in self.item_lookup:
59            raise ValueError ('I do not contain this item: %s' % item)
60        self.items[self.item_lookup[item.ID]].removeItem(item)
61        del self.item_lookup[item.ID]
62
63    def replaceItem(self, old_item, new_item):
64        """Replaces the old item with the new one
65        @param old_item: Old item which is removed
66        @type old_item: Carryable
67        @param new_item: New item which is added
68        @type new_item: Carryable
69        """
70        if not old_item.ID in self.item_lookup:
71            raise ValueError ('I do not contain this item: %s' % old_item)
72        self.items[self.item_lookup[old_item.ID]]\
73            .replaceItem(old_item, new_item)
74
75    def getWeight(self):
76        """Total weight of all items in container + container's own weight"""
77        return sum((item.weight for item in self.items.values()))
78
79    def setWeightDummy(self, weight):
80        pass
81
82    weight = property(getWeight, setWeightDummy, "Total weight of container")
83
84
85    def count(self, item_type = ""):
86        return sum(item.count(item_type) for item in self.items.values())
87   
88    def takeOff(self, item):
89        return self.moveItemToSlot(item, "backpack")
90
91    def moveItemToSlot(self,item,slot,index=None):
92        if not slot in self.items:
93            raise(ValueError("%s: No such slot" % slot))
94
95        if item.ID in self.item_lookup:
96            self.items[self.item_lookup[item.ID]].takeItem(item)
97        try:
98            self.items[slot].placeItem(item, index)
99        except Container.SlotBusy:
100            if index == None :
101                offending_item = self.items[slot].items[0]
102            else :
103                offending_item = self.items[slot].items[index]
104            self.items[slot].takeItem(offending_item)
105            self.items[slot].placeItem(item, index)
106            self.placeItem(offending_item)
107        self.item_lookup[item.ID] = slot
108     
109    def getItemsInSlot(self, slot, index=None):
110        if not slot in self.items:
111            raise(ValueError("%s: No such slot" % slot))
112        if index != None:
113            return self.items[slot].items.get(index)
114        else:
115            return copy.copy(self.items[slot].items)
116
117    def isSlotEmpty(self, slot, index=None):
118        if not slot in self.items:
119            raise(ValueError("%s: No such slot" % slot))
120        if index == None:
121            return self.items[slot].count() == 0
122        else:
123            return not index in self.items[slot].items
124                 
125
126    def has(self, item_ID):
127        return item_ID in self.item_lookup
128
129    def findItemByID(self, ID):
130        if ID not in self.item_lookup:
131            return None
132        return self.items[self.item_lookup[ID]].findItemByID(ID)
133
134    def findItem(self, **kwargs):
135        """Find an item in inventory by various attributes. All parameters
136           are optional.
137           @type name: String
138           @param name: Object name. If the name is non-unique,
139                        first matching object is returned
140           @type kind: String
141           @param kind: One of the possible object kinds like "openable" or
142                        "weapon" (see base.py)
143           @return: The item matching criteria or None if none was found"""
144        for slot in self.items:
145            item_found = self.items[slot].findItem(**kwargs)
146            if item_found != None:
147                return item_found
148        return None
149
150    def __repr__(self):
151        return "[Inventory contents: " + \
152                            reduce((lambda a,b: str(a) 
153                                    + ', ' + str(b)), 
154                                    self.items.values()) + " ]"
155
156    def serializeInventory(self):
157        """Returns the inventory items as a list"""
158        inventory = []
159        inventory.extend(self.items["backpack"].serializeItems())
160        for key, slot in self.items.iteritems():
161            if key == "ready" or key == "backpack":
162                continue
163            elif len(slot.items) > 0:
164                item = slot.items[0]
165                item_dict = item.getStateForSaving()
166                item_dict["slot"] = key                               
167                item_dict["type"] = type(item).__name__
168                inventory.append(item_dict)
169        return inventory
170           
171    def getStateForSaving(self):
172        """Returns state for saving
173        """
174        state = {}
175        state["Inventory"] = self.serializeInventory()
176        return state
Note: See TracBrowser for help on using the repository browser.