Mercurial > parpg-source
view entities/action.py @ 183:7b6aba7839ea
getGameEnvironment of GameState now returns a locals dictionary that is empty at the beginning of the game and will be saved in save games. The vals and funcs are now both in the globals dictionary.
This WILL break old saves.
author | Beliar <KarstenBock@gmx.net> |
---|---|
date | Thu, 15 Mar 2012 16:24:05 +0100 |
parents | 95461b06bac1 |
children | f4994e080d87 |
line wrap: on
line source
# This file is part of PARPG. # PARPG is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # PARPG is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with PARPG. If not, see <http://www.gnu.org/licenses/>. #exceptions import logging logger = logging.getLogger('action') from parpg.gui import drag_drop_data as data_drag from parpg.dialoguecontroller import DialogueController from parpg.components import container, lockable class NoSuchQuestException(Exception): """NoQuestException is used when there is no active quest with the id""" pass #classes class Action(object): """Base Action class, to define the structure""" def __init__(self, controller, commands = None): """Basic action constructor @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary """ self.commands = commands or () self.controller = controller self.model = controller.model self.executed = False def execute(self): """To be overwritten""" #Check if there are special commands and execute them for command_data in self.commands: command = command_data["Command"] if command == "SetQuestVariable": quest_id = command_data["ID"] variable = command_data["Variable"] value = command_data["Value"] quest_engine = self.model.game_state.quest_engine if quest_engine.hasQuest(quest_id): quest_engine[quest_id].setValue(variable, value) else: raise NoSuchQuestException elif command == "ResetMouseCursor": self.controller.resetMouseCursor() elif command == "StopDragging": data_drag.dragging = False self.executed = True class ChangeMapAction(Action): """A change map scheduled""" def __init__(self, controller, target_map_name, target_pos, commands=None): """Initiates a change of the position of the character possibly flagging a new map to be loaded. @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @type view: class derived from parpg.ViewBase @param view: The view @type target_map_name: String @param target_map_name: Target map id @type target_pos: Tuple @param target_pos: (X, Y) coordinates on the target map. @return: None""" super(ChangeMapAction, self).__init__(controller, commands) self.view = controller.view self.target_pos = target_pos self.target_map_name = target_map_name def execute(self): """Executes the map change.""" self.model.changeMap(self.target_map_name, self.target_pos) super(ChangeMapAction, self).execute() class OpenAction(Action): """Open an lockable""" def __init__(self, controller, lockable, commands=None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @type view: class derived from parpg.ViewBase @param view: The view @param lockable: A reference to the lockable """ Action.__init__(self, controller, commands) self.view = controller.view self.lockable = lockable def execute(self): """Open the lockable.""" try: lockable.open(self.lockable.lockable) self.lockable.fifeagent.behaviour.animate("open") self.lockable.fifeagent.behaviour.queue_animation("opened", repeating=True) except lockable.LockedError: self.view.hud.createExamineBox(self.lockable.description.view_name, "Locked") Action.execute(self) class CloseAction(Action): """Close an lockable""" def __init__(self, controller, lockable, commands=None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @type view: class derived from parpg.ViewBase @param view: The view @param lockable: A reference to the lockable """ Action.__init__(self, controller, commands) self.lockable = lockable def execute(self): """Close the lockable.""" lockable.close(self.lockable.lockable) self.lockable.fifeagent.behaviour.animate("close") self.lockable.fifeagent.behaviour.queue_animation("closed", repeating=True) Action.execute(self) class UnlockAction(Action): """Unlocks a lockable.""" def __init__(self, controller, lockable, commands = None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @param lockable: A reference to the lockable """ Action.__init__(self, controller, commands) self.lockable = lockable def execute(self): """Open the box.""" lockable.unlock(self.lockable.lockable) Action.execute(self) class LockAction(Action): """Locks a lockable.""" def __init__(self, controller, lockable, commands = None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @param lockable: A reference to the lockable """ Action.__init__(self, controller, commands) self.lockable = lockable self.view = controller.view def execute(self): """Lock the box.""" try: lockable.lock(self.lockable.lockable) except lockable.OpenError: self.view.hud.createExamineBox(self.lockable.description.view_name, "Is open") Action.execute(self) class ExamineAction(Action): """Examine an object.""" def __init__(self, controller, examine_id, examine_name, examine_desc=None, commands=None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param examine_id: An object id @type examine_id: integer @param examine_name: An object name @type examine_name: string @param examine_desc: A description of the object that will be displayed. @type examine_desc: string @param commands: Special commands that are executed @type commands: Dictionary """ super(ExamineAction, self).__init__(controller, commands) self.view = controller.view self.examine_id = examine_id self.examine_name = examine_name if examine_desc is not None: self.examine_desc = examine_desc else: self.examine_desc = "No Description" def execute(self): """Display the text.""" action_text = self.examine_desc self.view.hud.addAction(unicode(action_text)) logger.debug(action_text) #this code will cut the line up into smaller lines that will be displayed place = 25 while place < len(action_text): if action_text[place] == ' ': action_text = action_text[:place] +'\n'+action_text[place:] place += 26 #plus 1 character to offset the new line else: place += 1 self.view.displayObjectText(self.examine_id, unicode(action_text), time=3000) Action.execute(self) class ExamineItemAction(Action): """Examine an item.""" def __init__(self, controller, examine_name, examine_desc, commands = None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @type view: class derived from parpg.ViewBase @param view: The view @type examine_name: String @param examine_name: Name of the object to be examined. @type examine_name: String @param examine_name: Description of the object to be examined. """ super(ExamineItemAction, self).__init__(controller, commands) self.view = controller.view self.examine_name = examine_name self.examine_desc = examine_desc def execute(self): """Display the text.""" action_text = unicode(self.examine_desc) self.view.hud.addAction(action_text) logger.debug(action_text) Action.execute(self) class ExamineContentsAction(Action): """Examine the contens of an container""" def __init__(self, controller, container, commands=None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param container: The container @type container: parpg.entities.General @param commands: Special commands that are executed @type commands: Dictionary """ Action.__init__(self, controller, commands) self.view = controller.view self.container = container def execute(self): """Examine the contents""" self.view.hud.createBoxGUI(self.container.description.view_name, self.container.container) Action.execute(self) class ReadAction(Action): """Read a text.""" def __init__(self, controller, text_name, text, commands = None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @param view: The view @type view: class derived from parpg.ViewBase @param text_name: Name of the object containing the text @type text_name: String @param text: Text to be displayied @type text: String """ super(ReadAction, self).__init__(controller, commands) self.view = controller.view self.text_name = text_name self.text = text def execute(self): """Examine the box.""" action_text = unicode('\n'.join(["You read " + self.text_name + ".", self.text])) self.view.hud.addAction(action_text) logger.debug(action_text) super(ReadAction, self).execute() class TalkAction(Action): """An action to represent starting a dialogue""" def __init__(self, controller, npc, commands = None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param commands: Special commands that are executed @type commands: Dictionary @type view: class derived from parpg.ViewBase @param view: The view @type npc: NonPlayerCharacter @param npc: NPC to interact with. """ super(TalkAction, self).__init__(controller, commands) self.view = controller.view self.npc = npc def execute(self): """Talk with the NPC when close enough, otherwise move closer. @return: None""" player_char = self.model.game_state.\ getObjectById("PlayerCharacter").fifeagent player_char.behaviour.animate( 'stand', self.npc.fifeagent.behaviour.getLocation() ) if self.npc.dialogue.dialogue is not None: dialogue_controller = DialogueController( self.controller.engine, self.view, self.model, self.controller.application ) self.controller.application.manager.push_mode( dialogue_controller ) dialogue_controller.startTalk(self.npc) else: self.npc.fifeagent.behaviour.agent.say("Leave me alone!", 1000) self.model.game_state.getObjectById("PlayerCharacter").\ fifeagent.behaviour.idle() self.model.game_state.getObjectById("PlayerCharacter").\ fifeagent.behaviour.nextAction = None super(TalkAction, self).execute() class UseAction(Action): """Action for carryable items. It executes special commands that can be only used on carryable utens""" def __init__(self, controller, item, commands = None): """ @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param item: Item on which the action is called @type item: CarryableItem @param commands: Special commands that are executed @type commands: Dictionary """ super(UseAction, self).__init__(controller, commands) self.view = controller.view self.item = item def execute(self): #Check if there are special commands and execute them for command_data in self.commands: command = command_data["Command"] if command == "ReplaceItem": object_id = command_data["ID"] object_type = command_data["ObjectType"] containable = self.item.containable new_item = self.model.createItemByType(object_type, object_id, self.item.world) container.put_item(containable.container, new_item.containable, containable.slot) self.model.deleteObject(self.item.general.identifier) self.item.delete() self.view.hud.inventory.updateImages() super(UseAction, self).execute() class PickUpAction(Action): """Action for picking up items from a map""" def __init__(self, controller, item, commands = None): super(PickUpAction, self).__init__(controller, commands) self.item = item self.view = controller.view def execute(self): real_item = self.item.containable self.item.fifeagent = None player = self.model.game_state.getObjectById("PlayerCharacter") self.model.moveObject(self.item.general.identifier, None) self.model.updateObjectDB(self.item.world) container.put_item(player.container, real_item) super(PickUpAction, self).execute() class DropItemAction(Action): """Action for dropping an items on a map""" def __init__(self, controller, item, commands = None): super(DropItemAction, self).__init__(controller, commands) self.item = item def execute(self): map_name = self.model.game_state.current_map_name identifier = self.item.entity.general.identifier agent_values = self.model.items[identifier] coords = (self.model.game_state.getObjectById("PlayerCharacter"). fifeagent.behaviour.getLocation().getExactLayerCoordinates() ) agent_values["Position"] = (coords.x, coords.y) agent_values["Rotation"] = 0 agent_values["Map"] = map_name self.model.deleteObject(identifier) self.model.addAgent(self.model.ALL_AGENTS_KEY, {identifier: agent_values}) self.model.placeAgents(self.item.entity.world) self.model.updateObjectDB(self.item.entity.world) super(DropItemAction, self).execute() class DropItemFromContainerAction(DropItemAction): """Action for dropping an items from the Inventory to a map""" def __init__(self, controller, item, container_gui, commands = None): super(DropItemFromContainerAction, self).__init__(controller, item, commands) self.container_gui = container_gui def execute(self): super(DropItemFromContainerAction, self).execute() container.remove_item(self.item.container, self.item.slot) self.container_gui.updateImages() class RunScriptAction(Action): """Action that runs a specific script""" def __init__(self, controller, script, commands = None): """Basic action constructor @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param script: The name of the script to run. @type script: string @param commands: Special commands that are executed @type commands: Dictionary """ Action.__init__(self, controller, commands) self.script = script def execute(self): self.controller.systems.scripting.runScript(self.script) Action.execute(self) class BrewBeerAction(Action): """Action for brewing beer in a pot""" def __init__(self, controller, pot, commands = None): super(BrewBeerAction, self).__init__(controller, commands) self.pot = pot.container self.view = controller.view def execute(self): """Brew the beer""" has_water = False has_yeast = False has_fruit = False has_wood = False has_bottle = False player_character = (self.model.game_state. getObjectById("PlayerCharacter").container) for item in self.pot.children: if not item: continue if item.item_type == "Questionable water": if has_water: self.view.hud.addAction(unicode(\ "Please put only 1 water in the pot")) return has_water = True water_type = 1 water = item elif item.item_type == "Pure water": if has_water: self.view.hud.addAction(unicode(\ "Please put only 1 water in the pot")) return has_water = True water_type = 2 water = item elif item.item_type == "Grain": if has_fruit: self.view.hud.addAction(unicode(\ "Please put only 1 fruit in the pot")) return has_fruit = True fruit_type = 3 fruit = item elif item.item_type == "Wild potato": if has_fruit: self.view.hud.addAction(unicode(\ "Please put only 1 fruit in the pot")) return has_fruit = True fruit_type = 2 fruit = item elif item.item_type == "Rotten yam": if has_fruit: self.view.hud.addAction(unicode(\ "Please put only 1 fruit in the pot")) return has_fruit = True fruit_type = 1 fruit = item elif item.item_type == "Yeast": if has_yeast: self.view.hud.addAction(unicode(\ "Please put only 1 yeast in the pot")) return has_yeast = True yeast = item else: self.view.hud.addAction(unicode( "Item " + (item.entity.description.view_name) + " is not needed for brewing beer")) self.view.hud.addAction(unicode(\ "Please put only ingredients for the beer in the pot.\ Things like bottles and wood have to be in your inventory")) return wood = container.get_item(player_character, "Wood") if wood: has_wood = True bottle = container.get_item(player_character, "Empty beer bottle") if bottle: has_bottle = True if has_water and has_fruit and has_wood and has_bottle: container.remove_item(self.pot, water.slot) container.remove_item(self.pot, fruit.slot) if has_yeast: container.remove_item(self.pot, yeast.slot) container.remove_item(player_character, wood.slot) new_item = (self.model.createItemByType("Beer", "Beer", self.pot.entity.world) ) container.put_item(player_character, new_item.containable) self.view.hud.inventory.updateImages() beer_quality = 0 if water_type == 1: if fruit_type == 1: beer_quality = -1 elif fruit_type == 2: beer_quality = 2 elif fruit_type == 3: beer_quality = 3 if water_type == 2: if fruit_type == 1: beer_quality = 1 elif fruit_type == 2: beer_quality = 3 elif fruit_type == 3: beer_quality = 4 if beer_quality > 0 and has_yeast: beer_quality += 1 self.model.game_state.quest_engine.quests["beer"].\ setValue("beer_quality", beer_quality) else: self.view.hud.addAction(unicode( """For brewing beer you need at least: In the pot: Fruit (like grain, potato, yam) Water Optionally: Good quality yeast. Wild yeast will be used if none present. In the inventory: Wood Empty bottle""")) super(BrewBeerAction, self).execute() class SayAction(Action): """Action that will display a short text over the entity and in the action box.""" def __init__(self, controller, entity, text, commands = None): """Basic action constructor @param controller: A reference to the GameSceneController. @type controller: parpg.GameSceneController @param entity: The entity that says the text @type script: parpg.entities.General @param text: The text to be displayed @type text: string @param commands: Special commands that are executed @type commands: Dictionary """ Action.__init__(self, controller, commands) self.entity = entity self.text = text def execute(self): if self.entity.fifeagent: self.entity.fifeagent.behaviour.agent.say(self.text); if self.entity.description: self.controller.view.hud.actions_box.addDialog( self.entity.description.view_name, self.text) Action.execute(self) ACTIONS = {"ChangeMap":ChangeMapAction, "Open":OpenAction, "Close":CloseAction, "Unlock":UnlockAction, "Lock":LockAction, "ExamineItem":ExamineItemAction, "Examine":ExamineAction, "Look":ExamineItemAction, "Read":ReadAction, "Talk":TalkAction, "Use":UseAction, "PickUp":PickUpAction, "DropFromInventory":DropItemFromContainerAction, "BrewBeer":BrewBeerAction, "ExamineContents": ExamineContentsAction, "RunScript": RunScriptAction, "Say" : SayAction, "None": Action, }