def enterDisconnect(self, isPlaying, booted=0, bootReason=None): self.notify.info( "Disconnect details: isPlaying = %s, booted = %s, bootReason = %s" % (isPlaying, booted, bootReason)) style = 3 if isPlaying == 1: if not booted: msg = CIGlobals.DisconnectionMsg else: if not booted: msg = CIGlobals.JoinFailureMsg if self.isConnected(): self.sendDisconnect() self.disconnectDialog = GlobalDialog(message=msg, style=style, doneEvent="disconnectDone") self.disconnectDialog.show() if style == 3: self.acceptOnce("disconnectDone", sys.exit) else: self.acceptOnce("disconnectDone", self.handleDisconnectDone)
def __newFriendRequest(self, requester, name, dna): head = ToonGlobals.generateGuiHead(dna) size = (0.55 * 1.5, 0.55 * 1.5, 0.35 * 1.5) request = GlobalDialog( message=ChatGlobals.mentionAvatar(self.MessageFriendRequest, name), style=1, text_wordwrap=12, doneEvent='friendRequestDone-%d' % requester, extraArgs=[requester], text_scale=0.065, pos=(-0.85, 0, -0.275), geom=head, geom_scale=(0.125 * 1.25, 0.125 * 1.25, 0.1625 * 1.25), scale=size, image_scale=size, text_pos=(0.15, 0.075, 0), relief=None) request.reparentTo(base.a2dTopRight) text = request.component('text0') text.setScale(0.065, 0.1) for cmpt in request.components(): if 'Button' in cmpt: btn = request.component(cmpt) btn.setScale(btn, btn.getSx(), btn.getSy() + 0.1, btn.getSz() + 0.2) self.friendRequests[requester] = request self.acceptOnce('friendRequestDone-%d' % requester, self.handleFriendRequestChoice) self.requestIval = Sequence( Func(self.popUpSfx.play), LerpScaleInterval(request, 0.35, size, startScale=0.01, blendType='easeOut')) self.requestIval.start()
class CogInvasionClientRepository(AstronClientRepository): notify = directNotify.newCategory("CIClientRepository") GameGlobalsId = DO_ID_COGINVASION SetZoneDoneEvent = 'CICRSetZoneDone' EmuSetZoneDoneEvent = 'CICREmuSetZoneDone' SetInterest = 'Set' ClearInterest = 'Clear' ClearInterestDoneEvent = 'CICRClearInterestDone' ITAG_PERM = 'perm' ITAG_AVATAR = 'avatar' ITAG_SHARD = 'shard' ITAG_WORLD = 'world' ITAG_GAME = 'game' def __init__(self, serverVersion): self.serverVersion = serverVersion AstronClientRepository.__init__( self, ['phase_3/etc/direct.dc', 'phase_3/etc/toon.dc']) self.loginFSM = ClassicFSM('login', [ State('off', self.enterOff, self.exitOff), State('connect', self.enterConnect, self.exitConnect), State('disconnect', self.enterDisconnect, self.exitDisconnect), State('avChoose', self.enterAvChoose, self.exitAvChoose), State('playingGame', self.enterPlayingGame, self.exitPlayingGame), State('serverUnavailable', self.enterServerUnavailable, self.exitServerUnavailable), State('makeAToon', self.enterMakeAToon, self.exitMakeAToon), State('submitNewToon', self.enterSubmitNewToon, self.exitSubmitNewToon), State('noShards', self.enterNoShards, self.exitNoShards), State('waitForSetAvatarResponse', self.enterWaitForSetAvatarResponse, self.exitWaitForSetAvatarResponse), State('waitForShardList', self.enterWaitForShardList, self.exitWaitForShardList), State('ejected', self.enterEjected, self.exitEjected), State('districtReset', self.enterDistrictReset, self.exitDistrictReset), State('died', self.enterDied, self.exitDied), State('betaInform', self.enterBetaInform, self.exitBetaInform) ], 'off', 'off') self.loginFSM.enterInitialState() self.gameFSM = ClassicFSM('game', [ State('off', self.enterGameOff, self.exitGameOff), State('waitForGameEnterResponse', self.enterWaitForGameEnterResponse, self.exitWaitForGameEnterResponse), State('playGame', self.enterPlayGame, self.exitPlayGame), State('closeShard', self.enterCloseShard, self.exitCloseShard), State('switchShards', self.enterSwitchShards, self.exitSwitchShards) ], 'off', 'off') self.gameFSM.enterInitialState() #self.taskNameAllocator = UniqueIdAllocator(0, 1000000000) self.avChooser = AvChooser(self.loginFSM) self.playGame = PlayGame(self.gameFSM, "playGameDone") self.hoodMgr = HoodMgr() self.makeAToon = MakeAToon() self.loginToken = os.environ.get("LOGIN_TOKEN") self.serverAddress = os.environ.get("GAME_SERVER") self.serverURL = URLSpec("http://%s" % self.serverAddress) self.parentMgr.registerParent(CIGlobals.SPRender, render) self.parentMgr.registerParent(CIGlobals.SPHidden, hidden) self.adminAccess = False self.localAvChoice = None self.SuitsActive = 0 self.BossActive = 0 self.accServerTimesNA = 0 self.maxAccServerTimesNA = 10 self.setZonesEmulated = 0 self.old_setzone_interest_handle = None self.setZoneQueue = Queue() self.accept(self.SetZoneDoneEvent, self._handleEmuSetZoneDone) self.handler = None self.__currentAvId = 0 self.myDistrict = None self.activeDistricts = {} self.shardListHandle = None self.uberZoneInterest = None self.isShowingPlayerIds = False self.doBetaInform = False self.dTutorial = None self.requestedName = None self.whisperNoise = base.loadSfx( 'phase_3.5/audio/sfx/GUI_whisper_3.ogg') self.checkHttp() #self.http.addPreapprovedServerCertificateFilename(self.serverURL, Filename('phase_3/etc/gameserver.crt')) #self.tournamentMusicChunks = {} #self.threadedTaskChain = taskMgr.setupTaskChain("threadedTaskChainForSoundIntervals", numThreads = 2) self.attackMgr = base.cl_attackMgr base.minigame = None self.newToonSlot = None base.finalExitCallbacks.insert(0, self.__handleExit) self.accountName = os.environ.get('ACCOUNT_NAME', '') self.csm = self.generateGlobalObject(DO_ID_CLIENT_SERVICES_MANAGER, 'ClientServicesManager') self.friendsManager = self.generateGlobalObject( DO_ID_FRIENDS_MANAGER, 'FriendsManager') self.uin = self.generateGlobalObject(DO_ID_UNIQUE_INTEREST_NOTIFIER, 'UniqueInterestNotifier') self.statsManager = self.generateGlobalObject(DO_ID_STATS_MANAGER, 'StatsManager') self.pingToggle = False self.currentPing = None self.pingText = OnscreenText("", align=TextNode.ALeft, parent=base.a2dBottomLeft, fg=(1, 1, 1, 1), shadow=(0, 0, 0, 0.5), pos=(0.3, 0.09)) self.pingText.setBin('gsg-popup', 1000) self.pingText.hide() SpeedHackChecker.startChecking() self.loginFSM.request('connect') return def readerPollUntilEmpty(self, task): while self.readerPollOnce(): pass if not metadata.IS_PRODUCTION: if ConfigVariableBool('simulated-latency', False).getValue(): latency = random.uniform( ConfigVariableDouble('simulated-latency-min', 0.125).getValue(), ConfigVariableDouble('simulated-latency-max', 0.15).getValue()) task.delayTime = latency return task.again return task.cont def togglePing(self): self.pingToggle = not self.pingToggle if self.pingToggle: taskMgr.add(self.__districtPingTask, "CICR.districtPingTask") self.showPing() else: self.hidePing() taskMgr.remove("CICR.districtPingTask") def showPing(self): self.pingText.show() def hidePing(self): self.pingText.hide() def handleNewPing(self): if self.currentPing is None: display = "?" else: display = int(round(self.currentPing)) self.pingText.setText("Ping: {0} ms".format(display)) def __districtPingTask(self, task): if self.myDistrict: # Figure out how much network latency there is. self.myDistrict.d_ping() task.delayTime = 1.0 return task.again def deleteObject(self, doId): """ implementation copied from AstronClientRepository.py Brian: modified to also delete owner views Removes the object from the client's view of the world. This should normally not be called directly except in the case of error recovery, since the server will normally be responsible for deleting and disabling objects as they go out of scope. After this is called, future updates by server on this object will be ignored (with a warning message). The object will become valid again the next time the server sends a generate message for this doId. This is not a distributed message and does not delete the object on the server or on any other client. """ if doId in self.doId2do: # If it is in the dictionary, remove it. obj = self.doId2do[doId] # Remove it from the dictionary del self.doId2do[doId] # Disable, announce, and delete the object itself... # unless delayDelete is on... obj.deleteOrDelay() if self.isLocalId(doId): self.freeDoId(doId) elif doId in self.doId2ownerView: # If it is in the owner dictionary, remove it. obj = self.doId2ownerView[doId] # Remove it from the dictionary del self.doId2ownerView[doId] # Disable, announce, and delete the object itself... # unless delayDelete is on... obj.deleteOrDelay() if self.isLocalId(doId): self.freeDoId(doId) elif self.cache.contains(doId): # If it is in the cache, remove it. self.cache.delete(doId) if self.isLocalId(doId): self.freeDoId(doId) elif self.cacheOwner.contains(doId): # If it is in the owner cache, remove it. self.cacheOwner.delete(doId) if self.isLocalId(doId): self.freeDoId(doId) else: # Otherwise, ignore it self.notify.warning("Asked to delete non-existent DistObj " + str(doId)) #def uniqueName(self, idString): # return "%s-%s" % (idString, self.taskNameAllocator.allocate()) #def removeTask(self, taskName): # div = taskName.split('-') # self.taskNameAllocator.free(div[1]) # taskMgr.remove(taskName) def __handleExit(self): try: base.localAvatar.b_setAnimState('teleportOut') except: pass ccoginvasion.CTMusicData.stop_am_update_task() self.gameFSM.request('closeShard', ['off']) def isChristmas(self): return self.holidayManager.getHoliday() == HolidayType.CHRISTMAS def showPlayerIds(self): print "Showing player ids..." self.isShowingPlayerIds = True for av in self.doId2do.values(): if av.__class__.__name__ in [ "DistributedPlayerToon", "LocalToon", "DistributedSuit" ]: av.showAvId() def hidePlayerIds(self): print "Hiding player ids..." self.isShowingPlayerIds = False for av in self.doId2do.values(): if av.__class__.__name__ in [ "DistributedPlayerToon", "LocalToon", 'DistributedSuit' ]: av.showName() def sendSetLocation(self, doId, parentId, zoneId): dg = PyDatagram() dg.addUint16(CLIENT_OBJECT_LOCATION) dg.addUint32(doId) dg.addUint32(parentId) dg.addUint32(zoneId) self.send(dg) def getNextSetZoneDoneEvent(self): return '%s-%s' % (self.EmuSetZoneDoneEvent, self.setZonesEmulated + 1) def getLastSetZoneDoneEvent(self): return '%s-%s' % (self.EmuSetZoneDoneEvent, self.setZonesEmulated) def getQuietZoneLeftEvent(self): return 'leftQuietZone-%s' % (id(self), ) def b_setLocation(self, do, parentId, zoneId): self.sendSetLocation(do.doId, parentId, zoneId) do.setLocation(parentId, zoneId) def sendSetZoneMsg(self, zoneId, visibleZoneList=None): event = self.getNextSetZoneDoneEvent() self.setZonesEmulated += 1 parentId = base.localAvatar.defaultShard self.sendSetLocation(base.localAvatar.doId, parentId, zoneId) localAvatar.setLocation(parentId, zoneId) interestZones = zoneId if visibleZoneList is not None: interestZones = visibleZoneList self._addInterestOpToQueue( self.SetInterest, [parentId, interestZones, 'OldSetZoneEmulator'], event) return def resetInterestStateForConnectionLoss(self): self.old_setzone_interest_handle = None self.setZoneQueue.clear() return def _removeEmulatedSetZone(self, doneEvent): self._addInterestOpToQueue(self.ClearInterest, None, doneEvent) return def _addInterestOpToQueue(self, op, args, event): self.setZoneQueue.push([op, args, event]) if len(self.setZoneQueue) == 1: self._sendNextSetZone() def _sendNextSetZone(self): op, args, event = self.setZoneQueue.top() if op == self.SetInterest: parentId, interestZones, name = args if self.old_setzone_interest_handle is None: self.old_setzone_interest_handle = self.addInterest( parentId, interestZones, name, self.SetZoneDoneEvent) else: self.alterInterest(self.old_setzone_interest_handle, parentId, interestZones, name, self.SetZoneDoneEvent) elif op == self.ClearInterest: self.removeInterest(self.old_setzone_interest_handle, self.SetZoneDoneEvent) self.old_setzone_interest_handle = None else: self.notify.error('unknown setZone op: %s' % op) return def _handleEmuSetZoneDone(self): op, args, event = self.setZoneQueue.pop() queueIsEmpty = self.setZoneQueue.isEmpty() if event is not None: messenger.send(event) if not queueIsEmpty: self._sendNextSetZone() return def enterSwitchShards(self, shardId, hoodId, zoneId, avId): self._switchShardParams = [shardId, hoodId, zoneId, avId] self.removeShardInterest(self._handleOldShardGone) def _handleOldShardGone(self): status = {} status['hoodId'] = self._switchShardParams[1] status['zoneId'] = self._switchShardParams[2] status['avId'] = self._switchShardParams[3] self.gameFSM.request('waitForGameEnterResponse', [status, self._switchShardParams[0]]) def exitSwitchShards(self): del self._switchShardParams def enterBetaInform(self): msg = ( "Welcome to Cog Invasion Online!\n\nBefore playing, please remember that the game is in Alpha, " "and that you may encounter bugs and incomplete features.\n\nIf you happen to encounter any bugs, " "please report them to us by using the Contact Us Page at coginvasion.com.\n\nHave fun!" ) self.dialog = GlobalDialog(message=msg, style=3, doneEvent="gameEnterChoice") self.dialog.show() self.acceptOnce("gameEnterChoice", self.handleGameEnterChoice) def handleGameEnterChoice(self): self.loginFSM.request('avChoose') def exitBetaInform(self): self.ignore("gameEnterChoice") self.dialog.cleanup() del self.dialog def enterCloseShard(self, nextState='avChoose'): self.setNoNewInterests(True) self._removeLocalAvFromStateServer(nextState) def exitCloseShard(self): self.setNoNewInterests(False) self.ignore(self.ClearInterestDoneEvent) return def _removeLocalAvFromStateServer(self, nextState): self.sendSetAvatarIdMsg(0) self._removeAllOV() callback = Functor(self.loginFSM.request, nextState) self.removeShardInterest(callback) def removeShardInterest(self, callback): self._removeCurrentShardInterest( Functor(self._removeShardInterestComplete, callback)) def _removeShardInterestComplete(self, callback): self.cache.flush() self.doDataCache.flush() callback() return def _removeCurrentShardInterest(self, callback): if self.old_setzone_interest_handle is None: callback() return self.acceptOnce(self.ClearInterestDoneEvent, Functor(self._removeCurrentUberZoneInterest, callback)) self._removeEmulatedSetZone(self.ClearInterestDoneEvent) return def _removeCurrentUberZoneInterest(self, callback): self.acceptOnce(self.ClearInterestDoneEvent, Functor(self._removeShardInterestDone, callback)) self.removeInterest(self.uberZoneInterest, self.ClearInterestDoneEvent) def _removeShardInterestDone(self, callback): self.uberZoneInterest = None callback() return def _removeAllOV(self): owners = self.doId2ownerView.keys() for doId in owners: self.disableDoId(doId, ownerView=True) def enterDied(self): self.deathDialog = GlobalDialog(message=CIGlobals.SuitDefeatMsg, style=2, doneEvent="deathChoice") self.deathDialog.show() self.acceptOnce("deathChoice", self.handleDeathChoice) def handleDeathChoice(self): value = self.deathDialog.getValue() if value: self.loginFSM.request('avChoose') else: sys.exit() def exitDied(self): self.deathDialog.cleanup() del self.deathDialog self.ignore("deathChoice") def enterConnect(self): self.connectingDialog = GlobalDialog(message=CIGlobals.ConnectingMsg) self.connectingDialog.show() self.connect([self.serverURL], successCallback=self.handleConnected, failureCallback=self.handleConnectFail) def handleConnected(self): self.notify.info("Sending CLIENT_HELLO...") self.acceptOnce("CLIENT_HELLO_RESP", self.handleClientHelloResp) self.acceptOnce("CLIENT_EJECT", self.handleEjected) self.acceptOnce("LOST_CONNECTION", self.handleLostConnection) AstronClientRepository.sendHello(self, self.serverVersion) def handleLostConnection(self): self.deleteAllObjects() self.loginFSM.request('disconnect', [1]) def deleteAllObjects(self): for doId in self.doId2do.keys(): obj = self.doId2do[doId] if not isinstance(obj, DistributedObjectGlobal) and not hasattr( obj, 'isDistrict'): if hasattr(base, 'localAvatar') and doId != base.localAvatar.doId: self.deleteObject(doId) def handleEjected(self, errorCode, reason): self.notify.info("OMG I WAS EJECTED!") self.ignore("LOST_CONNECTION") errorMsg = ErrorCode2ErrorMsg.get(errorCode, None) or UnknownErrorMsg % errorCode self.loginFSM.request('ejected', [errorMsg]) def handleClientHelloResp(self): self.notify.info("Got CLIENT_HELLO_RESP!") self.acceptOnce(self.csm.getLoginAcceptedEvent(), self.handleLoginAccepted) self.csm.d_requestLogin(self.loginToken, self.accountName) def handleLoginAccepted(self): self.notify.info("Woo-hoo, I am authenticated!") base.cr.holidayManager = self.generateGlobalObject( DO_ID_HOLIDAY_MANAGER, 'HolidayManager') base.cr.nameServicesManager = self.generateGlobalObject( DO_ID_NAME_SERVICES_MANAGER, 'NameServicesManager') self.loginFSM.request('waitForShardList') def handleConnectFail(self, _, __): self.notify.info("Could not connect to gameserver, notifying user.") self.connectingDialog.cleanup() self.connectingDialog = GlobalDialog( message=CIGlobals.NoConnectionMsg % self.serverAddress + " " + CIGlobals.TryAgain, style=2, doneEvent="connectFail") self.connectingDialog.show() self.acceptOnce("connectFail", self.handleConnectFailButton) def handleConnectFailButton(self): value = self.connectingDialog.getValue() if value: self.loginFSM.request('connect') else: sys.exit() def exitConnect(self): self.ignore("connectFail") self.ignore("CLIENT_HELLO_RESP") self.ignore(self.csm.getLoginAcceptedEvent()) self.connectingDialog.cleanup() del self.connectingDialog def enterEjected(self, errorMsg): self.ejectDialog = GlobalDialog(message=errorMsg, style=3, doneEvent='ejectDone') self.ejectDialog.show() self.acceptOnce('ejectDone', sys.exit) def exitEjected(self): self.ignore('ejectDone') self.ejectDialog.cleanup() del self.ejectDialog def enterServerUnavailable(self): self.notify.info(CIGlobals.ServerUnavailable) self.serverNA = GlobalDialog(message=CIGlobals.ServerUnavailable, style=4, doneEvent="serverNAEvent") self.serverNA.show() self.acceptOnce("serverNAEvent", sys.exit) self.startServerNAPoll() def startServerNAPoll(self): self.notify.info("Starting server poll...") self.accServerTimesNA = 1 taskMgr.add(self.serverNAPoll, "serverNAPoll") def serverNAPoll(self, task): dg = PyDatagram() dg.addUint16(ACC_IS_SERVER_UP) self.send(dg) task.delayTime = 3.0 return Task.again def __handleServerNAResp(self, resp): if resp == ACC_SERVER_UP: taskMgr.remove("serverNAPoll") # Enter the previous state that we were in, which should have # been some state where we communicate with the acc server. self.loginFSM.request(self.loginFSM.getLastState().getName()) else: self.accServerTimesNA += 1 if self.accServerTimesNA >= self.maxAccServerTimesNA: taskMgr.remove("serverNAPoll") self.notify.info( "Giving up on polling account server after %s times." % self.accServerTimesNA) self.loginFSM.request("disconnect", enterArgList=[1]) self.accServerTimesNA = 0 def exitServerUnavailable(self): self.ignore("serverNAEvent") self.serverNA.cleanup() del self.serverNA def enterOff(self): pass def exitOff(self): pass def playTheme(self): base.playMusic(CIGlobals.getThemeSong(), looping=1) def enterAvChoose(self, newToonSlot=None): ModelPool.garbageCollect() TexturePool.garbageCollect() self.avChooser.load() self.avChooser.enter(newToonSlot) if newToonSlot is None: self.playTheme() self.accept("enterMakeAToon", self.__handleMakeAToonReq) self.accept("avChooseDone", self.__handleAvChooseDone) def __handleMakeAToonReq(self, slot): self.loginFSM.request('makeAToon', [slot]) def __handleAvChooseDone(self, avChoice): print "------- AvChooseDone -------" print "Toon name: %s" % avChoice.getName() print "Slot: %s" % avChoice.getSlot() print "DNA: %s" % avChoice.getDNA() self.loginFSM.request("waitForSetAvatarResponse", [avChoice]) def exitAvChoose(self): self.avChooser.exit() self.avChooser.unload() self.ignore("enterMakeAToon") self.ignore("avChooseDone") def handlePlayGame(self, msgType, di): if msgType == CLIENT_ENTER_OBJECT_REQUIRED_OTHER_OWNER: self.handleGenerateWithRequiredOtherOwner(msgType, di) else: AstronClientRepository.handleDatagram(self, di) def enterPlayingGame(self): zoneId = localAvatar.getLastHood() hoodId = ZoneUtil.getHoodId(zoneId) status = {"hoodId": hoodId, "zoneId": zoneId, "avId": self.localAvId} shardId = self.myDistrict.doId self.gameFSM.request('waitForGameEnterResponse', [status, shardId]) def exitPlayingGame(self): self.deleteAllObjects() self.handler = None self.gameFSM.request('off') camera.reparentTo(render) camera.setPos(0, 0, 0) camera.setHpr(0, 0, 0) self.localAvChoice = None if loader.inBulkBlock: loader.endBulkLoad(loader.blockName) def enterNoShards(self): self.noShardDialog = GlobalDialog(message=CIGlobals.NoShardsMsg + " " + CIGlobals.TryAgain, style=2, doneEvent='noShardsDone') self.noShardDialog.show() self.acceptOnce('noShardsDone', self.handleNoShardsDone) def handleNoShardsDone(self): value = self.noShardDialog.getValue() if value: self.loginFSM.request('waitForShardList') else: sys.exit() def exitNoShards(self): self.noShardDialog.cleanup() del self.noShardDialog self.ignore('noShardsDone') def enterWaitForShardList(self): self.shardListHandle = self.addTaggedInterest( self.GameGlobalsId, ZoneUtil.DistrictZone, self.ITAG_PERM, 'localShardList', event='shardList_complete') self.acceptOnce('shardList_complete', self._handleShardListComplete) def _handleShardListComplete(self): if self._shardsAreAvailable(): self.myDistrict = self._chooseAShard() if self.doBetaInform: self.loginFSM.request('betaInform') else: self.loginFSM.request('avChoose') taskMgr.add(self.monitorDistrict, "monitorMyDistrict") else: self.loginFSM.request('noShards') def monitorDistrict(self, task): if self.myDistrict is None and self.isConnected(): self.loginFSM.request('districtReset') return task.done return task.cont def _shardsAreAvailable(self): for shard in self.activeDistricts.values(): if shard.available: return True return False def _chooseAShard(self): choices = [] for shard in self.activeDistricts.values(): choices.append(shard) return random.choice(choices) def exitWaitForShardList(self): self.ignore('shardList_complete') def enterDistrictReset(self): self.districtResetDialog = GlobalDialog( message=CIGlobals.DistrictResetMsg, style=3, doneEvent='distresetdone') self.districtResetDialog.show() self.acceptOnce('distresetdone', sys.exit) def exitDistrictReset(self): self.districtResetDialog.cleanup() del self.districtResetDialog def enterWaitForSetAvatarResponse(self, choice): #self.acceptOnce(self.csm.getSetAvatarEvent(), self.__handleSetAvatarResponse) self.sendSetAvatarMsg(choice) def enterLoadDone(self): self.loginFSM.request("playingGame") def __handleSetAvatarResponse(self, avId, di): print "Entering game..." enterLoad = EnterLoad(self.enterLoadDone) dclass = self.dclassesByName['DistributedPlayerToon'] localAvatar = LocalToon.LocalToon(base.cr) localAvatar.dclass = dclass base.localAvatar = localAvatar __builtins__['localAvatar'] = base.localAvatar localAvatar.doId = avId self.localAvId = avId parentId = None zoneId = None localAvatar.setLocation(parentId, zoneId) localAvatar.generateInit() localAvatar.generate() dclass.receiveUpdateBroadcastRequiredOwner(localAvatar, di) localAvatar.announceGenerate() localAvatar.postGenerateMessage() self.doId2do[avId] = localAvatar # TEMPORARY: #localAvatar.hoodsDiscovered = [1000, 2000, 3000, 4000, 5000, 9000] #localAvatar.teleportAccess = [1000, 2000, 3000, 4000, 5000, 9000] enterLoad.load() del enterLoad def exitWaitForSetAvatarResponse(self): self.ignore(self.csm.getSetAvatarEvent()) def enterWaitForGameEnterResponse(self, status, shardId): if shardId is not None: district = self.activeDistricts[shardId] else: district = None if not district: self.loginFSM.request('noShards') return else: self.myDistrict = district self.notify.info("Entering shard %s" % shardId) localAvatar.setLocation(shardId, status['zoneId']) localAvatar.defaultShard = shardId self.handleEnteredShard(status) return def handleEnteredShard(self, status): self.uberZoneInterest = self.addInterest(localAvatar.defaultShard, ZoneUtil.UberZone, 'uberZone', 'uberZoneInterestComplete') self.acceptOnce('uberZoneInterestComplete', self.uberZoneInterestComplete, [status]) def uberZoneInterestComplete(self, status): self.__gotTimeSync = 0 if self.timeManager is None: print "No time manager" DistributedSmoothNode.globalActivateSmoothing(0, 0) self.gotTimeSync(status) else: print "Time manager found" DistributedSmoothNode.globalActivateSmoothing(1, 0) #h = HashVal() #hashPrcVariables(h) #pyc = HashVal() #if not __dev__: # self.hashFiles(pyc) #self.timeManager.d_setSignature(self.userSignature, h.asBin(), pyc.asBin()) #self.timeManager.sendCpuInfo() self.timeManager.lastAttempt = -self.timeManager.minWait * 2 if self.timeManager.synchronize('startup'): self.accept('gotTimeSync', self.gotTimeSync, [status]) else: self.gotTimeSync(status) return def getPing(self): if self.myDistrict: return self.myDistrict.currentPing return 0 def exitWaitForGameEnterResponse(self): self.ignore('uberZoneInterestComplete') return def gotTimeSync(self, status): self.notify.info('gotTimeSync') self.ignore('gotTimeSync') self.__gotTimeSync = 1 self.prepareToEnter(status) def prepareToEnter(self, status): if not self.__gotTimeSync: self.notify.info("still waiting for time sync") return self.gameFSM.request('playGame', [status]) def enterMakeAToon(self, slot): base.stopMusic() self.makeAToon.setSlot(slot) self.makeAToon.loadEnviron() self.makeAToon.load() self.makeAToon.matFSM.request('genderShop') self.acceptOnce("quitCreateAToon", self.__handleMakeAToonQuit) self.acceptOnce("createAToonFinished", self.__handleMakeAToonDone) def __handleMakeAToonQuit(self): self.loginFSM.request("avChoose") def __handleMakeAToonDone(self, dnaStrand, slot, name): self.loginFSM.request('submitNewToon', enterArgList=[dnaStrand, slot, name]) def exitMakeAToon(self): self.makeAToon.setSlot(-1) self.makeAToon.enterExit(None) self.ignore("quitCreateAToon") self.ignore("createAToonFinished") def enterSubmitNewToon(self, dnaStrand, slot, name, skipTutorial=0): self.newToonSlot = slot self.submittingDialog = GlobalDialog(message=CIGlobals.Submitting) self.submittingDialog.show() self.acceptOnce(self.csm.getToonCreatedEvent(), self.__handleSubmitNewToonResp) self.csm.sendSubmitNewToon(dnaStrand, slot, name, skipTutorial) def __handleSubmitNewToonResp(self, avId): # Now that our toon exists in the database, we can add send over the name we wanted to NameServicesManagerUD. if self.requestedName is not None: self.nameServicesManager.d_requestName(self.requestedName, avId) self.requestedName = None self.loginFSM.request('avChoose', [self.newToonSlot]) def exitSubmitNewToon(self): self.newToonSlot = None self.ignore(self.csm.getToonCreatedEvent()) self.submittingDialog.cleanup() del self.submittingDialog def enterGameOff(self): pass def exitGameOff(self): pass def enterPlayGame(self, status): base.stopMusic() base.transitions.noFade() if self.localAvChoice is None: self.notify.error( "called enterPlayGame() without self.localAvChoice being set!") return if localAvatar.getTutorialCompleted() == 1: zoneId = status['zoneId'] hoodId = status['hoodId'] avId = status['avId'] self.playGame.load() self.playGame.enter(hoodId, zoneId, avId) else: self.sendQuietZoneRequest() localAvatar.sendUpdate('createTutorial') self.myDistrict.d_joining() def tutorialCreated(self, zoneId): # zoneId = the zone the tutorial resides in # tutId = the doId of the tutorial requestStatus = {'zoneId': zoneId} self.tutQuietZoneState = QuietZoneState('tutQuietZoneDone') self.tutQuietZoneState.load() self.tutQuietZoneState.enter(requestStatus) self.acceptOnce('tutQuietZoneDone', self.__handleTutQuietZoneDone) def __handleTutQuietZoneDone(self): # We've entered the zone that the tutorial is in. self.tutQuietZoneState.exit() self.tutQuietZoneState.unload() del self.tutQuietZoneState def exitPlayGame(self): self.ignore('tutQuietZoneDone') if hasattr(self, 'tutQuietZoneDone'): self.tutQuietZoneState.exit() self.tutQuietZoneState.unload() del self.tutQuietZoneState base.stopMusic() self.playGame.exit() self.playGame.unload() def enterDisconnect(self, isPlaying, booted=0, bootReason=None): self.notify.info( "Disconnect details: isPlaying = %s, booted = %s, bootReason = %s" % (isPlaying, booted, bootReason)) style = 3 if isPlaying == 1: if not booted: msg = CIGlobals.DisconnectionMsg else: if not booted: msg = CIGlobals.JoinFailureMsg if self.isConnected(): self.sendDisconnect() self.disconnectDialog = GlobalDialog(message=msg, style=style, doneEvent="disconnectDone") self.disconnectDialog.show() if style == 3: self.acceptOnce("disconnectDone", sys.exit) else: self.acceptOnce("disconnectDone", self.handleDisconnectDone) def handleDisconnectDone(self): value = self.disconnectDialog.getValue() if value: self.loginFSM.request('connect') else: sys.exit() def exitDisconnect(self): self.ignore("disconnectDone") self.disconnectDialog.cleanup() del self.disconnectDialog def renderFrame(self): gsg = base.win.getGsg() if gsg: render2d.prepareScene(gsg) base.graphicsEngine.renderFrame() def renderFrames(self): base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() def handleDatagram(self, di): if self.notify.getDebug(): print "ClientRepository received datagram:" #di.getDatagram().dumpHex(ostream) msgType = self.getMsgType() self.currentSenderId = None if self.handler is None: self.astronHandle(di) else: self.handler(msgType, di) self.considerHeartbeat() def astronHandle(self, di): AstronClientRepository.handleDatagram(self, di) def handleQuietZoneGenerateWithRequired(self, di): doId = di.getUint32() parentId = di.getUint32() zoneId = di.getUint32() classId = di.getUint16() dclass = self.dclassesByNumber[classId] if dclass.getClassDef().neverDisable: dclass.startGenerate() distObj = self.generateWithRequiredFields(dclass, doId, di, parentId, zoneId) dclass.stopGenerate() def handleQuietZoneGenerateWithRequiredOther(self, di): doId = di.getUint32() parentId = di.getUint32() zoneId = di.getUint32() classId = di.getUint16() dclass = self.dclassesByNumber[classId] if dclass.getClassDef().neverDisable: dclass.startGenerate() distObj = self.generateWithRequiredOtherFields( dclass, doId, di, parentId, zoneId) dclass.stopGenerate() def handleQuietZoneUpdateField(self, di): di2 = DatagramIterator(di) doId = di2.getUint32() if doId in self.deferredDoIds: args, deferrable, dg0, updates = self.deferredDoIds[doId] dclass = args[2] if not dclass.getClassDef().neverDisable: return else: do = self.getDo(doId) if do: if not do.neverDisable: return AstronClientRepository.handleUpdateField(self, di) def handleDelete(self, di): doId = di.getUint32() self.deleteObject(doId) def _abandonShard(self): for doId, obj in self.doId2do.items(): if obj.parentId == localAvatar.defaultShard and obj is not localAvatar: self.deleteObject(doId) def handleEnterObjectRequiredOwner(self, di): if self.loginFSM.getCurrentState().getName( ) == 'waitForSetAvatarResponse': doId = di.getUint32() parentId = di.getUint32() zoneId = di.getUint32() dclassId = di.getUint16() self.__handleSetAvatarResponse(doId, di) else: AstronClientRepository.handleEnterObjectRequiredOwner(self, di) def addTaggedInterest(self, parentId, zoneId, mainTag, desc, otherTags=[], event=None): return self.addInterest(parentId, zoneId, desc, event) def sendSetAvatarMsg(self, choice): avId = choice.getAvId() self.sendSetAvatarIdMsg(avId) self.localAvChoice = choice def sendSetAvatarIdMsg(self, avId): if avId != self.__currentAvId: self.__currentAvId = avId self.csm.sendSetAvatar(avId) def sendQuietZoneRequest(self): self.sendSetZoneMsg(ZoneUtil.QuietZone)
def enterConnect(self): self.connectingDialog = GlobalDialog(message=CIGlobals.ConnectingMsg) self.connectingDialog.show() self.connect([self.serverURL], successCallback=self.handleConnected, failureCallback=self.handleConnectFail)
def enterEjected(self, errorMsg): self.ejectDialog = GlobalDialog(message=errorMsg, style=3, doneEvent='ejectDone') self.ejectDialog.show() self.acceptOnce('ejectDone', sys.exit)
class OptionsCategory(DirectObject): AppendOptions = True ApplyCancelButtons = True WantTitle = True def __init__(self, page): self.page = page self.page.header.setScale(0.1) if self.WantTitle: self.page.header.setText( self.Name + (" Options" if self.AppendOptions else "")) else: self.page.header.setText("") if self.ApplyCancelButtons: self.applyBtn = CIGlobals.makeOkayButton("Apply/Save", parent=self.page.book, command=self.applyChanges, pos=(0.45, -0.62, -0.62)) self.discardBtn = CIGlobals.makeCancelButton( "Discard", parent=self.page.book, command=self.discardChanges, pos=(0.65, -0.62, -0.62)) self.applying = GlobalDialog("Saving settings...") self.applying.hide() self.settingsMgr = CIGlobals.getSettingsMgr() # This is a list of ChoiceWidgets under this options category. self.widgets = [] def applyChanges(self): self._showApplying() if self.widgets: for widget in self.widgets: widget.saveSetting() self.settingsMgr.saveFile() self._hideApplying() def discardChanges(self): if self.widgets: for widget in self.widgets: widget.reset() def _showApplying(self): self.applying.show() base.cr.renderFrames() def _hideApplying(self): base.cr.renderFrames() self.applying.hide() def cleanup(self): self.page.header.setScale(0.12) if hasattr(self, 'title'): self.title.destroy() del self.title if hasattr(self, 'applyBtn'): self.applyBtn.destroy() del self.applyBtn if hasattr(self, 'discardBtn'): self.discardBtn.destroy() del self.discardBtn if hasattr(self, 'applying'): self.applying.cleanup() del self.applying self.widgets = None del self.widgets
def enterDied(self): self.deathDialog = GlobalDialog(message=CIGlobals.SuitDefeatMsg, style=2, doneEvent="deathChoice") self.deathDialog.show() self.acceptOnce("deathChoice", self.handleDeathChoice)
class DistributedMinigame(DistributedObject.DistributedObject, Timer.Timer): """Abstract class for any minigame (client side)""" def __init__(self, cr): try: self.DistributedMinigame_initialized return except: self.DistributedMinigame_initialized = 1 DistributedObject.DistributedObject.__init__(self, cr) Timer.Timer.__init__(self) self.headPanels = HeadPanels() self.finalScoreUI = FinalScoreGUI() self.fsm = ClassicFSM('DistributedMinigame', [ State('start', self.enterStart, self.exitStart, ['waitForOthers']), State('waitForOthers', self.enterWaitForOthers, self.exitWaitForOthers, ['play']), State('play', self.enterPlay, self.exitPlay, ['gameOver']), State('gameOver', self.enterGameOver, self.exitGameOver, ['off']), State('off', self.enterOff, self.exitOff) ], 'off', 'off') self.fsm.enterInitialState() self.cr = cr self.localAv = base.localAvatar self.localAvId = self.localAv.doId self.musicPath = "phase_4/audio/bgm/trolley_song.ogg" self.winSfx = base.loadSfx("phase_4/audio/sfx/MG_win.ogg") self.loseSfx = base.loadSfx("phase_4/audio/sfx/MG_lose.ogg") self.prizeHigh = base.loadSfx("phase_6/audio/sfx/KART_Applause_1.ogg") self.prizeLow = base.loadSfx("phase_6/audio/sfx/KART_Applause_4.ogg") self.music = None self.description = "" self.descDialog = None self.winnerPrize = 0 self.loserPrize = 0 self.round = 0 self.numPlayers = 0 self.winnerMsg = "Winner!\nYou have earned: %s Jellybeans" self.loserMsg = "Loser!\nYou have earned: %s Jellybeans" self.allWinnerMsgs = [ "Nice try!\nYou have earned: %s", "Good job!\nYou have earned: %s", "Way to go!\nYou have earned: %s", "Awesome!\nYou have earned: %s" ] self.timer = None self.timeLbl = None self.alertText = None self.alertPulse = None self.popupSound = None self.gameOverLbl = OnscreenText(text="TIME'S\nUP!", scale=0.25, font=CIGlobals.getMickeyFont(), fg=(1, 0, 0, 1)) self.gameOverLbl.setBin('gui-popup', 60) self.gameOverLbl.hide() return def setNumPlayers(self, num): self.numPlayers = num def getNumPlayers(self): return self.numPlayers def roundOver(self): pass def setRound(self, round): self.round = round def getRound(self): return self.round def getTeamDNAColor(self, team): pass def showAlert(self, text): self.stopPulse() base.playSfx(self.popupSound) self.alertText.setText(text) self.alertPulse = getAlertPulse(self.alertText) self.alertPulse.start() def stopPulse(self): if self.alertPulse: self.alertPulse.finish() self.alertPulse = None def enterFinalScores(self): # Not defined as a state in DistributedMinigame, but you # can define it in a minigame that might need to show scores. self.finalScoreUI.load() self.finalScoreUI.showFinalScores() def exitFinalScores(self): self.finalScoreUI.hideFinalScores() self.finalScoreUI.unload() def finalScores(self, avIdList, scoreList): self.finalScoreUI.handleFinalScores(avIdList, scoreList) def generateHeadPanel(self, gender, head, headtype, color, doId, name): self.headPanels.generate(gender, head, headtype, color, doId, name) def updateHeadPanelValue(self, doId, direction): self.headPanels.updateValue(doId, direction) def setTimerTime(self, time): self.setTime(time) def createTimer(self): Timer.Timer.load(self) def deleteTimer(self): Timer.Timer.unload(self) def setDescription(self, desc): self.description = desc def getDescription(self): return self.description def enterStart(self): self.descDialog = GlobalDialog(style=3, message=self.getDescription(), doneEvent='gameDescAck') self.acceptOnce('gameDescAck', self.handleDescAck) self.descDialog.show() def handleDescAck(self): self.d_ready() self.fsm.request('waitForOthers') def exitStart(self): self.ignore('gameDescAck') self.descDialog.cleanup() del self.descDialog def enterWaitForOthers(self): CIGlobals.showWaitForOthers() def exitWaitForOthers(self): CIGlobals.hideWaitForOthers() def setLoserPrize(self, prize): self.loserPrize = prize def setWinnerPrize(self, prize): self.winnerPrize = prize def getLoserPrize(self): return self.loserPrize def getWinnerPrize(self): return self.winnerPrize def winner(self): self.winSfx.play() self.localAv.b_setAnimState("happy") Sequence(Wait(3.5), Func(self.displayGameOver, "winner")).start() def showPrize(self, amt): self.winSfx.play() self.localAv.b_setAnimState("happy") Sequence(Wait(3.5), Func(self.displayGameOver, "showPrize", amt)).start() def loser(self): self.loseSfx.play() self.localAv.b_setAnimState("neutral") Sequence(Wait(3.5), Func(self.displayGameOver, "loser")).start() def displayGameOver(self, scenario, amt=None): if scenario == "winner": msg = self.winnerMsg % self.winnerPrize self.prizeHigh.play() elif scenario == "loser": msg = self.loserMsg % self.loserPrize self.prizeLow.play() elif scenario == 'showPrize': msg = random.choice(self.allWinnerMsgs) % amt self.prizeHigh.play() self.gameOverDialog = GlobalDialog(message=msg, style=3, doneEvent='gameOverAck') self.acceptOnce('gameOverAck', self.__handleGameOverAck) self.gameOverDialog.show() def deleteGameOverDialog(self): self.ignore('gameOverAck') if hasattr(self, 'gameOverDialog'): self.gameOverDialog.cleanup() del self.gameOverDialog def __handleGameOverAck(self): self.fsm.requestFinalState() Sequence(Func(base.transitions.irisOut, 1.0), Wait(1.2), Func(self.d_leaving), Func(self.headBackToMinigameArea)).start() def headBackToMinigameArea(self): whereName = ZoneUtil.getWhereName(ZoneUtil.MinigameAreaId) loaderName = ZoneUtil.getLoaderName(ZoneUtil.MinigameAreaId) requestStatus = { 'zoneId': ZoneUtil.MinigameAreaId, 'hoodId': ZoneUtil.MinigameArea, 'where': whereName, 'how': 'teleportIn', 'avId': base.localAvatar.doId, 'shardId': None, 'loader': loaderName } self.cr.playGame.hood.fsm.request('quietZone', [requestStatus]) def abort(self): self.headBackToMinigameArea() def load(self, showDesc=True): if showDesc: self.fsm.request('start') base.transitions.irisIn() def d_leaving(self): """ Tell the AI that we are leaving. """ self.sendUpdate("leaving", []) def allPlayersReady(self): self.fsm.request('play') def enterPlay(self): self.playMinigameMusic() def exitPlay(self): self.stopMinigameMusic() def enterOff(self): pass def exitOff(self): pass def enterGameOver(self, winner, winnerDoId, allPrize): if winner: if self.localAvId in winnerDoId: self.winner() else: self.loser() else: self.showPrize(allPrize) def exitGameOver(self): self.deleteGameOverDialog() def gameOver(self, winner=0, winnerDoId=[], allPrize=0): self.fsm.request('gameOver', [winner, winnerDoId, allPrize]) def setMinigameMusic(self, path): self.musicPath = path def getMinigameMusic(self): return self.musicPath def playMinigameMusic(self): self.stopMinigameMusic() self.music = base.loadMusic(self.musicPath) self.music.setLoop(True) self.music.play() def stopMinigameMusic(self): if self.music: self.music.stop() self.music = None def d_ready(self): self.sendUpdate('ready', []) def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) base.minigame = self self.alertText = getAlertText() self.popupSound = base.loadSfx( 'phase_3/audio/sfx/GUI_balloon_popup.ogg') NametagGlobals.setWant2dNametags(False) if not base.localAvatar.walkControls.getCollisionsActive(): base.localAvatar.walkControls.setCollisionsActive(1) def disable(self): self.deleteTimer() base.localAvatar.getGeomNode().setColorScale(VBase4(1, 1, 1, 1)) if hasattr(self, 'gameOverLbl') and self.gameOverLbl is not None: self.gameOverLbl.destroy() self.gameOverLbl = None NametagGlobals.setWant2dNametags(True) base.localAvatar.setPosHpr(0, 0, 0, 0, 0, 0) if hasattr(self, 'fsm'): self.fsm.requestFinalState() del self.fsm self.winSfx = None self.loseSfx = None self.prizeHigh = None self.prizeLow = None if self.headPanels is not None: self.headPanels.delete() self.headPanels = None if self.finalScoreUI is not None: self.finalScoreUI.unload() self.finalScoreUI = None self.numPlayers = None base.minigame = None DistributedObject.DistributedObject.disable(self)
class Place(StateData): notify = directNotify.newCategory("Place") def __init__(self, loader, doneEvent): StateData.__init__(self, doneEvent) self.loader = loader self.zoneId = None self.track = None self.interior = False self.firstPerson = FirstPerson() self.snowEffect = SnowEffect(self) self.lastBookPage = 2 self.useFirstPerson = config.GetBool('want-firstperson-battle') self.lampLights = [] self.lampLightColor = VBase4(255 / 255.0, 255 / 255.0, 218 / 255.0, 1.0) return def __handleChatInputOpened(self): if base.localAvatarReachable(): currentState = self.fsm.getCurrentState() if currentState and currentState.getName() == 'walk': base.localAvatar.disableAvatarControls(True) def __handleChatInputClosed(self): if base.localAvatarReachable(): currentState = self.fsm.getCurrentState() if currentState and currentState.getName() == 'walk': base.localAvatar.enableAvatarControls(True) def __acceptEvents(self): self.accept(CHAT_WINDOW_OPENED_EVENT, self.__handleChatInputOpened) self.accept(CHAT_WINDOW_CLOSED_EVENT, self.__handleChatInputClosed) def __ignoreEvents(self): self.ignore(CHAT_WINDOW_OPENED_EVENT) self.ignore(CHAT_WINDOW_CLOSED_EVENT) def maybeUpdateAdminPage(self): if self.fsm: currentState = self.fsm.getCurrentState() if currentState and currentState.getName() == 'shtickerBook': if hasattr(self, 'shtickerBookStateData'): if self.shtickerBookStateData.getCurrentPage( ) and self.shtickerBookStateData.getCurrentPage( ).title == 'Admin Page': if base.cr.playGame.suitManager: text2Change2 = 'Turn Suit Spawner ' if base.cr.playGame.suitManager.getSpawner(): text2Change2 += 'Off' else: text2Change2 += 'On' self.shtickerBookStateData.getCurrentPage( ).suitSpawnerBtn['text'] = text2Change2 # Used to disable all GUI interaction. def __disableInteraction(self): if base.localAvatar.invGui: base.localAvatar.invGui.disable() base.localAvatar.disableLaffMeter() def enterStart(self): pass def exitStart(self): pass def enterFinal(self): pass def exitFinal(self): pass def enter(self): StateData.enter(self) base.localAvatar.createChatInput() def exit(self): self.__disableInteraction() del self.lastBookPage base.localAvatar.disableChatInput() StateData.exit(self) def enterTrolleyOut(self, requestStatus): base.localAvatar.walkControls.setCollisionsActive(0) base.transitions.fadeScreen(1.0) prevZone = requestStatus['prevZoneId'] slot = requestStatus['slot'] for trolley in base.cr.doFindAll("DistributedBattleTrolley"): if trolley.toZone == prevZone: trolley.localAvOnTrolley = True CIGlobals.showWaitForOthers() trolley.sendUpdate('arrivedInTrolley', [slot]) def exitTrolleyOut(self): pass def enterDoorIn(self, distDoor): requestStatus = {} requestStatus['zoneId'] = distDoor.getToZone() requestStatus['hoodId'] = base.cr.playGame.hood.id requestStatus['how'] = 'doorOut' requestStatus['shardId'] = None requestStatus['doorIndex'] = distDoor.getDoorIndex() foundBlock = False for interior in base.cr.doFindAll("DistributedToonInterior"): if interior.zoneId == base.localAvatar.zoneId: foundBlock = True requestStatus['block'] = interior.getBlock() break if not foundBlock: requestStatus['block'] = distDoor.getBlock() requestStatus['where'] = ZoneUtil.getWhereName(requestStatus['zoneId']) requestStatus['loader'] = base.cr.playGame.hood.fsm.getCurrentState( ).getName() requestStatus['avId'] = base.localAvatar.doId self.acceptOnce('DistributedDoor_localAvatarWentInDoor', self.handleDoorInDone, [requestStatus]) self.acceptOnce('DistributedDoor_localAvatarGoingInDoor', base.transitions.irisOut) base.localAvatar.doFirstPersonCameraTransition() def exitDoorIn(self): self.ignore('DistributedDoor_localAvatarWentInDoor') self.ignore('DistributedDoor_localAvatarGoingInDoor') def handleDoorInDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def __waitOnDoor(self, door, task): if door.ready: self.__doorReady(door) return task.done return task.cont def enterDoorOut(self, requestStatus): base.localAvatar.d_clearSmoothing() base.localAvatar.stopPosHprBroadcast() base.localAvatar.walkControls.setCollisionsActive(0) block = requestStatus['block'] zoneId = requestStatus['zoneId'] doorIndex = requestStatus['doorIndex'] doorToExitFrom = None for door in base.cr.doFindAll("DistributedDoor"): if door.zoneId == zoneId: if door.getBlock() == block: if door.getDoorIndex() == doorIndex: doorToExitFrom = door break if not doorToExitFrom: self.notify.error('Could not find a DistributedDoor to exit from!') elif not doorToExitFrom.ready: base.taskMgr.add(self.__waitOnDoor, "Place.waitOnDoor", extraArgs=[doorToExitFrom], appendTask=True) return self.__doorReady(doorToExitFrom) def __doorReady(self, door): door.sendUpdate('requestExit', []) self.nextState = 'walk' self.acceptOnce('DistributedDoor_localAvatarCameOutOfDoor', self.handleDoorOutDone) def exitDoorOut(self): base.taskMgr.remove("Place.waitOnDoor") self.ignore('DistributedDoor_localAvatarCameOutOfDoor') def handleDoorOutDone(self): base.transitions.irisIn() base.localAvatar.walkControls.setCollisionsActive(1) self.fsm.request(self.nextState) def enterShtickerBook(self): base.localAvatar.createLaffMeter() base.localAvatar.startSmartCamera() base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() if base.localAvatar.isFirstPerson(): # Don't wait for an animation we can't see, open the book now. self.enterShtickerBookGui() else: base.localAvatar.b_setAnimState('openBook', self.enterShtickerBookGui) def enterShtickerBookGui(self): doneEvent = 'shtickerBookDone' self.shtickerBookStateData = ShtickerBook(doneEvent) self.acceptOnce(doneEvent, self.__shtickerBookDone) self.shtickerBookStateData.load() self.shtickerBookStateData.enter(self.lastBookPage) base.localAvatar.showBookButton(1) base.localAvatar.b_setAnimState('readBook') base.localAvatar.showFriendButton() NametagGlobals.setWantActiveNametags(True) NametagGlobals.makeTagsReady() self.acceptOnce('escape-up', base.localAvatar.bookButtonClicked, [0]) def __shtickerBookDone(self): self.hideFriendsStuff() NametagGlobals.setWantActiveNametags(False) NametagGlobals.makeTagsInactive() self.ignore('escape-up') doneStatus = self.shtickerBookStateData.getDoneStatus() base.localAvatar.hideBookButton() self.shtickerBookStateData.exit() data = [] if doneStatus['mode'] == 'exit': data = [self.__handleBookCloseExit, []] elif doneStatus['mode'] == 'teleport': data = [self.__handleBookCloseTeleport, [doneStatus]] elif doneStatus['mode'] == 'resume': data = [self.__handleBookCloseResume, [doneStatus]] elif doneStatus['mode'] == 'switchShard': data = [self.__handleBookCloseSwitchShard, [doneStatus]] if base.localAvatar.isFirstPerson(): # Don't wait for an animation we can't see. data[0](*data[1]) else: base.localAvatar.b_setAnimState('closeBook', data[0], data[1]) def __handleBookCloseSwitchShard(self, requestStatus): base.localAvatar.b_setAnimState('teleportOut', self.__handleBookSwitchShard, [requestStatus]) def __handleBookSwitchShard(self, requestStatus): params = [] params.append(requestStatus['shardId']) params.append(base.cr.playGame.hood.id) params.append(ZoneUtil.getZoneId(base.cr.playGame.hood.id)) params.append(base.localAvatar.doId) base.cr.gameFSM.request('switchShards', params) def __handleBookCloseResume(self, doneStatus): if doneStatus.get('callback'): doneStatus['callback'](*doneStatus.get("extraArgs", [])) if base.localAvatar.isFirstPerson(): base.localAvatar.getGeomNode().hide() self.fsm.request('walk', [0, 0]) def __handleBookCloseTeleport(self, requestStatus): self.fsm.request('teleportOut', [requestStatus]) def __teleportOutDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def __handleBookCloseExit(self): base.localAvatar.b_setAnimState('teleportOut', self.__handleBookExitTeleport) def __handleBookExitTeleport(self): base.transitions.fadeOut(0.0) base.cr.gameFSM.request('closeShard') def exitShtickerBook(self): base.localAvatar.stopPosHprBroadcast() base.localAvatar.disableLaffMeter() self.ignore(self.shtickerBookStateData.doneEvent) self.shtickerBookStateData.exit() self.shtickerBookStateData.unload() del self.shtickerBookStateData base.localAvatar.hideBookButton() self.hideFriendsStuff() NametagGlobals.setWantActiveNametags(False) NametagGlobals.makeTagsInactive() self.ignore('escape-up') def enterStop(self, doNeutral=1): if doNeutral: base.localAvatar.b_setAnimState('neutral') base.localAvatar.createLaffMeter() if base.localAvatar.getBattleZone(): base.localAvatar.enableGags(andKeys=0) def exitStop(self): self.__disableInteraction() if base.localAvatar.getBattleZone(): base.localAvatar.disableGags() def load(self): StateData.load(self) self.walkDoneEvent = "walkDone" self.walkStateData = PublicWalk(self.fsm, self.walkDoneEvent) self.walkStateData.load() if not self.interior and ( base.cr.holidayManager.getHoliday() == HolidayType.CHRISTMAS or base.cr.playGame.getCurrentWorldName() == 'BRHood'): self.snowEffect.load() self.__acceptEvents() def unload(self): StateData.unload(self) if not self.interior and ( base.cr.holidayManager.getHoliday() == HolidayType.CHRISTMAS or base.cr.playGame.getCurrentWorldName() == 'BRHood'): self.snowEffect.unload() del self.walkDoneEvent self.walkStateData.unload() del self.walkStateData del self.loader del self.snowEffect base.waterReflectionMgr.clearWaterNodes() self.__ignoreEvents() def enterTeleportIn(self, requestStatus): self.nextState = requestStatus.get('nextState', 'walk') if requestStatus['avId'] != base.localAvatar.doId: av = base.cr.doId2do.get(requestStatus['avId']) if av: base.localAvatar.gotoNode(av) base.localAvatar.b_setChat( ChatGlobals.getGreeting(av.getName())) base.localAvatar.startPosHprBroadcast() base.localAvatar.b_setAnimState('teleportIn', callback=self.teleportInDone) base.localAvatar.d_broadcastPositionNow() base.localAvatar.b_setParent(CIGlobals.SPRender) base.transitions.irisIn() def exitTeleportIn(self): base.localAvatar.stopPosHprBroadcast() return def teleportInDone(self): if hasattr(self, 'fsm'): self.fsm.request(self.nextState, [1]) def enterAcknowledgeDeath(self, foo=0): message = "You were defeated by the Cogs! Collect treasures in the Playground to refill your Laff meter." self.dialog = GlobalDialog(message=message, style=3, doneEvent='ackDeathDone') self.dialog.show() self.acceptOnce('ackDeathDone', self.handleAckDeathDone) def handleAckDeathDone(self): self.fsm.request('walk', [1]) def exitAcknowledgeDeath(self): self.ignore('ackDeathDone') self.dialog.cleanup() del self.dialog def enterDied(self, requestStatus, callback=None): if callback is None: callback = self.__diedDone base.localAvatar.createLaffMeter() base.localAvatar.b_setAnimState('died', callback, [requestStatus]) def __diedDone(self, requestStatus): self.doneStatus = requestStatus messenger.send(self.doneEvent) def exitDied(self): base.localAvatar.disableLaffMeter() def enterWalk(self, teleportIn=0, wantMouse=1): self.walkStateData.enter(wantMouse) if teleportIn == 0: self.walkStateData.fsm.request('walking') self.acceptOnce(self.walkDoneEvent, self.handleWalkDone) self.walkStateData.fsm.request('walking') self.watchTunnelSeq = Sequence(Wait(1.0), Func(LinkTunnel.globalAcceptCollisions)) self.watchTunnelSeq.start() NametagGlobals.setWantActiveNametags(True) NametagGlobals.makeTagsReady() if base.localAvatar.getBattleZone(): if self.useFirstPerson: base.localAvatar.stopSmartCamera() camera.setPos(base.localAvatar.smartCamera.firstPersonCamPos) self.firstPerson.start() self.firstPerson.reallyStart() self.firstPerson.disableMouse() base.localAvatar.getGeomNode().show() base.localAvatar.getShadow().hide() base.localAvatar.find('**/torso-top').hide() base.localAvatar.find('**/torso-bot').hide() base.localAvatar.getPart('head').hide() base.localAvatar.setBusy(1) else: base.localAvatar.setBusy(0) base.localAvatar.enablePicking() base.localAvatar.showFriendButton() base.localAvatar.questManager.enableShowQuestsHotkey() messenger.send(CIGlobals.ENTER_WALK_EVENT, []) def hideFriendsStuff(self): base.localAvatar.hideFriendButton() if base.localAvatar.friendsList: base.localAvatar.friendsList.fsm.requestFinalState() if base.localAvatar.panel: base.localAvatar.panel.fsm.requestFinalState() def exitWalk(self): self.walkStateData.exit() self.ignore(self.walkDoneEvent) if base.cr.playGame.hood.titleText != None: base.cr.playGame.hood.hideTitleText() if hasattr(self, 'watchTunnelSeq'): self.watchTunnelSeq.pause() del self.watchTunnelSeq NametagGlobals.setWantActiveNametags(False) NametagGlobals.makeTagsInactive() if base.localAvatar.getBattleZone(): base.localAvatar.setBusy(1) base.localAvatar.disablePicking() self.hideFriendsStuff() if base.localAvatar.invGui: base.localAvatar.invGui.disable() if base.localAvatar.questManager: base.localAvatar.questManager.disableShowQuestsHotkey() if self.useFirstPerson: if base.localAvatar.getBattleZone(): self.firstPerson.enableMouse() self.firstPerson.end() self.firstPerson.reallyEnd() base.localAvatar.getShadow().show() base.localAvatar.find('**/torso-top').show() base.localAvatar.find('**/torso-bot').show() base.localAvatar.getPart('head').show() return def handleWalkDone(self, doneStatus): pass def enterTeleportOut(self, requestStatus, callback=None): if not callback: callback = self.__teleportOutDone base.localAvatar.startPosHprBroadcast() base.localAvatar.d_broadcastPositionNow() base.localAvatar.b_setAnimState('teleportOut', callback, [requestStatus]) def exitTeleportOut(self): base.localAvatar.disableLaffMeter() base.localAvatar.stopPosHprBroadcast() def enterTunnelIn(self, linkTunnel): zoneId = linkTunnel.data['zoneId'] base.localAvatar.sendUpdate('goThroughTunnel', [zoneId, 0]) base.localAvatar.playMovementSfx('run') requestStatus = {} requestStatus['zoneId'] = linkTunnel.data['zoneId'] # Goes from safe zone to street. if linkTunnel.__class__.__name__ == "SafeZoneLinkTunnel": requestStatus['where'] = 'street' requestStatus['loader'] = 'townLoader' requestStatus['hoodId'] = base.cr.playGame.hood.id requestStatus['shardId'] = None requestStatus['avId'] = base.localAvatar.doId requestStatus['how'] = 'tunnelOut' requestStatus['fromZone'] = base.localAvatar.zoneId # Goes from street to safe zone. elif linkTunnel.__class__.__name__ == "StreetLinkTunnel": requestStatus['where'] = 'playground' requestStatus['loader'] = 'safeZoneLoader' requestStatus['hoodId'] = base.cr.playGame.hood.id requestStatus['shardId'] = None requestStatus['avId'] = base.localAvatar.doId requestStatus['how'] = 'tunnelOut' requestStatus['fromZone'] = base.localAvatar.zoneId # Goes from street to street. elif linkTunnel.__class__.__name__ == "NeighborhoodLinkTunnel": requestStatus['where'] = 'street' requestStatus['loader'] = 'townLoader' hoodId = ZoneUtil.getHoodId(linkTunnel.data['zoneId'], 1) requestStatus['hoodId'] = hoodId requestStatus['shardId'] = None requestStatus['avId'] = base.localAvatar.doId requestStatus['how'] = 'tunnelOut' requestStatus['fromZone'] = base.localAvatar.zoneId base.localAvatar.goThroughTunnel(zoneId, 0, requestStatus) def exitTunnelIn(self): base.localAvatar.playMovementSfx(None) base.localAvatar.reparentTo(hidden) #base.localAvatar.walkControls.setCollisionsActive(1) def enterTunnelOut(self, requestStatus): zone = requestStatus['fromZone'] base.localAvatar.sendUpdate('goThroughTunnel', [zone, 1]) base.localAvatar.playMovementSfx('run') self.nextState = requestStatus.get('nextState', 'walk') base.localAvatar.goThroughTunnel(zone, 1) def exitTunnelOut(self): base.localAvatar.playMovementSfx(None) del self.nextState def enterNoAccessFA(self): base.localAvatar.startSmartCamera() base.localAvatar.createLaffMeter() noAccess = "Watch out!\n\nThis neighborhood is too dangerous for your Toon. Complete Quests to unlock this neighborhood." self.dialog = GlobalDialog(noAccess, 'noAccessAck', Ok) self.acceptOnce('noAccessAck', self.__handleNoAccessAck) self.dialog.show() def __handleNoAccessAck(self): self.fsm.request('walk') def exitNoAccessFA(self): base.localAvatar.disableLaffMeter() if hasattr(self, 'dialog'): self.dialog.cleanup() del self.dialog
def enterStart(self): self.descDialog = GlobalDialog(style=3, message=self.getDescription(), doneEvent='gameDescAck') self.acceptOnce('gameDescAck', self.handleDescAck) self.descDialog.show()
class AboutCategory(OptionsCategory, DirectObject): Name = "About" AppendOptions = False ApplyCancelButtons = False WantTitle = False def __init__(self, page): OptionsCategory.__init__(self, page) DirectObject.__init__(self) self.logoNode, self.logoImg = CIGlobals.getLogoImage( self.page.book, 0.75, (0, 0, 0.48)) self.creditsScreen = None self.exitConfirmDlg = None font = CIGlobals.getToonLogoFont() self.gVersionText = OnscreenText(metadata.getBuildInformation(), parent=self.page.book, pos=(0, 0.15, 0.15), font=font, fg=(1, 1, 1, 1)) self.gBuildDate = OnscreenText(text=metadata.BUILD_DATE, parent=self.page.book, pos=(0, 0.085, 0.085), scale=0.06, font=font, fg=(1, 1, 1, 1)) self.eVersionText = OnscreenText(text="Engine Version {0}".format( PandaSystem.getVersionString()), parent=self.page.book, pos=(0, -0.05), font=font, fg=(1, 1, 1, 1)) self.eBuildDate = OnscreenText(text=PandaSystem.getBuildDate(), parent=self.page.book, pos=(0, -0.115), scale=0.06, font=font, fg=(1, 1, 1, 1)) self.exitToontown = CIGlobals.makeDefaultBtn( "Exit Toontown", pos=(-0.62, -0.62, -0.62), parent=self.page.book, scale=1.2, command=self.showConfirmDlg, geom_scale=(0.8, 0.8, 0.8)) self.credits = CIGlobals.makeDefaultBtn("Credits", pos=(0.0, 0.5, -0.62), parent=self.page.book, scale=1.2, command=self.rollCredits, geom_scale=(0.8, 0.8, 0.8)) def showConfirmDlg(self): self.hideConfirmDlg() self.acceptOnce('exitToontownChoice', self.__handleExitToontownChoice) self.exitConfirmDlg = GlobalDialog('Exit Toontown?', doneEvent='exitToontownChoice', style=YesCancel) self.exitConfirmDlg.show() def hideConfirmDlg(self): self.ignore('exitToontownChoice') if self.exitConfirmDlg: self.exitConfirmDlg.cleanup() self.exitConfirmDlg = None def __handleExitToontownChoice(self): if self.exitConfirmDlg.getValue(): self.page.book.finished("exit") self.hideConfirmDlg() def rollCredits(self): base.muteMusic() base.muteSfx() base.transitions.fadeOut(1.0) base.taskMgr.doMethodLater(1.1, self.__rollCreditsTask, "doRollCredits") def __rollCreditsTask(self, task): self.creditsScreen = Credits() self.creditsScreen.setup() base.localAvatar.toggleAspect2d() self.page.book.hide() self.acceptOnce('credits-Complete', self.showBook) base.transitions.fadeIn(1.0) return task.done def showBook(self): self.page.book.show() base.localAvatar.toggleAspect2d() def cleanup(self): self.hideConfirmDlg() if hasattr(self, 'gVersionText'): self.gVersionText.destroy() del self.gVersionText if hasattr(self, 'gBuildDate'): self.gBuildDate.destroy() del self.gBuildDate if hasattr(self, 'eVersionText'): self.eVersionText.destroy() del self.eVersionText if hasattr(self, 'eBuildDate'): self.eBuildDate.destroy() del self.eBuildDate if hasattr(self, 'logoImg'): self.logoImg.destroy() del self.logoImg if hasattr(self, 'logoNode'): self.logoNode.removeNode() del self.logoNode if hasattr(self, 'exitToontown'): self.exitToontown.destroy() del self.exitToontown if hasattr(self, 'credits'): self.credits.destroy() del self.credits if hasattr(self, 'creditsScreen'): self.creditsScreen = None del self.creditsScreen
class InitialLoad(LoadUtility): def __init__(self, callback): LoadUtility.__init__(self, callback) phasesToScan = ["phase_3/models"] self.models = FileUtility.findAllModelFilesInVFS(phasesToScan) self.version_lbl = None self.clouds = None self.barShadow = None def createGui(self): self.version_lbl = OnscreenText(text="Version {0} (Build {1} : {2})".format(metadata.VERSION, metadata.BUILD_NUMBER, metadata.BUILD_TYPE), scale=0.06, pos=(-1.32, -0.97, -0.97), align=TextNode.ALeft, fg = (1, 1, 1, 1), shadow = (0, 0, 0, 0), font = CIGlobals.getToonLogoFont()) gui = loader.loadModel('phase_3/models/gui/loading-background.bam') gui.find('**/fg').removeNode() self.clouds = OnscreenImage(image = gui.find("**/bg"), parent = render2d) gui.removeNode() def load(self): loader.progressScreen.bg_img.hide() loader.progressScreen.bgm.hide() loader.progressScreen.bg.hide() loader.progressScreen.toontipFrame.hide() loader.progressScreen.logoNode.setPos(0, 0, 0) loader.progressScreen.logoNode.setScale(1.8) self.createGui() loader.beginBulkLoad('init', 'init', len(self.models), 0, False) if base.config.GetBool('precache-assets', True): base.precacheStuff() self.done() # LoadUtility.load(self) def done(self): # Load C++ tournament music stuff. #ccoginvasion.CTMusicData.initialize_chunk_data() #ccoginvasion.CTMusicManager.spawn_load_tournament_music_task() taskMgr.add(self.__pollTournyMusic, "pollTournyMusic") self.dialog = GlobalDialog("Please wait...") self.dialog.show() def __pollTournyMusic(self, task): # Wait for the asynchronous load of tournament music to finish. #if ccoginvasion.CTMusicManager.is_loaded(): if True: self.dialog.cleanup() del self.dialog LoadUtility.done(self) loader.endBulkLoad('init') return task.done return task.cont def destroy(self): self.version_lbl.destroy() self.version_lbl = None self.clouds.destroy() self.clouds = None loader.progressScreen.bg_img.show() loader.progressScreen.bgm.show() loader.progressScreen.bg.show() loader.progressScreen.toontipFrame.show() loader.progressScreen.logoNode.setZ(loader.progressScreen.defaultLogoZ) loader.progressScreen.logoNode.setScale(loader.progressScreen.defaultLogoScale) LoadUtility.destroy(self)
class DistributedDroppableCollectableBackpack( DistributedDroppableCollectableObject): notify = directNotify.newCategory( "DistributedDroppableCollectableBackpack") MSG_CONFIRM = "This backpack contains:\n\n%s\n\nAre you sure you want to use this backpack?" MSG_UNZIPPING = "Unzipping..." UNZIP_TIME = 6.0 def __init__(self, cr): try: self.DistributedDroppableCollectableBackpack_initialized return except: self.DistributedDroppableCollectableBackpack_initialized = 1 DistributedDroppableCollectableObject.__init__(self, cr) self.backpack = None self.dropShadow = None self.bp = None self.pickUpDialog = None self.unzippingDialog = None self.soundUnzipping = None self.rotateTaskName = 'Rotate Pack' self.rotateSpeed = 30 self.backpackScale = 0.35 def setBP(self, bp): self.bp = bp def getBP(self): return self.bp def removePickUpGui(self): if self.pickUpDialog: self.pickUpDialog.cleanup() self.pickUpDialog = None def removeUnzipGui(self): if self.unzippingDialog: self.unzippingDialog.cleanup() self.unzippingDialog = None def __showPickUpGui(self): gagNameArray = [] gagString = "%s, %s, %s, %s" for gagId in self.getBP(): gagNameArray.append(GagGlobals.gagIds.get(gagId)) self.pickUpDialog = GlobalDialog(message=self.MSG_CONFIRM % (gagString % (gagNameArray[0], gagNameArray[1], gagNameArray[2], gagNameArray[3])), doneEvent='pickUpGui-Done', style=1) self.pickUpDialog.show() self.acceptOnce('pickUpGui-Done', self.__handleBackpackChoice) def __handleBackpackChoice(self): value = self.pickUpDialog.getValue() self.removePickUpGui() if value: self.__showUnzippingGui() else: self.cr.playGame.getPlace().fsm.request('walk') self.acceptCollisions() def __showUnzippingGui(self): self.unzippingDialog = GlobalDialog(message=self.MSG_UNZIPPING, style=0) self.unzippingDialog.show() self.soundUnzipping = base.loadSfx( "phase_3.5/audio/sfx/ci_s_bpunzip.ogg") SoundInterval(self.soundUnzipping).start() base.taskMgr.doMethodLater(self.UNZIP_TIME, self.__unzipWaitDone, 'DDCBackpack-unzipWaitDone') def __unzipWaitDone(self, task): self.sendUpdate('collectedObject', []) self.removeUnzipGui() self.cr.playGame.getPlace().fsm.request('walk') return Task.done def __rotateBackpack(self, task): if self.backpack: self.backpack.setH(task.time * self.rotateSpeed) return Task.cont return Task.done def loadObject(self): self.removeObject() self.backpack = loader.loadModel( "phase_4/models/accessories/tt_m_chr_avt_acc_pac_gags.bam") self.backpack.setScale(self.backpackScale) self.backpack.setZ(1.4) self.backpack.setH(random.uniform(0.0, 360.0)) self.backpack.reparentTo(self) self.dropShadow = loader.loadModel( 'phase_3/models/props/drop_shadow.bam') self.dropShadow.setColor(0, 0, 0, 0.5) self.dropShadow.setScale(0.25) self.dropShadow.setZ(0.025) self.dropShadow.flattenLight() self.dropShadow.reparentTo(self) base.taskMgr.add(self.__rotateBackpack, self.rotateTaskName) def removeObject(self): if self.backpack: base.taskMgr.remove(self.rotateTaskName) self.dropShadow.removeNode() self.backpack.removeNode() self.dropShadow = None self.backpack = None def handleCollisions(self, entry): self.cr.playGame.getPlace().fsm.request('stop') self.__showPickUpGui() def disable(self): base.taskMgr.remove('DDCBackpack-unzipWaitDone') self.removeUnzipGui() self.removePickUpGui() if self.cr.playGame.getPlace(): if self.cr.playGame.getPlace().fsm: if self.cr.playGame.getPlace().fsm.getCurrentState(): if self.cr.playGame.getPlace().fsm.getCurrentState( ).getName() == "stop": self.cr.playGame.getPlace().fsm.request('walk') self.soundUnzipping = None DistributedDroppableCollectableObject.disable(self)
class AdminPage(BookPage): def __init__(self, book): BookPage.__init__(self, book, 'Admin Panel') self.fsm = ClassicFSM( 'AdminPage', [ State('off', self.enterOff, self.exitOff), State('basePage', self.enterBasePage, self.exitBasePage), State('kickSection', self.enterKickSection, self.exitKickSection), #State('clickOnToon', self.enterClickOnToon, self.exitClickOnToon), State('sysMsgSection', self.enterSysMsgSection, self.exitSysMsgSection) ], 'off', 'off') self.fsm.enterInitialState() def load(self): BookPage.load(self) icons = loader.loadModel('phase_4/models/gui/tfa_images.bam') self.icon = icons.find('**/hq-dialog-image') icons.detachNode() def enterOff(self): pass def exitOff(self): pass def enter(self): BookPage.enter(self) self.fsm.request('basePage') def exit(self): self.fsm.requestFinalState() BookPage.exit(self) def unload(self): del self.book del self.fsm BookPage.unload(self) def enterSysMsgSection(self): geom = CIGlobals.getDefaultBtnGeom() self.infoLbl = OnscreenText( text="Inform all online players about something.", pos=(0, 0.45)) self.msgEntry = DirectEntry( initialText="System Message...", scale=0.055, width=15, numLines=4, command=self.sendSystemMessageCommand, focusInCommand=base.localAvatar.chatInput.disableKeyboardShortcuts, focusOutCommand=base.localAvatar.chatInput.enableKeyboardShortcuts, pos=(-0.4, 0, 0)) self.sendBtn = DirectButton( geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Send", pos=(0, 0, -0.35), text_pos=(0, -0.01), command=self.sendSystemMessageCommand, ) self.cancelBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Cancel", pos=(-0.45, 0.15, -0.55), text_pos=(0, -0.01), command=self.fsm.request, extraArgs=['basePage']) # Occasionally, extra arguments are sent and this extra variable must be here to capture them. def sendSystemMessageCommand(self, _=None): msg = self.msgEntry.get() DISTRICT_WIDE_MSG(msg) self.fsm.request('basePage') def exitSysMsgSection(self): self.infoLbl.destroy() del self.infoLbl self.msgEntry.destroy() del self.msgEntry self.sendBtn.destroy() del self.sendBtn self.cancelBtn.destroy() del self.cancelBtn def enterKickSection(self): geom = CIGlobals.getDefaultBtnGeom() self.infoLbl = OnscreenText(text="Kick or Ban?", pos=(0, 0.45)) self.kickBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Kick", pos=(0, 0, 0.1), text_pos=(0, -0.01), command=self.book.finishedResume, extraArgs=[KickBanDialog, [0]]) self.banBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Ban", pos=(0, 0, 0.0), text_pos=(0, -0.01), command=self.book.finishedResume, extraArgs=[KickBanDialog, [1]]) self.cancelBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Cancel", pos=(-0.45, 0.15, -0.45), text_pos=(0, -0.01), command=self.fsm.request, extraArgs=['basePage']) def exitKickSection(self): self.banBtn.destroy() del self.banBtn self.infoLbl.destroy() del self.infoLbl self.cancelBtn.destroy() del self.cancelBtn self.kickBtn.destroy() del self.kickBtn def enterBasePage(self): geom = CIGlobals.getDefaultBtnGeom() self.ghostBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle Ghost", pos=(-0.45, 0.15, 0.5), text_pos=(0, -0.01), command=TOGGLE_GHOST) self.bgBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle Background", pos=(-0.45, 0.15, 0.40), text_pos=(0, -0.01), command=self.toggleBackground) self.idBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle Player Ids", pos=(-0.45, 0.15, 0.3), text_pos=(0, -0.01), command=TOGGLE_PLAYER_IDS) self.kickBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Kick/Ban Player", pos=(0.45, 0.15, 0.5), text_pos=(0, -0.01), command=self.openKickPage) self.systemMsgBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="System Message", pos=(-0.45, 0.15, 0.1), text_pos=(0, -0.01), command=self.openSysMsgPage) self.oobeBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle OOBE", pos=(-0.45, 0.15, 0.2), text_pos=(0, -0.01), command=base.oobe) self.directBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Start DIRECT", pos=(-0.45, 0.15, 0.1), text_pos=(0, -0.01), command=self.doStartDirect) self.pstatsBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle PStats", pos=(-0.45, 0.15, 0.0), text_pos=(0, -0.01), command=self.togglePStats) self.pingBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle Ping", pos=(-0.45, 0.15, -0.1), text_pos=(0, -0.01), command=base.cr.togglePing) self.tokenBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Modify Access Level", pos=(0.45, 0.15, 0.4), text_pos=(0, -0.01), command=self.book.finishedResume, extraArgs=[AdminTokenDialog, []]) self.worldBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Give World Access", pos=(0.45, 0.15, 0.3), text_pos=(0, -0.01), command=self.book.finishedResume, extraArgs=[WorldAccessDialog, []]) self.allGagsBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Restock All Gags", pos=(0.45, 0.15, 0.2), text_pos=(0, -0.01), command=SEND_REQ_UNLOCK_GAGS) self.allLaffBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Refill Laff", pos=(0.45, 0.15, 0.1), text_pos=(0, -0.01), command=SEND_REQ_REFILL_LAFF) self.physDbgBtn = DirectButton(geom=geom, text_scale=0.039, relief=None, scale=1.0, text="Toggle Physics Debug", pos=(0.45, 0.15, 0.0), text_pos=(0, -0.01), command=self.togglePhysDbg) self.analyzeBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Analyze Scene", pos=(0.45, 0.15, -0.1), text_pos=(0, -0.01), command=self.doAnalyzeScene) self.listBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="List Scene", pos=(0.45, 0.15, -0.2), text_pos=(0, -0.01), command=render.ls) self.noClipBtn = DirectButton(geom=geom, text_scale=0.04, relief=None, scale=1.0, text="Toggle No Clip", pos=(0.45, 0.15, -0.3), text_pos=(0, -0.01), command=self.toggleNoClip) base.cr.playGame.getPlace().maybeUpdateAdminPage() del geom def doStartDirect(self): base.startTk() base.startDirect() def doAnalyzeScene(self): render.analyze() ls = LineStream() sga = SceneGraphAnalyzer() sga.addNode(render.node()) sga.write(ls) text = "" while ls.isTextAvailable(): text += ls.getLine() + "\n" self.acceptOnce('analyzedone', self.__handleAnalyzeDone) self.analyzeDlg = GlobalDialog(message=text, style=Ok, doneEvent='analyzedone', text_scale=0.05) self.analyzeDlg.show() def __handleAnalyzeDone(self): self.analyzeDlg.cleanup() del self.analyzeDlg def toggleNoClip(self): ncl = not base.localAvatar.walkControls.controller.noClip base.localAvatar.walkControls.controller.noClip = ncl if ncl: base.cr.myDistrict.systemMessage("No Clip Enabled") else: base.cr.myDistrict.systemMessage("No Clip Disabled") def togglePhysDbg(self): base.setPhysicsDebug(not base.physicsDbgFlag) def togglePStats(self): if PStatClient.isConnected(): PStatClient.disconnect() else: # in production, show stats viewer on the server if base.config.GetBool("pstats-view-on-server", False): PStatClient.connect("127.0.0.1" if not metadata.IS_PRODUCTION else "gameserver.coginvasion.online") else: PStatClient.connect("127.0.0.1") def toggleBackground(self): if render.isHidden(): render.show() else: render.hide() if self.book.isBackgroundHidden(): self.book.show() self.book.setBackgroundHidden(False) else: self.book.hide() self.book.setBackgroundHidden(True) def openKickPage(self): self.fsm.request('kickSection') def openSysMsgPage(self): self.fsm.request('sysMsgSection') def exitBasePage(self): self.noClipBtn.destroy() del self.noClipBtn self.systemMsgBtn.destroy() del self.systemMsgBtn self.idBtn.destroy() del self.idBtn self.kickBtn.destroy() del self.kickBtn self.bgBtn.destroy() del self.bgBtn self.ghostBtn.destroy() del self.ghostBtn self.oobeBtn.destroy() del self.oobeBtn self.tokenBtn.destroy() del self.tokenBtn self.worldBtn.destroy() del self.worldBtn self.allGagsBtn.destroy() del self.allGagsBtn self.allLaffBtn.destroy() del self.allLaffBtn self.physDbgBtn.destroy() del self.physDbgBtn self.analyzeBtn.destroy() del self.analyzeBtn if hasattr(self, 'analyzeDlg'): self.ignore('analyzedone') self.analyzeDlg.cleanup() del self.analyzeDlg self.directBtn.destroy() del self.directBtn self.listBtn.destroy() del self.listBtn self.pstatsBtn.destroy() del self.pstatsBtn self.pingBtn.destroy() del self.pingBtn