2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import *
|
2019-11-02 17:27:54 -05:00
|
|
|
from toontown.toonbase.ToonBaseGlobal import *
|
2019-12-30 00:07:56 -06:00
|
|
|
from .DistributedMinigame import *
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.fsm import ClassicFSM, State
|
|
|
|
from direct.fsm import State
|
|
|
|
from toontown.toonbase import TTLocalizer, ToontownTimer
|
|
|
|
from toontown.toonbase import ToontownBattleGlobals
|
|
|
|
from toontown.minigame import PlayingCardGlobals
|
|
|
|
from toontown.minigame import PairingGameCard
|
|
|
|
from toontown.minigame import PlayingCardDeck
|
|
|
|
from toontown.minigame import PairingGameGlobals
|
2019-12-30 00:07:56 -06:00
|
|
|
from .OrthoWalk import OrthoWalk
|
|
|
|
from .OrthoDrive import OrthoDrive
|
2019-11-02 17:27:54 -05:00
|
|
|
from direct.interval.IntervalGlobal import Sequence, Parallel, Func, LerpColorScaleInterval, LerpScaleInterval, LerpFunctionInterval, Wait, SoundInterval
|
|
|
|
from toontown.toonbase.ToontownGlobals import GlobalDialogColor
|
|
|
|
|
|
|
|
class DistributedPairingGame(DistributedMinigame):
|
|
|
|
TOON_SPEED = 11
|
|
|
|
MAX_FRAME_MOVE = 1
|
|
|
|
MAX_FACE_UP_CARDS = 2
|
|
|
|
notify = directNotify.newCategory('DistributedPairingGame')
|
|
|
|
bonusGlowTime = 0.5
|
|
|
|
EndGameTaskName = 'endPairingGame'
|
|
|
|
xCardInc = 4
|
|
|
|
cardsPerRow = 8
|
|
|
|
cardsPerCol = 5
|
|
|
|
|
|
|
|
def __init__(self, cr):
|
|
|
|
DistributedMinigame.__init__(self, cr)
|
|
|
|
self.gameFSM = ClassicFSM.ClassicFSM('DistributedPairingGame', [State.State('off', self.enterOff, self.exitOff, ['play']), State.State('play', self.enterPlay, self.exitPlay, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
|
|
|
|
self.addChildGameFSM(self.gameFSM)
|
|
|
|
self.cameraTopView = (17.6, 6.18756, 43.9956, 0, -89, 0)
|
|
|
|
self.cameraThreeQuarterView = (14.0, -8.93352, 33.4497, 0, -62.89, 0)
|
|
|
|
self.deckSeed = 0
|
|
|
|
self.faceUpList = []
|
|
|
|
self.localFaceUpList = []
|
|
|
|
self.inList = []
|
|
|
|
self.inactiveList = []
|
|
|
|
self.points = 0
|
|
|
|
self.flips = 0
|
|
|
|
self.matches = 0
|
|
|
|
self.yCardInc = 4
|
|
|
|
self.startingPositions = [(0, 0, 0, -45),
|
|
|
|
((self.cardsPerRow - 1) * self.xCardInc,
|
|
|
|
(self.cardsPerCol - 1) * self.yCardInc,
|
|
|
|
0,
|
|
|
|
135),
|
|
|
|
((self.cardsPerRow - 1) * self.xCardInc,
|
|
|
|
0,
|
|
|
|
0,
|
|
|
|
45),
|
|
|
|
(0,
|
|
|
|
(self.cardsPerCol - 1) * self.yCardInc,
|
|
|
|
0,
|
|
|
|
-135)]
|
|
|
|
self.stageMin = Point2(0, 0)
|
|
|
|
self.stageMax = Point2((self.cardsPerRow - 1) * self.xCardInc, (self.cardsPerCol - 1) * self.yCardInc)
|
|
|
|
self.gameDuration = PairingGameGlobals.EasiestGameDuration
|
|
|
|
|
|
|
|
def moveCameraToTop(self):
|
|
|
|
camera.reparentTo(render)
|
|
|
|
p = self.cameraThreeQuarterView
|
|
|
|
camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5])
|
|
|
|
|
|
|
|
def getTitle(self):
|
|
|
|
return TTLocalizer.PairingGameTitle
|
|
|
|
|
|
|
|
def getInstructions(self):
|
|
|
|
if self.numPlayers > 1:
|
|
|
|
return TTLocalizer.PairingGameInstructionsMulti
|
|
|
|
else:
|
|
|
|
return TTLocalizer.PairingGameInstructions
|
|
|
|
|
|
|
|
def getMaxDuration(self):
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
self.notify.debug('load')
|
|
|
|
DistributedMinigame.load(self)
|
|
|
|
self.gameDuration = PairingGameGlobals.calcGameDuration(self.getDifficulty())
|
|
|
|
self.gameBoard = loader.loadModel('phase_4/models/minigames/memory_room')
|
|
|
|
self.gameBoard.setPosHpr(0.5, 0, 0, 0, 0, 0)
|
|
|
|
self.gameBoard.setScale(1.0)
|
|
|
|
self.deck = PairingGameGlobals.createDeck(self.deckSeed, self.numPlayers)
|
|
|
|
self.notify.debug('%s' % self.deck.cards)
|
|
|
|
testCard = self.getDeckOrderIndex(self.cardsPerCol - 1, 0)
|
|
|
|
if not testCard > -1:
|
|
|
|
self.yCardInc *= 1.25
|
|
|
|
self.cards = []
|
2019-12-30 00:07:56 -06:00
|
|
|
for index in range(len(self.deck.cards)):
|
2019-11-02 17:27:54 -05:00
|
|
|
cardValue = self.deck.cards[index]
|
|
|
|
oneCard = PairingGameCard.PairingGameCard(cardValue)
|
|
|
|
oneCard.load()
|
|
|
|
xPos, yPos = self.getCardPos(index)
|
|
|
|
oneCard.setPos(xPos, yPos, 0)
|
|
|
|
oneCard.reparentTo(render)
|
|
|
|
self.notify.debug('%s' % oneCard.getPos())
|
|
|
|
self.notify.debug('suit %s rank %s value %s' % (oneCard.suit, oneCard.rank, oneCard.value))
|
|
|
|
self.accept('entercardCollision-%d' % oneCard.value, self.enterCard)
|
|
|
|
self.accept('exitcardCollision-%d' % oneCard.value, self.exitCard)
|
|
|
|
oneCard.turnDown(doInterval=False)
|
|
|
|
self.cards.append(oneCard)
|
|
|
|
|
2019-12-30 00:07:56 -06:00
|
|
|
self.bonusTraversal = list(range(len(self.cards)))
|
2019-11-02 17:27:54 -05:00
|
|
|
self.bonusGlow = render.attachNewNode('bonusGlow')
|
|
|
|
sign = loader.loadModel('phase_4/models/minigames/garden_sign_memory')
|
|
|
|
sign.find('**/sign1').removeNode()
|
|
|
|
sign.find('**/sign2').removeNode()
|
|
|
|
sign.find('**/collision').removeNode()
|
|
|
|
sign.setPos(0, 0, 0.05)
|
|
|
|
sign.reparentTo(self.bonusGlow)
|
|
|
|
self.bonusGlow.setScale(2.5)
|
|
|
|
self.pointsFrame = DirectFrame(relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=GlobalDialogColor, geom_scale=(4, 1, 1), pos=(-0.33, 0, 0.9), scale=0.1, text=TTLocalizer.PairingGamePoints, text_align=TextNode.ALeft, text_scale=TTLocalizer.DPGpointsFrame, text_pos=(-1.94, -0.1, 0.0))
|
|
|
|
self.pointsLabel = DirectLabel(parent=self.pointsFrame, relief=None, text='0', text_fg=VBase4(0, 0.5, 0, 1), text_align=TextNode.ARight, text_scale=0.7, pos=(1.82, 0, -0.15))
|
|
|
|
self.flipsFrame = DirectFrame(relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=GlobalDialogColor, geom_scale=(4, 1, 1), pos=(0.33, 0, 0.9), scale=0.1, text=TTLocalizer.PairingGameFlips, text_align=TextNode.ALeft, text_scale=TTLocalizer.DPGflipsFrame, text_pos=(-1.94, -0.1, 0.0))
|
|
|
|
self.flipsLabel = DirectLabel(parent=self.flipsFrame, relief=None, text='0', text_fg=VBase4(0, 1.0, 0, 1), text_align=TextNode.ARight, text_scale=0.7, pos=(1.82, 0, -0.15))
|
|
|
|
self.__textGen = TextNode('ringGame')
|
|
|
|
self.__textGen.setFont(ToontownGlobals.getSignFont())
|
|
|
|
self.__textGen.setAlign(TextNode.ACenter)
|
2020-01-14 13:28:52 -06:00
|
|
|
self.sndPerfect = base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_all_matched.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.calcBonusTraversal()
|
2020-01-14 13:28:52 -06:00
|
|
|
self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_Pairing.ogg')
|
|
|
|
self.matchSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_match.ogg')
|
|
|
|
self.matchWithBonusSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_match_bonus_both.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.signalSfx = []
|
|
|
|
for i in range(4):
|
2020-01-14 13:28:52 -06:00
|
|
|
self.signalSfx.append(base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_jumping_signal.ogg'))
|
2019-11-02 17:27:54 -05:00
|
|
|
|
2020-01-14 13:28:52 -06:00
|
|
|
self.bonusMovesSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_pairing_bonus_moves.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
return
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
self.notify.debug('unload')
|
|
|
|
DistributedMinigame.unload(self)
|
|
|
|
self.removeChildGameFSM(self.gameFSM)
|
|
|
|
del self.gameFSM
|
|
|
|
self.gameBoard.removeNode()
|
|
|
|
del self.gameBoard
|
|
|
|
for card in self.cards:
|
|
|
|
card.unload()
|
|
|
|
del card
|
|
|
|
|
|
|
|
self.cards = []
|
|
|
|
self.pointsFrame.removeNode()
|
|
|
|
del self.pointsFrame
|
|
|
|
self.flipsFrame.removeNode()
|
|
|
|
del self.flipsFrame
|
|
|
|
del self.__textGen
|
|
|
|
del self.sndPerfect
|
|
|
|
self.bonusGlow.removeNode()
|
|
|
|
del self.bonusGlow
|
|
|
|
del self.music
|
|
|
|
del self.matchSfx
|
|
|
|
del self.matchWithBonusSfx
|
|
|
|
for i in range(4):
|
|
|
|
del self.signalSfx[0]
|
|
|
|
|
|
|
|
self.signalSfx = []
|
|
|
|
del self.bonusMovesSfx
|
|
|
|
|
|
|
|
def onstage(self):
|
|
|
|
self.notify.debug('onstage')
|
|
|
|
DistributedMinigame.onstage(self)
|
|
|
|
self.gameBoard.reparentTo(render)
|
|
|
|
for card in self.cards:
|
|
|
|
card.reparentTo(render)
|
|
|
|
|
|
|
|
lt = base.localAvatar
|
|
|
|
lt.reparentTo(render)
|
|
|
|
lt.hideName()
|
|
|
|
self.__placeToon(self.localAvId)
|
|
|
|
lt.setAnimState('Happy', 1.0)
|
|
|
|
lt.setSpeed(0, 0)
|
|
|
|
self.moveCameraToTop()
|
|
|
|
|
|
|
|
def offstage(self):
|
|
|
|
self.notify.debug('offstage')
|
|
|
|
self.gameBoard.hide()
|
|
|
|
for card in self.cards:
|
|
|
|
card.hide()
|
|
|
|
|
|
|
|
DistributedMinigame.offstage(self)
|
|
|
|
|
|
|
|
def handleDisabledAvatar(self, avId):
|
|
|
|
self.notify.debug('handleDisabledAvatar')
|
|
|
|
self.notify.debug('avatar ' + str(avId) + ' disabled')
|
|
|
|
DistributedMinigame.handleDisabledAvatar(self, avId)
|
|
|
|
|
|
|
|
def setGameReady(self):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameReady')
|
|
|
|
if DistributedMinigame.setGameReady(self):
|
|
|
|
return
|
2019-12-30 00:07:56 -06:00
|
|
|
for index in range(self.numPlayers):
|
2019-11-02 17:27:54 -05:00
|
|
|
avId = self.avIdList[index]
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if toon:
|
|
|
|
toon.reparentTo(render)
|
|
|
|
self.__placeToon(avId)
|
|
|
|
toon.setAnimState('Happy', 1.0)
|
|
|
|
toon.startSmooth()
|
|
|
|
toon.startLookAround()
|
|
|
|
|
|
|
|
def setGameStart(self, timestamp):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameStart')
|
|
|
|
DistributedMinigame.setGameStart(self, timestamp)
|
|
|
|
for avId in self.remoteAvIdList:
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if toon:
|
|
|
|
toon.stopLookAround()
|
|
|
|
|
|
|
|
self.gameFSM.request('play')
|
|
|
|
|
|
|
|
def isInPlayState(self):
|
|
|
|
if not self.gameFSM.getCurrentState():
|
|
|
|
return False
|
|
|
|
if not self.gameFSM.getCurrentState().getName() == 'play':
|
|
|
|
return False
|
|
|
|
return True
|
|
|
|
|
|
|
|
def enterOff(self):
|
|
|
|
self.notify.debug('enterOff')
|
|
|
|
|
|
|
|
def exitOff(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterPlay(self):
|
|
|
|
self.notify.debug('enterPlay')
|
|
|
|
base.playMusic(self.music, looping=1, volume=0.9)
|
|
|
|
orthoDrive = OrthoDrive(self.TOON_SPEED, maxFrameMove=self.MAX_FRAME_MOVE, customCollisionCallback=self.__doPairingGameCollisions)
|
|
|
|
self.orthoWalk = OrthoWalk(orthoDrive, broadcast=not self.isSinglePlayer())
|
|
|
|
self.orthoWalk.start()
|
|
|
|
self.accept('insert', self.__flipKeyPressed)
|
|
|
|
self.accept('delete', self.__flipKeyPressed)
|
|
|
|
self.accept('time-control', self.__beginSignal)
|
|
|
|
self.accept('time-control-up', self.__endSignal)
|
|
|
|
self.bonusGlowIndex = 0
|
|
|
|
self.bonusGlowCard = self.bonusTraversal[self.bonusGlowIndex]
|
|
|
|
self.startBonusTask()
|
|
|
|
self.timer = ToontownTimer.ToontownTimer()
|
|
|
|
self.timer.posInTopRightCorner()
|
|
|
|
self.timer.setTime(self.gameDuration)
|
|
|
|
self.timer.countdown(self.gameDuration, self.timerExpired)
|
|
|
|
if base.localAvatar.laffMeter:
|
|
|
|
base.localAvatar.laffMeter.stop()
|
|
|
|
|
|
|
|
def exitPlay(self):
|
|
|
|
self.music.stop()
|
|
|
|
self.orthoWalk.stop()
|
|
|
|
self.orthoWalk.destroy()
|
|
|
|
del self.orthoWalk
|
|
|
|
self.bonusGlow.hide()
|
|
|
|
self.stopBonusTask()
|
|
|
|
self.timer.stop()
|
|
|
|
self.timer.destroy()
|
|
|
|
del self.timer
|
|
|
|
self.ignoreAll()
|
|
|
|
if base.localAvatar.laffMeter:
|
|
|
|
base.localAvatar.laffMeter.start()
|
|
|
|
if hasattr(self, 'perfectIval'):
|
|
|
|
self.perfectIval.pause()
|
|
|
|
del self.perfectIval
|
|
|
|
taskMgr.remove(self.EndGameTaskName)
|
|
|
|
taskMgr.remove('pairGameContinueSignal')
|
|
|
|
|
|
|
|
def enterCleanup(self):
|
|
|
|
self.notify.debug('enterCleanup')
|
|
|
|
|
|
|
|
def exitCleanup(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def __placeToon(self, avId):
|
|
|
|
toon = self.getAvatar(avId)
|
|
|
|
if self.numPlayers == 1:
|
|
|
|
toon.setPos(0, 0, 0)
|
|
|
|
toon.setHpr(0, 0, 0)
|
|
|
|
else:
|
|
|
|
posIndex = self.avIdList.index(avId)
|
|
|
|
pos = self.startingPositions[posIndex]
|
|
|
|
toon.setPos(pos[0], pos[1], pos[2])
|
|
|
|
toon.setHpr(pos[3], 0, 0)
|
|
|
|
|
|
|
|
def __doPairingGameCollisions(self, oldPos, newPos):
|
|
|
|
x = bound(newPos[0], self.stageMin[0], self.stageMax[0])
|
|
|
|
y = bound(newPos[1], self.stageMin[1], self.stageMax[1])
|
|
|
|
newPos.setX(x)
|
|
|
|
newPos.setY(y)
|
|
|
|
if self.inList:
|
|
|
|
newPos.setZ(0.15)
|
|
|
|
else:
|
|
|
|
newPos.setZ(0.0)
|
|
|
|
if not oldPos == newPos:
|
|
|
|
taskMgr.remove('pairGameContinueSignal')
|
|
|
|
return newPos
|
|
|
|
|
|
|
|
def getDeckOrderFromValue(self, value):
|
2019-12-30 00:07:56 -06:00
|
|
|
for index in range(len(self.cards)):
|
2019-11-02 17:27:54 -05:00
|
|
|
if self.cards[index].value == value:
|
|
|
|
return index
|
|
|
|
|
|
|
|
return -1
|
|
|
|
|
|
|
|
def getDeckOrderFromPairingGameCard(self, into):
|
|
|
|
try:
|
|
|
|
index = self.cards.index(into)
|
|
|
|
except ValueError:
|
|
|
|
index = -1
|
|
|
|
|
|
|
|
return index
|
|
|
|
|
|
|
|
def enterCard(self, colEntry):
|
|
|
|
intoName = colEntry.getIntoNodePath().getName()
|
|
|
|
parts = intoName.split('-')
|
|
|
|
value = int(parts[1])
|
|
|
|
self.notify.debug('entered cardValue %d' % value)
|
|
|
|
deckOrder = self.getDeckOrderFromValue(value)
|
|
|
|
if deckOrder not in self.inList:
|
|
|
|
self.inList.append(deckOrder)
|
|
|
|
|
|
|
|
def exitCard(self, colEntry):
|
|
|
|
intoName = colEntry.getIntoNodePath().getName()
|
|
|
|
parts = intoName.split('-')
|
|
|
|
value = int(parts[1])
|
|
|
|
self.notify.debug('exited cardValue %d' % value)
|
|
|
|
deckOrder = self.getDeckOrderFromValue(value)
|
|
|
|
if deckOrder in self.inList:
|
|
|
|
self.inList.remove(deckOrder)
|
|
|
|
|
|
|
|
def handleMatch(self, cardA, cardB, withBonus):
|
|
|
|
self.notify.debug('we got a match %d %d' % (cardA, cardB))
|
|
|
|
self.matches += 1
|
|
|
|
if cardA in self.faceUpList:
|
|
|
|
self.faceUpList.remove(cardA)
|
|
|
|
if cardB in self.faceUpList:
|
|
|
|
self.faceUpList.remove(cardB)
|
|
|
|
self.inactiveList.append(cardA)
|
|
|
|
self.inactiveList.append(cardB)
|
|
|
|
matchIval = Parallel()
|
|
|
|
for card in [cardA, cardB]:
|
|
|
|
self.cards[card].setTransparency(1)
|
|
|
|
cardSeq = Sequence(LerpColorScaleInterval(self.cards[card], duration=1, colorScale=Vec4(1.0, 1.0, 1.0, 0.0)), Func(self.cards[card].hide))
|
|
|
|
matchIval.append(cardSeq)
|
|
|
|
|
|
|
|
if withBonus:
|
|
|
|
matchIval.append(SoundInterval(self.matchWithBonusSfx, node=self.cards[card], listenerNode=base.localAvatar, cutOff=240))
|
|
|
|
else:
|
|
|
|
matchIval.append(SoundInterval(self.matchSfx, node=self.cards[card], listenerNode=base.localAvatar, cutOff=240))
|
|
|
|
matchIval.start()
|
|
|
|
if len(self.inactiveList) == len(self.cards):
|
|
|
|
self.sendUpdate('reportDone')
|
|
|
|
|
|
|
|
def turnUpCard(self, deckOrder):
|
|
|
|
self.cards[deckOrder].turnUp()
|
|
|
|
self.faceUpList.append(deckOrder)
|
|
|
|
|
|
|
|
def turnDownCard(self, deckOrder):
|
|
|
|
self.cards[deckOrder].turnDown()
|
|
|
|
if deckOrder in self.faceUpList:
|
|
|
|
self.faceUpList.remove(deckOrder)
|
|
|
|
|
|
|
|
def __flipKeyPressed(self):
|
|
|
|
if self.inList:
|
|
|
|
shortestDistance = 10000
|
|
|
|
cardToFlip = -1
|
|
|
|
for deckOrder in self.inList:
|
|
|
|
dist = base.localAvatar.getDistance(self.cards[deckOrder])
|
|
|
|
if dist < shortestDistance:
|
|
|
|
shortestDistance = dist
|
|
|
|
cardToFlip = deckOrder
|
|
|
|
|
|
|
|
deckOrderIndex = cardToFlip
|
|
|
|
card = self.cards[deckOrderIndex]
|
|
|
|
if card.isFaceDown() and deckOrderIndex not in self.inactiveList:
|
|
|
|
self.sendUpdate('openCardRequest', [deckOrderIndex, self.bonusGlowCard])
|
|
|
|
elif card.isFaceUp() and deckOrderIndex in self.faceUpList:
|
|
|
|
pass
|
|
|
|
|
|
|
|
def moveBonusGlowTask(self, task):
|
|
|
|
if len(self.cards) == 0:
|
|
|
|
return Task.done
|
|
|
|
curT = self.getCurrentGameTime()
|
|
|
|
intTime = int(curT / self.bonusGlowTime)
|
|
|
|
newIndex = intTime % len(self.cards)
|
|
|
|
if not newIndex == self.bonusGlowIndex:
|
|
|
|
self.bonusGlowIndex = newIndex
|
|
|
|
self.bonusGlowCard = self.bonusTraversal[self.bonusGlowIndex]
|
|
|
|
card = self.cards[self.bonusGlowCard]
|
|
|
|
self.bonusGlow.setPos(card.getPos())
|
|
|
|
base.playSfx(self.bonusMovesSfx, node=card, volume=0.25)
|
|
|
|
return Task.cont
|
|
|
|
|
|
|
|
def timerExpired(self):
|
|
|
|
self.sendUpdate('reportDone')
|
|
|
|
|
|
|
|
def setDeckSeed(self, deckSeed):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.deckSeed = deckSeed
|
|
|
|
|
|
|
|
def updateFlipText(self):
|
|
|
|
self.flipsLabel['text'] = str(self.flips)
|
|
|
|
lowFlipModifier = PairingGameGlobals.calcLowFlipModifier(self.matches, self.flips)
|
|
|
|
red = 1.0 - lowFlipModifier
|
|
|
|
green = lowFlipModifier
|
|
|
|
self.flipsLabel['text_fg'] = Vec4(red, green, 0, 1.0)
|
|
|
|
|
|
|
|
def openCardResult(self, cardToTurnUp, avId, matchingCard, points, cardsToTurnDown):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
if not self.isInPlayState():
|
|
|
|
return
|
|
|
|
if avId == base.localAvatar.doId:
|
|
|
|
self.localFaceUpList.append(cardToTurnUp)
|
|
|
|
self.turnUpCard(cardToTurnUp)
|
|
|
|
gotBonus = False
|
|
|
|
if points - self.points > 1:
|
|
|
|
gotBonus = True
|
|
|
|
if matchingCard > -1:
|
|
|
|
self.handleMatch(cardToTurnUp, matchingCard, gotBonus)
|
|
|
|
self.flips += 1
|
|
|
|
self.updateFlipText()
|
|
|
|
self.points = points
|
|
|
|
self.pointsLabel['text'] = str(self.points)
|
|
|
|
for card in cardsToTurnDown:
|
|
|
|
self.turnDownCard(card)
|
|
|
|
|
|
|
|
def startBonusTask(self):
|
|
|
|
taskMgr.add(self.moveBonusGlowTask, self.taskName('moveBonusGlowTask'))
|
|
|
|
|
|
|
|
def stopBonusTask(self):
|
|
|
|
taskMgr.remove(self.taskName('moveBonusGlowTask'))
|
|
|
|
|
|
|
|
def setEveryoneDone(self):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
if self.gameFSM.getCurrentState().getName() != 'play':
|
|
|
|
self.notify.warning('ignoring setEveryoneDone msg')
|
|
|
|
return
|
|
|
|
self.notify.debug('setEveryoneDone')
|
|
|
|
|
|
|
|
def endGame(task, self = self):
|
|
|
|
if not PairingGameGlobals.EndlessGame:
|
|
|
|
self.gameOver()
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
self.timer.hide()
|
|
|
|
self.bonusGlow.hide()
|
|
|
|
if len(self.inactiveList) == len(self.cards):
|
|
|
|
self.notify.debug('perfect game!')
|
|
|
|
perfectTextSubnode = hidden.attachNewNode(self.__genText(TTLocalizer.PairingGamePerfect))
|
|
|
|
perfectText = hidden.attachNewNode('perfectText')
|
|
|
|
perfectTextSubnode.reparentTo(perfectText)
|
|
|
|
frame = self.__textGen.getCardActual()
|
|
|
|
offsetY = -abs(frame[2] + frame[3]) / 2.0
|
|
|
|
perfectTextSubnode.setPos(0, 0, offsetY)
|
|
|
|
perfectText.setColor(1, 0.1, 0.1, 1)
|
|
|
|
|
|
|
|
def fadeFunc(t, text = perfectText):
|
|
|
|
text.setColorScale(1, 1, 1, t)
|
|
|
|
|
|
|
|
def destroyText(text = perfectText):
|
|
|
|
text.removeNode()
|
|
|
|
|
|
|
|
textTrack = Sequence(Func(perfectText.reparentTo, aspect2d), Parallel(LerpScaleInterval(perfectText, duration=0.5, scale=0.3, startScale=0.0), LerpFunctionInterval(fadeFunc, fromData=0.0, toData=1.0, duration=0.5)), Wait(2.0), Parallel(LerpScaleInterval(perfectText, duration=0.5, scale=1.0), LerpFunctionInterval(fadeFunc, fromData=1.0, toData=0.0, duration=0.5, blendType='easeIn')), Func(destroyText), WaitInterval(0.5), Func(endGame, None))
|
|
|
|
soundTrack = SoundInterval(self.sndPerfect)
|
|
|
|
self.perfectIval = Parallel(textTrack, soundTrack)
|
|
|
|
self.perfectIval.start()
|
|
|
|
else:
|
|
|
|
taskMgr.doMethodLater(1, endGame, self.EndGameTaskName)
|
|
|
|
return
|
|
|
|
|
|
|
|
def __genText(self, text):
|
|
|
|
self.__textGen.setText(text)
|
|
|
|
return self.__textGen.generate()
|
|
|
|
|
|
|
|
def b_setSignaling(self, avId):
|
|
|
|
self.setSignaling(avId)
|
|
|
|
self.sendUpdate('setSignaling', [self.localAvId])
|
|
|
|
|
|
|
|
def setSignaling(self, avId):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
avIndex = self.avIdList.index(avId)
|
|
|
|
av = base.cr.doId2do.get(avId)
|
|
|
|
if av and avIndex >= 0 and hasattr(self, 'signalSfx') and self.signalSfx:
|
|
|
|
base.playSfx(self.signalSfx[avIndex], node=av)
|
|
|
|
|
|
|
|
def __beginSignal(self, mouseParam):
|
|
|
|
self.notify.debug('beginSignal')
|
|
|
|
base.localAvatar.b_setEmoteState(1, 1.0)
|
|
|
|
self.b_setSignaling(self.localAvId)
|
|
|
|
taskMgr.doMethodLater(1.67, self.__continueSignal, 'pairGameContinueSignal')
|
|
|
|
|
|
|
|
def __endSignal(self, mouseParam):
|
|
|
|
self.notify.debug('endSignal')
|
|
|
|
base.localAvatar.b_setEmoteState(-1, 1.0)
|
|
|
|
taskMgr.remove('pairGameContinueSignal')
|
|
|
|
|
|
|
|
def __continueSignal(self, task):
|
|
|
|
base.localAvatar.b_setEmoteState(1, 1.0)
|
|
|
|
self.b_setSignaling(self.localAvId)
|
|
|
|
taskMgr.doMethodLater(1.67, self.__continueSignal, 'pairGameContinueSignal')
|
|
|
|
|
|
|
|
def getCardPos(self, deckOrderIndex):
|
|
|
|
col = deckOrderIndex % self.cardsPerRow
|
2019-12-31 12:36:56 -06:00
|
|
|
row = deckOrderIndex // self.cardsPerRow
|
2019-11-02 17:27:54 -05:00
|
|
|
x = col * self.xCardInc
|
|
|
|
y = row * self.yCardInc
|
|
|
|
return (x, y)
|
|
|
|
|
|
|
|
def getDeckOrderIndex(self, row, col):
|
|
|
|
retval = row * self.cardsPerRow
|
|
|
|
retval += col
|
|
|
|
if retval >= len(self.deck.cards):
|
|
|
|
retval = -1
|
|
|
|
return retval
|
|
|
|
|
|
|
|
def calcBonusTraversal(self):
|
|
|
|
self.bonusTraversal = []
|
2019-12-31 12:36:56 -06:00
|
|
|
halfRow = self.cardsPerRow // 2
|
2019-11-02 17:27:54 -05:00
|
|
|
if self.cardsPerRow % 2:
|
|
|
|
halfRow += 1
|
2019-12-30 00:07:56 -06:00
|
|
|
for i in range(halfRow):
|
|
|
|
for j in range(2):
|
2019-11-02 17:27:54 -05:00
|
|
|
col = i + j * halfRow
|
2019-12-30 00:07:56 -06:00
|
|
|
for row in range(self.cardsPerCol):
|
2019-11-02 17:27:54 -05:00
|
|
|
card = self.getDeckOrderIndex(row, col)
|
|
|
|
if card > -1:
|
|
|
|
self.bonusTraversal.append(card)
|