コード例 #1
0
class ToontownAIRepository(ToontownInternalRepository):
    def __init__(self, baseChannel, stateServerChannel, districtName):
        ToontownInternalRepository.__init__(self,
                                            baseChannel,
                                            stateServerChannel,
                                            dcSuffix='AI')

        self.districtName = districtName

        self.notify.setInfo(True)  # Our AI repository should always log info.
        self.hoods = []
        self.cogHeadquarters = []
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.suitPlanners = {}
        self.buildingManagers = {}
        self.factoryMgr = None
        self.mintMgr = None
        self.lawOfficeMgr = None
        self.countryClubMgr = None

        # For when in game events occur
        self.globalOccurrenceMgr = self.generateGlobalObject(
            OTP_DO_ID_GLOBAL_OCCURRENCE_MANAGER,
            'GlobalOccurrenceManager')  # OCCURRENCE-MANAGER-AI

        self.zoneAllocator = UniqueIdAllocator(
            ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd)
        self.zoneDataStore = AIZoneDataStore()

        self.wantFishing = self.config.GetBool('want-fishing', True)
        self.wantHousing = self.config.GetBool('want-housing', True)
        self.wantPets = self.config.GetBool('want-pets', True)
        self.wantParties = self.config.GetBool('want-parties', True)
        self.wantCogbuildings = self.config.GetBool('want-cogbuildings', True)
        self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True)
        self.doLiveUpdates = self.config.GetBool('want-live-updates', False)
        self.wantTrackClsends = self.config.GetBool('want-track-clsends',
                                                    False)
        self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0)
        self.wantHalloween = self.config.GetBool('want-halloween', False)
        self.wantChristmas = self.config.GetBool('want-christmas', False)
        self.wantFireworks = self.config.GetBool('want-fireworks', False)

        self.cogSuitMessageSent = False

    def createManagers(self):
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(2)
        self.magicWordManager = MagicWordManagerAI(self)
        self.magicWordManager.generateWithRequired(2)
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(2)

        self.holidayManager = HolidayManagerAI(self)

        self.safeZoneManager = SafeZoneManagerAI(self)
        self.safeZoneManager.generateWithRequired(2)
        self.tutorialManager = TutorialManagerAI(self)
        self.tutorialManager.generateWithRequired(2)
        self.friendManager = FriendManagerAI(self)
        self.friendManager.generateWithRequired(2)
        self.questManager = QuestManagerAI(self)
        self.banManager = BanManagerAI.BanManagerAI(self)
        self.suitInvasionManager = SuitInvasionManagerAI(self)
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(2)
        self.cogSuitMgr = CogSuitManagerAI.CogSuitManagerAI(self)
        self.promotionMgr = PromotionManagerAI.PromotionManagerAI(self)
        self.cogPageManager = CogPageManagerAI.CogPageManagerAI()

        if self.wantFishing:
            self.fishManager = FishManagerAI(self)
        if self.wantHousing:
            self.estateManager = EstateManagerAI(self)
            self.estateManager.generateWithRequired(2)
            self.catalogManager = CatalogManagerAI(self)
            self.catalogManager.generateWithRequired(2)
            self.deliveryManager = self.generateGlobalObject(
                OTP_DO_ID_TOONTOWN_DELIVERY_MANAGER,
                'DistributedDeliveryManager')
        if self.wantPets:
            self.petMgr = PetManagerAI(self)

        if self.wantParties:
            self.partyManager = DistributedPartyManagerAI(self)
            self.partyManager.generateWithRequired(2)
            # Setup view of global ub party manager
            self.globalPartyMgr = self.generateGlobalObject(
                OTP_DO_ID_GLOBAL_PARTY_MANAGER, 'GlobalPartyManager')

        self.wantLeaderBoardMgr = True
        if self.wantLeaderBoardMgr:
            self.leaderBoardMgr = DistributedLeaderBoardManagerAI(self)

        # Need work
        self.codeRedemptionManager = TTCodeRedemptionMgrAI(self)
        self.codeRedemptionManager.generateWithRequired(2)

    def createSafeZones(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-toontown-central', True):
            self.hoods.append(TTHoodAI.TTHoodAI(self))
        if self.config.GetBool('want-donalds-dock', True):
            self.hoods.append(DDHoodAI.DDHoodAI(self))
        if self.config.GetBool('want-daisys-garden', True):
            self.hoods.append(DGHoodAI.DGHoodAI(self))
        if self.config.GetBool('want-minnies-melodyland', True):
            self.hoods.append(MMHoodAI.MMHoodAI(self))
        if self.config.GetBool('want-the-burrrgh', True):
            self.hoods.append(BRHoodAI.BRHoodAI(self))
        if self.config.GetBool('want-donalds-dreamland', True):
            self.hoods.append(DLHoodAI.DLHoodAI(self))
        if self.config.GetBool('want-goofy-speedway', True):
            self.hoods.append(GSHoodAI.GSHoodAI(self))
        if self.config.GetBool('want-outdoor-zone', True):
            self.hoods.append(OZHoodAI.OZHoodAI(self))
        if self.config.GetBool('want-golf-zone', True):
            self.hoods.append(GZHoodAI.GZHoodAI(self))

    def createCogHeadquarters(self):
        if self.config.GetBool('want-sellbot-headquarters', True):
            self.factoryMgr = FactoryManagerAI.FactoryManagerAI(self)
            self.cogHeadquarters.append(SellbotHQAI.SellbotHQAI(self))
        if self.config.GetBool('want-cashbot-headquarters', True):
            self.mintMgr = MintManagerAI.MintManagerAI(self)
            self.cogHeadquarters.append(CashbotHQAI.CashbotHQAI(self))
        if self.config.GetBool('want-lawbot-headquarters', True):
            self.lawOfficeMgr = LawOfficeManagerAI.LawOfficeManagerAI(self)
            self.cogHeadquarters.append(LawbotHQAI.LawbotHQAI(self))
        if self.config.GetBool('want-bossbot-headquarters', True):
            self.countryClubMgr = CountryClubManagerAI.CountryClubManagerAI(
                self)
            self.cogHeadquarters.append(BossbotHQAI.BossbotHQAI(self))

    def handleConnected(self):
        self.districtId = self.allocateChannel()
        self.notify.info('Creating ToontownDistrictAI(%d)...' %
                         self.districtId)
        self.distributedDistrict = ToontownDistrictAI(self)
        self.distributedDistrict.setName(self.districtName)
        self.distributedDistrict.generateWithRequiredAndId(
            self.districtId, self.getGameDoId(), 2)
        self.notify.info('Claiming ownership of channel ID: %d...' %
                         self.districtId)
        self.claimOwnership(self.districtId)

        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.settoontownDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(self.allocateChannel(),
                                                     self.getGameDoId(), 3)
        self.notify.info('Created ToontownDistrictStats(%d)' %
                         self.districtStats.doId)

        self.notify.info('Creating managers...')
        self.createManagers()
        if self.config.GetBool('want-safe-zones', True):
            self.notify.info('Creating safe zones...')
            self.createSafeZones()
        if self.config.GetBool('want-cog-headquarters', True):
            self.notify.info('Creating Cog headquarters...')
            self.createCogHeadquarters()

        self.notify.info('Starting Holiday Manager...')
        self.holidayManager.start()

        self.notify.info('Making district available...')
        self.distributedDistrict.b_setAvailable(1)
        self.notify.info('Done.')

    def claimOwnership(self, channelId):
        datagram = PyDatagram()
        datagram.addServerHeader(channelId, self.ourChannel,
                                 STATESERVER_OBJECT_SET_AI)
        datagram.addChannel(self.ourChannel)
        self.send(datagram)

    def lookupDNAFileName(self, zoneId):
        zoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        hoodId = ZoneUtil.getCanonicalHoodId(zoneId)
        hood = ToontownGlobals.dnaMap[hoodId]
        if hoodId == zoneId:
            zoneId = 'sz'
            phaseNum = ToontownGlobals.phaseMap[hoodId]
        else:
            phaseNum = ToontownGlobals.streetPhaseMap[hoodId]
        return 'phase_%s/dna/%s_%s.pdna' % (phaseNum, hood, zoneId)

    def loadDNAFileAI(self, dnastore, filename):
        return loadDNAFileAI(dnastore, filename)

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() + 1)

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() - 1)

    def allocateZone(self):
        return self.zoneAllocator.allocate()

    def deallocateZone(self, zone):
        self.zoneAllocator.free(zone)

    def getZoneDataStore(self):
        return self.zoneDataStore

    def getTrackClsends(self):
        return self.wantTrackClsends

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % avId

    def trueUniqueName(self, name):
        return self.uniqueName(name)
