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
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
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()
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
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()
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)
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)
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)))
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)))
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
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
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
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)
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)
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
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()
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
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
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()
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)
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
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([])
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 """
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 """
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
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))
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()
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()
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()
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
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)
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)
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()
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)
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
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
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)
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)
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
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()
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)
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[]"
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()
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
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")