from panda3d.core import * from panda3d.otp import * from toontown.battle.BattleProps import * from toontown.battle.BattleSounds import * from toontown.distributed.ToontownMsgTypes import * from direct.gui.DirectGui import cleanupDialog from direct.directnotify import DirectNotifyGlobal from toontown.battle import BattlePlace from direct.fsm import ClassicFSM, State from direct.task import Task from otp.distributed.TelemetryLimiter import RotationLimitToH, TLGatherAllAvs from toontown.building import Elevator from toontown.hood import ZoneUtil from toontown.toonbase import ToontownGlobals from toontown.toon.Toon import teleportDebug from direct.interval.IntervalGlobal import * visualizeZones = ConfigVariableBool('visualize-zones', 0).value class Street(BattlePlace.BattlePlace): notify = DirectNotifyGlobal.directNotify.newCategory('Street') def __init__(self, loader, parentFSM, doneEvent): BattlePlace.BattlePlace.__init__(self, loader, doneEvent) self.fsm = ClassicFSM.ClassicFSM('Street', [State.State('start', self.enterStart, self.exitStart, ['walk', 'tunnelIn', 'doorIn', 'teleportIn', 'elevatorIn']), State.State('walk', self.enterWalk, self.exitWalk, ['push', 'sit', 'stickerBook', 'WaitForBattle', 'battle', 'DFA', 'trialerFA', 'doorOut', 'elevator', 'tunnelIn', 'tunnelOut', 'teleportOut', 'quest', 'stopped', 'fishing', 'purchase', 'died']), State.State('sit', self.enterSit, self.exitSit, ['walk']), State.State('push', self.enterPush, self.exitPush, ['walk']), State.State('stickerBook', self.enterStickerBook, self.exitStickerBook, ['walk', 'push', 'sit', 'battle', 'DFA', 'trialerFA', 'doorOut', 'elevator', 'tunnelIn', 'tunnelOut', 'WaitForBattle', 'teleportOut', 'quest', 'stopped', 'fishing', 'purchase']), State.State('WaitForBattle', self.enterWaitForBattle, self.exitWaitForBattle, ['battle', 'walk']), State.State('battle', self.enterBattle, self.exitBattle, ['walk', 'teleportOut', 'died']), State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['walk']), State.State('elevatorIn', self.enterElevatorIn, self.exitElevatorIn, ['walk']), State.State('elevator', self.enterElevator, self.exitElevator, ['walk']), State.State('trialerFA', self.enterTrialerFA, self.exitTrialerFA, ['trialerFAReject', 'DFA']), State.State('trialerFAReject', self.enterTrialerFAReject, self.exitTrialerFAReject, ['walk']), State.State('DFA', self.enterDFA, self.exitDFA, ['DFAReject', 'teleportOut', 'tunnelOut']), State.State('DFAReject', self.enterDFAReject, self.exitDFAReject, ['walk']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk', 'teleportOut', 'quietZone', 'WaitForBattle', 'battle']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn', 'quietZone', 'WaitForBattle']), State.State('died', self.enterDied, self.exitDied, ['quietZone']), State.State('tunnelIn', self.enterTunnelIn, self.exitTunnelIn, ['walk']), State.State('tunnelOut', self.enterTunnelOut, self.exitTunnelOut, ['final']), State.State('quietZone', self.enterQuietZone, self.exitQuietZone, ['teleportIn']), State.State('quest', self.enterQuest, self.exitQuest, ['walk', 'stopped']), State.State('stopped', self.enterStopped, self.exitStopped, ['walk']), State.State('stopped', self.enterStopped, self.exitStopped, ['walk']), State.State('fishing', self.enterFishing, self.exitFishing, ['walk']), State.State('purchase', self.enterPurchase, self.exitPurchase, ['walk']), State.State('final', self.enterFinal, self.exitFinal, ['start'])], 'start', 'final') self.parentFSM = parentFSM self.tunnelOriginList = [] self.elevatorDoneEvent = 'elevatorDone' self.halloweenLights = [] def enter(self, requestStatus, visibilityFlag = 1, arrowsOn = 1): teleportDebug(requestStatus, 'Street.enter(%s)' % (requestStatus,)) self._ttfToken = None self.fsm.enterInitialState() base.playMusic(self.loader.music, looping=1, volume=0.8) self.loader.geom.reparentTo(render) if visibilityFlag: self.visibilityOn() base.localAvatar.setGeom(self.loader.geom) base.localAvatar.setOnLevelGround(1) self._telemLimiter = TLGatherAllAvs('Street', RotationLimitToH) NametagGlobals.setMasterArrowsOn(arrowsOn) def __lightDecorationOn__(): geom = base.cr.playGame.getPlace().loader.geom self.halloweenLights = geom.findAllMatches('**/*light*') self.halloweenLights += geom.findAllMatches('**/*lamp*') self.halloweenLights += geom.findAllMatches('**/prop_snow_tree*') for light in self.halloweenLights: light.setColorScaleOff(1) newsManager = base.cr.newsManager if newsManager: holidayIds = base.cr.newsManager.getDecorationHolidayId() if (ToontownGlobals.HALLOWEEN_COSTUMES in holidayIds or ToontownGlobals.SPOOKY_COSTUMES in holidayIds) and self.loader.hood.spookySkyFile: lightsOff = Sequence(LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(0.55, 0.55, 0.65, 1)), Func(self.loader.hood.startSpookySky)) lightsOff.start() else: self.loader.hood.startSky() lightsOn = LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() else: self.loader.hood.startSky() lightsOn = LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() self.accept('doorDoneEvent', self.handleDoorDoneEvent) self.accept('DistributedDoor_doorTrigger', self.handleDoorTrigger) self.enterZone(requestStatus['zoneId']) self.tunnelOriginList = base.cr.hoodMgr.addLinkTunnelHooks(self, self.loader.nodeList, self.zoneId) self.fsm.request(requestStatus['how'], [requestStatus]) self.replaceStreetSignTextures() return def exit(self, visibilityFlag = 1): if visibilityFlag: self.visibilityOff() self.loader.geom.reparentTo(hidden) self._telemLimiter.destroy() del self._telemLimiter def __lightDecorationOff__(): for light in self.halloweenLights: light.reparentTo(hidden) newsManager = base.cr.newsManager NametagGlobals.setMasterArrowsOn(0) self.loader.hood.stopSky() self.loader.music.stop() base.localAvatar.setGeom(render) base.localAvatar.setOnLevelGround(0) def load(self): BattlePlace.BattlePlace.load(self) self.parentFSM.getStateNamed('street').addChild(self.fsm) def unload(self): self.parentFSM.getStateNamed('street').removeChild(self.fsm) del self.parentFSM del self.fsm self.enterZone(None) cleanupDialog('globalDialog') self.ignoreAll() BattlePlace.BattlePlace.unload(self) return def enterElevatorIn(self, requestStatus): self._eiwbTask = taskMgr.add(Functor(self._elevInWaitBldgTask, requestStatus['bldgDoId']), uniqueName('elevInWaitBldg')) def _elevInWaitBldgTask(self, bldgDoId, task): bldg = base.cr.doId2do.get(bldgDoId) if bldg: if bldg.elevatorNodePath is not None: self._enterElevatorGotElevator() return Task.done return Task.cont def _enterElevatorGotElevator(self): messenger.send('insideVictorElevator') def exitElevatorIn(self): taskMgr.remove(self._eiwbTask) def enterElevator(self, distElevator): base.localAvatar.cantLeaveGame = 1 self.accept(self.elevatorDoneEvent, self.handleElevatorDone) self.elevator = Elevator.Elevator(self.fsm.getStateNamed('elevator'), self.elevatorDoneEvent, distElevator) self.elevator.load() self.elevator.enter() def exitElevator(self): base.localAvatar.cantLeaveGame = 0 self.ignore(self.elevatorDoneEvent) self.elevator.unload() self.elevator.exit() del self.elevator def detectedElevatorCollision(self, distElevator): self.fsm.request('elevator', [distElevator]) return None def handleElevatorDone(self, doneStatus): self.notify.debug('handling elevator done event') where = doneStatus['where'] if where == 'reject': if hasattr(base.localAvatar, 'elevatorNotifier') and base.localAvatar.elevatorNotifier.isNotifierOpen(): pass else: self.fsm.request('walk') elif where == 'exit': self.fsm.request('walk') elif where in ('suitInterior', 'cogdoInterior'): self.doneStatus = doneStatus messenger.send(self.doneEvent) else: self.notify.error('Unknown mode: ' + where + ' in handleElevatorDone') def enterTunnelIn(self, requestStatus): self.enterZone(requestStatus['zoneId']) BattlePlace.BattlePlace.enterTunnelIn(self, requestStatus) def enterTeleportIn(self, requestStatus): teleportDebug(requestStatus, 'Street.enterTeleportIn(%s)' % (requestStatus,)) zoneId = requestStatus['zoneId'] self._ttfToken = self.addSetZoneCompleteCallback(Functor(self._teleportToFriend, requestStatus)) self.enterZone(zoneId) BattlePlace.BattlePlace.enterTeleportIn(self, requestStatus) def _teleportToFriend(self, requestStatus): avId = requestStatus['avId'] hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] if avId != -1: if avId not in base.cr.doId2do: teleportDebug(requestStatus, "couldn't find friend %s" % avId) handle = base.cr.identifyFriend(avId) requestStatus = {'how': 'teleportIn', 'hoodId': hoodId, 'zoneId': hoodId, 'shardId': None, 'loader': 'safeZoneLoader', 'where': 'playground', 'avId': avId} self.fsm.request('final') self.__teleportOutDone(requestStatus) return def exitTeleportIn(self): self.removeSetZoneCompleteCallback(self._ttfToken) self._ttfToken = None BattlePlace.BattlePlace.exitTeleportIn(self) return def enterTeleportOut(self, requestStatus): if 'battle' in requestStatus: self.__teleportOutDone(requestStatus) else: BattlePlace.BattlePlace.enterTeleportOut(self, requestStatus, self.__teleportOutDone) def __teleportOutDone(self, requestStatus): hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] shardId = requestStatus['shardId'] if hoodId == self.loader.hood.id and shardId == None: if zoneId == self.zoneId: self.fsm.request('teleportIn', [requestStatus]) elif requestStatus['where'] == 'street' and ZoneUtil.getBranchZone(zoneId) == self.loader.branchZone: self.fsm.request('quietZone', [requestStatus]) else: self.doneStatus = requestStatus messenger.send(self.doneEvent) elif hoodId == ToontownGlobals.MyEstate: self.getEstateZoneAndGoHome(requestStatus) else: self.doneStatus = requestStatus messenger.send(self.doneEvent) return def exitTeleportOut(self): BattlePlace.BattlePlace.exitTeleportOut(self) def goHomeFailed(self, task): self.notifyUserGoHomeFailed() self.ignore('setLocalEstateZone') self.doneStatus['avId'] = -1 self.doneStatus['zoneId'] = self.getZoneId() self.fsm.request('teleportIn', [self.doneStatus]) return Task.done def renameFloorPolys(self, nodeList): for i in nodeList: collNodePaths = i.findAllMatches('**/+CollisionNode') numCollNodePaths = collNodePaths.getNumPaths() visGroupName = i.node().getName() for j in range(numCollNodePaths): collNodePath = collNodePaths.getPath(j) bitMask = collNodePath.node().getIntoCollideMask() if bitMask.getBit(1): collNodePath.node().setName(visGroupName) def hideAllVisibles(self): for i in self.loader.nodeList: i.stash() def showAllVisibles(self): for i in self.loader.nodeList: i.unstash() def visibilityOn(self): self.hideAllVisibles() self.accept('on-floor', self.enterZone) def visibilityOff(self): self.ignore('on-floor') self.showAllVisibles() def doEnterZone(self, newZoneId): if self.zoneId != None: for i in self.loader.nodeDict[self.zoneId]: if newZoneId: if i not in self.loader.nodeDict[newZoneId]: self.loader.fadeOutDict[i].start() self.loader.exitAnimatedProps(i) else: i.stash() self.loader.exitAnimatedProps(i) if newZoneId != None: for i in self.loader.nodeDict[newZoneId]: if self.zoneId: if i not in self.loader.nodeDict[self.zoneId]: self.loader.fadeInDict[i].start() self.loader.enterAnimatedProps(i) else: if self.loader.fadeOutDict[i].isPlaying(): self.loader.fadeOutDict[i].finish() if self.loader.fadeInDict[i].isPlaying(): self.loader.fadeInDict[i].finish() self.loader.enterAnimatedProps(i) i.unstash() if newZoneId != self.zoneId: if visualizeZones: if self.zoneId != None: self.loader.zoneDict[self.zoneId].clearColor() if newZoneId != None: self.loader.zoneDict[newZoneId].setColor(0, 0, 1, 1, 100) if newZoneId != None: if not __astron__: base.cr.sendSetZoneMsg(newZoneId) else: visZones = [self.loader.node2zone[x] for x in self.loader.nodeDict[newZoneId]] visZones.append(ZoneUtil.getBranchZone(newZoneId)) if newZoneId not in visZones: visZones.append(newZoneId) base.cr.sendSetZoneMsg(newZoneId, visZones) self.notify.debug('Entering Zone %d' % newZoneId) self.zoneId = newZoneId geom = base.cr.playGame.getPlace().loader.geom self.halloweenLights = geom.findAllMatches('**/*light*') self.halloweenLights += geom.findAllMatches('**/*lamp*') self.halloweenLights += geom.findAllMatches('**/prop_snow_tree*') for light in self.halloweenLights: light.setColorScaleOff(1) return def replaceStreetSignTextures(self): if not hasattr(base.cr, 'playGame'): return place = base.cr.playGame.getPlace() if place is None: return geom = base.cr.playGame.getPlace().loader.geom signs = geom.findAllMatches('**/*tunnelAheadSign*;+s') if signs.getNumPaths() > 0: streetSign = base.cr.streetSign signTexturePath = streetSign.StreetSignBaseDir + '/' + streetSign.StreetSignFileName loaderTexturePath = Filename(str(signTexturePath)) alphaPath = 'phase_4/maps/tt_t_ara_gen_tunnelAheadSign_a.rgb' inDreamland = False if place.zoneId and ZoneUtil.getCanonicalHoodId(place.zoneId) == ToontownGlobals.DonaldsDreamland: inDreamland = True alphaPath = 'phase_4/maps/tt_t_ara_gen_tunnelAheadSign_a.rgb' if Filename(signTexturePath).exists(): signTexture = loader.loadTexture(loaderTexturePath, alphaPath) for sign in signs: if Filename(signTexturePath).exists(): sign.setTexture(signTexture, 1) if inDreamland: sign.setColorScale(0.525, 0.525, 0.525, 1) return