def avatarFinished(self, avId):
        if not avId in self.avatars:
            self.air.writeServerEvent('suspicious', avId, 'Toon tried to finish in a race they\'re not in!')
            return

        if avId in self.finishedAvatars:
            self.air.writeServerEvent('suspicious', avId, 'Toon tried to finish in a race twice!')
            return
        self.finishedAvatars.append(avId)

        av = self.air.doId2do.get(avId)
        place = len(self.finishedAvatars)
        entryFee = RaceGlobals.getEntryFee(self.trackId, self.raceType)
        bonus = 0
        totalTime = globalClockDelta.networkToLocalTime(globalClockDelta.getRealNetworkTime()) - self.startTime
        qualify = False
        if totalTime < RaceGlobals.getQualifyingTime(self.trackId):
            qualify = True
            self.air.leaderboardMgr.submitRace(self.trackId, av.getName(), totalTime)
        if self.raceType == RaceGlobals.Practice:
            winnings = RaceGlobals.PracticeWinnings
            trophies = []
        elif qualify:
            offset = 4 - len(self.avatarProgress) # self.avatarProgress contains the amount of STARTING players.
            winnings = entryFee * RaceGlobals.Winnings[(place+offset)-1]
            trophies = self.calculateTrophies(avId, place == 1, qualify, totalTime)
        else:
            winnings = 0
            trophies = []
        av.b_setTickets(av.getTickets() + winnings)
        if av.getTickets() > RaceGlobals.MaxTickets:
            av.b_setTickets(RaceGlobals.MaxTickets)
        self.sendUpdate('setPlace', [avId, totalTime, place, entryFee, qualify, max((winnings-entryFee), 0), bonus, trophies, [], 0])
    def __handleEnterSphere(self, collEntry):
        if base.localAvatar.doId == self.lastAvId and globalClock.getFrameCount() <= self.lastFrame + 1:
            self.notify.debug('Ignoring duplicate entry for avatar.')
            return
        if base.localAvatar.hp > 0:

            def handleEnterRequest(self = self):
                self.ignore('stoppedAsleep')
                if hasattr(self.dialog, 'doneStatus') and self.dialog.doneStatus == 'ok':
                    self.d_requestEnter()
                elif self.cr and not self.isDisabled():
                    self.cr.playGame.getPlace().setState('walk')
                else:
                    self.notify.warning('Warning! Object has already been disabled.')
                self.dialog.ignoreAll()
                self.dialog.cleanup()
                del self.dialog

            self.cr.playGame.getPlace().fsm.request('stopped')
            self.accept('stoppedAsleep', handleEnterRequest)
            doneEvent = 'enterRequest|dialog'
            if self.kartPad.isPractice():
                msg = TTLocalizer.StartingBlock_EnterPractice
            else:
                raceName = TTLocalizer.KartRace_RaceNames[self.kartPad.trackType]
                numTickets = RaceGlobals.getEntryFee(self.kartPad.trackId, self.kartPad.trackType)
                msg = TTLocalizer.StartingBlock_EnterNonPractice % (raceName, numTickets)
            self.dialog = TTGlobalDialog(msg, doneEvent, 4)
            self.dialog.accept(doneEvent, handleEnterRequest)
 def createRace(self):
     self.raceZone = self.air.allocateZone()
     avatars = []
     for block in self.startingBlocks:
         if block.avId != 0:
             avatars.append(block.avId)
             self.sendUpdateToAvatarId(block.avId, 'setRaceZone', [self.raceZone])
     race = DistributedRaceAI(self.air)
     race.setZoneId(self.raceZone)
     race.setTrackId(self.trackId)
     race.setRaceType(self.trackType)
     race.setCircuitLoop([])
     race.setAvatars(avatars)
     race.setStartingPlaces(range(len(avatars)))
     race.setLapCount(3)
     race.generateWithRequired(self.raceZone)
     for avId in avatars:
         if avId in self.air.doId2do:
             av = self.air.doId2do[avId]
             entryFee = RaceGlobals.getEntryFee(self.trackId, self.trackType)
             if av.getTickets() < entryFee:
                 self.air.writeServerEvent('suspicious', avId, 'Toon somehow lost tickets between entering a race and it leaving!')
                 av.b_setTickets(0)
             else:
                 av.b_setTickets(av.getTickets() - entryFee)
     self.b_setState('WaitEmpty', globalClockDelta.getRealNetworkTime())
    def findRacingPads(self, dnaGroup, zoneId, area, padType='racing_pad'):
        racingPads = []
        racingPadGroups = []
        if isinstance(dnaGroup, DNAGroup) and (padType in dnaGroup.getName()):
            racingPadGroups.append(dnaGroup)

            if padType == 'racing_pad':
                nameInfo = dnaGroup.getName().split('_')
                racingPad = DistributedRacePadAI(simbase.air)
                racingPad.setArea(zoneId)
                racingPad.nameType = nameInfo[3]
                racingPad.index = int(nameInfo[2])
                nextRaceInfo = RaceGlobals.getNextRaceInfo(-1, racingPad.nameType, racingPad.index)
                racingPad.setTrackInfo([nextRaceInfo[0], nextRaceInfo[1]])
                racingPad.generateWithRequired(zoneId)
            elif padType == 'viewing_pad':
                racingPad = DistributedViewPadAI(simbase.air)
                racingPad.setArea(zoneId)
                racingPad.generateWithRequired(zoneId)
            else:
                self.notify.error('Invalid racing pad type: ' + padType)

            racingPads.append(racingPad)
        elif isinstance(dnaGroup, DNAVisGroup):
            zoneId = int(dnaGroup.getName().split(':')[0])
        for i in xrange(dnaGroup.getNumChildren()):
            (foundRacingPads, foundRacingPadGroups) = self.findRacingPads(dnaGroup.at(i), zoneId, area, padType=padType)
            racingPads.extend(foundRacingPads)
            racingPadGroups.extend(foundRacingPadGroups)
        return (racingPads, racingPadGroups)
 def calculateTrophies(self, avId, won, qualify, time):
     av = self.air.doId2do[avId]
     kartingHistory = av.getKartingHistory()
     avTrophies = av.getKartingTrophies()
     numTrophies = 0
     for i in xrange(30):
         if avTrophies[i] != 0:
             numTrophies += 1
     oldLaffBoost = int(numTrophies/10)
     genre = RaceGlobals.getTrackGenre(self.trackId)
     trophies = []
     if won:
         kartingHistory[genre] += 1
         kartingHistory[3] += 1
         if kartingHistory[3] > RaceGlobals.TotalWonRaces:
             avTrophies[RaceGlobals.TotalWins] = 1
             trophies.append(RaceGlobals.TotalWins)
         for i in xrange(3):
             if kartingHistory[genre] >= RaceGlobals.WonRaces[i] and avTrophies[RaceGlobals.AllWinsList[genre][i]] != 1:
                 avTrophies[RaceGlobals.AllWinsList[genre][i]] = 1
                 trophies.append(RaceGlobals.AllWinsList[genre][i])
     if qualify:
         kartingHistory[genre + 4] += 1
         kartingHistory[7] += 1
         if kartingHistory[7] >= RaceGlobals.TotalQualifiedRaces and avTrophies[RaceGlobals.TotalQuals] != 1:
             avTrophies[RaceGlobals.TotalQuals] = 1
             trophies.append(RaceGlobals.TotalQuals)
         for i in xrange(3):
             if kartingHistory[genre + 4] >= RaceGlobals.QualifiedRaces[i] and avTrophies[RaceGlobals.AllQualsList[genre][i]] != 1:
                 avTrophies[RaceGlobals.AllQualsList[genre][i]] = 1
                 trophies.append(RaceGlobals.AllQualsList[genre][i])
     for i, history in enumerate(kartingHistory):
         if history > 255:
             kartingHistory[i] = 255
     av.b_setKartingHistory(kartingHistory)
     pKartingBest = av.getKartingPersonalBestAll()
     trackIndex = TTLocalizer.KartRace_TrackNames.keys().index(self.trackId)
     if pKartingBest[trackIndex] > time or not pKartingBest[trackIndex]:
         pKartingBest[trackIndex] = time
         av.b_setKartingPersonalBest(pKartingBest)
     gTourTrophy = True
     for bestTime in pKartingBest:
         if not bestTime:
             gTourTrophy = False
     if gTourTrophy:
         if avTrophies[RaceGlobals.GrandTouring] != 1:
             avTrophies[RaceGlobals.GrandTouring] = 1
             trophies.append(RaceGlobals.GrandTouring)
     newLaffBoost = int((len(trophies) + numTrophies)/10)
     if newLaffBoost - oldLaffBoost != 0:
         for i in xrange(newLaffBoost):
             if avTrophies[RaceGlobals.TrophyCups[i]] != 1:
                 avTrophies[RaceGlobals.TrophyCups[i]] = 1
                 trophies.append(RaceGlobals.TrophyCups[i])
         av.b_setMaxHp(av.getMaxHp() + newLaffBoost - oldLaffBoost)
         av.toonUp(av.getMaxHp())
     av.b_setKartingTrophies(avTrophies)
     return trophies
 def updateTunnelSignText(self):
     self.notify.debugStateCall(self)
     trackNameString = TTLocalizer.KartRace_TrackNames[self.trackId]
     if not self.trackNameNode:
         self.notify.warning('invalid trackNameNode, just returning')
         return
     self.trackNameNode.setText(trackNameString)
     trackTypeString = TTLocalizer.KartRace_RaceNames[self.trackType]
     self.trackTypeNode.setText(trackTypeString)
     deposit = 0
     if self.trackType:
         deposit = RaceGlobals.getEntryFee(self.trackId, self.trackType)
     depositString = TTLocalizer.KartRace_DepositPhrase + str(deposit)
     self.depositNode.setText(depositString)
     time = RaceGlobals.TrackDict[self.trackId][1]
     secs, hundredths = divmod(time, 1)
     min, sec = divmod(secs, 60)
     timeText = '%02d:%02d:%02d' % (min, sec, hundredths * 100)
     qualifyString = TTLocalizer.KartRace_QualifyPhrase + timeText
     self.qualifyNode.setText(qualifyString)
 def requestEnter(self):
     avId = self.air.getAvatarIdFromSender()
     av = self.air.doId2do.get(avId)
     if not av:
         return
     if not av.hasKart():
         self.sendUpdateToAvatarId(avId, 'rejectEnter', [KartGlobals.ERROR_CODE.eNoKart])
         return
     if av.getTickets() < RaceGlobals.getEntryFee(self.pad.trackId, self.pad.trackType):
         self.sendUpdateToAvatarId(avId, 'rejectEnter', [KartGlobals.ERROR_CODE.eTickets])
         return
     if self.pad.state == 'AllAboard' or self.pad.state == 'WaitBoarding' :
         self.sendUpdateToAvatarId(avId, 'rejectEnter', [KartGlobals.ERROR_CODE.eBoardOver])
         return
     if self.avId != 0:
         if self.avId == avId:
             self.air.writeServerEvent('suspicious', avId, 'Toon tried to board the same starting block twice!')
         self.sendUpdateToAvatarId(avId, 'rejectEnter', [KartGlobals.ERROR_CODE.eOccupied])
         return
     self.b_setOccupied(avId)
     self.b_setMovie(KartGlobals.ENTER_MOVIE)
 def getTunnelSign(self):
     cPadId = RaceGlobals.RaceInfo2RacePadId(self.trackId, self.trackType)
     genreId = RaceGlobals.getTrackGenre(self.trackId)
     tunnelName = RaceGlobals.getTunnelSignName(genreId, cPadId)
     self.tunnelSign = self.cr.playGame.hood.loader.geom.find('**/' + tunnelName)
 def changeTrack(self):
     nri = RaceGlobals.getNextRaceInfo(self.trackId, self.nameType, self.index)
     self.b_setTrackInfo([nri[0], nri[1]])
     taskMgr.doMethodLater(30, DistributedRacePadAI.changeTrack, 'changeTrack%i' % self.doId, [self])