Exemple #1
0
 def _initModel(self):
     baseName = '**/tt_t_gui_cmg_miniMap_'
     cardModel = CogdoUtil.loadMazeModel('miniMap_cards', group='gui')
     cm = CardMaker('bg')
     cm.setFrame(-1.1, 1.1, -1.1, 1.1)
     bg = self.attachNewNode(cm.generate())
     bg.setColor(*self._bgColor)
     bg.setBin('fixed', 0)
     frame = cardModel.find(baseName + 'frame')
     frame.reparentTo(self)
     frame.setScale(2.5)
     frame.setPos(0.01, 0, -0.01)
     self._entrance = cardModel.find(baseName + 'entrance')
     self._entrance.reparentTo(self)
     self._entrance.setScale(0.35)
     self._entrance.hide()
     self._exit = NodePath('exit')
     self._exit.setScale(0.35)
     self._exit.reparentTo(self)
     self._exitOpen = cardModel.find(baseName + 'exitOpen')
     self._exitOpen.reparentTo(self._exit)
     self._exitClosed = cardModel.find(baseName + 'exitClosed')
     self._exitClosed.reparentTo(self._exit)
     self._suitMarkerTemplate = cardModel.find(baseName + 'cogIcon')
     self._suitMarkerTemplate.detachNode()
     self._suitMarkerTemplate.setScale(0.225)
     self._waterCoolerTemplate = cardModel.find(baseName + 'waterDrop')
     self._waterCoolerTemplate.detachNode()
     self._waterCoolerTemplate.setScale(0.225)
     self._exit.hide()
     cardModel.removeNode()
    def _createMaskTextureCard(self):
        """
        This will return a NodePath with a card textured with the map mask.  It
        also creates several other members that re needed to change the mask.
        """
        # create and fill empty mask image
        self._maskImage = PNMImage(self._maskResolution, self._maskResolution,
                                   4)
        for x in range(self._maskResolution):
            for y in range(self._maskResolution):
                #maskImage.setXel(x,y,mapImage.getRed(x/13,y/10),mapImage.getGreen(x/13,y/10),mapImage.getBlue(x/13,y/10))
                self._maskImage.setXelA(x, y, 0, 0, 0, 1)

        # create the texture for the mask
        self.maskTexture = Texture("maskTexture")
        self.maskTexture.setupTexture(Texture.TT2dTexture,
                                      self._maskResolution,
                                      self._maskResolution, 1,
                                      Texture.TUnsignedByte, Texture.FRgba)
        self.maskTexture.setMinfilter(Texture.FTLinear)
        self.maskTexture.setWrapU(Texture.WMClamp)
        self.maskTexture.setWrapV(Texture.WMClamp)

        self.maskTexture.load(self._maskImage)
        base.graphicsEngine.renderFrame()

        # put the mask texture on a card and return it
        cm = CardMaker("mask_cardMaker")
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        mask = self.attachNewNode(cm.generate())
        mask.setTexture(self.maskTexture, 1)
        mask.setTransparency(1)
        return mask
Exemple #3
0
    def setupRightTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)

        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT)

        # the html area will be center aligned and vertically top aligned
        #cm.setFrame(-htmlWidth/2.0, htmlWidth/2.0, 1.0 - htmlHeight, 1.0)
        cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0)
        card = cm.generate()
        self.rightQuad = NodePath(card)
        self.rightQuad.reparentTo(self.parent)

        self.rightGuiTex = Texture("guiTex")
        self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH,
                                      WEB_HEIGHT, 1, Texture.TUnsignedByte,
                                      Texture.FRgba)
        self.rightGuiTex.setKeepRamImage(True)
        self.rightGuiTex.makeRamImage()
        self.rightGuiTex.setWrapU(Texture.WMClamp)
        self.rightGuiTex.setWrapV(Texture.WMClamp)

        ts = TextureStage('rightWebTS')
        self.rightQuad.setTexture(ts, self.rightGuiTex)
        self.rightQuad.setTexScale(ts, 1.0, -1.0)

        self.rightQuad.setTransparency(0)
        self.rightQuad.setTwoSided(True)
        self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)
