Exemple #1
0
class GroundManager:
	def __init__(self, gm):
		self.gm = gm # GameManager, from game.py
		self.playerData = self.gm.playerData
		self.gui = GroundGui(self.playerData)
		
		skyName = "hipshot1"
		self.sky = SkyBox()
		self.sky.load(skyName)
		#self.sky.set(skyName)
		self.currentSkyName = skyName
		#self.sky.clear()
		
		self.bgMusic = groundBgMusic["hesperida_shop"]
		self.bgMusic.setVolume(0.3)
		self.bgMusic.setLoop(True)
		
	def start(self):
		self.bgMusic.setVolume(0.3)
		self.bgMusic.play()
		self.show()
	
	def stop(self):
		#self.bgMusic.stop()
		taskMgr.add(self.fadeMusicTask, "fadeMusicTask")
		self.sky.clear()
		self.hide()
	
	def show(self):
		self.gui.show()
		self.sky.set(self.currentSkyName)
		
	def hide(self):
		self.gui.hide()
		
	def destroy(self):
		self.stop()
		self.gui.destroy()
		
	def fadeMusicTask(self, task):
		dt = globalClock.getDt()
		vol = self.bgMusic.getVolume()
		self.bgMusic.setVolume(vol - dt/2.0)
		if vol <= 0.02:
			self.bgMusic.stop()
			#print "Stopping music, sinve vol at %s" % (vol)
			return Task.done
		#print "Fading out music, volume at %s" % (vol)
		return Task.cont
Exemple #2
0
class Map:
	def __init__(self, filename = None):
		self.name = None
		self.filename = filename
		
		self.x = 0
		self.y = 0
		
		self.NPCroot = NodePath("NPCroot")
		self.NPCroot.reparentTo(render)
		
		self.mapObjectRoot = NodePath("mapObjectRoot")
		self.mapObjectRoot.reparentTo(render)
		#self.mapObjectRoot.setTransparency(True)
		#self.mapObjectRoot.setTransparency(TransparencyAttrib.MAlpha)
		self.mapObjects = {} # map objects
		self.walls = [] # dynamic walls, see WallBuilder in wallBuilder.py
		self.innerWall = None
		self.water = None
		
		self.creatureRoot = NodePath("creatureRoot")
		self.creatureRoot.reparentTo(render)
		
		self.collisionGrid = None
		self.sky = None
		self.bgMusic = None
		self.bgSound = None
		
		if self.filename is not None:
			self.load()
	
	def getAvailableName(self, genre):
		i = 1
		tmpName = genre + "_" + str(i)
		while tmpName in self.mapObjects:
			i = i+1
			tmpName = genre + "_" + str(i)
		return tmpName
		
	def collisionHide(self):
		self.collisionGrid.collisionHide()
		
	def collisionShow(self):
		self.collisionGrid.collisionShow()
	
	def setSize(self, x, y):
		self.x = int(x)
		self.y = int(y)
		self.collisionGrid.setSize(x, y)
		
	def save(self, filename):
		mapData = {}
		mapData["name"] = self.name
		mapData["X"] = self.x
		mapData["Y"] = self.y
		mapData["collision"] = self.collisionGrid.data
		mapData["groundTex"] = self.groundTex
		print "Map saving : groundTex = %s" % (self.groundTex)
		mapData["groundTexScale"] = self.groundTexScale
		
		if self.collisionGrid.hasGeoMip:
			mapData["mipImg"] = [self.collisionGrid.texPath, self.collisionGrid.geoMipPath]
			
		mapData["mapObjects"] = []
		for elem in self.mapObjects.values():
			mapData["mapObjects"].append(elem.getSaveData())
			
		mapData["walls"] = []
		for wall in self.walls:
			mapData["walls"].append(wall.getSaveData())
		
		if self.innerWall:
			mapData["innerWall"] = self.innerWall.getSaveData()
		
		if self.water:
			mapData["water"] = True
		
		if self.sky:
			mapData["skybox"] = self.sky.name
		
		if self.bgMusic:
			mapData["music"] = self.music
		if self.bgSound:
			mapData["ambientSound"] = self.ambientSound
		
		f = open(filename, 'w')
		pickle.dump(mapData, f)
		f.close()
		print "map data saved as %s" % (filename)
		
	def clearWalls(self):
		for wall in self.walls:
			wall.destroy()
		self.walls = []
		
	def clearInnerWall(self):
		if self.innerWall:
			self.innerWall.destroy()
			self.innerWall = None
		
	def setGroundTexture(self, texPath):
		if self.collisionGrid.ground:
			self.collisionGrid.ground.setTexture(texPath)
			self.groundTex = texPath
			
	def destroy(self):
		#print "Map : Map %s destroyed" % (self.name)
		if self.innerWall:
			self.innerWall.destroy()
			
		if self.collisionGrid:
			self.collisionGrid.destroy()
			del self.collisionGrid
			#print "Map : collisionGrid destroyed"
		for mapObj in self.mapObjects.values():
			self.removeMapObject(mapObj.name)
		#if self.ground:
		#	self.ground.destroy()
			
		if self.sky:
			self.sky.destroy()
		
		self.clearWalls()
		self.clearInnerWall()
		if self.water:
			self.water.destroy()
		#for wall in self.walls:
		#	wall.destroy()
		
	def load(self, filename=None):
		if filename is None:
			filename = self.filename
		if filename is None:
			return False
		#self.destroy()
		
		f = open(filename, 'r')
		mapData = pickle.load(f)
		f.close()
		
		if "name" in mapData:
			self.name = mapData["name"]
			print "Map : Loading map named %s" % (self.name)
		if "X" in mapData:
			self.x = mapData["X"]	
		if "Y" in mapData:
			self.y = mapData["Y"]
		
		if "groundTex" in mapData:
			self.groundTex = mapData["groundTex"]
		else:
			self.groundTex = "img/textures/ice01.jpg"
			
		if "groundTexScale" in mapData:
			self.groundTexScale = mapData["groundTexScale"]
		else:
			self.groundTexScale = 50.0
			
		if "mipImg" in mapData:
			#tex = mapData["geomip"][0]
			#geomipTex = mapData["geomip"][1]
			#print "Map : Creating mipmap collision grid on Map load"
			self.mipImg = mapData["mipImg"]
			self.collisionGrid = CollisionGrid(self, self.name, self.groundTex, self.mipImg, self.groundTexScale)
		else:
			#print "Map : Creating flat collision grid on Map load"
			self.collisionGrid = CollisionGrid(self, self.name, self.groundTex, None, self.groundTexScale)
			
		#if not self.collisionGrid:
		#	print "Map : WARNING : collision grid should be there"
		
		if "walls" in mapData:
			for wallData in mapData["walls"]:
				wall = WallBuilder(wallData[0], wallData[1], wallData[2], wallData[3])
				self.walls.append(wall)
		
		if "innerWall" in mapData:
			self.innerWall = InnerWall(self, mapData["innerWall"][0], mapData["innerWall"][1],mapData["innerWall"][2])
		else:
			self.innerWall = None
		
		if "water" in mapData:
			self.water = WaterPlane(-20, -20, self.x+20, self.y+20)
			
		if "skybox" in mapData:
			self.setSky(mapData["skybox"])
			#name = mapData["skybox"]
			#self.sky = SkyBox()
			#self.sky.load(name)
			#self.sky.set(name)
		else:
			self.sky = None
		
		if "music" in mapData:
			self.setBgMusic(mapData["music"])
			#self.music = mapData["music"]
			#self.bgMusic = loader.loadSfx(self.music)
			#self.bgMusic.setLoop(True)
		
		if "ambientSound" in mapData:
			self.setBgSound(mapData["ambientSound"])
			#self.ambientSound = mapData["ambientSound"]
			#self.bgSound = loader.loadSfx(self.ambientSound)
			#self.bgSound.setLoop(True)
			
		else:
			self.ambientSound = None
			self.bgSound = None
			
		self.collisionGrid.data = mapData["collision"]
		self.collisionGrid.rebuild()
		
		#print "models in use : %s" % (mapData["mapObjects"])
		for data in mapData["mapObjects"]:
			name = data[0]
			genre = data[1]
			pos = data[2]
			hpr = data[3]
			scale = data[4]
			self.addMapObject(
				genre,
				name,
				pos,
				hpr,
				scale
				#(pos.getX(), pos.getY(), pos.getZ()),
				#(hpr.getX(), hpr.getY(), hpr.getZ()),
				#(scale.getX(), scale.getY(), scale.getZ())
				)
		
		#self.rock = RockWallBuilder(self.mapObjectRoot, [Point3(0,0,0), Point3(self.x, 0,0), Point3(self.x, self.y,0), Point3(0,self.y,0), Point3(0,0,0)])
		#self.rock = ModelWallBuilder(self.mapObjectRoot, "models/props/rock1", ["img/textures/block01c.jpg", "img/textures/block01d.jpg"], 1.0, 1.5, 4.0, 180.0, [Point3(0,0,0), Point3(self.x, 0,0), Point3(self.x, self.y,0), Point3(0,self.y,0), Point3(0,0,0)])
		#self.rock.removeLastPoint()
		
	def setBgMusic(self, musicPath):
		#if self.bgMusic:
		#	self.bgMusic.stop()
		self.music = musicPath
		self.bgMusic = loader.loadSfx(self.music)
		self.bgMusic.setLoop(True)
		
	def setBgSound(self, soundPath):
		#if self.bgSound:
		#	self.bgSound.stop()
		self.ambientSound = soundPath
		self.bgSound = loader.loadSfx(self.ambientSound)
		self.bgSound.setLoop(True)
	
	def setSky(self, skyName):
		if self.sky:
			self.sky.destroy()
		self.sky = SkyBox()
		self.sky.load(skyName)
		self.sky.set(skyName)
		
	def addMapObject(self, genre, name, pos=(0,0,0), hpr=(0,0,0), scale=(1,1,1)):
		if name not in self.mapObjects:
			mapObject = MapObject(self, genre, name)
			mapObject.setPos(pos) #-self.collisionGrid.terrainScale/3.0)
			#print "Map add object : new object %s at position %s" % (name, mapObject.getPos())
			mapObject.setHpr(hpr)
			mapObject.setScale(scale)
			mapObject.reparentTo(self.mapObjectRoot)
			self.mapObjects[name] = mapObject
			#print "-> position is : %s" % (mapObject.getPos())
		
	def removeMapObject(self, name):
		if name in self.mapObjects:
			self.mapObjects[name].destroy()
			del self.mapObjects[name]
			
	def clearCollision(self, args=[]):
		print "Map %s : clear collision called" % (str(self))
		self.collisionGrid.clear()
		
	def fillCollision(self, args=[]):
		print "Map %s : fill collision called" % (str(self))
		self.collisionGrid.fill()
	
	def getClosestOpenTile(self, x, y):
		return self.collisionGrid.getClosestOpenTile(x,y)