コード例 #2
0
class ToontownAIRepository(ToontownInternalRepository):

    def __init__(self, baseChannel, stateServerChannel, districtName, startTime=6):
        ToontownInternalRepository.__init__(self, baseChannel, stateServerChannel, dcSuffix='AI')
        self.districtName = districtName
        self.notify.setInfo(True)
        self.hoods = []
        self.hoodId2Hood = {}
        self.cogHeadquarters = []
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.suitPlanners = {}
        self.buildingManagers = {}
        self.sillyMeterMgr = None
        self.factoryMgr = None
        self.mintMgr = None
        self.lawOfficeMgr = None
        self.countryClubMgr = None
        self.boardofficeMgr = None
        self.startTime = startTime
        import pymongo
        self.isRaining = False
        self.betaEventTTC = None
        self.betaEventBDHQ = None
        self.invLastPop = None
        self.invLastStatus = None

        import pymongo

        # Mongo stuff to store seperate database things
        self.dbConn = pymongo.MongoClient(config.GetString('mongodb-url', 'localhost'))
        self.dbGlobalCursor = self.dbConn.altis
        self.dbCursor = self.dbGlobalCursor['air-%d' % self.ourChannel]
        self.zoneAllocator = UniqueIdAllocator(ToontownGlobals.DynamicZonesBegin,
                                               ToontownGlobals.DynamicZonesEnd)
        self.zoneDataStore = AIZoneDataStore()

        self.wantFishing = self.config.GetBool('want-fishing', True)
        self.wantHousing = self.config.GetBool('want-housing', True)
        self.wantPets = self.config.GetBool('want-pets', True)
        self.wantParties = self.config.GetBool('want-parties', True)
        self.wantCogbuildings = self.config.GetBool('want-cogbuildings', True)
        self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True)
        self.doLiveUpdates = self.config.GetBool('want-live-updates', False)
        self.wantTrackClsends = self.config.GetBool('want-track-clsends', False)
        self.wantAchievements = self.config.GetBool('want-achievements', True)
        self.wantCharityScreen = self.config.GetBool('want-charity-screen', False)
        self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0)
        self.wantHalloween = self.config.GetBool('want-halloween', False)
        self.wantChristmas = self.config.GetBool('want-christmas', False)
        self.wantGardening = self.config.GetBool('want-gardening', False)
        self.cogSuitMessageSent = False
        self.weatherCycleDuration = self.config.GetInt('weather-cycle-duration', 100)

    def createManagers(self):
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(2)
        self.magicWordManager = MagicWordManagerAI(self)
        self.magicWordManager.generateWithRequired(2)
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(2)
        self.safeZoneManager = SafeZoneManagerAI(self)
        self.safeZoneManager.generateWithRequired(2)
        self.tutorialManager = TutorialManagerAI(self)
        self.tutorialManager.generateWithRequired(2)
        self.friendManager = FriendManagerAI(self)
        self.friendManager.generateWithRequired(2)
        self.questManager = QuestManagerAI(self)
        self.banManager = BanManagerAI.BanManagerAI(self)
        self.achievementsManager = AchievementsManagerAI(self)
        self.certManager = CertificateManagerAI(self)
        self.suitInvasionManager = SuitInvasionManagerAI(self)
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(2)
        self.cogSuitMgr = CogSuitManagerAI.CogSuitManagerAI(self)
        self.promotionMgr = PromotionManagerAI.PromotionManagerAI(self)
        self.experienceMgr = ExperienceRewardManagerAI.ExperienceRewardManagerAI(self)
        self.cogPageManager = CogPageManagerAI.CogPageManagerAI()
        self.sillyMeterMgr = DistributedSillyMeterMgrAI.DistributedSillyMeterMgrAI(self)
        self.sillyMeterMgr.generateWithRequired(2)
        self.hydrantZeroMgr = DistributedHydrantZeroMgrAI.DistributedHydrantZeroMgrAI(self)
        self.hydrantZeroMgr.generateWithRequired(2)
        self.mailboxZeroMgr = DistributedMailboxZeroMgrAI.DistributedMailboxZeroMgrAI(self)
        self.mailboxZeroMgr.generateWithRequired(2)
        self.trashcanZeroMgr = DistributedTrashcanZeroMgrAI.DistributedTrashcanZeroMgrAI(self)
        self.trashcanZeroMgr.generateWithRequired(2)
        self.dialogueManager = DialogueManagerAI(self)
        self.bingoHolidayMgr = BingoHolidayMgrAI(self, ToontownGlobals.FISH_BINGO_NIGHT)
        self.bingoWeekendMgr = BingoWeekendMgrAI(self, ToontownGlobals.SILLY_SATURDAY_BINGO)
        self.trolleyHolidayMgr = TrolleyHolidayMgrAI(self, ToontownGlobals.TROLLEY_HOLIDAY)
        self.trolleyWeekendMgr = TrolleyWeekendMgrAI(self, ToontownGlobals.TROLLEY_WEEKEND)
        self.holidayManager = HolidayManagerAI(self)


        if self.wantFishing:
            self.fishManager = FishManagerAI(self)

        if self.wantHousing:
            self.estateManager = EstateManagerAI(self)
            self.estateManager.generateWithRequired(2)
            self.catalogManager = CatalogManagerAI(self)
            self.catalogManager.generateWithRequired(2)
            self.deliveryManager = self.generateGlobalObject(OTP_DO_ID_TOONTOWN_DELIVERY_MANAGER, 'DistributedDeliveryManager')
            self.mailManager = self.generateGlobalObject(OTP_DO_ID_TOONTOWN_MAIL_MANAGER, 'DistributedMailManager')

        if self.wantPets:
            self.petMgr = PetManagerAI(self)

        self.publicPetMgr = DistributedPublicPetMgrAI.DistributedPublicPetMgrAI(self)
        self.publicPetMgr.generateWithRequired(2)

        if self.wantParties:
            self.partyManager = DistributedPartyManagerAI(self)
            self.partyManager.generateWithRequired(2)
            self.globalPartyMgr = self.generateGlobalObject(OTP_DO_ID_GLOBAL_PARTY_MANAGER, 'GlobalPartyManager')

        self.codeRedemptionMgr = TTCodeRedemptionMgrAI(self)
        self.codeRedemptionMgr.generateWithRequired(2)
        self.chatAgent = simbase.air.generateGlobalObject(OTP_DO_ID_CHAT_MANAGER, 'ChatAgent')

    def createSafeZones(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-toontown-central', True):
            hood = TTHoodAI.TTHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-donalds-dock', True):
            hood = DDHoodAI.DDHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-daisys-garden', True):
            hood = DGHoodAI.DGHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-minnies-melodyland', True):
            hood = MMHoodAI.MMHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-the-burrrgh', True):
            hood = BRHoodAI.BRHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-donalds-dreamland', True):
            hood = DLHoodAI.DLHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-goofy-speedway', True):
            hood = GSHoodAI.GSHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-outdoor-zone', True):
            hood = OZHoodAI.OZHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        if self.config.GetBool('want-golf-zone', True):
            hood = GZHoodAI.GZHoodAI(self)
            self.hoods.append(hood)
            self.hoodId2Hood[hood.zoneId] = hood
        hood = TTOHoodAI.TTOHoodAI(self)
        self.hoods.append(hood)
        self.hoodId2Hood[hood.zoneId] = hood

    def createCogHeadquarters(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-sellbot-headquarters', True):
            self.factoryMgr = FactoryManagerAI.FactoryManagerAI(self)
            self.cogHeadquarters.append(SellbotHQAI.SellbotHQAI(self))
        if self.config.GetBool('want-cashbot-headquarters', True):
            self.mintMgr = MintManagerAI.MintManagerAI(self)
            self.cogHeadquarters.append(CashbotHQAI.CashbotHQAI(self))
        if self.config.GetBool('want-lawbot-headquarters', True):
            self.lawOfficeMgr = LawOfficeManagerAI.LawOfficeManagerAI(self)
            self.cogHeadquarters.append(LawbotHQAI.LawbotHQAI(self))
        if self.config.GetBool('want-bossbot-headquarters', True):
            self.countryClubMgr = CountryClubManagerAI.CountryClubManagerAI(self)
            self.cogHeadquarters.append(BossbotHQAI.BossbotHQAI(self))
        if self.config.GetBool('want-bdhq', True):
            self.boardofficeMgr = BoardOfficeManagerAI.BoardOfficeManagerAI(self)
            self.cogHeadquarters.append(BoardbotHQAI.BoardbotHQAI(self))

    def handleConnected(self):
        self.registerForChannel(MESSENGER_CHANNEL_AI)

        self.districtId = self.allocateChannel()
        self.notify.info('Creating ToontownDistrictAI(%d)...' % self.districtId)
        self.distributedDistrict = ToontownDistrictAI(self)
        self.distributedDistrict.setName(self.districtName)
        self.distributedDistrict.generateWithRequiredAndId(
            self.districtId, self.getGameDoId(), 2)

        self.notify.info('Claiming ownership of channel ID: %d...' % self.districtId)
        self.setAI(self.districtId, self.ourChannel)

        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.settoontownDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(self.allocateChannel(),
            self.getGameDoId(), 3)

        self.notify.info('Created ToontownDistrictStats(%d)' % self.districtStats.doId)

        self.notify.info('Creating managers...')
        self.createManagers()
        if self.config.GetBool('want-safe-zones', True):
            self.notify.info('Creating safe zones...')
            self.createSafeZones()

        if self.config.GetBool('want-cog-headquarters', True):
            self.notify.info('Creating Cog headquarters...')
            self.createCogHeadquarters()

        self.notify.info('Making district available...')
        self.distributedDistrict.b_setAvailable(1)
        self.notify.info('Done.')

        self.notify.info("Starting Invasion Tracker...")
        taskMgr.doMethodLater(2, self.updateInvasionTrackerTask, 'updateInvasionTracker-%d' % self.ourChannel)
        self.notify.info("Invasion Tracker Started!")
        self.sendNetEvent('registerShard', [self.districtId, True], channels=[MESSENGER_CHANNEL_UD])

        atexit.register(self.shardDeath)

    def shardDeath(self):
        self.sendNetEvent('registerShard', [self.districtId, False], channels=[MESSENGER_CHANNEL_UD])

    def lookupDNAFileName(self, zoneId):
        zoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        hoodId = ZoneUtil.getCanonicalHoodId(zoneId)
        hood = ToontownGlobals.dnaMap[hoodId]
        if hoodId == zoneId:
            zoneId = 'sz'
            phaseNum = ToontownGlobals.phaseMap[hoodId]
        else:
            phaseNum = ToontownGlobals.streetPhaseMap[hoodId]

        return 'phase_%s/dna/%s_%s.pdna' % (phaseNum, hood, zoneId)

    def loadDNAFileAI(self, dnastore, filename):
        return loadDNAFileAI(dnastore, filename)

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(self.districtStats.getAvatarCount() + 1)

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(self.districtStats.getAvatarCount() - 1)

    def setHour(self, hour):
        pass # Todo: Hour on district page

    def allocateZone(self):
        return self.zoneAllocator.allocate()

    def deallocateZone(self, zone):
        self.zoneAllocator.free(zone)

    def getZoneDataStore(self):
        return self.zoneDataStore

    def getTrackClsends(self):
        return self.wantTrackClsends

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % (avId)

    def trueUniqueName(self, name):
        return self.uniqueName(name)

    def updateInvasionTrackerTask(self, task):
        task.delayTime = 10 # Set it to 10 after doing it the first time
        statusToType = {
        0: 'None',
        1: 'Bossbot',
        2: 'Lawbot',
        3: 'Cashbot',
        4: 'Sellbot',
        5: 'Boardbot'}
        pop = self.districtStats.getAvatarCount()
        invstatus = statusToType.get(self.districtStats.getInvasionStatus(), 'None')
        total = self.districtStats.getInvasionTotal()
        defeated = total - self.districtStats.getInvasionRemaining()
        tupleStatus = (self.districtStats.getInvasionStatus(), self.districtStats.getInvasionType())
        invstatus = self.statusToType(tupleStatus)
        timeleft = self.districtStats.getInvasionTimeRemaining()

        self.invLastPop = pop
        self.invLastStatus = invstatus

        return task.again

    def statusToType(self, tupleInvasionStatus):
        try:
            statusToSuit = {
                0: 'None',
                1: 'Bossbot',
                2: 'Lawbot',
                3: 'Cashbot',
                4: 'Sellbot',
                5: 'Boardbot'
            }
            suit = statusToSuit.get(tupleInvasionStatus[0], 'None')
            if suit == 'None':
                return suit

            Type = SuitInvasionGlobals.comboToType.get(str(tupleInvasionStatus[0]) + str(tupleInvasionStatus[1]), 'None')
            Type = Type.replace(' ', '%20')
            if Type == 'None':
                return Type
            return Type + '|' + suit
        except:
            return 'None'
コード例 #3
0
class ToontownAIRepository(ToontownInternalRepository):
    def __init__(self, baseChannel, stateServerChannel, districtName):
        ToontownInternalRepository.__init__(
            self, baseChannel, stateServerChannel, dcSuffix='AI')

        self.districtName = districtName

        self.notify.setInfo(True)  # Our AI repository should always log info.
        self.hoods = []
        self.cogHeadquarters = []
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.suitPlanners = {}
        self.buildingManagers = {}
        self.factoryMgr = None
        self.mintMgr = None
        self.lawOfficeMgr = None
        self.countryClubMgr = None

        self.zoneAllocator = UniqueIdAllocator(ToontownGlobals.DynamicZonesBegin,
                                               ToontownGlobals.DynamicZonesEnd)
        self.zoneDataStore = AIZoneDataStore()

        self.wantFishing = self.config.GetBool('want-fishing', True)
        self.wantHousing = self.config.GetBool('want-housing', True)
        self.wantPets = self.config.GetBool('want-pets', True)
        self.wantKarts = self.config.GetBool('want-karts', True)
        self.wantParties = self.config.GetBool('want-parties', True)
        self.wantEmblems = self.config.GetBool('want-emblems', True)
        self.wantCogbuildings = self.config.GetBool('want-cogbuildings', True)
        self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True)
        self.wantTrackClsends = self.config.GetBool('want-track-clsends', False)
        self.wantTopToons = self.config.GetBool('want-top-toons', True)
        self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0)

        self.cogSuitMessageSent = False

    def createManagers(self):
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(2)
        self.magicWordManager = MagicWordManagerAI(self)
        self.magicWordManager.generateWithRequired(2)
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(2)
        self.safeZoneManager = SafeZoneManagerAI(self)
        self.safeZoneManager.generateWithRequired(2)
        self.topToonsMgr = TopToonsManagerAI(self)
        #self.topToonsMgr.generateWithRequired(2)
        self.tutorialManager = TutorialManagerAI(self)
        self.tutorialManager.generateWithRequired(2)
        self.friendManager = FriendManagerAI(self)
        self.friendManager.generateWithRequired(2)
        self.questManager = QuestManagerAI(self)       
        self.banManager = BanManagerAI.BanManagerAI(self)
        self.suitInvasionManager = SuitInvasionManagerAI(self)
        self.blackCatMgr = DistributedBlackCatMgrAI(self)
        self.blackCatMgr.generateWithRequired(2)
        self.reportMgr = DistributedReportMgrAI(self)
        self.reportMgr.generateWithRequired(2)
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(2)
        self.cogSuitMgr = CogSuitManagerAI.CogSuitManagerAI()
        self.promotionMgr = PromotionManagerAI.PromotionManagerAI(self)
        self.cogPageManager = CogPageManagerAI.CogPageManagerAI()
        self.codeRedemptionMgr = TTCodeRedemptionMgrAI(self)
        self.codeRedemptionMgr.generateWithRequired(2)
        self.buildingQueryMgr = DistributedBuildingQueryMgrAI(self)
        self.buildingQueryMgr.generateWithRequired(2)
        if self.wantTopToons:
            self.topToonsMgr = TopToonsManagerAI(self)
        if self.wantKarts:
            self.leaderboardMgr = LeaderboardMgrAI(self)
        if self.wantFishing:
            self.fishManager = FishManagerAI(self)
        if self.wantHousing:
            self.estateManager = EstateManagerAI(self)
            self.estateManager.generateWithRequired(2)
            self.catalogManager = CatalogManagerAI(self)
            self.catalogManager.generateWithRequired(2)
        if self.wantPets:
            self.petMgr = PetManagerAI(self)
        if self.wantParties:
            self.partyManager = DistributedPartyManagerAI(self)
            self.partyManager.generateWithRequired(2)
            self.globalPartyMgr = self.generateGlobalObject(
                OTP_DO_ID_GLOBAL_PARTY_MANAGER, 'GlobalPartyManager')
        #self.lobbyManager = DistributedLobbyManagerAI(self)
        #self.lobbyManager.generateWithRequired(2)
        #self.globalLobbyMgr = self.generateGlobalObject(
        #    OTP_DO_ID_GLOBAL_LOBBY_MANAGER, 'GlobalLobbyManager')

    def createSafeZones(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-toontown-central', True):
            self.hoods.append(TTHoodAI.TTHoodAI(self))
        if self.config.GetBool('want-donalds-dock', True):
            self.hoods.append(DDHoodAI.DDHoodAI(self))
        if self.config.GetBool('want-daisys-garden', True):
            self.hoods.append(DGHoodAI.DGHoodAI(self))
        if self.config.GetBool('want-minnies-melodyland', True):
            self.hoods.append(MMHoodAI.MMHoodAI(self))
        if self.config.GetBool('want-the-brrrgh', True):
            self.hoods.append(BRHoodAI.BRHoodAI(self))
        if self.config.GetBool('want-donalds-dreamland', True):
            self.hoods.append(DLHoodAI.DLHoodAI(self))
        if self.config.GetBool('want-goofy-speedway', True):
            self.hoods.append(GSHoodAI.GSHoodAI(self))
        if self.config.GetBool('want-outdoor-zone', True):
            self.hoods.append(OZHoodAI.OZHoodAI(self))
        if self.config.GetBool('want-golf-zone', True):
            self.hoods.append(GZHoodAI.GZHoodAI(self))

    def createCogHeadquarters(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-sellbot-headquarters', True):
            self.factoryMgr = FactoryManagerAI.FactoryManagerAI(self)
            self.cogHeadquarters.append(SellbotHQAI.SellbotHQAI(self))
        if self.config.GetBool('want-cashbot-headquarters', True):
            self.mintMgr = MintManagerAI.MintManagerAI(self)
            self.cogHeadquarters.append(CashbotHQAI.CashbotHQAI(self))
        if self.config.GetBool('want-lawbot-headquarters', True):
            self.lawOfficeMgr = LawOfficeManagerAI.LawOfficeManagerAI(self)
            self.cogHeadquarters.append(LawbotHQAI.LawbotHQAI(self))
        if self.config.GetBool('want-bossbot-headquarters', True):
            self.countryClubMgr = CountryClubManagerAI.CountryClubManagerAI(self)
            self.cogHeadquarters.append(BossbotHQAI.BossbotHQAI(self))

    def handleConnected(self):
        ToontownInternalRepository.handleConnected(self)
        threading.Thread(target=self.startDistrict).start()
    
    def startDistrict(self):
        self.districtId = self.allocateChannel()
        self.notify.info('Creating ToontownDistrictAI(%d)...' % self.districtId)
        self.distributedDistrict = ToontownDistrictAI(self)
        self.distributedDistrict.setName(self.districtName)
        self.distributedDistrict.generateWithRequiredAndId(
            self.districtId, self.getGameDoId(), 2)
        self.notify.info('Claiming ownership of channel ID: %d...' % self.districtId)
        self.claimOwnership(self.districtId)

        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.setDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(
            self.allocateChannel(), self.getGameDoId(), 3)
        self.notify.info('Created ToontownDistrictStats(%d)' % self.districtStats.doId)

        self.notify.info('Creating managers...')
        self.createManagers()
        if self.config.GetBool('want-safe-zones', True):
            self.notify.info('Creating safe zones...')
            self.createSafeZones()
        if self.config.GetBool('want-cog-headquarters', True):
            self.notify.info('Creating Cog headquarters...')
            self.createCogHeadquarters()

        self.notify.info('Making district available...')
        self.distributedDistrict.b_setAvailable(1)
        self.notify.info('Done.')

    def claimOwnership(self, channelId):
        datagram = PyDatagram()
        datagram.addServerHeader(channelId, self.ourChannel, STATESERVER_OBJECT_SET_AI)
        datagram.addChannel(self.ourChannel)
        self.send(datagram)

    def lookupDNAFileName(self, zoneId):
        zoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        hoodId = ZoneUtil.getCanonicalHoodId(zoneId)
        hood = ToontownGlobals.dnaMap[hoodId]
        if hoodId == zoneId:
            zoneId = 'sz'
            phaseNum = ToontownGlobals.phaseMap[hoodId]
        else:
            phaseNum = ToontownGlobals.streetPhaseMap[hoodId]
        return 'phase_%s/dna/%s_%s.pdna' % (phaseNum, hood, zoneId)

    def loadDNAFileAI(self, dnastore, filename):
        return loadDNAFileAI(dnastore, filename)

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(self.districtStats.getAvatarCount() + 1)

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(self.districtStats.getAvatarCount() - 1)

    def allocateZone(self):
        return self.zoneAllocator.allocate()

    def deallocateZone(self, zone):
        self.zoneAllocator.free(zone)

    def getZoneDataStore(self):
        return self.zoneDataStore

    def getTrackClsends(self):
        return self.wantTrackClsends

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % avId

    def trueUniqueName(self, name):
        return self.uniqueName(name)
コード例 #4
0
class ToontownAIRepository(ToontownInternalRepository):
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'ToontownAIRepository')

    def __init__(self, baseChannel, serverId, districtName):
        ToontownInternalRepository.__init__(self,
                                            baseChannel,
                                            serverId,
                                            dcSuffix='AI')
        self.districtName = districtName
        self.doLiveUpdates = self.config.GetBool('want-live-updates', True)
        self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True)
        self.wantEmblems = self.config.GetBool('want-emblems', True)
        self.useAllMinigames = self.config.GetBool('want-all-minigames', True)
        self.districtId = None
        self.district = None
        self.districtStats = None
        self.timeManager = None
        self.newsManager = None
        self.holidayManager = None
        self.welcomeValleyManager = None
        self.catalogManager = None
        self.zoneDataStore = None
        self.inGameNewsMgr = None
        self.trophyMgr = None
        self.petMgr = None
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.zoneTable = {}
        self.hoods = []
        self.buildingManagers = {}
        self.suitPlanners = {}
        self.suitInvasionManager = None
        self.zoneAllocator = None
        self.zoneId2owner = {}
        self.questManager = None
        self.cogPageManager = None
        self.fishManager = None
        self.factoryMgr = None
        self.mintMgr = None
        self.lawMgr = None
        self.countryClubMgr = None
        self.promotionMgr = None
        self.cogSuitMgr = None
        self.partyManager = None
        self.safeZoneManager = None
        self.raceMgr = None
        self.polarPlaceEffectMgr = None
        self.resistanceEmoteMgr = None
        self.tutorialManager = None
        self.friendManager = None
        self.toontownTimeManager = None
        self.estateMgr = None
        self.magicWordManager = None
        self.deliveryManager = None
        self.defaultAccessLevel = OTPGlobals.accessLevelValues.get(
            'TTOFF_DEVELOPER')

    def getTrackClsends(self):
        return False

    def handleConnected(self):
        ToontownInternalRepository.handleConnected(self)

        # Generate our district...
        self.districtId = self.allocateChannel()
        self.notify.info('Creating district (%d)...' % self.districtId)
        self.district = ToontownDistrictAI(self)
        self.district.setName(self.districtName)
        self.district.generateWithRequiredAndId(self.districtId,
                                                self.getGameDoId(),
                                                OTP_ZONE_ID_MANAGEMENT)

        # Claim ownership of that district...
        self.notify.info('Claiming ownership of district (%d)...' %
                         self.districtId)
        datagram = PyDatagram()
        datagram.addServerHeader(self.districtId, self.ourChannel,
                                 STATESERVER_OBJECT_SET_AI)
        datagram.addChannel(self.ourChannel)
        self.send(datagram)

        # Create our local objects.
        self.notify.info('Creating local objects...')
        self.createLocals()

        # Create our global objects.
        self.notify.info('Creating global objects...')
        self.createGlobals()

        # Create our zones.
        self.notify.info('Creating zones (Playgrounds and Cog HQs)...')
        self.createZones()

        # Make our district available, and we're done.
        self.notify.info('Making district available...')
        self.district.b_setAvailable(1)
        self.notify.info('District is now ready. Have fun in Toontown Online!')

    def createLocals(self):
        """
        Creates "local" objects.
        """

        # Create our holiday manager...
        self.holidayManager = HolidayManagerAI(self)

        # Create our zone data store...
        self.zoneDataStore = AIZoneDataStore()

        # Create our pet manager...
        self.petMgr = PetManagerAI(self)

        # Create our suit invasion manager...
        self.suitInvasionManager = SuitInvasionManagerAI(self)

        # Create our zone allocator...
        self.zoneAllocator = UniqueIdAllocator(
            ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd)

        # Create our quest manager...
        self.questManager = QuestManagerAI(self)

        # Create our Cog page manager...
        self.cogPageManager = CogPageManagerAI(self)

        # Create our fish manager...
        self.fishManager = FishManagerAI(self)

        # Create our factory manager...
        self.factoryMgr = FactoryManagerAI(self)

        # Create our mint manager...
        self.mintMgr = MintManagerAI(self)

        # Create our law office manager...
        self.lawMgr = LawOfficeManagerAI(self)

        # Create our country club manager...
        self.countryClubMgr = CountryClubManagerAI(self)

        # Create our promotion manager...
        self.promotionMgr = PromotionManagerAI(self)

        # Create our Cog suit manager...
        self.cogSuitMgr = CogSuitManagerAI(self)

        # Create our race manager...
        self.raceMgr = RaceManagerAI(self)

        # Create our Toontown time manager...
        self.toontownTimeManager = ToontownTimeManager(
            serverTimeUponLogin=int(time.time()),
            globalClockRealTimeUponLogin=globalClock.getRealTime())

    def createGlobals(self):
        """
        Creates "global" objects.
        """

        # Generate our district stats...
        districtStatsId = self.allocateChannel()
        self.notify.info('Creating district stats AI (%d)...' %
                         districtStatsId)
        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.settoontownDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(districtStatsId,
                                                     self.getGameDoId(),
                                                     OTP_ZONE_ID_DISTRICTS)

        # Generate our time manager...
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our news manager...
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our Welcome Valley manager...
        self.welcomeValleyManager = WelcomeValleyManagerAI(self)
        self.welcomeValleyManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our catalog manager...
        self.catalogManager = CatalogManagerAI(self)
        self.catalogManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our in-game news manager...
        self.inGameNewsMgr = DistributedInGameNewsMgrAI(self)
        self.inGameNewsMgr.setLatestIssueStr('2013-08-22 23:49:46')
        self.inGameNewsMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our trophy manager...
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our party manager...
        self.partyManager = DistributedPartyManagerAI(self)
        self.partyManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our safezone manager...
        self.safeZoneManager = SafeZoneManagerAI(self)
        self.safeZoneManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our Polar Place effect manager...
        self.polarPlaceEffectMgr = DistributedPolarPlaceEffectMgrAI(self)
        self.polarPlaceEffectMgr.generateWithRequired(3821)

        # Generate our resistance emote manager...
        self.resistanceEmoteMgr = DistributedResistanceEmoteMgrAI(self)
        self.resistanceEmoteMgr.generateWithRequired(9720)

        # Generate our tutorial manager...
        self.tutorialManager = TutorialManagerAI(self)
        self.tutorialManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our friend manager...
        self.friendManager = FriendManagerAI(self)
        self.friendManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our estate manager...
        self.estateMgr = EstateManagerAI(self)
        self.estateMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our delivery manager...
        self.deliveryManager = self.generateGlobalObject(
            OTP_DO_ID_TOONTOWN_DELIVERY_MANAGER, 'DistributedDeliveryManager')

    def createHood(self, hoodCtr, zoneId):
        # Bossbot HQ doesn't use DNA, so we skip over that.
        if zoneId != ToontownGlobals.BossbotHQ:
            self.dnaStoreMap[zoneId] = DNAStorage()
            self.dnaDataMap[zoneId] = loadDNAFileAI(
                self.dnaStoreMap[zoneId], self.genDNAFileName(zoneId))
            if zoneId in ToontownGlobals.HoodHierarchy:
                for streetId in ToontownGlobals.HoodHierarchy[zoneId]:
                    self.dnaStoreMap[streetId] = DNAStorage()
                    self.dnaDataMap[streetId] = loadDNAFileAI(
                        self.dnaStoreMap[streetId],
                        self.genDNAFileName(streetId))

        hood = hoodCtr(self, zoneId)
        hood.startup()
        self.hoods.append(hood)

    def createZones(self):
        # First, generate our zone2NpcDict...
        NPCToons.generateZone2NpcDict()

        # Toontown Central
        self.zoneTable[ToontownGlobals.ToontownCentral] = (
            (ToontownGlobals.ToontownCentral, 1,
             0), (ToontownGlobals.SillyStreet, 1,
                  1), (ToontownGlobals.LoopyLane, 1,
                       1), (ToontownGlobals.PunchlinePlace, 1, 1))
        self.createHood(TTHoodDataAI, ToontownGlobals.ToontownCentral)

        # Donald's Dock
        self.zoneTable[ToontownGlobals.DonaldsDock] = (
            (ToontownGlobals.DonaldsDock, 1,
             0), (ToontownGlobals.BarnacleBoulevard, 1,
                  1), (ToontownGlobals.SeaweedStreet, 1,
                       1), (ToontownGlobals.LighthouseLane, 1, 1))
        self.createHood(DDHoodDataAI, ToontownGlobals.DonaldsDock)

        # Daisy Gardens
        self.zoneTable[ToontownGlobals.DaisyGardens] = (
            (ToontownGlobals.DaisyGardens, 1,
             0), (ToontownGlobals.ElmStreet, 1,
                  1), (ToontownGlobals.MapleStreet, 1,
                       1), (ToontownGlobals.OakStreet, 1, 1))
        self.createHood(DGHoodDataAI, ToontownGlobals.DaisyGardens)

        # Minnie's Melodyland
        self.zoneTable[ToontownGlobals.MinniesMelodyland] = (
            (ToontownGlobals.MinniesMelodyland, 1,
             0), (ToontownGlobals.AltoAvenue, 1,
                  1), (ToontownGlobals.BaritoneBoulevard, 1,
                       1), (ToontownGlobals.TenorTerrace, 1, 1))
        self.createHood(MMHoodDataAI, ToontownGlobals.MinniesMelodyland)

        # The Brrrgh
        self.zoneTable[ToontownGlobals.TheBrrrgh] = (
            (ToontownGlobals.TheBrrrgh, 1,
             0), (ToontownGlobals.WalrusWay, 1,
                  1), (ToontownGlobals.SleetStreet, 1,
                       1), (ToontownGlobals.PolarPlace, 1, 1))
        self.createHood(BRHoodDataAI, ToontownGlobals.TheBrrrgh)

        # Donald's Dreamland
        self.zoneTable[ToontownGlobals.DonaldsDreamland] = (
            (ToontownGlobals.DonaldsDreamland, 1,
             0), (ToontownGlobals.LullabyLane, 1,
                  1), (ToontownGlobals.PajamaPlace, 1, 1))
        self.createHood(DLHoodDataAI, ToontownGlobals.DonaldsDreamland)

        # Sellbot HQ
        self.zoneTable[ToontownGlobals.SellbotHQ] = (
            (ToontownGlobals.SellbotHQ, 0,
             1), (ToontownGlobals.SellbotFactoryExt, 0, 1))
        self.createHood(CSHoodDataAI, ToontownGlobals.SellbotHQ)

        # Cashbot HQ
        self.zoneTable[ToontownGlobals.CashbotHQ] = ((
            ToontownGlobals.CashbotHQ, 0, 1), )
        self.createHood(CashbotHQDataAI, ToontownGlobals.CashbotHQ)

        # Lawbot HQ
        self.zoneTable[ToontownGlobals.LawbotHQ] = ((ToontownGlobals.LawbotHQ,
                                                     0, 1), )
        self.createHood(LawbotHQDataAI, ToontownGlobals.LawbotHQ)

        # Bossbot HQ
        self.zoneTable[ToontownGlobals.BossbotHQ] = ((
            ToontownGlobals.BossbotHQ, 0, 0), )
        self.createHood(BossbotHQDataAI, ToontownGlobals.BossbotHQ)

        # Goofy Speedway
        self.zoneTable[ToontownGlobals.GoofySpeedway] = ((
            ToontownGlobals.GoofySpeedway, 1, 0), )
        self.createHood(GSHoodDataAI, ToontownGlobals.GoofySpeedway)

        # Chip 'n Dale's Acorn Acres
        self.zoneTable[ToontownGlobals.OutdoorZone] = ((
            ToontownGlobals.OutdoorZone, 1, 0), )
        self.createHood(OZHoodDataAI, ToontownGlobals.OutdoorZone)

        # Chip 'n Dale's MiniGolf
        self.zoneTable[ToontownGlobals.GolfZone] = ((ToontownGlobals.GolfZone,
                                                     1, 0), )
        self.createHood(GZHoodDataAI, ToontownGlobals.GolfZone)

        # Welcome Valley hoods (Toontown Central & Goofy Speedway)
        self.notify.info('Creating ' + TTLocalizer.WelcomeValley[2] + '...')
        self.welcomeValleyManager.createWelcomeValleyHoods()

        # Assign the initial suit buildings.
        self.notify.info(
            'Assigning initial Cog buildings and Field Offices...')
        for suitPlanner in self.suitPlanners.values():
            suitPlanner.assignInitialSuitBuildings()

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() + 1)

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() - 1)

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % avId

    def getZoneDataStore(self):
        return self.zoneDataStore

    def genDNAFileName(self, zoneId):
        zoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        hoodId = ZoneUtil.getCanonicalHoodId(zoneId)
        hood = ToontownGlobals.dnaMap[hoodId]
        if hoodId == zoneId:
            zoneId = 'sz'
            phase = ToontownGlobals.phaseMap[hoodId]
        else:
            phase = ToontownGlobals.streetPhaseMap[hoodId]

        if 'outdoor_zone' in hood or 'golf_zone' in hood:
            phase = '6'

        return 'phase_%s/dna/%s_%s.dna' % (phase, hood, zoneId)

    def findFishingPonds(self, dnaData, zoneId, area):
        fishingPonds = []
        fishingPondGroups = []
        if isinstance(dnaData, DNAGroup) and ('fishing_pond'
                                              in dnaData.getName()):
            fishingPondGroups.append(dnaData)
            pond = self.fishManager.generatePond(area, zoneId)
            fishingPonds.append(pond)
        elif isinstance(dnaData, DNAVisGroup):
            zoneId = ZoneUtil.getTrueZoneId(
                int(dnaData.getName().split(':')[0]), zoneId)

        for i in xrange(dnaData.getNumChildren()):
            foundFishingPonds, foundFishingPondGroups = self.findFishingPonds(
                dnaData.at(i), zoneId, area)
            fishingPonds.extend(foundFishingPonds)
            fishingPondGroups.extend(foundFishingPondGroups)

        return fishingPonds, fishingPondGroups

    def findFishingSpots(self, dnaData, fishingPond):
        fishingSpots = []
        if isinstance(dnaData, DNAGroup) and ('fishing_spot'
                                              in dnaData.getName()):
            spot = self.fishManager.generateSpots(dnaData, fishingPond)
            fishingSpots.append(spot)

        for i in xrange(dnaData.getNumChildren()):
            foundFishingSpots = self.findFishingSpots(dnaData.at(i),
                                                      fishingPond)
            fishingSpots.extend(foundFishingSpots)

        return fishingSpots

    def findPartyHats(self, dnaData, zoneId):
        return []

    def loadDNAFileAI(self, dnaStore, dnaFileName):
        return loadDNAFileAI(dnaStore, dnaFileName)

    def allocateZone(self, owner=None):
        zoneId = self.zoneAllocator.allocate()
        if owner:
            self.zoneId2owner[zoneId] = owner

        return zoneId

    def deallocateZone(self, zone):
        if self.zoneId2owner.get(zone):
            del self.zoneId2owner[zone]

        self.zoneAllocator.free(zone)

    def trueUniqueName(self, idString):
        return self.uniqueName(idString)

    def findRacingPads(self,
                       dnaData,
                       zoneId,
                       area,
                       type='racing_pad',
                       overrideDNAZone=False):
        racingPads, racingPadGroups = [], []
        if type in dnaData.getName():
            if type == 'racing_pad':
                nameSplit = dnaData.getName().split('_')
                racePad = DistributedRacePadAI(self)
                racePad.setArea(area)
                racePad.index = int(nameSplit[2])
                racePad.genre = nameSplit[3]
                trackInfo = RaceGlobals.getNextRaceInfo(
                    -1, racePad.genre, racePad.index)
                racePad.setTrackInfo([trackInfo[0], trackInfo[1]])
                racePad.laps = trackInfo[2]
                racePad.generateWithRequired(zoneId)
                racingPads.append(racePad)
                racingPadGroups.append(dnaData)
            elif type == 'viewing_pad':
                viewPad = DistributedViewPadAI(self)
                viewPad.setArea(area)
                viewPad.generateWithRequired(zoneId)
                racingPads.append(viewPad)
                racingPadGroups.append(dnaData)

        for i in xrange(dnaData.getNumChildren()):
            foundRacingPads, foundRacingPadGroups = self.findRacingPads(
                dnaData.at(i), zoneId, area, type, overrideDNAZone)
            racingPads.extend(foundRacingPads)
            racingPadGroups.extend(foundRacingPadGroups)

        return racingPads, racingPadGroups

    def findStartingBlocks(self, dnaData, pad):
        startingBlocks = []
        for i in xrange(dnaData.getNumChildren()):
            groupName = dnaData.getName()
            blockName = dnaData.at(i).getName()
            if 'starting_block' in blockName:
                cls = DistributedStartingBlockAI if 'racing_pad' in groupName else DistributedViewingBlockAI
                x, y, z = dnaData.at(i).getPos()
                h, p, r = dnaData.at(i).getHpr()
                padLocationId = int(dnaData.at(i).getName()[-1])
                startingBlock = cls(self, pad, x, y, z, h, p, r, padLocationId)
                startingBlock.generateWithRequired(pad.zoneId)
                startingBlocks.append(startingBlock)

        return startingBlocks

    def getAvatarDisconnectReason(self, avId):
        return self.timeManager.avId2disconnectcode.get(
            avId, ToontownGlobals.DisconnectUnknown)

    def lookupDNAFileName(self, dnaFile):
        searchPath = DSearchPath()
        searchPath.appendDirectory(Filename('/phase_3.5/dna'))
        searchPath.appendDirectory(Filename('/phase_4/dna'))
        searchPath.appendDirectory(Filename('/phase_5/dna'))
        searchPath.appendDirectory(Filename('/phase_5.5/dna'))
        searchPath.appendDirectory(Filename('/phase_6/dna'))
        searchPath.appendDirectory(Filename('/phase_8/dna'))
        searchPath.appendDirectory(Filename('/phase_9/dna'))
        searchPath.appendDirectory(Filename('/phase_10/dna'))
        searchPath.appendDirectory(Filename('/phase_11/dna'))
        searchPath.appendDirectory(Filename('/phase_12/dna'))
        searchPath.appendDirectory(Filename('/phase_13/dna'))
        filename = Filename(dnaFile)
        found = vfs.resolveFilename(filename, searchPath)
        if not found:
            self.notify.warning('lookupDNAFileName - %s not found on:' %
                                dnaFile)
            print searchPath
        else:
            return filename.getFullpath()

    def findLeaderBoards(self, dnaData, zoneId):
        leaderboards = []
        if 'leaderBoard' in dnaData.getName():
            x, y, z = dnaData.getPos()
            h, p, r = dnaData.getHpr()
            leaderboard = DistributedLeaderBoardAI(self, dnaData.getName(), x,
                                                   y, z, h, p, r)
            leaderboard.generateWithRequired(zoneId)
            leaderboards.append(leaderboard)

        for i in xrange(dnaData.getNumChildren()):
            foundLeaderBoards = self.findLeaderBoards(dnaData.at(i), zoneId)
            leaderboards.extend(foundLeaderBoards)

        return leaderboards
