def __doThrow(self, alreadyThrown):
     self.weapon.setScale(1)
     pathNP = NodePath('throwPath')
     if not alreadyThrown:
         pathNP.reparentTo(self.suit)
     else:
         pathNP.reparentTo(self.weapon)
     pathNP.setScale(render, 1.0)
     pathNP.setPos(0, 30, -100)
     pathNP.setHpr(90, -90, 90)
     print pathNP.getPos(base.render)
     if self.throwTrajectory:
         self.throwTrajectory.pause()
         self.throwTrajectory = None
     if alreadyThrown:
         startPos = self.weapon.getPos(base.render)
         gravity = 0.7
     else:
         gravity = 0.7
         startPos = self.suit.find('**/joint_Rhold').getPos(base.render)
     self.throwTrajectory = ProjectileInterval(self.weapon, startPos=startPos, endPos=pathNP.getPos(base.render), gravityMult=gravity, duration=3.0)
     self.throwTrajectory.start()
     self.weapon.setScale(10)
     self.weapon.reparentTo(render)
     self.weapon.setHpr(pathNP.getHpr(render))
     self.weapon_state = 'released'
     self.acceptOnce(self.wsnp.node().getName() + '-into', self.__handleHitFloor)
     return
Exemplo n.º 2
0
 def __doThrow(self, alreadyThrown):
     self.weapon.setScale(1)
     pathNP = NodePath('throwPath')
     if not alreadyThrown:
         pathNP.reparentTo(self.suit)
     else:
         pathNP.reparentTo(self.weapon)
     pathNP.setScale(render, 1.0)
     pathNP.setPos(0, 30, -100)
     pathNP.setHpr(90, -90, 90)
     print pathNP.getPos(base.render)
     if self.throwTrajectory:
         self.throwTrajectory.pause()
         self.throwTrajectory = None
     if alreadyThrown:
         startPos = self.weapon.getPos(base.render)
         gravity = 0.7
     else:
         gravity = 0.7
         startPos = self.suit.find('**/joint_Rhold').getPos(base.render)
     self.throwTrajectory = ProjectileInterval(self.weapon, startPos=startPos, endPos=pathNP.getPos(base.render), gravityMult=gravity, duration=3.0)
     self.throwTrajectory.start()
     self.weapon.setScale(10)
     self.weapon.reparentTo(render)
     self.weapon.setHpr(pathNP.getHpr(render))
     self.weapon_state = 'released'
     self.acceptOnce(self.wsnp.node().getName() + '-into', self.__handleHitFloor)
     return
Exemplo n.º 3
0
 def throwObject(self, projectile = True):
     if not self.weapon:
         return
     self.acceptOnce('enter' + self.wsnp.node().getName(), self.handleWeaponCollision)
     self.playWeaponSound()
     if self.weapon:
         self.weapon.wrtReparentTo(render)
         self.weapon.setHpr(Vec3(0, 0, 0))
     if self.attack not in ('glowerpower',):
         parent = self.suit.find('**/joint_Rhold')
     else:
         parent = self.suit.find('**/joint_head')
     startNP = parent.attachNewNode('startNp')
     startNP.lookAt(render, self.targetX, self.targetY, self.targetZ)
     pathNP = NodePath('throwPath')
     pathNP.reparentTo(startNP)
     pathNP.setScale(render, 1.0)
     pathNP.setPos(0, 50, 0)
     if self.attack in ('clipontie', 'powertie', 'halfwindsor'):
         self.weapon.setHpr(pathNP.getHpr(render))
     if projectile == True:
         self.throwTrajectory = ProjectileInterval(self.weapon, startPos=self.suit.find('**/joint_Rhold').getPos(render), endPos=pathNP.getPos(render), gravityMult=0.7, duration=1.0)
     else:
         self.weapon.setH(pathNP.getH(render))
         self.throwTrajectory = LerpPosInterval(self.weapon, duration=0.5, pos=pathNP.getPos(render), startPos=startNP.getPos(render) + (0, 3, 0))
     self.throwTrajectory.start()
     self.weapon_state = 'released'
     startNP.removeNode()
     del startNP
     pathNP.removeNode()
     del pathNP
Exemplo n.º 4
0
class Chaser():
    def __init__(self, geometry, pos, speed=6):
        self.node = NodePath("segment")
        geometry.instance_to(self.node)
        self.node.reparent_to(render)
        self.node.set_pos(pos)
        self.speed = speed
        self.flash = False

    def destroy(self):
        base.chasers.remove(self)
        self.node.remove_node()

    def update(self):
        dt = globalClock.get_dt()
        if base.player.alive:
            vector = base.player.node.getPos() - self.node.getPos()
            distance = vector.get_xy().length()
            if distance < 0.8:
                base.player.die(spider=True)
            vector.normalize()
            if self.flash:
                self.node.set_y(self.node.get_y() + 1)

            self.node.set_pos(self.node.get_pos() + (vector *
                                                     (self.speed * dt)))
            self.node.look_at(base.player.node)
        else:
            self.node.set_pos(self.node, (0, self.speed * dt, 0))
        if self.flash:
            self.flash = False
            self.node.set_color(1, 1, 1, 1)
        else:
            self.node.clear_color()
Exemplo n.º 5
0
 def throw(self, p):
     self.isAirborne = True
     self.owner.avatar.play('pie', partName='torso', fromFrame=60)
     base.playSfx(self.owner.throwSound, node=self.owner.avatar)
     start = NodePath('StartPath')
     start.reparentTo(self.owner.avatar)
     start.setScale(render, 1)
     start.setPos(0, 0, 0)
     start.setP(p)
     end = NodePath('ThrowPath')
     end.reparentTo(start)
     end.setScale(render, 1)
     end.setPos(0, 160, -90)
     end.setHpr(90, -90, 90)
     self.wrtReparentTo(render)
     self.setScale(1.0)
     self.throwIval = ProjectileInterval(
         self,
         startPos=self.owner.avatar.find('**/def_joint_right_hold').getPos(
             render),
         endPos=end.getPos(render),
         gravityMult=0.9,
         duration=3)
     self.throwIval.start()
     if self.owner.avId == base.localAvatar.doId:
         self.accept('snowball-coll-' + str(id(self)) + '-into',
                     self.__handleSnowballCollision)
     start.removeNode()
     del start
     end.removeNode()
     del end
 def throwObject(self, projectile=True):
     if not self.weapon:
         return
     self.acceptOnce('enter' + self.wsnp.node().getName(), self.handleWeaponCollision)
     self.playWeaponSound()
     if self.weapon:
         self.weapon.wrtReparentTo(render)
         self.weapon.setHpr(Vec3(0, 0, 0))
     if self.attack not in ('glowerpower', ):
         parent = self.suit.find('**/joint_Rhold')
     else:
         parent = self.suit.find('**/joint_head')
     startNP = parent.attachNewNode('startNp')
     startNP.lookAt(render, self.targetX, self.targetY, self.targetZ)
     pathNP = NodePath('throwPath')
     pathNP.reparentTo(startNP)
     pathNP.setScale(render, 1.0)
     pathNP.setPos(0, 50, 0)
     if self.attack in ('clipontie', 'powertie', 'halfwindsor'):
         self.weapon.setHpr(pathNP.getHpr(render))
     if projectile == True:
         self.throwTrajectory = ProjectileInterval(self.weapon, startPos=self.suit.find('**/joint_Rhold').getPos(render), endPos=pathNP.getPos(render), gravityMult=0.7, duration=1.0)
     else:
         self.weapon.setH(pathNP.getH(render))
         self.throwTrajectory = LerpPosInterval(self.weapon, duration=0.5, pos=pathNP.getPos(render), startPos=startNP.getPos(render) + (0,
                                                                                                                                         3,
                                                                                                                                         0))
     self.throwTrajectory.start()
     self.weapon_state = 'released'
     startNP.removeNode()
     del startNP
     pathNP.removeNode()
     del pathNP
Exemplo n.º 7
0
 def gagRelease(self, task):
     gagRange = NodePath('Gag Range')
     gagRange.reparentTo(self.localAvatar.find('**/joint_nameTag'))
     gagRange.setPos(0, 75, 0)
     gagRange.setHpr(90, -90, 90)
     if self.gag == None:
         gagRange.removeNode()
         base.taskMgr.doMethodLater(0.1, self.enableThrowing, 'Enable Gag Throw')
         return
     else:
         if self.height > 1:
             grav = 0.7 + self.height / 10
         else:
             grav = 0.7
         if self.height > 5.2:
             base.taskMgr.add(self.enableThrowing, 'Enable Gag Throw')
             return
         self.gag.reparentTo(render)
         self.gag.setHpr(gagRange.getHpr(render))
         self.gagMgr.getGagByName(self.currentGag).addCollision(self.gag)
         handJoint = self.localAvatar.find('**/def_joint_right_hold')
         startPos = Vec3(handJoint.getPos(render).getX(), handJoint.getPos(render).getY(), handJoint.getPos(render).getZ() + 0.8)
         self.projectile = ProjectileInterval(self.gag, startPos=startPos, endPos=gagRange.getPos(render), duration=1, gravityMult=grav)
         self.projectile.start()
         SoundBank.getSound('pie_throw').play()
         base.taskMgr.doMethodLater(0.8, self.enableThrowing, 'Enable Gag Throw')
         base.taskMgr.doMethodLater(2, self.destroyGag, 'Destroy Gag', extraArgs = [self.gag, self.projectile], appendTask = True)
         base.accept('delete-up', self.null)
         base.accept('p-up', self.null)
         self.throwingPie = False
         return Task.done
 def enterFly(self):
     self.acceptOnce(EGG.EAGLE_HIT_EVENT, self.__handleEagleHit)
     self.__setupCamera()
     cannon = self.cr.doId2do.get(self.cannonId)
     base.localAvatar.b_lookAtObject(0, 0, 0, blink=0)
     base.localAvatar.b_setAnimState('swim')
     dummyNode = NodePath('dummyNode')
     dummyNode.reparentTo(base.localAvatar)
     dummyNode.setPos(0, 160, -90)
     base.localAvatar.setPos(base.localAvatar.getPos(render))
     base.localAvatar.setHpr(cannon.find(self.cannonBarrel).getHpr(render))
     base.localAvatar.reparentTo(render)
     self.flyProjectile = FlightProjectileInterval(
         base.localAvatar,
         startPos=cannon.find(self.cannonBarrel).getPos(render) +
         (0, 5.0, 0),
         endPos=dummyNode.getPos(render),
         duration=5.0,
         name='DEagleGame-localAvatarFly',
         gravityMult=.25)
     self.flyProjectile.setDoneEvent(self.flyProjectile.getName())
     self.acceptOnce(self.flyProjectile.getDoneEvent(),
                     self.__handleMissedEagle)
     self.flyProjectile.start()
     dummyNode.removeNode()
     del dummyNode
     self.cannonId = None
     del cannon
     base.localAvatar.startPosHprBroadcast()
     base.localAvatar.d_broadcastPositionNow()
Exemplo n.º 9
0
    def throw(self):
        if not self.gag and not self.isLocal():
            self.setHandJoint()
            self.build()
        if self.gag and self.getLocation():
            self.startEntity()
        elif self.gag and self.trapMode == 1:
            throwPath = NodePath('ThrowPath')
            throwPath.reparentTo(self.avatar)
            throwPath.setScale(render, 1)
            throwPath.setPos(0, 160, -120)
            throwPath.setHpr(0, 90, 0)

            self.gag.setScale(self.gag.getScale(render))
            self.gag.reparentTo(render)
            self.gag.setHpr(throwPath.getHpr(render))

            self.setHandJoint()
            self.track = ProjectileInterval(
                self.gag,
                startPos=self.handJoint.getPos(render),
                endPos=throwPath.getPos(render),
                gravityMult=0.9,
                duration=3)
            self.track.start()
            self.buildProjCollisions()
            self.reset()
            self.avatar.acceptOnce('projSensor-into', self.onProjCollision)
Exemplo n.º 10
0
 def shoot(self, rangeVector):
     if not self.gag:
         return
     rangeNode = NodePath('Shoot Range')
     rangeNode.reparentTo(self.turret.getCannon())
     rangeNode.setScale(render, 1)
     rangeNode.setPos(rangeVector)
     rangeNode.setHpr(90, -90, 90)
     self.gag.setScale(self.gag.getScale(render))
     self.gag.setScale(self.gag.getScale(render))
     self.gag.setPos(self.gag.getPos(render))
     self.gag.reparentTo(render)
     self.gag.setHpr(rangeNode.getHpr(render))
     base.audio3d.attachSoundToObject(self.gagClass.woosh, self.gag)
     self.gagClass.woosh.play()
     self.track = ProjectileInterval(self.gag,
                                     startPos=self.gag.getPos(render),
                                     endPos=rangeNode.getPos(render),
                                     gravityMult=self.gravityMult,
                                     duration=self.duration,
                                     name=self.trackName)
     self.track.setDoneEvent(self.track.getName())
     self.acceptOnce(self.track.getDoneEvent(), self.cleanup)
     self.track.start()
     fireSfx = base.audio3d.loadSfx(
         'phase_4/audio/sfx/MG_cannon_fire_alt.ogg')
     base.audio3d.attachSoundToObject(fireSfx, self.turret.getCannon())
     fireSfx.play()
     if self.turret.isLocal():
         self.buildCollisions()
         self.acceptOnce(self.eventName, self.handleCollision)
Exemplo n.º 11
0
 def makeNew(self, pos, nor, parent=None):
     """Makes a new bullet hole."""
     if parent == None:
         parent = self.container
     else:
         # Add a subnode to the parent, if it's not already there
         child = parent.find('bullet-holes')
         if child.isEmpty():
             parent = parent.attachNewNode('bullet-holes')
         else:
             parent = child
     newhole = NodePath(self.card.generate())
     newhole.reparentTo(parent)
     newhole.lookAt(render, Point3(newhole.getPos(render) - nor))
     newhole.setR(newhole, random() * 360.0)
     newhole.setPos(render, pos)
     # Offset it a little to avoid z-fighting
     # Increase this value if you still see it.
     newhole.setY(newhole, -.001 - random() * 0.01)
     del newhole
     # We don't want one batch per bullet hole, so flatten it.
     # This could be made smarter to preserve culling, but
     # I have yet to see a performance loss.
     # The clearTexture() is a necessary hack.
     parent.clearTexture()
     parent.flattenStrong()
     parent.setTexture(self.texture)
     parent.setTransparency(TransparencyAttrib.MDual)
     parent.setShaderOff(1)
     parent.hide(BitMask32.bit(
         2))  # Invisible to volumetric lighting camera (speedup)
     parent.hide(BitMask32.bit(3))  # Invisible to shadow cameras (speedup)
    def release(self):
        throwPath = NodePath('ThrowPath')
        throwPath.reparentTo(self.avatar)
        throwPath.setScale(render, 1)
        throwPath.setPos(0, 160, -120)
        throwPath.setHpr(0, 90, 0)

        if not self.gag:
            self.build()

        self.entity = self.gag
        self.gag = None
        self.entity.wrtReparentTo(render)
        self.entity.setHpr(throwPath.getHpr(render))

        self.setHandJoint()
        self.track = ProjectileInterval(self.entity,
                                        startPos=self.handJoint.getPos(render),
                                        endPos=throwPath.getPos(render),
                                        gravityMult=0.9,
                                        duration=3)
        self.track.start()

        if self.isLocal():
            self.startTimeout()
            self.buildCollisions()
            self.avatar.acceptOnce('gagSensor-into', self.onCollision)

        self.reset()
        TrapGag.release(self)
 def shoot(self):
     pathNode = NodePath('pathForBullet')
     pathNode.reparentTo(self.gunNozzle)
     pathNode.setPos(0, 10000, 0)
     if self.local:
         pathNode.setPos(self.mg.toonFps.gui.crosshair.getX(render), 10000, 0)
     if self.gunName == 'pistol':
         self.bullet.lookAt(pathNode)
         LerpPosInterval(self.bullet, fluid=1, pos=pathNode.getPos(render), duration=15.0, startPos=self.gunNozzle.getPos(render)).start()
     else:
         if self.gunName == 'shotgun':
             self.bullet.setHpr(self.gunNozzle, random.uniform(89, 91), random.uniform(-1.0, 1.0), 0)
             self.bullet.setPos(self.gunNozzle.getPos(render))
             taskMgr.add(self.fireShotgunBulletTask, 'shotgunBulletTask' + str(id(self)))
         else:
             if self.gunName == 'sniper':
                 self.bullet.setHpr(self.gunNozzle, random.uniform(89, 91), random.uniform(-1.0, 1.0), 0)
                 self.bullet.setPos(self.gunNozzle.getPos(render))
                 taskMgr.add(self.fireSniperBulletTask, 'snipergunBulletTask' + str(id(self)))
     if self.local:
         self.acceptOnce('bulletCollNode-' + str(id(self)) + '-into', self.handleCollision)
     self.removeTrack = Sequence()
     self.removeTrack.append(Wait(10.0))
     self.removeTrack.append(Func(self.deleteBullet))
     self.removeTrack.start()
     taskMgr.add(self.calculateDamage, 'calculateBulletDamage' + str(id(self)))
Exemplo n.º 14
0
 def __init__(self, toon, mg):
     self.mg = mg
     self.toon = toon
     self.splat = Actor(GagGlobals.SPLAT_MDL,
                        {'chan': GagGlobals.SPLAT_CHAN})
     self.splat.setScale(0.5)
     self.splat.setColor(
         VBase4(250.0 / 255.0, 241.0 / 255.0, 24.0 / 255.0, 1.0))
     self.splat.setBillboardPointEye()
     self.gc = WholeCreamPie()
     self.gc.build()
     self.gag = self.gc.getGag()
     self.toon.play('toss', fromFrame=60, toFrame=85)
     self.gag.reparentTo(self.toon.find('**/def_joint_right_hold'))
     throwPath = NodePath('ThrowPath')
     throwPath.reparentTo(self.toon)
     throwPath.setScale(render, 1)
     throwPath.setPos(0, 150, -90)
     throwPath.setHpr(90, -90, 90)
     self.gag.wrtReparentTo(render)
     self.gag.setHpr(throwPath.getHpr(render))
     self.track = ProjectileInterval(
         self.gag,
         startPos=self.toon.find('**/def_joint_right_hold').getPos(render),
         endPos=throwPath.getPos(render),
         gravityMult=0.9,
         duration=3)
     self.track.start()
     taskMgr.doMethodLater(3, self.__handleThrowTrackDone,
                           'handleThrowTrackDoneDGP-' + str(hash(self)))
Exemplo n.º 15
0
 def _constrain_axis(self, body):
     """ Apply existing axis constraints to a body."""
     # Set displacements.
     for axis, (f, d) in enumerate(zip(self.axis_constraint_fac,
                                       self.axis_constraint_disp)):
         if not f and not isnan(d):
             nodep = NodePath(body)
             pos = nodep.getPos()
             pos[axis] = d
             nodep.setPos(pos)
     try:
         # Linear and angular factors of 0 mean forces in the
         # corresponding axis are scaled to 0.
         body.setLinearFactor(self.axis_constraint_fac)
         # Angular factors restrict rotation about an axis, so the
         # following logic selects the appropriate axes to
         # constrain.
         s = sum(self.axis_constraint_fac)
         if s == 3.:
             v = self.axis_constraint_fac
         elif s == 2.:
             v = -self.axis_constraint_fac + 1
         else:
             v = Vec3.zero()
         body.setAngularFactor(v)
     except AttributeError:
         # The body was not a rigid body (it didn't have
         # setLinearFactor method).
         pass
Exemplo n.º 16
0
class Camera:
    def __init__(self, vehicle, world):
        self.vehicle = vehicle
        self.world = world
        base.camera.reparentTo(vehicle)
        base.camera.setPos(0, -30, 10)
        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(render)
        self.pos = LPoint3f(0, -30, 6)
        self.cFloater = NodePath(PandaNode("cFloater"))
        self.cFloater.reparentTo(vehicle)
        self.cFloater.setPos(0, -30, 6)
        self.floater.setPos(vehicle.getPos())
        self.floater.setZ(vehicle.getZ() + 2.0)
        base.camera.setPos(self.pos)
        base.camera.setZ(self.floater, self.pos.getZ())
        base.camera.lookAt(self.floater)

    def update(self, vehicle):
        self.floater.setPos(vehicle.getPos())
        self.floater.setZ(vehicle.getZ() + 2.0)
        base.camera.setPos(self.pos)
        base.camera.setZ(self.floater, self.pos.getZ())
        base.camera.lookAt(self.floater)
        if self.pos.getY() < -30 or self.pos.getZ() > 6 or self.pos.getY() > -6 or self.pos.getZ() < 1:
            self.pos = LPoint3f(0, -30, 6)
        elif self.rayTest() == 1 and self.pos.getY() < -9 and self.pos.getZ() > 1.5:
            self.pos.setY(self.pos.getY() + 0.2)
            self.pos.setZ(self.pos.getZ() - 0.04)
        elif self.rayTest() == 0 and self.pos.getY() > -30 and self.pos.getZ() < 6:
            self.pos.setY(self.pos.getY() - 0.2)
            self.pos.setZ(self.pos.getZ() + 0.04)
        # base.camera.setPos(self.pos)
        # base.camera.setZ(self.floater, self.pos.getZ())
        # base.camera.lookAt(self.floater)

    def rayTest(self):
        frontResult = self.world.rayTestClosest(base.camera.getPos(render), self.floater.getPos())
        rearResult = self.world.rayTestClosest(base.camera.getPos(render), self.cFloater.getPos(render))

        if frontResult.hasHit() and frontResult.getNode().getName() == 'Track':
            return 1
        elif rearResult.hasHit() and rearResult.getNode().getName() == 'Track':
            return -1
        else:
            return 0
Exemplo n.º 17
0
class DamageText():
    """
        Floating damage/healing text that changes color based on whether the
         given value is - (healing) or + (damage).
        Automatically destroys itself after some amount of time.
    """
    def __init__(self, originObj, value, offset=(0, 0, 1)):
        self._root = NodePath('damageText')
        # Offset this text node (most likely to above the origin)
        self._root.setPos(originObj, *offset)
        self._root.reparentTo(base.render)
        # Configure text and assign color:
        font = loader.loadFont(PIERCEROMAN_FONT)
        self._textNode = TextNode('DamageTextText')
        self._textNode.setText(str(value))
        self._textNode.setAlign(TextNode.ACenter)
        self._textNode.setFont(font)
        self._textNodePath = self._root.attachNewNode(self._textNode)
        self._textNodePath.setScale(DAMAGE_TEXT_SCALE)
        self._textNodePath.setColor(self._getColorByValue(value))
        # Set initial physics variables:
        self._dx = random.uniform(-1, 1) * DAMAGE_TEXT_JUMP_VARIATION
        self._dy = random.uniform(-1, 1) * DAMAGE_TEXT_JUMP_VARIATION
        self._dz = DAMAGE_TEXT_INITIAL_JUMP_VELOCITY

        # Make this bar face the camera at all times (bill-boarding):
        self._textNodePath.setBillboardPointEye()

        self._physicsTask = taskMgr.add(self._applyPhysicsTask,
                                        'damagetText_physics')

        # Set the object to die in a constant time:
        taskMgr.doMethodLater(DAMAGE_TEXT_DESPAWN_DELAY, self._destroyTask,
                              'damageText_timedDespawn')

    def _applyPhysicsTask(self, task):
        """ Changes our velocity to simulate physics """
        deltaTime = globalClock.getDt()
        # Start physics simulation on object:
        self._dz += DAMAGE_TEXT_GRAVITY * deltaTime
        newTranslation = LVector3f(self._dx, self._dy, self._dz)
        self._root.setPos(self._root.getPos() + newTranslation)
        return task.cont

    def _getColorByValue(self, value):
        """ Returns a color dependent on value """
        if value < 0:
            return DAMAGE_TEXT_COLOR_HEAL
        elif value == 0:
            return DAMAGE_TEXT_COLOR_NEUTRAL
        else:
            return DAMAGE_TEXT_COLOR_DAMAGE

    def _destroyTask(self, task):
        """ Destroys this object """
        taskMgr.remove(self._physicsTask)  # End the physics task
        self._root.removeNode()
        del self
 def shootOut(self):
     pathNode = NodePath('path')
     pathNode.reparentTo(self.suit)
     pathNode.setPos(0, 50, self.phone.getZ(self.suit))
     self.collNP.reparentTo(render)
     self.shootIval = LerpPosInterval(self.collNP, duration=1.0, pos=pathNode.getPos(render), startPos=self.phone.getPos(render))
     self.shootIval.start()
     pathNode.removeNode()
     del pathNode
Exemplo n.º 19
0
 def shootOut(self):
     pathNode = NodePath('path')
     pathNode.reparentTo(self.suit)
     pathNode.setPos(0, 50, self.phone.getZ(self.suit))
     self.collNP.reparentTo(render)
     self.shootIval = LerpPosInterval(self.collNP, duration=1.0, pos=pathNode.getPos(render), startPos=self.phone.getPos(render))
     self.shootIval.start()
     pathNode.removeNode()
     del pathNode
Exemplo n.º 20
0
 def getSelectionCenter(self):
     if not self.selection:
         return Point3()
     else:
         min, max = Point3(), Point3()
         tmpmin, tmpmax = Point3(), Point3()
         np = NodePath(self.selection[0])
         np.calcTightBounds(min, max)
         min += np.getPos(render) - np.getPos()
         max += np.getPos(render) - np.getPos()
         for i in xrange(1, len(self.selection)):
             np = NodePath(self.selection[i])
             np.calcTightBounds(tmpmin, tmpmax)
             if np.getParent() != render:
                 tmpmin += np.getPos(render) - np.getPos()
                 tmpmax += np.getPos(render) - np.getPos()
             min = min.fmin(tmpmin)
             max = max.fmax(tmpmax)
         return Point3(min + (max - min)/2)
Exemplo n.º 21
0
 def getSelectionCenter(self):
     if not self.selection:
         return Point3()
     else:
         min, max = Point3(), Point3()
         tmpmin, tmpmax = Point3(), Point3()
         np = NodePath(self.selection[0])
         np.calcTightBounds(min, max)
         min += np.getPos(render) - np.getPos()
         max += np.getPos(render) - np.getPos()
         for i in xrange(1, len(self.selection)):
             np = NodePath(self.selection[i])
             np.calcTightBounds(tmpmin, tmpmax)
             if np.getParent() != render:
                 tmpmin += np.getPos(render) - np.getPos()
                 tmpmax += np.getPos(render) - np.getPos()
             min = min.fmin(tmpmin)
             max = max.fmax(tmpmax)
         return Point3(min + (max - min) / 2)
Exemplo n.º 22
0
class Flower():
    def __init__(self, pos):
        self.node = NodePath("flower")
        base.models["misc"]["flower"].instance_to(self.node)
        self.node.reparent_to(render)
        self.node.set_pos(pos)
        base.flowers.append(self)
        base.announce(choice(("here_comes_flower", "little_flower")))
        self.time = 0
        self.flowerpower = 3

    def destroy(self):
        base.flowers.remove(self)
        self.node.remove_node()

    def update(self):
        self.node.set_scale(self.node.get_scale() - globalClock.get_dt() / 15)
        scale = self.node.get_scale().x
        if scale <= 0.1:
            self.destroy()
            return
        for mine in base.mines:
            vector = mine.node.getPos() - self.node.getPos()
            distance = vector.get_xy().length()
            if distance < 0.5:
                mine.destroy()
        self.node.set_h(self.node.get_h() + 1)
        vector = base.player.node.getPos() - self.node.getPos()
        distance = vector.get_xy().length()
        if distance < 1:
            Score(self.node.get_pos(), "1000")
            base.sounds["2d"]["zap_b"].play()
            self.destroy()
            base.announce(choice(("flower_power", "butterzapper_recharge")))
            base.player.flowerpower = self.flowerpower * scale
            base.player.zapping = self.flowerpower * scale
Exemplo n.º 23
0
 def jump(self, extraArg):
     intoName = extraArg.getIntoNode().getName().lower()
     if not "floor" in intoName and not "plate" in intoName:
         return
     # setup the projectile interval
     startPos = self.player.getPos()
     self.jumpstartFloater.setPos(self.player, 0, 0.5, 0)
     tempFloater = NodePath(PandaNode("tempJumpFloater"))
     tempFloater.setPos(self.player, 0, -3.2, 0.1)
     endPos = tempFloater.getPos()
     tempFloater.removeNode()
     self.jumpInterval = ProjectileInterval(
         self.player, startPos=startPos, endPos=endPos, duration=1.5, gravityMult=0.25
     )
     self.request("Jump")
     self.jumpInterval.start()