class SpaceOdeWorldManager(DirectObject):
    def __init__(self, gamemanager):
        # GameManager, from game.py
        self.gm = gamemanager

        # ODE base setup
        self.world = makeWorld()
        self.space = OdeSimpleSpace()
        self.space.setAutoCollideWorld(self.world)
        self.space.setCollisionEvent("ode-collision")
        self.accept("ode-collision", self.onCollision)
        self.contactGroup = OdeJointGroup()
        self.space.setAutoCollideJointGroup(self.contactGroup)

        #---------------------------------------------------------------
        # space objects lists and dics
        #---------------------------------------------------------------
        self.shipList = []
        self.shipDic = {}

        self.laserList = []
        self.laserDic = {}

        self.lootList = []
        self.lootDic = {}

        self.baseList = []
        self.baseDic = {}

        #---------------------------------------------------------------
        self.dtCumul = 0.0
        self.stepSize = 1.0 / 75.0

        #---------------------------------------------------------------
        # crosshair stuff, to aim guns and click on 3D objects with the mouse.
        # This same crosshair is used when on the ground for GUI too, for now.
        #---------------------------------------------------------------

        self.gm.crosshair.setMode(1)
        self.currentTargetDest = None
        self.currentTargetNP = None

        self.picker = OdePicker(self)

        #-------------------------------------------------------------------
        # GUI
        #-------------------------------------------------------------------
        self.gui = SpaceGui(self.gm.playerData)

        #---------------------------------------------------------------
        # input handling
        self.keyMap = {}
        self.acceptAll()
        #---------------------------------------------------------------
        # some loot
        for i in range(10):
            cube = Cube(self, 5)
            #cube = Sphere(self, 5)
            cube.setPos((i * 0.02, i * 0.02, 5.5 * i + 2.51))
            name = "Cube " + str(i)
            cube.name = name
            self.lootList.append(cube)
            self.lootDic[cube.geom.getId()] = cube

        #---------------------------------------------------------------
        # player ship
        self.ship = Ship(self, self.gm.playerData.ship)
        self.ship.setPos((0, -20, 12.51))

        #---------------------------------------------------------------
        # bases
        self.addBase("hesperida")

        #---------------------------------------------------------------
        # camera
        self.mode = "manual"
        self.camHandler = SpaceCamManager(self)
        self.camHandler.update()

        #---------------------------------------------------------------
        # radar
        self.radar = OdeRadar(self)

        #---------------------------------------------------------------
        # light
        self.light = LightManager()
        self.light.lightCenter.reparentTo(self.ship.model)

        #---------------------------------------------------------------
        # stardust cloud surrounding the player ship
        #self.PE = ParticleEngine(self.ship.model.getPos(), nb=100, ray=100, move = True)
        self.PE = ParticleEngine(self.ship.model, nb=40, ray=50, move=True)
        self.PE.stop()

        #---------------------------------------------------------------
        # trail of the player ship, TODO : move that to the OdeShip class and update ShipData to handle it
        self.trailPE = AriTrail(self.ship.model, 20, 0.0)
        #self.trailPE2 = AriTrail(self.gun2,10,0.0)

        #skyName = "skyBox06"
        skyName = "purple0"
        self.sky = SkyBox()
        self.sky.load(skyName)
        self.sky.set(skyName)
        self.currentSkyName = skyName
        self.sky.stop()
        #self.sky.currentModel.hide(BitMask32.bit(1))

        # BG music
        self.bgMusic = spaceBgMusic["hesperida_space"]

        self.NPCTimer = 0.0

        #self.accept("t", self.step)
        #self.start()
        self.task = None

        self.stop()

    def acceptAll(self):
        self.accept("ode-collision", self.onCollision)

        for key in ("a", "z", "e", "q", "s", "d", "w", "c", "r", "arrow_up",
                    "arrow_down", "mouse1", "mouse3"):
            self.keyMap[key] = 0
            self.accept(key, self.setKey, [key, 1])
            keyup = key + "-up"
            self.accept(keyup, self.setKey, [key, 0])

        self.accept("space", self.toggleMode)
        self.accept("mouse1", self.selectClick)
        self.accept("p", self.spawnShip)

        self.accept("arrow_up", self.updateSize, [0.0, 0.1])
        self.accept("arrow_down", self.updateSize, [0.0, -0.1])
        self.accept("arrow_left", self.updateSize, [-0.1, 0.0])
        self.accept("arrow_right", self.updateSize, [0.1, 0.0])

    def updateSize(self, x, y):
        self.gui.label1.updateSize(x, y)
        self.gui.label2.updateSize(x, y)

    def start(self):
        #print "Starting the space world."
        self.acceptAll()
        self.task = taskMgr.doMethodLater(1.5, self.worldTask,
                                          "spaceWorldTask")
        self.sky.set(self.currentSkyName)
        self.PE.start()
        self.showAll()
        self.radar.hide()
        self.bgMusic.play()
        #print "Le root de audio3d c'est %s" % (audio3d.root)
        taskMgr.doMethodLater(1.5, self.start3DAudio, "start3DAudio")

    def start3DAudio(self, task):
        #audio3d.attachListener(camera)
        audio3d.__init__(base.sfxManagerList[0], camera)
        #taskMgr.add(audio3d.update, "Audio3DManager-updateTask", 51)
        #print "restarted 3D audio!"
        return Task.done

    def stop(self):
        #print "Stopping the space world."

        #audio3d.detachSound()
        '''
		for sound in laserSounds:
			audio3d.detachSound(laserSounds[sound])
		audio3d.detachListener()
		'''
        audio3d.disable()
        #print "disabled 3D audio!"

        if self.task:
            #print "really stopped the world"
            taskMgr.remove(self.task)
            self.sky.stop()
            self.PE.stop()
            self.task = None
        #else:
        #print "Found no world running to stop though..."

        self.hideAll()
        self.ignoreAll()  # inherited from DirectObject
        self.gm.crosshair.setMode(1)
        self.bgMusic.stop()

    def hideAll(self):
        for id in self.shipDic.keys():
            self.shipDic[id].hide()
        for id in self.lootDic.keys():
            self.lootDic[id].hide()
        for id in self.laserDic.keys():
            self.laserDic[id].hide()
        for id in self.baseDic.keys():
            self.baseDic[id].hide()

        self.ship.model.hide()
        self.radar.hide()
        #self.msgSpeed.hide()
        self.PE.stop()
        self.trailPE.stop()
        self.gui.hide()

    def showAll(self):
        for id in self.shipDic.keys():
            self.shipDic[id].show()
        for id in self.lootDic.keys():
            self.lootDic[id].show()
        for id in self.laserDic.keys():
            self.laserDic[id].show()
        for id in self.baseDic.keys():
            self.baseDic[id].show()

        self.ship.model.show()
        self.radar.show()
        #self.msgSpeed.show()
        self.PE.start()
        self.trailPE.start()
        self.gui.show()

    def destroy(self):
        self.stop()

        self.sky.clear()

        for id in self.shipDic.keys():
            self.destroyShip(id)

        for id in self.lootDic.keys():
            #print "Destroying ", self.lootDic[id].name
            self.destroyLoot(id)

        for id in self.laserDic.keys():
            self.destroyLaser(id)

        for id in self.baseDic.keys():
            self.destroyBase(id)

        self.gui.destroy()
        self.radar.destroy()
        self.ship.destroy()
        self.light.destroy()

    def setKey(self, k, v):
        self.keyMap[k] = v

    def onCollision(self, entry):
        geom1 = entry.getGeom1()
        geom2 = entry.getGeom2()
        body1 = entry.getBody1()
        body2 = entry.getBody2()

        # Must have hit someone
        #print "World, ", geom1, geom2, body1, body2
        id1 = geom1.getId()
        id2 = geom2.getId()

        contactPoint = entry.getContactPoints()[0]

        if ((id1 in self.lootDic) and (id2 in self.laserDic)):
            #print "Collision cube / laser!!! l'oeuf tombe sur la pierre!"
            #exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
            #audio3d.attachSoundToObject(exploSound1, self.lootDic[id1].model)
            audio3d.attachSoundToObject(exploSound1, self.laserDic[id2].model)
            exploSound1.play()
            self.destroyLaser(id2)

        elif ((id2 in self.lootDic) and (id1 in self.laserDic)):
            #print "Collision laser / cube!!! This is gonna hurt!"
            #exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
            #audio3d.attachSoundToObject(exploSound1, self.lootDic[id2].model)
            audio3d.attachSoundToObject(exploSound1, self.laserDic[id1].model)
            exploSound1.play()
            self.destroyLaser(id1)

        elif ((id1 in self.shipDic) and (id2 in self.laserDic)):
            #print "Collision ship / laser!"
            #exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
            #audio3d.attachSoundToObject(exploSound1, self.shipDic[id1].model)
            audio3d.attachSoundToObject(exploSound1, self.laserDic[id2].model)
            exploSound1.play()
            coqueDmg = self.laserDic[id2].gunData.coqueDmg
            shieldDmg = self.laserDic[id2].gunData.shieldDmg
            self.shipDic[id1].data.remShieldHP(shieldDmg)
            if self.shipDic[id1].data.shieldHP <= 0.0:
                self.shipDic[id1].data.remCoqueHP(coqueDmg)
            self.destroyLaser(id2)

        elif ((id2 in self.shipDic) and (id1 in self.laserDic)):
            #print "Collision laser / ship!"
            #exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
            #audio3d.attachSoundToObject(exploSound1, self.shipDic[id2].model)
            audio3d.attachSoundToObject(exploSound1, self.laserDic[id1].model)
            exploSound1.play()
            coqueDmg = self.laserDic[id1].gunData.coqueDmg
            shieldDmg = self.laserDic[id1].gunData.shieldDmg
            self.shipDic[id2].data.remShieldHP(shieldDmg)
            if self.shipDic[id2].data.shieldHP <= 0.0:
                self.shipDic[id2].data.remCoqueHP(coqueDmg)
            self.destroyLaser(id1)

    def selectClick(self):
        if self.picker.targetGeomId != None:
            #print "Selecting geom"
            if self.picker.targetGeomId in self.shipDic:
                self.radar.setTarget(
                    self.picker.targetGeomId,
                    self.shipDic[self.picker.targetGeomId].model,
                    self.shipDic[self.picker.targetGeomId].name, "ship")

            elif self.picker.targetGeomId in self.lootDic:
                self.radar.setTarget(
                    self.picker.targetGeomId,
                    self.lootDic[self.picker.targetGeomId].model,
                    self.lootDic[self.picker.targetGeomId].name, "loot")

            elif self.picker.targetGeomId in self.baseDic:
                self.radar.setTarget(
                    self.picker.targetGeomId,
                    self.baseDic[self.picker.targetGeomId].model,
                    self.baseDic[self.picker.targetGeomId].name, "base")

        self.shoot()

    def shoot(self, dt=1.0 / 75.0):
        targetPos = self.picker.crosshairModel.getPos(render)
        for loot in self.lootList:
            direction = targetPos - loot.model.getPos()
            loot.body.addForce(direction)
        for ship in self.shipList:
            ship.steerToPoint(targetPos, dt)
            ship.shootLasers(targetPos)

    def shoot2(self):
        targetPos = self.picker.crosshairModel.getPos(render)
        for loot in self.lootList:
            direction = -targetPos + loot.model.getPos()
            loot.body.addForce(direction * 10)

    #-------------------------------------------------------------------
    # base handling
    #-------------------------------------------------------------------
    def addBase(self, name):
        if name in spaceBaseDb:
            spacebase = OdeBase(self, name)
            spacebaseId = spacebase.getId()
            self.baseList.append(spacebase)
            self.baseDic[spacebaseId] = spacebase

    def destroyBase(self, id):
        self.baseDic[id].destroy()
        self.baseList.remove(self.baseDic[id])
        del self.baseDic[id]

    #-------------------------------------------------------------------
    # laser handling
    #-------------------------------------------------------------------
    def shootLaser(self, originPos, targetPos, shipSpeed, gunData):
        #laser = Laser(self, originPos, targetPos, speed, shipSpeed, lifeTime)
        laser = Laser(self, originPos, targetPos, shipSpeed, gunData)
        laser.model.show(BitMask32.bit(1))
        self.laserList.append(laser)
        self.laserDic[laser.getId()] = laser
        #laserSounds["slimeball"].play() # deprecated, laser now plays its own sound on init

    def updateLasers(self, dt):
        for laser in self.laserList:
            laser.update(dt)
            if not laser.alive:
                self.laserList.remove(laser)
                del self.laserDic[laser.getId()]
                del laser

    def destroyLaser(self, id):
        audio3d.detachSound(exploSound1)
        self.laserDic[id].destroy()
        self.laserList.remove(self.laserDic[id])
        del self.laserDic[id]

    #-------------------------------------------------------------------
    # loot handling
    #-------------------------------------------------------------------
    def updateLoot(self, dt):
        for loot in self.lootList:
            loot.update(dt)

    def destroyLoot(self, geomId):
        self.lootList.remove(self.lootDic[geomId])
        self.lootDic[geomId].destroy()
        del self.lootDic[geomId]

    #-------------------------------------------------------------------
    # ship handling
    #-------------------------------------------------------------------
    def spawnShip(self):
        NPCShip = Ship(self, shipDb["npc"].makeCopy())
        NPCShip.geom.setCollideBits(odeBitMask["npc"])
        NPCShip.geom.setCategoryBits(odeBitMask["npc"])

        #shipModels["sabreNew"].instanceTo(NPCShip.model)
        NPCShip.setPos((-8, 15, 45))
        #NPCShip.data.setGun(0, gunDb["laser1"])
        #NPCShip.data.setGun(1, gunDb["laser3"])
        #NPCShip.initGuns() # already called in Ship.__init__, but called again here to update the equipped guns

        self.shipList.append(NPCShip)
        self.shipDic[NPCShip.getId()] = NPCShip
        #print "Adding ship, we now have %s ships in space" % (len(self.shipList))

    def updateShips(self, dt):
        for ship in self.shipList:
            ship.update(dt)
            if ship.alive is False:
                id = ship.getId()
                if ship.model is self.radar.targetNP:
                    self.radar.clearTarget()
                self.destroyShip(id)
                print "Ship destroyed"

    def destroyShip(self, geomId):
        self.shipDic[geomId].destroy()
        self.shipList.remove(self.shipDic[geomId])
        #self.shipDic[geomId].destroy()
        del self.shipDic[geomId]
        #print "Destroyed ship, we now have %s ships in space" % (len(self.shipList))

    def setMode(self, mode):
        self.mode = str(mode)
        self.camHandler.mode = self.mode
        #if self.mode == "manual" or self.mode == "auto":
        #	self.camCube.body.setPosition(self.wm.ship.model.getPos()+(Point3(0,-20, 3)))

    def toggleMode(self):
        if self.mode == "auto":
            self.mode = "manual"
        elif self.mode == "manual":
            self.mode = "turret"
        else:
            self.mode = "auto"

        self.camHandler.mode = self.mode

    '''
	# this function is used if space.collide is used instead of autoCollide
	def handleCollisions(self, arg, geom1, geom2):
		entry = OdeUtil.collide(geom1, geom2)
		if entry.isEmpty():
			return
	'''

    #-------------------------------------------------------------------
    # World Task!
    #-------------------------------------------------------------------
    def worldTask(self, task):

        dt = globalClock.getDt()

        self.NPCTimer += dt

        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            dx = mpos.getX()
            dy = mpos.getY()
        else:
            mpos = None
            dx = 0
            dy = 0

        if mpos:
            self.picker.update(mpos)
        self.radar.update()

        #self.refireTimer += dt

        self.shipSpeed = self.ship.body.getLinearVel()
        self.currentSpeed = self.shipSpeed.length()
        self.PE.speed = self.currentSpeed
        #self.PE.draw(self.currentSpeed)

        dx = min(dx, 1.0)
        dx = max(dx, -1.0)

        dy = min(dy, 1.0)
        dy = max(dy, -1.0)

        if self.mode == "manual":
            self.ship.steer(dx, dy, dt * 100)
        elif self.mode == "auto":
            self.ship.steer(0, 0, dt * 100)
            #self.ship.setAngMotor3(-self.ship.model.getR()/20)
            self.ship.autoCorrectHpr()
        else:
            self.ship.setAngMotor1(0)
            self.ship.setAngMotor2(0)
            self.ship.setAngMotor3(0)

        # speed control
        if self.keyMap["z"]:
            self.ship.accelerate(dt)
            #self.ship.setLinMotor(self.ship.pushSpeed)
        elif self.keyMap["s"]:
            self.ship.decelerate(dt)
            #self.ship.setLinMotor(-self.ship.pushSpeed)
        else:
            self.ship.rest()

        # roll
        if self.keyMap["d"]:
            #self.ship.setAngMotor3(self.ship.steerRSpeed)
            self.ship.roll(self.ship.steerRMaxSpeed, dt * 100)
        elif self.keyMap["q"]:
            self.ship.roll(self.ship.steerRMaxSpeed, -dt * 100)
            #self.ship.setAngMotor3(-self.ship.steerRSpeed)
            #self.stopAngMotor3()
        else:
            if self.mode == "manual":
                self.ship.setAngMotor3(0)

        if self.keyMap["mouse3"]:
            self.ship.shootLasers(self.picker.crosshairModel.getPos())

        if self.keyMap["mouse1"]:
            self.shoot(dt)

        #self.space.collide("", self.handleCollisions)
        self.space.autoCollide()
        '''
		self.dtCumul += dt
		while self.dtCumul > self.stepSize:
			# Remove a stepSize from the accumulator until
			# the accumulated time is less than the stepsize
			self.dtCumul -= self.stepSize
			# Step the simulation
			self.world.quickStep(self.stepSize)
		'''
        self.world.quickStep(dt)

        self.contactGroup.empty()

        self.updateLoot(dt)
        self.updateLasers(dt)
        self.updateShips(dt)

        self.ship.update(dt)

        self.gui.laserHP.setVal(self.ship.data.gunHP)
        self.gui.shieldHP.setVal(self.ship.data.shieldHP)
        self.gui.coqueHP.setVal(self.ship.data.coqueHP)

        #---------------------------------------------------------------
        # speed message
        l = round(self.currentSpeed, 2)
        self.gui.setSpeed(l)

        #---------------------------------------------------------------
        # cam handling
        self.camHandler.update(dx, dy)

        return task.cont
