import string import time from direct.directnotify import DirectNotifyGlobal from direct.distributed.PyDatagram import * from panda3d.core import * from panda3d.toontown import * from otp.ai.AIZoneData import AIZoneDataStore from otp.ai.TimeManagerAI import TimeManagerAI from otp.distributed.OtpDoGlobals import * from otp.friends.FriendManagerAI import FriendManagerAI from otp.otpbase import OTPGlobals from toontown.ai.DistributedPolarPlaceEffectMgrAI import DistributedPolarPlaceEffectMgrAI from toontown.ai.DistributedResistanceEmoteMgrAI import DistributedResistanceEmoteMgrAI from toontown.ai.HolidayManagerAI import HolidayManagerAI from toontown.ai.NewsManagerAI import NewsManagerAI from toontown.ai.WelcomeValleyManagerAI import WelcomeValleyManagerAI from toontown.building.DistributedTrophyMgrAI import DistributedTrophyMgrAI from toontown.catalog.CatalogManagerAI import CatalogManagerAI from toontown.coderedemption.TTCodeRedemptionMgrAI import TTCodeRedemptionMgrAI from toontown.coghq.CogSuitManagerAI import CogSuitManagerAI from toontown.coghq.CountryClubManagerAI import CountryClubManagerAI from toontown.coghq.FactoryManagerAI import FactoryManagerAI from toontown.coghq.LawOfficeManagerAI import LawOfficeManagerAI from toontown.coghq.MintManagerAI import MintManagerAI from toontown.coghq.PromotionManagerAI import PromotionManagerAI from toontown.distributed.NonRepeatableRandomSourceAI import NonRepeatableRandomSourceAI from toontown.distributed.ToontownDistrictAI import ToontownDistrictAI from toontown.distributed.ToontownDistrictStatsAI import ToontownDistrictStatsAI from toontown.distributed.ToontownInternalRepository import ToontownInternalRepository from toontown.estate.EstateManagerAI import EstateManagerAI from toontown.fishing.FishManagerAI import FishManagerAI from toontown.hood import ZoneUtil from toontown.hood.BRHoodDataAI import BRHoodDataAI from toontown.hood.BossbotHQDataAI import BossbotHQDataAI from toontown.hood.CSHoodDataAI import CSHoodDataAI from toontown.hood.CashbotHQDataAI import CashbotHQDataAI from toontown.hood.DDHoodDataAI import DDHoodDataAI from toontown.hood.DGHoodDataAI import DGHoodDataAI from toontown.hood.DLHoodDataAI import DLHoodDataAI from toontown.hood.GSHoodDataAI import GSHoodDataAI from toontown.hood.GZHoodDataAI import GZHoodDataAI from toontown.hood.LawbotHQDataAI import LawbotHQDataAI from toontown.hood.MMHoodDataAI import MMHoodDataAI from toontown.hood.OZHoodDataAI import OZHoodDataAI from toontown.hood.TTHoodDataAI import TTHoodDataAI from toontown.hood.FFHoodDataAI import FFHoodDataAI from toontown.parties.ToontownTimeManager import ToontownTimeManager from toontown.pets.PetManagerAI import PetManagerAI from toontown.quest.QuestManagerAI import QuestManagerAI from toontown.racing import RaceGlobals from toontown.racing.DistributedLeaderBoardAI import DistributedLeaderBoardAI from toontown.racing.DistributedRacePadAI import DistributedRacePadAI from toontown.racing.DistributedStartingBlockAI import DistributedStartingBlockAI, DistributedViewingBlockAI from toontown.racing.DistributedViewPadAI import DistributedViewPadAI from toontown.racing.RaceManagerAI import RaceManagerAI from toontown.safezone import DistributedPartyGateAI from toontown.safezone.SafeZoneManagerAI import SafeZoneManagerAI from toontown.shtiker.CogPageManagerAI import CogPageManagerAI from toontown.spellbook.TTOffMagicWordManagerAI import TTOffMagicWordManagerAI from toontown.suit.SuitInvasionManagerAI import SuitInvasionManagerAI from toontown.toon import NPCToons from toontown.toonbase import ToontownGlobals, TTLocalizer from toontown.tutorial.TutorialManagerAI import TutorialManagerAI from toontown.uberdog.DistributedInGameNewsMgrAI import DistributedInGameNewsMgrAI from toontown.uberdog.DistributedPartyManagerAI import DistributedPartyManagerAI 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 Code Redemption manager... self.codeRedemptionManager = TTCodeRedemptionMgrAI(self) self.codeRedemptionManager.generateWithRequired(OTP_ZONE_ID_MANAGEMENT) # Generate our random source manager... self.randomSourceManager = NonRepeatableRandomSourceAI(self) self.randomSourceManager.generateWithRequired(OTP_ZONE_ID_OLD_QUIET_ZONE) # 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 Magic Word manager... self.magicWordManager = TTOffMagicWordManagerAI(self) self.magicWordManager.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) # Funny Farm self.zoneTable[ToontownGlobals.FunnyFarm] = ( (ToontownGlobals.FunnyFarm, 1, 0), (ToontownGlobals.ConstructionBlvd, 1, 1), (ToontownGlobals.SneedStreet, 1, 1), (ToontownGlobals.LoonyLane, 1, 1) ) self.createHood(FFHoodDataAI, ToontownGlobals.FunnyFarm) # 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, dnaGroup, zoneId, overrideDNAZone = 0): """ Recursively scans the given DNA tree for party hats. These are defined as all the groups whose code includes the string "party_gate". For each such group, creates a DistributedPartyGateAI. Returns the list of distributed objects. """ partyHats = [] if ((isinstance(dnaGroup, DNAGroup)) and # If it is a DNAGroup, and the name has party_gate, count it (string.find(dnaGroup.getName(), 'party_gate') >= 0)): # Here's a party hat! ph = DistributedPartyGateAI.DistributedPartyGateAI(self) ph.generateWithRequired(zoneId) partyHats.append(ph) else: # Now look in the children # Party hats cannot have other party hats in them, # so do not search the one we just found: # If we come across a visgroup, note the zoneId and then recurse if (isinstance(dnaGroup, DNAVisGroup) and not overrideDNAZone): # Make sure we get the real zone id, in case we are in welcome valley zoneId = ZoneUtil.getTrueZoneId( int(dnaGroup.getName().split(':')[0]), zoneId) for i in range(dnaGroup.getNumChildren()): childPartyHats = self.findPartyHats(dnaGroup.at(i), zoneId, overrideDNAZone) partyHats += childPartyHats return partyHats 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