class Vehicle(object):
    COUNT = 0

    def __init__(self, main, username, pos = LVecBase3(-5, -5, 1), isCurrentPlayer = False, carId=3):
        self.username = username
        self.main = main
        self.isCurrentPlayer = isCurrentPlayer
        self.boostCount = 0
        self.boostActive = False
        self.boostStep = 2
        self.boostDuration = 0
        self.moveStartTime = self.startTime = self.boostStartTime = time.time()
        self.pos = pos
        self.boostFactor = 1.2
        self.specs = {"mass": 800.0,
                    "maxWheelForce": 2000.0,
                    "brakeForce": 100.0,
                    "steeringLock": 45.0,
                    "maxSpeed": 33.0,
                    "maxReverseSpeed": 10.0}
        self.vehicleControlState = {"throttle": 0, "reverse": False, "brake": 0.0, "steering": 0.0, "health": 1}

        # Steering change per second, normalised to steering lock
        # Eg. 45 degrees lock and 1.0 rate means 45 degrees per second
        self.steeringRate = 0.8
        self.centreingRate = 1.2
        self.speed = 0

        self.setupVehicle(main)

        self.props = VehicleProps(carId)

        self.currentPowerups = {"powerup1": None, "powerup2": None, "powerup3": None}
        if isCurrentPlayer:
            #This command is required for Panda to render particles
            base.enableParticles()
            self.p = ParticleEffect()
        #     self.loadParticleConfig('steam.ptf')

    def setPropHealth(self, health):
        self.props.setHealth(health)
        if not self.isCurrentPlayer:
            self.main.updateStatusBars(self.username, self.props.health)

    def loadParticleConfig(self, file):
        #Start of the code from steam.ptf
        self.p.cleanup()
        self.p = ParticleEffect()
        self.p.loadConfig(Filename(file))
        # print type(main.worldNp)
        self.p.softStart()
        self.p.start(self.yugoNP)
        # self.p.setPos(0.000, -0.700, 0.250)
        self.p.setPos(0.000, -0.700, 0)

        #self.setupVehicle(bulletWorld)
        self.startTime = time.time()
        #COUNT = 1

    def move(self, steering, wheelForce, brakeForce, x, y, z, h, p, r):
        self.applyForcesAndSteering(steering, wheelForce, brakeForce)
        self.endTime = time.time()
        #print self.endTime
        elapsed = self.endTime - self.moveStartTime
        #self.startTime = self.endTime
        #if elapsed > 1:
        self.moveStartTime = self.endTime
        if not self.isCurrentPlayer:
            self.setVehiclePos(x, y, z, h, p, r)

        #print "Do Move"

    def applyForcesAndSteering(self, steering, wheelForce, brakeForce):
        # Apply steering to front wheels
        self.vehicle.setSteeringValue(steering, 0);
        self.vehicle.setSteeringValue(steering, 1);
        # Apply engine and brake to rear wheels
        self.vehicle.applyEngineForce(wheelForce, 2);
        self.vehicle.applyEngineForce(wheelForce, 3);
        self.vehicle.setBrake(brakeForce, 2);
        self.vehicle.setBrake(brakeForce, 3);
    def addBoost(self):
        if self.boostCount > 0:
            self.boostCount -= 1
            if not self.boostActive:
                self.boostStartTime = time.time()
                self.boostActive = True
            self.boostDuration += self.boostStep
    def checkDisableBoost(self):
        if time.time() - self.boostStartTime > self.boostDuration:
            self.boostActive = False

    def reset(self):
        self.chassisNP.setP(0)
        self.chassisNP.setR(0)

    def processInput(self, inputState, dt):
        # print self.chassisNP.getPos()
        #print self.chassisNP.getH()
        """Use controls to update the player's car"""
        # For keyboard throttle and brake are either 0 or 1
        self.checkDisableBoost()
        if inputState.isSet('forward'):
            self.vehicleControlState["throttle"] = 1.0
        else:
            self.vehicleControlState["throttle"] = 0.0

        velocity = self.chassisNode.getLinearVelocity()
        speed = math.sqrt(sum(v ** 2 for v in velocity))
        self.speed = speed
        # Update braking and reversing
        if inputState.isSet('brake'):
            if speed < 0.5 or self.vehicleControlState["reverse"]:
                # If we're stopped, then start reversing
                # Also keep reversing if we already were
                self.vehicleControlState["reverse"] = True
                self.vehicleControlState["throttle"] = 1.0
                self.vehicleControlState["brake"] = 0.0
            else:
                self.vehicleControlState["reverse"] = False
                self.vehicleControlState["brake"] = 1.0
        else:
            self.vehicleControlState["reverse"] = False
            self.vehicleControlState["brake"] = 0.0

        # steering is normalised from -1 to 1, corresponding
        # to the steering lock right and left
        steering = self.vehicleControlState["steering"]
        if inputState.isSet('left'):
            steering += dt * self.steeringRate
            steering = min(steering, 1.0)
        elif inputState.isSet('right'):
            steering -= dt * self.steeringRate
            steering = max(steering, -1.0)
        else:
            # gradually re-center the steering
            if steering > 0.0:
                steering -= dt * self.centreingRate
                if steering < 0.0:
                    steering = 0.0
            elif steering < 0.0:
                steering += dt * self.centreingRate
                if steering > 0.0:
                    steering = 0.0
        self.vehicleControlState["steering"] = steering

        # """Updates acceleration, braking and steering
        # These are all passed in through a controlState dictionary
        # """
        # Update acceleration and braking
        self.reversing = self.vehicleControlState["reverse"]
        brakeForce = self.vehicleControlState["brake"] * self.specs["brakeForce"]

        if self.reversing and self.speed > self.specs["maxReverseSpeed"]:
            self.applyForcesAndSteering(steering, 0, brakeForce)
            return
        if not self.reversing and self.speed > self.specs["maxSpeed"]:
            self.applyForcesAndSteering(steering, 0, brakeForce)
            return

        wheelForce = self.vehicleControlState["throttle"] * self.specs["maxWheelForce"]

        if self.reversing:
            # Make reversing a bit slower than moving forward
            wheelForce *= -0.5

        # Update steering
        # Steering control state is from -1 to 1
        steering = self.vehicleControlState["steering"] * self.specs["steeringLock"]
        if self.boostActive:
            wheelForce *= self.boostFactor
        self.applyForcesAndSteering(steering, wheelForce, brakeForce)
        return [steering, wheelForce, brakeForce]

    def getSpeed(self):
        velocity = self.chassisNode.getLinearVelocity()
        speed = math.sqrt(sum(v ** 2 for v in velocity))
        return speed, speed/self.specs["maxSpeed"]

    def getBoost(self):
        maxBoost = 3.0
        currentScaledBoost = self.boostCount / maxBoost
        return currentScaledBoost

    def updateHealth(self, damage):
        self.vehicleControlState["health"] -= 0.25
        if self.vehicleControlState["health"] <= 0.0:
            self.killVehicle("Lost health")

    def killVehicle(self, reason = ""):
        print "Sent request to server for killing this player because: ", reason

    def updateMovement(self, move, dt):
        """Use controls to update the player's car"""
        # For keyboard throttle and brake are either 0 or 1
        if move == 'f':
            self.vehicleControlState["throttle"] = 1.0
        else:
            self.vehicleControlState["throttle"] = 0.0

        velocity = self.chassisNode.getLinearVelocity()
        speed = math.sqrt(sum(v ** 2 for v in velocity))
        # Update braking and reversing
        if move == 'b':
            if speed < 0.5 or self.vehicleControlState["reverse"]:
                # If we're stopped, then start reversing
                # Also keep reversing if we already were
                self.vehicleControlState["reverse"] = True
                self.vehicleControlState["throttle"] = 1.0
                self.vehicleControlState["brake"] = 0.0
            else:
                self.vehicleControlState["reverse"] = False
                self.vehicleControlState["brake"] = 1.0
        else:
            self.vehicleControlState["reverse"] = False
            self.vehicleControlState["brake"] = 0.0

        # steering is normalised from -1 to 1, corresponding
        # to the steering lock right and left
        steering = self.vehicleControlState["steering"]
        if move == 'l':
            steering += dt * self.steeringRate
            steering = min(steering, 1.0)
        elif move == 'r':
            steering -= dt * self.steeringRate
            steering = max(steering, -1.0)
        else:
            # gradually re-center the steering
            if steering > 0.0:
                steering -= dt * self.centreingRate
                if steering < 0.0:
                    steering = 0.0
            elif steering < 0.0:
                steering += dt * self.centreingRate
                if steering > 0.0:
                    steering = 0.0
        self.vehicleControlState["steering"] = steering

        # """Updates acceleration, braking and steering
        # These are all passed in through a controlState dictionary
        # """
        # Update acceleration and braking
        wheelForce = self.vehicleControlState["throttle"] * self.specs["maxWheelForce"]
        self.reversing = self.vehicleControlState["reverse"]
        if self.reversing:
            # Make reversing a bit slower than moving forward
            wheelForce *= -0.5

        brakeForce = self.vehicleControlState["brake"] * self.specs["brakeForce"]

        # Update steering
        # Steering control state is from -1 to 1
        steering = self.vehicleControlState["steering"] * self.specs["steeringLock"]

        self.applyForcesAndSteering(steering, wheelForce, brakeForce)

        return [steering, wheelForce, brakeForce]

    def setVehiclePos(self, x,y, z, h, p, r):
        #self.chassisNP.setX(x)
        #self.chassisNP.setY(y)
        #self.chassisNP.setP(p)
        #self.chassisNP.setR(r)
        self.chassisNP.setPosHpr(x, y, z, h, p, r)
        return

    def setupVehicle(self, main):
        scale = 0.5
        # Chassis
        shape = BulletBoxShape(Vec3(0.6, 1.4, 0.5))
        ts = TransformState.makePos(Point3(0, 0, 0.5 * scale))

        name = self.username
        self.chassisNode = BulletRigidBodyNode(name)
        self.chassisNode.setTag('username', str(name))
        self.chassisNP = main.worldNP.attachNewNode(self.chassisNode)
        self.chassisNP.setName(str(name))
        self.chassisNP.node().addShape(shape, ts)
        self.chassisNP.setScale(scale)

        self.chassisNP.setPos(self.pos)
        if self.isCurrentPlayer:
            self.chassisNP.node().notifyCollisions(True)
            self.chassisNP.node().setMass(800.0)
        else:
            self.chassisNP.node().notifyCollisions(True)
            self.chassisNP.node().setMass(400.0)
        self.chassisNP.node().setDeactivationEnabled(False)

        main.world.attachRigidBody(self.chassisNP.node())

        #np.node().setCcdSweptSphereRadius(1.0)
        #np.node().setCcdMotionThreshold(1e-7)

        # Vehicle
        self.vehicle = BulletVehicle(main.world, self.chassisNP.node())
        self.vehicle.setCoordinateSystem(ZUp)
        main.world.attachVehicle(self.vehicle)

        self.yugoNP = loader.loadModel('models/yugo/yugo.egg')
        self.yugoNP.reparentTo(self.chassisNP)

        #self.carNP = loader.loadModel('models/batmobile-chassis.egg')
        #self.yugoNP.setScale(.7)
        #self.carNP.reparentTo(self.chassisNP)

        # Right front wheel
        np = loader.loadModel('models/yugo/yugotireR.egg')
        np.reparentTo(main.worldNP)
        self.addWheel(Point3( 0.70 * scale,  1.05 * scale, 0.3), True, np)

        # Left front wheel
        np = loader.loadModel('models/yugo/yugotireL.egg')
        np.reparentTo(main.worldNP)
        self.addWheel(Point3(-0.70 * scale,  1.05 * scale, 0.3), True, np)

        # Right rear wheel
        np = loader.loadModel('models/yugo/yugotireR.egg')
        np.reparentTo(main.worldNP)
        self.addWheel(Point3( 0.70 * scale, -1.05 * scale, 0.3), False, np)

        # Left rear wheel
        np = loader.loadModel('models/yugo/yugotireL.egg')
        np.reparentTo(main.worldNP)
        self.addWheel(Point3(-0.70 * scale, -1.05 * scale, 0.3), False, np)

    def addWheel(self, pos, front, np):
        wheel = self.vehicle.createWheel()

        wheel.setNode(np.node())
        wheel.setChassisConnectionPointCs(pos)
        wheel.setFrontWheel(front)

        wheel.setWheelDirectionCs(Vec3(0, 0, -1))
        wheel.setWheelAxleCs(Vec3(1, 0, 0))
        wheel.setWheelRadius(0.25)
        wheel.setMaxSuspensionTravelCm(40.0)

        wheel.setSuspensionStiffness(40.0)
        wheel.setWheelsDampingRelaxation(2.3)
        wheel.setWheelsDampingCompression(4.4)
        wheel.setFrictionSlip(100.0);
        wheel.setRollInfluence(0.1)


    def reset(self):
        #self.chassisNP.setP(0)
        #self.chassisNP.setR(0)
        #print "kegwe", self.chassisNP.getX(),self.chassisNP.getY(),self.chassisNP.getZ(),self.chassisNP.getH(),0,0
        self.chassisNP.setPosHpr(self.chassisNP.getX(),self.chassisNP.getY(),self.chassisNP.getZ(),self.chassisNP.getH(),0,0)


    def pickedPowerup(self, powerup):
        if not powerup.pickable:
            powerup.useAbility()
        else:
            if self.currentPowerups["powerup1"] is None:
                self.currentPowerups["powerup1"] = powerup
            elif self.currentPowerups["powerup2"] is None:
                self.currentPowerups["powerup2"] = powerup
            elif self.currentPowerups["powerup3"] is None:
                self.currentPowerups["powerup3"] = powerup


    def canPickUpPowerup(self):
        return (self.currentPowerups["powerup1"] is None or
                self.currentPowerups["powerup2"] is None or
                self.currentPowerups["powerup3"] is None)


    def usePowerup(self, powerupIndex):
        # Move usePowerupN to this function
        if powerupIndex == 0 and self.currentPowerups["powerup1"] is not None:
            self.currentPowerups["powerup1"].useAbility()
            self.currentPowerups["powerup1"] = None
        elif powerupIndex == 1 and self.currentPowerups["powerup2"] is not None:
            self.currentPowerups["powerup2"].useAbility()
            self.currentPowerups["powerup2"] = None
        elif powerupIndex == 2 and self.currentPowerups["powerup3"] is not None:
            self.currentPowerups["powerup3"].useAbility()
            self.currentPowerups["powerup3"] = None
