changeset 524:6037f79b0dcf

Multiple quests now work. Added the item layer. Made movement more like diablo by allowing you to hold and drag the left mouse button. All objects are now loaded from a separate "allobjects" file. Specific item attributes are loaded from the map objects file (like position). This allows for the possibility of multiple instances using the same FIFE model.
author prock@33b003aa-7bff-0310-803a-e67f0ece8222
date Thu, 27 May 2010 21:11:37 +0000
parents d01eb65b2726
children 19db5a8619a4
files demos/rpg/maps/allobjects.xml demos/rpg/maps/town.xml demos/rpg/maps/town_objects.xml demos/rpg/scripts/actors/baseactor.py demos/rpg/scripts/actors/player.py demos/rpg/scripts/gamecontroller.py demos/rpg/scripts/objects/baseobject.py demos/rpg/scripts/objects/items.py demos/rpg/scripts/scene.py demos/rpg/settings-dist.xml
diffstat 10 files changed, 99 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/demos/rpg/maps/allobjects.xml	Thu May 27 21:11:37 2010 +0000
@@ -0,0 +1,13 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<Settings>
+  <Module name="models">
+    <Setting name="GoldStack" type="dict"> type : ITEM ; model : goldstack </Setting>
+    <Setting name="Quiller" type="dict"> type : QUESTGIVER ; model : warrior </Setting>
+  </Module>
+  
+   <Module name="Quiller">
+   	<Setting name="questcount" type="int"> 2 </Setting>
+   	<Setting name="quest1" type="list"> Test quest ; This is the first quest you will get </Setting>
+   	<Setting name="quest2" type="list"> Second quest ; This is the second quest you will get </Setting>
+  </Module>
+</Settings>
--- a/demos/rpg/maps/town.xml	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/maps/town.xml	Thu May 27 21:11:37 2010 +0000
@@ -149,6 +149,10 @@
 			<i r="0" x="4.0" o="grass:01" z="0.0" y="8.0"></i>
 		</instances>
 	</layer>
+	<layer y_scale="1.0" y_offset="0.0" pathing="cell_edges_only" grid_type="square" id="item_layer" rotation="0.0" x_scale="1.0" x_offset="0.0" transparency="0">
+		<instances>
+		</instances>
+	</layer>
 	<layer y_scale="1.0" y_offset="0.0" pathing="cell_edges_only" grid_type="square" id="actor_layer" rotation="0.0" x_scale="1.0" x_offset="0.0" transparency="0">
 		<instances>
 		</instances>
--- a/demos/rpg/maps/town_objects.xml	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/maps/town_objects.xml	Thu May 27 21:11:37 2010 +0000
@@ -1,11 +1,11 @@
 <?xml version='1.0' encoding='UTF-8'?>
 <Settings>
-  <Module name="town">
-    <Setting name="npclist" type="list"> Quiller </Setting>
-    <Setting name="Quiller" type="list"> QUESTGIVER ; warrior ; 1.0 ; 1.0 </Setting>
+  <Module name="items">
+  	<Setting name="itemlist" type="list"> gstack1 </Setting>
+    <Setting name="gstack1" type="dict"> typename : GoldStack ; value : 5000 ; posx : 1.0 ; posy : 1.0 </Setting>
   </Module>
-  <Module name="Quiller">
-  	<Setting name="questcount" type="int"> 1 </Setting>
-  	<Setting name="quest1" type="list"> Test quest ; This is the first quest you will get </Setting>
+  <Module name="npcs">
+  	<Setting name="npclist" type="list"> Quiller </Setting>
+    <Setting name="Quiller" type="dict"> typename : Quiller ; stat1 : 20 ; stat2 : 343 ; posx : 1.0 ; posy : 1.0 </Setting>
   </Module>
 </Settings>
--- a/demos/rpg/scripts/actors/baseactor.py	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/scripts/actors/baseactor.py	Thu May 27 21:11:37 2010 +0000
@@ -54,13 +54,16 @@
 	def execute(self):
 		print "talking to: " + self._dest.instance.getId()
 		