Exemple #4
0
class Map:
    def __init__(self, filename=None):
        self.name = None
        self.filename = filename

        self.x = 0
        self.y = 0

        self.NPCroot = NodePath("NPCroot")
        self.NPCroot.reparentTo(render)

        self.mapObjectRoot = NodePath("mapObjectRoot")
        self.mapObjectRoot.reparentTo(render)
        #self.mapObjectRoot.setTransparency(True)
        #self.mapObjectRoot.setTransparency(TransparencyAttrib.MAlpha)
        self.mapObjects = {}  # map objects
        self.walls = []  # dynamic walls, see WallBuilder in wallBuilder.py
        self.innerWall = None
        self.water = None

        self.creatureRoot = NodePath("creatureRoot")
        self.creatureRoot.reparentTo(render)

        self.collisionGrid = None
        self.sky = None
        self.bgMusic = None
        self.bgSound = None

        if self.filename is not None:
            self.load()

    def getAvailableName(self, genre):
        i = 1
        tmpName = genre + "_" + str(i)
        while tmpName in self.mapObjects:
            i = i + 1
            tmpName = genre + "_" + str(i)
        return tmpName

    def collisionHide(self):
        self.collisionGrid.collisionHide()

    def collisionShow(self):
        self.collisionGrid.collisionShow()

    def setSize(self, x, y):
        self.x = int(x)
        self.y = int(y)
        self.collisionGrid.setSize(x, y)

    def save(self, filename):
        mapData = {}
        mapData["name"] = self.name
        mapData["X"] = self.x
        mapData["Y"] = self.y
        mapData["collision"] = self.collisionGrid.data
        mapData["groundTex"] = self.groundTex
        print "Map saving : groundTex = %s" % (self.groundTex)
        mapData["groundTexScale"] = self.groundTexScale

        if self.collisionGrid.hasGeoMip:
            mapData["mipImg"] = [
                self.collisionGrid.texPath, self.collisionGrid.geoMipPath
            ]

        mapData["mapObjects"] = []
        for elem in self.mapObjects.values():
            mapData["mapObjects"].append(elem.getSaveData())

        mapData["walls"] = []
        for wall in self.walls:
            mapData["walls"].append(wall.getSaveData())

        if self.innerWall:
            mapData["innerWall"] = self.innerWall.getSaveData()

        if self.water:
            mapData["water"] = True

        if self.sky:
            mapData["skybox"] = self.sky.name

        if self.bgMusic:
            mapData["music"] = self.music
        if self.bgSound:
            mapData["ambientSound"] = self.ambientSound

        f = open(filename, 'w')
        pickle.dump(mapData, f)
        f.close()
        print "map data saved as %s" % (filename)

    def clearWalls(self):
        for wall in self.walls:
            wall.destroy()
        self.walls = []

    def clearInnerWall(self):
        if self.innerWall:
            self.innerWall.destroy()
            self.innerWall = None

    def setGroundTexture(self, texPath):
        if self.collisionGrid.ground:
            self.collisionGrid.ground.setTexture(texPath)
            self.groundTex = texPath

    def destroy(self):
        #print "Map : Map %s destroyed" % (self.name)
        if self.innerWall:
            self.innerWall.destroy()

        if self.collisionGrid:
            self.collisionGrid.destroy()
            del self.collisionGrid
            #print "Map : collisionGrid destroyed"
        for mapObj in self.mapObjects.values():
            self.removeMapObject(mapObj.name)
        #if self.ground:
        #	self.ground.destroy()

        if self.sky:
            self.sky.destroy()

        self.clearWalls()
        self.clearInnerWall()
        if self.water:
            self.water.destroy()
        #for wall in self.walls:
        #	wall.destroy()

    def load(self, filename=None):
        if filename is None:
            filename = self.filename
        if filename is None:
            return False
        #self.destroy()

        f = open(filename, 'r')
        mapData = pickle.load(f)
        f.close()

        if "name" in mapData:
            self.name = mapData["name"]
            print "Map : Loading map named %s" % (self.name)
        if "X" in mapData:
            self.x = mapData["X"]
        if "Y" in mapData:
            self.y = mapData["Y"]

        if "groundTex" in mapData:
            self.groundTex = mapData["groundTex"]
        else:
            self.groundTex = "img/textures/ice01.jpg"

        if "groundTexScale" in mapData:
            self.groundTexScale = mapData["groundTexScale"]
        else:
            self.groundTexScale = 50.0

        if "mipImg" in mapData:
            #tex = mapData["geomip"][0]
            #geomipTex = mapData["geomip"][1]
            #print "Map : Creating mipmap collision grid on Map load"
            self.mipImg = mapData["mipImg"]
            self.collisionGrid = CollisionGrid(self, self.name, self.groundTex,
                                               self.mipImg,
                                               self.groundTexScale)
        else:
            #print "Map : Creating flat collision grid on Map load"
            self.collisionGrid = CollisionGrid(self, self.name, self.groundTex,
                                               None, self.groundTexScale)

        #if not self.collisionGrid:
        #	print "Map : WARNING : collision grid should be there"

        if "walls" in mapData:
            for wallData in mapData["walls"]:
                wall = WallBuilder(wallData[0], wallData[1], wallData[2],
                                   wallData[3])
                self.walls.append(wall)

        if "innerWall" in mapData:
            self.innerWall = InnerWall(self, mapData["innerWall"][0],
                                       mapData["innerWall"][1],
                                       mapData["innerWall"][2])
        else:
            self.innerWall = None

        if "water" in mapData:
            self.water = WaterPlane(-20, -20, self.x + 20, self.y + 20)

        if "skybox" in mapData:
            self.setSky(mapData["skybox"])
            #name = mapData["skybox"]
            #self.sky = SkyBox()
            #self.sky.load(name)
            #self.sky.set(name)
        else:
            self.sky = None

        if "music" in mapData:
            self.setBgMusic(mapData["music"])
            #self.music = mapData["music"]
            #self.bgMusic = loader.loadSfx(self.music)
            #self.bgMusic.setLoop(True)

        if "ambientSound" in mapData:
            self.setBgSound(mapData["ambientSound"])
            #self.ambientSound = mapData["ambientSound"]
            #self.bgSound = loader.loadSfx(self.ambientSound)
            #self.bgSound.setLoop(True)

        else:
            self.ambientSound = None
            self.bgSound = None

        self.collisionGrid.data = mapData["collision"]
        self.collisionGrid.rebuild()

        #print "models in use : %s" % (mapData["mapObjects"])
        for data in mapData["mapObjects"]:
            name = data[0]
            genre = data[1]
            pos = data[2]
            hpr = data[3]
            scale = data[4]
            self.addMapObject(
                genre, name, pos, hpr, scale
                #(pos.getX(), pos.getY(), pos.getZ()),
                #(hpr.getX(), hpr.getY(), hpr.getZ()),
                #(scale.getX(), scale.getY(), scale.getZ())
            )

        #self.rock = RockWallBuilder(self.mapObjectRoot, [Point3(0,0,0), Point3(self.x, 0,0), Point3(self.x, self.y,0), Point3(0,self.y,0), Point3(0,0,0)])
        #self.rock = ModelWallBuilder(self.mapObjectRoot, "models/props/rock1", ["img/textures/block01c.jpg", "img/textures/block01d.jpg"], 1.0, 1.5, 4.0, 180.0, [Point3(0,0,0), Point3(self.x, 0,0), Point3(self.x, self.y,0), Point3(0,self.y,0), Point3(0,0,0)])
        #self.rock.removeLastPoint()

    def setBgMusic(self, musicPath):
        #if self.bgMusic:
        #	self.bgMusic.stop()
        self.music = musicPath
        self.bgMusic = loader.loadSfx(self.music)
        self.bgMusic.setLoop(True)

    def setBgSound(self, soundPath):
        #if self.bgSound:
        #	self.bgSound.stop()
        self.ambientSound = soundPath
        self.bgSound = loader.loadSfx(self.ambientSound)
        self.bgSound.setLoop(True)

    def setSky(self, skyName):
        if self.sky:
            self.sky.destroy()
        self.sky = SkyBox()
        self.sky.load(skyName)
        self.sky.set(skyName)

    def addMapObject(self,
                     genre,
                     name,
                     pos=(0, 0, 0),
                     hpr=(0, 0, 0),
                     scale=(1, 1, 1)):
        if name not in self.mapObjects:
            mapObject = MapObject(self, genre, name)
            mapObject.setPos(pos)  #-self.collisionGrid.terrainScale/3.0)
            #print "Map add object : new object %s at position %s" % (name, mapObject.getPos())
            mapObject.setHpr(hpr)
            mapObject.setScale(scale)
            mapObject.reparentTo(self.mapObjectRoot)
            self.mapObjects[name] = mapObject
            #print "-> position is : %s" % (mapObject.getPos())

    def removeMapObject(self, name):
        if name in self.mapObjects:
            self.mapObjects[name].destroy()
            del self.mapObjects[name]

    def clearCollision(self, args=[]):
        print "Map %s : clear collision called" % (str(self))
        self.collisionGrid.clear()

    def fillCollision(self, args=[]):
        print "Map %s : fill collision called" % (str(self))
        self.collisionGrid.fill()

    def getClosestOpenTile(self, x, y):
        return self.collisionGrid.getClosestOpenTile(x, y)