Ejemplo n.º 2
0
class Vehicle(object):
    COUNT = 0

    def __init__(self, bulletWorld, pos, username, isMainChar=False):
        self.specs = {
            "mass": 400.0,
            "maxWheelForce": 2000.0,
            "brakeForce": 100.0,
            "steeringLock": 45.0
        }
        self.vehicleControlState = {
            "throttle": 0,
            "reverse": False,
            "brake": 0.0,
            "steering": 0.0
        }
        self.username = username
        self.isMainChar = isMainChar
        # Steering change per second, normalised to steering lock
        # Eg. 45 degrees lock and 1.0 rate means 45 degrees per second
        self.steeringRate = 0.8
        self.centreingRate = 1.2

        self.pos = pos

        self.currentPowerups = {
            "powerup1": None,
            "powerup2": None,
            "powerup3": None
        }

        self.setupVehicle(bulletWorld)
        self.startTime = time.time()
        COUNT = 1

    def move(self, steering, wheelForce, brakeForce, x, y, z, h, p, r):
        self.applyForcesAndSteering(steering, wheelForce, brakeForce)
        self.endTime = time.time()
        #print self.endTime
        elapsed = self.endTime - self.startTime
        #if elapsed > .1:
        #print "Set Pos Now"
        self.setVehiclePos(x, y, z, h, p, r)
        self.startTime = self.endTime
        #print "Do Move"

    def applyForcesAndSteering(self, steering, wheelForce, brakeForce):
        # Apply steering to front wheels
        self.vehicle.setSteeringValue(steering, 0)
        self.vehicle.setSteeringValue(steering, 1)
        # Apply engine and brake to rear wheels
        self.vehicle.applyEngineForce(wheelForce, 2)
        self.vehicle.applyEngineForce(wheelForce, 3)
        self.vehicle.setBrake(brakeForce, 2)
        self.vehicle.setBrake(brakeForce, 3)

    def processInput(self, inputState, dt):
        # print self.chassisNP.getPos()
        #print self.chassisNP.getH()
        """Use controls to update the player's car"""
        # For keyboard throttle and brake are either 0 or 1
        if inputState.isSet('forward'):
            self.vehicleControlState["throttle"] = 1.0
        else:
            self.vehicleControlState["throttle"] = 0.0

        velocity = self.chassisNode.getLinearVelocity()
        speed = math.sqrt(sum(v**2 for v in velocity))
        # Update braking and reversing
        if inputState.isSet('brake'):
            if speed < 0.5 or self.vehicleControlState["reverse"]:
                # If we're stopped, then start reversing
                # Also keep reversing if we already were
                self.vehicleControlState["reverse"] = True
                self.vehicleControlState["throttle"] = 1.0
                self.vehicleControlState["brake"] = 0.0
            else:
                self.vehicleControlState["reverse"] = False
                self.vehicleControlState["brake"] = 1.0
        else:
            self.vehicleControlState["reverse"] = False
            self.vehicleControlState["brake"] = 0.0

        # steering is normalised from -1 to 1, corresponding
        # to the steering lock right and left
        steering = self.vehicleControlState["steering"]
        if inputState.isSet('left'):
            steering += dt * self.steeringRate
            steering = min(steering, 1.0)
        elif inputState.isSet('right'):
            steering -= dt * self.steeringRate
            steering = max(steering, -1.0)
        else:
            # gradually re-center the steering
            if steering > 0.0:
                steering -= dt * self.centreingRate
                if steering < 0.0:
                    steering = 0.0
            elif steering < 0.0:
                steering += dt * self.centreingRate
                if steering > 0.0:
                    steering = 0.0
        self.vehicleControlState["steering"] = steering

        # """Updates acceleration, braking and steering
        # These are all passed in through a controlState dictionary
        # """
        # Update acceleration and braking
        wheelForce = self.vehicleControlState["throttle"] * self.specs[
            "maxWheelForce"]
        self.reversing = self.vehicleControlState["reverse"]
        if self.reversing:
            # Make reversing a bit slower than moving forward
            wheelForce *= -0.5

        brakeForce = self.vehicleControlState["brake"] * self.specs[
            "brakeForce"]

        # Update steering
        # Steering control state is from -1 to 1
        steering = self.vehicleControlState["steering"] * self.specs[
            "steeringLock"]

        self.applyForcesAndSteering(steering, wheelForce, brakeForce)

        return [steering, wheelForce, brakeForce]

    def setVehiclePos(self, x, y, z, h, p, r):
        self.chassisNP.setPosHpr(x, y, z, h, p, r)

    def setupVehicle(self, bulletWorld):
        # Chassis
        shape = BulletBoxShape(Vec3(1, 2.2, 0.5))
        ts = TransformState.makePos(Point3(0, 0, .7))
        if self.isMainChar:
            self.chassisNode = BulletRigidBodyNode(self.username)
        else:
            self.chassisNode = BulletRigidBodyNode('vehicle')
        self.chassisNode.setTag("username", str(self.username))

        self.chassisNP = render.attachNewNode(self.chassisNode)
        self.chassisNP.node().addShape(shape, ts)
        if self.isMainChar:
            self.chassisNP.node().notifyCollisions(True)
        else:
            self.chassisNP.node().notifyCollisions(False)
        self.setVehiclePos(self.pos[0], self.pos[1], self.pos[2], self.pos[3],
                           self.pos[4], self.pos[5])
        # self.chassisNP.setPos(-5.34744, 114.773, 6)
        #self.chassisNP.setPos(49.2167, 64.7968, 10)
        self.chassisNP.node().setMass(800.0)
        self.chassisNP.node().setDeactivationEnabled(False)

        bulletWorld.attachRigidBody(self.chassisNP.node())

        #np.node().setCcdSweptSphereRadius(1.0)
        #np.node().setCcdMotionThreshold(1e-7)

        # Vehicle
        self.vehicle = BulletVehicle(bulletWorld, self.chassisNP.node())
        self.vehicle.setCoordinateSystem(ZUp)
        bulletWorld.attachVehicle(self.vehicle)

        self.carNP = loader.loadModel('models/batmobile-chassis.egg')
        #self.yugoNP.setScale(.7)
        self.carNP.reparentTo(self.chassisNP)

        # Right front wheel
        np = loader.loadModel('models/batmobile-wheel-right.egg')
        np.reparentTo(render)
        self.addWheel(Point3(1, 1.1, .7), True, np)

        # Left front wheel
        np = loader.loadModel('models/batmobile-wheel-left.egg')
        np.reparentTo(render)
        self.addWheel(Point3(-1, 1.1, .7), True, np)

        # Right rear wheel
        np = loader.loadModel('models/batmobile-wheel-right.egg')
        np.reparentTo(render)
        self.addWheel(Point3(1, -2, .7), False, np)

        # Left rear wheel
        np = loader.loadModel('models/batmobile-wheel-left.egg')
        np.reparentTo(render)
        self.addWheel(Point3(-1, -2, .7), False, np)

    def addWheel(self, pos, front, np):
        wheel = self.vehicle.createWheel()

        wheel.setNode(np.node())
        wheel.setChassisConnectionPointCs(pos)
        wheel.setFrontWheel(front)

        wheel.setWheelDirectionCs(Vec3(0, 0, -1))
        wheel.setWheelAxleCs(Vec3(1, 0, 0))
        wheel.setWheelRadius(0.33)
        wheel.setMaxSuspensionTravelCm(40.0)

        wheel.setSuspensionStiffness(40.0)
        wheel.setWheelsDampingRelaxation(2.3)
        wheel.setWheelsDampingCompression(4.4)
        wheel.setFrictionSlip(100.0)
        wheel.setRollInfluence(0.1)

    def reset(self):
        self.chassisNP.setP(0)
        self.chassisNP.setR(0)

    def pickedPowerup(self, powerup):
        if not powerup.pickable:
            powerup.useAbility()
        else:
            if self.currentPowerups["powerup1"] is None:
                self.currentPowerups["powerup1"] = powerup
            elif self.currentPowerups["powerup2"] is None:
                self.currentPowerups["powerup2"] = powerup
            elif self.currentPowerups["powerup3"] is None:
                self.currentPowerups["powerup3"] = powerup

    def canPickUpPowerup(self):
        return (self.currentPowerups["powerup1"] is None
                or self.currentPowerups["powerup2"] is None
                or self.currentPowerups["powerup3"] is None)

    def usePowerup(self, powerupIndex):
        # Move usePowerupN to this function
        if powerupIndex == 0 and self.currentPowerups["powerup1"] is not None:
            self.currentPowerups["powerup1"].useAbility()
            self.currentPowerups["powerup1"] = None
        elif powerupIndex == 1 and self.currentPowerups["powerup2"] is not None:
            self.currentPowerups["powerup2"].useAbility()
            self.currentPowerups["powerup2"] = None
        elif powerupIndex == 2 and self.currentPowerups["powerup3"] is not None:
            self.currentPowerups["powerup3"].useAbility()
            self.currentPowerups["powerup3"] = None
