Esempio n. 1
0
class NPC(Agent):
	def __init__(self, settings, model, agentName, layer, world, uniqInMap=True, name=""):
		super(NPC, self).__init__(settings, model, agentName, layer, uniqInMap)
		self._state = _STATE_NONE
		self._name = name
		self._agentName = agentName
		self._layer = layer
		self._availableActions = { 'walk': False,
					   'run': False,
					   'talk': False,
					   'die': False,
					   'explode': False,
					   'holdgun': False,
					   'firegun': False,
					   'beshot': False,
					   'walkgun': False,
					   'rungun': False,
					   'diegun': False,
					   'beshotgun': False,
					   'holdpistol': False,
					   'aimpistolleft': False,
					   'aimpistolright': False,
					   'firepistolleft': False,
					   'firepistolright': False,
					   'walkpistol': False,
					   'runpistol': False,
					   'diepistol': False,
					   'beshotpistol': False,
					   'teleportstart': False,
					   'teleportend': False,
					   'glitch': False,
					   'describe' : True}
		self._action = { 'walk': self.walk,
				 'run': self.run,
				 'talk': self.talk,
				 'die': self.die,
				 'explode': self.explode,
				 'holdgun': self._idle,
				 'firegun': self.fire,
				 'beshot': self.beshot,
				 'walkgun': self.walk,
				 'rungun': self.run,
				 'diegun': self.die,
				 'beshotgun': self.beshot,
				 'holdpistol': self._idle,
				 'aimpistolleft': self.aimleft,
				 'aimpistolright': self.aimright,
				 'firepistolleft': self.fireleft,
				 'firepistolright': self.fireright,
				 'walkpistol': self.walk,
				 'runpistol': self.run,
				 'diepistol': self.die,
				 'beshotpistol': self.beshot,
				 'teleportstart': self.teleportstart,
				 'teleportend': self.teleportend,
				 'glitch': self.glitch,
				 'decribe' : self.describe }
		self._world = world
		self._loadNPC(self._name)
		
	def _loadNPC(self, name):
		self._npcFile = SimpleXMLSerializer(filename="npcs/" + name + ".xml")
		actionstr = self._npcFile.get("npc", "actions", None)
		actions = self._npcFile._deserializeDict(actionstr)
		for action, bool in actions.iteritems():
			if bool == "True":
				self._availableActions[action] = True
			else:
				self._availableActions[action] = False
		self._actionchance = self._npcFile.get("npc", "actionchance", 0)
		self._description = self._npcFile.get("npc", "description", "I can see a mysterious figure,\n but I can't quite make them out.")
		self._autowalk = self._npcFile.get("npc", "autowalk", True)
		self._hasdialogue = self._npcFile.get("npc", "hasdialogue", False)
		self._autowalk = self._npcFile.get("npc", "autowalk", True)
		self._loadDialogue()
		self._idle()
	
	def _loadDialogue(self):
		if not self._hasdialogue:
			return
		self._dialogue = {}
		self._idledialogue = []
		index = []
		index = self._npcFile._deserializeList(self._npcFile.get("dialogue", "index", ""))
		for line in index:
			self._dialogue[line] = self._npcFile._deserializeDict(self._npcFile.get("dialogue", line, ""))
		idleindex = self._npcFile._deserializeList(self._npcFile.get("dialogue", "idleindex", ""))
		for line in idleindex:
			self._idledialogue.append(self._dialogue[line])
	
	def _listAvailableTopics(self):
		returninglist = []
		if not self._hasdialogue:
			return returninglist
		for index, dialogue in self._dialogue.iteritems():
			if dialogue["requires"] in self._world._player._plots or dialogue["requires"] == '0' and dialogue not in self._idledialogue:
				returninglist.append((index, dialogue["topic"]))
		return returninglist
	
	def _talk(self, index):
		if self._world._gamestate == 'LEVEL' and index not in self._world._player._plots:
			self._world._player._plots.append(index)
		self._agent.say(self._dialogue[index]["text"], 5000)
	
	def onInstanceActionFinished(self, instance, action):
		self._idle()
		
	def _idle(self):
		self._state = _STATE_IDLE
		if self._autowalk:
			chance = random.randint(0,100)
			if chance < self._actionchance:
				self._waypointmove()
			else:
				self._agent.act('walk', self._agent.getFacingLocation())
			chance = random.randint(0,100)
			if chance < self._actionchance / 2 and self._hasdialogue:
				self.talk()
		
	def _waypointmove(self):
		no = random.randint(0, len(self._world._waypoints) - 1)
		point = self._world._waypoints[no]
		x, point, y = point.partition(',')
		location = fife.Location()
		location.setLayer(self._layer)
		location.setExactLayerCoordinates(fife.ExactModelCoordinate(int(x) + random.randint(-1,1), int(y) + random.randint(-1,1)))
		self.run(location)
		
	def run(self, location):
		self._state = _STATE_RUN
		self._agent.move('walk', location, 0.75)
		
	def walk(self):
		pass
		
	def talk(self):
		chance = random.randint(0, len(self._idledialogue) - 1)
		self._talk(self._idledialogue[chance]["index"])
	
	def die(self):
		pass
	
	def explode(self):
		pass
	
	def beshot(self):
		pass
	
	def aimleft(self):
		pass
	
	def aimright(self):
		pass
	
	def fire(self):
		pass
	
	def fireleft(self):
		pass
	
	def fireright(self):
		pass
	
	def teleportstart(self):
		pass
	
	def teleportend(self):
		pass
	
	def glitch(self):
		pass

	def describe(self):
		self._world._player._agent.say(self._description, 5000)