Exemple #5
0
class SpaceOdeWorldManager(DirectObject):
	def __init__(self, gamemanager):
		# GameManager, from game.py
		self.gm = gamemanager
		
		# ODE base setup
		self.world = makeWorld()
		self.space = OdeSimpleSpace()
		self.space.setAutoCollideWorld(self.world)
		self.space.setCollisionEvent("ode-collision")
		self.accept("ode-collision", self.onCollision)
		self.contactGroup = OdeJointGroup()
		self.space.setAutoCollideJointGroup(self.contactGroup)
		
		#---------------------------------------------------------------
		# space objects lists and dics
		#---------------------------------------------------------------
		self.shipList = []
		self.shipDic = {}
		
		self.laserList = []
		self.laserDic = {}
		
		self.lootList = []
		self.lootDic = {}
		
		self.baseList = []
		self.baseDic = {}
		
		
		#---------------------------------------------------------------
		self.dtCumul = 0.0
		self.stepSize = 1.0 / 75.0
		
		#---------------------------------------------------------------
		# crosshair stuff, to aim guns and click on 3D objects with the mouse.
		# This same crosshair is used when on the ground for GUI too, for now.
		#---------------------------------------------------------------
		
		self.gm.crosshair.setMode(1)
		self.currentTargetDest = None
		self.currentTargetNP = None
		
		self.picker = OdePicker(self)
		
		
		#-------------------------------------------------------------------
		# GUI
		#-------------------------------------------------------------------
		self.gui = SpaceGui(self.gm.playerData)
		
		#---------------------------------------------------------------
		# input handling
		self.keyMap = {}
		self.acceptAll()
		#---------------------------------------------------------------
		# some loot
		for i in range(10):
			cube = Cube(self, 5)
			#cube = Sphere(self, 5)
			cube.setPos((i*0.02,i*0.02,5.5*i+2.51))
			name = "Cube " + str(i)
			cube.name = name
			self.lootList.append(cube)
			self.lootDic[cube.geom.getId()] = cube
			
		#---------------------------------------------------------------
		# player ship
		self.ship = Ship(self, self.gm.playerData.ship)
		self.ship.setPos((0,-20,12.51))
		
		#---------------------------------------------------------------
		# bases
		self.addBase("hesperida")
		
		

		#---------------------------------------------------------------
		# camera
		self.mode = "manual"
		self.camHandler = SpaceCamManager(self)
		self.camHandler.update()
		
		#---------------------------------------------------------------
		# radar
		self.radar = OdeRadar(self)
		
		#---------------------------------------------------------------
		# light
		self.light = LightManager()
		self.light.lightCenter.reparentTo(self.ship.model)
		
		#---------------------------------------------------------------
		# stardust cloud surrounding the player ship
		#self.PE = ParticleEngine(self.ship.model.getPos(), nb=100, ray=100, move = True)
		self.PE = ParticleEngine(self.ship.model, nb=40, ray=50, move = True)
		self.PE.stop()
		
		#---------------------------------------------------------------
		# trail of the player ship, TODO : move that to the OdeShip class and update ShipData to handle it
		self.trailPE = AriTrail(self.ship.model,20,0.0)
		#self.trailPE2 = AriTrail(self.gun2,10,0.0)
		
		#skyName = "skyBox06"
		skyName = "purple0"
		self.sky = SkyBox()
		self.sky.load(skyName)
		self.sky.set(skyName)
		self.currentSkyName = skyName
		self.sky.stop()
		#self.sky.currentModel.hide(BitMask32.bit(1))
		
		# BG music
		self.bgMusic = spaceBgMusic["hesperida_space"]
		
		
		self.NPCTimer = 0.0
		
		#self.accept("t", self.step)
		#self.start()
		self.task = None
		
		self.stop()
		
	def acceptAll(self):
		self.accept("ode-collision", self.onCollision)
		
		for key in ("a", "z", "e", "q", "s", "d", "w", "c", "r",
		"arrow_up", "arrow_down", "mouse1", "mouse3"
		):
			self.keyMap[key] = 0
			self.accept(key, self.setKey, [key, 1])
			keyup = key + "-up"
			self.accept(keyup, self.setKey, [key, 0])
		
		self.accept("space", self.toggleMode)
		self.accept("mouse1", self.selectClick)
		self.accept("p", self.spawnShip)
		
		
		self.accept("arrow_up", self.updateSize, [0.0,0.1])
		self.accept("arrow_down", self.updateSize, [0.0,-0.1])
		self.accept("arrow_left", self.updateSize, [-0.1,0.0])
		self.accept("arrow_right", self.updateSize, [0.1,0.0])
		
	def updateSize(self, x, y):
		self.gui.label1.updateSize(x, y)
		self.gui.label2.updateSize(x, y)
		
	def start(self):
		#print "Starting the space world."
		self.acceptAll()
		self.task = taskMgr.doMethodLater(1.5, self.worldTask, "spaceWorldTask")
		self.sky.set(self.currentSkyName)
		self.PE.start()
		self.showAll()
		self.radar.hide()
		self.bgMusic.play()
		#print "Le root de audio3d c'est %s" % (audio3d.root)
		taskMgr.doMethodLater(1.5, self.start3DAudio, "start3DAudio")
		
	def start3DAudio(self, task):
		#audio3d.attachListener(camera)
		audio3d.__init__(base.sfxManagerList[0], camera)
		#taskMgr.add(audio3d.update, "Audio3DManager-updateTask", 51)
		#print "restarted 3D audio!"
		return Task.done
		
	def stop(self):
		#print "Stopping the space world."
		
		#audio3d.detachSound()
		'''
		for sound in laserSounds:
			audio3d.detachSound(laserSounds[sound])
		audio3d.detachListener()
		'''
		audio3d.disable()
		#print "disabled 3D audio!"
		
		if self.task:
			#print "really stopped the world"
			taskMgr.remove(self.task)
			self.sky.stop()
			self.PE.stop()
			self.task = None
		#else:
			#print "Found no world running to stop though..."

		self.hideAll()
		self.ignoreAll() # inherited from DirectObject
		self.gm.crosshair.setMode(1)
		self.bgMusic.stop()
		
	def hideAll(self):
		for id in self.shipDic.keys():
			self.shipDic[id].hide()
		for id in self.lootDic.keys():
			self.lootDic[id].hide()
		for id in self.laserDic.keys():
			self.laserDic[id].hide()
		for id in self.baseDic.keys():
			self.baseDic[id].hide()
			
		self.ship.model.hide()
		self.radar.hide()
		#self.msgSpeed.hide()
		self.PE.stop()
		self.trailPE.stop()
		self.gui.hide()
		
	def showAll(self):
		for id in self.shipDic.keys():
			self.shipDic[id].show()
		for id in self.lootDic.keys():
			self.lootDic[id].show()
		for id in self.laserDic.keys():
			self.laserDic[id].show()
		for id in self.baseDic.keys():
			self.baseDic[id].show()
			
		self.ship.model.show()
		self.radar.show()
		#self.msgSpeed.show()
		self.PE.start()
		self.trailPE.start()
		self.gui.show()
		
	def destroy(self):
		self.stop()
		
		self.sky.clear()
		
		for id in self.shipDic.keys():
			self.destroyShip(id)
		
		for id in self.lootDic.keys():
			#print "Destroying ", self.lootDic[id].name
			self.destroyLoot(id)
		
		for id in self.laserDic.keys():
			self.destroyLaser(id)
		
		for id in self.baseDic.keys():
			self.destroyBase(id)
		
		self.gui.destroy()
		self.radar.destroy()
		self.ship.destroy()
		self.light.destroy()
		
	def setKey(self, k, v):
		self.keyMap[k] = v
	
	def onCollision(self, entry):
		geom1 = entry.getGeom1()
		geom2 = entry.getGeom2()
		body1 = entry.getBody1()
		body2 = entry.getBody2()
		
		# Must have hit someone
		#print "World, ", geom1, geom2, body1, body2
		id1 = geom1.getId()
		id2 = geom2.getId()
		
		contactPoint = entry.getContactPoints()[0]
		
		if ((id1 in self.lootDic) and (id2 in self.laserDic)):
			#print "Collision cube / laser!!! l'oeuf tombe sur la pierre!"
			#exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
			#audio3d.attachSoundToObject(exploSound1, self.lootDic[id1].model)
			audio3d.attachSoundToObject(exploSound1, self.laserDic[id2].model)
			exploSound1.play()
			self.destroyLaser(id2)
		
		elif ((id2 in self.lootDic) and (id1 in self.laserDic)):
			#print "Collision laser / cube!!! This is gonna hurt!"
			#exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
			#audio3d.attachSoundToObject(exploSound1, self.lootDic[id2].model)
			audio3d.attachSoundToObject(exploSound1, self.laserDic[id1].model)
			exploSound1.play()
			self.destroyLaser(id1)
			
		elif ((id1 in self.shipDic) and (id2 in self.laserDic)):
			#print "Collision ship / laser!"
			#exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
			#audio3d.attachSoundToObject(exploSound1, self.shipDic[id1].model)
			audio3d.attachSoundToObject(exploSound1, self.laserDic[id2].model)
			exploSound1.play()
			coqueDmg = self.laserDic[id2].gunData.coqueDmg
			shieldDmg = self.laserDic[id2].gunData.shieldDmg
			self.shipDic[id1].data.remShieldHP(shieldDmg)
			if self.shipDic[id1].data.shieldHP <= 0.0:
				self.shipDic[id1].data.remCoqueHP(coqueDmg)
			self.destroyLaser(id2)
		
		elif ((id2 in self.shipDic) and (id1 in self.laserDic)):
			#print "Collision laser / ship!"
			#exploSound1 = audio3d.loadSfx("sounds/space/explosion01.ogg")
			#audio3d.attachSoundToObject(exploSound1, self.shipDic[id2].model)
			audio3d.attachSoundToObject(exploSound1, self.laserDic[id1].model)
			exploSound1.play()
			coqueDmg = self.laserDic[id1].gunData.coqueDmg
			shieldDmg = self.laserDic[id1].gunData.shieldDmg
			self.shipDic[id2].data.remShieldHP(shieldDmg)
			if self.shipDic[id2].data.shieldHP <= 0.0:
				self.shipDic[id2].data.remCoqueHP(coqueDmg)
			self.destroyLaser(id1)
			
		
	
	def selectClick(self):
		if self.picker.targetGeomId != None:
			#print "Selecting geom"
			if self.picker.targetGeomId in self.shipDic:
				self.radar.setTarget(
					self.picker.targetGeomId,
					self.shipDic[self.picker.targetGeomId].model,
					self.shipDic[self.picker.targetGeomId].name,
					"ship")
					
			elif self.picker.targetGeomId in self.lootDic:
				self.radar.setTarget(
					self.picker.targetGeomId,
					self.lootDic[self.picker.targetGeomId].model,
					self.lootDic[self.picker.targetGeomId].name,
					"loot")
					
			elif self.picker.targetGeomId in self.baseDic:
				self.radar.setTarget(
					self.picker.targetGeomId,
					self.baseDic[self.picker.targetGeomId].model,
					self.baseDic[self.picker.targetGeomId].name,
					"base")
				
		self.shoot()
		
	def shoot(self, dt=1.0/75.0):
		targetPos = self.picker.crosshairModel.getPos(render)
		for loot in self.lootList:
			direction = targetPos - loot.model.getPos()
			loot.body.addForce(direction)
		for ship in self.shipList:
			ship.steerToPoint(targetPos, dt)
			ship.shootLasers(targetPos)
			
	def shoot2(self):
		targetPos = self.picker.crosshairModel.getPos(render)
		for loot in self.lootList:
			direction = -targetPos + loot.model.getPos()
			loot.body.addForce(direction*10)
	
	#-------------------------------------------------------------------
	# base handling
	#-------------------------------------------------------------------
	def addBase(self, name):
		if name in spaceBaseDb:
			spacebase = OdeBase(self, name)
			spacebaseId = spacebase.getId()
			self.baseList.append(spacebase)
			self.baseDic[spacebaseId] = spacebase
		
	def destroyBase(self, id):
		self.baseDic[id].destroy()
		self.baseList.remove(self.baseDic[id])
		del self.baseDic[id]
		
	#-------------------------------------------------------------------
	# laser handling
	#-------------------------------------------------------------------
	def shootLaser(self, originPos, targetPos, shipSpeed, gunData):
		#laser = Laser(self, originPos, targetPos, speed, shipSpeed, lifeTime)
		laser = Laser(self, originPos, targetPos, shipSpeed, gunData)
		laser.model.show(BitMask32.bit(1))
		self.laserList.append(laser)
		self.laserDic[laser.getId()] = laser
		#laserSounds["slimeball"].play() # deprecated, laser now plays its own sound on init
		
	def updateLasers(self, dt):
		for laser in self.laserList:
			laser.update(dt)
			if not laser.alive:
				self.laserList.remove(laser)
				del self.laserDic[laser.getId()]
				del laser
				
	def destroyLaser(self, id):
		audio3d.detachSound(exploSound1)
		self.laserDic[id].destroy()
		self.laserList.remove(self.laserDic[id])
		del self.laserDic[id]
	
	#-------------------------------------------------------------------
	# loot handling
	#-------------------------------------------------------------------
	def updateLoot(self, dt):
		for loot in self.lootList:
			loot.update(dt)
	
	def destroyLoot(self, geomId):
		self.lootList.remove(self.lootDic[geomId])
		self.lootDic[geomId].destroy()
		del self.lootDic[geomId]
	#-------------------------------------------------------------------
	# ship handling
	#-------------------------------------------------------------------
	def spawnShip(self):
		NPCShip = Ship(self, shipDb["npc"].makeCopy())
		NPCShip.geom.setCollideBits(odeBitMask["npc"])
		NPCShip.geom.setCategoryBits(odeBitMask["npc"])
		
		#shipModels["sabreNew"].instanceTo(NPCShip.model)
		NPCShip.setPos((-8,15,45))
		#NPCShip.data.setGun(0, gunDb["laser1"])
		#NPCShip.data.setGun(1, gunDb["laser3"])
		#NPCShip.initGuns() # already called in Ship.__init__, but called again here to update the equipped guns
		
		
		self.shipList.append(NPCShip)
		self.shipDic[NPCShip.getId()] = NPCShip
		#print "Adding ship, we now have %s ships in space" % (len(self.shipList))
		
	def updateShips(self, dt):
		for ship in self.shipList:
			ship.update(dt)
			if ship.alive is False:
				id = ship.getId()
				if ship.model is self.radar.targetNP:
					self.radar.clearTarget()
				self.destroyShip(id)
				print "Ship destroyed"
	
	def destroyShip(self, geomId):
		self.shipDic[geomId].destroy()
		self.shipList.remove(self.shipDic[geomId])
		#self.shipDic[geomId].destroy()
		del self.shipDic[geomId]
		#print "Destroyed ship, we now have %s ships in space" % (len(self.shipList))
		
	def setMode(self, mode):
		self.mode = str(mode)
		self.camHandler.mode = self.mode
		#if self.mode == "manual" or self.mode == "auto":
		#	self.camCube.body.setPosition(self.wm.ship.model.getPos()+(Point3(0,-20, 3)))
			
		
	def toggleMode(self):
		if self.mode == "auto":
			self.mode = "manual"
		elif self.mode == "manual":
			self.mode = "turret"
		else:
			self.mode = "auto"
			
		self.camHandler.mode = self.mode
		
	
		
	'''
	# this function is used if space.collide is used instead of autoCollide
	def handleCollisions(self, arg, geom1, geom2):
		entry = OdeUtil.collide(geom1, geom2)
		if entry.isEmpty():
			return
	'''
	
	#-------------------------------------------------------------------
	# World Task!
	#-------------------------------------------------------------------	
	def worldTask(self, task):
		
		dt = globalClock.getDt()
		
		self.NPCTimer += dt
		
		
		if base.mouseWatcherNode.hasMouse():
			mpos = base.mouseWatcherNode.getMouse()
			dx = mpos.getX()
			dy = mpos.getY()
		else:
			mpos = None
			dx = 0
			dy = 0
		
		if mpos:
			self.picker.update(mpos)
		self.radar.update()
		
		#self.refireTimer += dt
			
		self.shipSpeed = self.ship.body.getLinearVel()
		self.currentSpeed = self.shipSpeed.length()
		self.PE.speed = self.currentSpeed
		#self.PE.draw(self.currentSpeed)
		
		
		dx = min(dx, 1.0)
		dx = max(dx, -1.0)
		
		dy = min(dy, 1.0)
		dy = max(dy, -1.0)
		
		if self.mode == "manual":
			self.ship.steer(dx, dy, dt*100)
		elif self.mode == "auto":
			self.ship.steer(0, 0, dt*100)
			#self.ship.setAngMotor3(-self.ship.model.getR()/20)
			self.ship.autoCorrectHpr()
		else:
			self.ship.setAngMotor1(0)
			self.ship.setAngMotor2(0)
			self.ship.setAngMotor3(0)
			
		# speed control
		if self.keyMap["z"]:
			self.ship.accelerate(dt)
			#self.ship.setLinMotor(self.ship.pushSpeed)
		elif self.keyMap["s"]:
			self.ship.decelerate(dt)
			#self.ship.setLinMotor(-self.ship.pushSpeed)
		else:
			self.ship.rest()
			
		# roll
		if self.keyMap["d"]:
			#self.ship.setAngMotor3(self.ship.steerRSpeed)
			self.ship.roll(self.ship.steerRMaxSpeed, dt*100)
		elif self.keyMap["q"]:
			self.ship.roll(self.ship.steerRMaxSpeed, -dt*100)
			#self.ship.setAngMotor3(-self.ship.steerRSpeed)
			#self.stopAngMotor3()
		else:
			if self.mode == "manual":
				self.ship.setAngMotor3(0)
			
		if self.keyMap["mouse3"]:
			self.ship.shootLasers(self.picker.crosshairModel.getPos())
		
		if self.keyMap["mouse1"]:
			self.shoot(dt)
		
		
		
		#self.space.collide("", self.handleCollisions)
		self.space.autoCollide()
		
		'''
		self.dtCumul += dt
		while self.dtCumul > self.stepSize:
			# Remove a stepSize from the accumulator until
			# the accumulated time is less than the stepsize
			self.dtCumul -= self.stepSize
			# Step the simulation
			self.world.quickStep(self.stepSize)
		'''
		self.world.quickStep(dt)
		
		self.contactGroup.empty()
		
		self.updateLoot(dt)
		self.updateLasers(dt)
		self.updateShips(dt)
		
		self.ship.update(dt)
		
		self.gui.laserHP.setVal(self.ship.data.gunHP)
		self.gui.shieldHP.setVal(self.ship.data.shieldHP)
		self.gui.coqueHP.setVal(self.ship.data.coqueHP)
		
		#---------------------------------------------------------------
		# speed message
		l = round(self.currentSpeed, 2)
		self.gui.setSpeed(l)
		
		#---------------------------------------------------------------
		# cam handling
		self.camHandler.update(dx, dy)
		
		return task.cont