Ejemplo n.º 3
0
class Vehicle(object):
    COUNT = 0

    def __init__(self, bulletWorld, pos, username, isMainChar=False):
        self.specs = {"mass": 400.0, "maxWheelForce": 2000.0, "brakeForce": 100.0, "steeringLock": 45.0}
        self.vehicleControlState = {"throttle": 0, "reverse": False, "brake": 0.0, "steering": 0.0}
        self.username = username
        self.isMainChar = isMainChar
        # Steering change per second, normalised to steering lock
        # Eg. 45 degrees lock and 1.0 rate means 45 degrees per second
        self.steeringRate = 0.8
        self.centreingRate = 1.2

        self.pos = pos

        self.currentPowerups = {"powerup1": None, "powerup2": None, "powerup3": None}

        self.setupVehicle(bulletWorld)
        self.startTime = time.time()
        COUNT = 1

    def move(self, steering, wheelForce, brakeForce, x, y, z, h, p, r):
        self.applyForcesAndSteering(steering, wheelForce, brakeForce)
        self.endTime = time.time()
        #print self.endTime
        elapsed = self.endTime - self.startTime
        #if elapsed > .1:
        #print "Set Pos Now"
        self.setVehiclePos(x, y, z, h, p, r)
        self.startTime = self.endTime
        #print "Do Move"

    def applyForcesAndSteering(self, steering, wheelForce, brakeForce):
        # Apply steering to front wheels
        self.vehicle.setSteeringValue(steering, 0);
        self.vehicle.setSteeringValue(steering, 1);
        # Apply engine and brake to rear wheels
        self.vehicle.applyEngineForce(wheelForce, 2);
        self.vehicle.applyEngineForce(wheelForce, 3);
        self.vehicle.setBrake(brakeForce, 2);
        self.vehicle.setBrake(brakeForce, 3);

    def processInput(self, inputState, dt):
        # print self.chassisNP.getPos()
        #print self.chassisNP.getH()
        """Use controls to update the player's car"""
        # For keyboard throttle and brake are either 0 or 1
        if inputState.isSet('forward'):
            self.vehicleControlState["throttle"] = 1.0
        else:
            self.vehicleControlState["throttle"] = 0.0

        velocity = self.chassisNode.getLinearVelocity()
        speed = math.sqrt(sum(v ** 2 for v in velocity))
        # Update braking and reversing
        if inputState.isSet('brake'):
            if speed < 0.5 or self.vehicleControlState["reverse"]:
                # If we're stopped, then start reversing
                # Also keep reversing if we already were
                self.vehicleControlState["reverse"] = True
                self.vehicleControlState["throttle"] = 1.0
                self.vehicleControlState["brake"] = 0.0
            else:
                self.vehicleControlState["reverse"] = False
                self.vehicleControlState["brake"] = 1.0
        else:
            self.vehicleControlState["reverse"] = False
            self.vehicleControlState["brake"] = 0.0

        # steering is normalised from -1 to 1, corresponding
        # to the steering lock right and left
        steering = self.vehicleControlState["steering"]
        if inputState.isSet('left'):
            steering += dt * self.steeringRate
            steering = min(steering, 1.0)
        elif inputState.isSet('right'):
            steering -= dt * self.steeringRate
            steering = max(steering, -1.0)
        else:
            # gradually re-center the steering
            if steering > 0.0:
                steering -= dt * self.centreingRate
                if steering < 0.0:
                    steering = 0.0
            elif steering < 0.0:
                steering += dt * self.centreingRate
                if steering > 0.0:
                    steering = 0.0
        self.vehicleControlState["steering"] = steering

        # """Updates acceleration, braking and steering
        # These are all passed in through a controlState dictionary
        # """
        # Update acceleration and braking
        wheelForce = self.vehicleControlState["throttle"] * self.specs["maxWheelForce"]
        self.reversing = self.vehicleControlState["reverse"]
        if self.reversing:
            # Make reversing a bit slower than moving forward
            wheelForce *= -0.5

        brakeForce = self.vehicleControlState["brake"] * self.specs["brakeForce"]

        # Update steering
        # Steering control state is from -1 to 1
        steering = self.vehicleControlState["steering"] * self.specs["steeringLock"]

        self.applyForcesAndSteering(steering, wheelForce, brakeForce)

        return [steering, wheelForce, brakeForce]

    def setVehiclePos(self, x,y, z, h, p, r):
        self.chassisNP.setPosHpr(x, y, z, h, p, r)

    def setupVehicle(self, bulletWorld):
        # Chassis
        shape = BulletBoxShape(Vec3(1, 2.2, 0.5))
        ts = TransformState.makePos(Point3(0, 0, .7))
        if self.isMainChar:
            self.chassisNode = BulletRigidBodyNode(self.username)
        else:
            self.chassisNode = BulletRigidBodyNode('vehicle')
        self.chassisNode.setTag("username", str(self.username))

        self.chassisNP = render.attachNewNode(self.chassisNode)
        self.chassisNP.node().addShape(shape, ts)
        if self.isMainChar:
            self.chassisNP.node().notifyCollisions(True)
        else:
            self.chassisNP.node().notifyCollisions(False)
        self.setVehiclePos(self.pos[0], self.pos[1], self.pos[2], self.pos[3], self.pos[4], self.pos[5])
        # self.chassisNP.setPos(-5.34744, 114.773, 6)
        #self.chassisNP.setPos(49.2167, 64.7968, 10)
        self.chassisNP.node().setMass(800.0)
        self.chassisNP.node().setDeactivationEnabled(False)

        bulletWorld.attachRigidBody(self.chassisNP.node())

        #np.node().setCcdSweptSphereRadius(1.0)
        #np.node().setCcdMotionThreshold(1e-7)

        # Vehicle
        self.vehicle = BulletVehicle(bulletWorld, self.chassisNP.node())
        self.vehicle.setCoordinateSystem(ZUp)
        bulletWorld.attachVehicle(self.vehicle)

        self.carNP = loader.loadModel('models/batmobile-chassis.egg')
        #self.yugoNP.setScale(.7)
        self.carNP.reparentTo(self.chassisNP)

        # Right front wheel
        np = loader.loadModel('models/batmobile-wheel-right.egg')
        np.reparentTo(render)
        self.addWheel(Point3(1, 1.1, .7), True, np)

        # Left front wheel
        np = loader.loadModel('models/batmobile-wheel-left.egg')
        np.reparentTo(render)
        self.addWheel(Point3(-1, 1.1, .7), True, np)

        # Right rear wheel
        np = loader.loadModel('models/batmobile-wheel-right.egg')
        np.reparentTo(render)
        self.addWheel(Point3(1, -2, .7), False, np)

        # Left rear wheel
        np = loader.loadModel('models/batmobile-wheel-left.egg')
        np.reparentTo(render)
        self.addWheel(Point3(-1, -2, .7), False, np)


    def addWheel(self, pos, front, np):
        wheel = self.vehicle.createWheel()

        wheel.setNode(np.node())
        wheel.setChassisConnectionPointCs(pos)
        wheel.setFrontWheel(front)

        wheel.setWheelDirectionCs(Vec3(0, 0, -1))
        wheel.setWheelAxleCs(Vec3(1, 0, 0))
        wheel.setWheelRadius(0.33)
        wheel.setMaxSuspensionTravelCm(40.0)

        wheel.setSuspensionStiffness(40.0)
        wheel.setWheelsDampingRelaxation(2.3)
        wheel.setWheelsDampingCompression(4.4)
        wheel.setFrictionSlip(100.0);
        wheel.setRollInfluence(0.1)


    def reset(self):
        self.chassisNP.setP(0)
        self.chassisNP.setR(0)


    def pickedPowerup(self, powerup):
        if not powerup.pickable:
            powerup.useAbility()
        else:
            if self.currentPowerups["powerup1"] is None:
                self.currentPowerups["powerup1"] = powerup
            elif self.currentPowerups["powerup2"] is None:
                self.currentPowerups["powerup2"] = powerup
            elif self.currentPowerups["powerup3"] is None:
                self.currentPowerups["powerup3"] = powerup


    def canPickUpPowerup(self):
        return (self.currentPowerups["powerup1"] is None or
                self.currentPowerups["powerup2"] is None or
                self.currentPowerups["powerup3"] is None)


    def usePowerup(self, powerupIndex):
        # Move usePowerupN to this function
        if powerupIndex == 0 and self.currentPowerups["powerup1"] is not None:
            self.currentPowerups["powerup1"].useAbility()
            self.currentPowerups["powerup1"] = None
        elif powerupIndex == 1 and self.currentPowerups["powerup2"] is not None:
            self.currentPowerups["powerup2"].useAbility()
            self.currentPowerups["powerup2"] = None
        elif powerupIndex == 2 and self.currentPowerups["powerup3"] is not None:
            self.currentPowerups["powerup3"].useAbility()
            self.currentPowerups["powerup3"] = None