def setupSignText(self): loader = self.cr.playGame.hood.loader partyGate = loader.geom.find('**/partyGateSignGroup') if partyGate.isEmpty(): self.notify.warning('Could not find partyGate_grp in loader.geom') return gateFont = ToontownGlobals.getMinnieFont() leftSign = partyGate.find('**/signTextL_locatorBack') signScale = 0.35 wordWrap = 8 leftText = DirectLabel.DirectLabel(parent=leftSign, pos=(0, 0.0, 0.0), relief=None, text=TTLocalizer.PartyGateLeftSign, text_align=TextNode.ACenter, text_font=gateFont, text_wordwrap=wordWrap, text_fg=Vec4(0.7, 0.3, 0.3, 1.0), scale=signScale) rightSign = partyGate.find('**/signTextR_locatorFront') rightText = DirectLabel.DirectLabel( parent=rightSign, pos=(0, 0.0, 0.0), relief=None, text=TTLocalizer.PartyGateRightSign, text_align=TextNode.ACenter, text_font=gateFont, text_wordwrap=wordWrap, text_fg=Vec4(0.7, 0.3, 0.3, 1.0), scale=signScale) return
def enter(self): doneStatus = {} questHistory = base.localAvatar.getQuestHistory() imgScale = 0.5 if questHistory != [] and questHistory != [1000] and questHistory != [101, 110]: doneStatus['mode'] = 'complete' messenger.send(self.doneEvent, [doneStatus]) elif len(base.localAvatar.quests) > 1 or len(base.localAvatar.quests) == 0: doneStatus['mode'] = 'complete' messenger.send(self.doneEvent, [doneStatus]) elif base.localAvatar.quests[0][0] != Quests.TROLLEY_QUEST_ID: doneStatus['mode'] = 'complete' messenger.send(self.doneEvent, [doneStatus]) else: base.localAvatar.b_setAnimState('neutral', 1) doneStatus['mode'] = 'incomplete' self.doneStatus = doneStatus imageModel = loader.loadModel('phase_4/models/gui/tfa_images') if Quests.avatarHasTrolleyQuest(base.localAvatar): if base.localAvatar.quests[0][4] != 0: imgNodePath = imageModel.find('**/hq-dialog-image') imgPos = (0, 0, -0.02) msg = TTLocalizer.NPCForceAcknowledgeMessage2 else: imgNodePath = imageModel.find('**/trolley-dialog-image') imgPos = (0, 0, 0.04) msg = TTLocalizer.NPCForceAcknowledgeMessage self.dialog = TTDialog.TTDialog(text=msg, command=self.handleOk, style=TTDialog.Acknowledge) imgLabel = DirectLabel.DirectLabel(parent=self.dialog, relief=None, pos=imgPos, scale=TTLocalizer.NPCFimgLabel, image=imgNodePath, image_scale=imgScale)
def _createIface(self): textFg = PiratesGuiGlobals.TextFG1 if self.world != None: scoreText = self.world.getScoreText(self.scoreValue) else: scoreText = '' self.descText = DirectLabel( parent=self, relief=None, text=scoreText, text_align=TextNode.ALeft, text_scale=PiratesGuiGlobals.TextScaleLarge, text_fg=textFg, text_shadow=PiratesGuiGlobals.TextShadow, textMayChange=1, pos=(0.04, 0, 0.015)) if self.itemColorScale: self.colorLabel(self.itemColorScale) if self.blink: textPos = self.descText['text_pos'] textPosX = textPos[0] textPosY = textPos[1] self.scaleSeq = Parallel( Sequence( LerpFunctionInterval(self.descText.setScale, duration=0.2, toData=1.05, fromData=1.0, blendType='easeInOut'), LerpFunctionInterval(self.descText.setScale, duration=0.7, toData=1.0, fromData=1.05, blendType='easeInOut')), Sequence( Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.05), Func(self.colorLabel, PiratesGuiGlobals.TextFG1), Func(self.moveLabel, (textPosX, textPosY)))) self.scaleSeq.start() return
def _createIface(self): textFg = PiratesGuiGlobals.TextFG1 if self.world != None: scoreText = self.world.getScoreText(self.scoreValue) else: scoreText = '' self.descText = DirectLabel(parent = self, relief = None, text = scoreText, text_align = TextNode.ALeft, text_scale = PiratesGuiGlobals.TextScaleLarge, text_fg = textFg, text_shadow = PiratesGuiGlobals.TextShadow, textMayChange = 1, pos = (0.040000000000000001, 0, 0.014999999999999999)) if self.itemColorScale: self.colorLabel(self.itemColorScale) if self.blink: textPos = self.descText['text_pos'] textPosX = textPos[0] textPosY = textPos[1] self.scaleSeq = Parallel(Sequence(LerpFunctionInterval(self.descText.setScale, duration = 0.20000000000000001, toData = 1.05, fromData = 1.0, blendType = 'easeInOut'), LerpFunctionInterval(self.descText.setScale, duration = 0.69999999999999996, toData = 1.0, fromData = 1.05, blendType = 'easeInOut')), Sequence(Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, PiratesGuiGlobals.TextFG1), Func(self.moveLabel, (textPosX, textPosY)))) self.scaleSeq.start()
class RaceGUI: GagPie = 0 gagRoot = 'phase_3.5/maps/inventory_' class RacerInfo: def __init__(self, face, mapSpot): self.curvetime = 0 self.maxlaphit = 0 self.face = face self.mapspot = mapSpot self.place = 1 self.enabled = True self.finished = False self.gag = None return def update(self, curvetime=None, maxlaphit=None, faceX=None, mapspotPt=None, place=None, finished=None): if self.enabled: if not curvetime == None: self.curvetime = curvetime if not maxlaphit == None: self.maxlaphit = maxlaphit if not faceX == None: self.face.setX(faceX) if not mapspotPt == None: self.mapspot.setPos(mapspotPt) if not place == None: self.place = place if not finished == None: self.finished = finished return def disable(self): self.enabled = False if not self.finished: self.face.hide() self.mapspot.hide() def enable(self): self.enabled = True self.face.show() self.mapspot.show() def __init__(self, distRace): self.race = distRace self.timerEnabled = False self.maxLapHit = 0 self.photoFinish = False toonInteriorTextures = loader.loadModel( 'phase_3.5/models/modules/toon_interior_textures') invTextures = loader.loadModel('phase_3.5/models/gui/inventory_icons') racingTextures = loader.loadModel( 'phase_6/models/karting/racing_textures') self.gagTextures = [ toonInteriorTextures.find('**/couch'), invTextures.find('**/inventory_bannana_peel'), racingTextures.find('**/boost_arrow'), invTextures.find('**/inventory_anvil'), invTextures.find('**/inventory_creampie') ] self.gagTextures[1].setScale(7.5) self.gagTextures[3].setScale(7.5) self.gagTextures[4].setScale(7.5) self.cardMaker = CardMaker('card') self.racerDict = {} self.render2dRoot = render2d.attachNewNode('RaceGuiRender2dRoot') self.render2dRoot.setDepthWrite(1) self.directObjList = [] self.aspect2dRoot = aspect2d.attachNewNode('RaceGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.raceModeRoot = self.aspect2dRoot.attachNewNode('RaceModeRoot') gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=1.05, text=TTLocalizer.KartRace_Leave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(-0.99, 0, 0.925), command=self.race.leaveRace) self.closeButton.reparentTo(self.aspect2dRoot) self.directObjList.append(self.closeButton) self.raceTimeDelta = 0 self.raceModeReady = False self.resultModeReady = False self.gagCycleSound = base.loadSfx( 'phase_3.5/audio/sfx/tick_counter.mp3') if hasattr(self.gagCycleSound, 'setPlayRate'): self.gagCycleSound.setPlayRate(0.2) self.gagCycleSound.setLoop(1) self.gagAcquireSound = base.loadSfx( 'phase_6/audio/sfx/SZ_MM_gliss.mp3') self.disable() return def initRaceMode(self): self.mapScene = self.raceModeRoot.attachNewNode('MapScene') self.mapScene.setPos(1.1, 0, 0.75) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(1.1, 0, 0.45), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.85), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=self.raceModeRoot, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(-1.13, 0, -0.5)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return def initResultMode(self): self.endPanel = RaceEndPanel(len(self.race.avIds), self.race) self.endPanel.reparentTo(self.aspect2dRoot) self.directObjList.append(self.endPanel) self.resultModeReady = True self.disable() def showGag(self, gagIndex): if gagIndex < len(self.gagTextures): for gag in self.gagTextures: gag.hide() self.gagTextures[gagIndex].show() def updateGag(self, gagIndex): if self.gag: if hasattr(self, 'gagCycleInterval'): self.gagCycleInterval.finish() del self.gagCycleInterval self.gag.setHpr(0, 0, 0) self.showGag(gagIndex) if gagIndex == 0: self.gag.hide() else: self.gag.show() self.gagAcquireSound.play() self.gagAcquireInterval = LerpHprInterval(self.gag, duration=0.5, blendType='easeOut', startHpr=Point3( 0, -90, 0), hpr=Point3(0, 0, 0)) self.gagAcquireInterval.start() def waitingOnGag(self, cycleTime): if self.gag: numTextures = len(self.gagTextures) startOffset = random.choice(range(0, numTextures)) self.gag.show() self.gagCycleInterval = Parallel( LerpFunc(self.showNextGag, fromData=startOffset, toData=numTextures * 2 * cycleTime + startOffset, blendType='easeOut', duration=cycleTime), LerpHprInterval(self.gag, duration=cycleTime, hpr=Point3( 0, 180 * numTextures * 2 * cycleTime - 90, 0), blendType='easeOut', startHpr=Point3(0, 0, 0)), SoundInterval(self.gagCycleSound, loop=1, duration=cycleTime, startTime=0), name='gagCycleInterval') self.gagCycleInterval.start() def showNextGag(self, t): if self.gag: currGagIndex = int(t % (len(self.gagTextures) - 1)) + 1 self.showGag(currGagIndex) def enableSpeedometer(self): self.race.localKart.showSpeedometer() def disableSpeedometer(self): self.race.localKart.hideSpeedometer() def disableRaceMode(self): self.disableSpeedometer() self.render2dRoot.hide() self.raceModeRoot.hide() for x in self.timeLabels: for y in x: y.hide() self.setTimerEnabled(False) def disableResultMode(self): self.endPanel.disable() def disable(self): self.closeButton.hide() taskMgr.removeTasksMatching('clearRaceEndPanel') if self.raceModeReady: self.disableRaceMode() if self.resultModeReady: self.disableResultMode() def enableRaceMode(self): self.enableSpeedometer() self.render2dRoot.show() self.raceModeRoot.show() self.maxLapHit = min(self.maxLapHit, self.race.lapCount - 1) for x in range(self.maxLapHit + 1): for y in self.timeLabels[x]: y.configure(text_font=ToontownGlobals.getSignFont()) y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) def enableResultMode(self): self.endPanel.enable() if not self.race.circuitLoop: taskMgr.doMethodLater(180, self.endPanel.closeButtonPressed, 'clearRaceEndPanel', extraArgs=[]) def destroy(self): self.disable() if hasattr(self, 'wrongWaySeq'): self.wrongWaySeq.finish() self.wrongWaySeq = None taskMgr.removeTasksMatching('removeIt') taskMgr.removeTasksMatching('removeCam*') taskMgr.removeTasksMatching('clearRaceEndPanel') for obj in self.directObjList: obj.destroy() if hasattr(self, 'mapScene'): self.mapScene.removeNode() self.mapScene = None self.aspect2dRoot.removeNode() self.aspect2dRoot = None self.raceModeRoot.removeNode() self.raceModeRoot = None self.render2dRoot.removeNode() self.render2dRoot = None self.closeButton = None self.gag = None self.lapLabel = None self.timeLabels = None self.placeLabelStr = None self.placeLabelNum = None self.photoFinishLabel = None self.mapScene = None self.race = None return def setSpotAsymptotic(self, diffT, spot): p = (-1, 1)[diffT > 0] * (1 - 1 / pow(abs(diffT) / self.cutoff + 1, 2)) spot.setX(p) def setSpotRaceLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t / self.lapCount)) def setSpotLapLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t - int(t))) def update(self, time): placeSorter = [] placeCount = 0 for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[self.maxLapHit - 1]: y.configure( text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure( text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime( ) - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice[ 'text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice[ 'text'] = TTLocalizer.KartRace_LapText % str( self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str( clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str( self.race.lapCount) suffix = { 1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix } placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[ 0] - localRacer.face.getX() < nearDiff: for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX( ) >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str( self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[ localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() elif not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish() def updateRacerInfo(self, avId, curvetime=None, maxlaphit=None): if avId in self.racerDict.keys(): self.racerDict[avId].update(curvetime=curvetime, maxlaphit=maxlaphit) def racerEntered(self, avId): toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.race.kartMap.get(avId, None), None) if not toon or not kart: return if kart.getBodyColor() == InvalidEntry: bodyColor = getDefaultColor() else: bodyColor = getAccessory(kart.getBodyColor()) headframe = RaceHeadFrame(av=toon, color=bodyColor) eyes = headframe.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) headframe.configure(geom_scale=(0.5, 0.5, 0.5)) headframe.setZ(self.faceStartPos[2]) headframe.setDepthWrite(True) headframe.setDepthTest(True) headframe.reparentTo(self.raceModeRoot) self.directObjList.append(headframe) mapspot = loader.loadModel('phase_6/models/karting/race_mapspot') mapspot.setColor(bodyColor) mapspot.reparentTo(self.mapLines) mapspot.setHpr(self.mapScene, 0, 0, 0) self.racerDict[avId] = self.RacerInfo(headframe, mapspot) for key, i in zip(self.racerDict.keys(), range(len(self.racerDict.keys()))): face = self.racerDict[key].face mapspot = self.racerDict[key].mapspot face.setX(self.faceStartPos[0]) face.setY(-1 - 5 * (i + 1)) face.setScale(0.15) mapspot.getChild(0).setY((-5 - 5 * (i + 1)) * 1000) mapspot.setScale(self.mapScene, 0.15) mapspot.setPos(self.race.startingPos[0][0]) if key == localAvatar.doId: face.setY(-1) face.setScale(face.getScale() * 1.25) mapspot.getChild(0).setY(-5 * 1000) mapspot.setScale(mapspot.getScale() * 1.25) self.face = face self.mapspot = mapspot return def racerLeft(self, avId, unexpected=False): racer = self.racerDict.get(avId, None) if racer: racer.disable() return def racerFinished(self, avId, trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): racer = self.racerDict.get(avId, None) if racer: racer.update(finished=True) racer.disable() self.endPanel.displayRacer(place, entryFee, qualify, winnings, trackId, bonus, trophies, racer.face, base.cr.doId2do[avId].getName(), totalTime, circuitPoints, circuitTime) self.directObjList.remove(racer.face) if avId == localAvatar.doId: self.disableRaceMode() self.enableResultMode() self.endPanel.startWinningsPanel(entryFee, winnings, trackId, bonus, trophies) return def racerFinishedCircuit(self, avId, place, entryFee, winnings, bonus, trophies): racer = self.racerDict.get(avId, None) if racer: newTotalTickets = winnings + entryFee + bonus self.endPanel.updateWinnings(place, newTotalTickets) if avId == localAvatar.doId: self.endPanel.updateWinningsFromCircuit( place, entryFee, winnings, bonus, trophies) return def circuitFinished(self, placeFixup): self.endPanel.circuitFinished(placeFixup) def setTimerEnabled(self, enabled): self.timerEnabled = enabled
def initRaceMode(self): self.mapScene = self.raceModeRoot.attachNewNode('MapScene') self.mapScene.setPos(1.1, 0, 0.75) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(1.1, 0, 0.45), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.85), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=self.raceModeRoot, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(-1.13, 0, -0.5)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return
def enterWaiting(self): self.waitingLabel = DirectLabel() self.waitingLabel['text'] = TTLocalizer.BuildingWaitingForVictors self.waitingLabel.setScale(TTLocalizer.DRenterWaiting)
class DistributedRace(DistributedObject.DistributedObject): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedRace') ReadyPost = 'RaceReady' WinEvent = 'RaceWinEvent' BGM_BaseDir = 'phase_6/audio/bgm/' SFX_BaseDir = 'phase_6/audio/sfx/' SFX_StartBoop = SFX_BaseDir + 'KART_raceStart1.ogg' SFX_StartBoop2 = SFX_BaseDir + 'KART_raceStart2.ogg' SFX_Applause = SFX_BaseDir + 'KART_Applause_%d.ogg' def __init__(self, cr): self.qbox = loader.loadModel('phase_6/models/karting/qbox') self.boostArrowTexture = loader.loadTexture('phase_6/maps/boost_arrow.jpg', 'phase_6/maps/boost_arrow_a.rgb') self.boostArrowTexture.setMinfilter(Texture.FTLinear) DistributedObject.DistributedObject.__init__(self, cr) self.kartMap = {} self.fsm = ClassicFSM.ClassicFSM('Race', [State.State('join', self.enterJoin, self.exitJoin, ['prep', 'leave']), State.State('prep', self.enterPrep, self.exitPrep, ['tutorial', 'leave']), State.State('tutorial', self.enterTutorial, self.exitTutorial, ['start', 'waiting', 'leave']), State.State('waiting', self.enterWaiting, self.exitWaiting, ['start', 'leave']), State.State('start', self.enterStart, self.exitStart, ['racing', 'leave']), State.State('racing', self.enterRacing, self.exitRacing, ['finished', 'leave']), State.State('finished', self.enterFinished, self.exitFinished, ['leave']), State.State('leave', self.enterLeave, self.exitLeave, [])], 'join', 'leave') self.gui = RaceGUI(self) base.race = self self.currT = 0 self.currLapT = 0 self.currGag = 0 self.tdelay = 0 self.finished = False self.thrownGags = [] self.effectManager = EffectManager.EffectManager() self.piejectileManager = PiejectileManager.PiejectileManager() self.lastTimeUpdate = globalClock.getFrameTime() self.initGags() self.canShoot = True self.isUrbanTrack = False self.hasFog = False self.dummyNode = None self.fog = None self.bananaSound = base.loader.loadSfx('phase_6/audio/sfx/KART_tossBanana.ogg') self.anvilFall = base.loader.loadSfx('phase_6/audio/sfx/KART_Gag_Hit_Anvil.ogg') self.accept('leaveRace', self.leaveRace) self.toonsToLink = [] self.curveTs = [] self.curvePoints = [] self.localKart = None self.musicTrack = None self.victory = None self.miscTaskNames = [] self.boostDir = {} self.knownPlace = {} self.placeFixup = [] self.curve = None self.barricadeSegments = 100.0 self.outerBarricadeDict = {} self.innerBarricadeDict = {} self.maxLap = 0 self.oldT = 0 self.debugIt = 0 self.startPos = None def generate(self): self.notify.debug('generate: %s' % self.doId) DistributedObject.DistributedObject.generate(self) bboard.post('race', self) self.roomWatcher = None self.cutoff = 0.01 self.startBoopSfx = base.loader.loadSfx(self.SFX_StartBoop) self.startBoop2Sfx = base.loader.loadSfx(self.SFX_StartBoop2) def announceGenerate(self): self.notify.debug('announceGenerate: %s' % self.doId) DistributedObject.DistributedObject.announceGenerate(self) musicFile = self.BGM_BaseDir + RaceGlobals.TrackDict[self.trackId][7] self.raceMusic = base.loader.loadMusic(musicFile) base.playMusic(self.raceMusic, looping=1, volume=0.8) camera.reparentTo(render) if self.trackId in (RaceGlobals.RT_Urban_1, RaceGlobals.RT_Urban_1_rev, RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.isUrbanTrack = True self.oldFarPlane = base.camLens.getFar() base.camLens.setFar(12000) localAvatar.startPosHprBroadcast() localAvatar.d_broadcastPositionNow() DistributedSmoothNode.activateSmoothing(1, 1) self.reversed = self.trackId / 2.0 > int(self.trackId / 2.0) for i in xrange(3): base.loader.tick() self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') self.sky.setPos(0, 0, 0) self.sky.setScale(20.0) self.sky.setFogOff() if self.trackId in (RaceGlobals.RT_Urban_1, RaceGlobals.RT_Urban_1_rev, RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.loadFog() self.setupGeom() self.startSky() for i in xrange(5): base.loader.tick() def disable(self): self.notify.debug('disable %s' % self.doId) if self.musicTrack: self.musicTrack.finish() self.raceMusic.stop() self.stopSky() if self.sky is not None: self.sky.removeNode() if self.dummyNode: self.dummyNode.removeNode() self.dummyNode = None for taskName in self.miscTaskNames: taskMgr.remove(taskName) taskMgr.remove('raceWatcher') self.ignoreAll() DistributedSmoothNode.activateSmoothing(1, 0) if self.isUrbanTrack: self.unloadUrbanTrack() if self.fog: render.setFogOff() del self.fog self.fog = None if self.geom is not None: self.geom.hide() base.camLens.setFar(self.oldFarPlane) DistributedObject.DistributedObject.disable(self) def delete(self): self.notify.debug('delete %s' % self.doId) if self.gui: self.gui.destroy() self.gui = None if self.geom is not None: self.geom.removeNode() self.geom = None for i in self.gags: i.delete() del i self.piejectileManager.delete() if self.curveTs: del self.curveTs if self.curvePoints: del self.curvePoints if self.curve: del self.curve if self.victory: del self.victory del self.fsm del self.anvilFall del self.bananaSound del self.localKart DistributedObject.DistributedObject.delete(self) taskMgr.remove(self.uniqueName('countdownTimerTask')) taskMgr.remove('raceWatcher') bboard.remove('race') self.ignoreAll() del base.race def d_requestThrow(self, x, y, z): self.sendUpdate('requestThrow', [x, y, z]) def d_requestKart(self): self.sendUpdate('requestKart', []) def waitingForJoin(self): self.notify.debug('I got the barrier') self.fsm.enterInitialState() def racerDisconnected(self, avId): self.notify.debug('lost racer: %s' % avId) if avId in self.kartMap: if avId in self.toonsToLink: self.toonsToLink.remove(avId) toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) self.avIds.remove(avId) del self.kartMap[avId] self.gui.racerLeft(avId, unexpected=True) if kart: kart.reparentTo(hidden) if toon: toon.reparentTo(hidden) if len(self.toonsToLink) == 0: self.doneBarrier('waitingForPrep') def setPlace(self, avId, totalTime, place, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): if self.fsm.getCurrentState().getName() == 'leaving': return if avId == localAvatar.doId: cheerToPlay = place + (4 - self.numRacers) if cheerToPlay > 4: cheerToPlay = 4 self.victory = base.loader.loadSfx(self.SFX_Applause % cheerToPlay) self.victory.play() self.knownPlace[avId] = place kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) avatar = base.cr.doId2do.get(avId, None) if avatar: self.gui.racerFinished(avId, self.trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime) taskName = 'hideAv: %s' % avId taskMgr.doMethodLater(6, avatar.reparentTo, taskName, extraArgs=[hidden]) self.miscTaskNames.append(taskName) if kart: taskName = 'hideKart: %s' % self.localKart.doId taskMgr.doMethodLater(6, kart.reparentTo, taskName, extraArgs=[hidden]) self.miscTaskNames.append(taskName) def setCircuitPlace(self, avId, place, entryFee, winnings, bonus, trophies): print 'setting cicruit place' if self.fsm.getCurrentState().getName() == 'leaving': return if avId == localAvatar.doId: cheerToPlay = place + (4 - self.numRacers) self.victory = base.loader.loadSfx(self.SFX_Applause % cheerToPlay) self.victory.play() oldPlace = 0 if self.knownPlace.get(avId): oldPlace = self.knownPlace[avId] self.placeFixup.append([oldPlace - 1, place - 1]) avatar = base.cr.doId2do.get(avId, None) if avatar: print 'circuit trophies %s' % trophies print 'winnings %s' % winnings self.gui.racerFinishedCircuit(avId, oldPlace, entryFee, winnings, bonus, trophies) def endCircuitRace(self): print self.placeFixup self.gui.circuitFinished(self.placeFixup) def prepForRace(self): self.fsm.request('prep') def startRace(self, startTime = 0): self.baseTime = globalClockDelta.networkToLocalTime(startTime) self.fsm.request('start') def startTutorial(self): self.fsm.request('tutorial') def genGag(self, slot, number, type): self.notify.debug('making gag...') if not self.gags[slot].isActive(): self.gags[slot].genGag(number, type) def dropAnvilOn(self, ownerId, avId, timeStamp): kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) if kart: if avId != ownerId: if avId == localAvatar.doId: self.anvilFall.play() kart.dropOnMe(timeStamp) else: kart.dropOnHim(timeStamp) def shootPiejectile(self, sourceId, targetId, type = 0): kart = base.cr.doId2do.get(self.kartMap.get(sourceId, None), None) if kart: self.piejectileManager.addPiejectile(sourceId, targetId, type) def goToSpeedway(self, avIds, reason = RaceGlobals.Exit_UserReq): self.notify.debug('goToSpeedway %s %s' % (avIds, reason)) if localAvatar.doId in avIds: base.loader.endBulkLoad('atRace') self.kartCleanup() self.doneBarrier('waitingForExit') self.sendUpdate('racerLeft', [localAvatar.doId]) out = {'loader': 'safeZoneLoader', 'where': 'playground', 'how': 'teleportIn', 'hoodId': localAvatar.lastHood, 'zoneId': localAvatar.lastHood, 'shardId': None, 'avId': -1, 'reason': reason} base.cr.playGame.fsm.request('quietZone', [out]) def kartCleanup(self): kart = self.localKart if kart: kart.setState('P', 0) for i in self.avIds: if i != localAvatar.doId: toon = base.cr.doId2do.get(i, None) if toon: toon.stopSmooth() toon.setScale(1) toon.setShear(0, 0, 0) toon.reparentTo(render) kart.doHeadScale(toon, None) localAvatar.setPos(0, 14, 0) localAvatar.sendCurrentPosition() def heresMyT(self, avId, avNumLaps, avTime, timestamp): self.gui.updateRacerInfo(avId, curvetime=avNumLaps + avTime) def setZoneId(self, zoneId): self.zoneId = zoneId def setRaceType(self, raceType): self.raceType = raceType def setCircuitLoop(self, circuitLoop): self.circuitLoop = circuitLoop def setTrackId(self, id): DistributedRace.notify.debug('setTrackId: %s' % id) self.trackId = id def setAvatars(self, avIds): ids = '' for i in avIds: ids += str(i) + ' ' DistributedRace.notify.debug('setAvatars: %s' % ids) self.avIds = avIds self.avT = [0] * len(self.avIds) def setLapCount(self, lapCount): self.lapCount = lapCount def setStartingPlaces(self, startList): self.startingPlaces = startList def enterJoin(self): self.doneBarrier('waitingForJoin') self.notify.debug('entering Join') def exitJoin(self): pass def setEnteredRacers(self, avAndKarts): self.notify.debug('setEnteredRacers %s' % avAndKarts) avatarsGone = [] avatarsLeft = [] self.numRacers = len(avAndKarts) for i in avAndKarts: if i[0] in self.avIds: self.kartMap[i[0]] = i[1] avatarsLeft.append(i[0]) for i in self.avIds: if i not in avatarsLeft: avatarsGone.append(i) base.loader.tick() for i in avatarsGone: self.avIds.remove(i) self.toonsToLink = list(self.avIds) for i in avAndKarts: self.cr.relatedObjectMgr.requestObjects(i, allCallback=self.__gotKartAvatarLink) def __gotKartAvatarLink(self, avAndKart): self.notify.debug('got a Link') toon = avAndKart[0] kart = avAndKart[1] base.loader.tick() if toon.doId in self.toonsToLink: self.toonsToLink.remove(toon.doId) if toon.doId == localAvatar.doId: self.localKart = kart if len(self.toonsToLink) == 0: self.doneBarrier('waitingForPrep') def enterPrep(self): self.d_requestKart() self.notify.debug('entering Prep State') if self.reversed: self.spin = Vec3(180, 0, 0) else: self.spin = Vec3(0, 0, 0) for i in xrange(4): base.loader.tick() self.gui.initRaceMode() self.gui.initResultMode() self.myPos = self.startingPos[self.startingPlaces[self.avIds.index(localAvatar.doId)]] self.localKart.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) self.localKart.setupLapCollisions() if self.dummyNode: self.dummyNode.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) self.currentPole = self.findSegmentStart() self.rabbitPoint = Vec3(0, 0, 0) self.doneBarrier('waitingForReady') def exitPrep(self): pass def enterTutorial(self): self.notify.debug('entering Tutorial State') base.loader.endBulkLoad('atRace') self.localKart.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) base.transitions.irisIn() self.rulesDoneEvent = 'finishedRules' self.accept(self.rulesDoneEvent, self.handleRulesDone) self.rulesPanel = MinigameRulesPanel.MinigameRulesPanel('RacingRulesPanel', self.getTitle(), self.getInstructions(), self.rulesDoneEvent, 10) self.rulesPanel.load() self.rulesPanel.frame.setPos(0, 0, -0.6667) self.rulesPanel.enter() def exitTutorial(self): self.ignore(self.rulesDoneEvent) self.rulesPanel.exit() self.rulesPanel.unload() del self.rulesPanel def getTitle(self): return TTLocalizer.KartRace_TitleInfo def getInstructions(self): return TTLocalizer.KartRace_TrackInfo[self.trackId] def handleRulesDone(self): self.doneBarrier('readRules') self.fsm.request('waiting') def enterWaiting(self): self.waitingLabel = DirectLabel() self.waitingLabel['text'] = TTLocalizer.BuildingWaitingForVictors self.waitingLabel.setScale(TTLocalizer.DRenterWaiting) def exitWaiting(self): self.waitingLabel.removeNode() def enterStart(self): waitTime = self.baseTime - globalClock.getFrameTime() taskName = 'enableRaceModeLater' taskMgr.doMethodLater(1, self.gui.enableRaceMode, taskName, extraArgs=[]) self.miscTaskNames.append(taskName) for i in self.avIds: self.gui.racerEntered(i) self.startCountdownClock(waitTime, 0) taskMgr.doMethodLater(waitTime, self.fsm.request, 'goToRacing', extraArgs=['racing']) def exitStart(self): pass def enterRacing(self): self.localKart.setInput(1) self.gui.setTimerEnabled(True) self.raceTask = taskMgr.add(self.raceWatcher, 'raceWatcher') def exitRacing(self): pass def raceWatcher(self, task): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) if self.localKart.amIClampingPosition(): self.notify.debug('teleporting kart %d back to main track' % localAvatar.doId) self.localKart.setPos(self.curvePoints[self.currentPole]) kartPoint = self.localKart.getPos() direction = 0 while True: currPoint = self.curvePoints[self.currentPole] nextPole = (self.currentPole + 1) % len(self.curvePoints) nextPoint = self.curvePoints[nextPole] segment = nextPoint - currPoint segment.setZ(0) segLength2 = segment.lengthSquared() kartVector = kartPoint - currPoint kartVector.setZ(0) project = segment * (segment.dot(kartVector) / segLength2) projLength2 = project.lengthSquared() if project.dot(segment) < 0: if direction == 1: break prevPole = (self.currentPole - 1) % len(self.curvePoints) self.currentPole = prevPole direction = -1 elif projLength2 > segLength2: if direction == -1: break self.currentPole = nextPole direction = 1 else: break if self.dummyNode: self.dummyNode.setPos(kartPoint[0], kartPoint[1], 0) self.dummyNode.setHpr(self.localKart.getH(), 0, 0) t = projLength2 / segLength2 if self.debugIt: self.notify.debug('self.debugIt = %d' % self.debugIt) import pdb pdb.set_trace() if nextPole < self.currentPole: newT = self.curveTs[self.currentPole] * (1 - t) + self.curve.getMaxT() * t else: newT = self.curveTs[self.currentPole] * (1 - t) + self.curveTs[nextPole] * t kartDirection = self.localKart.forward.getPos(render) - self.localKart.getPos(render) kartDirection.normalize() project.normalize() globalDirection = kartDirection.dot(project) if globalDirection < 0: self.wrongWay = True elif globalDirection > 0.1: self.wrongWay = False newLapT = (newT - self.startT) / self.curve.getMaxT() % 1.0 if newLapT - self.currLapT < -0.5: self.laps += 1 self.changeMusicTempo(1 + self.laps * 0.5) self.notify.debug('crossed the start line: %s, %s, %s, %s' % (self.laps, self.startT, self.currT, newT)) elif newLapT - self.currLapT > 0.5: self.laps -= 1 self.changeMusicTempo(1 + self.laps * 0.5) self.notify.debug('crossed the start line - wrong way: %s, %s, %s, %s' % (self.laps, self.startT, self.currT, newT)) self.currT = newT self.currLapT = newLapT if self.isUrbanTrack: self.showBuildings(self.currT) now = globalClock.getFrameTime() timestamp = globalClockDelta.localToNetworkTime(now) if self.laps == self.lapCount: self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) self.fsm.request('finished') if self.laps > self.maxLap: self.maxLap = self.laps self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) if now - self.lastTimeUpdate > 0.5: self.lastTimeUpdate = now self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) self.gui.updateRacerInfo(localAvatar.doId, curvetime=self.currLapT + self.laps) self.gui.update(now) return Task.cont def enterFinished(self): taskMgr.remove('raceWatcher') self.fadeOutMusic() self.localKart.interruptTurbo() self.localKart.disableControls() taskName = 'parkIt' taskMgr.doMethodLater(2, self.stopDriving, taskName, extraArgs=[]) self.miscTaskNames.append(taskName) self.finished = True camera.reparentTo(render) camera.setPos(self.localKart.getPos(render) + Vec3(0, 0, 10)) camera.setH(self.localKart.getH(render) + 180) self.gui.disableRaceMode() self.gui.enableResultMode() localAvatar.reparentTo(hidden) self.localKart.reparentTo(hidden) def exitFinished(self): pass def stopDriving(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) cpos = camera.getPos() chpr = camera.getHpr() localAvatar.reparentTo(hidden) self.localKart.reparentTo(hidden) self.localKart.stopSmooth() self.localKart.stopPosHprBroadcast() camera.setPos(cpos) camera.setHpr(chpr) def enterLeave(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) taskMgr.remove('raceWatcher') self.gui.disable() if self.localKart: self.localKart.disableControls() base.transitions.irisOut() if self.raceType == RaceGlobals.Circuit and not len(self.circuitLoop) == 0: self.sendUpdate('racerLeft', [localAvatar.doId]) else: taskMgr.doMethodLater(1, self.goToSpeedway, 'leaveRace', extraArgs=[[localAvatar.doId], RaceGlobals.Exit_UserReq]) if self.victory: self.victory.stop() self.bananaSound.stop() self.anvilFall.stop() def exitLeave(self): pass def getCountdownColor(self, countdownTimeInt): clockNodeColors = [Vec4(0, 1, 0, 1), Vec4(1, 1, 0, 1), Vec4(1, 0.5, 0, 1), Vec4(1, 0, 0, 1)] i = max(min(countdownTimeInt, len(clockNodeColors) - 1), 0) return clockNodeColors[i] def startCountdownClock(self, countdownTime, ts): self.clockNode = TextNode('k') self.clockNode.setFont(ToontownGlobals.getSignFont()) self.clockNode.setAlign(TextNode.ACenter) countdownInt = int(countdownTime) self.clockNode.setTextColor(self.getCountdownColor(countdownInt)) self.clockNode.setText(str(countdownInt)) self.clock = render2d.attachNewNode(self.clockNode) rs = TTLocalizer.DRrollScale self.clock.setPosHprScale(0, 0, 0, 0, 0, 0, rs, rs, rs) self.clock.hide() if ts < countdownTime: self.countdown(countdownTime - ts) def timerTask(self, task): countdownTime = int(task.duration - task.time) timeStr = str(countdownTime + 1) if self.clock.isHidden(): if task.duration - task.time <= task.maxCount: self.clock.show() if self.clockNode.getText() != timeStr: self.startBoopSfx.play() self.clockNode.setText(timeStr) self.clockNode.setTextColor(self.getCountdownColor(countdownTime + 1)) if task.time >= task.duration: self.startBoop2Sfx.play() self.clockNode.setText(TTLocalizer.KartRace_Go) self.clockNode.setTextColor(self.getCountdownColor(-1)) taskMgr.doMethodLater(1, self.endGoSign, 'removeGoSign') return Task.done else: return Task.cont def endGoSign(self, t): self.clock.removeNode() def countdown(self, duration): countdownTask = Task(self.timerTask) countdownTask.duration = duration countdownTask.maxCount = RaceGlobals.RaceCountdown taskMgr.remove(self.uniqueName('countdownTimerTask')) return taskMgr.add(countdownTask, self.uniqueName('countdownTimerTask')) def initGags(self): self.banana = globalPropPool.getProp('banana') self.banana.setScale(2) self.pie = globalPropPool.getProp('creampie') self.pie.setScale(1) def makeCheckPoint(self, trigger, location, event): cs = CollisionSphere(0, 0, 0, 140) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(self.geom) cnp.setPos(location) self.accept(triggerEvent, event) def loadUrbanTrack(self): self.dnaStore = DNAStorage() files = ('phase_4/dna/storage.pdna', 'phase_5/dna/storage_town.pdna', 'phase_4/dna/storage_TT.pdna', 'phase_5/dna/storage_TT_town.pdna', 'phase_8/dna/storage_BR.pdna', 'phase_8/dna/storage_BR_town.pdna', 'phase_8/dna/storage_DL.pdna', 'phase_8/dna/storage_DL_town.pdna') dnaBulk = DNABulkLoader(self.dnaStore, files) dnaBulk.loadDNAFiles() dnaFile = 'phase_6/dna/urban_track_town.pdna' if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): dnaFile = 'phase_6/dna/urban_track_town_B.pdna' node = loader.loadDNAFile(self.dnaStore, dnaFile) self.townGeom = self.geom.attachNewNode(node) self.townGeom.findAllMatches('**/+CollisionNode').stash() self.buildingGroups = {} self.currBldgInd = {} self.currBldgGroups = {} bgGeom = self.geom.find('**/polySurface8') if self.dummyNode: bgGeom.reparentTo(self.dummyNode) else: bgGeom.reparentTo(localAvatar) bgGeom.setScale(0.1) ce = CompassEffect.make(NodePath(), CompassEffect.PRot) bgGeom.node().setEffect(ce) bgGeom.setDepthTest(0) bgGeom.setDepthWrite(0) bgGeom.setBin('background', 102) bgGeom.setZ(-1) self.bgGeom = bgGeom l = self.geom.findAllMatches('**/+ModelNode') for n in l: n.node().setPreserveTransform(0) self.geom.flattenLight() maxNum = 0 for side in ['inner', 'outer']: self.buildingGroups[side] = [] self.currBldgInd[side] = None self.currBldgGroups[side] = None i = 0 while 1: bldgGroup = self.townGeom.find('**/Buildings_' + side + '-' + str(i)) if bldgGroup.isEmpty(): break l = bldgGroup.findAllMatches('**/+ModelNode') for n in l: n2 = n.getParent().attachNewNode(n.getName()) n.getChildren().reparentTo(n2) n.removeNode() bldgGroup.flattenStrong() if not bldgGroup.getNode(0).getBounds().isEmpty(): self.buildingGroups[side].append(bldgGroup) i += 1 if i > maxNum: maxNum = i for side in ['innersidest', 'outersidest']: self.buildingGroups[side] = [] self.currBldgInd[side] = None self.currBldgGroups[side] = None for i in xrange(maxNum): for barricade in ('innerbarricade', 'outerbarricade'): bldgGroup = self.townGeom.find('**/Buildings_' + side + '-' + barricade + '_' + str(i)) if bldgGroup.isEmpty(): continue l = bldgGroup.findAllMatches('**/+ModelNode') for n in l: n2 = n.getParent().attachNewNode(n.getName()) n.getChildren().reparentTo(n2) n.removeNode() self.buildingGroups[side].append(bldgGroup) treeNodes = self.townGeom.findAllMatches('**/prop_tree_*') for tree in treeNodes: tree.flattenStrong() snowTreeNodes = self.townGeom.findAllMatches('**/prop_snow_tree_*') for snowTree in snowTreeNodes: snowTree.flattenStrong() for side in ['inner', 'outer', 'innersidest', 'outersidest']: for grp in self.buildingGroups[side]: grp.stash() self.showBuildings(0) def unloadUrbanTrack(self): del self.buildingGroups self.townGeom.removeNode() def loadFog(self): self.hasFog = True if self.isUrbanTrack: base.camLens.setFar(650) else: base.camLens.setFar(650) self.dummyNode = render.attachNewNode('dummyNode') if base.wantFog: self.fog = Fog('TrackFog') self.fog.setColor(Vec4(0.6, 0.7, 0.8, 1.0)) if self.isUrbanTrack: self.fog.setLinearRange(200.0, 650.0) else: self.fog.setLinearRange(200.0, 800.0) render.setFog(self.fog) self.sky.setScale(1.725) self.sky.reparentTo(self.dummyNode) def showBuildings(self, t, forceRecompute = False): firstTimeCalled = 0 if self.curve: t = t / self.curve.getMaxT() else: firstTimeCalled = 1 if self.reversed: t = 1.0 - t numGroupsShown = 5 for side in ['inner', 'outer']: numBldgGroups = len(self.buildingGroups[side]) bldgInd = int(t * numBldgGroups) bldgInd = bldgInd % numBldgGroups if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): oldBldgInd = int(self.oldT * numBldgGroups) newBldgInd = int(t * numBldgGroups) kartPoint = self.startPos kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) if kart: kartPoint = self.localKart.getPos() if not self.currBldgInd[side]: self.currBldgInd[side] = 0 curInd = self.currBldgInd[side] myCurGroup = self.buildingGroups[side][curInd] prevGrp = (curInd - 1) % numBldgGroups myPrevGroup = self.buildingGroups[side][prevGrp] nextGrp = (curInd + 1) % numBldgGroups myNextGroup = self.buildingGroups[side][nextGrp] curVector = myCurGroup.getNode(0).getBounds().getCenter() - kartPoint curDistance = curVector.lengthSquared() prevVector = myPrevGroup.getNode(0).getBounds().getCenter() - kartPoint prevDistance = prevVector.lengthSquared() nextVector = myNextGroup.getNode(0).getBounds().getCenter() - kartPoint nextDistance = nextVector.lengthSquared() if curDistance <= prevDistance and curDistance <= nextDistance: bldgInd = self.currBldgInd[side] elif prevDistance <= curDistance and prevDistance <= nextDistance: bldgInd = prevGrp elif nextDistance <= curDistance and nextDistance <= prevDistance: bldgInd = nextGrp else: self.notify.warning('unhandled case!!!!') bldgInd = self.currBldgInd[side] if bldgInd != self.currBldgInd[side]: currBldgGroups = self.currBldgGroups[side] if currBldgGroups: for i in currBldgGroups: self.buildingGroups[side][i].stash() prevGrp2 = (bldgInd - 2) % numBldgGroups prevGrp = (bldgInd - 1) % numBldgGroups currGrp = bldgInd % numBldgGroups nextGrp = (bldgInd + 1) % numBldgGroups nextGrp2 = (bldgInd + 2) % numBldgGroups self.currBldgGroups[side] = [prevGrp2, prevGrp, currGrp, nextGrp, nextGrp2] for i in self.currBldgGroups[side]: self.buildingGroups[side][i].unstash() self.currBldgInd[side] = bldgInd if self.currBldgGroups['inner'] != self.currBldgGroups['outer']: pass if t != self.oldT: self.oldT = t if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): if self.reversed: t = 1.0 - t for side in ['innersidest', 'outersidest']: segmentInd = int(t * self.barricadeSegments) seglmentInd = segmentInd % self.barricadeSegments if segmentInd != self.currBldgInd[side] or forceRecompute: currBldgGroups = self.currBldgGroups[side] if currBldgGroups: for i in currBldgGroups: self.buildingGroups[side][i].stash() self.currBldgGroups[side] = [] if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict if segmentInd in dict: self.currBldgGroups[side] = dict[segmentInd] for i in self.currBldgGroups[side]: self.buildingGroups[side][i].unstash() self.currBldgInd[side] = segmentInd def setupGeom(self): trackFilepath = RaceGlobals.TrackDict[self.trackId][0] self.geom = loader.loadModel(trackFilepath) for i in xrange(10): base.loader.tick() self.geom.reparentTo(render) if self.reversed: lapStartPos = self.geom.find('**/lap_start_rev').getPos() else: lapStartPos = self.geom.find('**/lap_start').getPos() self.startPos = lapStartPos lapMidPos = self.geom.find('**/lap_middle').getPos() for i in xrange(5): base.loader.tick() self.startingPos = [] posLocators = self.geom.findAllMatches('**/start_pos*') for i in xrange(posLocators.getNumPaths()): base.loader.tick() self.startingPos.append([posLocators[i].getPos(), posLocators[i].getHpr()]) self.notify.debug('self.startingPos: %s' % self.startingPos) self.wrongWay = False self.laps = 0 if self.isUrbanTrack: self.loadUrbanTrack() self.genArrows() if self.reversed: self.curve = self.geom.find('**/curve_reverse').node() else: self.curve = self.geom.find('**/curve_forward').node() for i in xrange(4000): self.curvePoints.append(Point3(0, 0, 0)) self.curve.getPoint(i / 4000.0 * (self.curve.getMaxT() - 1e-11), self.curvePoints[-1]) self.curveTs.append(i / 4000.0 * (self.curve.getMaxT() - 1e-11)) if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.precomputeSideStreets() for i in xrange(10): base.loader.tick() self.startT = self.getNearestT(lapStartPos) self.midT = self.getNearestT(lapMidPos) self.gags = [] gagList = RaceGlobals.TrackDict[self.trackId][4] for i in xrange(len(gagList)): self.notify.debug('generating gag: %s' % i) self.gags.append(RaceGag(self, i, Vec3(*gagList[i]) + Vec3(0, 0, 3))) for i in xrange(5): base.loader.tick() def precomputeSideStreets(self): farDist = base.camLens.getFar() + 300 farDistSquared = farDist * farDist for i in xrange(int(self.barricadeSegments)): testPoint = Point3(0, 0, 0) self.curve.getPoint(i / self.barricadeSegments * (self.curve.getMaxT() - 1e-11), testPoint) for side in ('innersidest', 'outersidest'): for bldgGroupIndex in xrange(len(self.buildingGroups[side])): bldgGroup = self.buildingGroups[side][bldgGroupIndex] if not bldgGroup.getNode(0).getBounds().isEmpty(): bldgPoint = bldgGroup.getNode(0).getBounds().getCenter() vector = testPoint - bldgPoint if vector.lengthSquared() < farDistSquared: if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict else: self.notify.error('unhandled side') if i in dict: if bldgGroupIndex not in dict[i]: dict[i].append(bldgGroupIndex) else: dict[i] = [bldgGroupIndex] for childIndex in (0,): if childIndex >= bldgGroup.getNumChildren(): continue childNodePath = bldgGroup.getChild(childIndex) bldgPoint = childNodePath.node().getBounds().getCenter() vector = testPoint - bldgPoint if vector.lengthSquared() < farDistSquared: if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict else: self.notify.error('unhandled side') if i in dict: if bldgGroupIndex not in dict[i]: dict[i].append(bldgGroupIndex) else: dict[i] = [bldgGroupIndex] for side in ('innersidest', 'outersidest'): for bldgGroup in self.buildingGroups[side]: bldgGroup.flattenStrong() if self.isUrbanTrack: self.showBuildings(0, forceRecompute=True) def findSegmentStart(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) minLength2 = 1000000 minIndex = -1 currPoint = Point3(0, 0, 0) kartPoint = self.localKart.getPos() for i in xrange(len(self.curvePoints)): currPoint = self.curvePoints[i] currLength2 = (kartPoint - currPoint).lengthSquared() if currLength2 < minLength2: minLength2 = currLength2 minIndex = i currPoint = self.curvePoints[minIndex] if minIndex + 1 == len(self.curvePoints): nextPoint = self.curvePoints[0] else: nextPoint = self.curvePoints[minIndex + 1] if minIndex - 1 < 0: prevIndex = len(self.curvePoints) - 1 else: prevIndex = minIndex - 1 forwardSegment = nextPoint - currPoint if (kartPoint - currPoint).dot(forwardSegment) > 0: return minIndex else: return prevIndex def getNearestT(self, pos): minLength2 = 1000000 minIndex = -1 currPoint = Point3(0, 0, 0) for i in xrange(len(self.curvePoints)): currPoint = self.curvePoints[i] currLength2 = (pos - currPoint).lengthSquared() if currLength2 < minLength2: minLength2 = currLength2 minIndex = i currPoint = self.curvePoints[minIndex] if minIndex + 1 == len(self.curvePoints): nextPoint = self.curvePoints[0] else: nextPoint = self.curvePoints[minIndex + 1] if minIndex - 1 < 0: prevIndex = len(self.curvePoints) - 1 else: prevIndex = minIndex - 1 forwardSegment = nextPoint - currPoint if (pos - currPoint).dot(forwardSegment) > 0: pole = minIndex else: pole = prevIndex currPoint = self.curvePoints[pole] nextPole = (pole + 1) % len(self.curvePoints) nextPoint = self.curvePoints[nextPole] segment = nextPoint - currPoint segment.setZ(0) segLength2 = segment.lengthSquared() posVector = pos - currPoint posVector.setZ(0) project = segment * (segment.dot(posVector) / segLength2) percent = project.lengthSquared() / segLength2 if nextPole < pole: t = self.curveTs[pole] * (1 - percent) + self.curve.getMaxT() * percent else: t = self.curveTs[pole] * (1 - percent) + self.curveTs[nextPole] * percent return t def hasGag(self, slot, type, index): if self.gags[slot].isActive(): self.gags[slot].disableGag() def leaveRace(self): self.fsm.request('leave') def racerLeft(self, avId): if avId != localAvatar.doId: self.gui.racerLeft(avId, unexpected=False) def skyTrack(self, task): return SkyUtil.cloudSkyTrack(task) def startSky(self): if self.hasFog: SkyUtil.startCloudSky(self, parent=self.dummyNode, effects=CompassEffect.PRot) else: SkyUtil.startCloudSky(self, parent=render) def stopSky(self): taskMgr.remove('skyTrack') def pickupGag(self, slot, index): self.canShoot = False standing = self.gui.racerDict[localAvatar.doId].place - 1 self.currGag = RaceGlobals.GagFreq[standing][index] cycleTime = 2 self.gui.waitingOnGag(cycleTime) taskMgr.doMethodLater(cycleTime, self.enableShoot, 'enableShoot') self.sendUpdate('hasGag', [slot, self.currGag, index]) def shootGag(self): if self.canShoot: if self.currGag == 1: self.bananaSound.play() self.shootBanana() elif self.currGag == 2: self.d_requestThrow(0, 0, 0) self.localKart.startTurbo() elif self.currGag == 3: self.d_requestThrow(0, 0, 0) elif self.currGag == 4: self.bananaSound.play() self.shootPie() self.currGag = 0 self.gui.updateGag(0) def enableShoot(self, t): self.canShoot = True if self.gui: self.gui.updateGag(self.currGag) def shootBanana(self): pos = self.localKart.getPos(render) banana = self.banana.copyTo(self.geom) banana.setPos(pos) self.thrownGags.append(banana) self.d_requestThrow(pos[0], pos[1], pos[2]) def shootPie(self): pos = self.localKart.getPos(render) self.d_requestThrow(pos[0], pos[1], pos[2]) def genArrows(self): base.arrows = [] arrowId = 0 for boost in RaceGlobals.TrackDict[self.trackId][5]: self.genArrow(boost[0], boost[1], arrowId) arrowId += 1 def genArrow(self, pos, hpr, id): factory = CardMaker('factory') factory.setFrame(-0.5, 0.5, -0.5, 0.5) arrowNode = factory.generate() arrowRoot = NodePath('root') baseArrow = NodePath(arrowNode) baseArrow.setTransparency(1) baseArrow.setTexture(self.boostArrowTexture) baseArrow.reparentTo(arrowRoot) arrow2 = baseArrow.copyTo(baseArrow) arrow2.setPos(0, 0, 1) arrow3 = arrow2.copyTo(arrow2) arrowRoot.setPos(*pos) arrowRoot.setHpr(*hpr) baseArrow.setHpr(0, -90, 0) baseArrow.setScale(24) arrowRoot.reparentTo(self.geom) trigger = 'boostArrow' + str(id) cs = CollisionTube(Point3(0.6, -6, 0), Point3(0.6, 54, 0), 4.8) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(arrowRoot) self.accept(triggerEvent, self.hitBoostArrow) arrowVec = arrow2.getPos(self.geom) - baseArrow.getPos(self.geom) arrowVec.normalize() idStr = str(id) cnp.setTag('boostId', idStr) self.boostDir[idStr] = arrowVec base.arrows.append(arrowRoot) def hitBoostArrow(self, cevent): into = cevent.getIntoNodePath() idStr = into.getTag('boostId') arrowVec = self.boostDir.get(idStr) if arrowVec == None: print 'Unknown boost arrow %s' % idStr return fvec = self.localKart.forward.getPos(self.geom) - self.localKart.getPos(self.geom) fvec.normalize() dotP = arrowVec.dot(fvec) if dotP > 0.7: self.localKart.startTurbo() def fadeOutMusic(self): if self.musicTrack: self.musicTrack.finish() curVol = self.raceMusic.getVolume() interval = LerpFunctionInterval(self.raceMusic.setVolume, fromData=curVol, toData=0, duration=3) self.musicTrack = Sequence(interval) self.musicTrack.start() def changeMusicTempo(self, newPR): return if self.musicTrack: self.musicTrack.finish() curPR = self.raceMusic.getPlayRate() interval = LerpFunctionInterval(self.raceMusic.setPlayRate, fromData=curPR, toData=newPR, duration=3) self.musicTrack = Sequence(interval) self.musicTrack.start() def setRaceZone(self, zoneId, trackId): hoodId = self.cr.playGame.hood.hoodId base.loader.endBulkLoad('atRace') self.kartCleanup() self.doneBarrier('waitingForExit') self.sendUpdate('racerLeft', [localAvatar.doId]) out = {'loader': 'racetrack', 'where': 'racetrack', 'hoodId': hoodId, 'zoneId': zoneId, 'trackId': trackId, 'shardId': None, 'reason': RaceGlobals.Exit_UserReq} base.cr.playGame.hood.loader.fsm.request('quietZone', [out])
def initRaceMode(self): ## #setup the 'map' display region ## self.mapScene = NodePath('MapScene') ## self.mapScene.setTransparency(1) ## self.mapSize = 0.15 ## self.mapX = 0.84 ## self.mapY = 0.84 ## self.mapCam = None ## if (base.win.getNumDisplayRegions()>4): ## for x in range(base.win.getNumDisplayRegions()-4): ## dr = base.win.getDisplayRegion(x+4) ## if (dr.getCamera().getName() == 'MapCam'): ## self.mapCam = dr.getCamera() ## break ## if(self.mapCam == None): ## self.mapCam = base.makeCamera(base.win,sort=30,displayRegion = (self.mapX,self.mapX+self.mapSize,self.mapY,self.mapY+self.mapSize),camName = 'MapCam') ## self.mapCam.setY(-10) ## self.mapCam.node().setLens(OrthographicLens()) ## self.mapCam.node().getLens().setFilmSize(2) ## self.mapCam.node().getLens().setAspectRatio(4.0/3.0) ## self.mapCam.reparentTo(self.mapScene) ## self.cardMaker.reset() ## self.cardMaker.setName('MapBackground') ## self.cardMaker.setFrame(-1,1,-1,1) ## self.cardMaker.setColor(1,1,1,0.25) ## card = self.mapScene.attachNewNode(self.cardMaker.generate()) #setup the 'map' display region self.mapScene = self.raceModeRoot.attachNewNode('MapScene') self.mapScene.setPos(1.1, 0, 0.75) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if (x == 0): ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) #setup face info self.faceStartPos = Vec3(-0.80, 0, 0.93) self.faceEndPos = Vec3(0.80, 0, 0.93) #setup place(1st,2nd,...) reporting self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.placeLabelNum.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.placeLabelStr.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelStr) #setup lap reporting self.lapLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.45), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.lapLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.lapLabel) #setup photo finish label self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) #setup wrong way reporting self.wrongWayLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.85), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.wrongWayLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1)), ) #setup time reporting interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * (x) self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text='0\'', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text='00\'\'', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) #setup gag indicator self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=self.raceModeRoot, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(-1.13, 0, -0.5), ) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() #setup face line self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable()
class RaceGUI: GagPie = 0 gagRoot = 'phase_3.5/maps/inventory_' class RacerInfo: def __init__(self, face, mapSpot): self.curvetime = 0 self.maxlaphit = 0 self.face = face self.mapspot = mapSpot self.place = 1 self.enabled = True self.finished = False self.gag = None return def update(self, curvetime = None, maxlaphit = None, faceX = None, mapspotPt = None, place = None, finished = None): if self.enabled: if not curvetime == None: self.curvetime = curvetime if not maxlaphit == None: self.maxlaphit = maxlaphit if not faceX == None: self.face.setX(faceX) if not mapspotPt == None: self.mapspot.setPos(mapspotPt) if not place == None: self.place = place if not finished == None: self.finished = finished return def disable(self): self.enabled = False if not self.finished: self.face.hide() self.mapspot.hide() def enable(self): self.enabled = True self.face.show() self.mapspot.show() def __init__(self, distRace): self.race = distRace self.timerEnabled = False self.maxLapHit = 0 self.photoFinish = False toonInteriorTextures = loader.loadModel('phase_3.5/models/modules/toon_interior_textures') invTextures = loader.loadModel('phase_3.5/models/gui/inventory_icons') racingTextures = loader.loadModel('phase_6/models/karting/racing_textures') self.gagTextures = [toonInteriorTextures.find('**/couch'), invTextures.find('**/inventory_bannana_peel'), racingTextures.find('**/boost_arrow'), invTextures.find('**/inventory_anvil'), invTextures.find('**/inventory_creampie')] self.gagTextures[1].setScale(7.5) self.gagTextures[3].setScale(7.5) self.gagTextures[4].setScale(7.5) self.cardMaker = CardMaker('card') self.racerDict = {} self.render2dRoot = render2d.attachNewNode('RaceGuiRender2dRoot') self.render2dRoot.setDepthWrite(1) self.directObjList = [] self.aspect2dRoot = aspect2d.attachNewNode('RaceGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.raceModeRoot = self.aspect2dRoot.attachNewNode('RaceModeRoot') gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=1.05, text=TTLocalizer.KartRace_Leave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(-0.99, 0, 0.925), command=self.race.leaveRace) self.closeButton.reparentTo(self.aspect2dRoot) self.directObjList.append(self.closeButton) self.raceTimeDelta = 0 self.raceModeReady = False self.resultModeReady = False self.gagCycleSound = base.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') if hasattr(self.gagCycleSound, 'setPlayRate'): self.gagCycleSound.setPlayRate(0.2) self.gagCycleSound.setLoop(1) self.gagAcquireSound = base.loadSfx('phase_6/audio/sfx/SZ_MM_gliss.ogg') self.disable() return def initRaceMode(self): self.mapScene = base.a2dTopRight.attachNewNode('MapScene') self.mapScene.setPos(-0.2, 0, -0.2) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in xrange(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.5), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel(relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.2), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence(self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * (1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in xrange(self.race.lapCount): minLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame(parent=base.a2dBottomLeft, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(0.2, 0, 0.55)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in xrange(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos(self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return def initResultMode(self): self.endPanel = RaceEndPanel(len(self.race.avIds), self.race) self.endPanel.reparentTo(self.aspect2dRoot) self.directObjList.append(self.endPanel) self.resultModeReady = True self.disable() def showGag(self, gagIndex): if gagIndex < len(self.gagTextures): for gag in self.gagTextures: gag.hide() self.gagTextures[gagIndex].show() def updateGag(self, gagIndex): if self.gag: if hasattr(self, 'gagCycleInterval'): self.gagCycleInterval.finish() del self.gagCycleInterval self.gag.setHpr(0, 0, 0) self.showGag(gagIndex) if gagIndex == 0: self.gag.hide() else: self.gag.show() self.gagAcquireSound.play() self.gagAcquireInterval = LerpHprInterval(self.gag, duration=0.5, blendType='easeOut', startHpr=Point3(0, -90, 0), hpr=Point3(0, 0, 0)) self.gagAcquireInterval.start() def waitingOnGag(self, cycleTime): if self.gag: numTextures = len(self.gagTextures) startOffset = random.choice(range(0, numTextures)) self.gag.show() self.gagCycleInterval = Parallel(LerpFunc(self.showNextGag, fromData=startOffset, toData=numTextures * 2 * cycleTime + startOffset, blendType='easeOut', duration=cycleTime), LerpHprInterval(self.gag, duration=cycleTime, hpr=Point3(0, 180 * numTextures * 2 * cycleTime - 90, 0), blendType='easeOut', startHpr=Point3(0, 0, 0)), SoundInterval(self.gagCycleSound, loop=1, duration=cycleTime, startTime=0), name='gagCycleInterval') self.gagCycleInterval.start() def showNextGag(self, t): if self.gag: currGagIndex = int(t % (len(self.gagTextures) - 1)) + 1 self.showGag(currGagIndex) def enableSpeedometer(self): self.race.localKart.showSpeedometer() def disableSpeedometer(self): self.race.localKart.hideSpeedometer() def disableRaceMode(self): self.disableSpeedometer() self.render2dRoot.hide() self.raceModeRoot.hide() for x in self.timeLabels: for y in x: y.hide() self.setTimerEnabled(False) def disableResultMode(self): self.endPanel.disable() def disable(self): self.closeButton.hide() taskMgr.removeTasksMatching('clearRaceEndPanel') if self.raceModeReady: self.disableRaceMode() if self.resultModeReady: self.disableResultMode() def enableRaceMode(self): self.enableSpeedometer() self.render2dRoot.show() self.raceModeRoot.show() self.maxLapHit = min(self.maxLapHit, self.race.lapCount - 1) for x in xrange(self.maxLapHit + 1): for y in self.timeLabels[x]: y.configure(text_font=ToontownGlobals.getSignFont()) y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) def enableResultMode(self): self.endPanel.enable() if len(self.race.circuitLoop) > 1: taskMgr.doMethodLater(180, self.endPanel.closeButtonPressed, 'clearRaceEndPanel', extraArgs=[]) def destroy(self): self.disable() if hasattr(self, 'wrongWaySeq'): self.wrongWaySeq.finish() self.wrongWaySeq = None taskMgr.removeTasksMatching('removeIt') taskMgr.removeTasksMatching('removeCam*') taskMgr.removeTasksMatching('clearRaceEndPanel') for obj in self.directObjList: obj.destroy() if hasattr(self, 'mapScene'): self.mapScene.removeNode() self.mapScene = None self.aspect2dRoot.removeNode() self.aspect2dRoot = None self.raceModeRoot.removeNode() self.raceModeRoot = None self.render2dRoot.removeNode() self.render2dRoot = None self.closeButton = None self.gag = None self.lapLabel = None self.timeLabels = None self.placeLabelStr = None self.placeLabelNum = None self.photoFinishLabel = None self.mapScene = None self.race = None return def setSpotAsymptotic(self, diffT, spot): p = (-1, 1)[diffT > 0] * (1 - 1 / pow(abs(diffT) / self.cutoff + 1, 2)) spot.setX(p) def setSpotRaceLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t / self.lapCount)) def setSpotLapLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t - int(t))) def update(self, time): placeSorter = [] placeCount = 0 for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[self.maxLapHit - 1]: y.configure(text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime() - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice['text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice['text'] = TTLocalizer.KartRace_LapText % str(self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str(clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str(self.race.lapCount) suffix = {1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix} placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[0] - localRacer.face.getX() < nearDiff: for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX() >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str(self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() elif not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish() def updateRacerInfo(self, avId, curvetime = None, maxlaphit = None): if avId in self.racerDict.keys(): self.racerDict[avId].update(curvetime=curvetime, maxlaphit=maxlaphit) def racerEntered(self, avId): toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.race.kartMap.get(avId, None), None) if not toon or not kart: return if kart.getBodyColor() == InvalidEntry: bodyColor = getDefaultColor() else: bodyColor = getAccessory(kart.getBodyColor()) headframe = RaceHeadFrame(av=toon, color=bodyColor) eyes = headframe.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) headframe.configure(geom_scale=(0.5, 0.5, 0.5)) headframe.setZ(self.faceStartPos[2]) headframe.setDepthWrite(True) headframe.setDepthTest(True) headframe.reparentTo(self.raceModeRoot) self.directObjList.append(headframe) mapspot = loader.loadModel('phase_6/models/karting/race_mapspot') mapspot.setColor(bodyColor) mapspot.reparentTo(self.mapLines) mapspot.setHpr(self.mapScene, 0, 0, 0) self.racerDict[avId] = self.RacerInfo(headframe, mapspot) for key, i in zip(self.racerDict.keys(), range(len(self.racerDict.keys()))): face = self.racerDict[key].face mapspot = self.racerDict[key].mapspot face.setX(self.faceStartPos[0]) face.setY(-1 - 5 * (i + 1)) face.setScale(0.15) mapspot.getChild(0).setY((-5 - 5 * (i + 1)) * 1000) mapspot.setScale(self.mapScene, 0.15) mapspot.setPos(self.race.startingPos[0][0]) if key == localAvatar.doId: face.setY(-1) face.setScale(face.getScale() * 1.25) mapspot.getChild(0).setY(-5 * 1000) mapspot.setScale(mapspot.getScale() * 1.25) self.face = face self.mapspot = mapspot return def racerLeft(self, avId, unexpected = False): racer = self.racerDict.get(avId, None) if racer: racer.disable() return def racerFinished(self, avId, trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): racer = self.racerDict.get(avId, None) if racer: racer.update(finished=True) racer.disable() self.endPanel.displayRacer(place, entryFee, qualify, winnings, trackId, bonus, trophies, racer.face, base.cr.doId2do[avId].getName(), totalTime, circuitPoints, circuitTime) if racer.face in self.directObjList: self.directObjList.remove(racer.face) if avId == localAvatar.doId: self.disableRaceMode() self.enableResultMode() self.endPanel.startWinningsPanel(entryFee, winnings, trackId, bonus, trophies) return def racerFinishedCircuit(self, avId, place, entryFee, winnings, bonus, trophies): racer = self.racerDict.get(avId, None) if racer: newTotalTickets = winnings + entryFee + bonus self.endPanel.updateWinnings(place, newTotalTickets) if avId == localAvatar.doId: self.endPanel.updateWinningsFromCircuit(place, entryFee, winnings, bonus, trophies) return def circuitFinished(self, placeFixup): self.endPanel.circuitFinished(placeFixup) def setTimerEnabled(self, enabled): self.timerEnabled = enabled
def enterWaiting(self): self.waitingLabel = DirectLabel() self.waitingLabel['text'] = TTLocalizer.WaitingForOtherToons self.waitingLabel.setScale(TTLocalizer.DRenterWaiting)
class MiniScoreItemGui(DirectFrame.DirectFrame): Width = PiratesGuiGlobals.PVPPanelWidth - PiratesGuiGlobals.GridSize Height = 0.055 def __init__(self, scoreValue, parent = None, world = None, itemColorScale = None, blink = False, **kw): optiondefs = (('state', DGG.NORMAL, None), ('frameColor', (0, 0, 0, 0.0), None), ('borderWidth', PiratesGuiGlobals.BorderWidth, None), ('frameSize', (0.0, MiniScoreItemGui.Width, 0.0, MiniScoreItemGui.Height), None)) self.defineoptions(kw, optiondefs) DirectFrame.DirectFrame.__init__(self, parent) self.initialiseoptions(MiniScoreItemGui) self.scoreValue = scoreValue self.world = world self.itemColorScale = itemColorScale self.blink = blink self.scaleSeq = None self._createIface() def destroy(self): self._destroyIface() DirectFrame.DirectFrame.destroy(self) del self.scoreValue self.ignoreAll() def _createIface(self): textFg = PiratesGuiGlobals.TextFG1 if self.world != None: scoreText = self.world.getScoreText(self.scoreValue) else: scoreText = '' self.descText = DirectLabel(parent = self, relief = None, text = scoreText, text_align = TextNode.ALeft, text_scale = PiratesGuiGlobals.TextScaleLarge, text_fg = textFg, text_shadow = PiratesGuiGlobals.TextShadow, textMayChange = 1, pos = (0.040000000000000001, 0, 0.014999999999999999)) if self.itemColorScale: self.colorLabel(self.itemColorScale) if self.blink: textPos = self.descText['text_pos'] textPosX = textPos[0] textPosY = textPos[1] self.scaleSeq = Parallel(Sequence(LerpFunctionInterval(self.descText.setScale, duration = 0.20000000000000001, toData = 1.05, fromData = 1.0, blendType = 'easeInOut'), LerpFunctionInterval(self.descText.setScale, duration = 0.69999999999999996, toData = 1.0, fromData = 1.05, blendType = 'easeInOut')), Sequence(Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 0, 0, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, (1, 1, 1, 1)), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.moveLabel, (textPosX, textPosY)), Wait(0.050000000000000003), Func(self.colorLabel, PiratesGuiGlobals.TextFG1), Func(self.moveLabel, (textPosX, textPosY)))) self.scaleSeq.start() def moveLabel(self, xy): randX = random.random() * 0.0050000000000000001 + 0.0050000000000000001 randY = random.random() * 0.0050000000000000001 + 0.0050000000000000001 self.descText['text_pos'] = (xy[0] + randX, xy[1] + randY) def colorLabel(self, color): self.descText['text_fg'] = color def shakeItUp(self, .2): (x, y, r, g, b, a) = .2 self.colorLabel((r, g, b, a)) randX = random.random() * 0.0050000000000000001 + 0.0050000000000000001 randY = random.random() * 0.0050000000000000001 + 0.0050000000000000001 self.moveLabel((x + randX, y + randY)) Wait(0.050000000000000003) randX = random.random() * 0.0050000000000000001 + 0.0050000000000000001 randY = random.random() * 0.0050000000000000001 + 0.0050000000000000001 self.moveLabel((x + randX, y + randY)) Wait(0.050000000000000003) def _destroyIface(self): if self.scaleSeq: self.scaleSeq.finish() self.scaleSeq = None self.descText.destroy() del self.descText
def enterTeleportIn(self, requestStatus): assert (self.notify.debug("enterTeleportIn()")) imgScale = 0.25 # see if someone else is already showing a dialog if self.dialog: x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId( self.loader.hood.id) # See if we're sad elif (base.localAvatar.hp < 1): requestStatus['nextState'] = 'popup' x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId( self.loader.hood.id) self.accept("deathAck", self.__handleDeathAck, extraArgs=[requestStatus]) self.deathAckBox = DeathForceAcknowledge.DeathForceAcknowledge( doneEvent="deathAck") # Check to see if the toon has a tier zero quest elif ((base.localAvatar.hp > 0) and ((Quests.avatarHasTrolleyQuest(base.localAvatar)) or (Quests.avatarHasFirstCogQuest(base.localAvatar)) or (Quests.avatarHasFriendQuest(base.localAvatar)) or ((Quests.avatarHasPhoneQuest(base.localAvatar)) and (Quests.avatarHasCompletedPhoneQuest(base.localAvatar)))) and (self.loader.hood.id == ToontownGlobals.ToontownCentral)): requestStatus['nextState'] = 'popup' imageModel = loader.loadModel("phase_4/models/gui/tfa_images") # trolley quest if (base.localAvatar.quests[0][0] == Quests.TROLLEY_QUEST_ID): if not Quests.avatarHasCompletedTrolleyQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralInitialDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage3 imgNodePath = imageModel.find("**/trolley-dialog-image") imgPos = (0, 0, 0.04) imgScale = 0.5 else: x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage4 imgNodePath = imageModel.find("**/hq-dialog-image") imgPos = (0, 0, -0.02) imgScale = 0.5 # first cog quest elif (base.localAvatar.quests[0][0] == Quests.FIRST_COG_QUEST_ID): if not Quests.avatarHasCompletedFirstCogQuest( base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralTunnelDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage5 imgNodePath = imageModel.find("**/tunnelSignA") imgPos = (0, 0, 0.04) imgScale = 0.5 else: x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage6 imgNodePath = imageModel.find("**/hq-dialog-image") imgPos = (0, 0, 0.05) imgScale = 0.5 # make a friend quest elif (base.localAvatar.quests[0][0] == Quests.FRIEND_QUEST_ID): if not Quests.avatarHasCompletedFriendQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralInitialDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage7 gui = loader.loadModel( "phase_3.5/models/gui/friendslist_gui") imgNodePath = gui.find("**/FriendsBox_Closed") imgPos = (0, 0, 0.04) imgScale = 1.0 gui.removeNode() else: x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage8 imgNodePath = imageModel.find("**/hq-dialog-image") imgPos = (0, 0, 0.05) imgScale = 0.5 # phone quest elif (base.localAvatar.quests[0][0] == Quests.PHONE_QUEST_ID): if Quests.avatarHasCompletedPhoneQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage9 imgNodePath = imageModel.find("**/hq-dialog-image") imgPos = (0, 0, 0.05) imgScale = 0.5 self.dialog = TTDialog.TTDialog(text=msg, command=self.__cleanupDialog, style=TTDialog.Acknowledge) imgLabel = DirectLabel.DirectLabel(parent=self.dialog, relief=None, pos=imgPos, scale=TTLocalizer.PimgLabel, image=imgNodePath, image_scale=imgScale) imageModel.removeNode() else: # ...this toon has completed their trolley quest. # Choose a random location within the safezone to drop you. # We do this even if we plan to be teleporting to a toon, # because the gotoToon option may fail if the toon has moved # on. requestStatus['nextState'] = 'walk' x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId( self.loader.hood.id) # toon may not be parented to hidden at this point, if say the boat or piano # on-floor event has detected an intersection (which seems to occur when Toon # who lost a connection in battle re-enters in melodyland). In that case, # it would be parented to the moving platform, and for that case the coords below # are wrong, so before doing a setPos, reparent to hidden. base.localAvatar.detachNode() base.localAvatar.setPosHpr(render, x, y, z, h, p, r) Place.Place.enterTeleportIn(self, requestStatus)
def update(self, time): placeSorter = [] placeCount = 0 # begin updates for all racers for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if (not racer.finished and racer.enabled): placeSorter.append((curvetime, key)) if (racer.finished or racer.enabled): placeCount += 1 pt = Vec3(0, 0, 0) mapT = ( (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1) * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint((mapT % self.race.curve.getMaxT()), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) # subtract out previous lap times t = time - self.race.baseTime - self.raceTimeDelta # begin updates for self only if (key == localAvatar.doId): if (self.race.laps > maxlaphit): racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if (self.maxLapHit < self.race.lapCount): for y in self.timeLabels[self.maxLapHit - 1]: y.configure( text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure( text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime( ) - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(.1) if (self.maxLapHit == self.race.lapCount - 1): lapNotice[ 'text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice[ 'text'] = TTLocalizer.KartRace_LapText % str( self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, "removeIt", extraArgs=[]) self.lapLabel['text'] = str( clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str( self.race.lapCount) suffix = { 1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix, } placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=(p + placeCount - len(placeSorter))) # if we are close to the finish line, and so is someone else, # declare a 'photo finish' localRacer = self.racerDict[localAvatar.doId] (nearDiff, farDiff) = RaceGlobals.TrackDict[self.race.trackId][8] if (not localRacer.finished) and ( self.faceEndPos[0] - localRacer.face.getX() < nearDiff): for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if (not racer.enabled or (racerId == localAvatar.doId) or (racer.face.getX() >= self.faceEndPos[0])): continue if (self.faceEndPos[0] - racer.face.getX()) < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = "" self.placeLabelStr['text'] = "" else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str( self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[ localAvatar.doId].place] # convert the time into a label displayable string minutes = int(t / 60) t -= minutes * 60 seconds = int(t) # quick python ternary operator padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if (self.timerEnabled and self.maxLapHit < self.race.lapCount): self.timeLabels[self.maxLapHit][0]['text'] = '%d\'' % (minutes) self.timeLabels[self.maxLapHit][1]['text'] = '%s%d\'\'' % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % (fraction) if (self.race.wrongWay and not self.wrongWaySeq.isPlaying()): self.wrongWaySeq.loop() elif (not self.race.wrongWay and self.wrongWaySeq.isPlaying()): self.wrongWaySeq.finish()
class RaceGUI: GagPie = 0 gagRoot = "phase_3.5/maps/inventory_" class RacerInfo: def __init__(self, face, mapSpot): self.curvetime = 0 self.maxlaphit = 0 self.face = face self.mapspot = mapSpot self.place = 1 self.enabled = True self.finished = False self.gag = None def update(self, curvetime=None, maxlaphit=None, faceX=None, mapspotPt=None, place=None, finished=None): if (self.enabled): if (not curvetime == None): self.curvetime = curvetime if (not maxlaphit == None): self.maxlaphit = maxlaphit if (not faceX == None): self.face.setX(faceX) if (not mapspotPt == None): self.mapspot.setPos(mapspotPt) if (not place == None): self.place = place if (not finished == None): self.finished = finished def disable(self): self.enabled = False if (not self.finished): self.face.hide() self.mapspot.hide() def enable(self): self.enabled = True self.face.show() self.mapspot.show() def __init__(self, distRace): self.race = distRace self.timerEnabled = False self.maxLapHit = 0 self.photoFinish = False toonInteriorTextures = loader.loadModel( 'phase_3.5/models/modules/toon_interior_textures') invTextures = loader.loadModel('phase_3.5/models/gui/inventory_icons') racingTextures = loader.loadModel( 'phase_6/models/karting/racing_textures') self.gagTextures = [ toonInteriorTextures.find('**/couch'), invTextures.find('**/inventory_bannana_peel'), racingTextures.find('**/boost_arrow'), invTextures.find('**/inventory_anvil'), invTextures.find('**/inventory_creampie'), ] self.gagTextures[1].setScale(7.5) self.gagTextures[3].setScale(7.5) self.gagTextures[4].setScale(7.5) self.cardMaker = CardMaker('card') #racer info self.racerDict = {} #setup render2d self.render2dRoot = render2d.attachNewNode('RaceGuiRender2dRoot') self.render2dRoot.setDepthWrite(1) #setup a list of directobjects self.directObjList = [] #setup aspect2d self.aspect2dRoot = aspect2d.attachNewNode('RaceGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) #setup raceModeRoot self.raceModeRoot = self.aspect2dRoot.attachNewNode('RaceModeRoot') #setup the 'leave race' button gui = loader.loadModel("phase_3.5/models/gui/avatar_panel_gui") self.closeButton = DirectButton( image=( gui.find("**/CloseBtn_UP"), gui.find("**/CloseBtn_DN"), gui.find("**/CloseBtn_Rllvr"), gui.find("**/CloseBtn_UP"), ), relief=None, scale=1.05, text=TTLocalizer.KartRace_Leave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(-0.99, 0, 0.925), command=self.race.leaveRace, ) self.closeButton.reparentTo(self.aspect2dRoot) self.directObjList.append(self.closeButton) #setup the race gui self.raceTimeDelta = 0 self.raceModeReady = False # self.initRaceMode() #setup the end result mode gui self.resultModeReady = False # self.initResultMode() # Load the sounds for cycling through and picking a gag. # Since the methods for gag cycling are all here, it makes sense # for the sounds to be here as well. self.gagCycleSound = base.loadSfx( "phase_3.5/audio/sfx/tick_counter.mp3") if hasattr(self.gagCycleSound, "setPlayRate"): self.gagCycleSound.setPlayRate(0.2) self.gagCycleSound.setLoop(1) self.gagAcquireSound = base.loadSfx( "phase_6/audio/sfx/SZ_MM_gliss.mp3") self.disable() def initRaceMode(self): ## #setup the 'map' display region ## self.mapScene = NodePath('MapScene') ## self.mapScene.setTransparency(1) ## self.mapSize = 0.15 ## self.mapX = 0.84 ## self.mapY = 0.84 ## self.mapCam = None ## if (base.win.getNumDisplayRegions()>4): ## for x in range(base.win.getNumDisplayRegions()-4): ## dr = base.win.getDisplayRegion(x+4) ## if (dr.getCamera().getName() == 'MapCam'): ## self.mapCam = dr.getCamera() ## break ## if(self.mapCam == None): ## self.mapCam = base.makeCamera(base.win,sort=30,displayRegion = (self.mapX,self.mapX+self.mapSize,self.mapY,self.mapY+self.mapSize),camName = 'MapCam') ## self.mapCam.setY(-10) ## self.mapCam.node().setLens(OrthographicLens()) ## self.mapCam.node().getLens().setFilmSize(2) ## self.mapCam.node().getLens().setAspectRatio(4.0/3.0) ## self.mapCam.reparentTo(self.mapScene) ## self.cardMaker.reset() ## self.cardMaker.setName('MapBackground') ## self.cardMaker.setFrame(-1,1,-1,1) ## self.cardMaker.setColor(1,1,1,0.25) ## card = self.mapScene.attachNewNode(self.cardMaker.generate()) #setup the 'map' display region self.mapScene = self.raceModeRoot.attachNewNode('MapScene') self.mapScene.setPos(1.1, 0, 0.75) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if (x == 0): ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) #setup face info self.faceStartPos = Vec3(-0.80, 0, 0.93) self.faceEndPos = Vec3(0.80, 0, 0.93) #setup place(1st,2nd,...) reporting self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.placeLabelNum.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.placeLabelStr.reparentTo(self.raceModeRoot) self.directObjList.append(self.placeLabelStr) #setup lap reporting self.lapLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.45), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.lapLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.lapLabel) #setup photo finish label self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) #setup wrong way reporting self.wrongWayLabel = DirectLabel( relief=None, pos=(1.1, 0, 0.85), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont(), ) self.wrongWayLabel.reparentTo(self.raceModeRoot) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1)), ) #setup time reporting interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * (x) self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text='0\'', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text='00\'\'', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight, ) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) #setup gag indicator self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=self.raceModeRoot, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(-1.13, 0, -0.5), ) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() #setup face line self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() def initResultMode(self): self.endPanel = RaceEndPanel(len(self.race.avIds), self.race) self.endPanel.reparentTo(self.aspect2dRoot) self.directObjList.append(self.endPanel) self.resultModeReady = True self.disable() def showGag(self, gagIndex): if gagIndex < len(self.gagTextures): for gag in self.gagTextures: gag.hide() self.gagTextures[gagIndex].show() def updateGag(self, gagIndex): if (self.gag): # Make sure the gag cycle interval is cleaned up. # Do this before setting the final gag texture. if hasattr(self, "gagCycleInterval"): self.gagCycleInterval.finish() del self.gagCycleInterval #self.gagCycleSound.stop() self.gag.setHpr(0, 0, 0) # Set the actual gag texture. self.showGag(gagIndex) if gagIndex == 0: self.gag.hide() else: self.gag.show() self.gagAcquireSound.play() self.gagAcquireInterval = LerpHprInterval(self.gag, duration=0.5, blendType="easeOut", startHpr=Point3( 0, -90, 0), hpr=Point3(0, 0, 0)) self.gagAcquireInterval.start() def waitingOnGag(self, cycleTime): if (self.gag): numTextures = len(self.gagTextures) startOffset = random.choice(range(0, numTextures)) self.gag.show() self.gagCycleInterval = Parallel( LerpFunc(self.showNextGag, fromData=startOffset, toData=numTextures * 2 * cycleTime + startOffset, blendType="easeOut", duration=cycleTime), LerpHprInterval(self.gag, duration=cycleTime, hpr=Point3( 0, 180 * numTextures * 2 * cycleTime - 90, 0), blendType="easeOut", startHpr=Point3(0, 0, 0)), SoundInterval(self.gagCycleSound, loop=1, duration=cycleTime, startTime=0), name="gagCycleInterval") self.gagCycleInterval.start() def showNextGag(self, t): if (self.gag): # We don't want to show the texture at index 0. currGagIndex = int(t % (len(self.gagTextures) - 1)) + 1 self.showGag(currGagIndex) def enableSpeedometer(self): self.race.localKart.showSpeedometer() def disableSpeedometer(self): self.race.localKart.hideSpeedometer() def disableRaceMode(self): self.disableSpeedometer() ## self.mapCam.node().getDisplayRegion(0).setActive(False) self.render2dRoot.hide() self.raceModeRoot.hide() for x in self.timeLabels: for y in x: y.hide() self.setTimerEnabled(False) def disableResultMode(self): self.endPanel.disable() def disable(self): self.closeButton.hide() taskMgr.removeTasksMatching("clearRaceEndPanel") if self.raceModeReady: self.disableRaceMode() if self.resultModeReady: self.disableResultMode() def enableRaceMode(self): self.enableSpeedometer() ## self.closeButton.show() ## self.mapCam.node().getDisplayRegion(0).setActive(True) self.render2dRoot.show() self.raceModeRoot.show() self.maxLapHit = min(self.maxLapHit, self.race.lapCount - 1) for x in range(self.maxLapHit + 1): for y in self.timeLabels[x]: y.configure(text_font=ToontownGlobals.getSignFont()) y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) def enableResultMode(self): self.endPanel.enable() # make this panel eventually go away eventually if this is the last race if not self.race.circuitLoop: taskMgr.doMethodLater(180, self.endPanel.closeButtonPressed, "clearRaceEndPanel", extraArgs=[]) def destroy(self): self.disable() if hasattr(self, "wrongWaySeq"): self.wrongWaySeq.finish() self.wrongWaySeq = None taskMgr.removeTasksMatching('removeIt') taskMgr.removeTasksMatching('removeCam*') taskMgr.removeTasksMatching("clearRaceEndPanel") for obj in self.directObjList: obj.destroy() if hasattr(self, "mapScene"): self.mapScene.removeNode() self.mapScene = None self.aspect2dRoot.removeNode() self.aspect2dRoot = None self.raceModeRoot.removeNode() self.raceModeRoot = None self.render2dRoot.removeNode() self.render2dRoot = None self.closeButton = None self.gag = None self.lapLabel = None self.timeLabels = None self.placeLabelStr = None self.placeLabelNum = None self.photoFinishLabel = None self.mapScene = None self.race = None def setSpotAsymptotic(self, diffT, spot): p = (-1, 1)[diffT > 0] * (1 - 1 / pow(abs(diffT) / self.cutoff + 1, 2)) spot.setX(p) def setSpotRaceLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t / self.lapCount)) def setSpotLapLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t - int(t))) def update(self, time): placeSorter = [] placeCount = 0 # begin updates for all racers for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if (not racer.finished and racer.enabled): placeSorter.append((curvetime, key)) if (racer.finished or racer.enabled): placeCount += 1 pt = Vec3(0, 0, 0) mapT = ( (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1) * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint((mapT % self.race.curve.getMaxT()), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) # subtract out previous lap times t = time - self.race.baseTime - self.raceTimeDelta # begin updates for self only if (key == localAvatar.doId): if (self.race.laps > maxlaphit): racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if (self.maxLapHit < self.race.lapCount): for y in self.timeLabels[self.maxLapHit - 1]: y.configure( text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure( text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime( ) - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(.1) if (self.maxLapHit == self.race.lapCount - 1): lapNotice[ 'text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice[ 'text'] = TTLocalizer.KartRace_LapText % str( self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, "removeIt", extraArgs=[]) self.lapLabel['text'] = str( clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str( self.race.lapCount) suffix = { 1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix, } placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=(p + placeCount - len(placeSorter))) # if we are close to the finish line, and so is someone else, # declare a 'photo finish' localRacer = self.racerDict[localAvatar.doId] (nearDiff, farDiff) = RaceGlobals.TrackDict[self.race.trackId][8] if (not localRacer.finished) and ( self.faceEndPos[0] - localRacer.face.getX() < nearDiff): for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if (not racer.enabled or (racerId == localAvatar.doId) or (racer.face.getX() >= self.faceEndPos[0])): continue if (self.faceEndPos[0] - racer.face.getX()) < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = "" self.placeLabelStr['text'] = "" else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str( self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[ localAvatar.doId].place] # convert the time into a label displayable string minutes = int(t / 60) t -= minutes * 60 seconds = int(t) # quick python ternary operator padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if (self.timerEnabled and self.maxLapHit < self.race.lapCount): self.timeLabels[self.maxLapHit][0]['text'] = '%d\'' % (minutes) self.timeLabels[self.maxLapHit][1]['text'] = '%s%d\'\'' % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % (fraction) if (self.race.wrongWay and not self.wrongWaySeq.isPlaying()): self.wrongWaySeq.loop() elif (not self.race.wrongWay and self.wrongWaySeq.isPlaying()): self.wrongWaySeq.finish() def updateRacerInfo(self, avId, curvetime=None, maxlaphit=None): if (avId in self.racerDict.keys()): self.racerDict[avId].update(curvetime=curvetime, maxlaphit=maxlaphit) ##################################################### # Begin populating the gui elements with racer data # ##################################################### def racerEntered(self, avId): toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.race.kartMap.get(avId, None), None) if (not toon or not kart): return if (kart.getBodyColor() == InvalidEntry): bodyColor = getDefaultColor() else: bodyColor = getAccessory(kart.getBodyColor()) ######################################################### # When offscreen buffers are supported, this works... # ######################################################### ## # setup temporary portrait scene graph ## buf = base.graphicsEngine.makeBuffer(base.win.getGsg(),'test',0,128,128) ## par = buf.makeTextureBuffer('par',128,128) ## parcam = base.makeCamera(par,0,'parCam') ## parcam.node().setLens(OrthographicLens()) ## parcam.node().getLens().setFilmSize(0.5,0.5) ## portraitSceneGraph = NodePath('Portrait:%d'%avId) ## parcam.reparentTo(portraitSceneGraph) ## tex = par.getTexture() ## headframe = RaceHeadFrame(toon,bodyColor) ## headframe.configure(geom_scale=(0.5,0.5,0.5)) ## headframe.setY(10) ## headframe.reparentTo(portraitSceneGraph) ## # take picture and initialize cleanup ## buf.setOneShot(True) ## def cleanUpPortrait(task,s = portraitSceneGraph,f = headframe): ## f.destroy() ## s.removeNode() ## # if using this doMethodLater, be sure to remove it from the taskMgr ## # ## taskMgr.doMethodLater(1,cleanUpPortrait,'removeCam:%d'%avId) ## #setup face ## self.cardMaker.reset() ## self.cardMaker.setName('Face:%d'%avId) ## self.cardMaker.setFrame(-0.5,0.5,-0.5,0.5) ## face = NodePath(self.cardMaker.generate()) ## face.setTexture(tex,1) ## face.setZ(self.faceStartPos[2]) ## face.reparentTo(self.raceModeRoot) headframe = RaceHeadFrame(av=toon, color=bodyColor) eyes = headframe.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) headframe.configure(geom_scale=(0.5, 0.5, 0.5)) headframe.setZ(self.faceStartPos[2]) headframe.setDepthWrite(True) headframe.setDepthTest(True) headframe.reparentTo(self.raceModeRoot) self.directObjList.append(headframe) #setup map place mapspot = loader.loadModel('phase_6/models/karting/race_mapspot') mapspot.setColor(bodyColor) mapspot.reparentTo(self.mapLines) mapspot.setHpr(self.mapScene, 0, 0, 0) self.racerDict[avId] = self.RacerInfo(headframe, mapspot) for key, i in zip(self.racerDict.keys(), range(len(self.racerDict.keys()))): face = self.racerDict[key].face mapspot = self.racerDict[key].mapspot face.setX(self.faceStartPos[0]) face.setY(-1 - 5 * (i + 1)) face.setScale(0.15) mapspot.getChild(0).setY((-5 - 5 * (i + 1)) * 1000) mapspot.setScale(self.mapScene, 0.15) mapspot.setPos(self.race.startingPos[0][0]) if (key == localAvatar.doId): face.setY(-1) face.setScale(face.getScale() * 1.25) mapspot.getChild(0).setY((-5) * 1000) mapspot.setScale(mapspot.getScale() * 1.25) self.face = face self.mapspot = mapspot def racerLeft(self, avId, unexpected=False): racer = self.racerDict.get(avId, None) if (racer): racer.disable() def racerFinished(self, avId, trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): racer = self.racerDict.get(avId, None) if (racer): racer.update(finished=True) racer.disable() self.endPanel.displayRacer(place, entryFee, qualify, winnings, trackId, bonus, trophies, racer.face, base.cr.doId2do[avId].getName(), totalTime, circuitPoints, circuitTime) self.directObjList.remove(racer.face) if (avId == localAvatar.doId): self.disableRaceMode() self.enableResultMode() self.endPanel.startWinningsPanel(entryFee, winnings, trackId, bonus, trophies) def racerFinishedCircuit(self, avId, place, entryFee, winnings, bonus, trophies): #print("racerFinishedCircuit") racer = self.racerDict.get(avId, None) if (racer): newTotalTickets = winnings + entryFee + bonus self.endPanel.updateWinnings(place, newTotalTickets) if (avId == localAvatar.doId): self.endPanel.updateWinningsFromCircuit( place, entryFee, winnings, bonus, trophies) pass # self.disableRaceMode() # self.enableResultMode() # self.endPanel.startWinningsPanel(entryFee,winnings,trackId,bonus,trophies) def circuitFinished(self, placeFixup): #print "circuit finished" self.endPanel.circuitFinished(placeFixup) def setTimerEnabled(self, enabled): self.timerEnabled = enabled
def update(self, time): placeSorter = [] placeCount = 0 for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[self.maxLapHit - 1]: y.configure( text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure( text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime( ) - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice[ 'text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice[ 'text'] = TTLocalizer.KartRace_LapText % str( self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str( clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str( self.race.lapCount) suffix = { 1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix } placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[ 0] - localRacer.face.getX() < nearDiff: for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX( ) >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str( self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[ localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() elif not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish()
def enterTeleportIn(self, requestStatus): imgScale = 0.25 if self.dialog: x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId( self.loader.hood.id) elif base.localAvatar.hp < 1: requestStatus['nextState'] = 'popup' x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId( self.loader.hood.id) self.accept('deathAck', self.__handleDeathAck, extraArgs=[requestStatus]) self.deathAckBox = DeathForceAcknowledge.DeathForceAcknowledge( doneEvent='deathAck') elif base.localAvatar.hp > 0 and ( Quests.avatarHasTrolleyQuest(base.localAvatar) or Quests.avatarHasFirstCogQuest(base.localAvatar) or Quests.avatarHasFriendQuest(base.localAvatar) or Quests.avatarHasPhoneQuest(base.localAvatar) and Quests.avatarHasCompletedPhoneQuest(base.localAvatar) ) and self.loader.hood.id == ToontownGlobals.ToontownCentral: requestStatus['nextState'] = 'popup' imageModel = loader.loadModel('phase_4/models/gui/tfa_images') if base.localAvatar.quests[0][0] == Quests.TROLLEY_QUEST_ID: if not Quests.avatarHasCompletedTrolleyQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralInitialDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage3 imgNodePath = imageModel.find('**/trolley-dialog-image') imgPos = (0, 0, 0.04) imgScale = 0.5 else: x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage4 imgNodePath = imageModel.find('**/hq-dialog-image') imgPos = (0, 0, -0.02) imgScale = 0.5 elif base.localAvatar.quests[0][0] == Quests.FIRST_COG_QUEST_ID: if not Quests.avatarHasCompletedFirstCogQuest( base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralTunnelDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage5 imgNodePath = imageModel.find('**/tunnelSignA') imgPos = (0, 0, 0.04) imgScale = 0.5 else: x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage6 imgNodePath = imageModel.find('**/hq-dialog-image') imgPos = (0, 0, 0.05) imgScale = 0.5 elif base.localAvatar.quests[0][0] == Quests.FRIEND_QUEST_ID: if not Quests.avatarHasCompletedFriendQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralInitialDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage7 gui = loader.loadModel( 'phase_3.5/models/gui/friendslist_gui') imgNodePath = gui.find('**/FriendsBox_Closed') imgPos = (0, 0, 0.04) imgScale = 1.0 gui.removeNode() else: x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage8 imgNodePath = imageModel.find('**/hq-dialog-image') imgPos = (0, 0, 0.05) imgScale = 0.5 elif base.localAvatar.quests[0][0] == Quests.PHONE_QUEST_ID: if Quests.avatarHasCompletedPhoneQuest(base.localAvatar): x, y, z, h, p, r = base.cr.hoodMgr.getDropPoint( base.cr.hoodMgr.ToontownCentralHQDropPoints) msg = TTLocalizer.NPCForceAcknowledgeMessage9 imgNodePath = imageModel.find('**/hq-dialog-image') imgPos = (0, 0, 0.05) imgScale = 0.5 self.dialog = TTDialog.TTDialog(text=msg, command=self.__cleanupDialog, style=TTDialog.Acknowledge) imgLabel = DirectLabel.DirectLabel(parent=self.dialog, relief=None, pos=imgPos, scale=TTLocalizer.PimgLabel, image=imgNodePath, image_scale=imgScale) imageModel.removeNode() else: requestStatus['nextState'] = 'walk' x, y, z, h, p, r = base.cr.hoodMgr.getPlaygroundCenterFromId( self.loader.hood.id) base.localAvatar.detachNode() base.localAvatar.setPosHpr(render, x, y, z, h, p, r) Place.Place.enterTeleportIn(self, requestStatus) return
def enterWaiting(self): self.waitingLabel = DirectLabel() self.waitingLabel["text"] = TTLocalizer.WaitingForOtherToons self.waitingLabel.setScale(TTLocalizer.DRenterWaiting)
def initRaceMode(self): self.mapScene = base.a2dTopRight.attachNewNode('MapScene') self.mapScene.setPos(-0.2, 0, -0.2) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in xrange(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.5), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel(relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.2), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence(self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * (1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in xrange(self.race.lapCount): minLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame(parent=base.a2dBottomLeft, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(0.2, 0, 0.55)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in xrange(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos(self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return
class DistributedRace(DistributedObject.DistributedObject): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedRace') ReadyPost = 'RaceReady' WinEvent = 'RaceWinEvent' BGM_BaseDir = 'phase_6/audio/bgm/' SFX_BaseDir = 'phase_6/audio/sfx/' SFX_StartBoop = SFX_BaseDir + 'KART_raceStart1.ogg' SFX_StartBoop2 = SFX_BaseDir + 'KART_raceStart2.ogg' SFX_Applause = SFX_BaseDir + 'KART_Applause_%d.ogg' def __init__(self, cr): self.qbox = loader.loadModel('phase_6/models/karting/qbox') self.boostArrowTexture = loader.loadTexture('phase_6/maps/boost_arrow.jpg', 'phase_6/maps/boost_arrow_a.rgb') self.boostArrowTexture.setMinfilter(Texture.FTLinear) DistributedObject.DistributedObject.__init__(self, cr) self.kartMap = {} self.fsm = ClassicFSM.ClassicFSM('Race', [State.State('join', self.enterJoin, self.exitJoin, ['prep', 'leave']), State.State('prep', self.enterPrep, self.exitPrep, ['tutorial', 'leave']), State.State('tutorial', self.enterTutorial, self.exitTutorial, ['start', 'waiting', 'leave']), State.State('waiting', self.enterWaiting, self.exitWaiting, ['start', 'leave']), State.State('start', self.enterStart, self.exitStart, ['racing', 'leave']), State.State('racing', self.enterRacing, self.exitRacing, ['finished', 'leave']), State.State('finished', self.enterFinished, self.exitFinished, ['leave']), State.State('leave', self.enterLeave, self.exitLeave, [])], 'join', 'leave') self.gui = RaceGUI(self) base.race = self self.currT = 0 self.currLapT = 0 self.currGag = 0 self.tdelay = 0 self.finished = False self.thrownGags = [] self.effectManager = EffectManager.EffectManager() self.piejectileManager = PiejectileManager.PiejectileManager() self.lastTimeUpdate = globalClock.getFrameTime() self.initGags() self.canShoot = True self.isUrbanTrack = False self.hasFog = False self.dummyNode = None self.fog = None self.bananaSound = base.loadSfx('phase_6/audio/sfx/KART_tossBanana.ogg') self.anvilFall = base.loadSfx('phase_6/audio/sfx/KART_Gag_Hit_Anvil.ogg') self.accept('leaveRace', self.leaveRace) self.toonsToLink = [] self.curveTs = [] self.curvePoints = [] self.localKart = None self.musicTrack = None self.victory = None self.miscTaskNames = [] self.boostDir = {} self.knownPlace = {} self.placeFixup = [] self.curve = None self.barricadeSegments = 100.0 self.outerBarricadeDict = {} self.innerBarricadeDict = {} self.maxLap = 0 self.oldT = 0 self.debugIt = 0 self.startPos = None return def generate(self): self.notify.debug('generate: %s' % self.doId) DistributedObject.DistributedObject.generate(self) bboard.post('race', self) self.roomWatcher = None self.cutoff = 0.01 self.startBoopSfx = base.loadSfx(self.SFX_StartBoop) self.startBoop2Sfx = base.loadSfx(self.SFX_StartBoop2) return def announceGenerate(self): self.notify.debug('announceGenerate: %s' % self.doId) DistributedObject.DistributedObject.announceGenerate(self) musicFile = self.BGM_BaseDir + RaceGlobals.TrackDict[self.trackId][7] self.raceMusic = base.loadMusic(musicFile) base.playMusic(self.raceMusic, looping=1, volume=0.8) base.camera.reparentTo(render) if self.trackId in (RaceGlobals.RT_Urban_1, RaceGlobals.RT_Urban_1_rev, RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.isUrbanTrack = True self.oldFarPlane = base.camLens.getFar() base.camLens.setFar(12000) localAvatar.startPosHprBroadcast() localAvatar.d_broadcastPositionNow() DistributedSmoothNode.activateSmoothing(1, 1) self.reversed = self.trackId / 2.0 > int(self.trackId / 2.0) for i in xrange(3): base.loader.tick() self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') self.sky.setPos(0, 0, 0) self.sky.setScale(20.0) self.sky.setFogOff() if self.trackId in (RaceGlobals.RT_Urban_1, RaceGlobals.RT_Urban_1_rev, RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.loadFog() self.setupGeom() self.startSky() for i in xrange(5): base.loader.tick() def disable(self): self.notify.debug('disable %s' % self.doId) if self.musicTrack: self.musicTrack.finish() self.raceMusic.stop() self.stopSky() if self.sky is not None: self.sky.removeNode() if self.dummyNode: self.dummyNode.removeNode() self.dummyNode = None for taskName in self.miscTaskNames: taskMgr.remove(taskName) taskMgr.remove('raceWatcher') self.ignoreAll() DistributedSmoothNode.activateSmoothing(1, 0) if self.isUrbanTrack: self.unloadUrbanTrack() if self.fog: render.setFogOff() del self.fog self.fog = None if self.geom is not None: self.geom.hide() base.camLens.setFar(self.oldFarPlane) DistributedObject.DistributedObject.disable(self) return def delete(self): self.notify.debug('delete %s' % self.doId) if self.gui: self.gui.destroy() self.gui = None if self.geom is not None: self.geom.removeNode() self.geom = None for i in self.gags: i.delete() del i self.piejectileManager.delete() if self.curveTs: del self.curveTs if self.curvePoints: del self.curvePoints if self.curve: del self.curve if self.victory: del self.victory del self.fsm del self.anvilFall del self.bananaSound del self.localKart DistributedObject.DistributedObject.delete(self) taskMgr.remove(self.uniqueName('countdownTimerTask')) taskMgr.remove('raceWatcher') bboard.remove('race') self.ignoreAll() del base.race return def d_requestThrow(self, x, y, z): self.sendUpdate('requestThrow', [x, y, z]) def d_requestKart(self): self.sendUpdate('requestKart', []) def waitingForJoin(self): self.notify.debug('I got the barrier') self.fsm.enterInitialState() def racerDisconnected(self, avId): self.notify.debug('lost racer: %s' % avId) if avId in self.kartMap: if avId in self.toonsToLink: self.toonsToLink.remove(avId) toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) self.avIds.remove(avId) del self.kartMap[avId] self.gui.racerLeft(avId, unexpected=True) if kart: kart.reparentTo(hidden) if toon: toon.reparentTo(hidden) if len(self.toonsToLink) == 0: self.doneBarrier('waitingForPrep') return def setPlace(self, avId, totalTime, place, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): if self.fsm.getCurrentState().getName() == 'leaving': return if avId == localAvatar.doId: cheerToPlay = place + (4 - self.numRacers) if cheerToPlay > 4: cheerToPlay = 4 self.victory = base.loadSfx(self.SFX_Applause % cheerToPlay) self.victory.play() self.knownPlace[avId] = place kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) avatar = base.cr.doId2do.get(avId, None) if avatar: self.gui.racerFinished(avId, self.trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime) taskName = 'hideAv: %s' % avId taskMgr.doMethodLater(6, avatar.reparentTo, taskName, extraArgs=[hidden]) self.miscTaskNames.append(taskName) if kart: taskName = 'hideKart: %s' % self.localKart.doId taskMgr.doMethodLater(6, kart.reparentTo, taskName, extraArgs=[hidden]) self.miscTaskNames.append(taskName) return def setCircuitPlace(self, avId, place, entryFee, winnings, bonus, trophies): print 'setting cicruit place' if self.fsm.getCurrentState().getName() == 'leaving': return if avId == localAvatar.doId: cheerToPlay = place + (4 - self.numRacers) self.victory = base.loadSfx(self.SFX_Applause % cheerToPlay) self.victory.play() oldPlace = 0 if self.knownPlace.get(avId): oldPlace = self.knownPlace[avId] self.placeFixup.append([oldPlace - 1, place - 1]) avatar = base.cr.doId2do.get(avId, None) if avatar: print 'circuit trophies %s' % trophies print 'winnings %s' % winnings self.gui.racerFinishedCircuit(avId, oldPlace, entryFee, winnings, bonus, trophies) return def endCircuitRace(self): print self.placeFixup self.gui.circuitFinished(self.placeFixup) def prepForRace(self): self.fsm.request('prep') def startRace(self, startTime = 0): self.baseTime = globalClockDelta.networkToLocalTime(startTime) self.fsm.request('start') def startTutorial(self): self.fsm.request('tutorial') def genGag(self, slot, number, type): self.notify.debug('making gag...') if not self.gags[slot].isActive(): self.gags[slot].genGag(number, type) def dropAnvilOn(self, ownerId, avId, timeStamp): kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) if kart: if avId != ownerId: if avId == localAvatar.doId: self.anvilFall.play() kart.dropOnMe(timeStamp) else: kart.dropOnHim(timeStamp) return def shootPiejectile(self, sourceId, targetId, type = 0): kart = base.cr.doId2do.get(self.kartMap.get(sourceId, None), None) if kart: self.piejectileManager.addPiejectile(sourceId, targetId, type) return def goToSpeedway(self, avIds, reason = RaceGlobals.Exit_UserReq): self.notify.debug('goToSpeedway %s %s' % (avIds, reason)) if localAvatar.doId in avIds: base.loader.endBulkLoad('atRace') self.kartCleanup() self.doneBarrier('waitingForExit') self.sendUpdate('racerLeft', [localAvatar.doId]) out = {'loader': 'safeZoneLoader', 'where': 'playground', 'how': 'teleportIn', 'hoodId': localAvatar.lastHood, 'zoneId': localAvatar.lastHood, 'shardId': None, 'avId': -1, 'reason': reason} base.cr.playGame.fsm.request('quietZone', [out]) return def kartCleanup(self): kart = self.localKart if kart: kart.setState('P', 0) for i in self.avIds: if i != localAvatar.doId: toon = base.cr.doId2do.get(i, None) if toon: toon.stopSmooth() toon.setScale(1) toon.setShear(0, 0, 0) toon.reparentTo(render) kart.doHeadScale(toon, None) localAvatar.setPos(0, 14, 0) localAvatar.sendCurrentPosition() return def heresMyT(self, avId, avNumLaps, avTime, timestamp): self.gui.updateRacerInfo(avId, curvetime=avNumLaps + avTime) def setZoneId(self, zoneId): self.zoneId = zoneId def setRaceType(self, raceType): self.raceType = raceType def setCircuitLoop(self, circuitLoop): self.circuitLoop = circuitLoop def setTrackId(self, id): DistributedRace.notify.debug('setTrackId: %s' % id) self.trackId = id def setAvatars(self, avIds): ids = '' for i in avIds: ids += str(i) + ' ' DistributedRace.notify.debug('setAvatars: %s' % ids) self.avIds = avIds self.avT = [0] * len(self.avIds) def setLapCount(self, lapCount): self.lapCount = lapCount def setStartingPlaces(self, startList): self.startingPlaces = startList def enterJoin(self): self.doneBarrier('waitingForJoin') self.notify.debug('entering Join') def exitJoin(self): pass def setEnteredRacers(self, avAndKarts): self.notify.debug('setEnteredRacers %s' % avAndKarts) avatarsGone = [] avatarsLeft = [] self.numRacers = len(avAndKarts) for i in avAndKarts: if i[0] in self.avIds: self.kartMap[i[0]] = i[1] avatarsLeft.append(i[0]) for i in self.avIds: if i not in avatarsLeft: avatarsGone.append(i) base.loader.tick() for i in avatarsGone: self.avIds.remove(i) self.toonsToLink = list(self.avIds) for i in avAndKarts: self.cr.relatedObjectMgr.requestObjects(i, allCallback=self.__gotKartAvatarLink) def __gotKartAvatarLink(self, avAndKart): self.notify.debug('got a Link') toon = avAndKart[0] kart = avAndKart[1] base.loader.tick() if toon.doId in self.toonsToLink: self.toonsToLink.remove(toon.doId) if toon.doId == localAvatar.doId: self.localKart = kart if len(self.toonsToLink) == 0: self.doneBarrier('waitingForPrep') def enterPrep(self): self.d_requestKart() self.notify.debug('entering Prep State') if self.reversed: self.spin = Vec3(180, 0, 0) else: self.spin = Vec3(0, 0, 0) for i in xrange(4): base.loader.tick() self.gui.initRaceMode() self.gui.initResultMode() self.myPos = self.startingPos[self.startingPlaces[self.avIds.index(localAvatar.doId)]] self.localKart.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) self.localKart.setupLapCollisions() if self.dummyNode: self.dummyNode.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) self.currentPole = self.findSegmentStart() self.rabbitPoint = Vec3(0, 0, 0) self.doneBarrier('waitingForReady') def exitPrep(self): pass def enterTutorial(self): self.notify.debug('entering Tutorial State') base.loader.endBulkLoad('atRace') self.localKart.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) base.transitions.irisIn() self.rulesDoneEvent = 'finishedRules' self.accept(self.rulesDoneEvent, self.handleRulesDone) self.rulesPanel = MinigameRulesPanel.MinigameRulesPanel('RacingRulesPanel', self.getTitle(), self.getInstructions(), self.rulesDoneEvent, 10) self.rulesPanel.load() self.rulesPanel.frame.setPos(0, 0, -0.6667) self.rulesPanel.enter() def exitTutorial(self): self.ignore(self.rulesDoneEvent) self.rulesPanel.exit() self.rulesPanel.unload() del self.rulesPanel def getTitle(self): return TTLocalizer.KartRace_TitleInfo def getInstructions(self): return TTLocalizer.KartRace_TrackInfo[self.trackId] def handleRulesDone(self): self.doneBarrier('readRules') self.fsm.request('waiting') def enterWaiting(self): self.waitingLabel = DirectLabel() self.waitingLabel['text'] = TTLocalizer.BuildingWaitingForVictors self.waitingLabel.setScale(TTLocalizer.DRenterWaiting) def exitWaiting(self): self.waitingLabel.removeNode() def enterStart(self): waitTime = self.baseTime - globalClock.getFrameTime() taskName = 'enableRaceModeLater' taskMgr.doMethodLater(1, self.gui.enableRaceMode, taskName, extraArgs=[]) self.miscTaskNames.append(taskName) for i in self.avIds: self.gui.racerEntered(i) self.startCountdownClock(waitTime, 0) taskMgr.doMethodLater(waitTime, self.fsm.request, 'goToRacing', extraArgs=['racing']) def exitStart(self): pass def enterRacing(self): self.localKart.setInput(1) self.gui.setTimerEnabled(True) self.raceTask = taskMgr.add(self.raceWatcher, 'raceWatcher') def exitRacing(self): pass def raceWatcher(self, task): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) if self.localKart.amIClampingPosition(): self.notify.debug('teleporting kart %d back to main track' % localAvatar.doId) self.localKart.setPos(self.curvePoints[self.currentPole]) kartPoint = self.localKart.getPos() direction = 0 while True: currPoint = self.curvePoints[self.currentPole] nextPole = (self.currentPole + 1) % len(self.curvePoints) nextPoint = self.curvePoints[nextPole] segment = nextPoint - currPoint segment.setZ(0) segLength2 = segment.lengthSquared() kartVector = kartPoint - currPoint kartVector.setZ(0) project = segment * (segment.dot(kartVector) / segLength2) projLength2 = project.lengthSquared() if project.dot(segment) < 0: if direction == 1: break prevPole = (self.currentPole - 1) % len(self.curvePoints) self.currentPole = prevPole direction = -1 elif projLength2 > segLength2: if direction == -1: break self.currentPole = nextPole direction = 1 else: break if self.dummyNode: self.dummyNode.setPos(kartPoint[0], kartPoint[1], 0) self.dummyNode.setHpr(self.localKart.getH(), 0, 0) t = projLength2 / segLength2 if self.debugIt: self.notify.debug('self.debugIt = %d' % self.debugIt) import pdb pdb.set_trace() if nextPole < self.currentPole: newT = self.curveTs[self.currentPole] * (1 - t) + self.curve.getMaxT() * t else: newT = self.curveTs[self.currentPole] * (1 - t) + self.curveTs[nextPole] * t kartDirection = self.localKart.forward.getPos(render) - self.localKart.getPos(render) kartDirection.normalize() project.normalize() globalDirection = kartDirection.dot(project) if globalDirection < 0: self.wrongWay = True elif globalDirection > 0.1: self.wrongWay = False newLapT = (newT - self.startT) / self.curve.getMaxT() % 1.0 if newLapT - self.currLapT < -0.5: self.laps += 1 self.changeMusicTempo(1 + self.laps * 0.5) self.notify.debug('crossed the start line: %s, %s, %s, %s' % (self.laps, self.startT, self.currT, newT)) elif newLapT - self.currLapT > 0.5: self.laps -= 1 self.changeMusicTempo(1 + self.laps * 0.5) self.notify.debug('crossed the start line - wrong way: %s, %s, %s, %s' % (self.laps, self.startT, self.currT, newT)) self.currT = newT self.currLapT = newLapT if self.isUrbanTrack: self.showBuildings(self.currT) now = globalClock.getFrameTime() timestamp = globalClockDelta.localToNetworkTime(now) if self.laps == self.lapCount: self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) self.fsm.request('finished') if self.laps > self.maxLap: self.maxLap = self.laps self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) if now - self.lastTimeUpdate > 0.5: self.lastTimeUpdate = now self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) self.gui.updateRacerInfo(localAvatar.doId, curvetime=self.currLapT + self.laps) self.gui.update(now) return Task.cont def enterFinished(self): taskMgr.remove('raceWatcher') self.fadeOutMusic() self.localKart.interruptTurbo() self.localKart.disableControls() taskName = 'parkIt' taskMgr.doMethodLater(2, self.stopDriving, taskName, extraArgs=[]) self.miscTaskNames.append(taskName) self.finished = True base.camera.reparentTo(render) base.camera.setPos(self.localKart.getPos(render) + Vec3(0, 0, 10)) base.camera.setH(self.localKart.getH(render) + 180) self.gui.disableRaceMode() self.gui.enableResultMode() localAvatar.reparentTo(hidden) self.localKart.reparentTo(hidden) def exitFinished(self): pass def stopDriving(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) cpos = base.camera.getPos() chpr = base.camera.getHpr() localAvatar.reparentTo(hidden) self.localKart.reparentTo(hidden) self.localKart.stopSmooth() self.localKart.stopPosHprBroadcast() base.camera.setPos(cpos) base.camera.setHpr(chpr) return def enterLeave(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) taskMgr.remove('raceWatcher') self.gui.disable() if self.localKart: self.localKart.disableControls() base.transitions.irisOut() if self.raceType == RaceGlobals.Circuit and not len(self.circuitLoop) == 0: self.sendUpdate('racerLeft', [localAvatar.doId]) else: taskMgr.doMethodLater(1, self.goToSpeedway, 'leaveRace', extraArgs=[[localAvatar.doId], RaceGlobals.Exit_UserReq]) if self.victory: self.victory.stop() self.bananaSound.stop() self.anvilFall.stop() return def exitLeave(self): pass def getCountdownColor(self, countdownTimeInt): clockNodeColors = [Vec4(0, 1, 0, 1), Vec4(1, 1, 0, 1), Vec4(1, 0.5, 0, 1), Vec4(1, 0, 0, 1)] i = max(min(countdownTimeInt, len(clockNodeColors) - 1), 0) return clockNodeColors[i] def startCountdownClock(self, countdownTime, ts): self.clockNode = TextNode('k') self.clockNode.setFont(ToontownGlobals.getSignFont()) self.clockNode.setAlign(TextNode.ACenter) countdownInt = int(countdownTime) self.clockNode.setTextColor(self.getCountdownColor(countdownInt)) self.clockNode.setText(str(countdownInt)) self.clock = render2d.attachNewNode(self.clockNode) rs = TTLocalizer.DRrollScale self.clock.setPosHprScale(0, 0, 0, 0, 0, 0, rs, rs, rs) self.clock.hide() if ts < countdownTime: self.countdown(countdownTime - ts) def timerTask(self, task): countdownTime = int(task.duration - task.time) timeStr = str(countdownTime + 1) if self.clock.isHidden(): if task.duration - task.time <= task.maxCount: self.clock.show() if self.clockNode.getText() != timeStr: self.startBoopSfx.play() self.clockNode.setText(timeStr) self.clockNode.setTextColor(self.getCountdownColor(countdownTime + 1)) if task.time >= task.duration: self.startBoop2Sfx.play() self.clockNode.setText(TTLocalizer.KartRace_Go) self.clockNode.setTextColor(self.getCountdownColor(-1)) taskMgr.doMethodLater(1, self.endGoSign, 'removeGoSign') return Task.done else: return Task.cont def endGoSign(self, t): self.clock.removeNode() def countdown(self, duration): countdownTask = Task(self.timerTask) countdownTask.duration = duration countdownTask.maxCount = RaceGlobals.RaceCountdown taskMgr.remove(self.uniqueName('countdownTimerTask')) return taskMgr.add(countdownTask, self.uniqueName('countdownTimerTask')) def initGags(self): self.banana = globalPropPool.getProp('banana') self.banana.setScale(2) self.pie = globalPropPool.getProp('creampie') self.pie.setScale(1) def makeCheckPoint(self, trigger, location, event): cs = CollisionSphere(0, 0, 0, 140) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(self.geom) cnp.setPos(location) self.accept(triggerEvent, event) def loadUrbanTrack(self): self.dnaStore = DNAStorage() files = ('phase_4/dna/storage.pdna', 'phase_5/dna/storage_town.pdna', 'phase_4/dna/storage_TT.pdna', 'phase_5/dna/storage_TT_town.pdna', 'phase_8/dna/storage_BR.pdna', 'phase_8/dna/storage_BR_town.pdna', 'phase_8/dna/storage_DL.pdna', 'phase_8/dna/storage_DL_town.pdna') dnaBulk = DNABulkLoader(self.dnaStore, files) dnaBulk.loadDNAFiles() dnaFile = 'phase_6/dna/urban_track_town.pdna' if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): dnaFile = 'phase_6/dna/urban_track_town_B.pdna' node = loader.loadDNAFile(self.dnaStore, dnaFile) self.townGeom = self.geom.attachNewNode(node) self.townGeom.findAllMatches('**/+CollisionNode').stash() self.buildingGroups = {} self.currBldgInd = {} self.currBldgGroups = {} bgGeom = self.geom.find('**/polySurface8') if self.dummyNode: bgGeom.reparentTo(self.dummyNode) else: bgGeom.reparentTo(localAvatar) bgGeom.setScale(0.1) ce = CompassEffect.make(NodePath(), CompassEffect.PRot) bgGeom.node().setEffect(ce) bgGeom.setDepthTest(0) bgGeom.setDepthWrite(0) bgGeom.setBin('background', 102) bgGeom.setZ(-1) self.bgGeom = bgGeom l = self.geom.findAllMatches('**/+ModelNode') for n in l: n.node().setPreserveTransform(0) self.geom.flattenLight() maxNum = 0 for side in ['inner', 'outer']: self.buildingGroups[side] = [] self.currBldgInd[side] = None self.currBldgGroups[side] = None i = 0 while 1: bldgGroup = self.townGeom.find('**/Buildings_' + side + '-' + str(i)) if bldgGroup.isEmpty(): break l = bldgGroup.findAllMatches('**/+ModelNode') for n in l: n2 = n.getParent().attachNewNode(n.getName()) n.getChildren().reparentTo(n2) n.removeNode() bldgGroup.flattenStrong() if not bldgGroup.getNode(0).getBounds().isEmpty(): self.buildingGroups[side].append(bldgGroup) i += 1 if i > maxNum: maxNum = i for side in ['innersidest', 'outersidest']: self.buildingGroups[side] = [] self.currBldgInd[side] = None self.currBldgGroups[side] = None for i in xrange(maxNum): for barricade in ('innerbarricade', 'outerbarricade'): bldgGroup = self.townGeom.find('**/Buildings_' + side + '-' + barricade + '_' + str(i)) if bldgGroup.isEmpty(): continue l = bldgGroup.findAllMatches('**/+ModelNode') for n in l: n2 = n.getParent().attachNewNode(n.getName()) n.getChildren().reparentTo(n2) n.removeNode() self.buildingGroups[side].append(bldgGroup) treeNodes = self.townGeom.findAllMatches('**/prop_tree_*') for tree in treeNodes: tree.flattenStrong() snowTreeNodes = self.townGeom.findAllMatches('**/prop_snow_tree_*') for snowTree in snowTreeNodes: snowTree.flattenStrong() for side in ['inner', 'outer', 'innersidest', 'outersidest']: for grp in self.buildingGroups[side]: grp.stash() self.showBuildings(0) def unloadUrbanTrack(self): del self.buildingGroups self.townGeom.removeNode() def loadFog(self): self.hasFog = True if self.isUrbanTrack: base.camLens.setFar(650) else: base.camLens.setFar(650) self.dummyNode = render.attachNewNode('dummyNode') if base.wantFog: self.fog = Fog('TrackFog') self.fog.setColor(Vec4(0.6, 0.7, 0.8, 1.0)) if self.isUrbanTrack: self.fog.setLinearRange(200.0, 650.0) else: self.fog.setLinearRange(200.0, 800.0) render.setFog(self.fog) self.sky.setScale(1.725) self.sky.reparentTo(self.dummyNode) def showBuildings(self, t, forceRecompute = False): firstTimeCalled = 0 if self.curve: t = t / self.curve.getMaxT() else: firstTimeCalled = 1 if self.reversed: t = 1.0 - t numGroupsShown = 5 for side in ['inner', 'outer']: numBldgGroups = len(self.buildingGroups[side]) bldgInd = int(t * numBldgGroups) bldgInd = bldgInd % numBldgGroups if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): oldBldgInd = int(self.oldT * numBldgGroups) newBldgInd = int(t * numBldgGroups) kartPoint = self.startPos kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) if kart: kartPoint = self.localKart.getPos() if not self.currBldgInd[side]: self.currBldgInd[side] = 0 curInd = self.currBldgInd[side] myCurGroup = self.buildingGroups[side][curInd] prevGrp = (curInd - 1) % numBldgGroups myPrevGroup = self.buildingGroups[side][prevGrp] nextGrp = (curInd + 1) % numBldgGroups myNextGroup = self.buildingGroups[side][nextGrp] curVector = myCurGroup.getNode(0).getBounds().getCenter() - kartPoint curDistance = curVector.lengthSquared() prevVector = myPrevGroup.getNode(0).getBounds().getCenter() - kartPoint prevDistance = prevVector.lengthSquared() nextVector = myNextGroup.getNode(0).getBounds().getCenter() - kartPoint nextDistance = nextVector.lengthSquared() if curDistance <= prevDistance and curDistance <= nextDistance: bldgInd = self.currBldgInd[side] elif prevDistance <= curDistance and prevDistance <= nextDistance: bldgInd = prevGrp elif nextDistance <= curDistance and nextDistance <= prevDistance: bldgInd = nextGrp else: self.notify.warning('unhandled case!!!!') bldgInd = self.currBldgInd[side] if bldgInd != self.currBldgInd[side]: currBldgGroups = self.currBldgGroups[side] if currBldgGroups: for i in currBldgGroups: self.buildingGroups[side][i].stash() prevGrp2 = (bldgInd - 2) % numBldgGroups prevGrp = (bldgInd - 1) % numBldgGroups currGrp = bldgInd % numBldgGroups nextGrp = (bldgInd + 1) % numBldgGroups nextGrp2 = (bldgInd + 2) % numBldgGroups self.currBldgGroups[side] = [prevGrp2, prevGrp, currGrp, nextGrp, nextGrp2] for i in self.currBldgGroups[side]: self.buildingGroups[side][i].unstash() self.currBldgInd[side] = bldgInd if self.currBldgGroups['inner'] != self.currBldgGroups['outer']: pass if t != self.oldT: self.oldT = t if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): if self.reversed: t = 1.0 - t for side in ['innersidest', 'outersidest']: segmentInd = int(t * self.barricadeSegments) seglmentInd = segmentInd % self.barricadeSegments if segmentInd != self.currBldgInd[side] or forceRecompute: currBldgGroups = self.currBldgGroups[side] if currBldgGroups: for i in currBldgGroups: self.buildingGroups[side][i].stash() self.currBldgGroups[side] = [] if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict if segmentInd in dict: self.currBldgGroups[side] = dict[segmentInd] for i in self.currBldgGroups[side]: self.buildingGroups[side][i].unstash() self.currBldgInd[side] = segmentInd return def setupGeom(self): trackFilepath = RaceGlobals.TrackDict[self.trackId][0] self.geom = loader.loadModel(trackFilepath) for i in xrange(10): base.loader.tick() self.geom.reparentTo(render) if self.reversed: lapStartPos = self.geom.find('**/lap_start_rev').getPos() else: lapStartPos = self.geom.find('**/lap_start').getPos() self.startPos = lapStartPos lapMidPos = self.geom.find('**/lap_middle').getPos() for i in xrange(5): base.loader.tick() self.startingPos = [] posLocators = self.geom.findAllMatches('**/start_pos*') for i in xrange(posLocators.getNumPaths()): base.loader.tick() self.startingPos.append([posLocators[i].getPos(), posLocators[i].getHpr()]) self.notify.debug('self.startingPos: %s' % self.startingPos) self.wrongWay = False self.laps = 0 if self.isUrbanTrack: self.loadUrbanTrack() self.genArrows() if self.reversed: self.curve = self.geom.find('**/curve_reverse').node() else: self.curve = self.geom.find('**/curve_forward').node() for i in xrange(4000): self.curvePoints.append(Point3(0, 0, 0)) self.curve.getPoint(i / 4000.0 * (self.curve.getMaxT() - 1e-11), self.curvePoints[-1]) self.curveTs.append(i / 4000.0 * (self.curve.getMaxT() - 1e-11)) if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.precomputeSideStreets() for i in xrange(10): base.loader.tick() self.startT = self.getNearestT(lapStartPos) self.midT = self.getNearestT(lapMidPos) self.gags = [] gagList = RaceGlobals.TrackDict[self.trackId][4] for i in xrange(len(gagList)): self.notify.debug('generating gag: %s' % i) self.gags.append(RaceGag(self, i, Vec3(*gagList[i]) + Vec3(0, 0, 3))) for i in xrange(5): base.loader.tick() def precomputeSideStreets(self): farDist = base.camLens.getFar() + 300 farDistSquared = farDist * farDist for i in xrange(int(self.barricadeSegments)): testPoint = Point3(0, 0, 0) self.curve.getPoint(i / self.barricadeSegments * (self.curve.getMaxT() - 1e-11), testPoint) for side in ('innersidest', 'outersidest'): for bldgGroupIndex in xrange(len(self.buildingGroups[side])): bldgGroup = self.buildingGroups[side][bldgGroupIndex] if not bldgGroup.getNode(0).getBounds().isEmpty(): bldgPoint = bldgGroup.getNode(0).getBounds().getCenter() vector = testPoint - bldgPoint if vector.lengthSquared() < farDistSquared: if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict else: self.notify.error('unhandled side') if i in dict: if bldgGroupIndex not in dict[i]: dict[i].append(bldgGroupIndex) else: dict[i] = [bldgGroupIndex] for childIndex in (0,): if childIndex >= bldgGroup.getNumChildren(): continue childNodePath = bldgGroup.getChild(childIndex) bldgPoint = childNodePath.node().getBounds().getCenter() vector = testPoint - bldgPoint if vector.lengthSquared() < farDistSquared: if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict else: self.notify.error('unhandled side') if i in dict: if bldgGroupIndex not in dict[i]: dict[i].append(bldgGroupIndex) else: dict[i] = [bldgGroupIndex] for side in ('innersidest', 'outersidest'): for bldgGroup in self.buildingGroups[side]: bldgGroup.flattenStrong() if self.isUrbanTrack: self.showBuildings(0, forceRecompute=True) def findSegmentStart(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) minLength2 = 1000000 minIndex = -1 currPoint = Point3(0, 0, 0) kartPoint = self.localKart.getPos() for i in xrange(len(self.curvePoints)): currPoint = self.curvePoints[i] currLength2 = (kartPoint - currPoint).lengthSquared() if currLength2 < minLength2: minLength2 = currLength2 minIndex = i currPoint = self.curvePoints[minIndex] if minIndex + 1 == len(self.curvePoints): nextPoint = self.curvePoints[0] else: nextPoint = self.curvePoints[minIndex + 1] if minIndex - 1 < 0: prevIndex = len(self.curvePoints) - 1 else: prevIndex = minIndex - 1 forwardSegment = nextPoint - currPoint if (kartPoint - currPoint).dot(forwardSegment) > 0: return minIndex else: return prevIndex return def getNearestT(self, pos): minLength2 = 1000000 minIndex = -1 currPoint = Point3(0, 0, 0) for i in xrange(len(self.curvePoints)): currPoint = self.curvePoints[i] currLength2 = (pos - currPoint).lengthSquared() if currLength2 < minLength2: minLength2 = currLength2 minIndex = i currPoint = self.curvePoints[minIndex] if minIndex + 1 == len(self.curvePoints): nextPoint = self.curvePoints[0] else: nextPoint = self.curvePoints[minIndex + 1] if minIndex - 1 < 0: prevIndex = len(self.curvePoints) - 1 else: prevIndex = minIndex - 1 forwardSegment = nextPoint - currPoint if (pos - currPoint).dot(forwardSegment) > 0: pole = minIndex else: pole = prevIndex currPoint = self.curvePoints[pole] nextPole = (pole + 1) % len(self.curvePoints) nextPoint = self.curvePoints[nextPole] segment = nextPoint - currPoint segment.setZ(0) segLength2 = segment.lengthSquared() posVector = pos - currPoint posVector.setZ(0) project = segment * (segment.dot(posVector) / segLength2) percent = project.lengthSquared() / segLength2 if nextPole < pole: t = self.curveTs[pole] * (1 - percent) + self.curve.getMaxT() * percent else: t = self.curveTs[pole] * (1 - percent) + self.curveTs[nextPole] * percent return t def hasGag(self, slot, type, index): if self.gags[slot].isActive(): self.gags[slot].disableGag() def leaveRace(self): self.fsm.request('leave') def racerLeft(self, avId): if avId != localAvatar.doId: self.gui.racerLeft(avId, unexpected=False) def skyTrack(self, task): return SkyUtil.cloudSkyTrack(task) def startSky(self): if self.hasFog: SkyUtil.startCloudSky(self, parent=self.dummyNode, effects=CompassEffect.PRot) else: SkyUtil.startCloudSky(self, parent=render) def stopSky(self): taskMgr.remove('skyTrack') def pickupGag(self, slot, index): self.canShoot = False standing = self.gui.racerDict[localAvatar.doId].place - 1 self.currGag = RaceGlobals.GagFreq[standing][index] cycleTime = 2 self.gui.waitingOnGag(cycleTime) taskMgr.doMethodLater(cycleTime, self.enableShoot, 'enableShoot') self.sendUpdate('hasGag', [slot, self.currGag, index]) def shootGag(self): if self.canShoot: if self.currGag == 1: self.bananaSound.play() self.shootBanana() elif self.currGag == 2: self.d_requestThrow(0, 0, 0) self.localKart.startTurbo() elif self.currGag == 3: self.d_requestThrow(0, 0, 0) elif self.currGag == 4: self.bananaSound.play() self.shootPie() self.currGag = 0 self.gui.updateGag(0) def enableShoot(self, t): self.canShoot = True if self.gui: self.gui.updateGag(self.currGag) def shootBanana(self): pos = self.localKart.getPos(render) banana = self.banana.copyTo(self.geom) banana.setPos(pos) self.thrownGags.append(banana) self.d_requestThrow(pos[0], pos[1], pos[2]) def shootPie(self): pos = self.localKart.getPos(render) self.d_requestThrow(pos[0], pos[1], pos[2]) def genArrows(self): base.arrows = [] arrowId = 0 for boost in RaceGlobals.TrackDict[self.trackId][5]: self.genArrow(boost[0], boost[1], arrowId) arrowId += 1 def genArrow(self, pos, hpr, id): factory = CardMaker('factory') factory.setFrame(-.5, 0.5, -.5, 0.5) arrowNode = factory.generate() arrowRoot = NodePath('root') baseArrow = NodePath(arrowNode) baseArrow.setTransparency(1) baseArrow.setTexture(self.boostArrowTexture) baseArrow.reparentTo(arrowRoot) arrow2 = baseArrow.copyTo(baseArrow) arrow2.setPos(0, 0, 1) arrow3 = arrow2.copyTo(arrow2) arrowRoot.setPos(*pos) arrowRoot.setHpr(*hpr) baseArrow.setHpr(0, -90, 0) baseArrow.setScale(24) arrowRoot.reparentTo(self.geom) trigger = 'boostArrow' + str(id) cs = CollisionTube(Point3(0.6, -6, 0), Point3(0.6, 54, 0), 4.8) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(arrowRoot) self.accept(triggerEvent, self.hitBoostArrow) arrowVec = arrow2.getPos(self.geom) - baseArrow.getPos(self.geom) arrowVec.normalize() idStr = str(id) cnp.setTag('boostId', idStr) self.boostDir[idStr] = arrowVec base.arrows.append(arrowRoot) def hitBoostArrow(self, cevent): into = cevent.getIntoNodePath() idStr = into.getTag('boostId') arrowVec = self.boostDir.get(idStr) if arrowVec == None: print 'Unknown boost arrow %s' % idStr return fvec = self.localKart.forward.getPos(self.geom) - self.localKart.getPos(self.geom) fvec.normalize() dotP = arrowVec.dot(fvec) if dotP > 0.7: self.localKart.startTurbo() return def fadeOutMusic(self): if self.musicTrack: self.musicTrack.finish() curVol = self.raceMusic.getVolume() interval = LerpFunctionInterval(self.raceMusic.setVolume, fromData=curVol, toData=0, duration=3) self.musicTrack = Sequence(interval) self.musicTrack.start() def changeMusicTempo(self, newPR): return # TODO: Reenable when we have music change support. if self.musicTrack: self.musicTrack.finish() curPR = self.raceMusic.getPlayRate() interval = LerpFunctionInterval(self.raceMusic.setPlayRate, fromData=curPR, toData=newPR, duration=3) self.musicTrack = Sequence(interval) self.musicTrack.start() def setRaceZone(self, zoneId, trackId): hoodId = self.cr.playGame.hood.hoodId base.loader.endBulkLoad('atRace') self.kartCleanup() self.doneBarrier('waitingForExit') self.sendUpdate('racerLeft', [localAvatar.doId]) out = {'loader': 'racetrack', 'where': 'racetrack', 'hoodId': hoodId, 'zoneId': zoneId, 'trackId': trackId, 'shardId': None, 'reason': RaceGlobals.Exit_UserReq} base.cr.playGame.hood.loader.fsm.request('quietZone', [out]) return
def update(self, time): placeSorter = [] placeCount = 0 for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[self.maxLapHit - 1]: y.configure(text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime() - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice['text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice['text'] = TTLocalizer.KartRace_LapText % str(self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str(clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str(self.race.lapCount) suffix = {1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix} placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[0] - localRacer.face.getX() < nearDiff: for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX() >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str(self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() elif not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish()