Changeset 424


Ignore:
Timestamp:
12/03/09 10:02:10 (9 years ago)
Author:
b0rland_parpg
Message:

Ticket #107: patch by b0rland

  • Reworked inventory gui to use new inventory model
  • Made various additions and fixes to inventory model and base classes
  • Improved drag-and-drop support
  • Possibly broke dialog gui :(
Location:
trunk/game
Files:
17 edited

Legend:

Unmodified
Added
Removed
  • trunk/game

    • Property svn:ignore
      •  

        old new  
        11*.dll 
        22Thumbs.db 
         3.project 
        34update_dlls_mingw.bat 
        45update_dlls_msvc2005.bat 
  • trunk/game/scripts/gui/dialoguegui.py

    r415 r424  
    5555 
    5656        def get_stuff(state, thing): 
    57             if thing not in state['pc'].inventory: 
    58                 state['pc'].inventory.add(thing) 
     57            if not state['pc'].inventory.has(thing): 
     58                state['pc'].inventory.placeItem(thing) 
    5959                print "You've now have the %s" % thing 
    6060 
    6161        def take_stuff(state,thing): 
    62             if thing in state['pc'].inventory: 
    63                 state['pc'].inventory.remove(thing) 
     62            if state['pc'].inventory.has(thing): 
     63                state['pc'].inventory.takeItem(thing) 
    6464                print "You no longer have the %s" % thing 
    6565 
  • trunk/game/scripts/gui/drag_drop_data.py

    r372 r424  
    2424dragged_type = None 
    2525dragged_item = None 
    26 dropped_type = None 
     26dragged_widget = None 
     27dragged_container = None 
     28 
  • trunk/game/scripts/gui/hud.py

    r395 r424  
    2929class Hud(object): 
    3030    """Main Hud class""" 
    31     def __init__(self, engine, settings, inv_model, data, callbacks): 
     31    def __init__(self, engine, settings, data, callbacks): 
    3232        """Initialise the instance. 
    3333           @type engine: fife.Engine 
     
    4949        self.settings = settings 
    5050        self.data = data 
    51  
    52         inv_callbacks = { 
    53             'refreshReadyImages': self.refreshReadyImages, 
    54             'toggleInventoryButton': self.toggleInventoryButton, 
    55         } 
    56  
    57  
    58         self.inventory = inventorygui.InventoryGUI(self.engine, \ 
    59                                                    inv_model, inv_callbacks) 
    60  
    61         self.refreshReadyImages() 
     51        self.inventory = None 
     52         
     53 
    6254 
    6355        self.save_game_callback = callbacks['saveGame'] 
     
    138130        self.hud.hide() 
    139131 
     132    def initializeInventory(self): 
     133        inv_callbacks = { 
     134            'refreshReadyImages': self.refreshReadyImages, 
     135            'toggleInventoryButton': self.toggleInventoryButton, 
     136        } 
     137        self.inventory = inventorygui.InventoryGUI(self.engine, 
     138                                            self.data.game_state.PC.inventory, 
     139                                            inv_callbacks) 
     140        self.refreshReadyImages() 
     141         
     142 
    140143    def initializeContextMenu(self): 
    141144        """Initialize the Context Menu 
     
    393396        """Display's the inventory screen 
    394397           @return: None""" 
    395  
     398        if self.inventory == None: 
     399            self.initializeInventory() 
    396400        self.inventory.toggleInventory(toggleImage) 
    397401 
     
    572576        self.addAction(text) 
    573577         
    574     def createBoxGUI(self, title, items = [], events = ()): 
     578    def createBoxGUI(self, title, container, events = ()): 
    575579        """Creates a window to display the contents of a box 
    576580           @type title: string 
    577581           @param title: The title for the window 
    578            @param items: The contents of the box 
     582           @param items: The box to display 
    579583           @param events: The events of the window 
    580584           @return: A new ContainerGui""" 
    581585        box_container = ContainerGUI(self.engine, \ 
    582                                               unicode(title), items) 
     586                                              unicode(title), container) 
    583587        box_container.container_gui.mapEvents(events) 
    584588        return box_container 
  • trunk/game/scripts/gui/inventorygui.py

    r372 r424  
    1616#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>. 
    1717 
    18 import sys 
    19 import os 
    2018import fife 
    21 import fifelog 
    2219import pychan 
    2320from scripts.gui import drag_drop_data as data_drag 
    2421from pychan.tools import callbackWithArguments as cbwa 
    25 from scripts.items import item_image_dict 
    2622 
    2723class InventoryGUI(object): 
    2824    """Inventory GUI class""" 
    29     def __init__(self, engine, items, callbacks): 
     25    def __init__(self, engine, inventory, callbacks): 
    3026        """Initialise the instance. 
    3127           @type engine: fife.Engine 
    3228           @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 
     29           @type inventory: Inventory 
     30           @param inventory: An inventory object to be displayed and manipulated 
    3731           @type callbacks: dict 
    3832           @param callbacks: a dict of callbacks 
     
    4842        self.toggleInventoryButtonCallback = callbacks['toggleInventoryButton'] 
    4943        self.original_cursor_id = self.engine.getCursor().getId() 
    50         # TODO: remove hard-coded string? 
     44 
    5145        self.inventory = pychan.loadXML("gui/inventory.xml") 
    5246        self.inventory_shown = False 
    53         self.events_to_map = {} 
     47        events_to_map = {} 
     48        self.inventory_storage = inventory 
     49         
     50        # Buttons of inventory arranged by slots 
     51 
     52        self.slot_buttons = {'head': ('Head',), 'chest': ('Body',), 
     53                             'left_arm': ('LeftHand',), 
     54                             'right_arm': ('RightHand',), 
     55                             'hips' : ('Belt',), 'left_leg': ('LeftFoot',), 
     56                             'right_leg': ('RightFoot',), 
     57                             'left_hand': ('LeftHeld',), 
     58                             'right_hand': ('RightHeld',), 
     59                             'backpack': ('A1', 'A2', 'A3', 'A4', 'A5', 
     60                                          'B1', 'B2', 'B3', 'B4', 'B5', 
     61                                          'C1', 'C2', 'C3', 'C4', 'C5', 
     62                                          'D1', 'D2', 'D3', 'D4', 'D5'), 
     63                             'ready': ('Ready1', 'Ready2', 'Ready3', 'Ready4') 
     64        } 
    5465        # 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() 
     66        self.slot_empty_images = {'head':'gui/inv_images/inv_head.png', 
     67                                  'chest':'gui/inv_images/inv_torso.png', 
     68                                  'left_arm':'gui/inv_images/inv_lhand.png', 
     69                                  'right_arm':'gui/inv_images/inv_rhand.png', 
     70                                  'hips':'gui/inv_images/inv_belt.png', 
     71                                  'left_leg':'gui/inv_images/inv_lfoot.png', 
     72                                  'right_leg':'gui/inv_images/inv_rfoot.png', 
     73                                  'left_hand':'gui/inv_images/inv_litem.png', 
     74                                  'right_hand':'gui/inv_images/inv_ritem.png', 
     75                                  'backpack':'gui/inv_images/inv_backpack.png', 
     76                                  'ready':'gui/inv_images/inv_belt_pouches.png', 
     77                                  } 
     78 
     79        for slot in self.slot_buttons: 
     80            for index, button in enumerate(self.slot_buttons[slot]): 
     81                widget = self.inventory.findChild(name=button) 
     82                widget.slot = slot 
     83                widget.index = index 
     84                widget.item = self.inventory_storage.getItemsInSlot(widget.slot, 
     85                                                                   widget.index) 
     86                self.updateImage(widget) 
     87                events_to_map[button] = cbwa(self.dragDrop, button) 
     88           
     89        events_to_map['close_button'] = self.closeInventoryAndToggle 
     90        self.inventory.mapEvents(events_to_map) 
     91#        self.resetMouseCursor() 
     92 
     93    def updateImage(self, button): 
     94        if (button.item == None): 
     95            image = self.slot_empty_images[button.slot] 
     96        else: 
     97            image = button.item.getInventoryThumbnail() 
     98        button.up_image = image 
     99        button.down_image = image 
     100        button.hover_image = image 
    127101 
    128102    def closeInventory(self): 
     
    178152            target_cursor_id = img_pool.addResourceFromFile(image)   
    179153            dummy_cursor_id = img_pool.addResourceFromFile(dummy_image) 
    180             cursor.set(cursor_type,target_dummy_cursor_id) 
     154            cursor.set(cursor_type,dummy_cursor_id) 
    181155            cursor.setDrag(cursor_type,target_cursor_id,-16,-16) 
    182156        else: 
     
    190164           @return: None""" 
    191165        c = self.engine.getCursor() 
    192         img_pool = self.engine.getImagePool() 
    193166        cursor_type = fife.CURSOR_NATIVE 
    194167        # this is the path to the default image 
     
    216189        # get the widget from the inventory with the name obj 
    217190        drag_widget = self.inventory.findChild(name = obj) 
     191        drag_item = drag_widget.item 
    218192        # 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] 
     193        if (drag_item != None): 
    222194            # get the item that the widget is 'storing' 
    223195            data_drag.dragged_item = drag_widget.item 
     
    229201            data_drag.dragged_image = up_image.source 
    230202            data_drag.dragging = True 
     203            data_drag.dragged_widget = drag_widget 
     204            data_drag.dragged_container=self.inventory_storage 
    231205            # after dragging the 'item', set the widgets' images 
    232206            # 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 = "" 
     207            drag_widget.item = None 
     208            self.updateImage(drag_widget) 
     209             
    238210             
    239211    def dropObject(self, obj): 
     
    243215                       the dictionary 'self.buttons'  
    244216           @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                  
     217 
     218        drop_widget = self.inventory.findChild(name = obj) 
     219        if drop_widget != data_drag.dragged_widget: 
     220            if data_drag.dragged_container != self.inventory_storage: 
     221                data_drag.dragged_container.takeItem(data_drag.dragged_item) 
     222            self.inventory_storage.moveItemToSlot(data_drag.dragged_item, 
     223                                                  drop_widget.slot, drop_widget.index) 
     224        drop_widget.item = data_drag.dragged_item 
     225        self.updateImage(drop_widget) 
     226        self.resetMouseCursor() 
     227        data_drag.dragging = False 
     228               
    308229    def getImage(self, name): 
    309230        """Return a current image from the inventory 
  • trunk/game/scripts/gui/popups.py

    r372 r424  
    2323 
    2424class ContainerGUI(): 
    25     def __init__(self, engine, title, data): 
     25    def __init__(self, engine, title, container): 
    2626        """ 
    2727        A class to create a window showing the contents of a container. 
     
    3939        self.engine = engine 
    4040        pychan.init(self.engine, debug=True) 
    41          
    4241        self.container_gui = pychan.loadXML("gui/container_base.xml") 
    4342        self.container_gui.findChild(name="topWindow").title = title 
     
    4544        data_drag.dragging = False 
    4645        self.original_cursor_id = self.engine.getCursor().getId() 
    47          
    48          
     46        self.container = container 
     47         
     48        self.resetMouseCursor() 
     49             
     50    def updateImage(self, button): 
     51        if (button.item == None): 
     52            image = self.empty_images[button.name] 
     53        else: 
     54            image = button.item.getInventoryThumbnail() 
     55        button.up_image = image 
     56        button.down_image = image 
     57        button.hover_image = image 
     58       
     59    def showContainer(self): 
     60        """ 
     61        Show the container 
     62        @return: None 
     63        """ 
    4964        # Prepare slots 1 through 9 
    50         data_is_list = False 
    5165        empty_image = "gui/inv_images/inv_backpack.png" 
    5266        slot_count = 9 
    5367        self.empty_images = dict() 
    54         # Did this step because I'm unsure which is more costly , to check the 
    55         # type of object or the value of boolean object. Change as you see fit. 
    56         if type(data) == list: 
    57             data_is_list = True 
     68        self.events_to_map = {} 
    5869        for counter in range(1, slot_count): 
    5970            slot_name = "Slot%i" % counter 
    60             selected_data = None 
    61              
    62             if data_is_list: 
    63                 selected_data = data[counter-1] 
    64             else: 
    65                 selected_data = data 
    66              
    67             self.setContainerImage(slot_name, item_image_dict[selected_data]) 
    68             self.container_gui.findChild(name=slot_name).item = selected_data 
    6971            self.empty_images[slot_name] = empty_image 
    70          
    71          
    72         self.events_to_map = {} 
    73         self.buttons = {} 
    74  
    75         for key in self.empty_images: 
    76             self.buttons[key] = "main_inv" 
    77  
    78         for button in self.buttons: 
    79             # make every button's callback be self.dragDrop 
    80             self.events_to_map[button] = cbwa(self.dragDrop, button) 
    81  
    82         self.locations = ["main_inv"] 
    83  
    84         self.container_gui.mapEvents(self.events_to_map)    
    85         self.resetMouseCursor() 
    86              
    87  
    88     def setContainerImage(self, widget_name, image): 
    89         """ 
    90         Sets the up, down, and hover images of an image button to image 
    91  
    92         @type widget_name: string 
    93         @param widget_name: the name of the widget 
    94         @type image: string 
    95         @param image: the path to the image 
    96         @return None 
    97         """ 
    98         widget = self.container_gui.findChild(name=widget_name) 
    99         widget.up_image = image 
    100         widget.down_image = image 
    101         widget.hover_image = image 
    102         print 'Set all images on %s using %s' % (widget, image) 
    103          
    104     def showContainer(self): 
    105         """ 
    106         Show the container 
    107         @return: None 
    108         """ 
     72            widget = self.container_gui.findChild(name=slot_name) 
     73            widget.item = self.container.items.get(counter-1) 
     74            widget.index = counter-1 
     75            self.updateImage(widget) 
     76            self.events_to_map[slot_name] = cbwa(self.dragDrop, slot_name) 
     77 
     78        self.container_gui.mapEvents(self.events_to_map) 
     79 
    10980        self.container_gui.show() 
    11081 
     
    170141        # get the widget from the container_gui with the name obj 
    171142        drag_widget = self.container_gui.findChild(name = obj) 
     143        drag_item = drag_widget.item 
    172144        # only drag if the widget is not empty 
    173         if (drag_widget.up_image != self.empty_images[obj]): 
    174             # get it's type (e.g. main_inv) 
    175             data_drag.dragged_type = self.buttons[obj] 
     145        if (drag_item != None): 
    176146            # get the item that the widget is 'storing' 
    177147            data_drag.dragged_item = drag_widget.item 
     
    183153            data_drag.dragged_image = up_image.source 
    184154            data_drag.dragging = True 
     155            data_drag.dragged_widget = drag_widget 
     156            data_drag.dragged_container=self.container 
     157 
    185158            # after dragging the 'item', set the widgets' images 
    186159            # so that it has it's default 'empty' images 
    187             drag_widget.up_image = self.empty_images[obj] 
    188             drag_widget.down_image = self.empty_images[obj] 
    189             drag_widget.hover_image = self.empty_images[obj] 
    190             # then set it's item to nothing 
    191             drag_widget.item = "" 
     160            drag_widget.item = None 
     161            self.updateImage(drag_widget) 
    192162             
    193163    def dropObject(self, obj): 
     
    197167                       the dictionary 'self.buttons'  
    198168           @return: None""" 
    199         # find the type of the place that the object 
    200         # is being dropped onto 
    201         data_drag.dropped_type  =  self.buttons[obj] 
    202         # if the dragged obj or the place it is being dropped is 
    203         # in the main container_gui, drop the object 
    204         if((data_drag.dragged_type == 'main_inv') or 
    205            (data_drag.dropped_type == 'main_inv')): 
    206             drag_widget = self.container_gui.findChild(name = obj) 
    207             drag_widget.up_image = data_drag.dragged_image 
    208             drag_widget.down_image = data_drag.dragged_image 
    209             drag_widget.hover_image = data_drag.dragged_image 
    210             drag_widget.item = data_drag.dragged_item 
    211             print 'Item: ' + drag_widget.item 
    212             data_drag.dragging = False 
    213             #reset the mouse cursor to the normal cursor 
    214             self.resetMouseCursor() 
    215             # if the object was dropped onto a ready slot, then 
    216             # update the hud 
    217             if (data_drag.dropped_type == 'ready'): 
    218                 self.readyCallback() 
    219          
    220         # if the dragged object's type is the same as the location to 
    221         # to drop it at's, and the dragged object's type is in 
    222         # self.locations, then drop the object 
    223         elif((data_drag.dragged_type == data_drag.dropped_type) and 
    224              (data_drag.dragged_type in self.locations)): 
    225             drag_widget = self.container_gui.findChild(name = obj) 
    226             drag_widget.up_image = data_drag.dragged_image 
    227             drag_widget.down_image = data_drag.dragged_image 
    228             drag_widget.hover_image = data_drag.dragged_image 
    229             drag_widget.item = data_drag.dragged_item 
    230             print 'Item: ' + drag_widget.item 
    231             data_drag.dragging = False 
    232             # reset the mouse cursor 
    233             self.resetMouseCursor() 
    234             # if the object was dropped onto a ready slot, then 
    235             # update the hud 
    236             if(data_drag.dropped_type == 'ready'): 
    237                 self.readyCallback() 
    238         # otherwise, we assume that the player is trying to 
    239         # drop an object onto an incompatible slot 
    240         else: 
    241             # reset the mouse cursor 
    242             self.resetMouseCursor() 
    243             data_drag.dragging = False 
     169        drop_widget = self.container_gui.findChild(name = obj) 
     170        if drop_widget != data_drag.dragged_widget: 
     171            data_drag.dragged_container.takeItem(data_drag.dragged_item) 
     172            self.container.placeItem(data_drag.dragged_item, drop_widget.index) 
     173        drop_widget.item = data_drag.dragged_item 
     174        self.updateImage(drop_widget) 
     175        data_drag.dragging = False 
     176        #reset the mouse cursor to the normal cursor 
     177        self.resetMouseCursor() 
     178 
    244179 
    245180class ExaminePopup(): 
  • trunk/game/scripts/inventory.py

    r346 r424  
    2121    """The class to represent inventory 'model': allow operations with 
    2222    inventory contents, perform weight/bulk calculations, etc""" 
    23     def __init__(self, ID, **kwargs): 
     23    def __init__(self, **kwargs): 
    2424        """Initialise instance""" 
    25         CarryableContainer.__init__(self, ID=ID, **kwargs) 
    26         self.items = {"head": Slot(ID), "neck": Slot(ID), "shoulders": Slot(ID), 
    27                       "chest": Slot(ID), "abdomen": Slot(ID), "left_arm": Slot(ID), 
    28                       "right_arm": Slot(ID),"groin": Slot(ID), "hips": Slot(ID), 
    29                       "left_leg": Slot(ID), "right_leg": Slot(ID), 
    30                       "backpack": CarryableContainer(ID)} 
     25        CarryableContainer.__init__(self, **kwargs) 
     26        self.items = {"head": Slot(name="head"), "neck": Slot(name="neck"), "shoulders": Slot(name="shoulders"), 
     27                      "chest": Slot(), "abdomen": Slot(), "left_arm": Slot(), 
     28                      "right_arm": Slot(),"groin": Slot(), "hips": Slot(), 
     29                      "left_leg": Slot(), "right_leg": Slot(), 
     30                      "left_hand": Slot(), "right_hand": Slot(), 
     31                      "ready": CarryableContainer(), 
     32                      "backpack": CarryableContainer()} 
    3133        for key,item in self.items.iteritems(): 
    3234            item.name = key 
    3335        self.item_lookup = {} 
    3436 
    35     def placeItem(self,item): 
    36         self.items["backpack"].placeItem(item) 
     37    def placeItem(self,item, index=None): 
     38        self.items["backpack"].placeItem(item, index) 
    3739        self.item_lookup[item.ID] = "backpack" 
     40 
     41 
    3842         
    3943    def takeItem(self,item): 
     
    5963        return self.moveItemToSlot(item, "backpack") 
    6064 
    61     def moveItemToSlot(self,item,slot): 
     65    def moveItemToSlot(self,item,slot,index=None): 
    6266        if not slot in self.items: 
    6367            raise(ValueError,"%s: No such slot" % slot) 
     
    6670            self.items[self.item_lookup[item.ID]].takeItem(item) 
    6771        try: 
    68             self.items[slot].placeItem(item) 
     72            self.items[slot].placeItem(item, index) 
    6973        except ValueError: 
    70             self.takeOff(self.items[slot].items[0]) 
    71             self.items[slot].placeItem(item) 
     74            if index == None : 
     75                self.takeOff(self.items[slot].items[0]) 
     76            else : 
     77                self.takeOff(self.items[slot].items[index]) 
     78            self.items[slot].placeItem(item, index) 
    7279        self.item_lookup[item.ID] = slot 
    7380      
    74     def getItemsInSlot(self, slot): 
     81    def getItemsInSlot(self, slot, index=None): 
    7582        if not slot in self.items: 
    7683            raise(ValueError,"%s: No such slot" % slot) 
     84        if index != None: 
     85            if index < len(self.items[slot].items) : 
     86                return self.items[slot].items[index] 
     87            else : 
     88                return None 
    7789        return copy.copy(self.items[slot].items) 
    7890 
     
    8294        return self.items[slot].count() == 0 
    8395 
     96    def has(self, item): 
     97        return item.ID in self.item_lookup; 
     98 
    8499    def __repr__(self): 
    85100        return "[%s:%s "%(self.name, self.ID)+reduce((lambda a,b: str(a) +', '+str(b)), self.items.values())+" ]" 
  • trunk/game/scripts/objects/actors.py

    r362 r424  
    1818from scripts import world 
    1919from base import * 
     20from composed import * 
     21from scripts.inventory import Inventory 
    2022 
    2123"""All actors go here. Concrete classes only.""" 
     
    110112    PC class 
    111113    """ 
    112     def __init__ (self, ID, agent_layer = None, **kwargs): 
     114    def __init__ (self, ID, agent_layer = None, inventory = None, **kwargs): 
    113115        GameObject.__init__( self, ID, **kwargs ) 
    114116        Living.__init__( self, **kwargs ) 
     
    116118 
    117119        self.is_PC = True 
    118         self.inventory = set(('beer',)) 
     120         
     121        # PC _has_ an inventory, he _is not_ one 
     122        if inventory == None: 
     123            self.inventory = Inventory() 
     124            self.inventory.placeItem(CarryableItem(ID=456, name="Dagger123")) 
     125            self.inventory.placeItem(CarryableItem(ID=555, name="Beer")) 
     126        else: 
     127            self.inventory = inventory 
    119128        self.peopleIknow = set() 
     129 
    120130        self.state = _AGENT_STATE_NONE 
    121131        self.layer_id = agent_layer.getId() 
     
    260270    """ 
    261271    def __init__(self, ID, agent_layer=None, name='NPC', \ 
    262                  text = 'A nonplayer character', **kwargs): 
     272                 text = 'A nonplayer character', inventory = None, **kwargs): 
    263273        # init game object 
    264274        GameObject.__init__(self, ID, name=name, **kwargs) 
     
    268278 
    269279        self.is_NPC = True 
    270         self.inventory = None 
     280        if inventory == None: 
     281            self.inventory = Inventory() 
     282        else: 
     283            self.inventory = inventory 
    271284        self.layer_id = agent_layer.getId() 
    272285        self.createBehaviour(agent_layer)         
  • trunk/game/scripts/objects/base.py

    r395 r424  
    5656from scripts.gui.popups import ExaminePopup, ContainerGUI 
    5757 
    58 class GameObject (object): 
     58class DynamicObject (object): 
     59    """A base class that only supports dynamic attributes functionality""" 
     60    def __init__ (self, name="Dynamic object", **kwargs): 
     61        """Initialise minimalistic set of data 
     62        @type name: String 
     63        @param name: Object display name 
     64        """ 
     65        self.name = name 
     66 
     67    def trueAttr(self, attr): 
     68        """Shortcut function to check if the current object has a member named 
     69           is_%attr and if that attribute evaluates to True""" 
     70        return hasattr(self,'is_%s' % attr) and getattr(self, 'is_%s' % attr) 
     71 
     72 
     73class GameObject (DynamicObject): 
    5974    """A base class to be inherited by all game objects. This must be the 
    6075       first class (left to right) inherited by any game object.""" 
     
    8095           @param desc: A long description of the item that is displayed when it is examined 
    8196           """ 
    82          
     97        DynamicObject.__init__(self, name, **kwargs) 
    8398        self.ID = ID 
    8499        self.gfx = gfx 
     
    87102        self.map_id = map_id 
    88103        self.blocking = True 
    89         self.name = name 
    90104        self.text = text 
    91105        self.desc = desc 
    92106         
    93     def trueAttr(self, attr): 
    94         """Shortcut function to check if the current object has a member named 
    95            is_%attr and if that attribute evaluates to True""" 
    96         return hasattr(self,'is_%s' % attr) and getattr(self, 'is_%s' % attr) 
    97  
    98107    def _getCoords(self): 
    99108        """Get-er property function""" 
     
    179188        self.in_container = None 
    180189        self.weight = 1.0 
     190 
     191    def getInventoryThumbnail(self): 
     192        #TODO: Implement properly after the objects database is in place 
     193        return "gui/inv_images/inv_litem.png" 
    181194     
    182195class Container (object): 
     
    184197    def __init__ (self, 
    185198                  events = {}, 
    186                   items = ["empty", "empty", "empty", "empty", "empty","empty", "empty", "empty", "empty"], 
    187199                  engine = None, **kwargs): 
    188200        self.is_container = True 
    189         self.items = items 
     201        self.items = {} 
    190202        self.events = events 
     203        self.containergui = None 
    191204        if not self.events: 
    192205            self.events = {'takeAllButton':self.hideContainer, 
    193206                      'closeButton':self.hideContainer} 
    194         self.containergui = engine.view.hud.createBoxGUI(self.name, self.items, self.events) 
    195          
    196     def placeItem (self, item): 
     207        if engine : 
     208            self.containergui = engine.view.hud.createBoxGUI(self.name, self, self.events) 
     209         
     210    def placeItem (self, item, index=None): 
    197211        """Adds the provided carriable item to the inventory.  
    198212           Runs an 'onStoreItem' script, if present"""     
     
    200214            raise ValueError ('% is not carriable!' % item) 
    201215        item.in_container = self 
    202         self.items.append (item) 
     216        if index == None: 
     217            self.placeAtVacant(item) 
     218        else: 
     219            if index in self.items : 
     220                raise ValueError('Slot %d is busy in %s' % (index, self.name)) 
     221            self.items[index]=item 
     222 
    203223        # Run any scripts associated with storing an item in the container 
    204224        try: 
     
    208228            pass 
    209229 
     230    def placeAtVacant(self, item): 
     231        vacant = None 
     232        for i in range(len(self.items)): 
     233            if i not in self.items : 
     234                vacant = i 
     235        if vacant == None : 
     236            vacant = len(self.items) 
     237        self.items[vacant] = item 
     238 
     239 
    210240    def takeItem (self, item): 
    211241        """Takes the listed item out of the inventory.  
    212242           Runs an 'ontakeItem' script"""         
    213         if not item in self.items: 
     243        if not item in self.items.values(): 
    214244            raise ValueError ('I do not contain this item: %s' % item) 
    215         self.items.remove (item) 
     245        del self.items[self.items.keys()[self.items.values().index(item)]] 
     246 
    216247        # Run any scripts associated with popping an item out of the container 
    217248        try: 
     
    224255        return len(self.items) 
    225256 
    226     def showContainer (self):         
    227         self.containergui.showContainer() 
     257    def showContainer (self): 
     258        if self.containergui: 
     259            self.containergui.showContainer() 
    228260 
    229261    def hideContainer(self): 
    230         self.containergui.hideContainer() 
     262        if self.containergui: 
     263            self.containergui.hideContainer() 
    231264         
    232265class Living (object): 
  • trunk/game/scripts/objects/composed.py

    r373 r424  
    3232        self.blocking = True 
    3333 
    34 class CarryableContainer(GameObject, Container, Carryable): 
     34class CarryableContainer(DynamicObject, Container, Carryable): 
    3535    """Composite class that will be used for backpack, pouches, etc.""" 
    36     def __init__ (self, ID, **kwargs): 
    37         GameObject.__init__(self, ID, **kwargs) 
    38         Container.__init__(self, **kwargs) 
     36    def __init__ (self, **kwargs): 
     37        DynamicObject.__init__(self, **kwargs) 
     38        Container.__init__(self,**kwargs) 
    3939        Carryable.__init__(self,**kwargs) 
    4040        self.own_weight = 0 
     
    4242    def getWeight(self): 
    4343        """Total weight of all items in container + container's own weight""" 
    44         return sum((item.weight for item in self.items), self.own_weight) 
     44        return sum((item.weight for item in self.items.values()), self.own_weight) 
    4545 
    4646 
     
    5151 
    5252    def __repr__(self): 
    53         return "[%s:%s "%(self.name, self.ID) +str(reduce((lambda a,b: a +', '+str(b)), self.items,""))+" ]" 
     53        return "[%s"%self.name +str(reduce((lambda a,b: a +', '+str(b)), self.items,""))+" ]" 
    5454 
    5555 
    5656class SingleItemContainer (CarryableContainer) : 
    5757    """Container that can only store a single item. This class can represent single-item inventory slots""" 
    58     def __init__ (self, ID, **kwargs): 
    59         CarryableContainer.__init__(self, ID,**kwargs) 
     58    def __init__ (self, **kwargs): 
     59        CarryableContainer.__init__(self, **kwargs) 
    6060 
    61     def placeItem(self,item): 
     61    def placeItem(self,item, index=None): 
    6262        if len(self.items) > 0 : 
    6363            raise ValueError ('%s is already busy' % self) 
    6464        CarryableContainer.placeItem(self, item) 
     65 
     66class CarryableItem (GameObject, Carryable): 
     67    """Composite class that will be used for all carryable items, weapons, etc. 
     68    """ 
     69    def __init__(self, **kwargs): 
     70        GameObject.__init__(self,**kwargs) 
     71        Carryable.__init__(self,**kwargs) 
    6572 
    6673class Door(GameObject, Lockable, Scriptable, Trappable): 
  • trunk/game/scripts/objects/containers.py

    r395 r424  
    2424 
    2525from composed import ImmovableContainer 
     26from composed import CarryableItem 
    2627import fife 
    2728 
     
    3233          'closeButton':self.close} 
    3334        ImmovableContainer.__init__(self, ID = ID, name = name, gfx = gfx, \ 
    34                 text = text, events = events, items = ["dagger01", "empty", "empty", "empty", "empty", 
    35                     "empty", "empty", "empty", "empty"], **kwargs) 
     35                text = text, events = events, **kwargs) 
     36        self.placeItem(CarryableItem(ID=987,name="Dagger456")) 
    3637 
    3738    def close(self, *args, **kwargs): 
     
    4950                  'closeButton':self.close} 
    5051        ImmovableContainer.__init__(self, ID = ID, name = name, gfx = gfx, \ 
    51                 text = text, events = events, items = ["dagger01", "empty", "empty", "empty", "empty", 
    52                                                        "empty", "empty", "empty", "empty"], **kwargs) 
     52                text = text, events = events, **kwargs) 
     53        self.placeItem(CarryableItem(ID=987,name="Dagger456")) 
     54 
    5355        fife.InstanceActionListener.__init__(self) 
    5456        self.layer = agent_layer 
  • trunk/game/scripts/world.py

    r412 r424  
    8484        """Initialize the hud member 
    8585        @return: None""" 
    86         # setup the inventory model 
    87         # make slot 'A1' and 'A3' container daggers 
    88         inv_model = {'A1':'dagger01', 'A3':'dagger01'} 
    8986 
    9087        hud_callbacks = { 
     
    9390            'quitGame': self.quitGame, 
    9491        } 
    95         self.hud = hud.Hud(self.engine, TDS, inv_model, self.data, hud_callbacks) 
     92        self.hud = hud.Hud(self.engine, TDS, self.data, hud_callbacks) 
    9693     
    9794    def quitGame(self): 
  • trunk/game/tests/test_carryable_container.py

    r346 r424  
    4646        self.assertEquals(container.weight, 8) 
    4747        container.placeItem(self.item) 
     48        print(container.items) 
    4849        self.assertEquals(container.weight, 8+9) 
    4950        container.placeItem(self.item2) 
     51        print(container.items) 
    5052        self.assertEquals(container.weight, 8+9+10) 
    5153        container.takeItem(self.item) 
  • trunk/game/tests/test_container.py

    r346 r424  
    5858        """ Test Container mixin Place/Take functions """ 
    5959        container = self.NonScriptableContainer(5) 
    60         self.assertEqual(container.items,[]) 
     60        self.assertEqual(container.items,{}) 
    6161        self.assertEqual(self.item.in_container,None) 
    6262        self.assertEqual(container.count(), 0) 
    6363        container.placeItem(self.item) 
    64         self.assertEqual(container.items,[self.item]) 
     64        self.assertEqual(container.items,{0:self.item}) 
    6565        self.assertEqual(self.item.in_container, container) 
    6666        self.assertEqual(container.count(), 1) 
    6767        self.assertRaises(ValueError, container.takeItem, self.item2) 
    6868        container.takeItem(self.item) 
    69         self.assertEqual(container.items, []) 
     69        self.assertEqual(container.items, {}) 
    7070        self.assertEqual(container.count(), 0) 
    7171 
  • trunk/game/tests/test_inventory.py

    r346 r424  
    3131        self.item2 = self.CarryableObject(13) 
    3232        self.item2.weight = 13 
    33         self.inventory = Inventory(ID=11) 
     33        self.inventory = Inventory() 
    3434 
    3535    def testPlaceTakeMove(self): 
     
    3737        self.assertTrue(self.inventory.isSlotEmpty("backpack")) 
    3838        self.inventory.placeItem(self.item) 
    39         self.assertTrue(self.item in self.inventory.getItemsInSlot("backpack")) 
     39        self.assertTrue(self.item in self.inventory.getItemsInSlot("backpack").values()) 
    4040        self.assertEqual(self.inventory.weight, 12) 
    4141        self.assertEqual(self.inventory.count(), 1) 
     
    4343 
    4444        self.inventory.moveItemToSlot(self.item, "groin") 
    45         self.assertFalse(self.item in self.inventory.getItemsInSlot("backpack")) 
    46         self.assertTrue(self.item in self.inventory.getItemsInSlot("groin")) 
     45        self.assertFalse(self.item in self.inventory.getItemsInSlot("backpack").values()) 
     46        self.assertTrue(self.item in self.inventory.getItemsInSlot("groin").values()) 
    4747        self.assertEqual(self.inventory.count(), 1) 
    4848         
     
    5252        self.assertEqual(self.inventory.count(),2) 
    5353        self.assertEqual(self.inventory.weight, 12+13) 
    54         self.assertTrue(self.item2 in self.inventory.getItemsInSlot("chest")) 
     54        self.assertTrue(self.item2 in self.inventory.getItemsInSlot("chest").values()) 
    5555 
    5656        self.inventory.takeItem(self.item) 
     
    6363        self.inventory.moveItemToSlot(self.item,"neck") 
    6464        self.assertFalse(self.inventory.isSlotEmpty("neck")) 
    65         self.assertTrue(self.item in self.inventory.getItemsInSlot("neck")) 
     65        self.assertTrue(self.item in self.inventory.getItemsInSlot("neck").values()) 
    6666 
    6767        self.inventory.moveItemToSlot(self.item2, "neck") 
    6868        self.assertFalse(self.inventory.isSlotEmpty("neck")) 
    69         self.assertTrue(self.item2 in self.inventory.getItemsInSlot("neck")) 
    70         self.assertFalse(self.item in self.inventory.getItemsInSlot("neck")) 
     69        self.assertTrue(self.item2 in self.inventory.getItemsInSlot("neck").values()) 
     70        self.assertFalse(self.item in self.inventory.getItemsInSlot("neck").values()) 
    7171         
    7272if __name__ == '__main__': 
  • trunk/game/tests/test_objects_base.py

    r346 r424  
    5252            weight = 1.0, 
    5353            is_container = True, 
    54             items = [], 
     54            items = {}, 
    5555            is_living = True, 
    5656            is_scriptable = True 
  • trunk/game/tests/test_single_item_container.py

    r346 r424  
    3939    def testPlaceTake(self): 
    4040        """ Test SingleItemContainer Place/Take functions """ 
    41         container = SingleItemContainer(ID=5) 
     41        container = SingleItemContainer() 
    4242        container.placeItem(self.item) 
    4343        self.assertRaises(ValueError, container.placeItem, self.item2) 
    4444        container.takeItem(self.item) 
    45         self.assertEqual(container.items, []) 
     45        self.assertEqual(container.items, {}) 
    4646        container.placeItem(self.item2) 
    4747 
Note: See TracChangeset for help on using the changeset viewer.