Exemple #4
0
 def announceGenerate(self):
     assert (self.notify.debug("announceGenerate()"))
     DistributedObject.DistributedObject.announceGenerate(self)
     self.sendUpdate("avIdEnteredParty", [base.localAvatar.doId])
     # we probably just spent a lot of time loading, so
     # tell globalClock to update the frame timestamp
     globalClock.syncFrameTime()
     self.startPartyClock()
     base.localAvatar.chatMgr.chatInputSpeedChat.addInsidePartiesMenu()
     self.spawnTitleText()
     messenger.send(self.generatedEvent)
     if ConfigVariableBool('show-debug-party-grid', 0).getValue():
         # Debug grid
         self.testGrid = NodePath("test_grid")
         self.testGrid.reparentTo(base.cr.playGame.hood.loader.geom)
         for i in range(len(self.grid)):
             for j in range(len(self.grid[i])):
                 cm = CardMaker("gridsquare")
                 np = NodePath(cm.generate())
                 np.setScale(12)
                 np.setP(-90.0)
                 np.setPos(
                     PartyUtils.convertDistanceFromPartyGrid(j, 0) - 6.0,
                     PartyUtils.convertDistanceFromPartyGrid(i, 1) - 6.0,
                     0.1)
                 np.reparentTo(self.testGrid)
                 if self.grid[i][j]:
                     np.setColorScale(0.0, 1.0, 0.0, 1.0)
                 else:
                     np.setColorScale(1.0, 0.0, 0.0, 1.0)
    def __init__(self, player):

        self.player = player

        self.root = NodePath("CogdoFlyingGui")
        self.root.reparentTo(aspect2d)

        self.fuelMeter = NodePath("scrubMeter")
        self.fuelMeter.reparentTo(self.root)
        self.fuelMeter.setPos(1.1, 0.0, -0.7)
        self.fuelMeter.setSz(2.0)

        cm = CardMaker('card')
        cm.setFrame(-0.07, 0.07, 0.0, 0.75)
        self.fuelMeterBar = self.fuelMeter.attachNewNode(cm.generate())
        self.fuelMeterBar.setColor(0.95, 0.95, 0.0, 1.0)

        self.fuelLabel = DirectLabel(
            parent=self.root,
            relief=None,
            pos=(1.1, 0, -0.8),
            scale=0.075,
            text="Fuel",
            text_fg=(0.95, 0.95, 0, 1),
            text_shadow=(0, 0, 0, 1),
            text_font=ToontownGlobals.getInterfaceFont(),
        )

        self.messageLabel = DirectLabel(
            parent=self.root,
            relief=None,
            pos=(0.0, 0.0, -0.9),
            scale=0.1,
            text="                ",
            text_align=TextNode.ACenter,
            text_fg=(0.95, 0.95, 0, 1),
            text_shadow=(0, 0, 0, 1),
            text_font=ToontownGlobals.getInterfaceFont(),
            textMayChange=1,
        )
        self.messageLabel.stash()

        self.winLabel = DirectLabel(
            parent=self.root,
            relief=None,
            pos=(0.0, 0.0, 0.0),
            scale=0.25,
            text="You win!",
            text_align=TextNode.ACenter,
            text_fg=(0.95, 0.95, 0, 1),
            text_shadow=(0, 0, 0, 1),
            text_font=ToontownGlobals.getInterfaceFont(),
        )
        self.winLabel.stash()

        self.refuelLerp = LerpFunctionInterval(self.fuelMeterBar.setSz,
                                               fromData=0.0,
                                               toData=1.0,
                                               duration=2.0)
