def enterScoreMatch(self): sortedByDistance = [] for avId in self.avIdList: index = self.avIdList.index(avId) pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoresAsList = [] totalPointsAdded = 0 for index in xrange(len(self.avIdList)): pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) length = pos.length() points = length / IceGameGlobals.FarthestLength * (IceGameGlobals.PointsInCorner - IceGameGlobals.PointsDeadCenter[self.numPlayers]) points += IceGameGlobals.PointsDeadCenter[self.numPlayers] self.notify.debug('length = %s points=%s avId=%d' % (length, points, avId)) avId = self.avIdList[index] bonusIndex = 0 for sortIndex in xrange(len(sortedByDistance)): if sortedByDistance[sortIndex][0] == avId: bonusIndex = sortIndex bonusIndex += 4 - len(self.avIdList) pointsToAdd = int(points + 0.5) + IceGameGlobals.BonusPointsForPlace[bonusIndex] totalPointsAdded += pointsToAdd self.scoreDict[avId] += pointsToAdd self.scoresAsList.append(self.scoreDict[avId]) self.curMatch += 1 self.curRound = 0 self.sendUpdate('setScores', [self.curMatch, self.curRound, self.scoresAsList]) self.sendUpdate('setNewState', ['scoring']) def allToonsScoringMovieDone(self = self): self.notify.debug('allToonsScoringMovieDone') if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') def handleTimeout(avIds, self = self): self.notify.debug('handleTimeout: avatars %s did not report "done"' % avIds) if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') scoreMovieDuration = IceGameGlobals.FarthestLength * IceGameGlobals.ExpandFeetPerSec scoreMovieDuration += totalPointsAdded * IceGameGlobals.ScoreCountUpRate self.scoringMovieDoneBarrier = ToonBarrier('waitScoringMovieDone', self.uniqueName('waitScoringMovieDone'), self.avIdList, scoreMovieDuration + MinigameGlobals.latencyTolerance, allToonsScoringMovieDone, handleTimeout)
def enterScoreMatch(self): sortedByDistance = [] for avId in self.avIdList: index = self.avIdList.index(avId) pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoresAsList = [] totalPointsAdded = 0 for index in xrange(len(self.avIdList)): pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) length = pos.length() points = length / IceGameGlobals.FarthestLength * ( IceGameGlobals.PointsInCorner - IceGameGlobals.PointsDeadCenter[self.numPlayers]) points += IceGameGlobals.PointsDeadCenter[self.numPlayers] self.notify.debug('length = %s points=%s avId=%d' % (length, points, avId)) avId = self.avIdList[index] bonusIndex = 0 for sortIndex in xrange(len(sortedByDistance)): if sortedByDistance[sortIndex][0] == avId: bonusIndex = sortIndex bonusIndex += 4 - len(self.avIdList) pointsToAdd = int( points + 0.5) + IceGameGlobals.BonusPointsForPlace[bonusIndex] totalPointsAdded += pointsToAdd self.scoreDict[avId] += pointsToAdd self.scoresAsList.append(self.scoreDict[avId]) self.curMatch += 1 self.curRound = 0 self.sendUpdate('setScores', [self.curMatch, self.curRound, self.scoresAsList]) self.sendUpdate('setNewState', ['scoring']) def allToonsScoringMovieDone(self=self): self.notify.debug('allToonsScoringMovieDone') if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') def handleTimeout(avIds, self=self): self.notify.debug( 'handleTimeout: avatars %s did not report "done"' % avIds) if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') scoreMovieDuration = IceGameGlobals.FarthestLength * IceGameGlobals.ExpandFeetPerSec scoreMovieDuration += totalPointsAdded * IceGameGlobals.ScoreCountUpRate self.scoringMovieDoneBarrier = ToonBarrier( 'waitScoringMovieDone', self.uniqueName('waitScoringMovieDone'), self.avIdList, scoreMovieDuration + MinigameGlobals.latencyTolerance, allToonsScoringMovieDone, handleTimeout)
class DistributedIceGameAI(DistributedMinigameAI.DistributedMinigameAI): notify = directNotify.newCategory('DistributedIceGameAI') def __init__(self, air, minigameId): try: self.DistributedIceGameAI_initialized except: self.DistributedIceGameAI_initialized = 1 DistributedMinigameAI.DistributedMinigameAI.__init__( self, air, minigameId) self.gameFSM = ClassicFSM.ClassicFSM('DistributedIceGameAI', [ State.State('off', self.enterOff, self.exitOff, ['waitClientsChoices']), State.State('waitClientsChoices', self.enterWaitClientsChoices, self.exitWaitClientsChoices, ['cleanup', 'processChoices']), State.State('processChoices', self.enterProcessChoices, self.exitProcessChoices, ['waitEndingPositions', 'cleanup']), State.State('waitEndingPositions', self.enterWaitEndingPositions, self.exitWaitEndingPositions, ['processEndingPositions', 'cleanup']), State.State('processEndingPositions', self.enterProcessEndingPositions, self.exitProcessEndingPositions, ['waitClientsChoices', 'scoreMatch', 'cleanup']), State.State('scoreMatch', self.enterScoreMatch, self.exitScoreMatch, ['waitClientsChoices', 'finalResults', 'cleanup']), State.State('finalResults', self.enterFinalResults, self.exitFinalResults, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, ['off']) ], 'off', 'off') self.addChildGameFSM(self.gameFSM) self.avatarChoices = {} self.avatarEndingPositions = {} self.curRound = 0 self.curMatch = 0 self.finalEndingPositions = [ Point3(IceGameGlobals.StartingPositions[0]), Point3(IceGameGlobals.StartingPositions[1]), Point3(IceGameGlobals.StartingPositions[2]), Point3(IceGameGlobals.StartingPositions[3]) ] def generate(self): self.notify.debug('generate') DistributedMinigameAI.DistributedMinigameAI.generate(self) def delete(self): self.notify.debug('delete') taskMgr.remove(self.taskName('wait-choices-timeout')) taskMgr.remove(self.taskName('endingPositionsTimeout')) del self.gameFSM DistributedMinigameAI.DistributedMinigameAI.delete(self) def setGameReady(self): self.notify.debug('setGameReady') DistributedMinigameAI.DistributedMinigameAI.setGameReady(self) self.numTreasures = IceGameGlobals.NumTreasures[self.getSafezoneId()] self.numTreasuresTaken = 0 self.takenTreasuresTable = [0] * self.numTreasures self.numPenalties = IceGameGlobals.NumPenalties[self.getSafezoneId()] self.numPenaltiesTaken = 0 self.takenPenaltiesTable = [0] * self.numPenalties def setGameStart(self, timestamp): self.notify.debug('setGameStart') DistributedMinigameAI.DistributedMinigameAI.setGameStart( self, timestamp) self.gameFSM.request('waitClientsChoices') def setGameAbort(self): self.notify.debug('setGameAbort') if self.gameFSM.getCurrentState(): self.gameFSM.request('cleanup') DistributedMinigameAI.DistributedMinigameAI.setGameAbort(self) def gameOver(self): self.notify.debug('gameOver') self.gameFSM.request('cleanup') DistributedMinigameAI.DistributedMinigameAI.gameOver(self) def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterCleanup(self): self.notify.debug('enterCleanup') self.gameFSM.request('off') def exitCleanup(self): pass def enterWaitClientsChoices(self): self.notify.debug('enterWaitClientsChoices') self.resetChoices() self.sendUpdate('setMatchAndRound', [self.curMatch, self.curRound]) self.sendUpdate('setNewState', ['inputChoice']) taskMgr.doMethodLater(IceGameGlobals.InputTimeout, self.waitClientsChoicesTimeout, self.taskName('wait-choices-timeout')) self.sendUpdate('setTimerStartTime', [globalClockDelta.getFrameNetworkTime()]) def exitWaitClientsChoices(self): self.notify.debug('exitWaitClientsChoices') taskMgr.remove(self.taskName('wait-choices-timeout')) def enterProcessChoices(self): forceAndHeading = [] for avId in self.avIdList: force = self.avatarChoices[avId][0] heading = self.avatarChoices[avId][1] forceAndHeading.append([force, heading]) self.notify.debug('tireInputs = %s' % forceAndHeading) self.sendUpdate('setTireInputs', [forceAndHeading]) self.gameFSM.request('waitEndingPositions') def exitProcessChoices(self): pass def enterWaitEndingPositions(self): if self.curRound == 0: self.takenTreasuresTable = [0] * self.numTreasures self.takenPenaltiesTable = [0] * self.numPenalties taskMgr.doMethodLater(IceGameGlobals.InputTimeout, self.waitClientsChoicesTimeout, self.taskName('endingPositionsTimeout')) self.avatarEndingPositions = {} def exitWaitEndingPositions(self): taskMgr.remove(self.taskName('endingPositionsTimeout')) def enterProcessEndingPositions(self): averagePos = [ Point3(0, 0, 0), Point3(0, 0, 0), Point3(0, 0, 0), Point3(0, 0, 0) ] divisor = 0 for avId in self.avatarEndingPositions.keys(): divisor += 1 oneClientEndingPositions = self.avatarEndingPositions[avId] avIndex = self.avIdList.index(avId) for index in xrange(len(oneClientEndingPositions)): pos = oneClientEndingPositions[index] averagePos[index] += Point3(pos[0], pos[1], pos[2]) self.notify.debug('index = %d averagePos = %s' % (index, averagePos)) sentPos = [] if divisor: for newPos in averagePos: newPos /= divisor newPos.setZ(IceGameGlobals.TireRadius) sentPos.append([newPos[0], newPos[1], newPos[2]]) else: sentPos = self.finalEndingPositions self.sendUpdate('setFinalPositions', [sentPos]) self.finalEndingPositions = sentPos if self.curMatch == IceGameGlobals.NumMatches - 1 and self.curRound == IceGameGlobals.NumRounds - 1: self.gameFSM.request('scoreMatch') elif self.curRound == IceGameGlobals.NumRounds - 1: self.gameFSM.request('scoreMatch') else: self.curRound += 1 self.sendUpdate('setMatchAndRound', [self.curMatch, self.curRound]) self.gameFSM.request('waitClientsChoices') def exitProcessEndingPositions(self): pass def enterScoreMatch(self): sortedByDistance = [] for avId in self.avIdList: index = self.avIdList.index(avId) pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoresAsList = [] totalPointsAdded = 0 for index in xrange(len(self.avIdList)): pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) length = pos.length() points = length / IceGameGlobals.FarthestLength * ( IceGameGlobals.PointsInCorner - IceGameGlobals.PointsDeadCenter[self.numPlayers]) points += IceGameGlobals.PointsDeadCenter[self.numPlayers] self.notify.debug('length = %s points=%s avId=%d' % (length, points, avId)) avId = self.avIdList[index] bonusIndex = 0 for sortIndex in xrange(len(sortedByDistance)): if sortedByDistance[sortIndex][0] == avId: bonusIndex = sortIndex bonusIndex += 4 - len(self.avIdList) pointsToAdd = int( points + 0.5) + IceGameGlobals.BonusPointsForPlace[bonusIndex] totalPointsAdded += pointsToAdd self.scoreDict[avId] += pointsToAdd self.scoresAsList.append(self.scoreDict[avId]) self.curMatch += 1 self.curRound = 0 self.sendUpdate('setScores', [self.curMatch, self.curRound, self.scoresAsList]) self.sendUpdate('setNewState', ['scoring']) def allToonsScoringMovieDone(self=self): self.notify.debug('allToonsScoringMovieDone') if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') def handleTimeout(avIds, self=self): self.notify.debug( 'handleTimeout: avatars %s did not report "done"' % avIds) if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') scoreMovieDuration = IceGameGlobals.FarthestLength * IceGameGlobals.ExpandFeetPerSec scoreMovieDuration += totalPointsAdded * IceGameGlobals.ScoreCountUpRate self.scoringMovieDoneBarrier = ToonBarrier( 'waitScoringMovieDone', self.uniqueName('waitScoringMovieDone'), self.avIdList, scoreMovieDuration + MinigameGlobals.latencyTolerance, allToonsScoringMovieDone, handleTimeout) def exitScoreMatch(self): self.scoringMovieDoneBarrier.cleanup() self.scoringMovieDoneBarrier = None return def enterFinalResults(self): self.checkScores() self.sendUpdate('setNewState', ['finalResults']) taskMgr.doMethodLater(IceGameGlobals.ShowScoresDuration, self.__doneShowingScores, self.taskName('waitShowScores')) def exitFinalResults(self): taskMgr.remove(self.taskName('waitShowScores')) def __doneShowingScores(self, task): self.notify.debug('doneShowingScores') self.gameOver() return Task.done def waitClientsChoicesTimeout(self, task): self.notify.debug( 'waitClientsChoicesTimeout: did not hear from all clients') for avId in self.avatarChoices.keys(): if self.avatarChoices[avId] == (-1, 0): self.avatarChoices[avId] = (0, 0) self.gameFSM.request('processChoices') return Task.done def resetChoices(self): for avId in self.avIdList: self.avatarChoices[avId] = (-1, 0) def setAvatarChoice(self, force, direction): avatarId = self.air.getAvatarIdFromSender() self.notify.debug('setAvatarChoice: avatar: ' + str(avatarId) + ' votes: ' + str(force) + ' direction: ' + str(direction)) self.avatarChoices[avatarId] = self.checkChoice( avatarId, force, direction) if self.allAvatarsChosen(): self.notify.debug('setAvatarChoice: all avatars have chosen') self.gameFSM.request('processChoices') else: self.notify.debug( 'setAvatarChoice: still waiting for more choices') def checkChoice(self, avId, force, direction): retForce = force retDir = direction if retForce < 0: retForce = 0 if retForce > 100: retForce = 100 return (retForce, retDir) def allAvatarsChosen(self): for avId in self.avatarChoices.keys(): choice = self.avatarChoices[avId] if choice[0] == -1 and not self.stateDict[ avId] == DistributedMinigameAI.EXITED: return False return True def endingPositions(self, positions): if not self.gameFSM or not self.gameFSM.getCurrentState( ) or self.gameFSM.getCurrentState().getName() != 'waitEndingPositions': return self.notify.debug('got endingPositions from client %s' % positions) avId = self.air.getAvatarIdFromSender() self.avatarEndingPositions[avId] = positions if self.allAvatarsSentEndingPositions(): self.gameFSM.request('processEndingPositions') def allAvatarsSentEndingPositions(self): if len(self.avatarEndingPositions) == len(self.avIdList): return True return False def endingPositionsTimeout(self, task): self.notify.debug( 'endingPositionsTimeout : did not hear from all clients') self.gameFSM.request('processEndingPositions') return Task.done def reportScoringMovieDone(self): if not self.gameFSM or not self.gameFSM.getCurrentState( ) or self.gameFSM.getCurrentState().getName() != 'scoreMatch': return avId = self.air.getAvatarIdFromSender() self.notify.debug('reportScoringMovieDone: avatar %s is done' % avId) self.scoringMovieDoneBarrier.clear(avId) def claimTreasure(self, treasureNum): if not self.gameFSM or not self.gameFSM.getCurrentState( ) or self.gameFSM.getCurrentState().getName() != 'waitEndingPositions': return avId = self.air.getAvatarIdFromSender() if avId not in self.scoreDict: self.notify.warning( 'PROBLEM: avatar %s called claimTreasure(%s) but he is not in the scoreDict: %s. avIdList is: %s' % (avId, treasureNum, self.scoreDict, self.avIdList)) return if treasureNum < 0 or treasureNum >= self.numTreasures: self.air.writeServerEvent( 'warning', treasureNum, 'MazeGameAI.claimTreasure treasureNum out of range') return if self.takenTreasuresTable[treasureNum]: return self.takenTreasuresTable[treasureNum] = 1 avId = self.air.getAvatarIdFromSender() self.sendUpdate('setTreasureGrabbed', [avId, treasureNum]) self.scoreDict[avId] += 1 self.numTreasuresTaken += 1 def claimPenalty(self, penaltyNum): if not self.gameFSM or not self.gameFSM.getCurrentState( ) or self.gameFSM.getCurrentState().getName() != 'waitEndingPositions': return avId = self.air.getAvatarIdFromSender() if avId not in self.scoreDict: self.notify.warning( 'PROBLEM: avatar %s called claimPenalty(%s) but he is not in the scoreDict: %s. avIdList is: %s' % (avId, penaltyNum, self.scoreDict, self.avIdList)) return if penaltyNum < 0 or penaltyNum >= self.numPenalties: self.air.writeServerEvent( 'warning', penaltyNum, 'IceGameAI.claimPenalty penaltyNum out of range') return if self.takenPenaltiesTable[penaltyNum]: return self.takenPenaltiesTable[penaltyNum] = 1 avId = self.air.getAvatarIdFromSender() self.sendUpdate('setPenaltyGrabbed', [avId, penaltyNum]) self.scoreDict[avId] -= 1 self.numPenaltiesTaken += 1 def checkScores(self): self.scoresAsList = [] for index in xrange(len(self.avIdList)): avId = self.avIdList[index] if self.scoreDict[avId] < 0: self.scoreDict[avId] = 1 self.scoresAsList.append(self.scoreDict[avId])
class DistributedIceGameAI(DistributedMinigameAI.DistributedMinigameAI): notify = directNotify.newCategory('DistributedIceGameAI') def __init__(self, air, minigameId): try: self.DistributedIceGameAI_initialized except: self.DistributedIceGameAI_initialized = 1 DistributedMinigameAI.DistributedMinigameAI.__init__(self, air, minigameId) self.gameFSM = ClassicFSM.ClassicFSM('DistributedIceGameAI', [State.State('off', self.enterOff, self.exitOff, ['waitClientsChoices']), State.State('waitClientsChoices', self.enterWaitClientsChoices, self.exitWaitClientsChoices, ['cleanup', 'processChoices']), State.State('processChoices', self.enterProcessChoices, self.exitProcessChoices, ['waitEndingPositions', 'cleanup']), State.State('waitEndingPositions', self.enterWaitEndingPositions, self.exitWaitEndingPositions, ['processEndingPositions', 'cleanup']), State.State('processEndingPositions', self.enterProcessEndingPositions, self.exitProcessEndingPositions, ['waitClientsChoices', 'scoreMatch', 'cleanup']), State.State('scoreMatch', self.enterScoreMatch, self.exitScoreMatch, ['waitClientsChoices', 'finalResults', 'cleanup']), State.State('finalResults', self.enterFinalResults, self.exitFinalResults, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, ['off'])], 'off', 'off') self.addChildGameFSM(self.gameFSM) self.avatarChoices = {} self.avatarEndingPositions = {} self.curRound = 0 self.curMatch = 0 self.finalEndingPositions = [Point3(IceGameGlobals.StartingPositions[0]), Point3(IceGameGlobals.StartingPositions[1]), Point3(IceGameGlobals.StartingPositions[2]), Point3(IceGameGlobals.StartingPositions[3])] def generate(self): self.notify.debug('generate') DistributedMinigameAI.DistributedMinigameAI.generate(self) def delete(self): self.notify.debug('delete') taskMgr.remove(self.taskName('wait-choices-timeout')) taskMgr.remove(self.taskName('endingPositionsTimeout')) del self.gameFSM DistributedMinigameAI.DistributedMinigameAI.delete(self) def setGameReady(self): self.notify.debug('setGameReady') DistributedMinigameAI.DistributedMinigameAI.setGameReady(self) self.numTreasures = IceGameGlobals.NumTreasures[self.getSafezoneId()] self.numTreasuresTaken = 0 self.takenTreasuresTable = [0] * self.numTreasures self.numPenalties = IceGameGlobals.NumPenalties[self.getSafezoneId()] self.numPenaltiesTaken = 0 self.takenPenaltiesTable = [0] * self.numPenalties def setGameStart(self, timestamp): self.notify.debug('setGameStart') DistributedMinigameAI.DistributedMinigameAI.setGameStart(self, timestamp) self.gameFSM.request('waitClientsChoices') def setGameAbort(self): self.notify.debug('setGameAbort') if self.gameFSM.getCurrentState(): self.gameFSM.request('cleanup') DistributedMinigameAI.DistributedMinigameAI.setGameAbort(self) def gameOver(self): self.notify.debug('gameOver') self.gameFSM.request('cleanup') DistributedMinigameAI.DistributedMinigameAI.gameOver(self) def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterCleanup(self): self.notify.debug('enterCleanup') self.gameFSM.request('off') def exitCleanup(self): pass def enterWaitClientsChoices(self): self.notify.debug('enterWaitClientsChoices') self.resetChoices() self.sendUpdate('setMatchAndRound', [self.curMatch, self.curRound]) self.sendUpdate('setNewState', ['inputChoice']) taskMgr.doMethodLater(IceGameGlobals.InputTimeout, self.waitClientsChoicesTimeout, self.taskName('wait-choices-timeout')) self.sendUpdate('setTimerStartTime', [globalClockDelta.getFrameNetworkTime()]) def exitWaitClientsChoices(self): self.notify.debug('exitWaitClientsChoices') taskMgr.remove(self.taskName('wait-choices-timeout')) def enterProcessChoices(self): forceAndHeading = [] for avId in self.avIdList: force = self.avatarChoices[avId][0] heading = self.avatarChoices[avId][1] forceAndHeading.append([force, heading]) self.notify.debug('tireInputs = %s' % forceAndHeading) self.sendUpdate('setTireInputs', [forceAndHeading]) self.gameFSM.request('waitEndingPositions') def exitProcessChoices(self): pass def enterWaitEndingPositions(self): if self.curRound == 0: self.takenTreasuresTable = [0] * self.numTreasures self.takenPenaltiesTable = [0] * self.numPenalties taskMgr.doMethodLater(IceGameGlobals.InputTimeout, self.waitClientsChoicesTimeout, self.taskName('endingPositionsTimeout')) self.avatarEndingPositions = {} def exitWaitEndingPositions(self): taskMgr.remove(self.taskName('endingPositionsTimeout')) def enterProcessEndingPositions(self): averagePos = [Point3(0, 0, 0), Point3(0, 0, 0), Point3(0, 0, 0), Point3(0, 0, 0)] divisor = 0 for avId in self.avatarEndingPositions.keys(): divisor += 1 oneClientEndingPositions = self.avatarEndingPositions[avId] avIndex = self.avIdList.index(avId) for index in xrange(len(oneClientEndingPositions)): pos = oneClientEndingPositions[index] averagePos[index] += Point3(pos[0], pos[1], pos[2]) self.notify.debug('index = %d averagePos = %s' % (index, averagePos)) sentPos = [] if divisor: for newPos in averagePos: newPos /= divisor newPos.setZ(IceGameGlobals.TireRadius) sentPos.append([newPos[0], newPos[1], newPos[2]]) else: sentPos = self.finalEndingPositions self.sendUpdate('setFinalPositions', [sentPos]) self.finalEndingPositions = sentPos if self.curMatch == IceGameGlobals.NumMatches - 1 and self.curRound == IceGameGlobals.NumRounds - 1: self.gameFSM.request('scoreMatch') elif self.curRound == IceGameGlobals.NumRounds - 1: self.gameFSM.request('scoreMatch') else: self.curRound += 1 self.sendUpdate('setMatchAndRound', [self.curMatch, self.curRound]) self.gameFSM.request('waitClientsChoices') def exitProcessEndingPositions(self): pass def enterScoreMatch(self): sortedByDistance = [] for avId in self.avIdList: index = self.avIdList.index(avId) pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) sortedByDistance.append((avId, pos.length())) def compareDistance(x, y): if x[1] - y[1] > 0: return 1 elif x[1] - y[1] < 0: return -1 else: return 0 sortedByDistance.sort(cmp=compareDistance) self.scoresAsList = [] totalPointsAdded = 0 for index in xrange(len(self.avIdList)): pos = Point3(*self.finalEndingPositions[index]) pos.setZ(0) length = pos.length() points = length / IceGameGlobals.FarthestLength * (IceGameGlobals.PointsInCorner - IceGameGlobals.PointsDeadCenter[self.numPlayers]) points += IceGameGlobals.PointsDeadCenter[self.numPlayers] self.notify.debug('length = %s points=%s avId=%d' % (length, points, avId)) avId = self.avIdList[index] bonusIndex = 0 for sortIndex in xrange(len(sortedByDistance)): if sortedByDistance[sortIndex][0] == avId: bonusIndex = sortIndex bonusIndex += 4 - len(self.avIdList) pointsToAdd = int(points + 0.5) + IceGameGlobals.BonusPointsForPlace[bonusIndex] totalPointsAdded += pointsToAdd self.scoreDict[avId] += pointsToAdd self.scoresAsList.append(self.scoreDict[avId]) self.curMatch += 1 self.curRound = 0 self.sendUpdate('setScores', [self.curMatch, self.curRound, self.scoresAsList]) self.sendUpdate('setNewState', ['scoring']) def allToonsScoringMovieDone(self = self): self.notify.debug('allToonsScoringMovieDone') if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') def handleTimeout(avIds, self = self): self.notify.debug('handleTimeout: avatars %s did not report "done"' % avIds) if self.curMatch == IceGameGlobals.NumMatches: self.gameFSM.request('finalResults') else: self.gameFSM.request('waitClientsChoices') scoreMovieDuration = IceGameGlobals.FarthestLength * IceGameGlobals.ExpandFeetPerSec scoreMovieDuration += totalPointsAdded * IceGameGlobals.ScoreCountUpRate self.scoringMovieDoneBarrier = ToonBarrier('waitScoringMovieDone', self.uniqueName('waitScoringMovieDone'), self.avIdList, scoreMovieDuration + MinigameGlobals.latencyTolerance, allToonsScoringMovieDone, handleTimeout) def exitScoreMatch(self): self.scoringMovieDoneBarrier.cleanup() self.scoringMovieDoneBarrier = None return def enterFinalResults(self): self.checkScores() self.sendUpdate('setNewState', ['finalResults']) taskMgr.doMethodLater(IceGameGlobals.ShowScoresDuration, self.__doneShowingScores, self.taskName('waitShowScores')) def exitFinalResults(self): taskMgr.remove(self.taskName('waitShowScores')) def __doneShowingScores(self, task): self.notify.debug('doneShowingScores') self.gameOver() return Task.done def waitClientsChoicesTimeout(self, task): self.notify.debug('waitClientsChoicesTimeout: did not hear from all clients') for avId in self.avatarChoices.keys(): if self.avatarChoices[avId] == (-1, 0): self.avatarChoices[avId] = (0, 0) self.gameFSM.request('processChoices') return Task.done def resetChoices(self): for avId in self.avIdList: self.avatarChoices[avId] = (-1, 0) def setAvatarChoice(self, force, direction): avatarId = self.air.getAvatarIdFromSender() self.notify.debug('setAvatarChoice: avatar: ' + str(avatarId) + ' votes: ' + str(force) + ' direction: ' + str(direction)) self.avatarChoices[avatarId] = self.checkChoice(avatarId, force, direction) if self.allAvatarsChosen(): self.notify.debug('setAvatarChoice: all avatars have chosen') self.gameFSM.request('processChoices') else: self.notify.debug('setAvatarChoice: still waiting for more choices') def checkChoice(self, avId, force, direction): retForce = force retDir = direction if retForce < 0: retForce = 0 if retForce > 100: retForce = 100 return (retForce, retDir) def allAvatarsChosen(self): for avId in self.avatarChoices.keys(): choice = self.avatarChoices[avId] if choice[0] == -1 and not self.stateDict[avId] == DistributedMinigameAI.EXITED: return False return True def endingPositions(self, positions): if not self.gameFSM or not self.gameFSM.getCurrentState() or self.gameFSM.getCurrentState().getName() != 'waitEndingPositions': return self.notify.debug('got endingPositions from client %s' % positions) avId = self.air.getAvatarIdFromSender() self.avatarEndingPositions[avId] = positions if self.allAvatarsSentEndingPositions(): self.gameFSM.request('processEndingPositions') def allAvatarsSentEndingPositions(self): if len(self.avatarEndingPositions) == len(self.avIdList): return True return False def endingPositionsTimeout(self, task): self.notify.debug('endingPositionsTimeout : did not hear from all clients') self.gameFSM.request('processEndingPositions') return Task.done def reportScoringMovieDone(self): if not self.gameFSM or not self.gameFSM.getCurrentState() or self.gameFSM.getCurrentState().getName() != 'scoreMatch': return avId = self.air.getAvatarIdFromSender() self.notify.debug('reportScoringMovieDone: avatar %s is done' % avId) self.scoringMovieDoneBarrier.clear(avId) def claimTreasure(self, treasureNum): if not self.gameFSM or not self.gameFSM.getCurrentState() or self.gameFSM.getCurrentState().getName() != 'waitEndingPositions': return avId = self.air.getAvatarIdFromSender() if avId not in self.scoreDict: self.notify.warning('PROBLEM: avatar %s called claimTreasure(%s) but he is not in the scoreDict: %s. avIdList is: %s' % (avId, treasureNum, self.scoreDict, self.avIdList)) return if treasureNum < 0 or treasureNum >= self.numTreasures: self.air.writeServerEvent('warning', treasureNum, 'MazeGameAI.claimTreasure treasureNum out of range') return if self.takenTreasuresTable[treasureNum]: return self.takenTreasuresTable[treasureNum] = 1 avId = self.air.getAvatarIdFromSender() self.sendUpdate('setTreasureGrabbed', [avId, treasureNum]) self.scoreDict[avId] += 1 self.numTreasuresTaken += 1 def claimPenalty(self, penaltyNum): if not self.gameFSM or not self.gameFSM.getCurrentState() or self.gameFSM.getCurrentState().getName() != 'waitEndingPositions': return avId = self.air.getAvatarIdFromSender() if avId not in self.scoreDict: self.notify.warning('PROBLEM: avatar %s called claimPenalty(%s) but he is not in the scoreDict: %s. avIdList is: %s' % (avId, penaltyNum, self.scoreDict, self.avIdList)) return if penaltyNum < 0 or penaltyNum >= self.numPenalties: self.air.writeServerEvent('warning', penaltyNum, 'IceGameAI.claimPenalty penaltyNum out of range') return if self.takenPenaltiesTable[penaltyNum]: return self.takenPenaltiesTable[penaltyNum] = 1 avId = self.air.getAvatarIdFromSender() self.sendUpdate('setPenaltyGrabbed', [avId, penaltyNum]) self.scoreDict[avId] -= 1 self.numPenaltiesTaken += 1 def checkScores(self): self.scoresAsList = [] for index in xrange(len(self.avIdList)): avId = self.avIdList[index] if self.scoreDict[avId] < 0: self.scoreDict[avId] = 1 self.scoresAsList.append(self.scoreDict[avId])