toontown-just-works/toontown/coghq/DistributedBanquetTableAI.py
2024-07-07 18:08:39 -05:00

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