コード例 #5
0
class ToontownAIRepository(ToontownInternalRepository):
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'ToontownAIRepository')

    def __init__(self, baseChannel, serverId, districtName):
        ToontownInternalRepository.__init__(self,
                                            baseChannel,
                                            serverId,
                                            dcSuffix='AI')
        self.districtName = districtName
        self.doLiveUpdates = config.GetBool('want-live-updates', True)
        self.wantCogdominiums = config.GetBool('want-cogdominiums', True)
        self.useAllMinigames = config.GetBool('want-all-minigames', True)
        self.districtId = None
        self.district = None
        self.districtStats = None
        self.holidayManager = None
        self.zoneDataStore = None
        self.petMgr = None
        self.suitInvasionManager = None
        self.zoneAllocator = None
        self.zoneId2owner = {}
        self.questManager = None
        self.promotionMgr = None
        self.cogPageManager = None
        self.raceMgr = None
        self.countryClubMgr = None
        self.factoryMgr = None
        self.mintMgr = None
        self.lawMgr = None
        self.cogSuitMgr = None
        self.timeManager = None
        self.newsManager = None
        self.welcomeValleyManager = None
        self.inGameNewsMgr = None
        self.catalogManager = None
        self.trophyMgr = None
        self.zoneTable = {}
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.hoods = []
        self.buildingManagers = {}
        self.suitPlanners = {}

    def handleConnected(self):
        ToontownInternalRepository.handleConnected(self)

        # Generate our district...
        self.districtId = self.allocateChannel()
        self.district = ToontownDistrictAI(self)
        self.district.setName(self.districtName)
        self.district.generateWithRequiredAndId(self.districtId,
                                                self.getGameDoId(),
                                                OTP_ZONE_ID_DISTRICTS)

        # Claim ownership of that district...
        self.district.setAI(self.ourChannel)

        # Create our local objects.
        self.createLocals()

        # Create our global objects.
        self.createGlobals()

        # Create our zones.
        self.createZones()

        # Make our district available, and we're done.
        self.district.b_setAvailable(True)
        self.notify.info('Done.')

    def createLocals(self):
        """
        Creates "local" (non-distributed) objects.
        """

        # Create our holiday manager...
        self.holidayManager = HolidayManagerAI(self)

        # Create our zone data store...
        self.zoneDataStore = AIZoneDataStore()

        # Create our pet manager...
        self.petMgr = PetManagerAI(self)

        # Create our suit invasion manager...
        self.suitInvasionManager = SuitInvasionManagerAI(self)

        # Create our zone allocator...
        self.zoneAllocator = UniqueIdAllocator(
            ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd)

        # Create our quest manager...
        self.questManager = QuestManagerAI(self)

        # Create our promotion manager...
        self.promotionMgr = PromotionManagerAI(self)

        # Create our Cog page manager...
        self.cogPageManager = CogPageManagerAI(self)

        # Create our race manager...
        self.raceMgr = RaceManagerAI(self)

        # Create our country club manager...
        self.countryClubMgr = CountryClubManagerAI(self)

        # Create our factory manager...
        self.factoryMgr = FactoryManagerAI(self)

        # Create our mint manager...
        self.mintMgr = MintManagerAI(self)

        # Create our law office manager...
        self.lawMgr = LawOfficeManagerAI(self)

        # Create our Cog suit manager...
        self.cogSuitMgr = CogSuitManagerAI(self)

    def createGlobals(self):
        """
        Creates "global" (distributed) objects.
        """

        # Generate our district stats...
        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.settoontownDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(
            self.allocateChannel(), self.district.getDoId(),
            OTP_ZONE_ID_DISTRICTS_STATS)

        # Generate our time manager...
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our news manager...
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our Welcome Valley manager...
        self.welcomeValleyManager = WelcomeValleyManagerAI(self)
        self.welcomeValleyManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our in-game news manager...
        self.inGameNewsMgr = DistributedInGameNewsMgrAI(self)
        self.inGameNewsMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our catalog manager...
        self.catalogManager = CatalogManagerAI(self)
        self.catalogManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

        # Generate our trophy manager...
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)

    def generateHood(self, hoodConstructor, zoneId):
        # Bossbot HQ doesn't use DNA, so we skip over that.
        if zoneId != ToontownGlobals.BossbotHQ:
            self.dnaStoreMap[zoneId] = DNAStorage()
            self.dnaDataMap[zoneId] = loadDNAFileAI(
                self.dnaStoreMap[zoneId], self.genDNAFileName(zoneId))
            if zoneId in ToontownGlobals.HoodHierarchy:
                for streetId in ToontownGlobals.HoodHierarchy[zoneId]:
                    self.dnaStoreMap[streetId] = DNAStorage()
                    self.dnaDataMap[streetId] = loadDNAFileAI(
                        self.dnaStoreMap[streetId],
                        self.genDNAFileName(streetId))

        hood = hoodConstructor(self, zoneId)
        hood.startup()
        self.hoods.append(hood)

    def createZones(self):
        # First, generate our zone2NpcDict...
        NPCToons.generateZone2NpcDict()

        # Donald's Dock
        self.zoneTable[ToontownGlobals.DonaldsDock] = (
            (ToontownGlobals.DonaldsDock, 1,
             0), (ToontownGlobals.BarnacleBoulevard, 1,
                  1), (ToontownGlobals.SeaweedStreet, 1,
                       1), (ToontownGlobals.LighthouseLane, 1, 1))
        self.generateHood(DDHoodDataAI, ToontownGlobals.DonaldsDock)

        # Toontown Central
        self.zoneTable[ToontownGlobals.ToontownCentral] = (
            (ToontownGlobals.ToontownCentral, 1,
             0), (ToontownGlobals.SillyStreet, 1,
                  1), (ToontownGlobals.LoopyLane, 1,
                       1), (ToontownGlobals.PunchlinePlace, 1, 1))
        self.generateHood(TTHoodDataAI, ToontownGlobals.ToontownCentral)

        # The Brrrgh
        self.zoneTable[ToontownGlobals.TheBrrrgh] = (
            (ToontownGlobals.TheBrrrgh, 1,
             0), (ToontownGlobals.WalrusWay, 1,
                  1), (ToontownGlobals.SleetStreet, 1,
                       1), (ToontownGlobals.PolarPlace, 1, 1))
        self.generateHood(BRHoodDataAI, ToontownGlobals.TheBrrrgh)

        # Minnie's Melodyland
        self.zoneTable[ToontownGlobals.MinniesMelodyland] = (
            (ToontownGlobals.MinniesMelodyland, 1,
             0), (ToontownGlobals.AltoAvenue, 1,
                  1), (ToontownGlobals.BaritoneBoulevard, 1,
                       1), (ToontownGlobals.TenorTerrace, 1, 1))
        self.generateHood(MMHoodDataAI, ToontownGlobals.MinniesMelodyland)

        # Daisy Gardens
        self.zoneTable[ToontownGlobals.DaisyGardens] = (
            (ToontownGlobals.DaisyGardens, 1,
             0), (ToontownGlobals.ElmStreet, 1,
                  1), (ToontownGlobals.MapleStreet, 1,
                       1), (ToontownGlobals.OakStreet, 1, 1))
        self.generateHood(DGHoodDataAI, ToontownGlobals.DaisyGardens)

        # Chip 'n Dale's Acorn Acres
        self.zoneTable[ToontownGlobals.OutdoorZone] = ((
            ToontownGlobals.OutdoorZone, 1, 0), )
        self.generateHood(OZHoodDataAI, ToontownGlobals.OutdoorZone)

        # Goofy Speedway
        self.zoneTable[ToontownGlobals.GoofySpeedway] = ((
            ToontownGlobals.GoofySpeedway, 1, 0), )
        self.generateHood(GSHoodDataAI, ToontownGlobals.GoofySpeedway)

        # Donald's Dreamland
        self.zoneTable[ToontownGlobals.DonaldsDreamland] = (
            (ToontownGlobals.DonaldsDreamland, 1,
             0), (ToontownGlobals.LullabyLane, 1,
                  1), (ToontownGlobals.PajamaPlace, 1, 1))
        self.generateHood(DLHoodDataAI, ToontownGlobals.DonaldsDreamland)

        # Bossbot HQ
        self.zoneTable[ToontownGlobals.BossbotHQ] = ((
            ToontownGlobals.BossbotHQ, 0, 0), )
        self.generateHood(BossbotHQDataAI, ToontownGlobals.BossbotHQ)

        # Sellbot HQ
        self.zoneTable[ToontownGlobals.SellbotHQ] = (
            (ToontownGlobals.SellbotHQ, 0,
             1), (ToontownGlobals.SellbotFactoryExt, 0, 1))
        self.generateHood(CSHoodDataAI, ToontownGlobals.SellbotHQ)

        # Cashbot HQ
        self.zoneTable[ToontownGlobals.CashbotHQ] = ((
            ToontownGlobals.CashbotHQ, 0, 1), )
        self.generateHood(CashbotHQDataAI, ToontownGlobals.CashbotHQ)

        # Lawbot HQ
        self.zoneTable[ToontownGlobals.LawbotHQ] = ((ToontownGlobals.LawbotHQ,
                                                     0, 1), )
        self.generateHood(LawbotHQDataAI, ToontownGlobals.LawbotHQ)

        # Chip 'n Dale's MiniGolf
        self.zoneTable[ToontownGlobals.GolfZone] = ((ToontownGlobals.GolfZone,
                                                     1, 0), )
        self.generateHood(GZHoodDataAI, ToontownGlobals.GolfZone)

        # Welcome Valley zones
        self.welcomeValleyManager.createWelcomeValleyZones()

        # Assign the initial suit buildings.
        for suitPlanner in list(self.suitPlanners.values()):
            suitPlanner.assignInitialSuitBuildings()

    def genDNAFileName(self, zoneId):
        canonicalZoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        canonicalHoodId = ZoneUtil.getCanonicalHoodId(canonicalZoneId)
        hood = ToontownGlobals.dnaMap[canonicalHoodId]
        if canonicalHoodId == canonicalZoneId:
            canonicalZoneId = 'sz'
            phase = ToontownGlobals.phaseMap[canonicalHoodId]
        else:
            phase = ToontownGlobals.streetPhaseMap[canonicalHoodId]

        if 'outdoor_zone' in hood or 'golf_zone' in hood:
            phase = '6'

        return 'phase_%s/dna/%s_%s.dna' % (phase, hood, canonicalZoneId)

    def lookupDNAFileName(self, dnaFileName):
        searchPath = DSearchPath()
        searchPath.appendDirectory(Filename('resources/phase_3.5/dna'))
        searchPath.appendDirectory(Filename('resources/phase_4/dna'))
        searchPath.appendDirectory(Filename('resources/phase_5/dna'))
        searchPath.appendDirectory(Filename('resources/phase_5.5/dna'))
        searchPath.appendDirectory(Filename('resources/phase_6/dna'))
        searchPath.appendDirectory(Filename('resources/phase_8/dna'))
        searchPath.appendDirectory(Filename('resources/phase_9/dna'))
        searchPath.appendDirectory(Filename('resources/phase_10/dna'))
        searchPath.appendDirectory(Filename('resources/phase_11/dna'))
        searchPath.appendDirectory(Filename('resources/phase_12/dna'))
        searchPath.appendDirectory(Filename('resources/phase_13/dna'))
        filename = Filename(dnaFileName)
        found = vfs.resolveFilename(filename, searchPath)
        if not found:
            self.notify.warning('lookupDNAFileName - %s not found on:' %
                                dnaFileName)
            print(searchPath)
        else:
            return filename.getFullpath()

    def loadDNAFileAI(self, dnaStore, dnaFileName):
        return loadDNAFileAI(dnaStore, dnaFileName)

    def findFishingPonds(self, dnaData, zoneId, area):
        return [], []  # TODO

    def findPartyHats(self, dnaData, zoneId):
        return []  # TODO

    def findRacingPads(self,
                       dnaData,
                       zoneId,
                       area,
                       type='racing_pad',
                       overrideDNAZone=False):
        kartPads, kartPadGroups = [], []
        if type in dnaData.getName():
            if type == 'racing_pad':
                nameSplit = dnaData.getName().split('_')
                racePad = DistributedRacePadAI(self)
                racePad.setArea(area)
                racePad.index = int(nameSplit[2])
                racePad.genre = nameSplit[3]
                trackInfo = RaceGlobals.getNextRaceInfo(
                    -1, racePad.genre, racePad.index)
                racePad.setTrackInfo([trackInfo[0], trackInfo[1]])
                racePad.laps = trackInfo[2]
                racePad.generateWithRequired(zoneId)
                kartPads.append(racePad)
                kartPadGroups.append(dnaData)
            elif type == 'viewing_pad':
                viewPad = DistributedViewPadAI(self)
                viewPad.setArea(area)
                viewPad.generateWithRequired(zoneId)
                kartPads.append(viewPad)
                kartPadGroups.append(dnaData)

        for i in range(dnaData.getNumChildren()):
            foundKartPads, foundKartPadGroups = self.findRacingPads(
                dnaData.at(i), zoneId, area, type, overrideDNAZone)
            kartPads.extend(foundKartPads)
            kartPadGroups.extend(foundKartPadGroups)

        return kartPads, kartPadGroups

    def findStartingBlocks(self, dnaData, kartPad):
        startingBlocks = []
        for i in range(dnaData.getNumChildren()):
            groupName = dnaData.getName()
            block = dnaData.at(i)
            blockName = block.getName()
            if 'starting_block' in blockName:
                cls = DistributedStartingBlockAI if 'racing_pad' in groupName else DistributedViewingBlockAI
                x, y, z = block.getPos()
                h, p, r = block.getHpr()
                padLocationId = int(blockName[-1])
                startingBlock = cls(self, kartPad, x, y, z, h, p, r,
                                    padLocationId)
                startingBlock.generateWithRequired(kartPad.zoneId)
                startingBlocks.append(startingBlock)

        return startingBlocks

    def findLeaderBoards(self, dnaData, zoneId):
        leaderBoards = []
        if 'leaderBoard' in dnaData.getName():
            x, y, z = dnaData.getPos()
            h, p, r = dnaData.getHpr()
            leaderBoard = DistributedLeaderBoardAI(self, dnaData.getName(), x,
                                                   y, z, h, p, r)
            leaderBoard.generateWithRequired(zoneId)
            leaderBoards.append(leaderBoard)

        for i in range(dnaData.getNumChildren()):
            foundLeaderBoards = self.findLeaderBoards(dnaData.at(i), zoneId)
            leaderBoards.extend(foundLeaderBoards)

        return leaderBoards

    def getTrackClsends(self):
        return False

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % avId

    def getAvatarDisconnectReason(self, avId):
        return self.timeManager.avId2disconnectcode.get(
            avId, ToontownGlobals.DisconnectUnknown)

    def getZoneDataStore(self):
        return self.zoneDataStore

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() + 1)

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() - 1)

    def allocateZone(self, owner=None):
        zoneId = self.zoneAllocator.allocate()
        if owner:
            self.zoneId2owner[zoneId] = owner

        return zoneId

    def deallocateZone(self, zone):
        if self.zoneId2owner.get(zone):
            del self.zoneId2owner[zone]

        self.zoneAllocator.free(zone)

    def trueUniqueName(self, idString):
        return self.uniqueName(idString)

    def sendQueryToonMaxHp(self, avId, callback):
        pass  # TODO?
