class PickPocketAttack(Attack): notify = directNotify.newCategory('PickPocketAttack') attack = 'pickpocket' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.dollar = None self.pickSfx = None return def doAttack(self, ts=0): self.dollar = loader.loadModel('phase_5/models/props/1dollar-bill-mod.bam') self.dollar.setY(0.22) self.dollar.setHpr(289.18, 252.75, 0.0) if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doPickPocketAttack') else: name = 'doPickPocketAttack' self.suitTrack = Parallel(ActorInterval(self.suit, 'pickpocket'), Sequence(Wait(0.4), Func(self.attemptDamage)), name=name) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def attemptDamage(self): shouldDamage = False suitH = self.suit.getH(render) % 360 myH = base.localAvatar.getH(render) % 360 if not -90.0 <= suitH - myH <= 90.0: if base.localAvatar.getDistance(self.suit) <= 15.0: shouldDamage = True if shouldDamage: self.playWeaponSound() self.dollar.reparentTo(self.suit.find('**/joint_Rhold')) self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) def playWeaponSound(self): self.pickSfx = base.audio3d.loadSfx('phase_5/audio/sfx/SA_pick_pocket.ogg') base.audio3d.attachSoundToObject(self.pickSfx, self.suit) self.pickSfx.play() def cleanup(self): Attack.cleanup(self) if self.pickSfx: self.pickSfx.stop() self.pickSfx = None if self.dollar: self.dollar.removeNode() self.dollar = None return
class PickPocketAttack(Attack): notify = directNotify.newCategory('PickPocketAttack') attack = 'pickpocket' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.dollar = None self.pickSfx = None return def doAttack(self, ts = 0): self.dollar = loader.loadModel('phase_5/models/props/1dollar-bill-mod.bam') self.dollar.setY(0.22) self.dollar.setHpr(289.18, 252.75, 0.0) if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doPickPocketAttack') else: name = 'doPickPocketAttack' self.suitTrack = Parallel(ActorInterval(self.suit, 'pickpocket'), Sequence(Wait(0.4), Func(self.attemptDamage)), name=name) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def attemptDamage(self): shouldDamage = False suitH = self.suit.getH(render) % 360 myH = base.localAvatar.getH(render) % 360 if not -90.0 <= suitH - myH <= 90.0: if base.localAvatar.getDistance(self.suit) <= 15.0: shouldDamage = True if shouldDamage: self.playWeaponSound() self.dollar.reparentTo(self.suit.find('**/joint_Rhold')) self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) def playWeaponSound(self): self.pickSfx = base.audio3d.loadSfx('phase_5/audio/sfx/SA_pick_pocket.mp3') base.audio3d.attachSoundToObject(self.pickSfx, self.suit) self.pickSfx.play() def cleanup(self): Attack.cleanup(self) if self.pickSfx: self.pickSfx.stop() self.pickSfx = None if self.dollar: self.dollar.removeNode() self.dollar = None return
class FountainPenAttack(Attack): notify = directNotify.newCategory('FountainPenAttack') attack = 'fountainpen' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.pen = None self.spray = None self.splat = None self.spraySfx = None self.sprayParticle = None self.sprayScaleIval = None self.wsnp = None return def loadAttack(self): self.pen = loader.loadModel('phase_5/models/props/pen.bam') self.pen.reparentTo(self.suit.find('**/joint_Rhold')) self.sprayParticle = ParticleLoader.loadParticleEffect('phase_5/etc/penSpill.ptf') self.spray = loader.loadModel('phase_3.5/models/props/spray.bam') self.spray.setColor(VBase4(0, 0, 0, 1)) self.splat = Actor('phase_3.5/models/props/splat-mod.bam', {'chan': 'phase_3.5/models/props/splat-chan.bam'}) self.splat.setColor(VBase4(0, 0, 0, 1)) self.sprayScaleIval = LerpScaleInterval(self.spray, duration=0.3, scale=(1, 20, 1), startScale=(1, 1, 1)) sphere = CollisionSphere(0, 0, 0, 0.5) sphere.setTangible(0) if hasattr(self.suit, 'uniqueName'): collName = self.suit.uniqueName('fountainPenCollNode') else: collName = 'fountainPenCollNode' collNode = CollisionNode(collName) collNode.addSolid(sphere) collNode.setCollideMask(CIGlobals.WallBitmask) self.wsnp = self.spray.attachNewNode(collNode) self.wsnp.setY(1) def doAttack(self, ts = 0): self.loadAttack() if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doFountainPenAttack') else: name = 'doFountainPenAttack' self.suitTrack = Parallel(name=name) self.suitTrack.append(ActorInterval(self.suit, 'fountainpen')) self.suitTrack.append(Sequence(Wait(1.2), Func(self.acceptOnce, 'enter' + self.wsnp.node().getName(), self.handleSprayCollision), Func(self.playWeaponSound), Func(self.attachSpray), Func(self.sprayParticle.start, self.pen.find('**/joint_toSpray'), self.pen.find('**/joint_toSpray')), self.sprayScaleIval, Wait(0.5), Func(self.sprayParticle.cleanup), Func(self.spray.setScale, 1), Func(self.spray.reparentTo, hidden), Func(self.ignore, 'enter' + self.wsnp.node().getName()))) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def attachSpray(self): self.spray.reparentTo(self.pen.find('**/joint_toSpray')) pos = self.spray.getPos(render) hpr = self.spray.getHpr(render) self.spray.reparentTo(render) self.spray.setPos(pos) self.spray.setHpr(hpr) self.spray.setP(0) if self.suit.type == 'C': self.spray.setH(self.spray.getH() + 7.5) self.spray.setTwoSided(True) def handleSprayCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) self.sprayScaleIval.pause() def playWeaponSound(self): self.spraySfx = base.audio3d.loadSfx('phase_5/audio/sfx/SA_fountain_pen.mp3') base.audio3d.attachSoundToObject(self.spraySfx, self.pen) self.spraySfx.play() def cleanup(self): Attack.cleanup(self) if self.wsnp: self.wsnp.node().clearSolids() self.wsnp.removeNode() self.wsnp = None if self.pen: self.pen.removeNode() self.pen = None if self.sprayParticle: self.sprayParticle.cleanup() self.sprayParticle = None if self.spray: self.spray.removeNode() self.spray = None if self.splat: self.splat.cleanup() self.splat = None if self.sprayScaleIval: self.sprayScaleIval.pause() self.sprayScaleIval = None self.spraySfx = None return
class DistributedPieTurret(DistributedAvatar, DistributedSmoothNode): notify = directNotify.newCategory('DistributedPieTurret') def __init__(self, cr): DistributedAvatar.__init__(self, cr) DistributedSmoothNode.__init__(self, cr) self.fsm = ClassicFSM( 'DistributedPieTurret', [ State('off', self.enterOff, self.exitOff), State('scan', self.enterScan, self.exitScan), State('shoot', self.enterShoot, self.exitShoot) ], 'off', 'off' ) self.fsm.enterInitialState() self.reloadTime = 0.25 self.cannon = None self.track = None self.owner = None self.gag = None self.readyGag = None self.hitGag = None self.explosion = None self.wallCollNode = None self.eventCollNode = None self.event = None self.suit = None self.eventId = None self.entities = [] self.upgradeID = None self.deathEvent = None def setOwner(self, avatar): self.owner = avatar def getOwner(self): return self.owner def setGag(self, upgradeId): gags = {0 : CIGlobals.WholeCreamPie, 1 : CIGlobals.WholeFruitPie, 2 : CIGlobals.BirthdayCake, 3 : CIGlobals.WeddingCake} self.gag = gags.get(upgradeId) if not self.readyGag: self.loadGagInTurret() def b_setGag(self, upgradeId): self.sendUpdate('setGag', [upgradeId]) self.setGag(upgradeId) self.upgradeID = upgradeId def getGag(self): return self.gag def getGagID(self): return self.upgradeID def generate(self): DistributedAvatar.generate(self) DistributedSmoothNode.generate(self) def announceGenerate(self): DistributedAvatar.announceGenerate(self) DistributedSmoothNode.announceGenerate(self) self.healthLabel.setScale(1.1) self.deathEvent = self.uniqueName('DistributedPieTurret-death') self.makeTurret() def disable(self): self.fsm.requestFinalState() del self.fsm # This should fix crashes related to Sequences. if self.track: self.track.pause() self.track = None # Cleanup entities. for ent in self.entities: ent.cleanup() self.entities = None # Get rid of explosions. if self.explosion: self.explosion.removeNode() self.explosion = None self.removeTurret() DistributedSmoothNode.disable(self) DistributedAvatar.disable(self) def showAndMoveHealthLabel(self): self.unstashHpLabel() self.stopMovingHealthLabel() moveTrack = LerpPosInterval(self.healthLabel, duration = 0.5, pos = Point3(0, 0, 5), startPos = Point3(0, 0, 0), blendType = 'easeOut') self.healthLabelTrack = Sequence(moveTrack, Wait(1.0), Func(self.stashHpLabel)) self.healthLabelTrack.start() # BEGIN STATES def enterShoot(self, suitId): if self.cannon: smoke = loader.loadModel("phase_4/models/props/test_clouds.bam") smoke.setBillboardPointEye() smoke.reparentTo(self.cannon.find('**/cannon')) smoke.setPos(0, 6, -3) smoke.setScale(0.5) smoke.wrtReparentTo(render) self.suit = self.cr.doId2do.get(suitId) self.cannon.find('**/cannon').lookAt(self.suit.find('**/joint_head')) self.cannon.find('**/square_drop_shadow').headsUp(self.suit.find('**/joint_head')) self.track = Sequence(Parallel(LerpScaleInterval(smoke, 0.5, 3), LerpColorScaleInterval(smoke, 0.5, Vec4(2, 2, 2, 0))), Func(smoke.removeNode)) self.track.start() self.createAndShootGag() def exitShoot(self): if hasattr(self, 'suit'): del self.suit def shoot(self, suitId): self.fsm.request('shoot', [suitId]) def scan(self, timestamp = None, afterShooting = 0): if timestamp == None: ts = 0.0 else: ts = globalClockDelta.localElapsedTime(timestamp) self.fsm.request('scan', [ts, afterShooting]) def buildScanTrack(self, ts = None): if self.track: self.track.pause() self.track = None self.track = Parallel( Sequence( LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (60, 0, 0), startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0), startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'), ), Sequence( LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (60, 0, 0), startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0), startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'), ) ) if ts: self.track.loop(ts) else: self.track.loop() def enterScan(self, ts = 0, afterShooting = 0): if afterShooting: self.track = Parallel( LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0), startHpr = self.cannon.find('**/cannon').getHpr(), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0), startHpr = self.cannon.find('**/square_drop_shadow').getHpr(), blendType = 'easeInOut'), name = "afterShootTrack" + str(id(self)) ) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self._afterShootTrackDone) self.track.start(ts) else: self.buildScanTrack(ts) def exitScan(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None def enterOff(self): pass def exitOff(self): pass # END STATES def _afterShootTrackDone(self): self.buildScanTrack() def makeTurret(self): self.cannon = loader.loadModel('phase_4/models/minigames/toon_cannon.bam') self.cannon.reparentTo(self) self.loadGagInTurret() self.setupWallSphere() if self.isLocal(): self.setupEventSphere() def removeTurret(self): self.removeWallSphere() self.removeGagInTurret() if self.cannon: self.cannon.removeNode() self.cannon = None def getCannon(self): return self.cannon.find('**/cannon') def setupWallSphere(self): sphere = CollisionSphere(0.0, 0.0, 0.0, 3.0) node = CollisionNode('DistributedPieTurret.WallSphere') node.addSolid(sphere) node.setCollideMask(CIGlobals.WallBitmask) self.wallCollNode = self.cannon.attachNewNode(node) self.wallCollNode.setZ(2) self.wallCollNode.setY(1.0) def removeWallSphere(self): if self.wallCollNode: self.wallCollNode.removeNode() self.wallCollNode = None def createAndShootGag(self): if not self.readyGag: self.loadGagInTurret() if self.readyGag: self.readyGag.shoot(Point3(0, 200, -90)) self.entities.append(self.readyGag) collideEventName = self.readyGag.getCollideEventName() self.readyGag = None if self.isLocal(): self.acceptOnce(collideEventName, self.handleGagCollision) Sequence(Wait(self.reloadTime), Func(self.loadGagInTurret)).start() def loadGagInTurret(self): if self.cannon and self.gag: self.removeGagInTurret() self.eventId = random.uniform(0, 100000000) self.readyGag = TurretGag(self, self.uniqueName('pieTurretCollision') + str(self.eventId), self.gag) self.readyGag.build() def removeGagInTurret(self): if self.readyGag: self.readyGag.cleanup() self.readyGag = None def makeSplat(self, index, pos): if index >= len(self.entities): return ent = self.entities[index] gagClass = ent.gagClass splat = gagClass.buildSplat(gagClass.splatScale, gagClass.splatColor) base.audio3d.attachSoundToObject(gagClass.hitSfx, splat) splat.reparentTo(render) splat.setPos(pos[0], pos[1], pos[2]) gagClass.hitSfx.play() Sequence(Wait(0.5), Func(splat.cleanup)).start() self.hitGag = None def d_makeSplat(self, index, pos): self.sendUpdate('makeSplat', [index, pos]) def b_makeSplat(self, index, pos): self.d_makeSplat(index, pos) self.makeSplat(index, pos) def handleGagCollision(self, entry, ent): x, y, z = ent.getGag().getPos(render) self.b_makeSplat(self.entities.index(ent), [x, y, z]) if self.isLocal(): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() for key in self.cr.doId2do.keys(): obj = self.cr.doId2do[key] if obj.__class__.__name__ == 'DistributedSuit': if obj.getKey() == avNP.getKey(): if obj.getHealth() > 0: obj.sendUpdate('hitByGag', [ent.getID()]) ent.cleanup() def setHealth(self, hp): DistributedAvatar.setHealth(self, hp) if self.isLocal(): base.localAvatar.getMyBattle().getTurretManager().updateTurretGui() def die(self): self.fsm.requestFinalState() turretPos = self.cannon.getPos(render) self.removeTurret() self.explosion = loader.loadModel("phase_3.5/models/props/explosion.bam") self.explosion.setScale(0.5) self.explosion.reparentTo(render) self.explosion.setBillboardPointEye() self.explosion.setPos(turretPos + (0, 0, 5)) sfx = base.audio3d.loadSfx("phase_3.5/audio/sfx/ENC_cogfall_apart.ogg") base.audio3d.attachSoundToObject(sfx, self) base.playSfx(sfx) messenger.send(self.deathEvent) def isLocal(self): return self.getOwner() == base.localAvatar.doId def getDeathEvent(self): return self.deathEvent
class DistributedDodgeballGame(DistributedToonFPSGame, TeamMinigame): notify = directNotify.newCategory('DistributedDodgeballGame') TreeData = [ [ 'prop_snow_tree_small_ur', Point3(23.23, 66.52, 7.46)], [ 'prop_snow_tree_small_ul', Point3(-34.03, 88.02, 24.17)], [ 'prop_snow_tree_small_ur', Point3(-54.8, 0, 4.19)], [ 'prop_snow_tree_small_ul', Point3(54.8, -5, 4.19)], [ 'prop_snow_tree_small_ur', Point3(62.71, 62.66, 16.8)], [ 'prop_snow_tree_small_ul', Point3(-23.23, -66.52, 6)], [ 'prop_snow_tree_small_ur', Point3(34.03, -88.02, 23)], [ 'prop_snow_tree_small_ul', Point3(-62.71, -62.66, 16)]] SnowballData = [ Point3(30, 0, 0.75), Point3(22.5, 0, 0.75), Point3(15, 0, 0.75), Point3(7.5, 0, 0.75), Point3(0, 0, 0.75), Point3(-7.5, 0, 0.75), Point3(-15, 0, 0.75), Point3(-22.5, 0, 0.75), Point3(-30, 0, 0.75)] GameSong = 'phase_4/audio/bgm/MG_Dodgeball.ogg' GameDesc = 'Welcome to the north! You have been invited to play dodgeball with the penguins!\n\nHow To Play\nWASD to Move and use the mouse to aim.\nLeft click to Throw!\nThrow a snowball at a teammate to unfreeze them!\n\nObjective\nThe first team to freeze everyone!' InitCamTrans = [ Point3(25, 45, 19.5317), Vec3(154.001, -15, 0)] SnowBallDmg = 25 GetSnowBalls = 'Pick up a snowball from the center!' Team2OtherBarrier = {BLUE: 'red_barrier_coll', RED: 'blue_barrier_coll'} def __init__(self, cr): try: self.DistributedDodgeballGame_initialized return except: self.DistributedDodgeballGame_initialized = 1 DistributedToonFPSGame.__init__(self, cr) TeamMinigame.__init__(self, 'BlueSnow', ('phase_4/maps/db_blue_neutral.png', 'phase_4/maps/db_blue_hover.png', 'phase_4/maps/db_blue_hover.png'), 'RedIce', ('phase_4/maps/db_red_neutral.png', 'phase_4/maps/db_red_hover.png', 'phase_4/maps/db_red_hover.png')) self.fsm.addState(State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam, ['waitForOthers'])) self.fsm.addState(State('scrollBy', self.enterScrollBy, self.exitScrollBy, ['countdown'])) self.fsm.addState(State('countdown', self.enterCountdown, self.exitCountdown, ['play'])) self.fsm.addState(State('announceGameOver', self.enterAnnGameOver, self.exitAnnGameOver, ['displayWinners'])) self.fsm.addState(State('displayWinners', self.enterDisplayWinners, self.exitDisplayWinners, ['gameOver'])) self.fsm.getStateNamed('waitForOthers').addTransition('chooseTeam') self.fsm.getStateNamed('waitForOthers').addTransition('scrollBy') self.fsm.getStateNamed('play').addTransition('announceGameOver') self.firstPerson = DodgeballFirstPerson(self) self.scrollBySeq = None self.infoText = None self.redScoreLbl = None self.blueScoreLbl = None self.infoText = getAlertText() self.spawnPointsByTeam = {BLUE: [ [ Point3(5, 15, 0), Vec3(180, 0, 0)], [ Point3(15, 15, 0), Vec3(180, 0, 0)], [ Point3(-5, 15, 0), Vec3(180, 0, 0)], [ Point3(-15, 15, 0), Vec3(180, 0, 0)]], RED: [ [ Point3(5, -15, 0), Vec3(0, 0, 0)], [ Point3(15, -15, 0), Vec3(0, 0, 0)], [ Point3(-5, -15, 0), Vec3(0, 0, 0)], [ Point3(-15, -15, 0), Vec3(0, 0, 0)]]} self.winnerMusic = base.loadMusic('phase_9/audio/bgm/encntr_hall_of_fame.mid') self.loserMusic = base.loadMusic('phase_9/audio/bgm/encntr_sting_announce.mid') self.danceSound = base.loadSfx('phase_3.5/audio/sfx/ENC_Win.ogg') self.sky = None self.arena = None self.fog = None self.snow = None self.snowRender = None self.trees = [] self.snowballs = [] return def getTeamDNAColor(self, team): print 'getTeamDNAColor' if team == TEAM1: print 'blue' return ToonDNA.colorName2DNAcolor['blue'] if team == TEAM2: print 'bright red' return ToonDNA.colorName2DNAcolor['bright red'] def enterDisplayWinners(self): base.localAvatar.stopLookAround() base.localAvatar.resetHeadHpr() base.localAvatar.getGeomNode().show() camera.reparentTo(render) camera.setPos((-2.5, 12, 3.5)) camera.setHpr((-175.074, -5.47218, 0)) base.transitions.fadeIn() base.playSfx(self.danceSound, looping=1) if self.winnerTeam == self.team: base.playMusic(self.winnerMusic, volume=0.8) else: base.playMusic(self.loserMusic, volume=0.8) winnerPositions = [(-2, 0, 0), (2, 0, 0), (6, 0, 0), (-6, 0, 0)] loserPositions = [(-3.5, -10, 0), (-1.5, -15, 0), (3.0, -8, 0), (5.5, -12, 0)] for team in [RED, BLUE]: for avId in self.playerListByTeam[team]: av = self.cr.doId2do.get(avId) if av: av.stopSmooth() av.setHpr(0, 0, 0) if team == self.winnerTeam: posList = winnerPositions av.setAnimState('off') av.stop() if not self.getRemoteAvatar(avId).isFrozen: av.loop('win') else: posList = loserPositions av.setAnimState('off') av.stop() if not self.getRemoteAvatar(avId).isFrozen: av.loop('pout') pos = random.choice(posList) posList.remove(pos) av.setPos(pos) if self.winnerTeam == team: text = 'YOU WIN!' else: text = 'YOU LOSE!' self.gameOverLbl.setText(text) self.track = Sequence(Wait(2.0), Func(self.gameOverLbl.setScale, 0.01), Func(self.gameOverLbl.show), getAlertPulse(self.gameOverLbl, 0.27, 0.25)) self.track.start() def exitDisplayWinners(self): base.transitions.noTransitions() self.danceSound.stop() if hasattr(self, 'track'): self.track.finish() self.track = None self.gameOverLbl.hide() return def enterAnnGameOver(self, timeRanOut=0): self.firstPerson.vModel.hide() text = 'GAME\nOVER' if timeRanOut: text = "TIME's\nUP" self.gameOverLbl.setText(text) self.gameOverLbl.show() base.transitions.fadeScreen() taskMgr.doMethodLater(3.0, self.__annGameOverTask, self.uniqueName('annGameOverTask')) def __annGameOverTask(self, task): self.gameOverLbl.hide() self.ival = Sequence(base.transitions.getFadeOutIval(), Func(self.fsm.request, 'displayWinners')) self.ival.start() return task.done def exitAnnGameOver(self): taskMgr.remove(self.uniqueName('annGameOverTask')) if hasattr(self, 'ival'): self.ival.finish() del self.ival self.gameOverLbl.hide() def teamWon(self, team): self.winnerTeam = team base.localAvatar.disableAvatarControls() self.firstPerson.end() self.deleteTimer() self.fsm.request('announceGameOver') def incrementTeamScore(self, team): TeamMinigame.incrementTeamScore(self, team) if team == BLUE: self.blueScoreLbl.setText('BLUE: ' + str(self.scoreByTeam[team])) ToontownIntervals.start(ToontownIntervals.getPulseLargerIval(self.blueScoreLbl, 'blueScorePulse')) else: if team == RED: self.redScoreLbl.setText('RED: ' + str(self.scoreByTeam[team])) ToontownIntervals.start(ToontownIntervals.getPulseLargerIval(self.redScoreLbl, 'redScorePulse')) def getWinterDodgeballScoreText(self, color): text = OnscreenText(fg=color, font=CIGlobals.getMinnieFont(), scale=0.15, shadow=(0, 0, 0, 1)) return text def snowballHitWall(self, snowballIndex): snowball = self.snowballs[snowballIndex] snowball.handleHitWallOrPlayer() base.playSfx(snowball.impactSound, node=snowball, volume=1.5) def snowballHitGround(self, snowballIndex): snowball = self.snowballs[snowballIndex] snowball.handleHitGround() base.playSfx(snowball.impactSound, node=snowball, volume=1.5) def snowballHitPlayer(self, damagedPlayer, throwerTeam, snowballIndex): av = self.getRemoteAvatar(damagedPlayer) if av: if throwerTeam == av.team: if av.unFreeze(): if damagedPlayer == base.localAvatar.doId: self.showAlert('A team member has unfroze you!') self.firstPerson.camFSM.request('unfrozen') self.sendUpdate('teamMateUnfrozeMe', [self.team]) elif av.freeze(): if damagedPlayer == base.localAvatar.doId: self.showAlert("You've been frozen by an enemy!") self.firstPerson.camFSM.request('frozen') self.sendUpdate('enemyFrozeMe', [self.team, throwerTeam]) snowball = self.snowballs[snowballIndex] snowball.handleHitWallOrPlayer() base.playSfx(snowball.impactSound, node=snowball, volume=1.5) def playerCaughtSnowball(self, snowballIndex, catcherId): av = self.getRemoteAvatar(catcherId) if av: snowball = self.snowballs[snowballIndex] snowball.pauseThrowIval() snowball.pickup(av) def setupRemoteAvatar(self, avId): av = RemoteDodgeballAvatar(self, self.cr, avId) if avId == self.cr.localAvId: self.myRemoteAvatar = av self.remoteAvatars.append(av) def __getSnowTree(self, path): trees = loader.loadModel('phase_8/models/props/snow_trees.bam') tree = trees.find('**/' + path) tree.find('**/*shadow*').removeNode() return tree def load(self): self.setMinigameMusic(DistributedDodgeballGame.GameSong) self.setDescription(DistributedDodgeballGame.GameDesc) self.setWinnerPrize(200) self.setLoserPrize(0) self.createWorld() self.blueScoreLbl = self.getWinterDodgeballScoreText(VBase4(0, 0, 1, 1)) self.blueScoreLbl.reparentTo(base.a2dTopLeft) self.blueScoreLbl['align'] = TextNode.ALeft self.blueScoreLbl.setText('Blue: 0') self.blueScoreLbl.setZ(-0.17) self.blueScoreLbl.setX(0.05) self.blueScoreLbl.hide() self.redScoreLbl = self.getWinterDodgeballScoreText(VBase4(1, 0, 0, 1)) self.redScoreLbl.reparentTo(base.a2dTopLeft) self.redScoreLbl['align'] = TextNode.ALeft self.redScoreLbl.setText('Red: 0') self.redScoreLbl.setZ(-0.35) self.redScoreLbl.setX(0.05) self.redScoreLbl.hide() trans = DistributedDodgeballGame.InitCamTrans camera.setPos(trans[0]) camera.setHpr(trans[1]) DistributedToonFPSGame.load(self) def createWorld(self): self.deleteWorld() self.sky = loader.loadModel('phase_3.5/models/props/BR_sky.bam') self.sky.reparentTo(render) self.sky.setZ(-40) self.sky.setFogOff() self.arena = loader.loadModel('phase_4/models/minigames/dodgeball_arena.egg') self.arena.reparentTo(render) self.arena.setScale(0.75) self.arena.find('**/team_divider').setBin('ground', 18) self.arena.find('**/floor').setBin('ground', 18) self.arena.find('**/team_divider_coll').setCollideMask(CIGlobals.FloorBitmask) for data in DistributedDodgeballGame.TreeData: code = data[0] pos = data[1] tree = self.__getSnowTree(code) tree.reparentTo(self.arena) tree.setPos(pos) self.trees.append(tree) for i in xrange(len(DistributedDodgeballGame.SnowballData)): snowdata = DistributedDodgeballGame.SnowballData[i] snowball = Snowball(self, i) snowball.load() snowball.reparentTo(render) snowball.setPos(snowdata) self.snowballs.append(snowball) self.snow = ParticleLoader.loadParticleEffect('phase_8/etc/snowdisk.ptf') self.snow.setPos(0, 0, 5) self.snowRender = self.arena.attachNewNode('snowRender') self.snowRender.setDepthWrite(0) self.snowRender.setBin('fixed', 1) self.snow.start(camera, self.snowRender) self.fog = Fog('snowFog') self.fog.setColor(0.486, 0.784, 1) self.fog.setExpDensity(0.003) render.setFog(self.fog) def throw(self, snowballIndex, p): snowball = self.snowballs[snowballIndex] snowball.throw(p) def snowballPickup(self, snowballIndex, pickerUpperAvId): remoteAv = self.getRemoteAvatar(pickerUpperAvId) if remoteAv: snowball = self.snowballs[snowballIndex] snowball.pickup(remoteAv) def deleteWorld(self): if self.redScoreLbl: self.redScoreLbl.destroy() self.redScoreLbl = None if self.blueScoreLbl: self.blueScoreLbl.destroy() self.blueScoreLbl = None for snowball in self.snowballs: snowball.removeNode() self.snowballs = [] for tree in self.trees: tree.removeNode() self.trees = [] if self.snow: self.snow.cleanup() self.snow = None if self.snowRender: self.snowRender.removeNode() self.snowRender = None self.fog = None if self.sky: self.sky.removeNode() self.sky = None if self.arena: self.arena.removeNode() self.arena = None render.clearFog() return def enterPlay(self): self.createTimer() self.redScoreLbl.show() self.blueScoreLbl.show() self.firstPerson.camFSM.request('unfrozen') self.arena.find('**/' + self.Team2OtherBarrier[self.team]).stash() def exitPlay(self): self.firstPerson.crosshair.destroy() self.firstPerson.crosshair = None self.firstPerson.camFSM.request('off') DistributedToonFPSGame.exitPlay(self) return def enterCountdown(self): self.firstPerson.start() self.firstPerson.disableMouse() self.infoText.setText(DistributedDodgeballGame.GetSnowBalls) self.countdownText = getGameText() self.countdownIval = Parallel(Sequence(Func(self.countdownText.setText, '5'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '4'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '3'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '2'), getCountdownIval(self.countdownText), Func(self.countdownText.setText, '1'), getCountdownIval(self.countdownText)), getAlertPulse(self.infoText), name='COUNTDOWNIVAL') self.countdownIval.setDoneEvent(self.countdownIval.getName()) self.acceptOnce(self.countdownIval.getDoneEvent(), self.__handleCountdownDone) self.countdownIval.start() def __handleCountdownDone(self): self.fsm.request('play') def exitCountdown(self): if hasattr(self, 'countdownText'): self.countdownText.destroy() del self.countdownText if hasattr(self, 'countdownIval'): self.ignore(self.countdownIval.getDoneEvent()) self.countdownIval.finish() del self.countdownIval def enterScrollBy(self): BLUE_START_POS = Point3(-20, 0, 4) BLUE_END_POS = Point3(20, 0, 4) BLUE_HPR = Vec3(0, 0, 0) RED_START_POS = Point3(20, 0, 4) RED_END_POS = Point3(-20, 0, 4) RED_HPR = Vec3(180, 0, 0) self.playMinigameMusic() self.scrollBySeq = Sequence(Func(camera.setHpr, BLUE_HPR), LerpPosInterval(camera, duration=5.0, pos=BLUE_END_POS, startPos=BLUE_START_POS, blendType='easeOut'), Func(base.transitions.fadeOut, 0.4), Wait(0.5), Func(base.transitions.fadeIn, 0.4), Func(camera.setHpr, RED_HPR), LerpPosInterval(camera, duration=5.0, pos=RED_END_POS, startPos=RED_START_POS, blendType='easeOut'), name='SCROLLBYSEQ') self.scrollBySeq.setDoneEvent(self.scrollBySeq.getName()) self.acceptOnce(self.scrollBySeq.getDoneEvent(), self.__handleScrollByDone) self.scrollBySeq.start() def __handleScrollByDone(self): self.fsm.request('countdown') def exitScrollBy(self): if self.scrollBySeq: self.ignore(self.scrollBySeq.getDoneEvent()) self.scrollBySeq.finish() self.scrollBySeq = None return def allPlayersReady(self): self.fsm.request('scrollBy') def chooseUrTeam(self): self.fsm.request('chooseTeam') def enterChooseTeam(self): self.makeSelectionGUI() def acceptedIntoTeam(self, spawnPoint): TeamMinigame.acceptedIntoTeam(self) self.sendUpdate('readyToStart') self.fsm.request('waitForOthers') pos, hpr = self.spawnPointsByTeam[self.team][spawnPoint] base.localAvatar.setPos(pos) base.localAvatar.setHpr(hpr) def exitChooseTeam(self): self.destroySelectionGUI() def announceGenerate(self): DistributedToonFPSGame.announceGenerate(self) base.camLens.setMinFov(CIGlobals.GunGameFOV / (4.0 / 3.0)) self.load() def disable(self): base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4.0 / 3.0)) self.fsm.requestFinalState() self.deleteWorld() self.trees = None self.snowballs = None self.spawnPointsByTeam = None if self.firstPerson: self.firstPerson.reallyEnd() self.firstPerson.cleanup() self.firstPerson = None self.scrollBySeq = None self.winnerMusic = None self.loserMusic = None self.danceSound = None self.infoText = None base.localAvatar.setWalkSpeedNormal() DistributedToonFPSGame.disable(self) return
class Suit(Avatar): notify = directNotify.newCategory('Suit') def __init__(self): Avatar.__init__(self) self.dept = None self.suit = None self.head = None self.headModel = None self.variant = None self.handColor = None self.voice = None self.chat = None self.chatDial = None self.shadow = None self.deathSound = None self.propeller = None self.smallExp = None self.largeExp = None self.explosion = None self.hasSpawned = False self.suitTrack = None self.timestampAnimTrack = None self.propellerSounds = {} self.healthBar = None self.healthBarGlow = None self.condition = 0 self.avatarType = CIGlobals.Suit self.suitPlan = None self.footstepSound = None self.showNametagInMargins = False self.surfaceProp = "metal" self.activities = { ACT_WAKE_ANGRY: WakeAngry(self), ACT_SMALL_FLINCH: Flinch(self), ACT_DIE: Die(self), ACT_VICTORY_DANCE: VictoryDance(self), ACT_COG_FLY_DOWN: FlyDown(self), ACT_SIT: Sit(self), ACT_STUN: Stun(self) } self.standWalkRunReverse = [('neutral', 'walk', 0.0, 5.0, 1.0, 1.0)] self.gruntSound = base.audio3d.loadSfx( "phase_14/audio/sfx/cog_grunt.ogg") base.audio3d.attachSoundToObject(self.gruntSound, self) self.animFSM = ClassicFSM('Suit', [ State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('walk', self.enterWalk, self.exitWalk), State('die', self.enterDie, self.exitDie), State('win', self.enterWin, self.exitWin), State('flail', self.enterFlail, self.exitFlail), State('flyDown', self.enterFlyDown, self.exitFlyDown), State('flyAway', self.enterFlyAway, self.exitFlyAway), State('flyNeutral', self.enterFlyNeutral, self.exitFlyNeutral), State('trayWalk', self.enterTrayWalk, self.exitTrayWalk), State('trayNeutral', self.enterTrayNeutral, self.exitTrayNeutral), State('stunned', self.enterStunned, self.exitStunned), State('pie', self.enterPie, self.exitPie), State('drop', self.enterDrop, self.exitDrop), State('drop-react', self.enterDropReact, self.exitDropReact), State('soak', self.enterSoak, self.exitSoak), State('squirt-small', self.enterSquirtSmall, self.exitSquirtSmall) ], 'off', 'off') self.animFSM.enterInitialState() def getRightHandNode(self): return self.find("**/joint_Rhold") def getLeftHandNode(self): return self.find("**/joint_Lhold") def getHeadNode(self): return self.headModel def getUpperBodySubpart(self): return [None] def getLowerBodySubpart(self): return [None] def getMoveAction(self, forward, rotate, strafe): return 0 def enterPie(self, ts=0): self.play('pie') def exitPie(self): self.stop() def enterDrop(self, ts=0): self.play("drop") def exitDrop(self): self.stop() def enterDropReact(self, ts=0): self.play('drop-react') def exitDropReact(self): self.stop() def enterSoak(self, ts=0): self.play('soak') def exitSoak(self): self.stop() def enterSquirtSmall(self, ts=0): self.play('squirt-small') def exitSquirtSmall(self): self.stop() def enterStunned(self, animB4Stun, ts=0): self.show() if isinstance(animB4Stun, int): animB4Stun = SuitGlobals.getAnimById(animB4Stun).getName() self.stunnedSound = base.loadSfxOnNode( "phase_4/audio/sfx/SZ_TC_bird1.ogg", self) self.stunnedSound.setLoop(True) self.stunnedSound.play() self.stunnedIval = Parallel( Sequence(ActorInterval(self, animB4Stun), Func(self.loop, 'stunned')), SuitGlobals.createStunInterval(self, 0, 100)) self.stunnedIval.start() def clearStunnedIval(self): if hasattr(self, 'stunnedSound'): self.stunnedSound.stop() del self.stunnedSound if hasattr(self, 'stunnedIval'): self.stunnedIval.finish() del self.stunnedIval def exitStunned(self): self.clearStunnedIval() self.stop() def getLeftHand(self): return self.find("**/joint_Lhold") def getRightHand(self): return self.find("**/joint_Rhold") def getNametagJoints(self): return [] # BEGIN STATES def enterOff(self, ts=0): pass def exitOff(self): pass def exitGeneral(self): pass def enterTrayWalk(self, ts=0): self.show() self.loop('tray-walk') def exitTrayWalk(self): self.exitGeneral() def enterTrayNeutral(self, ts=0): self.loop('tray-neutral') def exitTrayNeutral(self): self.stop() def enterNeutral(self, ts=0): self.show() self.loop("neutral") def exitNeutral(self): self.exitTimestampAnimTrack() self.exitGeneral() def enterWalk(self, ts=0): self.show() self.loop("walk") self.enableRay() self.disableShadowRay() self.startFootsteps() def exitWalk(self): self.stopFootsteps() self.exitTimestampAnimTrack() self.exitGeneral() self.enableShadowRay() def enterFlail(self, ts=0): self.pingpong('flail', fromFrame=30, toFrame=35) def exitFlail(self): self.stop() def exitTimestampAnimTrack(self): if self.timestampAnimTrack: self.timestampAnimTrack.pause() self.timestampAnimTrack = None def enterFlyNeutral(self, ts=0): self.disableRay() self.enableShadowRay() if not self.propeller: self.generatePropeller() sfx = self.propellerSounds['neutral'] base.playSfx(sfx, node=self, looping=1) self.propeller.loop('chan', fromFrame=0, toFrame=3) self.setPlayRate(0.8, 'land') self.pingpong('land', fromFrame=0, toFrame=10) def exitFlyNeutral(self): self.cleanupPropeller() def enterFlyDown(self, ts=0): self.disableRay() self.enableShadowRay() if not self.propeller: self.generatePropeller() sfx = self.propellerSounds['in'] base.playSfx(sfx, node=self) groundF = 28 dur = self.getDuration('land') fr = self.getFrameRate('land') if fr: animTimeInAir = groundF / fr else: animTimeInAir = groundF impactLength = dur - animTimeInAir timeTillLanding = 6.5 - impactLength waitTime = timeTillLanding - animTimeInAir lastSpinFrame = 8 propDur = self.propeller.getDuration('chan') fr = self.propeller.getFrameRate('chan') spinTime = lastSpinFrame / fr openTime = (lastSpinFrame + 1) / fr if hasattr(self, 'uniqueName'): name = self.uniqueName('enterFlyDown') else: name = 'enterFlyDown' animTrack = Sequence(Func(self.pose, 'land', 0), Wait(waitTime), ActorInterval(self, 'land', duration=dur)) propTrack = Parallel( SoundInterval(sfx, duration=waitTime + dur, node=self), Sequence( ActorInterval(self.propeller, 'chan', constrainedLoop=1, duration=waitTime + spinTime, startTime=0.0, endTime=spinTime), ActorInterval(self.propeller, 'chan', duration=propDur - openTime, startTime=openTime))) self.suitTrack = Parallel(animTrack, propTrack, name=self.taskName('flyDown')) if not self.hasSpawned: self.show() fadeInTrack = Sequence( Func(self.setTransparency, 1), self.colorScaleInterval(1, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(1, 1, 1, 0)), Func(self.clearColorScale), Func(self.clearTransparency)) self.hasSpawned = True self.suitTrack.append(fadeInTrack) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyDown) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name) self.suitTrack.start(ts) def exitFlyDown(self): self.cleanupPropeller() self.enableRay() if self.suitTrack != None: self.ignore(self.suitTrack.getDoneEvent()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.exitGeneral() def enterFlyAway(self, ts=0, doFadeOut=0): self.show() if not self.propeller: self.generatePropeller() sfx = self.propellerSounds['out'] if hasattr(self, 'uniqueName'): name = self.uniqueName('enterFlyAway') else: name = 'enterFlyAway' dur = self.getDuration('land') actInt = ActorInterval(self, 'land', loop=0, startTime=dur, endTime=0.0) lastSpinFrame = 8 propDur = self.propeller.getDuration('chan') fr = self.propeller.getFrameRate('chan') spinTime = lastSpinFrame / fr openTime = (lastSpinFrame + 1) / fr propTrack = Parallel( SoundInterval(sfx, node=self), Sequence( Func(self.propeller.show), ActorInterval(self.propeller, 'chan', endTime=openTime, startTime=propDur), ActorInterval(self.propeller, 'chan', constrainedLoop=1, duration=propDur - openTime, startTime=spinTime, endTime=0.0))) self.suitTrack = Parallel(actInt, propTrack, name=self.taskName('trackName')) if doFadeOut: fadeOut = Sequence( Wait(4.0), Func(self.setTransparency, 1), self.colorScaleInterval(1, colorScale=VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.reparentTo, hidden)) self.suitTrack.append(fadeOut) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyAway) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name) self.suitTrack.start(ts) self.disableRay() self.enableShadowRay() def exitFlyAway(self): self.cleanupPropeller() if self.suitTrack: self.ignore(self.suitTrack.getDoneEvent()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.exitGeneral() def enterDie(self, ts=0): self.show() self.clearStunnedIval() self.generateCog(isLose=1) self.nametag.clearChatText() self.deleteNameTag() self.deathSound = base.audio3d.loadSfx( "phase_3.5/audio/sfx/Cog_Death_Full.ogg") base.audio3d.attachSoundToObject(self.deathSound, self) trackName = self.uniqueName('enterDie') smallGears = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosionSmall.ptf') #smallGears.getParticlesNamed('particles-1').setPoolSize(30) singleGear = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosion.ptf') singleGear.getParticlesNamed('particles-1').setPoolSize(1) smallGearExplosion = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosion.ptf') smallGearExplosion.getParticlesNamed('particles-1').setPoolSize(10) bigGearExplosion = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosionBig.ptf') bigGearExplosion.getParticlesNamed('particles-1').setPoolSize(30) smallGears.setDepthWrite(False) singleGear.setDepthWrite(False) smallGearExplosion.setDepthWrite(False) bigGearExplosion.setDepthWrite(False) gearPoint = self.getPos(render) + (0, 0, self.getHeight() - 0.2) self.smallGears = smallGears self.smallGears.setPos(gearPoint) self.singleGear = singleGear self.singleGear.setPos(gearPoint) self.smallGearExp = smallGearExplosion self.smallGearExp.setPos(gearPoint) self.bigGearExp = bigGearExplosion self.bigGearExp.setPos(gearPoint) gearTrack = Sequence(Wait(0.7), Func(self.doSingleGear), Wait(1.5), Func(self.doSmallGears), Wait(3.0), Func(self.doBigExp)) self.suitTrack = Parallel( Sequence(Wait(0.8), SoundInterval(self.deathSound, duration=4.28)), Sequence(Wait(0.7), Func(self.doSingleGear), Wait(4.5), Func(self.suitExplode), Wait(1.0), Func(self.disableBodyCollisions)), gearTrack, Sequence(ActorInterval(self, 'lose', duration=6), Func(self.getGeomNode().hide)), name=trackName) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getName(), self.exitDie) if self.isDistributed(): self.suitTrack.delayDelete = DelayDelete.DelayDelete( self, trackName) self.suitTrack.start(ts) def doSingleGear(self): self.singleGear.start(CIGlobals.getParticleRender()) def doSmallGears(self): self.smallGears.start(CIGlobals.getParticleRender()) def doSmallExp(self): self.smallGearExp.start(CIGlobals.getParticleRender()) def doBigExp(self): self.bigGearExp.start(CIGlobals.getParticleRender()) def suitExplode(self): pos = self.getPart('body').find('**/joint_head').getPos(render) + ( 0, 0, 2) # Force the loser suit to use UnlitGeneric shader, workaround for the has_mat() assertion BSPUtility.applyUnlitOverride(self) CIGlobals.makeExplosion(pos, 0.5, soundVol=0.32, smoke=False) def exitDie(self): if self.suitTrack != None: self.ignore(self.suitTrack.getName()) self.suitTrack.finish() if self.isDistributed(): DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None if hasattr(self, 'singleGear'): self.singleGear.softStop() del self.singleGear if hasattr(self, 'smallGears'): self.smallGears.softStop() del self.smallGears if hasattr(self, 'smallGearExp'): self.smallGearExp.softStop() del self.smallGearExp if hasattr(self, 'bigGearExp'): self.bigGearExp.softStop() del self.bigGearExp if self.deathSound: self.deathSound.stop() self.deathSound = None def enterWin(self, ts=0): self.play('win') def exitWin(self): self.exitGeneral() # END STATES def generateSuit(self, suitPlan, variant, voice=None, hideFirst=False): startTime = globalClock.getRealTime() self.suitPlan = suitPlan self.suit = suitPlan.getSuitType() self.head = suitPlan.getHead() self.dept = suitPlan.getDept() self.handColor = suitPlan.getHandColor() self.variant = variant self.setVoice(voice) self.generateCog() mat = CIGlobals.getCharacterMaterial(shininess=50.0, specular=(0.4, 0.4, 0.4, 1)) self.setMaterial(mat) #ts = TextureStage('shiny') #ts.setMode(TextureStage.MAdd) #ts.setRgbScale(2) #tex = loader.loadCubeMap('phase_14/maps/cubemap/defaultcubemap_#.png') #tex = loader.loadTexture('phase_14/maps/envmap001a_cog.png') #self.setTexGen(ts, TexGenAttrib.MEyeSphereMap) #self.setTexture(ts, tex) self.initializeBodyCollisions() if hideFirst: self.hide() else: self.show() endTime = globalClock.getRealTime() print("generateSuit took {0} ms".format((endTime - startTime) * 1000)) def __blinkRed(self, task): self.healthBar.setColor(SuitGlobals.healthColors[3], 1) #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[3], 1) if self.condition == 5: self.healthBar.setScale(1.17) return task.done def __blinkGray(self, task): if not self.healthBar: return self.healthBar.setColor(SuitGlobals.healthColors[4], 1) #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[4], 1) if self.condition == 5: self.healthBar.setScale(1.0) return task.done def generateHealthBar(self): self.removeHealthBar() button = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam' ).find('**/minnieCircle') button.setScale(3.0) button.setH(180) button.setColor(SuitGlobals.healthColors[0]) chestNull = self.find('**/def_joint_attachMeter') if chestNull.isEmpty(): chestNull = self.find('**/joint_attachMeter') button.reparentTo(chestNull) self.healthBar = button #self.healthBarGlow = loader.loadModel('phase_3.5/models/props/glow.bam') #self.healthBarGlow.reparentTo(self.healthBar) #self.healthBarGlow.setScale(0.28) #self.healthBarGlow.setPos(-0.005, 0.01, 0.015) #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[0]) button.flattenLight() button.setLightOff() self.condition = 0 if hasattr(self, 'getHealth'): self.updateHealthBar(self.getHealth()) def updateHealthBar(self, hp): if not self.healthBar: return if hp > self.health: self.health = hp health = 0.0 try: health = float(hp) / float(self.maxHealth) except: pass if health > 0.95: condition = 0 elif health > 0.7: condition = 1 elif health > 0.3: condition = 2 elif health > 0.05: condition = 3 elif health > 0.0: condition = 4 else: condition = 5 if self.condition != condition: taskMgr.remove(self.taskName('blink-task')) if condition == 4: blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) elif condition == 5: blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) else: self.healthBar.setColor(SuitGlobals.healthColors[condition], 1) #self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[condition], 1) self.condition = condition def removeHealthBar(self): if self.healthBar: self.healthBar.removeNode() self.healthBar = None if self.condition == 4 or self.condition == 5: taskMgr.remove(self.taskName('blink-task')) self.healthCondition = 0 return def initializeBodyCollisions(self): self.notify.info('Initializing Body Collisions!') self.setupPhysics(2, self.getHeight()) self.enableRay() def hideSuit(self): self.hide() def showSuit(self): self.show() fadeIn = Sequence( Func(self.setTransparency, 1), self.colorScaleInterval(0.6, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.reparentTo, render)) fadeIn.start() def doStunEffect(self): self.clearStunnedIval() self.stunnedIval = SuitGlobals.createStunInterval(self, 0, 2) self.stunnedIval.start() def doGagEffect(self, flags): GagEffects.doGagEffect(self, flags) def generateCog(self, isLose=0, nameTag=True): #startTime = globalClock.getRealTime() generateCollector.start() cleanupCollector.start() self.cleanup() cleanupCollector.stop() if not isLose: if self.suitPlan in SuitBank.suitSetups: setup = SuitBank.suitSetups[self.suitPlan] else: setup = SuitBank.SuitSetup() SuitBank.suitSetups[self.suitPlan] = setup if not self.variant in setup.actor: setupActor = Actor() if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE: setupActor.loadModel( 'phase_5/models/char/cog%s_robot-zero.bam' % (str(self.suit)), 'body') else: setupActor.loadModel( 'phase_3.5/models/char/suit%s-mod.bam' % (str(self.suit)), 'body') animations = SuitGlobals.animations anims = {} for anim in animations: if not self.suit in anim.getSuitTypes(): continue path = 'phase_%s/models/char/suit%s-%s.bam' % ( anim.getPhase(), self.suit, anim.getFile()) anims[anim.getName()] = path setupActor.loadAnims(anims, 'body') setup.actor[self.variant] = setupActor actorCollector.start() self.copyActor(setup.actor[self.variant]) actorCollector.stop() healthBarCollector.start() self.generateHealthBar() healthBarCollector.stop() footstepCollector.start() if self.suitPlan.suitType == SuitType.A: self.footstepSound = base.audio3d.loadSfx( "phase_5/audio/sfx/ENC_cogafssm.ogg") elif self.suitPlan.suitType == SuitType.B: self.footstepSound = base.audio3d.loadSfx( "phase_5/audio/sfx/ENC_cogbfssm.ogg") elif self.suitPlan.suitType == SuitType.C: self.footstepSound = base.audio3d.loadSfx( "phase_5/audio/sfx/ENC_cogcfssm.ogg") if self.footstepSound: base.audio3d.attachSoundToObject(self.footstepSound, self) self.footstepSound.setVolume(0.0) self.footstepSound.setLoop(True) self.footstepSound.play() footstepCollector.stop() else: if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE: self.loadModel( 'phase_5/models/char/cog%s_robot-lose-mod.bam' % (str(self.suit)), 'body') else: self.loadModel( 'phase_4/models/char/suit%s-lose-mod.bam' % (str(self.suit)), 'body') self.loadAnims( { 'lose': 'phase_4/models/char/suit%s-lose.bam' % (str(self.suit)) }, 'body') genHeadCollector.start() if self.variant != Variant.SKELETON: self.headModel = self.head.generate() self.headModel.reparentTo(self.find("**/joint_head")) if self.suitPlan.getName() == SuitGlobals.VicePresident: self.headModel.setScale(0.35) self.headModel.setHpr(270, 0, 270) self.headModel.setZ(-0.10) self.headModel.loop('neutral') if self.variant == Variant.SKELETON: self.headModel = self.find("**/joint_head") #antenna = loader.loadModel("models/police_antenna.bam") ##antenna.reparentTo(self.find("**/joint_head")) #antenna.setPos(0.5, -0.5, 0) #antenna.setScale(1.25) #antenna.clearModelNodes() #antenna.flattenStrong() genHeadCollector.stop() self.setClothes() classScale = 1.0 #self.suitPlan.getCogClassAttrs().scaleMod self.setAvatarScale( (self.suitPlan.getScale() / SuitGlobals.scaleFactors[self.suit]) * classScale) self.setHeight(self.suitPlan.getHeight()) nametagCollector.start() if nameTag: self.setupNameTag() nametagCollector.stop() Avatar.initShadow(self) if self.variant != Variant.SKELETON: # We've already done all manipulating to the cog, we can just flatten it. self.getPart('body').flattenStrong() self.postFlatten() self.headModel.flattenStrong() if isinstance(self.headModel, Actor): self.headModel.postFlatten() #endTime = globalClock.getRealTime() #print("GenerateCog took {0} seconds".format(endTime - startTime)) generateCollector.stop() def cleanup(self): if self.footstepSound: self.footstepSound.stop() self.footstepSound = None self.cleanupPropeller() self.clearChatbox() if self.shadow: self.deleteShadow() if self.headModel: self.headModel.removeNode() self.headModel = None if self.getPart('body'): self.removePart('body') self.timestampAnimTrack = None def generatePropeller(self): self.cleanupPropeller() self.propeller = Actor( 'phase_4/models/props/propeller-mod.bam', {'chan': 'phase_4/models/props/propeller-chan.bam'}) self.propeller.reparentTo(self.find("**/joint_head")) self.propellerSounds['in'] = base.audio3d.loadSfx( SuitGlobals.propellerInSfx) self.propellerSounds['out'] = base.audio3d.loadSfx( SuitGlobals.propellerOutSfx) self.propellerSounds['neutral'] = base.audio3d.loadSfx( SuitGlobals.propellerNeutSfx) for sound in self.propellerSounds.values(): base.audio3d.attachSoundToObject(sound, self.propeller) def cleanupPropeller(self): for sound in self.propellerSounds.values(): base.audio3d.detachSound(sound) sound.stop() self.propellerSounds = {} if self.propeller and not self.propeller.isEmpty(): self.propeller.cleanup() self.propeller = None def setVoice(self, voice): if not voice: if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE: self.voice = Voice.SKELETON else: self.voice = Voice.NORMAL else: self.voice = voice if self.variant == Variant.SKELETON: head = self else: head = self.headModel self.addSound("statement", self.voice.getSoundFile('statement'), node=head) self.addSound("grunt", self.voice.getSoundFile('grunt'), node=head) self.addSound("question", self.voice.getSoundFile('question'), node=head) if self.voice == Voice.NORMAL: self.addSound("question2", self.voice.getSoundFile('question_2'), node=head) self.chatSoundTable[CHAT_SHORT] = "statement" self.chatSoundTable[CHAT_MEDIUM] = "statement" self.chatSoundTable[CHAT_LONG] = "statement" self.chatSoundTable[CHAT_EXCLAIM] = "grunt" self.chatSoundTable[CHAT_HOWL] = "statement" if self.voice == Voice.NORMAL: self.chatSoundTable[CHAT_QUESTION] = ["question", "question2"] else: self.chatSoundTable[CHAT_QUESTION] = "question" def setClothes(self): setClothesCollector.start() if self.variant == Variant.SKELETON: parts = self.findAllMatches('**/pPlane*') for partNum in range(0, parts.getNumPaths()): bb = parts.getPath(partNum) bb.setTwoSided(1) tie = 'phase_5/maps/cog_robot_tie_%s.mat' % self.dept.getTie() #tie.setMinfilter(Texture.FTLinearMipmapLinear) #tie.setMagfilter(Texture.FTLinear) self.find('**/tie').setBSPMaterial(tie, 1) else: texture = 'phase_3.5/maps/tt_t_ene_' + self.dept.getName().lower( ) + '.mat' #texture = 'materials/models/suit/tt_t_ene_police.mat' #if self.variant == Variant.WAITER: # prefix = 'phase_3.5/maps/waiter_m_%s.mat' #elif self.variant == Variant.CORRODED: # prefix = 'phase_3.5/maps/' + self.dept.getClothingPrefix() + '_rust_%s.mat' #legTex = prefix % 'leg' #armTex = prefix % 'sleeve' #blazTex = prefix % 'blazer' #texs = [legTex, armTex, blazTex] #for texture in texs: # texture.setMinfilter(Texture.FTLinearMipmapLinear) # texture.setMagfilter(Texture.FTLinear) #self.find('**/legs').setBSPMaterial(legTex, 1) #self.find('**/arms').setBSPMaterial(armTex, 1) #self.find('**/torso').setBSPMaterial(blazTex, 1) #self.find('**/hands').setBSPMaterial("phase_3.5/maps/tt_t_ene_sellbotRental_hand.mat", 1) body = self.getPart('body') for child in body.getChildren(): if isinstance(child.node(), GeomNode): child.setBSPMaterial(texture, 1) if not self.variant == Variant.CORRODED: self.find('**/hands').setColor(self.handColor) else: self.find('**/hands').setColor(Variant.CORRODED_HAND_COLOR) setClothesCollector.stop() def startFootsteps(self): classAttrs = self.suitPlan.getCogClassAttrs() if not self.footstepSound or not classAttrs.footsteps: return self.footstepSound.setPlayRate(classAttrs.walkMod) self.footstepSound.setLoop(True) self.footstepSound.play() def stopFootsteps(self): if not self.footstepSound: return self.footstepSound.stop() def setSpeed(self, forwardSpeed, rotateSpeed, strafeSpeed=0.0): Avatar.setSpeed(self, forwardSpeed, rotateSpeed, strafeSpeed) currSpeed = self.currentSpeed if self.doingActivity: currSpeed = 0 if self.footstepSound and self.standWalkRunReverse is not None: action = self.getMoveAction(forwardSpeed, rotateSpeed, strafeSpeed) minSpeed = self.standWalkRunReverse[action][2] maxSpeed = self.standWalkRunReverse[action][3] self.footstepSound.setVolume( CIGlobals.clamp( CIGlobals.remapVal(currSpeed, minSpeed, maxSpeed, 0, 1), 0, 1)) self.footstepSound.setPlayRate(max(1, currSpeed / maxSpeed)) def setName(self, nameString, charName): Avatar.setName(self, nameString, charName=charName, createNow=1) def setupNameTag(self, tempName=None): Avatar.setupNameTag(self, tempName=tempName) if self.nametag: if self.level > 0: self.nametag.setText(self.nametag.getText() + '\n%s\nLevel %s %s' % (self.dept.getName(), self.level, self.suitPlan.getCogClassName())) else: self.nametag.setText(self.nametag.getText() + '\n%s' % (self.dept.getName())) def clearChatbox(self): self.clearChat() self.chat = None if self.chatDial: base.audio3d.detachSound(self.chatDial) self.chatDial.stop() self.chatDial = None def getDept(self): return self.dept def getVariant(self): return self.variant def disable(self): if self.suitTrack: self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.animFSM.requestFinalState() self.cleanup() Avatar.disable(self) def delete(self): Avatar.delete(self) self.cleanup()
class Suit(Avatar): notify = directNotify.newCategory('Suit') audio3d = Audio3DManager(base.sfxManagerList[0], camera) audio3d.setDistanceFactor(25) audio3d.setDropOffFactor(audio3d.getDistanceFactor() / 1000) def __init__(self): Avatar.__init__(self) self.dept = None self.suit = None self.head = None self.headModel = None self.variant = None self.handColor = None self.voice = None self.chat = None self.chatDial = None self.shadow = None self.propeller = None self.smallExp = None self.largeExp = None self.explosion = None self.hasSpawned = False self.suitTrack = None self.timestampAnimTrack = None self.propellerSounds = {} self.healthBar = None self.healthBarGlow = None self.condition = 0 self.avatarType = CIGlobals.Suit self.suitPlan = None self.animFSM = ClassicFSM('Suit', [ State('off', self.enterOff, self.exitOff), State('neutral', self.enterNeutral, self.exitNeutral), State('walk', self.enterWalk, self.exitWalk), State('die', self.enterDie, self.exitDie), State('win', self.enterWin, self.exitWin), State('attack', self.enterAttack, self.exitAttack), State('flail', self.enterFlail, self.exitFlail), State('flyDown', self.enterFlyDown, self.exitFlyDown), State('flyAway', self.enterFlyAway, self.exitFlyAway), State('flyNeutral', self.enterFlyNeutral, self.exitFlyNeutral), State('trayWalk', self.enterTrayWalk, self.exitTrayWalk), State('trayNeutral', self.enterTrayNeutral, self.exitTrayNeutral) ], 'off', 'off') self.animFSM.enterInitialState() self.initializeBodyCollisions() def getNametagJoints(self): return [] # BEGIN STATES def enterOff(self, ts=0): self.anim = None return def exitOff(self): pass def exitGeneral(self): self.stop() def enterTrayWalk(self, ts=0): self.show() self.loop('tray-walk') def exitTrayWalk(self): self.exitGeneral() def enterTrayNeutral(self, ts=0): self.loop('tray-neutral') def exitTrayNeutral(self): self.stop() def enterNeutral(self, ts=0): self.show() self.loop("neutral") def exitNeutral(self): self.exitTimestampAnimTrack() self.exitGeneral() def enterWalk(self, ts=0): self.show() self.loop("walk") self.disableShadowRay() def exitWalk(self): self.exitTimestampAnimTrack() self.exitGeneral() self.enableShadowRay() def enterFlail(self, ts=0): self.pingpong('flail', fromFrame=30, toFrame=35) def exitFlail(self): self.stop() def exitTimestampAnimTrack(self): if self.timestampAnimTrack: self.timestampAnimTrack.pause() self.timestampAnimTrack = None def enterAttack(self, attack, target, ts=0): self.show() if hasattr(self, 'uniqueName'): doneEvent = self.uniqueName('suitAttackDone') else: doneEvent = 'suitAttackDone' self.suitAttackState = SuitAttacks(doneEvent, self, target) self.suitAttackState.load(attack) self.suitAttackState.enter(ts) self.headsUp(target) self.acceptOnce(doneEvent, self.handleSuitAttackDone) def handleSuitAttackDone(self): self.exitAttack() def exitAttack(self): if hasattr(self, 'uniqueName'): self.ignore(self.uniqueName('suitAttackDone')) else: self.ignore('suitAttackDone') if hasattr(self, 'suitAttackState'): self.suitAttackState.exit() if hasattr(self, 'suitAttackState'): self.suitAttackState.unload() if hasattr(self, 'suitAttackState'): del self.suitAttackState def interruptAttack(self): if hasattr(self, 'suitAttackState'): self.suitAttackState.currentAttack.interruptAttack() self.clearChatbox() def handleWeaponTouch(self): if hasattr(self, 'suitAttackState'): currentAttack = self.suitAttackState.currentAttack if hasattr(currentAttack, 'handleWeaponTouch'): currentAttack.handleWeaponTouch() def enterFlyNeutral(self, ts=0): self.disableRay() if not self.propeller: self.generatePropeller() sfx = self.propellerSounds['neutral'] sfx.setLoop(True) base.playSfx(sfx, node=self) self.propeller.loop('chan', fromFrame=0, toFrame=3) self.setPlayRate(0.8, 'land') self.pingpong('land', fromFrame=0, toFrame=10) def exitFlyNeutral(self): self.cleanupPropeller() def enterFlyDown(self, ts=0): self.disableRay() if not self.propeller: self.generatePropeller() sfx = self.propellerSounds['in'] base.playSfx(sfx, node=self) groundF = 28 dur = self.getDuration('land') fr = self.getFrameRate('land') if fr: animTimeInAir = groundF / fr else: animTimeInAir = groundF impactLength = dur - animTimeInAir timeTillLanding = 6.5 - impactLength waitTime = timeTillLanding - animTimeInAir lastSpinFrame = 8 propDur = self.propeller.getDuration('chan') fr = self.propeller.getFrameRate('chan') spinTime = lastSpinFrame / fr openTime = (lastSpinFrame + 1) / fr if hasattr(self, 'uniqueName'): name = self.uniqueName('enterFlyDown') else: name = 'enterFlyDown' animTrack = Sequence(Func(self.pose, 'land', 0), Wait(waitTime), ActorInterval(self, 'land', duration=dur)) propTrack = Parallel( SoundInterval(sfx, duration=waitTime + dur, node=self), Sequence( ActorInterval(self.propeller, 'chan', constrainedLoop=1, duration=waitTime + spinTime, startTime=0.0, endTime=spinTime), ActorInterval(self.propeller, 'chan', duration=propDur - openTime, startTime=openTime))) self.suitTrack = Parallel(animTrack, propTrack, name=self.taskName('flyDown')) if not self.hasSpawned: self.show() fadeInTrack = Sequence( Func(self.setTransparency, 1), self.colorScaleInterval(1, colorScale=VBase4(1, 1, 1, 1), startColorScale=VBase4(1, 1, 1, 0)), Func(self.clearColorScale), Func(self.clearTransparency)) self.hasSpawned = True self.suitTrack.append(fadeInTrack) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyDown) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name) self.suitTrack.start(ts) def exitFlyDown(self): self.initializeRay(self.avatarType, 2) if self.suitTrack != None: self.ignore(self.suitTrack.getDoneEvent()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.exitGeneral() self.cleanupPropeller() def enterFlyAway(self, ts=0, doFadeOut=0): self.show() if not self.propeller: self.generatePropeller() sfx = self.propellerSounds['out'] if hasattr(self, 'uniqueName'): name = self.uniqueName('enterFlyAway') else: name = 'enterFlyAway' dur = self.getDuration('land') actInt = ActorInterval(self, 'land', loop=0, startTime=dur, endTime=0.0) lastSpinFrame = 8 propDur = self.propeller.getDuration('chan') fr = self.propeller.getFrameRate('chan') spinTime = lastSpinFrame / fr openTime = (lastSpinFrame + 1) / fr propTrack = Parallel( SoundInterval(sfx, node=self), Sequence( Func(self.propeller.show), ActorInterval(self.propeller, 'chan', endTime=openTime, startTime=propDur), ActorInterval(self.propeller, 'chan', constrainedLoop=1, duration=propDur - openTime, startTime=spinTime, endTime=0.0))) self.suitTrack = Parallel(actInt, propTrack, name=self.taskName('trackName')) if doFadeOut: fadeOut = Sequence( Wait(4.0), Func(self.setTransparency, 1), self.colorScaleInterval(1, colorScale=VBase4(1, 1, 1, 0), startColorScale=VBase4(1, 1, 1, 1)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.reparentTo, hidden)) self.suitTrack.append(fadeOut) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.exitFlyAway) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, name) self.suitTrack.start(ts) self.disableRay() def exitFlyAway(self): if self.suitTrack: self.ignore(self.suitTrack.getDoneEvent()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.cleanupPropeller() self.exitGeneral() def enterDie(self, ts=0): self.show() self.generateCog(isLose=1) self.nametag.clearChatText() self.deleteNameTag() deathSound = base.audio3d.loadSfx( "phase_3.5/audio/sfx/Cog_Death_Full.ogg") base.audio3d.attachSoundToObject(deathSound, self) trackName = self.uniqueName('enterDie') smallGears = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosionSmall.ptf') smallGears.getParticlesNamed('particles-1').setPoolSize(30) singleGear = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosion.ptf') singleGear.getParticlesNamed('particles-1').setPoolSize(1) smallGearExplosion = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosion.ptf') smallGearExplosion.getParticlesNamed('particles-1').setPoolSize(10) bigGearExplosion = ParticleLoader.loadParticleEffect( 'phase_3.5/etc/gearExplosionBig.ptf') bigGearExplosion.getParticlesNamed('particles-1').setPoolSize(30) smallGears.setDepthWrite(False) singleGear.setDepthWrite(False) smallGearExplosion.setDepthWrite(False) bigGearExplosion.setDepthWrite(False) self.smallGears = smallGears self.smallGears.setPos(self.find('**/joint_head').getPos() + (0, 0, 2)) self.singleGear = singleGear self.smallGearExp = smallGearExplosion self.bigGearExp = bigGearExplosion gearTrack = Sequence(Wait(0.7), Func(self.doSingleGear), Wait(1.5), Func(self.doSmallGears), Wait(3.0), Func(self.doBigExp)) self.suitTrack = Parallel(Sequence( Wait(0.8), SoundInterval(deathSound, node=self, duration=deathSound.length() / 2)), Sequence(Wait(0.7), Func(self.doSingleGear), Wait(4.3), Func(self.suitExplode), Wait(1.0), Func(self.disableBodyCollisions), Func(self.__cleanupExplosion)), gearTrack, Sequence( ActorInterval(self, 'lose', duration=6), Func(self.getGeomNode().hide)), name=trackName) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getName(), self.exitDie) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self, trackName) self.suitTrack.start(ts) del deathSound def doSingleGear(self): self.singleGear.start(self.getGeomNode()) def doSmallGears(self): self.smallGears.start(self.getGeomNode()) def doSmallExp(self): self.smallGearExp.start(self.getGeomNode()) def doBigExp(self): self.bigGearExp.start(self.getGeomNode()) def suitExplode(self): self.explosion = loader.loadModel( 'phase_3.5/models/props/explosion.bam') self.explosion.setScale(0.5) self.explosion.reparentTo(render) self.explosion.setBillboardPointEye() if self.variant == Variant.SKELETON: self.explosion.setPos( self.getPart('body').find('**/joint_head').getPos(render) + (0, 0, 2)) else: self.explosion.setPos(self.headModel.getPos(render) + (0, 0, 2)) def __cleanupExplosion(self): if self.explosion: self.explosion.removeNode() self.explosion = None def exitDie(self): if self.suitTrack != None: self.ignore(self.suitTrack.getName()) self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None if hasattr(self, 'singleGear'): self.singleGear.cleanup() del self.singleGear if hasattr(self, 'smallGears'): self.smallGears.cleanup() del self.smallGears if hasattr(self, 'smallGearExp'): self.smallGearExp.cleanup() del self.smallGearExp if hasattr(self, 'bigGearExp'): self.bigGearExp.cleanup() del self.bigGearExp self.__cleanupExplosion() def enterWin(self, ts=0): self.play('win') def exitWin(self): self.exitGeneral() # END STATES def generate(self, suitPlan, variant, voice=None, hideFirst=True): self.suitPlan = suitPlan self.suit = suitPlan.getSuitType() self.head = suitPlan.getHead() self.dept = suitPlan.getDept() self.handColor = suitPlan.getHandColor() self.variant = variant self.setVoice(voice) self.generateCog() if hideFirst: self.hide() def __blinkRed(self, task): self.healthBar.setColor(SuitGlobals.healthColors[3], 1) self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[3], 1) if self.condition == 5: self.healthBar.setScale(1.17) return Task.done def __blinkGray(self, task): if not self.healthBar: return self.healthBar.setColor(SuitGlobals.healthColors[4], 1) self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[4], 1) if self.condition == 5: self.healthBar.setScale(1.0) return Task.done def generateHealthBar(self): self.removeHealthBar() button = loader.loadModel('phase_3.5/models/gui/matching_game_gui.bam' ).find('**/minnieCircle') button.setScale(3.0) button.setH(180) button.setColor(SuitGlobals.healthColors[0]) chestNull = self.find('**/def_joint_attachMeter') if chestNull.isEmpty(): chestNull = self.find('**/joint_attachMeter') button.reparentTo(chestNull) self.healthBar = button self.healthBarGlow = loader.loadModel( 'phase_3.5/models/props/glow.bam') self.healthBarGlow.reparentTo(self.healthBar) self.healthBarGlow.setScale(0.28) self.healthBarGlow.setPos(-0.005, 0.01, 0.015) self.healthBarGlow.setColor(SuitGlobals.healthGlowColors[0]) button.flattenLight() self.condition = 0 if hasattr(self, 'getHealth'): self.updateHealthBar(self.getHealth()) def updateHealthBar(self, hp): if not self.healthBar: return if hp > self.health: self.health = hp health = 0.0 try: health = float(hp) / float(self.maxHealth) except: pass if health > 0.95: condition = 0 elif health > 0.7: condition = 1 elif health > 0.3: condition = 2 elif health > 0.05: condition = 3 elif health > 0.0: condition = 4 else: condition = 5 if self.condition != condition: if condition == 4: blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.75), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) elif condition == 5: if self.condition == 4: taskMgr.remove(self.taskName('blink-task')) blinkTask = Task.loop(Task(self.__blinkRed), Task.pause(0.25), Task(self.__blinkGray), Task.pause(0.1)) taskMgr.add(blinkTask, self.taskName('blink-task')) else: self.healthBar.setColor(SuitGlobals.healthColors[condition], 1) self.healthBarGlow.setColor( SuitGlobals.healthGlowColors[condition], 1) self.condition = condition def removeHealthBar(self): if self.healthBar: self.healthBar.removeNode() self.healthBar = None if self.condition == 4 or self.condition == 5: taskMgr.remove(self.taskName('blink-task')) self.healthCondition = 0 return def initializeLocalCollisions(self, name): self.notify.info('Initializing Local Collisions!') Avatar.initializeLocalCollisions(self, 1, 3, name) def initializeBodyCollisions(self): self.notify.info('Initializing Body Collisions!') Avatar.initializeBodyCollisions(self, self.avatarType, 6, 2) self.initializeRay(self.avatarType, 2) def hideSuit(self): self.hide() def showSuit(self): self.show() fadeIn = Sequence( Func(self.setTransparency, 1), self.colorScaleInterval(0.6, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), Func(self.clearColorScale), Func(self.clearTransparency), Func(self.reparentTo, render)) fadeIn.start() def generateCog(self, isLose=0): self.cleanup() if not isLose: if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE: self.loadModel( 'phase_5/models/char/cog%s_robot-zero.bam' % (str(self.suit)), 'body') else: self.loadModel( 'phase_3.5/models/char/suit%s-mod.bam' % (str(self.suit)), 'body') animations = SuitGlobals.animations anims = {} for anim in animations: if not self.suit in anim.getSuitTypes(): continue path = 'phase_%s/models/char/suit%s-%s.bam' % ( anim.getPhase(), self.suit, anim.getFile()) anims[anim.getName()] = path self.loadAnims(anims, 'body') self.generateHealthBar() self.generatePropeller() else: if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE: self.loadModel( 'phase_5/models/char/cog%s_robot-lose-mod.bam' % (str(self.suit)), 'body') else: self.loadModel( 'phase_4/models/char/suit%s-lose-mod.bam' % (str(self.suit)), 'body') self.loadAnims( { 'lose': 'phase_4/models/char/suit%s-lose.bam' % (str(self.suit)) }, 'body') if self.variant != Variant.SKELETON: self.headModel = self.head.generate() self.headModel.reparentTo(self.find('**/joint_head')) if self.suitPlan.getName() == SuitGlobals.VicePresident: self.headModel.setScale(0.35) self.headModel.setHpr(270, 0, 270) self.headModel.setZ(-0.10) self.headModel.loop('neutral') self.setClothes() self.setAvatarScale(self.suitPlan.getScale() / SuitGlobals.scaleFactors[self.suit]) self.setHeight(self.suitPlan.getHeight()) self.setupNameTag() Avatar.initShadow(self) def cleanup(self): self.cleanupPropeller() self.clearChatbox() if self.shadow: self.deleteShadow() if self.getPart('body'): self.removePart('body') if self.headModel: self.headModel.removeNode() self.headModel = None self.timestampAnimTrack = None def generatePropeller(self): self.cleanupPropeller() self.propeller = Actor( 'phase_4/models/props/propeller-mod.bam', {'chan': 'phase_4/models/props/propeller-chan.bam'}) self.propeller.reparentTo(self.find('**/joint_head')) self.propellerSounds['in'] = self.audio3d.loadSfx( SuitGlobals.propellerInSfx) self.propellerSounds['out'] = self.audio3d.loadSfx( SuitGlobals.propellerOutSfx) self.propellerSounds['neutral'] = self.audio3d.loadSfx( SuitGlobals.propellerNeutSfx) for sound in self.propellerSounds.values(): self.audio3d.attachSoundToObject(sound, self.propeller) def cleanupPropeller(self): for sound in self.propellerSounds.values(): self.audio3d.detachSound(sound) sound.stop() self.propellerSounds = {} if self.propeller: self.propeller.cleanup() self.propeller = None def setVoice(self, voice): if not voice: if self.variant == Variant.SKELETON or self.variant == Variant.ZOMBIE: self.voice = Voice.SKELETON else: self.voice = Voice.NORMAL else: self.voice = voice def setClothes(self): if self.variant == Variant.SKELETON: parts = self.findAllMatches('**/pPlane*') for partNum in range(0, parts.getNumPaths()): bb = parts.getPath(partNum) bb.setTwoSided(1) tie = loader.loadTexture('phase_5/maps/cog_robot_tie_%s.jpg' % self.dept.getTie()) tie.setMinfilter(Texture.FTLinearMipmapLinear) tie.setMagfilter(Texture.FTLinear) self.find('**/tie').setTexture(tie, 1) else: prefix = 'phase_3.5/maps/' + self.dept.getClothingPrefix( ) + '_%s.jpg' if self.variant == Variant.WAITER: prefix = 'phase_3.5/maps/waiter_m_%s.jpg' self.find('**/legs').setTexture(loader.loadTexture(prefix % 'leg'), 1) self.find('**/arms').setTexture( loader.loadTexture(prefix % 'sleeve'), 1) self.find('**/torso').setTexture( loader.loadTexture(prefix % 'blazer'), 1) self.find('**/hands').setColor(self.handColor) def setName(self, nameString, charName): Avatar.setName(self, nameString, avatarType=self.avatarType, charName=charName, createNow=1) def setupNameTag(self, tempName=None): Avatar.setupNameTag(self, tempName=tempName) if self.nametag: if self.level > 0: self.nametag.setText(self.nametag.getText() + '\n%s\nLevel %s' % (self.dept.getName(), self.level)) else: self.nametag.setText(self.nametag.getText() + '\n%s' % (self.dept.getName())) def setChat(self, chat): self.clearChatbox() Avatar.setChat(self, chat) self.chat = chat chatDial = None questionDial = self.voice.getSoundFile('question') question02Dial = None gruntDial = self.voice.getSoundFile('grunt') statementDial = self.voice.getSoundFile('statement') if self.voice == Voice.NORMAL: question02Dial = self.voice.getSoundFile('question_2') if '!' in self.chat: chatDial = self.audio3d.loadSfx(gruntDial) elif '?' in self.chat: questionDials = [questionDial] if self.voice == Voice.NORMAL: questionDials.append(question02Dial) chatDial = self.audio3d.loadSfx(random.choice(questionDials)) else: chatDial = self.audio3d.loadSfx(statementDial) self.chatDial = chatDial if self.variant == Variant.SKELETON: self.audio3d.attachSoundToObject(self.chatDial, self) else: self.audio3d.attachSoundToObject(self.chatDial, self.headModel) base.playSfx(self.chatDial, node=self) def clearChatbox(self): self.clearChat() self.chat = None if self.chatDial: self.chatDial.stop() self.chatDial = None def getDept(self): return self.dept def getVariant(self): return self.variant def disable(self): if self.suitTrack: self.suitTrack.finish() DelayDelete.cleanupDelayDeletes(self.suitTrack) self.suitTrack = None self.animFSM.requestFinalState() self.cleanup() Avatar.disable(self) def delete(self): Avatar.delete(self) self.cleanup()
class Place(StateData): notify = directNotify.newCategory('Place') def __init__(self, loader, doneEvent): StateData.__init__(self, doneEvent) self.loader = loader self.zoneId = None self.track = None return def maybeUpdateAdminPage(self): if self.fsm: if self.fsm.getCurrentState(): if self.fsm.getCurrentState().getName() == 'shtickerBook': if hasattr(self, 'shtickerBookStateData'): if self.shtickerBookStateData.fsm.getCurrentState().getName() == 'adminPage': if base.cr.playGame.suitManager: text2Change2 = 'Turn Suit Spawner ' if base.cr.playGame.suitManager.getSpawner(): text2Change2 += 'Off' else: text2Change2 += 'On' self.shtickerBookStateData.adminPageStateData.suitSpawnerBtn['text'] = text2Change2 def enterStart(self): pass def exitStart(self): pass def enterFinal(self): pass def exitFinal(self): pass def enter(self): StateData.enter(self) base.localAvatar.createChatInput() def exit(self): base.localAvatar.disableChatInput() StateData.exit(self) def enterDoorIn(self, distDoor): base.localAvatar.attachCamera() requestStatus = {} requestStatus['zoneId'] = distDoor.getToZone() requestStatus['hoodId'] = base.cr.playGame.hood.id requestStatus['how'] = 'doorOut' requestStatus['shardId'] = None requestStatus['doorIndex'] = distDoor.getDoorIndex() foundBlock = False for interior in base.cr.doFindAll('DistributedToonInterior'): if interior.zoneId == base.localAvatar.zoneId: foundBlock = True requestStatus['block'] = interior.getBlock() break if not foundBlock: requestStatus['block'] = distDoor.getBlock() requestStatus['where'] = ZoneUtil.getWhereName(requestStatus['zoneId']) requestStatus['loader'] = base.cr.playGame.hood.fsm.getCurrentState().getName() requestStatus['avId'] = base.localAvatar.doId self.acceptOnce('DistributedDoor_localAvatarWentInDoor', self.handleDoorInDone, [requestStatus]) self.acceptOnce('DistributedDoor_localAvatarGoingInDoor', base.transitions.irisOut) return def exitDoorIn(self): base.localAvatar.detachCamera() self.ignore('DistributedDoor_localAvatarWentInDoor') self.ignore('DistributedDoor_localAvatarGoingInDoor') def handleDoorInDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def __waitOnDoor(self, door, task): if door.ready: self.__doorReady(door) return task.done return task.cont def enterDoorOut(self, requestStatus): base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.d_clearSmoothing() base.localAvatar.stopPosHprBroadcast() base.localAvatar.walkControls.setCollisionsActive(0) block = requestStatus['block'] zoneId = requestStatus['zoneId'] doorIndex = requestStatus['doorIndex'] doorToExitFrom = None for door in base.cr.doFindAll('DistributedDoor'): if door.zoneId == zoneId: if door.getBlock() == block: if door.getDoorIndex() == doorIndex: doorToExitFrom = door break if not doorToExitFrom: self.notify.error('Could not find a DistributedDoor to exit from!') elif not doorToExitFrom.ready: base.taskMgr.add(self.__waitOnDoor, 'Place.waitOnDoor', extraArgs=[doorToExitFrom], appendTask=True) return self.__doorReady(doorToExitFrom) return def __doorReady(self, door): door.sendUpdate('requestExit', []) self.nextState = 'walk' self.acceptOnce('DistributedDoor_localAvatarCameOutOfDoor', self.handleDoorOutDone) def exitDoorOut(self): base.taskMgr.remove('Place.waitOnDoor') base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() self.ignore('DistributedDoor_localAvatarCameOutOfDoor') def handleDoorOutDone(self): base.transitions.irisIn() base.localAvatar.walkControls.setCollisionsActive(1) self.fsm.request(self.nextState) def enterShtickerBook(self): base.localAvatar.attachCamera() base.localAvatar.createLaffMeter() base.localAvatar.startSmartCamera() base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.b_setAnimState('openBook', self.enterShtickerBookGui) def enterShtickerBookGui(self): doneEvent = 'shtickerBookDone' self.shtickerBookStateData = ShtickerBook(self.fsm, doneEvent) self.acceptOnce(doneEvent, self.__shtickerBookDone) self.shtickerBookStateData.load() self.shtickerBookStateData.enter() base.localAvatar.showBookButton(1) base.localAvatar.b_setAnimState('readBook') def __shtickerBookDone(self): doneStatus = self.shtickerBookStateData.getDoneStatus() base.localAvatar.hideBookButton() self.shtickerBookStateData.exit() if doneStatus['mode'] == 'exit': base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseExit) elif doneStatus['mode'] == 'teleport': base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseTeleport, [doneStatus]) elif doneStatus['mode'] == 'resume': base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseResume) elif doneStatus['mode'] == 'switchShard': base.localAvatar.b_setAnimState('closeBook', self.__handleBookCloseSwitchShard, [doneStatus]) def __handleBookCloseSwitchShard(self, requestStatus): base.localAvatar.b_setAnimState('teleportOut', self.__handleBookSwitchShard, [requestStatus]) def __handleBookSwitchShard(self, requestStatus): params = [] params.append(requestStatus['shardId']) params.append(base.cr.playGame.hood.id) params.append(ZoneUtil.getZoneId(base.cr.playGame.hood.id)) params.append(base.localAvatar.doId) base.cr.gameFSM.request('switchShards', params) def __handleBookCloseResume(self): self.fsm.request('walk') def __handleBookCloseTeleport(self, requestStatus): self.fsm.request('teleportOut', [requestStatus]) def __teleportOutDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def __handleBookCloseExit(self): base.localAvatar.b_setAnimState('teleportOut', self.__handleBookExitTeleport) def __handleBookExitTeleport(self): base.transitions.fadeOut(0.0) base.cr.gameFSM.request('closeShard') def exitShtickerBook(self): base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.disableLaffMeter() self.ignore(self.shtickerBookStateData.doneEvent) self.shtickerBookStateData.exit() self.shtickerBookStateData.unload() del self.shtickerBookStateData base.localAvatar.hideBookButton() def enterStop(self, doNeutral = 1): if doNeutral: base.localAvatar.b_setAnimState('neutral') base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.createLaffMeter() base.localAvatar.createMoney() base.localAvatar.enablePies(0) def exitStop(self): base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() base.localAvatar.disableLaffMeter() base.localAvatar.disableMoney() base.localAvatar.disablePies() def load(self): StateData.load(self) self.walkDoneEvent = 'walkDone' self.walkStateData = PublicWalk(self.fsm, self.walkDoneEvent) self.walkStateData.load() def unload(self): StateData.unload(self) del self.walkDoneEvent self.walkStateData.unload() del self.walkStateData del self.loader def enterTeleportIn(self, requestStatus): if requestStatus['avId'] != base.localAvatar.doId: av = base.cr.doId2do.get(requestStatus['avId']) if av: base.localAvatar.gotoNode(av) base.localAvatar.b_setChat('Hi, %s.' % av.getName()) base.transitions.irisIn() self.nextState = requestStatus.get('nextState', 'walk') base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.startPosHprBroadcast() globalClock.tick() base.localAvatar.b_setAnimState('teleportIn', callback=self.teleportInDone) base.localAvatar.d_broadcastPositionNow() base.localAvatar.b_setParent(CIGlobals.SPRender) def exitTeleportIn(self): base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() base.localAvatar.stopPosHprBroadcast() def teleportInDone(self): if hasattr(self, 'fsm'): self.fsm.request(self.nextState, [1]) def enterAcknowledgeDeath(self, foo = 0): base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() message = 'You were defeated by the Cogs! Collect treasures in the Playground to refill your Laff meter.' self.dialog = GlobalDialog(message=message, style=3, doneEvent='ackDeathDone') self.dialog.show() self.acceptOnce('ackDeathDone', self.handleAckDeathDone) def handleAckDeathDone(self): self.fsm.request('walk', [1]) def exitAcknowledgeDeath(self): self.ignore('ackDeathDone') self.dialog.cleanup() del self.dialog base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() def enterDied(self, requestStatus, callback = None): if callback == None: callback = self.__diedDone base.localAvatar.createLaffMeter() base.localAvatar.attachCamera() base.localAvatar.b_setAnimState('died', callback, [requestStatus]) return def __diedDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def exitDied(self): base.localAvatar.disableLaffMeter() base.localAvatar.detachCamera() def enterWalk(self, teleportIn = 0): self.walkStateData.enter() if teleportIn == 0: self.walkStateData.fsm.request('walking') self.acceptOnce(self.walkDoneEvent, self.handleWalkDone) self.walkStateData.fsm.request('walking') self.watchTunnelSeq = Sequence(Wait(1.0), Func(LinkTunnel.globalAcceptCollisions)) self.watchTunnelSeq.start() base.localAvatar.setBusy(0) base.localAvatar.enablePicking() base.localAvatar.showFriendButton() def exitWalk(self): self.walkStateData.exit() self.ignore(self.walkDoneEvent) if base.cr.playGame.hood.titleText != None: base.cr.playGame.hood.hideTitleText() self.watchTunnelSeq.pause() del self.watchTunnelSeq base.localAvatar.setBusy(1) base.localAvatar.disablePicking() base.localAvatar.hideFriendButton() base.localAvatar.friendsList.fsm.requestFinalState() base.localAvatar.panel.fsm.requestFinalState() return def handleWalkDone(self, doneStatus): pass def enterTeleportOut(self, requestStatus, callback = None): if not callback: callback = self.__teleportOutDone base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.b_setAnimState('teleportOut', callback, [requestStatus]) def exitTeleportOut(self): base.localAvatar.disableLaffMeter() base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() base.localAvatar.stopPosHprBroadcast() def enterTunnelIn(self, linkTunnel): base.localAvatar.attachCamera() base.localAvatar.playMovementSfx('run') pivotPoint = linkTunnel.inPivotPoint self.pivotPointNode = linkTunnel.tunnel.attachNewNode('tunnelPivotPoint') self.pivotPointNode.setPos(pivotPoint) currCamPos = camera.getPos(linkTunnel.tunnel) currCamHpr = camera.getHpr(linkTunnel.tunnel) currPos = base.localAvatar.getPos(self.pivotPointNode) currHpr = base.localAvatar.getHpr(self.pivotPointNode) if linkTunnel.__class__.__name__ == 'SafeZoneLinkTunnel': base.localAvatar.setHpr(180, 0, 0) else: base.localAvatar.setHpr(0, 0, 0) base.localAvatar.setPos(currPos) base.localAvatar.reparentTo(self.pivotPointNode) base.localAvatar.walkControls.setCollisionsActive(0) base.localAvatar.detachCamera() camera.reparentTo(linkTunnel.tunnel) tunnelCamPos = linkTunnel.camPos tunnelCamHpr = linkTunnel.camHpr self.track = Parallel(LerpPosInterval(camera, duration=0.7, pos=tunnelCamPos, startPos=currCamPos, blendType='easeOut'), LerpQuatInterval(camera, duration=0.7, quat=tunnelCamHpr, startHpr=currCamHpr, blendType='easeOut'), Sequence(Func(base.localAvatar.b_setAnimState, 'run'), Wait(2.0), Func(base.transitions.irisOut)), Sequence(LerpHprInterval(self.pivotPointNode, duration=2.0, hpr=linkTunnel.inPivotEndHpr, startHpr=linkTunnel.inPivotStartHpr), LerpPosInterval(self.pivotPointNode, duration=1.0, pos=(linkTunnel.inPivotEndX, self.pivotPointNode.getY(), self.pivotPointNode.getZ()), startPos=(linkTunnel.inPivotStartX, self.pivotPointNode.getY(), self.pivotPointNode.getZ()))), name='Place.enterTunnelIn') requestStatus = {} requestStatus['zoneId'] = linkTunnel.data['zoneId'] if linkTunnel.__class__.__name__ == 'SafeZoneLinkTunnel': requestStatus['where'] = 'street' requestStatus['loader'] = 'townLoader' requestStatus['hoodId'] = base.cr.playGame.hood.id requestStatus['shardId'] = None requestStatus['avId'] = base.localAvatar.doId requestStatus['how'] = 'tunnelOut' requestStatus['fromZone'] = base.localAvatar.zoneId elif linkTunnel.__class__.__name__ == 'StreetLinkTunnel': requestStatus['where'] = 'playground' requestStatus['loader'] = 'safeZoneLoader' requestStatus['hoodId'] = base.cr.playGame.hood.id requestStatus['shardId'] = None requestStatus['avId'] = base.localAvatar.doId requestStatus['how'] = 'tunnelOut' requestStatus['fromZone'] = base.localAvatar.zoneId elif linkTunnel.__class__.__name__ == 'NeighborhoodLinkTunnel': requestStatus['where'] = 'street' requestStatus['loader'] = 'townLoader' hoodId = ZoneUtil.getHoodId(linkTunnel.data['zoneId'], 1) requestStatus['hoodId'] = hoodId requestStatus['shardId'] = None requestStatus['avId'] = base.localAvatar.doId requestStatus['how'] = 'tunnelOut' requestStatus['fromZone'] = base.localAvatar.zoneId self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__handleTunnelInDone, [requestStatus]) self.track.start() return def __handleTunnelInDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def exitTunnelIn(self): base.localAvatar.playMovementSfx(None) if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None base.localAvatar.reparentTo(render) self.pivotPointNode.removeNode() del self.pivotPointNode base.localAvatar.detachCamera() base.localAvatar.walkControls.setCollisionsActive(1) return def enterTunnelOut(self, requestStatus): base.localAvatar.playMovementSfx('run') base.transitions.irisIn() self.nextState = requestStatus.get('nextState', 'walk') linkTunnel = LinkTunnel.getTunnelThatGoesToZone(requestStatus['fromZone']) pivotPoint = linkTunnel.outPivotPoint self.pivotPointNode = linkTunnel.tunnel.attachNewNode('tunnelPivotPoint') self.pivotPointNode.setPos(pivotPoint) self.pivotPointNode.setHpr(linkTunnel.outPivotStartHpr) base.localAvatar.walkControls.setCollisionsActive(0) base.localAvatar.reparentTo(self.pivotPointNode) base.localAvatar.setHpr(linkTunnel.toonOutHpr) base.localAvatar.setPos(linkTunnel.toonOutPos) base.localAvatar.detachCamera() camera.reparentTo(linkTunnel.tunnel) tunnelCamPos = linkTunnel.camPos tunnelCamHpr = linkTunnel.camHpr camera.setPos(tunnelCamPos) camera.setHpr(tunnelCamHpr) self.track = Parallel(Sequence(Func(base.localAvatar.b_setAnimState, 'run'), LerpPosInterval(self.pivotPointNode, duration=1.0, pos=(linkTunnel.outPivotEndX, self.pivotPointNode.getY(), self.pivotPointNode.getZ()), startPos=(linkTunnel.outPivotStartX, self.pivotPointNode.getY(), self.pivotPointNode.getZ())), LerpHprInterval(self.pivotPointNode, duration=2.0, hpr=linkTunnel.outPivotEndHpr, startHpr=linkTunnel.outPivotStartHpr)), name='Place.enterTunnelOut') self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self.__handleTunnelOutDone) self.track.start() def __handleTunnelOutDone(self): base.localAvatar.walkControls.setCollisionsActive(1) self.fsm.request(self.nextState) def exitTunnelOut(self): base.localAvatar.playMovementSfx(None) base.localAvatar.walkControls.setCollisionsActive(1) if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None base.localAvatar.setPos(base.localAvatar.getPos(render)) base.localAvatar.setHpr(base.localAvatar.getHpr(render)) base.localAvatar.reparentTo(render) self.pivotPointNode.removeNode() del self.pivotPointNode base.localAvatar.detachCamera() del self.nextState return
class DistributedPlayerToon(DistributedToon, DistributedPlayerToonShared): notify = directNotify.newCategory('DistributedPlayerToon') def __init__(self, cr): try: self.DistributedPlayerToon_initialized return except: self.DistributedPlayerToon_initialized = 1 DistributedToon.__init__(self, cr) DistributedPlayerToonShared.__init__(self) self.role = None self.ghost = 0 self.puInventory = [] self.equippedPU = -1 self.backpack = Backpack(self) self.battleMeter = None self.headMeter = None self.firstTimeChangingHP = True # Quest-related variables. self.quests = "" self.tier = None self.questHistory = None self.busy = 1 self.friends = None self.tutDone = 0 self.hoodsDiscovered = [] self.teleportAccess = [] self.lastHood = 0 self.defaultShard = 0 self.tunnelTrack = None self.trackExperience = dict(GagGlobals.DefaultTrackExperiences) self.takeDmgSfx = base.audio3d.loadSfx( 'phase_5/audio/sfx/tt_s_ara_cfg_toonHit.ogg') base.audio3d.attachSoundToObject(self.takeDmgSfx, self) return def getHealth(self): return DistributedPlayerToonShared.getHealth(self) def getMaxHealth(self): return DistributedPlayerToonShared.getMaxHealth(self) def stopSmooth(self): DistributedToon.stopSmooth(self) localAvatarReachable = (hasattr(base, 'localAvatar') and base.localAvatar) if localAvatarReachable and self.doId != base.localAvatar.doId: self.resetTorsoRotation() def handleHealthChange(self, hp, oldHp): if hp < oldHp and not self.firstTimeChangingHP: # We took damage, make oof sound. self.takeDmgSfx.play() def setHealth(self, health): self.handleHealthChange(health, self.getHealth()) DistributedToon.setHealth(self, health) if self.doId != base.localAvatar.doId: if not self.firstTimeChangingHP: if health < self.getMaxHealth(): if not self.headMeter: self.__makeHeadMeter() else: self.__updateHeadMeter() else: self.__removeHeadMeter() self.firstTimeChangingHP = False def announceHealthAndPlaySound(self, level, hp, extraId=-1): DistributedToon.announceHealth(self, level, hp, extraId) hpSfx = base.audio3d.loadSfx('phase_11/audio/sfx/LB_toonup.ogg') base.audio3d.attachSoundToObject(hpSfx, self) SoundInterval(hpSfx, node=self).start() del hpSfx def setChat(self, chat): chat = ChatGlobals.filterChat(chat, self.animal) DistributedToon.setChat(self, chat) def goThroughTunnel(self, toZone, inOrOut, requestStatus=None): # inOrOut: 0 = in; 1 = out if self.tunnelTrack: self.ignore(self.tunnelTrack.getDoneEvent()) self.tunnelTrack.finish() self.tunnelTrack = None linkTunnel = LinkTunnel.getTunnelThatGoesToZone(toZone) if not linkTunnel: return self.tunnelTrack = Parallel( name=self.uniqueName('Place.goThroughTunnel')) if inOrOut == 0: # Going in a tunnel! pivotPoint = linkTunnel.inPivotPoint pivotPointNode = linkTunnel.tunnel.attachNewNode( 'tunnelPivotPoint') pivotPointNode.setPos(pivotPoint) pivotPointNode.setHpr(linkTunnel.inPivotStartHpr) x, y, z = self.getPos(render) surfZ = PhysicsUtils.getNearestGroundSurfaceZ( self, self.getHeight() + self.getHeight() / 2.0) if not surfZ == -1: # Let's use the ray-tested surface z-point instead so we don't come out of the tunnel hovering. # This is just in case the user jumped into the tunnel, which in that case would mean that they are # airborne and we can't depend on their current Z value. z = surfZ if base.localAvatar.doId == self.doId: doneMethod = self._handleWentInTunnel extraArgs = [requestStatus] base.localAvatar.walkControls.setCollisionsActive( 0, andPlaceOnGround=1) self.resetHeadHpr(override=True) camera.wrtReparentTo(linkTunnel.tunnel) currCamPos = camera.getPos() currCamHpr = camera.getHpr() tunnelCamPos = linkTunnel.camPos tunnelCamHpr = linkTunnel.camHpr camera.setPos(tunnelCamPos) camera.setHpr(tunnelCamHpr) self.tunnelTrack.append( LerpPosInterval(camera, duration=0.7, pos=tunnelCamPos, startPos=currCamPos, blendType='easeOut')) self.tunnelTrack.append( LerpQuatInterval(camera, duration=0.7, quat=tunnelCamHpr, startHpr=currCamHpr, blendType='easeOut')) self.wrtReparentTo(pivotPointNode) self.setPos(x, y, z) self.resetTorsoRotation() self.stopLookAround() if linkTunnel.__class__.__name__ == "SafeZoneLinkTunnel": self.setHpr(180, 0, 0) else: self.setHpr(0, 0, 0) exitSeq = Sequence(Func(self.loop, 'run')) if base.localAvatar.doId == self.doId: exitSeq.append(Wait(2.0)) exitSeq.append(Func(base.transitions.irisOut)) self.tunnelTrack.append(exitSeq) self.tunnelTrack.append( Sequence( LerpHprInterval( pivotPointNode, duration=2.0, hpr=linkTunnel.inPivotEndHpr, startHpr=linkTunnel.inPivotStartHpr, ), LerpPosInterval(pivotPointNode, duration=1.0, pos=(linkTunnel.inPivotEndX, pivotPointNode.getY(), pivotPointNode.getZ()), startPos=(linkTunnel.inPivotStartX, pivotPointNode.getY(), pivotPointNode.getZ())), Func(self.reparentTo, hidden))) elif inOrOut == 1: # Going out! pivotPoint = linkTunnel.outPivotPoint pivotPointNode = linkTunnel.tunnel.attachNewNode( 'tunnelPivotPoint') pivotPointNode.setPos(pivotPoint) pivotPointNode.setHpr(linkTunnel.outPivotStartHpr) exitSeq = Sequence() if base.localAvatar.doId == self.doId: base.localAvatar.walkControls.setCollisionsActive( 0, andPlaceOnGround=1) base.localAvatar.detachCamera() camera.reparentTo(linkTunnel.tunnel) tunnelCamPos = linkTunnel.camPos tunnelCamHpr = linkTunnel.camHpr camera.setPos(tunnelCamPos) camera.setHpr(tunnelCamHpr) doneMethod = self._handleCameOutTunnel extraArgs = [] exitSeq.append(Func(base.transitions.irisIn)) else: self.stopSmooth() self.reparentTo(pivotPointNode) self.setHpr(linkTunnel.toonOutHpr) self.setPos(linkTunnel.toonOutPos) seq = Sequence( Func(self.loop, 'run'), LerpPosInterval(pivotPointNode, duration=1.0, pos=(linkTunnel.outPivotEndX, pivotPointNode.getY(), pivotPointNode.getZ()), startPos=(linkTunnel.outPivotStartX, pivotPointNode.getY(), pivotPointNode.getZ())), LerpHprInterval( pivotPointNode, duration=2.0, hpr=linkTunnel.outPivotEndHpr, startHpr=linkTunnel.outPivotStartHpr, )) if base.localAvatar.doId != self.doId: seq.append(Func(self.startSmooth)) seq.append(Func(self.wrtReparentTo, render)) exitSeq.append(seq) self.tunnelTrack.append(exitSeq) if base.localAvatar.doId == self.doId: self.tunnelTrack.setDoneEvent(self.tunnelTrack.getName()) self.acceptOnce(self.tunnelTrack.getDoneEvent(), doneMethod, extraArgs) self.tunnelTrack.start() def setDefaultShard(self, shardId): self.defaultShard = shardId def getDefaultShard(self): return self.defaultShard def setLastHood(self, zoneId): self.lastHood = zoneId def b_setLastHood(self, zoneId): self.sendUpdate('setLastHood', [zoneId]) self.setLastHood(zoneId) def getLastHood(self): return self.lastHood def setTeleportAccess(self, array): self.teleportAccess = array def getTeleportAccess(self): return self.teleportAccess def setHoodsDiscovered(self, array): self.hoodsDiscovered = array def b_setHoodsDiscovered(self, array): self.sendUpdate('setHoodsDiscovered', [array]) self.setHoodsDiscovered(array) def getHoodsDiscovered(self): return self.hoodsDiscovered def setTutorialCompleted(self, value): self.tutDone = value def getTutorialCompleted(self): return self.tutDone def setFriendsList(self, friends): self.friends = friends def getFriendsList(self): return self.friends def setBusy(self, busy): self.busy = busy def getBusy(self): return self.busy def setTier(self, tier): self.tier = tier def getTier(self): return self.tier def setQuestHistory(self, array): self.questHistory = array def getQuestHistory(self): return self.questHistory def setQuests(self, dataStr): self.quests = dataStr def getQuests(self): return self.quests def maybeMakeHeadMeter(self): if base.localAvatar.doId != self.doId: if self.getHealth() < self.getMaxHealth(): if not self.headMeter: self.__makeHeadMeter() def __makeHeadMeter(self): self.headMeter = LaffOMeter(forRender=True) r, g, b, _ = self.getHeadColor() animal = self.getAnimal() maxHp = self.getMaxHealth() hp = self.getHealth() self.headMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp) self.headMeter.reparentTo(self) self.headMeter.setZ(self.getHeight() + 2) self.headMeter.setScale(0.4) self.headMeter.setBillboardAxis() self.__updateHeadMeter() def __removeHeadMeter(self): if self.headMeter: self.headMeter.disable() self.headMeter.delete() self.headMeter = None def __updateHeadMeter(self): if self.headMeter: self.headMeter.updateMeter(self.getHealth()) def d_createBattleMeter(self): self.sendUpdate('makeBattleMeter', []) def b_createBattleMeter(self): self.makeBattleMeter() self.d_createBattleMeter() def d_cleanupBattleMeter(self): self.sendUpdate('destroyBattleMeter', []) def b_cleanupBattleMeter(self): self.destroyBattleMeter() self.d_cleanupBattleMeter() def makeBattleMeter(self): if self.getHealth() < self.getMaxHealth(): if not self.battleMeter: self.battleMeter = LaffOMeter() r, g, b, _ = self.getHeadColor() animal = self.getAnimal() maxHp = self.getMaxHealth() hp = self.getHealth() self.battleMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp) self.battleMeter.reparentTo(self) self.battleMeter.setZ(self.getHeight() + 5) self.battleMeter.setScale(0.5) self.battleMeter.start() def destroyBattleMeter(self): if self.battleMeter: self.battleMeter.stop() self.battleMeter.disable() self.battleMeter.delete() self.battleMeter = None def setEquippedPU(self, index): self.equippedPU = index def getEquippedPU(self): return self.equippedPU def setPUInventory(self, array): self.puInventory = array def getPUInventory(self): return self.puInventory def setGhost(self, value): self.ghost = value self.handleGhost(value) def d_setGhost(self, value): self.sendUpdate("setGhost", [value]) def b_setGhost(self, value): self.d_setGhost(value) self.setGhost(value) def getGhost(self): return self.ghost def getBackpack(self): return self.backpack def setEquippedAttack(self, attackID): try: self.backpack.setCurrentGag(attackID) except: # If we couldn't do this, it means that the avatar was most likely disabled. pass DistributedToon.setEquippedAttack(self, attackID) def getCurrentGag(self): return self.getEquippedAttack() def setLoadout(self, gagIds): if self.backpack: loadout = [] for i in range(len(gagIds)): gagId = gagIds[i] gag = self.backpack.getGagByID(gagId) if gag: loadout.append(gag) self.backpack.setLoadout(loadout) def setBackpackAmmo(self, netString): if len(self.attackIds) != 0 or len(self.attacks) != 0: self.cleanupAttacks() self.clearAttackIds() return self.backpack.updateSuppliesFromNetString(netString) def getBackpackAmmo(self): if self.backpack: return self.backpack.netString return GagGlobals.getDefaultBackpack().toNetString() def setTrackExperience(self, netString): self.trackExperience = GagGlobals.getTrackExperienceFromNetString( netString) if GagGlobals.processTrackData( self.trackExperience, self.backpack) and self == base.localAvatar: if base.localAvatar.invGui: base.localAvatar.reloadInvGui() def getTrackExperience(self): return GagGlobals.trackExperienceToNetString(self.trackExperience) def updateAttackAmmo(self, gagId, ammo, maxAmmo, ammo2, maxAmmo2, clip, maxClip): if self.useBackpack(): self.backpack.setSupply(gagId, ammo) else: DistributedToon.updateAttackAmmo(self, gagId, ammo, maxAmmo, ammo2, maxAmmo2, clip, maxClip) def setMoney(self, money): self.money = money def getMoney(self): return self.money def setAccessLevel(self, value): prevLevel = self.getAccessLevel() self.role = AdminCommands.Roles.get(value, None) if prevLevel != AdminCommands.NoAccess: # Let's remove any tokens that already are showing up. DistributedToon.removeAdminToken(self) if self.role: # Let's put a new token above our head. DistributedToon.setAdminToken(self, self.role.token) def getAccessLevel(self): return AdminCommands.NoAccess if not self.role else self.role.accessLevel def disable(self): base.audio3d.detachSound(self.takeDmgSfx) self.takeDmgSfx = None if self.tunnelTrack: self.ignore(self.tunnelTrack.getDoneEvent()) self.tunnelTrack.finish() self.tunnelTrack = None self.role = None self.ghost = None self.puInventory = None self.equippedPU = None if self.backpack: self.backpack.cleanup() self.backpack = None self.firstTimeChangingHP = None self.quests = None self.tier = None self.questHistory = None self.busy = None self.friends = None self.tutDone = None self.hoodsDiscovered = None self.teleportAccess = None self.lastHood = None self.defaultShard = None self.trackExperience = None self.__removeHeadMeter() self.destroyBattleMeter() DistributedToon.disable(self) def delete(self): try: self.DistributedPlayerToon_deleted except: self.DistributedPlayerToon_deleted = 1 DistributedPlayerToonShared.delete(self) del self.takeDmgSfx del self.tunnelTrack del self.role del self.ghost del self.puInventory del self.equippedPU del self.backpack del self.firstTimeChangingHP del self.quests del self.tier del self.questHistory del self.busy del self.friends del self.tutDone del self.hoodsDiscovered del self.teleportAccess del self.lastHood del self.defaultShard del self.trackExperience del self.battleMeter del self.headMeter DistributedToon.delete(self) return
class ParticleAttack(Attack): notify = directNotify.newCategory('ParticleAttack') attack = 'particleattack' particleIvalDur = 1 shooterDistance = 50 def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.particles = [] self.handObj = None self.shootOutCollNP = None self.particleSound = None self.particleMoveIval = None self.targetX = None self.targetY = None self.targetZ = None return def handleWeaponTouch(self): pass def handleCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) def doAttack(self, particlePaths, track_name, particleCollId, animation_name, delayUntilRelease, animationSpeed = 1, handObjPath = None, handObjParent = None, startRightAway = True, ts = 0): for path in particlePaths: particle = ParticleLoader.loadParticleEffect(path) self.particles.append(particle) sphere = CollisionSphere(0, 0, 0, 1) sphere.setTangible(0) node = CollisionNode(particleCollId) node.addSolid(sphere) node.setCollideMask(CIGlobals.WallBitmask) self.targetX = self.attacksClass.target.getX(render) self.targetY = self.attacksClass.target.getY(render) self.targetZ = self.attacksClass.target.getZ(render) if len(self.particles) == 1: self.shootOutCollNP = self.particles[0].attachNewNode(node) else: self.shootOutCollNP = self.suit.attachNewNode(node) if handObjPath and handObjParent: self.handObj = loader.loadModel(handObjPath) self.handObj.reparentTo(handObjParent) self.suit.setPlayRate(animationSpeed, animation_name) self.suit.play(animation_name) if hasattr(self.suit, 'uniqueName'): track_name = self.suit.uniqueName(track_name) particleCollId = self.suit.uniqueName(particleCollId) self.suitTrack = Parallel(ActorInterval(self.suit, animation_name), name=track_name) seq = Sequence() seq.append(Wait(delayUntilRelease)) seq.append(Func(self.releaseAttack)) seq.append(Wait(self.particleIvalDur)) seq.setDoneEvent(self.suitTrack.getName()) self.suitTrack.append(seq) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) if startRightAway: self.suitTrack.start(ts) 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 def playParticleSound(self): if self.particleSound: base.audio3d.attachSoundToObject(self.particleSound, self.suit) base.playSfx(self.particleSound) def cleanup(self): Attack.cleanup(self) self.targetX = None self.targetY = None self.targetZ = None if self.particles: for particle in self.particles: particle.cleanup() self.particles = None if self.handObj: self.handObj.removeNode() self.handObj = None if self.shootOutCollNP: self.ignore('enter' + self.shootOutCollNP.node().getName()) self.shootOutCollNP.removeNode() self.shootOutCollNP = None if self.particleMoveIval: self.particleMoveIval.pause() self.particleMoveIval = None self.particleSound = None self.particleIvalDur = None return
class DistributedDodgeballGame(DistributedToonFPSGame, TeamMinigame): """The winter dodgeball minigame (client side)""" notify = directNotify.newCategory("DistributedDodgeballGame") TreeData = [['prop_snow_tree_small_ur', Point3(23.23, 66.52, 7.46)], ['prop_snow_tree_small_ul', Point3(-34.03, 88.02, 24.17)], ['prop_snow_tree_small_ur', Point3(-54.80, 0, 4.19)], ['prop_snow_tree_small_ul', Point3(54.80, -5, 4.19)], ['prop_snow_tree_small_ur', Point3(62.71, 62.66, 16.80)], ['prop_snow_tree_small_ul', Point3(-23.23, -66.52, 6)], ['prop_snow_tree_small_ur', Point3(34.03, -88.02, 23)], ['prop_snow_tree_small_ul', Point3(-62.71, -62.66, 16)]] SnowballData = [Point3(30, 0, 0.75), Point3(22.5, 0, 0.75), Point3(15, 0, 0.75), Point3(7.5, 0, 0.75), Point3(0, 0, 0.75), Point3(-7.5, 0, 0.75), Point3(-15, 0, 0.75), Point3(-22.5, 0, 0.75), Point3(-30, 0, 0.75)] GameSong = "phase_4/audio/bgm/MG_Dodgeball.ogg" GameDesc = ("Welcome to the north! You have been invited to play dodgeball with the penguins!\n\n" "How To Play\nWASD to Move and use the mouse to aim.\nLeft click to Throw!\nRight click" " to Catch!\n\nObjective\nThe first team to get everyone out wins!") InitCamTrans = [Point3(25, 45, 19.5317), Vec3(154.001, -15, 0)] SnowBallDmg = 25 GetSnowBalls = "Pick up a snowball from the center!" def __init__(self, cr): try: self.DistributedDodgeballGame_initialized return except: self.DistributedDodgeballGame_initialized = 1 DistributedToonFPSGame.__init__(self, cr) TeamMinigame.__init__(self, "BlueSnow", ('phase_4/maps/db_blue_neutral.png', 'phase_4/maps/db_blue_hover.png', 'phase_4/maps/db_blue_hover.png'), "RedIce", ('phase_4/maps/db_red_neutral.png', 'phase_4/maps/db_red_hover.png', 'phase_4/maps/db_red_hover.png')) self.fsm.addState(State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam, ['waitForOthers'])) self.fsm.addState(State('scrollBy', self.enterScrollBy, self.exitScrollBy, ['countdown'])) self.fsm.addState(State('countdown', self.enterCountdown, self.exitCountdown, ['play'])) self.fsm.getStateNamed('waitForOthers').addTransition('chooseTeam') self.fsm.getStateNamed('waitForOthers').addTransition('scrollBy') self.firstPerson = DodgeballFirstPerson(self) self.scrollBySeq = None self.infoText = None self.infoText = getAlertText() self.spawnPointsByTeam = { BLUE: [ [Point3(5, 15, 0), Vec3(180, 0, 0)], [Point3(15, 15, 0), Vec3(180, 0, 0)], [Point3(-5, 15, 0), Vec3(180, 0, 0)], [Point3(-15, 15, 0), Vec3(180, 0, 0)]], RED: [ [Point3(5, -15, 0), Vec3(0, 0, 0)], [Point3(15, -15, 0), Vec3(0, 0, 0)], [Point3(-5, -15, 0), Vec3(0, 0, 0)], [Point3(-15, -15, 0), Vec3(0, 0, 0)]]} # Environment vars self.sky = None self.arena = None self.fog = None self.snow = None self.snowRender = None self.trees = [] self.snowballs = [] def snowballHitWall(self, snowballIndex): snowball = self.snowballs[snowballIndex] snowball.handleHitWallOrPlayer() def snowballHitPlayer(self, damagedPlayer, snowballIndex): av = self.getRemoteAvatar(damagedPlayer) if av: print "setting health" av.setHealth(av.health - DistributedDodgeballGame.SnowBallDmg) if damagedPlayer == base.localAvatar.doId: self.showAlert("You were hit by a snowball!") snowball = self.snowballs[snowballIndex] snowball.handleHitWallOrPlayer() def playerCaughtSnowball(self, snowballIndex, catcherId): av = self.getRemoteAvatar(catcherId) if av: snowball = self.snowballs[snowballIndex] snowball.pauseThrowIval() snowball.pickup(av) def setupRemoteAvatar(self, avId): av = RemoteDodgeballAvatar(self, self.cr, avId) if avId == self.cr.localAvId: self.myRemoteAvatar = av print "setup remove avatar {0}".format(avId) self.remoteAvatars.append(av) def __getSnowTree(self, path): trees = loader.loadModel('phase_8/models/props/snow_trees.bam') tree = trees.find('**/' + path) tree.find('**/*shadow*').removeNode() return tree def load(self): self.setMinigameMusic(DistributedDodgeballGame.GameSong) self.setDescription(DistributedDodgeballGame.GameDesc) self.createWorld() trans = DistributedDodgeballGame.InitCamTrans camera.setPos(trans[0]) camera.setHpr(trans[1]) DistributedToonFPSGame.load(self) def createWorld(self): self.deleteWorld() self.sky = loader.loadModel("phase_3.5/models/props/BR_sky.bam") self.sky.reparentTo(render) self.sky.setZ(-40) self.sky.setFogOff() self.arena = loader.loadModel("phase_4/models/minigames/dodgeball_arena.egg") self.arena.reparentTo(render) self.arena.setScale(0.75) self.arena.find('**/team_divider').setBin('ground', 18) self.arena.find('**/floor').setBin('ground', 18) self.arena.find('**/team_divider_coll').setCollideMask(CIGlobals.FloorBitmask) for data in DistributedDodgeballGame.TreeData: code = data[0] pos = data[1] tree = self.__getSnowTree(code) tree.reparentTo(self.arena) tree.setPos(pos) self.trees.append(tree) for i in xrange(len(DistributedDodgeballGame.SnowballData)): snowdata = DistributedDodgeballGame.SnowballData[i] snowball = Snowball(self, i) snowball.load() snowball.reparentTo(render) snowball.setPos(snowdata) self.snowballs.append(snowball) self.snow = ParticleLoader.loadParticleEffect('phase_8/etc/snowdisk.ptf') self.snow.setPos(0, 0, 5) self.snowRender = self.arena.attachNewNode('snowRender') self.snowRender.setDepthWrite(0) self.snowRender.setBin('fixed', 1) self.snow.start(camera, self.snowRender) self.fog = Fog('snowFog') self.fog.setColor(0.486, 0.784, 1) self.fog.setExpDensity(0.003) render.setFog(self.fog) def throw(self, snowballIndex, p): snowball = self.snowballs[snowballIndex] snowball.throw(p) def snowballPickup(self, snowballIndex, pickerUpperAvId): remoteAv = self.getRemoteAvatar(pickerUpperAvId) if remoteAv: snowball = self.snowballs[snowballIndex] snowball.pickup(remoteAv) def deleteWorld(self): for snowball in self.snowballs: snowball.removeNode() self.snowballs = [] for tree in self.trees: tree.removeNode() self.trees = [] if self.snow: self.snow.cleanup() self.snow = None if self.snowRender: self.snowRender.removeNode() self.snowRender = None self.fog = None if self.sky: self.sky.removeNode() self.sky = None if self.arena: self.arena.removeNode() self.arena = None render.clearFog() def enterPlay(self): self.firstPerson.reallyStart() def exitPlay(self): self.firstPerson.end() def enterCountdown(self): self.firstPerson.start() self.firstPerson.disableMouse() self.infoText.setText(DistributedDodgeballGame.GetSnowBalls) self.countdownText = getGameText() self.countdownIval = Parallel( Sequence( Func(self.countdownText.setText, "5"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "4"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "3"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "2"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "1"), getCountdownIval(self.countdownText)), getAlertPulse(self.infoText), name = "COUNTDOWNIVAL") self.countdownIval.setDoneEvent(self.countdownIval.getName()) self.acceptOnce(self.countdownIval.getDoneEvent(), self.__handleCountdownDone) self.countdownIval.start() def __handleCountdownDone(self): self.fsm.request('play') def exitCountdown(self): if hasattr(self, 'countdownText'): self.countdownText.destroy() del self.countdownText if hasattr(self, 'countdownIval'): self.ignore(self.countdownIval.getDoneEvent()) self.countdownIval.finish() del self.countdownIval def enterScrollBy(self): BLUE_START_POS = Point3(-20, 0, 4) BLUE_END_POS = Point3(20, 0, 4) BLUE_HPR = Vec3(0, 0, 0) RED_START_POS = Point3(20, 0, 4) RED_END_POS = Point3(-20, 0, 4) RED_HPR = Vec3(180, 0, 0) self.playMinigameMusic() self.scrollBySeq = Sequence( Func(camera.setHpr, BLUE_HPR), LerpPosInterval( camera, duration = 5.0, pos = BLUE_END_POS, startPos = BLUE_START_POS, blendType = 'easeOut'), Func(base.transitions.fadeOut, 0.4), Wait(0.5), Func(base.transitions.fadeIn, 0.4), Func(camera.setHpr, RED_HPR), LerpPosInterval( camera, duration = 5.0, pos = RED_END_POS, startPos = RED_START_POS, blendType = 'easeOut'), name = "SCROLLBYSEQ") self.scrollBySeq.setDoneEvent(self.scrollBySeq.getName()) self.acceptOnce(self.scrollBySeq.getDoneEvent(), self.__handleScrollByDone) self.scrollBySeq.start() def __handleScrollByDone(self): self.fsm.request('countdown') def exitScrollBy(self): if self.scrollBySeq: self.ignore(self.scrollBySeq.getDoneEvent()) self.scrollBySeq.finish() self.scrollBySeq = None def allPlayersReady(self): self.fsm.request('scrollBy') def chooseUrTeam(self): # The AI has told us it's time to choose our team. self.fsm.request('chooseTeam') def enterChooseTeam(self): self.makeSelectionGUI() def acceptedIntoTeam(self, spawnPoint): TeamMinigame.acceptedIntoTeam(self) self.sendUpdate('readyToStart') self.fsm.request('waitForOthers') pos, hpr = self.spawnPointsByTeam[self.team][spawnPoint] base.localAvatar.setPos(pos) base.localAvatar.setHpr(hpr) def exitChooseTeam(self): self.destroySelectionGUI() def announceGenerate(self): DistributedToonFPSGame.announceGenerate(self) base.camLens.setMinFov(CIGlobals.GunGameFOV / (4./3.)) self.load() def disable(self): self.deleteWorld() self.trees = None self.snowballs = None self.spawnPointsByTeam = None if self.firstPerson: self.firstPerson.cleanup() self.firstPerson = None DistributedToonFPSGame.disable(self)
class ThrowAttack(Attack): notify = directNotify.newCategory('ThrowAttack') attack = 'throw' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.weapon_state = None self.weapon = None self.wss = None self.wsnp = None self.suitTrack = None self.weaponSfx = None self.throwTrajectory = None self.targetX = None self.targetY = None self.targetZ = None self.startNP = None self.theActorIval = None return def handleWeaponCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) self.suit.b_handleWeaponTouch() def doAttack(self, weapon_path, weapon_scale, track_name, animation_name, collsphere_radius, weapon_coll_id, weapon_h = 0, weapon_p = 0, weapon_r = 0, weapon_x = 0, weapon_y = 0, weapon_z = 0, ts = 0): self.weapon_state = 'start' if hasattr(self.suit, 'uniqueName'): track_name = self.suit.uniqueName(track_name) weapon_coll_id = self.suit.uniqueName(weapon_coll_id) self.weapon = loader.loadModel(weapon_path) self.weapon.setScale(weapon_scale) self.weapon.setHpr(weapon_h, weapon_p, weapon_r) self.weapon.setPos(weapon_x, weapon_y, weapon_z) self.wss = CollisionSphere(0, 0, 0, collsphere_radius) self.wss.setTangible(0) self.targetX = self.attacksClass.target.getX(render) self.targetY = self.attacksClass.target.getY(render) self.targetZ = self.attacksClass.target.getZ(render) if self.attack not in ('glowerpower',): actorIval = ActorInterval(self.suit, animation_name, playRate=2.0, duration=1.2) actorIval2 = ActorInterval(self.suit, animation_name, startTime=2.4) else: actorIval = ActorInterval(self.suit, animation_name) seq = Sequence() if self.attack not in ('glowerpower',): self.suitTrack = Parallel(Sequence(actorIval, actorIval2), name=track_name) self.weapon.reparentTo(self.suit.find('**/joint_Rhold')) seq.append(Wait(1.2)) if self.suit.suitPlan.getSuitType() == 'C': seq.append(Wait(0)) else: seq.append(Wait(0.7)) seq.append(Func(self.throwObject)) seq.append(Wait(1.0)) seq.append(Func(self.delWeapon)) else: self.suitTrack = Parallel(actorIval, name=track_name) seq.append(Wait(1)) seq.append(Func(self.throwObject)) seq.append(Wait(0.5)) seq.append(Func(self.delWeapon)) self.suitTrack.append(seq) wsnode = CollisionNode(weapon_coll_id) wsnode.addSolid(self.wss) wsnode.setCollideMask(CIGlobals.WallBitmask) self.wsnp = self.weapon.attachNewNode(wsnode) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, track_name) self.suitTrack.start(ts) def playWeaponSound(self): if self.weapon and self.weaponSfx: base.audio3d.attachSoundToObject(self.weaponSfx, self.suit) self.weaponSfx.play() 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 interruptAttack(self): if self.throwTrajectory: if self.throwTrajectory.isStopped(): self.delWeapon() def handleWeaponTouch(self): if self.throwTrajectory: self.throwTrajectory.pause() self.throwTrajectory = None self.delWeapon() return def delWeapon(self): if self.weapon: self.weapon.removeNode() self.weapon = None return def cleanup(self): Attack.cleanup(self) self.targetX = None self.targetY = None self.targetZ = None self.weapon_state = None if self.weaponSfx: self.weaponSfx.stop() self.weaponSfx = None if self.throwTrajectory: self.throwTrajectory.pause() self.throwTrajectory = None self.delWeapon() self.wss = None if self.wsnp: self.wsnp.node().clearSolids() self.wsnp.removeNode() self.wsnp = None return
class HangUpAttack(Attack): notify = directNotify.newCategory('HangUpAttack') attack = 'hangup' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.phone = None self.receiver = None self.collNP = None self.phoneSfx = None self.hangupSfx = None self.shootIval = None self.cord = None self.receiverOutCord = None self.phoneOutCord = None return def loadAttack(self): self.phone = loader.loadModel('phase_3.5/models/props/phone.bam') self.phone.setHpr(0, 0, 180) if self.suit.type == 'B': self.phone.setPos(0.7, 0.15, 0) else: if self.suit.type == 'C': self.phone.setPos(0.25, 0, 0) self.receiver = loader.loadModel('phase_3.5/models/props/receiver.bam') self.receiver.reparentTo(self.phone) self.cord = Rope() self.cord.ropeNode.setUseVertexColor(1) self.cord.ropeNode.setUseVertexThickness(1) self.cord.setup(3, ({'node': self.phone, 'point': (0.8, 0, 0.2), 'color': (0, 0, 0, 1), 'thickness': 1000}, {'node': self.phone, 'point': (2, 0, 0), 'color': (0, 0, 0, 1), 'thickness': 1000}, {'node': self.receiver, 'point': (1.1, 0.25, 0.5), 'color': (0, 0, 0, 1), 'thickness': 1000}), []) self.cord.setH(180) self.phoneSfx = base.audio3d.loadSfx('phase_3.5/audio/sfx/SA_hangup.ogg') base.audio3d.attachSoundToObject(self.phoneSfx, self.phone) self.hangupSfx = base.audio3d.loadSfx('phase_3.5/audio/sfx/SA_hangup_place_down.ogg') base.audio3d.attachSoundToObject(self.hangupSfx, self.phone) collSphere = CollisionSphere(0, 0, 0, 2) collSphere.setTangible(0) collNode = CollisionNode('phone_shootout') collNode.addSolid(collSphere) collNode.setCollideMask(CIGlobals.WallBitmask) self.collNP = self.phone.attachNewNode(collNode) def doAttack(self, ts=0): self.loadAttack() if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doHangupAttack') else: name = 'doHangupAttack' if self.suit.type == 'A': delay2playSound = 1.0 delayAfterSoundToPlaceDownReceiver = 0.2 delayAfterShootToIgnoreCollisions = 1.0 delay2PickUpReceiver = 1.0 receiverInHandPos = Point3(-0.5, 0.5, -1) else: if self.suit.type == 'B': delay2playSound = 1.5 delayAfterSoundToPlaceDownReceiver = 0.7 delayAfterShootToIgnoreCollisions = 1.0 delay2PickUpReceiver = 1.5 receiverInHandPos = Point3(-0.3, 0.5, -0.8) else: if self.suit.type == 'C': delay2playSound = 1.0 delayAfterSoundToPlaceDownReceiver = 1.15 delayAfterShootToIgnoreCollisions = 1.0 delay2PickUpReceiver = 1.5 receiverInHandPos = Point3(-0.3, 0.5, -0.8) self.suitTrack = Parallel(name=name) self.suitTrack.append(ActorInterval(self.suit, 'phone')) self.suitTrack.append(Sequence(Wait(delay2playSound), SoundInterval(self.phoneSfx, duration=2.1), Wait(delayAfterSoundToPlaceDownReceiver), Func(self.receiver.setPos, 0, 0, 0), Func(self.receiver.setH, 0.0), Func(self.receiver.reparentTo, self.phone), Func(self.acceptOnce, 'enter' + self.collNP.node().getName(), self.handleCollision), Func(self.shootOut), Parallel(SoundInterval(self.hangupSfx), Sequence(Wait(delayAfterShootToIgnoreCollisions), Func(self.ignore, 'enter' + self.collNP.node().getName()))))) self.suitTrack.append(Sequence(Func(self.phone.reparentTo, self.suit.find('**/joint_Lhold')), Func(self.cord.reparentTo, render), Wait(delay2PickUpReceiver), Func(self.receiver.reparentTo, self.suit.find('**/joint_Rhold')), Func(self.receiver.setPos, receiverInHandPos), Func(self.receiver.setH, 270.0))) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def handleCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) 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 cleanup(self): Attack.cleanup(self) if self.shootIval: self.shootIval.pause() self.shootIval = None if self.cord: self.cord.removeNode() self.cord = None if self.phone: self.phone.removeNode() self.phone = None if self.receiver: self.receiver.removeNode() self.receiver = None if self.collNP: self.collNP.node().clearSolids() self.collNP.removeNode() self.collNP = None if self.phoneSfx: self.phoneSfx.stop() self.phoneSfx = None return
class FountainPenAttack(Attack): notify = directNotify.newCategory('FountainPenAttack') attack = 'fountainpen' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.pen = None self.spray = None self.splat = None self.spraySfx = None self.sprayParticle = None self.sprayScaleIval = None self.wsnp = None return def loadAttack(self): self.pen = loader.loadModel('phase_5/models/props/pen.bam') self.pen.reparentTo(self.suit.find('**/joint_Rhold')) self.sprayParticle = ParticleLoader.loadParticleEffect('phase_5/etc/penSpill.ptf') self.spray = loader.loadModel('phase_3.5/models/props/spray.bam') self.spray.setColor(VBase4(0, 0, 0, 1)) self.splat = Actor('phase_3.5/models/props/splat-mod.bam', {'chan': 'phase_3.5/models/props/splat-chan.bam'}) self.splat.setColor(VBase4(0, 0, 0, 1)) self.sprayScaleIval = LerpScaleInterval(self.spray, duration=0.3, scale=(1, 20, 1), startScale=(1, 1, 1)) sphere = CollisionSphere(0, 0, 0, 0.5) sphere.setTangible(0) if hasattr(self.suit, 'uniqueName'): collName = self.suit.uniqueName('fountainPenCollNode') else: collName = 'fountainPenCollNode' collNode = CollisionNode(collName) collNode.addSolid(sphere) collNode.setCollideMask(CIGlobals.WallBitmask) self.wsnp = self.spray.attachNewNode(collNode) self.wsnp.setY(1) def doAttack(self, ts=0): self.loadAttack() if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doFountainPenAttack') else: name = 'doFountainPenAttack' self.suitTrack = Parallel(name=name) self.suitTrack.append(ActorInterval(self.suit, 'fountainpen')) self.suitTrack.append(Sequence(Wait(1.2), Func(self.acceptOnce, 'enter' + self.wsnp.node().getName(), self.handleSprayCollision), Func(self.playWeaponSound), Func(self.attachSpray), Func(self.sprayParticle.start, self.pen.find('**/joint_toSpray'), self.pen.find('**/joint_toSpray')), self.sprayScaleIval, Wait(0.5), Func(self.sprayParticle.cleanup), Func(self.spray.setScale, 1), Func(self.spray.reparentTo, hidden), Func(self.ignore, 'enter' + self.wsnp.node().getName()))) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def attachSpray(self): self.spray.reparentTo(self.pen.find('**/joint_toSpray')) pos = self.spray.getPos(render) hpr = self.spray.getHpr(render) self.spray.reparentTo(render) self.spray.setPos(pos) self.spray.setHpr(hpr) self.spray.setP(0) if self.suit.type == 'C': self.spray.setH(self.spray.getH() + 7.5) self.spray.setTwoSided(True) def handleSprayCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) self.sprayScaleIval.pause() def playWeaponSound(self): self.spraySfx = base.audio3d.loadSfx('phase_5/audio/sfx/SA_fountain_pen.ogg') base.audio3d.attachSoundToObject(self.spraySfx, self.pen) self.spraySfx.play() def cleanup(self): Attack.cleanup(self) if self.wsnp: self.wsnp.node().clearSolids() self.wsnp.removeNode() self.wsnp = None if self.pen: self.pen.removeNode() self.pen = None if self.sprayParticle: self.sprayParticle.cleanup() self.sprayParticle = None if self.spray: self.spray.removeNode() self.spray = None if self.splat: self.splat.cleanup() self.splat = None if self.sprayScaleIval: self.sprayScaleIval.pause() self.sprayScaleIval = None self.spraySfx = None return
class HangUpAttack(Attack): notify = directNotify.newCategory('HangUpAttack') attack = 'hangup' def __init__(self, attacksClass, suit): Attack.__init__(self, attacksClass, suit) self.phone = None self.receiver = None self.collNP = None self.phoneSfx = None self.hangupSfx = None self.shootIval = None self.cord = None self.receiverOutCord = None self.phoneOutCord = None return def loadAttack(self): self.phone = loader.loadModel('phase_3.5/models/props/phone.bam') self.phone.setHpr(0, 0, 180) if self.suit.type == 'B': self.phone.setPos(0.7, 0.15, 0) elif self.suit.type == 'C': self.phone.setPos(0.25, 0, 0) self.receiver = loader.loadModel('phase_3.5/models/props/receiver.bam') self.receiver.reparentTo(self.phone) self.cord = Rope() self.cord.ropeNode.setUseVertexColor(1) self.cord.ropeNode.setUseVertexThickness(1) self.cord.setup(3, ({'node': self.phone, 'point': (0.8, 0, 0.2), 'color': (0, 0, 0, 1), 'thickness': 1000}, {'node': self.phone, 'point': (2, 0, 0), 'color': (0, 0, 0, 1), 'thickness': 1000}, {'node': self.receiver, 'point': (1.1, 0.25, 0.5), 'color': (0, 0, 0, 1), 'thickness': 1000}), []) self.cord.setH(180) self.phoneSfx = base.audio3d.loadSfx('phase_3.5/audio/sfx/SA_hangup.mp3') base.audio3d.attachSoundToObject(self.phoneSfx, self.phone) self.hangupSfx = base.audio3d.loadSfx('phase_3.5/audio/sfx/SA_hangup_place_down.mp3') base.audio3d.attachSoundToObject(self.hangupSfx, self.phone) collSphere = CollisionSphere(0, 0, 0, 2) collSphere.setTangible(0) collNode = CollisionNode('phone_shootout') collNode.addSolid(collSphere) collNode.setCollideMask(CIGlobals.WallBitmask) self.collNP = self.phone.attachNewNode(collNode) def doAttack(self, ts = 0): self.loadAttack() if hasattr(self.suit, 'uniqueName'): name = self.suit.uniqueName('doHangupAttack') else: name = 'doHangupAttack' if self.suit.type == 'A': delay2playSound = 1.0 delayAfterSoundToPlaceDownReceiver = 0.2 delayAfterShootToIgnoreCollisions = 1.0 delay2PickUpReceiver = 1.0 receiverInHandPos = Point3(-0.5, 0.5, -1) elif self.suit.type == 'B': delay2playSound = 1.5 delayAfterSoundToPlaceDownReceiver = 0.7 delayAfterShootToIgnoreCollisions = 1.0 delay2PickUpReceiver = 1.5 receiverInHandPos = Point3(-0.3, 0.5, -0.8) elif self.suit.type == 'C': delay2playSound = 1.0 delayAfterSoundToPlaceDownReceiver = 1.15 delayAfterShootToIgnoreCollisions = 1.0 delay2PickUpReceiver = 1.5 receiverInHandPos = Point3(-0.3, 0.5, -0.8) self.suitTrack = Parallel(name=name) self.suitTrack.append(ActorInterval(self.suit, 'phone')) self.suitTrack.append(Sequence(Wait(delay2playSound), SoundInterval(self.phoneSfx, duration=2.1), Wait(delayAfterSoundToPlaceDownReceiver), Func(self.receiver.setPos, 0, 0, 0), Func(self.receiver.setH, 0.0), Func(self.receiver.reparentTo, self.phone), Func(self.acceptOnce, 'enter' + self.collNP.node().getName(), self.handleCollision), Func(self.shootOut), Parallel(SoundInterval(self.hangupSfx), Sequence(Wait(delayAfterShootToIgnoreCollisions), Func(self.ignore, 'enter' + self.collNP.node().getName()))))) self.suitTrack.append(Sequence(Func(self.phone.reparentTo, self.suit.find('**/joint_Lhold')), Func(self.cord.reparentTo, render), Wait(delay2PickUpReceiver), Func(self.receiver.reparentTo, self.suit.find('**/joint_Rhold')), Func(self.receiver.setPos, receiverInHandPos), Func(self.receiver.setH, 270.0))) self.suitTrack.setDoneEvent(self.suitTrack.getName()) self.acceptOnce(self.suitTrack.getDoneEvent(), self.finishedAttack) self.suitTrack.delayDelete = DelayDelete.DelayDelete(self.suit, name) self.suitTrack.start(ts) def handleCollision(self, entry): if self.suit: self.suit.sendUpdate('toonHitByWeapon', [self.getAttackId(self.attack), base.localAvatar.doId]) base.localAvatar.b_handleSuitAttack(self.getAttackId(self.attack), self.suit.doId) 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 cleanup(self): Attack.cleanup(self) if self.shootIval: self.shootIval.pause() self.shootIval = None if self.cord: self.cord.removeNode() self.cord = None if self.phone: self.phone.removeNode() self.phone = None if self.receiver: self.receiver.removeNode() self.receiver = None if self.collNP: self.collNP.node().clearSolids() self.collNP.removeNode() self.collNP = None if self.phoneSfx: self.phoneSfx.stop() self.phoneSfx = None return
class DistributedPieTurret(DistributedAvatar, DistributedSmoothNode): notify = directNotify.newCategory("DistributedPieTurret") def __init__(self, cr): DistributedAvatar.__init__(self, cr) DistributedSmoothNode.__init__(self, cr) self.fsm = ClassicFSM( 'DistributedPieTurret', [ State('off', self.enterOff, self.exitOff), State('scan', self.enterScan, self.exitScan), #State('lockOn', self.enterLockOn, self.exitLockOn), State('shoot', self.enterShoot, self.exitShoot) ], 'off', 'off' ) self.fsm.enterInitialState() self.cannon = None self.track = None self.avatar = None self.readyPie = None self.explosion = None self.wallCollNode = None self.eventCollNode = None self.event = None self.piesInFlight = [] def setHealth(self, hp): DistributedAvatar.setHealth(self, hp) if self.getAvatar() == base.localAvatar.doId: base.localAvatar.getMyBattle().getTurretManager().updateTurretGui() def die(self): self.fsm.requestFinalState() turretPos = self.cannon.getPos(render) self.removeTurret() self.explosion = loader.loadModel("phase_3.5/models/props/explosion.bam") self.explosion.setScale(0.5) self.explosion.reparentTo(render) self.explosion.setBillboardPointEye() self.explosion.setPos(turretPos + (0, 0, 1)) sfx = base.localAvatar.audio3d.loadSfx("phase_3.5/audio/sfx/ENC_cogfall_apart.mp3") base.localAvatar.audio3d.attachSoundToObject(sfx, self) base.playSfx(sfx) def showAndMoveHealthLabel(self): self.unstashHpLabel() self.stopMovingHealthLabel() moveTrack = LerpPosInterval(self.healthLabel, duration = 0.5, pos = Point3(0, 0, 5), startPos = Point3(0, 0, 0), blendType = 'easeOut') self.healthLabelTrack = Sequence(moveTrack, Wait(1.0), Func(self.stashHpLabel)) self.healthLabelTrack.start() def enterOff(self): pass def exitOff(self): pass def makeSplat(self, pos): splat = Actor("phase_3.5/models/props/splat-mod.bam", {"chan": "phase_3.5/models/props/splat-chan.bam"}) splat.setScale(0.5) splat.reparentTo(render) splat.setBillboardPointEye() splat.setColor(VBase4(1, 1, 0, 1)) x, y, z = pos splat.setPos(x, y, z) sfx = base.localAvatar.audio3d.loadSfx("phase_4/audio/sfx/AA_wholepie_only.mp3") base.localAvatar.audio3d.attachSoundToObject(sfx, splat) base.playSfx(sfx) track = Sequence( ActorInterval(splat, "chan"), Func(splat.cleanup), Func(splat.removeNode) ) track.start() def d_makeSplat(self, pos): self.sendUpdate("makeSplat", [pos]) def b_makeSplat(self, pos): self.d_makeSplat(pos) self.makeSplat(pos) def shoot(self, suitId): self.fsm.request('shoot', [suitId]) def enterShoot(self, suitId): if self.cannon: smoke = loader.loadModel("phase_4/models/props/test_clouds.bam") smoke.setBillboardPointEye() smoke.reparentTo(self.cannon.find('**/cannon')) smoke.setPos(0, 6, -3) smoke.setScale(0.5) smoke.wrtReparentTo(render) self.suit = self.cr.doId2do.get(suitId) self.cannon.find('**/cannon').lookAt(self.suit.find('**/joint_head')) self.cannon.find('**/square_drop_shadow').headsUp(self.suit.find('**/joint_head')) self.eventId = random.uniform(0, 100000000) track = Sequence(Parallel(LerpScaleInterval(smoke, 0.5, 3), LerpColorScaleInterval(smoke, 0.5, Vec4(2, 2, 2, 0))), Func(smoke.removeNode)) track.start() self.createAndShootPie() def loadPieInTurret(self): if self.cannon: if self.readyPie: self.readyPie.removeNode() self.readyPie = None pie = loader.loadModel("phase_3.5/models/props/tart.bam") pie.reparentTo(self.cannon.find('**/cannon')) pie.setY(5.2) pie.setHpr(90, -90, 90) self.readyPie = pie def removePieInTurret(self): if self.readyPie: self.readyPie.removeNode() self.readyPie = None def createAndShootPie(self): if not self.readyPie: self.loadPieInTurret() local = 0 if base.localAvatar.doId == self.getAvatar(): local = 1 proj = ProjectilePie(self.uniqueName('pieTurretCollision') + str(self.eventId), self.cannon.find('**/cannon'), self.readyPie, Point3(0, 200, -90), 0.9, 2.5, local, self) self.readyPie = None self.piesInFlight.append(proj) if local: self.acceptOnce(self.uniqueName('pieTurretCollision') + str(self.eventId), self.handlePieCollision) Sequence(Wait(0.25), Func(self.loadPieInTurret)).start() def handlePieCollision(self, entry, proj): x, y, z = proj.pie.getPos(render) self.b_makeSplat([x, y, z]) proj.cleanup() if base.localAvatar.doId == self.getAvatar(): intoNP = entry.getIntoNodePath() avNP = intoNP.getParent() for key in self.cr.doId2do.keys(): obj = self.cr.doId2do[key] if obj.__class__.__name__ == "DistributedSuit": if obj.getKey() == avNP.getKey(): if obj.getHealth() > 0: base.localAvatar.sendUpdate('suitHitByPie', [obj.doId, GagGlobals.getIDByName(CIGlobals.WholeCreamPie)]) def exitShoot(self): del self.suit del self.eventId def scan(self, timestamp = None, afterShooting = 0): if timestamp == None: ts = 0.0 else: ts = globalClockDelta.localElapsedTime(timestamp) self.fsm.request('scan', [ts, afterShooting]) def enterScan(self, ts = 0, afterShooting = 0): if afterShooting: self.track = Parallel( LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0), startHpr = self.cannon.find('**/cannon').getHpr(), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0), startHpr = self.cannon.find('**/square_drop_shadow').getHpr(), blendType = 'easeInOut'), name = "afterShootTrack" + str(id(self)) ) self.track.setDoneEvent(self.track.getName()) self.acceptOnce(self.track.getDoneEvent(), self._afterShootTrackDone) self.track.start(ts) else: self.track = Parallel( Sequence( LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (60, 0, 0), startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0), startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'), ), Sequence( LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (60, 0, 0), startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0), startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'), ) ) self.track.loop(ts) def _afterShootTrackDone(self): self.track = None self.track = Parallel( Sequence( LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (60, 0, 0), startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/cannon'), duration = 3, quat = (-60, 0, 0), startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'), ), Sequence( LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (60, 0, 0), startHpr = Vec3(-60, 0, 0), blendType = 'easeInOut'), LerpQuatInterval(self.cannon.find('**/square_drop_shadow'), duration = 3, quat = (-60, 0, 0), startHpr = Vec3(60, 0, 0), blendType = 'easeInOut'), ) ) self.track.loop() def exitScan(self): if self.track: self.ignore(self.track.getDoneEvent()) self.track.finish() self.track = None def setAvatar(self, avId): self.avatar = avId def getAvatar(self): return self.avatar def makeTurret(self): self.cannon = loader.loadModel("phase_4/models/minigames/toon_cannon.bam") self.cannon.reparentTo(self) self.loadPieInTurret() self.setupWallSphere() if self.getAvatar() == base.localAvatar.doId: self.setupEventSphere() def setupWallSphere(self): sphere = CollisionSphere(0.0, 0.0, 0.0, 3.0) node = CollisionNode('DistributedPieTurret.WallSphere') node.addSolid(sphere) node.setCollideMask(CIGlobals.WallBitmask) self.wallCollNode = self.cannon.attachNewNode(node) self.wallCollNode.setZ(2) self.wallCollNode.setY(1.0) def removeWallSphere(self): if self.wallCollNode: self.wallCollNode.removeNode() self.wallCollNode = None def removeTurret(self): self.removeWallSphere() self.removePieInTurret() if self.cannon: self.cannon.removeNode() self.cannon = None def generate(self): DistributedAvatar.generate(self) DistributedSmoothNode.generate(self) def announceGenerate(self): DistributedAvatar.announceGenerate(self) DistributedSmoothNode.announceGenerate(self) self.healthLabel.setScale(1.1) self.makeTurret() def disable(self): self.fsm.requestFinalState() del self.fsm for projs in self.piesInFlight: projs.cleanup() self.piesInFlight = None if self.explosion: self.explosion.removeNode() self.explosion = None self.removeTurret() DistributedSmoothNode.disable(self) DistributedAvatar.disable(self)
class DistributedDodgeballGame(DistributedToonFPSGame, TeamMinigame): """The winter dodgeball minigame (client side)""" notify = directNotify.newCategory("DistributedDodgeballGame") TreeData = [['prop_snow_tree_small_ur', Point3(23.23, 66.52, 7.46)], ['prop_snow_tree_small_ul', Point3(-34.03, 88.02, 24.17)], ['prop_snow_tree_small_ur', Point3(-54.80, 0, 4.19)], ['prop_snow_tree_small_ul', Point3(54.80, -5, 4.19)], ['prop_snow_tree_small_ur', Point3(62.71, 62.66, 16.80)], ['prop_snow_tree_small_ul', Point3(-23.23, -66.52, 6)], ['prop_snow_tree_small_ur', Point3(34.03, -88.02, 23)], ['prop_snow_tree_small_ul', Point3(-62.71, -62.66, 16)]] SnowballData = [ Point3(30, 0, 0.75), Point3(22.5, 0, 0.75), Point3(15, 0, 0.75), Point3(7.5, 0, 0.75), Point3(0, 0, 0.75), Point3(-7.5, 0, 0.75), Point3(-15, 0, 0.75), Point3(-22.5, 0, 0.75), Point3(-30, 0, 0.75) ] GameSong = "phase_4/audio/bgm/MG_Dodgeball.ogg" GameDesc = ( "Welcome to the north! You have been invited to play dodgeball with the penguins!\n\n" "How To Play\nWASD to Move and use the mouse to aim.\nLeft click to Throw!\nThrow a " "snowball at a teammate to unfreeze them!\n\nThe team with the most points after {0} rounds wins!" .format(MaxRounds)) InitCamTrans = [Point3(25, 45, 19.5317), Vec3(154.001, -15, 0)] SnowBallDmg = 25 GetSnowBalls = "Pick up a snowball from the center!" Team2OtherBarrier = {BLUE: "red_barrier_coll", RED: "blue_barrier_coll"} def __init__(self, cr): try: self.DistributedDodgeballGame_initialized return except: self.DistributedDodgeballGame_initialized = 1 DistributedToonFPSGame.__init__(self, cr) TeamMinigame.__init__( self, "BlueSnow", ('phase_4/maps/db_blue_neutral.png', 'phase_4/maps/db_blue_hover.png', 'phase_4/maps/db_blue_hover.png'), "RedIce", ('phase_4/maps/db_red_neutral.png', 'phase_4/maps/db_red_hover.png', 'phase_4/maps/db_red_hover.png')) self.fsm.addState( State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam, ['waitForOthers'])) self.fsm.addState( State('scrollBy', self.enterScrollBy, self.exitScrollBy, ['countdown'])) self.fsm.addState( State('countdown', self.enterCountdown, self.exitCountdown, ['play'])) self.fsm.addState( State('announceGameOver', self.enterAnnGameOver, self.exitAnnGameOver, ['displayWinners', 'countdown'])) self.fsm.addState( State('displayWinners', self.enterDisplayWinners, self.exitDisplayWinners, ['gameOver'])) self.fsm.getStateNamed('waitForOthers').addTransition('chooseTeam') self.fsm.getStateNamed('waitForOthers').addTransition('scrollBy') self.fsm.getStateNamed('play').addTransition('announceGameOver') self.firstPerson = DodgeballFirstPerson(self) self.scrollBySeq = None self.infoText = None self.redScoreLbl = None self.blueScoreLbl = None self.barrierIsStashed = False self.mySpawnPoint = 0 self.infoText = getAlertText() self.spawnPointsByTeam = { BLUE: [[Point3(5, 15, 0), Vec3(180, 0, 0)], [Point3(15, 15, 0), Vec3(180, 0, 0)], [Point3(-5, 15, 0), Vec3(180, 0, 0)], [Point3(-15, 15, 0), Vec3(180, 0, 0)]], RED: [[Point3(5, -15, 0), Vec3(0, 0, 0)], [Point3(15, -15, 0), Vec3(0, 0, 0)], [Point3(-5, -15, 0), Vec3(0, 0, 0)], [Point3(-15, -15, 0), Vec3(0, 0, 0)]] } self.winnerMusic = base.loadMusic( 'phase_9/audio/bgm/encntr_hall_of_fame.ogg') self.loserMusic = base.loadMusic( 'phase_9/audio/bgm/encntr_sting_announce.ogg') self.danceSound = base.loadSfx('phase_3.5/audio/sfx/ENC_Win.ogg') # Environment vars self.arena = None self.olc = None self.trees = [] self.snowballs = [] def snowballPickupResp(self, flag, idx): self.firstPerson.snowballPickupResp(flag, idx) def roundOver(self, time=0): teams = [BLUE, RED] teams.sort(key=lambda team: self.scoreByTeam[team], reverse=True) self.winnerTeam = teams[0] base.localAvatar.disableAvatarControls() self.firstPerson.end() self.deleteTimer() self.fsm.request('announceGameOver', [time]) def getTeamDNAColor(self, team): if team == TEAM1: return ToonDNA.colorDNA2color['18'] elif team == TEAM2: return ToonDNA.colorDNA2color['02'] def enterDisplayWinners(self): base.localAvatar.stopLookAround() base.localAvatar.resetHeadHpr() base.localAvatar.getGeomNode().show() camera.reparentTo(render) camera.setPos((-2.5, 12, 3.5)) camera.setHpr((-175.074, -5.47218, 0)) base.transitions.fadeIn() base.playSfx(self.danceSound, looping=1) if self.winnerTeam == self.team: base.playMusic(self.winnerMusic) else: base.playMusic(self.loserMusic) winnerPositions = [(-2, 0, 0), (2, 0, 0), (6, 0, 0), (-6, 0, 0)] loserPositions = [(-3.5, -10, 0), (-1.5, -15, 0), (3.0, -8, 0), (5.5, -12, 0)] for team in [RED, BLUE]: for avId in self.playerListByTeam[team]: av = self.cr.doId2do.get(avId) if av: av.stopSmooth() av.setHpr(0, 0, 0) if team == self.winnerTeam: posList = winnerPositions av.setAnimState("off") av.stop() if not self.getRemoteAvatar(avId).isFrozen: av.loop("win") else: posList = loserPositions av.setAnimState('off') av.stop() if not self.getRemoteAvatar(avId).isFrozen: av.loop("pout") pos = random.choice(posList) posList.remove(pos) av.setPos(pos) if self.winnerTeam == self.team: text = "YOU WIN!" else: text = "YOU LOSE!" self.gameOverLbl.setText(text) self.track = Sequence(Wait(2.0), Func(self.gameOverLbl.setScale, 0.01), Func(self.gameOverLbl.show), getAlertPulse(self.gameOverLbl, 0.27, 0.25)) self.track.start() base.localAvatar.collisionsOff() def exitDisplayWinners(self): base.localAvatar.collisionsOn() base.transitions.noTransitions() self.danceSound.stop() if hasattr(self, 'track'): self.track.finish() self.track = None self.gameOverLbl.hide() def __prepareForNextRound(self): for av in self.remoteAvatars: av.unFreeze() pos, hpr = self.spawnPointsByTeam[self.team][self.mySpawnPoint] base.localAvatar.setPos(pos) base.localAvatar.setHpr(hpr) self.playMinigameMusic() self.fsm.request('countdown') def enterAnnGameOver(self, timeRanOut=0): self.firstPerson.vModel.hide() text = getGameText() text.setBin('gui-popup', 60) ival = Sequence() if timeRanOut: ival.append(Func(text.setText, "Time's Up!")) ival.append(getRoundIval(text)) ival.append( Func(text.setText, "Round {0} Over!".format(self.getRound()))) ival.append(getRoundIval(text)) team = "Red" if self.winnerTeam == BLUE: team = "Blue" if self.round != MaxRounds: if self.scoreByTeam[RED] == self.scoreByTeam[BLUE]: ival.append(Func(text.setText, "The scores are tied!")) else: ival.append( Func(text.setText, "{0} is in the lead!".format(team))) else: ival.append(Func(text.setText, "{0} wins!".format(team))) ival.append(getRoundIval(text)) ival.setDoneEvent(self.uniqueName('annGameOverDone')) self.acceptOnce(ival.getDoneEvent(), self.__annGameOverTask) self.ival = ival self.ival.start() self.text = text base.transitions.fadeScreen() def __annGameOverTask(self): if self.round == MaxRounds: nextState = Func(self.fsm.request, "displayWinners") else: nextState = Func(self.__prepareForNextRound) self.ival = Sequence(base.transitions.getFadeOutIval(), nextState) self.ival.start() def exitAnnGameOver(self): if hasattr(self, 'ival'): self.ignore(self.ival.getDoneEvent()) self.ival.finish() del self.ival if hasattr(self, 'text'): self.text.destroy() del self.text def teamWon(self, team, time=0): TeamMinigame.teamWon(self, team, time) base.localAvatar.disableAvatarControls() self.firstPerson.end() self.deleteTimer() self.fsm.request('announceGameOver', [time]) def incrementTeamScore(self, team): TeamMinigame.incrementTeamScore(self, team) if team == BLUE: self.blueScoreLbl.setText("BLUE: " + str(self.scoreByTeam[team])) ToontownIntervals.start( ToontownIntervals.getPulseLargerIval(self.blueScoreLbl, 'blueScorePulse')) elif team == RED: self.redScoreLbl.setText("RED: " + str(self.scoreByTeam[team])) ToontownIntervals.start( ToontownIntervals.getPulseLargerIval(self.redScoreLbl, 'redScorePulse')) def getWinterDodgeballScoreText(self, color): text = OnscreenText(fg=color, font=CIGlobals.getMinnieFont(), scale=0.15, shadow=(0, 0, 0, 1)) return text def snowballHitWall(self, snowballIndex): snowball = self.snowballs[snowballIndex] snowball.handleHitWallOrPlayer() base.playSfx(snowball.impactSound, node=snowball, volume=1.5) def snowballHitGround(self, snowballIndex): snowball = self.snowballs[snowballIndex] snowball.handleHitGround() base.playSfx(snowball.impactSound, node=snowball, volume=1.5) def snowballHitPlayer(self, damagedPlayer, throwerTeam, snowballIndex): av = self.getRemoteAvatar(damagedPlayer) if av: if throwerTeam == av.team: # Someone on my team hit me. Unfreeze me if I am frozen. if av.unFreeze(): if damagedPlayer == base.localAvatar.doId: self.showAlert("A team member has unfroze you!") self.firstPerson.camFSM.request('unfrozen') self.sendUpdate('teamMateUnfrozeMe', [self.team]) else: # An enemy hit me. Become frozen if I am not already. if av.freeze(): if damagedPlayer == base.localAvatar.doId: self.showAlert("You've been frozen by an enemy!") self.firstPerson.camFSM.request('frozen') self.sendUpdate('enemyFrozeMe', [self.team, throwerTeam]) snowball = self.snowballs[snowballIndex] snowball.handleHitWallOrPlayer() base.playSfx(snowball.impactSound, node=snowball, volume=1.5) def playerCaughtSnowball(self, snowballIndex, catcherId): av = self.getRemoteAvatar(catcherId) if av: snowball = self.snowballs[snowballIndex] snowball.pauseThrowIval() snowball.pickup(av) def setupRemoteAvatar(self, avId): av = RemoteDodgeballAvatar(self, self.cr, avId) if avId == self.cr.localAvId: self.myRemoteAvatar = av self.remoteAvatars.append(av) def __getSnowTree(self, path): trees = loader.loadModel('phase_8/models/props/snow_trees.bam') tree = trees.find('**/' + path) tree.find('**/*shadow*').removeNode() return tree def load(self): self.setMinigameMusic(DistributedDodgeballGame.GameSong) self.setDescription(DistributedDodgeballGame.GameDesc) self.setWinnerPrize(200) self.setLoserPrize(0) self.createWorld() self.blueScoreLbl = self.getWinterDodgeballScoreText(VBase4( 0, 0, 1, 1)) self.blueScoreLbl.reparentTo(base.a2dTopLeft) self.blueScoreLbl['align'] = TextNode.ALeft self.blueScoreLbl.setText('Blue: 0') self.blueScoreLbl.setZ(-0.17) self.blueScoreLbl.setX(0.05) self.blueScoreLbl.hide() self.redScoreLbl = self.getWinterDodgeballScoreText(VBase4(1, 0, 0, 1)) self.redScoreLbl.reparentTo(base.a2dTopLeft) self.redScoreLbl['align'] = TextNode.ALeft self.redScoreLbl.setText('Red: 0') self.redScoreLbl.setZ(-0.35) self.redScoreLbl.setX(0.05) self.redScoreLbl.hide() trans = DistributedDodgeballGame.InitCamTrans camera.setPos(trans[0]) camera.setHpr(trans[1]) DistributedToonFPSGame.load(self) def createWorld(self): self.deleteWorld() self.arena = loader.loadModel( "phase_4/models/minigames/dodgeball_arena.egg") self.arena.reparentTo(render) self.arena.setScale(0.75) self.arena.find('**/team_divider').setBin('ground', 18) self.arena.find('**/floor').setBin('ground', 18) self.arena.find('**/team_divider_coll').setCollideMask( CIGlobals.FloorBitmask) for data in DistributedDodgeballGame.TreeData: code = data[0] pos = data[1] tree = self.__getSnowTree(code) tree.reparentTo(self.arena) tree.setPos(pos) self.trees.append(tree) for i in xrange(len(DistributedDodgeballGame.SnowballData)): snowdata = DistributedDodgeballGame.SnowballData[i] snowball = Snowball(self, i) snowball.load() snowball.reparentTo(render) snowball.setPos(snowdata) self.snowballs.append(snowball) self.olc = ZoneUtil.getOutdoorLightingConfig(ZoneUtil.TheBrrrgh) self.olc.setupAndApply() def throw(self, snowballIndex, p): snowball = self.snowballs[snowballIndex] snowball.throw(p) def snowballPickup(self, snowballIndex, pickerUpperAvId): remoteAv = self.getRemoteAvatar(pickerUpperAvId) if remoteAv: snowball = self.snowballs[snowballIndex] snowball.pickup(remoteAv) def deleteWorld(self): if self.redScoreLbl: self.redScoreLbl.destroy() self.redScoreLbl = None if self.blueScoreLbl: self.blueScoreLbl.destroy() self.blueScoreLbl = None for snowball in self.snowballs: snowball.removeNode() self.snowballs = [] for tree in self.trees: tree.removeNode() self.trees = [] if self.olc: self.olc.cleanup() self.olc = None if self.arena: self.arena.removeNode() self.arena = None render.clearFog() def enterPlay(self): self.createTimer() self.redScoreLbl.show() self.blueScoreLbl.show() self.firstPerson.camFSM.request('unfrozen') # Stash the other team's barrier. if not self.barrierIsStashed: self.arena.find('**/' + self.Team2OtherBarrier[self.team]).stash() self.barrierIsStashed = True def exitPlay(self): self.firstPerson.crosshair.destroy() self.firstPerson.crosshair = None self.firstPerson.camFSM.request('off') DistributedToonFPSGame.exitPlay(self) def enterCountdown(self): base.transitions.noTransitions() self.firstPerson.start() self.firstPerson.disableMouse() self.setRound(self.getRound() + 1) self.infoText.setText(DistributedDodgeballGame.GetSnowBalls) self.countdownText = getGameText() self.countdownIval = Parallel(Sequence( Func(self.countdownText.setText, "Round {0}".format(self.getRound())), getRoundIval(self.countdownText), Func(self.countdownText.setText, "5"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "4"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "3"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "2"), getCountdownIval(self.countdownText), Func(self.countdownText.setText, "1"), getCountdownIval(self.countdownText)), getAlertPulse(self.infoText), name="COUNTDOWNIVAL") self.countdownIval.setDoneEvent(self.countdownIval.getName()) self.acceptOnce(self.countdownIval.getDoneEvent(), self.__handleCountdownDone) self.countdownIval.start() def __handleCountdownDone(self): self.fsm.request('play') def exitCountdown(self): if hasattr(self, 'countdownIval'): self.ignore(self.countdownIval.getDoneEvent()) self.countdownIval.finish() del self.countdownIval if hasattr(self, 'countdownText'): self.countdownText.destroy() del self.countdownText def enterScrollBy(self): BLUE_START_POS = Point3(-20, 0, 4) BLUE_END_POS = Point3(20, 0, 4) BLUE_HPR = Vec3(0, 0, 0) RED_START_POS = Point3(20, 0, 4) RED_END_POS = Point3(-20, 0, 4) RED_HPR = Vec3(180, 0, 0) self.playMinigameMusic() self.scrollBySeq = Sequence(Func(camera.setHpr, BLUE_HPR), LerpPosInterval(camera, duration=5.0, pos=BLUE_END_POS, startPos=BLUE_START_POS, blendType='easeOut'), Func(base.transitions.fadeOut, 0.4), Wait(0.5), Func(base.transitions.fadeIn, 0.4), Func(camera.setHpr, RED_HPR), LerpPosInterval(camera, duration=5.0, pos=RED_END_POS, startPos=RED_START_POS, blendType='easeOut'), name="SCROLLBYSEQ") self.scrollBySeq.setDoneEvent(self.scrollBySeq.getName()) self.acceptOnce(self.scrollBySeq.getDoneEvent(), self.__handleScrollByDone) self.scrollBySeq.start() def __handleScrollByDone(self): self.fsm.request('countdown') def exitScrollBy(self): if self.scrollBySeq: self.ignore(self.scrollBySeq.getDoneEvent()) self.scrollBySeq.finish() self.scrollBySeq = None def allPlayersReady(self): self.fsm.request('scrollBy') def chooseUrTeam(self): # The AI has told us it's time to choose our team. self.fsm.request('chooseTeam') def enterChooseTeam(self): self.makeSelectionGUI() def acceptedIntoTeam(self, spawnPoint): TeamMinigame.acceptedIntoTeam(self) self.sendUpdate('readyToStart') self.fsm.request('waitForOthers') self.mySpawnPoint = spawnPoint pos, hpr = self.spawnPointsByTeam[self.team][spawnPoint] base.localAvatar.setPos(pos) base.localAvatar.setHpr(hpr) def exitChooseTeam(self): self.destroySelectionGUI() def announceGenerate(self): DistributedToonFPSGame.announceGenerate(self) base.camLens.setMinFov(CIGlobals.GunGameFOV / (4. / 3.)) self.load() def disable(self): base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.)) self.fsm.requestFinalState() self.deleteWorld() self.trees = None self.snowballs = None self.spawnPointsByTeam = None if self.firstPerson: self.firstPerson.reallyEnd() self.firstPerson.cleanup() self.firstPerson = None self.scrollBySeq = None self.winnerMusic = None self.loserMusic = None self.danceSound = None self.infoText = None base.localAvatar.setWalkSpeedNormal() DistributedToonFPSGame.disable(self)
class DistributedToon(Toon.Toon, DistributedAvatar, DistributedSmoothNode, DelayDeletable): def __init__(self, cr): try: self.DistributedToon_initialized return except: self.DistributedToon_initialized = 1 Toon.Toon.__init__(self, cr) DistributedAvatar.__init__(self, cr) DistributedSmoothNode.__init__(self, cr) self.questManager = QuestManager.QuestManager() self.token = -1 self.ghost = 0 self.puInventory = [] self.equippedPU = -1 self.backpack = None self.animState2animId = {} self.battleMeter = None for index in range(len(self.animFSM.getStates())): self.animState2animId[self.animFSM.getStates() [index].getName()] = index self.animId2animState = { v: k for k, v in self.animState2animId.items() } self.headMeter = None self.firstTimeChangingHP = True self.quests = [] self.tier = None self.questHistory = None self.busy = 1 self.friends = None self.tutDone = 0 self.hoodsDiscovered = [] self.teleportAccess = [] self.lastHood = 0 self.defaultShard = 0 self.dmgFadeIval = None self.tunnelTrack = None return def goThroughTunnel(self, toZone, inOrOut, requestStatus=None): if self.tunnelTrack: self.ignore(self.tunnelTrack.getDoneEvent()) self.tunnelTrack.finish() self.tunnelTrack = None linkTunnel = LinkTunnel.getTunnelThatGoesToZone(toZone) if not linkTunnel: return self.tunnelTrack = Parallel( name=self.uniqueName('Place.goThroughTunnel')) if inOrOut == 0: pivotPoint = linkTunnel.inPivotPoint pivotPointNode = linkTunnel.tunnel.attachNewNode( 'tunnelPivotPoint') pivotPointNode.setPos(pivotPoint) self.stopSmooth() self.wrtReparentTo(pivotPointNode) if linkTunnel.__class__.__name__ == 'SafeZoneLinkTunnel': self.setHpr(180, 0, 0) else: self.setHpr(0, 0, 0) if base.localAvatar.doId == self.doId: doneMethod = self._handleWentInTunnel extraArgs = [requestStatus] self.walkControls.setCollisionsActive(0) camera.wrtReparentTo(linkTunnel.tunnel) currCamPos = camera.getPos() currCamHpr = camera.getHpr() tunnelCamPos = linkTunnel.camPos tunnelCamHpr = linkTunnel.camHpr self.tunnelTrack.append( LerpPosInterval(camera, duration=0.7, pos=tunnelCamPos, startPos=currCamPos, blendType='easeOut')) self.tunnelTrack.append( LerpQuatInterval(camera, duration=0.7, quat=tunnelCamHpr, startHpr=currCamHpr, blendType='easeOut')) exitSeq = Sequence(Func(self.loop, 'run')) if base.localAvatar.doId == self.doId: exitSeq.append(Wait(2.0)) exitSeq.append(Func(base.transitions.irisOut)) self.tunnelTrack.append(exitSeq) self.tunnelTrack.append( Sequence( LerpHprInterval(pivotPointNode, duration=2.0, hpr=linkTunnel.inPivotEndHpr, startHpr=linkTunnel.inPivotStartHpr), LerpPosInterval(pivotPointNode, duration=1.0, pos=(linkTunnel.inPivotEndX, pivotPointNode.getY(), pivotPointNode.getZ()), startPos=(linkTunnel.inPivotStartX, pivotPointNode.getY(), pivotPointNode.getZ())))) else: if inOrOut == 1: pivotPoint = linkTunnel.outPivotPoint pivotPointNode = linkTunnel.tunnel.attachNewNode( 'tunnelPivotPoint') pivotPointNode.setPos(pivotPoint) pivotPointNode.setHpr(linkTunnel.outPivotStartHpr) if base.localAvatar.doId == self.doId: base.localAvatar.walkControls.setCollisionsActive(0) base.localAvatar.detachCamera() camera.reparentTo(linkTunnel.tunnel) tunnelCamPos = linkTunnel.camPos tunnelCamHpr = linkTunnel.camHpr camera.setPos(tunnelCamPos) camera.setHpr(tunnelCamHpr) doneMethod = self._handleCameOutTunnel extraArgs = [] self.reparentTo(pivotPointNode) self.setHpr(linkTunnel.toonOutHpr) self.setPos(linkTunnel.toonOutPos) exitSeq = Sequence( Func(self.loop, 'run'), LerpPosInterval(pivotPointNode, duration=1.0, pos=(linkTunnel.outPivotEndX, pivotPointNode.getY(), pivotPointNode.getZ()), startPos=(linkTunnel.outPivotStartX, pivotPointNode.getY(), pivotPointNode.getZ())), LerpHprInterval(pivotPointNode, duration=2.0, hpr=linkTunnel.outPivotEndHpr, startHpr=linkTunnel.outPivotStartHpr), Func(self.wrtReparentTo, render), Func(self.startSmooth)) self.tunnelTrack.append(exitSeq) if base.localAvatar.doId == self.doId: self.tunnelTrack.setDoneEvent(self.tunnelTrack.getName()) self.acceptOnce(self.tunnelTrack.getDoneEvent(), doneMethod, extraArgs) self.tunnelTrack.start() return def setupNameTag(self, tempName=None): Toon.Toon.setupNameTag(self, tempName) self.nametag.getNametag3d().setClickEvent('toonClicked', [self.doId]) self.nametag.getNametag2d().setClickEvent('toonClicked', [self.doId]) def setDefaultShard(self, shardId): self.defaultShard = shardId def getDefaultShard(self): return self.defaultShard def doSmoothTask(self, task): self.smoother.computeAndApplySmoothPosHpr(self, self) if not hasattr(base, 'localAvatar'): return task.done if self.doId != base.localAvatar.doId: self.setSpeed(self.smoother.getSmoothForwardVelocity(), self.smoother.getSmoothRotationalVelocity(), self.smoother.getSmoothLateralVelocity()) return task.cont def setLastHood(self, zoneId): self.lastHood = zoneId def b_setLastHood(self, zoneId): self.sendUpdate('setLastHood', [zoneId]) self.setLastHood(zoneId) def getLastHood(self): return self.lastHood def setTeleportAccess(self, array): self.teleportAccess = array def getTeleportAccess(self): return self.teleportAccess def setHoodsDiscovered(self, array): self.hoodsDiscovered = array def b_setHoodsDiscovered(self, array): self.sendUpdate('setHoodsDiscovered', [array]) self.setHoodsDiscovered(array) def getHoodsDiscovered(self): return self.hoodsDiscovered def setTutorialCompleted(self, value): self.tutDone = value def getTutorialCompleted(self): return self.tutDone def setFriendsList(self, friends): self.friends = friends def getFriendsList(self): return self.friends def setBusy(self, busy): self.busy = busy def getBusy(self): return self.busy def setTier(self, tier): self.tier = tier def getTier(self): return self.tier def setQuestHistory(self, array): self.questHistory = array def getQuestHistrory(self): return self.questHistory def setQuests(self, questIds, currentObjectives, currentObjectivesProgress): self.quests = [questIds, currentObjectives, currentObjectivesProgress] self.questManager.makeQuestsFromData() def getQuests(self): return self.quests def maybeMakeHeadMeter(self): if base.localAvatar.doId != self.doId: if self.health < self.getMaxHealth(): if not self.headMeter: self.__makeHeadMeter() def __makeHeadMeter(self): self.headMeter = LaffOMeter(forRender=True) r, g, b, _ = self.getHeadColor() animal = self.getAnimal() maxHp = self.getMaxHealth() hp = self.getHealth() self.headMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp) self.headMeter.reparentTo(self) self.headMeter.setZ(self.getHeight() + 2) self.headMeter.setScale(0.4) self.headMeter.setBillboardAxis() self.__updateHeadMeter() def __removeHeadMeter(self): if self.headMeter: self.headMeter.disable() self.headMeter.delete() self.headMeter = None return def __updateHeadMeter(self): if self.headMeter: self.headMeter.updateMeter(self.getHealth()) def setHealth(self, health): if self.doId != base.localAvatar.doId: if not self.firstTimeChangingHP: if health < self.getMaxHealth(): if not self.headMeter: self.__makeHeadMeter() else: self.__updateHeadMeter() else: self.__removeHeadMeter() self.health = health self.firstTimeChangingHP = False def d_createBattleMeter(self): self.sendUpdate('makeBattleMeter', []) def b_createBattleMeter(self): self.makeBattleMeter() self.d_createBattleMeter() def d_cleanupBattleMeter(self): self.sendUpdate('destroyBattleMeter', []) def b_cleanupBattleMeter(self): self.destroyBattleMeter() self.d_cleanupBattleMeter() def makeBattleMeter(self): if self.getHealth() < self.getMaxHealth(): if not self.battleMeter: self.battleMeter = LaffOMeter() r, g, b, _ = self.getHeadColor() animal = self.getAnimal() maxHp = self.getMaxHealth() hp = self.getHealth() self.battleMeter.generate(r, g, b, animal, maxHP=maxHp, initialHP=hp) self.battleMeter.reparentTo(self) self.battleMeter.setZ(self.getHeight() + 5) self.battleMeter.setScale(0.5) self.battleMeter.start() def destroyBattleMeter(self): if self.battleMeter: self.battleMeter.stop() self.battleMeter.disable() self.battleMeter.delete() self.battleMeter = None return def setEquippedPU(self, index): self.equippedPU = index def getEquippedPU(self): return self.equippedPU def setPUInventory(self, array): self.puInventory = array def getPUInventory(self): return self.puInventory def setGhost(self, value): self.ghost = value if value: self.ghostOn() else: self.ghostOff() def d_setGhost(self, value): self.sendUpdate('setGhost', [value]) def b_setGhost(self, value): self.d_setGhost(value) self.setGhost(value) def getGhost(self): return self.ghost def setDNAStrand(self, dnaStrand): Toon.Toon.setDNAStrand(self, dnaStrand) self.maybeMakeHeadMeter() def d_setDNAStrand(self, dnaStrand): self.sendUpdate('setDNAStrand', [dnaStrand]) def b_setDNAStrand(self, dnaStrand): self.setDNAStrand(dnaStrand) self.d_setDNAStrand(dnaStrand) def lookAtObject(self, h, p, r, blink=1): if self.getPart('head').getHpr() == (h, p, r): return Toon.Toon.lerpLookAt(self, self.getPart('head'), tuple((h, p, r))) if blink: self.stopBlink() maxBlinks = random.randint(1, 2) numBlinks = 0 delay = 0 for blink in range(maxBlinks): if numBlinks == 0: taskMgr.add(self.doBlink, self.uniqueName('blinkOnTurn')) else: delay += 0.22 taskMgr.doMethodLater(delay, self.doBlink, self.doBlinkTaskName) numBlinks += 1 taskMgr.doMethodLater(delay, self.__startBlinkAfterLook, self.uniqueName('sBAL')) def __startBlinkAfterLook(self, task): self.startBlink() return task.done def toonUp(self): pass def b_lookAtObject(self, h, p, r, blink=1): self.d_lookAtObject(h, p, r, blink) self.lookAtObject(h, p, r, blink) def d_lookAtObject(self, h, p, r, blink=1): self.sendUpdate('lookAtObject', [h, p, r, blink]) def setChat(self, chat): chat = ChatGlobals.filterChat(chat, self.animal) Toon.Toon.setChat(self, chat) def setTarget(self, gagId, targetId): gag = self.backpack.getGagByID(gagId) target = self.cr.doId2do.get(targetId, None) gag.setTarget(target) return def trapActivate(self, gagId, avId, entityId, suitId): sender = self.cr.doId2do.get(avId, None) suit = self.cr.doId2do.get(suitId, None) if sender: backpack = sender.getBackpack() trapGag = backpack.getGagByID(gagId) if backpack and trapGag: entity = None if hasattr(trapGag, 'getEntities') and 0 <= entityId <= len( trapGag.getEntities()) - 1: entity = trapGag.getEntities()[entityId] trapGag.onActivate(entity, suit) return def b_trapActivate(self, gagId, avId, entityId, suitId): self.trapActivate(gagId, avId, entityId, suitId) self.d_trapActivate(gagId, avId, entityId, suitId) def d_trapActivate(self, gagId, avId, entityId, suitId): self.sendUpdate('trapActivate', [gagId, avId, entityId, suitId]) def gagCollision(self, gagId): gag = self.backpack.getGagByID(gagId) gag.doCollision() def b_gagCollision(self, gagId): self.sendUpdate('gagCollision', [gagId]) self.gagCollision(gagId) def gagActivate(self, gagId): gag = self.backpack.getGagByID(gagId) if hasattr(gag, 'activate'): gag.activate() def b_gagActivate(self, gagId): self.sendUpdate('gagActivate', [gagId]) self.gagActivate(gagId) def setDropLoc(self, gagId, x, y, z): gag = self.backpack.getGagByID(gagId) gag.setEndPos(x, y, z) def setGagPos(self, gagId, x, y, z): pos = Point3(x, y, z) gag = self.backpack.getGagByID(gagId) ent = gag.getGag() if ent: ent.setPos(pos) def setThrowPower(self, gagId, power): gag = self.backpack.getGagByID(gagId) if gag: gag.setPower(power) def gagStart(self, gagId): gag = self.backpack.getGagByID(gagId) if gag: gag.start() def b_gagStart(self, gagId): self.sendUpdate('gagStart', [gagId]) self.gagStart(gagId) def gagThrow(self, gagId): gag = self.backpack.getGagByID(gagId) if gag: gag.throw() def b_gagThrow(self, gagId): self.sendUpdate('gagThrow', [gagId]) self.gagThrow(gagId) def gagRelease(self, gagId): gag = self.backpack.getGagByID(gagId) if gag and hasattr(gag, 'name'): gag.release() def b_gagRelease(self, gagId): self.sendUpdate('gagRelease', [gagId]) self.gagRelease(gagId) def setSplatPos(self, gagId, x, y, z): splatGag = self.backpack.getGagByID(gagId) if splatGag: splatGag.setSplatPos(x, y, z) def d_setSplatPos(self, gagId, x, y, z): self.sendUpdate('setSplatPos', [gagId, x, y, z]) def gagBuild(self, gagId): gag = self.backpack.getGagByID(gagId) if gag: gag.build() def b_gagBuild(self, gagId): self.gagBuild(gagId) self.sendUpdate('gagBuild', [gagId]) def handleSuitAttack(self, attack_id, suit_id): attack = SuitAttacks.SuitAttackLengths.keys()[attack_id] if attack == 'canned': sfx = base.audio3d.loadSfx( 'phase_5/audio/sfx/SA_canned_impact_only.ogg') base.audio3d.attachSoundToObject(sfx, self) SoundInterval(sfx, node=self).start() else: if attack == 'playhardball': sfx = base.audio3d.loadSfx( 'phase_5/audio/sfx/SA_hardball_impact_only_alt.ogg') base.audio3d.attachSoundToObject(sfx, self) SoundInterval(sfx, node=self).start() else: if attack == 'clipontie': sfx = base.audio3d.loadSfx( 'phase_5/audio/sfx/SA_powertie_impact.ogg') base.audio3d.attachSoundToObject(sfx, self) SoundInterval(sfx, node=self).start() if not self.isDead(): if attack in ('fountainpen', ): self.getPart('head').setColorScale(0, 0, 0, 1) Sequence(Wait(3.0), Func(self.resetHeadColor)).start() if self.dmgFadeIval: self.dmgFadeIval.finish() self.dmgFadeIval = None geomNode = self.getGeomNode() self.dmgFadeIval = Sequence( Func(geomNode.setTransparency, 1), LerpColorScaleInterval(geomNode, 0.3, (1, 1, 1, 0.5), (1, 1, 1, 1), blendType='easeOut'), LerpColorScaleInterval(geomNode, 0.3, (1, 1, 1, 1), (1, 1, 1, 0.5), blendType='easeIn'), Func(geomNode.setTransparency, 0)) self.dmgFadeIval.start() return def resetHeadColor(self): head = self.getPart('head') if head: head.setColorScale(1, 1, 1, 1) def b_handleSuitAttack(self, attack_id, suit_id): self.handleSuitAttack(attack_id, suit_id) self.b_lookAtObject(0, 0, 0, blink=1) self.sendUpdate('handleSuitAttack', [attack_id, suit_id]) def equip(self, gagId): if self.backpack: self.backpack.setCurrentGag(gagId) def unEquip(self): if self.backpack: self.backpack.setCurrentGag(None) return def b_unEquip(self): self.unEquip() self.sendUpdate('unEquip', []) def b_equip(self, gag_id): self.equip(gag_id) self.sendUpdate('equip', [gag_id]) def getBackpack(self): return self.backpack def setLoadout(self, gagIds): if self.backpack: loadout = [] for i in range(len(gagIds)): gagId = gagIds[i] gag = self.backpack.getGagByID(gagId) if gag: loadout.append(gag) self.backpack.setLoadout(loadout) def setBackpackAmmo(self, gagIds, ammoList): if not self.backpack: self.backpack = Backpack(self) for i in xrange(len(gagIds)): gagId = gagIds[i] ammo = ammoList[i] if not self.backpack.hasGag(gagId): self.backpack.addGag( gagId, ammo, GagGlobals.getGagData(gagId).get('maxSupply')) else: self.backpack.setSupply(gagId, ammo) def getBackpackAmmo(self): return ([], []) def setGagAmmo(self, gagId, ammo): self.backpack.setSupply(gagId, ammo) def setMoney(self, money): self.money = money def getMoney(self): return self.money def setAdminToken(self, value): self.token = value if value > -1: Toon.Toon.setAdminToken(self, value) else: Toon.Toon.removeAdminToken(self) def getAdminToken(self): return self.token def setAnimState(self, anim, timestamp=None, callback=None, extraArgs=[]): self.anim = anim if timestamp == None: ts = 0.0 else: ts = globalClockDelta.localElapsedTime(timestamp) if type(anim) == types.IntType: anim = self.animId2animState[anim] if self.animFSM.getStateNamed(anim): self.animFSM.request(anim, [ts, callback, extraArgs]) return def b_setAnimState(self, anim): self.d_setAnimState(anim) self.setAnimState(anim, None) return def d_setAnimState(self, anim): if type(anim) == types.StringType: anim = self.animState2animId[anim] timestamp = globalClockDelta.getFrameNetworkTime() self.sendUpdate('setAnimState', [anim, timestamp]) def getAnimState(self): return self.anim def setName(self, name): Toon.Toon.setName(self, name) if self.cr.isShowingPlayerIds: self.showAvId() def d_setName(self, name): self.sendUpdate('setName', [name]) def b_setName(self, name): self.d_setName(name) self.setName(name) def showAvId(self): self.setDisplayName(self.getName() + '\n' + str(self.doId)) def showName(self): self.setDisplayName(self.getName()) def setDisplayName(self, name): self.setupNameTag(tempName=name) def wrtReparentTo(self, parent): DistributedSmoothNode.wrtReparentTo(self, parent) def announceHealthAndPlaySound(self, level, hp): DistributedAvatar.announceHealth(self, level, hp) hpSfx = base.audio3d.loadSfx('phase_11/audio/sfx/LB_toonup.ogg') base.audio3d.attachSoundToObject(hpSfx, self) SoundInterval(hpSfx, node=self).start() del hpSfx def announceGenerate(self): DistributedAvatar.announceGenerate(self) if self.animFSM.getCurrentState().getName() == 'off': self.setAnimState('neutral') self.startBlink() def generate(self): DistributedAvatar.generate(self) DistributedSmoothNode.generate(self) self.startSmooth() def disable(self): if self.tunnelTrack: self.ignore(self.tunnelTrack.getDoneEvent()) self.tunnelTrack.finish() self.tunnelTrack = None if self.dmgFadeIval: self.dmgFadeIval.finish() self.dmgFadeIval = None self.busy = None taskMgr.remove(self.uniqueName('sBAL')) taskMgr.remove(self.uniqueName('blinkOnTurn')) if self.track != None: self.track.finish() DelayDelete.cleanupDelayDeletes(self.track) self.track = None self.stopBlink() self.__removeHeadMeter() self.ignore('showAvId') self.ignore('showName') self.token = None self.stopSmooth() Toon.Toon.disable(self) DistributedAvatar.disable(self) return def delete(self): try: self.DistributedToon_deleted except: self.DistributedToon_deleted = 1 self.tutDone = None self.defaultShard = None Toon.Toon.delete(self) DistributedAvatar.delete(self) DistributedSmoothNode.delete(self) return