241 lines
8 KiB
Python
241 lines
8 KiB
Python
import random
|
|
from direct.distributed import DistributedObjectAI
|
|
from direct.fsm import FSM
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from toontown.coghq import BanquetTableBase
|
|
from toontown.toonbase import ToontownGlobals
|
|
|
|
class DistributedBanquetTableAI(DistributedObjectAI.DistributedObjectAI, FSM.FSM, BanquetTableBase.BanquetTableBase):
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedBanquetTableAI')
|
|
|
|
def __init__(self, air, boss, index, numDiners, dinerLevel):
|
|
DistributedObjectAI.DistributedObjectAI.__init__(self, air)
|
|
FSM.FSM.__init__(self, 'DistributedBanquetTableAI')
|
|
self.boss = boss
|
|
self.index = index
|
|
self.numDiners = numDiners
|
|
self.numChairs = 8
|
|
self.dinerStatus = {}
|
|
self.dinerInfo = {}
|
|
for i in xrange(self.numDiners):
|
|
self.dinerStatus[i] = self.INACTIVE
|
|
diffSettings = ToontownGlobals.BossbotBossDifficultySettings[self.boss.battleDifficulty]
|
|
hungryDuration = diffSettings[4]
|
|
eatingDuration = diffSettings[5]
|
|
hungryDuration += random.uniform(-5, 5)
|
|
eatingDuration += random.uniform(-5, 5)
|
|
level = 12
|
|
if type(dinerLevel) == type(0):
|
|
level = dinerLevel
|
|
else:
|
|
level = random.choice(dinerLevel)
|
|
self.dinerInfo[i] = (hungryDuration, eatingDuration, level)
|
|
|
|
self.transitionTasks = {}
|
|
self.numFoodEaten = {}
|
|
self.avId = 0
|
|
|
|
def delete(self):
|
|
DistributedObjectAI.DistributedObjectAI.delete(self)
|
|
|
|
def getBossCogId(self):
|
|
return self.boss.doId
|
|
|
|
def getIndex(self):
|
|
return self.index
|
|
|
|
def getNumDiners(self):
|
|
return self.numDiners
|
|
|
|
def getDinerStatus(self, chairIndex):
|
|
retval = self.DEAD
|
|
if chairIndex in self.dinerStatus:
|
|
retval = self.dinerStatus[chairIndex]
|
|
return retval
|
|
|
|
def setDinerStatus(self, chairIndex, newStatus):
|
|
self.dinerStatus[chairIndex] = newStatus
|
|
|
|
def getDinerInfo(self):
|
|
hungryDurations = []
|
|
eatingDurations = []
|
|
dinerLevels = []
|
|
for i in xrange(self.numDiners):
|
|
hungryDurations.append(self.dinerInfo[i][0])
|
|
eatingDurations.append(self.dinerInfo[i][1])
|
|
dinerLevels.append(self.dinerInfo[i][2])
|
|
|
|
return (hungryDurations, eatingDurations, dinerLevels)
|
|
|
|
def d_setDinerStatus(self, chairIndex, newStatus):
|
|
self.sendUpdate('setDinerStatus', [chairIndex, newStatus])
|
|
|
|
def b_setDinerStatus(self, chairIndex, newStatus):
|
|
self.setDinerStatus(chairIndex, newStatus)
|
|
self.d_setDinerStatus(chairIndex, newStatus)
|
|
|
|
def setState(self, state):
|
|
self.request(state)
|
|
|
|
def d_setState(self, state, avId = 0, extraInfo = 0):
|
|
newState = state
|
|
if state == 'On':
|
|
newState = 'N'
|
|
elif state == 'Off':
|
|
newState = 'F'
|
|
elif state == 'Inactive':
|
|
newState = 'I'
|
|
elif state == 'Free':
|
|
newState = 'R'
|
|
elif state == 'Controlled':
|
|
newState = 'C'
|
|
elif state == 'Flat':
|
|
newState = 'L'
|
|
self.sendUpdate('setState', [newState, avId, extraInfo])
|
|
|
|
def b_setState(self, state, avId = 0, extraInfo = 0):
|
|
if state == 'Controlled' or state == 'Flat':
|
|
self.request(state, avId)
|
|
else:
|
|
self.request(state)
|
|
self.d_setState(state, avId, extraInfo)
|
|
|
|
def turnOn(self):
|
|
self.b_setState('On')
|
|
|
|
def turnOff(self):
|
|
self.b_setState('Off')
|
|
|
|
def foodServed(self, chairIndex):
|
|
self.b_setDinerStatus(chairIndex, self.EATING)
|
|
eatingDur = self.dinerInfo[chairIndex][1]
|
|
if chairIndex in self.transitionTasks:
|
|
self.removeTask(self.transitionTasks[chairIndex])
|
|
taskName = self.uniqueName('transition-%d' % chairIndex)
|
|
newTask = self.doMethodLater(eatingDur, self.finishedEating, taskName, extraArgs=[chairIndex])
|
|
self.transitionTasks[chairIndex] = newTask
|
|
|
|
def finishedEating(self, chairIndex):
|
|
if chairIndex in self.transitionTasks:
|
|
self.removeTask(self.transitionTasks[chairIndex])
|
|
self.incrementFoodEaten(chairIndex)
|
|
if self.numFoodEaten[chairIndex] >= ToontownGlobals.BossbotNumFoodToExplode:
|
|
self.b_setDinerStatus(chairIndex, self.DEAD)
|
|
self.boss.incrementDinersExploded()
|
|
else:
|
|
self.b_setDinerStatus(chairIndex, self.HUNGRY)
|
|
taskName = self.uniqueName('transition-%d' % chairIndex)
|
|
hungryDur = self.dinerInfo[chairIndex][0]
|
|
newTask = self.doMethodLater(hungryDur, self.finishedHungry, taskName, extraArgs=[chairIndex])
|
|
self.transitionTasks[chairIndex] = newTask
|
|
|
|
def incrementFoodEaten(self, chairIndex):
|
|
numFood = 0
|
|
if chairIndex in self.numFoodEaten:
|
|
numFood = self.numFoodEaten[chairIndex]
|
|
self.numFoodEaten[chairIndex] = numFood + 1
|
|
|
|
def finishedHungry(self, chairIndex):
|
|
self.b_setDinerStatus(chairIndex, self.ANGRY)
|
|
self.numFoodEaten[chairIndex] = 0
|
|
if chairIndex in self.transitionTasks:
|
|
self.removeTask(self.transitionTasks[chairIndex])
|
|
|
|
def goInactive(self):
|
|
self.b_setState('Inactive')
|
|
|
|
def goFree(self):
|
|
self.b_setState('Free')
|
|
|
|
def goFlat(self):
|
|
self.b_setState('Flat', self.avId)
|
|
|
|
def getNotDeadInfo(self):
|
|
notDeadList = []
|
|
for i in xrange(self.numDiners):
|
|
if self.dinerStatus[i] != self.DEAD:
|
|
notDeadList.append((self.index, i, self.dinerInfo[i][2]))
|
|
|
|
return notDeadList
|
|
|
|
def requestControl(self):
|
|
avId = self.air.getAvatarIdFromSender()
|
|
if avId in self.boss.involvedToons and self.avId == 0 and self.state == 'Free':
|
|
tableId = self.__getTableId(avId)
|
|
if tableId == 0:
|
|
grantRequest = True
|
|
if self.boss and not self.boss.isToonRoaming(avId):
|
|
grantRequest = False
|
|
if grantRequest:
|
|
self.b_setState('Controlled', avId)
|
|
|
|
def forceControl(self, avId):
|
|
self.notify.debug('forceContrl tableIndex=%d avId=%d' % (self.index, avId))
|
|
tableId = self.__getTableId(avId)
|
|
if tableId == self.doId:
|
|
if self.state == 'Flat':
|
|
self.b_setState('Controlled', avId)
|
|
else:
|
|
self.notify.warning('invalid forceControl from state %s' % self.state)
|
|
else:
|
|
self.notify.warning('tableId %d != self.doId %d ' % (tableId, self.doId))
|
|
|
|
def requestFree(self, gotHitByBoss):
|
|
avId = self.air.getAvatarIdFromSender()
|
|
if avId == self.avId:
|
|
if self.state == 'Controlled':
|
|
self.b_setState('Free', extraInfo=gotHitByBoss)
|
|
if self.boss:
|
|
self.boss.toonLeftTable(self.index)
|
|
else:
|
|
self.notify.debug('requestFree denied in state %s' % self.state)
|
|
|
|
def __getTableId(self, avId):
|
|
if self.boss and self.boss.tables != None:
|
|
for table in self.boss.tables:
|
|
if table.avId == avId:
|
|
return table.doId
|
|
|
|
return 0
|
|
|
|
def enterOn(self):
|
|
for i in xrange(self.numDiners):
|
|
self.b_setDinerStatus(i, self.HUNGRY)
|
|
|
|
def exitOn(slef):
|
|
pass
|
|
|
|
def enterOff(self):
|
|
pass
|
|
|
|
def exitOff(self):
|
|
pass
|
|
|
|
def enterInactive(self):
|
|
for task in self.transitionTasks.values():
|
|
self.removeTask(task)
|
|
|
|
self.transitionTasks = {}
|
|
|
|
def exitInactive(self):
|
|
pass
|
|
|
|
def enterFree(self):
|
|
self.notify.debug('enterFree tableIndex=%d' % self.index)
|
|
self.avId = 0
|
|
|
|
def exitFree(self):
|
|
pass
|
|
|
|
def enterControlled(self, avId):
|
|
self.notify.debug('enterControlled tableIndex=%d' % self.index)
|
|
self.avId = avId
|
|
|
|
def exitControlled(self):
|
|
pass
|
|
|
|
def enterFlat(self, avId):
|
|
self.notify.debug('enterFlat tableIndex=%d' % self.index)
|
|
|
|
def exitFlat(self):
|
|
pass
|