from panda3d.core import * from panda3d.toontown import * from toontown.toonbase.ToonBaseGlobal import * from direct.directnotify import DirectNotifyGlobal from direct.fsm import StateData from direct.fsm import ClassicFSM, State from direct.fsm import State from direct.task.Task import Task from .ToontownMsgTypes import * from toontown.toonbase import ToontownGlobals from toontown.hood import TTHood from toontown.hood import DDHood from toontown.hood import MMHood from toontown.hood import BRHood from toontown.hood import DGHood from toontown.hood import DLHood from toontown.hood import GSHood from toontown.hood import OZHood from toontown.hood import GZHood from toontown.hood import SellbotHQ, CashbotHQ, LawbotHQ, BossbotHQ from toontown.hood import TutorialHood from direct.task import TaskManagerGlobal from toontown.hood import QuietZoneState from toontown.hood import ZoneUtil from toontown.hood import EstateHood from toontown.hood import PartyHood from toontown.toonbase import TTLocalizer from toontown.parties.PartyGlobals import GoToPartyStatus class PlayGame(StateData.StateData): notify = DirectNotifyGlobal.directNotify.newCategory('PlayGame') Hood2ClassDict = {ToontownGlobals.ToontownCentral: TTHood.TTHood, ToontownGlobals.DonaldsDock: DDHood.DDHood, ToontownGlobals.TheBrrrgh: BRHood.BRHood, ToontownGlobals.MinniesMelodyland: MMHood.MMHood, ToontownGlobals.DaisyGardens: DGHood.DGHood, ToontownGlobals.DonaldsDreamland: DLHood.DLHood, ToontownGlobals.GoofySpeedway: GSHood.GSHood, ToontownGlobals.OutdoorZone: OZHood.OZHood, ToontownGlobals.Tutorial: TutorialHood.TutorialHood, ToontownGlobals.MyEstate: EstateHood.EstateHood, ToontownGlobals.BossbotHQ: BossbotHQ.BossbotHQ, ToontownGlobals.SellbotHQ: SellbotHQ.SellbotHQ, ToontownGlobals.CashbotHQ: CashbotHQ.CashbotHQ, ToontownGlobals.LawbotHQ: LawbotHQ.LawbotHQ, ToontownGlobals.GolfZone: GZHood.GZHood, ToontownGlobals.PartyHood: PartyHood.PartyHood} Hood2StateDict = {ToontownGlobals.ToontownCentral: 'TTHood', ToontownGlobals.DonaldsDock: 'DDHood', ToontownGlobals.TheBrrrgh: 'BRHood', ToontownGlobals.MinniesMelodyland: 'MMHood', ToontownGlobals.DaisyGardens: 'DGHood', ToontownGlobals.DonaldsDreamland: 'DLHood', ToontownGlobals.GoofySpeedway: 'GSHood', ToontownGlobals.OutdoorZone: 'OZHood', ToontownGlobals.Tutorial: 'TutorialHood', ToontownGlobals.MyEstate: 'EstateHood', ToontownGlobals.BossbotHQ: 'BossbotHQ', ToontownGlobals.SellbotHQ: 'SellbotHQ', ToontownGlobals.CashbotHQ: 'CashbotHQ', ToontownGlobals.LawbotHQ: 'LawbotHQ', ToontownGlobals.GolfZone: 'GZHood', ToontownGlobals.PartyHood: 'PartyHood'} def __init__(self, parentFSM, doneEvent): StateData.StateData.__init__(self, doneEvent) self.place = None self.fsm = ClassicFSM.ClassicFSM('PlayGame', [State.State('start', self.enterStart, self.exitStart, ['quietZone']), State.State('quietZone', self.enterQuietZone, self.exitQuietZone, ['TTHood', 'DDHood', 'BRHood', 'MMHood', 'DGHood', 'DLHood', 'GSHood', 'OZHood', 'GZHood', 'SellbotHQ', 'CashbotHQ', 'LawbotHQ', 'BossbotHQ', 'TutorialHood', 'EstateHood', 'PartyHood']), State.State('TTHood', self.enterTTHood, self.exitTTHood, ['quietZone']), State.State('DDHood', self.enterDDHood, self.exitDDHood, ['quietZone']), State.State('BRHood', self.enterBRHood, self.exitBRHood, ['quietZone']), State.State('MMHood', self.enterMMHood, self.exitMMHood, ['quietZone']), State.State('DGHood', self.enterDGHood, self.exitDGHood, ['quietZone']), State.State('DLHood', self.enterDLHood, self.exitDLHood, ['quietZone']), State.State('GSHood', self.enterGSHood, self.exitGSHood, ['quietZone']), State.State('OZHood', self.enterOZHood, self.exitOZHood, ['quietZone']), State.State('GZHood', self.enterGZHood, self.exitGZHood, ['quietZone']), State.State('BossbotHQ', self.enterBossbotHQ, self.exitBossbotHQ, ['quietZone']), State.State('SellbotHQ', self.enterSellbotHQ, self.exitSellbotHQ, ['quietZone']), State.State('CashbotHQ', self.enterCashbotHQ, self.exitCashbotHQ, ['quietZone']), State.State('LawbotHQ', self.enterLawbotHQ, self.exitLawbotHQ, ['quietZone']), State.State('TutorialHood', self.enterTutorialHood, self.exitTutorialHood, ['quietZone']), State.State('EstateHood', self.enterEstateHood, self.exitEstateHood, ['quietZone']), State.State('PartyHood', self.enterPartyHood, self.exitPartyHood, ['quietZone'])], 'start', 'start') self.fsm.enterInitialState() self.parentFSM = parentFSM self.parentFSM.getStateNamed('playGame').addChild(self.fsm) self.hoodDoneEvent = 'hoodDone' self.hood = None self.quietZoneDoneEvent = uniqueName('quietZoneDone') self.quietZoneStateData = None return def enter(self, hoodId, zoneId, avId): if hoodId == ToontownGlobals.Tutorial: loaderName = 'townLoader' whereName = 'toonInterior' elif hoodId == ToontownGlobals.MyEstate: self.getEstateZoneAndGoHome(avId, zoneId) return elif hoodId == ToontownGlobals.PartyHood: self.getPartyZoneAndGoToParty(avId, zoneId) return else: loaderName = ZoneUtil.getLoaderName(zoneId) whereName = ZoneUtil.getToonWhereName(zoneId) self.fsm.request('quietZone', [{'loader': loaderName, 'where': whereName, 'how': 'teleportIn', 'hoodId': hoodId, 'zoneId': zoneId, 'shardId': None, 'avId': avId}]) return def exit(self): if base.placeBeforeObjects and self.quietZoneStateData: self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None self.ignore(self.quietZoneDoneEvent) return def load(self): pass def loadDnaStoreTutorial(self): self.dnaStore = DNAStorage() loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_tutorial.dna') loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_interior.dna') def loadDnaStore(self): if not hasattr(self, 'dnaStore'): self.dnaStore = DNAStorage() loader.loadDNAFile(self.dnaStore, 'phase_4/dna/storage.dna') self.dnaStore.storeFont('humanist', ToontownGlobals.getInterfaceFont()) self.dnaStore.storeFont('mickey', ToontownGlobals.getSignFont()) self.dnaStore.storeFont('suit', ToontownGlobals.getSuitFont()) loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_interior.dna') def unloadDnaStore(self): if hasattr(self, 'dnaStore'): self.dnaStore.resetNodes() self.dnaStore.resetTextures() del self.dnaStore ModelPool.garbageCollect() TexturePool.garbageCollect() def unload(self): self.unloadDnaStore() if self.hood: self.notify.info('Aggressively cleaning up hood: %s' % self.hood) self.hood.exit() self.hood.unload() self.hood = None return def enterStart(self): pass def exitStart(self): pass def handleHoodDone(self): doneStatus = self.hood.getDoneStatus() shardId = doneStatus['shardId'] if shardId != None: self.doneStatus = doneStatus messenger.send(self.doneEvent) base.transitions.fadeOut(0) return if doneStatus['where'] == 'party': self.getPartyZoneAndGoToParty(doneStatus['avId'], doneStatus['zoneId']) return how = doneStatus['how'] if how in ['tunnelIn', 'teleportIn', 'doorIn', 'elevatorIn']: self.fsm.request('quietZone', [doneStatus]) else: self.notify.error('Exited hood with unexpected mode %s' % how) return def _destroyHood(self): self.ignore(self.hoodDoneEvent) self.hood.exit() self.hood.unload() self.hood = None base.cr.cache.flush() return def enterQuietZone(self, requestStatus): self.acceptOnce(self.quietZoneDoneEvent, self.handleQuietZoneDone) self.quietZoneStateData = QuietZoneState.QuietZoneState(self.quietZoneDoneEvent) self._quietZoneLeftEvent = self.quietZoneStateData.getQuietZoneLeftEvent() if base.placeBeforeObjects: self.acceptOnce(self._quietZoneLeftEvent, self.handleLeftQuietZone) self._enterWaitForSetZoneResponseMsg = self.quietZoneStateData.getEnterWaitForSetZoneResponseMsg() self.acceptOnce(self._enterWaitForSetZoneResponseMsg, self.handleWaitForSetZoneResponse) self.quietZoneStateData.load() self.quietZoneStateData.enter(requestStatus) def exitQuietZone(self): self.ignore(self._quietZoneLeftEvent) self.ignore(self._enterWaitForSetZoneResponseMsg) if not base.placeBeforeObjects: self.ignore(self.quietZoneDoneEvent) self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None return def handleWaitForSetZoneResponse(self, requestStatus): hoodId = requestStatus['hoodId'] canonicalHoodId = ZoneUtil.getCanonicalZoneId(hoodId) toHoodPhrase = ToontownGlobals.hoodNameMap[canonicalHoodId][0] hoodName = ToontownGlobals.hoodNameMap[canonicalHoodId][-1] zoneId = requestStatus['zoneId'] loaderName = requestStatus['loader'] avId = requestStatus.get('avId', -1) ownerId = requestStatus.get('ownerId', avId) if base.config.GetBool('want-qa-regression', 0): self.notify.info('QA-REGRESSION: NEIGHBORHOODS: Visit %s' % hoodName) count = ToontownGlobals.hoodCountMap[canonicalHoodId] if loaderName == 'safeZoneLoader': count += ToontownGlobals.safeZoneCountMap[canonicalHoodId] elif loaderName == 'townLoader': count += ToontownGlobals.townCountMap[canonicalHoodId] if not loader.inBulkBlock: if hoodId == ToontownGlobals.MyEstate: if avId == -1: loader.beginBulkLoad('hood', TTLocalizer.HeadingToYourEstate, count, 1, TTLocalizer.TIP_ESTATE) else: owner = base.cr.identifyAvatar(ownerId) if owner == None: friend = base.cr.identifyAvatar(avId) if friend != None: avName = friend.getName() loader.beginBulkLoad('hood', TTLocalizer.HeadingToFriend % avName, count, 1, TTLocalizer.TIP_ESTATE) else: self.notify.warning("we can't perform this teleport") return else: avName = owner.getName() loader.beginBulkLoad('hood', TTLocalizer.HeadingToEstate % avName, count, 1, TTLocalizer.TIP_ESTATE) elif ZoneUtil.isCogHQZone(zoneId): loader.beginBulkLoad('hood', TTLocalizer.HeadingToHood % {'to': toHoodPhrase, 'hood': hoodName}, count, 1, TTLocalizer.TIP_COGHQ) elif ZoneUtil.isGoofySpeedwayZone(zoneId): loader.beginBulkLoad('hood', TTLocalizer.HeadingToHood % {'to': toHoodPhrase, 'hood': hoodName}, count, 1, TTLocalizer.TIP_KARTING) else: loader.beginBulkLoad('hood', TTLocalizer.HeadingToHood % {'to': toHoodPhrase, 'hood': hoodName}, count, 1, TTLocalizer.TIP_GENERAL) if hoodId == ToontownGlobals.Tutorial: self.loadDnaStoreTutorial() else: self.loadDnaStore() hoodClass = self.getHoodClassByNumber(canonicalHoodId) self.hood = hoodClass(self.fsm, self.hoodDoneEvent, self.dnaStore, hoodId) self.hood.load() self.hood.loadLoader(requestStatus) if not base.placeBeforeObjects: loader.endBulkLoad('hood') return def handleLeftQuietZone(self): status = self.quietZoneStateData.getRequestStatus() hoodId = ZoneUtil.getCanonicalZoneId(status['hoodId']) hoodState = self.getHoodStateByNumber(hoodId) self.fsm.request(hoodState, [status]) def handleQuietZoneDone(self): if base.placeBeforeObjects: self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None loader.endBulkLoad('hood') else: self.handleLeftQuietZone() return def enterTTHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitTTHood(self): self._destroyHood() def enterDDHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitDDHood(self): self._destroyHood() def enterMMHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitMMHood(self): self._destroyHood() def enterBRHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitBRHood(self): self._destroyHood() def enterDGHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitDGHood(self): self._destroyHood() def enterDLHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitDLHood(self): self._destroyHood() def enterGSHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitGSHood(self): self._destroyHood() def enterOZHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitOZHood(self): self._destroyHood() def enterGZHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitGZHood(self): self._destroyHood() def enterSellbotHQ(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitSellbotHQ(self): self._destroyHood() def enterCashbotHQ(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitCashbotHQ(self): self._destroyHood() def enterLawbotHQ(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitLawbotHQ(self): self._destroyHood() def enterBossbotHQ(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitBossbotHQ(self): self._destroyHood() def enterTutorialHood(self, requestStatus): messenger.send('toonArrivedTutorial') self.accept(self.hoodDoneEvent, self.handleHoodDone) base.localAvatar.book.obscureButton(1) base.localAvatar.book.setSafeMode(1) base.localAvatar.laffMeter.obscure(1) base.localAvatar.chatMgr.obscure(1, 1) base.localAvatar.obscureFriendsListButton(1) requestStatus['how'] = 'tutorial' if base.config.GetString('language', 'english') == 'japanese': musicVolume = base.config.GetFloat('tutorial-music-volume', 0.5) requestStatus['musicVolume'] = musicVolume self.hood.enter(requestStatus) def exitTutorialHood(self): self.unloadDnaStore() self._destroyHood() base.localAvatar.book.obscureButton(0) base.localAvatar.book.setSafeMode(0) base.localAvatar.laffMeter.obscure(0) base.localAvatar.chatMgr.obscure(0, 0) base.localAvatar.obscureFriendsListButton(-1) def enterEstateHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) self.hood.enter(requestStatus) def exitEstateHood(self): self._destroyHood() def getEstateZoneAndGoHome(self, avId, zoneId): self.doneStatus = {'avId': avId, 'zoneId': zoneId, 'hoodId': ToontownGlobals.MyEstate, 'loader': 'safeZoneLoader', 'how': 'teleportIn', 'shardId': None} self.acceptOnce('setLocalEstateZone', self.goHome) if avId > 0: base.cr.estateMgr.getLocalEstateZone(avId) else: base.cr.estateMgr.getLocalEstateZone(base.localAvatar.getDoId()) return def goHome(self, ownerId, zoneId): self.notify.debug('goHome ownerId = %s' % ownerId) if ownerId > 0 and ownerId != base.localAvatar.doId and not base.cr.isFriend(ownerId): self.doneStatus['failed'] = 1 taskMgr.remove('goHomeFailed') taskMgr.add(self.goHomeFailed, 'goHomeFailed') return if ownerId == 0 and zoneId == 0: self.doneStatus['failed'] = 1 self.goHomeFailed(None) return if self.doneStatus['zoneId'] != zoneId: self.doneStatus['where'] = 'house' else: self.doneStatus['where'] = 'estate' self.doneStatus['ownerId'] = ownerId self.fsm.request('quietZone', [self.doneStatus]) return def goHomeFailed(self, task): self.notify.debug('goHomeFailed') failedToVisitAvId = self.doneStatus.get('avId') if failedToVisitAvId > 0: message = TTLocalizer.EstateTeleportFailedNotFriends % base.cr.identifyAvatar(failedToVisitAvId).getName() else: message = TTLocalizer.EstateTeleportFailed self.notify.debug('goHomeFailed, why =: %s' % message) self.ignore('setLocalEstateZone') zoneId = base.localAvatar.lastHood loaderName = ZoneUtil.getLoaderName(zoneId) whereName = ZoneUtil.getToonWhereName(zoneId) base.localAvatar.setSystemMessage(0, message) self.fsm.request('quietZone', [{'loader': loaderName, 'where': whereName, 'how': 'teleportIn', 'hoodId': zoneId, 'zoneId': zoneId, 'shardId': None}]) return Task.done def enterPartyHood(self, requestStatus): self.accept(self.hoodDoneEvent, self.handleHoodDone) requestStatus['where'] = 'party' self.hood.enter(requestStatus) def exitPartyHood(self): self._destroyHood() def getPartyZoneAndGoToParty(self, avId, zoneId): self.doneStatus = {'avId': avId, 'zoneId': zoneId, 'hoodId': ToontownGlobals.PartyHood, 'loader': 'safeZoneLoader', 'how': 'teleportIn', 'shardId': None} if avId < 0: avId = base.localAvatar.getDoId() base.cr.partyManager.requestPartyZone(avId, zoneId, callback=self.goToParty) return def goToParty(self, ownerId, partyId, zoneId): if ownerId == 0 and partyId == 0 and zoneId == 0: self.doneStatus['where'] = 'playground' else: self.doneStatus['where'] = 'party' self.doneStatus['ownerId'] = ownerId self.doneStatus['partyId'] = partyId self.doneStatus['zoneId'] = zoneId self.fsm.request('quietZone', [self.doneStatus]) def goToPartyFailed(self, reason): self.notify.debug('goToPartyFailed') failedToVisitAvId = self.doneStatus.get('avId') message = base.cr.partyManager.getGoToPartyFailedMessage(reason) self.notify.debug('goToPartyFailed, why =: %s' % message) self.ignore('gotLocalPartyZone') zoneId = base.localAvatar.lastHood loaderName = ZoneUtil.getLoaderName(zoneId) whereName = ZoneUtil.getToonWhereName(zoneId) base.localAvatar.setSystemMessage(0, message) self.fsm.request('quietZone', [{'loader': loaderName, 'where': whereName, 'how': 'teleportIn', 'hoodId': zoneId, 'zoneId': zoneId, 'shardId': None}]) return Task.done def getCatalogCodes(self, category): numCodes = self.dnaStore.getNumCatalogCodes(category) codes = [] for i in range(numCodes): codes.append(self.dnaStore.getCatalogCode(category, i)) return codes def getNodePathList(self, catalogGroup): result = [] codes = self.getCatalogCodes(catalogGroup) for code in codes: np = self.dnaStore.findNode(code) result.append(np) return result def getNodePathDict(self, catalogGroup): result = {} codes = self.getCatalogCodes(catalogGroup) for code in codes: np = self.dnaStore.findNode(code) result[code] = np return result def getHoodClassByNumber(self, hoodNumber): return self.Hood2ClassDict[hoodNumber] def getHoodStateByNumber(self, hoodNumber): return self.Hood2StateDict[hoodNumber] def setPlace(self, place): self.place = place if self.place: messenger.send('playGameSetPlace') def getPlace(self): return self.place def getPlaceId(self): if self.hood: return self.hood.hoodId else: return None return None