91 lines
3.3 KiB
Python
91 lines
3.3 KiB
Python
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
|