コード例 #6
0
class ToontownAIRepository(ToontownInternalRepository):
    notify = DirectNotifyGlobal.directNotify.newCategory(
        'ToontownAIRepository')

    def __init__(self, baseChannel, serverId, expMultiplier, meritMultiplier,
                 doodleMultiplier, defaultMaxToon, defaultZone, districtName,
                 districtLimit, districtDescription, districtWebsiteId,
                 eventId, defaultAccessLevel):
        ToontownInternalRepository.__init__(self,
                                            baseChannel,
                                            serverId,
                                            dcSuffix='AI')
        self.expMultiplier = expMultiplier
        self.meritMultiplier = meritMultiplier
        self.doodleMultiplier = doodleMultiplier
        self.defaultMaxToon = defaultMaxToon
        self.defaultZone = defaultZone
        self.districtName = districtName
        self.districtLimit = districtLimit
        if self.districtLimit < ToontownGlobals.MIN_POP:
            self.districtLimit = ToontownGlobals.MIN_POP
        elif self.districtLimit > ToontownGlobals.HIGH_POP:
            self.districtLimit = ToontownGlobals.HIGH_POP
        self.districtDescription = districtDescription
        self.districtWebsiteId = districtWebsiteId
        self.eventId = eventId
        self.defaultAccessLevel = defaultAccessLevel
        self.doLiveUpdates = self.config.GetBool('want-live-updates', True)
        self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True)
        self.wantEmblems = self.config.GetBool('want-emblems', True)
        self.useAllMinigames = self.config.GetBool('want-all-minigames', True)
        self.wantEmblems = self.config.GetBool('want-emblems', True)
        self.districtId = None
        self.district = None
        self.districtStats = None
        self.districtFull = False
        self.timeManager = None
        self.newsManager = None
        self.holidayManager = None
        self.welcomeValleyManager = None
        self.catalogManager = None
        self.zoneDataStore = None
        self.inGameNewsMgr = None
        self.trophyMgr = None
        self.petMgr = None
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.zoneTable = {}
        self.hoods = []
        self.buildingManagers = {}
        self.suitPlanners = {}
        self.suitInvasionManager = None
        self.zoneAllocator = None
        self.zoneId2owner = {}
        self.questManager = None
        self.cogPageManager = None
        self.fishManager = None
        self.factoryMgr = None
        self.mintMgr = None
        self.lawMgr = None
        self.countryClubMgr = None
        self.promotionMgr = None
        self.cogSuitMgr = None
        self.partyManager = None
        self.safeZoneManager = None
        self.raceMgr = None
        self.polarPlaceEffectMgr = None
        self.resistanceEmoteMgr = None
        self.tutorialManager = None
        self.friendManager = None
        self.chatManager = None
        self.toontownTimeManager = None
        self.estateMgr = None
        self.magicWordManager = None
        self.deliveryManager = None
        self.cogSuitMessageSent = False
        self.propGenerators = {}
        self.propGeneratorsLocked = False
        self.moddingManager = None
        self.discordManager = None
        return

    def getTrackClsends(self):
        return False

    def handleConnected(self):
        ToontownInternalRepository.handleConnected(self)
        self.districtId = self.allocateChannel()
        self.notify.info('Creating district (%d)...' % self.districtId)
        self.district = ToontownDistrictAI(self)
        self.district.setName(self.districtName)
        self.district.setDescription(self.districtDescription)
        self.district.generateWithRequiredAndId(self.districtId,
                                                self.getGameDoId(),
                                                OTP_ZONE_ID_MANAGEMENT)
        self.notify.info('Claiming ownership of district (%d)...' %
                         self.districtId)
        datagram = PyDatagram()
        datagram.addServerHeader(self.districtId, self.ourChannel,
                                 STATESERVER_OBJECT_SET_AI)
        datagram.addChannel(self.ourChannel)
        self.send(datagram)
        self.notify.info('Creating local objects...')
        self.createLocals()
        self.notify.info('Creating global objects...')
        self.createGlobals()
        self.notify.info('Creating zones (Playgrounds and Cog HQs)...')
        self.createZones()
        self.notify.info('Making district available...')
        self.district.b_setAvailable(1)
        self.notify.info(
            'District is now ready. Have fun in Toontown Offline!')

    def createLocals(self):
        self.holidayManager = HolidayManagerAI(self)
        self.zoneDataStore = AIZoneDataStore()
        self.petMgr = PetManagerAI(self)
        self.suitInvasionManager = SuitInvasionManagerAI(self)
        self.zoneAllocator = UniqueIdAllocator(
            ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd)
        self.questManager = QuestManagerAI(self)
        self.cogPageManager = CogPageManagerAI(self)
        self.fishManager = FishManagerAI(self)
        self.factoryMgr = FactoryManagerAI(self)
        self.mintMgr = MintManagerAI(self)
        self.lawMgr = LawOfficeManagerAI(self)
        self.countryClubMgr = CountryClubManagerAI(self)
        self.promotionMgr = PromotionManagerAI(self)
        self.cogSuitMgr = CogSuitManagerAI(self)
        self.raceMgr = RaceManagerAI(self)
        self.toontownTimeManager = ToontownTimeManager(
            serverTimeUponLogin=int(time.time()),
            globalClockRealTimeUponLogin=globalClock.getRealTime())

    def createGlobals(self):
        districtStatsId = self.allocateChannel()
        self.notify.info('Creating district stats AI (%d)...' %
                         districtStatsId)
        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.settoontownDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(districtStatsId,
                                                     self.getGameDoId(),
                                                     OTP_ZONE_ID_DISTRICTS)
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.newsManager.d_setExpMultiplier(self.expMultiplier)
        self.catalogManager = CatalogManagerAI(self)
        self.catalogManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.inGameNewsMgr = DistributedInGameNewsMgrAI(self)
        self.inGameNewsMgr.setLatestIssueStr('2013-08-22 23:49:46')
        self.inGameNewsMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.partyManager = DistributedPartyManagerAI(self)
        self.partyManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.safeZoneManager = SafeZoneManagerAI(self)
        self.safeZoneManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.polarPlaceEffectMgr = DistributedPolarPlaceEffectMgrAI(self)
        self.polarPlaceEffectMgr.generateWithRequired(3821)
        self.resistanceEmoteMgr = DistributedResistanceEmoteMgrAI(self)
        self.resistanceEmoteMgr.generateWithRequired(9720)
        self.tutorialManager = TutorialManagerAI(self)
        self.tutorialManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.friendManager = FriendManagerAI(self)
        self.friendManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.chatManager = TTOffChatManagerAI(self)
        self.chatManager.generateWithRequiredAndId(OTP_DO_ID_CHAT_MANAGER,
                                                   self.getGameDoId(),
                                                   OTP_ZONE_ID_MANAGEMENT)
        self.estateMgr = EstateManagerAI(self)
        self.estateMgr.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.magicWordManager = TTOffMagicWordManagerAI(self)
        self.magicWordManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT)
        self.deliveryManager = self.generateGlobalObject(
            OTP_DO_ID_TOONTOWN_DELIVERY_MANAGER, 'DistributedDeliveryManager')
        self.banManager = self.generateGlobalObject(OTP_DO_ID_BAN_MANAGER,
                                                    'BanManager')
        self.moddingManager = ModdingManagerAI(self)
        self.moddingManager.generateWithRequiredAndId(
            OTP_DO_ID_MODDING_MANAGER, self.getGameDoId(),
            OTP_ZONE_ID_MANAGEMENT)
        self.moddingManager.setColorsAiToUd(self.moddingManager.getColors())
        self.moddingManager.setCardsAiToUd(self.moddingManager.getCards())
        self.moddingManager.d_setDefaultMaxToon(self.defaultMaxToon)
        self.moddingManager.d_setDefaultZone(self.defaultZone)
        self.discordManager = DiscordManagerAI(self)
        self.discordManager.generateWithRequiredAndId(
            OTP_DO_ID_DISCORD_MANAGER, self.getGameDoId(),
            OTP_ZONE_ID_MANAGEMENT)

    def createHood(self, hoodCtr, zoneId):
        if zoneId != ToontownGlobals.BossbotHQ:
            self.dnaStoreMap[zoneId] = DNAStorage()
            self.dnaDataMap[zoneId] = self.loadDNAFileAI(
                self.dnaStoreMap[zoneId], self.genDNAFileName(zoneId))
            if zoneId in ToontownGlobals.HoodHierarchy:
                for streetId in ToontownGlobals.HoodHierarchy[zoneId]:
                    self.dnaStoreMap[streetId] = DNAStorage()
                    self.dnaDataMap[streetId] = self.loadDNAFileAI(
                        self.dnaStoreMap[streetId],
                        self.genDNAFileName(streetId))

        hood = hoodCtr(self, zoneId)
        hood.startup()
        self.hoods.append(hood)

    def createZones(self):
        NPCToons.generateZone2NpcDict()
        self.zoneTable[ToontownGlobals.ToontownCentral] = (
            (ToontownGlobals.ToontownCentral, 1,
             0), (ToontownGlobals.SillyStreet, 1,
                  1), (ToontownGlobals.LoopyLane, 1,
                       1), (ToontownGlobals.PunchlinePlace, 1, 1))
        self.createHood(TTHoodDataAI, ToontownGlobals.ToontownCentral)
        self.zoneTable[ToontownGlobals.DonaldsDock] = (
            (ToontownGlobals.DonaldsDock, 1,
             0), (ToontownGlobals.BarnacleBoulevard, 1,
                  1), (ToontownGlobals.SeaweedStreet, 1,
                       1), (ToontownGlobals.LighthouseLane, 1, 1))
        self.createHood(DDHoodDataAI, ToontownGlobals.DonaldsDock)
        self.zoneTable[ToontownGlobals.DaisyGardens] = (
            (ToontownGlobals.DaisyGardens, 1,
             0), (ToontownGlobals.ElmStreet, 1,
                  1), (ToontownGlobals.MapleStreet, 1,
                       1), (ToontownGlobals.OakStreet, 1, 1))
        self.createHood(DGHoodDataAI, ToontownGlobals.DaisyGardens)
        self.zoneTable[ToontownGlobals.MinniesMelodyland] = (
            (ToontownGlobals.MinniesMelodyland, 1,
             0), (ToontownGlobals.AltoAvenue, 1,
                  1), (ToontownGlobals.BaritoneBoulevard, 1,
                       1), (ToontownGlobals.TenorTerrace, 1, 1))
        self.createHood(MMHoodDataAI, ToontownGlobals.MinniesMelodyland)
        self.zoneTable[ToontownGlobals.TheBrrrgh] = (
            (ToontownGlobals.TheBrrrgh, 1,
             0), (ToontownGlobals.WalrusWay, 1,
                  1), (ToontownGlobals.SleetStreet, 1,
                       1), (ToontownGlobals.PolarPlace, 1, 1))
        self.createHood(BRHoodDataAI, ToontownGlobals.TheBrrrgh)
        self.zoneTable[ToontownGlobals.DonaldsDreamland] = (
            (ToontownGlobals.DonaldsDreamland, 1,
             0), (ToontownGlobals.LullabyLane, 1,
                  1), (ToontownGlobals.PajamaPlace, 1, 1))
        self.createHood(DLHoodDataAI, ToontownGlobals.DonaldsDreamland)
        self.zoneTable[ToontownGlobals.SellbotHQ] = (
            (ToontownGlobals.SellbotHQ, 0,
             1), (ToontownGlobals.SellbotFactoryExt, 0, 1))
        self.createHood(CSHoodDataAI, ToontownGlobals.SellbotHQ)
        self.zoneTable[ToontownGlobals.CashbotHQ] = ((
            ToontownGlobals.CashbotHQ, 0, 1), )
        self.createHood(CashbotHQDataAI, ToontownGlobals.CashbotHQ)
        self.zoneTable[ToontownGlobals.LawbotHQ] = ((ToontownGlobals.LawbotHQ,
                                                     0, 1), )
        self.createHood(LawbotHQDataAI, ToontownGlobals.LawbotHQ)
        self.zoneTable[ToontownGlobals.BossbotHQ] = ((
            ToontownGlobals.BossbotHQ, 0, 0), )
        self.createHood(BossbotHQDataAI, ToontownGlobals.BossbotHQ)
        self.zoneTable[ToontownGlobals.GoofySpeedway] = ((
            ToontownGlobals.GoofySpeedway, 1, 0), )
        self.createHood(GSHoodDataAI, ToontownGlobals.GoofySpeedway)
        self.zoneTable[ToontownGlobals.OutdoorZone] = ((
            ToontownGlobals.OutdoorZone, 1, 0), )
        self.createHood(OZHoodDataAI, ToontownGlobals.OutdoorZone)
        self.zoneTable[ToontownGlobals.GolfZone] = ((ToontownGlobals.GolfZone,
                                                     1, 0), )
        self.createHood(GZHoodDataAI, ToontownGlobals.GolfZone)
        self.zoneTable[ToontownGlobals.ToontownOutskirts] = (
            (ToontownGlobals.ToontownOutskirts, 1,
             0), (ToontownGlobals.TutorialTerrace, 1, 1))
        self.createHood(SpecialHoodDataAI, ToontownGlobals.ToontownOutskirts)
        self.zoneTable[ToontownGlobals.ToontownCentralBeta] = ((
            ToontownGlobals.ToontownCentralBeta, 1, 0), )
        self.createHood(TTBetaHoodDataAI, ToontownGlobals.ToontownCentralBeta)
        self.zoneTable[ToontownGlobals.DaisyGardensBeta] = (
            (ToontownGlobals.DaisyGardensBeta, 1,
             0), (ToontownGlobals.OakStreetBeta, 1, 0))
        self.createHood(DGBetaHoodDataAI, ToontownGlobals.DaisyGardensBeta)
        self.notify.info(
            'Assigning initial Cog buildings and Field Offices...')
        for suitPlanner in self.suitPlanners.values():
            suitPlanner.assignInitialSuitBuildings()

    def sendPing(self, task=None):
        if self.districtWebsiteId != '' and config.GetBool(
                'mini-server', False):
            gameMode = TTLocalizer.MiniserverLegit if self.defaultAccessLevel == 'NO_ACCESS' else TTLocalizer.MiniserverCheats
            try:
                self.sendPingToAPI(
                    self.districtWebsiteId,
                    name=self.districtName,
                    desc=self.districtDescription,
                    population=self.districtStats.getAvatarCount(),
                    mode=gameMode)
            except:
                self.notify.info(
                    'Could not ping the Toontown Offline website! Make sure you are connected to the Internet.'
                )

            return Task.again
        return Task.done

    def sendPingToAPI(self, serverId, **kwargs):
        columns = self.getColumns()
        data = {'uniqueId': serverId}
        for arg in kwargs.keys():
            if arg in columns:
                data['%s' % arg] = kwargs[arg]
                continue
            self.notify.info('%s is not a valid argument!' % arg)

        resp = self.HTTPReq('http://localhost/api/miniservers/ping', data=data)
        if not resp['success']:
            self.notify.info('Could not ping the website! (Message: %s)' %
                             resp['message'])
            return
        data = {'uniqueId': serverId}
        resp = self.HTTPReq('http://localhost/api/miniservers/id2icon',
                            data=data)
        if not resp['success']:
            self.notify.info('Could not retrieve server icon! (Message: %s)' %
                             resp['message'])
            return
        if resp['message']:
            self.district.b_setIconPath(resp['message'])

    def getColumns(self):
        data = self.HTTPReq('http://localhost/api/miniservers/columns')
        return data

    def HTTPReq(self, url, data=None):
        if type(data) == dict:
            data = urllib.urlencode(data)
            data = data.encode('utf-8')
        context = ssl.SSLContext(ssl.PROTOCOL_TLSv1)
        headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64)',
            'Authorization': 'Basic dHRvZmY6SmF6enlTdHVkaW9z'
        }
        request = urllib2.Request(url, data, headers=headers)
        response = urllib2.urlopen(request, context=context)
        data = json.loads(response.read().decode())
        return data

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() + 1)
        self.avatarCountCheck()

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() - 1)
        self.avatarCountCheck()

    def avatarCountCheck(self):
        self.sendPing()
        if not self.districtFull and self.districtStats.getAvatarCount(
        ) >= self.districtLimit:
            self.districtFull = True
            self.notify.warning(
                'Reached player limit! Making district unavailable...')
            self.district.b_setFull(0)
            self.notify.warning(
                'District is now unavailable. Incoming connections will be rejected.'
            )
        if self.districtFull and self.districtStats.getAvatarCount(
        ) < self.districtLimit:
            self.districtFull = False
            self.notify.info(
                'Player count dropped! Making district available...')
            self.district.b_setFull(1)
            self.notify.info(
                'District is now available. Incoming connections will be accepted.'
            )

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % avId

    def getZoneDataStore(self):
        return self.zoneDataStore

    def genDNAFileName(self, zoneId):
        zoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        hoodId = ZoneUtil.getCanonicalHoodId(zoneId)
        hood = ToontownGlobals.dnaMap[hoodId]
        if hoodId == zoneId:
            zoneId = 'sz'
            phase = ToontownGlobals.phaseMap[hoodId]
        else:
            phase = ToontownGlobals.streetPhaseMap[hoodId]
        if 'outdoor_zone' in hood or 'golf_zone' in hood:
            phase = '6'
        return 'phase_%s/dna/%s_%s.dna' % (phase, hood, zoneId)

    def findFishingPonds(self, dnaData, zoneId, area):
        fishingPonds = []
        fishingPondGroups = []
        if isinstance(dnaData,
                      DNAGroup) and 'fishing_pond' in dnaData.getName():
            fishingPondGroups.append(dnaData)
            pond = self.fishManager.generatePond(area, zoneId)
            fishingPonds.append(pond)
        else:
            if isinstance(dnaData, DNAVisGroup):
                zoneId = ZoneUtil.getTrueZoneId(
                    int(dnaData.getName().split(':')[0]), zoneId)
            for i in xrange(dnaData.getNumChildren()):
                foundFishingPonds, foundFishingPondGroups = self.findFishingPonds(
                    dnaData.at(i), zoneId, area)
                fishingPonds.extend(foundFishingPonds)
                fishingPondGroups.extend(foundFishingPondGroups)

        return (fishingPonds, fishingPondGroups)

    def findFishingSpots(self, dnaData, fishingPond):
        fishingSpots = []
        if isinstance(dnaData,
                      DNAGroup) and dnaData.getName()[:13] == 'fishing_spot_':
            spot = self.fishManager.generateSpots(dnaData, fishingPond)
            fishingSpots.append(spot)
        for i in xrange(dnaData.getNumChildren()):
            foundFishingSpots = self.findFishingSpots(dnaData.at(i),
                                                      fishingPond)
            fishingSpots.extend(foundFishingSpots)

        return fishingSpots

    def findClassicFishingSpots(self, dnaData, fishingPond):
        fishingSpots = []
        if isinstance(dnaData, DNAGroup) and dnaData.getName(
        )[:21] == 'classic_fishing_spot_':
            spot = self.fishManager.generateClassicSpots(dnaData, fishingPond)
            fishingSpots.append(spot)
        for i in xrange(dnaData.getNumChildren()):
            foundFishingSpots = self.findClassicFishingSpots(
                dnaData.at(i), fishingPond)
            fishingSpots.extend(foundFishingSpots)

        return fishingSpots

    def findPartyHats(self, dnaData, zoneId):
        return []

    def loadDNAFileAI(self, dnaStore, dnaFileName):
        return loadDNAFileAI(dnaStore, dnaFileName)

    def allocateZone(self, owner=None):
        zoneId = self.zoneAllocator.allocate()
        if owner:
            self.zoneId2owner[zoneId] = owner
        return zoneId

    def deallocateZone(self, zone):
        if self.zoneId2owner.get(zone):
            del self.zoneId2owner[zone]
        self.zoneAllocator.free(zone)

    def trueUniqueName(self, idString):
        return self.uniqueName(idString)

    def findRacingPads(self,
                       dnaData,
                       zoneId,
                       area,
                       type='racing_pad',
                       overrideDNAZone=False):
        racingPads, racingPadGroups = [], []
        if type in dnaData.getName():
            if type == 'racing_pad':
                nameSplit = dnaData.getName().split('_')
                racePad = DistributedRacePadAI(self)
                racePad.setArea(area)
                racePad.index = int(nameSplit[2])
                racePad.genre = nameSplit[3]
                trackInfo = RaceGlobals.getNextRaceInfo(
                    -1, racePad.genre, racePad.index)
                racePad.setTrackInfo([trackInfo[0], trackInfo[1]])
                racePad.laps = trackInfo[2]
                racePad.generateWithRequired(zoneId)
                racingPads.append(racePad)
                racingPadGroups.append(dnaData)
            elif type == 'viewing_pad':
                viewPad = DistributedViewPadAI(self)
                viewPad.setArea(area)
                viewPad.generateWithRequired(zoneId)
                racingPads.append(viewPad)
                racingPadGroups.append(dnaData)
        for i in xrange(dnaData.getNumChildren()):
            foundRacingPads, foundRacingPadGroups = self.findRacingPads(
                dnaData.at(i), zoneId, area, type, overrideDNAZone)
            racingPads.extend(foundRacingPads)
            racingPadGroups.extend(foundRacingPadGroups)

        return (racingPads, racingPadGroups)

    def findStartingBlocks(self, dnaData, pad):
        startingBlocks = []
        for i in xrange(dnaData.getNumChildren()):
            groupName = dnaData.getName()
            blockName = dnaData.at(i).getName()
            if 'starting_block' in blockName:
                cls = DistributedStartingBlockAI if 'racing_pad' in groupName else DistributedViewingBlockAI
                x, y, z = dnaData.at(i).getPos()
                h, p, r = dnaData.at(i).getHpr()
                padLocationId = int(dnaData.at(i).getName()[(-1)])
                startingBlock = cls(self, pad, x, y, z, h, p, r, padLocationId)
                startingBlock.generateWithRequired(pad.zoneId)
                startingBlocks.append(startingBlock)

        return startingBlocks

    def getAvatarDisconnectReason(self, avId):
        return self.timeManager.avId2disconnectcode.get(
            avId, ToontownGlobals.DisconnectUnknown)

    def findLeaderBoards(self, dnaData, zoneId):
        leaderboards = []
        if 'leaderBoard' in dnaData.getName():
            x, y, z = dnaData.getPos()
            h, p, r = dnaData.getHpr()
            leaderboard = DistributedLeaderBoardAI(self, dnaData.getName(), x,
                                                   y, z, h, p, r)
            leaderboard.generateWithRequired(zoneId)
            leaderboards.append(leaderboard)
        for i in xrange(dnaData.getNumChildren()):
            foundLeaderBoards = self.findLeaderBoards(dnaData.at(i), zoneId)
            leaderboards.extend(foundLeaderBoards)

        return leaderboards

    def systemMessage(self, message):
        for doId, do in self.doId2do.items():
            if isinstance(do, DistributedPlayerAI):
                if str(doId)[0] != str(self.districtId)[0]:
                    do.d_setSystemMessage(0, message, WhisperPopup.WTSystem)

    def announceMaintenance(self, reason, type, time):
        self.systemMessage(
            TTLocalizer.ServerShutdownAnnouncement.format(type, time))
        taskMgr.doMethodLater(time,
                              self.shutdownMaintenance,
                              'shutdownMaintenance',
                              extraArgs=[reason])
        if time - 60.0 > 1:
            taskMgr.doMethodLater(
                time - 60.0,
                self.systemMessage,
                'shutdownMaintenance',
                extraArgs=[TTLocalizer.ServerShutdownWarning.format(type)])

    def shutdownMaintenance(self, reason):
        for doId, do in self.doId2do.items():
            if isinstance(do, DistributedPlayerAI):
                if str(doId)[0] != str(self.districtId)[0]:
                    do.sendSetKick(reason=reason, target=do, silent=3)
