from direct.directnotify import DirectNotifyGlobal from toontown.racing import DistributedRaceAI from toontown.toonbase import ToontownGlobals, TTLocalizer from toontown.coghq import MintLayout from toontown.ai import HolidayBaseAI from direct.showbase import DirectObject from toontown.racing import RaceGlobals import os, pickle class RaceManagerAI(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory('RaceManagerAI') def __init__(self, air): DirectObject.DirectObject.__init__(self) self.air = air self.races = [] self.shard = str(air.districtId) self.filename = self.getFilename() self.trackRecords = self.loadRecords() def getDoId(self): return 0 def createRace(self, trackId, raceType, laps, players, circuitLoop, circuitPoints, circuitTimes, qualTimes=[], circuitTimeList={}, circuitTotalBonusTickets={}): raceZone = self.air.allocateZone() race = DistributedRaceAI.DistributedRaceAI(self.air, trackId, raceZone, players, laps, raceType, self.exitedRace, self.raceOver, circuitLoop, circuitPoints, circuitTimes, qualTimes, circuitTimeList, circuitTotalBonusTickets) race.generateWithRequired(raceZone) race.playersFinished = [] race.lastTotalTime = 0 self.races.append(race) return raceZone def exitedRace(self, race, playerInfo): self.notify.debug('exited race: %s' % playerInfo.avId) totalTime = playerInfo.totalTime entryFee = 0 bonus = 0 placeMultiplier = 0 qualify = 0 winnings = 0 trophies = [] points = [] newHistory = None race.playersFinished.append(playerInfo.avId) place = len(race.playersFinished) self.notify.debug('place: %s of %s' % (place, race.toonCount)) self.notify.debug('pre-tie totalTime: %s' % totalTime) if totalTime <= race.lastTotalTime: totalTime = race.lastTotalTime + 0.01 race.lastTotalTime = totalTime self.notify.debug('totalTime: %s, qualify: %s' % (totalTime, RaceGlobals.getQualifyingTime(race.trackId))) circuitTime = totalTime + race.circuitTimes.get(playerInfo.avId, 0) race.circuitTimes[playerInfo.avId] = circuitTime if not race.circuitTimeList.get(playerInfo.avId): race.circuitTimeList[playerInfo.avId] = [] race.circuitTimeList[playerInfo.avId].append([totalTime, 0]) self.notify.debug('CircuitTimeList %s' % race.circuitTimeList) if race.raceType == RaceGlobals.Circuit: points = race.circuitPoints.get(playerInfo.avId, []) points.append(RaceGlobals.CircuitPoints[place - 1]) race.circuitPoints[playerInfo.avId] = points currentTimeIndex = len(race.circuitTimeList[playerInfo.avId]) - 1 if totalTime <= RaceGlobals.getQualifyingTime(race.trackId): race.circuitTimeList[playerInfo.avId][currentTimeIndex][1] = 1 self.notify.debug('Racer Qualified time: %s required: %s' % (totalTime, RaceGlobals.getQualifyingTime(race.trackId))) qualify = 1 self.checkPersonalBest(race.trackId, totalTime, race.raceType, race.toonCount, playerInfo.avId) if race.raceType == RaceGlobals.Practice: winnings = RaceGlobals.PracticeWinnings self.notify.debug('GrandTouring: Checking from branch: practice %s' % playerInfo.avId) trophies = self.checkForNonRaceTrophies(playerInfo.avId) if trophies: self.updateTrophiesFromList(playerInfo.avId, trophies) else: self.air.writeServerEvent('kartingPlaced', playerInfo.avId, '%s|%s' % (place, race.toonCount)) if race.raceType != RaceGlobals.Circuit: entryFee = RaceGlobals.getEntryFee(race.trackId, race.raceType) placeMultiplier = RaceGlobals.Winnings[place - 1 + (RaceGlobals.MaxRacers - race.toonCount)] winnings = int(entryFee * placeMultiplier) newHistory = self.getNewSingleRaceHistory(race, playerInfo.avId, place) av = self.air.doId2do.get(playerInfo.avId) if newHistory: self.notify.debug('history %s' % newHistory) av.b_setKartingHistory(newHistory) trophies = self.checkForRaceTrophies(race, playerInfo.avId) else: trophies = self.checkForNonRaceTrophies(playerInfo.avId) if trophies: self.updateTrophiesFromList(playerInfo.avId, trophies) bonus = self.checkTimeRecord(race.trackId, totalTime, race.raceType, race.toonCount, playerInfo.avId) if playerInfo.avId in race.circuitTotalBonusTickets: race.circuitTotalBonusTickets[playerInfo.avId] += bonus else: race.circuitTotalBonusTickets[playerInfo.avId] = bonus av = self.air.doId2do.get(playerInfo.avId) if av: oldTickets = av.getTickets() self.notify.debug('old tickets: %s' % oldTickets) newTickets = oldTickets + winnings + entryFee + bonus self.air.writeServerEvent('kartingTicketsWon', playerInfo.avId, '%s' % (newTickets - oldTickets)) self.notify.debug('entry fee: %s' % entryFee) self.notify.debug('place mult: %s' % placeMultiplier) self.notify.debug('winnings: %s' % winnings) self.notify.debug('bonus: %s' % bonus) self.notify.debug('new tickets: %s' % newTickets) self.notify.debug('circuit points: %s' % points) self.notify.debug('circuit time: %s' % circuitTime) self.notify.debug('circuitTotalBonusTickets: %s' % race.circuitTotalBonusTickets) av.b_setTickets(newTickets) else: race.circuitTimeList[playerInfo.avId][currentTimeIndex][1] = -1 self.notify.debug('GrandTouring: Checking from branch: Not Qualified %s' % playerInfo.avId) trophies = self.checkForNonRaceTrophies(playerInfo.avId) if trophies: self.updateTrophiesFromList(playerInfo.avId, trophies) if race in self.races: race.d_setPlace(playerInfo.avId, totalTime, place, entryFee, qualify, winnings, bonus, trophies, points, circuitTime) if race.isCircuit(): self.notify.debug('isCircuit') if race.everyoneDone(): self.notify.debug('everyoneDone') if race.isLastRace(): taskMgr.doMethodLater(10, self.endCircuitRace, 'DelayEndCircuitRace=%d' % race.doId, (race, bonus)) else: self.endCircuitRace(race, bonus) else: self.notify.debug('not isCircuit') return def endCircuitRace(self, race, bonus=0): self.notify.debug('endCircuitRace') pointTotals = [] for avId in race.circuitPoints: pointTotals.append([avId, sum(race.circuitPoints[avId])]) numVals = len(pointTotals) finalStandings = [] def swap(x, y): t = pointTotals[x] pointTotals[x] = pointTotals[y] pointTotals[y] = t for i in range(numVals - 1, 0, -1): for j in range(i): if pointTotals[j][1] < pointTotals[j + 1][1]: swap(j, j + 1) elif pointTotals[j][1] == pointTotals[j + 1][1]: avId1 = pointTotals[j][0] avId2 = pointTotals[j + 1][0] if race.circuitTimes[avId1] > race.circuitTimes[avId2]: swap(j, j + 1) for i in range(numVals): finalStandings.append(pointTotals[i][0]) self.notify.debug('Final standings %s' % finalStandings) for avId in finalStandings: self.notify.debug('avId %s' % avId) place = finalStandings.index(avId) + 1 places = len(finalStandings) winnings = 0 trophies = [] if race.isLastRace(): self.notify.debug('isLastRace') av = self.air.doId2do.get(avId) if av and avId in race.playersFinished: self.air.writeServerEvent('kartingCircuitFinished', avId, '%s|%s' % (place, places)) print('kartingCircuitFinished', avId, '%s|%s' % (place, places)) entryFee = RaceGlobals.getEntryFee(race.trackId, race.raceType) placeMultiplier = RaceGlobals.Winnings[place - 1 + (RaceGlobals.MaxRacers - places)] winnings = int(entryFee * placeMultiplier) newHistory = self.getNewCircuitHistory(race, avId, place) if newHistory: self.notify.debug('history %s' % newHistory) trophies = self.checkForCircuitTrophies(race, avId, newHistory) av.b_setKartingHistory(newHistory) if trophies: self.updateTrophiesFromList(avId, trophies) else: self.notify.debug('no new history') trophies = self.checkForNonRaceTrophies(avId) oldTickets = av.getTickets() self.notify.debug('endCircuitRace: old tickets: %s' % oldTickets) newTickets = oldTickets + winnings + entryFee self.air.writeServerEvent('kartingTicketsWonCircuit', avId, '%s' % (newTickets - oldTickets)) self.notify.debug('entry fee: %s' % entryFee) self.notify.debug('place mult: %s' % placeMultiplier) self.notify.debug('winnings: %s' % winnings) self.notify.debug('new tickets: %s' % newTickets) self.notify.debug('trophies: %s' % trophies) self.notify.debug('bonus: %s' % bonus) av.b_setTickets(newTickets) finalBonus = 0 if avId in race.circuitTotalBonusTickets: finalBonus = race.circuitTotalBonusTickets[avId] race.d_setCircuitPlace(avId, place, entryFee, winnings, finalBonus, trophies) race.playersFinished = finalStandings race.d_endCircuitRace() def updateTrophiesFromList(self, avId, trophies): self.air.writeServerEvent('Writing Trophies: Updating trophies from list', avId, '%s' % trophies) av = self.air.doId2do.get(avId) if not av: return if not trophies: return trophyField = av.getKartingTrophies() for trophy in trophies: trophyField[trophy] = 1 av.b_setKartingTrophies(trophyField) def checkForCircuitTrophies(self, race, avId, inHistory=None): av = self.air.doId2do.get(avId) if not av: return [] trophies = av.getKartingTrophies() if inHistory: history = inHistory else: history = av.getKartingHistory() winIndex = RaceGlobals.CircuitWins winReqList = RaceGlobals.WonCircuitRaces winIndices = RaceGlobals.CircuitWinsList sweepIndex = RaceGlobals.CircuitSweeps sweepReqList = RaceGlobals.SweptCircuitRaces sweepIndices = RaceGlobals.CircuitSweepsList qualIndex = RaceGlobals.CircuitQuals qualReqList = RaceGlobals.QualifiedCircuitRaces qualIndices = RaceGlobals.CircuitQualList trophies = av.getKartingTrophies() newTrophies = [] newTrophies.extend(self.checkHistoryForTrophy(trophies, history, winIndex, winReqList, winIndices)) newTrophies.extend(self.checkHistoryForTrophy(trophies, history, sweepIndex, sweepReqList, sweepIndices)) newTrophies.extend(self.checkHistoryForTrophy(trophies, history, qualIndex, qualReqList, qualIndices)) self.notify.debug('GrandTouring: Checking from branch: Circuit %s' % avId) newTrophies.extend(self.checkForNonRaceTrophies(avId, history)) newTrophies.sort() return newTrophies def checkForRaceTrophies(self, race, avId, inHistory=None): av = self.air.doId2do.get(avId) if not av: return [] trophies = av.getKartingTrophies() if inHistory: history = inHistory else: history = av.getKartingHistory() newTrophies = [] numTrackGenres = len(RaceGlobals.WinsList) for genre in range(numTrackGenres): singleGenreNewTrophies = self.checkHistoryForTrophy(trophies, history, RaceGlobals.WinsList[genre], RaceGlobals.WonRaces, RaceGlobals.AllWinsList[genre]) newTrophies.extend(singleGenreNewTrophies) numTrackGenres = len(RaceGlobals.QualsList) for genre in range(numTrackGenres): singleGenreNewTrophies = self.checkHistoryForTrophy(trophies, history, RaceGlobals.QualsList[genre], RaceGlobals.QualifiedRaces, RaceGlobals.AllQualsList[genre]) newTrophies.extend(singleGenreNewTrophies) totalWins = 0 for genre in range(numTrackGenres): totalWins += history[RaceGlobals.WinsList[genre]] singleGenreNewTrophies = self.checkHistoryForTrophyByValue(trophies, history, totalWins, [ RaceGlobals.TotalWonRaces], [ RaceGlobals.TotalWins]) newTrophies.extend(singleGenreNewTrophies) totalQuals = 0 for genre in range(numTrackGenres): totalQuals += history[RaceGlobals.QualsList[genre]] singleGenreNewTrophies = self.checkHistoryForTrophyByValue(trophies, history, totalQuals, [ RaceGlobals.TotalQualifiedRaces], [ RaceGlobals.TotalQuals]) newTrophies.extend(singleGenreNewTrophies) self.notify.debug('GrandTouring: Checking from branch: Race %s ' % avId) newTrophies.extend(self.checkForNonRaceTrophies(avId, history)) newTrophies.sort() return newTrophies def checkForNonRaceTrophies(self, avId, inHistory=None): self.notify.debug('CHECKING FOR NONRACE TROPHIES') self.notify.debug('GrandTouring: Checking for non-race trophies %s' % avId) av = self.air.doId2do.get(avId) if not av: self.notify.debug('NO AV %s' % avId) self.notify.debug("GrandTouring: can't convert avId to Av %s" % avId) return [] trophies = av.getKartingTrophies() if inHistory: history = inHistory else: history = av.getKartingHistory() newTrophies = [] self.notify.debug('GrandTouring: history-- %s' % history) self.notify.debug('GrandTouring: trophies- %s' % trophies) addTrophyCount = 0 if not trophies[RaceGlobals.GrandTouring]: self.notify.debug('checking for grand touring') self.notify.debug('GrandTouring: checking for grand touring %s' % trophies[RaceGlobals.GrandTouring]) best = av.getKartingPersonalBestAll() self.notify.debug('personal best %s' % best) self.notify.debug('GrandTouring: checking personal best %s' % best) counter = 0 for time in best: if not time == 0: counter += 1 self.notify.debug('counter %s tracks %s' % (counter, len(RaceGlobals.TrackDict))) self.notify.debug('GrandTouring: bests comparison counter: %s tracks: %s' % (counter, len(RaceGlobals.TrackDict))) if counter >= len(RaceGlobals.TrackDict): newTrophies.append(RaceGlobals.GrandTouring) addTrophyCount += 1 self.air.writeServerEvent('kartingTrophy', avId, '%s' % RaceGlobals.GrandTouring) self.notify.debug('trophy: ' + TTLocalizer.KartTrophyDescriptions[RaceGlobals.GrandTouring]) self.notify.debug('GrandTouring: awarding grand touring new trophies %s' % newTrophies) else: self.notify.debug('already has grandtouring') self.notify.debug('trophies %s' % trophies) self.notify.debug('GrandTouring: already has grand touring %s' % trophies[RaceGlobals.GrandTouring]) for i in range(1, RaceGlobals.NumTrophies // RaceGlobals.TrophiesPerCup + 1): cupNum = (trophies[:RaceGlobals.NumTrophies].count(1) + addTrophyCount) // (i * RaceGlobals.TrophiesPerCup) self.notify.debug('cupNum: %s' % cupNum) trophyIndex = RaceGlobals.TrophyCups[i - 1] if cupNum and not trophies[trophyIndex]: newTrophies.append(trophyIndex) oldMaxHp = av.getMaxHp() newMaxHp = min(ToontownGlobals.MaxHpLimit, oldMaxHp + 1) self.notify.debug('cup awarded! new max laff : %s' % newMaxHp) av.b_setMaxHp(newMaxHp) av.toonUp(newMaxHp) self.air.writeServerEvent('kartingTrophy', avId, '%s' % trophyIndex) self.notify.debug('trophy: ' + TTLocalizer.KartTrophyDescriptions[trophyIndex]) self.notify.debug('NONRACE TROPHIES %s' % newTrophies) return newTrophies def checkHistoryForTrophyByValue(self, trophies, history, historyIndexValue, trophyReqList, trophyIndices): newTrophies = [] self.notify.debug('Checking History for Trophy') self.notify.debug('Index %s Num %s ReqList %s Indices %s' % (0, historyIndexValue, trophyReqList, trophyIndices)) for index in range(len(trophyIndices)): if not trophies[trophyIndices[index]]: if historyIndexValue >= trophyReqList[index]: trophies[trophyIndices[index]] = 1 newTrophies.append(trophyIndices[index]) return newTrophies def checkHistoryForTrophy(self, trophies, history, historyIndex, trophyReqList, trophyIndices): newTrophies = [] self.notify.debug('Checking History for Trophy') self.notify.debug('Index %s Num %s ReqList %s Indices %s' % (historyIndex, history[historyIndex], trophyReqList, trophyIndices)) for index in range(len(trophyIndices)): if not trophies[trophyIndices[index]]: if history[historyIndex] >= trophyReqList[index]: trophies[trophyIndices[index]] = 1 newTrophies.append(trophyIndices[index]) return newTrophies def mergeHistories(self, historyA, historyB): newHistorySize = len(historyA) if len(historyB) > len(historyA): newHistorySize = historyB mergedHistory = [] for index in range(newHistorySize): mergedHistory[index] = 0 if len(historyA) > index: if historyA[index] > mergedHistory[index]: historyA[index] = mergedHistory[index] if len(historyB) > index: if historyB[index] > mergedHistory[index]: historyB[index] = mergedHistory[index] return mergedHistory def getNewSingleRaceHistory(self, race, avId, positionFinished): newHistory = 0 av = self.air.doId2do.get(avId) if not av: return [] history = av.getKartingHistory() trackGenre = RaceGlobals.getTrackGenre(race.trackId) winIndex = RaceGlobals.WinsList[trackGenre] winReqList = RaceGlobals.WonRaces qualIndex = RaceGlobals.QualsList[trackGenre] qualReqList = RaceGlobals.QualifiedRaces if history[winIndex] < winReqList[-1] and positionFinished == 1: history[winIndex] += 1 self.notify.debug('New History Won!') newHistory = 1 if history[qualIndex] < qualReqList[-1]: history[qualIndex] += 1 self.notify.debug('New History Qualified!') newHistory = 1 if newHistory: return history def getNewCircuitHistory(self, race, avId, positionFinished): newHistory = 0 av = self.air.doId2do.get(avId) if not av: return [] history = av.getKartingHistory() trackGenre = RaceGlobals.getTrackGenre(race.trackId) historyIndex = RaceGlobals.CircuitWins trophyReqList = RaceGlobals.WonCircuitRaces sweepIndices = RaceGlobals.CircuitSweepsList sweepReqList = RaceGlobals.SweptCircuitRaces self.notify.debug('getNewCircuitHistory: avId=%d positionFinished=%d history =%s' % (avId, positionFinished, history)) if history[historyIndex] < trophyReqList[-1] and positionFinished == 1: history[historyIndex] += 1 self.notify.debug('New History Won!') newHistory = 1 swept = 0 totalPoints = sum(race.circuitPoints[avId]) if totalPoints == len(race.circuitPoints[avId]) * RaceGlobals.CircuitPoints[0]: swept = 1 if swept: if history[RaceGlobals.CircuitSweeps] < sweepReqList[-1]: if not history[RaceGlobals.CircuitSweeps]: history[RaceGlobals.CircuitSweeps] = 0 history[RaceGlobals.CircuitSweeps] += 1 self.notify.debug('New History Swept!') newHistory = 1 qualified = 0 self.notify.debug('qual times %s' % race.qualTimes) self.notify.debug('avatar times %s' % race.circuitTimeList[avId]) qualified = 1 self.notify.debug('End Race Circuit Time List %s' % race.circuitTimeList) self.notify.debug('check for qualify') for qual in race.circuitTimeList[avId]: self.notify.debug('qual %s' % qual) if qual[1] == -1: qualified = 0 self.notify.debug('not qualified') if qualified: self.notify.debug('qualified has %s needs %s' % (history[RaceGlobals.CircuitQuals], RaceGlobals.QualifiedCircuitRaces[-1])) if history[RaceGlobals.CircuitQuals] < RaceGlobals.QualifiedCircuitRaces[-1]: history[RaceGlobals.CircuitQuals] += 1 self.notify.debug('New History qualified!') newHistory = 1 if newHistory: return history def raceOver(self, race, normalExit=True): if race in self.races: if normalExit and race.isCircuit() and not race.isLastRace(): nextTrackId = race.circuitLoop[0] continuingAvs = [] for avId in race.avIds: if avId not in race.kickedAvIds: continuingAvs.append(avId) lastRace = False if len(continuingAvs) > 0: raceZone = self.createRace(nextTrackId, race.raceType, race.lapCount, continuingAvs, race.circuitLoop[1:], race.circuitPoints, race.circuitTimes, race.qualTimes, race.circuitTimeList, race.circuitTotalBonusTickets) race.sendToonsToNextCircuitRace(raceZone, nextTrackId) else: lastRace = True self.races.remove(race) race.requestDelete(lastRace) else: self.races.remove(race) race.requestDelete() def checkForTrophies(self, place, trackId, raceType, numRacers, avId): av = self.air.doId2do.get(avId) outHistory = av.getKartingHistory() trophies = av.getKartingTrophies() trophiesWon = [] trackGenre = RaceGlobals.getTrackGenre(trackId) if place == 1: historyIndex = RaceGlobals.WinsList[trackGenre] trophyIndices = RaceGlobals.AllWinsList[trackGenre] trophyReqList = RaceGlobals.WonRaces historyTotalList = RaceGlobals.WinsList totalTrophyIndex = RaceGlobals.TotalWins totalReq = RaceGlobals.TotalWonRaces trophiesWon += self.checkForTrophy(place, trackId, raceType, numRacers, avId, historyIndex, trophyIndices, trophyReqList, historyTotalList, totalTrophyIndex, totalReq) historyIndex = RaceGlobals.QualsList[trackGenre] trophyIndices = RaceGlobals.AllQualsList[trackGenre] trophyReqList = RaceGlobals.QualifiedRaces historyTotalList = RaceGlobals.QualsList totalTrophyIndex = RaceGlobals.TotalQuals totalReq = RaceGlobals.TotalQualifiedRaces trophiesWon += self.checkForTrophy(place, trackId, raceType, numRacers, avId, historyIndex, trophyIndices, trophyReqList, historyTotalList, totalTrophyIndex, totalReq) if not trophies[RaceGlobals.GrandTouring]: self.notify.debug('checking for grand touring') best = av.getKartingPersonalBestAll() self.notify.debug('personal best %s' % best) counter = 0 for time in best: if not time == 0: counter += 1 self.notify.debug('counter %s tracks %s' % (counter, len(RaceGlobals.TrackDict))) if counter >= len(RaceGlobals.TrackDict): trophiesWon.append(RaceGlobals.GrandTouring) if outHistory: av.b_setKartingHistory(outHistory) if len(trophiesWon): for trophy in trophiesWon: trophies[trophy] = 1 av.b_setKartingTrophies(trophies) trophiesWon.sort() return trophiesWon def checkForTrophy(self, place, trackId, raceType, numRacers, avId, historyIndex, trophyIndices, trophyReqList, historyTotalList, totalTrophyIndex, totalReq): av = self.air.doId2do.get(avId) if not av: return [] history = av.getKartingHistory() newHistory = 0 trophies = av.getKartingTrophies() newTrophies = [] if history[historyIndex] < trophyReqList[-1]: history[historyIndex] += 1 newHistory = 1 for i in range(0, len(trophyReqList)): if not trophies[trophyIndices[i]]: if history[historyIndex] == trophyReqList[i]: trophies[trophyIndices[i]] = 1 newTrophies.append(trophyIndices[i]) self.air.writeServerEvent('kartingTrophy', avId, '%s' % trophyIndices[i]) self.notify.debug('trophy: ' + TTLocalizer.KartTrophyDescriptions[trophyIndices[i]]) break if not raceType == RaceGlobals.Circuit: if not trophies[totalTrophyIndex]: total = 0 for i in historyTotalList: total += history[i] self.notify.debug('checking for total trophy: %s >= %s' % (total, totalReq)) if total >= totalReq: trophies[totalTrophyIndex] = 1 newTrophies.append(totalTrophyIndex) self.air.writeServerEvent('kartingTrophy', avId, '%s' % totalTrophyIndex) self.notify.debug('trophy: ' + TTLocalizer.KartTrophyDescriptions[totalTrophyIndex]) for i in range(1, RaceGlobals.NumTrophies // RaceGlobals.TrophiesPerCup + 1): cupNum = trophies[:RaceGlobals.NumTrophies].count(1) // (i * RaceGlobals.TrophiesPerCup) self.notify.debug('cupNum: %s' % cupNum) trophyIndex = RaceGlobals.TrophyCups[i - 1] if cupNum and not trophies[trophyIndex]: trophies[trophyIndex] = 1 newTrophies.append(trophyIndex) oldMaxHp = av.getMaxHp() newMaxHp = min(ToontownGlobals.MaxHpLimit, oldMaxHp + 1) self.notify.debug('cup awarded! new max laff : %s' % newMaxHp) av.b_setMaxHp(newMaxHp) av.toonUp(newMaxHp) self.air.writeServerEvent('kartingTrophy', avId, '%s' % trophyIndex) self.notify.debug('trophy: ' + TTLocalizer.KartTrophyDescriptions[trophyIndex]) self.notify.debug('newTrophies: %s' % newTrophies) self.notify.debug('trophies: %s' % trophies) self.notify.debug('kartingHistory: %s' % history) if newHistory: av.b_setKartingHistory(history) return newTrophies def checkPersonalBest(self, trackId, time, raceType, numRacers, avId): av = simbase.air.doId2do.get(avId) if av: bestTimes = av.getKartingPersonalBestAll() trackIndex = RaceGlobals.TrackIds.index(trackId) bestTime = bestTimes[trackIndex] self.notify.debug('thisTime: %s, bestTime: %s' % (time, bestTime)) if bestTime == 0.0 or time < bestTime: bestTimes[trackIndex] = time self.notify.debug('new personal best!') av.b_setKartingPersonalBest(bestTimes) self.notify.debug('personal best: %s' % bestTimes) def checkTimeRecord(self, trackId, time, raceType, numRacers, avId): bonus = 0 newRecord = 0 for period in RaceGlobals.PeriodIds: for record in range(0, RaceGlobals.NumRecordsPerPeriod): recordTime = self.trackRecords[trackId][period][record][0] if time < recordTime: newRecord = 1 self.notify.debug('new %s record!' % TTLocalizer.RecordPeriodStrings[period]) av = simbase.air.doId2do.get(avId) if av: name = av.name self.trackRecords[trackId][period].insert(record, (time, raceType, numRacers, name)) self.trackRecords[trackId][period] = self.trackRecords[trackId][period][:RaceGlobals.NumRecordsPerPeriod] self.updateLeaderboards(trackId, period) bonus = RaceGlobals.PeriodDict[period] self.air.writeServerEvent('kartingRecord', avId, '%s|%s|%s' % (period, trackId, time)) else: self.notify.warning('warning: av not logged in!') break if newRecord: self.updateRecordFile() return bonus def updateRecordFile(self): try: backup = self.filename + '.bu' if os.path.exists(self.filename): os.rename(self.filename, backup) file = open(self.filename, 'wb') file.seek(0) pickle.dump(self.trackRecords, file) file.close() if os.path.exists(backup): os.remove(backup) except EnvironmentError: self.notify.warning(str(sys.exc_info()[1])) def getFilename(self): return '%s%s.trackRecords' % (self.air.dataFolder, self.shard) def loadRecords(self): try: file = open(self.filename + '.bu', 'rb') if os.path.exists(self.filename): os.remove(self.filename) except IOError: try: file = open(self.filename, 'rb') except IOError: return self.getRecordTimes() file.seek(0) records = self.loadFrom(file) file.close() for trackId in RaceGlobals.TrackIds: if trackId not in records: records[trackId] = {} for i in RaceGlobals.PeriodIds: records[trackId][i] = [] for j in range(0, RaceGlobals.NumRecordsPerPeriod): records[trackId][i].append(RaceGlobals.getDefaultRecord(trackId)) self.resetLeaderboards() return records def loadFrom(self, file): records = {} try: while 1: records = pickle.load(file) except EOFError: pass return records def getRecordTimes(self): records = {} for trackId in RaceGlobals.TrackIds: records[trackId] = {} for i in RaceGlobals.PeriodIds: records[trackId][i] = [] for j in range(0, RaceGlobals.NumRecordsPerPeriod): records[trackId][i].append(RaceGlobals.getDefaultRecord(trackId)) return records def resetRecordPeriod(self, period): for trackId in RaceGlobals.TrackIds: for i in range(0, RaceGlobals.NumRecordsPerPeriod): self.trackRecords[trackId][period][i] = RaceGlobals.getDefaultRecord(trackId) self.updateLeaderboards(trackId, period) self.updateRecordFile() def getRecords(self, trackId, period): return self.trackRecords[trackId][period] def updateLeaderboards(self, trackId, period): messenger.send('UpdateRaceRecord', [(trackId, period)]) def resetLeaderboards(self): for track in RaceGlobals.TrackIds: for period in RaceGlobals.PeriodIds: self.updateLeaderboards(track, period) class KartRecordDailyResetter(HolidayBaseAI.HolidayBaseAI): notify = DirectNotifyGlobal.directNotify.newCategory('ResistanceEventMgrAI') PostName = 'kertRecordDailyReset' def __init__(self, air, holidayId): HolidayBaseAI.HolidayBaseAI.__init__(self, air, holidayId) def start(self): bboard.post(KartRecordDailyResetter.PostName) simbase.air.raceMgr.resetRecordPeriod(RaceGlobals.Daily) def stop(self): bboard.remove(KartRecordDailyResetter.PostName) class KartRecordWeeklyResetter(HolidayBaseAI.HolidayBaseAI): notify = DirectNotifyGlobal.directNotify.newCategory('ResistanceEventMgrAI') PostName = 'kartRecordWeeklyReset' def __init__(self, air, holidayId): HolidayBaseAI.HolidayBaseAI.__init__(self, air, holidayId) def start(self): bboard.post(KartRecordWeeklyResetter.PostName) simbase.air.raceMgr.resetRecordPeriod(RaceGlobals.Weekly) def stop(self): bboard.remove(KartRecordWeeklyResetter.PostName) class CircuitRaceHolidayMgr(HolidayBaseAI.HolidayBaseAI): notify = DirectNotifyGlobal.directNotify.newCategory('CircuitRaceHolidayMgr') PostName = 'CircuitRaceHoliday' StartStopMsg = 'CircuitRaceHolidayStartStop' def __init__(self, air, holidayId): HolidayBaseAI.HolidayBaseAI.__init__(self, air, holidayId) def start(self): bboard.post(CircuitRaceHolidayMgr.PostName, True) simbase.air.newsManager.circuitRaceStart() messenger.send(CircuitRaceHolidayMgr.StartStopMsg) def stop(self): bboard.remove(CircuitRaceHolidayMgr.PostName) simbase.air.newsManager.circuitRaceEnd() messenger.send(CircuitRaceHolidayMgr.StartStopMsg)