Exemplo n.º 24
0
def getCirclePoints(centerP, radius, normalVec, nbSides, angleStart = 0.0, angleEnd = 360.0):
	nCenter = NodePath("center")
	n0 = NodePath("tempRotator0")
	n1 = NodePath("tempRotator1")
	n2 = NodePath("tempRotator2")
	
	n0.setPos(centerP)
	n1.setPos(centerP + normalVec)
	
	n0.lookAt(n1)
	n2.reparentTo(n0)
	n2.setPos(0, 0, radius)
	dAngle = float(angleEnd-angleStart) / nbSides
	res = []
	for i in range(nbSides+1):
		n0.setR(angleStart + i*dAngle)
		res.append(n2.getPos(nCenter))
	return res
Exemplo n.º 25
0
class Mine():
    def __init__(self, pos):
        self.time = 0
        self.node = NodePath("mine")
        self.cross = NodePath("cross")
        base.models["misc"]["egg"].instance_to(self.node)
        self.node.reparent_to(render)
        self.cross.reparent_to(render)
        self.node.set_pos(pos)
        self.cross.set_pos(pos)
        base.mines.append(self)
        self.blown = False

    def destroy(self):
        Explosion(base.models["misc"]["explosion_a"], self.node.get_pos())
        base.mines.remove(self)
        self.node.remove_node()
        self.cross.remove_node()

    def update(self):
        self.time += globalClock.get_dt()
        if self.time > 1:
            if not self.blown:
                base.sounds["2d"]["lines"].set_loop(True)
                base.sounds["2d"]["lines"].play()
                self.blown = True
                base.models["lines"]["cross"].instance_to(self.cross)
            self.cross.set_scale(self.cross.get_scale() + 0.2)
            self.cross.set_color((0, 1, 0, 1))
            # Hittest with player
            x, y, z = self.node.get_pos()
            s = self.cross.get_scale()
            px, py, pz = base.player.node.get_pos()
            width = 0.2
            if (x < px + width and x > px - width) or (y < py + width
                                                       and y > py - width):
                vector = base.player.node.getPos() - self.node.getPos()
                distance = vector.get_xy().length()
                if distance < s:
                    base.player.die()
        if self.time > 5:
            self.destroy()
            return
Exemplo n.º 26
0
    def release(self):
        Gag.release(self)
        base.audio3d.attachSoundToObject(self.woosh, self.gag)
        base.playSfx(self.woosh, node=self.gag)

        throwPath = NodePath('ThrowPath')
        throwPath.reparentTo(self.avatar)
        throwPath.setScale(render, 1)
        throwPath.setPos(0, self.power, -90)
        throwPath.setHpr(90, -90, 90)

        entity = self.gag

        if not entity:
            entity = self.build()

        entity.wrtReparentTo(render)
        entity.setHpr(throwPath.getHpr(render))
        self.gag = None

        if not self.handJoint:
            self.handJoint = self.avatar.find('**/def_joint_right_hold')

        track = ProjectileInterval(entity,
                                   startPos=self.handJoint.getPos(render),
                                   endPos=throwPath.getPos(render),
                                   gravityMult=0.9,
                                   duration=3)
        event = self.avatar.uniqueName('throwIvalDone') + '-' + str(
            hash(entity))
        track.setDoneEvent(event)
        base.acceptOnce(event, self.__handlePieIvalDone, [entity])
        track.start()
        self.entities.append([entity, track])
        if self.isLocal():
            self.buildCollisions(entity)
            base.localAvatar.sendUpdate('usedGag', [self.id])
        self.reset()
Exemplo n.º 27
0
    def save(self, filePath=None):
        if filePath == None:
            filePath = self.fromFile

        config = []
        for element in self.elements:
            np = NodePath(element)
            
            od = {}

            od["type"] = element.getTypeName()
            od["pos"] = tuple(np.getPos())
            od["rot"] = tuple(np.getHpr())

            if element.getSkin() is not None:
                od["skin"] = element.getSkin()

            if element.getTypeName() == "Pinger":
                od["frequency"] = element.pinger_frequency

            config.append(od)

        plistlib.writePlist(config, filePath)
Exemplo n.º 28
0
    def save(self, filePath=None):
        if filePath == None:
            filePath = self.fromFile

        config = []
        for element in self.elements:
            np = NodePath(element)

            od = {}

            od["type"] = element.getTypeName()
            od["pos"] = tuple(np.getPos())
            od["rot"] = tuple(np.getHpr())

            if element.getSkin() is not None:
                od["skin"] = element.getSkin()

            if element.getTypeName() == "Pinger":
                od["frequency"] = element.pinger_frequency

            config.append(od)

        plistlib.writePlist(config, filePath)
Exemplo n.º 29
0
def getCirclePoints(centerP,
                    radius,
                    normalVec,
                    nbSides,
                    angleStart=0.0,
                    angleEnd=360.0):
    nCenter = NodePath("center")
    n0 = NodePath("tempRotator0")
    n1 = NodePath("tempRotator1")
    n2 = NodePath("tempRotator2")

    n0.setPos(centerP)
    n1.setPos(centerP + normalVec)

    n0.lookAt(n1)
    n2.reparentTo(n0)
    n2.setPos(0, 0, radius)
    dAngle = float(angleEnd - angleStart) / nbSides
    res = []
    for i in range(nbSides + 1):
        n0.setR(angleStart + i * dAngle)
        res.append(n2.getPos(nCenter))
    return res
Exemplo n.º 30
0
 def releaseBall(self):
   hits = self.rayCollision()
   if hits:
     foundBall = False
     for picked in hits:
       hit_node = picked.getNode()
       if 'ball' in hit_node.getName():
         foundBall = True
         x, y, z = picked.getHitPos()
         bodies = self.world.getRigidBodies()
         for elem in bodies:
           name = elem.getName()
           if name in self.picked:
             # apply some physics
             node = NodePath(elem.getChild(0).getChild(0))
             node_x, node_y, node_z = node.getPos(render)
             ix = (x - node_x)
             iy = (y - node_y)
             dir = atan2(iy, ix)
             dx, dy = SPEED * cos(dir), SPEED * sin(dir)
             elem.applyCentralImpulse(LVector3(dx, dy, z))
             node.setColor(self.ballColors[elem.getName()])
     if foundBall:
       self.picked = set([])
Exemplo n.º 31
0
class ShadowSource(DebugObject, ShaderStructElement):

    """ This class can be seen as a camera. It stores the necessary data to 
    generate and store the shadow map for the assigned lens (like computing the MVP), 
    and also stores information about the shadowmap, like position in the 
    shadow atlas, or resolution. Each ShadowSource has a unique index, 
    which is used by the lights to identify which sources belong to it.
    """

    # Store a global index for assigning unique ids to the instances
    _GlobalShadowIndex = 999

    @classmethod
    def getExposedAttributes(self):
        return {
            "resolution": "int",
            "atlasPos": "vec2",
            "mvp": "mat4",
            "nearPlane": "float",
            "farPlane": "float"
        }

    @classmethod
    def _generateUID(self):
        """ Generates an uid and returns that """
        self._GlobalShadowIndex += 1
        return self._GlobalShadowIndex

    def __init__(self):
        """ Creates a new ShadowSource. After the creation, a lens can be added
        with setupPerspectiveLens or setupOrtographicLens. """
        self.index = self._generateUID()
        DebugObject.__init__(self, "ShadowSource-" + str(self.index))
        ShaderStructElement.__init__(self)

        self.valid = False
        self.camera = Camera("ShadowSource-" + str(self.index))
        self.camera.setActive(False)
        self.cameraNode = NodePath(self.camera)
        self.cameraNode.reparentTo(Globals.render.find("RPCameraDummys"))
        self.cameraNode.hide()
        self.resolution = 512
        self.atlasPos = Vec2(0)
        self.doesHaveAtlasPos = False
        self.sourceIndex = 0
        self.mvp = UnalignedLMatrix4f()
        self.sourceIndex = -1
        self.nearPlane = 0.0
        self.farPlane = 1000.0
        self.converterYUR = None
        self.transforMat = TransformState.makeMat(
            Mat4.convertMat(Globals.base.win.getGsg().getInternalCoordinateSystem(),
                            CSZupRight))
            
    def cleanup(self):
        """ Cleans up the shadow source """
        self.cameraNode.removeNode()

    def setFilmSize(self, size_x, size_y):
        """ Sets the film size of the source, this is equivalent to setFilmSize
        on a Lens. """
        self.lens.setFilmSize(size_x, size_y)
        self.rebuildMatrixCache()

    def getLens(self):
        """ Returns the source lens """
        return self.lens

    def getSourceIndex(self):
        """ Returns the assigned source index. The source index is the index
        of the ShadowSource in the ShadowSources array of the assigned
        Light. """
        return self.sourceIndex

    def getUID(self):
        """ Returns the uid of the shadow source """
        return self.index

    def setSourceIndex(self, index):
        """ Sets the source index of this source. This is called by the light,
        as only the light knows at which position this source is in the
        Sources array. """
        self.sourceIndex = index

    def computeMVP(self):
        """ Computes the modelViewProjection matrix for the lens. Actually,
        this is the worldViewProjection matrix, but for convenience it is
        called mvp. """

        self.rebuildMatrixCache()
        projMat = self.converterYUR
        # modelViewMat = self.transforMat.invertCompose(
        modelViewMat = Globals.render.getTransform(self.cameraNode).getMat()
        return UnalignedLMatrix4f(modelViewMat * projMat)

    def assignAtlasPos(self, x, y):
        """ Assigns this source a position in the shadow atlas. This is called
        by the shadow atlas. Coordinates are float from 0 .. 1 """
        self.atlasPos = Vec2(x, y)
        self.doesHaveAtlasPos = True

    def update(self):
        """ Updates the shadow source. Currently only recomputes the mvp and
        triggers an array update """
        self.mvp = self.computeMVP()
        self.onPropertyChanged()

    def getAtlasPos(self):
        """ Returns the assigned atlas pos, if present. Coordinates are float
        from 0 .. 1 """
        return self.atlasPos

    def hasAtlasPos(self):
        """ Returns Whether this ShadowSource has already a position in the
        shadow atlas, or is currently unassigned """
        return self.doesHaveAtlasPos

    def removeFromAtlas(self):
        """ Deletes the atlas coordinates, this gets called by the atlas after the
        Source got removed from the atlas """
        self.doesHaveAtlasPos = False
        self.atlasPos = Vec2(0)

    def setResolution(self, resolution):
        """ Sets the resolution in pixels of this shadow source. Has to be
        a multiple of the tileSize specified in LightManager """
        assert(resolution > 1 and resolution <= 8192)
        self.resolution = resolution

    def getResolution(self):
        """ Returns the resolution of the shadow source in pixels """
        return self.resolution

    def setupPerspectiveLens(self, near=0.1, far=100.0, fov=(90, 90)):
        """ Setups a PerspectiveLens with a given near plane, far plane
        and FoV. The FoV is a tuple in the format (Horizontal FoV, Vertical FoV) """
        self.lens = PerspectiveLens()
        self.lens.setNearFar(near, far)
        self.lens.setFov(fov[0], fov[1])
        self.camera.setLens(self.lens)
        self.nearPlane = near
        self.farPlane = far
        self.rebuildMatrixCache()

    def setLens(self, lens):
        """ Setups the ShadowSource to use an external lens """
        self.lens = lens
        self.camera.setLens(self.lens)
        self.nearPlane = lens.getNear()
        self.farPlane = lens.getFar()
        self.nearPlane = 0.5
        self.farPlane = 50.0
        self.rebuildMatrixCache()

    def setupOrtographicLens(self, near=0.1, far=100.0, filmSize=(512, 512)):
        """ Setups a OrtographicLens with a given near plane, far plane
        and film size. The film size is a tuple in the format (filmWidth, filmHeight)
        in world space. """
        self.lens = OrthographicLens()
        self.lens.setNearFar(near, far)
        self.lens.setFilmSize(*filmSize)
        self.camera.setLens(self.lens)
        self.nearPlane = near
        self.farPlane = far
        self.rebuildMatrixCache()

    def rebuildMatrixCache(self):
        """ Internal method to precompute a part of the MVP to improve performance"""
        self.converterYUR = self.lens.getProjectionMat()

    def setPos(self, pos):
        """ Sets the position of the source in world space """
        self.cameraNode.setPos(pos)

    def getPos(self):
        """ Returns the position of the source in world space """
        return self.cameraNode.getPos()

    def setHpr(self, hpr):
        """ Sets the rotation of the source in world space """
        self.cameraNode.setHpr(hpr)

    def lookAt(self, pos):
        """ Looks at a point (in world space) """
        self.cameraNode.lookAt(pos.x, pos.y, pos.z)

    def invalidate(self):
        """ Invalidates this shadow source, means telling the LightManager
        that the shadow map for this light should be rebuilt. Otherwise it
        won't get refreshed. """
        self.valid = False

    def setValid(self):
        """ The LightManager calls this after the shadow map got updated
        successfully """
        self.valid = True

    def isValid(self):
        """ Returns wether the shadow map is still valid or should be refreshed """
        return self.valid

    def __repr__(self):
        """ Returns a representative string of this instance """
        return "ShadowSource[id=" + str(self.index) + "]"

    def __hash__(self):
        return self.index

    def onUpdated(self):
        """ Gets called when shadow source was updated """
Exemplo n.º 32
0
class ShadowSource(DebugObject, ShaderStructElement):
    """ This class can be seen as a camera. It stores the necessary data to 
    generate and store the shadow map for the assigned lens (like computing the MVP), 
    and also stores information about the shadowmap, like position in the 
    shadow atlas, or resolution. Each ShadowSource has a unique index, 
    which is used by the lights to identify which sources belong to it.
    """

    # Store a global index for assigning unique ids to the instances
    _GlobalShadowIndex = 999

    @classmethod
    def getExposedAttributes(self):
        return {
            "resolution": "int",
            "atlasPos": "vec2",
            "mvp": "mat4",
            "nearPlane": "float",
            "farPlane": "float"
        }

    @classmethod
    def _generateUID(self):
        """ Generates an uid and returns that """
        self._GlobalShadowIndex += 1
        return self._GlobalShadowIndex

    def __init__(self):
        """ Creates a new ShadowSource. After the creation, a lens can be added
        with setupPerspectiveLens or setupOrtographicLens. """
        self.index = self._generateUID()
        DebugObject.__init__(self, "ShadowSource-" + str(self.index))
        ShaderStructElement.__init__(self)

        self.valid = False
        self.camera = Camera("ShadowSource-" + str(self.index))
        self.camera.setActive(False)
        self.cameraNode = NodePath(self.camera)
        self.cameraNode.reparentTo(Globals.render.find("RPCameraDummys"))
        self.cameraNode.hide()
        self.resolution = 512
        self.atlasPos = Vec2(0)
        self.doesHaveAtlasPos = False
        self.sourceIndex = 0
        self.mvp = UnalignedLMatrix4f()
        self.sourceIndex = -1
        self.nearPlane = 0.0
        self.farPlane = 1000.0
        self.converterYUR = None
        self.transforMat = TransformState.makeMat(
            Mat4.convertMat(
                Globals.base.win.getGsg().getInternalCoordinateSystem(),
                CSZupRight))

    def cleanup(self):
        """ Cleans up the shadow source """
        self.cameraNode.removeNode()

    def setFilmSize(self, size_x, size_y):
        """ Sets the film size of the source, this is equivalent to setFilmSize
        on a Lens. """
        self.lens.setFilmSize(size_x, size_y)
        self.rebuildMatrixCache()

    def getLens(self):
        """ Returns the source lens """
        return self.lens

    def getSourceIndex(self):
        """ Returns the assigned source index. The source index is the index
        of the ShadowSource in the ShadowSources array of the assigned
        Light. """
        return self.sourceIndex

    def getUID(self):
        """ Returns the uid of the shadow source """
        return self.index

    def setSourceIndex(self, index):
        """ Sets the source index of this source. This is called by the light,
        as only the light knows at which position this source is in the
        Sources array. """
        self.sourceIndex = index

    def computeMVP(self):
        """ Computes the modelViewProjection matrix for the lens. Actually,
        this is the worldViewProjection matrix, but for convenience it is
        called mvp. """

        self.rebuildMatrixCache()
        projMat = self.converterYUR
        # modelViewMat = self.transforMat.invertCompose(
        modelViewMat = Globals.render.getTransform(self.cameraNode).getMat()
        return UnalignedLMatrix4f(modelViewMat * projMat)

    def assignAtlasPos(self, x, y):
        """ Assigns this source a position in the shadow atlas. This is called
        by the shadow atlas. Coordinates are float from 0 .. 1 """
        self.atlasPos = Vec2(x, y)
        self.doesHaveAtlasPos = True

    def update(self):
        """ Updates the shadow source. Currently only recomputes the mvp and
        triggers an array update """
        self.mvp = self.computeMVP()
        self.onPropertyChanged()

    def getAtlasPos(self):
        """ Returns the assigned atlas pos, if present. Coordinates are float
        from 0 .. 1 """
        return self.atlasPos

    def hasAtlasPos(self):
        """ Returns Whether this ShadowSource has already a position in the
        shadow atlas, or is currently unassigned """
        return self.doesHaveAtlasPos

    def removeFromAtlas(self):
        """ Deletes the atlas coordinates, this gets called by the atlas after the
        Source got removed from the atlas """
        self.doesHaveAtlasPos = False
        self.atlasPos = Vec2(0)

    def setResolution(self, resolution):
        """ Sets the resolution in pixels of this shadow source. Has to be
        a multiple of the tileSize specified in LightManager """
        assert (resolution > 1 and resolution <= 8192)
        self.resolution = resolution

    def getResolution(self):
        """ Returns the resolution of the shadow source in pixels """
        return self.resolution

    def setupPerspectiveLens(self, near=0.1, far=100.0, fov=(90, 90)):
        """ Setups a PerspectiveLens with a given near plane, far plane
        and FoV. The FoV is a tuple in the format (Horizontal FoV, Vertical FoV) """
        self.lens = PerspectiveLens()
        self.lens.setNearFar(near, far)
        self.lens.setFov(fov[0], fov[1])
        self.camera.setLens(self.lens)
        self.nearPlane = near
        self.farPlane = far
        self.rebuildMatrixCache()

    def setLens(self, lens):
        """ Setups the ShadowSource to use an external lens """
        self.lens = lens
        self.camera.setLens(self.lens)
        self.nearPlane = lens.getNear()
        self.farPlane = lens.getFar()
        self.nearPlane = 0.5
        self.farPlane = 50.0
        self.rebuildMatrixCache()

    def setupOrtographicLens(self, near=0.1, far=100.0, filmSize=(512, 512)):
        """ Setups a OrtographicLens with a given near plane, far plane
        and film size. The film size is a tuple in the format (filmWidth, filmHeight)
        in world space. """
        self.lens = OrthographicLens()
        self.lens.setNearFar(near, far)
        self.lens.setFilmSize(*filmSize)
        self.camera.setLens(self.lens)
        self.nearPlane = near
        self.farPlane = far
        self.rebuildMatrixCache()

    def rebuildMatrixCache(self):
        """ Internal method to precompute a part of the MVP to improve performance"""
        self.converterYUR = self.lens.getProjectionMat()

    def setPos(self, pos):
        """ Sets the position of the source in world space """
        self.cameraNode.setPos(pos)

    def getPos(self):
        """ Returns the position of the source in world space """
        return self.cameraNode.getPos()

    def setHpr(self, hpr):
        """ Sets the rotation of the source in world space """
        self.cameraNode.setHpr(hpr)

    def lookAt(self, pos):
        """ Looks at a point (in world space) """
        self.cameraNode.lookAt(pos.x, pos.y, pos.z)

    def invalidate(self):
        """ Invalidates this shadow source, means telling the LightManager
        that the shadow map for this light should be rebuilt. Otherwise it
        won't get refreshed. """
        self.valid = False

    def setValid(self):
        """ The LightManager calls this after the shadow map got updated
        successfully """
        self.valid = True

    def isValid(self):
        """ Returns wether the shadow map is still valid or should be refreshed """
        return self.valid

    def __repr__(self):
        """ Returns a representative string of this instance """
        return "ShadowSource[id=" + str(self.index) + "]"

    def __hash__(self):
        return self.index

    def onUpdated(self):
        """ Gets called when shadow source was updated """