コード例 #7
0
class ToontownAIRepository(ToontownInternalRepository):
    def __init__(self,
                 baseChannel,
                 stateServerChannel,
                 districtName,
                 startTime=6):
        ToontownInternalRepository.__init__(self,
                                            baseChannel,
                                            stateServerChannel,
                                            dcSuffix='AI')

        self.districtName = districtName
        self.notify.setInfo(True)
        self.hoods = []
        self.cogHeadquarters = []
        self.dnaStoreMap = {}
        self.dnaDataMap = {}
        self.suitPlanners = {}
        self.buildingManagers = {}
        self.sillyMeterMgr = None
        self.factoryMgr = None
        self.mintMgr = None
        self.lawOfficeMgr = None
        self.countryClubMgr = None
        self.startTime = startTime

        self.zoneAllocator = UniqueIdAllocator(
            ToontownGlobals.DynamicZonesBegin, ToontownGlobals.DynamicZonesEnd)
        self.zoneDataStore = AIZoneDataStore()

        self.wantFishing = self.config.GetBool('want-fishing', True)
        self.wantHousing = self.config.GetBool('want-housing', True)
        self.wantPets = self.config.GetBool('want-pets', True)
        self.wantParties = self.config.GetBool('want-parties', True)
        self.wantCogbuildings = self.config.GetBool('want-cogbuildings', True)
        self.wantCogdominiums = self.config.GetBool('want-cogdominiums', True)
        self.doLiveUpdates = self.config.GetBool('want-live-updates', False)
        self.wantTrackClsends = self.config.GetBool('want-track-clsends',
                                                    False)
        self.wantAchievements = self.config.GetBool('want-achievements', True)
        self.wantCharityScreen = self.config.GetBool('want-charity-screen',
                                                     False)
        self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0)
        self.wantHalloween = self.config.GetBool('want-halloween', False)
        self.wantChristmas = self.config.GetBool('want-christmas', False)
        self.cogSuitMessageSent = False
        self.weatherCycleDuration = self.config.GetInt(
            'weather-cycle-duration', 100)

    def createManagers(self):
        self.timeManager = TimeManagerAI(self)
        self.timeManager.generateWithRequired(2)
        self.magicWordManager = MagicWordManagerAI(self)
        self.magicWordManager.generateWithRequired(2)
        self.newsManager = NewsManagerAI(self)
        self.newsManager.generateWithRequired(2)
        self.safeZoneManager = SafeZoneManagerAI(self)
        self.safeZoneManager.generateWithRequired(2)
        self.tutorialManager = TutorialManagerAI(self)
        self.tutorialManager.generateWithRequired(2)
        self.friendManager = FriendManagerAI(self)
        self.friendManager.generateWithRequired(2)
        self.questManager = QuestManagerAI(self)
        self.banManager = BanManagerAI.BanManagerAI(self)
        self.achievementsManager = AchievementsManagerAI(self)
        self.suitInvasionManager = SuitInvasionManagerAI(self)
        self.trophyMgr = DistributedTrophyMgrAI(self)
        self.trophyMgr.generateWithRequired(2)
        self.cogSuitMgr = CogSuitManagerAI.CogSuitManagerAI(self)
        self.promotionMgr = PromotionManagerAI.PromotionManagerAI(self)
        self.experienceMgr = ExperienceRewardManagerAI.ExperienceRewardManagerAI(
            self)
        self.cogPageManager = CogPageManagerAI.CogPageManagerAI()
        self.sillyMeterMgr = DistributedSillyMeterMgrAI.DistributedSillyMeterMgrAI(
            self)
        self.sillyMeterMgr.generateWithRequired(2)
        self.hydrantZeroMgr = DistributedHydrantZeroMgrAI.DistributedHydrantZeroMgrAI(
            self)
        self.hydrantZeroMgr.generateWithRequired(2)
        self.mailboxZeroMgr = DistributedMailboxZeroMgrAI.DistributedMailboxZeroMgrAI(
            self)
        self.mailboxZeroMgr.generateWithRequired(2)
        self.trashcanZeroMgr = DistributedTrashcanZeroMgrAI.DistributedTrashcanZeroMgrAI(
            self)
        self.trashcanZeroMgr.generateWithRequired(2)
        self.dialogueManager = DialogueManagerAI(self)
        self.holidayManager = HolidayManagerAI(self)

        if self.wantFishing:
            self.fishManager = FishManagerAI(self)

        if self.wantHousing:
            self.estateManager = EstateManagerAI(self)
            self.estateManager.generateWithRequired(2)
            self.catalogManager = CatalogManagerAI(self)
            self.catalogManager.generateWithRequired(2)
            self.popularItemManager = PopularItemManagerAI(self)
            self.deliveryManager = self.generateGlobalObject(
                OTP_DO_ID_TOONTOWN_DELIVERY_MANAGER,
                'DistributedDeliveryManager')
            self.mailManager = self.generateGlobalObject(
                OTP_DO_ID_TOONTOWN_MAIL_MANAGER, 'DistributedMailManager')

        if self.wantPets:
            self.petMgr = PetManagerAI(self)

        if self.wantParties:
            self.partyManager = DistributedPartyManagerAI(self)
            self.partyManager.generateWithRequired(2)
            self.globalPartyMgr = self.generateGlobalObject(
                OTP_DO_ID_GLOBAL_PARTY_MANAGER, 'GlobalPartyManager')

        if self.wantCharityScreen:
            self.charityCounter = CharityScreenAI(self)
            self.charityCounter.generateWithRequired(2)
            self.charityCounter.start()

        self.codeRedemptionMgr = simbase.air.generateGlobalObject(
            OTP_DO_ID_TOONTOWN_CODE_REDEMPTION_MANAGER, 'TTCodeRedemptionMgr')
        self.chatAgent = simbase.air.generateGlobalObject(
            OTP_DO_ID_CHAT_MANAGER, 'ChatAgent')

    def createSafeZones(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-toontown-central', True):
            self.hoods.append(TTHoodAI.TTHoodAI(self))
        if self.config.GetBool('want-donalds-dock', True):
            self.hoods.append(DDHoodAI.DDHoodAI(self))
        if self.config.GetBool('want-daisys-garden', True):
            self.hoods.append(DGHoodAI.DGHoodAI(self))
        if self.config.GetBool('want-minnies-melodyland', True):
            self.hoods.append(MMHoodAI.MMHoodAI(self))
        if self.config.GetBool('want-the-burrrgh', True):
            self.hoods.append(BRHoodAI.BRHoodAI(self))
        if self.config.GetBool('want-donalds-dreamland', True):
            self.hoods.append(DLHoodAI.DLHoodAI(self))
        if self.config.GetBool('want-goofy-speedway', True):
            self.hoods.append(GSHoodAI.GSHoodAI(self))
        if self.config.GetBool('want-outdoor-zone', True):
            self.hoods.append(OZHoodAI.OZHoodAI(self))
        if self.config.GetBool('want-golf-zone', True):
            self.hoods.append(GZHoodAI.GZHoodAI(self))

    def createCogHeadquarters(self):
        NPCToons.generateZone2NpcDict()
        if self.config.GetBool('want-sellbot-headquarters', True):
            self.factoryMgr = FactoryManagerAI.FactoryManagerAI(self)
            self.cogHeadquarters.append(SellbotHQAI.SellbotHQAI(self))
        if self.config.GetBool('want-cashbot-headquarters', True):
            self.mintMgr = MintManagerAI.MintManagerAI(self)
            self.cogHeadquarters.append(CashbotHQAI.CashbotHQAI(self))
        if self.config.GetBool('want-lawbot-headquarters', True):
            self.lawOfficeMgr = LawOfficeManagerAI.LawOfficeManagerAI(self)
            self.cogHeadquarters.append(LawbotHQAI.LawbotHQAI(self))
        if self.config.GetBool('want-bossbot-headquarters', True):
            self.countryClubMgr = CountryClubManagerAI.CountryClubManagerAI(
                self)
            self.cogHeadquarters.append(BossbotHQAI.BossbotHQAI(self))

    def handleConnected(self):
        self.districtId = self.allocateChannel()
        self.notify.info('Creating ToontownDistrictAI(%d)...' %
                         self.districtId)
        self.distributedDistrict = ToontownDistrictAI(self)
        self.distributedDistrict.setName(self.districtName)
        self.distributedDistrict.generateWithRequiredAndId(
            self.districtId, self.getGameDoId(), 2)

        self.notify.info('Claiming ownership of channel ID: %d...' %
                         self.districtId)
        self.setAI(self.districtId, self.ourChannel)

        self.districtStats = ToontownDistrictStatsAI(self)
        self.districtStats.settoontownDistrictId(self.districtId)
        self.districtStats.generateWithRequiredAndId(self.allocateChannel(),
                                                     self.getGameDoId(), 3)

        self.notify.info('Created ToontownDistrictStats(%d)' %
                         self.districtStats.doId)

        self.notify.info('Creating managers...')
        self.createManagers()
        if self.config.GetBool('want-safe-zones', True):
            self.notify.info('Creating safe zones...')
            self.createSafeZones()

        if self.config.GetBool('want-cog-headquarters', True):
            self.notify.info('Creating Cog headquarters...')
            self.createCogHeadquarters()

        self.notify.info('Making district available...')
        self.distributedDistrict.b_setAvailable(1)
        self.notify.info('Done.')

    def lookupDNAFileName(self, zoneId):
        zoneId = ZoneUtil.getCanonicalZoneId(zoneId)
        hoodId = ZoneUtil.getCanonicalHoodId(zoneId)
        hood = ToontownGlobals.dnaMap[hoodId]
        if hoodId == zoneId:
            zoneId = 'sz'
            phaseNum = ToontownGlobals.phaseMap[hoodId]
        else:
            phaseNum = ToontownGlobals.streetPhaseMap[hoodId]

        return 'phase_%s/dna/%s_%s.pdna' % (phaseNum, hood, zoneId)

    def loadDNAFileAI(self, dnastore, filename):
        return loadDNAFileAI(dnastore, filename)

    def incrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() + 1)

    def decrementPopulation(self):
        self.districtStats.b_setAvatarCount(
            self.districtStats.getAvatarCount() - 1)

    def setHour(self, hour):
        pass  # Todo: Hour on district page

    def allocateZone(self):
        return self.zoneAllocator.allocate()

    def deallocateZone(self, zone):
        self.zoneAllocator.free(zone)

    def getZoneDataStore(self):
        return self.zoneDataStore

    def getTrackClsends(self):
        return self.wantTrackClsends

    def getAvatarExitEvent(self, avId):
        return 'distObjDelete-%d' % (avId)

    def trueUniqueName(self, name):
        return self.uniqueName(name)