from direct.showbase.ShowBaseGlobal import * from toontown.toonbase.ToonBaseGlobal import * from direct.interval.IntervalGlobal import * from toontown.toonbase import ToontownTimer from DistributedMinigame import * from direct.distributed.ClockDelta import * from direct.fsm import ClassicFSM from direct.fsm import State from direct.task import Task from direct.actor import Actor from toontown.toon import LaffMeter from direct.distributed import DistributedSmoothNode import ArrowKeys import Ring import RingTrack import DivingGameGlobals import RingGroup import RingTrackGroups import random import DivingGameToonSD import DivingFishSpawn import DivingTreasure import math import TreasureScorePanel from otp.distributed.TelemetryLimiter import TelemetryLimiter, TLGatherAllAvs from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer class DivingGameRotationLimiter(TelemetryLimiter): def __init__(self, h, p): self._h = h self._p = p def __call__(self, obj): obj.setHpr(self._h, self._p, obj.getR()) class DistributedDivingGame(DistributedMinigame): COLLISION_WATCH_TASK = 'DivingGameCollisionWatchTask' TREASURE_BOUNDS_TASK = 'DivingGameTreasureBoundsTask' CRAB_TASK = 'DivingGameCrabTask' UPDATE_LOCALTOON_TASK = 'DivingGameUpdateLocalToonTask' COLLISION_DETECTION_PRIORITY = 5 MAP_DIV = 2.8 MAP_OFF = 14.0 LAG_COMP = 1.25 def __init__(self, cr): DistributedMinigame.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedDivingGame', [State.State('off', self.enterOff, self.exitOff, ['swim']), State.State('swim', self.enterSwim, self.exitSwim, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.iCount = 0 self.reachedFlag = 0 self.grabbingTreasure = -1 self.dead = 0 def getTitle(self): return TTLocalizer.DivingGameTitle def getInstructions(self): p = self.avIdList.index(self.localAvId) if self.isSinglePlayer(): text = TTLocalizer.DivingInstructionsSinglePlayer else: text = TTLocalizer.DivingInstructionsMultiPlayer return text def load(self): self.notify.debug('load') DistributedMinigame.load(self) loadBase = 'phase_4/models/minigames/' loadBaseShip = 'phase_5/models/props/' self.sndAmbience = base.loadSfx('phase_4/audio/sfx/AV_ambient_water.ogg') self.environModel = loader.loadModel(loadBase + 'diving_game.bam') self.boatModel = self.environModel.find('**/boat') self.skyModel = self.environModel.find('**/sky') self.waterModel = self.environModel.find('**/seawater') self.frontMap = self.environModel.find('**/sea_front') self.frontMap.setY(3) self.frontMap.setBin('fixed', 0) self.frontMap.setDepthTest(0) self.waterModel.setY(1.0) bubbleModel = self.environModel.find('**/bubbles1') bubbleModel.setY(1.0) bubbleModel = self.environModel.find('**/bubbles2') bubbleModel.setY(1.0) bubbleModel = self.environModel.find('**/bubbles3') bubbleModel.setY(1.0) bubbleModel = self.environModel.find('**/bubbles4') bubbleModel.setY(1.0) bubbleModel = self.environModel.find('**/bubbles5') bubbleModel.setY(1.0) self.mapModel = loader.loadModel(loadBase + 'diving_game.bam') boatMap = self.mapModel.find('**/boat') skyMap = self.mapModel.find('**/sky') frontMap = self.mapModel.find('**/sea_front') skyMap.hide() frontMap.hide() boatMap.setZ(28.5) self.crabs = [] self.spawners = [] self.toonSDs = {} avId = self.localAvId toonSD = DivingGameToonSD.DivingGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() crabSoundName = 'King_Crab.ogg' crabSoundPath = 'phase_4/audio/sfx/%s' % crabSoundName self.crabSound = loader.loadSfx(crabSoundPath) treasureSoundName = 'SZ_DD_treasure.ogg' treasureSoundPath = 'phase_4/audio/sfx/%s' % treasureSoundName self.treasureSound = loader.loadSfx(treasureSoundPath) hitSoundName = 'diving_game_hit.ogg' hitSoundPath = 'phase_4/audio/sfx/%s' % hitSoundName self.hitSound = loader.loadSfx(hitSoundPath) self.music = base.loadMusic('phase_4/audio/bgm/MG_Target.ogg') self.addSound('dropGold', 'diving_treasure_drop_off.ogg', 'phase_4/audio/sfx/') self.addSound('getGold', 'diving_treasure_pick_up.ogg', 'phase_4/audio/sfx/') self.swimSound = loader.loadSfx('phase_4/audio/sfx/diving_swim_loop.ogg') self.swimSound.setVolume(0.0) self.swimSound.setPlayRate(1.0) self.swimSound.setLoop(True) self.swimSound.play() def addSound(self, name, soundName, path = None): if not hasattr(self, 'soundTable'): self.soundTable = {} if path: self.soundPath = path soundSource = '%s%s' % (self.soundPath, soundName) self.soundTable[name] = loader.loadSfx(soundSource) def playSound(self, name, volume = 1.0): self.soundTable[name].setVolume(1.0) self.soundTable[name].play() def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) self.mapModel.removeNode() del self.mapModel if hasattr(self, 'soundTable'): del self.soundTable del self.sndAmbience del self.hitSound del self.crabSound del self.treasureSound self.swimSound.stop() del self.swimSound self.environModel.removeNode() del self.environModel self.removeChildGameFSM(self.gameFSM) for avId in self.toonSDs.keys(): toonSD = self.toonSDs[avId] toonSD.unload() del self.toonSDs del self.gameFSM del self.music def fishCollision(self, collEntry): avId = int(collEntry.getFromNodePath().getName()) toonSD = self.toonSDs[avId] name = collEntry.getIntoNodePath().getName() if len(name) >= 7: if name[0:6] == 'crabby': self.sendUpdate('handleCrabCollision', [avId, toonSD.status]) else: spawnerId = int(name[2]) spawnId = int(name[3:len(name)]) if spawnId in self.spawners[spawnerId].fishArray: self.sendUpdate('handleFishCollision', [avId, spawnId, spawnerId, toonSD.status]) def fishSpawn(self, timestamp, fishcode, spawnerId, offset): if self.dead is 1: return ts = globalClockDelta.localElapsedTime(timestamp) if not hasattr(self, 'spawners'): return if abs(self.spawners[spawnerId].lastSpawn - timestamp) < 150: return fish = self.spawners[spawnerId].createFish(fishcode) fish.offset = offset fish.setPos(self.spawners[spawnerId].position) func = Func(self.fishRemove, fish.code) self.spawners[spawnerId].lastSpawn = timestamp iName = '%s %s' % (fish.name, self.iCount) self.iCount += 1 if fish.name == 'clown': fish.moveLerp = Sequence(LerpPosInterval(fish, duration=8 * self.SPEEDMULT * self.LAG_COMP, startPos=self.spawners[spawnerId].position, pos=self.spawners[spawnerId].position + Point3(50 * self.spawners[spawnerId].direction, 0, (offset - 4) / 2.0), name=iName), func) fish.specialLerp = Sequence() elif fish.name == 'piano': fish.moveLerp = Sequence(LerpPosInterval(fish, duration=5 * self.SPEEDMULT * self.LAG_COMP, startPos=self.spawners[spawnerId].position, pos=self.spawners[spawnerId].position + Point3(50 * self.spawners[spawnerId].direction, 0, (offset - 4) / 2.0), name=iName), func) fish.specialLerp = Sequence() elif fish.name == 'pbj': fish.moveLerp = Sequence(LerpFunc(fish.setX, duration=12 * self.SPEEDMULT * self.LAG_COMP, fromData=self.spawners[spawnerId].position.getX(), toData=self.spawners[spawnerId].position.getX() + 50 * self.spawners[spawnerId].direction, name=iName), func) fish.specialLerp = LerpFunc(self.pbjMove, duration=5 * self.SPEEDMULT * self.LAG_COMP, fromData=0, toData=2.0 * 3.14159, extraArgs=[fish, self.spawners[spawnerId].position.getZ()], blendType='easeInOut') elif fish.name == 'balloon': fish.moveLerp = Sequence(LerpPosInterval(fish, duration=10 * self.SPEEDMULT * self.LAG_COMP, startPos=self.spawners[spawnerId].position, pos=self.spawners[spawnerId].position + Point3(50 * self.spawners[spawnerId].direction, 0, (offset - 4) / 2.0), name=iName), func) fish.specialLerp = Sequence(Wait(offset / 10.0 * 2 + 1.5), Parallel(LerpScaleInterval(fish, duration=0.3, startScale=Vec3(2, 2, 2), scale=Vec3(5, 3, 5), blendType='easeInOut')), Wait(1.0), Parallel(LerpScaleInterval(fish, duration=0.4, startScale=Vec3(5, 3, 5), scale=Vec3(2, 2, 2), blendType='easeInOut'))) elif fish.name == 'bear' or fish.name == 'nurse': fish.moveLerp = Sequence(LerpPosInterval(fish, duration=20 * self.LAG_COMP, startPos=self.spawners[spawnerId].position, pos=self.spawners[spawnerId].position + Point3(50 * self.spawners[spawnerId].direction, 0, 0), name=iName), func) fish.specialLerp = Sequence() fish.moveLerp.start(ts) fish.specialLerp.loop(ts) def pbjMove(self, x, fish, Z): z = math.sin(x + fish.offset * 3) * 3 fish.setZ(z + Z) def getIntroMovie(self): seq = Sequence() seq.append(Wait(2.0)) seq.append(LerpFunc(camera.setZ, duration=5, fromData=36, toData=-23, blendType='easeInOut', name='intro')) seq.append(Wait(2.0)) seq.append(LerpFunc(camera.setZ, duration=5, fromData=-23, toData=36 + 3, blendType='easeInOut', name='intro')) return seq def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) base.localAvatar.collisionsOff() DistributedSmoothNode.activateSmoothing(1, 1) numToons = self.numPlayers self.NUMTREASURES = numToons camera.reparentTo(render) camera.setZ(36) camera.setHpr(0,0,0) camera.setX(0) base.camLens.setMinFov(31/(4./3.)) camera.setY(-54) base.camLens.setFar(1500) self.introMovie = self.getIntroMovie() self.introMovie.start() self.accept('FishHit', self.fishCollision) toonSD = self.toonSDs[self.localAvId] toonSD.enter() toonSD.fsm.request('normal') toon = base.localAvatar toon.reparentTo(render) toon.setPos(-9, -1, 36) self.__placeToon(self.localAvId) self.arrowKeys = ArrowKeys.ArrowKeys() self.xVel = 0 self.zVel = 0 self.orientNode = toon.attachNewNode('orientNode') self.orientNode.setPos(0, 0, 1) self.orientNode2 = toon.attachNewNode('orientNode') self.orientNode2.setPos(0, 0, -1) self.environNode = render.attachNewNode('environNode') self.environModel.reparentTo(self.environNode) self.environModel.setScale(2.8, 2.8, 2.73) self.environModel.setPos(0, 0.5, -41) self.skyModel.setScale(1.3, 1.0, 1.0) boatoff = 6.75 self.boatModel.reparentTo(self.environNode) self.boatModel.setPos(0, 3.0, 40 - boatoff) self.boatModel.setScale(2.8) cSphere = CollisionSphere(0.0, 0.0, 0.0 + 2.0, 3.0) cSphere.setTangible(0) name = 'boat' cSphereNode = CollisionNode(name) cSphereNode.setIntoCollideMask(DivingGameGlobals.CollideMask) cSphereNode.addSolid(cSphere) self.boatNode = cSphereNode self.boatCNP = self.boatModel.attachNewNode(cSphereNode) self.accept('reach-boat', self.__boatReached) self.boatTilt = Sequence(LerpFunc(self.boatModel.setR, duration=5, fromData=5, toData=-5, blendType='easeInOut', name='tilt'), LerpFunc(self.boatModel.setR, duration=5, fromData=-5, toData=5, blendType='easeInOut', name='tilt')) self.boatTilt.loop() self.mapScaleRatio = 40 self.mapModel.reparentTo(base.a2dTopRight) self.mapModel.setScale(1.0 / self.mapScaleRatio) self.mapModel.setTransparency(1) self.mapModel.setPos(-0.22, 0.0, -1.30) self.mapModel.setColorScale(1, 1, 1, 0.7) self.mapModel.hide() if self.sndAmbience: self.sndAmbience.setLoop(True) self.sndAmbience.play() self.sndAmbience.setVolume(0.01) return def offstage(self): self.notify.debug('offstage') DistributedMinigame.offstage(self) self.introMovie.finish() self.boatTilt.finish() self.mapModel.hide() DistributedSmoothNode.activateSmoothing(1, 0) for avId in self.toonSDs.keys(): self.toonSDs[avId].exit() base.camLens.setFar(ToontownGlobals.DefaultCameraFar) base.camLens.setMinFov(ToontownGlobals.DefaultCameraFov/(4./3.)) base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) self.arrowKeys.destroy() del self.arrowKeys self.environNode.removeNode() del self.environNode if None != self.sndAmbience: self.sndAmbience.stop() for avId in self.avIdList: av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() av.setAnimState('neutral', 1.0) self.dead = 1 self.__killCrabTask() for spawner in self.spawners: spawner.destroy() del spawner del self.spawners for crab in self.crabs: crab.moveLerp.finish() crab.moveLerp = None crab.removeNode() del crab if hasattr(self, 'treasures') and self.treasures: for i in xrange(self.NUMTREASURES): self.treasures[i].destroy() del self.treasures if hasattr(self, 'cSphereNodePath1'): self.cSphereNodePath1.removeNode() del self.cSphereNodePath1 if hasattr(self, 'cSphereNodePath1'): self.cSphereNodePath2.removeNode() del self.cSphereNodePath2 if hasattr(self, 'remoteToonCollNPs'): for np in self.remoteToonCollNPs.values(): np.removeNode() del self.remoteToonCollNPs self.pusher = None self.cTrav = None self.cTrav2 = None base.localAvatar.collisionsOn() return def handleDisabledAvatar(self, avId): self.dead = 1 self.notify.debug('handleDisabledAvatar') self.notify.debug('avatar ' + str(avId) + ' disabled') self.toonSDs[avId].exit(unexpectedExit=True) del self.toonSDs[avId] def __placeToon(self, avId): toon = self.getAvatar(avId) i = self.avIdList.index(avId) numToons = float(self.numPlayers) x = -10 + i * 5 toon.setPos(x, -1, 36) toon.setHpr(180, 180, 0) def getTelemetryLimiter(self): return TLGatherAllAvs('DivingGame', Functor(DivingGameRotationLimiter, 180, 180)) def setGameReady(self): self.notify.debug('setGameReady') if not self.hasLocalToon: return if DistributedMinigame.setGameReady(self): return self.dead = 0 self.difficultyPatterns = {ToontownGlobals.ToontownCentral: [1, 1.5, 65, 3], ToontownGlobals.DonaldsDock: [1, 1.3, 65, 1], ToontownGlobals.DaisyGardens: [2, 1.2, 65, 1], ToontownGlobals.MinniesMelodyland: [2, 1.0, 65, 1], ToontownGlobals.TheBrrrgh: [3, 1.0, 65, 1], ToontownGlobals.DonaldsDreamland: [3, 1.0, 65, 1]} pattern = self.difficultyPatterns[self.getSafezoneId()] self.NUMCRABS = pattern[0] self.SPEEDMULT = pattern[1] self.TIME = pattern[2] loadBase = 'phase_4/models/char/' for i in xrange(self.NUMCRABS): self.crabs.append(Actor.Actor(loadBase + 'kingCrab-zero.bam', {'anim': loadBase + 'kingCrab-swimLOOP.bam'})) for i in xrange(len(self.crabs)): crab = self.crabs[i] crab.reparentTo(render) crab.name = 'king' crab.crabId = i cSphere = CollisionSphere(0.0, 0.0, 1, 1.3) cSphereNode = CollisionNode('crabby' + str(i)) cSphereNode.addSolid(cSphere) cSphereNode.setFromCollideMask(BitMask32.allOff()) cSphereNode.setIntoCollideMask(DivingGameGlobals.CollideMask) cSphereNodePath = crab.attachNewNode(cSphereNode) cSphereNodePath.setScale(1, 3, 1) self.accept('hitby-' + 'crabby' + str(i), self.fishCollision) if i % 2 is 0: crab.setPos(20, 0, -40) crab.direction = -1 else: crab.setPos(-20, 0, -40) crab.direction = 1 crab.loop('anim') crab.setScale(1, 0.3, 1) crab.moveLerp = Sequence() self.collHandEvent = CollisionHandlerEvent() self.cTrav = CollisionTraverser('DistributedDiverGame') self.cTrav2 = CollisionTraverser('DistributedDiverGame') self.collHandEvent.addInPattern('reach-%in') self.collHandEvent.addAgainPattern('reach-%in') self.collHandEvent.addInPattern('into-%in') self.collHandEvent.addInPattern('hitby-%in') loadBase = 'phase_4/models/minigames/' self.treasures = [] self.chestIcons = {} for i in xrange(self.NUMTREASURES): self.chestIcons[i] = loader.loadModel(loadBase + 'treasure_chest.bam') self.chestIcons[i].reparentTo(self.mapModel) self.chestIcons[i].setScale(1.5) treasure = DivingTreasure.DivingTreasure(i) self.accept('grab-' + str(i), self.__treasureGrabbed) self.collHandEvent.addInPattern('grab-%in') self.collHandEvent.addAgainPattern('grab-%in') self.treasures.append(treasure) self.cTrav.traverse(render) spawnX = 24 * self.LAG_COMP spawnY = 0.6 self.spawners.append(DivingFishSpawn.DivingFishSpawn(0, 1, Point3(-spawnX, spawnY, 25), self.collHandEvent)) self.spawners.append(DivingFishSpawn.DivingFishSpawn(1, -1, Point3(spawnX, spawnY, 16), self.collHandEvent)) self.spawners.append(DivingFishSpawn.DivingFishSpawn(2, 1, Point3(-spawnX, spawnY, 6), self.collHandEvent)) self.spawners.append(DivingFishSpawn.DivingFishSpawn(3, -1, Point3(spawnX, spawnY, -4), self.collHandEvent)) self.spawners.append(DivingFishSpawn.DivingFishSpawn(4, 1, Point3(-spawnX, spawnY, -15), self.collHandEvent)) self.spawners.append(DivingFishSpawn.DivingFishSpawn(5, -1, Point3(spawnX, spawnY, -23), self.collHandEvent)) for spawner in self.spawners: spawner.lastSpawn = 0 cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.4) cSphereNode = CollisionNode('%s' % self.localAvId) cSphereNode.addSolid(cSphere) cSphereNode.setFromCollideMask(DivingGameGlobals.CollideMask) cSphereNode.setIntoCollideMask(BitMask32.allOff()) headparts = base.localAvatar.getHeadParts() pos = headparts[2].getPos() self.cSphereNodePath1 = base.localAvatar.attachNewNode(cSphereNode) self.cSphereNodePath1.setPos(pos + Point3(0, 1.5, 1)) self.cTrav.addCollider(self.cSphereNodePath1, self.collHandEvent) cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.4) cSphereNode = CollisionNode('%s' % self.localAvId) cSphereNode.addSolid(cSphere) cSphereNode.setFromCollideMask(DivingGameGlobals.CollideMask) cSphereNode.setFromCollideMask(BitMask32.allOff()) cSphereNode.setIntoCollideMask(BitMask32.allOff()) headparts = base.localAvatar.getHeadParts() pos = headparts[2].getPos() self.cSphereNodePath2 = base.localAvatar.attachNewNode(cSphereNode) self.cSphereNodePath2.setPos(pos + Point3(0, 1.5, -1)) self.cTrav.addCollider(self.cSphereNodePath2, self.collHandEvent) self.pusher = CollisionHandlerPusher() self.pusher.addCollider(self.cSphereNodePath1, base.localAvatar) self.pusher.addCollider(self.cSphereNodePath2, base.localAvatar) self.pusher.setHorizontal(0) self.cTrav2.addCollider(self.cSphereNodePath1, self.pusher) self.cTrav2.addCollider(self.cSphereNodePath2, self.pusher) self.remoteToonCollNPs = {} for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: headparts = toon.getHeadParts() pos = headparts[2].getPos() cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.4) cSphereNode = CollisionNode('%s' % avId) cSphereNode.addSolid(cSphere) cSphereNode.setCollideMask(DivingGameGlobals.CollideMask) cSphereNP = toon.attachNewNode(cSphereNode) cSphereNP.setPos(pos + Point3(0, 1.5, 1)) self.remoteToonCollNPs[int(str(avId) + str(1))] = cSphereNP cSphere = CollisionSphere(0.0, 0.0, 0.0, 1.4) cSphereNode = CollisionNode('%s' % avId) cSphereNode.addSolid(cSphere) cSphereNode.setCollideMask(DivingGameGlobals.CollideMask) cSphereNP = toon.attachNewNode(cSphereNode) cSphereNP.setPos(pos + Point3(0, 1.5, -1)) self.remoteToonCollNPs[int(str(avId) + str(1))] = cSphereNP toonSD = DivingGameToonSD.DivingGameToonSD(avId, self) self.toonSDs[avId] = toonSD toonSD.load() toonSD.enter() toonSD.fsm.request('normal') for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.reparentTo(render) self.__placeToon(avId) toon.startSmooth() self.remoteToons = {} for avId in self.remoteAvIdList: toon = self.getAvatar(avId) self.remoteToons[avId] = toon def setGameStart(self, timestamp): if not self.hasLocalToon: return DistributedMinigame.setGameStart(self, timestamp) self.notify.debug('setGameStart') self.treasurePanel = TreasureScorePanel.TreasureScorePanel() self.treasurePanel.setPos(0.145, 0, -0.27) self.treasurePanel.reparentTo(base.a2dTopLeft) self.treasurePanel.makeTransparent(0.7) self.introMovie.finish() self.gameFSM.request('swim') def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterSwim(self): self.notify.debug('enterSwim') base.playMusic(self.music, looping=1, volume=0.9) self.localLerp = Sequence() self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.setTime(self.TIME) self.timer.countdown(self.TIME, self.timerExpired) self.mapModel.show() self.mapAvatars = {} avatarScale = 0.025 * self.mapScaleRatio for avId in self.remoteAvIdList: avatar = base.cr.doId2do.get(avId, False) if avatar != False: self.mapAvatars[avId] = LaffMeter.LaffMeter(avatar.style, avatar.hp, avatar.maxHp) self.mapAvatars[avId].reparentTo(self.mapModel) self.mapAvatars[avId].setScale(avatarScale) self.mapAvatars[avId].start() avatar = base.cr.doId2do[self.localAvId] self.mapAvatars[self.localAvId] = LaffMeter.LaffMeter(avatar.style, avatar.hp, avatar.maxHp) self.mapAvatars[self.localAvId].reparentTo(self.mapModel) self.mapAvatars[self.localAvId].setScale(avatarScale) self.mapAvatars[self.localAvId].start() self.accept('resetClock', self.__resetClock) self.__spawnUpdateLocalToonTask() self.__spawnCrabTask() self.__spawnTreasureBoundsTask() def __resetClock(self, tOffset): self.notify.debug('resetClock') self.gameStartTime += tOffset self.timer.countdown(self.timer.currentTime + tOffset, self.timerExpired) def timerExpired(self): self.notify.debug('local timer expired') self.dead = 1 self.gameOver() def __initPosBroadcast(self): self.__posBroadcastPeriod = 0.2 self.__timeSinceLastPosBroadcast = 0.0 self.__lastPosBroadcast = self.getAvatar(self.localAvId).getPos() self.__storeStop = 0 lt = self.getAvatar(self.localAvId) lt.d_clearSmoothing() lt.sendCurrentPosition() def __posBroadcast(self, dt): self.__timeSinceLastPosBroadcast += dt if self.__timeSinceLastPosBroadcast > self.__posBroadcastPeriod: self.__timeSinceLastPosBroadcast -= self.__posBroadcastPeriod self.getAvatar(self.localAvId).cnode.broadcastPosHprFull() def __spawnTreasureBoundsTask(self): taskMgr.remove(self.TREASURE_BOUNDS_TASK) taskMgr.add(self.__treasureBoundsTask, self.TREASURE_BOUNDS_TASK) def __killTreasureBoundsTask(self): taskMgr.remove(self.TREASURE_BOUNDS_TASK) def __treasureBoundsTask(self, task): for i in xrange(self.NUMTREASURES): self.chestIcons[i].setPos(self.treasures[i].chest.getPos(render) / self.MAP_DIV) self.chestIcons[i].setZ(self.chestIcons[i].getZ() + self.MAP_OFF) if self.treasures[i].treasureNode.getZ() < -36: self.treasures[i].treasureNode.setZ(-36) if self.treasures[i].treasureNode.getX() < -20: self.treasures[i].treasureNode.setX(-20) if self.treasures[i].treasureNode.getX() > 20: self.treasures[i].treasureNode.setX(20) return Task.cont def incrementScore(self, avId, newSpot, timestamp): if not self.hasLocalToon: return newSpot += -15 ts = globalClockDelta.localElapsedTime(timestamp) toonSD = self.toonSDs[avId] if avId == self.localAvId: self.reachedFlag = 0 if toonSD.status == 'treasure' and self.treasures and self.chestIcons: for i in xrange(self.NUMTREASURES): if self.treasures[i].grabbedId == avId: self.treasures[i].treasureNode.wrtReparentTo(render) self.treasures[i].grabbedId = 0 seq = Sequence() shrink = LerpScaleInterval(self.treasures[i].treasureNode, duration=1.0, startScale=self.treasures[i].treasureNode.getScale(), scale=Vec3(0.001, 0.001, 0.001), blendType='easeIn') shrinkIcon = LerpScaleInterval(self.chestIcons[i], duration=1.0, startScale=self.chestIcons[i].getScale(), scale=Vec3(0.001, 0.001, 0.001), blendType='easeIn') jump = ProjectileInterval(self.treasures[i].treasureNode, duration=1.0, startPos=self.treasures[i].treasureNode.getPos(), endPos=Point3(0, 0, 40), gravityMult=0.7) shrinkJump = Parallel(shrink, shrinkIcon, jump) toonSD.fsm.request('normal') grow = LerpScaleInterval(self.treasures[i].treasureNode, duration=1.0, scale=self.treasures[i].treasureNode.getScale(), startScale=Vec3(0.001, 0.001, 0.001), blendType='easeIn') growIcon = LerpScaleInterval(self.chestIcons[i], duration=1.0, scale=self.chestIcons[i].getScale(), startScale=Vec3(0.001, 0.001, 0.001), blendType='easeIn') place = Parallel(Func(self.treasures[i].treasureNode.setPos, Vec3(newSpot, 0.25, -36)), Func(self.treasures[i].treasureNode.setHpr, Vec3(0, 0, 0))) growItems = Parallel(grow, growIcon) resetChest = Func(self.treasures[i].chestNode.setIntoCollideMask, DivingGameGlobals.CollideMask) seq = Sequence(shrinkJump, Wait(1.5), place, growItems, resetChest) self.treasures[i].moveLerp.pause() self.treasures[i].moveLerp = seq self.treasures[i].moveLerp.start(ts) self.playSound('dropGold') self.treasurePanel.incrScore() def __boatReached(self, collEntry): toonSD = self.toonSDs[self.localAvId] if toonSD.status == 'treasure' and not self.reachedFlag: self.sendUpdate('treasureRecovered') self.reachedFlag = 1 def __treasureGrabbed(self, collEntry): avId = int(collEntry.getFromNodePath().getName()) chestId = int(collEntry.getIntoNodePath().getName()) toonSD = self.toonSDs[avId] if toonSD.status == 'normal' and self.grabbingTreasure == -1: self.grabbingTreasure = chestId self.sendUpdate('pickupTreasure', [chestId]) def setTreasureDropped(self, avId, timestamp): if not hasattr(self, 'treasures'): return ts = globalClockDelta.localElapsedTime(timestamp) for i in xrange(self.NUMTREASURES): if self.treasures[i].grabbedId == avId: self.treasures[i].grabbedId = 0 toonSD = self.toonSDs[avId] dist = abs(36.0 + self.treasures[i].treasureNode.getZ(render)) delta = dist / 72.0 dur = 10 * delta self.treasures[i].treasureNode.wrtReparentTo(render) self.treasures[i].chestNode.setIntoCollideMask(BitMask32.allOff()) resetChest = Func(self.treasures[i].chestNode.setIntoCollideMask, DivingGameGlobals.CollideMask) self.treasures[i].moveLerp.pause() self.treasures[i].moveLerp = Parallel(Sequence(Wait(1.0), resetChest), LerpFunc(self.treasures[i].treasureNode.setZ, duration=dur, fromData=self.treasures[i].treasureNode.getZ(render), toData=-36, blendType='easeIn')) self.treasures[i].moveLerp.start(ts) def performCrabCollision(self, avId, timestamp): if not self.hasLocalToon: return ts = globalClockDelta.localElapsedTime(timestamp) toonSD = self.toonSDs[avId] toon = self.getAvatar(avId) distance = base.localAvatar.getDistance(toon) volume = 0 soundRange = 15.0 if distance < soundRange: volume = (soundRange - distance) / soundRange if toonSD.status == 'normal' or toonSD.status == 'treasure': self.localLerp.finish() self.localLerp = Sequence(Func(toonSD.fsm.request, 'freeze'), Wait(3.0), Func(toonSD.fsm.request, 'normal')) self.localLerp.start(ts) self.hitSound.play() self.hitSound.setVolume(volume) def performFishCollision(self, avId, spawnId, spawnerId, timestamp): if not hasattr(self, 'spawners'): return toonSD = self.toonSDs[avId] ts = globalClockDelta.localElapsedTime(timestamp) toon = self.getAvatar(avId) distance = base.localAvatar.getDistance(toon) volume = 0 soundRange = 15.0 if distance < soundRange: volume = (soundRange - distance) / soundRange if toonSD.status == 'normal' or toonSD.status == 'treasure': self.localLerp.finish() self.localLerp = Sequence(Func(toonSD.fsm.request, 'freeze'), Wait(3.0), Func(toonSD.fsm.request, 'normal')) self.localLerp.start(ts) if spawnId in self.spawners[spawnerId].fishArray: fish = self.spawners[spawnerId].fishArray[spawnId] endX = self.spawners[spawnerId].position.getX() if fish.name == 'clown': fishSoundName = 'Clownfish.ogg' elif fish.name == 'pbj': fishSoundName = 'PBJ_Fish.ogg' elif fish.name == 'balloon': fishSoundName = 'BalloonFish.ogg' elif fish.name == 'bear': fishSoundName = 'Bear_Acuda.ogg' elif fish.name == 'nurse': fishSoundName = 'Nurse_Shark.ogg' elif fish.name == 'piano': fishSoundName = 'Piano_Tuna.ogg' else: fishSoundName = ' ' fishSoundPath = 'phase_4/audio/sfx/%s' % fishSoundName fish.sound = loader.loadSfx(fishSoundPath) if fish.sound: fish.sound.play() fish.sound.setVolume(volume) self.hitSound.play() self.hitSound.setVolume(volume) if fish.name is 'bear' or fish.name is 'nurse': return colList = fish.findAllMatches('**/fc*') for col in colList: col.removeNode() fish.moveLerp.pause() if fish.name == 'clown' or fish.name == 'piano': if fish.name != 'piano': endHpr = Vec3(fish.getH() * -1, 0, 0) elif fish.direction == -1: endHpr = Vec3(180, 0, 0) else: endHpr = Vec3(0, 0, 0) fish.moveLerp = Sequence(LerpHprInterval(fish, duration=0.4, startHpr=fish.getHpr(), hpr=endHpr), LerpFunc(fish.setX, duration=1.5, fromData=fish.getX(), toData=endX), Func(self.fishRemove, str(spawnerId) + str(spawnId))) elif fish.name == 'pbj': fish.moveLerp = Sequence(LerpFunc(fish.setX, duration=2, fromData=fish.getX(), toData=endX), Func(self.fishRemove, str(spawnerId) + str(spawnId))) elif fish.name == 'balloon': fish.specialLerp.pause() anim = Func(fish.play, 'anim', fromFrame=110, toFrame=200) fish.setH(180) speed = Func(fish.setPlayRate, 3.0, 'anim') fish.moveLerp = Sequence(Func(fish.stop, 'anim'), speed, anim, Wait(1.0), LerpScaleInterval(fish, duration=0.8, startScale=fish.getScale, scale=0.001, blendType='easeIn'), Func(self.fishRemove, str(spawnerId) + str(spawnId))) fish.sound.setTime(11.5) fish.moveLerp.start(ts) def fishRemove(self, code): spawnId = int(code[1:len(code)]) spawnerId = int(code[0]) if spawnId in self.spawners[spawnerId].fishArray: fish = self.spawners[spawnerId].fishArray[spawnId] fish.specialLerp.finish() fish.moveLerp.finish() fish.specialLerp = None fish.moveLerp = None fish.removeNode() del fish del self.spawners[spawnerId].fishArray[spawnId] return def setTreasureGrabbed(self, avId, chestId): if not self.hasLocalToon: return if self.grabbingTreasure == chestId: self.grabbingTreasure = -1 toonSD = self.toonSDs.get(avId) if toonSD and toonSD.status == 'normal': toonSD.fsm.request('treasure') self.treasures[chestId].moveLerp.pause() self.treasures[chestId].moveLerp = Sequence() self.treasures[chestId].chestNode.setIntoCollideMask(BitMask32.allOff()) self.treasures[chestId].treasureNode.reparentTo(self.getAvatar(avId)) headparts = self.getAvatar(avId).getHeadParts() pos = headparts[2].getPos() self.treasures[chestId].treasureNode.setPos(pos + Point3(0, 0.2, 3)) self.treasures[chestId].grabbedId = avId timestamp = globalClockDelta.getFrameNetworkTime() self.playSound('getGold') def __spawnCrabTask(self): taskMgr.remove(self.CRAB_TASK) taskMgr.add(self.__crabTask, self.CRAB_TASK) def __killCrabTask(self): taskMgr.remove(self.CRAB_TASK) def __crabTask(self, task): dt = globalClock.getDt() for crab in self.crabs: if not crab.moveLerp.isPlaying(): crab.moveLerp = Wait(1.0) crab.moveLerp.loop() self.sendUpdate('getCrabMoving', [crab.crabId, crab.getX(), crab.direction]) return Task.cont return Task.cont def setCrabMoving(self, crabId, timestamp, rand1, rand2, crabX, dir): if self.dead == 1: self.__killCrabTask() return if not hasattr(self, 'crabs'): return crab = self.crabs[crabId] ts = globalClockDelta.localElapsedTime(timestamp) x = 0 for i in xrange(self.NUMTREASURES): x += self.treasures[i].treasureNode.getX(render) x /= self.NUMTREASURES goalX = int(x + dir * (rand1 / 10.0) * 12 + 4.0) goalZ = -40 + 5 + 5 * (rand2 / 10.0) xTime = 1 + rand1 / 10.0 * 2 zTime = 0.5 + rand2 / 10.0 wait = rand1 / 10.0 + rand2 / 10.0 + 1 crab.direction *= -1 if goalX > 20: goalX = 20 elif goalX < -20: goalX = 20 loc = crab.getPos(render) distance = base.localAvatar.getDistance(crab) crabVolume = 0 soundRange = 25.0 if distance < soundRange: crabVolume = (soundRange - distance) / soundRange crabSoundInterval = SoundInterval(self.crabSound, loop=0, duration=1.6, startTime=0.0) seq = Sequence(Wait(wait), LerpPosInterval(crab, duration=xTime, startPos=Point3(crabX, 0, -40), pos=Point3(goalX, 0, -40), blendType='easeIn'), Parallel(Func(self.grabCrapVolume, crab), LerpPosInterval(crab, duration=zTime, startPos=Point3(goalX, 0, -40), pos=Point3(goalX, 0, goalZ), blendType='easeOut')), LerpPosInterval(crab, duration=zTime, startPos=Point3(goalX, 0, goalZ), pos=Point3(goalX, 0, -40), blendType='easeInOut')) crab.moveLerp.pause() crab.moveLerp = seq crab.moveLerp.start(ts) def grabCrapVolume(self, crab): if crab: distance = base.localAvatar.getDistance(crab) self.crabVolume = 0 soundRange = 25.0 if distance < soundRange: crabVolume = (soundRange - distance) / soundRange crabSoundInterval = SoundInterval(self.crabSound, loop=0, duration=1.6, startTime=0.0, volume=crabVolume) crabSoundInterval.start() def __spawnUpdateLocalToonTask(self): self.__initPosBroadcast() taskMgr.remove(self.UPDATE_LOCALTOON_TASK) taskMgr.add(self.__updateLocalToonTask, self.UPDATE_LOCALTOON_TASK) def __killUpdateLocalToonTask(self): taskMgr.remove(self.UPDATE_LOCALTOON_TASK) def __updateLocalToonTask(self, task): dt = globalClock.getDt() toonPos = base.localAvatar.getPos() toonHpr = base.localAvatar.getHpr() self.xVel *= 0.99 self.zVel *= 0.99 pos = [toonPos[0], toonPos[1], toonPos[2]] hpr = [toonHpr[0], toonHpr[1], toonHpr[2]] r = 0 toonSD = self.toonSDs[self.localAvId] if toonSD.status == 'normal' or toonSD.status == 'treasure': if self.arrowKeys.leftPressed(): r -= 80 if self.arrowKeys.rightPressed(): r += 80 hpr[2] += r * dt pos1 = self.orientNode.getPos(render) pos2 = self.orientNode2.getPos(render) upVec = Vec2(pos1[0], pos1[2]) bkVec = Vec2(pos2[0], pos2[2]) forVec = upVec - Vec2(pos[0], pos[2]) bckVec = bkVec - Vec2(pos[0], pos[2]) r = 0 if self.arrowKeys.upPressed(): r += 20 self.xVel = forVec[0] * 8 self.zVel = forVec[1] * 8 elif self.arrowKeys.downPressed(): r -= 20 self.xVel = bckVec[0] * 4 self.zVel = bckVec[1] * 4 if self.xVel > 20: self.xVel = 20 elif self.xVel < -20: self.xVel = -20 if self.zVel > 10: self.zVel = 10 elif self.zVel < -10: self.zVel = -10 swimVolume = (abs(self.zVel) + abs(self.xVel)) / 15.0 self.swimSound.setVolume(swimVolume) pos[0] += self.xVel * dt pos[1] = -2 pos[2] += self.zVel * dt found = 0 for i in xrange(self.NUMTREASURES): if self.treasures[i].grabbedId == self.localAvId: found = 1 i = self.NUMTREASURES + 1 pos[2] -= 0.8 * dt if found == 0: pos[2] += 0.8 * dt if pos[2] < -38: pos[2] = -38 elif pos[2] > 36: pos[2] = 36 if pos[0] < -20: pos[0] = -20 elif pos[0] > 20: pos[0] = 20 base.localAvatar.setPos(pos[0], pos[1], pos[2]) base.localAvatar.setHpr(hpr[0], hpr[1], hpr[2]) posDiv = self.MAP_DIV self.mapAvatars[self.localAvId].setPos(pos[0] / posDiv, pos[1] / posDiv, pos[2] / posDiv + self.MAP_OFF) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: pos = toon.getPos() self.mapAvatars[avId].setPos(pos / posDiv) self.mapAvatars[avId].setZ(self.mapAvatars[avId].getZ() + self.MAP_OFF) self.cTrav.traverse(render) self.cTrav2.traverse(render) self.__posBroadcast(dt) z = self.getAvatar(self.localAvId).getZ() + 3 camBottom = math.tan(base.camLens.getVfov()/2.0*math.pi/180)*54 z = max(z, -42+camBottom) camera.setZ(z) ambVolume = abs(z - 25.0) / 50.0 + 0.1 if ambVolume < 0.0: ambVolume = 0.0 if ambVolume > 1.0: ambVolume = 1.0 ambVolume = pow(ambVolume, 0.75) self.sndAmbience.setVolume(ambVolume) return Task.cont def exitSwim(self): self.music.stop() self.ignore('resetClock') self.__killUpdateLocalToonTask() self.__killCrabTask() self.__killTreasureBoundsTask() self.timer.stop() self.timer.destroy() self.localLerp.finish() self.introMovie.finish() self.boatTilt.finish() self.treasurePanel.cleanup() self.mapAvatars[self.localAvId].destroy() del self.mapAvatars for i in xrange(self.NUMTREASURES): del self.chestIcons[i] del self.timer def enterCleanup(self): pass def exitCleanup(self): pass