Exemple #6
0
    def loadFlatQuad(self, fullFilename):
        """Load the flat jpg into a quad."""
        assert self.notify.debugStateCall(self)
        #Texture.setTexturesPower2(AutoTextureScale.ATSUp)
        #Texture.setTexturesPower2(2)

        cm = CardMaker('cm-%s' % fullFilename)
        cm.setColor(1.0, 1.0, 1.0, 1.0)
        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)

        # the html area will be center aligned and vertically top aligned
        #cm.setFrame(-htmlWidth/2.0, htmlWidth/2.0, 1.0 - htmlHeight, 1.0)
        cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0,
                    htmlHeight / 2.0)

        bottomRightX = (WEB_WIDTH_PIXELS) / float(WEB_WIDTH + 1)
        bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)

        #cm.setUvRange(Point2(0,0), Point2(bottomRightX, bottomRightY))
        cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))

        card = cm.generate()
        quad = NodePath(card)
        #quad.reparentTo(self.parent)

        jpgFile = PNMImage(WEB_WIDTH, WEB_HEIGHT)
        smallerJpgFile = PNMImage()
        readFile = smallerJpgFile.read(Filename(fullFilename))
        if readFile:
            jpgFile.copySubImage(smallerJpgFile, 0, 0)

            guiTex = Texture("guiTex")
            guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1,
                                Texture.TUnsignedByte, Texture.FRgba)
            guiTex.setMinfilter(Texture.FTLinear)
            guiTex.load(jpgFile)
            #guiTex.setKeepRamImage(True)
            #guiTex.makeRamImage()
            guiTex.setWrapU(Texture.WMClamp)
            guiTex.setWrapV(Texture.WMClamp)

            ts = TextureStage('webTS')
            quad.setTexture(ts, guiTex)
            #quad.setTexScale(ts, 1.0, -1.0)

            quad.setTransparency(0)
            quad.setTwoSided(True)
            quad.setColor(1.0, 1.0, 1.0, 1.0)
            result = quad
        else:
            # if we have an error loading the file, return None to signify an error
            result = None

        #Texture.setTexturesPower2(AutoTextureScale.ATSDown)
        Texture.setTexturesPower2(1)
        return result
    def _createMapTextureCard(self):
        """
        This will return a NodePath with a card textured with the minimap.  The
        minimap texture is dynamically created from the map data.
        """
        # create and fill empty map image
        mapImage = PNMImage(MAP_RESOLUTION, MAP_RESOLUTION)
        blockFiles = []
        for i in range(5):
            blockFiles.append(PNMImage())
            #blockFiles[i].read(Filename("mapBlock%i.png"%(i+1)))
            # TODO:maze either reference a set of textures for each piece or fill with color
            blockFiles[i].read(Filename('phase_4/maps/male_sleeve4New.png'))
        mapImage.fill(0.8, 0.8, 0.8)

        # iterate through the map data and place a block in the map image where appropriate
        for x in range(len(self._mazeLayout[0])):
            for y in range(len(self._mazeLayout)):
                if self._mazeLayout[y][x]:
                    ax = float(x) / len(self._mazeLayout[0]) * MAP_RESOLUTION
                    ay = float(y) / len(self._mazeLayout) * MAP_RESOLUTION

                    #TODO:maze use different blocks for different wall types or items
                    #mapImage.copySubImage(random.choice(blockFiles), int(ax), int(ay), 20, 20, 32, 32)

                    #TODO:maze find the ideal block texture size for the map so we dont
                    #          have to do this strange offset
                    #mapImage.copySubImage(blockFiles[0], int(ax), int(ay), 0, 0, 32, 32)
                    self._drawSquare(mapImage, int(ax), int(ay), 10,
                                     VBase4D(0.5, 0.5, 0.5, 1.0))

        # create a texture from the map image
        mapTexture = Texture("mapTexture")
        mapTexture.setupTexture(Texture.TT2dTexture, self._maskResolution,
                                self._maskResolution, 1, Texture.TUnsignedByte,
                                Texture.FRgba)
        mapTexture.setMinfilter(Texture.FTLinear)
        mapTexture.load(mapImage)
        mapTexture.setWrapU(Texture.WMClamp)
        mapTexture.setWrapV(Texture.WMClamp)

        mapImage.clear()
        del mapImage

        # put the texture on a card and return it
        cm = CardMaker("map_cardMaker")
        cm.setFrame(-1.0, 1.0, -1.0, 1.0)
        map = self.attachNewNode(cm.generate())
        map.setTexture(mapTexture, 1)
        return map
