# HG changeset patch # User prock@33b003aa-7bff-0310-803a-e67f0ece8222 # Date 1277320824 0 # Node ID 69d50e751c9ae55e53e08fc7f0d9c7e5e70cde67 # Parent cccff9b04f576d4390224ecb0c404aa3fe9191d1 Lots of changes. - Added the Serializer class - Made exceptions a little more usable - Added actor attributes (not used yet but will be with the combat engine) - Made the quest dialogs more customizable - Many other small changes diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/gui/quest.xml --- a/demos/rpg/gui/quest.xml Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/gui/quest.xml Wed Jun 23 19:20:24 2010 +0000 @@ -7,7 +7,7 @@ - + diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/maps/quests.xml --- a/demos/rpg/maps/quests.xml Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/maps/quests.xml Wed Jun 23 19:20:24 2010 +0000 @@ -5,8 +5,8 @@ test_quest1 ; test_quest2 - type : RETURN_ITEM ; name : Test quest ; desc : This is the first quest you will get - type : RETURN_ITEM ; name : Second quest ; desc : This is the second quest you will get ; items : GoldStack ; value : 5000 + type : RETURN_ITEM ; quest_incomplete_dialog : Come back with 5000 gold! ; quest_complete_dialog : Thank you for finding me 5000 gold. ; name : I need some money! ; desc : Greetings traveler! I have a quest for you should you choose to accept it. Go and find me 5000 gold pieces! + type : RETURN_ITEM ; quest_incomplete_dialog : Bah! Come back with 5000 gold! ; quest_complete_dialog : Thank you for finding me ANOTHER 5000 gold. ; name : More money! ; desc : Welcome back! I have a quest for you should you choose to accept it. Go and find me another 5000 gold pieces! I bet you will find the gold in that temple over there. gold1 diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/maps/town_objects.xml --- a/demos/rpg/maps/town_objects.xml Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/maps/town_objects.xml Wed Jun 23 19:20:24 2010 +0000 @@ -4,6 +4,6 @@ gstack1 ; temple ; Quiller objectname : goldstack ; value : 5000 ; posx : 3.0 ; posy : 3.0 objectname : templeportal ; dest : level1 ; posx : 3.0 ; posy : -2.0 - objectname : quiller ; posx : 1.0 ; posy : 1.0 + objectname : quiller ; posx : 1.0 ; posy : 1.0 ; noquest_dialog : I've got nothing for you. Run along now! diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/run.py --- a/demos/rpg/run.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/run.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/actors/baseactor.py --- a/demos/rpg/scripts/actors/baseactor.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/actors/baseactor.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil @@ -31,6 +30,7 @@ from scripts.objects.baseobject import ObjectActionListener, BaseGameObject, GameObjectTypes from scripts.objects.items import GoldStack +from scripts.misc.serializer import Serializer Actions = {'NONE':0, 'PICKUP':1, @@ -60,7 +60,7 @@ else: self._dest.completeQuest() else: - self._dest.say("I've got nothing for you... leave me alone.") + self._dest.showNoQuestDialog() else: self._dest.instance.say("Hello there!") @@ -95,19 +95,76 @@ self._object.stand() self._object.performNextAction() +class ActorAttributes(Serializer): + def __init__(self, strength=0, dexterity=0, intelligence=0, health=0): + self._str = strength + self._dex = dexterity + self._int = intelligence + self._hp = health + + def serialize(self): + lvars['str'] = self._str + lvars['dex'] = self._dex + lvars['int'] = self._int + lvars['hp'] = self._hp + + return lvars + + def deserialize(self, valuedict): + if valuedict.has_key("str"): + self._str = int(valuedict['str']) + if valuedict.has_key("dex"): + self._dex = int(valuedict['dex']) + if valuedict.has_key("int"): + self._int = int(valuedict['int']) + if valuedict.has_key("hp"): + self._hp = int(valuedict['hp']) + + def _getStrength(self): + return self._str + + def _setStrength(self, strength): + self._str = strength + + def _getDexterity(self): + return self._dexterity + + def _setDexterity(self, dexterity): + self._dexterity = dexterity + + def _getIntelligence(self): + return self._int + + def _setIntelligence(self, intelligence): + self._int = intelligence + + def _getHealth(self): + return self._hp + + def _setHealth(self, health): + self._hp = health + + + strength = property(_getStrength, _setStrength) + dexterity = property(_getDexterity, _setDexterity) + intelligence = property(_getIntelligence, _setIntelligence) + health = property(_getHealth, _setHealth) + + class Actor(BaseGameObject): def __init__(self, gamecontroller, layer, typename, baseobjectname, instancename, instanceid=None, createInstance=False): super(Actor, self).__init__(gamecontroller, layer, typename, baseobjectname, instancename, instanceid, createInstance) self._type = GameObjectTypes["DEFAULT"] - self._walkspeed = self._gamecontroller.settings.get("RPG", "DefaultActorWalkSpeed", 4.0) - self._nextaction = None self._inventory = [] self._maxinventoryitems = 20 + + self._walkspeed = self._gamecontroller.settings.get("RPG", "DefaultActorWalkSpeed", 4.0) self._gold = 0 + self._attributes = ActorAttributes() self.stand() @@ -128,21 +185,28 @@ self._nextaction = None def pickUpItem(self, item): - if len(self._inventory) >= self._maxinventoryitems: - return + if self.addItemToInventory(item): + item.onPickUp() else: - if type(item) == GoldStack: - self._gold += item.value - else: - self._inventory.append(item) - - item.onPickUp() + #could do something cool like throw the item back on the ground + pass def enterPortal(self, portal): if self._id == "player": self._gamecontroller.switchMap(portal.dest) else: self._gamecontroller.scene.removeObjectFromScene(self._id) + + def addItemToInventory(self, item): + if len(self._inventory) >= self._maxinventoryitems: + return False + else: + if type(item) == GoldStack: + self._gold += item.value + else: + self._inventory.append(item) + + return True def removeItemFromInventory(self, itemid): itemtoremove = None @@ -167,6 +231,9 @@ self._gold = int(valuedict['gold']) else: self._gold = 0 + + if valuedict.has_key("walk_speed"): + self._walkspeed = float(valuedict['walk_speed']) def _getState(self): return self._state @@ -189,7 +256,11 @@ def _getInventory(self): return self._inventory + def _getAttributes(self): + return self._attributes + state = property(_getState, _setState) nextaction = property(_getNextAction, _setNextAction) gold = property(_getGold, _setGold) inventory = property(_getInventory) + attributes = property(_getAttributes) diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/actors/player.py --- a/demos/rpg/scripts/actors/player.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/actors/player.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/actors/questgiver.py --- a/demos/rpg/scripts/actors/questgiver.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/actors/questgiver.py Wed Jun 23 19:20:24 2010 +0000 @@ -35,6 +35,8 @@ def __init__(self, gamecontroller, layer, typename, baseobjectname, instancename, instanceid=None, createInstance=False): super(QuestGiver, self).__init__(gamecontroller, layer, typename, baseobjectname, instancename, instanceid, createInstance) self._type = GameObjectTypes["QUESTGIVER"] + + self._noquest_dialog = "I've got nothing for you... leave me alone." def offerNextQuest(self): """ @@ -54,7 +56,10 @@ This is called after the player accepts a quest. It marks it as active or "in progress". """ self._gamecontroller.questmanager.activateQuest(quest) - + + def showNoQuestDialog(self): + self.say(self._noquest_dialog) + def completeQuest(self): """ Checks to see if the active quest owned by this QuestGiver is complete and @@ -63,7 +68,7 @@ for activequest in self._gamecontroller.questmanager.activequests: if activequest.ownerid == self.id: if activequest.checkQuestCompleted(self._gamecontroller.scene.player): - self.say("That everything I need. Thank you!") + self.say(activequest._complete_dialog) self._gamecontroller.scene.player.gold = self._gamecontroller.scene.player.gold - activequest.requiredgold @@ -72,7 +77,7 @@ self._gamecontroller.questmanager.completeQuest(activequest) else: - self.say("Come back when you have all the items I requested!") + self.say(activequest._incomplete_dialog) def haveQuest(self): """ @@ -80,6 +85,19 @@ the player. Returns False otherwise. """ return bool(self._gamecontroller.questmanager.getNextQuest(self.id)) or bool(self._getActiveQuest()) + + def serialize(self): + lvars = super(QuestGiver, self).serialize() + + lvars['noquest_dialog'] = self._noquest_dialog + + return lvars + + def deserialize(self, valuedict): + super(QuestGiver, self).deserialize(valuedict) + + self._noquest_dialog = valuedict['noquest_dialog'] + def _getActiveQuest(self): """ diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/gamecontroller.py --- a/demos/rpg/scripts/gamecontroller.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/gamecontroller.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil, glob, uuid @@ -305,9 +304,10 @@ for filename in glob.glob(os.path.join("saves" , "*.xml")): os.remove(filename) - - self._questmanager.destroy() - self._questmanager.initializeQuests() + + + self._questmanager.reset() + self._questmanager.deserialize() mapname = self._settings.get("RPG", "TownMapFile", "town") self.loadMap(mapname) @@ -358,7 +358,7 @@ self._listener.detach() self._scene.destroyScene() - self._questmanager.destroy() + self._questmanager.reset() self._scene = None self._instancerenderer = None diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/guicontroller.py --- a/demos/rpg/scripts/guicontroller.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/guicontroller.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/misc/exceptions.py --- a/demos/rpg/scripts/misc/exceptions.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/misc/exceptions.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,26 +22,50 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. +class RPGDemoException(Exception): + def __init__(self, msg=None): + if msg: + self._msg = msg + else: + self._msg = None -class InvalidCommandError(Exception): - def __init__(self): - return +class InvalidCommandError(RPGDemoException): + def __init__(self, msg=None): + super(InvalidCommandError, self).__init__(msg) + + def __str__(self): + if self._msg: + return repr(self._msg) + else: + return repr("Command not found!") + +class ObjectNotFoundError(RPGDemoException): + def __init__(self, msg=None): + super(ObjectNotFoundError, self).__init__(msg) def __str__(self): - print "","Command not found!" + if self._msg: + return repr(self._msg) + else: + return repr("Object was not found!") -class ObjectNotFoundError(Exception): - def __init__(self): - return +class ObjectAlreadyInSceneError(RPGDemoException): + def __init__(self, msg=None): + super(ObjectAlreadyInSceneError, self).__init__(msg) def __str__(self): - print "","Object was not found!" - -class ObjectAlreadyInSceneError(Exception): - def __init__(self): - return + if self._msg: + return repr(self._msg) + else: + return repr("Object was already part of the scene!") + +class InstanceNotFoundError(RPGDemoException): + def __init__(self, msg=None): + super(InstanceNotFoundError, self).__init__(msg) def __str__(self): - print "","Object was already part of the scene!" + if self._msg: + return repr(self._msg) + else: + return repr("Instance was not found on layer!") diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/misc/serializer.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/demos/rpg/scripts/misc/serializer.py Wed Jun 23 19:20:24 2010 +0000 @@ -0,0 +1,37 @@ +#!/usr/bin/env python + +# -*- coding: utf-8 -*- + +# #################################################################### +# Copyright (C) 2005-2010 by the FIFE team +# http://www.fifengine.net +# This file is part of FIFE. +# +# FIFE is free software; you can redistribute it and/or +# modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation; either +# version 2.1 of the License, or (at your option) any later version. +# +# This library 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this library; if not, write to the +# Free Software Foundation, Inc., +# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +# #################################################################### + +class Serializer(object): + def __init__(self): + return + + def serialize(self): + pass + + def deserialize(self, valuedict=None): + pass + + + diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/objects/baseobject.py --- a/demos/rpg/scripts/objects/baseobject.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/objects/baseobject.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,13 +22,15 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil from fife import fife from fife.extensions.loaders import loadMapFile +from scripts.misc.exceptions import * +from scripts.misc.serializer import Serializer + GameObjectTypes = { "DEFAULT": 0, "ITEM":1, @@ -66,7 +68,7 @@ pass -class BaseGameObject(object): +class BaseGameObject(Serializer): def __init__(self, gamecontroller, layer, typename, baseobjectname, instancename, instanceid=None, createInstance=False): """ @param gamecontroller: A reference to the master game controller @@ -129,9 +131,12 @@ #This doesnt work #self._instance.get2dGfxVisual().setVisible(True) - self._position.x = x - self._position.y = y - self._createFIFEInstance(self, self._layer) + if self._instance: + self._setMapPostion(x,y) + else: + self._position.x = x + self._position.y = y + self._createFIFEInstance(self, self._layer) self._activated = True @@ -155,7 +160,10 @@ return lvars - def deserialize(self, valuedict): + def deserialize(self, valuedict=None): + if not valuedict: + return + if valuedict.has_key("posx"): x = float(valuedict['posx']) else: @@ -179,14 +187,16 @@ fife.InstanceVisual.create(self._instance) self._instance.thisown = 0 - + def _findFIFEInstance(self, layer): """ - @todo: throw InstanceNotFoundError + Throws InstanceNotFound if the instance was not found on the specified layer. """ self._instance = self._layer.getInstance(self._id) if self._instance: - self._instance.thisown = 0 + self._instance.thisown = 0 + else: + raise InstanceNotFoundError(self._id + " was not found on the layer!") def _getLocation(self): return self._instance.getLocation() diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/objects/items.py --- a/demos/rpg/scripts/objects/items.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/objects/items.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/quests/basequest.py --- a/demos/rpg/scripts/quests/basequest.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/quests/basequest.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil, time from datetime import datetime @@ -38,6 +37,8 @@ self._questid = questid self._name = questtitle self._text = questtext + self._complete_dialog = "That everything I need. Thank you!" + self._incomplete_dialog = "Come back when you have all the items I requested!" def __eq__(self, other): return self._questid == other.id diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/quests/questmanager.py --- a/demos/rpg/scripts/quests/questmanager.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/quests/questmanager.py Wed Jun 23 19:20:24 2010 +0000 @@ -28,8 +28,9 @@ from fife.extensions.fife_settings import Setting from scripts.quests.basequest import Quest, ReturnItemQuest, QuestTypes +from scripts.misc.serializer import Serializer -class QuestManager(object): +class QuestManager(Serializer): def __init__(self, gamecontroller): self._gamecontroller = gamecontroller @@ -38,8 +39,11 @@ self._quests = {} self._activequests = [] self._completedquests = [] - - def initializeQuests(self): + + def serialize(self): + pass + + def deserialize(self, valuedict=None): questfile = self._gamecontroller.settings.get("RPG", "QuestFile", "maps/quests.xml") self._questsettings = Setting(settings_file=questfile) @@ -47,7 +51,6 @@ for identifier in self._questsettings.get("QuestGivers", "list", []): for quest in self._questsettings.get(identifier, "questlist", []): questdict = self._questsettings.get(identifier, quest, {}) - if questdict['type'] == "RETURN_ITEM": questobj = ReturnItemQuest(identifier, quest, questdict['name'], questdict['desc']) for ritem in self._questsettings.get(quest+"_items", "itemlist", []): @@ -59,9 +62,15 @@ else: questobj = Quest(identifier, quest, questdict['name'], questdict['desc']) + if questdict.has_key("quest_incomplete_dialog"): + questobj._incomplete_dialog = questdict['quest_incomplete_dialog'] + + if questdict.has_key("quest_complete_dialog"): + questobj._complete_dialog = questdict['quest_complete_dialog'] + self._gamecontroller.questmanager.addQuest(questobj) - def destroy(self): + def reset(self): self._quests = {} self._activequests = [] self._completedquests = [] @@ -82,17 +91,27 @@ return None def getNextQuest(self, ownerid): - for quest in self._quests[ownerid]: - if not quest in self._activequests and not quest in self._completedquests: - return quest - + if self._quests.has_key(ownerid): + for quest in self._quests[ownerid]: + if not quest in self._activequests and not quest in self._completedquests: + return quest + return None def activateQuest(self, quest): + """ + Adds the quest to the "active quests" list. Note that this does NOT affect + the quest in any way. It's just a way of keeping track of which quests + the player has accepted. + """ if not quest in self._activequests: self._activequests.append(quest) def completeQuest(self, quest): + """ + Marks the quest as completed. Note that this does NOT modify the quest in + any way. This is just a way to keep track of completed quests. + """ if not quest in self._completedquests: self._completedquests.append(quest) diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/rpg.py --- a/demos/rpg/scripts/rpg.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/rpg.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil, time from datetime import datetime @@ -175,7 +174,7 @@ def _pump(self): if self._listener.quit: self._gamecontroller.endGame() - self.quitRequested = True + self.quit() else: self._gamecontroller.pump() diff -r cccff9b04f57 -r 69d50e751c9a demos/rpg/scripts/scene.py --- a/demos/rpg/scripts/scene.py Tue Jun 22 15:41:36 2010 +0000 +++ b/demos/rpg/scripts/scene.py Wed Jun 23 19:20:24 2010 +0000 @@ -22,7 +22,6 @@ # Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA # #################################################################### -# This is the rio de hola client for FIFE. import sys, os, re, math, random, shutil, uuid @@ -38,8 +37,10 @@ from scripts.objects.baseobject import GameObjectTypes, getModuleByType from scripts.objects.items import BaseItem, GoldStack, Portal from scripts.misc.exceptions import ObjectNotFoundError, ObjectAlreadyInSceneError +from scripts.misc.serializer import Serializer -class Scene(object): + +class Scene(Serializer): def __init__(self, gamecontroller): self._gamecontroller = gamecontroller @@ -203,25 +204,34 @@ location.setMapCoordinates(target_mapcoord) return location + def getObject(self, objid): + """ + Throws ObjectNotFoundError when an object cannot be found on the scene + """ + + try: + return self._objectlist[objid] + except KeyError: + raise ObjectNotFoundError(objid + " was not found on the scene.") + def addObjectToScene(self, obj): if not self._objectlist.has_key(obj.id): self._objectlist[obj.id] = obj else: obj.destroy() raise ObjectAlreadyInSceneError - - def getObject(self, objid): + + def removeObjectFromScene(self, obj): """ - @todo: throw ObjectNowFoundError + Throws ObjectNotFoundError when an object cannot be found on the scene """ - if self._objectlist.has_key(objid): - return self._objectlist[objid] - else: - return None - - def removeObjectFromScene(self, obj): + obj.destroy() - del self._objectlist[obj.id] + + try: + del self._objectlist[obj.id] + except KeyError: + raise ObjectNotFoundError(obj.id + " could not be removed from the scene as it was not found in the scene.") def serialize(self): filename = os.path.join("saves", self._mapname + "_save.xml")