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 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 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 DistributedTutorial(DistributedObject): notify = directNotify.newCategory('DistributedTutorial') GUIDE_NAME = 'Professor Prepostera' GUIDE_START_POS = (5, 10, -0.5) GUIDE_WATCH_POS = (12.4, 27.92, 0) GUIDE_WATCH_HPR = (41.63, 0, 0) GUIDE_INTRO_SPEECH = [ 'Hey, looks like you made it!', 'So, welcome to OToontown.', 'OToontown is short for Old Toontown, or Toontown from the past.', 'Not long ago, Toons used to live in present day Toontown.', 'Unfortunately, the Cogs planned a mega-invasion that was sure to be a complete takeover of Toontown and make all Toons go sad for good.', "There was no way we could have let that happen, so we built a time machine, and sent every Toon back in time to OToontown, where Cogs didn't exist yet.", 'The Cogs completely took over present day Toontown, and turned it into what they wanted it to be - a business metropolis.', 'Toons happily live and play in OToontown now, but we want to learn about present day Toontown...', ' ...or as we now call it, CogTropolis.', "We've built time machines that send Toons back to CogTropolis to fight Cogs and to see what the Cogs have done.", "We know that the Cogs took over Toontown and turned it into a grey business city, but we don't know how they did it.", 'Shopkeepers around OToontown will reward you for finding evidence that may help solve the mystery of how the Cogs turned Toontown into CogTropolis.', 'Before you are able to head to CogTropolis, you need to be trained for battle.', 'The Cogs have become much more skilled battlers and no longer wait for you to throw a gag before attacking you.', 'This is much more difficult for Toons, and it may take some time to get used to.', "I'm going to give you 2 gags to start...", 'A cupcake, and a squirting flower.', 'Equip Gags in your loadout to use by pressing the corresponding key on your keyboard.', 'You can use or throw the Gag that you have equipped by pressing the ALT key.', 'Also, use the Arrow Keys on your keyboard to move, and press CTRL to jump.', "I'm going to summon one of our dummy bots for you to practice battling.", "Click your mouse when you're ready." ] GUIDE_PT2_INFO = [ "Now it'll get a tad bit tougher.", 'This next dummy bot will be walking around.', 'This will test your aiming skills.', "Click your mouse when you're ready." ] GUIDE_PT3_INFO = [ 'This final dummy bot will walk around and try to attack you at times.', 'Defeat this Cog to continue on to the next part of the tutorial.' ] GUIDE_DONE = [ 'Great!', 'Did you know that Cog Invasion Online Alpha allows you to use any Gag that you want?', 'Just use the Gags page in your Shticker Book to swap out the Gags that you want to be able to use!', 'Also during Alpha testing, your Toon will start off with 5000 jellybeans and 100 Laff points.', "If you're looking to fight some Cogs, hop on the Trolley in the playgrounds to be teleported to CogTropolis!", 'Each playground has a different difficulty of Cogs, so be careful!', "You can only fight Cogs in Toontown Central, Minnie's Melodyland, Donald's Dock, and Donald's Dreamland at the moment.", 'You can also visit the Minigame Area using your Shticker Book to play some fun minigames!', 'These games are best to play with other Toons!', 'Remember, if you find any bugs or strange things during gameplay, you can go to the Contact Us page at coginvasion.com to report the issue.', 'Have fun!' ] GUIDE_START_TRAINING = "Alright! Let's do this!" def __init__(self, cr): DistributedObject.__init__(self, cr) self.fsm = ClassicFSM.ClassicFSM('TutorialFSM', [ State.State('off', self.enterOff, self.exitOff), State.State('newPlayerEmerge', self.enterPlayerEmerge, self.exitPlayerEmerge, ['off', 'introSpeech']), State.State('introSpeech', self.enterGuideIntroSpeech, self.exitGuideIntroSpeech, ['off', 'introSpeech2Training']), State.State('introSpeech2Training', self.enterIntroSpeech2Training, self.exitIntroSpeech2Training, ['off', 'training1']), State.State('training1', self.enterTrainingPT1, self.exitTrainingPT1, ['off', 'training2info']), State.State('training2info', self.enterTraining2Info, self.exitTraining2Info, ['off', 'training2']), State.State('training2', self.enterTrainingPT2, self.exitTrainingPT2, ['off', 'training3info']), State.State('training3info', self.enterTraining3Info, self.exitTraining3Info, ['off', 'training3']), State.State('training3', self.enterTrainingPT3, self.exitTrainingPT3, ['off', 'trainingDone']), State.State('trainingDone', self.enterTrainingDone, self.exitTrainingDone, ['off', 'leaveTutorial']), State.State('leaveTutorial', self.enterLeaveTutorial, self.exitLeaveTutorial, ['off']) ], 'off', 'off') self.fsm.enterInitialState() self.dnaStore = DNAStorage() self.streetGeom = None self.sky = None self.skyUtil = SkyUtil() self.guide = None self.music = None self.battleMusic = None self.playerCamPos = None self.playerCamHpr = None return def enterOff(self): pass def exitOff(self): pass def introStuff(self): base.localAvatar.getGeomNode().hide() base.localAvatar.setPos(0, 0, -0.5) base.localAvatar.setHpr(0, 0, 0) self.guide.setPos(self.GUIDE_START_POS) self.guide.headsUp(base.localAvatar) base.localAvatar.attachCamera() def enterPlayerEmerge(self): self.introStuff() self.guide.loop('neutral') base.transitions.irisIn() base.taskMgr.doMethodLater(1.0, self.__playerEmerge, 'playerEmergeTask') def __playerEmerge(self, task): base.localAvatar.setAnimState('teleportIn', callback=self.__playerEmergeFinished) return Task.done def __playerEmergeFinished(self): base.localAvatar.setAnimState('neutral') self.fsm.request('introSpeech') def exitPlayerEmerge(self): base.localAvatar.detachCamera() base.taskMgr.remove('playerEmergeTask') base.transitions.noTransitions() def enterGuideIntroSpeech(self): base.localAvatar.attachCamera() renderPos = base.camera.getPos(render) renderHpr = base.camera.getHpr(render) base.localAvatar.detachCamera() endPos = base.localAvatar.getPos(render) + (0, 0, 4) base.camera.setPos(endPos) base.camera.lookAt(self.guide, 0, 0, 3) endHpr = base.camera.getHpr(render) base.camera.setPos(renderPos) base.camera.setHpr(renderHpr) self.chatIndex = -1 self.doNextIntroSpeech() self.camMoveTrack = Sequence( Parallel( LerpPosInterval(base.camera, duration=3.0, pos=endPos, startPos=renderPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=3.0, hpr=endHpr, startHpr=renderHpr, blendType='easeOut')), Func(base.localAvatar.getGeomNode().hide)) self.camMoveTrack.start() def __finishedReadingGuideIntroSpeech(self): self.guide.autoClearChat = True self.guide.setChat(self.GUIDE_START_TRAINING) self.fsm.request('introSpeech2Training') def doNextIntroSpeech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_INTRO_SPEECH): self.__finishedReadingGuideIntroSpeech() return self.guide.setChat(self.GUIDE_INTRO_SPEECH[self.chatIndex]) Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextIntroSpeech)).start() def exitGuideIntroSpeech(self): self.camMoveTrack.finish() base.localAvatar.getGeomNode().show() del self.camMoveTrack del self.chatIndex def enterIntroSpeech2Training(self): startCamPos = base.camera.getPos(render) startCamHpr = base.camera.getHpr(render) base.camera.setPosHpr(0, 0, 0, 0, 0, 0) base.localAvatar.attachCamera() endCamPos = base.camera.getPos(render) endCamHpr = base.camera.getHpr(render) base.localAvatar.detachCamera() startHpr = self.guide.getHpr(render) self.guide.headsUp(self.GUIDE_WATCH_POS) endHpr = self.guide.getHpr(render) self.guide.loop('run') self.camMoveIval = Parallel( LerpPosInterval(base.camera, duration=2.0, pos=endCamPos, startPos=startCamPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=2.0, hpr=endCamHpr, startHpr=startCamHpr, blendType='easeOut'), Sequence( LerpPosInterval(self.guide, duration=2.0, pos=self.GUIDE_WATCH_POS, startPos=self.guide.getPos(render)), Func(self.guide.loop, 'walk'), LerpHprInterval(self.guide, duration=1.0, hpr=self.GUIDE_WATCH_HPR, startHpr=endHpr), Func(self.guide.loop, 'neutral')), LerpHprInterval(self.guide, duration=1.0, hpr=endHpr, startHpr=startHpr)) self.camMoveIval.setDoneEvent('introSpeech2TrainingDone') self.acceptOnce('introSpeech2TrainingDone', self.__handleIS2TDone) self.camMoveIval.start() def __handleIS2TDone(self): self.fsm.request('training1') def exitIntroSpeech2Training(self): self.ignore('introSpeech2TrainingDone') self.camMoveIval.finish() del self.camMoveIval def makeWhisper(self, msg): whisper = WhisperPopup(msg, CIGlobals.getToonFont(), ChatGlobals.WTSystem) whisper.manage(base.marginManager) def enterTrainingPT1(self): self.music.stop() base.playMusic(self.battleMusic, volume=0.8, looping=1) self.sendUpdate('makeSuit', [0]) base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.startBlink() base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.collisionsOn() base.localAvatar.enableAvatarControls() base.localAvatar.enableGags(1) base.localAvatar.showGagButton() base.localAvatar.startTrackAnimToSpeed() self.makeWhisper( 'This should be pretty simple. Just throw a gag at this dummy bot to defeat it.' ) def suitNoHealth(self, index): if index == 0: self.makeWhisper( ('Good job, {0}!').format(base.localAvatar.getName())) else: if index == 1: self.makeWhisper("Wow, you're doing very well!") def suitExploded(self, index): if index == 0: self.makeWhisper( 'Pick up the jellybean that he dropped. You can use them to buy more gags for your Toon.' ) self.battleMusic.stop() base.playMusic(self.music, looping=1, volume=0.8) def pickedUpJellybean(self): if self.fsm.getCurrentState().getName() == 'training1': self.fsm.request('training2info') else: if self.fsm.getCurrentState().getName() == 'training2': self.fsm.request('training3info') else: if self.fsm.getCurrentState().getName() == 'training3': self.fsm.request('trainingDone') def exitTrainingPT1(self): base.localAvatar.lastState = None base.localAvatar.disableAvatarControls() base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopBlink() base.localAvatar.collisionsOff() base.localAvatar.controlManager.placeOnFloor() base.localAvatar.disableGags() base.localAvatar.stopTrackAnimToSpeed() base.localAvatar.hideGagButton() return def enterTraining2Info(self): base.camera.setPos(3.09, 37.16, 3.93) base.camera.setHpr(225, 0, 0) self.guide.autoClearChat = False self.chatIndex = -1 self.doNextTraining2Speech() def __finishedReadingGuideTraining2Speech(self): self.guide.autoClearChat = True self.guide.clearChat() self.fsm.request('training2') def doNextTraining2Speech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_PT2_INFO): self.__finishedReadingGuideTraining2Speech() return self.guide.setChat(self.GUIDE_PT2_INFO[self.chatIndex]) Sequence( Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining2Speech)).start() def exitTraining2Info(self): base.camera.setPosHpr(0, 0, 0, 0, 0, 0) del self.chatIndex def enterTrainingPT2(self): self.music.stop() base.playMusic(self.battleMusic, volume=0.8, looping=1) self.sendUpdate('makeSuit', [1]) base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.startBlink() base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.collisionsOn() base.localAvatar.enableAvatarControls() base.localAvatar.enableGags(1) base.localAvatar.showGagButton() base.localAvatar.startTrackAnimToSpeed() def exitTrainingPT2(self): base.localAvatar.lastState = None base.localAvatar.disableAvatarControls() base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopBlink() base.localAvatar.collisionsOff() base.localAvatar.controlManager.placeOnFloor() base.localAvatar.disableGags() base.localAvatar.stopTrackAnimToSpeed() base.localAvatar.hideGagButton() return def enterTraining3Info(self): base.camera.setPos(3.09, 37.16, 3.93) base.camera.setHpr(225, 0, 0) self.guide.autoClearChat = False self.chatIndex = -1 self.doNextTraining3Speech() def __finishedReadingGuideTraining3Speech(self): self.guide.autoClearChat = True self.guide.clearChat() self.fsm.request('training3') def doNextTraining3Speech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_PT3_INFO): self.__finishedReadingGuideTraining3Speech() return self.guide.setChat(self.GUIDE_PT3_INFO[self.chatIndex]) Sequence( Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining3Speech)).start() def exitTraining3Info(self): base.camera.setPosHpr(0, 0, 0, 0, 0, 0) del self.chatIndex def enterTrainingPT3(self): self.music.stop() base.playMusic(self.battleMusic, volume=0.8, looping=1) self.sendUpdate('makeSuit', [2]) base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.startBlink() base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.collisionsOn() base.localAvatar.enableAvatarControls() base.localAvatar.enableGags(1) base.localAvatar.showGagButton() base.localAvatar.startTrackAnimToSpeed() def exitTrainingPT3(self): base.localAvatar.lastState = None base.localAvatar.disableAvatarControls() base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopBlink() base.localAvatar.collisionsOff() base.localAvatar.controlManager.placeOnFloor() base.localAvatar.disableGags() base.localAvatar.stopTrackAnimToSpeed() base.localAvatar.hideGagButton() return def enterTrainingDone(self): base.camera.setPos(3.09, 37.16, 3.93) base.camera.setHpr(225, 0, 0) self.guide.autoClearChat = False self.chatIndex = -1 self.doNextTrainingDoneSpeech() def __finishedReadingGuideTrainingDoneSpeech(self): self.guide.autoClearChat = True self.guide.clearChat() self.fsm.request('leaveTutorial') def doNextTrainingDoneSpeech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_DONE): self.__finishedReadingGuideTrainingDoneSpeech() return self.guide.setChat(self.GUIDE_DONE[self.chatIndex]) Sequence( Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTrainingDoneSpeech)).start() def exitTrainingDone(self): base.camera.setPosHpr(0, 0, 0, 0, 0, 0) del self.chatIndex def enterLeaveTutorial(self): base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.b_setAnimState('teleportOut', callback=self.__teleOutDone) def __teleOutDone(self): zoneId = CIGlobals.ToontownCentralId hoodId = CIGlobals.ToontownCentral whereName = 'playground' avId = base.localAvatar.doId loaderName = 'safeZoneLoader' self.sendUpdate('finishedTutorial') self.cr.playGame.load() self.cr.playGame.enter(hoodId, zoneId, base.localAvatar.doId) def exitLeaveTutorial(self): base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() def announceGenerate(self): DistributedObject.announceGenerate(self) base.transitions.fadeScreen(0.0) self.guide = Toon(base.cr) self.guide.autoClearChat = False self.guide.parseDNAStrand(NPCGlobals.NPC_DNA[self.GUIDE_NAME]) self.guide.setName(self.GUIDE_NAME) self.guide.generateToon() self.guide.nametag.setNametagColor( NametagGlobals.NametagColors[NametagGlobals.CCNPC]) self.guide.nametag.setActive(0) self.guide.nametag.updateAll() self.guide.startBlink() self.guide.reparentTo(render) base.localAvatar.reparentTo(render) loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_tutorial.pdna') node = loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/tutorial_street.pdna') if node.getNumParents() == 1: self.streetGeom = NodePath(node.getParent(0)) self.streetGeom.reparentTo(hidden) else: self.streetGeom = hidden.attachNewNode(node) self.streetGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.streetGeom.prepareScene(gsg) self.streetGeom.reparentTo(render) self.streetGeom.setPos(20.5, -20, 0) self.streetGeom.setH(90) self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam') self.skyUtil.startSky(self.sky) self.sky.reparentTo(camera) ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ) self.sky.node().setEffect(ce) self.music = base.loadMusic('phase_3.5/audio/bgm/TC_SZ.mid') base.playMusic(self.music, volume=0.8, looping=1) self.battleMusic = base.loadMusic( 'phase_3.5/audio/bgm/encntr_general_bg.mid') self.fsm.request('newPlayerEmerge') base.localAvatar.inTutorial = True def disable(self): self.fsm.requestFinalState() del self.fsm if self.guide: self.guide.disable() self.guide.delete() self.guide = None if self.streetGeom: self.streetGeom.removeNode() self.streetGeom = None if self.sky: self.sky.removeNode() self.sky = None if self.music: self.music.stop() self.music = None if self.battleMusic: self.battleMusic.stop() self.battleMusic = None self.dnaStore.reset_nodes() self.dnaStore.reset_hood_nodes() self.dnaStore.reset_place_nodes() self.dnaStore.reset_hood() self.dnaStore.reset_fonts() self.dnaStore.reset_DNA_vis_groups() self.dnaStore.reset_textures() self.dnaStore.reset_block_numbers() self.dnaStore.reset_block_zones() self.dnaStore.reset_suit_points() self.dnaStore = None self.skyUtil = None base.localAvatar.inTutorial = False DistributedObject.disable(self) 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 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 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
class TrainController: """Object to control the locomotive. Implements changing the locomotive speed and animation. Also manages moving the locomotive along motion paths. Args: model (panda3d.core.NodePath): The locomotive model. """ def __init__(self, model): self._model = model self._move_snd, self._stop_snd, self._brake_snd = self._set_sounds( model) self._move_anim_int = model.actorInterval("move_forward", playRate=14) self._move_anim_int.loop() # parallel with the Train model and camera move intervals self._move_par = Parallel() self._is_stopped = False self._outing_available = None self._move_snd_volume = 1 self._garland = None self._confetti = None self._confetti_cooldown = False self._confetti_snd = None self.on_et = False self.critical_damage = False self.max_speed = 1 @property def current_speed(self): """Current locomotive speed. Returns float: Current locomotive speed (play rate). """ return 0 if self._is_stopped else self._move_anim_int.getPlayRate() def _change_speed(self, diff, task): """Actually change the locomotive speed. Args: diff (float): Coefficient to change the Train speed. """ if self._is_stopped and diff > 0: self.start_move() new_rate = round(self._move_anim_int.getPlayRate() + diff, 2) if (self.on_et # don't stop on enemy territory and diff < 0 # stop on enemy territory only # in case of critical damage and not self.critical_damage and new_rate < MIN_SPEED): return task.again if new_rate > self.max_speed and diff > 0: return task.again # change speed if 0 < new_rate <= 1: self._move_anim_int.setPlayRate(new_rate) self._move_par.setPlayRate(new_rate) new_snd_rate = new_rate * 1.2 if 0.25 <= new_snd_rate <= 1: self._move_snd.setPlayRate(new_snd_rate) return task.again if new_rate == 0: self._stop_move() return task.done def _change_speed_delayed(self, diff): """Start changing the locomotive speed. To make speed changing smoother delayed task is used. Args: diff (float): Coefficient to change speed. """ taskMgr.doMethodLater( # noqa: F821 0.6, self._change_speed, "change_train_speed", extraArgs=[diff], appendTask=True, ) def _finish_stopping(self, task): """Finish stopping the damaged Train.""" taskMgr.remove("stop_train") # noqa: F821 base.train.stop_sparks() # noqa: F821 base.main_menu.show(is_game_over=True) # noqa: F821 return task.done def _set_sounds(self, model): """Set interactive locomotive sounds. Args: model (panda3d.core.NodePath): The locomotive model. Returns: (panda3d.core.AudioSound...): Interactive locomotive sounds. """ move_snd = base.sound_mgr.loadSfx( "sounds/train/ride.ogg") # noqa: F821 base.sound_mgr.attachSoundToObject(move_snd, model) # noqa: F821 move_snd.setLoop(True) move_snd.setVolume(0) move_snd.play() stop_snd = base.sound_mgr.loadSfx( "sounds/train/stop.ogg") # noqa: F821 base.sound_mgr.attachSoundToObject(stop_snd, model) # noqa: F821 brake_snd = base.sound_mgr.loadSfx( "sounds/train/brake.ogg") # noqa: F821 brake_snd.setLoop(True) base.sound_mgr.attachSoundToObject(brake_snd, model) # noqa: F821 return move_snd, stop_snd, brake_snd def start_move_sound(self): """Start playing the move sound.""" self._move_snd.setVolume(1) def _shot_flapper(self): """Play an effect and sound of a flapper.""" if not self._confetti_cooldown and self._confetti is not None: for effect in self._confetti: effect.start(self._model, render) # noqa: F821 effect.softStart() taskMgr.doMethodLater( # noqa: F821 1.97, self._stop_flapper, "stop_flapper") self._confetti_cooldown = True self._confetti_snd.play() def _stop_flapper(self, task): """Stop all the flapper effects.""" for effect in self._confetti or []: effect.softStop() self._confetti_cooldown = False return task.done def _stop_move(self): """Stop the Train movement.""" taskMgr.doMethodLater( # noqa: F821 0.6, self._stop_snd.play, "train_stop_snd", extraArgs=[]) base.train.stop_sparks() # noqa: F821 self._move_par.pause() self._move_anim_int.pause() taskMgr.doMethodLater( # noqa: F821 0.7, base.train.stop, "release_steam", extraArgs=[] # noqa: F821 ) self._is_stopped = True taskMgr.doMethodLater( # noqa: F821 0.07, drown_snd, "drown_move_snd", extraArgs=[self._move_snd], appendTask=True, ) if self._outing_available: base.world.start_outing(self._outing_available) # noqa: F821 self._outing_available = None def _switch_garland(self): """Christmas related method. Enables or removes the locomotive garland and an ability to shot a flapper. """ if self._garland is None: self._garland = loader.loadModel(address("garland")) # noqa: F821 self._garland.reparentTo(self._model) self._confetti = [] for color in ("red", "blue", "green"): confetti = ParticleEffect() confetti.loadConfig("effects/confetti_{}.ptf".format(color)) confetti.setPos(0, 0.32, 0.29) self._confetti.append(confetti) self._confetti_snd = base.sound_mgr.loadSfx( # noqa: F821 "sounds/train/flapper.ogg") base.sound_mgr.attachSoundToObject( # noqa: F821 self._confetti_snd, self._model) else: self._garland.removeNode() self._garland = None for effect in self._confetti: effect.softStop() effect.cleanup() self._confetti = None base.sound_mgr.detach_sound(self._confetti_snd) # noqa: F821 self._confetti_snd = None def brake_down_to(self, target): """Slow down the Train to the given speed. Args: target (float): Target speed. """ if self._brake_snd.status() == AudioSound.PLAYING: self._brake_snd.setVolume(1) else: self._brake_snd.play() taskMgr.doMethodLater( # noqa: F821 3, drown_snd, "drown_brake_snd", extraArgs=[self._brake_snd], appendTask=True, ) self.slow_down_to(target) def drown_move_snd(self): """Reduce the main move sound volume.""" if self._move_snd_volume == 1: self._move_snd.setVolume(0.5) self._move_snd_volume = 0.5 def move_along_block(self, block, train_np, do_turn): """Start the locomotive move intervals for the given block. There are two intervals: the locomotive movement and synchronous camera movement. Args: block (world.block.Block): The World block to move along. train_np (panda3d.core.NodePath): Train node. do_turn (int): 0 if default direction was chosen, 1 if a turn is needed. """ self.on_et = block.enemy_territory self._outing_available = block.outing_available # use speed value from the last block rate = self._move_par.getPlayRate() if self._move_par else 1 is_fork = block.name in ("r_fork", "l_fork", "exit_from_fork") self._move_par = Parallel( MopathInterval( # locomotive movement block.path[do_turn] if is_fork else block.path, self._model, duration=4.4, name="current_path", ), MopathInterval( # camera movement block.cam_path[do_turn] if is_fork else block.cam_path, train_np, duration=4.4, name="current_camera_path", ), ) self._move_par.setDoneEvent("block_finished") self._move_par.start() self._move_par.setPlayRate(rate) def load_speed(self, speed): """Load previously saved locomotive speed. Args: speed (float): Rate to set for animation, move and sounds. """ self._move_par.setPlayRate(speed) self._move_anim_int.setPlayRate(speed) self._move_snd.setPlayRate(min(max(0.25, speed * 1.2), 1)) if not speed: self._move_snd.stop() self._is_stopped = True def pause_movement(self): """Make a movement pause (used when a tutorial page is shown).""" self._move_par.pause() self._move_anim_int.pause() self._move_snd.stop() def set_controls(self, train): """Configure the locomotive control keys. Args: train (train.Train): The locomotive object. """ # speed smoothly changes while holding w/s keys base.accept("w", self._change_speed_delayed, [0.05]) # noqa: F821 base.accept("s", self._change_speed_delayed, [-0.05]) # noqa: F821 base.accept("w-up", taskMgr.remove, ["change_train_speed"]) # noqa: F821 base.accept("s-up", taskMgr.remove, ["change_train_speed"]) # noqa: F821 base.accept("7", self._switch_garland) # noqa: F821 base.accept("8", self._shot_flapper) # noqa: F821 base.accept("9", base.effects_mgr.love_fog.switch) # noqa: F821 base.accept("f", train.toggle_lights) # noqa: F821 def start_move(self): """Start the Train movement.""" self._move_par.resume() self._move_anim_int.resume() self._move_snd.play() self._is_stopped = False def speed_to_min(self): """Accelerate to minimum speed. Used when locomotive got on enemy territory. """ taskMgr.remove("change_train_speed") # noqa: F821 speed = self._move_anim_int.getPlayRate() if speed >= MIN_SPEED: return # calculate acceleration length acc_steps = (MIN_SPEED - speed) / 0.05 # start accelerating taskMgr.doMethodLater( # noqa: F821 0.6, self._change_speed, "speed_up_train", extraArgs=[0.05], appendTask=True) # stop accelerating taskMgr.doMethodLater( # noqa: F821 0.6 * acc_steps + 0.2, taskMgr.remove, # noqa: F821 "stop_speedind_up", extraArgs=["speed_up_train"], ) def slow_down_to(self, target): """Slow down the locomotive to the given speed. Args: target (float): Target speed. """ taskMgr.remove("change_train_speed") # noqa: F821 speed = self._move_anim_int.getPlayRate() if speed <= target: return # calculate deceleration length acc_steps = (speed - target) / 0.05 # start decelerating taskMgr.doMethodLater( # noqa: F821 0.6, self._change_speed, "slow_down_train", extraArgs=[-0.05], appendTask=True, ) # stop decelerating taskMgr.doMethodLater( # noqa: F821 0.6 * acc_steps + 0.2, taskMgr.remove, # noqa: F821 "stop_slowing_down", extraArgs=["slow_down_train"], ) def stop(self, urgent=False, place_of_interest=False): """Completely stop the locomotive. Args: urgent (bool): If True, deceleration speed will be much higher. Used for stopping in places of interest and cities. place_of_interest (bool): If True, that means the stop is initiated by a place of interest. """ base.ignore("w") # noqa: F821 base.ignore("s") # noqa: F821 taskMgr.remove("change_train_speed") # noqa: F821 delay = 0.25 if urgent else 0.6 # calculate deceleration length speed = self._move_anim_int.getPlayRate() taskMgr.doMethodLater( # noqa: F821 delay, self._change_speed, "stop_train", extraArgs=[-0.05], appendTask=True) if urgent: if place_of_interest: taskMgr.doMethodLater( # noqa: F821 delay * (speed / 0.05) + 0.8, base.scenario.start_chapter, # noqa: F821 "start_scenario_chapter", ) else: # stop decelerating taskMgr.doMethodLater( # noqa: F821 delay * (speed / 0.05) + 0.8, self._finish_stopping, "finish_stopping") taskMgr.doMethodLater( # noqa: F821 delay * (speed / 0.05) + 0.2, base.world.enemy.stop_ride_anim, # noqa: F821 "stop_riding", ) def raise_move_snd(self): """Restore full volume of the main move sound.""" if self._move_snd_volume == 0.5: self._move_snd.setVolume(1) self._move_snd_volume = 1 def silence_move_snd(self): """Silence the movement sound.""" self._stop_snd.setVolume(0) taskMgr.doMethodLater( # noqa: F821 0.1, drown_snd, "stop_snd", extraArgs=[self._move_snd], appendTask=True) def unset_controls(self): """Disable all the locomotive controls.""" for key in ("w", "s", "w-up", "s-up", "f"): base.ignore(key) # noqa: F821
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 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 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 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 DistributedTutorial(DistributedObject): notify = directNotify.newCategory('DistributedTutorial') GUIDE_NAME = 'Professor Prepostera' GUIDE_START_POS = (5, 10, -0.5) GUIDE_WATCH_POS = (12.4, 27.92, 0) GUIDE_WATCH_HPR = (41.63, 0, 0) GUIDE_INTRO_SPEECH = ['Hey, looks like you made it!', 'So, welcome to OToontown.', 'OToontown is short for Old Toontown, or Toontown from the past.', 'Not long ago, Toons used to live present day Toontown.', 'Unfortunately, the Cogs planned a mega-invasion that was sure to be a complete takeover of Toontown and make all Toons go sad for good.', "There was no way we could have let that happen, so we built a time machine, and sent every Toon back in time to OToontown, where Cogs didn't exist yet.", 'The Cogs completely took over present day Toontown, and turned it into what they wanted it to be - a business metropolis.', 'Toons happily live and play in OToontown now, but we want to learn about present day Toontown...', ' ...or as we now call it, CogTropolis.', "We've built time machines that send Toons back to CogTropolis to fight Cogs and to see what the Cogs have done.", "We know that the Cogs took over Toontown and turned it into a grey business city, but we don't know how they did it.", 'Shopkeepers around OToontown will reward you for finding evidence that may help solve the mystery of how the Cogs turned Toontown into CogTropolis.', 'Before you are able to head to CogTropolis, you need to be trained for battle.', 'The Cogs have become much more skilled battlers and no longer wait for you to throw a gag before attacking you.', 'This is much more difficult for Toons, and it may take some time to get used to.', "I'm going to give you 4 gags to start...", 'A Toon-Up megaphone, a cupcake, a fruit pie slice, and a cream pie slice.', 'Equip Gags in your loadout to use by pressing the corresponding key on your keyboard.', 'You can use or throw the Gag that you have equipped by pressing the Delete key...', ' ...or by pressing the Throw Gag button at the top of your screen.', 'Also, use the Arrow Keys on your keyboard to move, and press CTRL to jump.', "I'm going to summon one of our dummy bots for you to practice battling.", "Click your mouse when you're ready."] GUIDE_PT2_INFO = ["Now it'll get a tad bit tougher.", 'This next dummy bot will be walking around.', 'This will test your aiming skills.', "Click your mouse when you're ready."] GUIDE_PT3_INFO = ['This final dummy bot will walk around and try to attack you at times.', 'Defeat this Cog, and you should be ready to go.'] GUIDE_DONE = ['Wow, you did great!', "You're definitely ready for battle in CogTropolis.", 'Click your mouse to head to OToontown.'] GUIDE_START_TRAINING = "Alright! Let's do this!" def __init__(self, cr): DistributedObject.__init__(self, cr) self.fsm = ClassicFSM.ClassicFSM('TutorialFSM', [State.State('off', self.enterOff, self.exitOff), State.State('newPlayerEmerge', self.enterPlayerEmerge, self.exitPlayerEmerge, ['off', 'introSpeech']), State.State('introSpeech', self.enterGuideIntroSpeech, self.exitGuideIntroSpeech, ['off', 'introSpeech2Training']), State.State('introSpeech2Training', self.enterIntroSpeech2Training, self.exitIntroSpeech2Training, ['off', 'training1']), State.State('training1', self.enterTrainingPT1, self.exitTrainingPT1, ['off', 'training2info']), State.State('training2info', self.enterTraining2Info, self.exitTraining2Info, ['off', 'training2']), State.State('training2', self.enterTrainingPT2, self.exitTrainingPT2, ['off', 'training3info']), State.State('training3info', self.enterTraining3Info, self.exitTraining3Info, ['off', 'training3']), State.State('training3', self.enterTrainingPT3, self.exitTrainingPT3, ['off', 'trainingDone']), State.State('trainingDone', self.enterTrainingDone, self.exitTrainingDone, ['off', 'leaveTutorial']), State.State('leaveTutorial', self.enterLeaveTutorial, self.exitLeaveTutorial, ['off'])], 'off', 'off') self.fsm.enterInitialState() self.dnaStore = DNAStorage() self.streetGeom = None self.sky = None self.skyUtil = SkyUtil() self.guide = None self.music = None self.battleMusic = None self.playerCamPos = None self.playerCamHpr = None return def enterOff(self): pass def exitOff(self): pass def introStuff(self): base.localAvatar.getGeomNode().hide() base.localAvatar.setPos(0, 0, -0.5) base.localAvatar.setHpr(0, 0, 0) self.guide.setPos(self.GUIDE_START_POS) self.guide.headsUp(base.localAvatar) base.localAvatar.attachCamera() def enterPlayerEmerge(self): self.introStuff() self.guide.loop('neutral') base.transitions.irisIn() base.taskMgr.doMethodLater(1.0, self.__playerEmerge, 'playerEmergeTask') def __playerEmerge(self, task): base.localAvatar.setAnimState('teleportIn', callback=self.__playerEmergeFinished) return Task.done def __playerEmergeFinished(self): base.localAvatar.setAnimState('neutral') self.fsm.request('introSpeech') def exitPlayerEmerge(self): base.localAvatar.detachCamera() base.taskMgr.remove('playerEmergeTask') base.transitions.noTransitions() def enterGuideIntroSpeech(self): base.localAvatar.attachCamera() renderPos = base.camera.getPos(render) renderHpr = base.camera.getHpr(render) base.localAvatar.detachCamera() endPos = base.localAvatar.getPos(render) + (0, 0, 4) base.camera.setPos(endPos) base.camera.lookAt(self.guide, 0, 0, 3) endHpr = base.camera.getHpr(render) base.camera.setPos(renderPos) base.camera.setHpr(renderHpr) self.chatIndex = -1 self.doNextIntroSpeech() self.camMoveTrack = Sequence(Parallel(LerpPosInterval(base.camera, duration=3.0, pos=endPos, startPos=renderPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=3.0, hpr=endHpr, startHpr=renderHpr, blendType='easeOut')), Func(base.localAvatar.getGeomNode().hide)) self.camMoveTrack.start() def __finishedReadingGuideIntroSpeech(self): self.guide.autoClearChat = True self.guide.setChat(self.GUIDE_START_TRAINING) self.fsm.request('introSpeech2Training') def doNextIntroSpeech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_INTRO_SPEECH): self.__finishedReadingGuideIntroSpeech() return self.guide.setChat(self.GUIDE_INTRO_SPEECH[self.chatIndex]) Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextIntroSpeech)).start() def exitGuideIntroSpeech(self): self.camMoveTrack.finish() base.localAvatar.getGeomNode().show() del self.camMoveTrack del self.chatIndex def enterIntroSpeech2Training(self): startCamPos = base.camera.getPos(render) startCamHpr = base.camera.getHpr(render) base.camera.setPosHpr(0, 0, 0, 0, 0, 0) base.localAvatar.attachCamera() endCamPos = base.camera.getPos(render) endCamHpr = base.camera.getHpr(render) base.localAvatar.detachCamera() startHpr = self.guide.getHpr(render) self.guide.headsUp(self.GUIDE_WATCH_POS) endHpr = self.guide.getHpr(render) self.guide.loop('run') self.camMoveIval = Parallel(LerpPosInterval(base.camera, duration=2.0, pos=endCamPos, startPos=startCamPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=2.0, hpr=endCamHpr, startHpr=startCamHpr, blendType='easeOut'), Sequence(LerpPosInterval(self.guide, duration=2.0, pos=self.GUIDE_WATCH_POS, startPos=self.guide.getPos(render)), Func(self.guide.loop, 'walk'), LerpHprInterval(self.guide, duration=1.0, hpr=self.GUIDE_WATCH_HPR, startHpr=endHpr), Func(self.guide.loop, 'neutral')), LerpHprInterval(self.guide, duration=1.0, hpr=endHpr, startHpr=startHpr)) self.camMoveIval.setDoneEvent('introSpeech2TrainingDone') self.acceptOnce('introSpeech2TrainingDone', self.__handleIS2TDone) self.camMoveIval.start() def __handleIS2TDone(self): self.fsm.request('training1') def exitIntroSpeech2Training(self): self.ignore('introSpeech2TrainingDone') self.camMoveIval.finish() del self.camMoveIval def enterTrainingPT1(self): self.music.stop() base.playMusic(self.battleMusic, volume=0.8, looping=1) self.sendUpdate('makeSuit', [0]) base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.startBlink() base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.collisionsOn() base.localAvatar.enableAvatarControls() base.localAvatar.enablePies(1) Whisper().createSystemMessage('This should be pretty simple. Just throw a gag at this dummy bot to defeat it.') def suitNoHealth(self, index): if index == 0: Whisper().createSystemMessage('Good job, {0}!'.format(base.localAvatar.getName())) elif index == 1: Whisper().createSystemMessage("Wow, you're doing very well!") def suitExploded(self, index): if index == 0: Whisper().createSystemMessage('Pick up the jellybean that he dropped. You can use them to buy more gags for your Toon.') self.battleMusic.stop() base.playMusic(self.music, looping=1, volume=0.8) def pickedUpJellybean(self): if self.fsm.getCurrentState().getName() == 'training1': self.fsm.request('training2info') elif self.fsm.getCurrentState().getName() == 'training2': self.fsm.request('training3info') elif self.fsm.getCurrentState().getName() == 'training3': self.fsm.request('trainingDone') def exitTrainingPT1(self): base.localAvatar.lastState = None base.localAvatar.disableAvatarControls() base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopBlink() base.localAvatar.collisionsOff() base.localAvatar.controlManager.placeOnFloor() base.localAvatar.disablePies() return def enterTraining2Info(self): base.camera.setPos(3.09, 37.16, 3.93) base.camera.setHpr(225, 0, 0) self.guide.autoClearChat = False self.chatIndex = -1 self.doNextTraining2Speech() def __finishedReadingGuideTraining2Speech(self): self.guide.autoClearChat = True self.guide.clearChat() self.fsm.request('training2') def doNextTraining2Speech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_PT2_INFO): self.__finishedReadingGuideTraining2Speech() return self.guide.setChat(self.GUIDE_PT2_INFO[self.chatIndex]) Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining2Speech)).start() def exitTraining2Info(self): base.camera.setPosHpr(0, 0, 0, 0, 0, 0) del self.chatIndex def enterTrainingPT2(self): self.music.stop() base.playMusic(self.battleMusic, volume=0.8, looping=1) self.sendUpdate('makeSuit', [1]) base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.startBlink() base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.collisionsOn() base.localAvatar.enableAvatarControls() base.localAvatar.enablePies(1) def exitTrainingPT2(self): base.localAvatar.lastState = None base.localAvatar.disableAvatarControls() base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopBlink() base.localAvatar.collisionsOff() base.localAvatar.controlManager.placeOnFloor() base.localAvatar.disablePies() return def enterTraining3Info(self): base.camera.setPos(3.09, 37.16, 3.93) base.camera.setHpr(225, 0, 0) self.guide.autoClearChat = False self.chatIndex = -1 self.doNextTraining3Speech() def __finishedReadingGuideTraining3Speech(self): self.guide.autoClearChat = True self.guide.clearChat() self.fsm.request('training3') def doNextTraining3Speech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_PT3_INFO): self.__finishedReadingGuideTraining3Speech() return self.guide.setChat(self.GUIDE_PT3_INFO[self.chatIndex]) Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining3Speech)).start() def exitTraining3Info(self): base.camera.setPosHpr(0, 0, 0, 0, 0, 0) del self.chatIndex def enterTrainingPT3(self): self.music.stop() base.playMusic(self.battleMusic, volume=0.8, looping=1) self.sendUpdate('makeSuit', [2]) base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.startBlink() base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.collisionsOn() base.localAvatar.enableAvatarControls() base.localAvatar.enablePies(1) def exitTrainingPT3(self): base.localAvatar.lastState = None base.localAvatar.disableAvatarControls() base.localAvatar.detachCamera() base.localAvatar.stopSmartCamera() base.localAvatar.stopPosHprBroadcast() base.localAvatar.stopBlink() base.localAvatar.collisionsOff() base.localAvatar.controlManager.placeOnFloor() base.localAvatar.disablePies() return def enterTrainingDone(self): base.camera.setPos(3.09, 37.16, 3.93) base.camera.setHpr(225, 0, 0) self.guide.autoClearChat = False self.chatIndex = -1 self.doNextTrainingDoneSpeech() def __finishedReadingGuideTrainingDoneSpeech(self): self.guide.autoClearChat = True self.guide.clearChat() self.fsm.request('leaveTutorial') def doNextTrainingDoneSpeech(self): self.chatIndex += 1 if self.chatIndex >= len(self.GUIDE_DONE): self.__finishedReadingGuideTrainingDoneSpeech() return self.guide.setChat(self.GUIDE_DONE[self.chatIndex]) Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTrainingDoneSpeech)).start() def exitTrainingDone(self): base.camera.setPosHpr(0, 0, 0, 0, 0, 0) del self.chatIndex def enterLeaveTutorial(self): base.localAvatar.attachCamera() base.localAvatar.startSmartCamera() base.localAvatar.b_setAnimState('teleportOut', callback=self.__teleOutDone) def __teleOutDone(self): zoneId = CIGlobals.ToontownCentralId hoodId = CIGlobals.ToontownCentral whereName = 'playground' avId = base.localAvatar.doId loaderName = 'safeZoneLoader' self.sendUpdate('finishedTutorial') self.cr.playGame.fsm.request('quietZone', [{'zoneId': zoneId, 'hoodId': hoodId, 'where': whereName, 'how': 'teleportIn', 'avId': avId, 'shardId': None, 'loader': loaderName}]) return def exitLeaveTutorial(self): base.localAvatar.stopSmartCamera() base.localAvatar.detachCamera() def announceGenerate(self): DistributedObject.announceGenerate(self) base.transitions.fadeScreen(0.0) self.guide = Toon(base.cr) self.guide.autoClearChat = False self.guide.parseDNAStrand(NPCGlobals.NPC_DNA[self.GUIDE_NAME]) self.guide.setName(self.GUIDE_NAME) self.guide.generateToon() self.guide.startBlink() self.guide.reparentTo(render) base.localAvatar.reparentTo(render) loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_tutorial.dna') node = loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/tutorial_street.dna') if node.getNumParents() == 1: self.streetGeom = NodePath(node.getParent(0)) self.streetGeom.reparentTo(hidden) else: self.streetGeom = hidden.attachNewNode(node) self.streetGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.streetGeom.prepareScene(gsg) self.streetGeom.reparentTo(render) self.streetGeom.setPos(20.5, -20, 0) self.streetGeom.setH(90) self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam') self.skyUtil.startSky(self.sky) self.sky.reparentTo(camera) ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ) self.sky.node().setEffect(ce) self.music = base.loadMusic('phase_3.5/audio/bgm/TC_SZ.mid') base.playMusic(self.music, volume=0.8, looping=1) self.battleMusic = base.loadMusic('phase_3.5/audio/bgm/encntr_general_bg.mid') self.fsm.request('newPlayerEmerge') base.localAvatar.inTutorial = True def disable(self): self.fsm.requestFinalState() del self.fsm if self.guide: self.guide.disable() self.guide.delete() self.guide = None if self.streetGeom: self.streetGeom.removeNode() self.streetGeom = None if self.sky: self.sky.removeNode() self.sky = None if self.music: self.music.stop() self.music = None if self.battleMusic: self.battleMusic.stop() self.battleMusic = None self.dnaStore = None self.skyUtil = None base.localAvatar.inTutorial = False DistributedObject.disable(self) return