source: branches/active/character_customization/game/parpg/objects/action.py @ 774

Revision 774, 21.6 KB checked in by aspidites, 9 years ago (diff)

Patch by Aspidites

  • removed shebang from all python files except launcher scripts
  • added shebang to pychan_designer
  • Property svn:eol-style set to native
RevLine 
[262]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
[568]16#exceptions
[601]17
[736]18from parpg.gui import drag_drop_data as data_drag
[601]19
[568]20class NoSuchQuestException(Exception):
21    """NoQuestException is used when there is no active quest with the id"""
22    pass
23
24#classes
25
[262]26class Action(object):
27    """Base Action class, to define the structure"""
[568]28
29
[571]30    def __init__(self, controller, commands = None):
[568]31        """Basic action constructor
[571]32        @param controller: A reference to the GameSceneController.
[736]33        @type controller: parpg.GameSceneController
[568]34        @param commands: Special commands that are executed
35        @type commands: Dictionary
36        """
[571]37        self.commands = commands or ()
38        self.controller = controller
39        self.model = controller.model
[568]40   
[262]41    def execute(self):
[568]42        """To be overwritten"""       
43        #Check if there are special commands and execute them
44        for command_data in self.commands:
45            command = command_data["Command"]
46            if command == "SetQuestVariable":
47                quest_id = command_data["ID"]
48                variable = command_data["Variable"]
49                value = command_data["Value"]
50                quest_engine = self.model.game_state.quest_engine
51                if quest_engine.hasQuest(quest_id):
52                    quest_engine[quest_id].setValue(variable, value)
53                else:
54                    raise NoSuchQuestException
[601]55            elif command == "ResetMouseCursor":
56                self.controller.resetMouseCursor()
57            elif command == "StopDragging":
58                data_drag.dragging = False
[568]59               
[262]60class ChangeMapAction(Action):
61    """A change map scheduled"""
[759]62    def __init__(self, controller, target_map_name, target_pos, commands=None):
[310]63        """Initiates a change of the position of the character
[568]64        possibly flagging a new map to be loaded.
[571]65        @param controller: A reference to the GameSceneController.
[736]66        @type controller: parpg.GameSceneController
[568]67        @param commands: Special commands that are executed
68        @type commands: Dictionary
[736]69        @type view: class derived from parpg.ViewBase
[568]70        @param view: The view
71        @type target_map_name: String
72        @param target_map_name: Target map id
73        @type target_pos: Tuple
74        @param target_pos: (X, Y) coordinates on the target map.
75        @return: None"""
[571]76        super(ChangeMapAction, self).__init__(controller, commands)
77        self.view = controller.view
[315]78        self.target_pos = target_pos
79        self.target_map_name = target_map_name
[310]80
[262]81    def execute(self):
[312]82        """Executes the map change."""
[563]83        self.model.changeMap(self.target_map_name,
[315]84                              self.target_pos)
[571]85        super(ChangeMapAction, self).execute()
[610]86
87class OpenAction(Action):
88    """Open a container"""
[759]89    def __init__(self, controller, container, commands=None):
[610]90        """
91        @param controller: A reference to the GameSceneController.
[736]92        @type controller: parpg.GameSceneController
[610]93        @param commands: Special commands that are executed
94        @type commands: Dictionary
[736]95        @type view: class derived from parpg.ViewBase
[610]96        @param view: The view
97        @param container: A reference to the container
98        """
99        super(OpenAction, self).__init__(controller, commands)
100        self.view = controller.view
101        self.container = container
102    def execute(self):
103        """Open the box."""
104        self.view.hud.createBoxGUI(self.container.name, \
105                                              self.container)
106        super(OpenAction, self).execute()
[262]107       
[610]108       
109class OpenBoxAction(OpenAction):
[262]110    """Open a box. Needs to be more generic, but will do for now."""
[571]111    def __init__(self, controller, container, commands = None):
[568]112        """
[571]113        @param controller: A reference to the GameSceneController.
[736]114        @type controller: parpg.GameSceneController
[568]115        @param commands: Special commands that are executed
116        @type commands: Dictionary
[736]117        @type view: class derived from parpg.ViewBase
[568]118        @param view: The view
119        @param container: A reference to the container
120        """
[571]121        super(OpenBoxAction, self).__init__(controller, commands)
122        self.view = controller.view
[395]123        self.container = container
124       
125    def execute(self):
126        """Open the box."""
127        try:
128            self.container.open()
[571]129            super(OpenBoxAction, self).execute()
[451]130
[395]131        except ValueError:
[553]132            self.view.hud.createExamineBox(self.container.name, \
[477]133                                                  "The container is locked")
[395]134       
135class UnlockBoxAction(Action):
136    """Unlocks a box. Needs to be more generic, but will do for now."""
[571]137    def __init__(self, controller, container, commands = None):
[568]138        """
[571]139        @param controller: A reference to the GameSceneController.
[736]140        @type controller: parpg.GameSceneController
[568]141        @param commands: Special commands that are executed
142        @type commands: Dictionary
143        @param container: A reference to the container
144        """
[571]145        super(UnlockBoxAction, self).__init__(controller, commands)
[395]146        self.container = container
[262]147   
148    def execute(self):
149        """Open the box."""
[395]150        self.container.unlock()
[571]151        super(UnlockBoxAction, self).execute()
[262]152       
[395]153class LockBoxAction(Action):
154    """Locks a box. Needs to be more generic, but will do for now."""
[571]155    def __init__(self, controller, container, commands = None):
[568]156        """
[571]157        @param controller: A reference to the GameSceneController.
[736]158        @type controller: parpg.GameSceneController
[568]159        @param commands: Special commands that are executed
160        @type commands: Dictionary
161        @param container: A reference to the container
162        """
[571]163        super(LockBoxAction, self).__init__(controller, commands)
[395]164        self.container = container
[477]165       
[395]166    def execute(self):
167        """Lock the box."""
168        self.container.lock()
[571]169        super(LockBoxAction, self).execute()
[395]170
171
[572]172class ExamineAction(Action):
173    """Examine an object."""
[739]174    def __init__(self, controller, examine_id, examine_name, examine_desc=None, commands=None):
[568]175        """
[571]176        @param controller: A reference to the GameSceneController.
[736]177        @type controller: parpg.GameSceneController
[603]178        @param examine_id: An object id
179        @type examine_id: integer
180        @param examine_name: An object name
181        @type examine_name: string
182        @param examine_desc: A description of the object that will be displayed.
183        @type examine_desc: string
[568]184        @param commands: Special commands that are executed
185        @type commands: Dictionary
[736]186        @type view: class derived from parpg.ViewBase
[568]187        @param view: The view
[603]188       
[568]189        """
[572]190        super(ExamineAction, self).__init__(controller, commands)
[571]191        self.view = controller.view
[603]192        self.examine_id = examine_id
[315]193        self.examine_name = examine_name
[739]194        if examine_desc is not None:
195            self.examine_desc = examine_desc
196        else:
197            self.examine_desc = "No Description"
[262]198       
199    def execute(self):
[603]200        """Display the text."""
201        action_text = self.examine_desc
202        self.view.hud.addAction(unicode(action_text))
[572]203        print action_text
[603]204        #this code will cut the line up into smaller lines that will be displayed
205        place = 25
206        while place <= len(action_text):
207            if action_text[place] == ' ':
208                action_text = action_text[:place] +'\n'+action_text[place:]
209                place += 26 #plus 1 character to offset the new line
210            else: place += 1
211        self.view.displayObjectText(self.examine_id, unicode(action_text), time=3000)
[287]212
[602]213class ExamineItemAction(Action):
214    """Examine an item."""
215    def __init__(self, controller, examine_name, examine_desc, commands = None):
216        """
217        @param controller: A reference to the GameSceneController.
[736]218        @type controller: parpg.GameSceneController
[602]219        @param commands: Special commands that are executed
220        @type commands: Dictionary
[736]221        @type view: class derived from parpg.ViewBase
[602]222        @param view: The view
223        @type examine_name: String
224        @param examine_name: Name of the object to be examined.
225        @type examine_name: String
226        @param examine_name: Description of the object to be examined.
227        """
228        super(ExamineItemAction, self).__init__(controller, commands)
229        self.view = controller.view
230        self.examine_name = examine_name
231        self.examine_desc = examine_desc
232       
233    def execute(self):
234        """Display the text."""
235        action_text = unicode(self.examine_desc)
236        self.view.hud.addAction(action_text)
237        print action_text
238
[568]239class ReadAction(Action):
240    """Read a text."""
[571]241    def __init__(self, controller, text_name, text, commands = None):
[568]242        """
[571]243        @param controller: A reference to the GameSceneController.
[736]244        @type controller: parpg.GameSceneController
[568]245        @param commands: Special commands that are executed
246        @type commands: Dictionary
247        @param view: The view
[736]248        @type view: class derived from parpg.ViewBase
[568]249        @param text_name: Name of the object containing the text
250        @type text_name: String
251        @param text: Text to be displayied
252        @type text: String
253        """
[571]254        super(ReadAction, self).__init__(controller, commands)
255        self.view = controller.view
[568]256        self.text_name = text_name
257        self.text = text
258       
259    def execute(self):
260        """Examine the box."""
[572]261        action_text = unicode('\n'.join(["You read " + self.text_name + ".", 
262                                         self.text]))
263        self.view.hud.addAction(action_text)
264        print action_text
[571]265        super(ReadAction, self).execute()
[568]266
[287]267class TalkAction(Action):
268    """An action to represent starting a dialogue"""
[571]269    def __init__(self, controller, npc, commands = None):
[568]270        """
[571]271        @param controller: A reference to the GameSceneController.
[736]272        @type controller: parpg.GameSceneController
[568]273        @param commands: Special commands that are executed
274        @type commands: Dictionary
[736]275        @type view: class derived from parpg.ViewBase
[568]276        @param view: The view
277        @type npc: NonPlayerCharacter
278        @param npc: NPC to interact with.
279        """
[571]280        super(TalkAction, self).__init__(controller, commands)
281        self.view = controller.view
[287]282        self.npc = npc
283       
284    def execute(self):
[477]285        """Talk with the NPC when close enough, otherwise move closer.
[360]286           @return: None"""
[736]287        from parpg.dialoguecontroller import DialogueController
[632]288       
[579]289        player_char = self.model.game_state.player_character
[360]290        npc_coordinates = self.npc.getLocation().getLayerCoordinates()
[568]291        pc_coordinates = player_char.behaviour.agent.\
292                            getLocation().getLayerCoordinates()
[360]293       
294        distance_squared = (npc_coordinates.x - pc_coordinates.x) *\
[477]295                           (npc_coordinates.x - pc_coordinates.x) +\
296                           (npc_coordinates.y - pc_coordinates.y) *\
297                           (npc_coordinates.y - pc_coordinates.y)
[360]298       
299        # If we are too far away, we approach the NPC again
300        if distance_squared > 2:
[568]301            player_char.approach([self.npc.getLocation().
[563]302                         getLayerCoordinates().x,
303                         self.npc.getLocation().
304                         getLayerCoordinates().y], 
[571]305                        TalkAction(self.controller,
306                                   self.npc, self.commands))       
[320]307        else:
[568]308            player_char.behaviour.agent.act('stand', self.npc.getLocation())
[360]309   
310            if self.npc.dialogue is not None:
[632]311                dialogue_controller = DialogueController(self.controller.engine,
312                                                         self.view,
313                                                         self.model,
314                                                         self.controller.application)
315                self.controller.application.pushController(dialogue_controller)
316                dialogue_controller.startTalk(self.npc)
[360]317            else:
318                self.npc.behaviour.agent.say("Leave me alone!", 1000)
319               
[579]320            self.model.game_state.player_character.behaviour.idle()
321            self.model.game_state.player_character.nextAction = None
[571]322            super(TalkAction, self).execute()
[568]323
[571]324class UseAction(Action):
325    """Action for carryable items. It executes special commands that can be only
326    used on carryable utens"""
327
328
329    def __init__(self, controller, item, commands = None):
330        """
331        @param controller: A reference to the GameSceneController.
[736]332        @type controller: parpg.GameSceneController
[571]333        @param item: Item on which the action is called
334        @type item: CarryableItem
335        @param commands: Special commands that are executed
336        @type commands: Dictionary
337        """
338        super(UseAction, self).__init__(controller, commands)
339        self.view = controller.view
340        self.item = item
341   
342    def execute(self):
343        #Check if there are special commands and execute them
344        for command_data in self.commands:
345            command = command_data["Command"]
346            if command == "ReplaceItem":
347                object_id = command_data["ID"]
348                object_type = command_data["ObjectType"]
349                container = self.item.in_container
350                inst_dict = {}
351                inst_dict["ID"] = object_id
352                inst_dict["object_type"] = object_type
353                new_item = self.model.createContainerObject(inst_dict)
354                container.replaceItem(self.item, new_item)
355                self.view.hud.inventory.updateInventoryButtons()
356        super(UseAction, self).execute()
357
[595]358class PickUpAction(Action):
359    """Action for picking up items from a map"""
360
361    def __init__(self, controller, map_item, commands = None):
362        super(PickUpAction, self).__init__(controller, commands)
363        self.map_item = map_item
[599]364        self.view = controller.view
365       
[595]366    def execute(self):
[608]367        real_item = self.map_item.item
[595]368        self.model.deleteObject(self.map_item.ID)
369        self.model.game_state.player_character.\
370                                inventory.placeItem(real_item)
[599]371        self.view.hud.inventory.updateInventoryButtons()
[595]372        super(PickUpAction, self).execute()
[601]373
[596]374class DropItemAction(Action):
375    """Action for dropping an items on a map"""
[601]376    def __init__(self, controller, item, commands = None):
[596]377        super(DropItemAction, self).__init__(controller, commands)
378        self.item = item
[601]379       
[596]380    def execute(self):
381        map_name = self.model.game_state.current_map_name
382        map_item_values = {}
383        map_item_values["ViewName"] = self.item.name
384        map_item_values["ObjectType"] = "MapItem"
385        map_item_values["ItemType"] = self.item.item_type
386        map_item_values["Map"] = map_name
387        coords = self.model.game_state.player_character.\
388                                        getLocation().getExactLayerCoordinates()
[599]389        map_item_values["Position"] = (coords.x, coords.y)
[596]390        map_item_values["Rotation"] = 0
[608]391        map_item_values["item"] = self.item
[596]392        agent = {}
393        agent[self.item.ID] = map_item_values
394        self.model.addAgent("All", agent)
395        self.model.placeAgents()
396        super(DropItemAction, self).execute()
[601]397       
398class DropItemFromContainerAction(DropItemAction):
399    """Action for dropping an items from the Inventory to a map"""
[596]400
[601]401    def __init__(self, controller, item, container_gui, commands = None):
402        super(DropItemFromContainerAction, self).__init__(controller, item, commands)
403        self.container_gui = container_gui
404
405    def execute(self):
406        super(DropItemFromContainerAction, self).execute()
[608]407        self.item.in_container.takeItem(self.item)
[601]408        self.container_gui.updateImages()
[618]409       
410class BrewBeerAction(Action):
411    """Action for brewing beer in a pot"""
412    def __init__(self, controller, pot, commands = None):
413        super(BrewBeerAction, self).__init__(controller, commands)
414        self.pot = pot
415        self.view = controller.view
416       
417    def execute(self):
418        """Brew the beer"""
419        has_water = False
420        has_yeast = False
421        has_fruit = False
422        has_wood = False
423        has_bottle = False
424        player_character = self.model.game_state.player_character
425        for item in self.pot.items.itervalues():
426            if item.item_type == "Questionable water":
427                if has_water:
428                    self.view.hud.addAction(unicode(\
429                        "Please put only 1 water in the pot"))
430                    return
431                has_water = True
432                water_type = 1 
433                water = item
434            elif item.item_type == "Pure water":
435                if has_water:
436                    self.view.hud.addAction(unicode(\
437                        "Please put only 1 water in the pot"))
438                    return
439                has_water = True
440                water_type = 2
441                water = item
442            elif item.item_type == "Grain":
443                if has_fruit:
444                    self.view.hud.addAction(unicode(\
445                        "Please put only 1 fruit in the pot"))
446                    return
447                has_fruit = True
448                fruit_type = 3
449                fruit = item
450            elif item.item_type == "Wild potato":
451                if has_fruit:
452                    self.view.hud.addAction(unicode(\
453                        "Please put only 1 fruit in the pot"))
454                    return
455                has_fruit = True
456                fruit_type = 2
457                fruit = item
458            elif item.item_type == "Rotten yam":
459                if has_fruit:
460                    self.view.hud.addAction(unicode(\
461                        "Please put only 1 fruit in the pot"))
462                    return
463                has_fruit = True
464                fruit_type = 1
465                fruit = item
466            elif item.item_type == "Yeast":
467                if has_yeast:
468                    self.view.hud.addAction(unicode(\
469                        "Please put only 1 yeast in the pot"))
470                    return
471                has_yeast = True
472                yeast = item
473            else:
474                self.view.hud.addAction(unicode("Item " + item.name + \
475                                                " is not needed for brewing beer"))
476                self.view.hud.addAction(unicode(\
477                    "Please put only ingredients for the beer in the pot.\
478                    Things like bottles and wood have to be in your inventory"))
479                return
480        wood = player_character.hasItem("Wood")
481        if wood:
482            has_wood = True       
483        bottle = player_character.hasItem("Empty beer bottle")
484        if bottle:
485            has_bottle = True       
486        if has_water and has_fruit and has_wood and has_bottle:
487            self.pot.removeItem(water)
488            self.pot.removeItem(fruit)
489            if has_yeast:
490                self.pot.removeItem(yeast)
491            player_character.inventory.removeItem(wood)
492            inst_dict = {}
493            inst_dict["ID"] = "Beer"
494            inst_dict["object_type"] = "Beer"
495            new_item = self.model.createContainerObject(inst_dict)
496            player_character.inventory.placeItem(new_item)
497            self.view.hud.inventory.updateInventoryButtons()
498            beer_quality = 0
499            if water_type == 1:
500                if fruit_type == 1:
501                    beer_quality = -1
502                elif fruit_type == 2:
503                    beer_quality = 2
504                elif fruit_type == 3:
505                    beer_quality = 3
506            if water_type == 2:
507                if fruit_type == 1:
508                    beer_quality = 1
509                elif fruit_type == 2:
510                    beer_quality = 3
511                elif fruit_type == 3:
512                    beer_quality = 4
513            if beer_quality > 0 and has_yeast:
514                beer_quality += 1
515            self.model.game_state.quest_engine.quests["beer"].\
516                    setValue("beer_quality", beer_quality)
517        else:
518            self.view.hud.addAction(unicode(
519            """For brewing beer you need at least:
520            In the pot:
521                Fruit (like grain, potato, yam)
522                Water
523                Optionally:
524                    Good quality yeast.
525                    Wild yeast will be used if none present.
526            In the inventory:
527                Wood
528                Empty bottle"""))
529        super(BrewBeerAction, self).execute()
[601]530
[568]531ACTIONS = {"ChangeMap":ChangeMapAction, 
[610]532           "Open":OpenAction,
[568]533           "OpenBox":OpenBoxAction, 
534           "Unlock":UnlockBoxAction,
535           "Lock":LockBoxAction,
[602]536           "ExamineItem":ExamineItemAction,
[572]537           "Examine":ExamineAction,
[602]538           "Look":ExamineItemAction,
[568]539           "Read":ReadAction,
[571]540           "Talk":TalkAction,
[595]541           "Use":UseAction,
[596]542           "PickUp":PickUpAction,
[618]543           "DropFromInventory":DropItemFromContainerAction,
544           "BrewBeer":BrewBeerAction}
Note: See TracBrowser for help on using the repository browser.