def enterCogdo(self): assert (self.debugPrint("enterCogdo()")) # We have to send this message again, even though we've # already sent it in becomingCogdo, because we might have come # to this state directly on startup. self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) # Create the suit planner for the interior zoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() self._cogdoLayout = CogdoLayout(self.numFloors) self.planner = SuitPlannerCogdoInteriorAI(self._cogdoLayout, self.difficulty, self.track, interiorZoneId) self.d_setState('cogdo') # Create the DistributedDoor: exteriorZoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() #todo: ...create the elevator. self.elevator = DistributedCogdoElevatorExtAI(self.air, self) self.elevator.generateWithRequired(exteriorZoneId) self.air.writeServerEvent( 'building-cogdo', self.doId, "%s|%s|%s" % (self.zoneId, self.block, self.numFloors))
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 enterCogdo(self): self.sendUpdate('setSuitData', [ord(self.track), 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) self.air.writeServerEvent('building-cogdo', self.doId, '%s|%s|%s' % (self.zoneId, self.block, self.numFloors))
def enterCogdo(self): self.sendUpdate('setSuitData', [ord(self.track), 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) self.air.writeServerEvent('building-cogdo', self.doId, '%s|%s|%s' % (self.zoneId, self.block, self.numFloors))
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)
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.difficulty = 1 self.numFloors = 0 self.savedBy = None self.becameSuitTime = 0 self.frontDoorPoint = None self.suitPlannerExt = None 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): 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): if not self.isToonBlock(): return self.updateSavedBy(None) (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 = 'c' self.difficulty = difficulty self.numFloors = numFloors 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) zoneId = ZoneUtil.getTrueZoneId(zoneId, self.zoneId) 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 self.air.doId2do.has_key(toonId): 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: if not ZoneUtil.isWelcomeValley(self.zoneId): self.trophyMgr.removeTrophy(avId, self.numFloors) self.savedBy = savedBy if self.savedBy: for (avId, name, dna) in self.savedBy: if not ZoneUtil.isWelcomeValley(self.zoneId): 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, activeToons) 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 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.toonKilledCogdo(toon, self.difficulty, self.numFloors, self.zoneId, activeToons) 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('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() self.trophyMgr.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.track), 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.track), 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) self.air.writeServerEvent( 'building-cogdo', self.doId, '%s|%s|%s' % (self.zoneId, self.block, self.numFloors)) 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.elevator) 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.fsm.request('WaitForAllToonsInside') self.interior.generateWithRequired(interiorZoneId) 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 cleanup(self): if self.isDeleted(): return None 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): 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): print 'Building %s (%s): suitTakeOver' % (self.doId, self.zoneId) if not self.isToonBlock(): return None self.updateSavedBy(None) self.realTrack = suitTrack if random.random() < (1 - config.GetFloat('lt-ratio', .06)): difficulty = min(difficulty, len(SuitBuildingGlobals.SuitBuildingInfo) - 1) (minFloors, maxFloors) = self._getMinMaxFloors(difficulty) if buildingHeight == None: numFloors = random.randint(minFloors, maxFloors) else: numFloors = buildingHeight + 1 if numFloors < minFloors or numFloors > maxFloors: numFloors = random.randint(minFloors, maxFloors) else: self.realTrack = "x" difficulty = 19 numFloors = random.choice((1, 5)) print '\tLT', numFloors self.track = suitTrack self.difficulty = difficulty self.numFloors = numFloors self.becameSuitTime = time.time() self.fsm.request('clearOutToonInterior') self.air.apiMgr.d_updateBlock(self) def cogdoTakeOver(self, difficulty, buildingHeight, track = 's'): print 'Building %s (%s): cogdoTakeOver' % (self.doId, self.zoneId) 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') self.air.apiMgr.d_updateBlock(self) 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 self.air.apiMgr.d_updateBlock(self) 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.realTrack), 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.getStorage(self.canonicalZoneId) zoneId = dnaStore.getZoneFromBlockNumber(blockNumber) zoneId = ZoneUtil.getTrueZoneId(zoneId, self.zoneId) 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 range(len(self.victorList)): if self.victorList[i] == avId: return i continue def recordVictorResponse(self, avId): if not self.victorResponses: return index = self.findVictorIndex(avId) if index == None: self.air.writeServerEvent('suspicious', avId, 'DistributedBuildingAI.setVictorReady from toon not in %s.' % self.victorList) return None self.victorResponses[index] = avId def allVictorsResponded(self): numWaiting = len(filter(None, self.victorList)) numReady = len(filter(None, self.victorResponses)) return numWaiting == numReady def setVictorReady(self): avId = self.air.getAvatarIdFromSender() if self.victorResponses == None: self.air.writeServerEvent('suspicious', avId, 'DistributedBuildingAI.setVictorReady in state %s.' % self.fsm.getCurrentState().getName()) return None print 'victor %d ready' % avId 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 self.air.doId2do.has_key(toonId): return self.air.doId2do[toonId] else: self.notify.warning('getToon() - toon: %d not in repository!' % toonId) def getBuildingHash(self): return self.zoneId << 16 | self.block def updateSavedBy(self, savedBy): if self.savedBy: for (avId, name, dna) in self.savedBy: if not ZoneUtil.isWelcomeValley(self.zoneId): if self.trophyMgr: self.trophyMgr.removeTrophy(self, avId) self.savedBy = savedBy if self.savedBy: for (avId, name, dna) in self.savedBy: if not ZoneUtil.isWelcomeValley(self.zoneId): if self.trophyMgr and not self.isCogdo(): self.trophyMgr.addTrophy(self, avId, name, self.numFloors) def enterWaitForVictors(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, self.numFloors, self.zoneId, activeToons) continue for i in range(0, 4): victor = victorList[i] if victor == None or not self.air.doId2do.has_key(victor): 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.toonKilledCogdo(toon, self.track, self.difficulty, self.numFloors, self.zoneId, activeToons) continue victorList.extend([None, None, None, None]) for i in range(0, 4): victor = victorList[i] if victor == None or not self.air.doId2do.has_key(victor): 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) 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.realTrack), 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.realTrack), self.difficulty, self.numFloors]) (zoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.planner = SuitPlannerInteriorAI.SuitPlannerInteriorAI(self.numFloors, self.difficulty, self.realTrack, interiorZoneId) self.d_setState('suit') (exteriorZoneId, interiorZoneId) = self.getExteriorAndInteriorZoneId() self.elevator = DistributedElevatorExtAI.DistributedElevatorExtAI(self.air, self) self.elevator.generateWithRequired(exteriorZoneId) 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): """ DistributedBuildingAI class: The server side representation of a single building. This is the object that remember who 'owns' the associated building (either the bad guys or the toons). The child of this object, the DistributedBuilding object, is the client side version and updates the display that client's display based on who 'owns' the building. """ if __debug__: notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedBuildingAI') FieldOfficeNumFloors = 1 def __init__(self, air, blockNumber, zoneId, trophyMgr): """blockNumber: the landmark building number (from the name)""" DistributedObjectAI.DistributedObjectAI.__init__(self, air) self.block = blockNumber assert (self.debugPrint("DistributedBuildingAI(%s, %s)" % ("the air", str(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', 'becomingCogdoFromCogdo' 'cogdo', ]), State.State('waitForVictors', self.enterWaitForVictors, self.exitWaitForVictors, [ 'becomingToon', ]), State.State( 'waitForVictorsFromCogdo', self.enterWaitForVictorsFromCogdo, self.exitWaitForVictorsFromCogdo, ['becomingToonFromCogdo', 'becomingCogdoFromCogdo']), 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', # debug only ]), State.State('clearOutToonInteriorForCogdo', self.enterClearOutToonInteriorForCogdo, self.exitClearOutToonInteriorForCogdo, ['becomingCogdo']), State.State('becomingCogdo', self.enterBecomingCogdo, self.exitBecomingCogdo, ['cogdo']), State.State('becomingCogdoFromCogdo', self.enterBecomingCogdoFromCogdo, self.exitBecomingCogdoFromCogdo, ['cogdo']), State.State( 'cogdo', self.enterCogdo, self.exitCogdo, [ 'waitForVictorsFromCogdo', 'becomingToonFromCogdo', # debug only ]) ], # Initial State 'off', # Final State 'off', ) self.fsm.enterInitialState() self.track = 'c' self.difficulty = 1 self.numFloors = 0 self.savedBy = None self.becameSuitTime = 0 self.frontDoorPoint = None self.suitPlannerExt = None 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): """ //////////////////////////////////////////////////////////////////// // Function: clean up tasks that might still be running for this // building // Parameters: // Changes: //////////////////////////////////////////////////////////////////// """ # make sure to remove any tasks we might have created taskMgr.remove(self.taskName('suitbldg-time-out')) # remove the doLater associated with the state transition of # a suit building becoming a toon building taskMgr.remove(self.taskName(str(self.block) + '_becomingToon-timer')) # remove the doLater associated with the state transition of # a toon building becoming a suit building taskMgr.remove(self.taskName(str(self.block) + '_becomingSuit-timer')) DistributedObjectAI.DistributedObjectAI.delete(self) del self.fsm def getPickleData(self): assert (self.debugPrint("getPickleData()")) 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): """Switch from toon to suit building suitTrack: one of 'c', 'l', 'm', or 's' difficulty: 0+ buildingHeight: 0..4, or None to choose based on the difficulty. """ if not self.isToonBlock(): return assert (suitTrack in ['c', 'l', 'm', 's']) # Remove the old saved by credit with the old number of floors self.updateSavedBy(None) difficulty = min(difficulty, len(SuitBuildingGlobals.SuitBuildingInfo) - 1) minFloors, maxFloors = self._getMinMaxFloors(difficulty) if buildingHeight == None: # Pick a random floor number from the appropriate range. numFloors = random.randint(minFloors, maxFloors) else: # The number of floors is specified. numFloors = buildingHeight + 1 if (numFloors < minFloors or numFloors > maxFloors): # Hmm, the number of floors is out of range for this # suit. There must be an invasion in effect. In that # case, go ahead and make a building of any height # appropriate to the suit. numFloors = random.randint(minFloors, maxFloors) assert (self.debugPrint("suitTakeOver(%s, %s, %s)" % (suitTrack, difficulty, numFloors - 1))) self.track = suitTrack self.difficulty = difficulty self.numFloors = numFloors self.becameSuitTime = time.time() self.fsm.request('clearOutToonInterior') def cogdoTakeOver(self, suitTrack, difficulty, buildingHeight): if not self.isToonBlock(): return numFloors = self.FieldOfficeNumFloors self.track = suitTrack self.difficulty = difficulty self.numFloors = numFloors self.becameSuitTime = time.time() self.fsm.request('clearOutToonInteriorForCogdo') def toonTakeOver(self): """Switch from suit to toon building savedBy: a list of 1 to 4 avatar [name, style] lists.""" assert (self.debugPrint("toonTakeOver(savedBy=%s)" % (self.savedBy))) isCogdo = 'cogdo' in self.fsm.getCurrentState().getName().lower() takenOver = True if isCogdo: if self.buildingDefeated: self.fsm.request('becomingToonFromCogdo') else: self.fsm.request('becomingCogdoFromCogdo') takenOver = False else: self.fsm.request('becomingToon') if self.suitPlannerExt: self.suitPlannerExt.recycleBuilding(isCogdo) if hasattr(self, "interior"): self.interior.requestDelete() del self.interior def getFrontDoorPoint(self): """get any associated path point for this building, useful for suits to know where to go when exiting from a building""" assert (self.debugPrint("getFrontDoorPoint()")) return self.frontDoorPoint def setFrontDoorPoint(self, point): """set the associated front door point with this building""" assert (self.debugPrint("setFrontDoorPoint(%s)" % (str(point)))) self.frontDoorPoint = point def getBlock(self): assert (self.debugPrint("getBlock()")) dummy, interiorZoneId = self.getExteriorAndInteriorZoneId() return [self.block, interiorZoneId] def getSuitData(self): assert (self.debugPrint("getSuitData()")) return [ord(self.track), self.difficulty, self.numFloors] def getState(self): assert (self.debugPrint("getState()")) return [ self.fsm.getCurrentState().getName(), globalClockDelta.getRealNetworkTime() ] def setState(self, state, timestamp=0): assert (self.notify.debug( str(self.block) + " setState(state=" + str(state) + ")")) self.fsm.request(state) def isSuitBuilding(self): """return true if that block is a suit building""" assert (self.debugPrint("isSuitBlock()")) state = self.fsm.getCurrentState().getName() return state=='suit' or state=='becomingSuit' or \ state=='clearOutToonInterior' def isCogdo(self): """return true if that block is a cogdo""" assert (self.debugPrint("isSuitBlock()")) state = self.fsm.getCurrentState().getName() return state=='cogdo' or state=='becomingCogdo' or \ state=='becomingCogdoFromCogdo' or \ state=='clearOutToonInteriorForCogdo' def isSuitBlock(self): """return true if that block is a suit block/building/cogdo""" assert (self.debugPrint("isSuitBlock()")) state = self.fsm.getCurrentState().getName() return self.isSuitBuilding() or self.isCogdo() def isEstablishedSuitBlock(self): """return true if that block is a fully established suit building""" assert (self.debugPrint("isEstablishedSuitBlock()")) state = self.fsm.getCurrentState().getName() return state == 'suit' def isToonBlock(self): """return true if that block is a toon block/building""" assert (self.debugPrint("isToonBlock()")) state = self.fsm.getCurrentState().getName() return state in ( 'toon', 'becomingToon', 'becomingToonFromCogdo', ) def getExteriorAndInteriorZoneId(self): assert (self.notify.debug(str(self.block) + " getInteriorZoneId()")) blockNumber = self.block assert (blockNumber < 100 ) # this may cause trouble for the interiorZoneId, # it may bump into the next higher zone range. dnaStore = self.air.dnaStoreMap[self.canonicalZoneId] zoneId = dnaStore.getZoneFromBlockNumber(blockNumber) zoneId = ZoneUtil.getTrueZoneId(zoneId, self.zoneId) interiorZoneId = (zoneId - zoneId % 100) + 500 + blockNumber assert (self.notify.debug( str(self.block) + " getInteriorZoneId() returning" + str(interiorZoneId))) return zoneId, interiorZoneId def d_setState(self, state): assert (self.notify.debug( str(self.block) + " d_setState(state=" + str(state) + ")")) self.sendUpdate('setState', [state, globalClockDelta.getRealNetworkTime()]) def b_setVictorList(self, victorList): self.setVictorList(victorList) self.d_setVictorList(victorList) return def d_setVictorList(self, victorList): self.sendUpdate("setVictorList", [victorList]) return def setVictorList(self, victorList): self.victorList = victorList return def findVictorIndex(self, avId): for i in range(len(self.victorList)): if self.victorList[i] == avId: return i return None def recordVictorResponse(self, avId): index = self.findVictorIndex(avId) if index == None: self.air.writeServerEvent( 'suspicious', avId, 'DistributedBuildingAI.setVictorReady from toon not in %s.' % (self.victorList)) return assert (self.victorResponses[index] == 0 or self.victorResponses[index] == avId) 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 == None: self.air.writeServerEvent( 'suspicious', avId, 'DistributedBuildingAI.setVictorReady in state %s.' % (self.fsm.getCurrentState().getName())) return assert (self.notify.debug("victor %d is ready for bldg %d" % (avId, self.doId))) self.recordVictorResponse(avId) # Don't tell us about this avatar exiting any more. 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() ##### off state ##### def enterOff(self): assert (self.debugPrint("enterOff()")) def exitOff(self): assert (self.debugPrint("exitOff()")) ##### waitForVictors state ##### 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) return None def updateSavedBy(self, savedBy): # Clear the old savedBy from the trophy manager if self.savedBy: for avId, name, dna in self.savedBy: # Don't change building take over score when the toon is in the welcome valley. if not ZoneUtil.isWelcomeValley(self.zoneId): self.trophyMgr.removeTrophy(avId, self.numFloors) # Update the new saved by list self.savedBy = savedBy if self.savedBy: for avId, name, dna in self.savedBy: # Don't change building take over score when the toon is in the welcome valley. if not ZoneUtil.isWelcomeValley(self.zoneId): self.trophyMgr.addTrophy(avId, name, self.numFloors) def enterWaitForVictors(self, victorList, savedBy): assert (len(victorList) == 4) # Grab the list of active toons to pass in for each toon # (this is used by the quest system) activeToons = [] for t in victorList: toon = None if (t): toon = self.getToon(t) if (toon != None): activeToons.append(toon) # Tell the quest manager that these toons defeated this building 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, self.numFloors, self.zoneId, activeToons) # Convert the list to all ints. 0 means no one is there. # Also, if a toon has disconnected, remove him from the list. for i in range(0, 4): victor = victorList[i] if victor == None or victor not in self.air.doId2do: victorList[i] = 0 else: # Handle unexpected exit messages for everyone else. event = self.air.getAvatarExitEvent(victor) self.accept(event, self.setVictorExited, extraArgs=[victor]) # Save the list and also tell it to all the clients. self.b_setVictorList(victorList) self.updateSavedBy(savedBy) # List of victor responses self.victorResponses = [0, 0, 0, 0] # Tell the client to go into waitForVictors state self.d_setState("waitForVictors") return def exitWaitForVictors(self): # Stop waiting for unexpected exits. self.victorResponses = None for victor in self.victorList: event = simbase.air.getAvatarExitEvent(victor) self.ignore(event) return def enterWaitForVictorsFromCogdo(self, victorList, savedBy): assert (len(victorList) == 4) # Grab the list of active toons to pass in for each toon # (this is used by the quest system) activeToons = [] for t in victorList: toon = None if (t): toon = self.getToon(t) if (toon != None): activeToons.append(toon) self.buildingDefeated = len(savedBy) > 0 if self.buildingDefeated: # Tell the quest manager that these toons defeated this building 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.toonKilledCogdo(toon, self.difficulty, self.numFloors, self.zoneId, activeToons) # Convert the list to all ints. 0 means no one is there. # Also, if a toon has disconnected, remove him from the list. for i in range(0, 4): victor = victorList[i] if victor == None or victor not in self.air.doId2do: victorList[i] = 0 else: # Handle unexpected exit messages for everyone else. event = self.air.getAvatarExitEvent(victor) self.accept(event, self.setVictorExited, extraArgs=[victor]) # Save the list and also tell it to all the clients. self.b_setVictorList(victorList) self.updateSavedBy(savedBy) # List of victor responses self.victorResponses = [0, 0, 0, 0] # Tell the client to go into waitForVictors state self.d_setState("waitForVictorsFromCogdo") return def exitWaitForVictorsFromCogdo(self): # Stop waiting for unexpected exits. self.victorResponses = None for victor in self.victorList: event = simbase.air.getAvatarExitEvent(victor) self.ignore(event) return ##### becomingToon state ##### def enterBecomingToon(self): assert (self.debugPrint("enterBecomingToon()")) self.d_setState('becomingToon') name = self.taskName(str(self.block) + '_becomingToon-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_SEQUENCE_TIME, self.becomingToonTask, name) def exitBecomingToon(self): assert (self.debugPrint("exitBecomingToon()")) name = self.taskName(str(self.block) + '_becomingToon-timer') taskMgr.remove(name) ##### becomingToonFromCogdo state ##### def enterBecomingToonFromCogdo(self): assert (self.debugPrint("enterBecomingToonFromCogdo()")) self.d_setState('becomingToonFromCogdo') name = self.taskName(str(self.block) + '_becomingToonFromCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_SEQUENCE_TIME, self.becomingToonTask, name) def exitBecomingToonFromCogdo(self): assert (self.debugPrint("exitBecomingToonFromCogdo()")) name = self.taskName(str(self.block) + '_becomingToonFromCogdo-timer') taskMgr.remove(name) ##### toon state ##### def becomingToonTask(self, task): assert (self.debugPrint("becomingToonTask()")) self.fsm.request("toon") # Save the building state whenever we convert a building to # toonness. self.suitPlannerExt.buildingMgr.save() return Task.done def enterToon(self): assert (self.debugPrint("enterToon()")) self.d_setState('toon') # Create the DistributedDoor: exteriorZoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() # Toon interior: if ConfigVariableBool("want-new-toonhall",1).getValue() 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) # Outside door: door = self.createExteriorDoor() # Inside of the same door (different zone, and different distributed object): insideDoor = DistributedDoorAI.DistributedDoorAI( self.air, self.block, DoorTypes.INT_STANDARD) # Tell them about each other: door.setOtherDoor(insideDoor) insideDoor.setOtherDoor(door) door.zoneId = exteriorZoneId insideDoor.zoneId = interiorZoneId # Now that they both now about each other, generate them: door.generateWithRequired(exteriorZoneId) insideDoor.generateWithRequired(interiorZoneId) # keep track of them: 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): """Return the DistributedDoor for the exterior, with correct door type set""" # Created so animated buildings can over ride this function result = DistributedDoorAI.DistributedDoorAI(self.air, self.block, DoorTypes.EXT_STANDARD) return result def exitToon(self): assert (self.debugPrint("exitToon()")) self.door.setDoorLock(FADoorCodes.BUILDING_TAKEOVER) # The door doesn't get unlocked, because # it will be distroyed and recreated. ##### clearOutToonInterior state ##### def enterClearOutToonInterior(self): assert (self.debugPrint("enterClearOutToonInterior()")) 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): assert (self.debugPrint("exitClearOutToonInterior()")) name = self.taskName(str(self.block) + '_clearOutToonInterior-timer') taskMgr.remove(name) ##### becomingSuit state ##### def clearOutToonInteriorTask(self, task): assert (self.debugPrint("clearOutToonInteriorTask()")) self.fsm.request("becomingSuit") return Task.done def enterBecomingSuit(self): assert (self.debugPrint("enterBecomingSuit()")) # We have to send this message before we send the distributed # update to becomingSuit state, because the clients depend on # knowing what kind of suit building we're becoming. 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): assert (self.debugPrint("exitBecomingSuit()")) name = self.taskName(str(self.block) + '_becomingSuit-timer') taskMgr.remove(name) # Clean up the toon distributed objects: 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 ##### suit state ##### def becomingSuitTask(self, task): assert (self.debugPrint("becomingSuitTask()")) self.fsm.request("suit") # Save the building state whenever we convert a building to # suitness. self.suitPlannerExt.buildingMgr.save() return Task.done def enterSuit(self): assert (self.debugPrint("enterSuit()")) # We have to send this message again, even though we've # already sent it in becomingSuit, because we might have come # to this state directly on startup. self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) # Create the suit planner for the interior zoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() self.planner = SuitPlannerInteriorAI.SuitPlannerInteriorAI( self.numFloors, self.difficulty, self.track, interiorZoneId) self.d_setState('suit') # Create the DistributedDoor: exteriorZoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() #todo: ...create the elevator. 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): assert (self.debugPrint("exitSuit()")) del self.planner # Clean up the suit distributed objects: if hasattr(self, "elevator"): self.elevator.requestDelete() del self.elevator ##### clearOutToonInteriorForCogdo state ##### def enterClearOutToonInteriorForCogdo(self): assert (self.debugPrint("enterClearOutToonInteriorForCogdo()")) 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): assert (self.debugPrint("exitClearOutToonInteriorForCogdo()")) name = self.taskName( str(self.block) + '_clearOutToonInteriorForCogdo-timer') taskMgr.remove(name) ##### becomingCogdo state ##### def clearOutToonInteriorForCogdoTask(self, task): assert (self.debugPrint("clearOutToonInteriorForCogdoTask()")) self.fsm.request("becomingCogdo") return Task.done def enterBecomingCogdo(self): assert (self.debugPrint("enterBecomingCogdo()")) # We have to send this message before we send the distributed # update to becomingCogdo state, because the clients depend on # knowing what kind of cogdo building we're becoming. self.sendUpdate('setSuitData', [ord(self.track), 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): assert (self.debugPrint("exitBecomingCogdo()")) name = self.taskName(str(self.block) + '_becomingCogdo-timer') taskMgr.remove(name) # Clean up the toon distributed objects: 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 ##### becomingCogdoFromCogdo state ##### def enterBecomingCogdoFromCogdo(self): assert (self.debugPrint("enterBecomingCogdoFromCogdo()")) self.d_setState('becomingCogdoFromCogdo') name = self.taskName(str(self.block) + '_becomingCogdoFromCogdo-timer') taskMgr.doMethodLater(SuitBuildingGlobals.VICTORY_RUN_TIME, self.becomingCogdoTask, name) def exitBecomingCogdoFromCogdo(self): assert (self.debugPrint("exitBecomingCogdoFromCogdo()")) self.fSkipElevatorOpening = True name = self.taskName(str(self.block) + '_becomingCogdoFromCogdo-timer') taskMgr.remove(name) ##### cogdo state ##### def becomingCogdoTask(self, task): assert (self.debugPrint("becomingCogdoTask()")) self.fsm.request("cogdo") # Save the building state whenever we convert a building to # cogdoness. self.suitPlannerExt.buildingMgr.save() return Task.done def enterCogdo(self): assert (self.debugPrint("enterCogdo()")) # We have to send this message again, even though we've # already sent it in becomingCogdo, because we might have come # to this state directly on startup. self.sendUpdate('setSuitData', [ord(self.track), self.difficulty, self.numFloors]) # Create the suit planner for the interior zoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() self._cogdoLayout = CogdoLayout(self.numFloors) self.planner = SuitPlannerCogdoInteriorAI(self._cogdoLayout, self.difficulty, self.track, interiorZoneId) self.d_setState('cogdo') # Create the DistributedDoor: exteriorZoneId, interiorZoneId = self.getExteriorAndInteriorZoneId() #todo: ...create the elevator. self.elevator = DistributedCogdoElevatorExtAI(self.air, self) self.elevator.generateWithRequired(exteriorZoneId) self.air.writeServerEvent( 'building-cogdo', self.doId, "%s|%s|%s" % (self.zoneId, self.block, self.numFloors)) def exitCogdo(self): assert (self.debugPrint("exitCogdo()")) del self.planner # Clean up the cogdo distributed objects: if hasattr(self, "elevator"): self.elevator.requestDelete() del self.elevator def setSuitPlannerExt(self, planner): """ //////////////////////////////////////////////////////////////////// // Function: let the building know which suit planner contains // its building manager // Parameters: planner, the governing suit planner for this bldg // Changes: //////////////////////////////////////////////////////////////////// """ self.suitPlannerExt = planner def _createSuitInterior(self): return DistributedSuitInteriorAI.DistributedSuitInteriorAI( self.air, self.elevator) def _createCogdoInterior(self): return DistributedCogdoInteriorAI(self.air, self.elevator) def createSuitInterior(self): # Create a building interior in the new (interior) zone self.interior = self._createSuitInterior() dummy, interiorZoneId = self.getExteriorAndInteriorZoneId() self.interior.fsm.request('WaitForAllToonsInside') self.interior.generateWithRequired(interiorZoneId) def createCogdoInterior(self): # Create a building interior in the new (interior) zone self.interior = self._createCogdoInterior() dummy, interiorZoneId = self.getExteriorAndInteriorZoneId() self.interior.fsm.request('WaitForAllToonsInside') self.interior.generateWithRequired(interiorZoneId) def deleteSuitInterior(self): if hasattr(self, "interior"): self.interior.requestDelete() del self.interior if hasattr(self, "elevator"): # -1 means the lobby. self.elevator.d_setFloor(-1) self.elevator.open() def deleteCogdoInterior(self): self.deleteSuitInterior() if __debug__: def debugPrint(self, message): """for debugging""" return self.notify.debug( str(self.__dict__.get('block', '?')) + ' ' + message)
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.difficulty = 1 self.numFloors = 0 self.savedBy = None self.becameSuitTime = 0 self.frontDoorPoint = None self.suitPlannerExt = None 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): if not self.isToonBlock(): return self.updateSavedBy(None) (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 = "c" self.difficulty = difficulty self.numFloors = numFloors 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) zoneId = ZoneUtil.getTrueZoneId(zoneId, self.zoneId) 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: if not ZoneUtil.isWelcomeValley(self.zoneId): self.trophyMgr.removeTrophy(avId, self.numFloors) self.savedBy = savedBy if self.savedBy: for (avId, name, dna) in self.savedBy: if not ZoneUtil.isWelcomeValley(self.zoneId): 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, activeToons ) 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 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.toonKilledCogdo(toon, self.difficulty, self.numFloors, self.zoneId, activeToons) 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("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.track), 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.track), 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) self.air.writeServerEvent("building-cogdo", self.doId, "%s|%s|%s" % (self.zoneId, self.block, self.numFloors)) 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.elevator) 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.fsm.request("WaitForAllToonsInside") self.interior.generateWithRequired(interiorZoneId) 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()