Exemplo n.º 33
0
class Player():
	def __init__(self, game, hp, mana, strength, dexterity, vigor, magic):

		self.game = game

		self.ori = 0.0
		self.lastori = -1
		self.zoomLevel = 0.0
		self.nextAttack = 0.0

		self.attacked = False

		# Atributes

		self.hp = hp
		self.mana = mana

		self.strength = strength
		self.dexterity = dexterity
		self.vigor = vigor
		self.magic = magic

		# Atributes calculated

		self.attackDamage = random(1, 7) + self.strength/100				# physical dmg = weapon damage * %str
		self.magicDamage = random(3, 12) + self.magic/100					# magic dmg = skill damage * %magic
		self.speed = 15 + 0													# speed = base speed + item
		self.runSpeed = 25 + 0												# run speed = base speed + item
		self.lateralSpeed = 10												# speed when moving sidewards
		self.lateralRunSpeed = 20											# run speed when moving sidewards
		self.backwardsSpeed = 10											# speed when moving backwards
		self.backwardsRunSpeed = 20											# run speed when moving backwards
		self.defense = 5 + self.vigor/2										# defense = armour + 1/2 vigor
		self.criticalChance = 10 + 0										# crit chance = base item + skill
		self.criticalMultiplier = self.attackDamage*1.5						# crit mult = base item + skill
		self.magicDefense = 2 + self.magic/2								# magic def = base item + 1/2 magic
		self.attackSpeed = (0.2 * self.dexterity) / 60						# attack speed = base * dex / 60


		self.keyMap = {
						"left":0,
						"right":0,
						"forward":0,
						"backward":0,

						"cam-left":0,
						"cam-right":0,

						"jump":0,
						"attack":0,
						"run":0
						}

		# Player Parts

		parts = ["head", "larm", "rarm", "lboot", "rboot", "lleg", "rleg", "lhand", "rhand", "torso"]

		self.previousPart = { name: None for name in parts }

		# Player Models & Animations

		models = { name: "models/hero/%s" % name for name in parts }

		animations = { name:{
								"standby":"models/hero/%s-standby" % name,
								"walk":"models/hero/%s-walk" % name,
								"walk-back":"models/hero/%s-walk-back" % name,
								"walk-side":"models/hero/%s-walk-side" % name,
								"slash-front": "models/hero/%s-slash-front" % name
							} for name in parts
						}

		for itemClass, items in self.game.items["items"].iteritems():
			if itemClass == "armours":
				for itemType, value in items["lightarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["midarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["heavyarmours"].iteritems():
					modelName = value["model"]

					models["torso-%s" % modelName] = "models/hero/torso-%s" % modelName

					animations["torso-%s" % modelName] = {
															"standby":"models/hero/torso-%s-standby" % modelName,
															"walk":"models/hero/torso-%s-walk" % modelName,
															"walk-back":"models/hero/torso-%s-walk-back" % modelName,
															"walk-side":"models/hero/torso-%s-walk-side" % modelName,
															"slash-front":"models/hero/torso-%s-slash-front" % modelName
														}

				for itemType, value in items["helmets"].iteritems():
					modelName = value["model"]

					models["head-%s" % modelName] = "models/hero/head-%s" % modelName

					animations["head-%s" % modelName] = {
															"standby":"models/hero/head-%s-standby" % modelName,
															"walk":"models/hero/head-%s-walk" % modelName,
															"walk-back":"models/hero/head-%s-walk-back" % modelName,
															"walk-side":"models/hero/head-%s-walk-side" % modelName,
															"slash-front":"models/hero/head-%s-slash-front" % modelName
														}



		# Init Actor

		self.playerActor = Actor(models, animations)



		# Hide All Player Parts

		for itemClass, items in self.game.items["items"].iteritems():
			if itemClass == "armours":
				for itemType, value in items["lightarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["midarmours"].iteritems():
					modelName = value["model"]

				for itemType, value in items["heavyarmours"].iteritems():
					modelName = value["model"]
					self.playerActor.hidePart("torso-%s" % modelName)

				for itemType, value in items["helmets"].iteritems():
					modelName = value["model"]
					self.playerActor.hidePart("head-%s" % modelName)



		#self.playerActor.ls()

		# Shaders

		self.shader = Shader.load("shaders/testShader.sha", Shader.SL_Cg)
		#self.playerActor.setShader(self.shader)

		# End shaders

		self.moveFloater = NodePath(PandaNode("moveFloater"))
		self.moveFloater.reparentTo(render)
		self.moveFloater.setPos(self.game.playerStartPos)

		self.floater = NodePath(PandaNode("floater"))
		self.floater.reparentTo(render)
		#self.floater.setZ(8.0)

		self.playerActor.setHpr(0,0,0)
		self.playerActor.setScale(0.5)

		self.playerActor.reparentTo(self.moveFloater)

		#self.playerHand = self.playerActor.exposeJoint(None, 'body', 'manod')
		#self.playerHead = self.playerActor.controlJoint(None, 'body', 'cabeza')
		#self.playerHead.setScale(10,10,10)

		self.inventory = [["0" for x in range(10)] for x in range(5)]

		#			COLS-ROWS		#			COLS-ROWS
		self.inventory[0][3] = self.game.items["items"]["armours"]["heavyarmours"]["ironplate"]
		self.inventory[0][4] = self.game.items["items"]["armours"]["heavyarmours"]["steelplate"]
		self.inventory[0][5] = self.game.items["items"]["armours"]["heavyarmours"]["cuirass"]
		self.inventory[3][3] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[0][0] = self.game.items["items"]["weapons"]["swords"]["longsword"]
		self.inventory[1][0] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[0][8] = self.game.items["items"]["weapons"]["swords"]["longsword"]
		self.inventory[0][7] = self.game.items["items"]["weapons"]["spears"]["ironspear"]
		self.inventory[3][9] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[1][9] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[1][8] = self.game.items["items"]["armours"]["boots"]["leatherboots"]
		self.inventory[1][7] = self.game.items["items"]["armours"]["helmets"]["woolchaco"]
		self.inventory[0][6] = self.game.items["items"]["armours"]["helmets"]["goldencrown"]
		self.inventory[0][8] = self.game.items["items"]["armours"]["helmets"]["ironhelmet"]
		self.inventory[1][6] = self.game.items["items"]["armours"]["cloacks"]["woolcloack"]
		self.inventory[2][9] = self.game.items["items"]["armours"]["midarmours"]["leatherarmour"]
		self.inventory[2][8] = self.game.items["items"]["armours"]["boots"]["leatherboots"]
		self.inventory[2][7] = self.game.items["items"]["armours"]["helmets"]["woolchaco"]
		self.inventory[2][6] = self.game.items["items"]["armours"]["cloacks"]["woolcloack"]
		self.inventory[2][5] = self.game.items["items"]["armours"]["gloves"]["woolgloves"]
		self.inventory[1][5] = self.game.items["items"]["armours"]["gloves"]["woolgloves"]
		self.inventory[2][4] = self.game.items["items"]["accesories"]["rings"]["simplering"]
		self.inventory[1][4] = self.game.items["items"]["accesories"]["rings"]["simplering"]
		self.inventory[2][3] = self.game.items["items"]["accesories"]["trinkets"]["rubyamulet"]
		self.inventory[1][3] = self.game.items["items"]["accesories"]["trinkets"]["rubyamulet"]
		self.inventory[2][2] = self.game.items["items"]["armours"]["shields"]["ironshield"]
		self.inventory[1][2] = self.game.items["items"]["armours"]["shields"]["ironshield"]

		self.equip = {
						"armour":None,
						"helmet":None,
						"gloves":None,
						"boots":None,

						"cloack":None,

						"ringLeft":None,
						"ringRight":None,
						"trinket":None,

						"weapon":None,
						"weaponLeft":None,
						"weaponRight":None,

						"shield":None
					}

		self.models = []                 #A list that will store our models objects
		items = [("models/sword1", (0.0, 0.6, 1.5), (0,-90,0), 0.2),
				("models/maze", (0.0, 0.6, -1.5), (0,90,0), 0.2)]
		"""
		for row in items:
			np = self.game.loader.loadModel(row[0])				#Load the model
			np.setPos(row[1][0], row[1][1], row[1][2])		#Position it
			np.setHpr(row[2][0], row[2][1], row[2][2])		#Rotate it
			np.setScale(row[3])								#Scale it
			np.reparentTo(self.playerHand)
			#weaponNP.reparentTo(self.playerHand)
			self.models.append(np)							#Add it to our models list
		"""


		self.item = 0
		
		self.isMovingForward = False
		self.isMovingBackward = False
		self.isMovingSideRight = False
		self.isMovingSideLeft = False
		
		self.isMovingForwardLeft = False
		self.isMovingForwardRight = False
		
		self.isMovingSideRightUp = False
		self.isMovingSideRightDown = False
		
		self.isMovingSideLeftUp = False
		self.isMovingSideLeftDown = False
		
		self.isMovingBackwardLeft = False
		self.isMovingBackwardRight = False
		
		self.isAttacking = False

		self.setupControls()
		self.setupCamera()

		self.playerActor.loop("standby", "head")

		self.game.taskMgr.add(self.checkEquip, "checkTorsoTask", extraArgs=["torso", "armour"], appendTask=True)
		self.game.taskMgr.add(self.checkEquip, "checkHeadTask", extraArgs=["head", "helmet"], appendTask=True)

	def update(self, task):
		self.playerActor.setShaderInput("timer", task.time)
		return task.cont

	def checkEquip(self, partName, equipPart, task):

		# Check Equiped Parts

		if self.previousPart[partName] != self.equip[equipPart]:
			if self.equip[equipPart] != None and self.previousPart[partName] == None:
				self.playerActor.hidePart(partName)
				self.playerActor.showPart("%s-%s" % (partName, self.equip[equipPart]["model"]))
				self.previousPart[partName] = self.equip[equipPart]

			elif self.equip[equipPart] != None and self.previousPart[partName] != None:
				self.playerActor.hidePart("%s-%s" % (partName, self.previousPart[partName]["model"]))
				self.playerActor.showPart("%s-%s" % (partName, self.equip[equipPart]["model"]))
				self.previousPart[partName] = self.equip[equipPart]


			elif self.equip[equipPart] == None:
				self.playerActor.hidePart("%s-%s" % (partName, self.previousPart[partName]["model"]))
				self.playerActor.showPart(partName)
				self.previousPart[partName] = None

		return task.cont

	def setupCamera(self):

		self.game.disableMouse()
		self.game.camera.setPos(self.playerActor.getPos()+50)

		self.lens = OrthographicLens()
		self.lens.setFilmSize(45+self.zoomLevel, 35+self.zoomLevel)  # Or whatever is appropriate for your scene

		self.game.cam.node().setLens(self.lens)

		self.game.camLens.setFov(120)

	def setupControls(self):

		self.game.accept("a", self.setKey, ["left",1])
		self.game.accept("shift-a", self.setKey, ["left",1])
		self.game.accept("d", self.setKey, ["right",1])
		self.game.accept("shift-d", self.setKey, ["right",1])
		self.game.accept("w", self.setKey, ["forward",1])
		self.game.accept("shift-w", self.setKey, ["forward",1])
		self.game.accept("s", self.setKey, ["backward",1])
		self.game.accept("shift-s", self.setKey, ["backward",1])

		self.game.accept("a-up", self.setKey, ["left",0])
		self.game.accept("d-up", self.setKey, ["right",0])
		self.game.accept("w-up", self.setKey, ["forward",0])
		self.game.accept("s-up", self.setKey, ["backward",0])

		self.game.accept("mouse1", self.setKey, ["attack",1])
		self.game.accept("mouse1-up", self.setKey, ["attack",0])

		self.game.accept("shift-mouse1", self.setKey, ["attack",1])
		self.game.accept("shift-mouse1-up", self.setKey, ["attack",0])

		#self.game.accept("q", self.setKey, ["cam-left",1])
		#self.game.accept("e", self.setKey, ["cam-right",1])

		#self.game.accept("q-up", self.setKey, ["cam-left",0])
		#self.game.accept("e-up", self.setKey, ["cam-right",0])

		self.game.accept("space", self.setKey, ["jump",1])
		self.game.accept("space-up", self.setKey, ["jump",0])


		self.game.accept("shift", self.setKey, ["run",1])
		self.game.accept("shift-up", self.setKey, ["run",0])

		self.game.accept("wheel_up", self.moveCam, [1])
		self.game.accept("wheel_down", self.moveCam, [0])

		self.game.accept("shift-wheel_up", self.moveCam, [1])
		self.game.accept("shift-wheel_down", self.moveCam, [0])

		self.game.accept("t", self.toggleObject)

	def moveCam(self, zoom):
		if zoom == 0:
			self.zoomLevel += 5
			#if self.zoomLevel >= 30:
				#self.zoomLevel = 30

		elif zoom == 1:
			self.zoomLevel -= 5
			if self.zoomLevel <= 0:
				self.zoomLevel = 0

		#print self.zoomLevel
		self.lens.setFilmSize(45+self.zoomLevel, 35+self.zoomLevel)
		self.game.cam.node().setLens(self.lens)

	#def checkAttack(self):
		#animControl = self.playerActor.getAnimControl('slash', "body")

		#return animControl.isPlaying()


	def attack(self):
		if self.isAttacking is False:
			self.playerActor.play("slash-front")
			self.isAttacking = True

		self.isAttacking = False


	def setKey(self, key, value):
		self.keyMap[key] = value

	def setObject(self, i):
		for np in self.models: np.hide()
		self.models[i].show()
		self.item = i

	def toggleObject(self):

		if self.item == 1:
			self.item = 0
		else:
			self.item = 1

		for np in self.models: np.hide()
		self.models[self.item].show()

	def move(self, task):

		#self.playerActor.setPos(self.moveFloater.getPos())
		#self.playerActor.setZ(self.moveFloater.getZ())

		dt = globalClock.getDt()
		speed = 0

		if (self.keyMap["left"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(2.0, 'walk-side')
			else:
				speed = self.speed
				#self.playerActor.setPlayRate(1.0, 'walk-side')

			self.moveFloater.setX(self.moveFloater, speed * dt)
			self.moveFloater.setY(self.moveFloater, -speed * dt)

		if (self.keyMap["right"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(2.0, 'walk-side')
			else:
				speed = self.lateralSpeed
				#self.playerActor.setPlayRate(1.0, 'walk-side')

			self.moveFloater.setX(self.moveFloater, -speed * dt)
			self.moveFloater.setY(self.moveFloater, speed * dt)


		if (self.keyMap["forward"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(1.5, 'walk')
			else:
				speed = self.speed
				#self.playerActor.setPlayRate(1.0, 'walk')

			self.moveFloater.setY(self.moveFloater, -speed * dt)
			self.moveFloater.setX(self.moveFloater, -speed * dt)


		if (self.keyMap["backward"]):

			if (self.keyMap["run"]):
				speed = self.runSpeed
				#self.playerActor.setPlayRate(2.0, 'walk-back')
			else:
				speed = self.speed
				#self.playerActor.setPlayRate(1.0, 'walk-back')

			self.moveFloater.setY(self.moveFloater, speed * dt)
			self.moveFloater.setX(self.moveFloater, speed * dt)

		if (self.keyMap["attack"])  and (task.time > self.nextAttack):
			self.attack()
			self.nextAttack = task.time + self.attackSpeed
		self.keyMap["attack"] = 0


		"""
		if self.lastori != self.ori :
			turn = Sequence(LerpQuatInterval(self.playerActor, duration=0.05,  hpr=Vec3(self.ori, 0, 0), blendType='easeOut')).start()
			self.lastori = self.ori
		"""

		self.playerActor.headsUp(self.game.lookPoint)
		self.playerActor.setH(self.playerActor.getH()-180)

		#print(self.playerActor.getH())

		# If player is moving, loop the run animation.
		# If he is standing still, stop the animation.

		if self.keyMap["forward"] and self.keyMap["right"]:

			if ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
					
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
					
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")
					
					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
					
				if self.isMovingSideLeft is False:
					
					if (self.keyMap["run"]):
						self.playerActor.setPlayRate(2.0, 'walk-side')
					else:
						self.playerActor.setPlayRate(1.0, 'walk-side')
					
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
		
		elif self.keyMap["right"] and self.keyMap["backward"]:

			if ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
		
		elif self.keyMap["backward"] and self.keyMap["left"]:

			if ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
		
		elif self.keyMap["left"] and self.keyMap["forward"]:

			if (((self.playerActor.getH() < -315) and (self.playerActor.getH() < 0)) or ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -45))):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -45) and (self.playerActor.getH() > -135)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -135) and (self.playerActor.getH() > -225)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -225) and (self.playerActor.getH() > -315)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False
					
		elif self.keyMap["forward"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

		elif self.keyMap["backward"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

		elif self.keyMap["left"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

		elif self.keyMap["right"]:

			if ((self.playerActor.getH() < 0) and (self.playerActor.getH() > -90)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideLeft is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = True
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -90) and (self.playerActor.getH() > -180)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk')
				else:
					self.playerActor.setPlayRate(1.0, 'walk')
				
				if self.isMovingForward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk")

					self.isMovingForward = True
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -180) and (self.playerActor.getH() > -270)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-side')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-side')
				
				if self.isMovingSideRight is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-side")

					self.isMovingForward = False
					self.isMovingSideRight = True
					self.isMovingSideLeft = False
					self.isMovingBackward = False

			elif ((self.playerActor.getH() < -270) and (self.playerActor.getH() < 0)):
				
				if (self.keyMap["run"]):
					self.playerActor.setPlayRate(2.0, 'walk-back')
				else:
					self.playerActor.setPlayRate(1.0, 'walk-back')
				
				if self.isMovingBackward is False:
					self.playerActor.stop()
					self.playerActor.loop("walk-back")

					self.isMovingForward = False
					self.isMovingSideRight = False
					self.isMovingSideLeft = False
					self.isMovingBackward = True

		else:
			if self.isMovingForward or self.isMovingBackward or self.isMovingSideLeft or self.isMovingSideRight:
				self.playerActor.stop()
				self.playerActor.loop("standby")
				self.isMovingForward = False
				self.isMovingBackward = False
				self.isMovingSideLeft = False
				self.isMovingSideRight = False

		return task.cont


	def updateCamera(self, task):

		self.floater.setPos(self.moveFloater.getPos())
		self.floater.setZ(self.moveFloater.getZ() + 2.0)

		self.game.camera.setPos(self.floater.getPos()+50)
		# The camera should look in player's direction,
		# but it should also try to stay horizontal, so look at
		# a floater which hovers above player's head.


		self.game.camera.lookAt(self.floater)

		return task.cont
Exemplo n.º 34
0
class LocalPlayer(object):
    def __init__(self, mapobj, showbase):
        self.x = None
        self.y = None
        self.win = showbase.win
        self.map = mapobj
        self.mouseWatcherNode = showbase.mouseWatcherNode
        self.accept = showbase.accept
        self.camera = showbase.camera
        self.setup_input()

        self.floater = NodePath(PandaNode("floater"))
        self.floater.reparentTo(showbase.render)
        self.up = Vec3(0, 1, 0)

        incarn = self.map.world.get_incarn()
        walker_color_dict = {
            "barrel_color": [219.0 / 255, 16.0 / 255, 50.0 / 255],
            "visor_color": [157.0 / 255, 14.0 / 255, 48.0 / 255],
            "body_primary_color": [44.0 / 255, 31.0 / 255, 54.0 / 255],
            "body_secondary_color": [80.0 / 255, 44.0 / 255, 62.0 / 255],
        }
        self.walker = self.map.world.attach(Walker(incarn, colordict=walker_color_dict, player=True))
        taskMgr.add(self.move, "move")

    def setup_input(self):
        self.key_map = {
            "cam_forward": 0,
            "cam_left": 0,
            "cam_backward": 0,
            "cam_right": 0,
            "left": 0,
            "right": 0,
            "forward": 0,
            "backward": 0,
            "rotateLeft": 0,
            "rotateRight": 0,
            "walkForward": 0,
            "crouch": 0,
            "fire": 0,
            "missile": 0,
            "grenade_fire": 0,
            "grenade": 0,
            "print_cam": 0,
        }
        self.accept("escape", sys.exit)
        self.accept("p", self.drop_blocks)

        for key, cmd in KeyMaps.flycam_input_settings:
            self.accept(key, self.set_key, [cmd, 1])
            self.accept(key + "-up", self.set_key, [cmd, 0])

    def move(self, task):
        dt = globalClock.getDt()
        if self.mouseWatcherNode.hasMouse():
            oldx = self.x
            oldy = self.y
            md = self.win.getPointer(0)
            self.x = md.getX()
            self.y = md.getY()
            centerx = self.win.getProperties().getXSize() / 2
            centery = self.win.getProperties().getYSize() / 2
            self.win.movePointer(0, centerx, centery)

            if oldx is not None:
                self.floater.setPos(self.camera, 0, 0, 0)
                self.floater.setHpr(self.camera, 0, 0, 0)
                self.floater.setH(self.floater, (centerx - self.x) * 10 * dt)
                p = self.floater.getP()
                self.floater.setP(self.floater, (centery - self.y) * 10 * dt)
                self.floater.setZ(self.floater, -1)
                angle = self.up.angleDeg(self.floater.getPos() - self.camera.getPos())
                if 10 > angle or angle > 170:
                    self.floater.setPos(self.camera, 0, 0, 0)
                    self.floater.setP(p)
                    self.floater.setZ(self.floater, -1)
                self.camera.lookAt(self.floater.getPos(), self.up)
        else:
            self.x = None
            self.y = None

        if self.key_map["cam_forward"]:
            self.camera.setZ(self.camera, -25 * dt)
        if self.key_map["cam_backward"]:
            self.camera.setZ(self.camera, 25 * dt)
        if self.key_map["cam_left"]:
            self.camera.setX(self.camera, -25 * dt)
        if self.key_map["cam_right"]:
            self.camera.setX(self.camera, 25 * dt)
        if self.key_map["print_cam"]:
            print "CAMERA: Pos - %s, Hpr - %s" % (self.camera.get_pos(), self.camera.get_hpr())
            self.key_map["print_cam"] = 0

        self.walker.handle_command("forward", self.key_map["forward"])
        self.walker.handle_command("left", self.key_map["left"])
        self.walker.handle_command("backward", self.key_map["backward"])
        self.walker.handle_command("right", self.key_map["right"])
        self.walker.handle_command("crouch", self.key_map["crouch"])

        self.walker.handle_command("fire", self.key_map["fire"])
        if self.key_map["fire"]:
            self.key_map["fire"] = 0
        self.walker.handle_command("missile", self.key_map["missile"])
        if self.key_map["missile"]:
            self.key_map["missile"] = 0
        self.walker.handle_command("grenade_fire", self.key_map["grenade_fire"])
        if self.key_map["grenade_fire"]:
            self.key_map["grenade_fire"] = 0
        self.walker.handle_command("grenade", self.key_map["grenade"])
        if self.key_map["grenade"]:
            self.key_map["grenade"] = 0

        return task.cont

    def set_key(self, key, value):
        self.key_map[key] = value

    def drop_blocks(self):
        block = self.map.world.attach(FreeSolid(Block((1, 1, 1), (1, 0, 0, 1), 0.01, (0, 40, 0), (0, 0, 0)), 0.01))
        for i in range(10):
            rand_pos = (random.randint(-25, 25), 40, random.randint(-25, 25))
            block = self.map.world.attach(FreeSolid(Block((1, 1, 1), (1, 0, 0, 1), 0.01, rand_pos, (0, 0, 0)), 0.01))
Exemplo n.º 35
0
class Bot(object):

    def __init__(self, team, position, direction):
        self._orders = Actions.DoNothing
        self._hp = 5
        self._death_played = False
        self._interval = None
        self.kills = 0

        self.team = team

        self._model = NodePath('bot')
        self._model.reparentTo(render)

        self._model.setPos(position)
        self._model.setHpr(direction, 0, 0)
        self._model.setColorScale(*self.team)
        self._model.setScale(.2, .2, .2)

        # Load the animations
        self._actor = Actor("models/RockGolem", {
            'idle': 'models/RockGolem-idle',
            'walk': 'models/RockGolem-walk',
            'reverse-walk': 'models/RockGolem-walk',
            'punch': 'models/RockGolem-punch',
            'death': 'models/RockGolem-death',
            'throw': 'models/RockGolem-throw',
        })
        self._actor.setPlayRate(2.65, 'walk')
        self._actor.setPlayRate(-2.65, 'reverse-walk')
        self._actor.setPlayRate(4, 'punch')
        self._actor.setPlayRate(5.25, 'throw')
        self._actor.setBlend(frameBlend=True)
        self._actor.reparentTo(self._model)
        self._actor.loop('idle')
        self._actor.setH(180)

        # Floating Label
        text = TextNode('node name')
        text.setText(self.__class__.__name__)
        text.setAlign(TextNode.ACenter)
        self._name_label = self._model.attachNewNode(text)
        self._name_label.setBillboardPointEye()
        self._name_label.setPos(Vec3(0, 0, 6))
        self._name_label.setScale(3, 3, 3)

        # Debug Field of View Cones
        # fov = make_fov()
        # fov.reparentTo(self._model)

    def update(self, tick_number, visible_objects):
        return Actions.DoNothing

    def get_position(self):
        """Return a rounded version of the position vector."""
        p = self._model.getPos()
        return Vec3(round(p.x, 0), round(p.y, 0), round(p.z, 0))

    def get_direction(self):
        """Return a rounded version of the direction vector."""
        v = render.getRelativeVector(self._model, Vec3(0, 1, 0))
        v.normalize()
        return Vec3(round(v.x, 0), round(v.y, 0), round(v.z, 0))

    def get_name(self):
        return self.__class__.__name__

    def _get_orders(self, tick_number, visible_objects):
        # If the health is too low, die.
        if self._hp <= 0:
            self._orders = Actions.Suicide
            return

        # noinspection PyBroadException
        try:
            self._orders = self.update(tick_number, visible_objects)
        except Exception as e:
            print(type(self), e)
            self._orders = None

    def _execute_orders(self, tick_length, battle):
        # Pre-calculate some useful things
        new_pos = self.get_position()
        new_dir = self._model.getHpr()  # TODO: Getting rounding errors here
        velocity = self.get_direction()

        # If we're outside of the arena, take damage
        ARENA_SIZE = 13
        if new_pos.length() > ARENA_SIZE:
            battle.announce("{} fled the battle!".format(self.get_name()))
            self.take_damage(999)

        # Execute the order
        if self._orders == Actions.MoveForward:
            new_pos += velocity
            self.safe_loop('walk')

        elif self._orders == Actions.MoveBackward:
            new_pos -= velocity
            self.safe_loop('reverse-walk')

        elif self._orders == Actions.StrafeLeft:
            v = render.getRelativeVector(self._model, Vec3(-1, 0, 0))
            v.normalize()
            v = Vec3(round(v.x, 0), round(v.y, 0), round(v.z, 0))
            new_pos += v
            self.safe_loop('walk')

        elif self._orders == Actions.StrafeRight:
            v = render.getRelativeVector(self._model, Vec3(1, 0, 0))
            v.normalize()
            v = Vec3(round(v.x, 0), round(v.y, 0), round(v.z, 0))
            new_pos += v
            self.safe_loop('walk')

        elif self._orders == Actions.TurnLeft:
            new_dir.x += 90
            self.safe_loop('walk')

        elif self._orders == Actions.TurnAround:
            new_dir.x += 180
            self.safe_loop('walk')

        elif self._orders == Actions.TurnRight:
            new_dir.x -= 90
            self.safe_loop('walk')

        elif self._orders == Actions.Punch:
            self.punch(battle)

        elif self._orders == Actions.DoNothing:
            self.safe_loop('idle')

        elif self._orders == Actions.Suicide:
            self._hp = 0
            battle.announce("{} killed itself.".format(self.get_name()))
            self.take_damage(999)

        else:  # Bad orders detected! Kill this bot.
            self._hp = 0
            battle.announce("{} made an illegal move and died.".format(self.get_name()))
            self.take_damage(999)

        # Animate the motion
        if self._hp <= 0:
            return
        self._interval = LerpPosHprInterval(
            self._model, tick_length-0.05, new_pos, new_dir)
        self._interval.start()

    def safe_loop(self, animation):
        if self._death_played:
            return
        if self._actor.getCurrentAnim() != animation:
            self._actor.loop(animation)

    def punch(self, battle):
        if not self._death_played:
            self._actor.play('punch')
        hazard = self.get_direction() + self.get_position()
        bot = battle.get_object_at_position(hazard)
        if isinstance(bot, Bot):
            bot.take_damage(5)  # TODO: This is fun as 1
            if bot._hp > 0:
                return
            if bot.team == self.team:
                message = "{self} killed its teammate {target}!"
                self.kills -= 1
            else:
                message = "{self} just pwned {target}!"
                self.kills += 1
            battle.announce(message.format(self=self.get_name(),
                                           target=bot.get_name()),
                            color=self.team,
                            sfx="Ownage" if self.kills == 1 else None)
            if self.kills == 2:
                battle.announce("{} is ON FIRE!".format(self.get_name()),
                                color=(1.0, 0.5, 0.0, 1.0), sfx="DoubleKill")
            elif self.kills == 3:
                battle.announce("{} is UNSTOPPABLE!".format(self.get_name()),
                                color=(1.0, 0.5, 0.0, 1.0), sfx="TripleKill")
            elif self.kills == 4:
                battle.announce("{} is DOMINATING!".format(self.get_name()),
                                color=(1.0, 0.5, 0.0, 1.0), sfx="Dominating")
            elif self.kills > 4:
                battle.announce("{} is GODLIKE!".format(self.get_name()),
                                color=(1.0, 0.5, 0.0, 1.0), sfx="Godlike")

    def take_damage(self, amount):
        self._hp -= amount
        if self._hp <= 0:
            self._name_label.hide()
            if self._interval:
                self._interval.pause()
            if not self._death_played:
                self._actor.play('death')
                self._death_played = True

    def delete(self):
        self._model.removeNode()
        self._actor.cleanup()
        self._name_label.removeNode()
Exemplo n.º 36
0
class Player(FSM, DirectObject):
    NormalMode = "Normal"
    FightMode = "Fight"

    GAMEPADMODE = "Gamepad"
    MOUSEANDKEYBOARD = "MouseAndKeyboard"

    def __init__(self):
        FSM.__init__(self, "FSM-Player")
        random.seed()

        #
        # PLAYER CONTROLS AND CAMERA
        #
        self.player = Actor(
            "Character",
            {
                "Idle": "Character-Idle",
                "Run": "Character-Run",
                "Activate": "Character-Activate",
                "Death": "Character-Death",
                "Jump": "Character-Jump",
                "Hit": "Character-Hit",
                "Fight_Attack": "Character-FightAttack",
                "Fight_Idle": "Character-FightIdle",
                "Fight_Left": "Character-FightLeft",
                "Fight_Right": "Character-FightRight",
            },
        )
        self.player.setBlend(frameBlend=True)
        # the initial cam distance
        self.fightCamDistance = 3.0
        # the next two vars will set the min and max distance the cam can have
        # to the node it is attached to
        self.maxCamDistance = 4.0
        self.minCamDistance = 1.2
        # the initial cam distance
        self.camDistance = (self.maxCamDistance - self.minCamDistance) / 2.0 + self.minCamDistance
        # the next two vars set the min and max distance on the Z-Axis to the
        # node the cam is attached to
        self.maxCamHeightDist = 3.0
        self.minCamHeightDist = 1.5
        # the average camera height
        self.camHeightAvg = (self.maxCamHeightDist - self.minCamHeightDist) / 2.0 + self.minCamHeightDist
        # an invisible object which will fly above the player and will be used to
        # track the camera on it
        self.camFloater = NodePath(PandaNode("playerCamFloater"))
        self.camFloater.setPos(0, 0, 1.5)
        self.camFloater.reparentTo(self.player)
        # screen sizes
        self.winXhalf = base.win.getXSize() / 2
        self.winYhalf = base.win.getYSize() / 2
        # Interval for the jump animation
        self.jumpInterval = None
        self.jumpstartFloater = NodePath(PandaNode("jumpstartFloater"))
        self.jumpstartFloater.reparentTo(render)
        self.deathComplete = None
        # Joystick/Gamepad support
        self.hasJoystick = False
        if gamepadSupport:
            # initialize controls
            joysticks = [pygame.joystick.Joystick(x) for x in range(pygame.joystick.get_count())]
            if len(joysticks) > 0:
                self.mainJoystick = joysticks[0]
                self.mainJoystick.init()
                self.hasJoystick = True

        #
        # WEAPONS AND ACCESSORIES
        #
        self.RightHandAttach = self.player.exposeJoint(None, "modelRoot", "HandAttach_R")
        self.spear = loader.loadModel("Spear")
        self.spear.setP(90)
        self.spear.setR(180)
        self.spear.reparentTo(self.RightHandAttach)
        self.LeftHandAttach = self.player.exposeJoint(None, "modelRoot", "HandAttach_L")
        self.shield = loader.loadModel("Shield")
        self.shield.setZ(0.05)
        self.shield.setH(-90)
        self.shield.reparentTo(self.LeftHandAttach)

        #
        # PLAYER COLLISION DETECTION AND PHYSICS
        #
        self.playerSphere = CollisionSphere(0, 0, 0.8, 0.7)
        self.playerCollision = self.player.attachNewNode(CollisionNode("playerCollision"))
        self.playerCollision.node().addSolid(self.playerSphere)
        base.pusher.addCollider(self.playerCollision, self.player)
        base.cTrav.addCollider(self.playerCollision, base.pusher)
        # The foot collision checks
        self.footRay = CollisionRay(0, 0, 0, 0, 0, -1)
        self.playerFootRay = self.player.attachNewNode(CollisionNode("playerFootCollision"))
        self.playerFootRay.node().addSolid(self.footRay)
        self.playerFootRay.node().setIntoCollideMask(0)
        self.lifter = CollisionHandlerFloor()
        self.lifter.addCollider(self.playerFootRay, self.player)
        self.lifter.setMaxVelocity(5)
        base.cTrav.addCollider(self.playerFootRay, self.lifter)
        # a collision segment slightly in front of the player to check for jump ledges
        self.jumpCheckSegment = CollisionSegment(0, -0.2, 0.5, 0, -0.2, -2)
        self.playerJumpRay = self.player.attachNewNode(CollisionNode("playerJumpCollision"))
        self.playerJumpRay.node().addSolid(self.jumpCheckSegment)
        self.playerJumpRay.node().setIntoCollideMask(0)
        self.jumper = CollisionHandlerEvent()
        self.jumper.addOutPattern("%fn-out")
        base.cTrav.addCollider(self.playerJumpRay, self.jumper)
        # a collision segment to check attacks
        self.attackCheckSegment = CollisionSegment(0, 0, 1, 0, -1.3, 1)
        self.playerAttackRay = self.player.attachNewNode(CollisionNode("playerAttackCollision"))
        self.playerAttackRay.node().addSolid(self.attackCheckSegment)
        self.playerAttackRay.node().setIntoCollideMask(0)
        self.attackqueue = CollisionHandlerQueue()
        base.cTrav.addCollider(self.playerAttackRay, self.attackqueue)

        #
        # SOUNDEFFECTS
        #
        self.footstep = loader.loadSfx("Footstep.ogg")
        self.footstep.setLoop(True)
        self.footstep.setPlayRate(1.5)
        self.footstep.setVolume(0.5)
        self.spearAttackSfx = loader.loadSfx("SpearAttack.ogg")
        self.spearAttackSfx.setVolume(0.5)

    #
    # START/STOP
    #
    def start(self, startPoint):
        self.player.setPos(startPoint.getPos())
        self.player.setHpr(startPoint.getHpr())
        self.player.reparentTo(render)
        self.jumpstartFloater.setPos(self.player.getPos())

        self.keyMap = {"horizontal": 0, "vertical": 0}

        self.health = 3
        self.trackedEnemy = None
        # this mode will be used to determine in which move mode the player currently is
        self.mode = Player.NormalMode
        # the initial cam height
        self.camHeight = self.camHeightAvg
        # a time to keep the cam zoom at a specific speed independent of
        # current framerate
        self.camElapsed = 0.0
        self.mouseSpeedX = 15.0 * base.mouseSensitivity
        self.mouseSpeedY = 0.2 * base.mouseSensitivity
        self.speed = 1.0

        self.camCenterEvents = ["centerCam", "home", "q"]
        self.camZoomInEvents = ["zoomIn", "+", "wheel_up"]
        self.camZoomOutEvents = ["zoomOut", "-", "wheel_down"]
        self.actionEvents = ["doAction", "enter", "e"]

        self.accept("arrow_left", self.setKey, ["horizontal", 1])
        self.accept("arrow_right", self.setKey, ["horizontal", -1])
        self.accept("arrow_up", self.setKey, ["vertical", -1])
        self.accept("arrow_down", self.setKey, ["vertical", 1])
        self.accept("arrow_left-up", self.setKey, ["horizontal", 0])
        self.accept("arrow_right-up", self.setKey, ["horizontal", 0])
        self.accept("arrow_up-up", self.setKey, ["vertical", 0])
        self.accept("arrow_down-up", self.setKey, ["vertical", 0])
        self.accept("a", self.setKey, ["horizontal", 1])
        self.accept("d", self.setKey, ["horizontal", -1])
        self.accept("w", self.setKey, ["vertical", -1])
        self.accept("s", self.setKey, ["vertical", 1])
        self.accept("a-up", self.setKey, ["horizontal", 0])
        self.accept("d-up", self.setKey, ["horizontal", 0])
        self.accept("w-up", self.setKey, ["vertical", 0])
        self.accept("s-up", self.setKey, ["vertical", 0])
        for event in self.camCenterEvents:
            self.acceptOnce(event, self.center)
        for event in self.camZoomInEvents:
            self.acceptOnce(event, self.zoom, [True])
        for event in self.camZoomOutEvents:
            self.acceptOnce(event, self.zoom, [False])
        for event in self.actionEvents:
            self.acceptOnce(event, self.request, ["Action"])
        self.accept("ActionDone", self.request, ["Idle"])

        self.accept("playerJumpCollision-out", self.jump)

        taskMgr.add(self.move, "task_movement", priority=-10)
        taskMgr.add(self.updateCam, "task_camActualisation", priority=-4)

        if self.hasJoystick:
            taskMgr.add(self.gamepadLoop, "task_gamepad_loop", priority=-5)

        camera.setPos(self.player, 0, self.camDistance, self.camHeightAvg)

        self.hasJumped = False
        self.isActionmove = False

        self.request("Idle")

    def stop(self):
        taskMgr.remove("task_movement")
        taskMgr.remove("task_camActualisation")
        taskMgr.remove("task_gamepad_loop")
        self.ignoreAll()
        self.player.hide()

    def cleanup(self):
        self.stop()
        if self.deathComplete is not None:
            self.deathComplete.finish()
        if self.jumpInterval is not None:
            self.jumpInterval.finish()
        self.spear.removeNode()
        self.shield.removeNode()
        self.player.cleanup()
        self.player.removeNode()
        self.jumpstartFloater.removeNode()
        self.camFloater.removeNode()

    #
    # BASIC FUNCTIONS
    #
    def die(self):
        self.health -= 1
        base.messenger.send("setHealth", [self.health])
        self.request("Death")

    def heal(self):
        if self.health >= 3:
            return
        self.health += 1
        base.messenger.send("setHealth", [self.health])

    def hit(self):
        self.health -= 1
        base.messenger.send("setHealth", [self.health])
        if self.health == 0:
            self.request("Death")
        else:
            self.request("Hit")

    def resetPlayerPos(self):
        self.player.setPos(self.jumpstartFloater.getPos())
        self.jumper.clear()
        self.request("Idle")

    def gameOver(self):
        base.messenger.send("GameOver", ["loose"])

    def enterFightMode(self, trackedEnemy):
        self.trackedEnemy = trackedEnemy
        self.mode = Player.FightMode
        base.messenger.send("EnterFightMode")

    def exitFightMode(self):
        self.trackedEnemy = None
        self.mode = Player.NormalMode
        base.messenger.send("ExitFightMode")

    def gamepadLoop(self, task):
        joymap = {0: "doAction", 5: "centerCam", 6: "zoomIn", 4: "zoomOut", 9: "escape"}
        for event in pygame.event.get():
            for button in range(self.mainJoystick.get_numbuttons()):
                if button in joymap and self.mainJoystick.get_button(button):
                    base.messenger.send(joymap[button])
            if event.type == pygame.JOYAXISMOTION:
                for axis in range(self.mainJoystick.get_numaxes()):
                    axisChange = 0.0
                    axisChange = self.mainJoystick.get_axis(axis)
                    if axis == 0:
                        self.setKey("horizontal", -axisChange)
                    if axis == 1:
                        self.setKey("vertical", axisChange)
        return task.cont

    def setAnimationSpeed(self, requestedState):
        if requestedState == "Run":
            self.player.setPlayRate(3 * self.speed, "Run")
        elif requestedState == "RunReverse":
            self.player.setPlayRate(-3 * self.speed, "Run")
        elif requestedState == "FightLeft":
            self.player.setPlayRate(2 * self.speed, "Fight_Left")
        elif requestedState == "FightRight":
            self.player.setPlayRate(2 * self.speed, "Fight_Right")

    #
    # MOVE FUNCTIONS
    #
    def setKey(self, key, value):
        self.keyMap[key] = value

    def move(self, task):
        dt = globalClock.getDt()
        resetMouse = False

        def resetMouse():
            if base.controlType == Player.MOUSEANDKEYBOARD:
                base.win.movePointer(0, self.winXhalf, self.winYhalf)

        if self.player.getAnimControl("Hit").isPlaying() or self.player.getAnimControl("Death").isPlaying():
            resetMouse()
            return task.cont
        if self.deathComplete is not None:
            if self.deathComplete.isPlaying():
                resetMouse()
                return task.cont
        if self.jumpInterval is not None:
            if self.jumpInterval.isPlaying():
                resetMouse()
                return task.cont
        if self.isActionmove:
            resetMouse()
            return task.cont

        if self.mode == Player.NormalMode:
            self.__normalMove(dt)
        else:
            self.__fightMove(dt)
        return task.cont

    def __normalMove(self, dt):
        requestState = "Idle"
        move = False
        if self.keyMap["horizontal"] != 0:
            requestState = "Run"
            move = True
        if self.keyMap["vertical"] != 0:
            requestState = "Run"
            move = True
        if move and base.controlType == Player.GAMEPADMODE:
            movementVec = Vec3(self.keyMap["horizontal"], self.keyMap["vertical"], 0)
            self.speed = max(abs(self.keyMap["horizontal"]), abs(self.keyMap["vertical"]))
            angle = math.atan2(-movementVec.getX(), movementVec.getY())
            rotation = angle * (180.0 / math.pi)
            self.player.setH(camera, rotation)
            self.player.setP(0)
            self.player.setR(0)
            self.player.setPos(self.player, (0, -2 * self.speed * dt, 0))
        elif base.controlType == Player.MOUSEANDKEYBOARD:
            if not base.mouseWatcherNode.hasMouse():
                return
            self.pointer = base.win.getPointer(0)
            mouseX = self.pointer.getX()
            mouseY = self.pointer.getY()

            if base.win.movePointer(0, self.winXhalf, self.winYhalf):
                z = camera.getZ() + (mouseY - self.winYhalf) * self.mouseSpeedY * dt
                camera.setZ(z)

                h = self.player.getH() - (mouseX - self.winXhalf) * self.mouseSpeedX * dt
                if h < -360:
                    h = 360
                elif h > 360:
                    h = -360
                self.player.setH(h)
                if move:
                    self.player.setPos(
                        self.player, (2 * dt * self.keyMap["horizontal"], 2 * dt * self.keyMap["vertical"], 0)
                    )
                self.center()
        if self.state != requestState:
            self.request(requestState)
        self.setAnimationSpeed(requestState)

    def __fightMove(self, dt):
        if self.trackedEnemy == None:
            return
        requestState = "Idle"
        self.player.lookAt(self.trackedEnemy)
        self.player.setH(self.player, 180)
        if self.keyMap["horizontal"] > 0:
            self.player.setX(self.player, 2 * self.speed * dt)
            requestState = "FightLeft"
        elif self.keyMap["horizontal"] < 0:
            self.player.setX(self.player, -2 * self.speed * dt)
            requestState = "FightRight"
        elif self.keyMap["vertical"] < 0:
            self.player.setY(self.player, -2 * self.speed * dt)
            requestState = "Run"
        elif self.keyMap["vertical"] > 0:
            self.player.setY(self.player, 2 * self.speed * dt)
            requestState = "RunReverse"
        if self.state != requestState:
            self.request(requestState)
        self.setAnimationSpeed(requestState)

    def jump(self, extraArg):
        intoName = extraArg.getIntoNode().getName().lower()
        if not "floor" in intoName and not "plate" in intoName:
            return
        # setup the projectile interval
        startPos = self.player.getPos()
        self.jumpstartFloater.setPos(self.player, 0, 0.5, 0)
        tempFloater = NodePath(PandaNode("tempJumpFloater"))
        tempFloater.setPos(self.player, 0, -3.2, 0.1)
        endPos = tempFloater.getPos()
        tempFloater.removeNode()
        self.jumpInterval = ProjectileInterval(
            self.player, startPos=startPos, endPos=endPos, duration=1.5, gravityMult=0.25
        )
        self.request("Jump")
        self.jumpInterval.start()

    #
    # CAMERA FUNCTIONS
    #
    def updateCam(self, task):
        if self.mode == Player.NormalMode:
            self.__normalCam()
        else:
            self.__fightCam()
        return task.cont

    def zoom(self, zoomIn):

        # Camera Movement Updates
        camvec = self.player.getPos() - camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()

        zoom = 0
        if zoomIn:
            if camdist > self.minCamDistance + 0.5:
                zoom = 0.5
            for event in self.camZoomInEvents:
                self.acceptOnce(event, self.zoom, [True])
        else:
            if camdist < self.maxCamDistance - 0.5:
                zoom = -0.5
            for event in self.camZoomOutEvents:
                self.acceptOnce(event, self.zoom, [False])
        camera.setPos(camera, 0, zoom, 0)

    def center(self):
        # Camera Movement Updates
        camvec = self.player.getPos() - camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        # get the cameras current offset to the player model on the z-axis
        offsetZ = camera.getZ() - self.player.getZ()
        camera.setPos(self.player, 0, camdist, offsetZ)
        for event in self.camCenterEvents:
            self.acceptOnce(event, self.center)

    def __normalCam(self):
        """This function will check the min and max distance of the camera to
        the defined model and will correct the position if the cam is to close
        or to far away"""

        # Camera Movement Updates
        camvec = self.player.getPos() - camera.getPos()
        camvec.setZ(0)
        camdist = camvec.length()
        camvec.normalize()

        # If far from player start following
        if camdist > self.maxCamDistance:
            camera.setPos(camera.getPos() + camvec * (camdist - self.maxCamDistance))
            camdist = self.maxCamDistance

        # If player to close move cam backwards
        if camdist < self.minCamDistance:
            camera.setPos(camera.getPos() - camvec * (self.minCamDistance - camdist))
            camdist = self.minCamDistance

        # get the cameras current offset to the player model on the z-axis
        offsetZ = camera.getZ() - self.player.getZ()
        # check if the camera is within the min and max z-axis offset
        if offsetZ < self.minCamHeightDist:
            camera.setZ(self.player.getZ() + self.minCamHeightDist)
            offsetZ = self.minCamHeightDist
        elif offsetZ > self.maxCamHeightDist:
            camera.setZ(self.player.getZ() + self.maxCamHeightDist)
            offsetZ = self.maxCamHeightDist

        if offsetZ != self.camHeightAvg and not base.controlType == Player.MOUSEANDKEYBOARD:
            # if we are not moving up or down, set the cam to an average position
            if offsetZ != self.camHeightAvg:
                if offsetZ > self.camHeightAvg:
                    # the cam is higher then the average cam height above the player
                    # so move it slowly down
                    camera.setZ(camera.getZ() - 5 * globalClock.getDt())
                    newOffsetZ = camera.getZ() - self.player.getZ()
                    # check if the cam has reached the desired offset
                    if newOffsetZ < self.camHeightAvg:
                        # set the cam z position to exactly the desired offset
                        camera.setZ(self.player.getZ() + self.camHeightAvg)
                else:
                    # the cam is lower then the average cam height above the player
                    # so move it slowly up
                    camera.setZ(camera.getZ() + 5 * globalClock.getDt())
                    newOffsetZ = camera.getZ() - self.player.getZ()
                    # check if the cam has reached the desired offset
                    if newOffsetZ > self.camHeightAvg:
                        # set the cam z position to exactly the desired offset
                        camera.setZ(self.player.getZ() + self.camHeightAvg)

        camera.lookAt(self.camFloater)

    def __fightCam(self):
        """This function will check the min and max distance of the camera to
        the defined model and will correct the position if the cam is to close
        or to far away"""
        camera.setX(self.player, 0)
        camera.setY(self.player, self.fightCamDistance)
        camera.setZ(0.5)

        camera.lookAt(self.camFloater)

    #
    # FSM FUNCTIONS
    #
    def enterIdle(self):
        if self.mode == Player.NormalMode:
            self.player.loop("Idle")
            self.footstep.stop()
        elif self.mode == Player.FightMode:
            self.player.loop("Fight_Idle")
            self.footstep.stop()

    def enterRun(self):
        self.player.loop("Run")
        self.footstep.play()

    def enterRunReverse(self):
        self.player.loop("Run")
        self.footstep.play()

    def enterAction(self):
        if self.player.getAnimControl("Hit").isPlaying() or self.player.getAnimControl("Death").isPlaying():
            self.__exitAction()
            return
        self.isActionmove = True
        if self.mode == Player.NormalMode:
            self.__enterActivate()
        elif self.mode == Player.FightMode:
            self.__enterFightAttack()
        self.accept("ActionDone", self.__exitAction)

    def __exitAction(self):
        self.isActionmove = False
        for event in self.actionEvents:
            self.acceptOnce(event, self.request, ["Action"])

    def __enterActivate(self):
        activateAnim = self.player.actorInterval("Activate", playRate=3)
        activateAnim.setDoneEvent("ActionDone")
        activateAnim.start()
        base.messenger.send("Player_Activate")
        self.footstep.stop()

    def enterDeath(self):
        self.footstep.stop()
        deathAnim = self.player.actorInterval("Death")
        deathComplete = None
        if self.health == 0:
            self.deathComplete = Sequence(deathAnim, Wait(2), Func(self.gameOver))
        else:
            self.deathComplete = Sequence(deathAnim, Wait(2), Func(self.resetPlayerPos))
        self.deathComplete.start()

    def enterJump(self):
        self.player.play("Jump")
        self.footstep.stop()

    def enterHit(self):
        self.player.setPlayRate(4, "Hit")
        self.player.play("Hit")
        self.footstep.stop()

    def __enterFightAttack(self):
        attackAnim = self.player.actorInterval("Fight_Attack", playRate=3)
        attackAnim.setDoneEvent("ActionDone")
        attackAnim.start()
        self.spearAttackSfx.play()
        for i in range(self.attackqueue.getNumEntries()):
            entry = self.attackqueue.getEntry(i)
            into = entry.getIntoNode()
            if "golemHitField" in into.getName():
                if random.random() > 0.15:
                    base.messenger.send("HitEnemy")
        self.footstep.stop()

    def enterFightLeft(self):
        self.player.loop("Fight_Left")
        self.footstep.play()

    def enterFightRight(self):
        self.player.loop("Fight_Right")
        self.footstep.play()
Exemplo n.º 37
0
class Player(DirectObject):
    def __init__(self, _main):
        self.main = _main

        # Stats
        self.moveSpeed = 8
        self.inventory = []
        self.maxCarryWeight = 20.0 #kg ?
        self.currentInventoryWeight = 0.0

        # Inventory GUI
        self.inventoryGui = Inventory()
        self.inventoryGui.hide()
        self.inventoryActive = False
        self.craftInventory = CraftInventory()
        self.craftInventory.hide()

        # enable movements through the level
        self.keyMap = {"left":0, "right":0, "forward":0, "backward":0}
        self.player = NodePath("Player")#loader.loadModel("smiley")
        self.player.setPos(149.032, 329.324, 11.3384)
        self.player.setH(180)
        self.player.reparentTo(render)

        self.accept("w", self.setKey, ["forward",1])
        self.accept("w-up", self.setKey, ["forward",0])
        self.accept("a", self.setKey, ["left",1])
        self.accept("a-up", self.setKey, ["left",0])
        self.accept("s", self.setKey, ["backward",1])
        self.accept("s-up", self.setKey, ["backward",0])
        self.accept("d", self.setKey, ["right",1])
        self.accept("d-up", self.setKey, ["right",0])
        self.accept("mouse1", self.handleLeftMouse)
        self.accept("i", self.toggleInventory)
        self.accept("c", self.toggleCraftInventory)


        # screen sizes
        self.winXhalf = base.win.getXSize() / 2
        self.winYhalf = base.win.getYSize() / 2

        self.mouseSpeedX = 0.1
        self.mouseSpeedY = 0.1

        camera.setH(180)
        camera.reparentTo(self.player)
        camera.setZ(self.player, 2)
        base.camLens.setFov(75)
        base.camLens.setNear(0.8)

        # Mouse controls
        self.mouseNode = CollisionNode('mouseRay')
        self.mouseNodeNP = camera.attachNewNode(self.mouseNode)
        self.mouseNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.mouseRay = CollisionRay()
        self.mouseNode.addSolid(self.mouseRay)
        self.mouseRayHandler = CollisionHandlerQueue()

        # Collision Traverser
        self.traverser = CollisionTraverser("Player Traverser")
        base.cTrav = self.traverser
        self.traverser.addCollider(self.mouseNodeNP, self.mouseRayHandler)

    def run(self):
        taskMgr.add(self.move, "moveTask", priority=-4)

    def pause(self):
        taskMgr.remove("moveTask")

    def setKey(self, key, value):
        self.keyMap[key] = value

    def move(self, task):
        if not base.mouseWatcherNode.hasMouse(): return task.cont

        pointer = base.win.getPointer(0)
        mouseX = pointer.getX()
        mouseY = pointer.getY()

        if base.win.movePointer(0, self.winXhalf, self.winYhalf):
            # calculate the looking up/down of the camera.
            # NOTE: for first person shooter, the camera here can be replaced
            # with a controlable joint of the player model
            p = camera.getP() - (mouseY - self.winYhalf) * self.mouseSpeedY
            if p <-80:
                p = -80
            elif p > 90:
                p = 90
            camera.setP(p)

            # rotate the player's heading according to the mouse x-axis movement
            h = self.player.getH() - (mouseX - self.winXhalf) * self.mouseSpeedX
            if h <-360:
                h = 360
            elif h > 360:
                h = -360
            self.player.setH(h)

        # basic movement of the player
        if self.keyMap["left"] != 0:
            self.player.setX(self.player, self.moveSpeed * globalClock.getDt())
        if self.keyMap["right"] != 0:
            self.player.setX(self.player, -self.moveSpeed * globalClock.getDt())
        if self.keyMap["forward"] != 0:
            self.player.setY(self.player, -self.moveSpeed * globalClock.getDt())
        if self.keyMap["backward"] != 0:
            self.player.setY(self.player, self.moveSpeed * globalClock.getDt())


        # keep the player on the ground
        elevation = self.main.t.terrain.getElevation(self.player.getX(), self.player.getY())
        self.player.setZ(elevation*self.main.t.zScale)

        return task.cont

    def toggleInventory(self):
        if self.inventoryActive:
            self.inventoryGui.hide()
            self.inventoryActive = False
            self.run()
        else:
            self.inventoryGui.show()
            self.inventoryActive = True
            self.pause()

    def toggleCraftInventory(self):
        if self.inventoryActive:
            self.craftInventory.hide()
            self.inventoryActive = False
            self.run()
        else:
            self.craftInventory.updateList(self.inventory)
            self.craftInventory.show()
            self.inventoryActive = True
            self.pause()

    def handleLeftMouse(self):
        # Do the mining
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.mouseRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())

            self.traverser.traverse(render)
            # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
            if self.mouseRayHandler.getNumEntries() > 0:
            # This is so we get the closest object.
                self.mouseRayHandler.sortEntries()
                pickedObj = self.mouseRayHandler.getEntry(0).getIntoNodePath()

                # Range check
                if (self.player.getPos() - pickedObj.getPos(render)).length() <= 3.0:
                    self.mine(pickedObj)
                else:
                    print "You are to far, move closer!"


    def mine(self, _nodeNP):
        self.nodeNP = _nodeNP

        # get the object class
        for node in self.main.nodeGen.currentNodes:
            if self.main.nodeGen.currentNodes[node] in self.inventory:
                print "new Loot:", self.main.nodeGen.currentNodes[node].giveLoot()
                self.inventory.append(self.main.nodeGen.currentNodes[node])
                if self.main.nodeGen.currentNodes[node].lootLeft == 0:
                    self.main.nodeGen.currentNodes[node].removeModel()
                    break
                break


            # if mining node
            else:

                if self.main.nodeGen.currentNodes[node].model and self.main.nodeGen.currentNodes[node].model.getPos() == self.nodeNP.getPos(render):
                    #self.main.nodeGen.currentNodes[node].removeModel()
                    self.inventory.append(self.main.nodeGen.currentNodes[node])
                    self.currentInventoryWeight += self.main.nodeGen.currentNodes[node].weight
                    self.inventoryGui.updateList(self.inventory)
                    print "You received:", self.main.nodeGen.currentNodes[node].giveLoot(), self.main.nodeGen.currentNodes[node].giveType(), "Ores"
                    print "Inventory:", self.inventory
                    print "Current Weight:", self.currentInventoryWeight
                    break

        print self.player.getPos()
Exemplo n.º 38
0
class Player(object):
    """
        Player is the main actor in the fps game
    """
    FORWARD = Vec3(0,2,0)
    BACK = Vec3(0,-1,0)
    LEFT = Vec3(-1,0,0)
    RIGHT = Vec3(1,0,0)
    FLYUP = Vec3(0,0,1)
    FLYDN = Vec3(0,0,-1)
    STOP = Vec3(0)
    PORTAL_CYCLE = {
        'blue' : 'orange',
        'orange' : 'blue',
        }

    def __init__(self, base, fps, osd):
        self.base = base
        self.fps = fps
        self.osd = osd
        self.speed = RUN_SPEED
        self.walk = self.STOP
        self.readyToJump = False
        self.intoPortal = None
        self.mass = Mass()
        self.origin = self.fps.level.settings.origin
        self.bporigin = (999,999,999)
        self.oporigin = (999,999,999)
        self.current_target = None
        self.canPortal = []
        self.canSetTarget = True
        self.selectedCubes = []
        self.editorTextureStage = TextureStage('editor')
        self.editorSelectedTexture = loader.loadTexture('models/tex/selected.png')
        self.selectingForMulti = False
        # Init functions
        self.loadModel()
        self.makePortals()
        self.setUpCamera()
        if self.fps.editor_mode:
            self.createMouseCollisions()
            self.speed = self.speed * 5
            self.attachEditorControls()
            self.attachEditorTasks()
        else:
            self.createCollisions()
            self.attachStandardControls()
            self.attachStandardTasks()

    def loadModel(self):
        """ make the nodepath for player """
        self.node = NodePath('player')
        self.node.reparentTo(render)
        self.node.setPos(*self.origin)
        self.node.setScale(0.05)
        self.mass.pos = VBase3(self.node.getX(), self.node.getY(), self.node.getZ())

    def makePortals(self):
        # The BLUE CUBE
        bpor = loader.loadModel("cube_nocol")
        bpor.setTag('noportals', '1')
        bpor.reparentTo(render)
        bpor.setPos(*self.bporigin)
        bpor.setScale(0.3,0.02,0.5)
        # The BLUE CUBE's camera
        bbuffer = self.base.win.makeTextureBuffer("B Buffer", 512, 512)
        bbuffer.setSort(-100)
        bcamera = self.base.makeCamera(bbuffer)
        bcamera.node().getLens().setAspectRatio(0.3/0.5)
        bcamera.node().getLens().setFov(15)
        bcamera.reparentTo(bpor)
        bcamera.node().setScene(render)

        # The ORANGE CUBE
        opor = loader.loadModel("cube_nocol")
        opor.setTag('noportals', '1')
        opor.reparentTo(render)
        opor.setPos(*self.oporigin)
        opor.setScale(0.3,0.02,0.5)
        # The ORANGE CUBE's camera
        obuffer = self.base.win.makeTextureBuffer("O Buffer", 512, 512)
        obuffer.setSort(-100)
        ocamera = self.base.makeCamera(obuffer)
        ocamera.node().getLens().setAspectRatio(0.3/0.5)
        ocamera.node().getLens().setFov(15)
        ocamera.reparentTo(opor)
        ocamera.node().setScene(render)

        # Assign the textures
        bpor.setTexture(obuffer.getTexture())
        opor.setTexture(bbuffer.getTexture())
        # Store the portals and theirs cameras
        self.bluePortal = bpor
        self.bluePortal.setHpr(0,90,0)
        self.orangePortal = opor
        self.orangePortal.setHpr(0,-90,0)
        self.bcamera = bcamera
        self.ocamera = ocamera

    def setUpCamera(self):
        """ puts camera at the players node """
        pl =  self.base.cam.node().getLens()
        pl.setFov(70)
        self.base.cam.node().setLens(pl)
        self.base.camera.reparentTo(self.node)
        self.base.camLens.setFov(100)
        if self.fps.editor_mode:
            self.node.lookAt(self.fps.level.cubes_hash.keys()[0])

    def createCollisions(self):
        self.createPlayerCollisions()
        self.createMouseCollisions()
        self.createPortalCollisions()

    def createPlayerCollisions(self):
        """ create a collision solid and ray for the player """
        cn = CollisionNode('player')
        cn.setFromCollideMask(COLLISIONMASKS['geometry'])
        cn.setIntoCollideMask(COLLISIONMASKS['portals'] | COLLISIONMASKS['exit'] | COLLISIONMASKS['lava'])
        cn.addSolid(CollisionSphere(0,0,0,3))
        solid = self.node.attachNewNode(cn)
        # TODO : find a way to remove that, it's the cause of the little
        # "push me left" effect we see sometime when exiting a portal
        self.base.cTrav.addCollider(solid,self.base.pusher)
        self.base.pusher.addCollider(solid,self.node, self.base.drive.node())
        # init players floor collisions
        ray = CollisionRay()
        ray.setOrigin(0,0,-.2)
        ray.setDirection(0,0,-1)
        cn = CollisionNode('playerRay')
        cn.setFromCollideMask(COLLISIONMASKS['player'])
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.addSolid(ray)
        solid = self.node.attachNewNode(cn)
        self.nodeGroundHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(solid, self.nodeGroundHandler)
        # init players ceil collisions
        ray = CollisionRay()
        ray.setOrigin(0,0,.2)
        ray.setDirection(0,0,1)
        cn = CollisionNode('playerUpRay')
        cn.setFromCollideMask(COLLISIONMASKS['player'])
        cn.setIntoCollideMask(BitMask32.allOff())
        cn.addSolid(ray)
        solid = self.node.attachNewNode(cn)
        self.ceilGroundHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(solid, self.ceilGroundHandler)

    def createMouseCollisions(self):
        # Fire the portals
        firingNode = CollisionNode('mouseRay')
        firingNP = self.base.camera.attachNewNode(firingNode)
        firingNode.setFromCollideMask(COLLISIONMASKS['geometry'])
        firingNode.setIntoCollideMask(BitMask32.allOff())
        firingRay = CollisionRay()
        firingRay.setOrigin(0,0,0)
        firingRay.setDirection(0,1,0)
        firingNode.addSolid(firingRay)
        self.firingHandler = CollisionHandlerQueue()
        self.base.cTrav.addCollider(firingNP, self.firingHandler)

    def createPortalCollisions(self):
        # Enter the portals
        cn = CollisionNode('bluePortal')
        cn.setFromCollideMask(COLLISIONMASKS['portals'])
        cn.setIntoCollideMask(BitMask32.allOff())
        np = self.bluePortal.attachNewNode(cn)
        cn.addSolid(CollisionSphere(0,0,0,2))
        h = CollisionHandlerEvent()
        h.addInPattern('%fn-into-%in')
        h.addOutPattern('%fn-outof-%in')
        self.base.cTrav.addCollider(np, h)
        cn = CollisionNode('orangePortal')
        cn.setFromCollideMask(COLLISIONMASKS['portals'])
        cn.setIntoCollideMask(BitMask32.allOff())
        np = self.orangePortal.attachNewNode(cn)
        cn.addSolid(CollisionSphere(0,0,0,2))
        h = CollisionHandlerEvent()
        h.addInPattern('%fn-into-%in')
        h.addOutPattern('%fn-outof-%in')
        self.base.cTrav.addCollider(np, h)

    def attachCommonControls(self):
        self.base.accept( "z" if AZERTY else "w" , self.addWalk,[self.FORWARD])
        self.base.accept( "z-up" if AZERTY else "w-up" , self.addWalk,[-self.FORWARD] )
        self.base.accept( "s" , self.addWalk,[self.BACK] )
        self.base.accept( "s-up" , self.addWalk,[-self.BACK] )
        self.base.accept( "q" if AZERTY else "a" , self.addWalk,[self.LEFT])
        self.base.accept( "q-up" if AZERTY else "a-up" , self.addWalk,[-self.LEFT] )
        self.base.accept( "d" , self.addWalk,[self.RIGHT] )
        self.base.accept( "d-up" , self.addWalk,[-self.RIGHT] )
        self.base.accept( "r-up" , self.resetPosition )
        self.base.accept( "p-up" , self.showPosition )
        self.base.accept( "b-up" , self.deBug )

    def attachStandardControls(self):
        self.attachCommonControls()
        self.base.accept( "space" , self.__setattr__,["readyToJump",True])
        self.base.accept( "space-up" , self.__setattr__,["readyToJump",False])
        self.base.accept( "c-up" , self.__setattr__,["intoPortal",None] )
        self.base.accept( "e-up" , self.erasePortals )
        self.base.accept( "mouse1" , self.fireBlue )
        self.base.accept( "mouse3" , self.fireOrange )
        # Events
        self.base.accept( "bluePortal-into-player" , self.enterPortal, ["blue"] )
        self.base.accept( "orangePortal-into-player" , self.enterPortal, ["orange"] )
        self.base.accept( "bluePortal-outof-player" , self.exitPortal, ["blue"] )
        self.base.accept( "orangePortal-outof-player" , self.exitPortal, ["orange"] )
        self.base.accept( "levelExit-into-player" , self.levelExit)
        self.base.accept( "lava-into-player" , self.fallIntoLava)

    def attachStandardTasks(self):
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveUpdate, 'move-task')
        taskMgr.add(self.jumpUpdate, 'jump-task')

    def attachEditorControls(self):
        self.attachCommonControls()
        self.base.accept( "space" , self.__setattr__, ['selectingForMulti', 1])
        self.base.accept( "space-up" , self.__setattr__, ['selectingForMulti', 0])
        self.base.accept( "shift-space" , self.__setattr__, ['selectingForMulti', 2])
        self.base.accept( "shift-space-up" , self.__setattr__, ['selectingForMulti', 0])
        self.base.accept( "c-up" , self.clearMultiSelectedCubes)
        self.base.accept( "mouse1" , self.selectCubeForCopy, [1])
        self.base.accept( "wheel_up" , self.selectCubeForChange, [1] )
        self.base.accept( "wheel_down" , self.selectCubeForChange, [-1] )
        self.base.accept( "mouse3" , self.selectCubeForDelete )
        self.base.accept("f11", self.saveLevel)
        self.base.accept("x", self.selectCubeForRectangle)
        self.base.accept("shift-x", self.selectCubeForRectangle, [True])
        self.base.accept("l", self.addLightHere)
        self.base.accept("u", self.fps.level.undo, [1])
        for i in range(1,10):
            self.base.accept( "%i-up" % (i,), self.selectCubeForCopy, [i])
        for key, vec in [("a" if AZERTY else "q", self.FLYUP),("w" if AZERTY else "z", self.FLYDN)]:
            self.base.accept(key, self.addWalk, [vec])
            self.base.accept(key + "-up", self.addWalk, [-vec])

    def attachEditorTasks(self):
        taskMgr.add(self.mouseUpdate, 'mouse-task')
        taskMgr.add(self.moveInEditor, 'move-task')

    def deBug(self):
        import pdb
        pdb.set_trace()
    def showPosition(self):
        print self.node.getPos()
        print self.mass
    def fallIntoLava(self, *args, **kwargs):
        # TODO : sound and message + little delay
        self.erasePortals()
        self.resetPosition()
    def resetPosition(self, *args, **kwargs):
        self.node.setHpr(VBase3(0,0,0))
        self.mass.pos = VBase3(*self.origin)
        self.mass.vel = VBase3(0,0,0)
        self.mass.force = VBase3(0,0,0)
        self.node.setPos(self.mass.pos)
    def erasePortals(self):
        self.bluePortal.setPos(*self.bporigin)
        self.orangePortal.setPos(*self.oporigin)
        self.bluePortal.detachNode()
        self.orangePortal.detachNode()
        self.intoPortal = None
        self.canPortal = []
    #@oldpostracker
    def mouseUpdate(self,task):
        """ this task updates the mouse """
        md = self.base.win.getPointer(0)
        x = md.getX()
        y = md.getY()
        if self.base.win.movePointer(0, self.base.win.getXSize()/2, self.base.win.getYSize()/2):
            self.node.setH(self.node.getH() -  (x - self.base.win.getXSize()/2)*0.1)
            if self.fps.editor_mode:
                self.node.setP(self.node.getP() - (y - self.base.win.getYSize()/2)*0.1)
            else:
                self.base.camera.setP(self.base.camera.getP() - (y - self.base.win.getYSize()/2)*0.1)
            self.canSetTarget = True
            self.bcamera.lookAt(self.bluePortal, self.node.getPos(self.orangePortal))
            self.ocamera.lookAt(self.orangePortal, self.node.getPos(self.bluePortal))
            #self.canPortal = ['blue','orange']
            if self.fps.editor_mode:
                cube, point, normal = self.selectCube()
                self.osd.updateTargetPosition(cube)
        if self.selectingForMulti:
            self.selectCubeForMulti()
        return task.cont

    def addWalk(self, vec):
        self.walk += vec

    def moveUpdate(self,task):
        """ this task makes the player move """
        # move where the keys set it
        self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed)
        return task.cont

    #@oldpostracker
    def jumpUpdate(self,task):
        """ this task simulates gravity and makes the player jump """
        # get the highest Z from the down casting ray
        highestZ = -100
        lowestZ = 100
        for i in range(self.nodeGroundHandler.getNumEntries()):
            entry = self.nodeGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z > highestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ):
                highestZ = z
        for i in range(self.ceilGroundHandler.getNumEntries()):
            entry = self.ceilGroundHandler.getEntry(i)
            z = entry.getSurfacePoint(render).getZ()
            if z < lowestZ and entry.getIntoNode().getName() in ( "CollisionStuff", "Plane", "Cube" ):
                lowestZ = z
        # gravity effects and jumps
        self.mass.simulate(globalClock.getDt())
        self.node.setZ(self.mass.pos.getZ())
        if highestZ > self.node.getZ()-PLAYER_TO_FLOOR_TOLERANCE:
            self.mass.zero()
            self.mass.pos.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE)
            self.node.setZ(highestZ+PLAYER_TO_FLOOR_TOLERANCE)
        if lowestZ < self.node.getZ()+PLAYER_TO_FLOOR_TOLERANCE:
            self.mass.zero()
            self.mass.pos.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE)
            self.node.setZ(lowestZ-PLAYER_TO_FLOOR_TOLERANCE)
        if self.readyToJump and self.node.getZ() < highestZ + PLAYER_TO_FLOOR_TOLERANCE_FOR_REJUMP:
            self.mass.jump(JUMP_FORCE)
        return task.cont

    def firePortal(self, name, node):
        def hasTagValue(node, tag, value):
            if node.getTag(tag) == value:
                return True
            for pnum in range(node.getNumParents()):
                return hasTagValue(node.getParent(pnum), tag, value)
            return False
        self.firingHandler.sortEntries()
        if self.firingHandler.getNumEntries() > 0:
            closest = self.firingHandler.getEntry(0)
            if hasTagValue(closest.getIntoNode(), 'noportals', '1'):
                return
            point = closest.getSurfacePoint(render)
            normal = closest.getSurfaceNormal(render)
            node.setPos(point)
            node.lookAt(point + normal)
            node.reparentTo(render)
            dest = self.PORTAL_CYCLE[name]
            if dest not in self.canPortal:
                self.canPortal.append(dest)

    def fireBlue(self, *arg, **kwargs):
        self.firePortal("blue", self.bluePortal)

    def fireOrange(self, *arg, **kwargs):
        self.firePortal("orange", self.orangePortal)

    #@oldpostracker
    def enterPortal(self, color, collision):
        if self.intoPortal is None and color in self.canPortal:
            self.intoPortal = color
            portal = {"orange": self.bluePortal, "blue": self.orangePortal}.get(color)
            otherportal = {"orange": self.orangePortal, "blue": self.bluePortal}.get(color)
            # Handle horizontal portals :
            if portal.getH() == 0:
                self.node.setP(0)
                self.node.setR(0)
            elif otherportal.getH() == 0:
                self.node.setH(portal.getH())
                self.node.setP(0)
                self.node.setR(0)
            else:
                # New HPR is relative to 'new' portal but it the 'same' value
                # as the old HPR seen from the 'other' portal
                oldh_fromportal = self.node.getH(otherportal)
                self.node.setHpr(Vec3(0,0,0))
                self.node.setH(portal, 180-oldh_fromportal)
                newh_fromportal = self.node.getH(portal)
            self.node.setPos(portal, self.walk * 10.)
            self.mass.pos = self.node.getPos()
            # Make half a turn (only if we straffing without walking)
            if self.walk.getY() == 0 and self.walk.getX() != 0:
                self.node.setH(self.node, 180)
                self.node.setPos(self.node, self.walk * 10)
    #@oldpostracker
    def exitPortal(self, color, collision):
        # When you entered the blue portal, you have to exit the orange one
        if self.intoPortal != color:
            self.intoPortal = None

    def levelExit(self, event):
        if self.fps.level.settings.next_level:
            self.fps.level.loadlevel(self.fps.level.settings.next_level)
            self.origin = self.fps.level.settings.origin
            self.resetPosition()
            self.erasePortals()
            self.walk = self.STOP
        else:
            print "You won !"
            sys.exit(0)

    # EDITOR MODE
    def selectCube(self):
        self.firingHandler.sortEntries()
        if self.firingHandler.getNumEntries() > 0:
            closest = self.firingHandler.getEntry(0)
            return closest.getIntoNodePath().getParent().getParent(), closest.getSurfacePoint(render), closest.getSurfaceNormal(render) # render/cube.egg/-PandaNode/-GeomNode
        else:
            return None, None, None

    def clearMultiSelectedCubes(self):
        for c in self.selectedCubes:
            c.clearTexture(self.editorTextureStage)
        self.selectedCubes = []

    def selectCubeForMulti(self):
        cube, point, normal = self.selectCube()
        if cube:
            if self.selectingForMulti == 1:
                cube.setTexture(self.editorTextureStage, self.editorSelectedTexture)
                if cube not in self.selectedCubes:
                    self.selectedCubes.append(cube)
            elif cube in self.selectedCubes:
                cube.clearTexture(self.editorTextureStage)
                self.selectedCubes.remove(cube)

    def selectCubeForCopy(self, qty = 1):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.copyCube(c, normal, qty)
            self.clearMultiSelectedCubes()
        else:
            self.fps.level.copyCube(cube, normal, qty)

    def selectCubeForDelete(self):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.deleteCube(c)
            self.clearMultiSelectedCubes()
        else:
            self.fps.level.deleteCube(cube)

    def selectCubeForChange(self, step = 1):
        cube, point, normal = self.selectCube()
        if not (cube and point and normal):
            return
        if self.selectedCubes:
            for c in self.selectedCubes:
                self.fps.level.changeCube(c, step)
        else:
            self.fps.level.changeCube(cube, step)

    def selectCubeForRectangle(self, makeRoom = False):
        cube, point, normal = self.selectCube()
        if makeRoom:
            self.fps.level.createRoom(cube, self.node) # creates a room from the selected cube to the player(camera) position
        else:
            self.fps.level.createRectangle(cube, self.node) # creates a rectangle from the selected cube to the player(camera) position

    def saveLevel(self):
        camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()]
        levelname = self.fps.levelname
        self.fps.level.savelevel(levelname, camerapos)

    def addLightHere(self):
        camerapos = [self.node.getX(), self.node.getY(), self.node.getZ()]
        self.fps.level.addLightHere(camerapos)

    def moveInEditor(self,task):
        self.node.setPos(self.node, self.walk*globalClock.getDt()*self.speed)
        self.osd.updatePosition(self.node)
        return task.cont
