from direct.directnotify.DirectNotifyGlobal import * from direct.distributed.DistributedObjectAI import DistributedObjectAI MAX_LISTING = 10 AV_ID_INDEX = 0 NAME_INDEX = 1 SCORE_INDEX = 2 class DistributedTrophyMgrAI(DistributedObjectAI): notify = directNotify.newCategory('DistributedTrophyMgrAI') def __init__(self, air): DistributedObjectAI.__init__(self, air) # Load the leaderboard backup for this shard: self.leaderInfo, self.trophyScores = simbase.backups.load( 'trophy-mgr', (simbase.air.districtId,), default=(([], [], []), {})) def requestTrophyScore(self): avId = self.air.getAvatarIdFromSender() av = self.air.doId2do.get(avId) if av is not None: av.d_setTrophyScore(self.trophyScores.get(avId, 0)) def addTrophy(self, avId, name, numFloors): if avId not in self.trophyScores: self.trophyScores[avId] = 0 trophyScore = self.trophyScores[avId] + numFloors self.updateTrophyScore(avId, trophyScore) def removeTrophy(self, avId, numFloors): if avId in self.trophyScores: trophyScore = self.trophyScores[avId] - numFloors self.updateTrophyScore(avId, trophyScore) def updateTrophyScore(self, avId, trophyScore): av = self.air.doId2do.get(avId) if trophyScore <= 0: # Take the player off the listing: if avId in self.trophyScores: del self.trophyScores[avId] if avId in self.leaderInfo[AV_ID_INDEX]: scoreIndex = self.leaderInfo[AV_ID_INDEX].index(avId) del self.leaderInfo[AV_ID_INDEX][scoreIndex] del self.leaderInfo[NAME_INDEX][scoreIndex] del self.leaderInfo[SCORE_INDEX][scoreIndex] else: # Add the player to the listing if they haven't been. Otherwise, # update their current trophy score: self.trophyScores[avId] = trophyScore if avId not in self.leaderInfo[AV_ID_INDEX]: if av is None: return self.leaderInfo[AV_ID_INDEX].append(avId) self.leaderInfo[NAME_INDEX].append(av.getName()) self.leaderInfo[SCORE_INDEX].append(trophyScore) else: scoreIndex = self.leaderInfo[AV_ID_INDEX].index(avId) self.leaderInfo[SCORE_INDEX][scoreIndex] = trophyScore # Truncate and reorganize the listing: self.reorganize() # Update the listing in the various Toon HQs: messenger.send('leaderboardChanged') messenger.send('leaderboardFlush') if av is not None: av.d_setTrophyScore(trophyScore) simbase.backups.save('trophy-mgr', (simbase.air.districtId,), (self.leaderInfo, self.trophyScores)) def reorganize(self): # Sort the leader info: leaderInfo = zip(*reversed(self.leaderInfo)) leaderInfo.sort(reverse=True) # Construct the new, truncated leader info: self.leaderInfo = [[], [], []] for trophyScore, name, avId in leaderInfo[:MAX_LISTING]: self.leaderInfo[AV_ID_INDEX].append(avId) self.leaderInfo[NAME_INDEX].append(name) self.leaderInfo[SCORE_INDEX].append(trophyScore) def getLeaderInfo(self): return self.leaderInfo