from direct.distributed import DistributedObjectAI from direct.distributed.ClockDelta import * from direct.fsm import ClassicFSM, State from otp.ai.AIBaseGlobal import * class DistributedDoorAI(DistributedObjectAI.DistributedObjectAI): def __init__(self, air, blockNumber, doorType, doorIndex=0, lockValue=0, swing=3): DistributedObjectAI.DistributedObjectAI.__init__(self, air) self.block = blockNumber self.swing = swing self.otherDoor = None self.doorType = doorType self.doorIndex = doorIndex self.setDoorLock(lockValue) self.fsm = ClassicFSM.ClassicFSM( 'DistributedDoorAI_right', [ State.State('off', self.enterOff, self.exitOff, ['closing', 'closed', 'opening', 'open']), State.State('closing', self.enterClosing, self.exitClosing, ['closed', 'opening']), State.State('closed', self.enterClosed, self.exitClosed, ['opening']), State.State('opening', self.enterOpening, self.exitOpening, ['open']), State.State('open', self.enterOpen, self.exitOpen, ['closing', 'open']) ], 'off', 'off') self.fsm.enterInitialState() self.exitDoorFSM = ClassicFSM.ClassicFSM( 'DistributedDoorAI_left', [ State.State('off', self.exitDoorEnterOff, self.exitDoorExitOff, ['closing', 'closed', 'opening', 'open']), State.State('closing', self.exitDoorEnterClosing, self.exitDoorExitClosing, ['closed', 'opening']), State.State('closed', self.exitDoorEnterClosed, self.exitDoorExitClosed, ['opening']), State.State('opening', self.exitDoorEnterOpening, self.exitDoorExitOpening, ['open']), State.State('open', self.exitDoorEnterOpen, self.exitDoorExitOpen, ['closing', 'open']) ], 'off', 'off') self.exitDoorFSM.enterInitialState() self.doLaterTask = None self.exitDoorDoLaterTask = None self.avatarsWhoAreEntering = {} self.avatarsWhoAreExiting = {} def delete(self): taskMgr.remove(self.uniqueName('door_opening-timer')) taskMgr.remove(self.uniqueName('door_open-timer')) taskMgr.remove(self.uniqueName('door_closing-timer')) taskMgr.remove(self.uniqueName('exit_door_open-timer')) taskMgr.remove(self.uniqueName('exit_door_closing-timer')) taskMgr.remove(self.uniqueName('exit_door_opening-timer')) self.ignoreAll() del self.block del self.swing del self.doorType del self.fsm del self.exitDoorFSM del self.otherDoor DistributedObjectAI.DistributedObjectAI.delete(self) def getDoorIndex(self): return self.doorIndex def setSwing(self, swing): self.swing = swing def getSwing(self): return self.swing def getDoorType(self): return self.doorType def getZoneIdAndBlock(self): return [self.zoneId, self.block] def setOtherDoor(self, door): self.otherDoor = door def getZoneId(self): return self.zoneId def getState(self): return [self.fsm.getCurrentState().getName(), globalClockDelta.getRealNetworkTime()] def getExitDoorState(self): return [self.exitDoorFSM.getCurrentState().getName(), globalClockDelta.getRealNetworkTime()] def isOpen(self): state = self.fsm.getCurrentState().getName() return state == 'open' or state == 'opening' def isClosed(self): return not self.isOpen() def setDoorLock(self, locked): self.lockedDoor = locked def isLockedDoor(self): if simbase.config.GetBool('no-locked-doors', 0): return 0 else: return self.lockedDoor def sendReject(self, avatarID, lockedVal): self.sendUpdateToAvatarId(avatarID, 'rejectEnter', [lockedVal]) def requestEnter(self): avatarID = self.air.getAvatarIdFromSender() lockedVal = self.isLockedDoor() if lockedVal: self.sendReject(avatarID, lockedVal) else: self.enqueueAvatarIdEnter(avatarID) self.sendUpdateToAvatarId( avatarID, 'setOtherZoneIdAndDoId', [self.otherDoor.getZoneId(), self.otherDoor.getDoId()]) def enqueueAvatarIdEnter(self, avatarID): if avatarID not in self.avatarsWhoAreEntering: self.avatarsWhoAreEntering[avatarID] = 1 self.sendUpdate('avatarEnter', [avatarID]) self.openDoor(self.fsm) def openDoor(self, doorFsm): stateName = doorFsm.getCurrentState().getName() if stateName == 'open': doorFsm.request('open') elif stateName != 'opening': doorFsm.request('opening') def requestExit(self): avatarID = self.air.getAvatarIdFromSender() self.sendUpdate('avatarExit', [avatarID]) self.enqueueAvatarIdExit(avatarID) def enqueueAvatarIdExit(self, avatarID): if avatarID in self.avatarsWhoAreEntering: del self.avatarsWhoAreEntering[avatarID] elif avatarID not in self.avatarsWhoAreExiting: self.avatarsWhoAreExiting[avatarID] = 1 self.openDoor(self.exitDoorFSM) def requestSuitEnter(self, avatarID): self.enqueueAvatarIdEnter(avatarID) def requestSuitExit(self, avatarID): self.sendUpdate('avatarExit', [avatarID]) self.enqueueAvatarIdExit(avatarID) def d_setState(self, state): self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()]) def d_setExitDoorState(self, state): self.sendUpdate('setExitDoorState', [state, globalClockDelta.getRealNetworkTime()]) def enterOff(self): pass def exitOff(self): pass def openTask(self, task): self.fsm.request('closing') return Task.done def enterClosing(self): self.d_setState('closing') self.doLaterTask = taskMgr.doMethodLater(1, self.closingTask, self.uniqueName('door_closing-timer')) def exitClosing(self): if self.doLaterTask: taskMgr.remove(self.doLaterTask) self.doLaterTask = None def closingTask(self, task): self.fsm.request('closed') return Task.done def enterClosed(self): self.d_setState('closed') def exitClosed(self): pass def enterOpening(self): self.d_setState('opening') self.doLaterTask = taskMgr.doMethodLater( 1, self.openingTask, self.uniqueName('door_opening-timer')) def exitOpening(self): if self.doLaterTask: taskMgr.remove(self.doLaterTask) self.doLaterTask = None def openingTask(self, task): self.fsm.request('open') return Task.done def enterOpen(self): self.d_setState('open') self.avatarsWhoAreEntering = {} self.doLaterTask = taskMgr.doMethodLater( 1, self.openTask, self.uniqueName('door_open-timer')) def exitOpen(self): if self.doLaterTask: taskMgr.remove(self.doLaterTask) self.doLaterTask = None def exitDoorEnterOff(self): pass def exitDoorExitOff(self): pass def exitDoorOpenTask(self, task): self.exitDoorFSM.request('closing') return Task.done def exitDoorEnterClosing(self): self.d_setExitDoorState('closing') self.exitDoorDoLaterTask = taskMgr.doMethodLater( 1, self.exitDoorClosingTask, self.uniqueName('exit_door_closing-timer')) def exitDoorExitClosing(self): if self.exitDoorDoLaterTask: taskMgr.remove(self.exitDoorDoLaterTask) self.exitDoorDoLaterTask = None def exitDoorClosingTask(self, task): self.exitDoorFSM.request('closed') return Task.done def exitDoorEnterClosed(self): self.d_setExitDoorState('closed') def exitDoorExitClosed(self): if self.exitDoorDoLaterTask: taskMgr.remove(self.exitDoorDoLaterTask) self.exitDoorDoLaterTask = None def exitDoorEnterOpening(self): self.d_setExitDoorState('opening') self.exitDoorDoLaterTask = taskMgr.doMethodLater( 1, self.exitDoorOpeningTask, self.uniqueName('exit_door_opening-timer')) def exitDoorExitOpening(self): if self.exitDoorDoLaterTask: taskMgr.remove(self.exitDoorDoLaterTask) self.exitDoorDoLaterTask = None def exitDoorOpeningTask(self, task): self.exitDoorFSM.request('open') return Task.done def exitDoorEnterOpen(self): self.d_setExitDoorState('open') self.avatarsWhoAreExiting = { } self.exitDoorDoLaterTask = taskMgr.doMethodLater( 1, self.exitDoorOpenTask, self.uniqueName('exit_door_open-timer')) def exitDoorExitOpen(self): if self.exitDoorDoLaterTask: taskMgr.remove(self.exitDoorDoLaterTask) self.exitDoorDoLaterTask = None