Exemplo n.º 39
0
 def shoot(self, rangeVector):
     if not self.gag:
         return
     rangeNode = NodePath('Shoot Range')
     rangeNode.reparentTo(self.turret.getCannon())
     rangeNode.setScale(render, 1)
     rangeNode.setPos(rangeVector)
     rangeNode.setHpr(90, -90, 90)
     self.gag.setScale(self.gag.getScale(render))
     self.gag.setScale(self.gag.getScale(render))
     self.gag.setPos(self.gag.getPos(render))
     self.gag.reparentTo(render)
     self.gag.setHpr(rangeNode.getHpr(render))
     base.audio3d.attachSoundToObject(self.gagClass.woosh, self.gag)
     self.gagClass.woosh.play()
     self.track = ProjectileInterval(self.gag, startPos=self.gag.getPos(render), endPos=rangeNode.getPos(render), gravityMult=self.gravityMult, duration=self.duration, name=self.trackName)
     self.track.setDoneEvent(self.track.getName())
     self.acceptOnce(self.track.getDoneEvent(), self.cleanup)
     self.track.start()
     fireSfx = base.audio3d.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.mp3')
     base.audio3d.attachSoundToObject(fireSfx, self.turret.getCannon())
     fireSfx.play()
     if self.turret.isLocal():
         self.buildCollisions()
         self.acceptOnce(self.eventName, self.handleCollision)