-		if self._dest.haveQuest():
-			if not self._dest.activequest:
-				self._dest.offerNextQuest()
+		if self._dest.type == GameObjectTypes["QUESTGIVER"]:
+			if self._dest.haveQuest():
+				if not self._dest.activequest:
+					self._dest.offerNextQuest()
+				else:
+					self._dest.completeQuest()
 			else:
-				self._dest.completeQuest()
+				self._dest.instance.say("I've got nothing for you...  leave me alone.", 2500)
 		else:
-			self._dest.instance.say("I've got nothing for you...  leave me alone.", 2500)
+			self._dest.instance.say("Hello there!")
 
 ActorStates = {'STAND':0,
 			   'WALK':1,
@@ -77,6 +80,10 @@
 
 class Actor(BaseGameObject):
 	def __init__(self, gamecontroller, instancename, instanceid=None, createInstance=False):
+
+		if not hasattr(self, "_type"):
+			self._type = GameObjectTypes["NPC"]
+			
 		super(Actor, self).__init__(gamecontroller, instancename, instanceid, createInstance)
 
 		self._walkspeed = self._gamecontroller.settings.get("RPG", "DefaultActorWalkSpeed", 4.0)
@@ -86,8 +93,6 @@
 		self._nextaction = None
 		
 		self.stand()
-		
-		self._type = GameObjectTypes["NPC"]
 
 	def stand(self):
 		self._state = ActorStates["STAND"]
@@ -144,9 +149,9 @@
 
 class QuestGiver(Actor):
 	def __init__(self, gamecontroller, instancename, instanceid=None, createInstance=False):
+		self._type = GameObjectTypes["QUESTGIVER"]
 		super(QuestGiver, self).__init__(gamecontroller, instancename, instanceid, createInstance)
 	
-		self._type = GameObjectTypes["QUESTGIVER"]
 		self._quests = []
 		
 		self._activequest = None
--- a/demos/rpg/scripts/actors/player.py	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/scripts/actors/player.py	Thu May 27 21:11:37 2010 +0000
@@ -42,9 +42,10 @@
 
 class Player(Actor):
 	def __init__(self, gamecontroller, playermodelname):
+		self._type = GameObjectTypes["PLAYER"]
 		super(Player, self).__init__(gamecontroller, playermodelname, "player", True)
 		self._playermodelname = playermodelname
 		
 		self._playeractionlistener = PlayerActionListener(self._gamecontroller, self)
 		
-		self._type = GameObjectTypes["PLAYER"]
+
--- a/demos/rpg/scripts/gamecontroller.py	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/scripts/gamecontroller.py	Thu May 27 21:11:37 2010 +0000
@@ -66,6 +66,8 @@
 		
 		self._attached = False
 		
+		self._lastmousepos = (0.0,0.0)
+		
 	def attach(self):
 		if not self._attached:
 			self._gamecontroller.keystate.reset()
@@ -85,7 +87,9 @@
 			return
 
 		clickpoint = fife.ScreenPoint(event.getX(), event.getY())
+
 		if (event.getButton() == fife.MouseEvent.LEFT):
+			self._lastmousepos = (clickpoint.x, clickpoint.y)
 			self._gamecontroller.scene.player.walk( self._gamecontroller.scene.getLocationAt(clickpoint) )
 			instances = self._gamecontroller.scene.getInstancesAt(clickpoint)
 			if instances:
@@ -133,7 +137,15 @@
 		pass
 		
 	def mouseDragged(self, event):
-		pass
+		if event.isConsumedByWidgets():
+			return
+
+		clickpoint = fife.ScreenPoint(event.getX(), event.getY())
+		if (event.getButton() == fife.MouseEvent.LEFT):
+			if clickpoint.x > self._lastmousepos[0] + 5 or  clickpoint.x < self._lastmousepos[0] - 5 or clickpoint.y > self._lastmousepos[1] + 5 or clickpoint.y < self._lastmousepos[1] - 5:
+				self._gamecontroller.scene.player.walk( self._gamecontroller.scene.getLocationAt(clickpoint) )
+
+			self._lastmousepos = (clickpoint.x, clickpoint.y)
 		
 	def keyPressed(self, event):
 		keyval = event.getKey().getValue()
@@ -187,6 +199,7 @@
 			self._scene = None
 			
 		loadImportFile("objects/actors/player/warrior/object.xml", self._engine)
+		loadImportFile("objects/items/goldstack/object.xml", self._engine)
 		
 		self._scene = Scene(self)
 		self._scene.createScene(self._settings.get("RPG", "TownMapFile", "maps/town.xml"))
--- a/demos/rpg/scripts/objects/baseobject.py	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/scripts/objects/baseobject.py	Thu May 27 21:11:37 2010 +0000
@@ -71,20 +71,32 @@
 			
 		self._instance = None
 		
+		if not hasattr(self, "_type"):
+			self._type = GameObjectTypes["DEFAULT"]
+
 		if createInstance:
-			self._createFIFEInstance()
+			if self._type == GameObjectTypes["ITEM"]:
+				layer = self._gamecontroller.scene.itemlayer
+			else:
+				layer = self._gamecontroller.scene.actorlayer
+				
+			self._createFIFEInstance(layer)
 		else:
 			self._instance = self._gamecontroller.scene.actorlayer.getInstance(self._id)
 			self._instance.thisown = 0
 			
-		self._type = GameObjectTypes["DEFAULT"]
-			
+		
 	def destroy(self):
 		"""
 		Deletes the FIFE instance from the actor layer on the map.
 		"""
 		if self._instance :
-			self._gamecontroller.scene.actorlayer.deleteInstance(self._instance)
+			if self._type == GameObjectTypes["ITEM"]:
+				layer = self._gamecontroller.scene.itemlayer
+			else:
+				layer = self._gamecontroller.scene.actorlayer
+			
+			layer.deleteInstance(self._instance)
 			self._instance = None	
 			
 	def setMapPosition(self, x, y):
@@ -97,14 +109,14 @@
 		curloc.setExactLayerCoordinates(exactloc)
 		self.location = curloc
 
-	def _createFIFEInstance(self):
+	def _createFIFEInstance(self, layer):
 		"""
 		Should not be called directly.  Use the constructor!
 		"""
 		mapmodel = self._gamecontroller.engine.getModel()
 		self._fifeobject = mapmodel.getObject(self._name, self._gamecontroller.settings.get("RPG", "ObjectNamespace", "http://www.fifengine.de/xml/rpg"))
 		
-		self._instance = self._gamecontroller.scene.actorlayer.createInstance(self._fifeobject, fife.ModelCoordinate(0,0), self._id)
+		self._instance = layer.createInstance(self._fifeobject, fife.ModelCoordinate(0,0), self._id)
 		fife.InstanceVisual.create(self._instance)
 		self._instance.thisown = 0
 
--- a/demos/rpg/scripts/objects/items.py	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/scripts/objects/items.py	Thu May 27 21:11:37 2010 +0000
@@ -33,9 +33,8 @@
 
 class BaseItem(BaseGameObject):
 	def __init__(self, gamecontroller, itemname, itemtype="unknown"):
-		super(Item, self).__init__(gamecontroller, itemtype, itemname, True)
-		
 		self._type = GameObjectTypes["ITEM"]
+		super(BaseItem, self).__init__(gamecontroller, itemtype, itemname, True)
 		
 	def onPickUp(self):
 		#remove item from the map
@@ -43,7 +42,7 @@
 	
 	def onDrop(self, dropx, dropy):
 		#recreate object
-		self._createFIFEInstance(self)
+		self._createFIFEInstance(self, self._gamecontroller.scene.itemlayer)
 		self.setMapPosition(dropx, dropy)
 		
 	def _getItemType(self):
--- a/demos/rpg/scripts/scene.py	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/scripts/scene.py	Thu May 27 21:11:37 2010 +0000
@@ -34,6 +34,7 @@
 from scripts.actors.baseactor import QuestGiver, Quest
 from scripts.actors.player import Player
 from scripts.objects.baseobject import GameObjectTypes
+from scripts.objects.items import BaseItem
 
 class Scene(object):
 	def __init__(self, gamecontroller):
@@ -47,7 +48,7 @@
 		
 		self._player = None
 		self._objectlist = {}
-		
+
 	def createScene(self, mapfilename):
 		if not self._map:
 			self._map = loadMapFile(mapfilename, self._gamecontroller.engine)
@@ -60,27 +61,38 @@
 		self._cameras[self._maincameraname].setZoom(self._gamecontroller.settings.get("RPG", "DefaultZoom", 2.0))
 		
 		self._actorlayer = self._map.getLayer(self._gamecontroller.settings.get("RPG", "ActorLayer", "actor_layer"))
+		self._itemlayer = self._map.getLayer(self._gamecontroller.settings.get("RPG", "ItemLayer", "item_layer"))
 		
 		self._player = Player(self._gamecontroller, "warrior")
 		
 		mapname = os.path.splitext(os.path.basename(mapfilename))
 		objectfile = "maps/" + mapname[0] + "_objects.xml"
+		itemfile = "maps/allobjects.xml"
 		objectsettings = Setting(app_name="",settings_file=objectfile)
+		itemsettings = Setting(app_name="", settings_file=itemfile)
 		
-		for npc in objectsettings.get(mapname[0], "npclist", []):
-			(objtype, modelname, posx, posy) = objectsettings.get(mapname[0], npc, ["NPC", "warrior", "0", "0"])
-			if objtype == "QUESTGIVER":
-				actor = QuestGiver(self._gamecontroller, modelname, npc, True)
-				questcount = objectsettings.get(npc, "questcount", 0)
+		for item in objectsettings.get("items", "itemlist", []):
+			itemdict = objectsettings.get("items", item, {})
+			modeldict = itemsettings.get("models", itemdict["typename"])
+			
+			newitem = BaseItem(self._gamecontroller, item, modeldict["model"])
+		
+		for npc in objectsettings.get("npcs", "npclist", []):
+			objdict = objectsettings.get("npcs", npc, {})
+			modeldict = itemsettings.get("models", objdict["typename"])
+			
+			if modeldict["type"] == "QUESTGIVER":
+				actor = QuestGiver(self._gamecontroller, modeldict["model"], npc, True)
+				questcount = itemsettings.get(npc, "questcount", 0)
 				for x in range(1,questcount+1):
 					quest = "quest" + str(x)
-					(qname, qtext) = objectsettings.get(npc, quest, [])
+					(qname, qtext) = itemsettings.get(npc, quest, [])
 					actor.addQuest(Quest(actor, qname, qtext))
 						
-			elif objtype == "NPC":
-				actor = Actor(self._gamecontroller, modelname, npc, True)
+			elif modeldict["type"] == "NPC":
+				actor = Actor(self._gamecontroller, modeldict["model"], npc, True)
 
-			actor.setMapPosition(float(posx), float(posy))
+			actor.setMapPosition(float(objdict["posx"]), float(objdict["posy"]))
 			self._objectlist[actor.instance.getId()] = actor
 			
 		
@@ -123,6 +135,9 @@
 		
 	def _getActorLayer(self):
 		return self._actorlayer
+		
+	def _getItemLayer(self):
+		return self._itemlayer
 	
 	def _getCameras(self):
 		return self._cameras
@@ -137,6 +152,7 @@
 		return self._map
 	
 	actorlayer = property(_getActorLayer)
+	itemlayer = property(_getItemLayer)
 	cameras = property(_getCameras)
 	player = property(_getPlayer)
 	objectlist = property(_getObjectList)
--- a/demos/rpg/settings-dist.xml	Thu May 27 18:29:20 2010 +0000
+++ b/demos/rpg/settings-dist.xml	Thu May 27 21:11:37 2010 +0000
@@ -29,6 +29,7 @@
 		<Setting name="DefaultZoom" type="float"> 2.0 </Setting>
 		<Setting name="ObjectNamespace" type="str"> http://www.fifengine.de/xml/rpg </Setting>
 		<Setting name="ActorLayer" type="str"> actor_layer </Setting>
+		<Setting name="ItemLayer" type="str"> item_layer </Setting>
 		<Setting name="HelpText" type="str"> misc/help.txt </Setting>
 		
 		<Setting name="DefaultActorWalkSpeed" type="float"> 2.5 </Setting>