toontown-just-works/toontown/minigame/DistributedDivingGame.py
2024-07-07 18:08:39 -05:00

978 lines
43 KiB
Python

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(settings['fov']/(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