class WaveGUI(NodePath): def __init__(self): NodePath.__init__(self, 'wave-gui') self.reparentTo(base.a2dBottomCenter) self.setBin('fixed', 60) self.setTransparency(True, 1) self.setAlphaScale(0.75, 1) self.setZ(0.1) self.frame = DirectFrame(image='materials/ui/wave_ui_base.png', parent=self, relief=None, image_scale=(.373, 1, .094)) self.waveText = OnscreenText(text="Wave 4", pos=(0, 0.0175, 0), scale=0.06, parent=self.frame) self.progress = DirectWaitBar(scale=(.324, 1, .3), relief=None, barColor=(1, 0.75, 0, 1), parent=self.frame, pos=(0, 0, -0.0293)) self.progress.setBin('fixed', 61) self.progress['range'] = 50 self.progress['value'] = 35 self.progressText = OnscreenText(text=str(self.progress['value']) + " / " + str(self.progress['range']), scale=0.04, parent=self.frame, pos=(0, -0.04, 0)) self.progressText.setBin('fixed', 62) self.hide() def doHide(self): Sequence( LerpColorScaleInterval(self, 1.0, (1, 1, 1, 0), (1, 1, 1, 0.75), override=1), Func(self.hide)).start() def doShow(self): Sequence( Func(self.show), LerpColorScaleInterval(self, 1.0, (1, 1, 1, 0.75), (1, 1, 1, 0), override=1)).start() def incProgress(self): self.adjustProgress(self.progress['value'] + 1) def adjustForWave(self, waveNum, suits): self.waveText['text'] = "Wave {0}".format(waveNum) self.progress['range'] = suits self.adjustProgress(0) def adjustProgress(self, progress): self.progress['value'] = progress self.progressText['text'] = str(self.progress['value']) + " / " + str( self.progress['range'])
class ToonPanel(DirectFrame): notify = directNotify.newCategory("ToonPanel") animal2HeadData = { 'dog': (0.125, 0.04), 'duck': (0.1, 0.025), 'cat': (0.115, 0.04), 'rabbit': (0.115, 0.04), 'horse': (0.115, 0.06), 'monkey': (0.115, 0.06), 'pig': (0.115, 0.07), 'mouse': (0.09, 0.02), 'bear': (0.125, 0.05) } State2Text = { 'status': ('Seeing if %s is available...', '%s is busy right now; try again later.'), 'teleport': ('Trying to go to %s...', 'Could not go to %s.'), 'friend': ('Asking %s to be your friend...', '%s said no, thank you.', 'You are now friends with %s!'), 'remove': ('Are you sure you want to remove %s from your friends list?', '%s left your friends list.') } def __init__(self): DirectFrame.__init__(self, scale=1.2) self['image'] = DGG.getDefaultDialogGeom() self['image_hpr'] = (0, 0, -90) self['image_scale'] = (0.67, 0.9, 0.325) self['image_color'] = (1, 1, 0.75, 1) self['image_pos'] = (0, 0, -0.09) self['relief'] = None self.reparentTo(base.a2dTopRight) self.setPos(-0.235, 0.0, -0.325) self.hide() self.head = None self.laffMeter = None self.exitButton = None self.friendButton = None self.teleportButton = None self.whisperButton = None self.nameText = None self.actionFrame = None self.actionFrameText = None self.actionFrameButton = None self.actionFrameButton2 = None self.avatarInfo = None self.action = None self.locationText = None self.shardText = None self.detailsExitBtn = None self.fsm = ClassicFSM.ClassicFSM('ToonPanel', [ State.State('off', self.enterOff, self.exitOff), State.State('waitOnAvatarInfoResponse', self.enterWaitOnAvatarInfoResponse, self.exitWaitOnAvatarInfoResponse, ['panel']), State.State('panel', self.enterPanel, self.exitPanel, ['off']) ], 'off', 'off') self.fsm.enterInitialState() self.actionFSM = ClassicFSM.ClassicFSM('ToonPanelActionFSM', [ State.State('off', self.enterOff, self.exitOff), State.State( 'waitOnAvatarStatusResponse', self.enterWaitOnAvatarStatusResponse, self.exitWaitOnAvatarStatusResponse, [ 'waitOnAvatarTeleportResponse', 'waitOnAvatarFriendListResponse', 'avatarBusy', 'off' ]), State.State('avatarBusy', self.enterAvatarBusy, self.exitAvatarBusy, ['off']), State.State('waitOnAvatarTeleportResponse', self.enterWaitOnAvatarTeleportResponse, self.exitWaitOnAvatarTeleportResponse, ['unableToTP']), State.State('unableToTP', self.enterUnableToTP, self.exitUnableToTP, ['off']), State.State('waitOnAvatarFriendListResponse', self.enterWaitOnAvatarFriendListResponse, self.exitWaitOnAvatarFriendListResponse, ['fRequestA', 'fRequestR']), State.State('fRequestA', self.enterFriendRequestAccepted, self.exitFriendRequestAccepted, ['off']), State.State('fRequestR', self.enterFriendRequestRejected, self.exitFriendRequestRejected, ['off']), State.State('removeFriendConfirm', self.enterRemoveFriendConfirm, self.exitRemoveFriendConfirm, ['off', 'removedFriend']), State.State('removedFriend', self.enterRemovedFriend, self.exitRemovedFriend, ['off']) ], 'off', 'off') self.actionFSM.enterInitialState() def makeMoreDetailsPanel(self): self.actionFSM.request('off') self.removeMoreDetailsPanel() self.removeActionPanel() self.makeActionPanel() zoneId = self.avatarInfo[5] shardId = self.avatarInfo[6] isOnline = self.avatarInfo[7] shardName = 'Unknown District' hoodName = ZoneUtil.getHoodId(zoneId, 1) for district in base.cr.activeDistricts.values(): if district.doId == shardId: shardName = district.getDistrictName() break if not isOnline: hoodName = 'Offline' shardName = 'Offline' self.locationText = OnscreenText('Location: {0}'.format(hoodName), parent=self.actionFrame, pos=(-0.3, 0.05, 0), align=TextNode.ALeft, scale=0.04) self.shardText = OnscreenText('District: {0}'.format(shardName), parent=self.actionFrame, pos=(-0.3, 0.0, 0), align=TextNode.ALeft, scale=0.04) self.detailsExitBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(), parent=self.actionFrame, relief=None, scale=0.8, pos=(-0.3, 0.0, -0.175), command=self.removeMoreDetailsPanel) def removeMoreDetailsPanel(self): if self.locationText: self.locationText.destroy() self.locationText = None if self.shardText: self.shardText.destroy() self.shardText = None if self.detailsExitBtn: self.detailsExitBtn.destroy() self.detailsExitBtn = None self.removeActionPanel() def maybeUpdateFriendButton(self): if self.friendButton: if self.avatarInfo: if not self.avatarInfo[0] in base.localAvatar.friends: self.friendButton['text'] = 'Add Friend' self.friendButton['extraArgs'] = [ 'waitOnAvatarFriendListResponse' ] else: self.friendButton['text'] = 'Remove Friend' self.friendButton['extraArgs'] = ['removeFriendConfirm'] def enterOff(self): pass def exitOff(self): pass def enterUnableToTP(self): pass def exitUnableToTP(self): pass def enterWaitOnAvatarTeleportResponse(self): self.setActionText(self.State2Text['teleport'][0] % self.getAvatarName()) self.makeButtons('Cancel') self.acceptOnce('gotAvatarTeleportResponse', self.handleTeleportResponse) base.cr.friendsManager.d_iWantToTeleportToAvatar(self.avatarInfo[0]) def handleTeleportResponse(self, avatarId, shardId, zoneId): if self.avatarInfo[0] == avatarId: requestStatus = {} whereName = ZoneUtil.getWhereName(zoneId) loaderName = ZoneUtil.getLoaderName(zoneId) requestStatus['zoneId'] = zoneId if base.localAvatar.parentId == shardId: requestStatus['shardId'] = None else: requestStatus['shardId'] = shardId requestStatus['hoodId'] = ZoneUtil.getHoodId(zoneId, 1) requestStatus['where'] = whereName requestStatus['loader'] = loaderName requestStatus['how'] = 'teleportIn' requestStatus['avId'] = avatarId base.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus]) self.cleanup() def exitWaitOnAvatarTeleportResponse(self): self.ignore('gotAvatarTeleportResponse') self.clearActionText() self.clearActionButtons() def setActionText(self, text): self.actionFrameText.setText(text) def clearActionText(self): self.actionFrameText.setText("") def makeButtons(self, button1, button2=None): button2GeomFunc = { 'Cancel': CIGlobals.getCancelBtnGeom, 'No': CIGlobals.getCancelBtnGeom, 'Okay': CIGlobals.getOkayBtnGeom, 'Yes': CIGlobals.getOkayBtnGeom } if button1 and not button2: button1Pos = (0, 0, -0.1) elif button1 and button2: button1Pos = (-0.1, 0, -0.1) button2Pos = (0.1, 0, -0.1) if button1: self.actionFrameButton = DirectButton( text=button1, geom=button2GeomFunc[button1](), parent=self.actionFrame, pos=button1Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[1], relief=None, geom_scale=0.75) if button2: self.actionFrameButton2 = DirectButton( text=button2, geom=button2GeomFunc[button2](), parent=self.actionFrame, pos=button2Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[2], relief=None, geom_scale=0.75) def actionButtonPressed(self, buttonNum): currentState = self.actionFSM.getCurrentState().getName() if buttonNum == 1: if currentState in [ 'waitOnAvatarStatusResponse', 'waitOnAvatarTeleportResponse', 'waitOnAvatarFriendListResponse', 'avatarBusy', 'unableToTP', 'fRequestA', 'fRequestR', 'removeFriendConfirm', 'removedFriend' ]: if currentState == 'waitOnAvatarFriendListResponse': base.cr.friendsManager.d_iCancelledFriendRequest( self.avatarInfo[0]) elif currentState == 'removeFriendConfirm': self.actionFSM.request('removedFriend') return self.actionFSM.request('off') self.removeActionPanel() self.action = None elif buttonNum == 2: self.actionFSM.request('off') self.removeActionPanel() self.action = None def clearActionButtons(self): if self.actionFrameButton2: self.actionFrameButton2.destroy() self.actionFrameButton2 = None if self.actionFrameButton: self.actionFrameButton.destroy() self.actionFrameButton = None def enterAvatarBusy(self): self.setActionText(self.State2Text['status'][1] % self.getAvatarName()) self.makeButtons('Okay') def exitAvatarBusy(self): self.clearActionText() self.clearActionButtons() def getAvatarName(self): if self.avatarInfo: return self.avatarInfo[1] def enterWaitOnAvatarStatusResponse(self): self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse) base.cr.friendsManager.d_requestAvatarStatus(self.avatarInfo[0]) self.setActionText(self.State2Text['status'][0] % self.getAvatarName()) self.makeButtons('Cancel') def handleAvatarStatusResponse(self, avatarId, status): if avatarId == self.avatarInfo[0]: # Busy if status == 1: self.actionFSM.request('avatarBusy') # Not busy else: self.actionFSM.request(self.action) else: self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse) def exitWaitOnAvatarStatusResponse(self): self.ignore('gotAvatarStatus') self.clearActionText() self.clearActionButtons() def enterWaitOnAvatarFriendListResponse(self): self.acceptOnce('friendRequestAccepted', self.handleFriendRequestAccepted) self.acceptOnce('friendRequestRejected', self.handleFriendRequestRejected) base.cr.friendsManager.d_askAvatarToBeFriends(self.avatarInfo[0]) self.setActionText(self.State2Text['friend'][0] % self.getAvatarName()) self.makeButtons('Cancel') def handleFriendRequestAccepted(self): self.actionFSM.request('fRequestA') def handleFriendRequestRejected(self): self.actionFSM.request('fRequestR') def exitWaitOnAvatarFriendListResponse(self): self.ignore('friendRequestAccepted') self.ignore('friendRequestRejected') self.clearActionText() self.clearActionButtons() def enterFriendRequestAccepted(self): self.setActionText(self.State2Text['friend'][2] % self.getAvatarName()) self.makeButtons('Okay') def exitFriendRequestAccepted(self): self.clearActionText() self.clearActionButtons() def enterFriendRequestRejected(self): self.setActionText(self.State2Text['friend'][1] % self.getAvatarName()) self.makeButtons('Okay') def exitFriendRequestRejected(self): self.clearActionText() self.clearActionButtons() def enterRemoveFriendConfirm(self): self.setActionText(self.State2Text['remove'][0] % self.getAvatarName()) self.makeButtons('Yes', 'No') def exitRemoveFriendConfirm(self): self.clearActionText() self.clearActionButtons() def enterRemovedFriend(self): base.cr.friendsManager.d_iRemovedFriend(self.avatarInfo[0]) self.setActionText(self.State2Text['remove'][1] % self.getAvatarName()) self.makeButtons('Okay') def exitRemovedFriend(self): self.clearActionText() self.clearActionButtons() def makeActionPanel(self): self.actionFrame = DirectFrame(image=DGG.getDefaultDialogGeom(), image_scale=(0.7, 0.5, 0.45), image_color=(1, 1, 0.75, 1), relief=None) self.actionFrame.reparentTo(base.a2dTopRight) self.actionFrame.setPos(-0.815, 0, -0.31) self.actionFrameText = OnscreenText(text="", parent=self.actionFrame, scale=0.05, wordwrap=12, pos=(0, 0.1)) def removeActionPanel(self): self.clearActionButtons() if self.actionFrameText: self.actionFrameText.destroy() self.actionFrameText = None if self.actionFrame: self.actionFrame.destroy() self.actionFrame = None def doAction(self, action): self.action = action self.actionFSM.requestFinalState() self.removeMoreDetailsPanel() self.removeActionPanel() self.makeActionPanel() if action != 'removeFriendConfirm': self.actionFSM.request('waitOnAvatarStatusResponse') else: self.actionFSM.request(action) def enterWaitOnAvatarInfoResponse(self): self.label = OnscreenText(text='Retrieving Toon\ndetails...', parent=self, scale=0.04) self.acceptOnce('avatarInfoResponse', self.handleAvatarInfoResponse) base.cr.friendsManager.d_requestAvatarInfo(self.avatarInfo[0]) def handleAvatarInfoResponse(self, name, dna, maxHealth, health, zoneId, shardId, isOnline, adminToken): if self.avatarInfo: self.avatarInfo.append(name) self.avatarInfo.append(dna) self.avatarInfo.append(maxHealth) self.avatarInfo.append(health) self.avatarInfo.append(zoneId) self.avatarInfo.append(shardId) self.avatarInfo.append(isOnline) self.avatarInfo.append(adminToken) self.fsm.request('panel') def exitWaitOnAvatarInfoResponse(self): self.label.destroy() del self.label self.ignore('avatarInfoResponse') def makePanel(self, avId): if self.avatarInfo: if self.avatarInfo[0] == avId: # They clicked on the same toon without closing the # previous panel, maybe they're spamming? return self.cleanup() base.localAvatar.hideFriendButton() self.show() self.avatarInfo = [] self.avatarInfo.append(avId) self.fsm.request('waitOnAvatarInfoResponse') def exitClicked(self): self.cleanup() base.localAvatar.showFriendButton() def cleanup(self): self.actionFSM.requestFinalState() self.fsm.requestFinalState() self.avatarInfo = None def enterPanel(self): adminToken = self.avatarInfo[8] text_color = CIGlobals.TextColorByAdminToken[adminToken] self.nameText = OnscreenText(text=self.avatarInfo[1], parent=self, pos=(0, 0.2), scale=0.035, wordwrap=8, fg=text_color) self.nameText.setBin('gui-popup', 60) dna = ToonDNA.ToonDNA() dna.setDNAStrand(self.avatarInfo[2]) self.head = ToonHead.ToonHead(base.cr) self.head.generateHead(dna.gender, dna.animal, dna.head, 1) self.head.setHeadColor(dna.headcolor) self.head.reparentTo(self) self.head.setDepthWrite(1) self.head.setDepthTest(1) self.head.setH(180) self.head.setScale(self.animal2HeadData[dna.animal][0]) self.head.setZ(self.animal2HeadData[dna.animal][1]) self.laffMeter = LaffOMeter() r, g, b, _ = dna.headcolor self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3], self.avatarInfo[4]) self.laffMeter.reparentTo(self) self.laffMeter.setBin('gui-popup', 60) self.laffMeter.setScale(0.045) self.laffMeter.setPos(0, 0, -0.1) self.friendButton = DirectButton( geom=CIGlobals.getDefaultBtnGeom(), text="Add Friend", scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarFriendListResponse']) self.friendButton.setPos(0, 0.0, -0.225) self.maybeUpdateFriendButton() self.teleportButton = DirectButton( geom=CIGlobals.getDefaultBtnGeom(), text="Teleport", scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarTeleportResponse']) self.teleportButton.setPos(0, 0, -0.275) self.whisperButton = DirectButton( geom=CIGlobals.getDefaultBtnGeom(), text="Whisper", scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=base.localAvatar.handleClickedWhisper, extraArgs=[self.avatarInfo[1], self.avatarInfo[0], 1]) self.whisperButton.setPos(0, 0, -0.325) self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(), parent=self, relief=None, scale=0.6, pos=(0, 0.0, -0.39), command=self.exitClicked) gui = loader.loadModel("phase_3.5/models/gui/friendslist_gui.bam") self.moreDetailsBtn = DirectButton( geom=(gui.find('**/Horiz_Arrow_UP'), gui.find('**/Horiz_Arrow_DN'), gui.find('**/Horiz_Arrow_Rllvr'), gui.find('**/Horiz_Arrow_UP')), relief=None, parent=self, pos=(-0.127, 0.0, -0.39), geom_hpr=(180, 0, 0), command=self.makeMoreDetailsPanel, scale=0.77, text=('', 'More Details', 'More Details', ''), text_scale=0.045, text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1), text_pos=(-0.08, -0.01), text_align=TextNode.ARight) def exitPanel(self): if self.actionFSM.getCurrentState().getName( ) == 'waitOnAvatarFriendListResponse': if self.avatarInfo: base.cr.friendsManager.d_iCancelledFriendRequest( self.avatarInfo[0]) self.actionFSM.requestFinalState() self.action = None self.avatarInfo = None self.removeActionPanel() self.removeMoreDetailsPanel() self.hide() if self.nameText: self.nameText.destroy() self.nameText = None if self.head: self.head.removeNode() self.head.delete() self.head = None if self.laffMeter: self.laffMeter.disable() self.laffMeter.delete() self.laffMeter = None if self.friendButton: self.friendButton.destroy() self.friendButton = None if self.teleportButton: self.teleportButton.destroy() self.teleportButton = None if self.whisperButton: self.whisperButton.destroy() self.whisperButton = None if self.exitButton: self.exitButton.destroy() self.exitButton = None if self.moreDetailsBtn: self.moreDetailsBtn.destroy() self.moreDetailsBtn = None
class GunGameLevelLoader: notify = directNotify.newCategory('GunGameLevelLoader') LevelData = {'momada': {'name': CIGlobals.ToonBattleOriginalLevel, 'camera': ( Point3(0.0, -25.8, 7.59), Vec3(0.0, 0.0, 0.0)), 'models': [ 'phase_11/models/lawbotHQ/LB_Zone03a.bam', 'phase_11/models/lawbotHQ/LB_Zone04a.bam', 'phase_11/models/lawbotHQ/LB_Zone7av2.bam', 'phase_11/models/lawbotHQ/LB_Zone08a.bam', 'phase_11/models/lawbotHQ/LB_Zone13a.bam', 'phase_10/models/cashbotHQ/ZONE17a.bam', 'phase_10/models/cashbotHQ/ZONE18a.bam', 'phase_11/models/lawbotHQ/LB_Zone22a.bam'], 'parents': [ render, 'EXIT', 'EXIT', 'EXIT', 'ENTRANCE', 'ENTRANCE', 'ENTRANCE', 'EXIT'], 'model_positions': [ Point3(0.0, 0.0, 0.0), Point3(-1.02, 59.73, 0.0), Point3(0.0, 74.77, 0.0), Point3(0.0, 89.37, -13.5), Point3(16.33, -136.53, 0.0), Point3(-1.01, -104.4, 0.0), Point3(0.65, -23.86, 0.0), Point3(-55.66, -29.01, 0.0)], 'model_orientations': [ Vec3(0.0, 0.0, 0.0), Vec3(0.0, 0.0, 0.0), Vec3(90.0, 0.0, 0.0), Vec3(180.0, 0.0, 0.0), Vec3(97.0, 0.0, 0.0), Vec3(359.95, 0.0, 0.0), Vec3(90.0, 0.0, 0.0), Vec3(270.0, 0.0, 0.0)], 'spawn_points': [ ( Point3(0, 0, 0), Vec3(0, 0, 0)), ( Point3(-20, 50, 0), Vec3(0, 0, 0)), ( Point3(20, 50, 0), Vec3(0, 0, 0)), ( Point3(0, 120, 0), Vec3(0, 0, 0)), ( Point3(0, 100, 0), Vec3(180, 0, 0)), ( Point3(-90, 0, 0), Vec3(0, 0, 0)), ( Point3(-170, 0, 0), Vec3(0, 0, 0)), ( Point3(-90, 50, 0), Vec3(0, 0, 0)), ( Point3(-170, 50, 0), Vec3(0, 0, 0)), ( Point3(35, 250, 0), Vec3(-90, 0, 0)), ( Point3(0, 285, 0), Vec3(180, 0, 0)), ( Point3(-185, 250, 0), Vec3(90, 0, 0))]}, 'dg': {'name': CIGlobals.DaisyGardens, 'camera': ( Point3(-33.13, -3.2, 48.62), Vec3(326.31, 332.68, 0.0)), 'dna': [ 'phase_8/dna/storage_DG.pdna', 'phase_8/dna/storage_DG_sz.pdna', 'phase_8/dna/daisys_garden_sz.pdna'], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[CIGlobals.DaisyGardens]}, 'mml': {'name': CIGlobals.MinniesMelodyland, 'camera': ( Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.8, 0.0)), 'dna': [ 'phase_6/dna/storage_MM.pdna', 'phase_6/dna/storage_MM_sz.pdna', 'phase_6/dna/minnies_melody_land_sz.pdna'], 'sky': 'MM', 'spawn_points': hoodMgr.dropPoints[CIGlobals.MinniesMelodyland]}, 'oz': {'name': CIGlobals.OutdoorZone, 'camera': ( Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.8, 0.0)), 'dna': [ 'phase_6/dna/storage_OZ.pdna', 'phase_6/dna/storage_OZ_sz.pdna', 'phase_6/dna/outdoor_zone_sz.pdna'], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[CIGlobals.OutdoorZone]}, 'cbhq': {'name': CIGlobals.CashbotHQ, 'camera': ( Point3(302.64, 5.0, 15.2), Vec3(135.0, 341.57, 0.0)), 'model': 'phase_10/models/cogHQ/CashBotShippingStation.bam', 'sky': None, 'spawn_points': hoodMgr.dropPoints[CIGlobals.CashbotHQ]}, 'sbf': {'name': CIGlobals.SellbotFactory, 'camera': ( Point3(0, 0, 0), Vec3(0, 0, 0)), 'model': 'phase_9/models/cogHQ/SelbotLegFactory.bam', 'sky': 'cog', 'sky_scale': 10.0, 'occluders': 'phase_9/models/cogHQ/factory_sneak_occluders.egg', 'spawn_points': {GGG.Teams.BLUE: [ ( Point3(13, 30, 3.73), Point3(0, 0, 0)), (Point3(21, 30, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0)), ( Point3(13, 20, 3.73), Point3(0, 0, 0)), (Point3(21, 20, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0))], GGG.Teams.RED: [ ( Point3(-644.43, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 363.22, 8.73), Point3(270, 0, 0)), ( Point3(-659.05, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 363.22, 8.73), Point3(270, 0, 0))]}, 'flag_points': {GGG.Teams.BLUE: [Point3(213.23, 340.59, 19.73), Point3(90, 0, 0)], GGG.Teams.RED: [ Point3(-543.6, 595.79, 9.73), Point3(270, 0, 0)]}, 'flagpoint_points': {GGG.Teams.BLUE: [Point3(-543.6, 595.79, 9.73), Point3(270, 0, 0)], GGG.Teams.RED: [ Point3(213.23, 340.59, 19.73), Point3(0, 0, 0)]}}, 'ttc': {'name': CIGlobals.ToontownCentral, 'dna': [ 'phase_4/dna/storage_TT.pdna', 'phase_4/dna/storage_TT_sz.pdna', 'phase_4/dna/new_ttc_sz.pdna'], 'sky': 'TT', 'spawn_points': [ (9.90324401855, 91.9139556885, 8.0364112854, -545.909545898, 0.0, 0.0), (77.9181442261, 50.953086853, 7.52815723419, -598.509460449, 0.0, 0.0), (93.7379760742, 6.37303066254, 7.99749088287, -626.209533691, 0.0, 0.0), (39.0383415222, -81.5989837646, 8.01874637604, -694.309265137, 0.0, 0.0), (-19.2093048096, -95.1359481812, 8.07303524017, -731.409240723, 0.0, 0.0), (-84.4093933105, -45.4780502319, 8.06541728973, -781.809143066, 0.0, 0.0), (-92.2512283325, 2.41426730156, 8.03108692169, -811.70916748, 0.0, 0.0), (46.8868179321, 81.3593673706, 8.04793071747, -955.309509277, 0.0, 0.0), (32.3203735352, 90.0017929077, 8.06353855133, -884.409301758, 0.0, 0.0)], 'cap_point': Point3(-1.5, 0, 0)}} SkyData = {'TT': 'phase_3.5/models/props', 'MM': 'phase_6/models/props', 'cog': 'phase_9/models/cogHQ', 'MovingSkies': [ 'TT']} def __init__(self, mg): self.mg = mg self.levelName = None self.dnaStore = DNAStorage() self.loadingText = None self.levelGeom = None self.skyUtil = None self.skyModel = None self.occluders = None self.momadaAreas = [] self.momadaAreaName2areaModel = {} return def getFlagPoint_Point(self, team): return self.LevelData[self.levelName]['flagpoint_points'][team] def getFlagPoint(self, team): return self.LevelData[self.levelName]['flag_points'][team] def getCapturePoint(self): return self.LevelData[self.levelName]['cap_point'] def setLevel(self, level): self.levelName = level def getLevel(self): return self.levelName def getCameraOfCurrentLevel(self): return self.LevelData[self.getLevel()]['camera'] def getSpawnPoints(self): pointData = self.LevelData[self.levelName]['spawn_points'] if self.levelName == 'momada': return pointData if self.mg.gameMode in [GGG.GameModes.CASUAL, GGG.GameModes.KOTH]: array = [] for posAndHpr in pointData: array.append(( Point3(posAndHpr[0], posAndHpr[1], posAndHpr[2]), Vec3(posAndHpr[3], posAndHpr[4], posAndHpr[5]))) else: if self.mg.gameMode == GGG.GameModes.CTF: array = pointData[self.mg.team] return array def getNameOfCurrentLevel(self): return self.LevelData[self.getLevel()]['name'] def load(self): self.unload() if self.loadingText: self.loadingText.destroy() self.loadingText = None self.loadingText = OnscreenText(text='', font=CIGlobals.getMinnieFont(), fg=(1, 1, 1, 1)) self.loadingText.setBin('gui-popup', 0) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() if self.levelName == 'momada': self.__momadaLoad() else: if self.levelName in ('cbhq', 'sbf'): modelPath = self.LevelData[self.levelName]['model'] self.levelGeom = loader.loadModel(modelPath) self.levelGeom.flattenMedium() self.levelGeom.reparentTo(render) if self.LevelData[self.levelName]['sky'] != None: self.skyModel = loader.loadModel(self.SkyData['cog'] + '/cog_sky.bam') self.skyUtil = SkyUtil() self.skyUtil.startSky(self.skyModel) self.skyModel.reparentTo(render) self.skyModel.setScale(self.LevelData[self.levelName].get('sky_scale', 1.0)) if self.LevelData[self.levelName].get('occluders'): self.occluders = loader.loadModel(self.LevelData[self.levelName]['occluders']) for occluderNode in self.occluders.findAllMatches('**/+OccluderNode'): base.render.setOccluder(occluderNode) occluderNode.node().setDoubleSided(True) if self.levelName == 'sbf': base.camLens.setFar(250) else: dnaFiles = self.LevelData[self.levelName]['dna'] skyType = self.LevelData[self.levelName]['sky'] skyPhase = self.SkyData[skyType] loadDNAFile(self.dnaStore, 'phase_4/dna/storage.pdna') for index in range(len(dnaFiles)): if index == len(dnaFiles) - 1: node = loadDNAFile(self.dnaStore, dnaFiles[index]) if node.getNumParents() == 1: self.levelGeom = NodePath(node.getParent(0)) self.levelGeom.reparentTo(hidden) else: self.levelGeom = hidden.attachNewNode(node) if self.levelName == 'ttc' and dnaFiles[index] == 'phase_4/dna/new_ttc_sz.pdna': self.levelGeom.find('**/prop_gazebo_DNARoot').removeNode() else: self.levelGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.levelGeom.prepareScene(gsg) self.levelGeom.reparentTo(render) else: loadDNAFile(self.dnaStore, dnaFiles[index]) children = self.levelGeom.findAllMatches('**/*doorFrameHole*') for child in children: child.hide() self.skyModel = loader.loadModel(skyPhase + '/' + skyType + '_sky.bam') self.skyUtil = SkyUtil() self.skyUtil.startSky(self.skyModel) self.skyModel.reparentTo(camera) ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ) self.skyModel.node().setEffect(ce) if self.loadingText: self.loadingText.destroy() self.loadingText = None return def __momadaLoad(self): def attachArea(itemNum): name = 'MomadaArea-%s' % itemNum area = self.momadaAreaName2areaModel.get(name) parents = self.LevelData['momada']['parents'] parent = parents[itemNum] if type(parent) == type(''): parent = self.momadaAreas[itemNum - 1].find('**/' + parent) pos = self.LevelData['momada']['model_positions'][itemNum] hpr = self.LevelData['momada']['model_orientations'][itemNum] area.reparentTo(parent) area.setPos(pos) area.setHpr(hpr) _numItems = 0 name = None for item in self.LevelData['momada']['models']: name = 'MomadaArea-%s' % _numItems area = loader.loadModel(item) self.momadaAreas.append(area) self.momadaAreaName2areaModel[name] = area attachArea(_numItems) _numItems += 1 self.notify.info('Loaded and attached %s momada areas.' % _numItems) return def unload(self): render.clearOccluder() if self.levelName == 'sbf': base.camLens.setFar(CIGlobals.DefaultCameraFar) if self.levelName == 'momada': for area in self.momadaAreas: self.momadaAreas.remove(area) area.removeNode() del area self.momadaAreas = [] self.momadaAreaName2areaModel = {} else: if self.occluders: self.occluders.removeNode() self.occluders = None if self.skyUtil: self.skyUtil.stopSky() self.skyUtil = None if self.skyModel: self.skyModel.removeNode() self.skyModel = None if self.levelGeom: self.levelGeom.removeNode() self.levelGeom = None return def cleanup(self): self.momadaAreas = None self.momadaAreaName2areaModel = None if self.dnaStore: self.dnaStore.reset_nodes() self.dnaStore.reset_hood_nodes() self.dnaStore.reset_place_nodes() self.dnaStore.reset_hood() self.dnaStore.reset_fonts() self.dnaStore.reset_DNA_vis_groups() self.dnaStore.reset_textures() self.dnaStore.reset_block_numbers() self.dnaStore.reset_block_zones() self.dnaStore.reset_suit_points() self.dnaStore = None return
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)
class DistributedMinigame(DistributedObject.DistributedObject, Timer.Timer): 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.mid' 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.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 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 return def enterFinalScores(self): 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) 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): self.waitLbl = DirectLabel(text='Waiting for other players...', relief=None, text_fg=(1, 1, 1, 1), text_scale=0.08, text_shadow=(0, 0, 0, 1)) return def exitWaitForOthers(self): self.waitLbl.destroy() del self.waitLbl 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() else: if scenario == 'loser': msg = self.loserMsg % self.loserPrize self.prizeLow.play() else: if 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(CIGlobals.MinigameAreaId) loaderName = ZoneUtil.getLoaderName(CIGlobals.MinigameAreaId) requestStatus = { 'zoneId': CIGlobals.MinigameAreaId, 'hoodId': CIGlobals.MinigameArea, 'where': whereName, 'how': 'teleportIn', 'avId': base.localAvatar.doId, 'shardId': None, 'loader': loaderName } self.cr.playGame.hood.fsm.request('quietZone', [requestStatus]) return def abort(self): self.headBackToMinigameArea() def load(self, showDesc=True): if showDesc: self.fsm.request('start') base.transitions.irisIn() def d_leaving(self): 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.setVolume(0.8) self.music.play() def stopMinigameMusic(self): if self.music: self.music.stop() self.music = None return 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) def disable(self): base.localAvatar.getGeomNode().setColorScale(VBase4(1, 1, 1, 1)) if hasattr(self, 'gameOverLbl') and self.gameOverLbl: self.gameOverLbl.destroy() self.gameOverLbl = None NametagGlobals.setWant2dNametags(True) base.localAvatar.setPosHpr(0, 0, 0, 0, 0, 0) self.fsm.requestFinalState() del self.fsm self.winSfx = None self.loseSfx = None self.prizeHigh = None self.prizeLow = None self.headPanels.delete() self.headPanels = None self.finalScoreUI.unload() self.finalScoreUI = None base.minigame = None DistributedObject.DistributedObject.disable(self) return
class Slot(DirectFrame): def __init__(self, baseGui, index, pos, parent): DirectFrame.__init__( self, pos=pos, parent=parent, image=loader.loadTexture('phase_3.5/maps/slot_%s_%s.png' % (str(index), 'idle')), scale=0.15, frameSize=(-1, 1, -1, 1), frameColor=(0, 0, 0, 0), sortOrder=0) self.initialiseoptions(Slot) self.gui = baseGui self.index = index self.hoverObj = None self.gagImage = None self.gag = None self.mouseRlvrSfx = base.loadSfx('phase_3/audio/sfx/GUI_rollover.ogg') self.soundRecharged = base.loadSfx( 'phase_3.5/audio/sfx/tt_s_gui_sbk_cdrSuccess.ogg') self.infoText = OnscreenText(text='No\nAmmo', fg=(1, 0, 0, 1), parent=self, scale=0.5, shadow=(0, 0, 0, 1), align=TextNode.ACenter, pos=(0, 0.1)) self.infoText.setBin('unsorted', 100) self.infoText.hide() self.rechargeBar = DirectWaitBar(value=0, range=100, frameColor=(1, 1, 1, 1), barColor=(0.286, 0.901, 1, 1), relief=DGG.RAISED, borderWidth=(0.04, 0.04), pos=(-1.25, 0, 0), hpr=(0, 0, -90), parent=self, frameSize=(-0.85, 0.85, -0.12, 0.12)) self.rechargeBar.setBin('fixed', 60) self.rechargeBar.hide() self.gagLabel = OnscreenText(text='Birthday Cake', fg=(1, 1, 1, 1), parent=self, scale=0.25, shadow=(0, 0, 0, 1), align=TextNode.ACenter, pos=(0, -0.9), mayChange=1) self.gagLabel.setBin('fixed', 50) self.gagLabel.hide() battleGui = loader.loadModel('phase_3.5/models/gui/battle_gui.bam') arrow = battleGui.find('**/PckMn_BackBtn') arrowRlvr = battleGui.find('**/PckMn_BackBtn_Rlvr') arrowDn = battleGui.find('**/PckMn_BackBtn_Dn') self.leftArrow = DirectButton(geom=(arrow, arrowDn, arrowRlvr, arrow), parent=self, pos=(-0.925, -2.0, -1.02), relief=None, scale=2, command=self.updateLoadout, extraArgs=[0], geom3_color=(0.5, 0.5, 0.5, 1.0)) self.leftArrow.setBin('fixed', 60) self.rightArrow = DirectButton(geom=(arrow, arrowDn, arrowRlvr, arrow), parent=self, pos=(0.925, -2.0, -1.02), hpr=(180, 0, 0), relief=None, scale=2, command=self.updateLoadout, extraArgs=[1], geom3_color=(0.5, 0.5, 0.5, 1.0)) self.rightArrow.setBin('fixed', 60) self.hoverObj = DirectButton(relief=None, parent=self, frameSize=self['frameSize']) self.setBin('transparent', 30) self.setOutlineImage('idle') self.hoverObj.guiItem.setActive(True) self.hoverObj.bind(DGG.WITHIN, self.mouseEntered) self.hoverObj.bind(DGG.WITHOUT, self.mouseExited) self.hoverObj.bind(DGG.B1CLICK, self.gui.click_setWeapon, [self]) return def toggleArrows(self, left, right): if left: self.leftArrow['state'] = DGG.NORMAL else: self.leftArrow['state'] = DGG.DISABLED if right: self.rightArrow['state'] = DGG.NORMAL else: self.rightArrow['state'] = DGG.DISABLED def updateArrows(self): if not self.gag: self.toggleArrows(False, False) else: track = GagGlobals.TrackGagNamesByTrackName.get( GagGlobals.getTrackOfGag(self.gag.getID())) index = None useTrack = [] for name in track: gag = self.gui.backpack.getGagByID( GagGlobals.getIDByName(name)) if gag == self.gag or gag not in self.gui.backpack.getLoadout( ): useTrack.append(name) index = useTrack.index(self.gag.getName()) if index == 0: self.toggleArrows(False, True) else: if index > 0 and index < len(useTrack) - 1: gagId = GagGlobals.getIDByName(useTrack[index + 1]) if not self.gui.backpack.hasGag(gagId): self.toggleArrows(True, False) else: if index == len(useTrack) - 1: self.toggleArrows(True, False) else: self.toggleArrows(True, True) return def updateLoadout(self, forward): if self.gag and self.gag.getState() in [ GagState.RECHARGING, GagState.LOADED ]: track = GagGlobals.TrackGagNamesByTrackName.get( GagGlobals.getTrackOfGag(self.gag.getID())) index = None useTrack = [] for name in track: gag = self.gui.backpack.getGagByID( GagGlobals.getIDByName(name)) if gag == self.gag or gag not in self.gui.backpack.getLoadout( ): useTrack.append(name) index = useTrack.index(self.gag.getName()) if forward == 1: nextGagIndex = index + 1 else: nextGagIndex = index - 1 if nextGagIndex < 0 or nextGagIndex >= len(useTrack): return gagId = GagGlobals.getIDByName(useTrack[nextGagIndex]) loadout = self.gui.backpack.getLoadout() if self.gui.backpack.hasGag(gagId) and self.gag in loadout: self.hideInfoText() if self.gag not in loadout: return loadout[loadout.index( self.gag)] = self.gui.backpack.getGagByID(gagId) self.gui.backpack.setLoadout(loadout) return def showNoAmmo(self): self.infoText['text'] = 'No\nAmmo' self.infoText['scale'] = 0.5 self.infoText['fg'] = (1, 0, 0, 1) self.infoText['pos'] = (0, 0.1) self.infoText.show() if self.gag and self.gag.getState() == GagState.RECHARGING: self.rechargeBar.show() def showRecharging(self): self.infoText['text'] = 'Recharging...' self.infoText['scale'] = 0.315 self.infoText['fg'] = (0.286, 0.901, 1, 1) self.infoText['pos'] = (0, 0) self.infoText.show() self.rechargeBar.show() def __tickRecharge(self): if not self.gag: self.ignoreAll() else: elapsedTime = float(self.gag.getRechargeElapsedTime()) totalTime = float(self.gag.getRechargeTime()) barValue = int( float(elapsedTime / totalTime) * self.rechargeBar['range']) self.rechargeBar['value'] = barValue if barValue == 0: self.gui.setWeapon(self, playSound=False) self.setOutlineImage('no_ammo') self.showRecharging() else: if barValue >= 100: base.playSfx(self.soundRecharged) slotImage = 'idle' if base.localAvatar.getBackpack().getSupply( self.gag.getID()) <= 0: slotImage = 'no_ammo' else: if self.gui.getActiveSlot() == self: slotImage = 'selected' Sequence(Wait(0.5), Func(self.setOutlineImage, slotImage)).start() def hideInfoText(self): self.infoText.hide() self.rechargeBar.hide() def setSlotImage(self, gagImage): if self.gagImage: self.gagImage.destroy() self.gagImage = None self.gagImage = OnscreenImage(image=gagImage, parent=self) self.gagImage.setTransparency(TransparencyAttrib.MAlpha) return def setOutline(self): self.setTransparency(TransparencyAttrib.MAlpha) def setOutlineImage(self, image): phase = 'phase_3.5/maps/' if hasattr(self, '_optionInfo'): self['image'] = loader.loadTexture(phase + 'slot_%s_%s.png' % (str(self.index), image)) self.setOutline() if image != 'no_ammo': if self.gag and base.localAvatar.getBackpack().getSupply( self.gag.getID( )) == 0 or self.gag and self.gag.getState( ) == GagState.RECHARGING: image = 'no_ammo' if image == 'no_ammo': if self.gag and self.gag.getState() == GagState.RECHARGING: self.showRecharging() else: self.showNoAmmo() self.rechargeBar.hide() self.setBin('fixed', 40) if self.gagImage: self.gagImage.setBin('transparent', 30) else: self.hideInfoText() if self.gagImage: self.gagImage.setBin('fixed', 40) self.setBin('transparent', 30) def getOutline(self): return self.outline def mouseEntered(self, cmd): if self.gag: self.gagLabel.show() self.mouseRlvrSfx.play() def mouseExited(self, cmd): self.gagLabel.hide() def setGag(self, gag): if type(gag) == types.IntType: gag = self.gui.backpack.getGagByID(gag) self.ignoreAll() self.gag = gag if gag: self.show() self.setSlotImage(self.gag.getImage()) self.gagLabel['text'] = self.gag.getName() self.accept('%s-Recharge-Tick' % str(self.gag.getID()), self.__tickRecharge) else: self.hide() self.gagLabel['text'] = '' self.updateArrows() def getGag(self): return self.gag
class GunGameLevelLoader: notify = directNotify.newCategory('GunGameLevelLoader') LevelData = {'momada': {'name': CIGlobals.ToonBattleOriginalLevel, 'camera': (Point3(0.0, -25.8, 7.59), Vec3(0.0, 0.0, 0.0)), 'models': ['phase_11/models/lawbotHQ/LB_Zone03a.bam', 'phase_11/models/lawbotHQ/LB_Zone04a.bam', 'phase_11/models/lawbotHQ/LB_Zone7av2.bam', 'phase_11/models/lawbotHQ/LB_Zone08a.bam', 'phase_11/models/lawbotHQ/LB_Zone13a.bam', 'phase_10/models/cashbotHQ/ZONE17a.bam', 'phase_10/models/cashbotHQ/ZONE18a.bam', 'phase_11/models/lawbotHQ/LB_Zone22a.bam'], 'parents': [render, 'EXIT', 'EXIT', 'EXIT', 'ENTRANCE', 'ENTRANCE', 'ENTRANCE', 'EXIT'], 'model_positions': [Point3(0.0, 0.0, 0.0), Point3(-1.02, 59.73, 0.0), Point3(0.0, 74.77, 0.0), Point3(0.0, 89.37, -13.5), Point3(16.33, -136.53, 0.0), Point3(-1.01, -104.4, 0.0), Point3(0.65, -23.86, 0.0), Point3(-55.66, -29.01, 0.0)], 'model_orientations': [Vec3(0.0, 0.0, 0.0), Vec3(0.0, 0.0, 0.0), Vec3(90.0, 0.0, 0.0), Vec3(180.0, 0.0, 0.0), Vec3(97.0, 0.0, 0.0), Vec3(359.95, 0.0, 0.0), Vec3(90.0, 0.0, 0.0), Vec3(270.0, 0.0, 0.0)], 'spawn_points': [(Point3(0, 0, 0), Vec3(0, 0, 0)), (Point3(-20, 50, 0), Vec3(0, 0, 0)), (Point3(20, 50, 0), Vec3(0, 0, 0)), (Point3(0, 120, 0), Vec3(0, 0, 0)), (Point3(0, 100, 0), Vec3(180, 0, 0)), (Point3(-90, 0, 0), Vec3(0, 0, 0)), (Point3(-170, 0, 0), Vec3(0, 0, 0)), (Point3(-90, 50, 0), Vec3(0, 0, 0)), (Point3(-170, 50, 0), Vec3(0, 0, 0)), (Point3(35, 250, 0), Vec3(-90, 0, 0)), (Point3(0, 285, 0), Vec3(180, 0, 0)), (Point3(-185, 250, 0), Vec3(90, 0, 0))]}, 'dg': {'name': CIGlobals.DaisyGardens, 'camera': (Point3(-33.13, -3.2, 48.62), Vec3(326.31, 332.68, 0.0)), 'dna': ['phase_8/dna/storage_DG.dna', 'phase_8/dna/storage_DG_sz.dna', 'phase_8/dna/daisys_garden_sz.dna'], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[CIGlobals.DaisyGardens]}, 'mml': {'name': CIGlobals.MinniesMelodyland, 'camera': (Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.8, 0.0)), 'dna': ['phase_6/dna/storage_MM.dna', 'phase_6/dna/storage_MM_sz.dna', 'phase_6/dna/minnies_melody_land_sz.dna'], 'sky': 'MM', 'spawn_points': hoodMgr.dropPoints[CIGlobals.MinniesMelodyland]}, 'oz': {'name': CIGlobals.OutdoorZone, 'camera': (Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.8, 0.0)), 'dna': ['phase_6/dna/storage_OZ.dna', 'phase_6/dna/storage_OZ_sz.dna', 'phase_6/dna/outdoor_zone_sz.dna'], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[CIGlobals.OutdoorZone]}, 'cbhq': {'name': CIGlobals.CashbotHQ, 'camera': (Point3(302.64, 5.0, 15.2), Vec3(135.0, 341.57, 0.0)), 'model': 'phase_10/models/cogHQ/CashBotShippingStation.bam', 'sky': None, 'spawn_points': hoodMgr.dropPoints[CIGlobals.CashbotHQ]}} SkyData = {'TT': 'phase_3.5/models/props', 'MM': 'phase_6/models/props', 'cog': 'phase_9/models/cogHQ', 'MovingSkies': ['TT']} def __init__(self): self.levelName = None self.dnaStore = DNAStorage() self.loadingText = None self.levelGeom = None self.skyUtil = None self.skyModel = None self.momadaAreas = [] self.momadaAreaName2areaModel = {} return def setLevel(self, level): self.levelName = level def getLevel(self): return self.levelName def getCameraOfCurrentLevel(self): return self.LevelData[self.getLevel()]['camera'] def getSpawnPoints(self): pointData = self.LevelData[self.levelName]['spawn_points'] if self.levelName == 'momada': return pointData else: array = [] for posAndHpr in pointData: array.append((Point3(posAndHpr[0], posAndHpr[1], posAndHpr[2]), Vec3(posAndHpr[3], posAndHpr[4], posAndHpr[5]))) return array def getNameOfCurrentLevel(self): return self.LevelData[self.getLevel()]['name'] def load(self): self.unload() if self.loadingText: self.loadingText.destroy() self.loadingText = None self.loadingText = OnscreenText(text='Loading ' + self.getNameOfCurrentLevel() + '...', font=CIGlobals.getMinnieFont(), fg=(1, 1, 1, 1)) self.loadingText.setBin('gui-popup', 0) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() if self.levelName == 'momada': self.__momadaLoad() elif self.levelName in ('cbhq',): modelPath = self.LevelData[self.levelName]['model'] self.levelGeom = loader.loadModel(modelPath) self.levelGeom.flattenMedium() self.levelGeom.reparentTo(render) if self.LevelData[self.levelName]['sky'] != None: self.skyModel = loader.loadModel(self.SkyData['cog'] + '/cog_sky.bam') self.skyUtil = SkyUtil() self.skyUtil.startSky(self.skyModel) self.skyModel.reparentTo(render) else: dnaFiles = self.LevelData[self.levelName]['dna'] skyType = self.LevelData[self.levelName]['sky'] skyPhase = self.SkyData[skyType] loader.loadDNAFile(self.dnaStore, 'phase_4/dna/storage.dna') for index in range(len(dnaFiles)): if index == len(dnaFiles) - 1: node = loader.loadDNAFile(self.dnaStore, dnaFiles[index]) if node.getNumParents() == 1: self.levelGeom = NodePath(node.getParent(0)) self.levelGeom.reparentTo(hidden) else: self.levelGeom = hidden.attachNewNode(node) self.levelGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.levelGeom.prepareScene(gsg) self.levelGeom.reparentTo(render) else: loader.loadDNAFile(self.dnaStore, dnaFiles[index]) self.skyModel = loader.loadModel(skyPhase + '/' + skyType + '_sky.bam') self.skyUtil = SkyUtil() self.skyUtil.startSky(self.skyModel) self.skyModel.reparentTo(camera) ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ) self.skyModel.node().setEffect(ce) if self.loadingText: self.loadingText.destroy() self.loadingText = None return def __momadaLoad(self): def attachArea(itemNum): name = 'MomadaArea-%s' % itemNum area = self.momadaAreaName2areaModel.get(name) parents = self.LevelData['momada']['parents'] parent = parents[itemNum] if type(parent) == type(''): parent = self.momadaAreas[itemNum - 1].find('**/' + parent) pos = self.LevelData['momada']['model_positions'][itemNum] hpr = self.LevelData['momada']['model_orientations'][itemNum] area.reparentTo(parent) area.setPos(pos) area.setHpr(hpr) _numItems = 0 name = None for item in self.LevelData['momada']['models']: name = 'MomadaArea-%s' % _numItems area = loader.loadModel(item) self.momadaAreas.append(area) self.momadaAreaName2areaModel[name] = area attachArea(_numItems) _numItems += 1 self.notify.info('Loaded and attached %s momada areas.' % _numItems) return def unload(self): if self.levelName == 'momada': for area in self.momadaAreas: self.momadaAreas.remove(area) area.removeNode() del area self.momadaAreas = [] self.momadaAreaName2areaModel = {} else: if self.skyUtil: self.skyUtil.stopSky() self.skyUtil = None if self.skyModel: self.skyModel.removeNode() self.skyModel = None if self.levelGeom: self.levelGeom.removeNode() self.levelGeom = None return def cleanup(self): self.momadaAreas = None self.momadaAreaName2areaModel = None self.dnaStore.resetAll() self.dnaStore = None return
class ChoiceWidget(DirectFrame): notify = directNotify.newCategory("ChoiceWidget") def __init__(self, parent, options, pos=(0, 0, 0), command=None, widgetName="", choiceTextScale=0.08, desc="", settingKeyName=None, mode=AUTO, requirement=None): """ Generates an ordered choice widget with the specified parameters. Parameters: parent: Pretty much self-explanatory, this is the parent of the widget. If an object with a `book` attribute is passed in, it will use that instead. options: A list of options that the user can select with the GUI. pos: Pretty much self-explanatory. command: Function that should be executed whenever a game setting is updated. The newly saved choice is passed to the specified function. widgetName: The label shown to the left of the widget identifying what the widget is for. choiceTextScale: The scale of the text which displays which option the user has currently selected. desc: Optional description of what the choices displayed by this widget are for. settingKeyName: The name of the key inside of the game settings map that this choice widget works with. This MUST be set if trying to simulate a game setting changer widget. mode: This is the kind of widget this is going to be. Use one of the following: - AUTO: - The system will attempt to figure out what the type of choices are available. * 2 options automatically looks like a true/false widget * - MULTICHOICE: - This overrides the system in case there are two options but true/false functionality isn't wanted. - DEGREE: - This means that the choice widget deals with x in front of some sort of degree value that should - be stripped away when selecting choices. This is used for the antialiasing choice widget. """ self.requirement = requirement self.options = options self.command = command self.currentChoiceIndex = 0 self.origChoice = None self.userChoice = None self.settingKeyName = settingKeyName self.mode = mode # Let's update the options if we specified a setting key name. if self.settingKeyName and len(self.settingKeyName) > 0: settingsMgr = CIGlobals.getSettingsMgr() settingInst = settingsMgr.getSetting(self.settingKeyName) if not settingInst: raise ValueError("Setting \"{0}\" could not be found!".format( self.settingKeyName)) else: self.options = settingInst.getOptions() desc = settingInst.getDescription() widgetParent = parent if hasattr(parent, 'book'): widgetParent = parent.book DirectFrame.__init__(self, parent=widgetParent, pos=pos) bg = loader.loadModel('phase_3/models/gui/ChatPanel.bam') self.selFrame = DirectFrame(pos=(0.4, 0, 0), frameColor=(1.0, 1.0, 1.0, 1.0), image=bg, relief=None, image_scale=(0.22, 0.11, 0.11), image_pos=(-0.107, 0.062, 0.062), parent=self) self.choiceText = OnscreenText(text="Hello!", align=TextNode.ACenter, parent=self.selFrame, pos=(0, -0.01), scale=choiceTextScale) self.fwdBtn = CIGlobals.makeDirectionalBtn(1, self.selFrame, pos=(0.2, 0, 0), command=self.__goFwd) self.bckBtn = CIGlobals.makeDirectionalBtn(0, self.selFrame, pos=(-0.2, 0, 0), command=self.__goBck) self.lbl = OnscreenText(text=widgetName + ":", pos=(-0.7, 0, 0), align=TextNode.ALeft, parent=self) if len(desc) > 0: self.desc = OnscreenText(text=desc, pos=(0.0, -0.1, 0.0), parent=self.selFrame, scale=0.05, bg=DESC_BACKGROUND_COLOR, mayChange=False) self.desc.setBin('gui-popup', 40) self.desc.hide() # Let's bind our events on the selection frame for the description. self.selFrame['state'] = DGG.NORMAL self.selFrame.bind(DGG.ENTER, self.__setDescVisible, extraArgs=[True]) self.selFrame.bind(DGG.EXIT, self.__setDescVisible, extraArgs=[False]) self.initialiseoptions(ChoiceWidget) self.reset() bg.detachNode() del bg def reset(self): """ Resets the selected choice to the very first option, or, if representing choices for a game setting, resets the widget to the currently saved setting. """ # The index of the original display choice. destIndex = 0 if self.settingKeyName: # This widget is supposed to be used to change game settings. Let's lookup the currently saved game setting. self.origChoice = self.__getCurrentSetting().getValue() try: if self.mode == DEGREE and not self.origChoice == 0: destIndex = self.options.index('x{0}'.format( str(self.origChoice))) elif (self.mode == AUTO and len(self.options) == 2) or isinstance( self.origChoice, (int, long)): destIndex = int(self.origChoice) elif isinstance(self.origChoice, (list, tuple)): destIndex = self.options.index('{0}x{1}'.format( str(self.origChoice[0]), str(self.origChoice[1]))) elif self.origChoice in self.options: destIndex = self.options.index(self.origChoice) elif self.origChoice.title() in self.options: destIndex = self.options.index(self.origChoice.title()) except: # We couldn't determine the right index for the original choice. Let's ignore any errors and default # to the very first choice when we reset. pass else: # If this widget is not being used to simulate changing game settings, let's use the first value in options as the original choice. self.origChoice = self.options[0] self.userChoice = self.origChoice self.goto(destIndex) def saveSetting(self): """ If `settingKeyName` was set, this updates the game setting key with the choice selected with the widget. However, if `settingKeyName` was not set, it will send the command specified with the current user choice. """ willUpdateChoice = (self.userChoice != self.origChoice) if self.settingKeyName and willUpdateChoice: settingInst = CIGlobals.getSettingsMgr().getSetting( self.settingKeyName) if settingInst: settingInst.setValue(self.userChoice) self.reset() if self.command and willUpdateChoice: # Let's send the command with the newly saved choice. self.command(self.userChoice) def __getCurrentSetting(self): return CIGlobals.getSettingsMgr().getSetting(self.settingKeyName) def __setDescVisible(self, visible, _): if visible: CIGlobals.getRolloverSound().play() self.desc.show() else: self.desc.hide() def cleanup(self): if hasattr(self, 'choiceText'): self.choiceText.destroy() del self.choiceText if hasattr(self, 'fwdBtn'): self.fwdBtn.destroy() del self.fwdBtn if hasattr(self, 'bckBtn'): self.bckBtn.destroy() del self.bckBtn if hasattr(self, 'lbl'): self.lbl.destroy() del self.lbl if hasattr(self, 'selFrame'): self.selFrame.destroy() del self.selFrame if hasattr(self, 'desc'): self.desc.destroy() del self.desc del self.options del self.command del self.currentChoiceIndex del self.settingKeyName del self.origChoice del self.userChoice del self.mode del self.requirement self.destroy() def goto(self, index): self.currentChoiceIndex = index self.updateDirectionalBtns() self.__setCurrentData(False) def __setCurrentData(self, doCmd=True): self.choiceText.setText(self.options[self.currentChoiceIndex]) if (doCmd): # Let's update the internal user choice. if self.mode == AUTO and len(self.options) == 2: # If we only have two options, we must be working with on/off choices. self.userChoice = bool(self.currentChoiceIndex) elif self.mode == INDEX: self.userChoice = self.currentChoiceIndex elif self.mode == DEGREE or self.mode == RESOLUTION: # We're working with either a degree based option or a resolution option. data = self.options[self.currentChoiceIndex].split('x') if CIGlobals.isEmptyString(data[0]): # This is a degree-based option. if self.currentChoiceIndex != 0: self.userChoice = int(data[1]) else: self.userChoice = 0 else: # This is a screen resolution option. self.userChoice = [int(data[0]), int(data[1])] else: self.userChoice = self.options[self.currentChoiceIndex] def updateDirectionalBtns(self): if self.requirement and callable(self.requirement): if not self.requirement(): # The requirement to modify this choice widget was not met. for btn in [self.fwdBtn, self.bckBtn]: btn['state'] = DGG.DISABLED btn.setColorScale(DISABLED_COLOR) return self.fwdBtn['state'] = DGG.NORMAL self.bckBtn['state'] = DGG.NORMAL self.fwdBtn.setColorScale(1, 1, 1, 1) self.bckBtn.setColorScale(1, 1, 1, 1) if self.currentChoiceIndex == 0: self.bckBtn['state'] = DGG.DISABLED self.bckBtn.setColorScale(DISABLED_COLOR) elif self.currentChoiceIndex == len(self.options) - 1: self.fwdBtn['state'] = DGG.DISABLED self.fwdBtn.setColorScale(DISABLED_COLOR) def __goFwd(self): if self.currentChoiceIndex < len(self.options) - 1: self.currentChoiceIndex += 1 self.__setCurrentData() self.updateDirectionalBtns() def __goBck(self): if self.currentChoiceIndex > 0: self.currentChoiceIndex -= 1 self.__setCurrentData() self.updateDirectionalBtns()
class ToonPanel(DirectFrame): notify = directNotify.newCategory('ToonPanel') animal2HeadData = {'dog': (0.125, 0.04), 'duck': (0.1, 0.025), 'cat': (0.115, 0.04), 'rabbit': (0.115, 0.04), 'horse': (0.115, 0.06), 'monkey': (0.115, 0.06), 'pig': (0.115, 0.07), 'mouse': (0.09, 0.02), 'bear': (0.125, 0.05)} State2Text = {'status': ('Seeing if %s is available...', '%s is busy right now; try again later.'), 'teleport': ('Trying to go to %s...', 'Could not go to %s.'), 'friend': ('Asking %s to be your friend...', '%s said no, thank you.', 'You are now friends with %s!'), 'remove': ('Are you sure you want to remove %s from your friends list?', '%s left your friends list.')} def __init__(self): DirectFrame.__init__(self, scale=1.2) self['image'] = DGG.getDefaultDialogGeom() self['image_hpr'] = (0, 0, -90) self['image_scale'] = (0.62, 0.9, 0.325) self['image_color'] = (1, 1, 0.75, 1) self['image_pos'] = (0, 0, -0.065) self['relief'] = None self.reparentTo(base.a2dTopRight) self.setPos(-0.235, 0.0, -0.325) self.hide() self.head = None self.laffMeter = None self.exitButton = None self.friendButton = None self.teleportButton = None self.nameText = None self.actionFrame = None self.actionFrameText = None self.actionFrameButton = None self.actionFrameButton2 = None self.avatarInfo = None self.action = None self.fsm = ClassicFSM.ClassicFSM('ToonPanel', [State.State('off', self.enterOff, self.exitOff), State.State('waitOnAvatarInfoResponse', self.enterWaitOnAvatarInfoResponse, self.exitWaitOnAvatarInfoResponse, ['panel']), State.State('panel', self.enterPanel, self.exitPanel, ['off'])], 'off', 'off') self.fsm.enterInitialState() self.actionFSM = ClassicFSM.ClassicFSM('ToonPanelActionFSM', [State.State('off', self.enterOff, self.exitOff), State.State('waitOnAvatarStatusResponse', self.enterWaitOnAvatarStatusResponse, self.exitWaitOnAvatarStatusResponse, ['waitOnAvatarTeleportResponse', 'waitOnAvatarFriendListResponse', 'avatarBusy', 'off']), State.State('avatarBusy', self.enterAvatarBusy, self.exitAvatarBusy, ['off']), State.State('waitOnAvatarTeleportResponse', self.enterWaitOnAvatarTeleportResponse, self.exitWaitOnAvatarTeleportResponse, ['unableToTP']), State.State('unableToTP', self.enterUnableToTP, self.exitUnableToTP, ['off']), State.State('waitOnAvatarFriendListResponse', self.enterWaitOnAvatarFriendListResponse, self.exitWaitOnAvatarFriendListResponse, ['fRequestA', 'fRequestR']), State.State('fRequestA', self.enterFriendRequestAccepted, self.exitFriendRequestAccepted, ['off']), State.State('fRequestR', self.enterFriendRequestRejected, self.exitFriendRequestRejected, ['off']), State.State('removeFriendConfirm', self.enterRemoveFriendConfirm, self.exitRemoveFriendConfirm, ['off', 'removedFriend']), State.State('removedFriend', self.enterRemovedFriend, self.exitRemovedFriend, ['off'])], 'off', 'off') self.actionFSM.enterInitialState() return def maybeUpdateFriendButton(self): if self.friendButton: if self.avatarInfo: if self.avatarInfo[0] not in base.localAvatar.friends: self.friendButton['text'] = 'Add Friend' self.friendButton['extraArgs'] = ['waitOnAvatarFriendListResponse'] else: self.friendButton['text'] = 'Remove Friend' self.friendButton['extraArgs'] = ['removeFriendConfirm'] def enterOff(self): pass def exitOff(self): pass def enterUnableToTP(self): pass def exitUnableToTP(self): pass def enterWaitOnAvatarTeleportResponse(self): self.setActionText(self.State2Text['teleport'][0] % self.getAvatarName()) self.makeButtons('Cancel') self.acceptOnce('gotAvatarTeleportResponse', self.handleTeleportResponse) base.cr.friendsManager.d_iWantToTeleportToAvatar(self.avatarInfo[0]) def handleTeleportResponse(self, avatarId, shardId, zoneId): if self.avatarInfo[0] == avatarId: requestStatus = {} whereName = ZoneUtil.getWhereName(zoneId) loaderName = ZoneUtil.getLoaderName(zoneId) requestStatus['zoneId'] = zoneId if base.localAvatar.parentId == shardId: requestStatus['shardId'] = None else: requestStatus['shardId'] = shardId requestStatus['hoodId'] = ZoneUtil.getHoodId(zoneId, 1) requestStatus['where'] = whereName requestStatus['loader'] = loaderName requestStatus['how'] = 'teleportIn' requestStatus['avId'] = avatarId base.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus]) self.cleanup() return def exitWaitOnAvatarTeleportResponse(self): self.ignore('gotAvatarTeleportResponse') self.clearActionText() self.clearActionButtons() def setActionText(self, text): self.actionFrameText.setText(text) def clearActionText(self): self.actionFrameText.setText('') def makeButtons(self, button1, button2 = None): button2GeomFunc = {'Cancel': CIGlobals.getCancelBtnGeom, 'No': CIGlobals.getCancelBtnGeom, 'Okay': CIGlobals.getOkayBtnGeom, 'Yes': CIGlobals.getOkayBtnGeom} if button1 and not button2: button1Pos = (0, 0, -0.1) elif button1 and button2: button1Pos = (-0.1, 0, -0.1) button2Pos = (0.1, 0, -0.1) if button1: self.actionFrameButton = DirectButton(text=button1, geom=button2GeomFunc[button1](), parent=self.actionFrame, pos=button1Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[1], relief=None, geom_scale=0.75) if button2: self.actionFrameButton2 = DirectButton(text=button2, geom=button2GeomFunc[button2](), parent=self.actionFrame, pos=button2Pos, text_scale=0.045, text_pos=(0, -0.08), command=self.actionButtonPressed, extraArgs=[2], relief=None, geom_scale=0.75) return def actionButtonPressed(self, buttonNum): currentState = self.actionFSM.getCurrentState().getName() if buttonNum == 1: if currentState in ('waitOnAvatarStatusResponse', 'waitOnAvatarTeleportResponse', 'waitOnAvatarFriendListResponse', 'avatarBusy', 'unableToTP', 'fRequestA', 'fRequestR', 'removeFriendConfirm', 'removedFriend'): if currentState == 'waitOnAvatarFriendListResponse': base.cr.friendsManager.d_iCancelledFriendRequest(self.avatarInfo[0]) elif currentState == 'removeFriendConfirm': self.actionFSM.request('removedFriend') return self.actionFSM.request('off') self.removeActionPanel() self.action = None elif buttonNum == 2: self.actionFSM.request('off') self.removeActionPanel() self.action = None return def clearActionButtons(self): if self.actionFrameButton2: self.actionFrameButton2.destroy() self.actionFrameButton2 = None if self.actionFrameButton: self.actionFrameButton.destroy() self.actionFrameButton = None return def enterAvatarBusy(self): self.setActionText(self.State2Text['status'][1] % self.getAvatarName()) self.makeButtons('Okay') def exitAvatarBusy(self): self.clearActionText() self.clearActionButtons() def getAvatarName(self): if self.avatarInfo: return self.avatarInfo[1] def enterWaitOnAvatarStatusResponse(self): self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse) base.cr.friendsManager.d_requestAvatarStatus(self.avatarInfo[0]) self.setActionText(self.State2Text['status'][0] % self.getAvatarName()) self.makeButtons('Cancel') def handleAvatarStatusResponse(self, avatarId, status): if avatarId == self.avatarInfo[0]: if status == 1: self.actionFSM.request('avatarBusy') else: self.actionFSM.request(self.action) else: self.acceptOnce('gotAvatarStatus', self.handleAvatarStatusResponse) def exitWaitOnAvatarStatusResponse(self): self.ignore('gotAvatarStatus') self.clearActionText() self.clearActionButtons() def enterWaitOnAvatarFriendListResponse(self): self.acceptOnce('friendRequestAccepted', self.handleFriendRequestAccepted) self.acceptOnce('friendRequestRejected', self.handleFriendRequestRejected) base.cr.friendsManager.d_askAvatarToBeFriends(self.avatarInfo[0]) self.setActionText(self.State2Text['friend'][0] % self.getAvatarName()) self.makeButtons('Cancel') def handleFriendRequestAccepted(self): self.actionFSM.request('fRequestA') def handleFriendRequestRejected(self): self.actionFSM.request('fRequestR') def exitWaitOnAvatarFriendListResponse(self): self.ignore('friendRequestAccepted') self.ignore('friendRequestRejected') self.clearActionText() self.clearActionButtons() def enterFriendRequestAccepted(self): self.setActionText(self.State2Text['friend'][2] % self.getAvatarName()) self.makeButtons('Okay') def exitFriendRequestAccepted(self): self.clearActionText() self.clearActionButtons() def enterFriendRequestRejected(self): self.setActionText(self.State2Text['friend'][1] % self.getAvatarName()) self.makeButtons('Okay') def exitFriendRequestRejected(self): self.clearActionText() self.clearActionButtons() def enterRemoveFriendConfirm(self): self.setActionText(self.State2Text['remove'][0] % self.getAvatarName()) self.makeButtons('Yes', 'No') def exitRemoveFriendConfirm(self): self.clearActionText() self.clearActionButtons() def enterRemovedFriend(self): base.cr.friendsManager.d_iRemovedFriend(self.avatarInfo[0]) self.setActionText(self.State2Text['remove'][1] % self.getAvatarName()) self.makeButtons('Okay') def exitRemovedFriend(self): self.clearActionText() self.clearActionButtons() def makeActionPanel(self): self.actionFrame = DirectFrame(image=DGG.getDefaultDialogGeom(), image_scale=(0.7, 0.5, 0.45), image_color=(1, 1, 0.75, 1), relief=None) self.actionFrame.reparentTo(base.a2dTopRight) self.actionFrame.setPos(-0.815, 0, -0.31) self.actionFrameText = OnscreenText(text='', parent=self.actionFrame, scale=0.05, wordwrap=12, pos=(0, 0.1)) return def removeActionPanel(self): self.clearActionButtons() if self.actionFrameText: self.actionFrameText.destroy() self.actionFrameText = None if self.actionFrame: self.actionFrame.destroy() self.actionFrame = None return def doAction(self, action): self.action = action self.actionFSM.requestFinalState() self.removeActionPanel() self.makeActionPanel() if action != 'removeFriendConfirm': self.actionFSM.request('waitOnAvatarStatusResponse') else: self.actionFSM.request(action) def enterWaitOnAvatarInfoResponse(self): self.label = OnscreenText(text='Retrieving Toon\ndetails...', parent=self, scale=0.04) self.acceptOnce('avatarInfoResponse', self.handleAvatarInfoResponse) base.cr.friendsManager.d_requestAvatarInfo(self.avatarInfo[0]) def handleAvatarInfoResponse(self, name, dna, maxHealth, health): if self.avatarInfo: self.avatarInfo.append(name) self.avatarInfo.append(dna) self.avatarInfo.append(maxHealth) self.avatarInfo.append(health) self.fsm.request('panel') def exitWaitOnAvatarInfoResponse(self): self.label.destroy() del self.label self.ignore('avatarInfoResponse') def makePanel(self, avId): if self.avatarInfo: if self.avatarInfo[0] == avId: return self.cleanup() base.localAvatar.hideFriendButton() self.show() self.avatarInfo = [] self.avatarInfo.append(avId) self.fsm.request('waitOnAvatarInfoResponse') def exitClicked(self): self.cleanup() base.localAvatar.showFriendButton() def cleanup(self): self.actionFSM.requestFinalState() self.fsm.requestFinalState() self.avatarInfo = None return def enterPanel(self): self.nameText = OnscreenText(text=self.avatarInfo[1], parent=self, pos=(0, 0.2), scale=0.035, wordwrap=8) self.nameText.setBin('gui-popup', 60) dna = ToonDNA.ToonDNA() dna.setDNAStrand(self.avatarInfo[2]) self.head = ToonHead.ToonHead(base.cr) self.head.generateHead(dna.gender, dna.animal, dna.head, 1) self.head.setHeadColor(dna.headcolor) self.head.reparentTo(self) self.head.setDepthWrite(1) self.head.setDepthTest(1) self.head.setH(180) self.head.setScale(self.animal2HeadData[dna.animal][0]) self.head.setZ(self.animal2HeadData[dna.animal][1]) self.laffMeter = LaffOMeter() r, g, b, _ = dna.headcolor self.laffMeter.generate(r, g, b, dna.animal, self.avatarInfo[3], self.avatarInfo[4]) self.laffMeter.reparentTo(self) self.laffMeter.setBin('gui-popup', 60) self.laffMeter.setScale(0.045) self.laffMeter.setPos(0, 0, -0.1) self.friendButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Add Friend', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarFriendListResponse']) self.friendButton.setPos(0, 0.0, -0.225) self.maybeUpdateFriendButton() self.teleportButton = DirectButton(geom=CIGlobals.getDefaultBtnGeom(), text='Teleport', scale=0.58, relief=None, text_scale=0.058, geom_scale=(1.25, 0, 0.9), text_pos=(0, -0.0125), parent=self, pos=(0, 0, -0.12), command=self.doAction, extraArgs=['waitOnAvatarTeleportResponse']) self.teleportButton.setPos(0, 0, -0.275) self.exitButton = DirectButton(geom=CIGlobals.getCancelBtnGeom(), parent=self, relief=None, scale=0.6, pos=(-0.127, 0.0, -0.3425), command=self.exitClicked) return def exitPanel(self): if self.actionFSM.getCurrentState().getName() == 'waitOnAvatarFriendListResponse': if self.avatarInfo: base.cr.friendsManager.d_iCancelledFriendRequest(self.avatarInfo[0]) self.actionFSM.requestFinalState() self.action = None self.avatarInfo = None self.removeActionPanel() self.hide() if self.nameText: self.nameText.destroy() self.nameText = None if self.head: self.head.removeNode() self.head.delete() self.head = None if self.laffMeter: self.laffMeter.disable() self.laffMeter.delete() self.laffMeter = None if self.friendButton: self.friendButton.destroy() self.friendButton = None if self.teleportButton: self.teleportButton.destroy() self.teleportButton = None if self.exitButton: self.exitButton.destroy() self.exitButton = None return
class Credits(DirectObject): developers = {'Game Development': ['DuckyDuck1553', 'DecodedLogic']} webDevelopers = { 'Web Development': ['totok', 'DuckyDuck1553', 'DecodedLogic'] } artists = { 'Artists': [ 'John L. (supertricky)', 'DuckyDuck1553', 'DecodedLogic', 'Baru (fatigue)', 'Isabel (allyjean)', 'Colorblind', 'loonatic' ] } composers = {'Composers': ['Dylan J.', 'Doc. Dynamite', 'CBiard']} communityManager = {'Community Manager': ['Leo (Bradley)']} moderators = { 'Moderation Team': ['Mark (Black & White)', 'Jackson M.', 'Gabriel A.', 'Davon M.'] } specialThanks = { 'Special Thanks': [ 'Jesse Schell', 'rdb', 'Baribal', 'ThomasEgi', 'tobspr', 'jjkoletar', 'mmavipc', 'CFSWorks', 'loblao', 'HarvTarv', 'Hawkheart', 'TheRandomDog', 'Joey Z. (joey19982)', 'Disney Interactive', 'Microsoft', 'YorkeTheMouse', 'Disyer', '\n\n\nAnd of course, YOU!\n\n\n' ] } def __init__(self): DirectObject.__init__(self) base.setBackgroundColor(0, 0, 0) self.textParent = base.credits2d.attachNewNode('textParent') self.textParent.setBin("gui-popup", 61) self.textParent.setDepthWrite(False) self.textParent.setTransparency(True) self.logoImage = OnscreenImage('phase_3/maps/CogInvasion_Logo.png', parent=self.textParent, scale=(0.685, 1.0, 0.325)) self.logoImage.setTransparency(1) text = self.buildCreditsText() self.creditsText = OnscreenText(parent=self.textParent, font=CIGlobals.getToonFont(), fg=(1, 1, 1, 1), scale=0.065, pos=(0, -0.5, 0), text=text, shadow=(0, 0, 0, 1)) self.posInterval = None self.backgroundImg = OnscreenImage('phase_3/maps/credits_fade.png', parent=render2d) self.backgroundImg.setTransparency(True) self.backgroundImg.setColor(0, 0, 0, 1.0) self.backgroundImg.setBin("gui-popup", 62) self.backgroundImg.setDepthWrite(False) self.exitText = OnscreenText(parent=base.credits2d, font=CIGlobals.getToonFont(), fg=(1.0, 0, 0, 1.0), shadow=(0, 0, 0, 1), scale=0.085, pos=(0, -0.96, 0), text='Press any key to exit') self.exitText.hide() self.exitText.setBin("gui-popup", 63) self.exitText.setDepthWrite(False) self.exitText.setTransparency(True) self.creditsAudioMgr = AudioManager.createAudioManager() self.creditsAudioMgr.setVolume(0.65) self.bgm = self.creditsAudioMgr.getSound( 'phase_4/audio/bgm/new_years_fireworks_music.ogg') def buildCreditsText(self): def writeNames(message, namesList): for name in namesList: message = '%s%s\n' % (message, name) return message message = 'Cog Invasion Online\n{0}\n'.format( metadata.getBuildInformation()) message += '\nCREDITS\n\n' # Write the game developers' names message += 'Programming\n\n' message += '%s\n' % self.developers.keys()[0] message = writeNames(message, self.developers.values()[0]) message += '\n\n' # Write the web developers' names message += '%s\n' % self.webDevelopers.keys()[0] message = writeNames(message, self.webDevelopers.values()[0]) # Let's begin the art section message += '\n\nArt\n\n' # Write the artists' names message += '%s\n' % self.artists.keys()[0] message = writeNames(message, self.artists.values()[0]) message += '\n\n' # Write the composers' names message += '%s\n' % self.composers.keys()[0] message = writeNames(message, self.composers.values()[0]) ########################################## # Let's begin the community section. message += '\n\nCommunity\n\n' # Write the community manager names message += '%s\n' % self.communityManager.keys()[0] message = writeNames(message, self.communityManager.values()[0]) message += '\n\n' # Write the moderators' names message += '%s\n' % self.moderators.keys()[0] message = writeNames(message, self.moderators.values()[0]) # Let's begin the Special Thanks section. message += '\n\n' # Write the special thanks' names message += '%s\n' % self.specialThanks.keys()[0] message = writeNames(message, self.specialThanks.values()[0]) message += '\nWe thank the original Toontown Online team.\nNot only for the game, but for the memories.' message += "\n\n\n\n\"Don't cry because it's over.\nSmile because it happened.\"\n - Dr. Seuss" return message def exit(self, key): self.__fadeOut() base.taskMgr.doMethodLater(1.1, self.__exitTask, "exitTask") def __exitTask(self, task): messenger.send('credits-Complete') self.ignoreAll() self.destroy() base.unMuteMusic() base.unMuteSfx() base.setBackgroundColor(0.05, 0.15, 0.4) base.transitions.fadeIn(1.0) return task.done def watchTextPosition(self, task): if self.textParent.getZ() >= 5.187: self.exitText.show() self.acceptOnce('button', self.exit) return task.done return task.cont def __fadeIn(self): Parallel( LerpColorScaleInterval(self.textParent, 1.0, (1, 1, 1, 1), (1, 1, 1, 0)), LerpColorScaleInterval(self.backgroundImg, 1.0, (1, 1, 1, 1), (1, 1, 1, 0)), LerpColorScaleInterval(self.exitText, 1.0, (1, 1, 1, 1), (1, 1, 1, 0))).start() def __fadeOut(self): Parallel( LerpColorScaleInterval(self.textParent, 1.0, (1, 1, 1, 0), (1, 1, 1, 1)), LerpColorScaleInterval(self.backgroundImg, 1.0, (1, 1, 1, 0), (1, 1, 1, 1)), LerpColorScaleInterval(self.exitText, 1.0, (1, 1, 1, 0), (1, 1, 1, 1))).start() def setup(self): self.__fadeIn() b3 = self.textParent.getTightBounds() dimensions = b3[1] - b3[0] self.posInterval = self.textParent.posInterval( 50, Point3(0, 0, dimensions[2] + 2), Point3(0, 0, 0)) self.posInterval.start() self.bgm.setLoop(1) self.bgm.play() base.buttonThrowers[0].node().setButtonDownEvent('button') taskMgr.add(self.watchTextPosition, 'Watch Text Position') def destroy(self): if self.posInterval: self.posInterval.pause() self.posInterval = None if self.bgm: self.bgm.stop() self.bgm = None if self.backgroundImg: self.backgroundImg.destroy() self.backgroundImg = None if self.creditsText: self.creditsText.destroy() self.creditsText = None if self.exitText: self.exitText.destroy() self.exitText = None if self.logoImage: self.logoImage.destroy() self.logoImage = None if self.textParent: self.textParent.removeNode() self.textParent = None if self.creditsAudioMgr: self.creditsAudioMgr.stopAllSounds() self.creditsAudioMgr = None self.developers = None self.webDevelopers = None self.artists = None self.specialThanks = None self.composers = None self.communityManager = None self.moderators = None self.prevMusic = None
class GunGameLevelLoader: notify = directNotify.newCategory("GunGameLevelLoader") LevelData = { # momada means: Mix Of Mint And District Attorney's 'momada': { 'name': ZoneUtil.ToonBattleOriginalLevel, 'camera': (Point3(0.0, -25.80, 7.59), Vec3(0.00, 0.00, 0.00)), 'models': [ "phase_11/models/lawbotHQ/LB_Zone03a.bam", "phase_11/models/lawbotHQ/LB_Zone04a.bam", "phase_11/models/lawbotHQ/LB_Zone7av2.bam", "phase_11/models/lawbotHQ/LB_Zone08a.bam", "phase_11/models/lawbotHQ/LB_Zone13a.bam", "phase_10/models/cashbotHQ/ZONE17a.bam", "phase_10/models/cashbotHQ/ZONE18a.bam", "phase_11/models/lawbotHQ/LB_Zone22a.bam" ], 'parents': [ render, "EXIT", "EXIT", "EXIT", "ENTRANCE", "ENTRANCE", "ENTRANCE", "EXIT" ], 'model_positions': [ Point3(0.00, 0.00, 0.00), Point3(-1.02, 59.73, 0.00), Point3(0.00, 74.77, 0.00), Point3(0.00, 89.37, -13.50), Point3(16.33, -136.53, 0.00), Point3(-1.01, -104.40, 0.00), Point3(0.65, -23.86, 0.00), Point3(-55.66, -29.01, 0.00) ], 'model_orientations': [ Vec3(0.00, 0.00, 0.00), Vec3(0.00, 0.00, 0.00), Vec3(90.00, 0.00, 0.00), Vec3(180.00, 0.00, 0.00), Vec3(97.00, 0.00, 0.00), Vec3(359.95, 0.00, 0.00), Vec3(90.00, 0.00, 0.00), Vec3(270.00, 0.00, 0.00) ], 'spawn_points': [ (Point3(0, 0, 0), Vec3(0, 0, 0)), (Point3(-20, 50, 0), Vec3(0, 0, 0)), (Point3(20, 50, 0), Vec3(0, 0, 0)), (Point3(0, 120, 0), Vec3(0, 0, 0)), (Point3(0, 100, 0), Vec3(180, 0, 0)), (Point3(-90, 0, 0), Vec3(0, 0, 0)), (Point3(-170, 0, 0), Vec3(0, 0, 0)), (Point3(-90, 50, 0), Vec3(0, 0, 0)), (Point3(-170, 50, 0), Vec3(0, 0, 0)), (Point3(35, 250, 0), Vec3(-90, 0, 0)), (Point3(0, 285, 0), Vec3(180, 0, 0)), (Point3(-185, 250, 0), Vec3(90, 0, 0)) ] }, 'dg': { 'name': ZoneUtil.DaisyGardens, 'camera': (Point3(-33.13, -3.20, 48.62), Vec3(326.31, 332.68, 0.00)), 'dna': [ 'phase_8/dna/storage_DG.pdna', 'phase_8/dna/storage_DG_sz.pdna', 'phase_8/dna/daisys_garden_sz.pdna' ], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[ZoneUtil.DaisyGardens] }, 'mml': { 'name': ZoneUtil.MinniesMelodyland, 'camera': (Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.80, 0.00)), 'dna': [ 'phase_6/dna/storage_MM.pdna', 'phase_6/dna/storage_MM_sz.pdna', 'phase_6/dna/minnies_melody_land_sz.pdna' ], 'sky': 'MM', 'spawn_points': hoodMgr.dropPoints[ZoneUtil.MinniesMelodyland] }, 'oz': { 'name': ZoneUtil.OutdoorZone, 'camera': (Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.80, 0.00)), 'dna': [ 'phase_6/dna/storage_OZ.pdna', 'phase_6/dna/storage_OZ_sz.pdna', 'phase_6/dna/outdoor_zone_sz.pdna' ], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[ZoneUtil.OutdoorZone] }, 'cbhq': { 'name': ZoneUtil.CashbotHQ, 'camera': (Point3(302.64, 5.00, 15.20), Vec3(135.00, 341.57, 0.00)), 'model': 'phase_10/models/cogHQ/CashBotShippingStation.bam', 'sky': None, 'spawn_points': hoodMgr.dropPoints[ZoneUtil.CashbotHQ] }, 'sbf': { 'name': ZoneUtil.SellbotFactory, 'camera': (Point3(0, 0, 0), Vec3(0, 0, 0)), 'model': "phase_9/models/cogHQ/SelbotLegFactory.bam", 'sky': 'cog', 'sky_scale': 10.0, 'occluders': 'phase_9/models/cogHQ/factory_sneak_occluders.egg', 'spawn_points': {GGG.Teams.BLUE: [ (Point3(13, 30, 3.73), Point3(0, 0, 0)), (Point3(21, 30, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0)), (Point3(13, 20, 3.73), Point3(0, 0, 0)), (Point3(21, 20, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0))], GGG.Teams.RED: [ (Point3(-644.43, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 363.22, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 363.22, 8.73), Point3(270, 0, 0))] }, 'flag_points': {GGG.Teams.BLUE: [Point3(213.23, 340.59, 19.73), Point3(90, 0, 0)], GGG.Teams.RED: [Point3(-543.60, 595.79, 9.73), Point3(270, 0, 0)]}, 'flagpoint_points': {GGG.Teams.BLUE: [Point3(-543.60, 595.79, 9.73), Point3(270, 0, 0)], GGG.Teams.RED: [Point3(213.23, 340.59, 19.73), Point3(0, 0, 0)]} }, 'ttc' : { 'name' : ZoneUtil.ToontownCentral, 'dna' : [ 'phase_4/dna/storage_TT.pdna', 'phase_4/dna/storage_TT_sz.pdna', 'phase_4/dna/new_ttc_sz.pdna', ], 'sky' : 'TT', 'spawn_points' : [ (9.90324401855, 91.9139556885, 8.0364112854, -545.909545898, 0.0, 0.0), (77.9181442261, 50.953086853, 7.52815723419, -598.509460449, 0.0, 0.0), (93.7379760742, 6.37303066254, 7.99749088287, -626.209533691, 0.0, 0.0), (39.0383415222, -81.5989837646, 8.01874637604, -694.309265137, 0.0, 0.0), (-19.2093048096, -95.1359481812, 8.07303524017, -731.409240723, 0.0, 0.0), (-84.4093933105, -45.4780502319, 8.06541728973, -781.809143066, 0.0, 0.0), (-92.2512283325, 2.41426730156, 8.03108692169, -811.70916748, 0.0, 0.0), (46.8868179321, 81.3593673706, 8.04793071747, -955.309509277, 0.0, 0.0), (32.3203735352, 90.0017929077, 8.06353855133, -884.409301758, 0.0, 0.0) ], 'cap_point' : Point3(-1.5, 0, 0) } } SkyData = { 'TT': 'phase_3.5/models/props', 'MM': 'phase_6/models/props', 'cog': 'phase_9/models/cogHQ', 'MovingSkies': ['TT'] } def __init__(self, mg): self.mg = mg self.levelName = None self.dnaStore = DNAStorage() self.loadingText = None # for not momada only: self.levelGeom = None self.olc = None self.occluders = None # for momada only: self.momadaAreas = [] self.momadaAreaName2areaModel = {} def getFlagPoint_Point(self, team): return self.LevelData[self.levelName]['flagpoint_points'][team] def getFlagPoint(self, team): return self.LevelData[self.levelName]['flag_points'][team] def getCapturePoint(self): return self.LevelData[self.levelName]['cap_point'] def setLevel(self, level): self.levelName = level def getLevel(self): return self.levelName def getCameraOfCurrentLevel(self): return self.LevelData[self.getLevel()]['camera'] def getSpawnPoints(self): # Return the spawn points for this level. pointData = self.LevelData[self.levelName]['spawn_points'] if self.levelName == "momada": return pointData else: if self.mg.gameMode in [GGG.GameModes.CASUAL, GGG.GameModes.KOTH]: # These points come from src.coginvasion.distributed.HoodMgr, # which is a tuple of a bunch of arrays with pos as first # 3, and hpr as last 3 list elements. # # Disect the arrays and return a tuple holding a Point3 pos, and a Vec3 hpr. array = [] for posAndHpr in pointData: array.append( ( Point3( posAndHpr[0], posAndHpr[1], posAndHpr[2] ), Vec3( posAndHpr[3], posAndHpr[4], posAndHpr[5] ) ) ) elif self.mg.gameMode == GGG.GameModes.CTF: array = pointData[self.mg.team] return array def getNameOfCurrentLevel(self): return self.LevelData[self.getLevel()]['name'] def load(self): self.unload() if self.loadingText: self.loadingText.destroy() self.loadingText = None self.loadingText = OnscreenText(text = "", font = CIGlobals.getMinnieFont(), fg = (1, 1, 1, 1)) self.loadingText.setBin('gui-popup', 0) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() if self.levelName == "momada": # momada is completely different from the other levels, # so it has it's own separate method for loading. self.__momadaLoad() elif self.levelName in ['cbhq', 'sbf']: # Cog hqs are just one model with everything in it. no dna loading needed. modelPath = self.LevelData[self.levelName]['model'] self.levelGeom = loader.loadModel(modelPath) self.levelGeom.flattenMedium() self.levelGeom.reparentTo(render) if self.LevelData[self.levelName].get('occluders'): self.occluders = loader.loadModel(self.LevelData[self.levelName]['occluders']) for occluderNode in self.occluders.findAllMatches('**/+OccluderNode'): base.render.setOccluder(occluderNode) occluderNode.node().setDoubleSided(True) if self.levelName == 'sbf': base.camLens.setFar(250) else: # It's a playground with dna and stuff. Just do the # normal loading procedure. dnaFiles = self.LevelData[self.levelName]['dna'] loadDNAFile(self.dnaStore, 'phase_4/dna/storage.pdna') for index in range(len(dnaFiles)): if index == len(dnaFiles) - 1: node = loadDNAFile(self.dnaStore, dnaFiles[index]) if node.getNumParents() == 1: self.levelGeom = NodePath(node.getParent(0)) self.levelGeom.reparentTo(hidden) else: self.levelGeom = hidden.attachNewNode(node) if self.levelName == 'ttc' and dnaFiles[index] == 'phase_4/dna/new_ttc_sz.pdna': self.levelGeom.find('**/prop_gazebo_DNARoot').removeNode() else: self.levelGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.levelGeom.prepareScene(gsg) self.levelGeom.reparentTo(render) else: loadDNAFile(self.dnaStore, dnaFiles[index]) children = self.levelGeom.findAllMatches('**/*doorFrameHole*') for child in children: child.hide() self.olc = ZoneUtil.getOutdoorLightingConfig(self.LevelData[self.levelName].get('name')) self.olc.setupAndApply() if self.loadingText: self.loadingText.destroy() self.loadingText = None def __momadaLoad(self): def attachArea(itemNum): name = 'MomadaArea-%s' % itemNum area = self.momadaAreaName2areaModel.get(name) parents = self.LevelData['momada']['parents'] parent = parents[itemNum] if type(parent) == type(""): parent = self.momadaAreas[itemNum - 1].find('**/' + parent) pos = self.LevelData['momada']['model_positions'][itemNum] hpr = self.LevelData['momada']['model_orientations'][itemNum] area.reparentTo(parent) area.setPos(pos) area.setHpr(hpr) _numItems = 0 name = None for item in self.LevelData['momada']['models']: name = 'MomadaArea-%s' % _numItems area = loader.loadModel(item) self.momadaAreas.append(area) self.momadaAreaName2areaModel[name] = area attachArea(_numItems) _numItems += 1 self.notify.info("Loaded and attached %s momada areas." % _numItems) def unload(self): render.clearOccluder() if self.olc: self.olc.cleanup() self.olc = None if self.levelName == "sbf": base.camLens.setFar(CIGlobals.DefaultCameraFar) if self.levelName == "momada": for area in self.momadaAreas: self.momadaAreas.remove(area) area.removeNode() del area self.momadaAreas = [] self.momadaAreaName2areaModel = {} else: if self.occluders: self.occluders.removeNode() self.occluders = None if self.levelGeom: self.levelGeom.removeNode() self.levelGeom = None def cleanup(self): self.momadaAreas = None self.momadaAreaName2areaModel = None if self.dnaStore: self.dnaStore.reset_nodes() self.dnaStore.reset_hood_nodes() self.dnaStore.reset_place_nodes() self.dnaStore.reset_hood() self.dnaStore.reset_fonts() self.dnaStore.reset_DNA_vis_groups() self.dnaStore.reset_materials() self.dnaStore.reset_block_numbers() self.dnaStore.reset_block_zones() self.dnaStore.reset_suit_points() self.dnaStore = None