Example #1
0
class HitscanWeapon(Weapon):
    def __init__(self, mask, damage, knockback, range=None):
        Weapon.__init__(self, mask, range, damage, knockback)

        if range is None:
            self.ray = CollisionRay(0, 0, 0, 0, 1, 0)
        else:
            self.ray = CollisionSegment(0, 0, 0, 1, 0, 0)

        rayNode = CollisionNode("playerRay")
        rayNode.addSolid(self.ray)

        rayNode.setFromCollideMask(mask)
        rayNode.setIntoCollideMask(0)

        self.rayNodePath = render.attachNewNode(rayNode)
        self.rayQueue = CollisionHandlerQueue()

        self.traverser = CollisionTraverser()
        self.traverser.addCollider(self.rayNodePath, self.rayQueue)

    def performRayCast(self, origin, direction):
        if isinstance(self.ray, CollisionRay):
            self.ray.setOrigin(origin)
            self.ray.setDirection(direction)
        else:
            self.ray.setPointA(origin)
            self.ray.setPointB(origin + direction * self.range)

        self.traverser.traverse(render)

        if self.rayQueue.getNumEntries() > 0:
            self.rayQueue.sortEntries()
            rayHit = self.rayQueue.getEntry(0)

            return True, rayHit
        else:
            return False, None

    def fire(self, owner, dt):
        Weapon.fire(self, owner, dt)
        rayDir = owner.weaponNP.getQuat(render).getForward()
        hit, hitEntry = self.performRayCast(owner.weaponNP.getPos(render),
                                            rayDir)

        if hit:
            hitNP = hitEntry.getIntoNodePath()
            if hitNP.hasPythonTag(TAG_OWNER):
                subject = hitNP.getPythonTag(TAG_OWNER)
                subject.alterHealth(-self.damage, rayDir * self.knockback,
                                    self.flinchValue)

    def cleanup(self):
        self.traverser.removeCollider(self.rayNodePath)
        self.traverser = None

        if self.rayNodePath is not None:
            self.rayNodePath.removeNode()
            self.rayNodePath = None

        Weapon.cleanup(self)
Example #2
0
class Weapon(DirectObject):
    def __init__(self, _main, _name, _fireRate, _dmg=20,_mountSlot=0, weaponType="Pistol"):
        self.main = _main
        self.name = _name
        self.fireRate = _fireRate
        self.dmg = _dmg
        self.weaponType = weaponType
        self.mountSlot = _mountSlot

        self.muzzleFlash = loader.loadModel("muzzleflash")
        if weaponType == "Pistol":
            self.style = "OneHand"
            self.model = loader.loadModel("Pistol")
            self.muzzleFlash.setZ(0.65)
            self.muzzleFlash.setX(-0.04)
            self.muzzleFlash.setScale(0.25)
            self.muzzleFlash.find('**/+SequenceNode').node().setFrameRate(20)
        else:
            self.style = "TwoHand"
            self.model = loader.loadModel("MG")
            self.muzzleFlash.setZ(0.65)
            self.muzzleFlash.setX(0.08)
            self.muzzleFlash.setScale(0.3)
            self.muzzleFlash.find('**/+SequenceNode').node().setFrameRate(20)
        self.model.setY(2)
        self.muzzleFlash.reparentTo(self.model)
        self.muzzleFlash.find('**/+SequenceNode').node().stop()
        self.muzzleFlash.hide()

        # Load bullet model
        self.bullet = loader.loadModel("Bullet")
        self.bullet.setP(-90)
        self.bullet.setH(180)
        #self.bullet.setPos(0, 0.5, 0)

        # Control
        self.isFiring = False

        # Collision Stuff
        self.wepRay = None
        # Make weapon ray
        self.setupRay()
        self.model.show()

    def setAmmo(self):
        pass

    def setupRay(self):
        self.shootTraverser = CollisionTraverser()
        self.shootingQH = CollisionHandlerQueue()
        #self.shootingEH = CollisionHandlerEvent()
        #self.shootingEH.addInPattern('into-%in')
        # Create a collision Node
        shootNode = CollisionNode('WeaponRay')
        # set the nodes collision bitmask
        shootNode.setFromCollideMask(BitMask32.bit(1))
        # create a collision segment (ray like)
        self.shootRay = CollisionSegment()
        shootNode.addSolid(self.shootRay)
        #self.pickerNP = self.main.player.model.attachNewNode(pickerNode)
        self.shootNP = render.attachNewNode(shootNode)
        #self.shootTraverser.addCollider(self.shootNP, self.shootingEH)
        self.shootTraverser.addCollider(self.shootNP, self.shootingQH)
        #self.shootNP.show()

    def doFire(self, _toPos=(0, 0, 0)):
        self.isFiring = True

        if self.weaponType == "Pistol":
            self.muzzleFlash.find('**/+SequenceNode').node().play(0, 1)
        else:
            self.muzzleFlash.find('**/+SequenceNode').node().loop(True)
        self.muzzleFlash.show()

        # For some reason the mouse ray end up at posZ -1 (which causes a problem when we make the enemy spheres smaller in radius)
        # so here for now.. ill make a quick fix.
        adjustedZ = (_toPos[0], _toPos[1], 0)

        self.shootRay.setPointA(self.main.player.model.getPos())
        self.shootRay.setPointB(adjustedZ)

        fromPos = self.main.player.model.getPos() #self.model.getPos()
        #self.setProjectile(fromPos, adjustedZ)#_toPos)

        self.shootTraverser.traverse(self.main.enemyParent)
        if self.shootingQH.getNumEntries() > 0:
            self.shootingQH.sortEntries()
            enemyCol = self.shootingQH.getEntry(0).getIntoNodePath().node().getName()
            base.messenger.send("into-" + enemyCol, [self.dmg])

    def stopFire(self):
        if self.weaponType == "Pistol" and \
               self.muzzleFlash.find('**/+SequenceNode').node().isPlaying():
            taskMgr.add(self.waitForFrame, "waitForFrame")
            return
        self.muzzleFlash.find('**/+SequenceNode').node().stop()
        self.muzzleFlash.hide()

    def waitForFrame(self, task):
        if self.muzzleFlash.find('**/+SequenceNode').node().isPlaying():
            return task.cont
        self.muzzleFlash.find('**/+SequenceNode').node().stop()
        self.muzzleFlash.hide()

    def reload(self):
        pass

    def setProjectile(self, _from, _to):
        self.bullet.reparentTo(render)#self.model)
        # setup the projectile interval
        #self.bulletProjectile = ProjectileInterval(self.bullet,
        #                                startPos = Point3(_from),
        #                                duration = 1,
        #                                endPos = Point3(_to))
        #self.bulletProjectile = self.bullet.posInterval(1.0, Point3(_to), startPos=Point3(_from))
        #self.bulletProjectile = LerpPosInterval(self.bullet, 2.0, _to, _from)
        print "POSITIONS:"
        print _to
        print _from
        frm = render.getPos(self.main.player.model)
        print frm

        self.bulletProjectile = LerpPosInterval(self.bullet, 1.0, _to, _from)
        self.bulletProjectile.start()
