from pandac.PandaModules import * from toontown.toonbase.ToonBaseGlobal import * from direct.interval.IntervalGlobal import * from .DistributedMinigame import * from direct.gui.DirectGui import * from pandac.PandaModules import * from direct.fsm import ClassicFSM, State from direct.fsm import State from toontown.toonbase import ToontownTimer from . import PatternGameGlobals from toontown.toon import ToonHead from toontown.char import CharDNA from toontown.char import Char from . import ArrowKeys import random from toontown.toonbase import ToontownGlobals import string from toontown.toonbase import TTLocalizer class DistributedPatternGame(DistributedMinigame): phase4snd = 'phase_4/audio/sfx/' ButtonSoundNames = (phase4snd + 'm_match_trumpet.mp3', phase4snd + 'm_match_guitar.mp3', phase4snd + 'm_match_drums.mp3', phase4snd + 'm_match_piano.mp3') bgm = 'phase_4/audio/bgm/m_match_bg1.mid' strWatch = TTLocalizer.PatternGameWatch strGo = TTLocalizer.PatternGameGo strRight = TTLocalizer.PatternGameRight strWrong = TTLocalizer.PatternGameWrong strPerfect = TTLocalizer.PatternGamePerfect strBye = TTLocalizer.PatternGameBye strWaitingOtherPlayers = TTLocalizer.PatternGameWaitingOtherPlayers strPleaseWait = TTLocalizer.PatternGamePleaseWait strRound = TTLocalizer.PatternGameRound minnieAnimNames = ['up', 'left', 'down', 'right'] toonAnimNames = ['up', 'left', 'down', 'right', 'slip-forward', 'slip-backward', 'victory'] def __init__(self, cr): DistributedMinigame.__init__(self, cr) self.gameFSM = ClassicFSM.ClassicFSM('DistributedPatternGame', [State.State('off', self.enterOff, self.exitOff, ['waitForServerPattern']), State.State('waitForServerPattern', self.enterWaitForServerPattern, self.exitWaitForServerPattern, ['showServerPattern', 'cleanup']), State.State('showServerPattern', self.enterShowServerPattern, self.exitShowServerPattern, ['getUserInput', 'playBackPatterns', 'cleanup']), State.State('getUserInput', self.enterGetUserInput, self.exitGetUserInput, ['waitForPlayerPatterns', 'playBackPatterns', 'cleanup']), State.State('waitForPlayerPatterns', self.enterWaitForPlayerPatterns, self.exitWaitForPlayerPatterns, ['playBackPatterns', 'cleanup', 'checkGameOver']), State.State('playBackPatterns', self.enterPlayBackPatterns, self.exitPlayBackPatterns, ['checkGameOver', 'cleanup']), State.State('checkGameOver', self.enterCheckGameOver, self.exitCheckGameOver, ['waitForServerPattern', 'cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.arrowColor = VBase4(1, 0, 0, 1) self.xColor = VBase4(1, 0, 0, 1) self.celebrate = 0 self.oldBgColor = None self.trans = VBase4(1, 0, 0, 0) self.opaq = VBase4(1, 0, 0, 1) self.normalTextColor = VBase4(0.537, 0.84, 0.33, 1.0) self.__otherToonIndex = {} return def getTitle(self): return TTLocalizer.PatternGameTitle def getInstructions(self): return TTLocalizer.PatternGameInstructions def getMaxDuration(self): inputDur = PatternGameGlobals.NUM_ROUNDS * PatternGameGlobals.InputTime return inputDur * 1.3 def load(self): self.notify.debug('load') DistributedMinigame.load(self) self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() self.room = loader.loadModel('phase_4/models/minigames/matching_room') self.buttonSounds = [] for soundName in self.ButtonSoundNames: self.buttonSounds.append(base.loader.loadSfx(soundName)) self.correctSound = base.loader.loadSfx('phase_4/audio/sfx/MG_pos_buzzer.wav') self.incorrectSound = base.loader.loadSfx('phase_4/audio/sfx/MG_neg_buzzer.wav') self.perfectSound = base.loader.loadSfx('phase_4/audio/sfx/MG_win.mp3') self.fallSound = base.loader.loadSfx('phase_4/audio/sfx/MG_Tag_A.mp3') self.music = base.loader.loadMusic(self.bgm) self.waitingText = DirectLabel(text=self.strPleaseWait, text_fg=(0.9, 0.9, 0.9, 1.0), frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0, 0, -.78), scale=0.12) self.roundText = DirectLabel(text=self.strRound % 1, text_fg=self.normalTextColor, frameColor=(1, 1, 1, 0), text_font=ToontownGlobals.getSignFont(), pos=(0.014, 0, -.84), scale=0.12) self.roundText.hide() self.waitingText.hide() matchingGameGui = loader.loadModel('phase_3.5/models/gui/matching_game_gui') minnieArrow = matchingGameGui.find('**/minnieArrow') minnieX = matchingGameGui.find('**/minnieX') minnieCircle = matchingGameGui.find('**/minnieCircle') self.arrows = [None] * 5 for x in range(0, 5): self.arrows[x] = minnieArrow.copyTo(hidden) self.arrows[x].hide() self.xs = [None] * 5 for x in range(0, 5): self.xs[x] = minnieX.copyTo(hidden) self.xs[x].hide() self.statusBalls = [] self.totalMoves = PatternGameGlobals.INITIAL_ROUND_LENGTH + PatternGameGlobals.ROUND_LENGTH_INCREMENT * (PatternGameGlobals.NUM_ROUNDS - 1) for x in range(0, 4): self.statusBalls.append([None] * self.totalMoves) for x in range(0, 4): for y in range(0, self.totalMoves): self.statusBalls[x][y] = minnieCircle.copyTo(hidden) self.statusBalls[x][y].hide() minnieArrow.removeNode() minnieX.removeNode() minnieCircle.removeNode() matchingGameGui.removeNode() self.minnie = Char.Char() m = self.minnie dna = CharDNA.CharDNA() dna.newChar('mn') m.setDNA(dna) m.setName(TTLocalizer.Minnie) m.reparentTo(hidden) self.backRowHome = Point3(3, 11, 0) self.backRowXSpacing = 1.8 self.frontRowHome = Point3(0, 18, 0) self.frontRowXSpacing = 3.0 self.stdNumDanceStepPingFrames = self.minnie.getNumFrames(self.minnieAnimNames[0]) self.stdNumDanceStepPingPongFrames = self.__numPingPongFrames(self.stdNumDanceStepPingFrames) self.buttonPressDelayPercent = (self.stdNumDanceStepPingFrames - 1.0) / self.stdNumDanceStepPingPongFrames self.animPlayRates = [] animPlayRate = 1.4 animPlayRateMult = 1.06 for i in range(PatternGameGlobals.NUM_ROUNDS): self.animPlayRates.append(animPlayRate) animPlayRate *= animPlayRateMult return def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) self.timer.destroy() del self.timer del self.lt del self.buttonSounds del self.music del self.__otherToonIndex del self.correctSound del self.incorrectSound del self.perfectSound del self.fallSound self.waitingText.destroy() del self.waitingText self.roundText.destroy() del self.roundText for x in list(self.arrowDict.values()): x[0].removeNode() x[1].removeNode() if len(x) == 3: for y in x[2]: y.removeNode() del self.arrowDict for x in self.arrows: if x: x.removeNode() del self.arrows for x in self.xs: if x: x.removeNode() del self.xs for x in self.statusBalls: if x: for y in x: if y: y.removeNode() del y del self.statusBalls self.room.removeNode() del self.room self.minnie.delete() del self.minnie self.removeChildGameFSM(self.gameFSM) del self.gameFSM def onstage(self): self.notify.debug('onstage') DistributedMinigame.onstage(self) self.arrowDict = {} self.lt = base.localAvatar camera.reparentTo(render) camera.setPosHpr(0.0, -14.59, 10.56, 0.0, -16.39, 0.0) base.camLens.setFov(24.66) NametagGlobals.setGlobalNametagScale(0.6) self.arrowKeys = ArrowKeys.ArrowKeys() self.room.reparentTo(render) self.room.setPosHpr(0.0, 18.39, -ToontownGlobals.FloorOffset, 0.0, 0.0, 0.0) self.room.setScale(1) for anim in self.minnieAnimNames: self.minnie.pose(anim, 0) for anim in self.toonAnimNames: self.lt.pose(anim, 0) self.minnieAnimSpeedMult = {} self.toonAnimSpeedMult = {} for anim in self.minnieAnimNames: numFrames = self.minnie.getNumFrames(anim) self.minnieAnimSpeedMult[anim] = float(self.__numPingPongFrames(numFrames)) / float(self.stdNumDanceStepPingPongFrames) for anim in self.toonAnimNames: numFrames = self.lt.getNumFrames(anim) self.toonAnimSpeedMult[anim] = float(self.__numPingPongFrames(numFrames)) / float(self.stdNumDanceStepPingPongFrames) lt = self.lt lt.reparentTo(render) lt.useLOD(1000) lt.setPos(-3.5, 11, 0.0) lt.setScale(1) self.makeToonLookatCamera(lt) lt.loop('neutral') lt.startBlink() lt.startLookAround() self.arrowDict['lt'] = [self.arrows.pop(), self.xs.pop(), self.statusBalls.pop()] jj = self.lt.nametag3d for k in range(0, 2): self.arrowDict['lt'][k].setBillboardAxis() self.arrowDict['lt'][k].setBin('fixed', 100) self.arrowDict['lt'][k].reparentTo(jj) if k == 0: self.arrowDict['lt'][k].setScale(2.5) self.arrowDict['lt'][k].setColor(self.arrowColor) else: self.arrowDict['lt'][k].setScale(4, 4, 4) self.arrowDict['lt'][k].setColor(self.xColor) self.arrowDict['lt'][k].setPos(0, 0, 1) self.formatStatusBalls(self.arrowDict['lt'][2], jj) m = self.minnie m.reparentTo(render) m.setPos(-1.6, 20, 0) m.setScale(1) self.makeToonLookatCamera(m) m.loop('neutral') m.startBlink() self.minnie.nametag.manage(base.marginManager) self.minnie.startEarTask() self.minnie.setPickable(0) self.minnie.nametag.getNametag3d().setChatWordwrap(8) self.arrowDict['m'] = [self.arrows.pop(), self.xs.pop()] jj = self.minnie.nametag3d for k in range(0, 2): self.arrowDict['m'][k].setBillboardAxis() self.arrowDict['m'][k].setBin('fixed', 100) self.arrowDict['m'][k].setColor(self.arrowColor) self.arrowDict['m'][k].reparentTo(jj) self.arrowDict['m'][k].setScale(4) self.arrowDict['m'][k].setPos(0, 0, 1.7) base.playMusic(self.music, looping=1, volume=1) def offstage(self): self.notify.debug('offstage') DistributedMinigame.offstage(self) self.music.stop() base.camLens.setFov(ToontownGlobals.DefaultCameraFov) NametagGlobals.setGlobalNametagScale(1.0) self.arrowKeys.destroy() del self.arrowKeys self.room.reparentTo(hidden) self.roundText.hide() self.minnie.nametag.unmanage(base.marginManager) self.minnie.stopEarTask() self.minnie.stop() self.minnie.stopBlink() self.minnie.reparentTo(hidden) self.lt.setScale(1) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: toon.setScale(1) for avId in self.avIdList: av = self.getAvatar(avId) if av: av.resetLOD() for anim in self.toonAnimNames: av.setPlayRate(1.0, anim) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: self.arrowDict[avId] = [self.arrows.pop(), self.xs.pop(), self.statusBalls.pop()] jj = toon.nametag3d for k in range(0, 2): self.arrowDict[avId][k].setBillboardAxis() self.arrowDict[avId][k].setBin('fixed', 100) self.arrowDict[avId][k].reparentTo(jj) if k == 0: self.arrowDict[avId][k].setScale(2.5) self.arrowDict[avId][k].setColor(self.arrowColor) else: self.arrowDict[avId][k].setScale(4, 4, 4) self.arrowDict[avId][k].setColor(self.xColor) self.arrowDict[avId][k].setPos(0, 0, 1) self.formatStatusBalls(self.arrowDict[avId][2], jj) toon.reparentTo(render) toon.useLOD(1000) toon.setPos(self.getBackRowPos(avId)) toon.setScale(0.9) self.makeToonLookatCamera(toon) for anim in self.toonAnimNames: toon.pose(anim, 0) toon.loop('neutral') if self.isSinglePlayer(): self.waitingText['text'] = self.strPleaseWait else: self.waitingText['text'] = self.strWaitingOtherPlayers self.animTracks = {} for avId in self.avIdList: self.animTracks[avId] = None self.__initGameVars() return def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) self.gameFSM.request('waitForServerPattern') def __initGameVars(self): self.round = 0 self.perfectGame = 1 def __numPingPongFrames(self, numFrames): return numFrames * 2 - 1 def makeToonLookatCamera(self, toon): toon.headsUp(camera) def setText(self, t, newtext): t['text'] = newtext def setTextFG(self, t, fg): t['text_fg'] = fg def getWalkTrack(self, toon, posList, startPos = None, lookAtCam = 1, endHeading = 180): walkSpeed = 7 origPos = toon.getPos() origHpr = toon.getHpr() track = Sequence(Func(toon.loop, 'run')) if startPos: toon.setPos(startPos) track.append(Func(toon.setPos, startPos)) for endPos in posList: toon.headsUp(Point3(endPos)) track.append(Func(toon.setHpr, Point3(toon.getH(), 0, 0))) lastPos = toon.getPos() distance = Vec3(endPos - lastPos).length() duration = distance / walkSpeed toon.setPos(endPos) track.append(LerpPosInterval(toon, duration=duration, pos=Point3(endPos), startPos=Point3(lastPos))) if lookAtCam: saveHpr = toon.getHpr() toon.headsUp(camera) endHeading = toon.getHpr()[0] toon.setHpr(saveHpr) curHeading = toon.getH() if endHeading - curHeading > 180.0: endHeading -= 360 elif endHeading - curHeading < -180.0: endHeading += 360 endHpr = Point3(endHeading, 0, 0) duration = abs(endHeading - curHeading) / 180.0 * 0.3 track.extend([Func(toon.loop, 'walk'), LerpHprInterval(toon, duration, endHpr), Func(toon.loop, 'neutral')]) toon.setPos(origPos) toon.setHpr(origHpr) return track def getDanceStepDuration(self): numFrames = self.stdNumDanceStepPingPongFrames return numFrames / abs(self.animPlayRate * self.minnieAnimSpeedMult[self.minnieAnimNames[0]] * self.minnie.getFrameRate(self.minnieAnimNames[0])) def __getDanceStepAnimTrack(self, toon, anim, speedScale): numFrames = toon.getNumFrames(anim) return Sequence(Func(toon.pingpong, anim, fromFrame=0, toFrame=numFrames - 1), Wait(self.getDanceStepDuration())) def __getMinnieDanceStepAnimTrack(self, minnie, direction): animName = self.minnieAnimNames[direction] return self.__getDanceStepAnimTrack(minnie, animName, self.minnieAnimSpeedMult[animName]) def __getToonDanceStepAnimTrack(self, toon, direction): animName = self.toonAnimNames[direction] return self.__getDanceStepAnimTrack(toon, animName, self.toonAnimSpeedMult[animName]) def getDanceStepButtonSoundTrack(self, index): duration = self.getDanceStepDuration() wait = duration * self.buttonPressDelayPercent return Sequence(Wait(wait), Func(base.playSfx, self.__getButtonSound(index)), Wait(duration - wait)) def getDanceArrowAnimTrack(self, toonID, pattern, speedy): track = Sequence() track.append(Func(self.showArrow, toonID)) for buttonIndex in pattern: track.append(self.getDanceArrowSingleTrack(toonID, buttonIndex, speedy)) track.append(Func(self.hideArrow, toonID)) return track def changeArrow(self, toonID, index): self.arrowDict[toonID][0].setR(-(90 - 90 * index)) def showArrow(self, toonID): self.arrowDict[toonID][0].show() def hideArrow(self, toonID): self.arrowDict[toonID][0].hide() def showX(self, toonID): self.arrowDict[toonID][1].show() def hideX(self, toonID): self.arrowDict[toonID][1].hide() def celebrated(self): self.celebrate = 1 def returnCelebrationIntervals(self, turnOn): ri = [] if turnOn: ri.append(ActorInterval(actor=self.lt, animName='victory', duration=5.5)) else: ri.append(Func(self.lt.loop, 'neutral')) for avId in self.remoteAvIdList: toon = self.getAvatar(avId) if toon: if turnOn: ri.append(ActorInterval(actor=toon, animName='victory', duration=5.5)) else: ri.append(Func(toon.loop, 'neutral')) if len(self.remoteAvIdList) == 0: return ri else: return Parallel(ri) def formatStatusBalls(self, sb, jj): for x in range(0, self.totalMoves): sb[x].setBillboardAxis() sb[x].setBin('fixed', 100) sb[x].reparentTo(jj) sb[x].setScale(1) xpos = +(int(self.totalMoves / 2) * 0.25) - 0.25 * x sb[x].setPos(xpos, 0, 0.3) def showStatusBalls(self, toonID): sb = self.arrowDict[toonID][2] for x in range(0, len(self.__serverPattern)): sb[x].setColor(1, 1, 1, 1) sb[x].show() def hideStatusBalls(self, toonID): sb = self.arrowDict[toonID][2] for x in range(0, len(sb)): sb[x].hide() def colorStatusBall(self, toonID, which, good): if good: self.arrowDict[toonID][2][which].setColor(0, 1, 0, 1) else: self.arrowDict[toonID][2][which].setColor(1, 0, 0, 1) def getDanceArrowSingleTrack(self, toonID, index, speedy): duration = self.getDanceStepDuration() wait = duration * self.buttonPressDelayPercent d = duration - wait if speedy: track = Sequence(Func(self.changeArrow, toonID, index), Wait(wait)) else: track = Sequence(Func(self.changeArrow, toonID, index), Wait(wait), LerpColorInterval(self.arrowDict[toonID][0], d, self.trans, self.opaq)) return track def getDanceSequenceAnimTrack(self, toon, pattern): getDanceStepTrack = self.__getToonDanceStepAnimTrack if toon == self.minnie: getDanceStepTrack = self.__getMinnieDanceStepAnimTrack tracks = Sequence() for direction in pattern: tracks.append(getDanceStepTrack(toon, direction)) if len(pattern): tracks.append(Func(toon.loop, 'neutral')) return tracks def getDanceSequenceButtonSoundTrack(self, pattern): track = Sequence() for buttonIndex in pattern: track.append(self.getDanceStepButtonSoundTrack(buttonIndex)) return track def __getRowPos(self, rowHome, xSpacing, index, numSpots): xOffset = xSpacing * index - xSpacing * (numSpots - 1) / 2.0 return rowHome + Point3(xOffset, 0, 0) def getBackRowPos(self, avId): index = self.remoteAvIdList.index(avId) return self.__getRowPos(self.backRowHome, self.backRowXSpacing, index, len(self.remoteAvIdList)) def getFrontRowPos(self, avId): index = self.avIdList.index(avId) return self.__getRowPos(self.frontRowHome, self.frontRowXSpacing, index, len(self.avIdList)) def __setMinnieChat(self, str, giggle): str = string.replace(str, '%s', self.getAvatar(self.localAvId).getName()) self.minnie.setChatAbsolute(str, CFSpeech) if giggle: self.minnie.playDialogue('statementA', 1) def __clearMinnieChat(self): self.minnie.clearChat() def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterWaitForServerPattern(self): self.notify.debug('enterWaitForServerPattern') self.sendUpdate('reportPlayerReady', []) def setPattern(self, pattern): if not self.hasLocalToon: return self.notify.debug('setPattern: ' + str(pattern)) self.__serverPattern = pattern self.gameFSM.request('showServerPattern') def exitWaitForServerPattern(self): pass def enterShowServerPattern(self): self.notify.debug('enterShowServerPattern') self.round += 1 self.roundText.show() self.roundText.setScale(0.12) self.roundText['text'] = self.strRound % self.round self.animPlayRate = self.animPlayRates[self.round - 1] for avId in self.avIdList: toon = self.getAvatar(avId) if toon: for anim in self.toonAnimNames: toon.setPlayRate(self.animPlayRate * self.toonAnimSpeedMult[anim], anim) for anim in self.minnieAnimNames: self.minnie.setPlayRate(self.animPlayRate * self.minnieAnimSpeedMult[anim], anim) text = self.strWatch danceTrack = self.getDanceSequenceAnimTrack(self.minnie, self.__serverPattern) arrowTrack = self.getDanceArrowAnimTrack('m', self.__serverPattern, 0) soundTrack = self.getDanceSequenceButtonSoundTrack(self.__serverPattern) self.showTrack = Sequence(Func(self.__setMinnieChat, text, 1), Wait(0.5), Parallel(danceTrack, soundTrack, arrowTrack), Wait(0.2), Func(self.__clearMinnieChat), Func(self.gameFSM.request, 'getUserInput')) self.showTrack.start() def exitShowServerPattern(self): if self.showTrack.isPlaying(): self.showTrack.pause() del self.showTrack def enterGetUserInput(self): self.notify.debug('enterGetUserInput') self.setupTrack = None self.proceedTrack = None def startTimer(self = self): self.currentStartTime = globalClock.getFrameTime() self.timer.show() self.timer.countdown(PatternGameGlobals.InputTime, self.__handleInputTimeout) def enableKeys(self = self): def keyPress(self, index): self.__pressHandler(index) def keyRelease(self, index): self.__releaseHandler(index) self.arrowKeys.setPressHandlers([lambda self = self, keyPress = keyPress: keyPress(self, 0), lambda self = self, keyPress = keyPress: keyPress(self, 2), lambda self = self, keyPress = keyPress: keyPress(self, 3), lambda self = self, keyPress = keyPress: keyPress(self, 1)]) self.arrowKeys.setReleaseHandlers([lambda self = self, keyRelease = keyRelease: keyRelease(self, 0), lambda self = self, keyRelease = keyRelease: keyRelease(self, 2), lambda self = self, keyRelease = keyRelease: keyRelease(self, 3), lambda self = self, keyRelease = keyRelease: keyRelease(self, 1)]) self.__localPattern = [] self.__otherToonIndex.clear() self.showStatusBalls('lt') for avId in self.remoteAvIdList: self.showStatusBalls(avId) self.__otherToonIndex[avId] = 0 self.setupTrack = Sequence(Func(self.__setMinnieChat, self.strGo, 0), Func(self.setText, self.roundText, TTLocalizer.PatternGameGo), Func(self.roundText.setScale, 0.3), Func(enableKeys), Func(startTimer), Wait(0.8), Func(self.__clearMinnieChat), Func(self.setText, self.roundText, ' '), Func(self.roundText.setScale, 0.12), Func(self.setTextFG, self.roundText, self.normalTextColor)) self.setupTrack.start() return def __handleInputTimeout(self): self.__doneGettingInput(self.__localPattern) def __pressHandler(self, index): self.__buttonPressed(index) def __releaseHandler(self, index): pass def remoteButtonPressed(self, avId, index, wrong): if not self.hasLocalToon: return if self.gameFSM.getCurrentState().getName() not in ['getUserInput', 'waitForPlayerPatterns']: return if avId != self.localAvId: if self.animTracks[avId]: self.animTracks[avId].finish() av = self.getAvatar(avId) if wrong: acts = ['slip-forward', 'slip-backward'] ag = random.choice(acts) self.arrowDict[avId][0].hide() self.animTracks[avId] = Sequence(Func(self.showX, avId), Func(self.colorStatusBall, avId, self.__otherToonIndex[avId], 0), ActorInterval(actor=av, animName=ag, duration=2.35), Func(av.loop, 'neutral'), Func(self.hideX, avId)) else: self.colorStatusBall(avId, self.__otherToonIndex[avId], 1) arrowTrack = self.getDanceArrowAnimTrack(avId, [index], 1) potTrack = self.getDanceSequenceAnimTrack(av, [index]) self.animTracks[avId] = Parallel(potTrack, arrowTrack) self.__otherToonIndex[avId] += 1 self.animTracks[avId].start() def __getButtonSound(self, index): return self.buttonSounds[index] def __buttonPressed(self, index): if len(self.__localPattern) >= len(self.__serverPattern): return if self.animTracks[self.localAvId]: self.animTracks[self.localAvId].finish() badd = 0 if index != self.__serverPattern[len(self.__localPattern)]: badd = 1 acts = ['slip-forward', 'slip-backward'] ag = random.choice(acts) self.animTracks[self.localAvId] = Sequence(Func(self.showX, 'lt'), Func(self.colorStatusBall, 'lt', len(self.__localPattern), 0), ActorInterval(actor=self.lt, animName=ag, duration=2.35), Func(self.lt.loop, 'neutral'), Func(self.hideX, 'lt')) self.arrowDict['lt'][0].hide() base.playSfx(self.fallSound) else: self.colorStatusBall('lt', len(self.__localPattern), 1) base.playSfx(self.__getButtonSound(index)) arrowTrack = self.getDanceArrowAnimTrack('lt', [index], 1) potTrack = self.getDanceSequenceAnimTrack(self.lt, [index]) self.animTracks[self.localAvId] = Parallel(potTrack, arrowTrack) self.sendUpdate('reportButtonPress', [index, badd]) self.animTracks[self.localAvId].start() self.__localPattern.append(index) if len(self.__localPattern) == len(self.__serverPattern) or badd: self.__doneGettingInput(self.__localPattern) def __doneGettingInput(self, pattern): self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS) self.currentTotalTime = globalClock.getFrameTime() - self.currentStartTime self.proceedTrack = Sequence(Wait(self.getDanceStepDuration()), Func(self.sendUpdate, 'reportPlayerPattern', [pattern, self.currentTotalTime]), Func(self.gameFSM.request, 'waitForPlayerPatterns')) self.proceedTrack.start() def exitGetUserInput(self): self.timer.stop() self.timer.hide() self.arrowKeys.setPressHandlers(self.arrowKeys.NULL_HANDLERS) self.arrowKeys.setReleaseHandlers(self.arrowKeys.NULL_HANDLERS) if self.setupTrack and self.setupTrack.isPlaying(): self.setupTrack.pause() if self.proceedTrack and self.proceedTrack.isPlaying(): self.proceedTrack.pause() del self.setupTrack del self.proceedTrack self.__clearMinnieChat() def enterWaitForPlayerPatterns(self): self.notify.debug('enterWaitForPlayerPatterns') def setPlayerPatterns(self, pattern1, pattern2, pattern3, pattern4, fastestAvId): if not self.hasLocalToon: return self.fastestAvId = fastestAvId self.notify.debug('setPlayerPatterns:' + ' pattern1:' + str(pattern1) + ' pattern2:' + str(pattern2) + ' pattern3:' + str(pattern3) + ' pattern4:' + str(pattern4)) self.playerPatterns = {} patterns = [pattern1, pattern2, pattern3, pattern4] for i in range(len(self.avIdList)): self.playerPatterns[self.avIdList[i]] = patterns[i] self.gameFSM.request('playBackPatterns') def exitWaitForPlayerPatterns(self): self.waitingText.hide() def enterPlayBackPatterns(self): self.notify.debug('enterPlayBackPatterns') if self.fastestAvId == self.localAvId: self.roundText.setScale(0.1) if self.numPlayers != 2: self.roundText['text'] = TTLocalizer.PatternGameFastest else: self.roundText['text'] = TTLocalizer.PatternGameFaster jumpTrack = Sequence(ActorInterval(actor=self.lt, animName='jump', duration=1.7), Func(self.lt.loop, 'neutral')) elif self.fastestAvId == 0: if self.round == PatternGameGlobals.NUM_ROUNDS: self.roundText['text'] = ' ' else: self.roundText.setScale(0.1) self.roundText['text'] = TTLocalizer.PatternGameYouCanDoIt jumpTrack = Sequence(Wait(0.5), Wait(0.5)) elif self.fastestAvId == 1: self.roundText.setScale(0.1) self.roundText['text'] = TTLocalizer.PatternGameGreatJob jumpTrack = Sequence(Wait(0.5), Wait(0.5)) else: self.roundText.setScale(0.08) av = self.getAvatar(self.fastestAvId) jumpTrack = Sequence(ActorInterval(actor=av, animName='jump', duration=1.7), Func(av.loop, 'neutral')) if self.numPlayers != 2: rewardStr = TTLocalizer.PatternGameOtherFastest else: rewardStr = TTLocalizer.PatternGameOtherFaster self.roundText['text'] = av.getName() + rewardStr success = self.playerPatterns[self.localAvId] == self.__serverPattern self.hideStatusBalls('lt') for avId in self.remoteAvIdList: self.hideStatusBalls(avId) if success: sound = self.correctSound text = self.strRight else: self.perfectGame = 0 sound = self.incorrectSound text = self.strWrong soundTrack = Sequence(Func(base.playSfx, sound), Wait(1.6)) textTrack = Sequence(Wait(0.2), Func(self.__setMinnieChat, text, 0), Wait(1.3), Func(self.__clearMinnieChat)) self.playBackPatternsTrack = Sequence(Parallel(soundTrack, textTrack, jumpTrack), Func(self.gameFSM.request, 'checkGameOver')) self.playBackPatternsTrack.start() def exitPlayBackPatterns(self): if self.playBackPatternsTrack.isPlaying(): self.playBackPatternsTrack.pause() del self.playBackPatternsTrack def enterCheckGameOver(self): self.notify.debug('enterCheckGameOver') self.__winTrack = None if self.round < PatternGameGlobals.NUM_ROUNDS: self.gameFSM.request('waitForServerPattern') else: text = self.strBye sound = None delay = 2.0 if self.perfectGame: text = self.strPerfect sound = self.perfectSound delay = 2.2 if self.celebrate: text = TTLocalizer.PatternGameImprov self.__winTrack = Sequence(Func(self.__setMinnieChat, text, 1), Func(base.playSfx, self.perfectSound), Sequence(self.returnCelebrationIntervals(1)), Sequence(self.returnCelebrationIntervals(0)), Func(self.__clearMinnieChat), Func(self.gameOver)) else: self.__winTrack = Sequence(Func(self.__setMinnieChat, text, 1), Func(base.playSfx, sound), Wait(delay), Func(self.__clearMinnieChat), Func(self.gameOver)) self.__winTrack.start() return def exitCheckGameOver(self): if self.__winTrack and self.__winTrack.isPlaying(): self.__winTrack.pause() del self.__winTrack def enterCleanup(self): self.notify.debug('enterCleanup') for track in list(self.animTracks.values()): if track and track.isPlaying(): track.pause() del self.animTracks def exitCleanup(self): pass