class ToonBlitzAssetMgr(DirectObject): """ This class controls all the art and sound assets of Toon Blitz minigame. """ notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedToonBlitzAssets') # define constants that you won't want to tweak here def __init__(self, game): self.__defineConstants() self.game = game self.load() def __defineConstants(self): '''Define all the Toon Blitz contants here.''' pass def load(self): assert self.notify.debugStateCall(self) # Create top node for the world. Reparent all the assets to this. self.world = NodePath('ToonBlitzWorld') # Loading the models self.background = loader.loadModel( "phase_4/models/minigames/toonblitz_game") self.background.reparentTo(self.world) self.startingWall = loader.loadModel( "phase_4/models/minigames/toonblitz_game_wall") self.startingPipe = loader.loadModel( "phase_4/models/minigames/toonblitz_game_start") self.exitElevator = loader.loadModel( "phase_4/models/minigames/toonblitz_game_elevator") self.arrow = loader.loadModel( "phase_4/models/minigames/toonblitz_game_arrow") self.sprayProp = loader.loadModel( "phase_4/models/minigames/prop_waterspray") self.treasureModelList = [] salesIcon = loader.loadModel("phase_4/models/minigames/salesIcon") self.treasureModelList.append(salesIcon) moneyIcon = loader.loadModel("phase_4/models/minigames/moneyIcon") self.treasureModelList.append(moneyIcon) legalIcon = loader.loadModel("phase_4/models/minigames/legalIcon") self.treasureModelList.append(legalIcon) corpIcon = loader.loadModel("phase_4/models/minigames/corpIcon") self.treasureModelList.append(corpIcon) self.particleGlow = loader.loadModel( "phase_4/models/minigames/particleGlow") self.blockTypes = [] for i in range(4): blockType = loader.loadModel( "phase_4/models/minigames/toonblitz_game_block0" + str(i)) self.blockTypes.append(blockType) self.stomper = loader.loadModel( "phase_4/models/minigames/toonblitz_game_stomper") # Creating bottom floor plane = CollisionPlane(Plane(Vec3(0, 0, 1), Point3(0, 0, -50))) dropPlane = CollisionNode('dropPlane') dropPlane.addSolid(plane) dropPlane.setCollideMask(ToontownGlobals.FloorBitmask) self.world.attachNewNode(dropPlane) # Loading the music self.gameMusic = base.loadMusic("phase_4/audio/bgm/MG_TwoDGame.mid") self.treasureGrabSound = loader.loadSfx( "phase_4/audio/sfx/SZ_DD_treasure.mp3") self.sndOof = base.loader.loadSfx( 'phase_4/audio/sfx/MG_cannon_hit_dirt.mp3') self.soundJump = base.loader.loadSfx( 'phase_4/audio/sfx/MG_sfx_vine_game_jump.mp3') self.fallSound = base.loader.loadSfx( "phase_4/audio/sfx/MG_sfx_vine_game_fall.mp3") self.watergunSound = base.loader.loadSfx( "phase_4/audio/sfx/AA_squirt_seltzer_miss.mp3") self.splashSound = base.loader.loadSfx( "phase_4/audio/sfx/Seltzer_squirt_2dgame_hit.mp3") self.threeSparkles = loader.loadSfx( "phase_4/audio/sfx/threeSparkles.mp3") self.sparkleSound = loader.loadSfx("phase_4/audio/sfx/sparkly.mp3") self.headCollideSound = loader.loadSfx( "phase_3.5/audio/sfx/AV_collision.mp3") # Card for the progress line self.faceStartPos = Vec3(-0.80, 0, -0.87) self.faceEndPos = Vec3(0.80, 0, -0.87) self.aspect2dRoot = aspect2d.attachNewNode('TwoDGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.cardMaker = CardMaker('card') self.cardMaker.reset() self.cardMaker.setName('ProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.progressLine = self.aspect2dRoot.attachNewNode( self.cardMaker.generate()) self.progressLine.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) self.progressLine.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range( ToonBlitzGlobals.NumSections[self.game.getSafezoneId()] + 1): hash = self.aspect2dRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(self.progressLine.getScale()[2], 1, self.progressLine.getScale()[2] * 5) t = float(n) / ToonBlitzGlobals.NumSections[ self.game.getSafezoneId()] hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) def destroy(self): assert self.notify.debugStateCall(self) while len(self.blockTypes): blockType = self.blockTypes[0] self.blockTypes.remove(blockType) del blockType self.blockTypes = None while len(self.treasureModelList): treasureModel = self.treasureModelList[0] self.treasureModelList.remove(treasureModel) del treasureModel self.treasureModelList = None self.startingWall.removeNode() del self.startingWall self.startingPipe.removeNode() del self.startingPipe self.exitElevator.removeNode() del self.exitElevator self.stomper.removeNode() del self.stomper self.arrow.removeNode() del self.arrow self.sprayProp.removeNode() del self.sprayProp self.aspect2dRoot.removeNode() del self.aspect2dRoot self.world.removeNode() del self.world del self.gameMusic del self.treasureGrabSound del self.sndOof del self.soundJump del self.fallSound del self.watergunSound del self.splashSound del self.threeSparkles del self.sparkleSound del self.headCollideSound self.game = None def onstage(self): assert self.notify.debugStateCall(self) # parent things to render, start playing music... self.world.reparentTo(render) base.playMusic(self.gameMusic, looping=1, volume=0.9) def offstage(self): assert self.notify.debugStateCall(self) # parent things to hidden, stop the music... self.world.hide() self.gameMusic.stop() def enterPlay(self): """ This function is called when the minigame enters the play state.""" pass def exitPlay(self): """ This function will be called when the minigame exits the play state.""" pass def enterPause(self): pass def exitPause(self): pass def playJumpSound(self): base.localAvatar.soundRun.stop() base.playSfx(self.soundJump, looping=0) def playWatergunSound(self): self.watergunSound.stop() base.playSfx(self.watergunSound, looping=0) def playSplashSound(self): self.splashSound.stop() base.playSfx(self.splashSound, looping=0) def playHeadCollideSound(self): self.headCollideSound.stop() base.playSfx(self.headCollideSound, looping=0)
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.RGplaceLabelNumPos, 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.RGplaceLabelStrPos, 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.RGphotoFinish, 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(list(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 list(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, range(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 list(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 list(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(list(self.racerDict.keys()), list(range(len(list(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