toontown-just-works/toontown/fishing/BingoCardGui.py
2024-07-07 18:08:39 -05:00

437 lines
17 KiB
Python

from direct.directnotify import DirectNotifyGlobal
from direct.gui.DirectGui import *
from panda3d.core import *
from direct.task import Task
import random
from toontown.fishing import BingoCardCell
from toontown.fishing import BingoGlobals
from toontown.fishing import FishBase
from toontown.fishing import FishGlobals
from direct.showbase import RandomNumGen
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import ToontownTimer
from toontown.toonbase import TTLocalizer
from toontown.toontowngui import TTDialog
BG = BingoGlobals
class BingoCardGui(DirectFrame):
notify = DirectNotifyGlobal.directNotify.newCategory('BingoCardGui')
def __init__(self, parent = aspect2d, **kw):
self.notify.debug('Bingo card initialized')
self.model = loader.loadModel('phase_4/models/gui/FishBingo')
optiondefs = (('relief', None, None),
('state', DGG.NORMAL, None),
('image', self.model.find('**/g'), None),
('image_color', BG.getColor(0), None),
('image_scale', BG.CardImageScale, None),
('image_hpr', (0.0, 90.0, 0.0), None),
('pos', BG.CardPosition, None))
self.defineoptions(kw, optiondefs)
DirectFrame.__init__(self, parent)
self.initialiseoptions(BingoCardGui)
self.game = None
self.cellGuiList = []
self.parent = parent
self.load()
self.hide()
self.taskNameFlashFish = 'flashMatchingFishTask'
return
def show(self):
DirectFrame.show(self)
if self.game and self.game.checkForBingo():
self.__indicateBingo(True)
if self.game.getGameType() == BG.BLOCKOUT_CARD:
self.showJackpot()
def hide(self):
self.hideTutorial()
self.hideJackpot()
DirectFrame.hide(self)
def loadGameTimer(self):
self.timer = ToontownTimer.ToontownTimer()
self.timer.reparentTo(self)
self.timer.setScale(0.17)
self.timer.setPos(0.24, 0, -0.18)
def resetGameTimer(self):
self.timer.reset()
def startGameCountdown(self, time):
self.notify.debug('startGameCountdown: %s' % time)
self.timer.countdown(time)
def startNextGameCountdown(self, time):
self.nextGameTimer.countdown(time)
def hideNextGameTimer(self):
self.nextGame['text'] = ''
self.nextGame.hide()
def showNextGameTimer(self, text):
self.nextGame['text'] = text
self.nextGame.show()
def resetNextGameTimer(self):
self.nextGameTimer.reset()
def stopNextGameTimer(self):
self.nextGameTimer.stop()
def setNextGameText(self, text):
self.nextGame['text'] = text
def setJackpotText(self, text):
if text:
str = TTLocalizer.FishBingoJackpotWin % text
else:
str = ''
self.jpText['text'] = str
def resetGameTypeText(self):
self.gameType['text'] = ''
self.gameType.setFrameSize()
self.gameType.hide()
def loadNextGameTimer(self):
self.nextGame = DirectLabel(parent=self, relief=None, text='', text_font=ToontownGlobals.getSignFont(), text_scale=TTLocalizer.BCGnextGame * BG.CardImageScale[2], text_fg=(1.0, 1.0, 1.0, 1), pos=(BG.GridXOffset, 0, 4 * BG.CardImageScale[2]))
self.nextGameTimer = ToontownTimer.ToontownTimer()
self.nextGameTimer.reparentTo(self.nextGame)
self.nextGameTimer.setPos(0, 0, -5 * BG.CardImageScale[2])
self.nextGameTimer.setProp('image', None)
self.nextGameTimer.setProp('text_font', ToontownGlobals.getSignFont())
self.nextGameTimer.setProp('text_scale', 0.2 * BG.CardImageScale[2])
self.nextGameTimer.setFontColor(Vec4(1.0, 1.0, 1.0, 1))
return
def setGameOver(self, text):
self.gameOver['text'] = text
def load(self):
self.notify.debug('Bingo card loading')
self.loadGameTimer()
self.loadNextGameTimer()
textScale = 0.06
textHeight = 0.38 * BG.CardImageScale[2]
guiButton = loader.loadModel('phase_3/models/gui/quit_button')
self.bingo = DirectButton(parent=self, pos=(BG.GridXOffset, 0, 0.305), scale=(0.0343, 0.035, 0.035), relief=None, state=DGG.DISABLED, geom=self.model.find('**/BINGObutton'), geom_pos=(0, 0, 0), geom_hpr=(0, 90, 0), image=(self.model.find('**/Gold_TTButtUP'), self.model.find('**/goldTTButtDown'), self.model.find('**/RolloverBingoButton1')), image_pos=(0, 0, 0), image_hpr=(0, 90, 0), image_color=BG.getButtonColor(0), pressEffect=False)
guiButton.removeNode()
arrowModel = loader.loadModel('phase_3.5/models/gui/speedChatGui')
self.gameType = DirectButton(parent=self, pos=(BG.GridXOffset, 0, -8 * BG.CardImageScale[2] - 0.01), relief=None, image=arrowModel.find('**/chatArrow'), image_scale=-0.05, image_pos=(-0.2, 0, 0.025), text='', text_scale=0.045, text_fg=(1, 1, 1, 1), text_font=ToontownGlobals.getSignFont(), text_wordwrap=10.5, text_pos=(0.01, 0.008), pressEffect=False)
arrowModel.removeNode()
self.gameType.bind(DGG.ENTER, self.onMouseEnter)
self.gameType.bind(DGG.EXIT, self.onMouseLeave)
self.gameType.hide()
self.jpText = DirectLabel(parent=self, pos=(BG.GridXOffset, 0, 0.22), relief=None, state=DGG.NORMAL, text='', text_scale=TTLocalizer.BCGjpText, text_pos=(0, 0, 0), text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_font=ToontownGlobals.getInterfaceFont(), text_wordwrap=TTLocalizer.BCGjpTextWordwrap)
self.gameOver = DirectLabel(parent=self, pos=(BG.GridXOffset, 0, 0), relief=None, state=DGG.NORMAL, text='', text_scale=textScale, text_fg=(1, 1, 1, 1), text_font=ToontownGlobals.getSignFont())
self.jpSign = DirectFrame(parent=self.parent, relief=None, state=DGG.NORMAL, pos=BG.CardPosition, scale=(0.035, 0.035, 0.035), text=TTLocalizer.FishBingoJackpot, text_scale=2, text_pos=(-1.5, 18.6), text_fg=(1, 1, 1, 1), image=self.model.find('**/jackpot'), image_pos=(0, 0, 0), image_hpr=(0, 90, 0), sortOrder=DGG.BACKGROUND_SORT_INDEX)
self.makeJackpotLights(self.jpSign)
self.hideJackpot()
self.makeTutorial()
return
def destroy(self):
self.cleanTutorial()
self.removeGame()
del self.cellGuiList
self.gameOver.destroy()
self.destroyJackpotLights()
self.jpSign.destroy()
self.nextGameTimer.destroy()
self.nextGame.destroy()
self.timer.destroy()
self.bingo.destroy()
self.gameType.destroy()
DirectFrame.destroy(self)
self.notify.debug('Bingo card destroyed')
def loadCard(self):
cardSize = self.game.getCardSize()
for index in xrange(cardSize):
self.cellGuiList[index].generateLogo()
if index == cardSize / 2:
self.cellGuiList[index].generateMarkedLogo()
elif self.game.getGameState() & 1 << index:
self.cellGuiList[index].disable()
def enableCard(self, callback = None):
self.notify.info('enable Bingo card')
self.stopCellBlinking()
for index in xrange(len(self.cellGuiList)):
if index != self.game.getCardSize() / 2:
self.cellGuiList[index].enable(callback)
def generateCard(self, tileSeed, zoneId):
rng = RandomNumGen.RandomNumGen(tileSeed)
rowSize = self.game.getRowSize()
fishList = FishGlobals.getPondGeneraList(zoneId)
for i in xrange(len(fishList)):
fishTuple = fishList.pop(0)
weight = FishGlobals.getRandomWeight(fishTuple[0], fishTuple[1])
fish = FishBase.FishBase(fishTuple[0], fishTuple[1], weight)
fishList.append(fish)
emptyCells = self.game.getCardSize() - 1 - len(fishList)
rodId = 0
for i in xrange(emptyCells):
fishVitals = FishGlobals.getRandomFishVitals(zoneId, rodId, rng)
while not fishVitals[0]:
fishVitals = FishGlobals.getRandomFishVitals(zoneId, rodId, rng)
fish = FishBase.FishBase(fishVitals[1], fishVitals[2], fishVitals[3])
fishList.append(fish)
rodId += 1
if rodId > 4:
rodId = 0
for i in xrange(rowSize):
for j in xrange(self.game.getColSize()):
color = self.getCellColor(i * rowSize + j)
if i * rowSize + j == self.game.getCardSize() / 2:
tmpFish = 'Free'
else:
choice = rng.randrange(0, len(fishList))
tmpFish = fishList.pop(choice)
xPos = BG.CellImageScale * (j - 2) + BG.GridXOffset
yPos = BG.CellImageScale * (i - 2) - 0.015
cellGui = BingoCardCell.BingoCardCell(i * rowSize + j, tmpFish, self.model, color, self, image_scale=BG.CellImageScale, pos=(xPos, 0, yPos))
self.cellGuiList.append(cellGui)
def cellUpdateCheck(self, id, genus, species):
fishTuple = (genus, species)
if self.cellGuiList[id].getFishGenus() == genus or fishTuple == FishGlobals.BingoBoot:
self.notify.debug('Square found! Cell disabled: %s' % id)
self.stopCellBlinking()
self.cellGuiList[id].disable()
self.game.setGameState(self.game.getGameState() | 1 << id)
if self.game.checkForBingo():
return BG.WIN
return BG.UPDATE
return BG.NO_UPDATE
def cellUpdate(self, cellId):
self.cellGuiList[cellId].disable()
def addGame(self, game):
self.game = game
type = game.getGameType()
self.gameType.setProp('text', BG.getGameName(type))
self.gameType.setFrameSize()
self.gameType.show()
def getGame(self):
return self.game
def removeGame(self):
self.stopCellBlinking()
if self.game:
self.game.destroy()
self.game = None
self.setJackpotText(None)
self.resetGameTypeText()
for cell in self.cellGuiList:
cell.destroy()
self.cellGuiList = []
return
def getUnmarkedMatches(self, fish):
if self.game is None:
return []
matches = []
for cell in self.cellGuiList:
if cell['state'] == DGG.NORMAL:
if cell.getFishGenus() == fish[0] or fish == FishGlobals.BingoBoot:
matches.append(cell)
return matches
def getCellColor(self, id):
if self.game.checkForColor(id):
return BG.CellColorActive
return BG.CellColorInactive
def resetCellColors(self):
for cell in self.cellGuiList:
c = self.getCellColor(cell.cellId)
cell['image'].setColor(c[0], c[1], c[2], c[3])
cell.setImage()
def stopCellBlinking(self):
self.hideTutorial()
self.resetCellColors()
taskMgr.remove(self.taskNameFlashFish)
def __indicateMatches(self, bFlipFlop, fish):
unmarkedMatches = self.getUnmarkedMatches(fish)
if len(unmarkedMatches) is 0:
return Task.done
if bFlipFlop:
for cell in unmarkedMatches:
cell['image'].setColor(1, 0, 0, 1)
cell.setImage()
else:
self.resetCellColors()
taskMgr.doMethodLater(0.5, self.__indicateMatches, self.taskNameFlashFish, extraArgs=(not bFlipFlop, fish))
return Task.done
def fishCaught(self, fish):
self.stopCellBlinking()
self.__indicateMatches(True, fish)
def setBingo(self, state = DGG.DISABLED, callback = None):
self.notify.debug('setBingo: %s %s' % (state, callback))
if self.bingo['state'] == state:
return
if not self.game:
return
if state == DGG.NORMAL:
self.__indicateBingo(True)
if self.game.getGameType() == BG.BLOCKOUT_CARD:
self.showJackpot()
else:
taskMgr.remove('bingoFlash')
c = BG.getButtonColor(self.game.getGameType())
self.bingo['image_color'] = Vec4(c[0], c[1], c[2], c[3])
self.hideJackpot()
self.bingo['state'] = state
self.bingo['command'] = callback
def checkForBingo(self):
return self.game.checkForBingo()
def __indicateBingo(self, bFlipFlop):
if not self.game:
return Task.done
if bFlipFlop:
gameType = self.game.getGameType()
if gameType == BG.DIAGONAL_CARD:
color = Vec4(1, 1, 1, 1)
else:
color = Vec4(1, 0, 0, 1)
self.bingo['image_color'] = color
else:
c = BG.getButtonColor(self.game.getGameType())
self.bingo['image_color'] = Vec4(c[0], c[1], c[2], c[3])
taskMgr.doMethodLater(0.5, self.__indicateBingo, 'bingoFlash', extraArgs=(not bFlipFlop,))
return Task.done
NumLights = 32
Off = False
On = True
def showJackpot(self):
self.jpSign.show()
for light in self.jpLights:
light.show()
self.flashJackpotLights(random.randrange(3))
def hideJackpot(self):
self.jpSign.hide()
for light in self.jpLights:
light.hide()
taskMgr.remove('jackpotLightFlash')
def getLightName(self, lightIndex, bOn):
lightIndex += 1
if bOn == self.On:
return '**/LightOn_0%02d' % lightIndex
else:
return '**/LightOff_0%02d' % lightIndex
def makeJackpotLights(self, parent):
self.jpLights = []
for nLight in xrange(self.NumLights):
lightName = self.getLightName(nLight, self.Off)
light = DirectFrame(parent=parent, relief=None, image=self.model.find(lightName), image_hpr=(0, 90, 0))
self.jpLights.append(light)
return
def destroyJackpotLights(self):
taskMgr.remove('jackpotLightFlash')
for light in self.jpLights:
light.destroy()
def lightSwitch(self, bOn, lightIndex = -1):
if lightIndex == -1:
for nLight in xrange(self.NumLights):
self.lightSwitch(bOn, nLight)
else:
lightIndex %= self.NumLights
light = self.jpLights[lightIndex - 1]
light['image'] = self.model.find(self.getLightName(lightIndex, bOn))
light['image_hpr'] = (0, 90, 0)
def flashJackpotLights(self, flashMode, nTimeIndex = 0):
if flashMode == 2:
self.lightSwitch(self.Off)
self.lightSwitch(self.On, nTimeIndex)
self.lightSwitch(self.On, self.NumLights - nTimeIndex)
self.lightSwitch(self.On, self.NumLights / 2 + nTimeIndex)
self.lightSwitch(self.On, self.NumLights / 2 - nTimeIndex)
nTimeIndex = (nTimeIndex + 1) % (self.NumLights / 2)
delay = 0.05
elif flashMode == 1:
if nTimeIndex:
self.lightSwitch(self.On)
else:
self.lightSwitch(self.Off)
nTimeIndex = not nTimeIndex
delay = 0.5
elif flashMode == 0:
for nLight in xrange(self.NumLights):
if nLight % 2 == nTimeIndex:
self.lightSwitch(self.On, nLight)
else:
self.lightSwitch(self.Off, nLight)
nTimeIndex = (nTimeIndex + 1) % 2
delay = 0.2
taskMgr.doMethodLater(delay, self.flashJackpotLights, 'jackpotLightFlash', extraArgs=(flashMode, nTimeIndex))
return Task.done
def makeTutorial(self):
self.tutorial = TTDialog.TTDialog(fadeScreen=0, pad=(0.05, 0.05), midPad=0, topPad=0, sidePad=0, text=TTLocalizer.FishBingoHelpBlockout, style=TTDialog.NoButtons, pos=BG.TutorialPosition, scale=BG.TutorialScale)
self.tutorial.hide()
def cleanTutorial(self):
self.tutorial.cleanup()
self.tutorial = None
return
def showTutorial(self, messageType):
if messageType == BG.TutorialIntro:
self.tutorial['text'] = TTLocalizer.FishBingoHelpMain
elif messageType == BG.TutorialMark:
self.tutorial['text'] = TTLocalizer.FishBingoHelpFlash
elif messageType == BG.TutorialCard:
if self.game:
gameType = self.game.getGameType()
self.tutorial['text'] = BG.getHelpString(gameType)
elif messageType == BG.TutorialBingo:
self.tutorial['text'] = TTLocalizer.FishBingoHelpBingo
self.tutorial.show()
def hideTutorial(self, event = None):
if self.tutorial:
self.tutorial.hide()
def onMouseEnter(self, event):
if self.gameType['text'] is not '':
self.showTutorial(BG.TutorialCard)
def onMouseLeave(self, event):
self.hideTutorial()
def castingStarted(self):
if taskMgr.hasTaskNamed(self.taskNameFlashFish):
if not base.localAvatar.fishBingoMarkTutorialDone:
self.showTutorial(BG.TutorialMark)
base.localAvatar.b_setFishBingoMarkTutorialDone(True)