from otp.ai.AIBase import * from toontown.toonbase import ToontownGlobals from direct.distributed.ClockDelta import * from ElevatorConstants import * import DistributedElevatorAI from direct.fsm import ClassicFSM from direct.fsm import State from direct.task import Task from direct.directnotify import DirectNotifyGlobal class DistributedElevatorExtAI(DistributedElevatorAI.DistributedElevatorAI): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedElevatorExtAI') def __init__(self, air, bldg, numSeats = 4, antiShuffle = 0): DistributedElevatorAI.DistributedElevatorAI.__init__(self, air, bldg, numSeats, antiShuffle=antiShuffle) self.anyToonsBailed = 0 self.boardingParty = None return def delete(self): for seatIndex in xrange(len(self.seats)): avId = self.seats[seatIndex] if avId: self.clearFullNow(seatIndex) self.clearEmptyNow(seatIndex) DistributedElevatorAI.DistributedElevatorAI.delete(self) def d_setFloor(self, floorNumber): self.sendUpdate('setFloor', [floorNumber]) def acceptBoarder(self, avId, seatIndex, wantBoardingShow = 0): DistributedElevatorAI.DistributedElevatorAI.acceptBoarder(self, avId, seatIndex, wantBoardingShow) self.acceptOnce(self.air.getAvatarExitEvent(avId), self.__handleUnexpectedExit, extraArgs=[avId]) self.fsm.request('waitCountdown') def __handleUnexpectedExit(self, avId): self.notify.warning('Avatar: ' + str(avId) + ' has exited unexpectedly') seatIndex = self.findAvatar(avId) if seatIndex == None: pass else: self.clearFullNow(seatIndex) self.clearEmptyNow(seatIndex) if self.countFullSeats() == 0: self.fsm.request('waitEmpty') return def acceptExiter(self, avId): seatIndex = self.findAvatar(avId) if seatIndex == None: pass else: self.clearFullNow(seatIndex) bailFlag = 0 timeToSend = self.countdownTime if self.antiShuffle: myTask = taskMgr.getTasksNamed(self.uniqueName('countdown-timer'))[0] timeLeft = myTask.wakeTime - globalClock.getFrameTime() timeLeft = max(0, timeLeft) timeToSet = timeLeft + 10.0 timeToSet = min(timeLeft + 10.0, self.countdownTime) self.setCountdown(timeToSet) timeToSend = timeToSet self.sendUpdate('emptySlot' + str(seatIndex), [avId, 1, globalClockDelta.getRealNetworkTime(), timeToSend]) elif self.anyToonsBailed == 0: bailFlag = 1 self.resetCountdown() self.anyToonsBailed = 1 self.sendUpdate('emptySlot' + str(seatIndex), [avId, bailFlag, globalClockDelta.getRealNetworkTime(), timeToSend]) else: self.sendUpdate('emptySlot' + str(seatIndex), [avId, bailFlag, globalClockDelta.getRealNetworkTime(), timeToSend]) if self.countFullSeats() == 0: self.fsm.request('waitEmpty') taskMgr.doMethodLater(TOON_EXIT_ELEVATOR_TIME, self.clearEmptyNow, self.uniqueName('clearEmpty-%s' % seatIndex), extraArgs=(seatIndex,)) return def enterOpening(self): DistributedElevatorAI.DistributedElevatorAI.enterOpening(self) taskMgr.doMethodLater(ElevatorData[ELEVATOR_NORMAL]['openTime'], self.waitEmptyTask, self.uniqueName('opening-timer')) def waitEmptyTask(self, task): self.fsm.request('waitEmpty') return Task.done def enterWaitEmpty(self): DistributedElevatorAI.DistributedElevatorAI.enterWaitEmpty(self) self.anyToonsBailed = 0 def enterWaitCountdown(self): DistributedElevatorAI.DistributedElevatorAI.enterWaitCountdown(self) taskMgr.doMethodLater(self.countdownTime, self.timeToGoTask, self.uniqueName('countdown-timer')) def timeToGoTask(self, task): if self.countFullSeats() > 0: self.fsm.request('allAboard') else: self.fsm.request('waitEmpty') return Task.done def resetCountdown(self): taskMgr.remove(self.uniqueName('countdown-timer')) taskMgr.doMethodLater(self.countdownTime, self.timeToGoTask, self.uniqueName('countdown-timer')) def setCountdown(self, timeToSet): taskMgr.remove(self.uniqueName('countdown-timer')) taskMgr.doMethodLater(timeToSet, self.timeToGoTask, self.uniqueName('countdown-timer')) def enterAllAboard(self): DistributedElevatorAI.DistributedElevatorAI.enterAllAboard(self) currentTime = globalClock.getRealTime() elapsedTime = currentTime - self.timeOfBoarding self.notify.debug('elapsed time: ' + str(elapsedTime)) waitTime = max(TOON_BOARD_ELEVATOR_TIME - elapsedTime, 0) waitTime += self.getBoardingShowTimeLeft() taskMgr.doMethodLater(waitTime, self.closeTask, self.uniqueName('waitForAllAboard')) def getBoardingShowTimeLeft(self): currentTime = globalClock.getRealTime() timeLeft = 0.0 if hasattr(self, 'timeOfGroupBoarding') and self.timeOfGroupBoarding: elapsedTime = currentTime - self.timeOfGroupBoarding timeLeft = max(MAX_GROUP_BOARDING_TIME - elapsedTime, 0) if timeLeft > MAX_GROUP_BOARDING_TIME: timeLeft = 0.0 return timeLeft def closeTask(self, task): if self.countFullSeats() > 0: self.fsm.request('closing') else: self.fsm.request('waitEmpty') return Task.done def enterClosing(self): DistributedElevatorAI.DistributedElevatorAI.enterClosing(self) taskMgr.doMethodLater(ElevatorData[ELEVATOR_NORMAL]['closeTime'], self.elevatorClosedTask, self.uniqueName('closing-timer')) def elevatorClosedTask(self, task): self.elevatorClosed() return Task.done def _createInterior(self): self.bldg.createSuitInterior() def elevatorClosed(self): numPlayers = self.countFullSeats() if numPlayers > 0: self._createInterior() for seatIndex in xrange(len(self.seats)): avId = self.seats[seatIndex] if avId: self.clearFullNow(seatIndex) else: self.notify.warning('The elevator left, but was empty.') self.fsm.request('closed') def requestExit(self, *args): self.notify.debug('requestExit') avId = self.air.getAvatarIdFromSender() av = self.air.doId2do.get(avId) if self.boardingParty and self.boardingParty.getGroupLeader(avId) and avId: if avId == self.boardingParty.getGroupLeader(avId): memberIds = self.boardingParty.getGroupMemberList(avId) for memberId in memberIds: member = simbase.air.doId2do.get(memberId) if member: if self.accepting: self.acceptingExitersHandler(memberId) else: self.rejectingExitersHandler(memberId) else: self.rejectingExitersHandler(avId) else: 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) return