class InteractiveObject(fife.InstanceActionListener):
	def __init__(self, objectmanager, model, file):
		fife.InstanceActionListener.__init__(self)
		self._manager = objectmanager
		self._model = model
		self._objectFile = SimpleXMLSerializer(file)
		self._agentName = self._objectFile.get("object", "agentname", "dummy")
		self._layer = self._manager._world._map.getLayer(self._objectFile.get("object", "layer", "player"))
		self._agent = self._layer.getInstance(self._agentName)
		self._agent.addActionListener(self)
		self._status = self._objectFile.get("object", "status", 'INACTIVE')
		
		self._actions = { 'use' : self.use,
				  'destroy' : self.destroy,
				  'turnon' : self.activate,
				  'turnoff' : self.deactivate,
				  'explode' : self.explode,
				  'describe': self.describe,
				  'glitch' : self.glitch }
		self._availableactions = { 'use' : False,
					   'destroy' : False,
					   'turnon' : False,
					   'turnoff' : False,
					   'explode' : False,
					   'describe' : True,
					   'glitch' : False }
		
		actionstr = self._objectFile.get("object", "actions", None)
		actions = self._objectFile._deserializeDict(actionstr)
		for action, bool in actions.iteritems():
			if bool in ("True"):
				self._availableactions[action] = True
			else:
				self._availableactions[action] = False
		self._description = self._objectFile.get("object", "description", "I can see something, but\n I can't tell what it is")
		self._talk = self._objectFile.get("object", "talk", False)
		self._message = self._objectFile._deserializeList(self._objectFile.get("object", "messages", ""))
		self._usesound = self._objectFile.get("object", "sound", False)
		if self._usesound:
			self._manager._world._sounds._loadclip(self._agentName, self._objectFile.get("object", "soundfile", ""), False, False)
			self._sound = self._manager._world._sounds._emitters[self._agentName]
		self._loadObject()
		self.onInstanceActionFinished(self._agent, "")
	
	def onInstanceActionFinished(self, instance, action):
		if self._status == 'ACTIVE':
			self._agent.act('on', self._agent.getFacingLocation())
		elif self._status == 'INACTIVE':
			self._agent.act('off', self._agent.getFacingLocation())
		elif self._status == 'DESTROYED':
			self._agent.act('dead', self._agent.getFacingLocation())
		elif self._status == 'GLITCHED':
			self._agent.act('glitch', self._agent.getFacingLocation())
	
	def use(self):
		if self._status == 'ACTIVE':
			self._agent.act('use', self._agent.getFacingLocation())
			self._manager._world._player._agent.setFacingLocation(self._agent.getLocation())
			if self._noactioncallbacks == 0:
				self._action()
			elif self._noactioncallbacks == 1:
				self._action(self._actioncallbacks[0])
			elif self._noactioncallbacks == 2:
				self._action(self._actioncallbacks[0], self._actioncallbacks[1])
			elif self._noactioncallbacks == 3:
				self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2])
			elif self._noactioncallbacks == 4:
				self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2], self._actioncallbacks[3])
			elif self._noactioncallbacks == 5:
				self._action(self._actioncallbacks[0], self._actioncallbacks[1], self._actioncallbacks[2], self._actioncallbacks[3], self._actioncallbacks[4])
			if self._talk:
				rand = random.randint(0, len(self._message) - 1)
				self._manager._world._player._agent.say(self._message[rand], 3500)
			if self._usesound:
				self._sound.play()

	def destroy(self):
		self._agent.act('die', self._agent.getFacingLoaction)
		self._status = 'DESTROYED'
	
	def activate(self):
		self._agent.act('turnon', self._agent.getFacingLoaction)
		self._status = 'ACTIVE'
	
	def deactivate(self):
		self._agent.act('turnoff', self._agent.getFacingLoaction)
		self._status = 'INACTIVE'
	
	def explode(self):
		self._agent.act('explode', self._agent.getFacingLoaction)
		self._status = 'DESTROYED'
	
	def describe(self):
		self._manager._world._player._agent.say(self._description, 5000)
	
	def glitch(self):
		self._agent.act('glitch', self._agent.getFacingLoaction)
		self._status = 'GLITCHED'
		
	def noAction(self):
		pass # This function exists purely to act as a void function
		     # for objects that make a pretty light
		
	def _loadObject(self):
		action = self._objectFile.get("object", "action", "none")
		if action == "none":
			self._action = self.noAction
			self._noactioncallbacks = 0
			self._actioncallbacks = {}
		elif action == "door":
			loc1 = fife.Location()
			loc1.setLayer(self._manager._world._map.getLayer('player'))
			loc1.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "newx", 0), self._file.get("event", "newy", 0)))
			
			loc2 = fife.Location()
			loc2.setLayer(self._manager._world._map.getLayer('player'))
			loc2.setExactLayerCoordinates(fife.ExactModelCoordinate(self._file.get("event", "refx", 0), self._file.get("event", "refy", 0)))
			
			self._action = self._manager._world._loadMap
			self._noactioncallbacks = 5
			self._actioncallbakcs = { 0 : self._objectFile.get("object", "mapfile", "") ,
						  1 : 'LEVEL' ,
						  2 : True ,
						  3 : loc1 ,
						  4 : loc2 }
		elif action == "plot":
			self._action = self._manager._world._eventtracker._evaluateItem
			self._noactioncallbacks = 1
			self._actioncallbacks = { 0 : self._agentName }
		elif action == "book":
			pass # Needs GUI manager
		elif action == "computer":
			pass # Needs GUI manager
		elif action == "teleport":
			pass # Needs hooks in the player and NPC classes
