oldschool-toontown/toontown/distributed/PlayGame.py
2019-11-17 16:29:23 -05:00

568 lines
22 KiB
Python

from pandac.PandaModules import *
from libtoontown 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