class DistributedBuildingAI(DistributedObjectAI.DistributedObjectAI): def __init__(self, air, blockNumber, zoneId, trophyMgr): DistributedObjectAI.DistributedObjectAI.__init__(self, air) self.block = blockNumber self.zoneId = zoneId self.canonicalZoneId = ZoneUtil.getCanonicalZoneId(zoneId) self.trophyMgr = trophyMgr self.victorResponses = None self.fsm = ClassicFSM.ClassicFSM( 'DistributedBuildingAI', [ State.State('off', self.enterOff, self.exitOff, ['waitForVictors', 'becomingToon', 'toon', 'clearOutToonInterior', 'becomingSuit', 'suit', 'clearOutToonInteriorForCogdo', 'becomingCogdo', 'cogdo']), State.State('waitForVictors', self.enterWaitForVictors, self.exitWaitForVictors, ['becomingToon']), State.State('waitForVictorsFromCogdo', self.enterWaitForVictorsFromCogdo, self.exitWaitForVictorsFromCogdo, ['becomingToonFromCogdo']), State.State('becomingToon', self.enterBecomingToon, self.exitBecomingToon, ['toon']), State.State('becomingToonFromCogdo', self.enterBecomingToonFromCogdo, self.exitBecomingToonFromCogdo, ['toon']), State.State('toon', self.enterToon, self.exitToon, ['clearOutToonInterior', 'clearOutToonInteriorForCogdo']), State.State('clearOutToonInterior', self.enterClearOutToonInterior, self.exitClearOutToonInterior, ['becomingSuit']), State.State('becomingSuit', self.enterBecomingSuit, self.exitBecomingSuit, ['suit']), State.State('suit', self.enterSuit, self.exitSuit, ['waitForVictors', 'becomingToon']), State.State('clearOutToonInteriorForCogdo', self.enterClearOutToonInteriorForCogdo, self.exitClearOutToonInteriorForCogdo, ['becomingCogdo']), State.State('becomingCogdo', self.enterBecomingCogdo, self.exitBecomingCogdo, ['cogdo']), State.State('cogdo', self.enterCogdo, self.exitCogdo, ['waitForVictorsFromCogdo', 'becomingToonFromCogdo']) ], 'off', 'off') self.fsm.enterInitialState() self.track = 'c' self.realTrack = 'c' self.difficulty = 1 self.numFloors = 0 self.savedBy = None self.becameSuitTime = 0 self.frontDoorPoint = None self.suitPlannerExt = None def announceGenerate(self): DistributedObjectAI.DistributedObjectAI.announceGenerate(self) (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.air.buildingQueryMgr.buildings[exteriorZoneId] = self self.air.buildingQueryMgr.buildings[interiorZoneId] = self def cleanup(self): if self.isDeleted(): return self.fsm.requestFinalState() if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior if hasattr(self, 'door'): self.door.requestDelete() del self.door self.insideDoor.requestDelete() del self.insideDoor self.knockKnock.requestDelete() del self.knockKnock if hasattr(self, 'elevator'): self.elevator.requestDelete() del self.elevator self.requestDelete() def delete(self): self.cleanup() taskMgr.remove(self.taskName('suitbldg-time-out')) taskMgr.remove(self.taskName(str(self.block) + '_becomingToon-timer')) taskMgr.remove(self.taskName(str(self.block) + '_becomingSuit-timer')) DistributedObjectAI.DistributedObjectAI.delete(self) del self.fsm def getPickleData(self): pickleData = { 'state': str(self.fsm.getCurrentState().getName()), 'block': str(self.block), 'track': str(self.track), 'difficulty': str(self.difficulty), 'numFloors': str(self.numFloors), 'savedBy': self.savedBy, 'becameSuitTime': self.becameSuitTime } return pickleData def _getMinMaxFloors(self, difficulty): return SuitBuildingGlobals.SuitBuildingInfo[difficulty][0] def suitTakeOver(self, suitTrack, difficulty, buildingHeight): if not self.isToonBlock(): return self.updateSavedBy(None) difficulty = min(difficulty, len(SuitBuildingGlobals.SuitBuildingInfo) - 1) (minFloors, maxFloors) = self._getMinMaxFloors(difficulty) if buildingHeight is None: numFloors = random.randint(minFloors, maxFloors) else: numFloors = buildingHeight + 1 if (numFloors < minFloors) or (numFloors > maxFloors): numFloors = random.randint(minFloors, maxFloors) self.track = suitTrack self.difficulty = difficulty self.numFloors = numFloors self.becameSuitTime = time.time() self.fsm.request('clearOutToonInterior') def cogdoTakeOver(self, difficulty, buildingHeight, track = 's'): if not self.isToonBlock(): return None self.updateSavedBy(None) self.track = track self.realTrack = track self.difficulty = difficulty self.numFloors = 0 self.becameSuitTime = time.time() self.fsm.request('clearOutToonInteriorForCogdo') def toonTakeOver(self): if 'cogdo' in self.fsm.getCurrentState().getName().lower(): self.fsm.request('becomingToonFromCogdo') else: self.fsm.request('becomingToon') if self.suitPlannerExt: self.suitPlannerExt.recycleBuilding() if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior def getFrontDoorPoint(self): return self.frontDoorPoint def setFrontDoorPoint(self, point): self.frontDoorPoint = point def getBlock(self): (dummy, interiorZoneId) = self.getExteriorAndInteriorZoneId() return [self.block, interiorZoneId] def getSuitData(self): return [ord(self.track), self.difficulty, self.numFloors] def getState(self): return [self.fsm.getCurrentState().getName(), globalClockDelta.getRealNetworkTime()] def setState(self, state, timestamp=0): self.fsm.request(state) def isSuitBuilding(self): state = self.fsm.getCurrentState().getName() return state in ('suit', 'becomingSuit', 'clearOutToonInterior') def isCogdo(self): state = self.fsm.getCurrentState().getName() return state in ('cogdo', 'becomingCogdo', 'clearOutToonInteriorForCogdo') def isSuitBlock(self): return self.isSuitBuilding() or self.isCogdo() def isEstablishedSuitBlock(self): state = self.fsm.getCurrentState().getName() return state == 'suit' def isToonBlock(self): state = self.fsm.getCurrentState().getName() return state in ('toon', 'becomingToon', 'becomingToonFromCogdo') def getExteriorAndInteriorZoneId(self): blockNumber = self.block dnaStore = self.air.dnaStoreMap[self.canonicalZoneId] zoneId = dnaStore.getZoneFromBlockNumber(blockNumber) interiorZoneId = (zoneId - (zoneId%100)) + 500 + blockNumber return (zoneId, interiorZoneId) def d_setState(self, state): self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()]) def b_setVictorList(self, victorList): self.setVictorList(victorList) self.d_setVictorList(victorList) def d_setVictorList(self, victorList): self.sendUpdate('setVictorList', [victorList]) def setVictorList(self, victorList): self.victorList = victorList def findVictorIndex(self, avId): for i in xrange(len(self.victorList)): if self.victorList[i] == avId: return i def recordVictorResponse(self, avId): index = self.findVictorIndex(avId) if index is None: self.air.writeServerEvent('suspicious', avId, 'DistributedBuildingAI.setVictorReady from toon not in %s.' % self.victorList) return self.victorResponses[index] = avId def allVictorsResponded(self): if self.victorResponses == self.victorList: return 1 else: return 0 def setVictorReady(self): avId = self.air.getAvatarIdFromSender() if self.victorResponses is None: self.air.writeServerEvent('suspicious', avId, 'DistributedBuildingAI.setVictorReady in state %s.' % self.fsm.getCurrentState().getName()) return self.recordVictorResponse(avId) event = self.air.getAvatarExitEvent(avId) self.ignore(event) if self.allVictorsResponded(): self.toonTakeOver() def setVictorExited(self, avId): print 'victor %d exited unexpectedly for bldg %d' % (avId, self.doId) self.recordVictorResponse(avId) if self.allVictorsResponded(): self.toonTakeOver() def enterOff(self): pass def exitOff(self): pass def getToon(self, toonId): if toonId in self.air.doId2do: return self.air.doId2do[toonId] else: self.notify.warning('getToon() - toon: %d not in repository!' % toonId) def updateSavedBy(self, savedBy): if self.savedBy: for (avId, name, dna) in self.savedBy: self.trophyMgr.removeTrophy(avId, self.numFloors) self.savedBy = savedBy if self.savedBy: for (avId, name, dna) in self.savedBy: self.trophyMgr.addTrophy(avId, name, self.numFloors) def enterWaitForVictors(self, victorList, savedBy): activeToons = [] for t in victorList: toon = None if t: toon = self.getToon(t) if toon is not None: activeToons.append(toon) for t in victorList: toon = None if t: toon = self.getToon(t) self.air.writeServerEvent('buildingDefeated', t, '%s|%s|%s|%s' % (self.track, self.numFloors, self.zoneId, victorList)) if toon is not None: self.air.questManager.toonKilledBuilding(toon, self.track, self.difficulty, self.numFloors, self.zoneId, 0) for i in xrange(0, 4): victor = victorList[i] if (victor is None) or (victor not in self.air.doId2do): victorList[i] = 0 continue event = self.air.getAvatarExitEvent(victor) self.accept(event, self.setVictorExited, extraArgs=[victor]) self.b_setVictorList(victorList) self.updateSavedBy(savedBy) self.victorResponses = [0, 0, 0, 0] self.d_setState('waitForVictors') def exitWaitForVictors(self): self.victorResponses = None for victor in self.victorList: event = simbase.air.getAvatarExitEvent(victor) self.ignore(event) def enterWaitForVictorsFromCogdo(self, victorList, savedBy): activeToons = [] for t in victorList: toon = None if t: toon = self.getToon(t) if toon != None: activeToons.append(toon) continue for t in victorList: toon = None if t: toon = self.getToon(t) self.air.writeServerEvent('buildingDefeated', t, '%s|%s|%s|%s' % (self.track, self.numFloors, self.zoneId, victorList)) if toon != None: self.air.questManager.toonKilledBuilding(toon, self.track, self.difficulty, 5, self.zoneId, 1) continue victorList.extend([None, None, None, None]) for i in xrange(0, 4): victor = victorList[i] if victor == None or not victor in self.air.doId2do: victorList[i] = 0 continue event = self.air.getAvatarExitEvent(victor) self.accept(event, self.setVictorExited, extraArgs = [ victor]) self.b_setVictorList(victorList[:4]) self.updateSavedBy(savedBy) self.victorResponses = [ 0, 0, 0, 0] self.d_setState('waitForVictorsFromCogdo') def exitWaitForVictorsFromCogdo(self): self.victorResponses = None for victor in self.victorList: event = simbase.air.getAvatarExitEvent(victor) self.ignore(event) def enterBecomingToon(self): self.d_setState('becomingToon') name = self.taskName(str(self.block) + '_becomingToon-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_SEQUENCE_TIME, self.becomingToonTask, name) def exitBecomingToon(self): name = self.taskName(str(self.block) + '_becomingToon-timer') taskMgr.remove(name) def enterBecomingToonFromCogdo(self): self.d_setState('becomingToonFromCogdo') name = self.taskName(str(self.block) + '_becomingToonFromCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_SEQUENCE_TIME, self.becomingToonTask, name) def exitBecomingToonFromCogdo(self): name = self.taskName(str(self.block) + '_becomingToonFromCogdo-timer') taskMgr.remove(name) def becomingToonTask(self, task): self.fsm.request('toon') self.suitPlannerExt.buildingMgr.save() return Task.done def enterToon(self): self.d_setState('toon') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() if simbase.config.GetBool('want-new-toonhall', 1) and ZoneUtil.getCanonicalZoneId(interiorZoneId) == ToonHall: self.interior = DistributedToonHallInteriorAI.DistributedToonHallInteriorAI(self.block, self.air, interiorZoneId, self) else: self.interior = DistributedToonInteriorAI.DistributedToonInteriorAI(self.block, self.air, interiorZoneId, self) self.interior.generateWithRequired(interiorZoneId) door = self.createExteriorDoor() insideDoor = DistributedDoorAI.DistributedDoorAI(self.air, self.block, DoorTypes.INT_STANDARD) door.setOtherDoor(insideDoor) insideDoor.setOtherDoor(door) door.zoneId = exteriorZoneId insideDoor.zoneId = interiorZoneId door.generateWithRequired(exteriorZoneId) insideDoor.generateWithRequired(interiorZoneId) self.door = door self.insideDoor = insideDoor self.becameSuitTime = 0 self.knockKnock = DistributedKnockKnockDoorAI.DistributedKnockKnockDoorAI(self.air, self.block) self.knockKnock.generateWithRequired(exteriorZoneId) self.air.writeServerEvent('building-toon', self.doId, '%s|%s' % (self.zoneId, self.block)) def createExteriorDoor(self): result = DistributedDoorAI.DistributedDoorAI(self.air, self.block, DoorTypes.EXT_STANDARD) return result def exitToon(self): self.door.setDoorLock(FADoorCodes.BUILDING_TAKEOVER) def enterClearOutToonInterior(self): self.d_setState('clearOutToonInterior') if hasattr(self, 'interior'): self.interior.setState('beingTakenOver') name = self.taskName(str(self.block) + '_clearOutToonInterior-timer') taskMgr.doMethodLater(SuitBuildingGlobals.CLEAR_OUT_TOON_BLDG_TIME, self.clearOutToonInteriorTask, name) def exitClearOutToonInterior(self): name = self.taskName(str(self.block) + '_clearOutToonInterior-timer') taskMgr.remove(name) def clearOutToonInteriorTask(self, task): self.fsm.request('becomingSuit') return Task.done def enterBecomingSuit(self): self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) self.d_setState('becomingSuit') name = self.taskName(str(self.block) + '_becomingSuit-timer') taskMgr.doMethodLater(SuitBuildingGlobals.TO_SUIT_BLDG_TIME, self.becomingSuitTask, name) def exitBecomingSuit(self): name = self.taskName(str(self.block) + '_becomingSuit-timer') taskMgr.remove(name) if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior self.door.requestDelete() del self.door self.insideDoor.requestDelete() del self.insideDoor self.knockKnock.requestDelete() del self.knockKnock def becomingSuitTask(self, task): self.fsm.request('suit') self.suitPlannerExt.buildingMgr.save() return Task.done def enterSuit(self): self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) (zoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.planner = SuitPlannerInteriorAI.SuitPlannerInteriorAI(self.numFloors, self.difficulty, self.track, interiorZoneId) self.d_setState('suit') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.elevator = DistributedElevatorExtAI.DistributedElevatorExtAI(self.air, self) self.elevator.generateWithRequired(exteriorZoneId) self.air.writeServerEvent('building-cog', self.doId, '%s|%s|%s|%s' % (self.zoneId, self.block, self.track, self.numFloors)) def exitSuit(self): del self.planner if hasattr(self, 'elevator'): self.elevator.requestDelete() del self.elevator def enterClearOutToonInteriorForCogdo(self): self.d_setState('clearOutToonInteriorForCogdo') if hasattr(self, 'interior'): self.interior.setState('beingTakenOver') name = self.taskName(str(self.block) + '_clearOutToonInteriorForCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.CLEAR_OUT_TOON_BLDG_TIME, self.clearOutToonInteriorForCogdoTask, name) def exitClearOutToonInteriorForCogdo(self): name = self.taskName(str(self.block) + '_clearOutToonInteriorForCogdo-timer') taskMgr.remove(name) def clearOutToonInteriorForCogdoTask(self, task): self.fsm.request('becomingCogdo') return Task.done def enterBecomingCogdo(self): self.sendUpdate('setSuitData', [ ord(self.realTrack), self.difficulty, self.numFloors]) self.d_setState('becomingCogdo') name = self.taskName(str(self.block) + '_becomingCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.TO_SUIT_BLDG_TIME, self.becomingCogdoTask, name) def exitBecomingCogdo(self): name = self.taskName(str(self.block) + '_becomingCogdo-timer') taskMgr.remove(name) if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior self.door.requestDelete() del self.door self.insideDoor.requestDelete() del self.insideDoor self.knockKnock.requestDelete() del self.knockKnock def becomingCogdoTask(self, task): self.fsm.request('cogdo') self.suitPlannerExt.buildingMgr.save() return Task.done def enterCogdo(self): self.sendUpdate('setSuitData', [ ord(self.realTrack), self.difficulty, self.numFloors]) (zoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self._cogdoLayout = CogdoLayout(self.numFloors) self.planner = SuitPlannerCogdoInteriorAI(self._cogdoLayout, self.difficulty, self.track, interiorZoneId) self.d_setState('cogdo') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.elevator = DistributedCogdoElevatorExtAI(self.air, self) self.elevator.generateWithRequired(exteriorZoneId) def exitCogdo(self): del self.planner if hasattr(self, 'elevator'): self.elevator.requestDelete() del self.elevator def setSuitPlannerExt(self, planner): self.suitPlannerExt = planner def _createSuitInterior(self): return DistributedSuitInteriorAI.DistributedSuitInteriorAI(self.air, self.elevator) def _createCogdoInterior(self): return DistributedCogdoInteriorAI(self.air, self) def createSuitInterior(self): self.interior = self._createSuitInterior() (dummy, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.interior.fsm.request('WaitForAllToonsInside') self.interior.generateWithRequired(interiorZoneId) def createCogdoInterior(self): self.interior = self._createCogdoInterior() (dummy, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.interior.generateWithRequired(interiorZoneId) self.interior.b_setState('WaitForAllToonsInside') def deleteSuitInterior(self): if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior if hasattr(self, 'elevator'): self.elevator.d_setFloor(-1) self.elevator.open() def deleteCogdoInterior(self): self.deleteSuitInterior()
class DistributedBuildingAI(DistributedObjectAI.DistributedObjectAI): def __init__(self, air, blockNumber, zoneId, trophyMgr): DistributedObjectAI.DistributedObjectAI.__init__(self, air) self.block = blockNumber self.zoneId = zoneId self.canonicalZoneId = ZoneUtil.getCanonicalZoneId(zoneId) self.trophyMgr = trophyMgr self.victorResponses = None self.fsm = ClassicFSM.ClassicFSM('DistributedBuildingAI', [ State.State('off', self.enterOff, self.exitOff, [ 'waitForVictors', 'becomingToon', 'toon', 'clearOutToonInterior', 'becomingSuit', 'suit', 'clearOutToonInteriorForCogdo', 'becomingCogdo', 'cogdo' ]), State.State('waitForVictors', self.enterWaitForVictors, self.exitWaitForVictors, ['becomingToon']), State.State( 'waitForVictorsFromCogdo', self.enterWaitForVictorsFromCogdo, self.exitWaitForVictorsFromCogdo, ['becomingToonFromCogdo']), State.State('becomingToon', self.enterBecomingToon, self.exitBecomingToon, ['toon']), State.State('becomingToonFromCogdo', self.enterBecomingToonFromCogdo, self.exitBecomingToonFromCogdo, ['toon']), State.State( 'toon', self.enterToon, self.exitToon, ['clearOutToonInterior', 'clearOutToonInteriorForCogdo']), State.State('clearOutToonInterior', self.enterClearOutToonInterior, self.exitClearOutToonInterior, ['becomingSuit']), State.State('becomingSuit', self.enterBecomingSuit, self.exitBecomingSuit, ['suit']), State.State('suit', self.enterSuit, self.exitSuit, ['waitForVictors', 'becomingToon']), State.State('clearOutToonInteriorForCogdo', self.enterClearOutToonInteriorForCogdo, self.exitClearOutToonInteriorForCogdo, ['becomingCogdo']), State.State('becomingCogdo', self.enterBecomingCogdo, self.exitBecomingCogdo, ['cogdo']), State.State('cogdo', self.enterCogdo, self.exitCogdo, ['waitForVictorsFromCogdo', 'becomingToonFromCogdo']) ], 'off', 'off') self.fsm.enterInitialState() self.track = 'c' self.realTrack = 'c' self.difficulty = 1 self.numFloors = 0 self.savedBy = None self.becameSuitTime = 0 self.frontDoorPoint = None self.suitPlannerExt = None def announceGenerate(self): DistributedObjectAI.DistributedObjectAI.announceGenerate(self) (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.air.buildingQueryMgr.buildings[exteriorZoneId] = self self.air.buildingQueryMgr.buildings[interiorZoneId] = self def cleanup(self): if self.isDeleted(): return self.fsm.requestFinalState() if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior if hasattr(self, 'door'): self.door.requestDelete() del self.door self.insideDoor.requestDelete() del self.insideDoor self.knockKnock.requestDelete() del self.knockKnock if hasattr(self, 'elevator'): self.elevator.requestDelete() del self.elevator self.requestDelete() def delete(self): self.cleanup() taskMgr.remove(self.taskName('suitbldg-time-out')) taskMgr.remove(self.taskName(str(self.block) + '_becomingToon-timer')) taskMgr.remove(self.taskName(str(self.block) + '_becomingSuit-timer')) DistributedObjectAI.DistributedObjectAI.delete(self) del self.fsm def getPickleData(self): pickleData = { 'state': str(self.fsm.getCurrentState().getName()), 'block': str(self.block), 'track': str(self.track), 'difficulty': str(self.difficulty), 'numFloors': str(self.numFloors), 'savedBy': self.savedBy, 'becameSuitTime': self.becameSuitTime } return pickleData def _getMinMaxFloors(self, difficulty): return SuitBuildingGlobals.SuitBuildingInfo[difficulty][0] def suitTakeOver(self, suitTrack, difficulty, buildingHeight): if not self.isToonBlock(): return self.updateSavedBy(None) difficulty = min(difficulty, len(SuitBuildingGlobals.SuitBuildingInfo) - 1) (minFloors, maxFloors) = self._getMinMaxFloors(difficulty) if buildingHeight is None: numFloors = random.randint(minFloors, maxFloors) else: numFloors = buildingHeight + 1 if (numFloors < minFloors) or (numFloors > maxFloors): numFloors = random.randint(minFloors, maxFloors) self.track = suitTrack self.difficulty = difficulty self.numFloors = numFloors self.becameSuitTime = time.time() self.fsm.request('clearOutToonInterior') def cogdoTakeOver(self, difficulty, buildingHeight, track='s'): if not self.isToonBlock(): return None self.updateSavedBy(None) self.track = track self.realTrack = track self.difficulty = difficulty self.numFloors = 0 self.becameSuitTime = time.time() self.fsm.request('clearOutToonInteriorForCogdo') def toonTakeOver(self): if 'cogdo' in self.fsm.getCurrentState().getName().lower(): self.fsm.request('becomingToonFromCogdo') else: self.fsm.request('becomingToon') if self.suitPlannerExt: self.suitPlannerExt.recycleBuilding() if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior def getFrontDoorPoint(self): return self.frontDoorPoint def setFrontDoorPoint(self, point): self.frontDoorPoint = point def getBlock(self): (dummy, interiorZoneId) = self.getExteriorAndInteriorZoneId() return [self.block, interiorZoneId] def getSuitData(self): return [ord(self.track), self.difficulty, self.numFloors] def getState(self): return [ self.fsm.getCurrentState().getName(), globalClockDelta.getRealNetworkTime() ] def setState(self, state, timestamp=0): self.fsm.request(state) def isSuitBuilding(self): state = self.fsm.getCurrentState().getName() return state in ('suit', 'becomingSuit', 'clearOutToonInterior') def isCogdo(self): state = self.fsm.getCurrentState().getName() return state in ('cogdo', 'becomingCogdo', 'clearOutToonInteriorForCogdo') def isSuitBlock(self): return self.isSuitBuilding() or self.isCogdo() def isEstablishedSuitBlock(self): state = self.fsm.getCurrentState().getName() return state == 'suit' def isToonBlock(self): state = self.fsm.getCurrentState().getName() return state in ('toon', 'becomingToon', 'becomingToonFromCogdo') def getExteriorAndInteriorZoneId(self): blockNumber = self.block dnaStore = self.air.dnaStoreMap[self.canonicalZoneId] zoneId = dnaStore.getZoneFromBlockNumber(blockNumber) interiorZoneId = (zoneId - (zoneId % 100)) + 500 + blockNumber return (zoneId, interiorZoneId) def d_setState(self, state): self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()]) def b_setVictorList(self, victorList): self.setVictorList(victorList) self.d_setVictorList(victorList) def d_setVictorList(self, victorList): self.sendUpdate('setVictorList', [victorList]) def setVictorList(self, victorList): self.victorList = victorList def findVictorIndex(self, avId): for i in xrange(len(self.victorList)): if self.victorList[i] == avId: return i def recordVictorResponse(self, avId): index = self.findVictorIndex(avId) if index is None: self.air.writeServerEvent( 'suspicious', avId, 'DistributedBuildingAI.setVictorReady from toon not in %s.' % self.victorList) return self.victorResponses[index] = avId def allVictorsResponded(self): if self.victorResponses == self.victorList: return 1 else: return 0 def setVictorReady(self): avId = self.air.getAvatarIdFromSender() if self.victorResponses is None: self.air.writeServerEvent( 'suspicious', avId, 'DistributedBuildingAI.setVictorReady in state %s.' % self.fsm.getCurrentState().getName()) return self.recordVictorResponse(avId) event = self.air.getAvatarExitEvent(avId) self.ignore(event) if self.allVictorsResponded(): self.toonTakeOver() def setVictorExited(self, avId): print 'victor %d exited unexpectedly for bldg %d' % (avId, self.doId) self.recordVictorResponse(avId) if self.allVictorsResponded(): self.toonTakeOver() def enterOff(self): pass def exitOff(self): pass def getToon(self, toonId): if toonId in self.air.doId2do: return self.air.doId2do[toonId] else: self.notify.warning('getToon() - toon: %d not in repository!' % toonId) def updateSavedBy(self, savedBy): if self.savedBy: for (avId, name, dna) in self.savedBy: self.trophyMgr.removeTrophy(avId, self.numFloors) self.savedBy = savedBy if self.savedBy: for (avId, name, dna) in self.savedBy: self.trophyMgr.addTrophy(avId, name, self.numFloors) def enterWaitForVictors(self, victorList, savedBy): activeToons = [] for t in victorList: toon = None if t: toon = self.getToon(t) if toon is not None: activeToons.append(toon) for t in victorList: toon = None if t: toon = self.getToon(t) self.air.writeServerEvent( 'buildingDefeated', t, '%s|%s|%s|%s' % (self.track, self.numFloors, self.zoneId, victorList)) if toon is not None: self.air.questManager.toonKilledBuilding( toon, self.track, self.difficulty, self.numFloors, self.zoneId, 0) for i in xrange(0, 4): victor = victorList[i] if (victor is None) or (victor not in self.air.doId2do): victorList[i] = 0 continue event = self.air.getAvatarExitEvent(victor) self.accept(event, self.setVictorExited, extraArgs=[victor]) self.b_setVictorList(victorList) self.updateSavedBy(savedBy) self.victorResponses = [0, 0, 0, 0] self.d_setState('waitForVictors') def exitWaitForVictors(self): self.victorResponses = None for victor in self.victorList: event = simbase.air.getAvatarExitEvent(victor) self.ignore(event) def enterWaitForVictorsFromCogdo(self, victorList, savedBy): activeToons = [] for t in victorList: toon = None if t: toon = self.getToon(t) if toon != None: activeToons.append(toon) continue for t in victorList: toon = None if t: toon = self.getToon(t) self.air.writeServerEvent( 'buildingDefeated', t, '%s|%s|%s|%s' % (self.track, self.numFloors, self.zoneId, victorList)) if toon != None: self.air.questManager.toonKilledBuilding( toon, self.track, self.difficulty, 5, self.zoneId, 1) continue victorList.extend([None, None, None, None]) for i in xrange(0, 4): victor = victorList[i] if victor == None or not victor in self.air.doId2do: victorList[i] = 0 continue event = self.air.getAvatarExitEvent(victor) self.accept(event, self.setVictorExited, extraArgs=[victor]) self.b_setVictorList(victorList[:4]) self.updateSavedBy(savedBy) self.victorResponses = [0, 0, 0, 0] self.d_setState('waitForVictorsFromCogdo') def exitWaitForVictorsFromCogdo(self): self.victorResponses = None for victor in self.victorList: event = simbase.air.getAvatarExitEvent(victor) self.ignore(event) def enterBecomingToon(self): self.d_setState('becomingToon') name = self.taskName(str(self.block) + '_becomingToon-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_SEQUENCE_TIME, self.becomingToonTask, name) def exitBecomingToon(self): name = self.taskName(str(self.block) + '_becomingToon-timer') taskMgr.remove(name) def enterBecomingToonFromCogdo(self): self.d_setState('becomingToonFromCogdo') name = self.taskName(str(self.block) + '_becomingToonFromCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_SEQUENCE_TIME, self.becomingToonTask, name) def exitBecomingToonFromCogdo(self): name = self.taskName(str(self.block) + '_becomingToonFromCogdo-timer') taskMgr.remove(name) def becomingToonTask(self, task): self.fsm.request('toon') self.suitPlannerExt.buildingMgr.save() return Task.done def enterToon(self): self.d_setState('toon') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() if simbase.config.GetBool( 'want-new-toonhall', 1) and ZoneUtil.getCanonicalZoneId(interiorZoneId) == ToonHall: self.interior = DistributedToonHallInteriorAI.DistributedToonHallInteriorAI( self.block, self.air, interiorZoneId, self) else: self.interior = DistributedToonInteriorAI.DistributedToonInteriorAI( self.block, self.air, interiorZoneId, self) self.interior.generateWithRequired(interiorZoneId) door = self.createExteriorDoor() insideDoor = DistributedDoorAI.DistributedDoorAI( self.air, self.block, DoorTypes.INT_STANDARD) door.setOtherDoor(insideDoor) insideDoor.setOtherDoor(door) door.zoneId = exteriorZoneId insideDoor.zoneId = interiorZoneId door.generateWithRequired(exteriorZoneId) insideDoor.generateWithRequired(interiorZoneId) self.door = door self.insideDoor = insideDoor self.becameSuitTime = 0 self.knockKnock = DistributedKnockKnockDoorAI.DistributedKnockKnockDoorAI( self.air, self.block) self.knockKnock.generateWithRequired(exteriorZoneId) self.air.writeServerEvent('building-toon', self.doId, '%s|%s' % (self.zoneId, self.block)) def createExteriorDoor(self): result = DistributedDoorAI.DistributedDoorAI(self.air, self.block, DoorTypes.EXT_STANDARD) return result def exitToon(self): self.door.setDoorLock(FADoorCodes.BUILDING_TAKEOVER) def enterClearOutToonInterior(self): self.d_setState('clearOutToonInterior') if hasattr(self, 'interior'): self.interior.setState('beingTakenOver') name = self.taskName(str(self.block) + '_clearOutToonInterior-timer') taskMgr.doMethodLater(SuitBuildingGlobals.CLEAR_OUT_TOON_BLDG_TIME, self.clearOutToonInteriorTask, name) def exitClearOutToonInterior(self): name = self.taskName(str(self.block) + '_clearOutToonInterior-timer') taskMgr.remove(name) def clearOutToonInteriorTask(self, task): self.fsm.request('becomingSuit') return Task.done def enterBecomingSuit(self): self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) self.d_setState('becomingSuit') name = self.taskName(str(self.block) + '_becomingSuit-timer') taskMgr.doMethodLater(SuitBuildingGlobals.TO_SUIT_BLDG_TIME, self.becomingSuitTask, name) def exitBecomingSuit(self): name = self.taskName(str(self.block) + '_becomingSuit-timer') taskMgr.remove(name) if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior self.door.requestDelete() del self.door self.insideDoor.requestDelete() del self.insideDoor self.knockKnock.requestDelete() del self.knockKnock def becomingSuitTask(self, task): self.fsm.request('suit') self.suitPlannerExt.buildingMgr.save() return Task.done def enterSuit(self): self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) (zoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.planner = SuitPlannerInteriorAI.SuitPlannerInteriorAI( self.numFloors, self.difficulty, self.track, interiorZoneId) self.d_setState('suit') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.elevator = DistributedElevatorExtAI.DistributedElevatorExtAI( self.air, self) self.elevator.generateWithRequired(exteriorZoneId) self.air.writeServerEvent( 'building-cog', self.doId, '%s|%s|%s|%s' % (self.zoneId, self.block, self.track, self.numFloors)) def exitSuit(self): del self.planner if hasattr(self, 'elevator'): self.elevator.requestDelete() del self.elevator def enterClearOutToonInteriorForCogdo(self): self.d_setState('clearOutToonInteriorForCogdo') if hasattr(self, 'interior'): self.interior.setState('beingTakenOver') name = self.taskName( str(self.block) + '_clearOutToonInteriorForCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.CLEAR_OUT_TOON_BLDG_TIME, self.clearOutToonInteriorForCogdoTask, name) def exitClearOutToonInteriorForCogdo(self): name = self.taskName( str(self.block) + '_clearOutToonInteriorForCogdo-timer') taskMgr.remove(name) def clearOutToonInteriorForCogdoTask(self, task): self.fsm.request('becomingCogdo') return Task.done def enterBecomingCogdo(self): self.sendUpdate('setSuitData', [ord(self.realTrack), self.difficulty, self.numFloors]) self.d_setState('becomingCogdo') name = self.taskName(str(self.block) + '_becomingCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.TO_SUIT_BLDG_TIME, self.becomingCogdoTask, name) def exitBecomingCogdo(self): name = self.taskName(str(self.block) + '_becomingCogdo-timer') taskMgr.remove(name) if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior self.door.requestDelete() del self.door self.insideDoor.requestDelete() del self.insideDoor self.knockKnock.requestDelete() del self.knockKnock def becomingCogdoTask(self, task): self.fsm.request('cogdo') self.suitPlannerExt.buildingMgr.save() return Task.done def enterCogdo(self): self.sendUpdate('setSuitData', [ord(self.realTrack), self.difficulty, self.numFloors]) (zoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self._cogdoLayout = CogdoLayout(self.numFloors) self.planner = SuitPlannerCogdoInteriorAI(self._cogdoLayout, self.difficulty, self.track, interiorZoneId) self.d_setState('cogdo') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.elevator = DistributedCogdoElevatorExtAI(self.air, self) self.elevator.generateWithRequired(exteriorZoneId) def exitCogdo(self): del self.planner if hasattr(self, 'elevator'): self.elevator.requestDelete() del self.elevator def setSuitPlannerExt(self, planner): self.suitPlannerExt = planner def _createSuitInterior(self): return DistributedSuitInteriorAI.DistributedSuitInteriorAI( self.air, self.elevator) def _createCogdoInterior(self): return DistributedCogdoInteriorAI(self.air, self) def createSuitInterior(self): self.interior = self._createSuitInterior() (dummy, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.interior.fsm.request('WaitForAllToonsInside') self.interior.generateWithRequired(interiorZoneId) def createCogdoInterior(self): self.interior = self._createCogdoInterior() (dummy, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.interior.generateWithRequired(interiorZoneId) self.interior.b_setState('WaitForAllToonsInside') def deleteSuitInterior(self): if hasattr(self, 'interior'): self.interior.requestDelete() del self.interior if hasattr(self, 'elevator'): self.elevator.d_setFloor(-1) self.elevator.open() def deleteCogdoInterior(self): self.deleteSuitInterior()