Exemplo n.º 40
0
class GameObject(GameEntity, XMLExportable, PropertiesTableAbstract):
    '''
    used to add objects to game that intersects (or not) walkability
    @param attribues list of xml loaded attributes
    '''
    def __init__(self, attributes, parent, innerX, innerY, innerDimension, baseDimension):
        GameEntity.__init__(self, parent) #running parent constructor
        
        self.onPicked = ''
        
        self.innerX = innerX
        self.innerY = innerY
        self.innerDimension = innerDimension
        self.baseDimension = baseDimension
        self.typeName = 'object'
        
        self.properties = {
            'url' : '',
            'id' : '',
            'scale' : '',
            'name' : '',
            'inclination' : '',
            'elevation' : '',
            'rotation' : '',
            'offsetheight' : '',
            'offsetwidth' : '',
            'offsethorizontal' : '',
            'offsetvertical' : '',
            'offsetcollisionh' : '',
            'offsetcollisionv' : '',
            'collisionmode' : '',
            'walkable' : '',
            'avoidable' : '',
            'onPicked' : '',
            'onWalked' : ''
        }
        
        self.propertiesUpdateFactor = {
            'scale' : 0.1,
            'inclination' : 0.2,
            'elevation' : 0.02,
            'rotation' : 1.0,
            'offsetheight' : 0.02,
            'offsetwidth' : 0.02,
            'offsethorizontal' : 0.02,
            'offsetvertical' : 0.02,
            'offsetcollisionh' : 0.02,
            'offsetcollisionv' : 0.02
        }
        
        self.node = None
        self.collisionNodeNp = None
        #manage attributes directly in object creation,
        #this was many attributes are not mandatory
        if 'url' in attributes:
            self.properties['url'] = name = attributes['url'].value
        else:
            print("WARNING: url not defined, loading placeholder")
            self.properties['url'] = name = 'misc/placeholder'
        
        if 'id' in attributes:
            self.properties['id'] = self.uid = attributes['id'].value
        else:
            self.properties['id'] = self.uid = 'all'
        
        if 'inclination' in attributes:
            self.properties['inclination'] = float(attributes['inclination'].value)
        else:
            self.properties['inclination'] = 30.0
        
        if 'rotation' in attributes:
            self.properties['rotation'] = float(attributes['rotation'].value)
        else:
            self.properties['rotation'] = 0.0
        
        if 'offsetwidth' in attributes:
            self.properties['offsetwidth'] = float(attributes['offsetwidth'].value)
        else:
            self.properties['offsetwidth'] = 0.0
        
        if 'offsetheight' in attributes:
            self.properties['offsetheight'] = float(attributes['offsetheight'].value)
        else:
            self.properties['offsetheight'] = 0.0
        
        if 'offsethorizontal' in attributes:
            self.properties['offsethorizontal'] = float(attributes['offsethorizontal'].value)
        else:
            self.properties['offsethorizontal'] = 0.0
        
        if 'offsetcollisionh' in attributes:
            self.properties['offsetcollisionh'] = float(attributes['offsetcollisionh'].value)
        else:
            self.properties['offsetcollisionh'] = 0.0
        
        if 'offsetcollisionv' in attributes:
            self.properties['offsetcollisionv'] = float(attributes['offsetcollisionv'].value)
        else:
            self.properties['offsetcollisionv'] = 0.0
        
        if 'offsetvertical' in attributes:
            self.properties['offsetvertical'] = float(attributes['offsetvertical'].value)
        else:
            self.properties['offsetvertical'] = 0.0
        
        if 'elevation' in attributes:
            self.properties['elevation'] = float(attributes['elevation'].value)
        else:
            self.properties['elevation'] = 0.0
        
        if 'scale' in attributes:
            self.properties['scale'] = float(attributes['scale'].value)
        else:
            self.properties['scale'] = 1.0
        
        if 'onWalked' in attributes:
            self.properties['onWalked'] = self.onWalked = attributes['onWalked'].value
        else:
            self.properties['onWalked'] = self.onWalked = ""
        
        if 'onPicked' in attributes:
            if self.onPicked == '':
                self.properties['onPicked'] = self.onPicked = attributes['onPicked'].value
        
        if 'collisionmode' in attributes:
            self.properties['collisionmode'] = attributes['collisionmode'].value
        else:
            self.properties['collisionmode'] = "2d"
        
        if 'walkable' in attributes:
            if attributes['walkable'].value == "true":
                self.properties['walkable'] = walkable = 'true'
            else:
                self.properties['walkable'] = walkable = 'false'
        else:
            self.properties['walkable'] = walkable = 'false'
        
        if 'avoidable' in attributes:
            if attributes['avoidable'].value == "true":
                self.properties['avoidable'] = self.avoidable = True
            else:
                self.properties['avoidable'] = self.avoidable = False
        else:
            self.properties['avoidable'] = self.avoidable = False
        
        self.generateNode()
    
    def generateNode(self):        
        self.destroy()
        
        self.node = NodePath('gameobjectnode')
        self.node.setTwoSided(True)
        self.node.reparentTo(self.parent.node)
        
        if self.properties['avoidable'] == True:
            self.node.setTag("avoidable", 'true')
        else:
            self.node.setTag("avoidable", 'false')
        
        #setting scripting part
        self.node.setTag("onWalked", self.onWalked)
        self.node.setTag("onPicked", self.onPicked)
        #set unique id
        self.node.setTag("id", self.properties['id'])
        
        tex = loader.loadTexture(resourceManager.getResource(self.properties['url'])+'.png')
        tex.setWrapV(Texture.WM_clamp)
        tex.setWrapU(Texture.WM_clamp)
        
        #this is true pixel art
        #change to FTLinear for linear interpolation between pixel colors
        tex.setMagfilter(Texture.FTNearest)
        tex.setMinfilter(Texture.FTNearest)
        
        xorig = tex.getOrigFileXSize() / self.baseDimension
        yorig = tex.getOrigFileYSize() / self.baseDimension
        xscaled = (tex.getOrigFileXSize() / self.baseDimension) * self.properties['scale']
        yscaled = (tex.getOrigFileYSize() / self.baseDimension) * self.properties['scale']
        
        self.node.setTag("xscaled", str(xscaled))
        self.node.setTag("yscaled", str(yscaled))
        
        cm = CardMaker("tileobject")
        cm.setFrame(0,xorig,0,yorig)
        
        ts = TextureStage('ts')
        ts.setMode(TextureStage.MDecal)
        
        # distinguish between 3d collisions (for objects with an height and sensible self.properties['inclination'])
        # and 2d collisions for plain sprites
        if self.properties['walkable'] == 'false':
            if self.properties['collisionmode'] == "3d":
                #must handle differently objects which are small and big
                if xscaled < 1:
                    self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
                    
                if xscaled >= 1:
                    self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],0.1,0.3 + self.properties['offsetheight']))
                
                self.collisionNode = CollisionNode('objectSphere')
                self.collisionNode.addSolid(self.collisionTube)
                self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
                self.collisionNodeNp.setX(self.properties['offsethorizontal'])
                self.collisionNodeNp.setZ(self.properties['offsetvertical'])
                self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
                self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
                if main.editormode:
                    self.collisionNodeNp.show()
                
            elif self.properties['collisionmode'] == "2d":
                #must handle differently objects which are small and big
                if xscaled < 1:
                    self.collisionTube = CollisionBox(LPoint3f(0.5 - xscaled/2 - self.properties['offsetwidth'],0,0),LPoint3f(0.5 + xscaled/2 + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3))
                    
                if xscaled >= 1:
                    self.collisionTube = CollisionBox(LPoint3f(0 - self.properties['offsetwidth'],0,0),LPoint3f(xscaled + self.properties['offsetwidth'],yscaled + self.properties['offsetheight'],0.3))
                
                self.collisionNode = CollisionNode('objectSphere')
                self.collisionNode.addSolid(self.collisionTube)
                self.collisionNodeNp = self.node.attachNewNode(self.collisionNode)
                self.collisionNodeNp.setP(-(270-int(self.properties['inclination'])))
                self.collisionNodeNp.setX(self.properties['offsethorizontal'])
                self.collisionNodeNp.setZ(self.properties['offsetvertical'])
                self.collisionNodeNp.setX(self.collisionNodeNp.getX()+self.properties['offsetcollisionh'])
                self.collisionNodeNp.setZ(self.collisionNodeNp.getZ()+self.properties['offsetcollisionv']+0.1)
                if main.editormode:
                    self.collisionNodeNp.show()
        
        geomnode = NodePath(cm.generate())
        if geomnode.node().isGeomNode():
            vdata = geomnode.node().modifyGeom(0).modifyVertexData()
            writer = GeomVertexWriter(vdata, 'vertex')
            reader = GeomVertexReader(vdata, 'vertex')
            
            '''
            this part apply rotation flattening to the perspective view
            by modifying directly structure vertices
            '''
            i = 0 #counter
            while not reader.isAtEnd():
                v = reader.getData3f()
                x = v[0]
                y = v[1]
                z = v[2]
                newx = x
                newy = y
                newz = z
                if self.properties['rotation'] == -90.0:
                    if i == 0:
                        newx = math.fabs(math.cos(math.radians(self.properties['inclination']))) * z
                        newz = 0
                        ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z
                        sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen
                        spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen
                        newy -= spercos
                        newz += sparsen
                    if i == 2:
                        newx += math.fabs(math.cos(math.radians(self.properties['inclination']))) * z
                        newz = 0
                        ssen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * z
                        sparsen = math.fabs(math.sin(math.radians(self.properties['inclination']))) * ssen
                        spercos = math.fabs(math.cos(math.radians(self.properties['inclination']))) * ssen
                        newy -= spercos
                        newz += sparsen
                    writer.setData3f(newx, newy, newz)
                i += 1 #increase vertex counter
        if xscaled >= 1:
            geomnode.setX(0)
        if xscaled < 1:
            geomnode.setX(0.5 - xscaled/2)
        geomnode.setScale(self.properties['scale'])
        geomnode.setX(geomnode.getX()+self.properties['offsethorizontal'])
        geomnode.setZ(geomnode.getZ()+self.properties['offsetvertical'])
        geomnode.setY(-self.properties['elevation'])
        geomnode.setP(int(self.properties['inclination'])-360)
        geomnode.setTexture(tex)
        geomnode.setTransparency(TransparencyAttrib.MAlpha)
        geomnode.reparentTo(self.node)
        self.node.setR(self.properties['rotation'])
    
    def getName(self):
        return self.properties['url']
    
    def xmlAttributes(self):
        return self.properties
    
    def xmlTypeName(self):
        return self.typeName
    
    '''
    Sanitize properties data to be of correct type from string
    '''
    def sanitizeProperties(self):
        #sanitizing data
        self.properties['inclination'] = float(self.properties['inclination'])
        self.properties['rotation'] = float(self.properties['rotation'])
        self.properties['offsetwidth'] = float(self.properties['offsetwidth'])
        self.properties['offsetheight'] = float(self.properties['offsetheight'])
        self.properties['offsethorizontal'] = float(self.properties['offsethorizontal'])
        self.properties['offsetcollisionh'] = float(self.properties['offsetcollisionh'])
        self.properties['offsetcollisionv'] = float(self.properties['offsetcollisionv'])
        self.properties['offsetvertical'] = float(self.properties['offsetvertical'])
        self.properties['elevation'] = float(self.properties['elevation'])
        self.properties['scale'] = float(self.properties['scale'])
        
        self.updateTilePosition()
    
    #interface needed by PropertiesTable
    # regenerates the node at every change
    def onPropertiesUpdated(self):
        self.sanitizeProperties()
        self.generateNode()
        
    
    #interface needed by PropertiesTable
    #TODO: implement as real interface?
    def getPropertyList(self):
        return self.properties
    
    #interface needed by PropertiesTable
    def setProperty(self, key, value):
        self.properties[key] = value
    
    def increaseProperty(self, key, multiplier):
        if key in self.propertiesUpdateFactor:
            self.setProperty(key, self.properties[key]+self.propertiesUpdateFactor[key]*multiplier)
        
    def decreaseProperty(self, key, multiplier):
        if key in self.propertiesUpdateFactor:
            self.setProperty(key, self.properties[key]-self.propertiesUpdateFactor[key]*multiplier)
    
    def copyProperties(self):
        return self.getPropertyList()
    
    def pasteProperties(self, props):
        for key, value in props.items():
            if key in self.properties:
                self.properties[key] = value
        self.onPropertiesUpdated()
    
    #called before destruction
    def destroy(self):
        #clearing old node
        if self.node != None:
            self.node.removeNode()
        
        if self.collisionNodeNp != None:
            self.collisionNodeNp.removeNode()
    
    #here for polymorph
    def getTileX(self):
        return self.parent.getX()
    
    #here for polymorph
    def getTileY(self):
        return self.parent.getY()
    
    def getWorldPos(self):
        return self.node.getPos(render)
    
    #directly returning panda nodepath
    def getNode(self):
        return self.node
    def test_door_setup(self):
        parent_np = NodePath('parent_np')
        parent_np.setPosHpr(0, 10, .5, 180, 0, 0)

        door_origin = parent_np.attachNewNode('door_origin')
        door_origin.setPos(10, -25, .5)

        block = 4
        color = Vec4(.842, .167, .361, 1)

        # Set up door_np nodes
        door_np = NodePath('door_np')

        left_hole = door_np.attachNewNode('door_0_hole_left')
        right_hole = door_np.attachNewNode('door_0_hole_right')

        left_door = door_np.attachNewNode('door_0_left')
        right_door = door_np.attachNewNode('door_0_right')

        door_flat = door_np.attachNewNode('door_0_flat')
        door_trigger = door_np.attachNewNode('door_0_trigger')

        DNADoor.setupDoor(door_np, parent_np, door_origin, self.store, block, color)

        # Check if the nodes attributes and parents are correct
        self.assertEqual(door_np.getPos(door_origin), Point3(0, 0, 0))
        self.assertEqual(door_np.getHpr(door_origin), Point3(0, 0, 0))
        self.assertEqual(door_np.getScale(door_origin), Point3(1, 1, 1))

        def verify_color(color1, color2):
            self.assertAlmostEqual(color1.getX(), color2.getX(), places=4)
            self.assertAlmostEqual(color1.getY(), color2.getY(), places=4)
            self.assertAlmostEqual(color1.getZ(), color2.getZ(), places=4)
            self.assertAlmostEqual(color1.getW(), color2.getW(), places=4)

        verify_color(color, door_np.getColor())

        self.assertEqual(left_hole.getParent(), door_flat)
        self.assertEqual(left_hole.getName(), 'doorFrameHoleLeft')

        self.assertEqual(right_hole.getParent(), door_flat)
        self.assertEqual(right_hole.getName(), 'doorFrameHoleRight')

        self.assertEqual(left_door.getParent(), parent_np)
        self.assertEqual(left_door.getName(), 'leftDoor')
        verify_color(color, right_door.getColor())

        self.assertEqual(right_door.getParent(), parent_np)
        self.assertEqual(right_door.getName(), 'rightDoor')
        verify_color(color, right_door.getColor())

        self.assertEqual(door_trigger.getParent(), parent_np)
        self.assertEqual(door_trigger.getName(), 'door_trigger_%d' % block)

        store_np = self.store.getDoorPosHprFromBlockNumber(block)
        self.assertFalse(store_np.isEmpty())

        # Testing the pos is a pain because of decimal precision
        pos = store_np.getPos()
        self.assertAlmostEqual(pos.getX(), -10, places=2)
        self.assertAlmostEqual(pos.getY(), 35, places=2)
        self.assertAlmostEqual(pos.getZ(), 1, places=2)

        # Sometimes getH() returns -180 and others 180
        # Test the modulus (better than abs I guess)
        self.assertEqual(store_np.getH() % 180, 0)
