oldschool-toontown/toontown/minigame/DistributedPatternGame.py
2023-04-29 22:20:11 -04:00

861 lines
33 KiB
Python

from panda3d.core import Point3, VBase4, Vec3
from panda3d.otp import CFSpeech, NametagGlobals
from direct.directnotify.DirectNotifyGlobal import directNotify
from direct.fsm.ClassicFSM import ClassicFSM
from direct.fsm.State import State
from direct.gui.DirectGui import DirectLabel
from direct.interval.IntervalGlobal import (
ActorInterval,
Func,
LerpColorInterval,
LerpHprInterval,
LerpPosInterval,
Parallel,
Sequence,
Wait
)
from toontown.char.Char import Char
from toontown.char.CharDNA import CharDNA
from toontown.minigame import PatternGameGlobals
from toontown.minigame.ArrowKeys import ArrowKeys
from toontown.minigame.DistributedMinigame import DistributedMinigame
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from toontown.toonbase.ToonBaseGlobal import base
from toontown.toonbase.ToontownTimer import ToontownTimer
from random import choice
class DistributedPatternGame(DistributedMinigame):
notify = directNotify.newCategory('DistributedPatternGame')
phase4snd = 'phase_4/audio/sfx/'
ButtonSoundNames = (phase4snd + 'm_match_trumpet.ogg',
phase4snd + 'm_match_guitar.ogg',
phase4snd + 'm_match_drums.ogg',
phase4snd + 'm_match_piano.ogg')
bgm = 'phase_4/audio/bgm/m_match_bg1.ogg'
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('DistributedPatternGame', [State('off', self.enterOff, self.exitOff, ['waitForServerPattern']),
State('waitForServerPattern', self.enterWaitForServerPattern, self.exitWaitForServerPattern, ['showServerPattern', 'cleanup']),
State('showServerPattern', self.enterShowServerPattern, self.exitShowServerPattern, ['getUserInput', 'playBackPatterns', 'cleanup']),
State('getUserInput', self.enterGetUserInput, self.exitGetUserInput, ['waitForPlayerPatterns', 'playBackPatterns', 'cleanup']),
State('waitForPlayerPatterns', self.enterWaitForPlayerPatterns, self.exitWaitForPlayerPatterns, ['playBackPatterns', 'cleanup', 'checkGameOver']),
State('playBackPatterns', self.enterPlayBackPatterns, self.exitPlayBackPatterns, ['checkGameOver', 'cleanup']),
State('checkGameOver', self.enterCheckGameOver, self.exitCheckGameOver, ['waitForServerPattern', 'cleanup']),
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 = {}
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()
self.timer.posInTopRightCorner()
self.timer.hide()
self.room = base.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.ogg')
self.incorrectSound = base.loader.loadSfx('phase_4/audio/sfx/MG_neg_buzzer.ogg')
self.perfectSound = base.loader.loadSfx('phase_4/audio/sfx/MG_win.ogg')
self.fallSound = base.loader.loadSfx('phase_4/audio/sfx/MG_Tag_A.ogg')
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 = base.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(base.hidden)
self.arrows[x].hide()
self.xs = [None] * 5
for x in range(0, 5):
self.xs[x] = minnieX.copyTo(base.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(base.hidden)
self.statusBalls[x][y].hide()
minnieArrow.removeNode()
minnieX.removeNode()
minnieCircle.removeNode()
matchingGameGui.removeNode()
self.minnie = Char()
m = self.minnie
dna = CharDNA()
dna.newChar('mn')
m.setDNA(dna)
m.setName(TTLocalizer.Minnie)
m.reparentTo(base.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 _ in range(PatternGameGlobals.NUM_ROUNDS):
self.animPlayRates.append(animPlayRate)
animPlayRate *= animPlayRateMult
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
base.camera.reparentTo(base.render)
base.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()
self.room.reparentTo(base.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(base.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(base.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(base.hidden)
self.roundText.hide()
self.minnie.nametag.unmanage(base.marginManager)
self.minnie.stopEarTask()
self.minnie.stop()
self.minnie.stopBlink()
self.minnie.reparentTo(base.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(base.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()
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(base.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(base.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 = str.replace('%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 = base.clock.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()
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 = 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 = 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 = base.clock.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()
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