# HG changeset patch
# User KarstenBock@gmx.net
# Date 1318186968 -7200
# Node ID 2241722311bfd7493f6d0d4952bc9d801daa7766
# Parent bb29d81d7ce65586f6ef19ffe57e76cdc0a46378
Moved the action module into the entities package.
Removed the objects package.
diff -r bb29d81d7ce6 -r 2241722311bf entities/action.py
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/entities/action.py Sun Oct 09 21:02:48 2011 +0200
@@ -0,0 +1,598 @@
+# 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 .
+
+#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
+
+ 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
+
+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
+ npc_coordinates = self.npc.fifeagent.behaviour.getLocation().\
+ getLayerCoordinates()
+ pc_coordinates = player_char.behaviour.agent.\
+ getLocation().getLayerCoordinates()
+
+ distance_squared = (npc_coordinates.x - pc_coordinates.x) *\
+ (npc_coordinates.x - pc_coordinates.x) +\
+ (npc_coordinates.y - pc_coordinates.y) *\
+ (npc_coordinates.y - pc_coordinates.y)
+
+ # If we are too far away, we approach the NPC again
+ if distance_squared > 2:
+ player_char.behaviour.approach(
+ [npc_coordinates.x, npc_coordinates.y],
+ TalkAction(self.controller,
+ self.npc,
+ self.commands
+ )
+ )
+ else:
+ player_char.behaviour.agent.act(
+ '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 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()
+
+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,
+ }
diff -r bb29d81d7ce6 -r 2241722311bf gamescenecontroller.py
--- a/gamescenecontroller.py Sun Oct 09 20:54:03 2011 +0200
+++ b/gamescenecontroller.py Sun Oct 09 21:02:48 2011 +0200
@@ -28,7 +28,7 @@
from controllerbase import ControllerBase
from parpg.gui.hud import Hud
from parpg.gui import drag_drop_data as data_drag
-from objects.action import (ChangeMapAction, ExamineAction, TalkAction,
+from entities.action import (ChangeMapAction, ExamineAction, TalkAction,
OpenAction, CloseAction, UnlockAction, LockAction,
PickUpAction, DropItemAction,
ExamineContentsAction,
diff -r bb29d81d7ce6 -r 2241722311bf gui/containergui_base.py
--- a/gui/containergui_base.py Sun Oct 09 20:54:03 2011 +0200
+++ b/gui/containergui_base.py Sun Oct 09 21:02:48 2011 +0200
@@ -18,7 +18,7 @@
from parpg import vfs
from parpg.gui import drag_drop_data as data_drag
-from parpg.objects.action import ACTIONS
+from parpg.entities.action import ACTIONS
from parpg.entities import General
class ContainerGUIBase(object):
@@ -142,7 +142,7 @@
def executeMenuItem(self, action):
"""Executes the items action
@param action: The action to run
- @type action: Class derived from parpg.objects.action.Action
+ @type action: Class derived from parpg.entities.action.Action
"""
action.execute()
diff -r bb29d81d7ce6 -r 2241722311bf gui/hud.py
--- a/gui/hud.py Sun Oct 09 20:54:03 2011 +0200
+++ b/gui/hud.py Sun Oct 09 21:02:48 2011 +0200
@@ -28,7 +28,7 @@
from parpg.gui import drag_drop_data as data_drag
from parpg.gui.inventorygui import CharacterGUI
from actionsbox import ActionsBox
-from parpg.objects.action import DropItemAction
+from parpg.entities.action import DropItemAction
from parpg.components import container
logger = logging.getLogger('hud')
diff -r bb29d81d7ce6 -r 2241722311bf gui/inventorygui.py
--- a/gui/inventorygui.py Sun Oct 09 20:54:03 2011 +0200
+++ b/gui/inventorygui.py Sun Oct 09 21:02:48 2011 +0200
@@ -21,7 +21,7 @@
from parpg.gui import drag_drop_data as data_drag
from parpg.gui.containergui_base import ContainerGUIBase
-from parpg.objects.action import ACTIONS
+from parpg.entities.action import ACTIONS
from parpg.components import equip, equipable, container
from parpg.entities import General
diff -r bb29d81d7ce6 -r 2241722311bf inventory.py
--- a/inventory.py Sun Oct 09 20:54:03 2011 +0200
+++ b/inventory.py Sun Oct 09 21:02:48 2011 +0200
@@ -13,9 +13,6 @@
# You should have received a copy of the GNU General Public License
# along with PARPG. If not, see .
-#from parpg.objects.base import Container
-#from parpg.objects.composed import SingleItemContainer as Slot
-
import copy
# TODO: many missing function definitions in this code
diff -r bb29d81d7ce6 -r 2241722311bf objects/__init__.py
--- a/objects/__init__.py Sun Oct 09 20:54:03 2011 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,14 +0,0 @@
-# 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 .
diff -r bb29d81d7ce6 -r 2241722311bf objects/action.py
--- a/objects/action.py Sun Oct 09 20:54:03 2011 +0200
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,598 +0,0 @@
-# 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 .
-
-#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
-
- 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
-
-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
- npc_coordinates = self.npc.fifeagent.behaviour.getLocation().\
- getLayerCoordinates()
- pc_coordinates = player_char.behaviour.agent.\
- getLocation().getLayerCoordinates()
-
- distance_squared = (npc_coordinates.x - pc_coordinates.x) *\
- (npc_coordinates.x - pc_coordinates.x) +\
- (npc_coordinates.y - pc_coordinates.y) *\
- (npc_coordinates.y - pc_coordinates.y)
-
- # If we are too far away, we approach the NPC again
- if distance_squared > 2:
- player_char.behaviour.approach(
- [npc_coordinates.x, npc_coordinates.y],
- TalkAction(self.controller,
- self.npc,
- self.commands
- )
- )
- else:
- player_char.behaviour.agent.act(
- '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 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()
-
-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,
- }