source: trunk/game/scripts/objects/action.py @ 610

Revision 610, 16.4 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#!/usr/bin/env python
2#   This file is part of PARPG.
3
4#   PARPG is free software: you can redistribute it and/or modify
5#   it under the terms of the GNU General Public License as published by
6#   the Free Software Foundation, either version 3 of the License, or
7#   (at your option) any later version.
8
9#   PARPG is distributed in the hope that it will be useful,
10#   but WITHOUT ANY WARRANTY; without even the implied warranty of
11#   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12#   GNU General Public License for more details.
13
14#   You should have received a copy of the GNU General Public License
15#   along with PARPG.  If not, see <http://www.gnu.org/licenses/>.
16
17#exceptions
18
19from scripts.gui import drag_drop_data as data_drag
20
21class NoSuchQuestException(Exception):
22    """NoQuestException is used when there is no active quest with the id"""
23    pass
24
25#classes
26
27class Action(object):
28    """Base Action class, to define the structure"""
29
30
31    def __init__(self, controller, commands = None):
32        """Basic action constructor
33        @param controller: A reference to the GameSceneController.
34        @type controller: scripts.GameSceneController
35        @param commands: Special commands that are executed
36        @type commands: Dictionary
37        """
38        self.commands = commands or ()
39        self.controller = controller
40        self.model = controller.model
41   
42    def execute(self):
43        """To be overwritten"""       
44        #Check if there are special commands and execute them
45        for command_data in self.commands:
46            command = command_data["Command"]
47            if command == "SetQuestVariable":
48                quest_id = command_data["ID"]
49                variable = command_data["Variable"]
50                value = command_data["Value"]
51                quest_engine = self.model.game_state.quest_engine
52                if quest_engine.hasQuest(quest_id):
53                    quest_engine[quest_id].setValue(variable, value)
54                else:
55                    raise NoSuchQuestException
56            elif command == "ResetMouseCursor":
57                self.controller.resetMouseCursor()
58            elif command == "StopDragging":
59                data_drag.dragging = False
60               
61class ChangeMapAction(Action):
62    """A change map scheduled"""
63    def __init__(self, controller, target_map_name, target_pos, commands = None):
64        """Initiates a change of the position of the character
65        possibly flagging a new map to be loaded.
66        @param controller: A reference to the GameSceneController.
67        @type controller: scripts.GameSceneController
68        @param commands: Special commands that are executed
69        @type commands: Dictionary
70        @type view: class derived from scripts.ViewBase
71        @param view: The view
72        @type target_map_name: String
73        @param target_map_name: Target map id
74        @type target_pos: Tuple
75        @param target_pos: (X, Y) coordinates on the target map.
76        @return: None"""
77        super(ChangeMapAction, self).__init__(controller, commands)
78        self.view = controller.view
79        self.target_pos = target_pos
80        self.target_map_name = target_map_name
81
82    def execute(self):
83        """Executes the map change."""
84        self.model.changeMap(self.target_map_name,
85                              self.target_pos)
86        super(ChangeMapAction, self).execute()
87
88class OpenAction(Action):
89    """Open a container"""
90    def __init__(self, controller, container, commands = None):
91        """
92        @param controller: A reference to the GameSceneController.
93        @type controller: scripts.GameSceneController
94        @param commands: Special commands that are executed
95        @type commands: Dictionary
96        @type view: class derived from scripts.ViewBase
97        @param view: The view
98        @param container: A reference to the container
99        """
100        super(OpenAction, self).__init__(controller, commands)
101        self.view = controller.view
102        self.container = container
103    def execute(self):
104        """Open the box."""
105        self.view.hud.createBoxGUI(self.container.name, \
106                                              self.container)
107        super(OpenAction, self).execute()
108       
109       
110class OpenBoxAction(OpenAction):
111    """Open a box. Needs to be more generic, but will do for now."""
112    def __init__(self, controller, container, commands = None):
113        """
114        @param controller: A reference to the GameSceneController.
115        @type controller: scripts.GameSceneController
116        @param commands: Special commands that are executed
117        @type commands: Dictionary
118        @type view: class derived from scripts.ViewBase
119        @param view: The view
120        @param container: A reference to the container
121        """
122        super(OpenBoxAction, self).__init__(controller, commands)
123        self.view = controller.view
124        self.container = container
125       
126    def execute(self):
127        """Open the box."""
128        try:
129            self.container.open()
130            super(OpenBoxAction, self).execute()
131
132        except ValueError:
133            self.view.hud.createExamineBox(self.container.name, \
134                                                  "The container is locked")
135       
136class UnlockBoxAction(Action):
137    """Unlocks a box. Needs to be more generic, but will do for now."""
138    def __init__(self, controller, container, commands = None):
139        """
140        @param controller: A reference to the GameSceneController.
141        @type controller: scripts.GameSceneController
142        @param commands: Special commands that are executed
143        @type commands: Dictionary
144        @param container: A reference to the container
145        """
146        super(UnlockBoxAction, self).__init__(controller, commands)
147        self.container = container
148   
149    def execute(self):
150        """Open the box."""
151        self.container.unlock()
152        super(UnlockBoxAction, self).execute()
153       
154class LockBoxAction(Action):
155    """Locks a box. Needs to be more generic, but will do for now."""
156    def __init__(self, controller, container, commands = None):
157        """
158        @param controller: A reference to the GameSceneController.
159        @type controller: scripts.GameSceneController
160        @param commands: Special commands that are executed
161        @type commands: Dictionary
162        @param container: A reference to the container
163        """
164        super(LockBoxAction, self).__init__(controller, commands)
165        self.container = container
166       
167    def execute(self):
168        """Lock the box."""
169        self.container.lock()
170        super(LockBoxAction, self).execute()
171
172
173class ExamineAction(Action):
174    """Examine an object."""
175    def __init__(self, controller, examine_id, examine_name, examine_desc, commands = None):
176        """
177        @param controller: A reference to the GameSceneController.
178        @type controller: scripts.GameSceneController
179        @param examine_id: An object id
180        @type examine_id: integer
181        @param examine_name: An object name
182        @type examine_name: string
183        @param examine_desc: A description of the object that will be displayed.
184        @type examine_desc: string
185        @param commands: Special commands that are executed
186        @type commands: Dictionary
187        @type view: class derived from scripts.ViewBase
188        @param view: The view
189       
190        """
191        super(ExamineAction, self).__init__(controller, commands)
192        self.view = controller.view
193        self.examine_id = examine_id
194        self.examine_name = examine_name
195        self.examine_desc = examine_desc
196       
197    def execute(self):
198        """Display the text."""
199        action_text = self.examine_desc
200        self.view.hud.addAction(unicode(action_text))
201        print action_text
202        #this code will cut the line up into smaller lines that will be displayed
203        place = 25
204        while place <= len(action_text):
205            if action_text[place] == ' ':
206                action_text = action_text[:place] +'\n'+action_text[place:]
207                place += 26 #plus 1 character to offset the new line
208            else: place += 1
209        self.view.displayObjectText(self.examine_id, unicode(action_text), time=3000)
210
211class ExamineItemAction(Action):
212    """Examine an item."""
213    def __init__(self, controller, examine_name, examine_desc, commands = None):
214        """
215        @param controller: A reference to the GameSceneController.
216        @type controller: scripts.GameSceneController
217        @param commands: Special commands that are executed
218        @type commands: Dictionary
219        @type view: class derived from scripts.ViewBase
220        @param view: The view
221        @type examine_name: String
222        @param examine_name: Name of the object to be examined.
223        @type examine_name: String
224        @param examine_name: Description of the object to be examined.
225        """
226        super(ExamineItemAction, self).__init__(controller, commands)
227        self.view = controller.view
228        self.examine_name = examine_name
229        self.examine_desc = examine_desc
230       
231    def execute(self):
232        """Display the text."""
233        action_text = unicode(self.examine_desc)
234        self.view.hud.addAction(action_text)
235        print action_text
236
237class ReadAction(Action):
238    """Read a text."""
239    def __init__(self, controller, text_name, text, commands = None):
240        """
241        @param controller: A reference to the GameSceneController.
242        @type controller: scripts.GameSceneController
243        @param commands: Special commands that are executed
244        @type commands: Dictionary
245        @param view: The view
246        @type view: class derived from scripts.ViewBase
247        @param text_name: Name of the object containing the text
248        @type text_name: String
249        @param text: Text to be displayied
250        @type text: String
251        """
252        super(ReadAction, self).__init__(controller, commands)
253        self.view = controller.view
254        self.text_name = text_name
255        self.text = text
256       
257    def execute(self):
258        """Examine the box."""
259        action_text = unicode('\n'.join(["You read " + self.text_name + ".", 
260                                         self.text]))
261        self.view.hud.addAction(action_text)
262        print action_text
263        super(ReadAction, self).execute()
264
265class TalkAction(Action):
266    """An action to represent starting a dialogue"""
267    def __init__(self, controller, npc, commands = None):
268        """
269        @param controller: A reference to the GameSceneController.
270        @type controller: scripts.GameSceneController
271        @param commands: Special commands that are executed
272        @type commands: Dictionary
273        @type view: class derived from scripts.ViewBase
274        @param view: The view
275        @type npc: NonPlayerCharacter
276        @param npc: NPC to interact with.
277        """
278        super(TalkAction, self).__init__(controller, commands)
279        self.view = controller.view
280        self.npc = npc
281       
282    def execute(self):
283        """Talk with the NPC when close enough, otherwise move closer.
284           @return: None"""
285     
286        player_char = self.model.game_state.player_character
287        npc_coordinates = self.npc.getLocation().getLayerCoordinates()
288        pc_coordinates = player_char.behaviour.agent.\
289                            getLocation().getLayerCoordinates()
290       
291        distance_squared = (npc_coordinates.x - pc_coordinates.x) *\
292                           (npc_coordinates.x - pc_coordinates.x) +\
293                           (npc_coordinates.y - pc_coordinates.y) *\
294                           (npc_coordinates.y - pc_coordinates.y)
295       
296        # If we are too far away, we approach the NPC again
297        if distance_squared > 2:
298            player_char.approach([self.npc.getLocation().
299                         getLayerCoordinates().x,
300                         self.npc.getLocation().
301                         getLayerCoordinates().y], 
302                        TalkAction(self.controller,
303                                   self.npc, self.commands))       
304        else:
305            player_char.behaviour.agent.act('stand', self.npc.getLocation())
306   
307            if self.npc.dialogue is not None:
308                self.npc.talk(player_char)
309                self.view.hud.showDialogue(self.npc)
310            else:
311                self.npc.behaviour.agent.say("Leave me alone!", 1000)
312               
313            self.model.game_state.player_character.behaviour.idle()
314            self.model.game_state.player_character.nextAction = None
315            super(TalkAction, self).execute()
316
317class UseAction(Action):
318    """Action for carryable items. It executes special commands that can be only
319    used on carryable utens"""
320
321
322    def __init__(self, controller, item, commands = None):
323        """
324        @param controller: A reference to the GameSceneController.
325        @type controller: scripts.GameSceneController
326        @param item: Item on which the action is called
327        @type item: CarryableItem
328        @param commands: Special commands that are executed
329        @type commands: Dictionary
330        """
331        super(UseAction, self).__init__(controller, commands)
332        self.view = controller.view
333        self.item = item
334   
335    def execute(self):
336        #Check if there are special commands and execute them
337        for command_data in self.commands:
338            command = command_data["Command"]
339            if command == "ReplaceItem":
340                object_id = command_data["ID"]
341                object_type = command_data["ObjectType"]
342                container = self.item.in_container
343                inst_dict = {}
344                inst_dict["ID"] = object_id
345                inst_dict["object_type"] = object_type
346                new_item = self.model.createContainerObject(inst_dict)
347                container.replaceItem(self.item, new_item)
348                self.view.hud.inventory.updateInventoryButtons()
349        super(UseAction, self).execute()
350
351class PickUpAction(Action):
352    """Action for picking up items from a map"""
353
354    def __init__(self, controller, map_item, commands = None):
355        super(PickUpAction, self).__init__(controller, commands)
356        self.map_item = map_item
357        self.view = controller.view
358       
359    def execute(self):
360        real_item = self.map_item.item
361        self.model.deleteObject(self.map_item.ID)
362        self.model.game_state.player_character.\
363                                inventory.placeItem(real_item)
364        self.view.hud.inventory.updateInventoryButtons()
365        super(PickUpAction, self).execute()
366
367class DropItemAction(Action):
368    """Action for dropping an items on a map"""
369    def __init__(self, controller, item, commands = None):
370        super(DropItemAction, self).__init__(controller, commands)
371        self.item = item
372       
373    def execute(self):
374        map_name = self.model.game_state.current_map_name
375        map_item_values = {}
376        map_item_values["ViewName"] = self.item.name
377        map_item_values["ObjectType"] = "MapItem"
378        map_item_values["ItemType"] = self.item.item_type
379        map_item_values["Map"] = map_name
380        coords = self.model.game_state.player_character.\
381                                        getLocation().getExactLayerCoordinates()
382        map_item_values["Position"] = (coords.x, coords.y)
383        map_item_values["Rotation"] = 0
384        map_item_values["item"] = self.item
385        agent = {}
386        agent[self.item.ID] = map_item_values
387        self.model.addAgent("All", agent)
388        self.model.placeAgents()
389        super(DropItemAction, self).execute()
390       
391class DropItemFromContainerAction(DropItemAction):
392    """Action for dropping an items from the Inventory to a map"""
393
394    def __init__(self, controller, item, container_gui, commands = None):
395        super(DropItemFromContainerAction, self).__init__(controller, item, commands)
396        self.container_gui = container_gui
397
398    def execute(self):
399        super(DropItemFromContainerAction, self).execute()
400        self.item.in_container.takeItem(self.item)
401        self.container_gui.updateImages()
402
403ACTIONS = {"ChangeMap":ChangeMapAction, 
404           "Open":OpenAction,
405           "OpenBox":OpenBoxAction, 
406           "Unlock":UnlockBoxAction,
407           "Lock":LockBoxAction,
408           "ExamineItem":ExamineItemAction,
409           "Examine":ExamineAction,
410           "Look":ExamineItemAction,
411           "Read":ReadAction,
412           "Talk":TalkAction,
413           "Use":UseAction,
414           "PickUp":PickUpAction,
415           "DropFromInventory":DropItemFromContainerAction}
Note: See TracBrowser for help on using the repository browser.