Example #3
0
class Physics:
    def __init__(self):
        self.rayCTrav = CollisionTraverser("collision traverser for ray tests")
        #self.pusher = PhysicsCollisionHandler()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addInPattern('%fn-in-%in')
        self.pusher.addOutPattern('%fn-out-%in')
        self.pusher.addInPattern('%fn-in')
        self.pusher.addOutPattern('%fn-out')

    def startPhysics(self):
        #self.actorNode = ActorNode("playerPhysicsControler")
        #base.physicsMgr.attachPhysicalNode(self.actorNode)
        #self.actorNode.getPhysicsObject().setMass(self.player_mass)
        #self.mainNode = render.attachNewNode(self.actorNode)
        self.mainNode = render.attachNewNode("CharacterColliders")
        self.reparentTo(self.mainNode)

        charCollisions = self.mainNode.attachNewNode(CollisionNode(self.char_collision_name))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0, self.player_height/4.0))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0*3.05, self.player_height/4.0))
        charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/2.0, self.player_height/4.0))
        charCollisions.node().setIntoCollideMask(BitMask32(0x80))  # 1000 0000
        if self.show_collisions:
            charCollisions.show()
        self.pusher.addCollider(charCollisions, self.mainNode)
        base.cTrav.addCollider(charCollisions, self.pusher)

        charFFootCollisions = self.attachNewNode(CollisionNode("floor_ray"))
        charFFootCollisions.node().addSolid(CollisionRay(0, 0, 0.5, 0, 0, -1))
        #charFFootCollisions.node().addSolid(CollisionSegment((0, 0, 0.2), (0, 0, -1)))
        charFFootCollisions.node().setIntoCollideMask(BitMask32.allOff())
        charFFootCollisions.node().setFromCollideMask(BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            charFFootCollisions.show()

        self.floor_handler = CollisionHandlerFloor()
        self.floor_handler.addCollider(charFFootCollisions, self.mainNode)
        #self.floor_handler.setOffset(0)
        self.floor_handler.setMaxVelocity(5)
        base.cTrav.addCollider(charFFootCollisions, self.floor_handler)

        self.accept("{}-in".format(self.char_collision_name), self.checkCharCollisions)

        self.raytest_segment = CollisionSegment(0, 1)
        self.raytest_np = render.attachNewNode(CollisionNode("testRay"))
        self.raytest_np.node().addSolid(self.raytest_segment)
        self.raytest_np.node().setIntoCollideMask(BitMask32.allOff())
        self.raytest_np.node().setFromCollideMask(BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            self.raytest_np.show()

        self.raytest_queue = CollisionHandlerQueue()
        self.rayCTrav.addCollider(self.raytest_np, self.raytest_queue)

    def stopPhysics(self):
        self.raytest_segment.removeNode()
        self.pusher.clearColliders()
        self.floor_handler.clearColliders()
        self.rayCTrav.clearColliders()

    def updatePlayerPos(self, speed, heading, dt):
        if heading is not None:
            self.mainNode.setH(camera, heading)
            self.mainNode.setP(0)
            self.mainNode.setR(0)
        self.mainNode.setFluidPos(self.mainNode, speed)
        self.doStep()

    def checkCharCollisions(self, args):
        self.doStep()

    def doStep(self):
        # do the step height check
        tmpNP = self.mainNode.attachNewNode("temporary")
        tmpNP.setPos(self.mainNode, 0, 0, -self.stepheight)
        pointA = self.mainNode.getPos(render)
        pointA.setZ(pointA.getZ() + self.player_height/1.8)
        pointB = tmpNP.getPos(render)
        if pointA == pointB: return
        char_step_collision = self.getFirstCollisionInLine(pointA, pointB)
        tmpNP.removeNode()
        if char_step_collision is not None:
            self.mainNode.setFluidZ(char_step_collision.getZ())
            return True
        return False

    def getFirstCollisionInLine(self, pointA, pointB):
        """A simple raycast check which will return the first collision point as
        seen from point A towards pointB"""
        self.raytest_segment.setPointA(pointA)
        self.raytest_segment.setPointB(pointB)
        self.rayCTrav.traverse(render)
        self.raytest_queue.sortEntries()
        pos = None
        if self.raytest_queue.getNumEntries() > 0:
            pos = self.raytest_queue.getEntry(0).getSurfacePoint(render)
        return pos
Example #4
0
class Physics:
    def __init__(self):
        self.rayCTrav = CollisionTraverser("collision traverser for ray tests")
        #self.pusher = PhysicsCollisionHandler()
        self.pusher = CollisionHandlerPusher()
        self.pusher.addInPattern('%fn-in-%in')
        self.pusher.addOutPattern('%fn-out-%in')
        self.pusher.addInPattern('%fn-in')
        self.pusher.addOutPattern('%fn-out')

    def startPhysics(self):
        #self.actorNode = ActorNode("playerPhysicsControler")
        #base.physicsMgr.attachPhysicalNode(self.actorNode)
        #self.actorNode.getPhysicsObject().setMass(self.player_mass)
        #self.mainNode = render.attachNewNode(self.actorNode)
        self.mainNode = render.attachNewNode("CharacterColliders")
        self.reparentTo(self.mainNode)

        charCollisions = self.mainNode.attachNewNode(
            CollisionNode(self.char_collision_name))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0, self.player_height/4.0))
        #charCollisions.node().addSolid(CollisionSphere(0, 0, self.player_height/4.0*3.05, self.player_height/4.0))
        charCollisions.node().addSolid(
            CollisionSphere(0, 0, self.player_height / 2.0,
                            self.player_height / 4.0))
        charCollisions.node().setIntoCollideMask(BitMask32(0x80))  # 1000 0000
        if self.show_collisions:
            charCollisions.show()
        self.pusher.addCollider(charCollisions, self.mainNode)
        base.cTrav.addCollider(charCollisions, self.pusher)

        charFFootCollisions = self.attachNewNode(CollisionNode("floor_ray"))
        charFFootCollisions.node().addSolid(CollisionRay(0, 0, 0.5, 0, 0, -1))
        #charFFootCollisions.node().addSolid(CollisionSegment((0, 0, 0.2), (0, 0, -1)))
        charFFootCollisions.node().setIntoCollideMask(BitMask32.allOff())
        charFFootCollisions.node().setFromCollideMask(
            BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            charFFootCollisions.show()

        self.floor_handler = CollisionHandlerFloor()
        self.floor_handler.addCollider(charFFootCollisions, self.mainNode)
        #self.floor_handler.setOffset(0)
        self.floor_handler.setMaxVelocity(5)
        base.cTrav.addCollider(charFFootCollisions, self.floor_handler)

        self.accept("{}-in".format(self.char_collision_name),
                    self.checkCharCollisions)

        self.raytest_segment = CollisionSegment(0, 1)
        self.raytest_np = render.attachNewNode(CollisionNode("testRay"))
        self.raytest_np.node().addSolid(self.raytest_segment)
        self.raytest_np.node().setIntoCollideMask(BitMask32.allOff())
        self.raytest_np.node().setFromCollideMask(BitMask32(0x7f))  # 0111 1111
        if self.show_collisions:
            self.raytest_np.show()

        self.raytest_queue = CollisionHandlerQueue()
        self.rayCTrav.addCollider(self.raytest_np, self.raytest_queue)

    def stopPhysics(self):
        self.raytest_segment.removeNode()
        self.pusher.clearColliders()
        self.floor_handler.clearColliders()
        self.rayCTrav.clearColliders()

    def updatePlayerPos(self, speed, heading, dt):
        if heading is not None:
            self.mainNode.setH(camera, heading)
            self.mainNode.setP(0)
            self.mainNode.setR(0)
        self.mainNode.setFluidPos(self.mainNode, speed)
        self.doStep()

    def checkCharCollisions(self, args):
        self.doStep()

    def doStep(self):
        # do the step height check
        tmpNP = self.mainNode.attachNewNode("temporary")
        tmpNP.setPos(self.mainNode, 0, 0, -self.stepheight)
        pointA = self.mainNode.getPos(render)
        pointA.setZ(pointA.getZ() + self.player_height / 1.8)
        pointB = tmpNP.getPos(render)
        if pointA == pointB: return
        char_step_collision = self.getFirstCollisionInLine(pointA, pointB)
        tmpNP.removeNode()
        if char_step_collision is not None:
            self.mainNode.setFluidZ(char_step_collision.getZ())
            return True
        return False

    def getFirstCollisionInLine(self, pointA, pointB):
        """A simple raycast check which will return the first collision point as
        seen from point A towards pointB"""
        self.raytest_segment.setPointA(pointA)
        self.raytest_segment.setPointB(pointB)
        self.rayCTrav.traverse(render)
        self.raytest_queue.sortEntries()
        pos = None
        if self.raytest_queue.getNumEntries() > 0:
            pos = self.raytest_queue.getEntry(0).getSurfacePoint(render)
        return pos
class WalkingEnemy(Enemy):
    def __init__(self, pos):
        Enemy.__init__(
            self, pos, "Models/Misc/simpleEnemy", {
                "stand": "Models/Misc/simpleEnemy-stand",
                "walk": "Models/Misc/simpleEnemy-walk",
                "attack": "Models/Misc/simpleEnemy-attack",
                "die": "Models/Misc/simpleEnemy-die",
                "spawn": "Models/Misc/simpleEnemy-spawn"
            }, 3.0, 7.0, "walkingEnemy")

        self.attackDistance = 0.75
        self.attackDelay = 0.3
        self.attackDelayTimer = 0
        self.attackWaitTimer = 0
        self.acceleration = 100.0

        mask = BitMask32()
        mask.setBit(2)

        self.collider.node().setIntoCollideMask(mask)

        self.attackSegment = CollisionSegment(0, 0, 0, 1, 0, 0)

        segmentNode = CollisionNode("enemyAttackSegment")
        segmentNode.addSolid(self.attackSegment)

        mask = BitMask32()
        mask.setBit(1)

        segmentNode.setFromCollideMask(mask)

        mask = BitMask32()

        segmentNode.setIntoCollideMask(mask)

        self.attackSegmentNodePath = render.attachNewNode(segmentNode)
        self.segmentQueue = CollisionHandlerQueue()

        base.cTrav.addCollider(self.attackSegmentNodePath, self.segmentQueue)

        self.attackDamage = -1

        self.deathSound = loader.loadSfx("Sounds/enemyDie.ogg")
        self.attackSound = loader.loadSfx("Sounds/enemyAttack.ogg")

        self.yVector = Vec2(0, 1)

        self.actor.play("spawn")

    def runLogic(self, player, dt):
        spawnControl = self.actor.getAnimControl("spawn")
        if spawnControl is not None and spawnControl.isPlaying():
            return

        vectorToPlayer = player.actor.getPos() - self.actor.getPos()

        vectorToPlayer2D = vectorToPlayer.getXy()
        distanceToPlayer = vectorToPlayer2D.length()

        vectorToPlayer2D.normalize()

        heading = self.yVector.signedAngleDeg(vectorToPlayer2D)

        self.attackSegment.setPointA(self.actor.getPos())
        self.attackSegment.setPointB(self.actor.getPos() +
                                     self.actor.getQuat().getForward() *
                                     self.attackDistance)

        if distanceToPlayer > self.attackDistance * 0.9:
            attackControl = self.actor.getAnimControl("attack")
            if not attackControl.isPlaying():
                self.walking = True
                vectorToPlayer.setZ(0)
                vectorToPlayer.normalize()
                self.velocity += vectorToPlayer * self.acceleration * dt
                self.attackWaitTimer = 0.2
                self.attackDelayTimer = 0
        else:
            self.walking = False
            self.velocity.set(0, 0, 0)

            if self.attackDelayTimer > 0:
                self.attackDelayTimer -= dt
                if self.attackDelayTimer <= 0:
                    if self.segmentQueue.getNumEntries() > 0:
                        self.segmentQueue.sortEntries()
                        segmentHit = self.segmentQueue.getEntry(0)

                        hitNodePath = segmentHit.getIntoNodePath()
                        if hitNodePath.hasPythonTag("owner"):
                            hitObject = hitNodePath.getPythonTag("owner")
                            hitObject.alterHealth(self.attackDamage)
                            self.attackWaitTimer = 1.0
            elif self.attackWaitTimer > 0:
                self.attackWaitTimer -= dt
                if self.attackWaitTimer <= 0:
                    self.attackWaitTimer = random.uniform(0.5, 0.7)
                    self.attackDelayTimer = self.attackDelay
                    self.actor.play("attack")
                    self.attackSound.play()

        self.actor.setH(heading)

    def alterHealth(self, dHealth):
        Enemy.alterHealth(self, dHealth)
        self.updateHealthVisual()

    def updateHealthVisual(self):
        perc = self.health / self.maxHealth
        if perc < 0:
            perc = 0
        self.actor.setColorScale(perc, perc, perc, 1)

    def cleanup(self):
        base.cTrav.removeCollider(self.attackSegmentNodePath)
        self.attackSegmentNodePath.removeNode()

        GameObject.cleanup(self)
class PositionExaminer(DirectObject, NodePath):

    def __init__(self):
        try:
            self.__initialized
            return
        except:
            self.__initialized = 1

        NodePath.__init__(self, hidden.attachNewNode('PositionExaminer'))
        self.cRay = CollisionRay(0.0, 0.0, 6.0, 0.0, 0.0, -1.0)
        self.cRayNode = CollisionNode('cRayNode')
        self.cRayNode.addSolid(self.cRay)
        self.cRayNodePath = self.attachNewNode(self.cRayNode)
        self.cRayNodePath.hide()
        self.cRayBitMask = CIGlobals.FloorBitmask
        self.cRayNode.setFromCollideMask(self.cRayBitMask)
        self.cRayNode.setIntoCollideMask(BitMask32.allOff())
        self.cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.5)
        self.cSphereNode = CollisionNode('cSphereNode')
        self.cSphereNode.addSolid(self.cSphere)
        self.cSphereNodePath = self.attachNewNode(self.cSphereNode)
        self.cSphereNodePath.hide()
        self.cSphereBitMask = CIGlobals.WallBitmask
        self.cSphereNode.setFromCollideMask(self.cSphereBitMask)
        self.cSphereNode.setIntoCollideMask(BitMask32.allOff())
        self.ccLine = CollisionSegment(0.0, 0.0, 0.0, 1.0, 0.0, 0.0)
        self.ccLineNode = CollisionNode('ccLineNode')
        self.ccLineNode.addSolid(self.ccLine)
        self.ccLineNodePath = self.attachNewNode(self.ccLineNode)
        self.ccLineNodePath.hide()
        self.ccLineBitMask = CIGlobals.CameraBitmask
        self.ccLineNode.setFromCollideMask(self.ccLineBitMask)
        self.ccLineNode.setIntoCollideMask(BitMask32.allOff())
        self.cRayTrav = CollisionTraverser('PositionExaminer.cRayTrav')
        self.cRayTrav.setRespectPrevTransform(False)
        self.cRayQueue = CollisionHandlerQueue()
        self.cRayTrav.addCollider(self.cRayNodePath, self.cRayQueue)
        self.cSphereTrav = CollisionTraverser('PositionExaminer.cSphereTrav')
        self.cSphereTrav.setRespectPrevTransform(False)
        self.cSphereQueue = CollisionHandlerQueue()
        self.cSphereTrav.addCollider(self.cSphereNodePath, self.cSphereQueue)
        self.ccLineTrav = CollisionTraverser('PositionExaminer.ccLineTrav')
        self.ccLineTrav.setRespectPrevTransform(False)
        self.ccLineQueue = CollisionHandlerQueue()
        self.ccLineTrav.addCollider(self.ccLineNodePath, self.ccLineQueue)

    def delete(self):
        del self.cRay
        del self.cRayNode
        self.cRayNodePath.removeNode()
        del self.cRayNodePath
        del self.cSphere
        del self.cSphereNode
        self.cSphereNodePath.removeNode()
        del self.cSphereNodePath
        del self.ccLine
        del self.ccLineNode
        self.ccLineNodePath.removeNode()
        del self.ccLineNodePath
        del self.cRayTrav
        del self.cRayQueue
        del self.cSphereTrav
        del self.cSphereQueue
        del self.ccLineTrav
        del self.ccLineQueue

    def consider(self, node, pos, eyeHeight):
        self.reparentTo(node)
        self.setPos(pos)
        result = None
        self.cRayTrav.traverse(render)
        if self.cRayQueue.getNumEntries() != 0:
            self.cRayQueue.sortEntries()
            floorPoint = self.cRayQueue.getEntry(0).getSurfacePoint(self.cRayNodePath)
            if abs(floorPoint[2]) <= 4.0:
                pos += floorPoint
                self.setPos(pos)
                self.cSphereTrav.traverse(render)
                if self.cSphereQueue.getNumEntries() == 0:
                    self.ccLine.setPointA(0, 0, eyeHeight)
                    self.ccLine.setPointB(-pos[0], -pos[1], eyeHeight)
                    self.ccLineTrav.traverse(render)
                    if self.ccLineQueue.getNumEntries() == 0:
                        result = pos
        self.reparentTo(hidden)
        self.cRayQueue.clearEntries()
        self.cSphereQueue.clearEntries()
        self.ccLineQueue.clearEntries()
        return result
