from otp.ai.AIBase import * from toontown.toonbase import ToontownGlobals from direct.distributed.ClockDelta import * from ElevatorConstants import * from direct.distributed import DistributedObjectAI from direct.task import Task from direct.directnotify import DirectNotifyGlobal from direct.fsm.FSM import FSM class DistributedElevatorFSMAI(DistributedObjectAI.DistributedObjectAI, FSM): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedElevatorFSMAI') defaultTransitions = {'Off': ['Opening', 'Closed'], 'Opening': ['WaitEmpty', 'WaitCountdown', 'Opening', 'Closing'], 'WaitEmpty': ['WaitCountdown', 'Closing'], 'WaitCountdown': ['WaitEmpty', 'AllAboard', 'Closing'], 'AllAboard': ['WaitEmpty', 'Closing'], 'Closing': ['Closed', 'WaitEmpty', 'Closing', 'Opening'], 'Closed': ['Opening']} id = 0 def __init__(self, air, bldg, numSeats = 4, antiShuffle = 0, minLaff = 0): DistributedObjectAI.DistributedObjectAI.__init__(self, air) FSM.__init__(self, 'Elevator_%s_FSM' % self.id) self.type = ELEVATOR_NORMAL self.countdownTime = ElevatorData[self.type]['countdown'] self.bldg = bldg self.bldgDoId = bldg.getDoId() self.seats = [] for seat in xrange(numSeats): self.seats.append(None) self.accepting = 0 self.setAntiShuffle(antiShuffle) self.setMinLaff(minLaff) if self.antiShuffle: if not hasattr(simbase.air, 'elevatorTripId'): simbase.air.elevatorTripId = 1 self.elevatorTripId = simbase.air.elevatorTripId simbase.air.elevatorTripId += 1 else: self.elevatorTripId = 0 return def delete(self): del self.bldg self.ignoreAll() DistributedObjectAI.DistributedObjectAI.delete(self) def generate(self): DistributedObjectAI.DistributedObjectAI.generate(self) self.start() def getBldgDoId(self): return self.bldgDoId def findAvailableSeat(self): for i in xrange(len(self.seats)): if self.seats[i] == None: return i return def findAvatar(self, avId): for i in xrange(len(self.seats)): if self.seats[i] == avId: return i return None def countFullSeats(self): avCounter = 0 for i in self.seats: if i: avCounter += 1 return avCounter def countOpenSeats(self): openSeats = 0 for i in xrange(len(self.seats)): if self.seats[i] == None: openSeats += 1 return openSeats def rejectingBoardersHandler(self, avId, reason = 0): self.rejectBoarder(avId, reason) def rejectBoarder(self, avId, reason = 0): self.sendUpdateToAvatarId(avId, 'rejectBoard', [avId, reason]) def acceptingBoardersHandler(self, avId, reason = 0): self.notify.debug('acceptingBoardersHandler') seatIndex = self.findAvailableSeat() if seatIndex == None: self.rejectBoarder(avId, REJECT_NOSEAT) else: self.acceptBoarder(avId, seatIndex) return def acceptBoarder(self, avId, seatIndex): self.notify.debug('acceptBoarder') if self.findAvatar(avId) != None: return self.seats[seatIndex] = avId self.timeOfBoarding = globalClock.getRealTime() self.sendUpdate('fillSlot' + str(seatIndex), [avId]) return def rejectingExitersHandler(self, avId): self.rejectExiter(avId) def rejectExiter(self, avId): pass def acceptingExitersHandler(self, avId): self.acceptExiter(avId) def clearEmptyNow(self, seatIndex): self.sendUpdate('emptySlot' + str(seatIndex), [0, 0, globalClockDelta.getRealNetworkTime()]) def clearFullNow(self, seatIndex): avId = self.seats[seatIndex] if avId == None: self.notify.warning('Clearing an empty seat index: ' + str(seatIndex) + ' ... Strange...') else: self.seats[seatIndex] = None self.sendUpdate('fillSlot' + str(seatIndex), [0]) self.ignore(self.air.getAvatarExitEvent(avId)) return def d_setState(self, state): self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()]) def getState(self): return self.state def avIsOKToBoard(self, av): return av.hp > self.minLaff and self.accepting def checkBoard(self, av): if av.hp < self.minLaff: return REJECT_MINLAFF return 0 def requestBoard(self, *args): self.notify.debug('requestBoard') avId = self.air.getAvatarIdFromSender() if self.findAvatar(avId) != None: self.notify.warning('Ignoring multiple requests from %s to board.' % avId) return av = self.air.doId2do.get(avId) if av: newArgs = (avId,) + args boardResponse = self.checkBoard(av) newArgs = (avId,) + args + (boardResponse,) if boardResponse == 0: self.acceptingBoardersHandler(*newArgs) else: self.rejectingBoardersHandler(*newArgs) else: self.notify.warning('avid: %s does not exist, but tried to board an elevator' % avId) return def requestExit(self, *args): if hasattr(self, 'air'): self.notify.debug('requestExit') avId = self.air.getAvatarIdFromSender() av = self.air.doId2do.get(avId) if av: newArgs = (avId,) + args if self.accepting: self.acceptingExitersHandler(*newArgs) else: self.rejectingExitersHandler(*newArgs) else: self.notify.warning('avId: %s does not exist, but tried to exit an elevator' % avId) def start(self): self.open() def enterOff(self): self.accepting = 0 self.timeOfBoarding = None if hasattr(self, 'doId'): for seatIndex in xrange(len(self.seats)): taskMgr.remove(self.uniqueName('clearEmpty-' + str(seatIndex))) return def exitOff(self): self.accepting = 0 def open(self): self.request('Opening') def enterOpening(self): self.d_setState('Opening') self.accepting = 0 for seat in self.seats: seat = None return def exitOpening(self): self.accepting = 0 taskMgr.remove(self.uniqueName('opening-timer')) def enterWaitCountdown(self): self.d_setState('WaitCountdown') self.accepting = 1 def exitWaitCountdown(self): print 'exit wait countdown' self.accepting = 0 taskMgr.remove(self.uniqueName('countdown-timer')) self.newTrip() def enterAllAboard(self): self.accepting = 0 def exitAllAboard(self): self.accepting = 0 taskMgr.remove(self.uniqueName('waitForAllAboard')) def enterClosing(self): self.d_setState('Closing') self.accepting = 0 def exitClosing(self): self.accepting = 0 taskMgr.remove(self.uniqueName('closing-timer')) def enterClosed(self): if hasattr(self, 'doId'): print self.doId self.d_setState('Closed') def exitClosed(self): pass def enterWaitEmpty(self): for i in xrange(len(self.seats)): self.seats[i] = None print self.seats self.d_setState('WaitEmpty') self.accepting = 1 return def exitWaitEmpty(self): self.accepting = 0 def setElevatorTripId(self, id): self.elevatorTripId = id def getElevatorTripId(self): return self.elevatorTripId def newTrip(self): if self.antiShuffle: self.elevatorTripId = simbase.air.elevatorTripId if simbase.air.elevatorTripId > 2100000000: simbase.air.elevatorTripId = 1 simbase.air.elevatorTripId += 1 self.sendUpdate('setElevatorTripId', [self.elevatorTripId]) def setAntiShuffle(self, antiShuffle): self.antiShuffle = antiShuffle def getAntiShuffle(self): return self.antiShuffle def setMinLaff(self, minLaff): self.minLaff = minLaff def getMinLaff(self): return self.minLaff