Exemplo n.º 42
0
class DistributedTreasure(DistributedObject):
    notify = directNotify.newCategory('DistributedTreasure')

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.grabSoundPath = None
        self.rejectSoundPath = 'phase_4/audio/sfx/ring_miss.mp3'
        self.dropShadow = None
        self.treasureTrack = None
        self.nodePath = None
        self.modelPath = None
        self.modelChildString = None
        self.sphereRadius = 2.0
        self.scale = 1.0
        self.zOffset = 0.0
        self.playSoundForRemoteToons = True
        self.fly = True
        self.shadow = True
        self.billboard = False
        self.av = None
        return

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        self.loadModel(self.modelPath, self.modelChildString)
        self.startAnimation()
        self.nodePath.reparentTo(render)
        self.accept(self.uniqueName('entertreasureSphere'), self.handleEnterSphere)

    def loadModel(self, mdlPath, childString = None):
        self.grabSound = base.loadSfx(self.grabSoundPath)
        self.rejectSound = base.loadSfx(self.rejectSoundPath)
        if self.nodePath == None:
            self.makeNodePath()
        else:
            self.treasure.getChildren().detach()
        model = loader.loadModel(mdlPath)
        if childString:
            model = model.find('**/' + childString)
        model.instanceTo(self.treasure)
        return

    def makeNodePath(self):
        self.nodePath = NodePath('treasure')
        if self.billboard:
            self.nodePath.setBillboardPointEye()
        self.nodePath.setScale(0.9 * self.scale)
        self.treasure = self.nodePath.attachNewNode('treasure')
        if self.shadow:
            if not self.dropShadow:
                self.dropShadow = loader.loadModel('phase_3/models/props/drop_shadow.bam')
                self.dropShadow.setColor(0, 0, 0, 0.5)
                self.dropShadow.setPos(0, 0, 0.025)
                self.dropShadow.setScale(0.4 * self.scale)
                self.dropShadow.flattenLight()
            self.dropShadow.reparentTo(self.nodePath)
        collSphere = CollisionSphere(0, 0, 0, self.sphereRadius)
        collSphere.setTangible(0)
        collNode = CollisionNode(self.uniqueName('treasureSphere'))
        collNode.setIntoCollideMask(CIGlobals.WallBitmask)
        collNode.addSolid(collSphere)
        self.collNodePath = self.nodePath.attachNewNode(collNode)
        self.collNodePath.stash()

    def handleEnterSphere(self, collEntry = None):
        localAvId = base.localAvatar.doId
        if not self.fly:
            self.setGrab(localAvId)
        self.d_requestGrab()

    def setPosition(self, x, y, z):
        if not self.nodePath:
            self.makeNodePath()
        self.nodePath.reparentTo(render)
        self.nodePath.setPos(x, y, z + self.zOffset)
        self.collNodePath.unstash()

    def setReject(self):
        self.cleanupTrack()
        base.playSfx(self.rejectSound, node=self.nodePath)
        self.treasureTrack = Sequence(LerpColorScaleInterval(self.nodePath, 0.8, colorScale=VBase4(0, 0, 0, 0), startColorScale=VBase4(1, 1, 1, 1), blendType='easeIn'), LerpColorScaleInterval(self.nodePath, 0.2, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(0, 0, 0, 0), blendType='easeOut', name='treasureFlyTrack'))
        self.treasureTrack.start()

    def setGrab(self, avId):
        self.collNodePath.stash()
        self.avId = avId
        if self.cr.doId2do.has_key(avId):
            self.av = self.cr.doId2do[avId]
        else:
            self.nodePath.detachNode()
            return
        if self.playSoundForRemoteToons or self.avId == base.localAvatar.doId:
            base.playSfx(self.grabSound, node=self.nodePath)
        if not self.fly:
            self.nodePath.detachNode()
            return
        self.cleanupTrack()
        avatarGoneName = self.av.uniqueName('disable')
        self.accept(avatarGoneName, self.handleUnexpectedExit)
        flyTime = 1.0
        track = Sequence(LerpPosInterval(self.nodePath, flyTime, pos=Point3(0, 0, 3), startPos=self.nodePath.getPos(self.av), blendType='easeInOut'), Func(self.nodePath.detachNode), Func(self.ignore, avatarGoneName))
        if self.shadow:
            self.treasureTrack = Sequence(HideInterval(self.dropShadow), track, ShowInterval(self.dropShadow), name='treasureFlyTrack')
        else:
            self.treasureTrack = Sequence(track, name='treasureFlyTrack')
        self.nodePath.reparentTo(self.av)
        self.treasureTrack.start()

    def handleUnexpectedExit(self):
        self.notify.warning('%s disconnected while collecting treasure.' % str(self.avId))
        self.cleanupTrack()

    def d_requestGrab(self):
        self.sendUpdate('requestGrab', [])

    def startAnimation(self):
        pass

    def disable(self):
        self.ignoreAll()
        self.nodePath.detachNode()
        DistributedObject.disable(self)

    def cleanupTrack(self):
        if self.treasureTrack:
            self.treasureTrack.finish()
            self.treasureTrack = None
        return

    def delete(self):
        self.cleanupTrack()
        DistributedObject.delete(self)
        self.nodePath.removeNode()
Exemplo n.º 43
0
class PartyCog(FSM):
    notify = directNotify.newCategory('PartyCog')
    HpTextGenerator = TextNode('HpTextGenerator')
    hpText = None
    height = 7

    def __init__(self,
                 parentNode,
                 id,
                 bounceSpeed=3,
                 bounceHeight=1,
                 rotateSpeed=1,
                 heightShift=1,
                 xMoveSpeed=0,
                 xMoveDistance=0,
                 bounceOffset=0):
        self.id = id
        FSM.__init__(self, 'PartyCogFSM-%d' % self.id)
        self.showFacingStatus = False
        self.xMoveSpeed = xMoveSpeed
        self.xMoveDistance = xMoveDistance
        self.heightShift = heightShift
        self.bounceSpeed = bounceSpeed
        self.bounceHeight = bounceHeight
        self.rotateSpeed = rotateSpeed
        self.parentNode = parentNode
        self.bounceOffset = bounceOffset
        self.hitInterval = None
        self.kaboomTrack = None
        self.resetRollIval = None
        self.netTimeSentToStartByHit = 0
        self.load()
        self.request('Down')
        return

    def load(self):
        self.root = NodePath('PartyCog-%d' % self.id)
        self.root.reparentTo(self.parentNode)
        path = 'phase_13/models/parties/cogPinata_'
        self.actor = Actor(
            path + 'actor', {
                'idle': path + 'idle_anim',
                'down': path + 'down_anim',
                'up': path + 'up_anim',
                'bodyHitBack': path + 'bodyHitBack_anim',
                'bodyHitFront': path + 'bodyHitFront_anim',
                'headHitBack': path + 'headHitBack_anim',
                'headHitFront': path + 'headHitFront_anim'
            })
        self.actor.reparentTo(self.root)
        self.temp_transform = Mat4()
        self.head_locator = self.actor.attachNewNode('temphead')
        self.bodyColl = CollisionTube(0, 0, 1, 0, 0, 5.75, 0.75)
        self.bodyColl.setTangible(1)
        self.bodyCollNode = CollisionNode('PartyCog-%d-Body-Collision' %
                                          self.id)
        self.bodyCollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.bodyCollNode.addSolid(self.bodyColl)
        self.bodyCollNodePath = self.root.attachNewNode(self.bodyCollNode)
        self.headColl = CollisionTube(0, 0, 3, 0, 0, 3.0, 1.5)
        self.headColl.setTangible(1)
        self.headCollNode = CollisionNode('PartyCog-%d-Head-Collision' %
                                          self.id)
        self.headCollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.headCollNode.addSolid(self.headColl)
        self.headCollNodePath = self.root.attachNewNode(self.headCollNode)
        self.arm1Coll = CollisionSphere(1.65, 0, 3.95, 1.0)
        self.arm1Coll.setTangible(1)
        self.arm1CollNode = CollisionNode('PartyCog-%d-Arm1-Collision' %
                                          self.id)
        self.arm1CollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.arm1CollNode.addSolid(self.arm1Coll)
        self.arm1CollNodePath = self.root.attachNewNode(self.arm1CollNode)
        self.arm2Coll = CollisionSphere(-1.65, 0, 3.45, 1.0)
        self.arm2Coll.setTangible(1)
        self.arm2CollNode = CollisionNode('PartyCog-%d-Arm2-Collision' %
                                          self.id)
        self.arm2CollNode.setCollideMask(ToontownGlobals.PieBitmask)
        self.arm2CollNode.addSolid(self.arm2Coll)
        self.arm2CollNodePath = self.root.attachNewNode(self.arm2CollNode)
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splatType = globalPropPool.getPropType(splatName)
        self.pieHitSound = globalBattleSoundCache.getSound(
            'AA_wholepie_only.ogg')
        self.upSound = globalBattleSoundCache.getSound('AV_jump_to_side.ogg')
        self.hole = loader.loadModel('phase_13/models/parties/cogPinataHole')
        self.hole.setTransparency(True)
        self.hole.setP(-90.0)
        self.hole.setScale(3)
        self.hole.setBin('ground', 3)
        self.hole.reparentTo(self.parentNode)

    def unload(self):
        self.request('Off')
        self.clearHitInterval()
        if self.hole is not None:
            self.hole.removeNode()
            self.hole = None
        if self.actor is not None:
            self.actor.cleanup()
            self.actor.removeNode()
            self.actor = None
        if self.root is not None:
            self.root.removeNode()
            self.root = None
        if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.kaboomTrack = None
        if self.resetRollIval is not None and self.resetRollIval.isPlaying():
            self.resetRollIval.finish()
        self.resetRollIval = None
        if self.hitInterval is not None and self.hitInterval.isPlaying():
            self.hitInterval.finish()
        self.hitInterval = None
        del self.upSound
        del self.pieHitSound
        return

    def enterStatic(self):
        pass

    def exitStatic(self):
        pass

    def enterActive(self, startTime):
        self.root.setR(0.0)
        updateTask = Task.Task(self.updateTask)
        updateTask.startTime = startTime
        taskMgr.add(updateTask, 'PartyCog.update-%d' % self.id)

    def exitActive(self):
        taskMgr.remove('PartyCog.update-%d' % self.id)
        taskMgr.remove('PartyCog.bounceTask-%d' % self.id)
        self.clearHitInterval()
        self.resetRollIval = self.root.hprInterval(0.5,
                                                   Point3(
                                                       self.root.getH(), 0.0,
                                                       0.0),
                                                   blendType='easeInOut')
        self.resetRollIval.start()
        self.actor.stop()

    def enterDown(self):
        if self.oldState == 'Off':
            downAnimControl = self.actor.getAnimControl('down')
            self.actor.pose('down', downAnimControl.getNumFrames() - 1)
            return
        self.clearHitInterval()
        startScale = self.hole.getScale()
        endScale = Point3(5, 5, 5)
        self.hitInterval = Sequence(
            LerpFunc(self.setAlongSpline,
                     duration=1.0,
                     fromData=self.currentT,
                     toData=0.0),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=endScale,
                              startScale=startScale,
                              blendType='easeIn'),
            Parallel(
                SoundInterval(self.upSound,
                              volume=0.6,
                              node=self.actor,
                              cutOff=PartyGlobals.PARTY_COG_CUTOFF),
                ActorInterval(self.actor, 'down', loop=0)),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=Point3(3, 3, 3),
                              startScale=endScale,
                              blendType='easeOut'))
        self.hitInterval.start()

    def exitDown(self):
        self.root.setR(0.0)
        self.root.setH(0.0)
        self.targetDistance = 0.0
        self.targetFacing = 0.0
        self.currentT = 0.0
        self.setAlongSpline(0.0)
        self.clearHitInterval()
        startScale = self.hole.getScale()
        endScale = Point3(5, 5, 5)
        self.hitInterval = Sequence(
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=endScale,
                              startScale=startScale,
                              blendType='easeIn'),
            Parallel(
                SoundInterval(self.upSound,
                              volume=0.6,
                              node=self.actor,
                              cutOff=PartyGlobals.PARTY_COG_CUTOFF),
                ActorInterval(self.actor, 'up', loop=0)),
            Func(self.actor.loop, 'idle'),
            LerpScaleInterval(self.hole,
                              duration=0.175,
                              scale=Point3(3, 3, 3),
                              startScale=endScale,
                              blendType='easeOut'))
        self.hitInterval.start()

    def filterDown(self, request, args):
        if request == 'Down':
            return None
        else:
            return self.defaultFilter(request, args)
        return None

    def setEndPoints(self, start, end, amplitude=1.7):
        self.sinAmplitude = amplitude
        self.sinPeriod = (end.getX() - start.getX()) / 2
        self.sinDisplacement = start.getY()
        self.startPoint = start
        self.endPoint = end
        self.currentT = 0.0
        self.targetDistance = 0.0
        self.currentFacing = 0.0
        self.targetFacing = 0.0
        self.setAlongSpline(self.currentT)
        self.hole.setPos(self.root.getPos())
        self.hole.setZ(0.02)

    def rockBackAndForth(self, task):
        t = task.startTime + task.time
        angle = math.sin(t) * 20.0
        self.root.setR(angle)
        return task.cont

    def updateDistance(self, distance):
        self.targetDistance = clamp(distance, -1.0, 1.0)

    def updateTask(self, task):
        self.rockBackAndForth(task)
        if self.targetDistance > self.currentT:
            self.currentT += min(0.01, self.targetDistance - self.currentT)
            self.setAlongSpline(self.currentT)
        elif self.targetDistance < self.currentT:
            self.currentT += max(-0.01, self.targetDistance - self.currentT)
            self.setAlongSpline(self.currentT)
        if self.currentT < 0.0:
            self.targetFacing = -90.0
        elif self.currentT > 0.0:
            self.targetFacing = 90.0
        else:
            self.targetFacing = 0.0
        if self.targetFacing > self.currentFacing:
            self.currentFacing += min(10,
                                      self.targetFacing - self.currentFacing)
        elif self.targetFacing < self.currentFacing:
            self.currentFacing += max(-10,
                                      self.targetFacing - self.currentFacing)
        self.root.setH(self.currentFacing)
        return task.cont

    def setAlongSpline(self, t):
        t = t + 1.0
        dist = (self.endPoint.getX() - self.startPoint.getX()) / 2.0
        x = self.startPoint.getX() + t * dist
        y = self.startPoint.getY() - math.sin(
            t * 2 * math.pi) * self.sinAmplitude
        self.root.setPos(x, y, 0)

    def startBounce(self):
        taskMgr.add(self.bounce, 'PartyCog.bounceTask-%d' % self.id)

    def bounce(self, task):
        self.root.setZ(
            math.sin((self.bounceOffset + task.time) * self.bounceSpeed) *
            self.bounceHeight + self.heightShift)
        return task.cont

    def setPos(self, position):
        self.root.setPos(position)

    def respondToPieHit(self, timestamp, position, hot=False, direction=1.0):
        if self.netTimeSentToStartByHit < timestamp:
            self.__showSplat(position, direction, hot)
            if self.netTimeSentToStartByHit < timestamp:
                self.netTimeSentToStartByHit = timestamp
        else:
            self.notify.debug(
                'respondToPieHit self.netTimeSentToStartByHit = %s' %
                self.netTimeSentToStartByHit)

    def clearHitInterval(self):
        if self.hitInterval is not None and self.hitInterval.isPlaying():
            self.hitInterval.clearToInitial()
        return

    def __showSplat(self, position, direction, hot=False):
        if self.kaboomTrack is not None and self.kaboomTrack.isPlaying():
            self.kaboomTrack.finish()
        self.clearHitInterval()
        splatName = 'splat-creampie'
        self.splat = globalPropPool.getProp(splatName)
        self.splat.setBillboardPointEye()
        self.splat.reparentTo(render)
        self.splat.setPos(self.root, position)
        self.splat.setAlphaScale(1.0)
        if not direction == 1.0:
            self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[0])
            if self.currentFacing > 0.0:
                facing = 'HitFront'
            else:
                facing = 'HitBack'
        else:
            self.splat.setColorScale(PartyGlobals.CogActivitySplatColors[1])
            if self.currentFacing > 0.0:
                facing = 'HitBack'
            else:
                facing = 'HitFront'
        if hot:
            targetscale = 0.75
            part = 'head'
        else:
            targetscale = 0.5
            part = 'body'

        def setSplatAlpha(amount):
            self.splat.setAlphaScale(amount)

        self.hitInterval = Sequence(
            ActorInterval(self.actor, part + facing, loop=0),
            Func(self.actor.loop, 'idle'))
        self.hitInterval.start()
        self.kaboomTrack = Parallel(
            SoundInterval(self.pieHitSound,
                          volume=1.0,
                          node=self.actor,
                          cutOff=PartyGlobals.PARTY_COG_CUTOFF),
            Sequence(
                Func(self.splat.showThrough),
                Parallel(
                    Sequence(
                        LerpScaleInterval(self.splat,
                                          duration=0.175,
                                          scale=targetscale,
                                          startScale=Point3(0.1, 0.1, 0.1),
                                          blendType='easeOut'), Wait(0.175)),
                    Sequence(
                        Wait(0.1),
                        LerpFunc(setSplatAlpha,
                                 duration=1.0,
                                 fromData=1.0,
                                 toData=0.0,
                                 blendType='easeOut'))),
                Func(self.splat.cleanup), Func(self.splat.removeNode)))
        self.kaboomTrack.start()
        return

    def showHitScore(self, number, scale=1):
        if number <= 0:
            return
        if self.hpText:
            self.hideHitScore()
        self.HpTextGenerator.setFont(ToontownGlobals.getSignFont())
        if number < 0:
            self.HpTextGenerator.setText(str(number))
        else:
            self.HpTextGenerator.setText('+' + str(number))
        self.HpTextGenerator.clearShadow()
        self.HpTextGenerator.setAlign(TextNode.ACenter)
        r = 1
        g = 1
        b = 0
        a = 1
        self.HpTextGenerator.setTextColor(r, g, b, a)
        self.hpTextNode = self.HpTextGenerator.generate()
        self.hpText = render.attachNewNode(self.hpTextNode)
        self.hpText.setScale(scale)
        self.hpText.setBillboardPointEye()
        self.hpText.setBin('fixed', 100)
        self.hpText.setPos(self.root, 0, 0, self.height / 2)
        seq = Sequence(
            self.hpText.posInterval(
                0.25,
                Point3(self.root.getX(render), self.root.getY(render),
                       self.root.getZ(render) + self.height + 1.0),
                blendType='easeOut'), Wait(0.25),
            self.hpText.colorInterval(0.1, Vec4(r, g, b, 0)),
            Func(self.hideHitScore))
        seq.start()

    def hideHitScore(self):
        if self.hpText:
            taskMgr.remove('PartyCogHpText' + str(self.id))
            self.hpText.removeNode()
            self.hpText = None
        return

    def getHeadLocation(self):
        self.actor.getJoints(jointName='head')[0].getNetTransform(
            self.temp_transform)
        self.head_locator.setMat(self.temp_transform)
        return self.head_locator.getZ(self.root)
Exemplo n.º 44
0
class Transform(Component):
    """Each game object has exactly one of these. A transform holds data
    about position, rotation, scale and parent relationship.
    
    In Panity this is a wrapper for a NodePath.
    """
    def __init__(self, game_object, name):
        # Component class sets self.game_object = game_object
        Component.__init__(self, game_object)
        self.node = NodePath(name)
        self.node.setPythonTag("transform", self)

    @classmethod
    def getClassSerializedProperties(cls):
        """Return all special property attributes in a dict. Only attributes
        derived from SerializedProperty are respected.

        On transform component this method always returns local position,
        -rotation and scale only.
        """
        d = {}
        d["local_position"] = Transform.local_position
        d["local_euler_angles"] = Transform.local_euler_angles
        d["local_scale"] = Transform.local_scale
        return d

    def getSerializedProperties(self):
        """Return all properties for serialization. In the case of transform
        this only returns local position, -rotation and -scale, which are
        required to restore the state of the node.
        """
        d = {}
        d["local_position"] = self.local_position
        d["local_euler_angles"] = self.local_euler_angles
        d["local_scale"] = self.local_scale
        return d

    # We use the panda node to save the name on it for better debugging and
    # efficient finding of nodes with NodePath().find()
    @SerializedPropertyDecorator
    def name(self):
        return self.node.getName()

    @name.setter
    def name(self, name):
        if name == "render":
            name = "_render"
        self.node.setName(name)

    @SerializedPropertyDecorator
    def position(self):
        return self.node.getPos(self.root.node)

    @position.setter
    def position(self, position):
        self.node.setPos(self.root.node, *position)

    @SerializedPropertyDecorator
    def local_position(self):
        return self.node.getPos()

    @local_position.setter
    def local_position(self, position):
        self.node.setPos(*position)

    @SerializedPropertyDecorator
    def euler_angles(self):
        return self.node.getHpr(self.root.node)

    @euler_angles.setter
    def euler_angles(self, angles):
        self.node.setHpr(self.root.node, *angles)

    @SerializedPropertyDecorator
    def local_euler_angles(self):
        return self.node.getHpr()

    @local_euler_angles.setter
    def local_euler_angles(self, angles):
        self.node.setHpr(*angles)

    @SerializedPropertyDecorator
    def rotation(self):
        return self.node.getQuat(self.root.node)

    @rotation.setter
    def rotation(self, quaternion):
        self.node.setQuat(self.root.node, *quaternion)

    @SerializedPropertyDecorator
    def local_rotation(self):
        return self.node.getQuat()

    @local_rotation.setter
    def local_rotation(self, quaternion):
        self.node.setQuat(*quaternion)

    @SerializedPropertyDecorator
    def local_scale(self):
        return self.node.getScale()

    @local_scale.setter
    def local_scale(self, scale):
        self.node.setScale(*scale)

    @SerializedPropertyDecorator
    def parent(self):
        p = self.node.getParent()
        if p.isEmpty() or p.getName() == "render":
            return self
        elif p.hasPythonTag("transform"):
            return p.getPythonTag("transform")

    @parent.setter
    def parent(self, parent):
        self.node.wrtReparentTo(parent.node)

    @SerializedPropertyDecorator
    def root(self):
        if self.parent is not self:
            return self.parent.root()
        else:
            return self

    def destroy(self):
        """Ultimately remove this transform. Warning: this might cause errors
        for other components on this game object. Use this only when removing
        the whole GameObject.
        """
        self.node.removeNode()

    def getChildren(self):
        """Return children as Transforms."""
        # this requires the __iter__() method
        return [c for c in self]

    def __iter__(self):
        """Iterate over children nodes and yield the transform instances."""
        for child in self.node.getChildren():
            if child.hasPythonTag("transform"):
                yield child.getPythonTag("transform")

    def __str__(self):
        r = "Transform for '{}'\n".format(self.name)
        r += "local position: {}\n".format(self.local_position)
        r += "local rotation: {}\n".format(self.local_euler_angles)
        r += "local scale:    {}\n".format(self.local_scale)
        return r
Exemplo n.º 45
0
class HtmlView(DirectObject):
    notify = DirectNotifyGlobal.directNotify.newCategory('HtmlView')
    useHalfTexture = base.config.GetBool('news-half-texture', 0)

    def __init__(self, parent = aspect2d):
        global GlobalWebcore
        self.parent_ = parent
        self.mx = 0
        self.my = 0
        self.htmlFile = 'index.html'
        self.transparency = False
        if GlobalWebcore:
            pass
        else:
            GlobalWebcore = AwWebCore(AwWebCore.LOGVERBOSE, True, AwWebCore.PFBGRA)
            GlobalWebcore.setBaseDirectory('.')
            for errResponse in xrange(400, 600):
                GlobalWebcore.setCustomResponsePage(errResponse, 'error.html')

        self.webView = GlobalWebcore.createWebView(WEB_WIDTH, WEB_HEIGHT, self.transparency, False, 70)
        frameName = ''
        inGameNewsUrl = self.getInGameNewsUrl()
        self.imgBuffer = array.array('B')
        for i in xrange(WEB_WIDTH * WEB_HEIGHT):
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(0)
            self.imgBuffer.append(255)

        if self.useHalfTexture:
            self.leftBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(0)
                self.leftBuffer.append(255)

            self.rightBuffer = array.array('B')
            for i in xrange(WEB_HALF_WIDTH * WEB_HEIGHT):
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(0)
                self.rightBuffer.append(255)

        self.setupTexture()
        if self.useHalfTexture:
            self.setupHalfTextures()
        self.accept('mouse1', self.mouseDown, [AwWebView.LEFTMOUSEBTN])
        self.accept('mouse3', self.mouseDown, [AwWebView.RIGHTMOUSEBTN])
        self.accept('mouse1-up', self.mouseUp, [AwWebView.LEFTMOUSEBTN])
        self.accept('mouse3-up', self.mouseUp, [AwWebView.RIGHTMOUSEBTN])

    def getInGameNewsUrl(self):
        result = base.config.GetString('fallback-news-url', 'http://cdn.toontown.disney.go.com/toontown/en/gamenews/')
        override = base.config.GetString('in-game-news-url', '')
        if override:
            self.notify.info('got an override url,  using %s for in a game news' % override)
            result = override
        else:
            try:
                launcherUrl = base.launcher.getValue('GAME_IN_GAME_NEWS_URL', '')
                if launcherUrl:
                    result = launcherUrl
                    self.notify.info('got GAME_IN_GAME_NEWS_URL from launcher using %s' % result)
                else:
                    self.notify.info('blank GAME_IN_GAME_NEWS_URL from launcher, using %s' % result)
            except:
                self.notify.warning('got exception getting GAME_IN_GAME_NEWS_URL from launcher, using %s' % result)

        return result

    def setupTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)
        cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1)
        bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)
        cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))
        card = cm.generate()
        self.quad = NodePath(card)
        self.quad.reparentTo(self.parent_)
        self.guiTex = Texture('guiTex')
        self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.guiTex.setMinfilter(Texture.FTLinear)
        self.guiTex.setKeepRamImage(True)
        self.guiTex.makeRamImage()
        self.guiTex.setWrapU(Texture.WMRepeat)
        self.guiTex.setWrapV(Texture.WMRepeat)
        ts = TextureStage('webTS')
        self.quad.setTexture(ts, self.guiTex)
        self.quad.setTexScale(ts, 1.0, -1.0)
        self.quad.setTransparency(0)
        self.quad.setTwoSided(True)
        self.quad.setColor(1.0, 1.0, 1.0, 1.0)
        self.calcMouseLimits()

    def setupHalfTextures(self):
        self.setupLeftTexture()
        self.setupRightTexture()
        self.fullPnmImage = PNMImage(WEB_WIDTH, WEB_HEIGHT, 4)
        self.leftPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)
        self.rightPnmImage = PNMImage(WEB_HALF_WIDTH, WEB_HEIGHT, 4)

    def setupLeftTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
        cm.setFrame(-htmlWidth / 2.0, 0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.leftQuad = NodePath(card)
        self.leftQuad.reparentTo(self.parent_)
        self.leftGuiTex = Texture('guiTex')
        self.leftGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.leftGuiTex.setKeepRamImage(True)
        self.leftGuiTex.makeRamImage()
        self.leftGuiTex.setWrapU(Texture.WMClamp)
        self.leftGuiTex.setWrapV(Texture.WMClamp)
        ts = TextureStage('leftWebTS')
        self.leftQuad.setTexture(ts, self.leftGuiTex)
        self.leftQuad.setTexScale(ts, 1.0, -1.0)
        self.leftQuad.setTransparency(0)
        self.leftQuad.setTwoSided(True)
        self.leftQuad.setColor(1.0, 1.0, 1.0, 1.0)

    def setupRightTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)
        cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.rightQuad = NodePath(card)
        self.rightQuad.reparentTo(self.parent_)
        self.rightGuiTex = Texture('guiTex')
        self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba)
        self.rightGuiTex.setKeepRamImage(True)
        self.rightGuiTex.makeRamImage()
        self.rightGuiTex.setWrapU(Texture.WMClamp)
        self.rightGuiTex.setWrapV(Texture.WMClamp)
        ts = TextureStage('rightWebTS')
        self.rightQuad.setTexture(ts, self.rightGuiTex)
        self.rightQuad.setTexScale(ts, 1.0, -1.0)
        self.rightQuad.setTransparency(0)
        self.rightQuad.setTwoSided(True)
        self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)

    def calcMouseLimits(self):
        ll = Point3()
        ur = Point3()
        self.quad.calcTightBounds(ll, ur)
        self.notify.debug('ll=%s ur=%s' % (ll, ur))
        offset = self.quad.getPos(aspect2d)
        self.notify.debug('offset = %s ' % offset)
        ll.setZ(ll.getZ() + offset.getZ())
        ur.setZ(ur.getZ() + offset.getZ())
        self.notify.debug('new LL=%s, UR=%s' % (ll, ur))
        relPointll = self.quad.getRelativePoint(aspect2d, ll)
        self.notify.debug('relPoint = %s' % relPointll)
        self.mouseLL = (aspect2d.getScale()[0] * ll[0], aspect2d.getScale()[2] * ll[2])
        self.mouseUR = (aspect2d.getScale()[0] * ur[0], aspect2d.getScale()[2] * ur[2])
        self.notify.debug('original mouseLL=%s, mouseUR=%s' % (self.mouseLL, self.mouseUR))

    def writeTex(self, filename = 'guiText.png'):
        self.notify.debug('writing texture')
        self.guiTex.generateRamMipmapImages()
        self.guiTex.write(filename)

    def toggleRotation(self):
        if self.interval.isPlaying():
            self.interval.finish()
        else:
            self.interval.loop()

    def mouseDown(self, button):
        messenger.send('wakeup')
        self.webView.injectMouseDown(button)

    def mouseUp(self, button):
        self.webView.injectMouseUp(button)

    def reload(self):
        pass

    def zoomIn(self):
        self.webView.zoomIn()

    def zoomOut(self):
        self.webView.zoomOut()

    def toggleTransparency(self):
        self.transparency = not self.transparency
        self.webView.setTransparent(self.transparency)

    def update(self, task):
        if base.mouseWatcherNode.hasMouse():
            x, y = self._translateRelativeCoordinates(base.mouseWatcherNode.getMouseX(), base.mouseWatcherNode.getMouseY())
            if self.mx - x != 0 or self.my - y != 0:
                self.webView.injectMouseMove(x, y)
                self.mx, self.my = x, y
            if self.webView.isDirty():
                self.webView.render(self.imgBuffer.buffer_info()[0], WEB_WIDTH * 4, 4)
                Texture.setTexturesPower2(2)
                textureBuffer = self.guiTex.modifyRamImage()
                textureBuffer.setData(self.imgBuffer.tostring())
                if self.useHalfTexture:
                    self.guiTex.store(self.fullPnmImage)
                    self.leftPnmImage.copySubImage(self.fullPnmImage, 0, 0, 0, 0, WEB_HALF_WIDTH, WEB_HEIGHT)
                    self.rightPnmImage.copySubImage(self.fullPnmImage, 0, 0, WEB_HALF_WIDTH, 0, WEB_HALF_WIDTH, WEB_HEIGHT)
                    self.leftGuiTex.load(self.leftPnmImage)
                    self.rightGuiTex.load(self.rightPnmImage)
                    self.quad.hide()
                Texture.setTexturesPower2(1)
            GlobalWebcore.update()
        return Task.cont

    def _translateRelativeCoordinates(self, x, y):
        sx = int((x - self.mouseLL[0]) / (self.mouseUR[0] - self.mouseLL[0]) * WEB_WIDTH_PIXELS)
        sy = WEB_HEIGHT_PIXELS - int((y - self.mouseLL[1]) / (self.mouseUR[1] - self.mouseLL[1]) * WEB_HEIGHT_PIXELS)
        return (sx, sy)

    def unload(self):
        self.ignoreAll()
        self.webView.destroy()
        self.webView = None
        return

    def onCallback(self, name, args):
        if name == 'requestFPS':
            pass

    def onBeginNavigation(self, url, frameName):
        pass

    def onBeginLoading(self, url, frameName, statusCode, mimeType):
        pass

    def onFinishLoading(self):
        self.notify.debug('finished loading')

    def onReceiveTitle(self, title, frameName):
        pass

    def onChangeTooltip(self, tooltip):
        pass

    def onChangeCursor(self, cursor):
        pass

    def onChangeKeyboardFocus(self, isFocused):
        pass

    def onChangeTargetURL(self, url):
        pass