Example #7
0
class Player():
    def __init__(self, camera, accept, render, loader, maxJPHeight):
        #initial variables and sounds

        self.developer = True  # Developer tools (building tools) will be accessible if this is turned on.
        self.gameMode = self.mode0  # the current playerUpdate function that is in use
        # self.playerModeParameters = () # the parameters being fed into the function above.
        self.groundContact = False  # if the player is on the ground or a surface, gravity will not pull the player below the surface
        self.jetPack_energy = 100
        self.maximumHeight = maxJPHeight  # maximum height in which the jetpack can fly to, this is dependent on the map loaded.
        self.jetPack_AUDIO = loader.loadSfx("assets/base/sounds/jetpack2.wav")
        self.jetPack_AUDIO.setLoop(True)
        self.vertical_velocity = 0  # Current Z velocity, positive = Upwards.
        self.z_velocity = 0  # Current Y velocity
        self.x_velocity = 0
        self.movingZ = False
        self.movingX = False

        #initiate GUI
        self.HUD = GUI()
        self.playerHolder = render.attachNewNode('player')

        # camera control - Hiding mouse and using it to rotate the camera
        props = WindowProperties()
        props.setCursorHidden(True)
        props.setMouseMode(WindowProperties.M_relative)
        base.win.requestProperties(props)

        # PLAYER MODEL SCENE GRAPH
        self.thirdPersonCamera_ZOOM = -50  # initial distance of third person camera.
        self.character = loader.loadModel(
            'assets/base/models/playerModel/player.bam')
        self.toggleFPCam = False  # Whether first person camera is on, this is initially off.
        self.character.setPos(0, 0, 0)
        self.character.reparentTo(self.playerHolder)
        self.playerBase = self.playerHolder.attachNewNode('camParent')
        self.thirdPersonNode = self.playerBase.attachNewNode('thirdPersonCam')
        camera.reparentTo(self.thirdPersonNode)
        self.mouseSeconds = []
        self.playerHolder.setScale(4)
        self.monitor = loader.loadModel(
            'assets/base/models/faces/playerMonitor.bam')
        self.monitor.reparentTo(self.playerHolder)
        self.cTrav = CollisionTraverser()

        # Horizontal collisions
        self.pusher = CollisionHandlerPusher()
        self.pusher.horizontal = True
        self.colliderNode = CollisionNode("player")
        self.colliderNode.addSolid(CollisionSphere(0, 0, 0, 2))
        self.colliderNode.setFromCollideMask(CollideMask.bit(1))
        self.colliderNode.setFromCollideMask(CollideMask.bit(0))
        self.colliderNode.setIntoCollideMask(BitMask32.allOff())
        collider = self.playerHolder.attachNewNode(self.colliderNode)
        collider.show()
        self.pusher.addCollider(collider, self.playerHolder)
        self.cTrav.addCollider(collider, self.pusher)

        # Vertical collisions - Downwards
        self.groundRay = CollisionRay()
        self.groundRay.setDirection(0, 0, -1)
        self.groundRayCol = CollisionNode('playerRay')
        self.groundRayCol.addSolid(self.groundRay)
        self.groundRayCol.setFromCollideMask(CollideMask.bit(1))
        self.groundRayCol.setIntoCollideMask(CollideMask.allOff())
        self.groundColNp = self.playerHolder.attachNewNode(self.groundRayCol)
        self.groundHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.groundColNp, self.groundHandler)

        # Third Person Camera Collision
        self.cameraRay = CollisionSegment()
        self.cameraRayNode = CollisionNode('camerRay')
        self.cameraRayNode.addSolid(self.cameraRay)
        self.cameraRayNodePath = render.attachNewNode(self.cameraRayNode)
        self.cameraCollisionHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.cameraRayNodePath,
                               self.cameraCollisionHandler)

        # Vertical collisions - Upwards
        self.upwardsRay = CollisionRay()
        self.upwardsRay.setDirection(0, 0, 1)
        self.upwardsRayCol = CollisionNode('playerupRay')
        self.upwardsRayCol.addSolid(self.upwardsRay)
        self.upwardsRayCol.setFromCollideMask(CollideMask.bit(1))
        self.upwardsRayCol.setIntoCollideMask(CollideMask.allOff())
        self.upwardsColNp = self.playerHolder.attachNewNode(self.upwardsRayCol)
        self.upwardsHandler = CollisionHandlerQueue()
        self.cTrav.addCollider(self.upwardsColNp, self.upwardsHandler)
        #self.cTrav.showCollisions(render)

        if self.developer == True:
            self.tool = buildingTool(
                "newbuildings", self.playerHolder, loader,
                accept)  # Load up building tool if developer modee is on.

        #self.setupLighting() # light
        #initial position
        self.playerHolder.setPos(45178.3, 43109.3, 0)
        self.keyMap = {
            "left": False,
            "right": False,
            "forward": False,
            "backwards": False,
            "change_camera": False,
            "leftClick": False,
            "space": False,
            "p": False,
            "scrollup": False,
            "scrolldown": False
        }

        accept("escape", sys.exit)
        accept("w", self.updateKey, ["forward", True])  #
        accept("w-up", self.updateKey, ["forward", False])

        accept("a", self.updateKey, ["left", True])
        accept("a-up", self.updateKey, ["left", False])

        accept("s", self.updateKey, ["backwards", True])
        accept("s-up", self.updateKey, ["backwards", False])

        accept("d", self.updateKey, ["right", True])
        accept("d-up", self.updateKey, ["right", False])

        accept("c", self.updateKey, ["change_camera", True])

        accept("wheel_up", self.updateKey, ["scrollup", True])

        accept("wheel_down", self.updateKey, ["scrolldown", True])

        accept("p", self.updateKey, ["p", True])
        accept("p-up", self.updateKey, ["p", False])

        accept("space", self.updateKey, ["space", True])
        accept("space-up", self.updateKey, ["space", False])

        self.playerMode = playerModes(
            self.playerBase, self.playerHolder, self.character,
            self.vertical_velocity, self.z_velocity, self.x_velocity,
            self.keyMap, self.monitor, self.thirdPersonNode,
            self.jetPack_energy, self.jetPack_AUDIO,
            self.thirdPersonCamera_ZOOM, self.toggleFPCam, self.HUD,
            self.cTrav, self.groundHandler, self.upwardsHandler,
            self.maximumHeight)

    def playerUpdate(self, task):  # our UPDATE TASK
        self.gameMode()
        return task.cont

    def updateKey(self, key, value):
        self.keyMap[key] = value
        if key == "change_camera":
            self.changeCamera()
        self.scrollFactor = 10
        if key == "scrollup":  # third person zoom in/out
            self.thirdPersonCamera_ZOOM += self.scrollFactor
        if key == "scrolldown":
            self.thirdPersonCamera_ZOOM -= self.scrollFactor

    def changeCamera(self):  # Toggle first person camera.
        if self.toggleFPCam == False:
            self.toggleFPCam = True
        else:
            self.toggleFPCam = False

    def recenterMouse(self):
        base.win.movePointer(0, int(base.win.getProperties().getXSize() / 2),
                             int(base.win.getProperties().getYSize() / 2))

    def setupLighting(self):
        plight = PointLight('plight')
        plight.setColor((1, 1, 1, 1))
        plnp = self.playerHolder.attachNewNode(plight)
        plnp.setPos(0, 1, 7)
        render.setLight(plnp)

