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

Revision 313, 13.9 KB checked in by Kaydeth_parpg, 10 years ago (diff)

Ticket #2: Patch by Kaydeth. Updated the rest of the classes in the scripts directory to correct some obvious discrepancies with our coding standard. Still need to go through the common and objects sub directories. comment[s:trac, t:2]

  • Property svn:eol-style set to native
Line 
1#/usr/bin/python
2
3#   This file is part of PARPG.
4
5#   PARPG is free software: you can redistribute it and/or modify
6#   it under the terms of the GNU General Public License as published by
7#   the Free Software Foundation, either version 3 of the License, or
8#   (at your option) any later version.
9
10#   PARPG is distributed in the hope that it will be useful,
11#   but WITHOUT ANY WARRANTY; without even the implied warranty of
12#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13#   GNU General Public License for more details.
14
15#   You should have received a copy of the GNU General Public License
16#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
17
18import sys
19import os
20import fife
21import fifelog
22import pychan
23from scripts import drag_drop_data as data_drag
24from pychan.tools import callbackWithArguments as cbwa
25from scripts.items import item_image_dict
26
27class Inventory(object):
28    """Main inventory class"""
29    def __init__(self, engine, items, callbacks):
30        """Initialise the instance.
31           @type engine: fife.Engine
32           @param engine: An instance of the fife engine
33           @type items: dict
34           @param items: A dictionary for every slot that goes '{slot:item,
35                         slot:item}' if a slot is not included in the dict,
36                         it is assumed to be empty
37           @type callbacks: dict
38           @param callbacks: a dict of callbacks
39               refreshReadyImages:
40                   Function that will make the ready slots on the HUD
41                   reflect those within the inventory
42               toggleInventoryButton:
43                   Function that will toggle the state of the inventory button
44           @return: None"""
45        pychan.init(engine, debug = True)
46        self.engine = engine
47        self.readyCallback = callbacks['refreshReadyImages']
48        self.toggleInventoryButtonCallback = callbacks['toggleInventoryButton']
49        self.original_cursor_id = self.engine.getCursor().getId()
50        # TODO: remove hard-coded string?
51        self.inventory = pychan.loadXML("gui/inventory.xml")
52        self.inventory_shown = False 
53        self.events_to_map = {}
54        # the images that should be used for the buttons when they are "empty"
55        self.empty_images = {'A1':'gui/inv_images/inv_backpack.png',
56                             'A2':'gui/inv_images/inv_backpack.png',
57                             'A3':'gui/inv_images/inv_backpack.png',
58                             'A4':'gui/inv_images/inv_backpack.png',
59                             'A5':'gui/inv_images/inv_backpack.png',
60                             'B1':'gui/inv_images/inv_backpack.png',
61                             'B2':'gui/inv_images/inv_backpack.png',
62                             'B3':'gui/inv_images/inv_backpack.png',
63                             'B4':'gui/inv_images/inv_backpack.png',
64                             'B5':'gui/inv_images/inv_backpack.png',
65                             'C1':'gui/inv_images/inv_backpack.png',
66                             'C2':'gui/inv_images/inv_backpack.png',
67                             'C3':'gui/inv_images/inv_backpack.png',
68                             'C4':'gui/inv_images/inv_backpack.png',
69                             'C5':'gui/inv_images/inv_backpack.png',
70                             'D1':'gui/inv_images/inv_backpack.png',
71                             'D2':'gui/inv_images/inv_backpack.png',
72                             'D3':'gui/inv_images/inv_backpack.png',
73                             'D4':'gui/inv_images/inv_backpack.png',
74                             'D5':'gui/inv_images/inv_backpack.png',
75                             'Head':'gui/inv_images/inv_head.png',
76                             'LeftHeld':'gui/inv_images/inv_litem.png',
77                             'RightHeld':'gui/inv_images/inv_ritem.png',
78                             'LeftHand':'gui/inv_images/inv_lhand.png',
79                             'RightHand':'gui/inv_images/inv_rhand.png',
80                             'Body':'gui/inv_images/inv_torso.png',
81                             'Belt':'gui/inv_images/inv_belt.png',
82                             'Ready1':'gui/inv_images/inv_belt_pouches.png',
83                             'Ready2':'gui/inv_images/inv_belt_pouches.png',
84                             'Ready3':'gui/inv_images/inv_belt_pouches.png',
85                             'Ready4':'gui/inv_images/inv_belt_pouches.png',
86                             'LeftFoot':'gui/inv_images/inv_lfoot.png',
87                             'RightFoot':'gui/inv_images/inv_rfoot.png'}
88        # every button on the inventory and its category
89        self.buttons = {'A1':'main_inv', 'A2':'main_inv', 'A3':'main_inv',
90                        'A4':'main_inv', 'A5':'main_inv', 'B1':'main_inv',
91                        'B2':'main_inv', 'B3':'main_inv', 'B4':'main_inv',
92                        'B5':'main_inv', 'C1':'main_inv', 'C2':'main_inv',
93                        'C3':'main_inv', 'C4':'main_inv', 'C5':'main_inv',
94                        'D1':'main_inv', 'D2':'main_inv', 'D3':'main_inv',
95                        'D4':'main_inv', 'D5':'main_inv',
96                        'LeftFoot':'foot', 'RightFoot':'foot',
97                        'LeftHand':'hand', 'RightHand':'hand',
98                        'Head':'head', 'Ready1':'ready', 
99                        'Ready2':'ready', 'Ready3':'ready', 
100                        'Ready4':'ready', 'Belt':'belt', 'LeftHeld':'held',
101                        'RightHeld':'held', 'Body':'body'}
102        # all possible categories
103        self.locations = ['ready', 'head', 'foot', 'hand',
104                          'belt', 'held', 'body']
105
106        for key in items:
107            widget = self.inventory.findChild(name=key)
108            item = items[key]
109            image = item_image_dict[item]
110
111            widget.item = item
112            widget.up_image = image
113            widget.down_image = image
114            widget.hover_image = image           
115
116        for button in self.buttons:
117            # make every button's callback be self.dragDrop
118            self.events_to_map[button] = cbwa(self.dragDrop, button)
119            ch = self.inventory.findChild(name=button)
120            # make every slot's item be none if it has not already been set
121            if button not in items:
122                ch.item = ""
123
124        self.events_to_map['close_button'] = self.closeInventoryAndToggle
125        self.inventory.mapEvents(self.events_to_map)   
126        self.resetMouseCursor()
127
128    def closeInventory(self):
129        """Close the inventory.
130           @return: None"""
131        self.inventory.hide()
132
133    def closeInventoryAndToggle(self):
134        """Close the inventory screen.
135           @return: None"""
136        self.closeInventory()
137        self.toggleInventoryButtonCallback()
138        self.inventory_shown = False
139
140    def toggleInventory(self, toggleImage=True):
141        """Pause the game and enter the inventory screen, or close the
142           inventory screen and resume the game.
143           @type toggleImage: bool
144           @param toggleImage:
145               Call toggleInventoryCallback if True. Toggling via a
146               keypress requires that we toggle the Hud inventory image
147               explicitly. Clicking on the Hud inventory button toggles the
148               image implicitly, so we don't change it.
149           @return: None"""
150        if not self.inventory_shown:
151            self.showInventory()
152            self.inventory_shown = True
153        else:
154            self.closeInventory()
155            self.inventory_shown = False
156
157        if toggleImage:
158            self.toggleInventoryButtonCallback()
159
160    def showInventory(self):
161        """Show the inventory.
162           @return: None"""
163        self.inventory.show()
164
165    def setMouseCursor(self, image, dummy_image, type="native"): 
166        """Set the mouse cursor to an image.
167           @type image: string
168           @param image: The image you want to set the cursor to
169           @type dummy_image: string
170           @param dummy_image: ???
171           @type type: string
172           @param type: ???
173           @return: None"""
174        cursor = self.engine.getCursor()
175        cursor_type = fife.CURSOR_IMAGE
176        img_pool = self.engine.getImagePool()
177        if(type == "target"):
178            target_cursor_id = img_pool.addResourceFromFile(image) 
179            dummy_cursor_id = img_pool.addResourceFromFile(dummy_image)
180            cursor.set(cursor_type,target_dummy_cursor_id)
181            cursor.setDrag(cursor_type,target_cursor_id,-16,-16)
182        else:
183            cursor_type = fife.CURSOR_IMAGE
184            zero_cursor_id = img_pool.addResourceFromFile(image)
185            cursor.set(cursor_type,zero_cursor_id)
186            cursor.setDrag(cursor_type,zero_cursor_id)
187           
188    def resetMouseCursor(self):
189        """Reset cursor to default image.
190           @return: None"""
191        c = self.engine.getCursor()
192        img_pool = self.engine.getImagePool()
193        cursor_type = fife.CURSOR_NATIVE
194        # this is the path to the default image
195        cursor_id = self.original_cursor_id
196        c.setDrag(cursor_type, cursor_id)
197        c.set(cursor_type, cursor_id)
198       
199    def dragDrop(self, obj):
200        """Decide whether to drag or drop the image.
201           @type obj: string
202           @param obj: The name of the object within
203                       the dictionary 'self.buttons'
204           @return: None"""
205        if(data_drag.dragging == True):
206            self.dropObject(obj)
207        elif(data_drag.dragging == False):
208            self.dragObject(obj)
209               
210    def dragObject(self, obj):
211        """Drag the selected object.
212           @type obj: string
213           @param obj: The name of the object within
214                       the dictionary 'self.buttons'
215           @return: None"""
216        # get the widget from the inventory with the name obj
217        drag_widget = self.inventory.findChild(name = obj)
218        # only drag if the widget is not empty
219        if (drag_widget.up_image != self.empty_images[obj]):
220            # get it's type (e.g. main_inv)
221            data_drag.dragged_type = self.buttons[obj]
222            # get the item that the widget is 'storing'
223            data_drag.dragged_item = drag_widget.item
224            # get the up and down images of the widget
225            up_image = drag_widget.up_image
226            down_image = drag_widget.down_image
227            # set the mouse cursor to be the widget's image
228            self.setMouseCursor(up_image.source,down_image.source)
229            data_drag.dragged_image = up_image.source
230            data_drag.dragging = True
231            # after dragging the 'item', set the widgets' images
232            # so that it has it's default 'empty' images
233            drag_widget.up_image=(self.empty_images[obj])
234            drag_widget.down_image=(self.empty_images[obj])
235            drag_widget.hover_image=(self.empty_images[obj])
236            # then set it's item to nothing
237            drag_widget.item = ""
238           
239    def dropObject(self, obj):
240        """Drops the object being dropped
241           @type obj: string
242           @param obj: The name of the object within
243                       the dictionary 'self.buttons'
244           @return: None"""
245        # find the type of the place that the object
246        # is being dropped onto
247        data_drag.dropped_type  =  self.buttons[obj]
248        # if the dragged obj or the place it is being dropped is
249        # in the main inventory, drop the object
250        if((data_drag.dragged_type == 'main_inv') or
251           (data_drag.dropped_type == 'main_inv')):
252            drag_widget = self.inventory.findChild(name = obj)
253            drag_widget.up_image = data_drag.dragged_image
254            drag_widget.hover_image = data_drag.dragged_image
255            drag_widget.down_image = data_drag.dragged_image
256            drag_widget.item = data_drag.dragged_item
257            print 'Item: ' + drag_widget.item
258            data_drag.dragging = False
259            #reset the mouse cursor to the normal cursor
260            self.resetMouseCursor()
261            # if the object was dropped onto a ready slot, then
262            # update the hud
263            if (data_drag.dropped_type == 'ready'):
264                self.readyCallback()
265       
266        # if the dragged object's type is the same as the location to
267        # to drop it at's, and the dragged object's type is in
268        # self.locations, then drop the object
269        elif((data_drag.dragged_type == data_drag.dropped_type) and
270             (data_drag.dragged_type in self.locations)):
271            drag_widget = self.inventory.findChild(name = obj)
272            drag_widget.up_image = data_drag.dragged_image
273            drag_widget.hover_image = data_drag.dragged_image
274            drag_widget.down_image = data_drag.dragged_image
275            drag_widget.item = data_drag.dragged_item
276            print 'Item: ' + drag_widget.item
277            data_drag.dragging = False
278            # reset the mouse cursor
279            self.resetMouseCursor()
280            # if the object was dropped onto a ready slot, then
281            # update the hud
282            if(data_drag.dropped_type == 'ready'):
283                self.readyCallback()
284        # otherwise, we assume that the player is trying to
285        # drop an object onto an incompatible slot
286        else:
287            # reset the mouse cursor
288            self.resetMouseCursor()
289            data_drag.dragging = False
290
291    def getItems(self):
292        """
293        Get the items in the inventory slots. If there is no item in the slot,
294        it is skipped
295       
296        @rtype: dict
297        @return: The items in the inventory
298        """
299        items = {}
300
301        for button in self.buttons:
302            widget = self.inventory.findChild(name=button)
303            if (widget.item != ""):
304                items[button] = widget.item
305
306        return items
307               
308    def getImage(self, name):
309        """Return a current image from the inventory
310           @type name: string
311           @param name: name of image to get
312           @return: None"""
313        return self.inventory.findChild(name=name)
314
Note: See TracBrowser for help on using the repository browser.