Exemplo n.º 46
0
class Player(DirectObject):
    
    #using this to be our player
    #define tehings like health in here
    #have to tie the camera to this
    #game manager ->player ->camera as far as instantiating goes
    
    def __init__(self):
        
        #Color values
        self.red = 0
        self.green = 1
        self.blue = 1
        self.oRed = 0
        self.oGreen = 1
        self.oBlue = 1
        
        #Limits use of weapons on menus
        self.canUseWeapons = True
        #Current overheat value
        self.overHeat = 0
        #Amount of overheat reduced per cycle
        self.overHeatCount = .1
        #Flag for overheated weapons
        self.isOverHeated = False

        #Flag for ccritical health 
        self.down = True

        #Create player node
        self.playerNode = NodePath('player')
        self.playerNode.reparentTo(render)
        self.playerNode.setPos(0,-30,30)
        self.playerNode.setScale(1.0)
        
        #Create player model and reparent it to playerNode
        self.playerModel = loader.loadModel("./resources/player")
        self.playerModel.reparentTo(self.playerNode)
        self.playerModel.setPos(0,0,2)

        #Create weapons and store them in a map
        self.rRifle = RecursionRifle(base.camera, len(base.projectileList))
        self.mhBlunder = MHB(base.camera, len(base.projectileList))
        self.kvDuals = KeyValue(base.camera, len(base.projectileList))
        self.weaponMap = {1:self.rRifle, 2:self.mhBlunder, 3:self.kvDuals}
        self.curWeapon = 1

        #Names of weapons for switcching images
        self.weaponNameMap = {1:"./resources/rrName.png", 2:"./resources/mhbName.png", 3:"./resources/kvdName.png"}
        
        #Load all weaponName images in so it doesn't stutter on swap
        self.weaponName = OnscreenImage(self.weaponNameMap[3])
        self.weaponName.setTransparency(True)
        self.weaponName.setImage(self.weaponNameMap[2])
        self.weaponName.setTransparency(True)
        self.weaponName.setImage(self.weaponNameMap[1])
        self.weaponName.setTransparency(True)
        self.weaponName.reparentTo(render2d)
       
        #Hide weapons currently not in use
        self.mhBlunder.hide()
        self.kvDuals.hide()

        #Weapon controls
        self.accept("mouse1", self.fireWeapon)
        self.accept("mouse3", self.swapWeapon)
        
        #Display HUD
        self.hud = OnscreenImage("resources/hud.png")
        self.hud.setTransparency(True)
        self.hud.reparentTo(render2d)
        
        # define player health here
        # try not to re-create the player object, will alter reset these values
        # alernatively, dump player stats off in save file before recreating
        print "Mod:",base.damageMod
        self.maxEnergy = 100/base.damageMod
        self.curEnergy = self.maxEnergy
        self.accept("cnode", self.hit)
        self.accept("pickuphealth", self.energyUpgrade)
        
        #Load font for text nodes
        font = loader.loadFont("./resources/ni7seg.ttf")

        #Text node for health bar
        self.healthLable = TextNode('health field name')
        self.healthLable.setFont(font)
        self.healthLable.setText("Abstraction")
        self.textNodePath = aspect2d.attachNewNode(self.healthLable)
        self.textNodePath.setScale(0.05)
        self.healthLable.setAlign(TextNode.ACenter)
        self.textNodePath.setPos(0, 0, .68)
        self.healthLable.setTextColor(self.red, self.green, self.blue, 1)

        #TextNode for enemy counter
        self.enemiesLeft = TextNode('monsters to kill')
        self.enemiesLeft.setFont(font)
        self.enemiesLeft.setText(str(len(base.enemyList)))
        self.texnp = aspect2d.attachNewNode(self.enemiesLeft)
        self.texnp.setScale(.1)
        self.texnp.setPos(-1.68, 0, -.75)
        self.enemiesLeft.setTextColor(1, 1, 0, 1)
        

        #Health bar
        self.bar = DirectWaitBar(text = "", value = self.curEnergy, range = self.maxEnergy, pos = (0,.4,.95), barColor = (self.red, self.green, self.blue, 1))
        self.bar.setScale(0.5)
        #Usage bar       
        self.usageBar = DirectWaitBar(text = "", value = self.overHeat, range = 100,  pos = (1.25, -.4, -.95), barColor =(1, 0, 0,1))
        self.usageBar.setScale(0.5)

        #Initailize player collision
        self.createColision()
        
        #Add player tasks
        base.taskMgr.add(self.updateUsage, "usagePaint", taskChain='Gametasks')
        base.taskMgr.add(self.hFlicker, "hflicker", taskChain='GameTasks')
        base.taskMgr.add(self.updateCount, "Ecount", taskChain='GameTasks')
        base.taskMgr.add(CameraMovement(self.playerModel).cameraControl, "cameraControl", taskChain='GameTasks')
        base.taskMgr.add(self.overHeatTask, "overHeatTask")
        base.taskMgr.add(self.killFloor, "Kill Floor") 

    #Deducts health and updates health bar
    def hit(self, damage):

        self.curEnergy = self.curEnergy-damage
        self.bar['value'] = self.curEnergy
        
        #If the player dies
        if self.curEnergy <= 0:

            #Hide player HUD elements
            self.hide()

            #Player can't use weapons while dead
            self.canUseWeapons = False

            #Request game over menu from fsm
            base.fsm.request('GameOver', 1)
    
    #Hides all visable elements attached to the player
    def hide(self):

        self.weaponMap[self.curWeapon].reticle.setScale(0) 
        self.weaponMap[self.curWeapon].curScale = 0
        self.weaponMap[self.curWeapon].step = False

        self.textNodePath.hide()
        self.texnp.hide()
        self.hud.setScale(0)
        self.weaponName.setScale(0)
        self.usageBar.hide()
        self.bar.hide()

    #Display all visable elements attached to the player
    def show(self):

        self.textNodePath.show()
        self.texnp.show()
        self.hud.setScale(1)
        self.weaponName.setScale(1)
        self.usageBar.show()
        self.bar.show()
        
        #Reset the reticle for the current weapon   
        if self.curWeapon == 1:
            
            self.weaponMap[1].reticle.setScale(.025)
            self.weaponMap[1].curScale = .025

        elif self.curWeapon == 2:
            
            self.weaponMap[2].reticle.setScale(.075)
            self.weaponMap[2].curScale = .075
        else:

            self.weaponMap[3].reticle.setScale(.025)
            self.weaponMap[3].curScale = .025


    # set the player health to a specific value        
    def adjustHealth(self, value):

        self.curEnergy = value
        self.bar['value'] = self.curEnergy
    
    #Update enemy counter
    def updateCount(self, task):
        self.enemiesLeft.setText(str(len(base.enemyList)))
        return task.cont 
    
    #Update usage bar and color
    def updateUsage(self, task):

        if self.curEnergy > 0:
            if self.overHeat < 50:
                self.usageBar['barColor'] = (.2, 1, .5, 1)
            elif self.overHeat >=50 and self.overHeat <70:
                self.usageBar['barColor'] = (1, 1, .2, 1)
            elif self.overHeat >= 70:
                self.usageBar['barColor'] = (1, 0, 0, 1)
            self.usageBar['value'] = self.overHeat
            if self.isOverHeated:
                self.usageBar['barColor'] = (1, 0, 0, 1)
            
        return task.cont

    #Swaps to next weapon in the map
    def swapWeapon(self):

        #If you're not in a menu
        if self.canUseWeapons:
            
            #Reset weapon delay
            self.weaponMap[self.curWeapon].resetWeapon
            
            #Change to next weapon and hide reticles
            if  self.curWeapon == 1:
            
                self.weaponName.setImage(self.weaponNameMap[2])
                self.weaponName.setTransparency(True)
                self.weaponMap[1].reticle.setScale(0)
                self.weaponMap[1].curScale = 0
                self.weaponMap[1].step = False
          
                self.rRifle.hide()
                self.mhBlunder.show()
            
                self.curWeapon = 2
                self.weaponMap[2].reticle.setScale(.075)
                self.weaponMap[2].curScale = .075
            elif self.curWeapon == 2:
            
                self.weaponName.setImage(self.weaponNameMap[3])
                self.weaponName.setTransparency(True)
                self.weaponMap[2].reticle.setScale(0)
                self.weaponMap[2].curScale = 0
                self.weaponMap[2].step = False
            
                self.mhBlunder.hide()
                self.kvDuals.show()
            
                self.curWeapon = 3
                self.weaponMap[3].reticle.setScale(.025)
                self.weaponMap[3].curScale = .025
            elif self.curWeapon == 3:

                self.weaponName.setImage(self.weaponNameMap[1])
                self.weaponName.setTransparency(True)
                self.weaponMap[3].reticle.setScale(0)
                self.weaponMap[3].curScale = 0
                self.weaponMap[3].step = False
            
                self.kvDuals.hide()
                self.rRifle.show()
           
                self.curWeapon = 1
                self.weaponMap[1].reticle.setScale(.025)
                self.weaponMap[1].curScale = .025
         
            base.taskMgr.remove("weaponDelay")
    
    #Fires current weapon
    def fireWeapon(self):

        #If the player is not in a menu
        if self.canUseWeapons:

            #If there isn't a weapon delay task add one
            if base.taskMgr.hasTaskNamed("weaponDelay") == False:
                
                #If your not overheated
                if not self.isOverHeated:

                    base.taskMgr.add(self.weaponMap[self.curWeapon].fire, "fire")

            #If you can shoot as defined by weapon delay
            elif self.weaponMap[self.curWeapon].canShoot() == True:

                #and if your not overheated
                if not self.isOverHeated:
                    
                    base.taskMgr.remove("weaponDelay")
                    base.taskMgr.add(self.weaponMap[self.curWeapon].fire, "fire")

    #Handles weapon overheat
    def overHeatTask(self, task):
        
        #Every cycle decrement your overheat by the specified amount
        self.overHeat -= self.overHeatCount
        
        #If you exceed the limit
        if self.overHeat >= 100:
            
            #Increase cooldown amount and set overheated flag
            self.overHeatCount = .5
            self.isOverHeated = True

        #If your are not overheated anymore reset not default cooldown values
        elif self.overHeat < 0:
            
            self.overHeatCount = .1
            self.overHeat = 0
            self.isOverHeated = False

        return task.cont

    #Initialize player collision
    def createColision(self):
        
        #Set up floor collision handler
        base.floor = CollisionHandlerGravity()
        base.floor.setGravity(9.8)

        #Create player collision node and add to traverser
        self.playerCollNodePath = self.initCollisionSphere(self.playerNode.getChild(0))
        base.cTrav.addCollider(self.playerCollNodePath, base.pusher)
        base.pusher.addCollider(self.playerCollNodePath, self.playerNode)
        
        # Create Floor Ray - for gravity / floor
        floorCollRayPath = self.initCollisionRay(1,-1) 
        base.floor.addCollider(floorCollRayPath, self.playerNode)
        base.cTrav.addCollider(floorCollRayPath, base.floor)
        floorCollRayPath.reparentTo(self.playerModel)

    #Initialize player collision sphere
    def initCollisionSphere(self, obj):
        
        # Create sphere and attach to player
        cNode = CollisionNode('player')

        cs = CollisionSphere(0, 0, 4, 2)
        cNodePath = obj.attachNewNode(CollisionNode('cnode'))
        cNodePath.node().addSolid(cs)
        cNodePath.show()
        
        return cNodePath
    
    #Attach player to a collision ray
    def initCollisionRay(self, originZ, dirZ):
        ray = CollisionRay(0,0,originZ,0,0,dirZ)
        collNode = CollisionNode('playerRay')
        collNode.addSolid(ray)
        collNode.setFromCollideMask(BitMask32.bit(1))
        collNode.setIntoCollideMask(BitMask32.allOff())
        collRayNP = self.playerNode.attachNewNode(collNode)
        collRayNP.show()
        return collRayNP

    #call this method when collide with a health upgrade
    def energyUpgrade(self):

        self.maxEnergy +=(10/base.damageMod)
        self.curEnergy = self.curEnergy+(10/base.damageMod)
        self.bar['range'] = self.maxEnergy
        self.adjustHealth(self.curEnergy)
    
    #Hurts player and resets the to the levels origin upon falliong in a pit.
    def killFloor(self, task):
        
	    z = int(self.playerNode.getPos()[2])

	    if(z < -7):

		    self.playerNode.setPos(0, 0, 6) #resets height
		    self.playerModel.setPos(base.xPos, base.yPos, base.zPos) #resets position
		    self.hit(10)
	    return task.cont

    #Makes the health bar flicker when your health is critical
    def hFlicker(self, task):

        if self.curEnergy <=30:
            if self.down:
                self.red = self.red+0.1
                self.blue = self.blue-.01
                self.green = self.green-.01
            else:
                self.red = self.red-0.1
                self.blue = self.green+0.1
                self.green = self.green+0.1
        else:
            self.red = self.oRed
            self.blue = self.oBlue
            self.green = self.oGreen
        if self.red >=1:
            self.down = False
        if self.red <=0:
            self.down = True
        self.healthLable.setTextColor(self.red, self.green, self.blue, 1)
        self.bar['barColor']=(self.red, self.green, self.blue, 1)
        return task.cont
        
    #Resets players health and signifies they have restarted level after death
    def resetEnergy(self):

        self.canUseWeapons = True
        self.curEnergy = self.maxEnergy
        self.adjustHealth(self.curEnergy)
Exemplo n.º 47
0
class CameraManager:
    nextID = 0

    def __init__(self, cameraNP):
        self.cameraNP = cameraNP
        self.id = CameraManager.nextID
        CameraManager.nextID += 1
        self.otherNP = render
        self.lookAtNP = NodePath('CameraManager%d.lookAtNP' % self.id)
        self.lookAtEnabled = False
        self.targetPos = Point3(0.0, 0.0, 0.0)
        self.targetLookAtPos = Point3(0.0, 1.0, 0.0)
        self.enabled = False
        self.rate = 10.0

    def destroy(self):
        if self.enabled:
            self.setEnabled(False)
        self.lookAtNP.removeNode()
        del self.lookAtNP
        del self.targetPos
        del self.targetLookAtPos
        del self.otherNP

    def setEnabled(self, enabled):
        if enabled != self.enabled:
            if enabled:
                taskMgr.add(self.updateTask, 'CameraManager%d.update' % self.id)
            else:
                taskMgr.remove('CameraManager%d.update' % self.id)
            self.enabled = enabled

    def setTargetPos(self, p):
        self.targetPos = p

    def setPos(self, p):
        self.targetPos = p
        self.cameraNP.setPos(self.otherNP, p)

    def setTargetLookAtPos(self, p):
        self.lookAtEnabled = True
        self.targetLookAtPos = p

    def setLookAtPos(self, p):
        self.lookAtEnabled = True
        self.targetLookAtPos = p
        self.lookAtNP.setPos(p)

    def setHpr(self, hpr):
        self.lookAtEnabled = False
        self.cameraNP.setHpr(self.otherNP, hpr)

    def updateTask(self, task):
        newCameraPos = self.rateInterpolate(self.cameraNP.getPos(self.otherNP), self.targetPos)
        self.cameraNP.setPos(self.otherNP, newCameraPos)
        if self.lookAtEnabled:
            newLookAtPos = self.rateInterpolate(self.lookAtNP.getPos(self.otherNP), self.targetLookAtPos)
            self.lookAtNP.setPos(self.otherNP, newLookAtPos)
            self.cameraNP.lookAt(self.lookAtNP)
        return task.cont

    def rateInterpolate(self, currentPos, targetPos):
        dt = globalClock.getDt()
        vec = currentPos - targetPos
        return targetPos + vec * inverse_e ** (dt * self.rate)
Exemplo n.º 48
0
class CogdoFlyingCameraManager:
    def __init__(self, cam, parent, player, level):
        self._toon = player.toon
        self._camera = cam
        self._parent = parent
        self._player = player
        self._level = level
        self._enabled = False

    def enable(self):
        if self._enabled:
            return
        self._toon.detachCamera()
        self._prevToonY = 0.0
        levelBounds = self._level.getBounds()
        l = Globals.Camera.LevelBoundsFactor
        self._bounds = ((levelBounds[0][0] * l[0], levelBounds[0][1] * l[0]),
                        (levelBounds[1][0] * l[1], levelBounds[1][1] * l[1]),
                        (levelBounds[2][0] * l[2], levelBounds[2][1] * l[2]))
        self._lookAtZ = self._toon.getHeight(
        ) + Globals.Camera.LookAtToonHeightOffset
        self._camParent = NodePath('CamParent')
        self._camParent.reparentTo(self._parent)
        self._camParent.setPos(self._toon, 0, 0, 0)
        self._camParent.setHpr(180, Globals.Camera.Angle, 0)
        self._camera.reparentTo(self._camParent)
        self._camera.setPos(0, Globals.Camera.Distance, 0)
        self._camera.lookAt(self._toon, 0, 0, self._lookAtZ)
        self._cameraLookAtNP = NodePath('CameraLookAt')
        self._cameraLookAtNP.reparentTo(self._camera.getParent())
        self._cameraLookAtNP.setPosHpr(self._camera.getPos(),
                                       self._camera.getHpr())
        self._levelBounds = self._level.getBounds()
        self._enabled = True
        self._frozen = False
        self._initCollisions()

    def _initCollisions(self):
        self._camCollRay = CollisionRay()
        camCollNode = CollisionNode('CameraToonRay')
        camCollNode.addSolid(self._camCollRay)
        camCollNode.setFromCollideMask(OTPGlobals.WallBitmask
                                       | OTPGlobals.CameraBitmask
                                       | ToontownGlobals.FloorEventBitmask
                                       | ToontownGlobals.CeilingBitmask)
        camCollNode.setIntoCollideMask(0)
        self._camCollNP = self._camera.attachNewNode(camCollNode)
        self._camCollNP.show()
        self._collOffset = Vec3(0, 0, 0.5)
        self._collHandler = CollisionHandlerQueue()
        self._collTrav = CollisionTraverser()
        self._collTrav.addCollider(self._camCollNP, self._collHandler)
        self._betweenCamAndToon = {}
        self._transNP = NodePath('trans')
        self._transNP.reparentTo(render)
        self._transNP.setTransparency(True)
        self._transNP.setAlphaScale(Globals.Camera.AlphaBetweenToon)
        self._transNP.setBin('fixed', 10000)

    def _destroyCollisions(self):
        self._collTrav.removeCollider(self._camCollNP)
        self._camCollNP.removeNode()
        del self._camCollNP
        del self._camCollRay
        del self._collHandler
        del self._collOffset
        del self._betweenCamAndToon
        self._transNP.removeNode()
        del self._transNP

    def freeze(self):
        self._frozen = True

    def unfreeze(self):
        self._frozen = False

    def disable(self):
        if not self._enabled:
            return
        self._destroyCollisions()
        self._camera.wrtReparentTo(render)
        self._cameraLookAtNP.removeNode()
        del self._cameraLookAtNP
        self._camParent.removeNode()
        del self._camParent
        del self._prevToonY
        del self._lookAtZ
        del self._bounds
        del self._frozen
        self._enabled = False

    def update(self, dt=0.0):
        self._updateCam(dt)
        self._updateCollisions()

    def _updateCam(self, dt):
        toonPos = self._toon.getPos()
        camPos = self._camParent.getPos()
        x = camPos[0]
        z = camPos[2]
        toonWorldX = self._toon.getX(render)
        maxX = Globals.Camera.MaxSpinX
        toonWorldX = clamp(toonWorldX, -1.0 * maxX, maxX)
        spinAngle = Globals.Camera.MaxSpinAngle * toonWorldX * toonWorldX / (
            maxX * maxX)
        newH = 180.0 + spinAngle
        self._camParent.setH(newH)
        spinAngle = spinAngle * (pi / 180.0)
        distBehindToon = Globals.Camera.SpinRadius * cos(spinAngle)
        distToRightOfToon = Globals.Camera.SpinRadius * sin(spinAngle)
        d = self._camParent.getX() - clamp(toonPos[0], *self._bounds[0])
        if abs(d) > Globals.Camera.LeewayX:
            if d > Globals.Camera.LeewayX:
                x = toonPos[0] + Globals.Camera.LeewayX
            else:
                x = toonPos[0] - Globals.Camera.LeewayX
        x = self._toon.getX(render) + distToRightOfToon
        boundToonZ = min(toonPos[2], self._bounds[2][1])
        d = z - boundToonZ
        if d > Globals.Camera.MinLeewayZ:
            if self._player.velocity[2] >= 0 and toonPos[
                    1] != self._prevToonY or self._player.velocity[2] > 0:
                z = boundToonZ + d * INVERSE_E**(dt *
                                                 Globals.Camera.CatchUpRateZ)
            elif d > Globals.Camera.MaxLeewayZ:
                z = boundToonZ + Globals.Camera.MaxLeewayZ
        elif d < -Globals.Camera.MinLeewayZ:
            z = boundToonZ - Globals.Camera.MinLeewayZ
        if self._frozen:
            y = camPos[1]
        else:
            y = self._toon.getY(render) - distBehindToon
        self._camParent.setPos(x, smooth(camPos[1], y), smooth(camPos[2], z))
        if toonPos[2] < self._bounds[2][1]:
            h = self._cameraLookAtNP.getH()
            if d >= Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._toon, 0, 0, self._lookAtZ)
            elif d <= -Globals.Camera.MinLeewayZ:
                self._cameraLookAtNP.lookAt(self._camParent, 0, 0,
                                            self._lookAtZ)
            self._cameraLookAtNP.setHpr(h, self._cameraLookAtNP.getP(), 0)
            self._camera.setHpr(
                smooth(self._camera.getHpr(), self._cameraLookAtNP.getHpr()))
        self._prevToonY = toonPos[1]

    def _updateCollisions(self):
        pos = self._toon.getPos(self._camera) + self._collOffset
        self._camCollRay.setOrigin(pos)
        direction = -Vec3(pos)
        direction.normalize()
        self._camCollRay.setDirection(direction)
        self._collTrav.traverse(render)
        nodesInBetween = {}
        if self._collHandler.getNumEntries() > 0:
            self._collHandler.sortEntries()
            for entry in self._collHandler.getEntries():
                name = entry.getIntoNode().getName()
                if name.find('col_') >= 0:
                    np = entry.getIntoNodePath().getParent()
                    if np not in nodesInBetween:
                        nodesInBetween[np] = np.getParent()

        for np in nodesInBetween.keys():
            if np in self._betweenCamAndToon:
                del self._betweenCamAndToon[np]
            else:
                np.setTransparency(True)
                np.wrtReparentTo(self._transNP)
                if np.getName().find('lightFixture') >= 0:
                    if not np.find('**/*floor_mesh').isEmpty():
                        np.find('**/*floor_mesh').hide()
                elif np.getName().find('platform') >= 0:
                    if not np.find('**/*Floor').isEmpty():
                        np.find('**/*Floor').hide()

        for np, parent in self._betweenCamAndToon.items():
            np.wrtReparentTo(parent)
            np.setTransparency(False)
            if np.getName().find('lightFixture') >= 0:
                if not np.find('**/*floor_mesh').isEmpty():
                    np.find('**/*floor_mesh').show()
            elif np.getName().find('platform') >= 0:
                if not np.find('**/*Floor').isEmpty():
                    np.find('**/*Floor').show()

        self._betweenCamAndToon = nodesInBetween