Esempio n. 3
0
class World(EventListenerBase):
	"""
	World Class
	Sets up the map, gui, soundmanager and calls the Actor class to deal with actors
	
	Keyword Arguments
	EventListenerBase - World inherits from EventListenerBase
	"""
	def __init__(self, app, engine, setting):
		"""
		__init__ Function
		Starts an instance of the World class
		
		Keyword Arguments
		app - A pointer to the main application
		engine - A pointer to fife.engine
		setting - A pointer to a fife settings XML file
		"""
		super(World, self).__init__(engine, regKeys=True, regCmd=False, regMouse=True)

		# Throw values into their variables
		self._applictaion = app
		self._engine = engine
		self._setting = setting
		self._timemanager = engine.getTimeManager()
		self._eventmanager = engine.getEventManager()
		self._model = engine.getModel()
		self._filename = ''
		self._keystate = { 'UP': False, 
		                   'DOWN': False, 
		                   'LEFT': False, 
		                   'RIGHT': False, 
		                   'CTRL': False, 
		                   'SPACE': False,
				   'Q': False,
				   'E': False,}
		self._cameras = {}
		self._npcs = {}
		self._npclist = None
		self._pump_ctr = 0
		self._map = None
		self._scene = None
		self._paused = True
		self._pausedtime = 0
		self._starttime = 0
		self._gamestate = 'NONE'
		self._quit = False
		self._player = None
		self._eventtracker = None
		self._objects = {}
		self._contextmenu = contextmenu.ContextMenu('rightclickmenu', self)
		self._mouseMoved = False
		
		# Start pychan
		pychan.init(self._engine)
		
		# Set all GUI types to empty
		self._hud = None
		self._mainmenu = None
		self._pausemenu = None
		self._loadingmenu = None
		self._settingsmenu = None
		self._aboutmenu = None
		
		# Start the sound manager
		self._soundmanager = SoundManager(self._engine)
		self._sounds = musicmanager.MusicManager(self._engine, self._soundmanager, self._timemanager)
		
	def _loadGui(self, type, guifile, imports):
		"""
		_loadGui Function
		Loads a pychan GUI file to one of the four GUI slots, then loads a python package to run to initilise the gui
		
		Keyword Arguments
		type - String, the type of GUI being loaded
		guifile - String, name of the pychan file being loaded
		imports - Boolean
		"""
		if type == 'MAIN':
			self._mainmenu = menuhandler.MenuHandler(guifile, self)
		elif type == 'HUD':
			self._hud = hudhandler.HUDHandler(guifile, self)
		elif type == 'SETTINGS':
			self._settingsmenu = settingshandler.SettingsHandler(guifile, self)
		elif type == 'ABOUT':
			self._aboutmenu = abouthandler.AboutHandler(guifile, self)
		elif type == 'PAUSE':
			self._pause = pychan.loadXML('gui/' + guifile + '.xml')
			if imports:
				guiinit = __import__('scripts.gui.' + guifile)
				guiinit.run()
		elif type == 'LOAD':
			self._loadingmenu = pychan.loadXML('gui/' + guifile + '.xml')
			if imports:
				guiinit = __import__('scripts.gui.' + guifile)
				guiinit.run()
		else:
			pass
	
	def _hideAllGuis(self):
		"""
		_hideAllGuis Function
		Hides any active GUI elements
		"""
		if self._hud != None:
			self._hud.hide()
		if self._mainmenu != None:
			self._mainmenu.hide()
		if self._pausemenu != None:
			self._pausemenu.hide()
		if self._loadingmenu != None:
			self._loadingmenu.hide()
		if self._settingsmenu != None:
			self._settingsmenu.hide()
		if self._aboutmenu != None:
			self._aboutmenu.hide()

	def _loadLevelMapCallback(self, action, percentdone):
		"""
		_loadLevelMapCallback Function
		Acts as a callback for level loading.
		
		Keyword Arguments
		action - String, what has just been loaded
		percentdone - Float, percentage loaded
		"""
		# You have to pump the engine, else it doesn't render anything
		# until the map has loaded
		self._engine.pump()
		
		# If it's loaded, hide the loading screen and load the HUD
		if percentdone == 1:
			self._hideAllGuis()
		# Otherwise set the loading screens percentage label
		else:
			loaded = self._loadingmenu.findChild(name="loading")
			loaded.text = str(math.floor(percentdone * 100)) + u'% Loaded'			
	
	def _loadMenuMapCallback(self, action, percentdone):
		"""
		_loadMenuMapCallback Function
		Acts as a callback for level loading.
		
		Keyword Arguments
		action - String, what has just been loaded
		percentdone - Float, percentage loaded
		"""
		# You have to pump the engine, else it doesn't render anything
		# until the map has loaded
		self._engine.pump()
		
		# If it's loaded, hide the loading screen and load the menu
		if percentdone == 1:
			self._hideAllGuis()
			if self._mainmenu != None:
				self._mainmenu.show()
		# Otherwise set the loading screens percentage label
		else:
			loaded = self._loadingmenu.findChild(name="loading")
			loaded.text = str(math.floor(percentdone * 100)) + u'% Loaded'

	def _loadMap(self, filename, purpose, port=False, location=None, direction=None):
		"""
		_loadMap Function
		Deletes the old map and loads a new one. Also initilises cameras.
		
		Keyword Arguments
		filename - String, path to the map file
		purpose - String, LEVEL or MENU
		"""
		self._model.deleteMap(self._map)
		self._map = None
		self._npcs = {}
		self._npclist = False
		self._mapsettings = SimpleXMLSerializer(filename=filename +".config")
		self._eventtracker = None
		
		
		if purpose == 'LEVEL':
			# Hide any active GUIs
			self._hideAllGuis()
			
			# Pump the engine to force it to move to a new frame
			self._engine.pump()
			
			# If the loading menu is loaded, show it
			if self._loadingmenu != None:
				self._loadingmenu.show()
				loadwindow = self._loadingmenu.findChild(name="loadwindow")
				autoposition.placeWidget(loadwindow, 'automatic')
			
			# Load the map
			self._map = loadMapFile(filename, self._engine, self._loadLevelMapCallback)
			
		elif purpose == 'MENU':
			# Hide any active GUIs
			self._hideAllGuis()
			
			# Pump the engine to force it to move to a new frame
			self._engine.pump()
			
			# If the loading menu is loaded, show it
			if self._loadingmenu != None:
				self._loadingmenu.show()
				loadwindow = self._loadingmenu.findChild(name="loadwindow")
				autoposition.placeWidget(loadwindow, 'automatic')
				
			# Load the map
			self._map = loadMapFile(filename, self._engine, self._loadMenuMapCallback)
		
		# Start (or clear) the camera array
		self._cameras = {}
		
		# For each camera in the map
		for cam in self._map.getCameras():
			# Get the camera ID
			camera_id = cam.getId()
			# Add the camera with that ID to the array
			self._cameras[camera_id] = cam
			# Reset the camera
			cam.resetRenderers()
			
		if purpose == 'LEVEL':
			# Start the player character
			self._startPlayerActor()
			if location != None:
				self._player._agent.setLocation(location)
			if direction != None:
				self._player._agent.setFacingLocation(direction)
			if self._hud != None:
				self._hud.show()
			
			self._loadLevelMapCallback("", 0.775)
		
		# Start the floating text renderer
		renderer = fife.FloatingTextRenderer.getInstance(self._cameras['main'])
		textfont = self._engine.getGuiManager().createFont('fonts/rpgfont.png', 0, str(self._setting.get("FIFE", "FontGlyphs")))
		renderer.changeDefaultFont(textfont)
		renderer.setDefaultBackground(0,0,0,0)
		renderer.setDefaultBorder(0,0,0,0)
		renderer.activateAllLayers(self._map)
		renderer.setEnabled(True)
		
		if purpose == 'LEVEL':
			self._loadLevelMapCallback("", 0.8)
		else:
			self._loadMenuMapCallback("", 0.8)
	
		if self._mapsettings.get("map", "usewaypoints", False):
			self._waypoints = self._mapsettings._deserializeList(self._mapsettings.get("map", "waypoints", ""))
		else:
			self._waypoints = None

		if purpose == 'LEVEL':
			self._loadLevelMapCallback("", 0.825)
		else:
			self._loadMenuMapCallback("", 0.825)
		
		if self._mapsettings.get("map", "useobjects", False):
			self._objects = objectmanager.ObjectManager(self)
			objlist = self._mapsettings._deserializeList(self._mapsettings.get("map", "objectlist", False))
			for file in objlist:
				self._objects._loadObjects(file)
		
		if purpose == 'LEVEL':
			self._loadLevelMapCallback("", 0.85)
		else:
			self._loadMenuMapCallback("", 0.85)
		
		if self._mapsettings.get("map", "dynamicnpcs", False):
			self._npclist = self._mapsettings._deserializeDict(self._mapsettings.get("map", "npclist", False))
			if self._npclist != False:
				for id, name in self._npclist.iteritems():
					self._npcs[name] = npc.NPC(self._setting, self._model, id, self._map.getLayer('player'), self, True, name)
		
		if purpose == 'LEVEL':
			self._loadLevelMapCallback("", 0.9)
		else:
			self._loadMenuMapCallback("", 0.9)
		
		self._eventtracker = eventtracker.EventTracker(self._engine, self._model, self._sounds, self)
		if self._mapsettings.get("map", "useevents", False):
			eventlist = self._mapsettings._deserializeList(self._mapsettings.get("map", "eventslist", ""))
			for file in eventlist:
				self._eventtracker._addEvent(file)
				
		if purpose == 'LEVEL':
			self._loadLevelMapCallback("", 0.95)
		else:
			self._loadMenuMapCallback("", 0.95)
			
		self._drift = {}
		self._drift = self._mapsettings._deserializeDict(self._mapsettings.get("map", "drift", "use : False"))
		if self._drift["use"] == "True":
			self._drift["use"] = True
			self._drift["x"] = float(self._drift["x"])
			self._drift["y"] = float(self._drift["y"])

			start = self._drift["start"].partition(",")
			loc = fife.Location(self._map.getLayer('player'))
			loc.setExactLayerCoordinates(fife.ExactModelCoordinate(float(start[0]), float(start[2])))
			self._cameras['main'].setLocation(loc)
		else:
			self._drift["use"] = False
		
		self._gamestate = purpose
			
	def _getLocationAt(self, clickpoint, layer):
		"""
		Query the main camera for the Map location (on the agent layer)
		that a screen point refers to.
		"""
		target_mapcoord = self._cameras['main'].toMapCoordinates(clickpoint, False)
		target_mapcoord.z = 0
		location = fife.Location(layer)
		location.setMapCoordinates(target_mapcoord)
		return location
	
	def _getInstancesAt(self, clickpoint, layer):
		"""
		Query the main camera for instances on a given layer.
		"""
		return self._cameras['main'].getMatchingInstances(clickpoint, layer)
			
	def mousePressed(self, evt):
		if evt.isConsumedByWidgets() or self._gamestate != 'LEVEL':
			return
		clickpoint = fife.ScreenPoint(evt.getX(), evt.getY())
		playerinstance = self._getInstancesAt(clickpoint, self._map.getLayer('player'))
		playerinstance = playerinstance + self._getInstancesAt(clickpoint, self._map.getLayer('waypoints'))
		if (evt.getButton() == fife.MouseEvent.LEFT):
			self._player.run(self._getLocationAt(clickpoint, self._map.getLayer('player')))
			self._contextmenu._hide()
		elif (evt.getButton() == fife.MouseEvent.RIGHT):
			self._contextmenu._show(playerinstance, clickpoint, self)
		evt.consume()
			
	def mouseMoved(self, evt, ext=False, cursor=None):
		self._mouseMoved = True
		if self._map == None or self._gamestate != 'LEVEL':
			return
		
		renderer = fife.InstanceRenderer.getInstance(self._cameras['main'])
		renderer.removeAllOutlines()
	
		if ext:
			pt = fife.ScreenPoint(cursor.getX(), cursor.getY())
		else:
			pt = fife.ScreenPoint(evt.getX(), evt.getY())
		instances = self._getInstancesAt(pt, self._map.getLayer('player'))
		instances = instances + self._getInstancesAt(pt, self._map.getLayer('waypoints'))
		for i in instances:
			for name, object in self._objects._objects.iteritems():
				if i.getId() == name:
					renderer.addOutlined(i, random.randint(20,255), random.randint(20,255), random.randint(20,255), 1)
			for name, object in self._npcs.iteritems():
				if i.getId() == object._agentName:
					renderer.addOutlined(i, random.randint(20,255), random.randint(20,255), random.randint(20,255), 1)

	def _keyPressed(self, evt):
		keyval = evt.getKey().getValue()
		keystr = evt.getKey().getAsString().lower()

	def _startPlayerActor(self):
		self._player = Player(self._setting, self._model, "actor-pc", self._map.getLayer('player'))
		self._cameras['main'].setLocation(self._player._agent.getLocation())
		self._cameras['main'].attach(self._map.getLayer('player').getInstance("actor-pc"))
		if self._cameras['main'].getAttached() == None:
	
	def cameraDrift(self):
		if self._drift["use"]:
			oldloc = self._cameras['main'].getLocation().getExactLayerCoordinates()
			border = self._drift["end"].partition(",")
			if oldloc.x < float(border[0]):
				self._drift["x"] = (self._drift["x"] + random.randint(-1, 1) * 0.025) * -1
			if oldloc.y < float(border[2]):
				self._drift["y"] = (self._drift["y"] + random.randint(-1, 1) * 0.025) * -1
			border2 = self._drift["start"].partition(",")
			if oldloc.x > float(border2[0]):
				self._drift["x"] = (self._drift["x"] + random.randint(-1, 1) * 0.025) * -1
			if oldloc.y > float(border2[2]):
				self._drift["y"] = (self._drift["y"] + random.randint(-1, 1) * 0.025) * -1
			delta = self._timemanager.getTimeDelta() / 100.0
			loc = fife.Location(self._map.getLayer('player'))
			deltax = round(oldloc.x + self._drift["x"] * delta, 2)
			deltay = round(oldloc.y + self._drift["y"] * delta, 2)
			loc.setExactLayerCoordinates(fife.ExactModelCoordinate(deltax, deltay))
			self._cameras['main'].setLocation(loc)