Exemple #8
0
    def setupTexture(self):
        cm = CardMaker('quadMaker')
        cm.setColor(1.0, 1.0, 1.0, 1.0)

        aspect = base.camLens.getAspectRatio()
        htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH)
        htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT)

        # the html area will be center aligned and vertically top aligned
        #cm.setFrame(-htmlWidth/2.0, htmlWidth/2.0, 1.0 - htmlHeight, 1.0)
        cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0,
                    htmlHeight / 2.0)

        bottomRightX = (WEB_WIDTH_PIXELS) / float(WEB_WIDTH + 1)
        bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1)

        #cm.setUvRange(Point2(0,0), Point2(bottomRightX, bottomRightY))
        cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1))

        card = cm.generate()
        self.quad = NodePath(card)
        self.quad.reparentTo(self.parent)

        self.guiTex = Texture("guiTex")
        self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1,
                                 Texture.TUnsignedByte, Texture.FRgba)
        self.guiTex.setMinfilter(Texture.FTLinear)
        self.guiTex.setKeepRamImage(True)
        self.guiTex.makeRamImage()
        self.guiTex.setWrapU(Texture.WMRepeat)
        self.guiTex.setWrapV(Texture.WMRepeat)

        ts = TextureStage('webTS')
        self.quad.setTexture(ts, self.guiTex)
        self.quad.setTexScale(ts, 1.0, -1.0)

        self.quad.setTransparency(0)
        self.quad.setTwoSided(True)
        self.quad.setColor(1.0, 1.0, 1.0, 1.0)
        #self.quad.setZ(0.1) # shtickerbook is moved up by 0.1

        self.calcMouseLimits()
    def addLock(self, x, y, color):
        """
        Adds a lock to the minimap.  This will add a colored dot to the map
        that represents a lock.
        --- This is subject to change pending a new player-lock data system. ---
        """
        assert self.notify.debugCall()

        x, y = self._tileToActualPosition(x, y)

        # TODO:maze: replace with lock model / texture
        cm = CardMaker("lock_cardMaker")
        cm.setFrame(-0.04, 0.04, -0.04, 0.04)
        lock = self.maskedLayer.attachNewNode(cm.generate())

        lock.setColor(color)
        lock.setPos(x / self._maskResolution * 2.0 - 0.97, 0,
                    y / self._maskResolution * -2.0 + 1.02)

        self._locks.append(lock)
    def addPlayer(self, x, y, color):
        """
        Adds a player to the minimap.  This will add a colored dot to the map
        that represents the player.  The dot location can then be updated
        using the revealCell call.
        --- This is subject to change pending a new player-lock data system. ---
        """
        assert self.notify.debugCall()

        x, y = self._tileToActualPosition(x, y)

        # TODO:maze: replace with player model / texture
        cm = CardMaker("player_cardMaker")
        cm.setFrame(-0.04, 0.04, -0.04, 0.04)
        player = self.visibleLayer.attachNewNode(cm.generate())

        player.setColor(color)
        player.setPos(x / self._maskResolution * 2.0 - 0.97, 0,
                      y / self._maskResolution * -2.0 + 1.02)

        self._players.append(player)
Exemple #11
0
 def __init__(self, av, **kw):
     DirectFrame.__init__(self, relief=None, sortOrder=50)
     self.initialiseoptions(QuestMap)
     self.container = DirectFrame(parent=self, relief=None)
     self.marker = DirectFrame(parent=self.container, relief=None)
     self.cogInfoFrame = DirectFrame(parent=self.container, relief=None)
     cm = CardMaker('bg')
     cm.setFrame(-0.5, 0.5, -0.5, 0.5)
     bg = self.cogInfoFrame.attachNewNode(cm.generate())
     bg.setTransparency(1)
     bg.setColor(0.5, 0.5, 0.5, 0.5)
     bg.setBin('fixed', 0)
     self.cogInfoFrame['geom'] = bg
     self.cogInfoFrame['geom_pos'] = (0, 0, 0)
     self.cogInfoFrame['geom_scale'] = (6, 1, 2)
     self.cogInfoFrame.setScale(0.05)
     self.cogInfoFrame.setPos(0, 0, 0.6)
     self.buildingMarkers = []
     self.av = av
     self.wantToggle = False
     if ConfigVariableBool('want-toggle-quest-map', True).getValue():
         self.wantToggle = True
     self.updateMarker = True
     self.cornerPosInfo = None
     self.hqPosInfo = None
     self.fishingSpotInfo = None
     self.load()
     self.setScale(1.5)
     bg.removeNode()
     self.hoodId = None
     self.zoneId = None
     self.suitPercentage = {}
     for currHoodInfo in SuitPlannerBase.SuitPlannerBase.SuitHoodInfo:
         tracks = currHoodInfo[
             SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK]
         self.suitPercentage[currHoodInfo[
             SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks
Exemple #12
0
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)
Exemple #13
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