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 *
|
|
|
|
from toontown.toonbase.ToontownGlobals import GlobalDialogColor
|
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
|
|
|
|
from toontown.toonbase import ToontownTimer
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import TravelGameGlobals
|
2019-11-02 17:27:54 -05:00
|
|
|
import math
|
2022-12-16 18:40:57 -06:00
|
|
|
from panda3d.core import rad2Deg
|
2019-11-02 17:27:54 -05:00
|
|
|
from toontown.toontowngui import TTDialog
|
|
|
|
from direct.interval.IntervalGlobal import *
|
2019-12-30 00:07:56 -06:00
|
|
|
from . import VoteResultsPanel
|
|
|
|
from . import VoteResultsTrolleyPanel
|
2019-11-02 17:27:54 -05:00
|
|
|
IconDict = {ToontownGlobals.RaceGameId: 'mg_trolley_sign_race',
|
|
|
|
ToontownGlobals.CannonGameId: 'mg_trolley_sign_cannon',
|
|
|
|
ToontownGlobals.TagGameId: 'mg_trolley_sign_tag',
|
|
|
|
ToontownGlobals.PatternGameId: 'mg_trolley_sign_minnie',
|
|
|
|
ToontownGlobals.RingGameId: 'mg_trolley_sign_ring',
|
|
|
|
ToontownGlobals.MazeGameId: 'mg_trolley_sign_maze',
|
|
|
|
ToontownGlobals.TugOfWarGameId: 'mg_trolley_sign_tugawar',
|
|
|
|
ToontownGlobals.CatchGameId: 'mg_trolley_sign_catch',
|
|
|
|
ToontownGlobals.DivingGameId: 'mg_trolley_sign_dive',
|
|
|
|
ToontownGlobals.TargetGameId: 'mg_trolley_sign_umbrella',
|
|
|
|
ToontownGlobals.PairingGameId: 'mg_trolley_sign_card',
|
|
|
|
ToontownGlobals.VineGameId: 'mg_trolley_sign_vine',
|
|
|
|
ToontownGlobals.IceGameId: 'mg_trolley_sign_ice',
|
|
|
|
ToontownGlobals.PhotoGameId: 'mg_trolley_sign_photo',
|
|
|
|
ToontownGlobals.TwoDGameId: 'mg_trolley_sign_2d',
|
|
|
|
ToontownGlobals.CogThiefGameId: 'mg_trolley_sign_theif'}
|
|
|
|
MinigameNameDict = {ToontownGlobals.RaceGameId: TTLocalizer.RaceGameTitle,
|
|
|
|
ToontownGlobals.CannonGameId: TTLocalizer.CannonGameTitle,
|
|
|
|
ToontownGlobals.TagGameId: TTLocalizer.TagGameTitle,
|
|
|
|
ToontownGlobals.PatternGameId: TTLocalizer.PatternGameTitle,
|
|
|
|
ToontownGlobals.RingGameId: TTLocalizer.RingGameTitle,
|
|
|
|
ToontownGlobals.MazeGameId: TTLocalizer.MazeGameTitle,
|
|
|
|
ToontownGlobals.TugOfWarGameId: TTLocalizer.TugOfWarGameTitle,
|
|
|
|
ToontownGlobals.CatchGameId: TTLocalizer.CatchGameTitle,
|
|
|
|
ToontownGlobals.DivingGameId: TTLocalizer.DivingGameTitle,
|
|
|
|
ToontownGlobals.TargetGameId: TTLocalizer.TargetGameTitle,
|
|
|
|
ToontownGlobals.PairingGameId: TTLocalizer.PairingGameTitle,
|
|
|
|
ToontownGlobals.VineGameId: TTLocalizer.VineGameTitle,
|
|
|
|
ToontownGlobals.TravelGameId: TTLocalizer.TravelGameTitle,
|
|
|
|
ToontownGlobals.IceGameId: TTLocalizer.IceGameTitle,
|
|
|
|
ToontownGlobals.PhotoGameId: TTLocalizer.PhotoGameTitle,
|
|
|
|
ToontownGlobals.TwoDGameId: TTLocalizer.TwoDGameTitle,
|
|
|
|
ToontownGlobals.CogThiefGameId: TTLocalizer.CogThiefGameTitle}
|
|
|
|
|
|
|
|
def makeLabel(itemName, itemNum, *extraArgs):
|
|
|
|
intVersion = int(itemName)
|
|
|
|
if intVersion < 0:
|
|
|
|
textColor = Vec4(0, 0, 1, 1)
|
|
|
|
intVersion = -intVersion
|
|
|
|
elif intVersion == 0:
|
|
|
|
textColor = Vec4(0, 0, 0, 1)
|
|
|
|
else:
|
|
|
|
textColor = Vec4(1, 0, 0, 1)
|
|
|
|
return DirectLabel(text=str(intVersion), text_fg=textColor, relief=DGG.RIDGE, frameSize=(-1.2,
|
|
|
|
1.2,
|
|
|
|
-0.225,
|
|
|
|
0.8), scale=1.0)
|
|
|
|
|
|
|
|
|
|
|
|
def map3dToAspect2d(node, point):
|
|
|
|
p3 = base.cam.getRelativePoint(node, point)
|
|
|
|
p2 = Point2()
|
|
|
|
if not base.camLens.project(p3, p2):
|
|
|
|
return None
|
|
|
|
r2d = Point3(p2[0], 0, p2[1])
|
|
|
|
a2d = aspect2d.getRelativePoint(render2d, r2d)
|
|
|
|
return a2d
|
|
|
|
|
|
|
|
|
|
|
|
def invertTable(table):
|
|
|
|
index = {}
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(table.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
value = table[key]
|
2019-12-30 00:07:56 -06:00
|
|
|
if value not in index:
|
2019-11-02 17:27:54 -05:00
|
|
|
index[value] = key
|
|
|
|
|
|
|
|
return index
|
|
|
|
|
|
|
|
|
|
|
|
class DistributedTravelGame(DistributedMinigame):
|
|
|
|
notify = directNotify.newCategory('DistributedTravelGame')
|
|
|
|
idToNames = MinigameNameDict
|
|
|
|
TrolleyMoveDuration = 3
|
|
|
|
UseTrolleyResultsPanel = True
|
|
|
|
FlyCameraUp = True
|
|
|
|
FocusOnTrolleyWhileMovingUp = False
|
|
|
|
|
|
|
|
def __init__(self, cr):
|
|
|
|
DistributedMinigame.__init__(self, cr)
|
|
|
|
self.gameFSM = ClassicFSM.ClassicFSM('DistributedTravelGame', [State.State('off', self.enterOff, self.exitOff, ['inputChoice']),
|
|
|
|
State.State('inputChoice', self.enterInputChoice, self.exitInputChoice, ['waitServerChoices', 'displayVotes', 'cleanup']),
|
|
|
|
State.State('waitServerChoices', self.enterWaitServerChoices, self.exitWaitServerChoices, ['displayVotes', 'cleanup']),
|
|
|
|
State.State('displayVotes', self.enterDisplayVotes, self.exitDisplayVotes, ['moveTrolley', 'cleanup']),
|
|
|
|
State.State('moveTrolley', self.enterMoveTrolley, self.exitMoveTrolley, ['inputChoice', 'winMovie', 'cleanup']),
|
|
|
|
State.State('winMovie', self.enterWinMovie, self.exitWinMovie, ['cleanup']),
|
|
|
|
State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup')
|
|
|
|
self.addChildGameFSM(self.gameFSM)
|
|
|
|
self.currentVotes = {}
|
|
|
|
self.cameraTopView = (100, -20, 280, 0, -89, 0)
|
|
|
|
self.timer = None
|
|
|
|
self.timerStartTime = None
|
|
|
|
self.currentSwitch = 0
|
|
|
|
self.destSwitch = 0
|
|
|
|
self.minigameLabels = []
|
|
|
|
self.minigameIcons = []
|
|
|
|
self.bonusLabels = []
|
2020-01-14 13:28:52 -06:00
|
|
|
self.trolleyAwaySfx = base.loader.loadSfx('phase_4/audio/sfx/SZ_trolley_away.ogg')
|
|
|
|
self.trolleyBellSfx = base.loader.loadSfx('phase_4/audio/sfx/SZ_trolley_bell.ogg')
|
|
|
|
self.turntableRotateSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_sfx_travel_game_turntble_rotate_2.ogg')
|
|
|
|
self.wonGameSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_sfx_travel_game_bonus.ogg')
|
|
|
|
self.lostGameSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_sfx_travel_game_no_bonus_2.ogg')
|
|
|
|
self.noWinnerSfx = base.loader.loadSfx('phase_4/audio/sfx/MG_sfx_travel_game_no_bonus.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.boardIndex = 0
|
|
|
|
self.avNames = []
|
|
|
|
self.disconnectedAvIds = []
|
|
|
|
return
|
|
|
|
|
|
|
|
def getTitle(self):
|
|
|
|
return TTLocalizer.TravelGameTitle
|
|
|
|
|
|
|
|
def getInstructions(self):
|
|
|
|
return TTLocalizer.TravelGameInstructions
|
|
|
|
|
|
|
|
def getMaxDuration(self):
|
|
|
|
return 0
|
|
|
|
|
|
|
|
def load(self):
|
|
|
|
self.notify.debug('load')
|
|
|
|
DistributedMinigame.load(self)
|
|
|
|
self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
|
|
|
|
self.gameBoard = loader.loadModel('phase_4/models/minigames/toon_cannon_gameground')
|
|
|
|
self.gameBoard.setPosHpr(100, 0, 0, 0, 0, 0)
|
|
|
|
self.gameBoard.setScale(1.0)
|
|
|
|
station = loader.loadModel('phase_4/models/modules/trolley_station_TT.bam')
|
|
|
|
self.trolleyCar = station.find('**/trolley_car')
|
|
|
|
self.trolleyCar.reparentTo(hidden)
|
|
|
|
self.trolleyCarOrigPos = self.trolleyCar.getPos()
|
|
|
|
self.trolleyCarOrigHpr = self.trolleyCar.getHpr()
|
|
|
|
self.trolleyCar.setPosHpr(0, 0, 0, 0, 0, 0)
|
|
|
|
self.trolleyCar.setScale(1.0)
|
|
|
|
self.trolleyCar.setX(self.trolleyCar.getX() - TravelGameGlobals.xInc)
|
|
|
|
station.removeNode()
|
|
|
|
self.keys = self.trolleyCar.findAllMatches('**/key')
|
|
|
|
self.numKeys = self.keys.getNumPaths()
|
|
|
|
self.keyInit = []
|
|
|
|
self.keyRef = []
|
|
|
|
for i in range(self.numKeys):
|
|
|
|
key = self.keys[i]
|
|
|
|
key.setTwoSided(1)
|
2019-12-30 00:07:56 -06:00
|
|
|
ref = self.trolleyCar.attachNewNode('key' + repr(i) + 'ref')
|
2019-11-23 16:30:18 -06:00
|
|
|
ref.setPosHpr(key, 0, 0, 0, 0, 0, 0)
|
2019-11-02 17:27:54 -05:00
|
|
|
self.keyRef.append(ref)
|
|
|
|
self.keyInit.append(key.getTransform())
|
|
|
|
|
|
|
|
self.frontWheels = self.trolleyCar.findAllMatches('**/front_wheels')
|
|
|
|
self.numFrontWheels = self.frontWheels.getNumPaths()
|
|
|
|
self.frontWheelInit = []
|
|
|
|
self.frontWheelRef = []
|
|
|
|
for i in range(self.numFrontWheels):
|
|
|
|
wheel = self.frontWheels[i]
|
2019-12-30 00:07:56 -06:00
|
|
|
ref = self.trolleyCar.attachNewNode('frontWheel' + repr(i) + 'ref')
|
2019-11-23 16:30:18 -06:00
|
|
|
ref.setPosHpr(wheel, 0, 0, 0, 0, 0, 0)
|
2019-11-02 17:27:54 -05:00
|
|
|
self.frontWheelRef.append(ref)
|
|
|
|
self.frontWheelInit.append(wheel.getTransform())
|
|
|
|
|
|
|
|
self.backWheels = self.trolleyCar.findAllMatches('**/back_wheels')
|
|
|
|
self.numBackWheels = self.backWheels.getNumPaths()
|
|
|
|
self.backWheelInit = []
|
|
|
|
self.backWheelRef = []
|
|
|
|
for i in range(self.numBackWheels):
|
|
|
|
wheel = self.backWheels[i]
|
2019-12-30 00:07:56 -06:00
|
|
|
ref = self.trolleyCar.attachNewNode('backWheel' + repr(i) + 'ref')
|
2019-11-23 16:30:18 -06:00
|
|
|
ref.setPosHpr(wheel, 0, 0, 0, 0, 0, 0)
|
2019-11-02 17:27:54 -05:00
|
|
|
self.backWheelRef.append(ref)
|
|
|
|
self.backWheelInit.append(wheel.getTransform())
|
|
|
|
|
|
|
|
trolleyAnimationReset = Func(self.resetAnimation)
|
|
|
|
self.trainSwitches = {}
|
|
|
|
self.trainTracks = {}
|
|
|
|
self.tunnels = {}
|
|
|
|
self.extraTrainTracks = []
|
|
|
|
turnTable = loader.loadModel('phase_4/models/minigames/trolley_game_turntable')
|
|
|
|
minPoint = Point3(0, 0, 0)
|
|
|
|
maxPoint = Point3(0, 0, 0)
|
|
|
|
turnTable.calcTightBounds(minPoint, maxPoint)
|
|
|
|
self.fullLength = maxPoint[0]
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(TravelGameGlobals.BoardLayouts[self.boardIndex].keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
info = TravelGameGlobals.BoardLayouts[self.boardIndex][key]
|
|
|
|
switchModel = turnTable.find('**/turntable1').copyTo(render)
|
|
|
|
switchModel.setPos(*info['pos'])
|
|
|
|
switchModel.reparentTo(hidden)
|
|
|
|
self.trainSwitches[key] = switchModel
|
|
|
|
zAdj = 0
|
|
|
|
for otherSwitch in info['links']:
|
|
|
|
info2 = TravelGameGlobals.BoardLayouts[self.boardIndex][otherSwitch]
|
|
|
|
x1, y1, z1 = info['pos']
|
|
|
|
x2, y2, z2 = info2['pos']
|
|
|
|
linkKey = (key, otherSwitch)
|
|
|
|
trainTrack = self.loadTrainTrack(x1, y1, x2, y2, zAdj)
|
|
|
|
trainTrack.reparentTo(hidden)
|
|
|
|
self.trainTracks[linkKey] = trainTrack
|
|
|
|
zAdj += 0.005
|
|
|
|
|
|
|
|
rootInfo = TravelGameGlobals.BoardLayouts[self.boardIndex][0]
|
|
|
|
rootX, rootY, rootZ = rootInfo['pos']
|
|
|
|
startX = rootX - TravelGameGlobals.xInc
|
|
|
|
trainTrack = self.loadTrainTrack(startX, rootY, rootX, rootY)
|
|
|
|
self.extraTrainTracks.append(trainTrack)
|
|
|
|
tunnelX = None
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(TravelGameGlobals.BoardLayouts[self.boardIndex].keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
if self.isLeaf(key):
|
|
|
|
info = TravelGameGlobals.BoardLayouts[self.boardIndex][key]
|
|
|
|
switchX, switchY, switchZ = info['pos']
|
|
|
|
endX = switchX + TravelGameGlobals.xInc
|
|
|
|
trainTrack = self.loadTrainTrack(switchX, switchY, endX, switchY)
|
|
|
|
self.extraTrainTracks.append(trainTrack)
|
|
|
|
tempModel = loader.loadModel('phase_4/models/minigames/trolley_game_turntable')
|
|
|
|
tunnel = tempModel.find('**/tunnel1')
|
|
|
|
tunnel.reparentTo(render)
|
|
|
|
tempModel.removeNode()
|
|
|
|
if not tunnelX:
|
|
|
|
minTrackPoint = Point3(0, 0, 0)
|
|
|
|
maxTrackPoint = Point3(0, 0, 0)
|
|
|
|
trainTrack.calcTightBounds(minTrackPoint, maxTrackPoint)
|
|
|
|
tunnelX = maxTrackPoint[0]
|
|
|
|
tunnel.setPos(tunnelX, switchY, 0)
|
|
|
|
tunnel.wrtReparentTo(trainTrack)
|
|
|
|
self.tunnels[key] = tunnel
|
|
|
|
|
|
|
|
turnTable.removeNode()
|
|
|
|
self.loadGui()
|
|
|
|
self.introMovie = self.getIntroMovie()
|
2020-01-14 13:28:52 -06:00
|
|
|
self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_Travel.ogg')
|
2019-11-02 17:27:54 -05:00
|
|
|
self.flashWinningBeansTrack = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def loadTrainTrack(self, x1, y1, x2, y2, zAdj = 0):
|
|
|
|
turnTable = loader.loadModel('phase_4/models/minigames/trolley_game_turntable')
|
|
|
|
trainPart = turnTable.find('**/track_a2')
|
|
|
|
trackHeight = 0.03
|
|
|
|
trainTrack = render.attachNewNode('trainTrack%d%d%d%d' % (x1,
|
|
|
|
y1,
|
|
|
|
x2,
|
|
|
|
y2))
|
|
|
|
trainTrack.setPos(x1, y1, trackHeight)
|
|
|
|
xDiff = abs(x2 - x1)
|
|
|
|
yDiff = abs(y2 - y1)
|
|
|
|
angleInRadians = math.atan((float(y2) - y1) / (x2 - x1))
|
|
|
|
angle = rad2Deg(angleInRadians)
|
|
|
|
desiredLength = math.sqrt(xDiff * xDiff + yDiff * yDiff)
|
|
|
|
lengthToGo = desiredLength
|
|
|
|
partIndex = 0
|
|
|
|
lengthCovered = 0
|
|
|
|
while lengthToGo > self.fullLength / 2.0:
|
|
|
|
onePart = trainPart.copyTo(trainTrack)
|
|
|
|
onePart.setX(lengthCovered)
|
|
|
|
lengthToGo -= self.fullLength
|
|
|
|
lengthCovered += self.fullLength
|
|
|
|
|
|
|
|
trainTrack.setH(angle)
|
|
|
|
newX = x1 + (x2 - x1) / 2.0
|
|
|
|
newY = y1 + (y2 - y1) / 2.0
|
|
|
|
trainTrack.setPos(x1, y1, trackHeight + zAdj)
|
|
|
|
turnTable.removeNode()
|
|
|
|
return trainTrack
|
|
|
|
|
|
|
|
def loadGui(self):
|
|
|
|
scoreText = [str(self.currentVotes[self.localAvId])]
|
|
|
|
self.gui = DirectFrame()
|
|
|
|
self.remainingVotesFrame = DirectFrame(parent=self.gui, relief=None, geom=DGG.getDefaultDialogGeom(), geom_color=GlobalDialogColor, geom_scale=(7, 1, 1), pos=(-0.9, 0, 0.8), scale=0.1, text=TTLocalizer.TravelGameRemainingVotes, text_align=TextNode.ALeft, text_scale=TTLocalizer.DTGremainingVotesFrame, text_pos=(-3.4, -0.1, 0.0))
|
|
|
|
self.localVotesRemaining = DirectLabel(parent=self.remainingVotesFrame, relief=None, text=scoreText, text_fg=VBase4(0, 0.5, 0, 1), text_align=TextNode.ARight, text_scale=0.7, pos=(3.2, 0, -0.15))
|
|
|
|
guiModel = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
|
|
|
|
self.choiceFrame = DirectFrame(parent=self.gui, relief=None, pos=(-0.55, 0, -0.85), image=DGG.getDefaultDialogGeom(), image_scale=(1.4, 1, 0.225), image_color=GlobalDialogColor)
|
|
|
|
self.useLabel = DirectLabel(text=TTLocalizer.TravelGameUse, parent=self.choiceFrame, pos=(-0.59, 0, -0.01), text_scale=TTLocalizer.DTGuseLabel, relief=None)
|
|
|
|
self.votesPeriodLabel = DirectLabel(text=TTLocalizer.TravelGameVotesWithPeriod, parent=self.choiceFrame, pos=(-0.21, 0, -0.01), text_scale=TTLocalizer.DTGvotesPeriodLabel, relief=None, text_align=TextNode.ALeft)
|
|
|
|
self.votesToGoLabel = DirectLabel(text=TTLocalizer.TravelGameVotesToGo, parent=self.choiceFrame, pos=(-0.21, 0, -0.01), text_scale=TTLocalizer.DTGvotesToGoLabel, relief=None, text_align=TextNode.ALeft)
|
|
|
|
self.upLabel = DirectLabel(text=TTLocalizer.TravelGameUp, parent=self.choiceFrame, pos=(0.31, 0, -0.01), text_scale=TTLocalizer.DTGupLabel, text_fg=Vec4(0, 0, 1, 1), relief=None, text_align=TextNode.ALeft)
|
|
|
|
self.downLabel = DirectLabel(text=TTLocalizer.TravelGameDown, parent=self.choiceFrame, pos=(0.31, 0, -0.01), text_scale=TTLocalizer.DTGdownLabel, text_fg=Vec4(1, 0, 0, 1), relief=None, text_align=TextNode.ALeft)
|
|
|
|
self.scrollList = DirectScrolledList(parent=self.choiceFrame, relief=None, pos=(-0.36, 0, -0.02), incButton_image=(guiModel.find('**/FndsLst_ScrollUp'),
|
|
|
|
guiModel.find('**/FndsLst_ScrollDN'),
|
|
|
|
guiModel.find('**/FndsLst_ScrollUp_Rllvr'),
|
|
|
|
guiModel.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_pos=(0.0, 0.0, -0.04), incButton_image3_color=Vec4(0.6, 0.6, 0.6, 0.6), incButton_scale=(1.0, 1.0, -1.0), decButton_image=(guiModel.find('**/FndsLst_ScrollUp'),
|
|
|
|
guiModel.find('**/FndsLst_ScrollDN'),
|
|
|
|
guiModel.find('**/FndsLst_ScrollUp_Rllvr'),
|
|
|
|
guiModel.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_pos=(0.0, 0.0, 0.095), decButton_image3_color=Vec4(0.6, 0.6, 0.6, 0.6), itemFrame_pos=(0.0, 0.0, 0.0), itemFrame_relief=DGG.GROOVE, numItemsVisible=1, itemMakeFunction=makeLabel, items=[], scrollSpeed=3.0, itemFrame_scale=0.1, command=self.scrollChoiceChanged)
|
|
|
|
self.putChoicesInScrollList()
|
|
|
|
buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
|
|
|
|
okImageList = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))
|
|
|
|
self.voteButton = DirectButton(parent=self.choiceFrame, relief=None, image=okImageList, image_scale=3.0, pos=(0.85, 0, 0.0), text=TTLocalizer.TravelGameVoteWithExclamation, text_scale=TTLocalizer.DTGvoteButton, text_pos=(0, 0), command=self.handleInputChoice)
|
|
|
|
self.waitingChoicesLabel = DirectLabel(text=TTLocalizer.TravelGameWaitingChoices, text_fg=VBase4(1, 1, 1, 1), relief=None, pos=(-0.2, 0, -0.85), scale=0.075)
|
|
|
|
self.waitingChoicesLabel.hide()
|
|
|
|
self.gui.hide()
|
|
|
|
return
|
|
|
|
|
|
|
|
def unload(self):
|
|
|
|
self.notify.debug('unload')
|
|
|
|
DistributedMinigame.unload(self)
|
|
|
|
self.introMovie.finish()
|
|
|
|
del self.introMovie
|
|
|
|
self.gameBoard.removeNode()
|
|
|
|
del self.gameBoard
|
|
|
|
self.sky.removeNode()
|
|
|
|
del self.sky
|
|
|
|
self.trolleyCar.removeNode()
|
|
|
|
del self.trolleyCar
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.trainSwitches.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.trainSwitches[key].removeNode()
|
|
|
|
del self.trainSwitches[key]
|
|
|
|
|
|
|
|
self.trainSwitches = {}
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.tunnels.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.tunnels[key].removeNode()
|
|
|
|
del self.tunnels[key]
|
|
|
|
|
|
|
|
self.tunnels = {}
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.trainTracks.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.trainTracks[key].removeNode()
|
|
|
|
del self.trainTracks[key]
|
|
|
|
|
|
|
|
self.trainTracks = {}
|
|
|
|
for trainTrack in self.extraTrainTracks:
|
|
|
|
trainTrack.removeNode()
|
|
|
|
del trainTrack
|
|
|
|
|
|
|
|
self.extraTrainTracks = []
|
|
|
|
self.gui.removeNode()
|
|
|
|
del self.gui
|
|
|
|
self.waitingChoicesLabel.destroy()
|
|
|
|
del self.waitingChoicesLabel
|
|
|
|
if self.flashWinningBeansTrack:
|
|
|
|
self.flashWinningBeansTrack.finish()
|
|
|
|
del self.flashWinningBeansTrack
|
|
|
|
for label in self.minigameLabels:
|
|
|
|
label.destroy()
|
|
|
|
del label
|
|
|
|
|
|
|
|
self.minigameLabels = []
|
|
|
|
for icon in self.minigameIcons:
|
|
|
|
icon.destroy()
|
|
|
|
icon.removeNode()
|
|
|
|
|
|
|
|
self.minigameIcons = []
|
|
|
|
if hasattr(self, 'mg_icons'):
|
|
|
|
del self.mg_icons
|
|
|
|
for label in self.bonusLabels:
|
|
|
|
label.destroy()
|
|
|
|
del label
|
|
|
|
|
|
|
|
self.bonusLabels = []
|
|
|
|
self.scrollList.destroy()
|
|
|
|
del self.scrollList
|
|
|
|
self.voteButton.destroy()
|
|
|
|
del self.voteButton
|
|
|
|
self.removeChildGameFSM(self.gameFSM)
|
|
|
|
del self.gameFSM
|
|
|
|
del self.music
|
|
|
|
|
|
|
|
def moveCameraToTop(self):
|
|
|
|
camera.reparentTo(render)
|
|
|
|
p = self.cameraTopView
|
|
|
|
camera.setPosHpr(p[0], p[1], p[2], p[3], p[4], p[5])
|
|
|
|
|
|
|
|
def moveCameraToTrolley(self):
|
|
|
|
camera.reparentTo(self.trolleyCar)
|
|
|
|
camera.setPos(-25, 0, 7.5)
|
|
|
|
camera.setHpr(-90, 0, 0)
|
|
|
|
|
|
|
|
def onstage(self):
|
|
|
|
self.notify.debug('onstage')
|
|
|
|
NametagGlobals.setOnscreenChatForced(1)
|
|
|
|
DistributedMinigame.onstage(self)
|
|
|
|
self.gameBoard.reparentTo(render)
|
|
|
|
self.sky.reparentTo(render)
|
|
|
|
self.moveCameraToTop()
|
|
|
|
self.trolleyCar.reparentTo(render)
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.trainSwitches.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.trainSwitches[key].reparentTo(render)
|
|
|
|
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.trainTracks.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.trainTracks[key].reparentTo(render)
|
|
|
|
|
|
|
|
for trainTrack in self.extraTrainTracks:
|
|
|
|
trainTrack.reparentTo(render)
|
|
|
|
|
|
|
|
base.transitions.irisIn(0.4)
|
|
|
|
base.setBackgroundColor(0.1875, 0.7929, 0)
|
|
|
|
base.playMusic(self.music, looping=1, volume=0.9)
|
|
|
|
self.introMovie.start()
|
|
|
|
|
|
|
|
def offstage(self):
|
|
|
|
self.notify.debug('offstage')
|
|
|
|
NametagGlobals.setOnscreenChatForced(0)
|
|
|
|
base.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor)
|
|
|
|
self.introMovie.finish()
|
|
|
|
self.gameBoard.hide()
|
|
|
|
self.sky.hide()
|
|
|
|
self.trolleyCar.hide()
|
|
|
|
self.gui.hide()
|
|
|
|
self.hideMinigamesAndBonuses()
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.trainSwitches.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.trainSwitches[key].hide()
|
|
|
|
|
2019-12-30 00:07:56 -06:00
|
|
|
for key in list(self.trainTracks.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
self.trainTracks[key].hide()
|
|
|
|
|
|
|
|
for trainTrack in self.extraTrainTracks:
|
|
|
|
trainTrack.hide()
|
|
|
|
|
|
|
|
DistributedMinigame.offstage(self)
|
|
|
|
if base.localAvatar.laffMeter:
|
|
|
|
base.localAvatar.laffMeter.start()
|
|
|
|
self.music.stop()
|
|
|
|
|
|
|
|
def setGameReady(self):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameReady')
|
|
|
|
if DistributedMinigame.setGameReady(self):
|
|
|
|
return
|
|
|
|
for index in range(self.numPlayers):
|
|
|
|
avId = self.avIdList[index]
|
|
|
|
name = ''
|
|
|
|
avatar = self.getAvatar(avId)
|
|
|
|
if avatar:
|
|
|
|
avatar.reparentTo(self.trolleyCar)
|
|
|
|
avatar.animFSM.request('Sit')
|
|
|
|
avatar.setPosHpr(-4, -4.5 + index * 3, 2.8, 90, 0, 0)
|
|
|
|
name = avatar.getName()
|
|
|
|
self.avNames.append(name)
|
|
|
|
|
|
|
|
self.trolleyCar.setH(90)
|
|
|
|
|
|
|
|
def setGameStart(self, timestamp):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setGameStart')
|
|
|
|
DistributedMinigame.setGameStart(self, timestamp)
|
|
|
|
self.introMovie.finish()
|
|
|
|
self.gameFSM.request('inputChoice')
|
|
|
|
|
|
|
|
def enterOff(self):
|
|
|
|
self.notify.debug('enterOff')
|
|
|
|
|
|
|
|
def exitOff(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def enterInputChoice(self):
|
|
|
|
self.notify.debug('enterInputChoice')
|
|
|
|
NametagGlobals.setOnscreenChatForced(1)
|
|
|
|
self.timer = ToontownTimer.ToontownTimer()
|
|
|
|
self.timer.hide()
|
|
|
|
if self.timerStartTime != None:
|
|
|
|
self.startTimer()
|
|
|
|
if base.localAvatar.laffMeter:
|
|
|
|
base.localAvatar.laffMeter.stop()
|
|
|
|
self.gui.show()
|
|
|
|
self.showMinigamesAndBonuses()
|
|
|
|
return
|
|
|
|
|
|
|
|
def exitInputChoice(self):
|
|
|
|
NametagGlobals.setOnscreenChatForced(0)
|
|
|
|
if self.timer != None:
|
|
|
|
self.timer.destroy()
|
|
|
|
self.timer = None
|
|
|
|
self.timerStartTime = None
|
|
|
|
self.gui.hide()
|
|
|
|
return
|
|
|
|
|
|
|
|
def enterWaitServerChoices(self):
|
|
|
|
self.notify.debug('enterWaitServerChoices')
|
|
|
|
self.waitingChoicesLabel.show()
|
|
|
|
self.gui.hide()
|
|
|
|
|
|
|
|
def exitWaitServerChoices(self):
|
|
|
|
self.waitingChoicesLabel.hide()
|
|
|
|
|
|
|
|
def enterDisplayVotes(self, votes, directions, directionToGo, directionReason):
|
|
|
|
if self.UseTrolleyResultsPanel:
|
|
|
|
self.moveCameraToTrolley()
|
|
|
|
self.hideMinigamesAndBonuses()
|
|
|
|
else:
|
|
|
|
self.moveCameraToTop()
|
|
|
|
self.resultVotes = votes
|
|
|
|
self.resultDirections = directions
|
|
|
|
self.directionToGo = directionToGo
|
|
|
|
self.directionReason = directionReason
|
|
|
|
self.resultsStr = ''
|
|
|
|
directionTotals = [0] * TravelGameGlobals.MaxDirections
|
|
|
|
for index in range(len(votes)):
|
|
|
|
if index < len(self.avNames):
|
|
|
|
avId = self.avIdList[index]
|
|
|
|
dir = directions[index]
|
|
|
|
numVotes = votes[index]
|
|
|
|
directionTotals[dir] += numVotes
|
|
|
|
curStr = TTLocalizer.TravelGameOneToonVote % {'name': self.avNames[index],
|
|
|
|
'numVotes': numVotes,
|
|
|
|
'dir': TTLocalizer.TravelGameDirections[dir]}
|
|
|
|
if not (numVotes == 0 and avId in self.disconnectedAvIds):
|
|
|
|
self.resultsStr += curStr
|
|
|
|
|
|
|
|
directionStr = TTLocalizer.TravelGameTotals
|
|
|
|
for index in range(len(directionTotals)):
|
|
|
|
directionStr += ' ' + TTLocalizer.TravelGameDirections[index] + ':'
|
|
|
|
directionStr += str(directionTotals[index])
|
|
|
|
|
|
|
|
directionStr += '\n'
|
|
|
|
self.resultsStr += directionStr
|
|
|
|
reasonStr = ''
|
|
|
|
if directionReason == TravelGameGlobals.ReasonVote:
|
|
|
|
if directionToGo == 0:
|
|
|
|
losingDirection = 1
|
|
|
|
else:
|
|
|
|
losingDirection = 0
|
|
|
|
diffVotes = directionTotals[directionToGo] - directionTotals[losingDirection]
|
|
|
|
reasonStr = ''
|
|
|
|
if diffVotes > 1:
|
|
|
|
reasonStr = TTLocalizer.TravelGameReasonVotesPlural % {'dir': TTLocalizer.TravelGameDirections[directionToGo],
|
|
|
|
'numVotes': diffVotes}
|
|
|
|
else:
|
|
|
|
reasonStr = TTLocalizer.TravelGameReasonVotesSingular % {'dir': TTLocalizer.TravelGameDirections[directionToGo],
|
|
|
|
'numVotes': diffVotes}
|
|
|
|
elif directionReason == TravelGameGlobals.ReasonRandom:
|
|
|
|
reasonStr = TTLocalizer.TravelGameReasonRandom % {'dir': TTLocalizer.TravelGameDirections[directionToGo],
|
|
|
|
'numVotes': directionTotals[directionToGo]}
|
|
|
|
elif directionReason == TravelGameGlobals.ReasonPlaceDecider:
|
|
|
|
reasonStr = TravelGameReasonPlace % {'name': 'TODO NAME',
|
|
|
|
'dir': TTLocalizer.TravelGameDirections[directionToGo]}
|
|
|
|
self.resultsStr += reasonStr
|
|
|
|
self.dialog = TTDialog.TTDialog(text=self.resultsStr, command=self.__cleanupDialog, style=TTDialog.NoButtons, pos=(0, 0, 1))
|
|
|
|
self.dialog.hide()
|
|
|
|
if self.UseTrolleyResultsPanel:
|
|
|
|
self.votesPanel = VoteResultsTrolleyPanel.VoteResultsTrolleyPanel(len(self.avIdList), self.avIdList, votes, directions, self.avNames, self.disconnectedAvIds, directionToGo, directionReason, directionTotals)
|
|
|
|
else:
|
|
|
|
self.votesPanel = VoteResultsPanel.VoteResultsPanel(len(self.avIdList), self.avIdList, votes, directions, self.avNames, self.disconnectedAvIds, directionToGo, directionReason, directionTotals)
|
|
|
|
self.votesPanel.startMovie()
|
|
|
|
numPlayers = len(self.avIdList)
|
|
|
|
if TravelGameGlobals.SpoofFour:
|
|
|
|
numPlayers = 4
|
|
|
|
delay = TravelGameGlobals.DisplayVotesTimePerPlayer * (numPlayers + 1)
|
|
|
|
taskMgr.doMethodLater(delay, self.displayVotesTimeoutTask, self.taskName('displayVotes-timeout'))
|
|
|
|
curSwitch = TravelGameGlobals.BoardLayouts[self.boardIndex][self.currentSwitch]
|
|
|
|
self.destSwitch = curSwitch['links'][directionToGo]
|
|
|
|
self.updateCurrentVotes()
|
|
|
|
|
|
|
|
def exitDisplayVotes(self):
|
|
|
|
taskMgr.remove(self.taskName('displayVotes-timeout'))
|
|
|
|
self.__cleanupDialog(0)
|
|
|
|
if not self.UseTrolleyResultsPanel:
|
|
|
|
self.showMinigamesAndBonuses()
|
|
|
|
self.votesPanel.destroy()
|
|
|
|
|
|
|
|
def enterMoveTrolley(self):
|
|
|
|
self.notify.debug('enterMoveTrolley')
|
|
|
|
camera.wrtReparentTo(render)
|
|
|
|
keyAngle = round(self.TrolleyMoveDuration) * 360
|
|
|
|
dist = Vec3(self.trainSwitches[self.destSwitch].getPos() - self.trainSwitches[self.currentSwitch].getPos()).length()
|
|
|
|
wheelAngle = dist / (2.0 * math.pi * 0.95) * 360
|
|
|
|
trolleyAnimateInterval = LerpFunctionInterval(self.animateTrolley, duration=self.TrolleyMoveDuration, blendType='easeInOut', extraArgs=[keyAngle, wheelAngle], name='TrolleyAnimate')
|
|
|
|
moveTrolley = Sequence()
|
|
|
|
moveTrolley.append(Func(self.resetAnimation))
|
|
|
|
newPos = self.trainSwitches[self.destSwitch].getPos()
|
|
|
|
linkKey = (self.currentSwitch, self.destSwitch)
|
|
|
|
origHeading = self.trainTracks[linkKey].getH()
|
|
|
|
heading = origHeading + 90
|
|
|
|
firstTurn = Parallel()
|
|
|
|
firstTurn.append(LerpHprInterval(self.trolleyCar, 1, Vec3(heading, 0, 0)))
|
|
|
|
firstTurn.append(LerpHprInterval(self.trainSwitches[self.currentSwitch], 1, Vec3(origHeading, 0, 0)))
|
|
|
|
firstTurn.append(LerpHprInterval(self.trainSwitches[self.destSwitch], 1, Vec3(origHeading, 0, 0)))
|
|
|
|
moveTrolley.append(firstTurn)
|
|
|
|
moveTrolley.append(Parallel(LerpPosInterval(self.trolleyCar, self.TrolleyMoveDuration, newPos, blendType='easeInOut'), trolleyAnimateInterval))
|
|
|
|
secondTurn = Parallel()
|
|
|
|
secondTurn.append(LerpHprInterval(self.trolleyCar, 1, Vec3(90, 0, 0)))
|
|
|
|
secondTurn.append(LerpHprInterval(self.trainSwitches[self.currentSwitch], 1, Vec3(0, 0, 0)))
|
|
|
|
secondTurn.append(LerpHprInterval(self.trainSwitches[self.destSwitch], 1, Vec3(0, 0, 0)))
|
|
|
|
moveTrolley.append(secondTurn)
|
|
|
|
soundTrack = Sequence()
|
|
|
|
trolleyExitBellInterval = Parallel(SoundInterval(self.trolleyBellSfx, duration=1), SoundInterval(self.turntableRotateSfx, duration=1, volume=0.5))
|
|
|
|
trolleyExitAwayInterval = SoundInterval(self.trolleyAwaySfx, duration=3)
|
|
|
|
soundTrack.append(trolleyExitBellInterval)
|
|
|
|
soundTrack.append(trolleyExitAwayInterval)
|
|
|
|
soundTrack.append(trolleyExitBellInterval)
|
|
|
|
self.moveTrolleyIval = Parallel(moveTrolley, soundTrack)
|
|
|
|
duration = self.moveTrolleyIval.getDuration()
|
|
|
|
|
|
|
|
def focusOnTrolley(t, self = self):
|
|
|
|
pos = self.trolleyCar.getPos()
|
|
|
|
pos.setZ(pos.getZ() + 7.5)
|
|
|
|
camera.lookAt(pos)
|
|
|
|
self.lastFocusHpr = camera.getHpr()
|
|
|
|
|
|
|
|
setRightHprTime = 0
|
|
|
|
if self.FlyCameraUp:
|
|
|
|
setRightHprTime = 1.0
|
|
|
|
camIval1 = Parallel()
|
|
|
|
camIval1.append(LerpFunc(focusOnTrolley, duration - setRightHprTime, name='focusOnTrolley'))
|
|
|
|
finalPos = Vec3(self.cameraTopView[0], self.cameraTopView[1], self.cameraTopView[2])
|
|
|
|
finalHpr = Vec3(self.cameraTopView[3], self.cameraTopView[4], self.cameraTopView[5])
|
|
|
|
if self.FlyCameraUp:
|
|
|
|
if self.FocusOnTrolleyWhileMovingUp:
|
|
|
|
camIval1.append(LerpPosInterval(camera, duration - setRightHprTime, finalPos, name='cameraMove'))
|
|
|
|
camIval2 = Sequence(LerpHprInterval(camera, setRightHprTime, finalHpr, name='cameraHpr'))
|
|
|
|
else:
|
|
|
|
camIval2 = Sequence(LerpPosHprInterval(camera, setRightHprTime, finalPos, finalHpr, blendType='easeIn', name='cameraHpr'))
|
|
|
|
camIval = Sequence(camIval1, camIval2)
|
|
|
|
else:
|
|
|
|
camIval = Sequence(camIval1)
|
|
|
|
if self.UseTrolleyResultsPanel:
|
|
|
|
self.moveTrolleyIval.append(camIval)
|
|
|
|
temp = self.moveTrolleyIval
|
|
|
|
self.moveTrolleyIval = Sequence(temp)
|
|
|
|
if self.isLeaf(self.destSwitch):
|
|
|
|
self.moveTrolleyIval.append(Func(self.gameFSM.request, 'winMovie'))
|
|
|
|
else:
|
|
|
|
self.moveTrolleyIval.append(Func(self.gameFSM.request, 'inputChoice'))
|
|
|
|
self.moveTrolleyIval.start()
|
|
|
|
|
|
|
|
def exitMoveTrolley(self):
|
|
|
|
self.notify.debug('exitMoveTrolley')
|
|
|
|
self.currentSwitch = self.destSwitch
|
|
|
|
self.moveTrolleyIval.finish()
|
|
|
|
self.moveCameraToTop()
|
|
|
|
self.showMinigamesAndBonuses()
|
|
|
|
|
|
|
|
def enterWinMovie(self):
|
|
|
|
resultStr = TTLocalizer.TravelGamePlaying % {'game': self.idToNames[self.switchToMinigameDict[self.currentSwitch]]}
|
|
|
|
numToons = 0
|
|
|
|
for avId in self.avIdList:
|
|
|
|
if avId not in self.disconnectedAvIds:
|
|
|
|
numToons += 1
|
|
|
|
|
|
|
|
if numToons <= 1:
|
|
|
|
resultStr = TTLocalizer.TravelGameGoingBackToShop
|
|
|
|
reachedGoalStr = None
|
|
|
|
localAvatarWon = False
|
|
|
|
localAvatarLost = False
|
|
|
|
noWinner = True
|
2019-12-30 00:07:56 -06:00
|
|
|
for avId in list(self.avIdBonuses.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
name = ''
|
|
|
|
avatar = self.getAvatar(avId)
|
|
|
|
if avatar:
|
|
|
|
name = avatar.getName()
|
|
|
|
if self.avIdBonuses[avId][0] == self.currentSwitch:
|
|
|
|
noWinner = False
|
|
|
|
reachedGoalStr = TTLocalizer.TravelGameGotBonus % {'name': name,
|
|
|
|
'numBeans': self.avIdBonuses[avId][1]}
|
|
|
|
if avId == base.localAvatar.doId:
|
|
|
|
if not TravelGameGlobals.ReverseWin:
|
|
|
|
self.wonGameSfx.play()
|
|
|
|
bonusLabel = self.switchToBonusLabelDict[self.currentSwitch]
|
|
|
|
self.flashWinningBeansTrack = Sequence(LerpColorScaleInterval(bonusLabel, 0.75, Vec4(0.5, 1, 0.5, 1)), LerpColorScaleInterval(bonusLabel, 0.75, Vec4(1, 1, 1, 1)))
|
|
|
|
self.flashWinningBeansTrack.loop()
|
|
|
|
else:
|
|
|
|
self.lostGameSfx.play()
|
|
|
|
elif not TravelGameGlobals.ReverseWin:
|
|
|
|
self.lostGameSfx.play()
|
|
|
|
else:
|
|
|
|
self.wonGameSfx.play()
|
|
|
|
|
|
|
|
if noWinner:
|
|
|
|
self.noWinnerSfx.play()
|
|
|
|
resultStr += '\n\n'
|
|
|
|
resultStr += TTLocalizer.TravelGameNoOneGotBonus
|
|
|
|
if reachedGoalStr:
|
|
|
|
resultStr += '\n\n'
|
|
|
|
resultStr += reachedGoalStr
|
|
|
|
self.winDialog = TTDialog.TTDialog(text=resultStr, command=self.__cleanupWinDialog, style=TTDialog.NoButtons)
|
|
|
|
info = TravelGameGlobals.BoardLayouts[self.boardIndex][self.currentSwitch]
|
|
|
|
leafX, leafY, leafZ = info['pos']
|
|
|
|
endX = leafX + TravelGameGlobals.xInc
|
|
|
|
heading = 90
|
|
|
|
moveTrolley = Sequence()
|
|
|
|
moveTrolley.append(LerpHprInterval(self.trolleyCar, 1, Vec3(heading, 0, 0)))
|
|
|
|
moveTrolley.append(LerpPosInterval(self.trolleyCar, 3, Vec3(endX + 20, leafY, 0)))
|
|
|
|
soundTrack = Sequence()
|
|
|
|
trolleyExitBellInterval = SoundInterval(self.trolleyBellSfx, duration=1)
|
|
|
|
trolleyExitAwayInterval = SoundInterval(self.trolleyAwaySfx, duration=3)
|
|
|
|
soundTrack.append(trolleyExitBellInterval)
|
|
|
|
soundTrack.append(trolleyExitAwayInterval)
|
|
|
|
soundTrack.append(trolleyExitBellInterval)
|
|
|
|
self.moveTrolleyIval = Parallel(moveTrolley, soundTrack)
|
|
|
|
self.moveTrolleyIval.start()
|
|
|
|
delay = 8
|
|
|
|
taskMgr.doMethodLater(delay, self.gameOverCallback, self.taskName('playMovie'))
|
|
|
|
return
|
|
|
|
|
|
|
|
def exitWinMovie(self):
|
|
|
|
taskMgr.remove(self.taskName('playMovie'))
|
|
|
|
self.moveTrolleyIval.finish()
|
|
|
|
|
|
|
|
def enterCleanup(self):
|
|
|
|
self.notify.debug('enterCleanup')
|
|
|
|
|
|
|
|
def exitCleanup(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
def setStartingVotes(self, startingVotesArray):
|
|
|
|
if not len(startingVotesArray) == len(self.avIdList):
|
|
|
|
self.notify.error('length does not match, startingVotes=%s, avIdList=%s' % (startingVotesArray, self.avIdList))
|
|
|
|
return
|
|
|
|
for index in range(len(self.avIdList)):
|
|
|
|
avId = self.avIdList[index]
|
|
|
|
self.startingVotes[avId] = startingVotesArray[index]
|
2019-12-30 00:07:56 -06:00
|
|
|
if avId not in self.currentVotes:
|
2019-11-02 17:27:54 -05:00
|
|
|
self.currentVotes[avId] = startingVotesArray[index]
|
|
|
|
|
|
|
|
self.notify.debug('starting votes = %s' % self.startingVotes)
|
|
|
|
|
|
|
|
def startTimer(self):
|
|
|
|
now = globalClock.getFrameTime()
|
|
|
|
elapsed = now - self.timerStartTime
|
|
|
|
self.timer.setPos(1.16, 0, -0.83)
|
|
|
|
self.timer.setTime(TravelGameGlobals.InputTimeout)
|
|
|
|
self.timer.countdown(TravelGameGlobals.InputTimeout - elapsed, self.handleChoiceTimeout)
|
|
|
|
self.timer.show()
|
|
|
|
|
|
|
|
def setTimerStartTime(self, timestamp):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.timerStartTime = globalClockDelta.networkToLocalTime(timestamp)
|
|
|
|
if self.timer != None:
|
|
|
|
self.startTimer()
|
|
|
|
return
|
|
|
|
|
|
|
|
def handleChoiceTimeout(self):
|
|
|
|
self.sendUpdate('setAvatarChoice', [0, 0])
|
|
|
|
self.gameFSM.request('waitServerChoices')
|
|
|
|
|
|
|
|
def putChoicesInScrollList(self):
|
|
|
|
available = self.currentVotes[self.localAvId]
|
|
|
|
if len(self.scrollList['items']) > 0:
|
|
|
|
self.scrollList.removeAllItems()
|
|
|
|
self.indexToVotes = {}
|
|
|
|
index = 0
|
|
|
|
for vote in range(available)[::-1]:
|
|
|
|
self.scrollList.addItem(str(-(vote + 1)))
|
|
|
|
self.indexToVotes[index] = vote + 1
|
|
|
|
index += 1
|
|
|
|
|
|
|
|
self.scrollList.addItem(str(0))
|
|
|
|
self.indexToVotes[index] = 0
|
|
|
|
self.zeroVoteIndex = index
|
|
|
|
index += 1
|
|
|
|
for vote in range(available):
|
|
|
|
self.scrollList.addItem(str(vote + 1))
|
|
|
|
self.indexToVotes[index] = vote + 1
|
|
|
|
index += 1
|
|
|
|
|
|
|
|
self.scrollList.scrollTo(self.zeroVoteIndex)
|
|
|
|
|
|
|
|
def getAbsVoteChoice(self):
|
|
|
|
available = self.currentVotes[self.localAvId]
|
|
|
|
retval = 0
|
|
|
|
if hasattr(self, 'scrollList'):
|
|
|
|
selectedIndex = self.scrollList.getSelectedIndex()
|
2019-12-30 00:07:56 -06:00
|
|
|
if selectedIndex in self.indexToVotes:
|
2019-11-02 17:27:54 -05:00
|
|
|
retval = self.indexToVotes[selectedIndex]
|
|
|
|
return retval
|
|
|
|
|
|
|
|
def getAbsDirectionChoice(self):
|
|
|
|
selectedIndex = self.scrollList.getSelectedIndex()
|
|
|
|
if selectedIndex < self.zeroVoteIndex:
|
|
|
|
retval = 0
|
|
|
|
elif selectedIndex == self.zeroVoteIndex:
|
|
|
|
retval = 0
|
|
|
|
else:
|
|
|
|
retval = 1
|
|
|
|
return retval
|
|
|
|
|
|
|
|
def makeTextMatchChoice(self):
|
|
|
|
self.votesPeriodLabel.hide()
|
|
|
|
self.votesToGoLabel.hide()
|
|
|
|
self.upLabel.hide()
|
|
|
|
self.downLabel.hide()
|
|
|
|
if not hasattr(self, 'scrollList') or not hasattr(self, 'zeroVoteIndex'):
|
|
|
|
return
|
|
|
|
selectedIndex = self.scrollList.getSelectedIndex()
|
|
|
|
if selectedIndex < self.zeroVoteIndex:
|
|
|
|
self.votesToGoLabel.show()
|
|
|
|
self.upLabel.show()
|
|
|
|
elif selectedIndex == self.zeroVoteIndex:
|
|
|
|
self.votesPeriodLabel.show()
|
|
|
|
else:
|
|
|
|
self.votesToGoLabel.show()
|
|
|
|
self.downLabel.show()
|
|
|
|
|
|
|
|
def scrollChoiceChanged(self):
|
|
|
|
choiceVotes = self.getAbsVoteChoice()
|
|
|
|
if choiceVotes == 1:
|
|
|
|
self.votesToGoLabel['text'] = TTLocalizer.TravelGameVoteToGo
|
|
|
|
else:
|
|
|
|
self.votesToGoLabel['text'] = TTLocalizer.TravelGameVotesToGo
|
|
|
|
available = self.currentVotes[self.localAvId]
|
|
|
|
self.localVotesRemaining['text'] = str(available - choiceVotes)
|
|
|
|
self.makeTextMatchChoice()
|
|
|
|
|
|
|
|
def setAvatarChose(self, avId):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('setAvatarChose: avatar: ' + str(avId) + ' choose a number')
|
|
|
|
|
|
|
|
def handleInputChoice(self):
|
|
|
|
numVotes = self.getAbsVoteChoice()
|
|
|
|
direction = self.getAbsDirectionChoice()
|
|
|
|
self.sendUpdate('setAvatarChoice', [numVotes, direction])
|
|
|
|
self.gameFSM.request('waitServerChoices')
|
|
|
|
|
|
|
|
def setServerChoices(self, votes, directions, directionToGo, directionReason):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.notify.debug('requesting displayVotes, curState=%s' % self.gameFSM.getCurrentState().getName())
|
|
|
|
self.gameFSM.request('displayVotes', [votes,
|
|
|
|
directions,
|
|
|
|
directionToGo,
|
|
|
|
directionReason])
|
|
|
|
|
|
|
|
def __cleanupDialog(self, value):
|
|
|
|
if self.dialog:
|
|
|
|
self.dialog.cleanup()
|
|
|
|
self.dialog = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def displayVotesTimeoutTask(self, task):
|
|
|
|
self.notify.debug('Done waiting for display votes')
|
|
|
|
self.gameFSM.request('moveTrolley')
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
def updateCurrentVotes(self):
|
|
|
|
for index in range(len(self.resultVotes)):
|
|
|
|
avId = self.avIdList[index]
|
|
|
|
oldCurrentVotes = self.currentVotes[avId]
|
|
|
|
self.currentVotes[avId] -= self.resultVotes[index]
|
|
|
|
|
|
|
|
self.putChoicesInScrollList()
|
|
|
|
self.makeTextMatchChoice()
|
|
|
|
|
|
|
|
def isLeaf(self, switchIndex):
|
|
|
|
retval = False
|
|
|
|
links = TravelGameGlobals.BoardLayouts[self.boardIndex][switchIndex]['links']
|
|
|
|
if len(links) == 0:
|
|
|
|
retval = True
|
|
|
|
return retval
|
|
|
|
|
|
|
|
def __cleanupWinDialog(self, value):
|
|
|
|
if hasattr(self, 'winDialog') and self.winDialog:
|
|
|
|
self.winDialog.cleanup()
|
|
|
|
self.winDialog = None
|
|
|
|
return
|
|
|
|
|
|
|
|
def gameOverCallback(self, task):
|
|
|
|
self.__cleanupWinDialog(0)
|
|
|
|
self.gameOver()
|
|
|
|
return Task.done
|
|
|
|
|
|
|
|
def setMinigames(self, switches, minigames):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.switchToMinigameDict = {}
|
|
|
|
for index in range(len(switches)):
|
|
|
|
switch = switches[index]
|
|
|
|
minigame = minigames[index]
|
|
|
|
self.switchToMinigameDict[switch] = minigame
|
|
|
|
|
|
|
|
self.notify.debug('minigameDict = %s' % self.switchToMinigameDict)
|
|
|
|
self.loadMinigameIcons()
|
|
|
|
|
|
|
|
def loadMinigameIcons(self):
|
|
|
|
self.mg_icons = loader.loadModel('phase_4/models/minigames/mg_icons')
|
2019-12-30 00:07:56 -06:00
|
|
|
for switch in list(self.switchToMinigameDict.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
minigame = self.switchToMinigameDict[switch]
|
|
|
|
switchPos = self.trainSwitches[switch].getPos()
|
|
|
|
labelPos = map3dToAspect2d(render, switchPos)
|
|
|
|
useText = True
|
|
|
|
iconName = None
|
2019-12-30 00:07:56 -06:00
|
|
|
if minigame in list(IconDict.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
iconName = IconDict[minigame]
|
|
|
|
icon = None
|
|
|
|
if self.mg_icons:
|
|
|
|
icon = self.mg_icons.find('**/%s' % iconName)
|
|
|
|
if not icon.isEmpty():
|
|
|
|
useText = False
|
|
|
|
if labelPos:
|
|
|
|
if useText:
|
|
|
|
labelPos.setZ(labelPos.getZ() - 0.1)
|
|
|
|
label = DirectLabel(text=self.idToNames[minigame], relief=None, scale=0.1, pos=labelPos, text_fg=(1.0, 1.0, 1.0, 1.0))
|
|
|
|
label.hide()
|
|
|
|
self.minigameLabels.append(label)
|
|
|
|
else:
|
|
|
|
placeHolder = DirectButton(image=icon, relief=None, text=('',
|
|
|
|
'',
|
|
|
|
self.idToNames[minigame],
|
|
|
|
''), text_scale=0.3, text_pos=(0, -0.7, 0), text_fg=(1, 1, 1, 1), clickSound=None, pressEffect=0)
|
|
|
|
placeHolder.setPos(labelPos)
|
|
|
|
placeHolder.setScale(0.2)
|
|
|
|
placeHolder.hide()
|
|
|
|
self.minigameIcons.append(placeHolder)
|
|
|
|
tunnel = self.tunnels[switch]
|
|
|
|
sign = tunnel.attachNewNode('sign')
|
|
|
|
icon.copyTo(sign)
|
|
|
|
sign.setH(-90)
|
|
|
|
sign.setZ(26)
|
|
|
|
sign.setScale(10)
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
def showMinigamesAndBonuses(self):
|
|
|
|
for label in self.minigameLabels:
|
|
|
|
label.show()
|
|
|
|
|
|
|
|
for label in self.bonusLabels:
|
|
|
|
label.show()
|
|
|
|
|
|
|
|
for icon in self.minigameIcons:
|
|
|
|
icon.show()
|
|
|
|
|
|
|
|
def hideMinigamesAndBonuses(self):
|
|
|
|
for label in self.minigameLabels:
|
|
|
|
label.hide()
|
|
|
|
|
|
|
|
for label in self.bonusLabels:
|
|
|
|
label.hide()
|
|
|
|
|
|
|
|
for icon in self.minigameIcons:
|
|
|
|
icon.hide()
|
|
|
|
|
|
|
|
def loadBonuses(self):
|
|
|
|
self.switchToBonusLabelDict = {}
|
2019-12-30 00:07:56 -06:00
|
|
|
for avId in list(self.avIdBonuses.keys()):
|
2019-11-02 17:27:54 -05:00
|
|
|
if avId == self.localAvId:
|
|
|
|
switch = self.avIdBonuses[avId][0]
|
|
|
|
beans = self.avIdBonuses[avId][1]
|
|
|
|
switchPos = self.trainSwitches[switch].getPos()
|
|
|
|
labelPos = map3dToAspect2d(render, switchPos)
|
|
|
|
if labelPos:
|
|
|
|
labelPos.setX(labelPos.getX() + 0.1)
|
|
|
|
labelPos.setZ(labelPos.getZ() - 0.02)
|
|
|
|
bonusStr = TTLocalizer.TravelGameBonusBeans % {'numBeans': beans}
|
|
|
|
label = DirectLabel(text=bonusStr, relief=None, scale=0.1, pos=labelPos, text_fg=(1.0, 1.0, 1.0, 1.0), text_align=TextNode.ALeft)
|
|
|
|
label.hide()
|
|
|
|
self.bonusLabels.append(label)
|
|
|
|
self.switchToBonusLabelDict[switch] = label
|
|
|
|
break
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
def setBonuses(self, switches, beans):
|
|
|
|
if not self.hasLocalToon:
|
|
|
|
return
|
|
|
|
self.avIdBonuses = {}
|
|
|
|
for index in range(len(self.avIdList)):
|
|
|
|
avId = self.avIdList[index]
|
|
|
|
switch = switches[index]
|
|
|
|
bean = beans[index]
|
|
|
|
self.avIdBonuses[avId] = (switch, bean)
|
|
|
|
|
|
|
|
self.notify.debug('self.avIdBonuses = %s' % self.avIdBonuses)
|
|
|
|
self.loadBonuses()
|
|
|
|
|
|
|
|
def handleDisabledAvatar(self, avId):
|
|
|
|
self.notify.warning('DistrbutedTravelGame: handleDisabledAvatar: disabled avId: ' + str(avId))
|
|
|
|
self.disconnectedAvIds.append(avId)
|
|
|
|
|
|
|
|
def setBoardIndex(self, boardIndex):
|
|
|
|
self.boardIndex = boardIndex
|
|
|
|
|
|
|
|
def getIntroMovie(self):
|
|
|
|
rootInfo = TravelGameGlobals.BoardLayouts[self.boardIndex][0]
|
|
|
|
rootX, rootY, rootZ = rootInfo['pos']
|
|
|
|
startX = rootX - TravelGameGlobals.xInc
|
|
|
|
heading = 90
|
|
|
|
moveTrolley = Sequence()
|
|
|
|
moveTrolley.append(Func(self.trolleyCar.setH, 90))
|
|
|
|
moveTrolley.append(LerpPosInterval(self.trolleyCar, 3, Vec3(rootX, rootY, 0), startPos=Vec3(startX, rootY, 0)))
|
|
|
|
moveTrolley.append(LerpHprInterval(self.trolleyCar, 1, Vec3(heading, 0, 0)))
|
|
|
|
soundTrack = Sequence()
|
|
|
|
trolleyExitAwayInterval = SoundInterval(self.trolleyAwaySfx, duration=3)
|
|
|
|
trolleyExitBellInterval = SoundInterval(self.trolleyBellSfx, duration=1)
|
|
|
|
soundTrack.append(trolleyExitAwayInterval)
|
|
|
|
soundTrack.append(trolleyExitBellInterval)
|
|
|
|
retval = Parallel(moveTrolley, soundTrack)
|
|
|
|
return retval
|
|
|
|
|
|
|
|
def animateTrolley(self, t, keyAngle, wheelAngle):
|
|
|
|
for i in range(self.numKeys):
|
|
|
|
key = self.keys[i]
|
|
|
|
ref = self.keyRef[i]
|
|
|
|
key.setH(ref, t * keyAngle)
|
|
|
|
|
|
|
|
for i in range(self.numFrontWheels):
|
|
|
|
frontWheel = self.frontWheels[i]
|
|
|
|
ref = self.frontWheelRef[i]
|
|
|
|
frontWheel.setH(ref, t * wheelAngle)
|
|
|
|
|
|
|
|
for i in range(self.numBackWheels):
|
|
|
|
backWheel = self.backWheels[i]
|
|
|
|
ref = self.backWheelRef[i]
|
|
|
|
backWheel.setH(ref, t * wheelAngle)
|
|
|
|
|
|
|
|
def resetAnimation(self):
|
|
|
|
for i in range(self.numKeys):
|
|
|
|
self.keys[i].setTransform(self.keyInit[i])
|
|
|
|
|
|
|
|
for i in range(self.numFrontWheels):
|
|
|
|
self.frontWheels[i].setTransform(self.frontWheelInit[i])
|
|
|
|
|
|
|
|
for i in range(self.numBackWheels):
|
|
|
|
self.backWheels[i].setTransform(self.backWheelInit[i])
|