Exemplo n.º 49
0
class Handle(PandaNode, MouseEventListener):
    
    def __init__(self):
        PandaNode.__init__(self, 'PositionHandle')

        CameraController.getInstance().addEventHandler(EVT_CAMERA_MOVE,
                self._fixScale)
        self.path = NodePath(self)

        self.xHandle = DirectionHandle(self, Vec4(1, 0, 0, 0.6),
                Vec3(0, 0, 90), 'x')
        self.addChild(self.xHandle)

        self.yHandle = DirectionHandle(self, Vec4(0, 1, 0, 0.6),
                Vec3(0, -90, 0), 'y')
        self.addChild(self.yHandle)
        
        self.zHandle = DirectionHandle(self, Vec4(0, 0, 1, 0.6),
                Vec3(0, 0, 0), 'z')
        self.addChild(self.zHandle)
        
        self.hHandle = RotationHandle(self, Vec4(0, 0, 1, 0.6),
                Vec3(0, 0, 0), 'z')
        self.addChild(self.hHandle)
        NodePath(self.hHandle).setScale(1.02)

        self.pHandle = RotationHandle(self, Vec4(0, 1, 0, 0.6),
                Vec3(0, -90, 0), 'y')
        self.addChild(self.pHandle)
        NodePath(self.pHandle).setScale(0.98)

        self.rHandle = RotationHandle(self, Vec4(1, 0, 0, 0.6),
                Vec3(0, 0, 90), 'x')
        self.addChild(self.rHandle)
        self._tPressed()
        
        self.path.setTransparency(1)
        self.path.setBin('transparent', 30, 50)
        #self.path.setDepthTest(False)
        self.path.setLightOff()
        self.path.setRenderModeThickness(2)
        self.setClients([])

        self.evtWatcher = DirectObject.DirectObject()
        self.evtWatcher.accept(base.win.getWindowEvent(),
            self._windowEventHandler)
        self.evtWatcher.accept('r', self._rPressed)
        self.evtWatcher.accept('t', self._tPressed)

        self.originalPos = self.path.getPos()
        self.fLenPx = base.cam.node().getLens().getFocalLength() * base.win.getXSize()
        self._fixScale()

    def _rPressed(self):
        self.xHandle.path.stash()
        self.yHandle.path.stash()
        self.zHandle.path.stash()
        self.hHandle.path.unstash()
        self.pHandle.path.unstash()
        self.rHandle.path.unstash()

    def _tPressed(self):
        self.xHandle.path.unstash()
        self.yHandle.path.unstash()
        self.zHandle.path.unstash()
        self.hHandle.path.stash()
        self.pHandle.path.stash()
        self.rHandle.path.stash()

    def setClients(self, clients, center=Vec3()):
        if clients:
            self.path.show(BitMask32(1|4|16))
            self.path.setPos(center)
            self._fixScale()
        else:
            self.path.hide(BitMask32(1|2|4|8|16))
        self.clients = [[client, None] for client in clients]

    def beginTransformation(self):
        self.originalMat = Mat4(Mat4.identMat())
        self.originalMat.setRow(3, self.path.getMat(render).getRow(3))
        self.originalMatInv = Mat4()
        self.originalMatInv.invertAffineFrom(self.originalMat)
        for i in xrange(len(self.clients)):
            print 'Their matrix * My matrix'
            print self.clients[i][0].getMat(self.path) * self.path.getMat()
            print 'Total matrix:'
            print self.clients[i][0].getMat()
            #self.clients[i][1] = self.clients[i][0].getMat(self.path)
            self.clients[i][1] = (self.clients[i][0].getMat() *
                    self.originalMatInv)

    def transform(self, xform):
        transl = Mat4(Mat4.identMat())
        transl.setRow(3, xform.getRow3(3))
        self.path.setMat(render, transl * self.originalMat)
        self._fixScale()
        xform.setRow(3, Vec3())
        for client, originalMat in self.clients:
            #client.setMat(self.path, originalMat * xform)
            client.setMat(originalMat * xform * transl * self.originalMat)

    def _fixScale(self, camera=base.camera):
        myPos = self.path.getPos()
        dist = (camera.getPos() - myPos).length()
        self.path.setScale(dist * HANDLE_SIZE / self.fLenPx)

    def _windowEventHandler(self, window):
        self.fLenPx = (base.cam.node().getLens().getFocalLength() *
                 window.getXSize())
        self._fixScale()
Exemplo n.º 50
0
class CameraManager:
    nextID = 0

    def __init__(self, cameraNP):
        self.cameraNP = cameraNP
        self.id = CameraManager.nextID
        CameraManager.nextID += 1
        self.otherNP = render
        self.lookAtNP = NodePath('CameraManager%d.lookAtNP' % self.id)
        self.lookAtEnabled = False
        self.targetPos = Point3(0.0, 0.0, 0.0)
        self.targetLookAtPos = Point3(0.0, 1.0, 0.0)
        self.enabled = False
        self.rate = 10.0

    def destroy(self):
        if self.enabled:
            self.setEnabled(False)
        self.lookAtNP.removeNode()
        del self.lookAtNP
        del self.targetPos
        del self.targetLookAtPos
        del self.otherNP

    def setEnabled(self, enabled):
        if enabled != self.enabled:
            if enabled:
                taskMgr.add(self.updateTask, 'CameraManager%d.update' % self.id)
            else:
                taskMgr.remove('CameraManager%d.update' % self.id)
            self.enabled = enabled

    def setTargetPos(self, p):
        self.targetPos = p

    def setPos(self, p):
        self.targetPos = p
        self.cameraNP.setPos(self.otherNP, p)

    def setTargetLookAtPos(self, p):
        self.lookAtEnabled = True
        self.targetLookAtPos = p

    def setLookAtPos(self, p):
        self.lookAtEnabled = True
        self.targetLookAtPos = p
        self.lookAtNP.setPos(p)

    def setHpr(self, hpr):
        self.lookAtEnabled = False
        self.cameraNP.setHpr(self.otherNP, hpr)

    def updateTask(self, task):
        newCameraPos = self.rateInterpolate(self.cameraNP.getPos(self.otherNP), self.targetPos)
        self.cameraNP.setPos(self.otherNP, newCameraPos)
        if self.lookAtEnabled:
            newLookAtPos = self.rateInterpolate(self.lookAtNP.getPos(self.otherNP), self.targetLookAtPos)
            self.lookAtNP.setPos(self.otherNP, newLookAtPos)
            self.cameraNP.lookAt(self.lookAtNP)
        return task.cont

    def rateInterpolate(self, currentPos, targetPos):
        dt = globalClock.getDt()
        vec = currentPos - targetPos
        return targetPos + vec * inverse_e ** (dt * self.rate)
Exemplo n.º 51
0
class PartyCogActivityLocalPlayer(PartyCogActivityPlayer):

    def __init__(self, activity, position, team, exitActivityCallback = None):
        PartyCogActivityPlayer.__init__(self, activity, base.localAvatar, position, team)
        self.input = PartyCogActivityInput(exitActivityCallback)
        self.gui = PartyCogActivityGui()
        self.throwPiePrevTime = 0
        self.lastMoved = 0
        if base.localAvatar:
            self.prevPos = base.localAvatar.getPos()
        self.cameraManager = None
        self.control = None
        self.consecutiveShortThrows = 0
        return

    def destroy(self):
        if self.enabled:
            self.disable()
        if self.cameraManager is not None:
            self.cameraManager.setEnabled(False)
            self.cameraManager.destroy()
        del self.cameraManager
        del self.gui
        del self.input
        if self.control is not None:
            self.control.destroy()
        del self.control
        PartyCogActivityPlayer.destroy(self)
        return

    def _initOrthoWalk(self):
        orthoDrive = OrthoDrive(9.778, customCollisionCallback=self.activity.view.checkOrthoDriveCollision)
        self.orthoWalk = OrthoWalk(orthoDrive, broadcast=True)

    def _destroyOrthoWalk(self):
        self.orthoWalk.stop()
        self.orthoWalk.destroy()
        del self.orthoWalk

    def getPieThrowingPower(self, time):
        elapsed = max(time - self.input.throwPiePressedStartTime, 0.0)
        w = 1.0 / PartyGlobals.CogActivityPowerMeterTime * 2.0 * math.pi
        power = int(round(-math.cos(w * elapsed) * 50.0 + 50.0))
        return power

    def isShortThrow(self, time):
        elapsed = max(time - self.input.throwPiePressedStartTime, 0.0)
        return elapsed <= PartyGlobals.CogActivityShortThrowTime

    def checkForThrowSpam(self, time):
        if self.isShortThrow(time):
            self.consecutiveShortThrows += 1
        else:
            self.consecutiveShortThrows = 0
        return self.consecutiveShortThrows >= PartyGlobals.CogActivityShortThrowSpam

    def _startUpdateTask(self):
        task = Task(self._updateTask)
        task.lastPositionBroadcastTime = 0.0
        self.throwPiePrevTime = 0
        taskMgr.add(task, UPDATE_TASK_NAME)

    def _stopUpdateTask(self):
        taskMgr.remove(UPDATE_TASK_NAME)

    def _updateTask(self, task):
        self._update()
        if base.localAvatar.getPos() != self.prevPos:
            self.prevPos = base.localAvatar.getPos()
            self.lastMoved = self.activity.getCurrentActivityTime()
        if max(self.activity.getCurrentActivityTime() - self.lastMoved, 0) > PartyGlobals.ToonMoveIdleThreshold:
            self.gui.showMoveControls()
        if max(self.activity.getCurrentActivityTime() - self.throwPiePrevTime, 0) > PartyGlobals.ToonAttackIdleThreshold:
            self.gui.showAttackControls()
        if self.input.throwPieWasReleased:
            if self.checkForThrowSpam(globalClock.getFrameTime()):
                self.gui.showSpamWarning()
            self.input.throwPieWasReleased = False
            self.throwPie(self.getPieThrowingPower(globalClock.getFrameTime()))
        return Task.cont

    def throwPie(self, piePower):
        if not self.activity.isState('Active'):
            return
        if self.activity.getCurrentActivityTime() - self.throwPiePrevTime > THROW_PIE_LIMIT_TIME:
            self.throwPiePrevTime = self.activity.getCurrentActivityTime()
            self.activity.b_pieThrow(self.toon, piePower)

    def _update(self):
        self.control.update()

    def getLookat(self, whosLooking, refNode = None):
        if refNode is None:
            refNode = render
        dist = 5.0
        oldParent = self.tempNP.getParent()
        self.tempNP.reparentTo(whosLooking)
        self.tempNP.setPos(0.0, dist, 0.0)
        pos = self.tempNP.getPos(refNode)
        self.tempNP.reparentTo(oldParent)
        return pos

    def entersActivity(self):
        base.cr.playGame.getPlace().setState('activity')
        PartyCogActivityPlayer.entersActivity(self)
        self.gui.disableToontownHUD()
        self.cameraManager = CameraManager(camera)
        self.tempNP = NodePath('temp')
        self.lookAtMyTeam()
        self.control = StrafingControl(self)

    def exitsActivity(self):
        PartyCogActivityPlayer.exitsActivity(self)
        self.gui.enableToontownHUD()
        self.cameraManager.setEnabled(False)
        self.tempNP.removeNode()
        self.tempNP = None
        if not aspect2d.find('**/JellybeanRewardGui*'):
            base.cr.playGame.getPlace().setState('walk')
        else:
            self.toon.startPosHprBroadcast()
        return

    def getRunToStartPositionIval(self):
        targetH = self.locator.getH()
        travelVec = self.position - self.toon.getPos(self.activity.root)
        duration = travelVec.length() / 9.778
        startH = 0.0
        if travelVec.getY() < 0.0:
            startH = 180.0
        return Sequence(Func(self.toon.startPosHprBroadcast, 0.1), Func(self.toon.b_setAnimState, 'run'), Parallel(self.toon.hprInterval(0.5, VBase3(startH, 0.0, 0.0), other=self.activity.root), self.toon.posInterval(duration, self.position, other=self.activity.root)), Func(self.toon.b_setAnimState, 'neutral'), self.toon.hprInterval(0.25, VBase3(targetH, 0.0, 0.0), other=self.activity.root), Func(self.toon.stopPosHprBroadcast))

    def enable(self):
        if self.enabled:
            return
        PartyCogActivityPlayer.enable(self)
        self.toon.b_setAnimState('Happy')
        self._initOrthoWalk()
        self.orthoWalk.start()
        self.orthoWalking = True
        self.input.enable()
        self.gui.disableToontownHUD()
        self.gui.load()
        self.gui.setScore(0)
        self.gui.showScore()
        self.gui.setTeam(self.team)
        self.gui.startTrackingCogs(self.activity.view.cogManager.cogs)
        self.control.enable()
        self._startUpdateTask()

    def disable(self):
        if not self.enabled:
            return
        self._stopUpdateTask()
        self.toon.b_setAnimState('neutral')
        PartyCogActivityPlayer.disable(self)
        self.orthoWalking = False
        self.orthoWalk.stop()
        self._destroyOrthoWalk()
        self.input.disable()
        self._aimMode = False
        self.cameraManager.setEnabled(False)
        self.gui.hide()
        self.gui.stopTrackingCogs()
        self.gui.unload()

    def updateScore(self):
        self.gui.setScore(self.score)

    def b_updateToonPosition(self):
        self.updateToonPosition()
        self.d_updateToonPosition()

    def d_updateToonPosition(self):
        self.toon.d_setPos(self.toon.getX(), self.toon.getY(), self.toon.getZ())
        self.toon.d_setH(self.toon.getH())

    def lookAtArena(self):
        self.cameraManager.setEnabled(True)
        self.cameraManager.setTargetPos(self.activity.view.arena.find('**/conclusionCamPos_locator').getPos(render))
        self.cameraManager.setTargetLookAtPos(self.activity.view.arena.find('**/conclusionCamAim_locator').getPos(render))

    def lookAtMyTeam(self):
        activityView = self.activity.view
        arena = activityView.arena
        pos = activityView.teamCamPosLocators[self.team].getPos()
        aim = activityView.teamCamAimLocators[self.team].getPos()
        camera.wrtReparentTo(arena)
        self.cameraManager.setPos(camera.getPos(render))
        self.tempNP.reparentTo(arena)
        self.tempNP.setPos(arena, pos)
        self.cameraManager.setTargetPos(self.tempNP.getPos(render))
        self.cameraManager.setLookAtPos(self.getLookat(camera))
        self.tempNP.reparentTo(arena)
        self.tempNP.setPos(arena, aim)
        self.cameraManager.setTargetLookAtPos(self.tempNP.getPos(render))
        self.cameraManager.setEnabled(True)
        camera.setP(0.0)
        camera.setR(0.0)
Exemplo n.º 52
0
class SpotLight(Light, DebugObject):

    """ This light type simulates a SpotLight. It has a position
    and an orientation. """

    def __init__(self):
        """ Creates a new spot light. """
        Light.__init__(self)
        DebugObject.__init__(self, "SpotLight")
        self.typeName = "SpotLight"

        self.nearPlane = 0.5
        self.radius = 30.0
        self.spotSize = Vec2(30, 30)

        # Used to compute the MVP
        self.ghostCamera = Camera("PointLight")
        self.ghostCamera.setActive(False)
        self.ghostLens = PerspectiveLens()
        self.ghostLens.setFov(130)
        self.ghostCamera.setLens(self.ghostLens)
        self.ghostCameraNode = NodePath(self.ghostCamera)
        self.ghostCameraNode.reparentTo(Globals.render)
        self.ghostCameraNode.hide()

    def getLightType(self):
        """ Internal method to fetch the type of this light, used by Light """
        return LightType.Spot

    def _updateLens(self):
        """ Internal method which gets called when the lens properties changed """
        for source in self.shadowSources:
            source.rebuildMatrixCache()

    def cleanup(self):
        """ Internal method which gets called when the light got deleted """
        self.ghostCameraNode.removeNode()
        Light.cleanup(self)

    def setFov(self, fov):
        """ Sets the field of view of the spotlight """
        assert(fov > 1 and fov < 180)
        self.ghostLens.setFov(fov)
        self._updateLens()

    def setPos(self, pos):
        """ Sets the position of the spotlight """
        self.ghostCameraNode.setPos(pos)
        Light.setPos(self, pos)

    def lookAt(self, pos):
        """ Makes the spotlight look at the given position """
        self.ghostCameraNode.lookAt(pos)

    def _computeAdditionalData(self):
        """ Internal method to recompute the spotlight MVP """
        self.ghostCameraNode.setPos(self.position)

        projMat = self.ghostLens.getProjectionMat()

        modelViewMat = Globals.render.getTransform(self.ghostCameraNode).getMat()
        self.mvp = modelViewMat * projMat

    def _computeLightBounds(self):
        """ Recomputes the bounds of this light. For a SpotLight, we for now
        use a simple BoundingSphere """
        self.bounds = BoundingSphere(Point3(self.position), self.radius * 2.0)

    def setNearFar(self, near, far):
        """ Sets the near and far plane of the spotlight """
        self.nearPlane = near
        self.radius = far
        self.ghostLens.setNearFar(near, far)
        self._updateLens()

    def _updateDebugNode(self):
        """ Internal method to generate new debug geometry. """
        debugNode = NodePath("SpotLightDebugNode")

        # Create the inner image 
        cm = CardMaker("SpotLightDebug")
        cm.setFrameFullscreenQuad()
        innerNode = NodePath(cm.generate())
        innerNode.setTexture(Globals.loader.loadTexture("Data/GUI/Visualization/SpotLight.png"))
        innerNode.setBillboardPointEye()
        innerNode.reparentTo(debugNode)
        innerNode.setPos(self.position)
        innerNode.setColorScale(1,1,0,1)

        # Create the outer lines
        lineNode = debugNode.attachNewNode("lines")

        currentNodeTransform = render.getTransform(self.ghostCameraNode).getMat()
        currentCamTransform = self.ghostLens.getProjectionMat()
        currentRelativeCamPos = self.ghostCameraNode.getPos(render)
        currentCamBounds = self.ghostLens.makeBounds()
        currentCamBounds.xform(self.ghostCameraNode.getMat(render))

        p = lambda index: currentCamBounds.getPoint(index)

        # Make a circle at the bottom
        frustumBottomCenter = (p(0) + p(1) + p(2) + p(3)) * 0.25
        upVector = (p(0) + p(1)) / 2 - frustumBottomCenter
        rightVector = (p(1) + p(2)) / 2 - frustumBottomCenter
        points = []
        for idx in xrange(64):
            rad = idx / 64.0 * math.pi * 2.0
            pos = upVector * math.sin(rad) + rightVector * math.cos(rad)
            pos += frustumBottomCenter
            points.append(pos)
        frustumLine = self._createDebugLine(points, True)
        frustumLine.setColorScale(1,1,0,1)
        frustumLine.reparentTo(lineNode)


        # Create frustum lines which connect the origin to the bottom circle
        pointArrays = [
            [self.position, frustumBottomCenter + upVector],
            [self.position, frustumBottomCenter - upVector],
            [self.position, frustumBottomCenter + rightVector],
            [self.position, frustumBottomCenter - rightVector],
        ]

        for pointArray in pointArrays:
            frustumLine = self._createDebugLine(pointArray, False)
            frustumLine.setColorScale(1,1,0,1)
            frustumLine.reparentTo(lineNode)

        # Create line which is in the direction of the spot light
        startPoint = (p(0) + p(1) + p(2) + p(3)) * 0.25
        endPoint = (p(4) + p(5) + p(6) + p(7)) * 0.25
        line = self._createDebugLine([startPoint, endPoint], False)
        line.setColorScale(1,1,1,1)
        line.reparentTo(lineNode)

        # Remove the old debug node
        self.debugNode.node().removeAllChildren()

        # Attach the new debug node
        debugNode.reparentTo(self.debugNode)
        # self.debugNode.flattenStrong()

    def _initShadowSources(self):
        """ Internal method to init the shadow sources """
        source = ShadowSource()
        source.setResolution(self.shadowResolution)
        source.setLens(self.ghostLens)
        self._addShadowSource(source)

    def _updateShadowSources(self):
        """ Recomputes the position of the shadow source """
        self.shadowSources[0].setPos(self.position)
        self.shadowSources[0].setHpr(self.ghostCameraNode.getHpr())

    def __repr__(self):
        """ Generates a string representation of this instance """
        return "SpotLight[]"
Exemplo n.º 53
0
class Transform(Component):
    """Each game object has exactly one of these. A transform holds data
    about position, rotation, scale and parent relationship.
    
    In Panity this is a wrapper for a NodePath.
    """

    def __init__(self, game_object, name):
        # Component class sets self.game_object = game_object
        Component.__init__(self, game_object)
        self.node = NodePath(name)
        self.node.setPythonTag("transform", self)

    @classmethod
    def getClassSerializedProperties(cls):
        """Return all special property attributes in a dict. Only attributes
        derived from SerializedProperty are respected.

        On transform component this method always returns local position,
        -rotation and scale only.
        """
        d = {}
        d["local_position"] = Transform.local_position
        d["local_euler_angles"] = Transform.local_euler_angles
        d["local_scale"] = Transform.local_scale
        return d

    def getSerializedProperties(self):
        """Return all properties for serialization. In the case of transform
        this only returns local position, -rotation and -scale, which are
        required to restore the state of the node.
        """
        d = {}
        d["local_position"] = self.local_position
        d["local_euler_angles"] = self.local_euler_angles
        d["local_scale"] = self.local_scale
        return d

    # We use the panda node to save the name on it for better debugging and
    # efficient finding of nodes with NodePath().find()
    @SerializedPropertyDecorator
    def name(self):
        return self.node.getName()
    @name.setter
    def name(self, name):
        if name == "render":
            name = "_render"
        self.node.setName(name)

    @SerializedPropertyDecorator
    def position(self):
        return self.node.getPos(self.root.node)
    @position.setter
    def position(self, position):
        self.node.setPos(self.root.node, *position)
    
    @SerializedPropertyDecorator
    def local_position(self):
        return self.node.getPos()
    @local_position.setter
    def local_position(self, position):
        self.node.setPos(*position)

    @SerializedPropertyDecorator
    def euler_angles(self):
        return self.node.getHpr(self.root.node)
    @euler_angles.setter
    def euler_angles(self, angles):
        self.node.setHpr(self.root.node, *angles)
    
    @SerializedPropertyDecorator
    def local_euler_angles(self):
        return self.node.getHpr()
    @local_euler_angles.setter
    def local_euler_angles(self, angles):
        self.node.setHpr(*angles)
    
    @SerializedPropertyDecorator
    def rotation(self):
        return self.node.getQuat(self.root.node)
    @rotation.setter
    def rotation(self, quaternion):
        self.node.setQuat(self.root.node, *quaternion)

    @SerializedPropertyDecorator
    def local_rotation(self):
        return self.node.getQuat()
    @local_rotation.setter
    def local_rotation(self, quaternion):
        self.node.setQuat(*quaternion)

    @SerializedPropertyDecorator
    def local_scale(self):
        return self.node.getScale()
    @local_scale.setter
    def local_scale(self, scale):
        self.node.setScale(*scale)

    @SerializedPropertyDecorator
    def parent(self):
        p = self.node.getParent()
        if p.isEmpty() or p.getName() == "render":
            return self
        elif p.hasPythonTag("transform"):
            return p.getPythonTag("transform")
    @parent.setter
    def parent(self, parent):
        self.node.wrtReparentTo(parent.node)

    @SerializedPropertyDecorator
    def root(self):
        if self.parent is not self:
            return self.parent.root()
        else:
            return self
    
    def destroy(self):
        """Ultimately remove this transform. Warning: this might cause errors
        for other components on this game object. Use this only when removing
        the whole GameObject.
        """
        self.node.removeNode()

    def getChildren(self):
        """Return children as Transforms."""
        # this requires the __iter__() method
        return [c for c in self]

    def __iter__(self):
        """Iterate over children nodes and yield the transform instances."""
        for child in self.node.getChildren():
            if child.hasPythonTag("transform"):
                yield child.getPythonTag("transform")
    
    def __str__(self):
        r = "Transform for '{}'\n".format(self.name)
        r += "local position: {}\n".format(self.local_position)
        r += "local rotation: {}\n".format(self.local_euler_angles)
        r += "local scale:    {}\n".format(self.local_scale)
        return r
Exemplo n.º 54
0
 def throw(self):
     if not self.gag and not self.isLocal():
         self.setHandJoint()
         self.build()
     if self.gag and self.getLocation():
         self.startEntity()
     elif self.gag and self.trapMode == 1:
         throwPath = NodePath('ThrowPath')
         throwPath.reparentTo(self.avatar)
         throwPath.setScale(render, 1)
         throwPath.setPos(0, 160, -120)
         throwPath.setHpr(0, 90, 0)
         self.gag.setScale(self.gag.getScale(render))
         self.gag.reparentTo(render)
         self.gag.setHpr(throwPath.getHpr(render))
         self.setHandJoint()
         self.track = ProjectileInterval(self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3)
         self.track.start()
         self.buildProjCollisions()
         self.reset()
         self.avatar.acceptOnce('projSensor-into', self.onProjCollision)
         if self.isLocal():
             base.localAvatar.enablePieKeys()
Exemplo n.º 55
0
    def releaseAttack(self, releaseFromJoint, onlyMoveColl = True, blendType = 'noBlend'):
        startNP = releaseFromJoint.attachNewNode('startNP')
        if None not in [self.targetX, self.targetY, self.targetZ]:
            startNP.lookAt(render, self.targetX, self.targetY, self.targetZ + 2)
            pathNP = NodePath('path')
            pathNP.reparentTo(startNP)
            pathNP.setScale(render, 1.0)
            pathNP.setPos(0, self.shooterDistance, 0)
            for particle in self.particles:
                if not onlyMoveColl:
                    particle.start(render)
                else:
                    particle.start(self.suit)
                particle.lookAt(pathNP)
                if self.attack == 'razzledazzle':
                    particle.setP(particle, 90)

            if onlyMoveColl:
                target = self.shootOutCollNP
                target.wrtReparentTo(render)
            else:
                target = self.particles[0]
            self.particleMoveIval = LerpPosInterval(target, duration=self.particleIvalDur, pos=pathNP.getPos(render), startPos=startNP.getPos(render), blendType=blendType)
            self.particleMoveIval.start()
            self.acceptOnce('enter' + self.shootOutCollNP.node().getName(), self.handleCollision)
            pathNP.removeNode()
            startNP.removeNode()
            del pathNP
            del startNP
        self.playParticleSound()
        return
Exemplo n.º 56
0
class Bot:
    _orders = Actions.DoNothing
    _hp = 5
    _death_played = False

    def __init__(self, team, position, direction):
        self.team = team

        self._model = NodePath("bot")
        self._model.reparentTo(render)

        self._model.setPos(position)
        self._model.setHpr(direction, 0, 0)
        self._model.setColorScale(*self.team)
        self._model.setScale(0.15, 0.15, 0.15)

        # Load the animations
        self._actor = Actor(
            "models/RockGolem",
            {
                "idle": "models/RockGolem-idle",
                "walk": "models/RockGolem-walk",
                "reverse-walk": "models/RockGolem-walk",
                "punch": "models/RockGolem-punch",
                "death": "models/RockGolem-death",
            },
        )
        self._actor.setPlayRate(2.65, "walk")
        self._actor.setPlayRate(-2.65, "reverse-walk")
        self._actor.setPlayRate(4, "punch")
        self._actor.setBlend(frameBlend=True)
        self._actor.reparentTo(self._model)
        self._actor.loop("idle")
        self._actor.setH(90)

        # fov = make_fov()
        # fov.reparentTo(self._model)

    def update(self, tick_number, visible_objects):
        return Actions.DoNothing

    def _get_orders(self, tick_number, visible_objects):
        if self._hp <= 0:
            return

        # noinspection PyBroadException
        try:
            self._orders = self.update(tick_number, visible_objects)
        except Exception as e:
            print(type(self), e)
            self._orders = Actions.Suicide

    def _execute_orders(self, tick_length):
        # Pre-calculate some useful things
        new_pos = self._model.getPos()
        new_dir = self._model.getHpr()
        velocity = render.getRelativeVector(self._model, Vec3(1, 0, 0))
        velocity.normalize()

        if self._orders == Actions.MoveForward:
            new_pos += velocity
            self.safe_loop("walk")

        elif self._orders == Actions.MoveBackward:
            new_pos -= velocity
            self.safe_loop("reverse-walk")

        elif self._orders == Actions.StrafeLeft:
            new_pos += velocity
            self.safe_loop("walk")

        elif self._orders == Actions.StrafeRight:
            new_pos += velocity
            self.safe_loop("walk")

        elif self._orders == Actions.TurnLeft:
            new_dir.x += 90
            self.safe_loop("walk")

        elif self._orders == Actions.TurnAround:
            new_dir.x += 180
            self.safe_loop("walk")

        elif self._orders == Actions.TurnRight:
            new_dir.x -= 90
            self.safe_loop("walk")

        elif self._orders == Actions.Punch:
            self.punch()

        elif self._orders == Actions.Shoot:
            self.shoot()

        elif self._orders == Actions.DoNothing:
            self.safe_loop("idle")

        elif self._orders == Actions.Suicide:
            self._hp = 0
            self.die()

        else:  # Bad orders detected! Kill this bot.
            self._hp = 0
            self.die()

        # Animate the motion
        tick = tick_length - 0.05  # Shave off a tiny bit to finish the interval
        LerpPosHprInterval(self._model, tick, new_pos, new_dir).start()

    def safe_loop(self, animation):
        if self._actor.getCurrentAnim() != animation:
            self._actor.loop(animation)

    def die(self):
        if not self._death_played:
            self._actor.play("death")
            self._death_played = True

    def punch(self):
        print("Punching not implemented yet!")
        self._actor.play("punch")

    def shoot(self):
        print("Shooting not implemented yet!")
        self._actor.play("shoot")