class ToonBase(OTPBase.OTPBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): OTPBase.OTPBase.__init__(self) self.disableShowbaseMouse() self.addCullBins() self.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0) self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = self.config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(settings['fov']/(4./3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.exitFunc = self.userExit globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) # OS X Specific Actions if platform == "darwin": self.acceptOnce(ToontownGlobals.QuitGameHotKeyOSX, self.exitOSX) self.accept(ToontownGlobals.QuitGameHotKeyRepeatOSX, self.exitOSX) self.acceptOnce(ToontownGlobals.HideGameHotKeyOSX, self.hideGame) self.accept(ToontownGlobals.HideGameHotKeyRepeatOSX, self.hideGame) self.acceptOnce(ToontownGlobals.MinimizeGameHotKeyOSX, self.minimizeGame) self.accept(ToontownGlobals.MinimizeGameHotKeyRepeatOSX, self.minimizeGame) self.accept('f3', self.toggleGui) self.accept('f4', self.oobe) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.inactivityTimeout = self.config.GetFloat('inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool('random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool('random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool('want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool('skip-battle-movies', 0) self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool('kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) tpMgr.setProperties('WLDisplay', WLDisplay) WLRed = tpMgr.getProperties('red') WLRed.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLRed', WLRed) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.accept('shift', self.setSprinting) self.accept('shift-up', self.exitSprinting) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.isSprinting = 1 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None self.filters = CommonFilters(self.win, self.cam) self.wantCogInterface = settings.get('cogInterface', True) self.aspect2d.setAntialias(AntialiasAttrib.MMultisample) def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def setCursorAndIcon(self): atexit.register(shutil.rmtree, tempdir) wp = WindowProperties() wp.setCursorFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'toonmono.cur'))) wp.setIconFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'icon.ico'))) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTUnsorted, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def setSprinting(self): if self.walking: base.localAvatar.currentSpeed = OTPGlobals.ToonForwardSprintSpeed base.localAvatar.currentReverseSpeed = OTPGlobals.ToonReverseSprintSpeed base.localAvatar.controlManager.setSpeeds(OTPGlobals.ToonForwardSprintSpeed, OTPGlobals.ToonJumpForce, OTPGlobals.ToonReverseSprintSpeed, OTPGlobals.ToonRotateSpeed) self.isSprinting = 1 else: if self.isSprinting == 1: self.exitSprinting() def exitSprinting(self): if hasattr(base, 'localAvatar'): base.localAvatar.currentSpeed = OTPGlobals.ToonForwardSpeed base.localAvatar.currentReverseSpeed = OTPGlobals.ToonReverseSpeed base.localAvatar.controlManager.setSpeeds(OTPGlobals.ToonForwardSpeed, OTPGlobals.ToonJumpForce, OTPGlobals.ToonReverseSpeed, OTPGlobals.ToonRotateSpeed) self.isSprinting = 0 def toggleGui(self): if aspect2d.isHidden(): aspect2d.show() else: aspect2d.hide() def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() self.snapshotSfx = base.loader.loadSfx('phase_4/audio/sfx/Photo_shutter.ogg') base.playSfx(self.snapshotSfx) if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton(PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode(self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager # TODO: Dynamicaly add more and reposition cells padding = 0.0225 # Order: Top to bottom self.leftCells = [ mm.addGridCell(0.2 + padding, -0.45, base.a2dTopLeft), # Above boarding groups mm.addGridCell(0.2 + padding, -0.9, base.a2dTopLeft), # 1 mm.addGridCell(0.2 + padding, -1.35, base.a2dTopLeft) # Below Boarding Groups ] # Order: Left to right self.bottomCells = [ mm.addGridCell(-0.87, 0.2 + padding, base.a2dBottomCenter), # To the right of the laff meter mm.addGridCell(-0.43, 0.2 + padding, base.a2dBottomCenter), # 1 mm.addGridCell(0.01, 0.2 + padding, base.a2dBottomCenter), # 2 mm.addGridCell(0.45, 0.2 + padding, base.a2dBottomCenter), # 3 mm.addGridCell(0.89, 0.2 + padding, base.a2dBottomCenter) # To the left of the shtiker book ] # Order: Bottom to top self.rightCells = [ mm.addGridCell(-0.2 - padding, -1.35, base.a2dTopRight), # Above the street map mm.addGridCell(-0.2 - padding, -0.9, base.a2dTopRight), # Below the friends list mm.addGridCell(-0.2 - padding, -0.45, base.a2dTopRight) # Behind the friends list ] def hideFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], False) def showFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], True) def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def startShow(self, cr): self.cr = cr base.graphicsEngine.renderFrame() # Get the base port. serverPort = base.config.GetInt('server-port', 7199) # Get the number of client-agents. clientagents = base.config.GetInt('client-agents', 1) - 1 # Get a new port. serverPort += (random.randint(0, clientagents) * 100) serverList = [] for name in launcher.getGameServer().split(';'): url = URLSpec(name, 1) if base.config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = base.config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('connect', [serverList]) # Start detecting speed hacks: self.lastSpeedHackCheck = time.time() self.lastTrueClockTime = TrueClock.getGlobalPtr().getLongTime() taskMgr.add(self.__speedHackCheckTick, 'speedHackCheck-tick') def __speedHackCheckTick(self, task): elapsed = time.time() - self.lastSpeedHackCheck tcElapsed = TrueClock.getGlobalPtr().getLongTime() - self.lastTrueClockTime if tcElapsed > (elapsed + 0.05): # The TrueClock is running faster than it should. This means the # player may have sped up the process. Disconnect them: self.cr.stopReaderPollTask() self.cr.lostConnection() return task.done self.lastSpeedHackCheck = time.time() self.lastTrueClockTime = TrueClock.getGlobalPtr().getLongTime() return task.cont def removeGlitchMessage(self): self.ignore('InputState-forward') def exitShow(self, errorCode = None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.ignore(ToontownGlobals.QuitGameHotKeyOSX) self.ignore(ToontownGlobals.QuitGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.HideGameHotKeyOSX) self.ignore(ToontownGlobals.HideGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyRepeatOSX) self.exitShow() def panda3dRenderError(self): if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def playMusic(self, music, looping = 0, interrupt = 1, volume = None, time = 0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) def setFrameRateMeter(self, flag): if flag: if not self.frameRateMeter: self.frameRateMeter = TTFrameRateMeter() else: if self.frameRateMeter: self.frameRateMeter.destroy() self.frameRateMeter = None def setCopyright(self, flag): self.copyright = TTCopyright() # OS X Specific Actions def exitOSX(self): self.confirm = TTDialog.TTGlobalDialog(doneEvent='confirmDone', message=TTLocalizer.OptionsPageExitConfirm, style=TTDialog.TwoChoice) self.confirm.show() self.accept('confirmDone', self.handleConfirm) def handleConfirm(self): status = self.confirm.doneStatus self.ignore('confirmDone') self.confirm.cleanup() del self.confirm if status == 'ok': self.userExit() def hideGame(self): # Hacky, I know, but it works hideCommand = """osascript -e 'tell application "System Events" set frontProcess to first process whose frontmost is true set visible of frontProcess to false end tell'""" os.system(hideCommand) def minimizeGame(self): wp = WindowProperties() wp.setMinimized(True) base.win.requestProperties(wp)
class ToonBase(OTPBase.OTPBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): OTPBase.OTPBase.__init__(self) # First, build a list of all possible resolutions: self.resList = [] displayInfo = self.pipe.getDisplayInformation() for i in xrange(displayInfo.getTotalDisplayModes()): width = displayInfo.getDisplayModeWidth(i) height = displayInfo.getDisplayModeHeight(i) if (width, height) not in self.resList: self.resList.append((width, height)) # Next, separate the resolutions by their ratio: self.resDict = {} for res in self.resList: width = float(res[0]) height = float(res[1]) ratio = round(width / height, 2) self.resDict.setdefault(ratio, []).append(res) # Get the native width, height and ratio: self.nativeWidth = displayInfo.getMaximumWindowWidth() self.nativeHeight = displayInfo.getMaximumWindowHeight() self.nativeRatio = round(float(self.nativeWidth) / float(self.nativeHeight), 2) # Finally, choose the best resolution if we're either fullscreen, or # don't have one defined in our preferences: fullscreen = self.settings.get('fullscreen', False) if ('res' not in self.settings.all()) or fullscreen: if fullscreen: # If we're fullscreen, we want to fit the entire screen: res = (self.nativeWidth, self.nativeHeight) elif len(self.resDict[self.nativeRatio]) > 1: # We have resolutions that match our native ratio and fit it! Let's # use one: res = self.resDict[self.nativeRatio][0] else: # Okay, we don't have any resolutions that match our screen's # resolutions and fit it (besides the native ratio itself, of # course). Let's just use the second largest ratio: ratios = sorted(self.resDict.keys(), reverse=False) nativeIndex = ratios.index(self.nativeRatio) res = ratios[nativeIndex + 1][0] # Reload the graphics pipe: properties = WindowProperties() # If we're in fullscreen mode, we'll want to fit to the screen: if fullscreen: res = self.resList[-1] properties.setSize(res[0], res[1]) properties.setFullscreen(fullscreen) properties.setParentWindow(0) # Store the window sort for later: sort = self.win.getSort() if self.win: currentProperties = WindowProperties(self.win.getProperties()) gsg = self.win.getGsg() else: currentProperties = WindowProperties.getDefault() gsg = None newProperties = WindowProperties(currentProperties) newProperties.addProperties(properties) if (gsg is None) or (currentProperties.getFullscreen() != newProperties.getFullscreen()) or (currentProperties.getParentWindow() != newProperties.getParentWindow()): self.openMainWindow(props=properties, gsg=gsg, keepCamera=True) self.graphicsEngine.openWindows() self.disableShowbaseMouse() from otp.nametag import NametagGlobals NametagGlobals.setCamera(self.cam) NametagGlobals.setMouseWatcher(self.mouseWatcherNode) else: self.win.requestProperties(properties) self.graphicsEngine.renderFrame() self.win.setSort(sort) self.graphicsEngine.renderFrame() self.graphicsEngine.renderFrame() self.disableShowbaseMouse() self.addCullBins() self.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = self.config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(ToontownGlobals.DefaultCameraFov/(4./3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.exitFunc = self.userExit if __builtins__.has_key('launcher') and launcher: launcher.setPandaErrorCode(11) globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) # OS X Specific Actions if platform == "darwin": self.acceptOnce(ToontownGlobals.QuitGameHotKeyOSX, self.exitOSX) self.accept(ToontownGlobals.QuitGameHotKeyRepeatOSX, self.exitOSX) self.acceptOnce(ToontownGlobals.HideGameHotKeyOSX, self.hideGame) self.accept(ToontownGlobals.HideGameHotKeyRepeatOSX, self.hideGame) self.acceptOnce(ToontownGlobals.MinimizeGameHotKeyOSX, self.minimizeGame) self.accept(ToontownGlobals.MinimizeGameHotKeyRepeatOSX, self.minimizeGame) self.accept('f3', self.toggleGui) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.friendMode = self.config.GetBool('switchboard-friends', 0) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.wantNewSpecies = self.config.GetBool('want-new-species', 0) self.wantAchievements = self.config.GetBool('want-achievements', 1) self.inactivityTimeout = self.config.GetFloat('inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool('random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool('random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool('want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool('skip-battle-movies', 0) self.creditCardUpFront = self.config.GetInt('credit-card-up-front', -1) if self.creditCardUpFront == -1: del self.creditCardUpFront else: self.creditCardUpFront = self.creditCardUpFront != 0 self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 1) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 1) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.goonsEnabled = self.config.GetBool('estate-goon', 0) self.restrictTrialers = self.config.GetBool('restrict-trialers', 1) self.roamingTrialers = self.config.GetBool('roaming-trialers', 1) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool('kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) WLEnter = TextProperties() WLEnter.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLDisplay', WLDisplay) tpMgr.setProperties('WLEnter', WLEnter) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None return def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def windowEvent(self, win): OTPBase.OTPBase.windowEvent(self, win) if not config.GetInt('keep-aspect-ratio', 0): return x = max(1, win.getXSize()) y = max(1, win.getYSize()) maxX = base.pipe.getDisplayWidth() maxY = base.pipe.getDisplayHeight() cwp = win.getProperties() originX = 0 originY = 0 if cwp.hasOrigin(): originX = cwp.getXOrigin() originY = cwp.getYOrigin() if originX > maxX: originX = originX - maxX if originY > maxY: oringY = originY - maxY maxX -= originX maxY -= originY if math.fabs(x - self.oldX) > math.fabs(y - self.oldY): newY = x / self.aspectRatio newX = x if newY > maxY: newY = maxY newX = self.aspectRatio * maxY else: newX = self.aspectRatio * y newY = y if newX > maxX: newX = maxX newY = maxX / self.aspectRatio wp = WindowProperties() wp.setSize(newX, newY) base.win.requestProperties(wp) base.cam.node().getLens().setFilmSize(newX, newY) self.oldX = newX self.oldY = newY def setCursorAndIcon(self): tempdir = tempfile.mkdtemp() atexit.register(shutil.rmtree, tempdir) vfs = VirtualFileSystem.getGlobalPtr() searchPath = DSearchPath() if __debug__: searchPath.appendDirectory(Filename('resources/phase_3/etc')) searchPath.appendDirectory(Filename('/phase_3/etc')) for filename in ['toonmono.cur', 'icon.ico']: p3filename = Filename(filename) found = vfs.resolveFilename(p3filename, searchPath) if not found: return # Can't do anything past this point. with open(os.path.join(tempdir, filename), 'wb') as f: f.write(vfs.readFile(p3filename, False)) wp = WindowProperties() wp.setCursorFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'toonmono.cur'))) wp.setIconFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'icon.ico'))) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTUnsorted, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def toggleGui(self): if aspect2d.isHidden(): aspect2d.show() else: aspect2d.hide() def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton(PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode(self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager self.leftCells = [ mm.addGridCell(0.25, -0.6, base.a2dTopLeft), mm.addGridCell(0.25, -1.0, base.a2dTopLeft), mm.addGridCell(0.25, -1.4, base.a2dTopLeft) ] self.bottomCells = [ mm.addGridCell(0.4, 0.2, base.a2dBottomCenter), mm.addGridCell(-0.4, 0.2, base.a2dBottomCenter), mm.addGridCell(-1.0, 0.2, base.a2dBottomCenter), mm.addGridCell(1.0, 0.2, base.a2dBottomCenter) ] self.rightCells = [ mm.addGridCell(-0.25, -0.6, base.a2dTopRight), mm.addGridCell(-0.25, -1.0, base.a2dTopRight), mm.addGridCell(-0.25, -1.4, base.a2dTopRight) ] def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def cleanupDownloadWatcher(self): self.downloadWatcher.cleanup() self.downloadWatcher = None return def startShow(self, cr, launcherServer = None): self.cr = cr base.graphicsEngine.renderFrame() self.downloadWatcher = ToontownDownloadWatcher.ToontownDownloadWatcher(TTLocalizer.LauncherPhaseNames) if launcher.isDownloadComplete(): self.cleanupDownloadWatcher() else: self.acceptOnce('launcherAllPhasesComplete', self.cleanupDownloadWatcher) gameServer = base.config.GetString('game-server', '') if gameServer: self.notify.info('Using game-server from Configrc: %s ' % gameServer) elif launcherServer: gameServer = launcherServer self.notify.info('Using gameServer from launcher: %s ' % gameServer) else: gameServer = 'localhost' serverPort = base.config.GetInt('server-port', 7198) serverList = [] for name in gameServer.split(';'): url = URLSpec(name, 1) if base.config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = base.config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('connect', [serverList]) self.ttAccess = ToontownAccess.ToontownAccess() self.ttAccess.initModuleInfo() def removeGlitchMessage(self): self.ignore('InputState-forward') print 'ignoring InputState-forward' def exitShow(self, errorCode = None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) if errorCode: launcher.setPandaErrorCode(errorCode) else: launcher.setPandaErrorCode(0) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code if os.name == 'nt': exitCode2exitPage = {OTPLauncherGlobals.ExitEnableChat: 'chat', OTPLauncherGlobals.ExitSetParentPassword: '******', OTPLauncherGlobals.ExitPurchase: 'purchase'} if code in exitCode2exitPage: launcher.setRegistry('EXIT_PAGE', exitCode2exitPage[code]) def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if hasattr(self, 'ttAccess'): self.ttAccess.delete() if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.ignore(ToontownGlobals.QuitGameHotKeyOSX) self.ignore(ToontownGlobals.QuitGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.HideGameHotKeyOSX) self.ignore(ToontownGlobals.HideGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyRepeatOSX) self.exitShow() def panda3dRenderError(self): launcher.setPandaErrorCode(14) if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def getShardPopLimits(self): if self.cr.productName == 'JP': return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP_JP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP_JP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP_JP)) elif self.cr.productName in ['BR', 'FR']: return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP_INTL), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP_INTL), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP_INTL)) else: return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP)) def playMusic(self, music, looping = 0, interrupt = 1, volume = None, time = 0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) # OS X Specific Actions def exitOSX(self): self.confirm = TTDialog.TTGlobalDialog(doneEvent='confirmDone', message=TTLocalizer.OptionsPageExitConfirm, style=TTDialog.TwoChoice) self.confirm.show() self.accept('confirmDone', self.handleConfirm) def handleConfirm(self): status = self.confirm.doneStatus self.ignore('confirmDone') self.confirm.cleanup() del self.confirm if status == 'ok': self.userExit() def hideGame(self): # Hacky, I know, but it works hideCommand = """osascript -e 'tell application "System Events" set frontProcess to first process whose frontmost is true set visible of frontProcess to false end tell'""" os.system(hideCommand) def minimizeGame(self): wp = WindowProperties() wp.setMinimized(True) base.win.requestProperties(wp)
class ToonBase(OTPBase.OTPBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): self.display = DisplayOptions() OTPBase.OTPBase.__init__(self) base.enableMusic(self.display.settings.getBool('game', 'music', True)) base.enableSoundEffects( self.display.settings.getBool('game', 'sfx', True)) self.disableShowbaseMouse() self.addCullBins() base.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.textToSpeech = self.display.settings.getBool( 'game', 'textToSpeech', False) self.placeBeforeObjects = config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(ToontownGlobals.DefaultCameraFov / (4.0 / 3.0)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.cam2d.node().setCameraMask(BitMask32.bit(1)) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.snapshotSfx = base.loader.loadSfx( 'phase_4/audio/sfx/Photo_shutter.ogg') self.flashTrack = None self.exitFunc = self.userExit if __builtins__.has_key('launcher') and launcher: launcher.setPandaErrorCode(11) globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) if platform == 'darwin': self.acceptOnce(ToontownGlobals.QuitGameHotKeyOSX, self.exitOSX) self.accept(ToontownGlobals.QuitGameHotKeyRepeatOSX, self.exitOSX) self.acceptOnce(ToontownGlobals.HideGameHotKeyOSX, self.hideGame) self.accept(ToontownGlobals.HideGameHotKeyRepeatOSX, self.hideGame) self.acceptOnce(ToontownGlobals.MinimizeGameHotKeyOSX, self.minimizeGame) self.accept(ToontownGlobals.MinimizeGameHotKeyRepeatOSX, self.minimizeGame) self.accept('f3', self.toggleGui) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.friendMode = self.config.GetBool('switchboard-friends', 0) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.wantNewSpecies = self.config.GetBool('want-new-species', 0) self.inactivityTimeout = self.config.GetFloat( 'inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool( 'random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool( 'random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool( 'want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool( 'skip-battle-movies', 0) self.creditCardUpFront = self.config.GetInt('credit-card-up-front', -1) if self.creditCardUpFront == -1: del self.creditCardUpFront else: self.creditCardUpFront = self.creditCardUpFront != 0 self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.goonsEnabled = self.config.GetBool('estate-goon', 0) self.restrictTrialers = self.config.GetBool('restrict-trialers', 1) self.roamingTrialers = self.config.GetBool('roaming-trialers', 1) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool( 'kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) WLEnter = TextProperties() WLEnter.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLDisplay', WLDisplay) tpMgr.setProperties('WLEnter', WLEnter) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None self.shaderMgr = ShaderManager.ShaderManager() self.sosCheck = False return def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def windowEvent(self, win): OTPBase.OTPBase.windowEvent(self, win) if not config.GetInt('keep-aspect-ratio', 0): return x = max(1, win.getXSize()) y = max(1, win.getYSize()) maxX = base.pipe.getDisplayWidth() maxY = base.pipe.getDisplayHeight() cwp = win.getProperties() originX = 0 originY = 0 if cwp.hasOrigin(): originX = cwp.getXOrigin() originY = cwp.getYOrigin() if originX > maxX: originX = originX - maxX if originY > maxY: oringY = originY - maxY maxX -= originX maxY -= originY if math.fabs(x - self.oldX) > math.fabs(y - self.oldY): newY = x / self.aspectRatio newX = x if newY > maxY: newY = maxY newX = self.aspectRatio * maxY else: newX = self.aspectRatio * y newY = y if newX > maxX: newX = maxX newY = maxX / self.aspectRatio wp = WindowProperties() wp.setSize(newX, newY) base.win.requestProperties(wp) base.cam.node().getLens().setFilmSize(newX, newY) self.oldX = newX self.oldY = newY def setCursorAndIcon(self): tempdir = tempfile.mkdtemp() atexit.register(shutil.rmtree, tempdir) vfs = VirtualFileSystem.getGlobalPtr() searchPath = DSearchPath() searchPath.appendDirectory(Filename('/phase_3/etc')) for filename in ['toonmono.cur', 'icon.ico']: p3filename = Filename(filename) found = vfs.resolveFilename(p3filename, searchPath) if not found: return with open(os.path.join(tempdir, filename), 'wb') as (f): f.write(vfs.readFile(p3filename, False)) wp = WindowProperties() wp.setCursorFilename( Filename.fromOsSpecific(os.path.join(tempdir, 'toonmono.cur'))) wp.setIconFilename( Filename.fromOsSpecific(os.path.join(tempdir, 'icon.ico'))) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTFixed, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def toggleGui(self): if aspect2d.isHidden(): aspect2d.show() else: aspect2d.hide() def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return if self.flashTrack and self.flashTrack.isPlaying(): self.flashTrack.finish() self.transitions.noFade() coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() self.transitions.setFadeColor(1, 1, 1) self.flashTrack = Sequence( Func(base.playSfx, self.snapshotSfx), Func(self.transitions.fadeOut, 0.15), Wait(0.2), Func(self.transitions.fadeIn, 0.8), Wait(1.0), Func(self.transitions.setFadeColor, 0, 0, 0)) self.flashTrack.start() if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) exclaim3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_exclaim_cutout')) speech2d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_noarrow')) if config.GetBool('want-retro-mode', False): rtex = loader.loadTexture( 'phase_3/maps/avatar_palette_1llla_1_retro.jpg') speech3d.model.setTexture(rtex, 1) thought3d.model.setTexture(rtex, 1) speech2d.model.setTexture(rtex, 1) exclaim3d.model.setTexture( loader.loadTexture('phase_3/maps/spikey_bubble_retro.jpg'), 1) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setExclaimBalloon3d(exclaim3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setExclaimBalloon2d(speech2d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton( PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode( self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager padding = 0.0225 self.leftCells = [ mm.addGridCell(0.2 + padding, -0.45, base.a2dTopLeft), mm.addGridCell(0.2 + padding, -0.9, base.a2dTopLeft), mm.addGridCell(0.2 + padding, -1.35, base.a2dTopLeft) ] self.bottomCells = [ mm.addGridCell(-0.87, 0.2 + padding, base.a2dBottomCenter), mm.addGridCell(-0.43, 0.2 + padding, base.a2dBottomCenter), mm.addGridCell(0.01, 0.2 + padding, base.a2dBottomCenter), mm.addGridCell(0.45, 0.2 + padding, base.a2dBottomCenter), mm.addGridCell(0.89, 0.2 + padding, base.a2dBottomCenter) ] self.rightCells = [ mm.addGridCell(-0.2 - padding, -1.35, base.a2dTopRight), mm.addGridCell(-0.2 - padding, -0.9, base.a2dTopRight), mm.addGridCell(-0.2 - padding, -0.45, base.a2dTopRight) ] def hideFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], False) def showFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], True) def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def cleanupDownloadWatcher(self): self.downloadWatcher.cleanup() self.downloadWatcher = None return def startShow(self, cr, launcherServer=None): self.cr = cr if self.display.antialias: render.setAntialias(AntialiasAttrib.MAuto) base.graphicsEngine.renderFrame() self.downloadWatcher = ToontownDownloadWatcher.ToontownDownloadWatcher( TTLocalizer.LauncherPhaseNames) if launcher.isDownloadComplete(): self.cleanupDownloadWatcher() else: self.acceptOnce('launcherAllPhasesComplete', self.cleanupDownloadWatcher) gameServer = config.GetString('game-server', '') if gameServer: self.notify.info('Using game-server from Configrc: %s ' % gameServer) else: if launcherServer: gameServer = launcherServer self.notify.info('Using gameServer from launcher: %s ' % gameServer) else: gameServer = '127.0.0.1' serverPort = config.GetInt('server-port', 7198) serverList = [] for name in gameServer.split(';'): url = URLSpec(name, 1) if config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) else: if url != serverURL: serverList.append(url) cr.loginFSM.request('connect', [serverList]) self.ttAccess = ToontownAccess.ToontownAccess() self.ttAccess.initModuleInfo() if config.GetBool('want-speedhack-fix', False): self.lastSpeedhackCheck = time.time() taskMgr.doMethodLater(config.GetFloat('speedhack-interval', 10.0), self.__speedhackCheckTick, 'speedhack-tick') def __speedhackCheckTick(self, task): elapsed = time.time() - self.lastSpeedhackCheck if elapsed < config.GetFloat('speedhack-interval', 10.0) - 1: self.__killSpeedHacker() return task.done self.lastSpeedhackCheck = time.time() return task.again def __killSpeedHacker(self): self.cr.bootedIndex = 128 self.cr.bootedText = 'Toon tripped speed-hack check.' self.cr.stopReaderPollTask() self.cr.lostConnection() def removeGlitchMessage(self): self.ignore('InputState-forward') print 'ignoring InputState-forward' def exitShow(self, errorCode=None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) if errorCode: launcher.setPandaErrorCode(errorCode) else: launcher.setPandaErrorCode(0) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code if os.name == 'nt': exitCode2exitPage = { OTPLauncherGlobals.ExitEnableChat: 'chat', OTPLauncherGlobals.ExitSetParentPassword: '******', OTPLauncherGlobals.ExitPurchase: 'purchase' } if code in exitCode2exitPage: launcher.setRegistry('EXIT_PAGE', exitCode2exitPage[code]) def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass else: if hasattr(self, 'ttAccess'): self.ttAccess.delete() if self.cr.timeManager: self.cr.timeManager.setDisconnectReason( ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.ignore(ToontownGlobals.QuitGameHotKeyOSX) self.ignore(ToontownGlobals.QuitGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.HideGameHotKeyOSX) self.ignore(ToontownGlobals.HideGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyRepeatOSX) self.exitShow() def panda3dRenderError(self): launcher.setPandaErrorCode(14) if self.cr.timeManager: self.cr.timeManager.setDisconnectReason( ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def getShardPopLimits(self): return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP)) def playMusic(self, music, looping=0, interrupt=1, volume=None, time=0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) def exitOSX(self): self.confirm = TTDialog.TTGlobalDialog( doneEvent='confirmDone', message=TTLocalizer.OptionsPageExitConfirm, style=TTDialog.TwoChoice) self.confirm.show() self.accept('confirmDone', self.handleConfirm) def handleConfirm(self): status = self.confirm.doneStatus self.ignore('confirmDone') self.confirm.cleanup() del self.confirm if status == 'ok': self.userExit() def hideGame(self): hideCommand = 'osascript -e \'tell application "System Events"\n set frontProcess to first process whose frontmost is true\n set visible of frontProcess to false\n end tell\'' os.system(hideCommand) def minimizeGame(self): wp = WindowProperties() wp.setMinimized(True) base.win.requestProperties(wp)
class ToonBase(OTPBase.OTPBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): self.display = DisplayOptions() OTPBase.OTPBase.__init__(self) base.enableMusic(self.display.settings.getBool('game', 'music', True)) base.enableSoundEffects(self.display.settings.getBool('game', 'sfx', True)) self.disableShowbaseMouse() self.addCullBins() base.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(ToontownGlobals.DefaultCameraFov/(4./3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.cam2d.node().setCameraMask(BitMask32.bit(1)) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.snapshotSfx = base.loadSfx('phase_4/audio/sfx/Photo_shutter.ogg') self.flashTrack = None self.exitFunc = self.userExit if __builtins__.has_key('launcher') and launcher: launcher.setPandaErrorCode(11) globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) # OS X Specific Actions if platform == "darwin": self.acceptOnce(ToontownGlobals.QuitGameHotKeyOSX, self.exitOSX) self.accept(ToontownGlobals.QuitGameHotKeyRepeatOSX, self.exitOSX) self.acceptOnce(ToontownGlobals.HideGameHotKeyOSX, self.hideGame) self.accept(ToontownGlobals.HideGameHotKeyRepeatOSX, self.hideGame) self.acceptOnce(ToontownGlobals.MinimizeGameHotKeyOSX, self.minimizeGame) self.accept(ToontownGlobals.MinimizeGameHotKeyRepeatOSX, self.minimizeGame) self.accept('f3', self.toggleGui) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.friendMode = self.config.GetBool('switchboard-friends', 0) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.wantNewSpecies = self.config.GetBool('want-new-species', 0) self.inactivityTimeout = self.config.GetFloat('inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool('random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool('random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool('want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool('skip-battle-movies', 0) self.creditCardUpFront = self.config.GetInt('credit-card-up-front', -1) if self.creditCardUpFront == -1: del self.creditCardUpFront else: self.creditCardUpFront = self.creditCardUpFront != 0 self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.goonsEnabled = self.config.GetBool('estate-goon', 0) self.restrictTrialers = self.config.GetBool('restrict-trialers', 1) self.roamingTrialers = self.config.GetBool('roaming-trialers', 1) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool('kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) WLEnter = TextProperties() WLEnter.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLDisplay', WLDisplay) tpMgr.setProperties('WLEnter', WLEnter) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None return def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def windowEvent(self, win): OTPBase.OTPBase.windowEvent(self, win) if not config.GetInt('keep-aspect-ratio', 0): return x = max(1, win.getXSize()) y = max(1, win.getYSize()) maxX = base.pipe.getDisplayWidth() maxY = base.pipe.getDisplayHeight() cwp = win.getProperties() originX = 0 originY = 0 if cwp.hasOrigin(): originX = cwp.getXOrigin() originY = cwp.getYOrigin() if originX > maxX: originX = originX - maxX if originY > maxY: oringY = originY - maxY maxX -= originX maxY -= originY if math.fabs(x - self.oldX) > math.fabs(y - self.oldY): newY = x / self.aspectRatio newX = x if newY > maxY: newY = maxY newX = self.aspectRatio * maxY else: newX = self.aspectRatio * y newY = y if newX > maxX: newX = maxX newY = maxX / self.aspectRatio wp = WindowProperties() wp.setSize(newX, newY) base.win.requestProperties(wp) base.cam.node().getLens().setFilmSize(newX, newY) self.oldX = newX self.oldY = newY def setCursorAndIcon(self): tempdir = tempfile.mkdtemp() atexit.register(shutil.rmtree, tempdir) vfs = VirtualFileSystem.getGlobalPtr() searchPath = DSearchPath() searchPath.appendDirectory(Filename('/phase_3/etc')) for filename in ['toonmono.cur', 'icon.ico']: p3filename = Filename(filename) found = vfs.resolveFilename(p3filename, searchPath) if not found: return # Can't do anything past this point. with open(os.path.join(tempdir, filename), 'wb') as f: f.write(vfs.readFile(p3filename, False)) wp = WindowProperties() wp.setCursorFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'toonmono.cur'))) wp.setIconFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'icon.ico'))) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTFixed, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def toggleGui(self): if aspect2d.isHidden(): aspect2d.show() else: aspect2d.hide() def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return if self.flashTrack and self.flashTrack.isPlaying(): self.flashTrack.finish() self.transitions.noFade() coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() self.transitions.setFadeColor(1, 1, 1) self.flashTrack = Sequence( Func(base.playSfx, self.snapshotSfx), Func(self.transitions.fadeOut, 0.15), Wait(0.2), Func(self.transitions.fadeIn, 0.8), Wait(1.0), Func(self.transitions.setFadeColor, 0, 0, 0) ) self.flashTrack.start() if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton(PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode(self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager # TODO: Dynamicaly add more and reposition cells padding = 0.0225 # Order: Top to bottom self.leftCells = [ mm.addGridCell(0.2 + padding, -0.45, base.a2dTopLeft), # Above boarding groups mm.addGridCell(0.2 + padding, -0.9, base.a2dTopLeft), # 1 mm.addGridCell(0.2 + padding, -1.35, base.a2dTopLeft) # Below Boarding Groups ] # Order: Left to right self.bottomCells = [ mm.addGridCell(-0.87, 0.2 + padding, base.a2dBottomCenter), # To the right of the laff meter mm.addGridCell(-0.43, 0.2 + padding, base.a2dBottomCenter), # 1 mm.addGridCell(0.01, 0.2 + padding, base.a2dBottomCenter), # 2 mm.addGridCell(0.45, 0.2 + padding, base.a2dBottomCenter), # 3 mm.addGridCell(0.89, 0.2 + padding, base.a2dBottomCenter) # To the left of the shtiker book ] # Order: Bottom to top self.rightCells = [ mm.addGridCell(-0.2 - padding, -1.35, base.a2dTopRight), # Above the street map mm.addGridCell(-0.2 - padding, -0.9, base.a2dTopRight), # Below the friends list mm.addGridCell(-0.2 - padding, -0.45, base.a2dTopRight) # Behind the friends list ] def hideFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], False) def showFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], True) def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def cleanupDownloadWatcher(self): self.downloadWatcher.cleanup() self.downloadWatcher = None return def startShow(self, cr, launcherServer = None): self.cr = cr if self.display.antialias: render.setAntialias(AntialiasAttrib.MAuto) base.graphicsEngine.renderFrame() self.downloadWatcher = ToontownDownloadWatcher.ToontownDownloadWatcher(TTLocalizer.LauncherPhaseNames) if launcher.isDownloadComplete(): self.cleanupDownloadWatcher() else: self.acceptOnce('launcherAllPhasesComplete', self.cleanupDownloadWatcher) gameServer = config.GetString('game-server', '') if gameServer: self.notify.info('Using game-server from Configrc: %s ' % gameServer) elif launcherServer: gameServer = launcherServer self.notify.info('Using gameServer from launcher: %s ' % gameServer) else: gameServer = 'localhost' serverPort = config.GetInt('server-port', 7198) serverList = [] for name in gameServer.split(';'): url = URLSpec(name, 1) if config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('connect', [serverList]) self.ttAccess = ToontownAccess.ToontownAccess() self.ttAccess.initModuleInfo() if config.GetBool('want-speedhack-fix', False): # Start checking for speedhacks. self.lastSpeedhackCheck = time.time() taskMgr.doMethodLater(config.GetFloat('speedhack-interval', 10.0), self.__speedhackCheckTick, 'speedhack-tick') def __speedhackCheckTick(self, task): # Check if the time elapsed is less than interval-1 (1 second extra just in case) elapsed = time.time() - self.lastSpeedhackCheck if elapsed < config.GetFloat('speedhack-interval', 10.0) - 1: # They responded too fast. This indicates that the TaskManager is running faster # than normal, and possibly means they sped the process up. self.__killSpeedHacker() return task.done # Clean! Lets wait until the next iteration... self.lastSpeedhackCheck = time.time() return task.again def __killSpeedHacker(self): # go f**k yo' self and yo' cheat engine, f**k'r. self.cr.bootedIndex = 128 self.cr.bootedText = 'SERVER CONNECTION FAILURE. CLIENT HAS EXCEEDED RATE-LIMIT.' self.cr.stopReaderPollTask() self.cr.lostConnection() def removeGlitchMessage(self): self.ignore('InputState-forward') print 'ignoring InputState-forward' def exitShow(self, errorCode = None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) if errorCode: launcher.setPandaErrorCode(errorCode) else: launcher.setPandaErrorCode(0) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code if os.name == 'nt': exitCode2exitPage = {OTPLauncherGlobals.ExitEnableChat: 'chat', OTPLauncherGlobals.ExitSetParentPassword: '******', OTPLauncherGlobals.ExitPurchase: 'purchase'} if code in exitCode2exitPage: launcher.setRegistry('EXIT_PAGE', exitCode2exitPage[code]) def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if hasattr(self, 'ttAccess'): self.ttAccess.delete() if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.ignore(ToontownGlobals.QuitGameHotKeyOSX) self.ignore(ToontownGlobals.QuitGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.HideGameHotKeyOSX) self.ignore(ToontownGlobals.HideGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyRepeatOSX) self.exitShow() def panda3dRenderError(self): launcher.setPandaErrorCode(14) if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def getShardPopLimits(self): return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP)) def playMusic(self, music, looping = 0, interrupt = 1, volume = None, time = 0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) # OS X Specific Actions def exitOSX(self): self.confirm = TTDialog.TTGlobalDialog(doneEvent='confirmDone', message=TTLocalizer.OptionsPageExitConfirm, style=TTDialog.TwoChoice) self.confirm.show() self.accept('confirmDone', self.handleConfirm) def handleConfirm(self): status = self.confirm.doneStatus self.ignore('confirmDone') self.confirm.cleanup() del self.confirm if status == 'ok': self.userExit() def hideGame(self): # Hacky, I know, but it works hideCommand = """osascript -e 'tell application "System Events" set frontProcess to first process whose frontmost is true set visible of frontProcess to false end tell'""" os.system(hideCommand) def minimizeGame(self): wp = WindowProperties() wp.setMinimized(True) base.win.requestProperties(wp)
class ToonBase(OTPBase.OTPBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): OTPBase.OTPBase.__init__(self) self.disableShowbaseMouse() self.addCullBins() self.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.baseXpMultiplier = self.config.GetFloat('base-xp-multiplier', 1.0) self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = self.config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(settings['fov']/(4./3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.exitFunc = self.userExit globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) # OS X Specific Actions if platform == "darwin": self.acceptOnce(ToontownGlobals.QuitGameHotKeyOSX, self.exitOSX) self.accept(ToontownGlobals.QuitGameHotKeyRepeatOSX, self.exitOSX) self.acceptOnce(ToontownGlobals.HideGameHotKeyOSX, self.hideGame) self.accept(ToontownGlobals.HideGameHotKeyRepeatOSX, self.hideGame) self.acceptOnce(ToontownGlobals.MinimizeGameHotKeyOSX, self.minimizeGame) self.accept(ToontownGlobals.MinimizeGameHotKeyRepeatOSX, self.minimizeGame) self.accept('f3', self.toggleGui) self.accept('f4', self.oobe) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.inactivityTimeout = self.config.GetFloat('inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool('random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool('random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool('want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool('skip-battle-movies', 0) self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool('kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) tpMgr.setProperties('WLDisplay', WLDisplay) WLRed = tpMgr.getProperties('red') WLRed.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLRed', WLRed) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None self.filters = CommonFilters(self.win, self.cam) self.wantCogInterface = settings.get('cogInterface', True) self.wantWASD = settings.get('want-WASD', False) self.wantNews = settings.get('want-News', True) self.Move_Up = 'arrow_up' self.Move_Left = 'arrow_left' self.Move_Down = 'arrow_down' self.Move_Right = 'arrow_right' self.JUMP = 'control' if self.wantWASD: self.Move_Up = 'w' self.Move_Left = 'a' self.Move_Down = 's' self.Move_Right = 'd' self.JUMP = 'shift' def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def setCursorAndIcon(self): atexit.register(shutil.rmtree, tempdir) wp = WindowProperties() wp.setCursorFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'toonmono.cur'))) wp.setIconFilename(Filename.fromOsSpecific(os.path.join(tempdir, 'icon.ico'))) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTUnsorted, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def toggleGui(self): if aspect2d.isHidden(): aspect2d.show() else: aspect2d.hide() def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() self.snapshotSfx = base.loadSfx('phase_4/audio/sfx/Photo_shutter.ogg') base.playSfx(self.snapshotSfx) if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton(PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode(self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager # TODO: Dynamicaly add more and reposition cells padding = 0.0225 # Order: Top to bottom self.leftCells = [ mm.addGridCell(0.2 + padding, -0.45, base.a2dTopLeft), # Above boarding groups mm.addGridCell(0.2 + padding, -0.9, base.a2dTopLeft), # 1 mm.addGridCell(0.2 + padding, -1.35, base.a2dTopLeft) # Below Boarding Groups ] # Order: Left to right self.bottomCells = [ mm.addGridCell(-0.87, 0.2 + padding, base.a2dBottomCenter), # To the right of the laff meter mm.addGridCell(-0.43, 0.2 + padding, base.a2dBottomCenter), # 1 mm.addGridCell(0.01, 0.2 + padding, base.a2dBottomCenter), # 2 mm.addGridCell(0.45, 0.2 + padding, base.a2dBottomCenter), # 3 mm.addGridCell(0.89, 0.2 + padding, base.a2dBottomCenter) # To the left of the shtiker book ] # Order: Bottom to top self.rightCells = [ mm.addGridCell(-0.2 - padding, -1.35, base.a2dTopRight), # Above the street map mm.addGridCell(-0.2 - padding, -0.9, base.a2dTopRight), # Below the friends list mm.addGridCell(-0.2 - padding, -0.45, base.a2dTopRight) # Behind the friends list ] def hideFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], False) def showFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], True) def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def startShow(self, cr): self.cr = cr base.graphicsEngine.renderFrame() # Get the base port. serverPort = base.config.GetInt('server-port', 7199) # Get the number of client-agents. clientagents = base.config.GetInt('client-agents', 1) - 1 # Get a new port. serverPort += (random.randint(0, clientagents) * 100) serverList = [] for name in launcher.getGameServer().split(';'): url = URLSpec(name, 1) if base.config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = base.config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('connect', [serverList]) # Start detecting speed hacks: self.lastSpeedHackCheck = time.time() self.lastTrueClockTime = TrueClock.getGlobalPtr().getLongTime() taskMgr.add(self.__speedHackCheckTick, 'speedHackCheck-tick') def __speedHackCheckTick(self, task): elapsed = time.time() - self.lastSpeedHackCheck tcElapsed = TrueClock.getGlobalPtr().getLongTime() - self.lastTrueClockTime if tcElapsed > (elapsed + 0.05): # The TrueClock is running faster than it should. This means the # player may have sped up the process. Disconnect them: self.cr.stopReaderPollTask() self.cr.lostConnection() return task.done self.lastSpeedHackCheck = time.time() self.lastTrueClockTime = TrueClock.getGlobalPtr().getLongTime() return task.cont def removeGlitchMessage(self): self.ignore('InputState-forward') def exitShow(self, errorCode = None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.ignore(ToontownGlobals.QuitGameHotKeyOSX) self.ignore(ToontownGlobals.QuitGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.HideGameHotKeyOSX) self.ignore(ToontownGlobals.HideGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyRepeatOSX) self.exitShow() def panda3dRenderError(self): if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def playMusic(self, music, looping = 0, interrupt = 1, volume = None, time = 0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) # OS X Specific Actions def exitOSX(self): self.confirm = TTDialog.TTGlobalDialog(doneEvent='confirmDone', message=TTLocalizer.OptionsPageExitConfirm, style=TTDialog.TwoChoice) self.confirm.show() self.accept('confirmDone', self.handleConfirm) def handleConfirm(self): status = self.confirm.doneStatus self.ignore('confirmDone') self.confirm.cleanup() del self.confirm if status == 'ok': self.userExit() def hideGame(self): # Hacky, I know, but it works hideCommand = """osascript -e 'tell application "System Events" set frontProcess to first process whose frontmost is true set visible of frontProcess to false end tell'""" os.system(hideCommand) def minimizeGame(self): wp = WindowProperties() wp.setMinimized(True) base.win.requestProperties(wp)
class ToonBase(OTPBase.OTPBase, FNAFBase.FNAFBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): OTPBase.OTPBase.__init__(self) FNAFBase.FNAFBase.__init__(self, True) self.disableShowbaseMouse() self.addCullBins() base.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(ToontownGlobals.DefaultCameraFov / (4. / 3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.exitFunc = self.userExit if __builtins__.has_key('launcher') and launcher: launcher.setPandaErrorCode(11) globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.friendMode = self.config.GetBool('switchboard-friends', 0) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.wantNewSpecies = self.config.GetBool('want-new-species', 0) self.inactivityTimeout = self.config.GetFloat( 'inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool( 'random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool( 'random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool( 'want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool( 'skip-battle-movies', 0) self.creditCardUpFront = self.config.GetInt('credit-card-up-front', -1) if self.creditCardUpFront == -1: del self.creditCardUpFront else: self.creditCardUpFront = self.creditCardUpFront != 0 self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.goonsEnabled = self.config.GetBool('estate-goon', 0) self.restrictTrialers = self.config.GetBool('restrict-trialers', 1) self.roamingTrialers = self.config.GetBool('roaming-trialers', 1) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool( 'kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) WLEnter = TextProperties() WLEnter.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLDisplay', WLDisplay) tpMgr.setProperties('WLEnter', WLEnter) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None return def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def loadSettings(self): Settings.load() self.enableMusic(Settings.getEnableMusic()) self.enableSoundEffects(Settings.getEnableSFX()) self.toonChatSounds = Settings.getEnableChatSound() def windowEvent(self, win): OTPBase.OTPBase.windowEvent(self, win) if not config.GetInt('keep-aspect-ratio', 0): return x = max(1, win.getXSize()) y = max(1, win.getYSize()) maxX = base.pipe.getDisplayWidth() maxY = base.pipe.getDisplayHeight() cwp = win.getProperties() originX = 0 originY = 0 if cwp.hasOrigin(): originX = cwp.getXOrigin() originY = cwp.getYOrigin() if originX > maxX: originX = originX - maxX if originY > maxY: oringY = originY - maxY maxX -= originX maxY -= originY if math.fabs(x - self.oldX) > math.fabs(y - self.oldY): newY = x / self.aspectRatio newX = x if newY > maxY: newY = maxY newX = self.aspectRatio * maxY else: newX = self.aspectRatio * y newY = y if newX > maxX: newX = maxX newY = maxX / self.aspectRatio wp = WindowProperties() wp.setSize(newX, newY) base.win.requestProperties(wp) base.cam.node().getLens().setFilmSize(newX, newY) self.oldX = newX self.oldY = newY def setCursorAndIcon(self): wp = WindowProperties() cursor = os.path.join(os.path.abspath(os.curdir), 'toonmono.cur') cursor = Filename.fromOsSpecific(cursor) cursor.setBinary() wp.setCursorFilename(cursor) icon = os.path.join(os.path.abspath(os.curdir), 'icon.ico') icon = Filename.fromOsSpecific(icon) icon.setBinary() wp.setIconFilename(icon) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTUnsorted, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() #elf.transitions.fadeScreenColor(1) #self.transitions.setFadeColor(1, 1, 1) #self.transitions.fadeIn(0.8) self.snapshotSfx = base.loadSfx('phase_4/audio/sfx/Photo_shutter.ogg') base.playSfx(self.snapshotSfx) if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton( PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode( self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager self.leftCells = [ mm.addGridCell(0, 1, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(0, 2, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(0, 3, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop) ] self.bottomCells = [ mm.addGridCell(0.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(1.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(2.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(3.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(4.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop) ] self.rightCells = [ mm.addGridCell(5, 2, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(5, 1, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop) ] def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def cleanupDownloadWatcher(self): self.downloadWatcher.cleanup() self.downloadWatcher = None return def startShow(self, cr, launcherServer=None): self.cr = cr base.graphicsEngine.renderFrame() self.downloadWatcher = ToontownDownloadWatcher.ToontownDownloadWatcher( TTLocalizer.LauncherPhaseNames) if launcher.isDownloadComplete(): self.cleanupDownloadWatcher() else: self.acceptOnce('launcherAllPhasesComplete', self.cleanupDownloadWatcher) gameServer = base.config.GetString('game-server', '127.0.0.1') if gameServer: self.notify.info('Using game-server from Configrc: %s ' % gameServer) elif launcherServer: gameServer = launcherServer self.notify.info('Using gameServer from launcher: %s ' % gameServer) else: gameServer = base.config.GetString('game-server') serverPort = base.config.GetInt('server-port', 7198) serverList = [] for name in gameServer.split(';'): url = URLSpec(name, 1) if base.config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = base.config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('launcher', [serverList]) self.ttAccess = ToontownAccess.ToontownAccess() self.ttAccess.initModuleInfo() def removeGlitchMessage(self): self.ignore('InputState-forward') def exitShow(self, errorCode=None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) if errorCode: launcher.setPandaErrorCode(errorCode) else: launcher.setPandaErrorCode(0) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code if os.name == 'nt': exitCode2exitPage = { OTPLauncherGlobals.ExitEnableChat: 'chat', OTPLauncherGlobals.ExitSetParentPassword: '******', OTPLauncherGlobals.ExitPurchase: 'purchase' } if code in exitCode2exitPage: launcher.setRegistry('EXIT_PAGE', exitCode2exitPage[code]) def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if hasattr(self, 'ttAccess'): self.ttAccess.delete() if self.cr.timeManager: self.cr.timeManager.setDisconnectReason( ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.exitShow() def panda3dRenderError(self): launcher.setPandaErrorCode(14) if self.cr.timeManager: self.cr.timeManager.setDisconnectReason( ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def getShardPopLimits(self): if self.cr.productName == 'JP': return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP_JP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP_JP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP_JP)) elif self.cr.productName in ['BR', 'FR']: return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP_INTL), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP_INTL), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP_INTL)) else: return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP)) def playMusic(self, music, looping=0, interrupt=1, volume=None, time=0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) def __DISABLED__adjustWindowAspectRatio(self, aspectRatio): # Moved from ShowBase.py # This will NOT change 3D aspect ratio # Experimental if self._ShowBase__configAspectRatio: aspectRatio = self._ShowBase__configAspectRatio if aspectRatio != self._ShowBase__oldAspectRatio: self._ShowBase__oldAspectRatio = aspectRatio # Fix up some anything that depends on the aspectRatio if aspectRatio < 1: # If the window is TALL, lets expand the top and bottom self.aspect2d.setScale(1.0, aspectRatio, aspectRatio) self.a2dTop = 1.0 / aspectRatio self.a2dBottom = -1.0 / aspectRatio self.a2dLeft = -1 self.a2dRight = 1.0 # Don't forget 2dp self.aspect2dp.setScale(1.0, aspectRatio, aspectRatio) self.a2dpTop = 1.0 / aspectRatio self.a2dpBottom = -1.0 / aspectRatio self.a2dpLeft = -1 self.a2dpRight = 1.0 else: # If the window is WIDE, lets expand the left and right self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0) self.a2dTop = 1.0 self.a2dBottom = -1.0 self.a2dLeft = -aspectRatio self.a2dRight = aspectRatio # Don't forget 2dp self.aspect2dp.setScale(1.0 / aspectRatio, 1.0, 1.0) self.a2dpTop = 1.0 self.a2dpBottom = -1.0 self.a2dpLeft = -aspectRatio self.a2dpRight = aspectRatio # Reposition the aspect2d marker nodes self.a2dTopCenter.setPos(0, self.a2dTop, self.a2dTop) self.a2dBottomCenter.setPos(0, self.a2dBottom, self.a2dBottom) self.a2dLeftCenter.setPos(self.a2dLeft, 0, 0) self.a2dRightCenter.setPos(self.a2dRight, 0, 0) self.a2dTopLeft.setPos(self.a2dLeft, self.a2dTop, self.a2dTop) self.a2dTopRight.setPos(self.a2dRight, self.a2dTop, self.a2dTop) self.a2dBottomLeft.setPos(self.a2dLeft, self.a2dBottom, self.a2dBottom) self.a2dBottomRight.setPos(self.a2dRight, self.a2dBottom, self.a2dBottom) # Reposition the aspect2d marker nodes self.a2dTopCenterNs.setPos(0, self.a2dTop, self.a2dTop) self.a2dBottomCenterNs.setPos(0, self.a2dBottom, self.a2dBottom) self.a2dLeftCenterNs.setPos(self.a2dLeft, 0, 0) self.a2dRightCenterNs.setPos(self.a2dRight, 0, 0) self.a2dTopLeftNs.setPos(self.a2dLeft, self.a2dTop, self.a2dTop) self.a2dTopRightNs.setPos(self.a2dRight, self.a2dTop, self.a2dTop) self.a2dBottomLeftNs.setPos(self.a2dLeft, self.a2dBottom, self.a2dBottom) self.a2dBottomRightNs.setPos(self.a2dRight, self.a2dBottom, self.a2dBottom) # Reposition the aspect2dp marker nodes self.a2dpTopCenter.setPos(0, self.a2dpTop, self.a2dpTop) self.a2dpBottomCenter.setPos(0, self.a2dpBottom, self.a2dpBottom) self.a2dpLeftCenter.setPos(self.a2dpLeft, 0, 0) self.a2dpRightCenter.setPos(self.a2dpRight, 0, 0) self.a2dpTopLeft.setPos(self.a2dpLeft, self.a2dpTop, self.a2dpTop) self.a2dpTopRight.setPos(self.a2dpRight, self.a2dpTop, self.a2dpTop) self.a2dpBottomLeft.setPos(self.a2dpLeft, self.a2dpBottom, self.a2dpBottom) self.a2dpBottomRight.setPos(self.a2dpRight, self.a2dpBottom, self.a2dpBottom) # If anybody needs to update their GUI, put a callback on this event messenger.send("aspectRatioChanged")
class ToonBase(OTPBase.OTPBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): OTPBase.OTPBase.__init__(self) self.disableShowbaseMouse() self.addCullBins() base.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(settings['fieldofview'] / (4. / 3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.cam2d.node().setCameraMask(BitMask32.bit(1)) self.musicManager.setVolume(settings.get("musicVol")) for sfm in self.sfxManagerList: sfm.setVolume(settings.get("sfxVol")) self.sfxActive = settings.get("sfxVol") > 0.0 self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.snapshotSfx = base.loadSfx('phase_4/audio/sfx/Photo_shutter.ogg') self.flashTrack = None self.exitFunc = self.userExit if __builtins__.has_key('launcher') and launcher: launcher.setPandaErrorCode(11) globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() # OS X Specific Actions if platform == "darwin": self.acceptOnce(ToontownGlobals.QuitGameHotKeyOSX, self.exitOSX) self.accept(ToontownGlobals.QuitGameHotKeyRepeatOSX, self.exitOSX) self.acceptOnce(ToontownGlobals.HideGameHotKeyOSX, self.hideGame) self.accept(ToontownGlobals.HideGameHotKeyRepeatOSX, self.hideGame) self.acceptOnce(ToontownGlobals.MinimizeGameHotKeyOSX, self.minimizeGame) self.accept(ToontownGlobals.MinimizeGameHotKeyRepeatOSX, self.minimizeGame) self.accept('f3', self.toggleGui) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader self.asyncLoader = ToontownAsyncLoader.ToontownAsyncLoader(self) __builtins__['asyncloader'] = self.asyncLoader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.friendMode = self.config.GetBool('switchboard-friends', 0) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.wantNewSpecies = self.config.GetBool('want-new-species', 0) self.inactivityTimeout = self.config.GetFloat( 'inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool( 'random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool( 'random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool( 'want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool( 'skip-battle-movies', 0) self.creditCardUpFront = self.config.GetInt('credit-card-up-front', -1) if self.creditCardUpFront == -1: del self.creditCardUpFront else: self.creditCardUpFront = self.creditCardUpFront != 0 self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.goonsEnabled = self.config.GetBool('estate-goon', 0) self.restrictTrialers = self.config.GetBool('restrict-trialers', 1) self.roamingTrialers = self.config.GetBool('roaming-trialers', 1) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool( 'kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) WLEnter = TextProperties() WLEnter.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLDisplay', WLDisplay) tpMgr.setProperties('WLEnter', WLEnter) textShadow = TextProperties() textShadow.setShadow(.01) textShadow.setTextColor(0.8, 0.4, 0.0, 1) tpMgr.setProperties('textShadow', textShadow) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None self.wantCustomControls = settings.get('want-Custom-Controls', False) self.MOVE_UP = 'arrow_up' self.MOVE_DOWN = 'arrow_down' self.MOVE_LEFT = 'arrow_left' self.MOVE_RIGHT = 'arrow_right' self.JUMP = 'control' self.ACTION_BUTTON = 'delete' self.SCREENSHOT_KEY = 'f9' keymap = settings.get('keymap', {}) if self.wantCustomControls: self.MOVE_UP = keymap.get('MOVE_UP', self.MOVE_UP) self.MOVE_DOWN = keymap.get('MOVE_DOWN', self.MOVE_DOWN) self.MOVE_LEFT = keymap.get('MOVE_LEFT', self.MOVE_LEFT) self.MOVE_RIGHT = keymap.get('MOVE_RIGHT', self.MOVE_RIGHT) self.JUMP = keymap.get('JUMP', self.JUMP) self.ACTION_BUTTON = keymap.get('ACTION_BUTTON', self.ACTION_BUTTON) self.SCREENSHOT_KEY = keymap.get('SCREENSHOT_KEY', self.SCREENSHOT_KEY) ToontownGlobals.OptionsPageHotkey = keymap.get( 'OPTIONS-PAGE', ToontownGlobals.OptionsPageHotkey) self.CHAT_HOTKEY = keymap.get('CHAT_HOTKEY', 'r') self.accept( self.SCREENSHOT_KEY, self.takeScreenShot ) # TODO: Make the game ignore this and then re-accept it on a new key if it is rebinded self.Widescreen = settings.get('Widescreen', 0) self.currentScale = settings.get('texture-scale', 1.0) self.setTextureScale() self.setRatio() self.showDisclaimer = settings.get( 'show-disclaimer', True ) # Show this the first time the user starts the game, it is set in the settings to False once they pick a toon self.lodMaxRange = 750 self.lodMinRange = 5 self.lodDelayFactor = 0.4 # enable this feature, if you have render pipeline installed if config.GetBool('want-pipeline-renderer', False): from rpcore import RenderPipeline, SpotLight self.loadPipeline() def loadPipeline(self): self._pipelineEngine = RenderPipeline() self._pipelineEngine.create(self) # set the time of day for the daytime cycle self._pipelineEngine.daytime_mgr.time = '1:00' def updateAspectRatio(self): fadeSequence = Sequence(Func(base.transitions.fadeOut, .2), Wait(.2), Func(self.setRatio), Func(base.transitions.fadeIn, .2)).start() def setRatio(self): # Set the aspect ratio print(GraphicsOptions.AspectRatios[self.Widescreen]) base.setAspectRatio(GraphicsOptions.AspectRatios[self.Widescreen]) def setTextureScale(self): # Set the global texture scale (TODO) scale = settings.get('texture-scale') def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def windowEvent(self, win): OTPBase.OTPBase.windowEvent(self, win) if not config.GetInt('keep-aspect-ratio', 0): return x = max(1, win.getXSize()) y = max(1, win.getYSize()) maxX = base.pipe.getDisplayWidth() maxY = base.pipe.getDisplayHeight() cwp = win.getProperties() originX = 0 originY = 0 if cwp.hasOrigin(): originX = cwp.getXOrigin() originY = cwp.getYOrigin() if originX > maxX: originX = originX - maxX if originY > maxY: oringY = originY - maxY maxX -= originX maxY -= originY if math.fabs(x - self.oldX) > math.fabs(y - self.oldY): newY = x / self.aspectRatio newX = x if newY > maxY: newY = maxY newX = self.aspectRatio * maxY else: newX = self.aspectRatio * y newY = y if newX > maxX: newX = maxX newY = maxX / self.aspectRatio wp = WindowProperties() wp.setSize(newX, newY) base.win.requestProperties(wp) base.cam.node().getLens().setFilmSize(newX, newY) self.oldX = newX self.oldY = newY def setCursorAndIcon(self): tempdir = tempfile.mkdtemp() atexit.register(shutil.rmtree, tempdir) vfs = VirtualFileSystem.getGlobalPtr() searchPath = DSearchPath() searchPath.appendDirectory(Filename('/phase_3/etc')) for filename in ['toonmono.cur', 'icon.ico']: p3filename = Filename(filename) found = vfs.resolveFilename(p3filename, searchPath) if not found: return # Can't do anything past this point. with open(os.path.join(tempdir, filename), 'wb') as f: f.write(vfs.readFile(p3filename, False)) wp = WindowProperties() wp.setCursorFilename( Filename.fromOsSpecific(os.path.join(tempdir, 'toonmono.cur'))) wp.setIconFilename( Filename.fromOsSpecific(os.path.join(tempdir, 'icon.ico'))) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTFixed, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def toggleGui(self): if aspect2d.isHidden(): aspect2d.show() else: aspect2d.hide() def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return if self.flashTrack and self.flashTrack.isPlaying(): self.flashTrack.finish() self.transitions.noFade() coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() self.transitions.setFadeColor(1, 1, 1) self.flashTrack = Sequence( Func(base.playSfx, self.snapshotSfx), Func(self.transitions.fadeOut, 0.15), Wait(0.2), Func(self.transitions.fadeIn, 0.8), Wait(1.0), Func(self.transitions.setFadeColor, 0, 0, 0)) self.flashTrack.start() if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon( loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton( PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode( self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager # TODO: Dynamicaly add more and reposition cells padding = 0.0225 # Order: Top to bottom self.leftCells = [ mm.addGridCell(0.2 + padding, -0.45, base.a2dTopLeft), # Above boarding groups mm.addGridCell(0.2 + padding, -0.9, base.a2dTopLeft), # 1 mm.addGridCell(0.2 + padding, -1.35, base.a2dTopLeft) # Below Boarding Groups ] # Order: Left to right self.bottomCells = [ mm.addGridCell( -0.87, 0.2 + padding, base.a2dBottomCenter), # To the right of the laff meter mm.addGridCell(-0.43, 0.2 + padding, base.a2dBottomCenter), # 1 mm.addGridCell(0.01, 0.2 + padding, base.a2dBottomCenter), # 2 mm.addGridCell(0.45, 0.2 + padding, base.a2dBottomCenter), # 3 mm.addGridCell( 0.89, 0.2 + padding, base.a2dBottomCenter) # To the left of the shtiker book ] # Order: Bottom to top self.rightCells = [ mm.addGridCell(-0.2 - padding, -1.35, base.a2dTopRight), # Above the street map mm.addGridCell(-0.2 - padding, -0.9, base.a2dTopRight), # Below the friends list mm.addGridCell(-0.2 - padding, -0.45, base.a2dTopRight) # Behind the friends list ] def hideFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], False) def showFriendMargins(self): middleCell = self.rightCells[1] topCell = self.rightCells[2] self.setCellsAvailable([middleCell, topCell], True) def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def cleanupDownloadWatcher(self): self.downloadWatcher.cleanup() self.downloadWatcher = None return def startShow(self, cr, launcherServer=None): self.cr = cr base.graphicsEngine.renderFrame() self.downloadWatcher = ToontownDownloadWatcher.ToontownDownloadWatcher( TTLocalizer.LauncherPhaseNames) if launcher.isDownloadComplete(): self.cleanupDownloadWatcher() else: self.acceptOnce('launcherAllPhasesComplete', self.cleanupDownloadWatcher) gameServer = config.GetString('game-server', '') if gameServer: self.notify.info('Using game-server from Configrc: %s ' % gameServer) elif launcherServer: gameServer = launcherServer self.notify.info('Using gameServer from launcher: %s ' % gameServer) else: gameServer = 'gs1.projectaltis.com' serverPort = config.GetInt('server-port', 7198) serverList = [] for name in gameServer.split(';'): url = URLSpec(name, 1) url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('connect', [serverList]) self.ttAccess = ToontownAccess.ToontownAccess() self.ttAccess.initModuleInfo() if config.GetBool('want-speedhack-fix', False): # Start checking for speedhacks. self.lastSpeedhackCheck = time.time() self.trueClock = TrueClock.getGlobalPtr() self.lastTrueClockTime = self.trueClock.getLongTime() taskMgr.add(self.__speedhackCheckTick, 'speedhack-tick') def __speedhackCheckTick(self, task): # Check if the time elapsed is less than interval-1 (1 second extra # just in case) elapsed = time.time() - self.lastSpeedhackCheck tc_elapsed = self.trueClock.getLongTime() - self.lastTrueClockTime if tc_elapsed > elapsed + 1: # They responded too fast. This indicates that the TrueClock is running faster # than normal, and possibly means they sped the process up. self.__killSpeedHacker() return task.done # Clean! Lets wait until the next iteration... self.lastSpeedhackCheck = time.time() self.lastTrueClockTime = self.trueClock.getLongTime() return task.cont def __killSpeedHacker(self): # go f**k yo' self and yo' cheat engine, f**k'r. self.cr.bootedIndex = 128 self.cr.bootedText = 'SERVER CONNECTION FAILURE. CLIENT HAS EXCEEDED RATE-LIMIT.' self.cr.stopReaderPollTask() self.cr.lostConnection() def removeGlitchMessage(self): self.ignore('InputState-forward') print 'ignoring InputState-forward' def exitShow(self, errorCode=None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) if errorCode: launcher.setPandaErrorCode(errorCode) else: launcher.setPandaErrorCode(0) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code if os.name == 'nt': exitCode2exitPage = { OTPLauncherGlobals.ExitEnableChat: 'chat', OTPLauncherGlobals.ExitSetParentPassword: '******', OTPLauncherGlobals.ExitPurchase: 'purchase' } if code in exitCode2exitPage: launcher.setRegistry('EXIT_PAGE', exitCode2exitPage[code]) def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if hasattr(self, 'ttAccess'): self.ttAccess.delete() if self.cr.timeManager: self.cr.timeManager.setDisconnectReason( ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.ignore(ToontownGlobals.QuitGameHotKeyOSX) self.ignore(ToontownGlobals.QuitGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.HideGameHotKeyOSX) self.ignore(ToontownGlobals.HideGameHotKeyRepeatOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyOSX) self.ignore(ToontownGlobals.MinimizeGameHotKeyRepeatOSX) self.exitShow() def panda3dRenderError(self): launcher.setPandaErrorCode(14) if self.cr.timeManager: self.cr.timeManager.setDisconnectReason( ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def getShardPopLimits(self): return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP)) def playMusic(self, music, looping=0, interrupt=1, volume=None, time=0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) # OS X Specific Actions def exitOSX(self): self.confirm = TTDialog.TTGlobalDialog( doneEvent='confirmDone', message=TTLocalizer.OptionsPageExitConfirm, style=TTDialog.TwoChoice) self.confirm.show() self.accept('confirmDone', self.handleConfirm) def handleConfirm(self): status = self.confirm.doneStatus self.ignore('confirmDone') self.confirm.cleanup() del self.confirm if status == 'ok': self.userExit() def hideGame(self): # Hacky, I know, but it works hideCommand = """osascript -e 'tell application "System Events" set frontProcess to first process whose frontmost is true set visible of frontProcess to false end tell'""" os.system(hideCommand) def minimizeGame(self): wp = WindowProperties() wp.setMinimized(True) base.win.requestProperties(wp) def reloadControls(self): keymap = settings.get('keymap', {}) self.CHAT_HOTKEY = keymap.get('CHAT_HOTKEY', 'r') if self.wantCustomControls: self.MOVE_UP = keymap.get('MOVE_UP', self.MOVE_UP) self.MOVE_DOWN = keymap.get('MOVE_DOWN', self.MOVE_DOWN) self.MOVE_LEFT = keymap.get('MOVE_LEFT', self.MOVE_LEFT) self.MOVE_RIGHT = keymap.get('MOVE_RIGHT', self.MOVE_RIGHT) self.JUMP = keymap.get('JUMP', self.JUMP) self.ACTION_BUTTON = keymap.get('ACTION_BUTTON', self.ACTION_BUTTON) ToontownGlobals.OptionsPageHotkey = keymap.get( 'OPTIONS-PAGE', ToontownGlobals.OptionsPageHotkey) else: self.MOVE_UP = 'arrow_up' self.MOVE_DOWN = 'arrow_down' self.MOVE_LEFT = 'arrow_left' self.MOVE_RIGHT = 'arrow_right' self.JUMP = 'control' self.ACTION_BUTTON = 'delete'
class ToonBase(OTPBase.OTPBase, FNAFBase.FNAFBase): notify = DirectNotifyGlobal.directNotify.newCategory('ToonBase') def __init__(self): OTPBase.OTPBase.__init__(self) FNAFBase.FNAFBase.__init__(self, True) self.disableShowbaseMouse() self.addCullBins() base.debugRunningMultiplier /= OTPGlobals.ToonSpeedFactor self.toonChatSounds = self.config.GetBool('toon-chat-sounds', 1) self.placeBeforeObjects = config.GetBool('place-before-objects', 1) self.endlessQuietZone = False self.wantDynamicShadows = 0 self.exitErrorCode = 0 camera.setPosHpr(0, 0, 0, 0, 0, 0) self.camLens.setMinFov(ToontownGlobals.DefaultCameraFov/(4./3.)) self.camLens.setNearFar(ToontownGlobals.DefaultCameraNear, ToontownGlobals.DefaultCameraFar) self.musicManager.setVolume(0.65) self.setBackgroundColor(ToontownGlobals.DefaultBackgroundColor) tpm = TextPropertiesManager.getGlobalPtr() candidateActive = TextProperties() candidateActive.setTextColor(0, 0, 1, 1) tpm.setProperties('candidate_active', candidateActive) candidateInactive = TextProperties() candidateInactive.setTextColor(0.3, 0.3, 0.7, 1) tpm.setProperties('candidate_inactive', candidateInactive) self.transitions.IrisModelName = 'phase_3/models/misc/iris' self.transitions.FadeModelName = 'phase_3/models/misc/fade' self.exitFunc = self.userExit if __builtins__.has_key('launcher') and launcher: launcher.setPandaErrorCode(11) globalClock.setMaxDt(0.2) if self.config.GetBool('want-particles', 1) == 1: self.notify.debug('Enabling particles') self.enableParticles() self.accept(ToontownGlobals.ScreenshotHotkey, self.takeScreenShot) self.accept('panda3d-render-error', self.panda3dRenderError) oldLoader = self.loader self.loader = ToontownLoader.ToontownLoader(self) __builtins__['loader'] = self.loader oldLoader.destroy() self.accept('PandaPaused', self.disableAllAudio) self.accept('PandaRestarted', self.enableAllAudio) self.friendMode = self.config.GetBool('switchboard-friends', 0) self.wantPets = self.config.GetBool('want-pets', 1) self.wantBingo = self.config.GetBool('want-fish-bingo', 1) self.wantKarts = self.config.GetBool('want-karts', 1) self.wantNewSpecies = self.config.GetBool('want-new-species', 0) self.inactivityTimeout = self.config.GetFloat('inactivity-timeout', ToontownGlobals.KeyboardTimeout) if self.inactivityTimeout: self.notify.debug('Enabling Panda timeout: %s' % self.inactivityTimeout) self.mouseWatcherNode.setInactivityTimeout(self.inactivityTimeout) self.mouseWatcherNode.setEnterPattern('mouse-enter-%r') self.mouseWatcherNode.setLeavePattern('mouse-leave-%r') self.mouseWatcherNode.setButtonDownPattern('button-down-%r') self.mouseWatcherNode.setButtonUpPattern('button-up-%r') self.randomMinigameAbort = self.config.GetBool('random-minigame-abort', 0) self.randomMinigameDisconnect = self.config.GetBool('random-minigame-disconnect', 0) self.randomMinigameNetworkPlugPull = self.config.GetBool('random-minigame-netplugpull', 0) self.autoPlayAgain = self.config.GetBool('auto-play-again', 0) self.skipMinigameReward = self.config.GetBool('skip-minigame-reward', 0) self.wantMinigameDifficulty = self.config.GetBool('want-minigame-difficulty', 0) self.minigameDifficulty = self.config.GetFloat('minigame-difficulty', -1.0) if self.minigameDifficulty == -1.0: del self.minigameDifficulty self.minigameSafezoneId = self.config.GetInt('minigame-safezone-id', -1) if self.minigameSafezoneId == -1: del self.minigameSafezoneId cogdoGameSafezoneId = self.config.GetInt('cogdo-game-safezone-id', -1) cogdoGameDifficulty = self.config.GetFloat('cogdo-game-difficulty', -1) if cogdoGameDifficulty != -1: self.cogdoGameDifficulty = cogdoGameDifficulty if cogdoGameSafezoneId != -1: self.cogdoGameSafezoneId = cogdoGameSafezoneId ToontownBattleGlobals.SkipMovie = self.config.GetBool('skip-battle-movies', 0) self.creditCardUpFront = self.config.GetInt('credit-card-up-front', -1) if self.creditCardUpFront == -1: del self.creditCardUpFront else: self.creditCardUpFront = self.creditCardUpFront != 0 self.housingEnabled = self.config.GetBool('want-housing', 1) self.cannonsEnabled = self.config.GetBool('estate-cannons', 0) self.fireworksEnabled = self.config.GetBool('estate-fireworks', 0) self.dayNightEnabled = self.config.GetBool('estate-day-night', 0) self.cloudPlatformsEnabled = self.config.GetBool('estate-clouds', 0) self.greySpacing = self.config.GetBool('allow-greyspacing', 0) self.goonsEnabled = self.config.GetBool('estate-goon', 0) self.restrictTrialers = self.config.GetBool('restrict-trialers', 1) self.roamingTrialers = self.config.GetBool('roaming-trialers', 1) self.slowQuietZone = self.config.GetBool('slow-quiet-zone', 0) self.slowQuietZoneDelay = self.config.GetFloat('slow-quiet-zone-delay', 5) self.killInterestResponse = self.config.GetBool('kill-interest-response', 0) tpMgr = TextPropertiesManager.getGlobalPtr() WLDisplay = TextProperties() WLDisplay.setSlant(0.3) WLEnter = TextProperties() WLEnter.setTextColor(1.0, 0.0, 0.0, 1) tpMgr.setProperties('WLDisplay', WLDisplay) tpMgr.setProperties('WLEnter', WLEnter) del tpMgr self.lastScreenShotTime = globalClock.getRealTime() self.accept('InputState-forward', self.__walking) self.canScreenShot = 1 self.glitchCount = 0 self.walking = 0 self.oldX = max(1, base.win.getXSize()) self.oldY = max(1, base.win.getYSize()) self.aspectRatio = float(self.oldX) / self.oldY self.localAvatarStyle = None return def openMainWindow(self, *args, **kw): result = OTPBase.OTPBase.openMainWindow(self, *args, **kw) self.setCursorAndIcon() return result def loadSettings(self): Settings.load() self.enableMusic(Settings.getEnableMusic()) self.enableSoundEffects(Settings.getEnableSFX()) self.toonChatSounds = Settings.getEnableChatSound() def windowEvent(self, win): OTPBase.OTPBase.windowEvent(self, win) if not config.GetInt('keep-aspect-ratio', 0): return x = max(1, win.getXSize()) y = max(1, win.getYSize()) maxX = base.pipe.getDisplayWidth() maxY = base.pipe.getDisplayHeight() cwp = win.getProperties() originX = 0 originY = 0 if cwp.hasOrigin(): originX = cwp.getXOrigin() originY = cwp.getYOrigin() if originX > maxX: originX = originX - maxX if originY > maxY: oringY = originY - maxY maxX -= originX maxY -= originY if math.fabs(x - self.oldX) > math.fabs(y - self.oldY): newY = x / self.aspectRatio newX = x if newY > maxY: newY = maxY newX = self.aspectRatio * maxY else: newX = self.aspectRatio * y newY = y if newX > maxX: newX = maxX newY = maxX / self.aspectRatio wp = WindowProperties() wp.setSize(newX, newY) base.win.requestProperties(wp) base.cam.node().getLens().setFilmSize(newX, newY) self.oldX = newX self.oldY = newY def setCursorAndIcon(self): wp = WindowProperties() cursor = os.path.join(os.path.abspath(os.curdir), 'toonmono.cur') cursor = Filename.fromOsSpecific(cursor) cursor.setBinary() wp.setCursorFilename(cursor) icon = os.path.join(os.path.abspath(os.curdir), 'icon.ico') icon = Filename.fromOsSpecific(icon) icon.setBinary() wp.setIconFilename(icon) self.win.requestProperties(wp) def addCullBins(self): cbm = CullBinManager.getGlobalPtr() cbm.addBin('ground', CullBinManager.BTUnsorted, 18) cbm.addBin('shadow', CullBinManager.BTBackToFront, 19) cbm.addBin('gui-popup', CullBinManager.BTUnsorted, 60) def disableShowbaseMouse(self): self.useDrive() self.disableMouse() if self.mouseInterface: self.mouseInterface.detachNode() if self.mouse2cam: self.mouse2cam.detachNode() def __walking(self, pressed): self.walking = pressed def takeScreenShot(self): if not os.path.exists(TTLocalizer.ScreenshotPath): os.mkdir(TTLocalizer.ScreenshotPath) self.notify.info('Made new directory to save screenshots.') namePrefix = TTLocalizer.ScreenshotPath + launcher.logPrefix + 'screenshot' timedif = globalClock.getRealTime() - self.lastScreenShotTime if self.glitchCount > 10 and self.walking: return if timedif < 1.0 and self.walking: self.glitchCount += 1 return if not hasattr(self, 'localAvatar'): self.screenshot(namePrefix=namePrefix) self.lastScreenShotTime = globalClock.getRealTime() return coordOnScreen = self.config.GetBool('screenshot-coords', 0) self.localAvatar.stopThisFrame = 1 ctext = self.localAvatar.getAvPosStr() self.screenshotStr = '' messenger.send('takingScreenshot') if coordOnScreen: coordTextLabel = DirectLabel(pos=(-0.81, 0.001, -0.87), text=ctext, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) coordTextLabel.setBin('gui-popup', 0) strTextLabel = None if len(self.screenshotStr): strTextLabel = DirectLabel(pos=(0.0, 0.001, 0.9), text=self.screenshotStr, text_scale=0.05, text_fg=VBase4(1.0, 1.0, 1.0, 1.0), text_bg=(0, 0, 0, 0), text_shadow=(0, 0, 0, 1), relief=None) strTextLabel.setBin('gui-popup', 0) self.graphicsEngine.renderFrame() self.screenshot(namePrefix=namePrefix, imageComment=ctext + ' ' + self.screenshotStr) self.lastScreenShotTime = globalClock.getRealTime() #elf.transitions.fadeScreenColor(1) #self.transitions.setFadeColor(1, 1, 1) #self.transitions.fadeIn(0.8) self.snapshotSfx = base.loadSfx('phase_4/audio/sfx/Photo_shutter.ogg') base.playSfx(self.snapshotSfx) if coordOnScreen: if strTextLabel is not None: strTextLabel.destroy() coordTextLabel.destroy() return def addScreenshotString(self, str): if len(self.screenshotStr): self.screenshotStr += '\n' self.screenshotStr += str def initNametagGlobals(self): arrow = loader.loadModel('phase_3/models/props/arrow') card = loader.loadModel('phase_3/models/props/panel') speech3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox')) thought3d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_thought_cutout')) speech2d = ChatBalloon(loader.loadModel('phase_3/models/props/chatbox_noarrow')) chatButtonGui = loader.loadModel('phase_3/models/gui/chat_button_gui') NametagGlobals.setCamera(self.cam) NametagGlobals.setArrowModel(arrow) NametagGlobals.setNametagCard(card, VBase4(-0.5, 0.5, -0.5, 0.5)) if self.mouseWatcherNode: NametagGlobals.setMouseWatcher(self.mouseWatcherNode) NametagGlobals.setSpeechBalloon3d(speech3d) NametagGlobals.setThoughtBalloon3d(thought3d) NametagGlobals.setSpeechBalloon2d(speech2d) NametagGlobals.setThoughtBalloon2d(thought3d) NametagGlobals.setPageButton(PGButton.SReady, chatButtonGui.find('**/Horiz_Arrow_UP')) NametagGlobals.setPageButton(PGButton.SDepressed, chatButtonGui.find('**/Horiz_Arrow_DN')) NametagGlobals.setPageButton(PGButton.SRollover, chatButtonGui.find('**/Horiz_Arrow_Rllvr')) NametagGlobals.setQuitButton(PGButton.SReady, chatButtonGui.find('**/CloseBtn_UP')) NametagGlobals.setQuitButton(PGButton.SDepressed, chatButtonGui.find('**/CloseBtn_DN')) NametagGlobals.setQuitButton(PGButton.SRollover, chatButtonGui.find('**/CloseBtn_Rllvr')) rolloverSound = DirectGuiGlobals.getDefaultRolloverSound() if rolloverSound: NametagGlobals.setRolloverSound(rolloverSound) clickSound = DirectGuiGlobals.getDefaultClickSound() if clickSound: NametagGlobals.setClickSound(clickSound) NametagGlobals.setToon(self.cam) self.marginManager = MarginManager() self.margins = self.aspect2d.attachNewNode(self.marginManager, DirectGuiGlobals.MIDGROUND_SORT_INDEX + 1) mm = self.marginManager self.leftCells = [mm.addGridCell(0, 1, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(0, 2, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(0, 3, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop)] self.bottomCells = [mm.addGridCell(0.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(1.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(2.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(3.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(4.5, 0, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop)] self.rightCells = [mm.addGridCell(5, 2, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop), mm.addGridCell(5, 1, base.a2dLeft, base.a2dRight, base.a2dBottom, base.a2dTop)] def setCellsAvailable(self, cell_list, available): for cell in cell_list: self.marginManager.setCellAvailable(cell, available) def cleanupDownloadWatcher(self): self.downloadWatcher.cleanup() self.downloadWatcher = None return def startShow(self, cr, launcherServer = None): self.cr = cr base.graphicsEngine.renderFrame() self.downloadWatcher = ToontownDownloadWatcher.ToontownDownloadWatcher(TTLocalizer.LauncherPhaseNames) if launcher.isDownloadComplete(): self.cleanupDownloadWatcher() else: self.acceptOnce('launcherAllPhasesComplete', self.cleanupDownloadWatcher) gameServer = base.config.GetString('game-server', '127.0.0.1') if gameServer: self.notify.info('Using game-server from Configrc: %s ' % gameServer) elif launcherServer: gameServer = launcherServer self.notify.info('Using gameServer from launcher: %s ' % gameServer) else: gameServer = base.config.GetString('game-server') serverPort = base.config.GetInt('server-port', 7198) serverList = [] for name in gameServer.split(';'): url = URLSpec(name, 1) if base.config.GetBool('server-force-ssl', False): url.setScheme('s') if not url.hasPort(): url.setPort(serverPort) serverList.append(url) if len(serverList) == 1: failover = base.config.GetString('server-failover', '') serverURL = serverList[0] for arg in failover.split(): try: port = int(arg) url = URLSpec(serverURL) url.setPort(port) except: url = URLSpec(arg, 1) if url != serverURL: serverList.append(url) cr.loginFSM.request('launcher', [serverList]) self.ttAccess = ToontownAccess.ToontownAccess() self.ttAccess.initModuleInfo() def removeGlitchMessage(self): self.ignore('InputState-forward') def exitShow(self, errorCode = None): self.notify.info('Exiting Toontown: errorCode = %s' % errorCode) if errorCode: launcher.setPandaErrorCode(errorCode) else: launcher.setPandaErrorCode(0) sys.exit() def setExitErrorCode(self, code): self.exitErrorCode = code if os.name == 'nt': exitCode2exitPage = {OTPLauncherGlobals.ExitEnableChat: 'chat', OTPLauncherGlobals.ExitSetParentPassword: '******', OTPLauncherGlobals.ExitPurchase: 'purchase'} if code in exitCode2exitPage: launcher.setRegistry('EXIT_PAGE', exitCode2exitPage[code]) def getExitErrorCode(self): return self.exitErrorCode def userExit(self): try: self.localAvatar.d_setAnimState('TeleportOut', 1) except: pass if hasattr(self, 'ttAccess'): self.ttAccess.delete() if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectCloseWindow) base.cr._userLoggingOut = False try: localAvatar except: pass else: messenger.send('clientLogout') self.cr.dumpAllSubShardObjects() self.cr.loginFSM.request('shutdown') self.notify.warning('Could not request shutdown; exiting anyway.') self.exitShow() def panda3dRenderError(self): launcher.setPandaErrorCode(14) if self.cr.timeManager: self.cr.timeManager.setDisconnectReason(ToontownGlobals.DisconnectGraphicsError) self.cr.sendDisconnect() sys.exit() def getShardPopLimits(self): if self.cr.productName == 'JP': return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP_JP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP_JP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP_JP)) elif self.cr.productName in ['BR', 'FR']: return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP_INTL), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP_INTL), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP_INTL)) else: return (config.GetInt('shard-low-pop', ToontownGlobals.LOW_POP), config.GetInt('shard-mid-pop', ToontownGlobals.MID_POP), config.GetInt('shard-high-pop', ToontownGlobals.HIGH_POP)) def playMusic(self, music, looping = 0, interrupt = 1, volume = None, time = 0.0): OTPBase.OTPBase.playMusic(self, music, looping, interrupt, volume, time) def __DISABLED__adjustWindowAspectRatio(self, aspectRatio): # Moved from ShowBase.py # This will NOT change 3D aspect ratio # Experimental if self._ShowBase__configAspectRatio: aspectRatio = self._ShowBase__configAspectRatio if aspectRatio != self._ShowBase__oldAspectRatio: self._ShowBase__oldAspectRatio = aspectRatio # Fix up some anything that depends on the aspectRatio if aspectRatio < 1: # If the window is TALL, lets expand the top and bottom self.aspect2d.setScale(1.0, aspectRatio, aspectRatio) self.a2dTop = 1.0 / aspectRatio self.a2dBottom = - 1.0 / aspectRatio self.a2dLeft = -1 self.a2dRight = 1.0 # Don't forget 2dp self.aspect2dp.setScale(1.0, aspectRatio, aspectRatio) self.a2dpTop = 1.0 / aspectRatio self.a2dpBottom = - 1.0 / aspectRatio self.a2dpLeft = -1 self.a2dpRight = 1.0 else: # If the window is WIDE, lets expand the left and right self.aspect2d.setScale(1.0 / aspectRatio, 1.0, 1.0) self.a2dTop = 1.0 self.a2dBottom = -1.0 self.a2dLeft = -aspectRatio self.a2dRight = aspectRatio # Don't forget 2dp self.aspect2dp.setScale(1.0 / aspectRatio, 1.0, 1.0) self.a2dpTop = 1.0 self.a2dpBottom = -1.0 self.a2dpLeft = -aspectRatio self.a2dpRight = aspectRatio # Reposition the aspect2d marker nodes self.a2dTopCenter.setPos(0, self.a2dTop, self.a2dTop) self.a2dBottomCenter.setPos(0, self.a2dBottom, self.a2dBottom) self.a2dLeftCenter.setPos(self.a2dLeft, 0, 0) self.a2dRightCenter.setPos(self.a2dRight, 0, 0) self.a2dTopLeft.setPos(self.a2dLeft, self.a2dTop, self.a2dTop) self.a2dTopRight.setPos(self.a2dRight, self.a2dTop, self.a2dTop) self.a2dBottomLeft.setPos(self.a2dLeft, self.a2dBottom, self.a2dBottom) self.a2dBottomRight.setPos(self.a2dRight, self.a2dBottom, self.a2dBottom) # Reposition the aspect2d marker nodes self.a2dTopCenterNs.setPos(0, self.a2dTop, self.a2dTop) self.a2dBottomCenterNs.setPos(0, self.a2dBottom, self.a2dBottom) self.a2dLeftCenterNs.setPos(self.a2dLeft, 0, 0) self.a2dRightCenterNs.setPos(self.a2dRight, 0, 0) self.a2dTopLeftNs.setPos(self.a2dLeft, self.a2dTop, self.a2dTop) self.a2dTopRightNs.setPos(self.a2dRight, self.a2dTop, self.a2dTop) self.a2dBottomLeftNs.setPos(self.a2dLeft, self.a2dBottom, self.a2dBottom) self.a2dBottomRightNs.setPos(self.a2dRight, self.a2dBottom, self.a2dBottom) # Reposition the aspect2dp marker nodes self.a2dpTopCenter.setPos(0, self.a2dpTop, self.a2dpTop) self.a2dpBottomCenter.setPos(0, self.a2dpBottom, self.a2dpBottom) self.a2dpLeftCenter.setPos(self.a2dpLeft, 0, 0) self.a2dpRightCenter.setPos(self.a2dpRight, 0, 0) self.a2dpTopLeft.setPos(self.a2dpLeft, self.a2dpTop, self.a2dpTop) self.a2dpTopRight.setPos(self.a2dpRight, self.a2dpTop, self.a2dpTop) self.a2dpBottomLeft.setPos(self.a2dpLeft, self.a2dpBottom, self.a2dpBottom) self.a2dpBottomRight.setPos(self.a2dpRight, self.a2dpBottom, self.a2dpBottom) # If anybody needs to update their GUI, put a callback on this event messenger.send("aspectRatioChanged")