ToonTownRewritten/toontown/minigame/DistributedRingGameAI.py

146 lines
5.2 KiB
Python

from DistributedMinigameAI import *
from direct.distributed.ClockDelta import *
from direct.fsm import ClassicFSM, State
from direct.fsm import State
import RingGameGlobals
import random
import types
class DistributedRingGameAI(DistributedMinigameAI):
def __init__(self, air, minigameId):
try:
self.DistributedRingGameAI_initialized
except:
self.DistributedRingGameAI_initialized = 1
DistributedMinigameAI.__init__(self, air, minigameId)
self.gameFSM = ClassicFSM.ClassicFSM('DistributedRingGameAI', [State.State('inactive', self.enterInactive, self.exitInactive, ['swimming']), State.State('swimming', self.enterSwimming, self.exitSwimming, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, ['inactive'])], 'inactive', 'inactive')
self.addChildGameFSM(self.gameFSM)
self.__timeBase = globalClockDelta.localToNetworkTime(globalClock.getRealTime())
self.selectColorIndices()
def delete(self):
self.notify.debug('delete')
del self.gameFSM
DistributedMinigameAI.delete(self)
def setGameReady(self):
self.notify.debug('setGameReady')
DistributedMinigameAI.setGameReady(self)
def setGameStart(self, timestamp):
self.notify.debug('setGameStart')
DistributedMinigameAI.setGameStart(self, timestamp)
self.gameFSM.request('swimming')
def setGameAbort(self):
self.notify.debug('setGameAbort')
if self.gameFSM.getCurrentState():
self.gameFSM.request('cleanup')
DistributedMinigameAI.setGameAbort(self)
def gameOver(self):
self.notify.debug('gameOver')
self.gameFSM.request('cleanup')
DistributedMinigameAI.gameOver(self)
def enterInactive(self):
self.notify.debug('enterInactive')
def exitInactive(self):
pass
def getTimeBase(self):
return self.__timeBase
def getColorIndices(self):
return self.colorIndices
def selectColorIndices(self):
self.colorIndices = [None,
None,
None,
None]
chooseFrom = RingGameGlobals.ringColorSelection[:]
for i in range(0, 4):
c = random.choice(chooseFrom)
chooseFrom.remove(c)
if isinstance(c, types.TupleType):
c = random.choice(c)
self.colorIndices[i] = c
return
def enterSwimming(self):
self.notify.debug('enterSwimming')
self.__nextRingGroup = {}
for avId in self.avIdList:
self.__nextRingGroup[avId] = 0
self.__numRingsPassed = [0] * RingGameGlobals.NUM_RING_GROUPS
self.__ringResultBitfield = [0] * RingGameGlobals.NUM_RING_GROUPS
self.perfectGames = {}
for avId in self.avIdList:
self.perfectGames[avId] = 1
for avId in self.avIdList:
self.scoreDict[avId] = 0
def exitSwimming(self):
pass
def enterCleanup(self):
self.notify.debug('enterCleanup')
self.gameFSM.request('inactive')
def exitCleanup(self):
pass
def setToonGotRing(self, success):
avId = self.air.getAvatarIdFromSender()
if avId not in self.avIdList:
self.air.writeServerEvent('suspicious', avId=avId, issue='RingGameAI.setToonGotRing: invalid avId')
return
if self.gameFSM.getCurrentState() is None or self.gameFSM.getCurrentState().getName() != 'swimming':
self.air.writeServerEvent('suspicious', avId=avId, issue='RingGameAI.setToonGotRing: game not in swimming state')
return
ringGroupIndex = self.__nextRingGroup[avId]
if ringGroupIndex >= RingGameGlobals.NUM_RING_GROUPS:
self.notify.warning('warning: got extra ToonGotRing msg from av %s' % avId)
return
self.__nextRingGroup[avId] += 1
if not success:
self.__ringResultBitfield[ringGroupIndex] |= 1 << self.avIdList.index(avId)
self.perfectGames[avId] = 0
else:
self.scoreDict[avId] += 1
self.__numRingsPassed[ringGroupIndex] += 1
if self.__numRingsPassed[ringGroupIndex] >= self.numPlayers:
if not self.isSinglePlayer():
bitfield = self.__ringResultBitfield[ringGroupIndex]
if bitfield == 0:
for id in self.avIdList:
self.scoreDict[id] += 0.5
self.sendUpdate('setRingGroupResults', [bitfield])
if ringGroupIndex >= RingGameGlobals.NUM_RING_GROUPS - 1:
perfectBonuses = {1: 5,
2: 5,
3: 10,
4: 18}
numPerfectToons = 0
for avId in self.avIdList:
if self.perfectGames[avId]:
numPerfectToons += 1
for avId in self.avIdList:
if self.perfectGames[avId]:
self.scoreDict[avId] += perfectBonuses[numPerfectToons]
self.logPerfectGame(avId)
for avId in self.avIdList:
self.scoreDict[avId] = max(1, self.scoreDict[avId])
if not RingGameGlobals.ENDLESS_GAME:
self.gameOver()
return