# PLAYER MODES, HOW THE USER INTERACTS AND CONTROLS WITH THE USER

#   MODE 0
# Mode 0 is the default update mode, it allows WASD movement,
# mouse controlled camera rotations, first person and third
# person switching, it also has GUI display and player physics.

    def mode0(self):

        #THIRD PERSON CAMERA COLLISION

        # print("thirdpersonnode")
        # print(self.playerBase.getHpr())
        # print("pb")
        # print(self.character.getHpr())

        deltaTime = globalClock.getDt()
        self.movingZ = False
        self.movingX = False
        self.walkConstant = 25
        self.rotateConstant = 750

        # Keyboard controls
        # LEVITATION STUFF (FORMERLY CALLED JETPACK)

        if self.keyMap["space"] and self.jetPack_energy > 0:
            jetpack = 0.00001 * ((
                (self.playerHolder.getZ()) - self.maximumHeight)**2) + 9.81
            self.playerHolder.setZ(self.playerBase, jetpack)
            self.jetPack_energy -= 15 * deltaTime
            self.walkConstant = 70
            self.jetPack_AUDIO.play()
        else:
            self.jetPack_AUDIO.stop()
        if self.jetPack_energy < 100:
            self.jetPack_energy += 10 * deltaTime
        if self.jetPack_energy > 100:
            self.jetPack_energy = 100

        self.HUD.jetpackStatus.text = "Levitation Battery: " + str(
            int(self.jetPack_energy)) + "%"

        if (self.keyMap["forward"]
                or self.keyMap["backwards"]) and (self.keyMap["right"]
                                                  or self.keyMap["left"]):
            self.walkConstant = int(((self.walkConstant**2) / 2)**0.5)

        # WASD MOVEMENT
        if self.keyMap["forward"]:
            self.monitor.setH(self.playerBase.getH() - 90)
            self.movingZ = True
            self.z_velocity += 5
            if self.z_velocity > self.walkConstant:
                self.z_velocity = self.walkConstant

        if self.keyMap["right"]:
            self.monitor.setH(self.playerBase.getH() - 180)
            self.movingX = True
            self.x_velocity += 5
            if self.x_velocity > self.walkConstant:
                self.x_velocity = self.walkConstant
        if self.keyMap["p"]:
            print(self.playerHolder.getPos())
            print(self.thirdPersonCamera_ZOOM)
            self.gameMode = self.mode1
        if self.keyMap["left"]:
            self.monitor.setH(self.playerBase.getH())
            self.movingX = True
            self.x_velocity -= 5
            if self.x_velocity < -self.walkConstant:
                self.x_velocity = -self.walkConstant
        if self.keyMap["backwards"]:
            self.monitor.setH(self.playerBase.getH() + 90)
            self.movingZ = True
            self.z_velocity -= 20
            if self.z_velocity < -self.walkConstant:
                self.z_velocity = -self.walkConstant

        if self.movingZ == False:
            if self.z_velocity <= 7 or (
                    self.z_velocity >= -5
                    and self.z_velocity < 0):  # Shaking bug fix
                self.z_velocity = 0
            if self.z_velocity > 0:
                self.z_velocity -= 10
            elif self.z_velocity < 0:
                self.z_velocity += 10
        if self.movingX == False:
            if self.x_velocity <= 5 or (
                    self.x_velocity >= -5
                    and self.x_velocity < 0):  # Shaking bug fix
                self.x_velocity = 0
            if self.x_velocity > 0:
                self.x_velocity -= 10
            elif self.x_velocity < 0:
                self.x_velocity += 10
        # MONITOR HEADINGS FOR DOUBLE INPUT
        if self.keyMap["forward"] and self.keyMap["right"]:
            self.monitor.setH(self.playerBase.getH() - 135)
        elif self.keyMap["forward"] and self.keyMap["left"]:
            self.monitor.setH(self.playerBase.getH() - 45)
        elif self.keyMap["backwards"] and self.keyMap["left"]:
            self.monitor.setH(self.playerBase.getH() + 45)
        elif self.keyMap["backwards"] and self.keyMap["right"]:
            self.monitor.setH(self.playerBase.getH() + 135)

        # third person camera control
        if (self.toggleFPCam == False):  # third person camera controls
            if (base.mouseWatcherNode.hasMouse() == True):
                mouseposition = base.mouseWatcherNode.getMouse()
                self.thirdPersonNode.setP(mouseposition.getY() * 30)
                self.playerBase.setH(mouseposition.getX() * -50)
                if (mouseposition.getX() < 0.1
                        and mouseposition.getX() > -0.1):
                    self.playerBase.setH(self.playerBase.getH())

            if self.thirdPersonNode.getP() > 90:
                self.recenterMouse()
                self.thirdPersonNode.setP(90)  # TRACK MOUSE
            elif self.thirdPersonNode.getP() < -90:
                self.recenterMouse()
                self.thirdPersonNode.setP(-90)
            if self.thirdPersonCamera_ZOOM > -20:  # validate zoom
                self.thirdPersonCamera_ZOOM = -20
            elif self.thirdPersonCamera_ZOOM < -390:
                self.thirdPersonCamera_ZOOM = -390
        # CAMERA STUFF
        # FIRST PERSON CAMERA
        if self.toggleFPCam:  # first person camera controls
            camera.setPos(self.character.getPos())  # 0,-50,-10
            camera.setZ(camera.getZ() + 6)
            self.playerHolder.hide()
            if (base.mouseWatcherNode.hasMouse() == True):
                mouseposition = base.mouseWatcherNode.getMouse()
                camera.setP(mouseposition.getY() * 20)
                self.playerBase.setH(mouseposition.getX() * -50)
                if (mouseposition.getX() < 0.1
                        and mouseposition.getX() > -0.1):
                    self.playerBase.setH(self.playerBase.getH())
            if camera.getP() > 90:
                self.recenterMouse()
                camera.setP(90)  # TRACK MOUSE
            elif camera.getP() < -90:
                self.recenterMouse()
                camera.setP(-90)
        else:  # takes out of first person perspective if toggleFPS is turned off.
            self.playerHolder.show()
            camera.setPos(0, self.thirdPersonCamera_ZOOM, 0)  # 0,-50,-4
            camera.lookAt(self.character)
        # movement updates
        self.playerHolder.setY(self.playerBase, (self.z_velocity * deltaTime))
        self.playerHolder.setX(self.playerBase, (self.x_velocity * deltaTime))

        # forward/backward rolling
        axis = self.playerBase.getQuat().getRight()
        angle = (self.z_velocity * deltaTime * -8)
        quat = Quat()
        quat.setFromAxisAngle(angle, axis)
        newVec = self.character.getQuat() * quat
        # print(newVec.getHpr())
        self.character.setQuat(newVec)

        # sideways rolling
        axis = self.playerBase.getQuat().getForward()
        angle = (self.x_velocity * deltaTime * 8)
        quat = Quat()
        quat.setFromAxisAngle(angle, axis)
        newVec = self.character.getQuat() * quat
        # print(self.playerBase.getPos())
        self.character.setQuat(newVec)
        self.cameraRay.setPointA(self.playerBase.getPos())
        if camera.getPos() != (0, 0, 0):
            self.cameraRay.setPointB(camera.getPos(base.render))

        self.cTrav.traverse(render)

        # checking for camera collisions
        entries = list(self.cameraCollisionHandler.entries)
        for entry in entries:
            if str(entry.getIntoNodePath())[:19] != "render/worldTerrain":
                #camera.setPos(entry.getSurfacePoint(self.thirdPersonNode))
                self.thirdPersonCamera_ZOOM += 1

        # if len(entries) > 0:
        #     if (self.playerHolder.getZ() < entries[-1].getSurfacePoint(render).getZ() + 8):
        #         self.playerHolder.setZ(entries[-1].getSurfacePoint(render).getZ() + 8)
        #         self.vertical_velocity = 0

        # checking for collisions - downwards
        entries = list(self.groundHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        self.performGravity = True
        if self.performGravity == True:
            self.vertical_velocity -= (deltaTime * 9.81)
            if self.vertical_velocity <= -15:
                self.vertical_velocity = -15
            self.playerHolder.setPos(self.playerHolder,
                                     Vec3(0, 0,
                                          self.vertical_velocity))  # Gravity
        if len(entries) > 0:
            if (self.playerHolder.getZ() <
                    entries[-1].getSurfacePoint(render).getZ() + 8):
                self.playerHolder.setZ(
                    entries[-1].getSurfacePoint(render).getZ() + 8)
                self.vertical_velocity = 0

        # checking for collisions - upwards
        entries = list(self.upwardsHandler.entries)
        entries.sort(key=lambda x: x.getSurfacePoint(render).getZ())
        if len(entries) > 0:
            for entry in entries:
                if (self.playerHolder.getZ() >
                        entry.getSurfacePoint(render).getZ() - 70):
                    self.playerHolder.setZ(
                        entry.getSurfacePoint(render).getZ() - 130)

    # PLAYER MODES, HOW THE USER INTERACTS AND CONTROLS WITH THE USER
    #   MODE 1
    # Mode 1 is a test update loop used to test player loop switching.
    # it simply freezes the controls.

    def mode1(self):
        self.playerHolder.hide()
        self.playerHolder.setHpr(0, 0, 0)
        if self.keyMap["backwards"]:
            self.playerHolder.show()
            self.gameMode = self.mode0