class SliderWidget(DirectFrame):
    notify = directNotify.newCategory("SliderWidget")

    def __init__(self, page, widgetname, slrange, slcommand, pos = (0, 0, 0)):
        DirectFrame.__init__(self, parent = page.book, pos = pos)

        self.page = page

        self.text = OnscreenText(text = widgetname + ":", pos = (-0.7, 0, 0), align = TextNode.ALeft, parent = self)
        self.slider = DirectSlider(range=slrange, pageSize=0.1, command=slcommand, scale=0.3,
                                        orientation=DGG.HORIZONTAL, pos=(0.35, 0, 0.025), parent = self)
        self.valText = OnscreenText(text = "", pos = (0.7, -0.005, -0.005), align = TextNode.ALeft, parent = self)

    def setValText(self, text):
        self.valText.setText(text)

    def getSliderVal(self):
        return self.slider['value']

    def setSliderVal(self, val):
        self.slider['value'] = val

    def cleanup(self):
        if hasattr(self, 'text'):
            self.text.destroy()
            del self.text
        if hasattr(self, 'slider'):
            self.slider.destroy()
            del self.slider
        if hasattr(self, 'valText'):
            self.valText.destroy()
            del self.valText
        del self.page
class QuestNote(DirectFrame):
    notify = directNotify.newCategory("QuestNote")

    spots = [(-0.45, 0, 0.3), (0.45, 0, 0.3), (0.45, 0, -0.25),
             (-0.45, 0, -0.25)]
    RewardTextPos = (0, -0.4)
    RewardTextScale = 0.06
    ProgressTextScale = 0.07
    ProgressTextPos = (0, -0.19)
    TaskInfoTextPos = (0, 0.05)
    NonHeadingTextScale = 0.08
    HeadingTextPos = (0, 0.23)
    HeadingTextScale = 0.1

    def __init__(self, index):
        DirectFrame.__init__(self, scale=0.5)
        stickergui = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')
        self['image'] = stickergui.find('**/paper_note')
        self.setPos(self.spots[index])
        self.headingText = OnscreenText(parent=self,
                                        text="",
                                        font=CIGlobals.getToonFont(),
                                        pos=self.HeadingTextPos,
                                        scale=self.HeadingTextScale)
        self.taskInfoText = OnscreenText(parent=self,
                                         text="",
                                         font=CIGlobals.getToonFont(),
                                         pos=self.TaskInfoTextPos,
                                         scale=self.NonHeadingTextScale)
        self.progressText = OnscreenText(parent=self,
                                         text="",
                                         font=CIGlobals.getToonFont(),
                                         pos=self.ProgressTextPos,
                                         scale=self.ProgressTextScale)
        self.rewardText = OnscreenText(parent=self,
                                       text="",
                                       font=CIGlobals.getToonFont(),
                                       pos=self.RewardTextPos,
                                       scale=self.RewardTextScale)
        self.hide()

    def setHeading(self, text):
        self.headingText.setText(text)

    def setTaskInfo(self, text):
        self.taskInfoText.setText(text)

    def setProgress(self, text):
        self.progressText.setText(text)

    def setReward(self, text):
        self.rewardText.setText(text)

    def setCompleted(self, value):
        if value:
            self.setProgress("Completed")
            self.progressText['fg'] = (0, 0.6, 0, 1)
Esempio n. 3
0
class QuestNote(DirectFrame):
    notify = directNotify.newCategory('QuestNote')
    spots = [(-0.45, 0, 0.3),
     (0.45, 0, 0.3),
     (0.45, 0, -0.25),
     (-0.45, 0, -0.25)]
    RewardTextPos = (0, -0.4)
    RewardTextScale = 0.06
    ProgressTextScale = 0.07
    ProgressTextPos = (0, -0.19)
    TaskInfoTextPos = (0, 0.05)
    NonHeadingTextScale = 0.08
    HeadingTextPos = (0, 0.23)
    HeadingTextScale = 0.1

    def __init__(self, index):
        DirectFrame.__init__(self, scale=0.5)
        stickergui = loader.loadModel('phase_3.5/models/gui/stickerbook_gui.bam')
        self['image'] = stickergui.find('**/paper_note')
        self.setPos(self.spots[index])
        self.headingText = OnscreenText(parent=self, text='', font=CIGlobals.getToonFont(), pos=self.HeadingTextPos, scale=self.HeadingTextScale)
        self.taskInfoText = OnscreenText(parent=self, text='', font=CIGlobals.getToonFont(), pos=self.TaskInfoTextPos, scale=self.NonHeadingTextScale)
        self.progressText = OnscreenText(parent=self, text='', font=CIGlobals.getToonFont(), pos=self.ProgressTextPos, scale=self.ProgressTextScale)
        self.rewardText = OnscreenText(parent=self, text='', font=CIGlobals.getToonFont(), pos=self.RewardTextPos, scale=self.RewardTextScale)
        self.hide()

    def setHeading(self, text):
        self.headingText.setText(text)

    def setTaskInfo(self, text):
        self.taskInfoText.setText(text)

    def setProgress(self, text):
        self.progressText.setText(text)

    def setReward(self, text):
        self.rewardText.setText(text)

    def setCompleted(self, value):
        if value:
            self.setProgress('Completed')
            self.progressText['fg'] = (0, 0.6, 0, 1)
Esempio n. 4
0
class PointCloudViewerApp(Navigator3D):
    def __init__(self, point_cloud_size=17776):
        Navigator3D.__init__(self)
        self._point_cloud = None
        self._point_cloud_coloring = None
        self._cuboids = []
        self.points_vb = PointCloudVertexBuffer(point_cloud_size)
        self._user_text = OnscreenText('', style=1, fg=(1, 1, 1, 1), scale=.04)
        self._user_text.setPos(-0.9, 0.9)

    def redraw_boxes(self):
        if self._boxes is not None:
            for c_index, box in enumerate(self._boxes):
                self._cuboids[c_index].show()

    def draw(self,
             point_cloud=None,
             point_cloud_coloring=None,
             on_screen_text=None,
             boxes=None):
        self._boxes = boxes
        if point_cloud is not None:
            pc_color = self.color_pc(point_cloud, point_cloud_coloring)
            self.draw_pc(point_cloud, pc_color)
        if on_screen_text is not None:
            self._user_text.setText(textwrap.fill(on_screen_text, 90))
        else:
            self._user_text.setText('')
        if boxes is not None:
            self.draw_cuboids(boxes)
            # self.redraw_boxes()

    def color_pc(self,
                 pc,
                 coloring='reflectivity_and_label',
                 colormap='pc_cmap'):
        """
        Generate coloring for point cloud based on multiple options
        :param pc: point cloud
        :param coloring: Coloring option. Supported: 'reflectivity', np.array of point cloud size x 4 with points colors
        :return:
        """
        if colormap is 'pc_cmap':
            colormap = pc_cmap

        points = pc[:, :3]
        color = np.zeros((len(pc), 4))
        color[:, -1] = 1.

        if isinstance(coloring, np.ndarray
                      ) and coloring.dtype == np.int and coloring.shape == (
                          points.shape[0], ):
            cmap = ListedColormap([
                'w',
                'magenta',
                'orange',
                'mediumspringgreen',
                'deepskyblue',
                'pink',
                'y',
                'g',
                'r',
                'purple',
            ])
            coloring = np.mod(coloring, len(cmap.colors))
            c = cm.ScalarMappable(cmap=cmap,
                                  norm=mcolors.Normalize(
                                      vmin=0, vmax=len(cmap.colors) - 1))
            color = c.to_rgba(coloring)
        elif isinstance(coloring, np.ndarray):
            if coloring.shape == (points.shape[0], 4):
                color = coloring
            if coloring.shape == (points.shape[0], ):
                c = cm.ScalarMappable(cmap=colormap)
                color = c.to_rgba(coloring, norm=False)
        elif isinstance(coloring, collections.Callable):
            colors = coloring(points)
            c = cm.ScalarMappable(cmap=colormap)
            color = c.to_rgba(colors)
        elif coloring == 'reflectivity':
            reflectivity = pc[:, 3]
            reflectivity[reflectivity > 1] = 1
            c = cm.ScalarMappable(cmap=colormap)
            color = c.to_rgba(reflectivity, norm=False)
            color[reflectivity < 0] = np.array([1.0, 1.0, 1.0, 1.0])
        elif coloring == 'reflectivity_and_label':
            # pc_colors
            reflectivity = pc[:, 3]
            reflectivity[reflectivity > 1] = 1
            c = cm.ScalarMappable(cmap=colormap)
            color = c.to_rgba(reflectivity, norm=False)
            if pc.shape[-1] == 5:
                labels = pc[:, 4]
                labels_valid = labels[labels > 0]
                c = cm.ScalarMappable(cmap=label_cmap)
                color_labels = c.to_rgba(labels_valid, norm=True)
                color[labels > 0] = color_labels
        else:
            color = np.ones((points.shape[0], 4))
            color[:, -1] = 1.
        return color

    def draw_pc(self, pc, color):
        points = pc[:, np.array([1, 0, 2])]
        self.points_vb.assign_points(points, color)

    def clear_point_cloud(self):
        self.points_vb.clear_pc()

    def draw_cuboids(self, boxes):
        for box_idx, box in enumerate(boxes):
            color = box['color'] if hasattr(box, 'color') else np.ones(4)
            size = box['size']
            translation = box['translation']
            rotation = box['rotation'] / np.pi * 180.
            try:
                text = box['text']
            except:
                text = ''

            if box_idx < len(self._cuboids):
                self._cuboids[box_idx].show()
                self._cuboids[box_idx].update_values(size, translation,
                                                     rotation, color, text)
            else:
                self._cuboids.append(
                    Cuboid(size, translation, rotation, color, text))
        for c in self._cuboids[len(boxes):]:
            c.hide()
Esempio n. 5
0
class NamePage(StateData):
    notify = directNotify.newCategory('NamePage')

    def __init__(self, book, parentFSM):
        self.book = book
        self.parentFSM = parentFSM
        StateData.__init__(self, 'namePageDone')
        self.fsm = ClassicFSM('NamePage', [
            State('off', self.enterOff, self.exitOff),
            State('basePage', self.enterBasePage, self.exitBasePage)
        ], 'off', 'off')
        self.fsm.enterInitialState()
        self.parentFSM.getStateNamed('namePage').addChild(self.fsm)
        self.nameServ = base.cr.nameServicesManager
        self.baseRequestIndex = 0
        self.requestsPerCluster = 5
        self.requestsContainer = {}
        self.loadingLabel = None
        self.selectedName = None
        self.nameButtons = []
        self.avId2NameData = {}
        geom = CIGlobals.getDefaultBtnGeom()
        self.acceptBtn = DirectButton(geom=geom,
                                      text_scale=0.04,
                                      relief=None,
                                      scale=0.5,
                                      text='Accept',
                                      pos=(0.5, posY, 0),
                                      text_pos=(0, -0.01),
                                      command=self.acceptName)
        self.acceptBtn.hide()
        self.declineBtn = DirectButton(geom=geom,
                                       text_scale=0.04,
                                       relief=None,
                                       scale=0.5,
                                       text='Decline',
                                       pos=(0.75, posY, 0),
                                       text_pos=(0, -0.01),
                                       command=self.declineName)
        self.declineBtn.hide()
        self.avIdLbl = OnscreenText(text='',
                                    scale=0.08,
                                    pos=(0.3, 0, 0.5),
                                    align=TextNode.ACenter)
        self.avIdLbl.hide()
        self.accIdLbl = OnscreenText(text='',
                                     scale=0.08,
                                     pos=(0.3, 0, 0.3),
                                     align=TextNode.ACenter)
        self.accIdLbl.hide()
        return

    def handleRequests(self):
        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        self.nameList = DirectScrolledList(
            relief=None,
            pos=(-0.54, 0, 0.08),
            incButton_image=(gui.find('**/FndsLst_ScrollUp'),
                             gui.find('**/FndsLst_ScrollDN'),
                             gui.find('**/FndsLst_ScrollUp_Rllvr'),
                             gui.find('**/FndsLst_ScrollUp')),
            incButton_relief=None,
            incButton_scale=(arrowButtonScale, arrowButtonScale,
                             -arrowButtonScale),
            incButton_pos=(buttonXstart, 0, itemFrameZorigin - 0.999),
            incButton_image3_color=Vec4(1, 1, 1, 0.2),
            incButton_command=self.__moveItems,
            incButton_extraArgs=[1],
            decButton_image=(gui.find('**/FndsLst_ScrollUp'),
                             gui.find('**/FndsLst_ScrollDN'),
                             gui.find('**/FndsLst_ScrollUp_Rllvr'),
                             gui.find('**/FndsLst_ScrollUp')),
            decButton_relief=None,
            decButton_scale=(arrowButtonScale, arrowButtonScale,
                             arrowButtonScale),
            decButton_pos=(buttonXstart, 0, itemFrameZorigin + 0.125),
            decButton_image3_color=Vec4(1, 1, 1, 0.2),
            decButton_command=self.__moveItems,
            decButton_extraArgs=[0],
            itemFrame_pos=(itemFrameXorigin, 0, itemFrameZorigin),
            itemFrame_scale=1.0,
            itemFrame_relief=DGG.SUNKEN,
            itemFrame_frameSize=(listXorigin, listXorigin + listFrameSizeX,
                                 listZorigin, listZorigin + listFrameSizeZ),
            itemFrame_frameColor=(0.85, 0.95, 1, 1),
            itemFrame_borderWidth=(0.01, 0.01),
            numItemsVisible=5,
            forceHeight=0.075,
            items=self.nameButtons)
        self.__buildItems()
        return

    def __moveItems(self, direction):
        if direction == 0:
            self.baseRequestIndex += 1
        else:
            if direction == 1:
                self.baseRequestIndex -= 1
        self.clearItems()
        self.__buildItems()

    def clearItems(self):
        for btn in self.nameButtons:
            btn.destroy()

        self.nameButtons = []
        self.nameList.removeAndDestroyAllItems()

    def __buildItems(self):
        for i in xrange(self.requestsPerCluster):
            request = self.nameServ.getNameRequests()[self.baseRequestIndex +
                                                      i]
            date = request['date']
            date = date.replace(' ', '-')
            data = NameData(request['name'], date, request['avId'],
                            request['accId'])
            self.avId2NameData[data.avId] = data
            btn = DirectButton(relief=None,
                               text=data.name,
                               text_scale=0.07,
                               text_align=TextNode.ALeft,
                               text1_bg=textDownColor,
                               text2_bg=textRolloverColor,
                               text3_fg=textDisabledColor,
                               textMayChange=0,
                               command=self.__handleNameButton,
                               extraArgs=[data],
                               text_pos=(0, 0, 0.0))
            data.btn = btn
            self.nameButtons.append(btn)

        self.loadingLabel.hide()
        return

    def __handleNameButton(self, data):
        self.selectedName = data
        data.btn['state'] = DGG.DISABLED
        self.avIdLbl.setText('Avatar ID:\n' + str(data.avId))
        self.avIdLbl.show()
        self.accIdLbl.setText('Account ID:\n' + str(data.accId))
        self.accIdLbl.show()
        self.acceptBtn.show()
        self.declineBtn.show()

    def acceptName(self):
        pass

    def load(self):
        StateData.load(self)
        self.loadingLabel = OnscreenText(text='Loading...',
                                         font=CIGlobals.getToonFont(),
                                         pos=(0, 0.1, 0),
                                         scale=0.08,
                                         parent=aspect2d)

    def unload(self):
        StateData.unload(self)
        self.loadingLabel.destroy()
        self.loadingLabel = None
        for request in self.requestsContainer.values():
            for element in request:
                element.destroy()

        self.requestsContainer = {}
        return

    def enter(self):
        StateData.enter(self)
        self.fsm.request('basePage')
        base.acceptOnce(self.nameServ.getRequestCompleteName(),
                        self.handleRequests)
        self.nameServ.d_requestNameData()

    def exit(self):
        self.fsm.requestFinalState()
        StateData.exit(self)

    def enterBasePage(self):
        self.book.createPageButtons('adminPage', None)
        self.book.setTitle('Name Approval')
        return

    def exitBasePage(self):
        self.book.deletePageButtons(True, False)
        self.book.clearTitle()

    def enterOff(self):
        pass

    def exitOff(self):
        pass
class CIProgressScreen:

    Color = (118 / 255.0, 121 / 255.0, 127 / 255.0, 1.0)
    BarColor = (152 / 255.0, 129 / 255.0, 64 / 255.0, 1.0)

    def __init__(self):
        self.defaultLogoScale = 1
        self.defaultLogoZ = 0.65
        self.bgm = loader.loadModel(
            "phase_3/models/gui/progress-background.bam")
        self.bgm.find('**/logo').stash()
        self.barShadow = OnscreenImage(image=self.bgm.find("**/bar_shadow"),
                                       parent=hidden)
        self.bgm.find("**/bar_shadow").removeNode()
        self.bg = self.bgm.find('**/bg')
        self.defaultBgTexture = self.bg.findTexture('*')

        self.logoNode, self.logoImg = CIGlobals.getLogoImage(
            hidden, self.defaultLogoScale, (0, 0, self.defaultLogoZ))

        self.bg_img = OnscreenImage(image=self.bg, parent=hidden)
        self.bg_img.setSx(1.35)
        self.bg_img.hide()
        self.progress_bar = DirectWaitBar(value=0,
                                          pos=(0, 0, -0.85),
                                          parent=hidden,
                                          text_pos=(0, 0, 0.2))
        self.progress_bar.setSx(1.064)
        self.progress_bar.setSz(0.38)
        toontipgui = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')
        poster = toontipgui.find('**/questCard')
        self.toontipFrame = DirectFrame(image=poster,
                                        image_scale=(1.4, 1, 1),
                                        parent=hidden,
                                        relief=None,
                                        pos=(0, 0, -0.1),
                                        scale=0.85)
        self.toontipLbl = OnscreenText(text="",
                                       parent=self.toontipFrame,
                                       fg=(89.0 / 255, 95.0 / 255, 98.0 / 255,
                                           1),
                                       font=CIGlobals.getToonFont(),
                                       wordwrap=13,
                                       pos=(-0.59, 0.25),
                                       align=TextNode.ALeft,
                                       scale=0.08)
        self.loading_lbl = DirectLabel(text="",
                                       relief=None,
                                       scale=0.08,
                                       pos=(-1.0725, 0, -0.79),
                                       text_align=TextNode.ALeft,
                                       sortOrder=100,
                                       text_fg=(1, 1, 1, 1),
                                       text_font=CIGlobals.getMinnieLogoFont(),
                                       parent=hidden,
                                       text_shadow=(0, 0, 0, 0))

        # This is useful when the user has chosen to hide aspect2d before the loading screen.
        # However, we want to show the loading screen all the time, so we need to restore the
        # previous state after the loading screen ends.
        self.mustRestoreHiddenAspect2d = False

    def begin(self, hood, range, wantGui):
        render.hide()
        NametagGlobals.setWant2dNametags(False)

        if base.aspect2d.isHidden():
            base.aspect2d.show()
            self.mustRestoreHiddenAspect2d = True

        self.renderFrames()
        base.setBackgroundColor(0, 0, 0)
        if hood == "localAvatarEnterGame":
            self.loading_lbl['text'] = "Entering..."
        elif hood == "init":
            self.loading_lbl['text'] = "Loading..."
        else:
            self.loading_lbl['text'] = "Heading to %s..." % hood
        self.progress_bar['barColor'] = self.BarColor
        self.progress_bar['range'] = range
        self.bgm.reparentTo(aspect2d)

        ZoneUtil.Hood2ZoneId.keys()

        # We only want to show special loading screens for actual in-game locations.
        if hood in ZoneUtil.Hood2ZoneId.keys():
            abbr = ZoneUtil.ZoneId2HoodAbbr.get(
                ZoneUtil.Hood2ZoneId.get(hood)).lower()
            bgTexture = loader.loadTexture(
                'phase_14/maps/{0}_loading.png'.format(abbr), okMissing=True)

            if bgTexture:
                self.bg.setTexture(bgTexture, 1)

        self.barShadow.reparentTo(aspect2d)
        self.bg.reparentTo(render2d)
        self.bg_img.reparentTo(hidden)
        self.loading_lbl.reparentTo(aspect2d)
        self.logoNode.reparentTo(aspect2d)
        self.progress_bar.reparentTo(aspect2d)
        tip = random.choice(CIGlobals.ToonTips)
        self.toontipLbl.setText("TOON TIP:\n" + tip)
        self.toontipFrame.reparentTo(aspect2d)
        self.__count = 0
        self.__expectedCount = range
        self.progress_bar.update(self.__count)

    def renderFramesTask(self, task):
        self.renderFrames()
        return task.cont

    def end(self):
        base.setBackgroundColor(CIGlobals.DefaultBackgroundColor)
        taskMgr.remove("renderFrames")
        render.show()

        if self.mustRestoreHiddenAspect2d:
            base.aspect2d.hide()
            self.mustRestoreHiddenAspect2d = False

        self.progress_bar.finish()
        self.bg_img.reparentTo(hidden)
        self.logoNode.reparentTo(hidden)
        self.barShadow.reparentTo(hidden)
        self.bg.reparentTo(hidden)

        # Let's get rid of the extra texture stage.
        self.bg.setTexture(self.defaultBgTexture, 1)

        self.bgm.reparentTo(hidden)
        self.loading_lbl.reparentTo(hidden)
        self.progress_bar.reparentTo(hidden)
        self.toontipFrame.reparentTo(hidden)
        base.transitions.fadeScreen(1.0)
        NametagGlobals.setWant2dNametags(True)
        self.renderFrames()

    def destroy(self):
        self.bg.removeNode()
        del self.bg
        self.bgm.removeNode()
        del self.bgm
        self.bg_img.destroy()
        self.barShadow.destroy()
        del self.barShadow
        self.loading_lbl.destroy()
        self.progress_bar.destroy()
        self.bgm.destroy()
        self.mustRestoreHiddenAspect2d = False
        del self.bg_img
        del self.loading_lbl
        del self.progress_bar
        del self.bgm
        del self.defaultBgTexture
        del self.mustRestoreHiddenAspect2d

    def renderFrames(self):
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()

    def tick(self):
        self.__count += 1
        self.progress_bar.update(self.__count)
class PandaPmViewer:
    
    def __init__(self, mesh, pm_filebuf):

        scene_members = getSceneMembers(mesh)
        
        base = ShowBase()
        
        if len(scene_members) > 1:
            print('There is more than one geometry in the scene, so I think this is not a progressive base mesh.')
            sys.exit(1)
        
        rotateNode = GeomNode("rotater")
        rotatePath = render.attachNewNode(rotateNode)
        matrix = numpy.identity(4)
        if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
            r = collada.scene.RotateTransform(0,1,0,90)
            matrix = r.matrix
        elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
            r = collada.scene.RotateTransform(1,0,0,90)
            matrix = r.matrix
        rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))
        
        geom, renderstate, mat4 = scene_members[0]
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        self.geomPath = rotatePath.attachNewNode(node)
        self.geomPath.setMat(mat4)
            
        wrappedNode = ensureCameraAt(self.geomPath, base.camera)
        base.disableMouse()
        attachLights(render)
        render.setShaderAuto()
        render.setTransparency(TransparencyAttrib.MDual, 1)
    
        base.render.analyze()
        KeyboardMovement()
        MouseDrag(wrappedNode)
        MouseScaleZoom(wrappedNode)
        ButtonUtils(wrappedNode)
        MouseCamera()
        
        print('Loading pm into memory... ', end=' ')
        sys.stdout.flush()
        self.pm_refinements = readPDAE(pm_filebuf)
        self.pm_index = 0
        print('Done')

        self.slider = DirectSlider(range=(0,len(self.pm_refinements)),
                                   value=0, pageSize=len(self.pm_refinements)/20,
                                   command=self.sliderMoved, pos=(0, 0, -.9), scale=1)
        for key, val in uiArgs.items():
            self.slider.thumb[key] = val
        
        self.triText = OnscreenText(text="", pos=(-1,0.85), scale = 0.15,
                                    fg=(1, 0.5, 0.5, 1), align=TextNode.ALeft, mayChange=1)
        
        base.run()
        
    def sliderMoved(self):
        sliderVal = int(self.slider['value'])
        if self.pm_index != sliderVal:
            self.movePmTo(sliderVal)
        self.triText.setText('Triangles: ' + str(self.geomPath.node().getGeom(0).getPrimitive(0).getNumFaces()))

    def movePmTo(self, dest_index):
        geom = self.geomPath.node().modifyGeom(0)
        vertdata = geom.modifyVertexData()
        prim = geom.modifyPrimitive(0)
        indexdata = prim.modifyVertices()
        
        indexrewriter = GeomVertexRewriter(indexdata)
        indexrewriter.setColumn(0)
        nextTriangleIndex = indexdata.getNumRows()
        
        vertwriter = GeomVertexWriter(vertdata, 'vertex')
        numverts = vertdata.getNumRows()
        vertwriter.setRow(numverts)
        normalwriter = GeomVertexWriter(vertdata, 'normal')
        normalwriter.setRow(numverts)
        uvwriter = GeomVertexWriter(vertdata, 'texcoord')
        uvwriter.setRow(numverts)
        
        while self.pm_index < dest_index:
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    indexrewriter.setRow(nextTriangleIndex)
                    nextTriangleIndex += 3
                    indexrewriter.addData1i(vals[1])
                    indexrewriter.addData1i(vals[2])
                    indexrewriter.addData1i(vals[3])
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader
                    
                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()
                    
                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts += 1
                    vertwriter.addData3f(vals[1], vals[2], vals[3])
                    normalwriter.addData3f(vals[4], vals[5], vals[6])
                    uvwriter.addData2f(vals[7], vals[8])
                
            self.pm_index += 1

        while self.pm_index > dest_index:
            self.pm_index -= 1
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    nextTriangleIndex -= 3
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader
                    
                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()
                    
                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op, vals[1], oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts -= 1

        if nextTriangleIndex < indexdata.getNumRows():
            indexdata.setNumRows(nextTriangleIndex)
        if numverts < vertdata.getNumRows():
            vertdata.setNumRows(numverts)
class FriendsList(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory("FriendsList")

    GRAYED_OUT_COLOR = (128.0 / 255.0, 128.0 / 255.0, 128.0 / 255.0, 1.0)
    NORMAL_COLOR = (1.0, 1.0, 1.0, 1.0)

    def __init__(self):
        DirectFrame.__init__(self,
                             parent=base.a2dTopRight,
                             pos=(-0.2235, 0.0, -0.457))
        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        self['image'] = gui.find('**/FriendsBox_Open')

        self.headingText = OnscreenText(text="",
                                        parent=self,
                                        pos=(0.01, 0.2),
                                        fg=(0.1, 0.1, 0.4, 1.0),
                                        scale=0.04)

        self.frameForNames = DirectScrolledList(
            frameSize=(0.0, 0.35, 0, 0.35),
            incButton_geom=(gui.find('**/FndsLst_ScrollUp'),
                            gui.find('**/FndsLst_ScrollDN'),
                            gui.find('**/FndsLst_ScrollUp_Rllvr'),
                            gui.find('**/FndsLst_ScrollUp')),
            incButton_relief=None,
            incButton_hpr=(0, 0, 180),
            incButton_pos=(0.17, 0, -0.04),
            decButton_geom=(gui.find('**/FndsLst_ScrollUp'),
                            gui.find('**/FndsLst_ScrollDN'),
                            gui.find('**/FndsLst_ScrollUp_Rllvr'),
                            gui.find('**/FndsLst_ScrollUp')),
            decButton_relief=None,
            decButton_pos=(0.17, 0, 0.395),
            pos=(-0.1625, 0.0, -0.27),
            parent=self,
            numItemsVisible=9,
            forceHeight=0.04,
            itemFrame_frameSize=(-0.15, 0.15, 0, -0.35),
            itemFrame_pos=(0, 0, 0.3275),
            itemFrame_relief=None,
            relief=None)

        self.fwdBtn = CIGlobals.makeDirectionalBtn(1,
                                                   self, (0.17, 0.0, -0.38),
                                                   command=self.doState)
        self.backBtn = CIGlobals.makeDirectionalBtn(0,
                                                    self, (-0.15, 0.0, -0.38),
                                                    command=self.doState)

        self.closeBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                     relief=None,
                                     parent=self,
                                     command=self.exitClicked)
        self.closeBtn.setPos(0.015, 0.0, -0.375)

        gui.removeNode()
        del gui

        self.hide()

        self.friends = {}
        self.onlineFriends = {}

        self.fsm = ClassicFSM.ClassicFSM('FriendsList', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('onlineFriendsList', self.enterOnlineFriendsList,
                        self.exitOnlineFriendsList),
            State.State('allFriendsList', self.enterAllFriendsList,
                        self.exitAllFriendsList)
        ], 'off', 'off')
        self.fsm.enterInitialState()
        self.accept('gotFriendsList', self.handleFriendsList)

    def destroy(self):
        self.ignore('gotFriendsList')
        self.fsm.requestFinalState()
        del self.fsm
        self.headingText.destroy()
        del self.headingText
        self.frameForNames.destroy()
        del self.frameForNames
        self.fwdBtn.destroy()
        del self.fwdBtn
        self.backBtn.destroy()
        del self.backBtn
        self.closeBtn.destroy()
        del self.closeBtn
        del self.friends
        del self.onlineFriends
        DirectFrame.destroy(self)

    def doState(self, state):
        self.fsm.request(state)

    def exitClicked(self):
        self.fsm.request('off')
        base.localAvatar.showFriendButton()

    def setButtons(self, fwd=None, back=None):
        if fwd:
            self.fwdBtn['extraArgs'] = [fwd]
            self.fwdBtn['state'] = DGG.NORMAL
            self.fwdBtn.setColorScale(self.NORMAL_COLOR)
        else:
            self.fwdBtn['extraArgs'] = []
            self.fwdBtn['state'] = DGG.DISABLED
            self.fwdBtn.setColorScale(self.GRAYED_OUT_COLOR)

        if back:
            self.backBtn['extraArgs'] = [back]
            self.backBtn['state'] = DGG.NORMAL
            self.backBtn.setColorScale(self.NORMAL_COLOR)
        else:
            self.backBtn['extraArgs'] = []
            self.backBtn['state'] = DGG.DISABLED
            self.backBtn.setColorScale(self.GRAYED_OUT_COLOR)

        if self.frameForNames.incButton['state'] == DGG.DISABLED:
            self.frameForNames.incButton.setColorScale(self.GRAYED_OUT_COLOR)
        else:
            self.frameForNames.incButton.setColorScale(self.NORMAL_COLOR)

        if self.frameForNames.decButton['state'] == DGG.DISABLED:
            self.frameForNames.decButton.setColorScale(self.GRAYED_OUT_COLOR)
        else:
            self.frameForNames.decButton.setColorScale(self.NORMAL_COLOR)

    def handleFriendsList(self, friendIdArray, nameArray, flags, accessLevels):
        self.friends = {}
        self.onlineFriends = {}
        for i in xrange(len(friendIdArray)):
            avatarId = friendIdArray[i]
            name = nameArray[i]
            accessLevel = accessLevels[i]
            self.friends[avatarId] = [name, accessLevel]
            if flags[i] == 1:
                # This friend is online
                self.onlineFriends[avatarId] = [name, accessLevel]

    def enterOff(self):
        self.hide()

    def exitOff(self):
        self.show()

    def addFriend(self, name, avatarId, accessLevel):
        text_fg = AdminCommands.Roles.get(
            accessLevel
        ).token.color if accessLevel > AdminCommands.NoAccess else (0, 0, 0, 1)
        self.frameForNames.addItem(
            DirectButton(text=name,
                         extraArgs=[avatarId],
                         command=self.friendClicked,
                         scale=0.035,
                         relief=None,
                         text_fg=text_fg,
                         text1_bg=textDownColor,
                         text2_bg=textRolloverColor,
                         text_align=TextNode.ALeft))

    def friendClicked(self, avatarId):
        base.localAvatar.panel.makePanel(avatarId)

    def maybeShowList(self):
        if self.isHidden() and self.fsm.getCurrentState().getName() != 'off':
            base.localAvatar.hideFriendButton()
            self.show()

    def resetAll(self):
        self.headingText.setText("")
        self.frameForNames.removeAndDestroyAllItems()
        self.setButtons(None, None)

    def sortListItems(self):
        self.frameForNames['items'].sort(key=lambda x: x['text'])
        self.frameForNames.refresh()

    def enterAllFriendsList(self):
        self.headingText.setText("ALL\nFRIENDS")
        for friendId, data in self.friends.items():
            name = data[0]
            accessLevel = data[1]
            self.addFriend(name, friendId, accessLevel)
        self.sortListItems()
        self.setButtons(None, 'onlineFriendsList')

    def exitAllFriendsList(self):
        self.resetAll()

    def enterOnlineFriendsList(self):
        self.headingText.setText("ONLINE\nFRIENDS")
        for friendId, data in self.onlineFriends.items():
            name = data[0]
            accessLevel = data[1]
            self.addFriend(name, friendId, accessLevel)
        self.sortListItems()
        self.setButtons('allFriendsList', None)

    def exitOnlineFriendsList(self):
        self.resetAll()
Esempio n. 9
0
class FriendsList(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('FriendsList')

    def __init__(self):
        DirectFrame.__init__(self,
                             parent=base.a2dTopRight,
                             pos=(-0.25, 0.0, -0.46))
        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        self['image'] = gui.find('**/FriendsBox_Open')
        self.headingText = OnscreenText(text='',
                                        parent=self,
                                        pos=(0.01, 0.2),
                                        fg=(0.1, 0.1, 0.4, 1.0),
                                        scale=0.04)
        self.frameForNames = DirectScrolledList(
            frameSize=(0.0, 0.35, 0, 0.35),
            incButton_geom=(gui.find('**/FndsLst_ScrollUp'),
                            gui.find('**/FndsLst_ScrollDN'),
                            gui.find('**/FndsLst_ScrollUp_Rllvr'),
                            gui.find('**/FndsLst_ScrollUp')),
            incButton_relief=None,
            incButton_hpr=(0, 0, 180),
            incButton_pos=(0.17, 0, -0.04),
            decButton_geom=(gui.find('**/FndsLst_ScrollUp'),
                            gui.find('**/FndsLst_ScrollDN'),
                            gui.find('**/FndsLst_ScrollUp_Rllvr'),
                            gui.find('**/FndsLst_ScrollUp')),
            decButton_relief=None,
            decButton_pos=(0.17, 0, 0.395),
            pos=(-0.1625, 0.0, -0.27),
            parent=self,
            numItemsVisible=9,
            forceHeight=0.04,
            itemFrame_frameSize=(-0.15, 0.15, 0, -0.35),
            itemFrame_pos=(0, 0, 0.3275),
            itemFrame_relief=None,
            relief=None)
        self.fwdBtn = 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.17, 0.0, -0.38),
                                   command=self.doState)
        self.backBtn = 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.15, 0.0, -0.38),
                                    hpr=(180, 0, 0),
                                    command=self.doState)
        self.closeBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                     relief=None,
                                     parent=self,
                                     command=self.exitClicked)
        self.closeBtn.setPos(0.015, 0.0, -0.375)
        gui.removeNode()
        del gui
        self.hide()
        self.friends = {}
        self.onlineFriends = {}
        self.fsm = ClassicFSM.ClassicFSM('FriendsList', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('onlineFriendsList', self.enterOnlineFriendsList,
                        self.exitOnlineFriendsList),
            State.State('allFriendsList', self.enterAllFriendsList,
                        self.exitAllFriendsList)
        ], 'off', 'off')
        self.fsm.enterInitialState()
        self.accept('gotFriendsList', self.handleFriendsList)
        return

    def destroy(self):
        self.ignore('gotFriendsList')
        self.fsm.requestFinalState()
        del self.fsm
        self.headingText.destroy()
        del self.headingText
        self.frameForNames.destroy()
        del self.frameForNames
        self.fwdBtn.destroy()
        del self.fwdBtn
        self.backBtn.destroy()
        del self.backBtn
        self.closeBtn.destroy()
        del self.closeBtn
        del self.friends
        del self.onlineFriends
        DirectFrame.destroy(self)

    def doState(self, state):
        self.fsm.request(state)

    def exitClicked(self):
        self.fsm.request('off')
        base.localAvatar.showFriendButton()

    def setButtons(self, fwd=None, back=None):
        if fwd:
            self.fwdBtn['extraArgs'] = [fwd]
            self.fwdBtn['state'] = DGG.NORMAL
        else:
            self.fwdBtn['extraArgs'] = []
            self.fwdBtn['state'] = DGG.DISABLED
        if back:
            self.backBtn['extraArgs'] = [back]
            self.backBtn['state'] = DGG.NORMAL
        else:
            self.backBtn['extraArgs'] = []
            self.backBtn['state'] = DGG.DISABLED

    def handleFriendsList(self, friendIdArray, nameArray, flags, adminTokens):
        self.friends = {}
        self.onlineFriends = {}
        for i in xrange(len(friendIdArray)):
            avatarId = friendIdArray[i]
            name = nameArray[i]
            adminToken = adminTokens[i]
            self.friends[avatarId] = [name, adminToken]
            if flags[i] == 1:
                self.onlineFriends[avatarId] = [name, adminToken]

    def enterOff(self):
        self.hide()

    def exitOff(self):
        self.show()

    def addFriend(self, name, avatarId, adminToken):
        text_fg = CIGlobals.TextColorByAdminToken[adminToken]
        self.frameForNames.addItem(
            DirectButton(text=name,
                         extraArgs=[avatarId],
                         command=self.friendClicked,
                         scale=0.035,
                         relief=None,
                         text_fg=text_fg,
                         text1_bg=textDownColor,
                         text2_bg=textRolloverColor,
                         text_align=TextNode.ALeft))
        return

    def friendClicked(self, avatarId):
        self.fsm.request('off')
        base.localAvatar.panel.makePanel(avatarId)

    def resetAll(self):
        self.headingText.setText('')
        self.frameForNames.removeAndDestroyAllItems()
        self.setButtons(None, None)
        return

    def sortListItems(self):
        self.frameForNames['items'].sort(key=lambda x: x['text'])
        self.frameForNames.refresh()

    def enterAllFriendsList(self):
        self.headingText.setText('All\nFriends')
        for friendId, data in self.friends.items():
            name = data[0]
            adminToken = data[1]
            self.addFriend(name, friendId, adminToken)

        self.sortListItems()
        self.setButtons(None, 'onlineFriendsList')
        return

    def exitAllFriendsList(self):
        self.resetAll()

    def enterOnlineFriendsList(self):
        self.headingText.setText('Online\nFriends')
        for friendId, data in self.onlineFriends.items():
            name = data[0]
            adminToken = data[1]
            self.addFriend(name, friendId, adminToken)

        self.sortListItems()
        self.setButtons('allFriendsList', None)
        return

    def exitOnlineFriendsList(self):
        self.resetAll()
Esempio n. 10
0
class LocalToon(DistributedPlayerToon, BaseLocalAvatar):
    neverDisable = 1

    GTAControls = ConfigVariableBool('want-gta-controls', False)

    def __init__(self, cr):
        try:
            self.LocalToon_initialized
            return
        except:
            self.LocalToon_initialized = 1
        DistributedPlayerToon.__init__(self, cr)
        BaseLocalAvatar.__init__(self)
        self.chatInputState = False
        self.avatarChoice = cr.localAvChoice
        self.chatInput = ChatInput()
        self.positionExaminer = PositionExaminer()
        self.friendRequestManager = FriendRequestManager()
        self.friendsList = FriendsList()
        self.questManager = QuestManager(self)
        self.questUpdateGUI = QuestUpdateGUI()
        self.panel = ToonPanel()
        self.firstTimeGenerating = True
        friendsgui = loader.loadModel(
            'phase_3.5/models/gui/friendslist_gui.bam')
        self.friendButton = DirectButton(
            geom=(friendsgui.find('**/FriendsBox_Closed'),
                  friendsgui.find('**/FriendsBox_Rollover'),
                  friendsgui.find('**/FriendsBox_Rollover')),
            text=("", "Friends", "Friends", ""),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1),
            text_scale=0.09,
            text_pos=(0, -0.18),
            relief=None,
            parent=base.a2dTopRight,
            pos=(-0.141, 0, -0.125),
            command=self.friendsButtonClicked,
            scale=0.8)
        friendsgui.removeNode()
        del friendsgui
        self.hideFriendButton()
        self.runSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_runloop.ogg")
        self.runSfx.setLoop(True)
        self.walkSfx = base.loadSfx(
            "phase_3.5/audio/sfx/AV_footstep_walkloop.ogg")
        self.walkSfx.setLoop(True)
        self.offset = 3.2375
        self.firstPersonCamPos = None
        self.movementKeymap = {
            "forward": 0,
            "backward": 0,
            "left": 0,
            "right": 0,
            "jump": 0
        }
        self.avatarMovementEnabled = False
        self.isMoving_forward = False
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_jump = False
        self.gagThrowBtn = None

        self.pickerTrav = None
        self.pickerRay = None
        self.pickerRayNode = None
        self.pickerHandler = None
        self.rolledOverTag = None

        self.clickToonCallback = None

        self.inTutorial = False
        self.hasDoneJump = False
        self.lastState = None
        self.lastAction = None

        self.jumpHardLandIval = None

        # This is used by CutsceneGUI
        self.allowA2dToggle = True

        # This is used by the animation traverser.
        self.__traverseGUI = None

    def primaryFirePress(self):
        if not self.canUseGag():
            return

        DistributedPlayerToon.primaryFirePress(self)

    def primaryFireRelease(self):
        if not self.canUseGag():
            return

        DistributedPlayerToon.primaryFireRelease(self)

    def secondaryFirePress(self):
        if not self.canUseGag():
            return

        DistributedPlayerToon.secondaryFirePress(self)

    def secondaryFireRelease(self):
        if not self.canUseGag():
            return

        DistributedPlayerToon.secondaryFireRelease(self)

    def stopPlay(self):
        if not self.playState:
            self.notify.warning("Redundant call to stopPlay()")
            return

        self.hideBookButton()
        self.hideFriendButton()

        BaseLocalAvatar.stopPlay(self)

        self.stopTrackAnimToSpeed()

    def startPlay(self,
                  gags=False,
                  book=False,
                  friends=False,
                  laff=False,
                  chat=False,
                  wantMouse=1):
        if self.playState:
            self.notify.warning("Redundant call to startPlay()")
            return

        if book:
            self.showBookButton()
        if friends:
            self.showFriendButton()
        if chat:
            self.createChatInput()

        self.startTrackAnimToSpeed()

        BaseLocalAvatar.startPlay(self, gags, laff, wantMouse)

    def handleSuitAttack(self, attack):
        if self.isFirstPerson():
            self.getFPSCam().handleSuitAttack(attack)

    def areGagsAllowed(self):
        return (BaseLocalAvatar.areGagsAllowed(self) and
                (self.chatInput is not None
                 and self.chatInput.fsm.getCurrentState().getName() == 'idle'))

    def setEquippedAttack(self, gagId):
        DistributedPlayerToon.setEquippedAttack(self, gagId)
        BaseLocalAvatar.setEquippedAttack(self, gagId)

    def updateAttackAmmo(self, attackId, ammo, maxAmmo, ammo2, maxAmmo2, clip,
                         maxClip):
        DistributedPlayerToon.updateAttackAmmo(self, attackId, ammo, maxAmmo,
                                               ammo2, maxAmmo2, clip, maxClip)
        BaseLocalAvatar.updateAttackAmmo(self, attackId, ammo, maxAmmo, ammo2,
                                         maxAmmo2, clip, maxClip)

    def setupAttacks(self):
        DistributedPlayerToon.setupAttacks(self)
        BaseLocalAvatar.setupAttacks(self)

    def _handleWentInTunnel(self, requestStatus):
        self.cr.playGame.getPlace().doneStatus = requestStatus
        messenger.send(self.cr.playGame.getPlace().doneEvent)

    def _handleCameOutTunnel(self):
        self.wrtReparentTo(render)

        self.cr.playGame.getPlace().fsm.request(
            self.cr.playGame.getPlace().nextState)

    def handleClickedWhisper(self,
                             senderName,
                             fromId,
                             isPlayer,
                             openPanel=False):
        place = self.cr.playGame.getPlace()
        if place is None or not hasattr(place, 'fsm') or place.fsm is None:
            return

        if openPanel and place.fsm.getCurrentState().getName() in [
                'walk', 'shtickerBook'
        ]:
            self.panel.makePanel(fromId)

        self.chatInput.disableKeyboardShortcuts()
        self.chatInput.fsm.request('input', ["", fromId])

    def handleClickedSentWhisper(self, senderName, fromId, isPlayer):
        self.handleClickedWhisper(senderName, fromId, isPlayer, True)

    def hasDiscoveredHood(self, zoneId):
        return zoneId in self.hoodsDiscovered

    def hasTeleportAccess(self, zoneId):
        return zoneId in self.teleportAccess

    def tutorialCreated(self, zoneId):
        self.cr.tutorialCreated(zoneId)

    def friendsButtonClicked(self):
        self.hideFriendButton()
        self.friendsList.fsm.request('onlineFriendsList')

    def destroyFriendButton(self):
        if CIGlobals.isNodePathOk(self.friendButton):
            self.friendButton.destroy()
            self.friendButton = None

    def hideFriendButton(self):
        self.friendButton.hide()

    def showFriendButton(self):
        self.friendButton.show()

    def gotoNode(self, node, eyeHeight=3):
        possiblePoints = (Point3(0, 0, 0), Point3(3, 6, 0), Point3(-3, 6, 0),
                          Point3(6, 6, 0), Point3(-6, 6, 0), Point3(3, 9, 0),
                          Point3(-3, 9, 0), Point3(6, 9, 0), Point3(-6, 9, 0),
                          Point3(9, 9, 0), Point3(-9, 9, 0), Point3(6, 0, 0),
                          Point3(-6, 0, 0), Point3(6, 3, 0), Point3(-6, 3, 0),
                          Point3(9, 9, 0), Point3(-9, 9, 0), Point3(0, 12, 0),
                          Point3(3, 12, 0), Point3(-3, 12,
                                                   0), Point3(6, 12, 0),
                          Point3(-6, 12, 0), Point3(9, 12,
                                                    0), Point3(-9, 12, 0),
                          Point3(0, -6,
                                 0), Point3(-3, -6,
                                            0), Point3(0, -9,
                                                       0), Point3(-6, -9, 0))
        for point in possiblePoints:
            pos = self.positionExaminer.consider(node, point, eyeHeight)
            if pos:
                self.setPos(node, pos)
                self.lookAt(node)
                self.setHpr(self.getH() + random.choice((-10, 10)), 0, 0)
                return

        self.setPos(node, 0, 0, 0)

    def setFriendsList(self, friends):
        DistributedPlayerToon.setFriendsList(self, friends)
        self.cr.friendsManager.d_requestFriendsList()
        self.panel.maybeUpdateFriendButton()

    def d_requestAddFriend(self, avId):
        self.sendUpdate('requestAddFriend', [avId])

    def enablePicking(self):
        self.accept('toonClicked', self.toonClicked)

    def disablePicking(self):
        self.ignore('toonClicked')

    def toonClicked(self, avId):
        if not self.clickToonCallback:
            self.panel.makePanel(avId)
        else:
            self.clickToonCallback(avId)
            self.clickToonCallback = None

    def prepareToSwitchControlType(self):
        # Hack fix for getting stuck moving in one direction without pressing the movement keys.
        inputs = [
            "run", "forward", "reverse", "turnLeft", "turnRight", "slideLeft",
            "slideRight", "jump"
        ]
        for inputName in inputs:
            try:
                inputState.releaseInputs(inputName)
            except:
                pass

    def getBackpack(self):
        return DistributedPlayerToon.getBackpack(self)

    def enterReadBook(self, ts=0, callback=None, extraArgs=[]):
        self.stopLookAround()
        self.b_lookAtObject(0, -45, 0)
        DistributedPlayerToon.enterReadBook(self, ts, callback, extraArgs)

    def exitReadBook(self):
        DistributedPlayerToon.exitReadBook(self)
        self.startLookAround()

    def getAirborneHeight(self):
        return self.offset + 0.025000000000000001

    def setupControls(self):
        self.walkControls = CILocalControls()
        self.walkControls.setupControls()
        self.walkControls.setMode(
            CIGlobals.getSettingsMgr().getSetting("bpov").getValue())

    def setWalkSpeedNormal(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed,
                                       CIGlobals.ToonJumpForce,
                                       CIGlobals.ToonReverseSpeed,
                                       CIGlobals.ToonRotateSpeed)

    def setWalkSpeedNormalNoJump(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSpeed, 0.0,
                                       CIGlobals.ToonForwardSpeed,
                                       CIGlobals.ToonRotateSpeed)

    def setWalkSpeedSlow(self):
        self.walkControls.setWalkSpeed(CIGlobals.ToonForwardSlowSpeed,
                                       CIGlobals.ToonJumpSlowForce,
                                       CIGlobals.ToonReverseSlowSpeed,
                                       CIGlobals.ToonRotateSlowSpeed)

    def setDNAStrand(self, dnaStrand):
        DistributedPlayerToon.setDNAStrand(self, dnaStrand)
        if self.firstTimeGenerating:
            self.setupCamera()
            self.firstTimeGenerating = False

    def setMoney(self, money):
        DistributedPlayerToon.setMoney(self, money)

    def setupNameTag(self, tempName=None):
        DistributedPlayerToon.setupNameTag(self, tempName)
        self.nametag.setNametagColor(
            NametagGlobals.NametagColors[NametagGlobals.CCLocal])
        self.nametag.unmanage(base.marginManager)
        self.nametag.setActive(0)
        self.nametag.updateAll()

    def b_setAnimState(self, anim, callback=None, extraArgs=[]):
        if self.anim != anim:
            self.d_setAnimState(anim)
            DistributedPlayerToon.setAnimState(self,
                                               anim,
                                               callback=callback,
                                               extraArgs=extraArgs)

            camTransitionStates = ['teleportIn', 'teleportOut', 'died']
            if anim in camTransitionStates and not NO_TRANSITION in extraArgs:
                self.doFirstPersonCameraTransition()

    def enableAvatarControls(self, wantMouse=0):
        BaseLocalAvatar.enableAvatarControls(self, wantMouse)
        self.accept('jumpStart', self.__jump)

    def handleJumpLand(self):
        if self.jumpHardLandIval:
            self.jumpHardLandIval.finish()
            self.jumpHardLandIval = None
        if self.getHealth() > 0:
            self.b_setAnimState('Happy')

    def handleJumpHardLand(self):
        if self.jumpHardLandIval:
            self.jumpHardLandIval.finish()
            self.jumpHardLandIval = None
        self.jumpHardLandIval = ActorInterval(self, 'zend')
        self.jumpHardLandIval.setDoneEvent('LT::zend-done')
        self.acceptOnce('LT::zend-done', self.handleJumpLand)
        self.jumpHardLandIval.start()

    def disableAvatarControls(self, chat=False):
        BaseLocalAvatar.disableAvatarControls(self, chat)
        self.ignore('jumpStart')
        for k, _ in self.movementKeymap.items():
            self.updateMovementKeymap(k, 0)
        self.resetTorsoRotation()
        self.resetHeadHpr()

    def updateMovementKeymap(self, key, value):
        self.movementKeymap[key] = value

    def getMovementKeyValue(self, key):
        return self.movementKeymap[key]

    def playMovementSfx(self, movement):
        """ This previously was the main method of playing movement sfxs, but now this is only used for tunnels """

        if movement == 'run':
            self.walkSfx.stop()
            self.runSfx.play()
        elif movement == 'walk':
            self.runSfx.stop()
            self.walkSfx.play()
        else:
            self.runSfx.stop()
            self.walkSfx.stop()

    def __forward(self):
        self.resetHeadHpr()
        self.stopLookAround()
        if self.getHealth() < 1:
            self.setPlayRate(1.2, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setAnimState('run')
        self.isMoving_side = False
        self.isMoving_back = False
        self.isMoving_forward = True
        self.isMoving_jump = False

    def __turn(self):
        self.resetHeadHpr()
        self.stopLookAround()
        if self.getHealth() < 1:
            self.setPlayRate(1.2, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setPlayRate(1.0, "walk")
            self.setAnimState("walk")
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_side = True
        self.isMoving_jump = False

    def __reverse(self):
        self.resetHeadHpr()
        self.stopLookAround()
        if self.getHealth() < 1:
            self.setPlayRate(-1.0, 'dwalk')
            self.setAnimState('deadWalk')
        else:
            self.setAnimState("walkBack")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = True
        self.isMoving_jump = False

    def __jump(self):
        if self.getHealth() > 0:
            if self.playingAnim in ['run', 'walk']:
                self.b_setAnimState("leap")
            else:
                self.b_setAnimState("jump")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = True

    def __neutral(self):
        self.resetHeadHpr()
        self.startLookAround()
        if self.getHealth() > 0:
            self.setAnimState("neutral")
        else:
            self.setPlayRate(1.0, 'dneutral')
            self.setAnimState("deadNeutral")
        self.isMoving_side = False
        self.isMoving_forward = False
        self.isMoving_back = False
        self.isMoving_jump = False

    def movementTask(self, task):
        if self.getMovementKeyValue("jump") == 1:
            if not self.walkControls.isAirborne:
                if self.walkControls.mayJump:
                    self.__jump()
                    self.hasDoneJump = True
                else:
                    if self.hasDoneJump:
                        if self.getHealth() > 0:
                            self.b_setAnimState('Happy')
                        self.hasDoneJump = False
        else:
            if not self.walkControls.isAirborne:
                if self.hasDoneJump:
                    if self.getHealth() > 0:
                        self.b_setAnimState('Happy')
                    self.hasDoneJump = False
        return task.cont

    def startTrackAnimToSpeed(self):
        if not base.taskMgr.hasTaskNamed(self.uniqueName('trackAnimToSpeed')):
            base.taskMgr.add(self.trackAnimToSpeed,
                             self.uniqueName('trackAnimToSpeed'))

    def stopTrackAnimToSpeed(self):
        base.taskMgr.remove(self.uniqueName('trackAnimToSpeed'))

    def trackAnimToSpeed(self, task):
        slideSpeed, speed, rotSpeed = self.walkControls.getSpeeds()
        state = None
        if self.isSwimming:
            state = 'swim'
        else:
            if self.getHealth() > 0:
                state = 'Happy'
            else:
                state = 'Sad'
        if state != self.lastState:
            self.lastState = state
            self.b_setAnimState(state)
            if base.minigame is None and not self.battleControls:
                if state == 'Sad' and not self.isSwimming:
                    self.setWalkSpeedSlow()
                else:
                    self.setWalkSpeedNormal()
        action = self.setSpeed(speed, rotSpeed, slideSpeed)
        if action != self.lastAction:
            self.lastAction = action
            if action == CIGlobals.WALK_INDEX:
                self.resetHeadHpr()
                self.stopLookAround()
            elif action == CIGlobals.RUN_INDEX or action in [
                    CIGlobals.STRAFE_LEFT_INDEX, CIGlobals.STRAFE_RIGHT_INDEX
            ] or action == CIGlobals.REVERSE_INDEX:
                self.resetHeadHpr()
                self.stopLookAround()
            else:
                self.resetHeadHpr()
                self.stopLookAround()
                if self.walkControls.mode == self.walkControls.MThirdPerson:
                    if state == 'Happy':
                        self.startLookAround()
        return task.cont

    def setLoadout(self, gagIds):
        DistributedPlayerToon.setLoadout(self, gagIds)
        place = base.cr.playGame.getPlace()
        if place and place.fsm.getCurrentState().getName() == 'shtickerBook':
            if hasattr(place, 'shtickerBookStateData'):
                stateData = place.shtickerBookStateData
                if stateData.getCurrentPage() is not None:
                    if stateData.getCurrentPage().title == 'Gags':
                        stateData.getCurrentPage().gui.fsm.request('idle')

    def resetHeadHpr(self, override=False):
        if self.lookMode == self.LMOff or not self.walkControls.controlsEnabled or override:
            self.b_lookAtObject(0, 0, 0, blink=0)

    def checkSuitHealth(self, suit):
        pass

    def handleLookSpot(self, hpr):
        h, p, r = hpr
        self.d_lookAtObject(h, p, r, blink=1)

    def showBookButton(self, inBook=0):
        self.book_gui = loader.loadModel(
            "phase_3.5/models/gui/stickerbook_gui.bam")
        self.book_btn = DirectButton(
            image=(self.book_gui.find('**/BookIcon_CLSD'),
                   self.book_gui.find('**/BookIcon_OPEN'),
                   self.book_gui.find('**/BookIcon_RLVR')),
            relief=None,
            pos=(-0.158, 0, 0.17),
            command=self.bookButtonClicked,
            scale=0.305,
            parent=base.a2dBottomRight)
        self.book_btn.setBin('gui-popup', 60)
        if inBook:
            self.book_btn["image"] = (self.book_gui.find('**/BookIcon_OPEN'),
                                      self.book_gui.find('**/BookIcon_CLSD'),
                                      self.book_gui.find('**/BookIcon_RLVR2'))
            self.book_btn["command"] = self.bookButtonClicked
            self.book_btn["extraArgs"] = [0]

    def hideBookButton(self):
        if hasattr(self, 'book_gui'):
            self.book_gui.removeNode()
            del self.book_gui
        if hasattr(self, 'book_btn'):
            self.book_btn.destroy()
            del self.book_btn

    def bookButtonClicked(self, openIt=1):
        if openIt:
            base.cr.playGame.getPlace().fsm.request('shtickerBook')
        else:
            base.cr.playGame.getPlace().shtickerBookStateData.finishedResume()

    def handleHealthChange(self, hp, oldHp):
        if hp > 0 and oldHp < 1:
            if self.cr.playGame and self.cr.playGame.getPlace():
                if self.cr.playGame.getPlace().fsm.getCurrentState().getName(
                ) == 'walk':
                    if self.cr.playGame.getPlace(
                    ).walkStateData.fsm.getCurrentState().getName(
                    ) == 'deadWalking':
                        self.cr.playGame.getPlace().walkStateData.fsm.request(
                            'walking')
            if self.animFSM.getCurrentState().getName() == 'deadNeutral':
                self.b_setAnimState("neutral")
            elif self.animFSM.getCurrentState().getName() == 'deadWalk':
                self.b_setAnimState("run")

        BaseLocalAvatar.handleHealthChange(self, hp, oldHp)

        DistributedPlayerToon.handleHealthChange(self, hp, oldHp)

    def setSessionHealth(self, hp):
        currHp = self.getSessionHealth()

        self.handleHealthChange(hp, currHp)

        DistributedPlayerToon.setSessionHealth(self, hp)

    def reparentTo(self, parent):
        self.notify.debug("Local toon reparent to {0}".format(
            parent.node().getName()))
        DistributedPlayerToon.reparentTo(self, parent)

    def wrtReparentTo(self, parent):
        self.notify.debug("Local toon wrtReparent to {0}".format(
            parent.node().getName()))
        DistributedPlayerToon.wrtReparentTo(self, parent)

    def loadAvatar(self):
        DistributedPlayerToon.loadAvatar(self)
        base.avatars.remove(self)

    def diedStateDone(self, requestStatus):
        hood = self.cr.playGame.hood.id
        if hood == ZoneUtil.BattleTTC:
            hood = ZoneUtil.ToontownCentral
        toZone = ZoneUtil.getZoneId(hood)
        if self.zoneId != toZone:
            requestStatus = {
                'zoneId': toZone,
                'hoodId': hood,
                'where': ZoneUtil.getWhereName(toZone),
                'avId': self.doId,
                'loader': ZoneUtil.getLoaderName(toZone),
                'shardId': None,
                'wantLaffMeter': 1,
                'how': 'teleportIn'
            }
            self.cr.playGame.getPlace().doneStatus = requestStatus
            messenger.send(self.cr.playGame.getPlace().doneEvent)
        else:
            return

    def teleportToCT(self):
        toZone = ZoneUtil.CogTropolisId
        hood = ZoneUtil.CogTropolis
        requestStatus = {
            'zoneId': toZone,
            'hoodId': hood,
            'where': ZoneUtil.getWhereName(toZone),
            'avId': self.doId,
            'loader': ZoneUtil.getLoaderName(toZone),
            'shardId': None,
            'wantLaffMeter': 1,
            'how': 'teleportIn'
        }
        self.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus])

    def setQuests(self, dataStr):
        oldDataStr = self.quests
        DistributedPlayerToon.setQuests(self, dataStr)
        self.questManager.makeQuestsFromData()

        # Let's send our quest data update event.
        messenger.send(QUEST_DATA_UPDATE_EVENT, [oldDataStr, dataStr])

    def createChatInput(self):
        if not self.chatInputState:
            self.chatInput.load()
            self.chatInput.enter()
            self.chatInputState = True

    def disableChatInput(self):
        if self.chatInputState:
            self.chatInput.exit()
            self.chatInput.unload()
            self.chatInputState = False

    def toggleAspect2d(self):
        if self.allowA2dToggle:
            if base.aspect2d.isHidden():
                base.aspect2d.show()
            else:
                base.aspect2d.hide()

    def startTraverseAnimationControls(self, animName):
        if not self.__traverseGUI:
            if not self.getNumFrames(animName) is None:
                frame = self.getCurrentFrame(animName)

                if frame is None:
                    frame = 0
                    self.pose(animName, 0)

                self.accept('h',
                            self.__traverseAnimation,
                            extraArgs=[animName, -1])
                self.accept('j',
                            self.__traverseAnimation,
                            extraArgs=[animName, 1])

                self.__traverseGUI = OnscreenText(
                    text=
                    'Current Frame: {0}\n\'H\' Decrease Frame, \'J\' Increase Frame'
                    .format(str(frame)),
                    pos=(0, -0.75),
                    font=CIGlobals.getToonFont(),
                    fg=(1, 1, 1, 1),
                    shadow=(0, 0, 0, 1))
            else:
                self.notify.info(
                    'Tried to traverse unknown animation: {0}'.format(
                        animName))

    def __traverseAnimation(self, animName, delta):
        frame = self.getCurrentFrame(animName)
        if frame is None:
            frame = 0

        if (frame + delta) < 0:
            frame = self.getNumFrames(animName) - 1
        elif (frame + delta) > (self.getNumFrames(animName) - 1):
            frame = self.getNumFrames(animName) - 1
        else:
            frame += delta
        self.pose(animName, frame)
        self.__traverseGUI.setText(
            'Current Frame: {0}\n\'H\' Decrease Frame, \'J\' Increase Frame'.
            format(str(frame)))

    def endTraverseAnimationControls(self):
        self.ignore('h')
        self.ignore('j')

        if self.__traverseGUI:
            self.__traverseGUI.destroy()
            self.__traverseGUI = None

    def generate(self):
        DistributedPlayerToon.generate(self)

    def delete(self):
        DistributedPlayerToon.delete(self)
        self.deleteLaffMeter()
        return

    def disable(self):
        DistributedPlayerToon.disable(self)

        self.stopTrackAnimToSpeed()
        base.camLens.setMinFov(CIGlobals.OriginalCameraFov / (4. / 3.))
        if self.jumpHardLandIval:
            self.ignore('LT::zend-done')
            self.jumpHardLandIval.finish()
            self.jumpHardLandIval = None
        if self.friendsList:
            self.friendsList.destroy()
            self.friendsList = None
        if self.panel:
            self.panel.cleanup()
            self.panel = None
        if self.positionExaminer:
            self.positionExaminer.delete()
            self.positionExaminer = None
        self.disablePicking()
        self.destroyFriendButton()
        self.stopLookAround()
        self.disableAvatarControls()
        self.destroyControls()
        if self.smartCamera:
            self.smartCamera.stopUpdateSmartCamera()
            self.smartCamera.deleteSmartCameraCollisions()
            self.smartCamera = None
        if self.questManager:
            self.questManager.cleanup()
            self.questManager = None
        if self.questUpdateGUI:
            self.questUpdateGUI.cleanup()
            self.questUpdateGUI = None
        if self.friendRequestManager:
            self.friendRequestManager.cleanup()
            self.friendRequestManager = None
        self.destroyInvGui()
        if self.crosshair:
            self.crosshair.destroy()
            self.crosshair = None
        self.disableLaffMeter()
        self.disableGags()
        self.disableChatInput()
        self.hideBookButton()
        self.weaponType = None
        self.runSfx = None
        self.walkSfx = None
        self.offset = None
        self.movementKeymap = None
        self.minigame = None
        self.inTutorial = None
        self.avatarChoice = None
        self.chatInputState = None
        self.playState = None
        self.endTraverseAnimationControls()
        self.ignore("gotLookSpot")
        self.ignore("clickedWhisper")
        self.ignore('/')
        self.ignore(base.inputStore.ToggleAspect2D)
        return

    def delete(self):
        DistributedPlayerToon.delete(self)
        del base.localAvatar
        del __builtins__['localAvatar']
        print "Local avatar finally deleted"

    def sewerHeadOff(self, zoneId):
        # TEMPORARY
        requestStatus = {
            'zoneId': zoneId,
            'hoodId': 0,
            'where': 'sewer',
            'avId': self.doId,
            'loader': 'sewer',
            'shardId': None,
            'wantLaffMeter': 1
        }
        self.cr.playGame.getPlace().fsm.request('teleportOut', [requestStatus])

    def announceGenerate(self):
        DistributedPlayerToon.announceGenerate(self)
        self.setupControls()
        self.startLookAround()
        self.friendRequestManager.watch()
        self.accept("gotLookSpot", self.handleLookSpot)
        self.accept("clickedWhisper", self.handleClickedSentWhisper)
        self.accept(base.inputStore.ToggleAspect2D, self.toggleAspect2d)

        if not metadata.IS_PRODUCTION:
            self.acceptOnce('m', self.sendUpdate, ['reqMakeSewer'])
            self.accept('l', render.ls)
            self.accept('/', self.printPos)
            self.accept('\\', self.printPos_cam)

        #self.accept('c', self.walkControls.setCollisionsActive, [0])

        self.createInvGui()

        # Unused developer methods.
        #self.accept('p', self.enterPictureMode)
        #self.accept('c', self.teleportToCT)
        #posBtn = DirectButton(text = "Get Pos", scale = 0.08, pos = (0.3, 0, 0), parent = base.a2dLeftCenter, command = self.printAvPos)

    def enterHiddenToonMode(self):
        self.laffMeter.stop()
        self.laffMeter.disable()
        self.laffMeter.destroy()
        self.getGeomNode().hide()
        self.deleteNameTag()
        self.invGui.disable()
        self.hideFriendButton()
        self.hideBookButton()
        self.removeAdminToken()
Esempio n. 11
0
class PandaPmViewer:
    def __init__(self, mesh, pm_filebuf):

        scene_members = getSceneMembers(mesh)

        base = ShowBase()

        if len(scene_members) > 1:
            print 'There is more than one geometry in the scene, so I think this is not a progressive base mesh.'
            sys.exit(1)

        rotateNode = GeomNode("rotater")
        rotatePath = render.attachNewNode(rotateNode)
        matrix = numpy.identity(4)
        if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
            r = collada.scene.RotateTransform(0, 1, 0, 90)
            matrix = r.matrix
        elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
            r = collada.scene.RotateTransform(1, 0, 0, 90)
            matrix = r.matrix
        rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))

        geom, renderstate, mat4 = scene_members[0]
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        self.geomPath = rotatePath.attachNewNode(node)
        self.geomPath.setMat(mat4)

        wrappedNode = ensureCameraAt(self.geomPath, base.camera)
        base.disableMouse()
        attachLights(render)
        render.setShaderAuto()
        render.setTransparency(TransparencyAttrib.MDual, 1)

        base.render.analyze()
        KeyboardMovement()
        MouseDrag(wrappedNode)
        MouseScaleZoom(wrappedNode)
        ButtonUtils(wrappedNode)
        MouseCamera()

        print 'Loading pm into memory... ',
        sys.stdout.flush()
        self.pm_refinements = readPDAE(pm_filebuf)
        self.pm_index = 0
        print 'Done'

        self.slider = DirectSlider(range=(0, len(self.pm_refinements)),
                                   value=0,
                                   pageSize=len(self.pm_refinements) / 20,
                                   command=self.sliderMoved,
                                   pos=(0, 0, -.9),
                                   scale=1)
        for key, val in uiArgs.iteritems():
            self.slider.thumb[key] = val

        self.triText = OnscreenText(text="",
                                    pos=(-1, 0.85),
                                    scale=0.15,
                                    fg=(1, 0.5, 0.5, 1),
                                    align=TextNode.ALeft,
                                    mayChange=1)

        base.run()

    def sliderMoved(self):
        sliderVal = int(self.slider['value'])
        if self.pm_index != sliderVal:
            self.movePmTo(sliderVal)
        self.triText.setText(
            'Triangles: ' +
            str(self.geomPath.node().getGeom(0).getPrimitive(0).getNumFaces()))

    def movePmTo(self, dest_index):
        geom = self.geomPath.node().modifyGeom(0)
        vertdata = geom.modifyVertexData()
        prim = geom.modifyPrimitive(0)
        indexdata = prim.modifyVertices()

        indexrewriter = GeomVertexRewriter(indexdata)
        indexrewriter.setColumn(0)
        nextTriangleIndex = indexdata.getNumRows()

        vertwriter = GeomVertexWriter(vertdata, 'vertex')
        numverts = vertdata.getNumRows()
        vertwriter.setRow(numverts)
        normalwriter = GeomVertexWriter(vertdata, 'normal')
        normalwriter.setRow(numverts)
        uvwriter = GeomVertexWriter(vertdata, 'texcoord')
        uvwriter.setRow(numverts)

        while self.pm_index < dest_index:
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    indexrewriter.setRow(nextTriangleIndex)
                    nextTriangleIndex += 3
                    indexrewriter.addData1i(vals[1])
                    indexrewriter.addData1i(vals[2])
                    indexrewriter.addData1i(vals[3])
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader

                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()

                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op,
                                                                    vals[1],
                                                                    oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts += 1
                    vertwriter.addData3f(vals[1], vals[2], vals[3])
                    normalwriter.addData3f(vals[4], vals[5], vals[6])
                    uvwriter.addData2f(vals[7], vals[8])

            self.pm_index += 1

        while self.pm_index > dest_index:
            self.pm_index -= 1
            for op_index in range(len(self.pm_refinements[self.pm_index])):
                vals = self.pm_refinements[self.pm_index][op_index]
                op = vals[0]
                if op == PM_OP.TRIANGLE_ADDITION:
                    nextTriangleIndex -= 3
                elif op == PM_OP.INDEX_UPDATE:
                    #TODO: ugly workaround for p3d 1.7 bug, change to below for 1.8
                    indexreader = GeomVertexReader(indexdata)
                    indexreader.setColumn(0)
                    indexreader.setRow(vals[1])
                    oldval = indexreader.getData1i()
                    del indexreader

                    #indexrewriter.setRow(vals[1])
                    #oldval = indexrewriter.getData1i()

                    indexrewriter.setRow(vals[1])
                    indexrewriter.setData1i(vals[2])
                    self.pm_refinements[self.pm_index][op_index] = (op,
                                                                    vals[1],
                                                                    oldval)
                elif op == PM_OP.VERTEX_ADDITION:
                    numverts -= 1

        if nextTriangleIndex < indexdata.getNumRows():
            indexdata.setNumRows(nextTriangleIndex)
        if numverts < vertdata.getNumRows():
            vertdata.setNumRows(numverts)
class QuestNote(DirectFrame):
    notify = directNotify.newCategory("QuestNote")

    spots = [(-0.45, 0, 0.3), (0.45, 0, 0.3), (0.45, 0, -0.25),
             (-0.45, 0, -0.25)]
    RewardTextPos = (0, -0.4)
    RewardTextScale = 0.06
    ProgressTextScale = 0.07
    ProgressBarPos = (0, 0, -0.19)
    ProgressTextPos = (0, -0.19)
    TaskInfoTextPos = (0, 0.05)
    NonHeadingTextScale = 0.08
    HeadingTextPos = (0, 0.23)
    HeadingTextScale = 0.1

    def __init__(self, index):
        DirectFrame.__init__(self, scale=0.5)
        stickergui = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')
        self['image'] = stickergui.find('**/paper_note')
        self['image_scale'] = (1.3, 1, 1)
        self.setPos(self.spots[index])
        self.useProgressBar = False
        self.headingText = OnscreenText(parent=self,
                                        text="",
                                        font=CIGlobals.getToonFont(),
                                        pos=self.HeadingTextPos,
                                        scale=self.HeadingTextScale)
        self.taskInfoText = OnscreenText(parent=self,
                                         text="",
                                         font=CIGlobals.getToonFont(),
                                         pos=self.TaskInfoTextPos,
                                         scale=self.NonHeadingTextScale)
        self.progressText = OnscreenText(parent=self,
                                         text="",
                                         font=CIGlobals.getToonFont(),
                                         pos=self.ProgressTextPos,
                                         scale=self.ProgressTextScale)
        self.progressBar = DirectWaitBar(
            parent=self,
            relief=DGG.SUNKEN,
            frameSize=(-0.95, 0.95, -0.1, 0.12),
            borderWidth=(0.025, 0.025),
            scale=0.4,
            frameColor=(251.0 / 255, 252.0 / 255, 176.0 / 255, 1.0),
            barColor=(0.5, 0.7, 0.5, 1),
            text='0/0',
            text_font=CIGlobals.getToonFont(),
            text_scale=0.19,
            text_fg=(0.05, 0.14, 0.4, 1),
            text_align=TextNode.ACenter,
            text_pos=(0, -0.05),  #-0.02
            pos=self.ProgressBarPos)
        self.progressBar.hide()
        self.rewardText = OnscreenText(parent=self,
                                       text="",
                                       font=CIGlobals.getToonFont(),
                                       pos=self.RewardTextPos,
                                       scale=self.RewardTextScale,
                                       fg=(1, 0.1, 0.1, 1.0))
        self.hide()

    def setHeading(self, text):
        self.headingText.setText(text)

    def setTaskInfo(self, text):
        self.taskInfoText.setText(text)

    def setProgress(self, text, range=0, value=0):
        if self.useProgressBar:
            self.progressBar.show()
            self.progressBar['text'] = text
            self.progressBar['range'] = range
            self.progressBar['value'] = value
        else:
            self.progressText['text'] = text

    def setReward(self, text):
        self.rewardText.setText(text)

    def setCompleted(self, value):
        if value:
            self.progressBar.hide()
            self['image_color'] = QuestGlobals.LIGHT_GREEN
Esempio n. 13
0
class DistributedGunGame(DistributedToonFPSGame, TeamMinigame):
    notify = directNotify.newCategory("DistributedGunGame")
    GameMode2Description = {GGG.GameModes.CASUAL: "Battle and defeat the Toons on the other team with your gun to gain points. " + \
                        "Remember to reload your gun when you're out of ammo! " + \
                        "The Toon with the most points when the timer runs out gets a nice prize!",
                        GGG.GameModes.CTF: "Steal the other team's flag and take it to where your flag is to score a point. Follow the arrows at the bottom of the screen to find the flags! Use your gun to defend yourself and your flag!",
                        GGG.GameModes.KOTH : "Capture the central point and defend it from the other Toons. The Toon who holds the point the longest wins."}
    GameMode2Music = {
        GGG.GameModes.CASUAL: 'phase_4/audio/bgm/MG_TwoDGame.ogg',
        GGG.GameModes.CTF: 'phase_9/audio/bgm/CHQ_FACT_bg.ogg',
        GGG.GameModes.KOTH: 'phase_7/audio/bgm/encntr_suit_winning_indoor.ogg'
    }

    def __init__(self, cr):
        try:
            self.DistributedGunGame_initialized
            return
        except:
            self.DistributedGunGame_initialized = 1
        DistributedToonFPSGame.__init__(self, cr)

        TeamMinigame.__init__(
            self, GGG.BLUE,
            ('phase_4/maps/blue_neutral.png', 'phase_4/maps/blue_hover.png',
             'phase_4/maps/blue_hover.png'), GGG.RED,
            ('phase_4/maps/red_neutral.png', 'phase_4/maps/red_hover.png',
             'phase_4/maps/red_hover.png'))

        self.fsm.addState(
            State('countdown', self.enterCountdown, self.exitCountdown,
                  ['play']))
        self.fsm.addState(
            State('announceGameOver', self.enterAnnounceGameOver,
                  self.exitAnnounceGameOver, ['finalScores']))
        self.fsm.addState(
            State('finalScores', self.enterFinalScores, self.exitFinalScores,
                  ['gameOver']))
        self.fsm.addState(
            State('voteGM', self.enterVoteGameMode, self.exitVoteGameMode,
                  ['start']))
        self.fsm.addState(
            State('chooseTeam', self.enterChooseTeam, self.exitChooseTeam,
                  ['chooseGun']))
        self.fsm.addState(
            State('chooseGun', self.enterChooseGun, self.exitChooseGun,
                  ['waitForOthers']))
        self.fsm.addState(
            State('announceTeamWon', self.enterAnnounceTeamWon,
                  self.exitAnnounceTeamWon, ['finalScores']))
        self.fsm.getStateNamed('waitForOthers').addTransition('countdown')
        self.fsm.getStateNamed('waitForOthers').addTransition('voteGM')
        self.fsm.getStateNamed('play').addTransition('announceGameOver')
        self.fsm.getStateNamed('play').addTransition('announceTeamWon')
        self.fsm.getStateNamed('start').addTransition('chooseTeam')
        self.fsm.getStateNamed('start').addTransition('chooseGun')
        self.toonFps = GunGameToonFPS(self)
        self.loader = GunGameLevelLoader.GunGameLevelLoader(self)
        self.track = None
        self.isTimeUp = False
        self.cameraMovmentSeq = None
        self.gameMode = None
        self.flags = []
        self.localAvHasFlag = False
        self.blueScoreLbl = None
        self.redScoreLbl = None
        self.redArrow = None
        self.blueArrow = None
        self.infoLbl = None
        self.scoreByTeam = {GGG.Teams.RED: 0, GGG.Teams.BLUE: 0}
        self.balloonSound = base.loadSfx(
            'phase_3/audio/sfx/GUI_balloon_popup.ogg')
        self.decidedSound = base.loadSfx(
            'phase_4/audio/sfx/MG_sfx_travel_game_win_vote.ogg')
        return

    def setKOTHPoints(self, points):
        self.toonFps.setKOTHPoints(points)
        DistributedToonFPSGame.setMyKOTHPoints(self, points)

    def getFlagOfOtherTeam(self, team):
        for flag in self.flags:
            if flag.team != team:
                return flag

    def startGameModeVote(self):
        self.fsm.request('voteGM')

    def enterVoteGameMode(self):
        render.hide()
        font = CIGlobals.getMickeyFont()
        imp = CIGlobals.getToonFont()
        box = DGG.getDefaultDialogGeom()
        geom = CIGlobals.getDefaultBtnGeom()
        self.container = DirectFrame()
        self.bg = OnscreenImage(image=box,
                                color=(1, 1, 0.75, 1),
                                scale=(2.4, 1.4, 1.4),
                                parent=self.container)
        self.title = OnscreenText(text="Vote  on  Game  Mode",
                                  pos=(0, 0.5, 0),
                                  font=font,
                                  scale=(0.12),
                                  parent=self.container,
                                  fg=(1, 0.9, 0.3, 1))
        self.btnFrame = DirectFrame(parent=self.container, pos=(0.14, 0, 0))
        self.casualFrame = DirectFrame(parent=self.btnFrame, pos=(-0.80, 0, 0))
        self.ctfFrame = DirectFrame(parent=self.btnFrame, pos=(-0.125, 0, 0))
        self.kothFrame = DirectFrame(parent=self.btnFrame, pos=(0.55, 0, 0))
        self.casual = DirectButton(parent=self.casualFrame,
                                   relief=None,
                                   pressEffect=0,
                                   image=('phase_4/maps/casual_neutral.png',
                                          'phase_4/maps/casual_hover.png',
                                          'phase_4/maps/casual_hover.png'),
                                   image_scale=(0.9, 1, 1),
                                   scale=0.4,
                                   command=self.__pickedGameMode,
                                   extraArgs=[GGG.GameModes.CASUAL])
        self.casual_votesLbl = OnscreenText(parent=self.casualFrame,
                                            text="0",
                                            pos=(0, -0.46, 0),
                                            font=imp)
        self.ctf = DirectButton(parent=self.ctfFrame,
                                relief=None,
                                pressEffect=0,
                                image=('phase_4/maps/ctf_neutral.png',
                                       'phase_4/maps/ctf_hover.png',
                                       'phase_4/maps/ctf_hover.png'),
                                image_scale=(0.9, 1, 1),
                                scale=0.4,
                                command=self.__pickedGameMode,
                                extraArgs=[GGG.GameModes.CTF])
        self.ctf_votesLbl = OnscreenText(parent=self.ctfFrame,
                                         text="0",
                                         pos=(0, -0.46, 0),
                                         font=imp)
        self.koth = DirectButton(parent=self.kothFrame,
                                 relief=None,
                                 pressEffect=0,
                                 image=('phase_4/maps/koth_neutral.png',
                                        'phase_4/maps/koth_hover.png',
                                        'phase_4/maps/koth_hover.png'),
                                 image_scale=(0.9, 1, 1),
                                 scale=0.4,
                                 command=self.__pickedGameMode,
                                 extraArgs=[GGG.GameModes.KOTH])
        self.koth_votesLbl = OnscreenText(parent=self.kothFrame,
                                          text="0",
                                          pos=(0, -0.46, 0),
                                          font=imp)
        self.outcomeLbl = OnscreenText(parent=self.container,
                                       text="",
                                       pos=(0, -0.6, 0),
                                       font=imp,
                                       scale=0.1)

    def __pickedGameMode(self, mode):
        self.sendUpdate('myGameModeVote', [mode])
        self.ctf['state'] = DGG.DISABLED
        self.casual['state'] = DGG.DISABLED
        self.koth['state'] = DGG.DISABLED
        if mode == GGG.GameModes.CASUAL:
            self.ctf['image'] = 'phase_4/maps/ctf_neutral.png'
            self.koth['image'] = 'phase_4/maps/koth_neutral.png'
            self.casual['image'] = 'phase_4/maps/casual_hover.png'
        elif mode == GGG.GameModes.CTF:
            self.ctf['image'] = 'phase_4/maps/ctf_hover.png'
            self.casual['image'] = 'phase_4/maps/casual_neutral.png'
            self.koth['image'] = 'phase_4/maps/koth_neutral.png'
        elif mode == GGG.GameModes.KOTH:
            self.ctf['image'] = 'phase_4/maps/ctf_neutral.png'
            self.casual['image'] = 'phase_4/maps/casual_neutral.png'
            self.koth['image'] = 'phase_4/maps/koth_hover.png'

    def incrementGameModeVote(self, mode):
        base.playSfx(self.balloonSound)
        lbl = None
        if mode == GGG.GameModes.CTF:
            lbl = self.ctf_votesLbl
        elif mode == GGG.GameModes.CASUAL:
            lbl = self.casual_votesLbl
        elif mode == GGG.GameModes.KOTH:
            lbl = self.koth_votesLbl
        if lbl:
            lbl.setText(str(int(lbl.getText()) + 1))

    def gameModeDecided(self, mode, wasRandom):
        base.playSfx(self.decidedSound)
        if wasRandom:
            msg = GGG.MSG_CHOSE_MODE_TIE.format(GGG.GameModeNameById[mode])
        else:
            msg = GGG.MSG_CHOSE_MODE.format(GGG.GameModeNameById[mode])
        self.outcomeLbl.setText(msg)
        base.taskMgr.doMethodLater(3.0, self.__decided2chooseTeamTask,
                                   self.uniqueName('decided2chooseTeamTask'))

    def __decided2chooseTeamTask(self, task):
        self.fsm.request('start')
        return task.done

    def exitVoteGameMode(self):
        base.taskMgr.remove(self.uniqueName('decided2chooseTeamTask'))
        self.outcomeLbl.destroy()
        del self.outcomeLbl
        self.ctf_votesLbl.destroy()
        del self.ctf_votesLbl
        self.casual_votesLbl.destroy()
        del self.casual_votesLbl
        self.ctf.destroy()
        del self.ctf
        self.koth_votesLbl.destroy()
        del self.koth_votesLbl
        self.casual.destroy()
        del self.casual
        self.ctfFrame.destroy()
        del self.ctfFrame
        self.casualFrame.destroy()
        del self.casualFrame
        self.kothFrame.destroy()
        del self.kothFrame
        self.koth.destroy()
        del self.koth
        self.title.destroy()
        del self.title
        self.bg.destroy()
        del self.bg
        self.container.destroy()
        del self.container

    def enterChooseTeam(self):
        TeamMinigame.makeSelectionGUI(self)

    def acceptedIntoTeam(self):
        TeamMinigame.acceptedIntoTeam(self)

        self.fsm.request('chooseGun')
        pos, hpr = self.pickSpawnPoint()
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)

    def exitChooseTeam(self):
        TeamMinigame.destroySelectionGUI(self)

    def setTeamOfPlayer(self, avId, team):
        remoteAvatar = self.getRemoteAvatar(avId)
        if remoteAvatar:
            remoteAvatar.setTeam(team)

    def enterChooseGun(self):
        font = CIGlobals.getToonFont()
        box = DGG.getDefaultDialogGeom()
        geom = CIGlobals.getDefaultBtnGeom()
        self.container = DirectFrame()
        self.bg = OnscreenImage(image=box,
                                color=(1, 1, 0.75, 1),
                                scale=(1.9, 1.4, 1.4),
                                parent=self.container)
        self.title = OnscreenText(text="Choose a Gun",
                                  pos=(0, 0.5, 0),
                                  font=font,
                                  scale=(0.12),
                                  parent=self.container)
        self.pistolBtn = DirectButton(geom=geom,
                                      text="Pistol",
                                      relief=None,
                                      text_scale=0.055,
                                      text_pos=(0, -0.01),
                                      command=self.__gunChoice,
                                      extraArgs=["pistol"],
                                      pos=(0, 0, 0.35),
                                      parent=self.container)
        self.shotgunBtn = DirectButton(geom=geom,
                                       text="Shotgun",
                                       relief=None,
                                       text_scale=0.055,
                                       text_pos=(0, -0.01),
                                       command=self.__gunChoice,
                                       extraArgs=["shotgun"],
                                       pos=(0, 0, 0.25),
                                       parent=self.container)
        self.sniperBtn = DirectButton(geom=geom,
                                      text="Sniper",
                                      relief=None,
                                      text_scale=0.055,
                                      text_pos=(0, -0.01),
                                      command=self.__gunChoice,
                                      extraArgs=["sniper"],
                                      pos=(0, 0, 0.15),
                                      parent=self.container)

    def __gunChoice(self, choice):
        self.toonFps.cleanup()
        self.toonFps = None
        self.toonFps = GunGameToonFPS(self, choice)
        self.toonFps.load()
        self.sendUpdate('readyToStart')
        self.fsm.request('waitForOthers')

    def exitChooseGun(self):
        self.sniperBtn.destroy()
        del self.sniperBtn
        self.shotgunBtn.destroy()
        del self.shotgunBtn
        self.pistolBtn.destroy()
        del self.pistolBtn
        self.title.destroy()
        del self.title
        self.bg.destroy()
        del self.bg
        self.container.destroy()
        del self.container

    def gunChoice(self, choice, avId):
        remoteAvatar = self.getRemoteAvatar(avId)
        if remoteAvatar:
            remoteAvatar.setGunName(choice)

    def setGameMode(self, mode):
        self.gameMode = mode
        self.setDescription(self.GameMode2Description[mode])
        self.setMinigameMusic(self.GameMode2Music[mode])

    def getGameMode(self):
        return self.gameMode

    def avatarHitByBullet(self, avId, damage):
        avatar = self.getRemoteAvatar(avId)
        if avatar:
            avatar.grunt()

    def headBackToMinigameArea(self):
        if self.loader:
            self.loader.unload()
            self.loader.cleanup()
            self.loader = None
        DistributedToonFPSGame.headBackToMinigameArea(self)

    def setupRemoteAvatar(self, avId):
        self.remoteAvatars.append(RemoteToonBattleAvatar(self, self.cr, avId))

    def setLevelName(self, levelName):
        self.loader.setLevel(levelName)
        self.loader.load()

    def pickSpawnPoint(self):
        return random.choice(self.loader.getSpawnPoints())

    def load(self):
        self.toonFps.load()
        self.myRemoteAvatar = RemoteToonBattleAvatar(self, self.cr,
                                                     base.localAvatar.doId)
        self.setWinnerPrize(200)
        self.setLoserPrize(15)

        if not base.localAvatar.tokenIcon is None:
            base.localAvatar.tokenIcon.hide()

        #pos, hpr = self.loader.getCameraOfCurrentLevel()
        #camera.setPos(pos)
        #camera.setHpr(hpr)
        DistributedToonFPSGame.load(self, showDesc=False)
        DistributedToonFPSGame.handleDescAck(self)

    def handleDescAck(self):
        if self.gameMode in GGG.FFA_MODES:
            # This is a free for all game mode, don't choose teams.
            self.fsm.request('chooseGun')
            pos, hpr = self.pickSpawnPoint()
            base.localAvatar.setPos(pos)
            base.localAvatar.setHpr(hpr)
        else:
            self.fsm.request('chooseTeam')

    def incrementKills(self):
        self.toonFps.killedSomebody()

    def allPlayersReady(self):
        self.fsm.request('countdown')

    def timeUp(self):
        if not self.isTimeUp:
            self.fsm.request('announceGameOver')
            self.isTimeUp = True

    def teamWon(self, team, timeRanOut=0):
        self.fsm.request('announceTeamWon', [team])

    def enterAnnounceTeamWon(self, team):
        whistleSfx = base.loadSfx("phase_4/audio/sfx/AA_sound_whistle.ogg")
        whistleSfx.play()
        del whistleSfx

        if self.gameMode == GGG.GameModes.KOTH and DistributedToonFPSGame.getKOTHKing(
                self):
            text = DistributedToonFPSGame.getKOTHKing(self).getName()
        else:
            text = GGG.TeamNameById[team].split(' ')[0]
        self.gameOverLbl.setText("{0}\nWins!".format(text))
        self.gameOverLbl.show()
        self.track = Sequence(Wait(3.0), Func(self.fsm.request, 'finalScores'))
        self.track.start()

    def exitAnnounceTeamWon(self):
        if self.track:
            self.track.pause()
            self.track = None

    def enterAnnounceGameOver(self):
        whistleSfx = base.loadSfx("phase_4/audio/sfx/AA_sound_whistle.ogg")
        whistleSfx.play()
        del whistleSfx
        self.gameOverLbl.setText("TIME's\nUP!")
        self.gameOverLbl.show()
        self.track = Sequence(Wait(3.0), Func(self.fsm.request, 'finalScores'))
        self.track.start()

    def exitAnnounceGameOver(self):
        if self.track:
            self.track.pause()
            self.track = None

    def enterFinalScores(self):
        DistributedToonFPSGame.enterFinalScores(self)
        self.sendUpdate('myFinalScore', [self.toonFps.points])

    def exitFinalScores(self):
        DistributedToonFPSGame.exitFinalScores(self)

    def incrementTeamScore(self, team):
        self.scoreByTeam[team] += 1
        if team == GGG.Teams.BLUE:
            self.blueScoreLbl.setText("Blue: {0}".format(
                self.scoreByTeam[team]))
        elif team == GGG.Teams.RED:
            self.redScoreLbl.setText('Red: {0}'.format(self.scoreByTeam[team]))

    def __updateArrows(self, task):
        blueFlag = None
        redFlag = None

        for flag in self.flags:
            if flag.team == GGG.Teams.BLUE:
                blueFlag = flag
            if flag.team == GGG.Teams.RED:
                redFlag = flag

        if not blueFlag or not redFlag:
            return task.done

        bLocation = blueFlag.flagMdl.getPos(base.cam)
        bRotation = base.cam.getQuat(base.cam)
        bCamSpacePos = bRotation.xform(bLocation)
        bArrowRadians = math.atan2(bCamSpacePos[0], bCamSpacePos[1])
        bArrowDegrees = (bArrowRadians / math.pi) * 180
        self.blueArrow.setR(bArrowDegrees - 90)

        rLocation = redFlag.flagMdl.getPos(base.cam)
        rRotation = base.cam.getQuat(base.cam)
        rCamSpacePos = rRotation.xform(rLocation)
        rArrowRadians = math.atan2(rCamSpacePos[0], rCamSpacePos[1])
        rArrowDegrees = (rArrowRadians / math.pi) * 180
        self.redArrow.setR(rArrowDegrees - 90)

        return task.cont

    def getTeamScoreLbl(self, team):
        if team == GGG.Teams.BLUE:
            return self.blueScoreLbl
        elif team == GGG.Teams.RED:
            return self.redScoreLbl

    def getTeamFlagArrow(self, team):
        if team == GGG.Teams.BLUE:
            return self.blueArrow
        elif team == GGG.Teams.RED:
            return self.redArrow

    def getTeamFrame(self, team):
        if team == GGG.Teams.BLUE:
            return self.blueFrame
        elif team == GGG.Teams.RED:
            return self.redFrame

    def enterCountdown(self):
        render.show()
        if self.gameMode == GGG.GameModes.CTF:
            self.blueFrame = DirectFrame(pos=(-0.1, 0, -0.85))
            self.blueScoreLbl = OnscreenText(
                text="Blue: 0",
                scale=0.1,
                parent=self.blueFrame,
                fg=GGG.TeamColorById[GGG.Teams.BLUE],
                shadow=(0, 0, 0, 1),
                align=TextNode.ARight)
            self.blueArrow = loader.loadModel('phase_3/models/props/arrow.bam')
            self.blueArrow.setColor(GGG.TeamColorById[GGG.Teams.BLUE])
            self.blueArrow.reparentTo(self.blueFrame)
            self.blueArrow.setPos(-0.1, 0, 0.15)
            self.blueArrow.setScale(0.1)
            self.redFrame = DirectFrame(pos=(0.1, 0, -0.85))
            self.redScoreLbl = OnscreenText(
                text="Red: 0",
                scale=0.1,
                parent=self.redFrame,
                fg=GGG.TeamColorById[GGG.Teams.RED],
                shadow=(0, 0, 0, 1),
                align=TextNode.ALeft)
            self.redArrow = loader.loadModel('phase_3/models/props/arrow.bam')
            self.redArrow.setColor(GGG.TeamColorById[GGG.Teams.RED])
            self.redArrow.reparentTo(self.redFrame)
            self.redArrow.setPos(0.1, 0, 0.15)
            self.redArrow.setScale(0.1)
            self.infoLbl = OnscreenText(text="Playing to: 3",
                                        scale=0.1,
                                        pos=(0, -0.95),
                                        fg=(1, 1, 1, 1),
                                        shadow=(0, 0, 0, 1))
            base.taskMgr.add(self.__updateArrows,
                             self.uniqueName('updateArrows'))
        camera.setPos(0, 0, 0)
        camera.setHpr(0, 0, 0)
        self.toonFps.fsm.request('alive')
        text = OnscreenText(text="",
                            scale=0.1,
                            pos=(0, 0.5),
                            fg=(1, 1, 1, 1),
                            shadow=(0, 0, 0, 1))
        self.track = Sequence(Func(text.setText, "5"), Wait(1.0),
                              Func(text.setText, "4"), Wait(1.0),
                              Func(text.setText, "3"), Wait(1.0),
                              Func(text.setText, "2"), Wait(1.0),
                              Func(text.setText, "1"), Wait(1.0),
                              Func(text.setText, "FIGHT!"),
                              Func(self.fsm.request, 'play'), Wait(1.0),
                              Func(text.destroy))
        self.track.start()
        self.sendUpdate('gunChoice',
                        [self.toonFps.weaponName, base.localAvatar.doId])

    def exitCountdown(self):
        if self.track:
            self.track.finish()
            self.track = None

    def enterPlay(self):
        DistributedToonFPSGame.enterPlay(self)
        self.toonFps.reallyStart()
        self.createTimer()

    def exitPlay(self):
        self.deleteTimer()
        if self.toonFps:
            self.toonFps.end()
        DistributedToonFPSGame.exitPlay(self)

    def announceGenerate(self):
        DistributedToonFPSGame.announceGenerate(self)
        base.localAvatar.walkControls.setWalkSpeed(GGG.ToonForwardSpeed,
                                                   GGG.ToonJumpForce,
                                                   GGG.ToonReverseSpeed,
                                                   GGG.ToonRotateSpeed)
        self.load()
        base.camLens.setMinFov(CIGlobals.GunGameFOV / (4. / 3.))

    def disable(self):
        render.show()
        base.localAvatar.setWalkSpeedNormal()

        # Show the staff icon again.
        if not base.localAvatar.tokenIcon is None:
            base.localAvatar.tokenIcon.show()

        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.))
        base.taskMgr.remove(self.uniqueName('updateArrows'))
        self.playersByTeam = None
        if self.blueArrow:
            self.blueArrow.removeNode()
            self.blueArrow = None
        if self.redArrow:
            self.redArrow.removeNode()
            self.redArrow = None
        if self.blueScoreLbl:
            self.blueScoreLbl.destroy()
            self.blueScoreLbl = None
        if self.redScoreLbl:
            self.redScoreLbl.destroy()
            self.redScoreLbl = None
        if self.infoLbl:
            self.infoLbl.destroy()
            self.infoLbl = None
        self.scoreByTeam = None
        self.flags = None
        self.gameMode = None
        self.team = None
        self.localAvHasFlag = None
        if self.loader:
            self.loader.unload()
            self.loader.cleanup()
            self.loader = None
        self.isTimeUp = None
        self.toonFps.reallyEnd()
        self.toonFps.cleanup()
        self.toonFps = None
        self.spawnPoints = None
        DistributedToonFPSGame.disable(self)
Esempio n. 14
0
class DistributedCameraShyGame(DistributedMinigame):
    notify = directNotify.newCategory('DistributedCameraShyGame')

    def __init__(self, cr):
        try:
            self.DistributedCameraShyGame_initialized
            return
        except:
            self.DistributedCameraShyGame_initialized = 1

        DistributedMinigame.__init__(self, cr)
        self.headPanels.delete()
        self.headPanels = CameraShyHeadPanels()
        self.fsm.addState(State('countdown', self.enterCountdown, self.exitCountdown, ['play']))
        self.fsm.addState(State('announceGameOver', self.enterAnnounceGameOver, self.exitAnnounceGameOver, ['showWinner']))
        self.fsm.addState(State('showWinner', self.enterShowWinner, self.exitShowWinner, ['gameOver']))
        self.fsm.getStateNamed('waitForOthers').addTransition('countdown')
        self.fsm.getStateNamed('play').addTransition('announceGameOver')
        self.maze = None
        self.mazeCollModel = None
        self.spawnPoints = []
        self.remoteAvatars = []
        self.myRemoteAvatar = None
        self.thisPlayerWinsLbl = None
        self.sky = None
        self.firstPerson = CameraShyFirstPerson(self)
        self.skyUtil = None
        self.pbpText = None
        return

    def generateOtherPlayerGui(self):
        self.headPanels.generateOtherPlayerGui()

    def updateOtherPlayerHead(self, avId, otherAvId, state):
        self.headPanels.updateOtherPlayerHead(avId, otherAvId, state)

    def getPlayByPlayText(self):
        return OnscreenText(text='', fg=(1, 1, 1, 1), shadow=(0, 0, 0, 1), pos=(0, 0.75))

    def removePlayByPlay(self):
        if self.pbpText:
            taskMgr.remove('DCameraShyGame-removePlayByPlay')
            self.pbpText.destroy()
            self.pbpText = None
        return

    def removePlayByPlayTask(self, task):
        self.removePlayByPlay()
        return Task.done

    def showPlayByPlay(self, situation, avId):
        self.removePlayByPlay()
        av = self.cr.doId2do.get(avId)
        name = av.getName()
        if situation == 0:
            self.pbpText = self.getPlayByPlayText()
            self.pbpText.setText('{0} took a picture of you!'.format(name))
        taskMgr.doMethodLater(3.0, self.removePlayByPlayTask, 'DCameraShyGame-removePlayByPlay')

    def tookPictureOfMe(self, avId):
        self.headPanels.hideFrames()
        self.firstPerson.stopCameraFlash()
        base.transitions.setFadeColor(1, 1, 1)
        base.transitions.fadeOut(0.1)
        self.showPlayByPlay(0, avId)
        Sequence(Wait(1), Func(self.respawn)).start()

    def respawn(self):
        base.transitions.fadeIn()
        pos, hpr = self.pickSpawnPoint()
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr - (180, 0, 0))
        base.localAvatar.d_broadcastPositionNow()
        Sequence(Wait(0.6), Func(self.headPanels.showFrames), Func(base.transitions.setFadeColor, 0, 0, 0)).start()

    def announceGameOver(self):
        self.fsm.request('announceGameOver')

    def showWinner(self, avId):
        base.transitions.fadeOut()
        Sequence(Wait(0.51), Func(self.fsm.request, 'showWinner', [avId])).start()

    def enterGameOver(self, winner, winnerDoId, allPrize):
        try:
            currentCamPos = base.camera.getPos(render)
            currentCamHpr = base.camera.getHpr(render)
            self.firstPerson.reallyEnd()
            base.camera.setPos(currentCamPos)
            base.camera.setHpr(currentCamHpr)
        except:
            pass

        DistributedMinigame.enterGameOver(self, winner, winnerDoId, allPrize)

    def enterShowWinner(self, winnerId):
        self.firstPerson.reallyEnd()
        avatar = self.getRemoteAvatar(winnerId)
        avatar.avatar.loop('neutral')
        avatar.detachCamera()
        self.thisPlayerWinsLbl = OnscreenText(text='{0} Wins!'.format(avatar.avatar.getName()), fg=(1, 1, 1, 1), font=CIGlobals.getMinnieFont(), pos=(0, 0.8), scale=0.1)
        if winnerId == base.localAvatar.doId:
            self.thisPlayerWinsLbl.setText('You Win!')
        base.camera.reparentTo(avatar.avatar)
        base.camera.setPos(0, 7, 3)
        base.camera.setH(180)
        base.transitions.fadeIn()
        Sequence(Wait(0.5), Func(avatar.doWinDance)).start()

    def exitShowWinner(self):
        pass

    def enterAnnounceGameOver(self):
        whistle = base.loadSfx('phase_4/audio/sfx/AA_sound_whistle.mp3')
        base.playSfx(whistle)
        self.gameOverLbl = OnscreenText(text='Game Over!', fg=(1, 1, 1, 1), font=CIGlobals.getMinnieFont(), scale=0.1)
        self.gameOverScaleIval = LerpScaleInterval(self.gameOverLbl, duration=1.0, scale=0.1, startScale=0.0, blendType='easeOut')

    def exitAnnounceGameOver(self):
        self.gameOverScaleIval.finish()
        del self.gameOverScaleIval
        self.gameOverLbl.destroy()
        del self.gameOverLbl

    def remoteAvatarTakePicture(self, avId):
        avatar = self.getRemoteAvatar(avId)
        if avatar:
            avatar.takePicture()

    def standingAvatar(self, avId):
        avatar = self.getRemoteAvatar(avId)
        if avatar:
            avatar.stand()

    def runningAvatar(self, avId):
        avatar = self.getRemoteAvatar(avId)
        if avatar:
            avatar.run()

    def createRemoteAvatar(self, avId):
        if avId == base.localAvatar.doId:
            self.myRemoteAvatar = RemoteCameraShyAvatar(self, self.cr, avId)
            self.remoteAvatars.append(self.myRemoteAvatar)
        else:
            av = RemoteCameraShyAvatar(self, self.cr, avId)
            av.stand()
            self.remoteAvatars.append(av)

    def getRemoteAvatar(self, avId):
        for avatar in self.remoteAvatars:
            if avatar.avId == avId:
                return avatar

    def allPlayersReady(self):
        self.fsm.request('countdown')

    def enterCountdown(self):
        base.localAvatar.chatInput.disableKeyboardShortcuts()
        base.localAvatar.disableChatInput()
        base.setBackgroundColor(CIGlobals.DefaultBackgroundColor)
        base.render.show()
        self.playMinigameMusic()
        self.countdownLbl = OnscreenText(text='', fg=(1, 1, 1, 1), font=CIGlobals.getMinnieFont(), scale=0.1)
        self.countdownTrack = Sequence(Func(self.countdownLbl.setText, '5'), Wait(1.0), Func(self.countdownLbl.setText, '4'), Wait(1.0), Func(self.countdownLbl.setText, '3'), Wait(1.0), Func(self.countdownLbl.setText, '2'), Wait(1.0), Func(self.countdownLbl.setText, '1'), Wait(1.0), Func(self.fsm.request, 'play'))
        self.countdownTrack.start()
        self.firstPerson.start()
        self.firstPerson.disableMouse()

    def exitCountdown(self):
        if hasattr(self, 'countdownTrack'):
            self.countdownTrack.pause()
            del self.countdownTrack
        if hasattr(self, 'countdownLbl'):
            self.countdownLbl.destroy()
            del self.countdownLbl

    def enterPlay(self):
        self.createTimer()
        self.firstPerson.reallyStart()

    def exitPlay(self):
        self.firstPerson.end()
        self.firstPerson.enableMouse()
        self.deleteTimer()
        base.localAvatar.createChatInput()
        base.localAvatar.chatInput.enableKeyboardShortcuts()
        DistributedMinigame.exitPlay(self)

    def createWorld(self):
        self.deleteWorld()
        self.maze = loader.loadModel('phase_4/models/minigames/maze_1player.bam')
        self.maze.find('**/maze_walls').setSz(1.5)
        self.maze.reparentTo(base.render)
        self.mazeCollModel = loader.loadModel('phase_4/models/minigames/maze_1player_collisions.egg')
        self.mazeCollModel.reparentTo(base.render)
        self.mazeCollModel.hide()
        self.mazeCollModel.setTransparency(1)
        self.mazeCollModel.setColorScale(1, 1, 1, 0)
        for node in self.mazeCollModel.findAllMatches('**'):
            node.setSz(1.5)

        self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam')
        self.skyUtil = SkyUtil()
        self.skyUtil.startSky(self.sky)
        self.sky.reparentTo(base.camera)
        ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ)
        self.sky.node().setEffect(ce)
        self.spawnPoints.append((Point3(0, 0, 0), Vec3(0, 0, 0)))
        self.spawnPoints.append((Point3(-23.89, 18.58, 0.0), Vec3(90.0, 0.0, 0.0)))
        self.spawnPoints.append((Point3(-23.89, 6.3, 0.0), Vec3(0.0, 0.0, 0.0)))
        self.spawnPoints.append((Point3(23.78, 6.3, 0.0), Vec3(0.0, 0.0, 0.0)))
        self.spawnPoints.append((Point3(8.12, -17.79, 0.0), Vec3(270.0, 0.0, 0.0)))

    def deleteWorld(self):
        if self.maze:
            self.maze.removeNode()
            self.maze = None
        if self.mazeCollModel:
            self.mazeCollModel.removeNode()
            self.mazeCollModel = None
        if self.skyUtil:
            self.skyUtil.stopSky()
            self.skyUtil = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        return

    def pickSpawnPoint(self):
        return random.choice(self.spawnPoints)

    def setSpawnPoint(self, index):
        pos, hpr = self.spawnPoints[index]
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)

    def load(self):
        self.createWorld()
        self.setMinigameMusic('phase_6/audio/bgm/GS_Race_SS.mid')
        self.setDescription('Be the first to take 3 pictures of all the other Toons with your camera. ' + 'Use WASD to move and the mouse to look around. Press the left mouse button to take a picture. ' + 'Your camera takes some time to recharge after taking a picture. ' + 'You know you have a good shot when the view finder is green!')
        self.setWinnerPrize(30)
        self.setLoserPrize(15)
        base.render.hide()
        base.setBackgroundColor(0, 0, 0)
        DistributedMinigame.load(self)

    def announceGenerate(self):
        base.camLens.setMinFov(CIGlobals.GunGameFOV / (4.0 / 3.0))
        self.load()
        DistributedMinigame.announceGenerate(self)

    def disable(self):
        if self.thisPlayerWinsLbl:
            self.thisPlayerWinsLbl.destroy()
            self.thisPlayerWinsLbl = None
        base.camera.reparentTo(render)
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        if self.myRemoteAvatar:
            self.myRemoteAvatar.cleanup()
            del self.myRemoteAvatar
        self.firstPerson.cleanup()
        del self.firstPerson
        self.deleteWorld()
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4.0 / 3.0))
        DistributedMinigame.disable(self)
        return
Esempio n. 15
0
class RewardPanel(DirectFrame):
    notify = directNotify.newCategory('RewardPanel')

    def __init__(self, panelData):
        dialogBox = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
        DirectFrame.__init__(self,
                             relief=None,
                             geom=dialogBox,
                             geom_color=CIGlobals.DialogColor,
                             geom_scale=(1.75, 1, 0.75 * 1.1),
                             geom_pos=Point3(0, 0, -0.05),
                             pos=(0, 0, 0.661))
        self.initialiseoptions(RewardPanel)
        self.setScale(0.8)

        # The data for the reward panel inside of a RPToonData object.
        self.panelData = panelData

        # Top wood panel saying Reward Panel
        gagShopNodes = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        # Original pos: (-0.02, 0, 0.3) scale = (1.55, 1, 1)
        self.titlePanel = OnscreenImage(
            parent=self,
            image=gagShopNodes.find('**/Goofys_Sign'),
            pos=(0, 0, 0.3),
            hpr=(1, 0, 0),
            scale=(1.3, 1, 0.9))

        self.avatarNamePanel = DirectFrame(parent=self.titlePanel,
                                           pos=(0, 0.005, 0))
        self.avatarText = OnscreenText(parent=self.avatarNamePanel,
                                       text='',
                                       font=CIGlobals.getMickeyFont(),
                                       fg=(0.698, 0.13, 0.13, 1),
                                       mayChange=1,
                                       scale=(0.1, 0.13, 0.1))

        self.panelContentsTitle = OnscreenText(parent=self,
                                               text=GagPanelName,
                                               font=CIGlobals.getMickeyFont(),
                                               pos=(0, 0.24, 0),
                                               fg=(0.3725, 0.619, 0.627, 1),
                                               mayChange=1)

        self.playerInfo = DirectFrame(parent=self,
                                      relief=None,
                                      pos=(-0.5, 0, 0))
        self.playerInfo.setBin('gui-popup', 0)

        self.bonusText = OnscreenText(parent=self.playerInfo,
                                      text='2X Cog Office Bonus!',
                                      font=CIGlobals.getToonFont(),
                                      pos=(0, 0.15, 0),
                                      scale=(0.055, 0.055, 0.055),
                                      align=TextNode.ACenter)
        self.bonusText.hide()

        ##################################################################################
        # GUI Elements relating to the Favorite Gag/Gag Popup Used for showing Gag Unlock#
        ##################################################################################
        self.favoriteGagText = OnscreenText(parent=self.playerInfo,
                                            text=FavoriteGag,
                                            font=CIGlobals.getMickeyFont(),
                                            pos=FavoriteGagTitlePos,
                                            fg=(1, 0.2, 0.2, 1),
                                            sort=0)

        glow = loader.loadModel('phase_4/models/minigames/particleGlow.bam')
        self.favoriteGagGlow = OnscreenImage(parent=self.playerInfo,
                                             image=glow,
                                             pos=FavoriteGagPos,
                                             color=GagGlowColor,
                                             scale=(0.8, 0.8, 0.8))
        self.favoriteGagGlow.setBin('gui-popup', 10)
        # particleGlow.bam uses a material since it's normally part of render, not render2d.
        # Since render2d is still fixed-function, we have to explicitly enable shader generation
        # to correctly display the glow in render2d.
        self.favoriteGagGlow.setShaderAuto()

        invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam')
        gag = invIcons.find(
            GagGlobals.InventoryIconByName.get(GagGlobals.Foghorn))
        self.favoriteGag = OnscreenImage(parent=self.playerInfo,
                                         image=gag,
                                         pos=FavoriteGagPos,
                                         scale=(1.65, 1.65, 1.65))
        self.favoriteGag.setBin('gui-popup', 20)

        self.favoriteGagName = OnscreenText(parent=self.playerInfo,
                                            text=GagGlobals.Foghorn,
                                            font=CIGlobals.getToonFont(),
                                            pos=FavoriteGagNamePos,
                                            mayChange=1)

        ################################################################################
        # GUI elements showing gag experience on the right-side of the gag exp panel   #
        ################################################################################

        self.gagExpFrame = DirectFrame(parent=self,
                                       relief=None,
                                       pos=(0.085, 0, 0.15))
        self.trackLabels = []
        self.trackIncLabels = []
        self.trackBars = []
        self.trackBarsOffset = 0

        for i in range(len(GagGlobals.TrackNameById.values())):
            track = GagGlobals.TrackNameById.values()[i]
            color = GagGlobals.TrackColorByName.get(track)
            label = DirectLabel(parent=self.gagExpFrame,
                                relief=None,
                                text=track.upper(),
                                text_scale=0.05,
                                text_align=TextNode.ARight,
                                pos=(0.13, 0, -0.09 * i),
                                text_pos=(0, -0.02))
            incrementLabel = DirectLabel(parent=self.gagExpFrame,
                                         relief=None,
                                         text='',
                                         text_scale=0.05,
                                         text_align=TextNode.ALeft,
                                         pos=(0.65, 0, -0.09 * i),
                                         text_pos=(0, -0.02))
            progressBar = DirectWaitBar(
                parent=self.gagExpFrame,
                relief=DGG.SUNKEN,
                frameSize=(-1, 1, -0.15, 0.15),
                borderWidth=(0.02, 0.02),
                scale=0.25,
                frameColor=(color[0] * 0.7, color[1] * 0.7, color[2] * 0.7, 1),
                barColor=(color[0], color[1], color[2], 1),
                text='0/0',
                text_scale=0.18,
                text_fg=(0, 0, 0, 1),
                text_align=TextNode.ACenter,
                text_pos=(0, -0.05),
                pos=(0.4, 0, -0.09 * i))
            self.trackLabels.append(label)
            self.trackIncLabels.append(incrementLabel)
            self.trackBars.append(progressBar)

        ################################################################################
        # GUI elements showing progress updates on quests                              #
        ################################################################################

        self.questFrame = DirectFrame(parent=self, relief=None)
        self.questPosters = []

        self.congratsLeft = OnscreenText(parent=self.playerInfo,
                                         pos=(-0.1, 0.125, -0.1),
                                         text='',
                                         scale=0.06,
                                         align=TextNode.ARight)
        self.congratsLeft.setR(-30)
        self.congratsRight = OnscreenText(parent=self.playerInfo,
                                          pos=(0.1, 0.125, 0.1),
                                          text='',
                                          scale=0.06,
                                          align=TextNode.ALeft)
        self.congratsRight.setR(30)

        glow.removeNode()
        invIcons.removeNode()
        gagShopNodes.removeNode()
        dialogBox.removeNode()

    def __getAvatarTextScale(self):
        totalWidth = self.avatarText.node().getWidth()
        panelWidth = 9.2
        defaultTextScale = 1.0

        scale = min(defaultTextScale,
                    defaultTextScale / (totalWidth / panelWidth))
        return (scale, scale, scale)

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def setPanelData(self, panelData):
        self.panelData = panelData
        self.avatarText['text'] = self.panelData.avatarName
        self.avatarNamePanel.setScale(self.__getAvatarTextScale())

        # Let's set the data for our gag experience here.
        for i in range(len(self.trackLabels)):
            track = self.panelData.getTrackByName(
                GagGlobals.TrackNameById.values()[i])
            bar = self.trackBars[i]
            bar['text'] = '%d/%d' % (track.exp, track.maxExp)

            # When the maximum experience of a track isn't 0, we know it isn't unlocked.
            if track.maxExp == -1:
                bar.hide()

            self.trackIncLabels[i]['text'] = ''
            self.trackIncLabels[i].show()

    def __chooseRewardShot(self, av):
        shotChoices = [(0, 8, av.getHeight() * 0.66, 179, 15, 0),
                       (5.2, 5.45, av.getHeight() * 0.66, 131.5, 3.6, 0)]
        shot = random.choice(shotChoices)
        return shot

    def getQuestsProgressInterval(self):
        avatar = self.panelData.avatar
        intervals = []

        def toggleFavoriteGagItems(visible):
            for item in [
                    self.favoriteGag, self.favoriteGagGlow,
                    self.favoriteGagText, self.favoriteGagName
            ]:
                if not visible:
                    item.hide()
                else:
                    item.show()

        def setupQuestPosters():
            questManager = avatar.questManager
            numQuests = len(questManager.quests.values())

            yPos = 0.47

            displayData = {
                1: [[Point3(0.0, 0.0, yPos)], 0.88],
                2: [[Point3(-0.42, 0.0, yPos),
                     Point3(0.45, 0.0, yPos)], 0.88],
                3: [[
                    Point3(-0.57, 0.0, yPos),
                    Point3(0.0, 0.0, yPos),
                    Point3(0.57, 0.0, yPos)
                ], 0.70],
                4: [[
                    Point3(-0.32, 0.0, 0.62),
                    Point3(-0.32, 0.0, 0.30),
                    Point3(0.32, 0.0, 0.62),
                    Point3(0.32, 0.0, 0.30)
                ], 0.52]
            }

            # A full frame is a frame showing two quests at once.
            howManyFullFrames = math.ceil(numQuests / 2.0)
            howManyRemainderFrames = (numQuests - howManyFullFrames)

            for i, quest in enumerate(questManager.quests.values()):
                poster = QuestGlobals.generatePoster(quest,
                                                     parent=self.questFrame)
                poster.setScale(displayData.get(numQuests)[1])
                poster.setPos(displayData.get(numQuests)[0][i])
                poster.show()
                self.questPosters.append(poster)

        intervals.append(Func(self.gagExpFrame.hide))
        intervals.append(Func(self.playerInfo.show))
        intervals.append(Func(self.panelContentsTitle.setText,
                              QuestsPanelName))
        intervals.append(Func(toggleFavoriteGagItems, False))
        intervals.append(Func(setupQuestPosters))
        #intervals.append(Func(self.playerInfo.initialiseoptions, DirectFrame))

        return intervals

    def getGagExperienceInterval(self):
        avatar = self.panelData.avatar
        intervals = []

        shot = self.__chooseRewardShot(avatar)

        intervals.append(Func(base.camera.reparentTo, avatar))
        intervals.append(Func(base.camera.setPosHpr, *shot))
        intervals.append(Func(self.congratsLeft.hide))
        intervals.append(Func(self.congratsRight.hide))
        intervals.append(Func(self.panelContentsTitle.setText, GagPanelName))
        intervals.append(Func(self.setFavoriteGag, self.panelData.favoriteGag))
        intervals.append(Func(self.gagExpFrame.show))
        intervals.append(Func(self.playerInfo.show))
        intervals.append(Wait(1.0))

        for i in range(len(self.trackLabels)):
            track = self.panelData.getTrackByName(
                GagGlobals.TrackNameById.values()[i])
            intervals.extend(self.getTrackIntervalList(track, i))

        return intervals

    def getNextExpValue(self, newValue, track):
        if newValue < track.maxExp or track.maxExp == 0:
            return track.maxExp
        else:
            levels = GagGlobals.TrackExperienceAmounts[track.name]
            index = levels.index(track.maxExp)

            if index + 1 < len(levels):
                return levels[index + 1]
            return -1

    def incrementExp(self, trackIndex, track, newValue):
        bar = self.trackBars[trackIndex]
        nextExp = GagGlobals.getMaxExperienceValue(newValue, track.name)
        oldValue = bar['value']
        color = GagGlobals.TrackColorByName.get(track.name)

        bar['text'] = '%d/%d' % (newValue, nextExp)
        bar['range'] = nextExp if not nextExp == -1 else newValue
        bar['value'] = newValue
        bar['barColor'] = (color[0], color[1], color[2], 1)

    def resetBarColor(self, trackIndex):
        color = GagGlobals.TrackColorByName.get(
            GagGlobals.TrackNameById.values()[trackIndex])
        self.trackBars[trackIndex]['barColor'] = (color[0] * 0.8,
                                                  color[1] * 0.8,
                                                  color[2] * 0.8, 1)

    def showTrackIncLabel(self, trackIndex, track, increment):
        label = self.trackIncLabels[trackIndex]

        # Only show increments when that track is unlocked.
        if track.exp != -1:
            label['text'] = '+%d' % increment
        label.show()

    def getTrackIntervalList(self, track, trackIndex):
        tickDelay = 1.0 / 60
        intervalList = []

        intervalList.append(
            Func(self.showTrackIncLabel, trackIndex, track, track.increment))

        barTime = 2.0 if track.exp > 0 else 0.25
        numTicks = int(math.ceil(barTime / tickDelay))
        for i in range(numTicks):
            t = (i + 1) / float(numTicks)
            newValue = int(track.exp + t * track.increment + 0.5)
            intervalList.append(
                Func(self.incrementExp, trackIndex, track, newValue))
            intervalList.append(Wait(tickDelay))

        intervalList.append(Func(self.resetBarColor, trackIndex))
        intervalList.append(Wait(0.2))

        if track.maxExp > 0 and (track.maxExp != GagGlobals.MaxedTrackExperiences.get(track.name) \
                    and (track.exp + track.increment) >= track.maxExp):
            gagIndex = GagGlobals.TrackExperienceAmounts.get(track.name).index(
                track.maxExp) + 1
            newGag = GagGlobals.TrackGagNamesByTrackName.get(
                track.name)[gagIndex]
            intervalList.append(
                self.getShowGagUnlockedInterval(track.name, newGag))

        return intervalList

    def getShowGagUnlockedInterval(self, track, gagName):
        seq = Sequence(
            Func(self.gagExpFrame.hide),
            Func(self.panelContentsTitle.setText, 'Gag Unlocked!'),
            Func(self.playerInfo.show), Func(self.setFavoriteGag, gagName),
            Func(self.favoriteGagName.setY, -0.35),
            Func(self.favoriteGagText.setY, 0.105),
            Func(self.favoriteGagText.setText, 'New %s Gag' % track),
            Func(self.bonusText.hide), Func(self.playerInfo.setPos, 0, 0, 0),
            Func(self.playerInfo.initialiseoptions, DirectFrame))
        seq.append(self.getCongratsInterval())
        seq.append(Wait(1.0))
        seq.append(self.getHideGagUnlockedInterval())
        seq.append(Func(self.gagExpFrame.show))
        seq.append(Wait(0.5))
        return seq

    def getHideGagUnlockedInterval(self):
        def correctPositioning(guiElement, pos):
            guiElement['pos'] = pos

        seq = Sequence(
            Func(self.panelContentsTitle.setText, GagPanelName),
            Func(self.setFavoriteGag, self.panelData.favoriteGag),
            Func(self.playerInfo.setX, -0.5),
            Func(correctPositioning, self.favoriteGagName, FavoriteGagNamePos),
            Func(self.favoriteGagText.setText, FavoriteGag),
            Func(correctPositioning, self.favoriteGagText,
                 FavoriteGagTitlePos), Func(self.congratsLeft.hide),
            Func(self.congratsRight.hide))

        return seq

    def __getRandomCongratsPair(self):
        msgs = list(NewGagCongratsMessages)

        msg = msgs[random.randint(0, len(msgs) - 1)]
        msgs.remove(msg)

        return (msg, msgs[random.randint(0, len(msgs) - 1)])

    def getCongratsInterval(self):
        msgs = self.__getRandomCongratsPair()
        self.congratsLeft['text'] = msgs[0]
        self.congratsRight['text'] = msgs[1]

        sfx = loader.loadSfx('phase_3/audio/sfx/GUI_balloon_popup.ogg')
        sfx.setLoop(False)
        sfx.setVolume(1.0)

        def makeSequence(text):
            seq = Sequence(Wait(1.0), Func(text.show))
            seq.append(Func(sfx.play))
            seq.append(
                CIGlobals.makePulseEffectInterval(text, 1.0, 0.01, 1.05, 0.5,
                                                  0.25))
            seq.append(Func(sfx.stop))
            return seq

        return Sequence(makeSequence(self.congratsLeft),
                        makeSequence(self.congratsRight))

    def setFavoriteGag(self, gagName):
        invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam')
        gag = invIcons.find(GagGlobals.InventoryIconByName.get(gagName))
        self.favoriteGagName.setText(gagName)
        self.favoriteGag['image'] = gag
        invIcons.removeNode()

    def destroy(self):
        if self.titlePanel:
            self.titlePanel.destroy()
        if self.avatarText:
            self.avatarText.destroy()
        if self.avatarNamePanel:
            self.avatarNamePanel.destroy()
        if self.panelContentsTitle:
            self.panelContentsTitle.destroy()
        if self.favoriteGag:
            self.favoriteGag.destroy()
        if self.favoriteGagGlow:
            self.favoriteGagGlow.destroy()
        if self.favoriteGagName:
            self.favoriteGagName.destroy()
        if self.playerInfo:
            self.playerInfo.destroy()
        if self.trackLabels:
            for label in self.trackLabels:
                label.destroy()
        if self.trackIncLabels:
            for label in self.trackIncLabels:
                label.destroy()
        if self.trackBars:
            for bar in self.trackBars:
                bar.destroy()
        if self.congratsLeft:
            self.congratsLeft.destroy()
        if self.congratsRight:
            self.congratsRight.destroy()
        if self.gagExpFrame:
            self.gagExpFrame.destroy()
        if self.panelData:
            self.panelData = None
        del self.titlePanel
        del self.avatarText
        del self.avatarNamePanel
        del self.panelContentsTitle
        del self.favoriteGag
        del self.favoriteGagGlow
        del self.favoriteGagName
        del self.playerInfo
        del self.trackLabels
        del self.trackIncLabels
        del self.trackBars
        del self.gagExpFrame
        del self.congratsLeft
        del self.congratsRight
        del self.panelData
        DirectFrame.destroy(self)
class Introduction(DirectObject, FSM):
    notify = directNotify.newCategory('Introduction')

    def __init__(self):
        DirectObject.__init__(self)
        FSM.__init__(self, self.__class__.__name__)

        self.label = OnscreenText(
            '', parent=hidden, font=ToontownGlobals.getMinnieFont(),
            fg=Vec4(1, 1, 1, 1), scale=0.06, align=TextNode.ACenter,
            wordwrap=35)
        self.label.setColorScale(Vec4(0, 0, 0, 0))

        gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui.bam')
        shuffleUp = gui.find('**/tt_t_gui_mat_shuffleUp')
        shuffleDown = gui.find('**/tt_t_gui_mat_shuffleDown')
        okUp = gui.find('**/tt_t_gui_mat_okUp')
        okDown = gui.find('**/tt_t_gui_mat_okDown')
        closeUp = gui.find('**/tt_t_gui_mat_closeUp')
        closeDown = gui.find('**/tt_t_gui_mat_closeDown')
        gui.removeNode()
        del gui

        self.exitButton = DirectButton(
            parent=hidden, relief=None,
            image=(shuffleUp, shuffleDown, shuffleUp),
            image_scale=(0.6, 0.6, 0.6), image1_scale=(0.63, 0.6, 0.6),
            image2_scale=(0.63, 0.6, 0.6),
            text=(TTLocalizer.IntroExitButton, TTLocalizer.IntroExitButton,
                  TTLocalizer.IntroExitButton, ''),
            text_font=ToontownGlobals.getInterfaceFont(),
            text_scale=TTLocalizer.SBshuffleBtn, text_pos=(0, -0.02),
            text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1))

        self.yesButton = DirectButton(
            parent=hidden, relief=None, image=(okUp, okDown, okUp, okDown),
            image_scale=(0.6, 0.6, 0.6), image1_scale=(0.7, 0.7, 0.7),
            image2_scale=(0.7, 0.7, 0.7),
            text=('', TTLocalizer.IntroYesButton, TTLocalizer.IntroYesButton),
            text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08,
            text_align=TextNode.ACenter, text_pos=(0, -0.175),
            text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1))
        self.noButton = DirectButton(
            parent=hidden, relief=None,
            image=(closeUp, closeDown, closeUp, closeDown),
            image_scale=(0.6, 0.6, 0.6), image1_scale=(0.7, 0.7, 0.7),
            image2_scale=(0.7, 0.7, 0.7),
            text=('', TTLocalizer.IntroNoButton, TTLocalizer.IntroNoButton),
            text_font=ToontownGlobals.getInterfaceFont(), text_scale=0.08,
            text_align=TextNode.ACenter, text_pos=(0, -0.175),
            text_fg=(1, 1, 1, 1), text_shadow=(0, 0, 0, 1))

        self.disclaimerTrack = None
        self.presentsTrack = None

    def delete(self):
        if self.presentsTrack is not None:
            self.presentsTrack.finish()
            self.presentsTrack = None

        if self.disclaimerTrack is not None:
            self.disclaimerTrack.finish()
            self.disclaimerTrack = None

        if self.noButton is not None:
            self.noButton.destroy()
            self.noButton = None

        if self.yesButton is not None:
            self.yesButton.destroy()
            self.yesButton = None

        if self.exitButton is not None:
            self.exitButton.destroy()
            self.exitButton = None

        if self.label is not None:
            self.label.destroy()
            self.label = None

    def calcLabelY(self):
        sy = self.label.getScale()[1]
        height = self.label.textNode.getHeight()
        return (height * sy) / 2.0

    def enterOff(self):
        pass

    def enterDisclaimer(self):
        self.label.setText(TTLocalizer.IntroDisclaimer)
        self.label.setPos(0, self.calcLabelY())
        self.label.reparentTo(aspect2d)

        if self.disclaimerTrack is not None:
            self.disclaimerTrack.finish()
            self.disclaimerTrack = None

        self.disclaimerTrack = Sequence(
            LerpColorScaleInterval(
                self.label, 2, Vec4(1, 1, 1, 1), Vec4(0, 0, 0, 0),
                blendType='easeIn'),
            Wait(3),
            LerpColorScaleInterval(
                self.label, 2, Vec4(0, 0, 0, 0), Vec4(1, 1, 1, 1),
                blendType='easeOut'),
        )
        self.disclaimerTrack.start()

    def exitDisclaimer(self):
        if self.disclaimerTrack is not None:
            self.disclaimerTrack.finish()
            self.disclaimerTrack = None

        self.label.reparentTo(hidden)
        self.label.setPos(0, 0)
        self.label.setText('')

    def enterPresents(self):
        self.label.setText(TTLocalizer.IntroPresents)
        self.label.setPos(0, self.calcLabelY())
        self.label.reparentTo(aspect2d)

        if self.presentsTrack is not None:
            self.presentsTrack.finish()
            self.presentsTrack = None

        self.presentsTrack = Sequence(
            LerpColorScaleInterval(
                self.label, 2, Vec4(1, 1, 1, 1), Vec4(0, 0, 0, 0),
                blendType='easeIn'),
            Wait(3),
            LerpColorScaleInterval(
                self.label, 2, Vec4(0, 0, 0, 0), Vec4(1, 1, 1, 1),
                blendType='easeOut'),
        )
        self.presentsTrack.start()

    def exitPresents(self):
        if self.presentsTrack is not None:
            self.presentsTrack.finish()
            self.presentsTrack = None

        self.label.reparentTo(hidden)
        self.label.setPos(0, 0)
        self.label.setText('')

    def enterLabel(self, text):
        self.label.setText(text)
        self.label.setPos(0, self.calcLabelY())
        self.label.reparentTo(aspect2d)
        self.label.setColorScale(Vec4(1, 1, 1, 1))

    def exitLabel(self):
        self.label.setColorScale(Vec4(0, 0, 0, 0))
        self.label.reparentTo(hidden)
        self.label.setPos(0, 0)
        self.label.setText('')

    def enterExitDialog(self, text, exitButtonCommand=None,
                        exitButtonExtraArgs=[]):
        self.label.setText(text)

        sy = self.label.getScale()[1]
        bottom = self.label.textNode.getBottom() * sy
        lineHeight = self.label.textNode.getLineHeight() * sy
        self.exitButton.setPos(0, 0, bottom - (lineHeight * 2))
        self.exitButton['command'] = exitButtonCommand
        self.exitButton['extraArgs'] = exitButtonExtraArgs

        labelY = self.calcLabelY()

        self.label.setPos(0, labelY)

        self.exitButton.setZ(self.exitButton, labelY)

        self.exitButton.reparentTo(aspect2d)
        self.label.reparentTo(aspect2d)

        self.label.setColorScale(Vec4(1, 1, 1, 1))

    def exitExitDialog(self):
        self.label.setColorScale(Vec4(0, 0, 0, 0))

        self.label.reparentTo(hidden)
        self.exitButton.reparentTo(hidden)

        self.label.setPos(0, 0)
        self.label.setText('')

        self.exitButton['command'] = None
        self.exitButton['extraArgs'] = []
        self.exitButton.setPos(0, 0, 0)

    def enterYesNoDialog(self, text, yesButtonCommand=None,
                         yesButtonExtraArgs=[], noButtonCommand=None,
                         noButtonExtraArgs=[]):
        self.label.setText(text)

        sy = self.label.getScale()[1]
        bottom = self.label.textNode.getBottom() * sy
        lineHeight = self.label.textNode.getLineHeight() * sy
        self.yesButton.setPos(-0.1, 0, bottom - (lineHeight * 2))
        self.yesButton['command'] = yesButtonCommand
        self.yesButton['extraArgs'] = yesButtonExtraArgs
        self.noButton.setPos(0.1, 0, bottom - (lineHeight * 2))
        self.noButton['command'] = noButtonCommand
        self.noButton['extraArgs'] = noButtonExtraArgs

        labelY = self.calcLabelY()

        self.label.setPos(0, labelY)

        self.yesButton.setZ(self.yesButton, labelY)
        self.noButton.setZ(self.noButton, labelY)

        self.yesButton.reparentTo(aspect2d)
        self.noButton.reparentTo(aspect2d)
        self.label.reparentTo(aspect2d)

        self.label.setColorScale(Vec4(1, 1, 1, 1))

    def exitYesNoDialog(self):
        self.label.setColorScale(Vec4(0, 0, 0, 0))

        self.label.reparentTo(hidden)
        self.noButton.reparentTo(hidden)
        self.yesButton.reparentTo(hidden)

        self.label.setPos(0, 0)
        self.label.setText('')

        self.noButton['command'] = None
        self.noButton['extraArgs'] = []
        self.noButton.setPos(0, 0, 0)
        self.yesButton['command'] = None
        self.yesButton['extraArgs'] = []
        self.yesButton.setPos(0, 0, 0)

    def enterClickToStart(self):
        base.cr.clickToStart.start()

    def exitClickToStart(self):
        base.cr.clickToStart.stop()
Esempio n. 17
0
class CIProgressScreen:

    def __init__(self):
        self.defaultLogoScale = 0.85
        self.defaultLogoZ = 0.65
        self.bgm = loader.loadModel('phase_3/models/gui/progress-background.bam')
        self.bgm.find('**/logo').stash()
        self.bg = self.bgm.find('**/bg')
        self.logo = loader.loadTexture('phase_3/maps/CogInvasion_Logo.png')
        self.logoNode = hidden.attachNewNode('logoNode')
        self.logoNode.setScale(self.defaultLogoScale)
        self.logoNode.setPos(0, self.defaultLogoZ, 0)
        self.logoImg = OnscreenImage(image=self.logo, scale=(0.685, 0, 0.3), parent=self.logoNode)
        self.logoImg.setTransparency(True)
        self.bg_img = OnscreenImage(image=self.bg, parent=hidden)
        self.bg_img.setSx(1.35)
        self.bg_img.hide()
        self.progress_bar = DirectWaitBar(value=0, pos=(0, 0, -0.85), parent=hidden, text_pos=(0,
                                                                                               0,
                                                                                               0.2))
        self.progress_bar.setSx(1.064)
        self.progress_bar.setSz(0.38)
        toontipgui = loader.loadModel('phase_3.5/models/gui/stickerbook_gui.bam')
        poster = toontipgui.find('**/questCard')
        self.toontipFrame = DirectFrame(image=poster, image_scale=(1.4, 1, 1), parent=hidden, relief=None, pos=(0,
                                                                                                                0,
                                                                                                                -0.1), scale=0.85)
        self.toontipLbl = OnscreenText(text='', parent=self.toontipFrame, fg=(0.35,
                                                                              0.35,
                                                                              0.35,
                                                                              1), font=CIGlobals.getToonFont(), wordwrap=14.5, pos=(-0.59,
                                                                                                                                    0.25), align=TextNode.ALeft, scale=0.08)
        self.loading_lbl = DirectLabel(text='', relief=None, scale=0.08, pos=(-1.0725,
                                                                              0,
                                                                              -0.79), text_align=TextNode.ALeft, sortOrder=100, text_fg=(0.343,
                                                                                                                                         0.343,
                                                                                                                                         0.343,
                                                                                                                                         1.0), text_font=CIGlobals.getMinnieFont(), parent=hidden, text_shadow=(0,
                                                                                                                                                                                                                0,
                                                                                                                                                                                                                0,
                                                                                                                                                                                                                1))
        return

    def begin(self, hood, range, wantGui):
        render.hide()
        self.renderFrames()
        base.setBackgroundColor(0, 0, 0)
        if hood == 'localAvatarEnterGame':
            self.loading_lbl['text'] = 'Entering...'
        else:
            if hood == 'init':
                self.loading_lbl['text'] = 'Loading...'
            else:
                self.loading_lbl['text'] = 'Heading to %s...' % hood
        self.progress_bar['barColor'] = (0.343, 0.343, 0.343, 1.0)
        self.progress_bar['range'] = range
        self.bgm.reparentTo(aspect2d)
        self.bg.reparentTo(render2d)
        self.bg_img.reparentTo(hidden)
        self.loading_lbl.reparentTo(aspect2d)
        self.logoNode.reparentTo(aspect2d)
        self.progress_bar.reparentTo(aspect2d)
        tip = random.choice(CIGlobals.ToonTips)
        self.toontipLbl.setText('TOON TIP:\n' + tip)
        self.toontipFrame.reparentTo(aspect2d)
        self.__count = 0
        self.__expectedCount = range
        self.progress_bar.update(self.__count)

    def renderFramesTask(self, task):
        self.renderFrames()
        return task.cont

    def end(self):
        base.setBackgroundColor(CIGlobals.DefaultBackgroundColor)
        taskMgr.remove('renderFrames')
        render.show()
        self.progress_bar.finish()
        self.bg_img.reparentTo(hidden)
        self.logoNode.reparentTo(hidden)
        self.bg.reparentTo(hidden)
        self.bgm.reparentTo(hidden)
        self.loading_lbl.reparentTo(hidden)
        self.progress_bar.reparentTo(hidden)
        self.toontipFrame.reparentTo(hidden)
        self.renderFrames()

    def destroy(self):
        self.bg.removeNode()
        del self.bg
        self.bgm.removeNode()
        del self.bgm
        self.bg_img.destroy()
        self.loading_lbl.destroy()
        self.progress_bar.destroy()
        self.bgm.destroy()
        del self.bg_img
        del self.loading_lbl
        del self.progress_bar
        del self.bgm

    def renderFrames(self):
        base.graphicsEngine.renderFrame()
        base.graphicsEngine.renderFrame()

    def tick(self):
        self.__count += 1
        self.progress_bar.update(self.__count)
class TeamMinigame:
    notify = directNotify.newCategory('TeamMinigame')

    def __init__(self, team1Name, team1BtnImg, team2Name, team2BtnImg):
        self.team1Name = team1Name
        self.team1BtnImg = team1BtnImg
        self.team2Name = team2Name
        self.team2BtnImg = team2BtnImg
        self.teamNameById = {TEAM1: self.team1Name, TEAM2: self.team2Name}
        self.team = None
        self.winnerTeam = None
        self.playersByTeam = {TEAM1: 0, TEAM2: 0}
        self.playerListByTeam = {TEAM1: [], TEAM2: []}
        self.scoreByTeam = {TEAM1: 0, TEAM2: 0}
        self.container = None
        self.bg = None
        self.title = None
        self.btnFrame = None
        self.team1Frame = None
        self.team1Btn = None
        self.team1Plyrs_Lbl = None
        self.team2Frame = None
        self.team2Btn = None
        self.team2Plyrs_Lbl = None
        self.teamFull_Lbl = None
        return

    def makeSelectionGUI(self):
        font = CIGlobals.getMickeyFont()
        box = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
        imp = CIGlobals.getToonFont()
        geom = CIGlobals.getDefaultBtnGeom()
        self.container = DirectFrame()
        self.bg = OnscreenImage(image=box,
                                color=(1, 1, 0.75, 1),
                                scale=(1.9, 1.4, 1.4),
                                parent=self.container)
        self.title = OnscreenText(text='Join  a  Team',
                                  pos=(0, 0.5, 0),
                                  font=font,
                                  scale=0.12,
                                  parent=self.container,
                                  fg=(1, 0.9, 0.3, 1))
        self.btnFrame = DirectFrame(parent=self.container, pos=(0.14, 0, 0))
        self.team1BtnFrame = DirectFrame(parent=self.btnFrame,
                                         pos=(-0.5, 0, 0))
        self.team2BtnFrame = DirectFrame(parent=self.btnFrame,
                                         pos=(0.22, 0, 0))
        self.team1Btn = DirectButton(parent=self.team1BtnFrame,
                                     relief=None,
                                     pressEffect=0,
                                     image=self.team1BtnImg,
                                     image_scale=(0.9, 1, 1),
                                     scale=0.4,
                                     command=self.choseTeam,
                                     extraArgs=[TEAM1])
        self.team1Plyrs_Lbl = OnscreenText(parent=self.team1BtnFrame,
                                           text=str(self.playersByTeam[TEAM1]),
                                           pos=(0, -0.46, 0),
                                           font=imp)
        self.team2Btn = DirectButton(parent=self.team2BtnFrame,
                                     relief=None,
                                     pressEffect=0,
                                     image=self.team2BtnImg,
                                     image_scale=(0.9, 1, 1),
                                     scale=0.4,
                                     command=self.choseTeam,
                                     extraArgs=[TEAM2])
        self.team2Plyrs_Lbl = OnscreenText(parent=self.team2BtnFrame,
                                           text=str(self.playersByTeam[TEAM2]),
                                           pos=(0, -0.46, 0),
                                           font=imp)
        self.teamFull_Lbl = OnscreenText(parent=self.container,
                                         text='',
                                         pos=(0, -0.6, 0),
                                         font=imp)
        return

    def destroySelectionGUI(self):
        if self.teamFull_Lbl:
            self.teamFull_Lbl.destroy()
            self.teamFull_Lbl = None
        if self.team2Plyrs_Lbl:
            self.team2Plyrs_Lbl.destroy()
            self.team2Plyrs_Lbl = None
        if self.team1Plyrs_Lbl:
            self.team1Plyrs_Lbl.destroy()
            self.team1Plyrs_Lbl = None
        if self.team2Btn:
            self.team2Btn.destroy()
            self.team2Btn = None
        if self.team1Btn:
            self.team1Btn.destroy()
            self.team1Btn = None
        if self.team2BtnFrame:
            self.team2BtnFrame.destroy()
            self.team2BtnFrame = None
        if self.team1BtnFrame:
            self.team1BtnFrame.destroy()
            self.team1BtnFrame = None
        if self.title:
            self.title.destroy()
            self.title = None
        if self.bg:
            self.bg.destroy()
            self.bg = None
        if self.container:
            self.container.destroy()
            self.container = None
        return

    def choseTeam(self, team):
        self.team = team
        self.team1Btn['state'] = DGG.DISABLED
        self.team2Btn['state'] = DGG.DISABLED
        self.sendUpdate('choseTeam', [team])

    def acceptedIntoTeam(self):
        message = MSG_WELCOME.format(self.teamNameById[self.team])
        whisper = WhisperPopup(message, CIGlobals.getToonFont(),
                               ChatGlobals.WTSystem)
        whisper.manage(base.marginManager)

    def teamFull(self):
        self.teamFull_Lbl.setText('Sorry, that team is full.')
        self.team = None
        self.team1Btn['state'] = DGG.NORMAL
        self.team2Btn['state'] = DGG.NORMAL
        return

    def incrementTeamPlayers(self, team):
        self.playersByTeam[team] += 1
        if self.fsm.getCurrentState().getName() == 'chooseTeam':
            if team == TEAM2:
                lbl = self.team2Plyrs_Lbl
            else:
                if team == TEAM1:
                    lbl = self.team1Plyrs_Lbl
            lbl.setText(str(self.playersByTeam[team]))

    def setTeamOfPlayer(self, avId, team):
        if not hasattr(self, 'getRemoteAvatar'):
            self.notify.error('Minigame must have remote avatars!!')
        self.playerListByTeam[team].append(avId)
        remoteAvatar = self.getRemoteAvatar(avId)
        if remoteAvatar:
            print('setting team of {0}').format(avId)
            remoteAvatar.setTeam(team)

    def incrementTeamScore(self, team):
        self.scoreByTeam[team] += 1

    def teamWon(self, team):
        self.winnerTeam = team

    def cleanup(self):
        self.destroySelectionGUI()
        del self.scoreByTeam
        del self.team1Name
        del self.teamNameById
        del self.team2Name
        del self.team1BtnImg
        del self.team2BtnImg
        del self.team
        del self.playersByTeam
        del self.winnerTeam
        del self.playerListByTeam
class TeamMinigame:
    """An abstract class for any minigame that is team-based."""

    notify = directNotify.newCategory("TeamMinigame")

    def __init__(self, team1Name, team1BtnImg, team2Name, team2BtnImg):
        """
        team1Name - A string name of the first playable team.
        team1BtnImg - A tuple of textures for the team 1 selection button.

        team2Name - A string name of the second playable team.
        team2BtnImg - A tuple of textures for the team 2 selection button.
        """

        self.team1Name = team1Name
        self.team1BtnImg = team1BtnImg

        self.team2Name = team2Name
        self.team2BtnImg = team2BtnImg

        self.teamNameById = {TEAM1: self.team1Name, TEAM2: self.team2Name}

        # The team we are part of.
        self.team = None

        # Both teams have 0 players to start.
        self.playersByTeam = {TEAM1: 0, TEAM2: 0}

        ##### TEAM SELECTION STUFF!!! #####

        self.container = None

        self.bg = None

        self.title = None

        self.btnFrame = None

        self.team1Frame = None
        self.team1Btn = None
        self.team1Plyrs_Lbl = None

        self.team2Frame = None
        self.team2Btn = None
        self.team2Plyrs_Lbl = None

        self.teamFull_Lbl = None

    def makeSelectionGUI(self):
        font = CIGlobals.getMickeyFont()
        box = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
        imp = CIGlobals.getToonFont()
        geom = CIGlobals.getDefaultBtnGeom()
        self.container = DirectFrame()
        self.bg = OnscreenImage(image=box,
                                color=(1, 1, 0.75, 1),
                                scale=(1.9, 1.4, 1.4),
                                parent=self.container)
        self.title = OnscreenText(text="Join  a  Team",
                                  pos=(0, 0.5, 0),
                                  font=font,
                                  scale=(0.12),
                                  parent=self.container,
                                  fg=(1, 0.9, 0.3, 1))
        self.btnFrame = DirectFrame(parent=self.container, pos=(0.14, 0, 0))
        self.team1BtnFrame = DirectFrame(parent=self.btnFrame,
                                         pos=(-0.5, 0, 0))
        self.team2BtnFrame = DirectFrame(parent=self.btnFrame,
                                         pos=(0.22, 0, 0))
        self.team1Btn = DirectButton(parent=self.team1BtnFrame,
                                     relief=None,
                                     pressEffect=0,
                                     image=self.team1BtnImg,
                                     image_scale=(0.9, 1, 1),
                                     scale=0.4,
                                     command=self.choseTeam,
                                     extraArgs=[TEAM1])
        self.team1Plyrs_Lbl = OnscreenText(parent=self.team1BtnFrame,
                                           text=str(self.playersByTeam[TEAM1]),
                                           pos=(0, -0.46, 0),
                                           font=imp)
        self.team2Btn = DirectButton(parent=self.team2BtnFrame,
                                     relief=None,
                                     pressEffect=0,
                                     image=self.team2BtnImg,
                                     image_scale=(0.9, 1, 1),
                                     scale=0.4,
                                     command=self.choseTeam,
                                     extraArgs=[TEAM2])
        self.team2Plyrs_Lbl = OnscreenText(parent=self.team2BtnFrame,
                                           text=str(self.playersByTeam[TEAM2]),
                                           pos=(0, -0.46, 0),
                                           font=imp)
        self.teamFull_Lbl = OnscreenText(parent=self.container,
                                         text="",
                                         pos=(0, -0.6, 0),
                                         font=imp)

    def destroySelectionGUI(self):
        if self.teamFull_Lbl:
            self.teamFull_Lbl.destroy()
            self.teamFull_Lbl = None
        if self.team2Plyrs_Lbl:
            self.team2Plyrs_Lbl.destroy()
            self.team2Plyrs_Lbl = None
        if self.team1Plyrs_Lbl:
            self.team1Plyrs_Lbl.destroy()
            self.team1Plyrs_Lbl = None
        if self.team2Btn:
            self.team2Btn.destroy()
            self.team2Btn = None
        if self.team1Btn:
            self.team1Btn.destroy()
            self.team1Btn = None
        if self.team2BtnFrame:
            self.team2BtnFrame.destroy()
            self.team2BtnFrame = None
        if self.team1BtnFrame:
            self.team1BtnFrame.destroy()
            self.team1BtnFrame = None
        if self.title:
            self.title.destroy()
            self.title = None
        if self.bg:
            self.bg.destroy()
            self.bg = None
        if self.container:
            self.container.destroy()
            self.container = None

    def choseTeam(self, team):
        self.team = team
        self.team1Btn['state'] = DGG.DISABLED
        self.team2Btn['state'] = DGG.DISABLED
        self.sendUpdate('choseTeam', [team])

    def acceptedIntoTeam(self):
        message = MSG_WELCOME.format(self.teamNameById[self.team])
        whisper = WhisperPopup(message, CIGlobals.getToonFont(),
                               ChatGlobals.WTSystem)
        whisper.manage(base.marginManager)

    def teamFull(self):
        # Oh, man, the team is full. Let's try again.
        self.teamFull_Lbl.setText('Sorry, that team is full.')
        self.team = None
        self.team1Btn['state'] = DGG.NORMAL
        self.team2Btn['state'] = DGG.NORMAL

    def incrementTeamPlayers(self, team):
        self.playersByTeam[team] += 1
        if self.fsm.getCurrentState().getName() == 'chooseTeam':
            if team == TEAM2:
                lbl = self.team2Plyrs_Lbl
            elif team == TEAM1:
                lbl = self.team1Plyrs_Lbl
            lbl.setText(str(self.playersByTeam[team]))

    def setTeamOfPlayer(self, avId, team):
        if not hasattr(self, 'getRemoteAvatar'):
            self.notify.error('Minigame must have remote avatars!!')

        remoteAvatar = self.getRemoteAvatar(avId)
        if remoteAvatar:
            print "setting team of {0}".format(avId)
            remoteAvatar.setTeam(team)

    def cleanup(self):
        self.destroySelectionGUI()
        del self.team1Name
        del self.teamNameById
        del self.team2Name
        del self.team1BtnImg
        del self.team2BtnImg
        del self.team
        del self.playersByTeam
Esempio n. 20
0
class NewGame(State):
	def __init__(self):
		State.__init__(self)

		modeOptions = ['Single-Player', 'Multi-Player']
		self.optState = ['single', 'multi']

		self.menu = Menu()
		self.menu.addOptions(modeOptions)
		self.innerState = "Choosing Mode"

	def register(self, render, camera, keys):
		State.register(self, render, camera, keys)

		cm = CardMaker('CardMaker-NewGame')
		#tex = loadTexture('titlescreen.png')

		cm.setFrame(-1, 1, -1, 1)

		self.bg = self.node.attachNewNode(cm.generate())
		self.bg.setPos(0, 0, 0)
		self.bg.setColor(0, 0, 0)
		#self.bg.setTexture(tex)

		menuActions = {'left': (Menu.previousOpt, self.menu),
						'right': (Menu.nextOpt, self.menu),
						'action': (self.selectOption, None)
						}

		self.menu.registerKeys(keys, menuActions)

		self.title = OnscreenText(text="Game Mode", mayChange = True , style=2, fg=(1,1,1,1), pos=(0, 0.75), scale = 0.15)
		self.text = {}

		id=0
		for opt in self.menu.options:
			self.text[opt] = OnscreenText(text=opt, mayChange = True , style=2, fg=(1,1,1,1), pos=(-0.5 + 1*id, -0.3), scale = .1)
			id+=1

		self.title.reparentTo(self.node)
		for opt in self.text.keys():
			self.text[opt].reparentTo(self.node)

		State.register(self, render, camera, keys)


	def iterate(self):
		State.iterate(self)
		self.camera.look()

		for option in self.text.keys():
			self.text[option].setScale(0.1)
		self.text[self.menu.options[self.menu.selected]].setScale(0.12)

		if self.innerState == "Choosing Mode":
			ret = self.menu.iterate()
			if ret != None:
				for opt in self.menu.options:
					self.text[opt].removeNode()
				self.title.setText("Choose Player")

				playerOptions = ['Jackson', 'Jackson2']
				self.menu.clearOptions()
				self.menu.addOptions(playerOptions)

				id = 0
				for opt in self.menu.options:
					self.text[opt] = OnscreenText(text=opt, mayChange = True , style=2, fg=(1,1,1,1), pos=(-0.5 + 1*id, -0.3), scale = .1)
					self.text[opt].reparentTo(self.node)
					id+=1

				if ret == "single":
					self.innerState = "Choosing Single"
				elif ret == "multi":
					self.innerState = "Choosing Multi"

			return None
		elif self.innerState == "Choosing Single":
			ret = self.menu.iterate()
			if ret != None:
				return 'InGame'
		elif self.innerState == "Choosing Multi":
			ret = self.menu.iterate()
			if ret != None:
				return 'InGame'

	def selectOption(self, opt):
		return self.optState[self.menu.selected]
Esempio n. 21
0
class DistributedDeliveryGame(DistributedMinigame):
    notify = directNotify.newCategory("DistributedDeliveryGame")

    def __init__(self, cr):
        DistributedMinigame.__init__(self, cr)
        self.fsm.addState(
            State.State("announceGameOver", self.enterAnnounceGameOver, self.exitAnnounceGameOver, ["gameOver"])
        )
        self.fsm.getStateNamed("play").addTransition("announceGameOver")
        self.world = None
        self.gagShop = None
        self.sky = None
        self.skyUtil = SkyUtil()
        base.localAvatar.hasBarrel = False
        self.truckBarrelIsFrom = None
        self.soundPickUpBarrel = None
        self.soundDropOff = None
        self.barrelsByAvId = {}
        self.bsLabel = None
        self.brLabel = None
        self.bdLabel = None
        self.gagShopCollNP = None
        self.barrelsRemaining = 0
        self.barrelsStolen = 0
        self.barrelsDelivered = 0
        return

    def allBarrelsGone(self):
        self.fsm.request("announceGameOver")

    def enterAnnounceGameOver(self):
        whistleSfx = base.loadSfx("phase_4/audio/sfx/AA_sound_whistle.mp3")
        whistleSfx.play()
        del whistleSfx
        self.gameOverLbl = DirectLabel(
            text="GAME\nOVER!", relief=None, scale=0.35, text_font=CIGlobals.getMickeyFont(), text_fg=(1, 0, 0, 1)
        )
        return

    def exitAnnounceGameOver(self):
        self.gameOverLbl.destroy()
        del self.gameOverLbl

    def setBarrelsRemaining(self, num):
        self.barrelsRemaining = num
        self.__updateLabels()

    def getBarrelsRemaining(self):
        return self.barrelsRemaining

    def setBarrelsStolen(self, num):
        self.barrelsStolen = num
        self.__updateLabels()

    def getBarrelsStolen(self):
        return self.barrelsStolen

    def setBarrelsDelivered(self, num):
        self.barrelsDelivered = num
        self.__updateLabels()

    def getBarrelsDelivered(self):
        return self.barrelsDelivered

    def giveBarrelToSuit(self, suitId):
        suit = self.cr.doId2do.get(suitId)
        if suit:
            barrel = loader.loadModel("phase_4/models/cogHQ/gagTank.bam")
            barrel.reparentTo(suit.find("**/joint_Rhold"))
            barrel.setP(180)
            barrel.setScale(0.2)
            barrel.find("**/gagTankColl").removeNode()
            self.barrelsByAvId[suitId] = barrel

    def giveBarrelToPlayer(self, avId, truckId):
        if avId == self.localAvId:
            if not base.localAvatar.hasBarrel:
                base.localAvatar.hasBarrel = True
                base.playSfx(self.soundPickUpBarrel)
                self.truckBarrelIsFrom = truckId
            else:
                return
        av = self.cr.doId2do.get(avId)
        if av:
            av.setForcedTorsoAnim("catchneutral")
            barrel = loader.loadModel("phase_4/models/cogHQ/gagTank.bam")
            barrel.reparentTo(av.find("**/def_joint_right_hold"))
            barrel.setP(90)
            barrel.setZ(0.25)
            barrel.setScale(0.2)
            barrel.find("**/gagTankColl").removeNode()
            self.barrelsByAvId[avId] = barrel

    def dropOffBarrel(self, avId):
        if avId == self.localAvId:
            if base.localAvatar.hasBarrel:
                base.localAvatar.hasBarrel = False
                base.playSfx(self.soundDropOff)
            else:
                return
        av = self.cr.doId2do.get(avId)
        if av:
            av.clearForcedTorsoAnim()
            barrel = self.barrelsByAvId.get(avId)
            if barrel != None or not barrel.isEmpty():
                barrel.removeNode()
                del self.barrelsByAvId[avId]
        return

    def load(self):
        spawn = random.choice(DGG.SpawnPoints)
        base.localAvatar.setPos(spawn)
        base.localAvatar.setHpr(0, 0, 0)
        self.soundPickUpBarrel = base.loadSfx("phase_6/audio/sfx/SZ_MM_gliss.mp3")
        self.soundDropOff = base.loadSfx("phase_4/audio/sfx/MG_sfx_travel_game_bell_for_trolley.mp3")
        self.setMinigameMusic("phase_4/audio/bgm/MG_Delivery.mp3")
        self.setDescription(
            "A new supply of Gags were just shipped to Toontown! "
            + "Run over to a truck with Gag barrels to take a barrel out. Then, carry it over to the Gag Shop. "
            + "Try to unload and deliver as many barrels as you can to the Gag Shop. "
            + "Watch out for the Cogs - they might try to snatch a barrel!"
        )
        self.setWinnerPrize(100)
        self.setLoserPrize(0)
        self.gagShop = loader.loadModel("phase_4/models/modules/gagShop_TT.bam")
        self.gagShop.reparentTo(base.render)
        self.gagShop.setY(-70)
        sphere = CollisionSphere(0, 0, 0, 3)
        sphere.setTangible(0)
        node = CollisionNode("MGDeliveryGagShop")
        node.addSolid(sphere)
        self.gagShopCollNP = self.gagShop.attachNewNode(node)
        self.world = loader.loadModel("phase_4/models/minigames/delivery_area.egg")
        self.world.setY(-5)
        self.world.reparentTo(base.render)
        self.sky = loader.loadModel("phase_3.5/models/props/TT_sky.bam")
        self.sky.reparentTo(base.camera)
        ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ)
        self.sky.node().setEffect(ce)
        self.sky.setZ(-20)
        self.skyUtil.startSky(self.sky)
        base.camera.setPos(20, 50, 30)
        base.camera.lookAt(20, 0, 7.5)
        DistributedMinigame.load(self)

    def enterStart(self):
        DistributedMinigame.enterStart(self)
        beepSound = base.loadSfx("phase_4/audio/sfx/MG_delivery_truck_beep.mp3")
        base.playSfx(beepSound)

    def enterPlay(self):
        DistributedMinigame.enterPlay(self)
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.enableAvatarControls()
        self.brLabel = OnscreenText(
            text="",
            parent=base.a2dTopRight,
            fg=(1, 1, 1, 1),
            shadow=(0, 0, 0, 1),
            pos=(-0.1, -0.1, 0),
            align=TextNode.ARight,
        )
        self.bdLabel = OnscreenText(
            text="",
            parent=base.a2dTopLeft,
            fg=(1, 1, 1, 1),
            shadow=(0, 0, 0, 1),
            pos=(0.1, -0.1, 0),
            align=TextNode.ALeft,
        )
        self.bsLabel = OnscreenText(
            text="",
            parent=base.a2dTopLeft,
            fg=(1, 1, 1, 1),
            shadow=(0, 0, 0, 1),
            pos=(0.1, -0.2, 0),
            align=TextNode.ALeft,
        )
        self.accept("enterMGDeliveryGagShop", self.__maybeDropOffBarrel)

    def __maybeDropOffBarrel(self, entry):
        if base.localAvatar.hasBarrel and self.truckBarrelIsFrom != None:
            self.sendUpdate("requestDropOffBarrel", [self.truckBarrelIsFrom])
            self.truckBarrelIsFrom = None
        return

    def __updateLabels(self):
        if self.brLabel:
            self.brLabel.setText("Barrels Remaining: {0}".format(self.getBarrelsRemaining()))
        if self.bdLabel:
            self.bdLabel.setText("Barrels Delivered: {0}".format(self.getBarrelsDelivered()))
        if self.bsLabel:
            self.bsLabel.setText("Barrels Stolen: {0}".format(self.getBarrelsStolen()))

    def exitPlay(self):
        self.ignore("enterMGDeliveryGagShop")
        base.localAvatar.disableAvatarControls()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()
        self.brLabel.destroy()
        self.brLabel = None
        self.bsLabel.destroy()
        self.bsLabel = None
        self.bdLabel.destroy()
        self.bdLabel = None
        DistributedMinigame.exitPlay(self)
        return

    def announceGenerate(self):
        DistributedMinigame.announceGenerate(self)
        self.load()

    def disable(self):
        if self.world:
            self.world.removeNode()
            self.world = None
        if self.gagShop:
            self.gagShop.removeNode()
            self.gagShop = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.gagShopCollNP:
            self.gagShopCollNP.removeNode()
            self.gagShopCollNP = None
        self.skyUtil = None
        self.soundPickUpBarrel = None
        self.soundDropOff = None
        self.truckBarrelIsFrom = None
        del base.localAvatar.hasBarrel
        self.barrelsByAvId = None
        DistributedMinigame.disable(self)
        return
class KOTHGui(DirectFrame):
    notify = directNotify.newCategory('KOTHGui')
    pointsSfx = None
    points = None

    def __init__(self):
        DirectFrame.__init__(self,
                             parent=base.a2dTopLeft,
                             relief=None,
                             pos=(0.275, 1, -0.7),
                             sortOrder=0)
        self.pointsSfx = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg')
        self.points = 0
        gui = loader.loadModel('phase_4/models/gui/purchase_gui.bam')
        panel = gui.find('**/yellowPanel')
        self.bg = OnscreenImage(image=panel, parent=self)
        self.title = OnscreenText(text='Capture Points',
                                  font=CIGlobals.getMinnieFont(),
                                  parent=self,
                                  scale=0.0475,
                                  pos=(0, 0.18),
                                  fg=(1, 0, 0, 1),
                                  shadow=(0.2, 0.2, 0.2, 1))
        self.amt_label = OnscreenText(text=str(self.points),
                                      font=CIGlobals.getToonFont(),
                                      parent=self,
                                      scale=0.15,
                                      pos=(0, 0.03525),
                                      shadow=(0.5, 0.5, 0.5, 0.6))
        self.info = OnscreenText(
            text=
            'First Toon to 100 points wins!\nEarn points by standing on the\nhill after capturing it.',
            parent=self,
            font=CIGlobals.getToonFont(),
            scale=0.035,
            pos=(0, -0.05),
            fg=(1.5, 0, 0, 1),
            shadow=(0.2, 0.2, 0.2, 1))
        self.hide()
        return

    def show(self):
        self.title.show()
        self.amt_label.show()
        self.info.show()
        self.bg.show()

    def hide(self):
        self.title.hide()
        self.amt_label.hide()
        self.info.hide()
        self.bg.hide()

    def destroy(self):
        self.title.destroy()
        self.amt_label.destroy()
        self.info.destroy()
        self.bg.destroy()
        self.title = None
        self.amt_label = None
        self.info = None
        self.bg = None
        self.pointsSfx.stop()
        self.pointsSfx = None
        self.points = None
        DirectFrame.destroy(self)
        return

    def setPoints(self, points):
        self.points = points
        self.amt_label.setText(str(self.points))
        self.pointsSfx.play()

    def getPoints(self):
        return self.points
class PandaTextureViewer(object):
    
    def __init__(self, mesh_path, progressive_texture_path):

        resolutions = []
        f = tarfile.open(progressive_texture_path)
        for resolution_name in f.getnames():
            toset = {'size': resolution_name[:-4],
                     'contents': f.extractfile(resolution_name).read()}
            texpnm = PNMImage()
            texpnm.read(StringStream(toset['contents']), 'something.jpg')
            newtex = Texture()
            newtex.load(texpnm)
            toset['texture'] = newtex
            resolutions.append(toset)
        
        self.resolutions = resolutions
        def aux_loader(fname):
            return resolutions[0]['contents']
        mesh = collada.Collada(mesh_path, aux_file_loader=aux_loader)
        
        scene_members = getSceneMembers(mesh)
        
        base = ShowBase()
        
        rotateNode = GeomNode("rotater")
        rotatePath = render.attachNewNode(rotateNode)
        matrix = numpy.identity(4)
        if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
            r = collada.scene.RotateTransform(0,1,0,90)
            matrix = r.matrix
        elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
            r = collada.scene.RotateTransform(1,0,0,90)
            matrix = r.matrix
        rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))
        
        geom, renderstate, mat4 = scene_members[0]
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        self.geomPath = rotatePath.attachNewNode(node)
        self.geomPath.setMat(mat4)
            
        wrappedNode = ensureCameraAt(self.geomPath, base.camera)
        base.disableMouse()
        attachLights(render)
        render.setShaderAuto()
        render.setTransparency(TransparencyAttrib.MDual, 1)
    
        base.render.analyze()
        KeyboardMovement()
        MouseDrag(wrappedNode)
        MouseScaleZoom(wrappedNode)
        MouseCamera()
        
        num_resolutions = len(resolutions) - 1
        self.slider = DirectSlider(range=(0, num_resolutions),
                                   value=0, pageSize=1,
                                   command=self.sliderMoved, pos=(0, 0, -.9), scale=1)
        for key, val in uiArgs.iteritems():
            self.slider.thumb[key] = val
        
        self.triText = OnscreenText(text="", pos=(-1,0.85), scale = 0.15,
                                    fg=(1, 0.5, 0.5, 1), align=TextNode.ALeft, mayChange=1)
        
        base.run()
        
    def sliderMoved(self):
        sliderVal = int(self.slider['value'])
        #if self.pm_index != sliderVal:
        #    self.movePmTo(sliderVal)
        np = render.find("**/rotater/collada")
        np.setTextureOff(1)
        np.setTexture(self.resolutions[sliderVal]['texture'], 1)
        self.triText.setText('Resolution: %s' % self.resolutions[sliderVal]['size'])
class KOTHGui(DirectFrame):
    notify = directNotify.newCategory('KOTHGui')

    pointsSfx = None
    points = None

    def __init__(self):
        # Let's load up the DirectFrame
        DirectFrame.__init__(self,
                             parent=base.a2dTopLeft,
                             relief=None,
                             pos=(0.275, 1, -0.7),
                             sortOrder=0)

        # The variables we're going to be using.
        self.pointsSfx = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg')
        self.points = 0

        # Background because it won't work for whatever reason.
        gui = loader.loadModel('phase_4/models/gui/purchase_gui.bam')
        panel = gui.find('**/yellowPanel')
        self.bg = OnscreenImage(image=panel, parent=self)

        # Let's setup the header text.
        self.title = OnscreenText(text='Capture Points',
                                  font=CIGlobals.getMinnieFont(),
                                  parent=self,
                                  scale=0.0475,
                                  pos=(0, 0.18),
                                  fg=(1, 0, 0, 1),
                                  shadow=(0.2, 0.2, 0.2, 1))

        # Let's setup the amount text.
        self.amt_label = OnscreenText(text=str(self.points),
                                      font=CIGlobals.getToonFont(),
                                      parent=self,
                                      scale=0.15,
                                      pos=(0, 0.03525),
                                      shadow=(0.5, 0.5, 0.5, 0.6))

        # Let's setup the info text.
        self.info = OnscreenText(
            text=
            'First Toon to 100 points wins!\nEarn points by standing on the\nhill after capturing it.',
            parent=self,
            font=CIGlobals.getToonFont(),
            scale=0.035,
            pos=(0, -0.05),
            fg=(1.5, 0, 0, 1),
            shadow=(0.2, 0.2, 0.2, 1))

        # We're not ready to show the GUI yet.
        self.hide()

    def show(self):
        self.title.show()
        self.amt_label.show()
        self.info.show()
        self.bg.show()

    def hide(self):
        self.title.hide()
        self.amt_label.hide()
        self.info.hide()
        self.bg.hide()

    def destroy(self):
        self.title.destroy()
        self.amt_label.destroy()
        self.info.destroy()
        self.bg.destroy()
        self.title = None
        self.amt_label = None
        self.info = None
        self.bg = None

        # Let's get rid of the sound.
        self.pointsSfx.stop()
        self.pointsSfx = None

        self.points = None
        DirectFrame.destroy(self)

    def setPoints(self, points):
        self.points = points
        self.amt_label.setText(str(self.points))
        self.pointsSfx.play()

    def getPoints(self):
        return self.points
Esempio n. 25
0
class KOTHKingGui(DirectFrame):
    notify = directNotify.newCategory('KOTHKingGui')
    
    def __init__(self, mg, king, points):
        DirectFrame.__init__(self, parent = aspect2d)
        self.setBin('gui-popup', 60)
        self.mg = mg
        
        # Let's create the background
        box = DGG.getDefaultDialogGeom()
        self.bg = OnscreenImage(image = box, color = (1, 1, 0.75, 1), scale = (1.9, 1.4, 1.4), parent = self)
        
        # Let's create the header
        toonFont = CIGlobals.getToonFont()
        minnieFont = CIGlobals.getMinnieFont()
        
        name = 'Nobody'
        
        if king:
            name = king.getName()
            self.kingId = king.doId
        else:
            king = base.localAvatar
            self.kingId = 0
        
        self.title = OnscreenText(text = '%s is King!' % name, pos = (0, 0.5, 0), font = toonFont, 
            scale = 0.12, parent = self, shadow = (0.5, 0.5, 0.5, 0.6))
        
        # Let's create the Toon head
        headFrame = self.attachNewNode('head')
        headFrame.setPosHprScale(0, 0, -0.1, 180, 0, 0, 0.3, 0.3, 0.3)
        head = ToonGlobals.generateGuiHead(king)
        head.reparentTo(headFrame)
        
        # Let's create the points text
        self.amt_label = OnscreenText(text = 'Your Points: 0', pos = (-0.012, -0.4, 0), font = toonFont,
            scale = 0.12, parent = self, shadow = (0.5, 0.5, 0.5, 0.6))
        self.amt_label.hide()
        
        # Let's create the bad news text
        self.motivator = OnscreenText(text = 'Better luck next time!', pos = (0, -0.6, 0), font = minnieFont,
            scale = 0.125, parent = self, fg = (1, 0, 0, 1), shadow = (0.2, 0.2, 0.2, 1))
        self.motivator.hide()
        
        self.easterEgg = False
        
        if 50 < points != 100:
            self.motivator['fg'] = (0, 1, 0, 1)
            self.motivator.setText('Great job!')
        elif points == 100:
            self.motivator['fg'] = (0, 1, 0, 1)
            if random.randint(0, 100) <= 10:
                self.motivator.setText('YOU THE REAL MVP!')
                self.easterEgg = True
            else:
                self.motivator.setText('AMAZING!')
        
        # Let's create the sound effects
        self.zeroPointsSfx = loader.loadSfx('phase_4/audio/sfx/MG_neg_buzzer.ogg')
        self.poorScoreSfx = loader.loadSfx('phase_4/audio/sfx/MG_sfx_travel_game_no_bonus.ogg')
        self.goodScoreSfx = loader.loadSfx('phase_4/audio/sfx/MG_pairing_match_bonus_both.ogg')
        self.stomperSfx = loader.loadSfx('phase_4/audio/sfx/CHQ_FACT_stomper_small.ogg')
        self.fireworkSfx = loader.loadSfx('phase_4/audio/sfx/firework_explosion_02.ogg')
        self.perfectSfx = loader.loadSfx('phase_5/audio/sfx/SZ_MM_fanfare.ogg')
        self.tick_fastSfx = loader.loadSfx('phase_4/audio/sfx/MG_maze_pickup.ogg')
        self.tick_slowSfx = loader.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg')
        self.easterEggSfx = loader.loadSfx('phase_4/audio/sfx/avatar_emotion_very_sad.ogg')
        
        # Let's create the basic sequence
        self.pointsSeq = Sequence(Func(self.amt_label.show),
            Wait(0.25))
        
        self.seqLevel = 0
        self.fakeNumber = 0
        self.points = points
    
    def start(self):
        base.transitions.fadeScreen(0.5)
        if self.points == 0:
            self.__doZero()
        else:
            self.__doRegular()
            
    def destroy(self):
        # Let's stop the sequence.
        if self.pointsSeq:
            self.pointsSeq.finish()
        self.pointsSeq = None
        
        # Let's stop and destroy all the sounds.
        if self.zeroPointsSfx:
            self.zeroPointsSfx.stop()
            self.poorScoreSfx.stop()
            self.goodScoreSfx.stop()
            self.stomperSfx.stop()
            self.fireworkSfx.stop()
            self.perfectSfx.stop()
            self.tick_fastSfx.stop()
            self.tick_slowSfx.stop()
            self.easterEggSfx.stop()
        self.zeroPointsSfx = None
        self.poorScoreSfx = None
        self.goodScoreSfx = None
        self.stomperSfx = None
        self.fireworkSfx = None
        self.perfectSfx = None
        self.tick_fastSfx = None
        self.tick_slowSfx = None
        self.easterEggSfx = None
        
        # Let's destroy all the variables.
        self.points = None
        self.easterEgg = None
        self.seqLevel = None
        self.fakeNumber = None
        self.kingId = None
        self.mg = None
        
        # Let's destroy all the frames.
        if self.bg:
            self.bg.destroy()
            self.title.destroy()
            self.amt_label.destroy()
            self.motivator.destroy()
        self.bg = None
        self.title = None
        self.amt_label = None
        self.motivator = None
        
        DirectFrame.destroy(self)
        
    def unload(self):
        pass
    
    def hideFinalScores(self):
        base.transitions.noTransitions()
        self.hide()
        
    def handleExit(self):
        winner = 0
        if self.kingId != 0:
            winner = 1
        self.pointsSeq.append(Sequence(Wait(5), Func(self.mg.gameOver, winner, [self.kingId])))
        return
        
    def __doZeroEffect(self, task):
        if self.seqLevel == 0:
            task.delayTime = 0.2
            self.tick_fastSfx.play()
            self.amt_label.setText('Your Points: %s' % str(self.fakeNumber))
            self.fakeNumber += 1
            
            if self.fakeNumber == 3:
                self.seqLevel = 1
        elif self.seqLevel == 1:
            task.delayTime = 0.35
            self.tick_slowSfx.play()
            self.amt_label.setText('Your Points: %s' % str(self.fakeNumber))
            self.fakeNumber += 1
            
            if self.fakeNumber == 6:
                self.seqLevel = 2
                task.delayTime = 0.35
                
        elif self.seqLevel == 2:
            task.delayTime = 0.10
            self.tick_fastSfx.play()
            self.amt_label.setText('Your Points: %s' % str(self.fakeNumber))
            self.fakeNumber -= 1
            
            if self.fakeNumber == -1:
                self.stomperSfx.play()
                ToontownIntervals.start(ToontownIntervals.getPulseLargerIval(self.amt_label, 'effect'))
                self.pointsSeq = Sequence(Wait(0.25), Func(self.zeroPointsSfx.play), Func(self.motivator.show))
                self.handleExit()
                self.pointsSeq.start()
                return task.done
        return task.again
    
    def __doRegularEffect(self, task):
        if self.points <= 5 and self.seqLevel == 0:
            self.seqLevel = 2
            
        if self.seqLevel == 0:
            task.delayTime = 0.35
            self.fakeNumber += 1
            self.amt_label.setText('Your Points: %s' % str(self.fakeNumber))
            self.tick_slowSfx.play()
            
            if self.fakeNumber == 2:
                task.delayTime = 0.25
                self.seqLevel = 1
        
        elif self.seqLevel == 1:
            if self.points <= 50:
                task.delayTime = 0.12
            elif 50 < self.points != 100:
                task.delayTime = 0.075
            else:
                task.delayTime = 0.065
            self.fakeNumber += 1
            self.amt_label.setText('Your Points: %s' % str(self.fakeNumber))
            self.tick_fastSfx.play()
            
            if self.fakeNumber == self.points - 5:
                task.delayTime = 0.25
                self.seqLevel = 2
        
        elif self.seqLevel == 2:
            task.delayTime = 0.35
            self.fakeNumber += 1
            self.amt_label.setText('Your Points: %s' % str(self.fakeNumber))
            self.tick_slowSfx.play()
            
            if self.fakeNumber == self.points:
                if self.points <= 50:
                    self.pointsSeq = Sequence(Wait(0.25), Func(self.poorScoreSfx.play), Func(self.motivator.show))
                elif 50 < self.points != 100:
                    pulse = ToontownIntervals.getPulseLargerIval(self.amt_label, 'effect')
                    self.pointsSeq = Sequence(Wait(0.25), Func(self.goodScoreSfx.play),
                        Func(ToontownIntervals.start, pulse), Func(self.motivator.show))
                elif self.points == 100:
                    pulse = ToontownIntervals.getPulseLargerIval(self.amt_label, 'effect')
                    self.pointsSeq = Sequence(Wait(0.25), Func(ToontownIntervals.start, pulse), 
                        Func(self.fireworkSfx.play), Wait(0.25), Func(self.perfectSfx.play), Func(self.motivator.show))
                    
                    if self.easterEgg:
                        self.pointsSeq.append(Sequence(Wait(0.30), Func(self.easterEggSfx.play)))
                self.handleExit()
                self.pointsSeq.start()
                return task.done
        return task.again
        
    def __doZero(self):
        self.pointsSeq.append(Sequence(
            Func(taskMgr.add, self.__doZeroEffect, 'Point Effect')
        ))
        self.pointsSeq.start()
        
    def __doRegular(self):
        self.pointsSeq.append(Sequence(
            Func(taskMgr.add, self.__doRegularEffect, 'Point Effect')
        ))
        self.pointsSeq.start()
Esempio n. 26
0
class GagSelectionGui(DirectFrame, FSM):
    InactivityTime = 5.0

    AmmoZSelect = -0.15
    AmmoZIdle = 0.035

    def __init__(self):
        DirectFrame.__init__(self,
                             parent=aspect2d,
                             pos=(0, 0, 0.93),
                             scale=0.7)
        FSM.__init__(self, 'GagSelectionGui')
        self.setTransparency(TransparencyAttrib.MDual)
        self.tracks = []
        self.currentTrack = 0
        self.currentGag = None
        self.fwdShakeIval = None
        self.revShakeIval = None
        self.newTrackSound = None
        self.keyScrollSound = None
        self.selectSound = None
        self.selectDenySound = None
        self.lastActivityTime = 0.0
        self.activityTask = None
        self.midpoint = 0.0

        self.ammoFrame = DirectFrame(parent=self,
                                     pos=(0, 0, -0.2),
                                     image='phase_14/maps/status_bar.png',
                                     image_scale=(0.461 * 0.7, 0, 0.098),
                                     relief=None)
        self.ammoFrame.hide()
        self.ammoTitle = OnscreenText(parent=self.ammoFrame,
                                      text='SUPPLY',
                                      fg=(0, 0, 0, 0.65),
                                      align=TextNode.ALeft,
                                      pos=(-0.37 * 0.7, -0.015, 0))
        self.ammoText = OnscreenText(parent=self.ammoFrame,
                                     text='',
                                     fg=(1, 1, 1, 1),
                                     shadow=(0, 0, 0, 1),
                                     align=TextNode.ARight,
                                     pos=(0.37 * 0.7, -0.015, 0))

    def update(self):
        plyr = base.localAvatar

        if not base.localAvatar.hasAttacks():
            return

        gagId = -1
        if self.getCurrentOrNextState() == 'Idle':
            gagId = plyr.getEquippedAttack()
        elif self.getCurrentOrNextState() == 'Select' and self.currentGag:
            gagId = self.currentGag.gagId

        if gagId != -1:
            self.ammoFrame.showThrough()
            if plyr.hasAttackId(gagId):
                self.ammoText.setText(
                    '%i/%i' %
                    (plyr.getAttackAmmo(gagId), plyr.getAttackMaxAmmo(gagId)))
            else:
                self.ammoText.setText('')
            col = GagGlobals.TrackColorByName[GagGlobals.getTrackOfGag(gagId)]
            self.ammoFrame['image_color'] = (col[0], col[1], col[2], 1.0)
        else:
            self.ammoFrame.hide()

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def hide(self):
        showAmmo = False
        if not self.ammoFrame.isHidden():
            showAmmo = True
        DirectFrame.hide(self)
        if showAmmo:
            self.ammoFrame.showThrough()

    def enterSelect(self):
        base.localAvatar.disableGagKeys()
        self.ammoFrame.setZ(self.AmmoZSelect)
        self.show()
        self.update()
        self.acceptSelectionClick()
        self.resetTimeout()
        self.activityTask = taskMgr.add(self.__activityTask, "activityTask")

    def acceptSelectionClick(self):
        self.accept('mouse1-up', self.selectCurrentGag)

    def ignoreSelectionClick(self):
        self.ignore('mouse1-up')

    def resetTimeout(self):
        self.lastActivityTime = globalClock.getFrameTime()

    def __activityTask(self, task):
        time = globalClock.getFrameTime()
        if time - self.lastActivityTime >= self.InactivityTime:
            self.request('Idle')
            return task.done
        return task.cont

    def exitSelect(self):
        self.activityTask.remove()
        self.activityTask = None
        self.hide()
        self.ignoreSelectionClick()

    def enterIdle(self):
        self.ammoFrame.setZ(self.AmmoZIdle)
        self.hide()
        self.update()
        if base.localAvatar.avatarMovementEnabled:
            base.localAvatar.enableGagKeys()

    def exitIdle(self):
        pass

    def disable(self):
        self.disableControls()
        self.hide()

    def enable(self):
        self.enableControls()
        self.show()

    def cleanup(self):
        self.request('Off')

        self.disableControls()

        self.newTrackSound = None
        self.keyScrollSound = None
        self.selectSound = None
        self.selectDenySound = None

        if self.fwdShakeIval:
            self.fwdShakeIval.finish()
            self.fwdShakeIval = None
        if self.revShakeIval:
            self.revShakeIval.finish()
            self.revShakeIval = None
        self.currentTrack = None
        self.currentGag = None
        if self.tracks:
            for track in self.tracks:
                track.cleanup()
        self.tracks = None

        self.destroy()

    def __accumulateTracks(self):
        tracks = []
        for gagId in base.localAvatar.attacks.keys():
            trackId = GagGlobals.getTrackOfGag(gagId, getId=True)
            if trackId not in tracks:
                tracks.append(trackId)
        tracks.sort()
        return tracks

    def load(self):
        tracks = self.__accumulateTracks()
        for i in xrange(len(tracks)):
            track = GagTrack(self, tracks[i])
            track.load()
            track.reparentTo(self)
            track.setX(FRAME_OFFSET * i)
            self.tracks.append(track)

        self.midpoint = (len(self.tracks) / 2.0) * -FRAME_OFFSET
        # Center the gui horizontally
        self.setX(self.midpoint)
        self.ammoFrame.setX(-self.midpoint)

        if base.config.GetBool('gsg-want-hlsounds', False):
            self.newTrackSound = base.loadSfx(
                "phase_14/audio/sfx/wpn_hudon.ogg")
            self.keyScrollSound = base.loadSfx(
                'phase_14/audio/sfx/wpn_moveselect.ogg')
            self.selectSound = base.loadSfx(
                'phase_14/audio/sfx/wpn_select.ogg')
            self.selectDenySound = base.loadSfx(
                'phase_14/audio/sfx/wpn_denyselect.ogg')
        else:
            self.newTrackSound = base.loadSfx(
                "phase_3/audio/sfx/GUI_create_toon_back.ogg")
            self.keyScrollSound = base.loadSfx(
                'phase_3/audio/sfx/GUI_rollover.ogg')
            self.selectSound = base.loadSfx(
                'phase_3/audio/sfx/GUI_create_toon_fwd.ogg')
            self.selectDenySound = base.loadSfx(
                'phase_4/audio/sfx/ring_miss.ogg')

        self.fwdShakeIval = Effects.createXBounce(self, 1,
                                                  Vec3(self.midpoint, 0, 0.93),
                                                  0.05, 0.05)
        self.revShakeIval = Effects.createXBounce(self, 1,
                                                  Vec3(self.midpoint, 0, 0.93),
                                                  0.05, -0.05)

        if base.localAvatar.hasAttacks():
            self.updateCurrentTrack(0)

    def enableControls(self):
        self.accept('wheel_up', self.__handleScrollUp)
        self.accept('wheel_down', self.__handleScrollDown)

        for i in xrange(len(self.tracks)):
            self.accept(str(i + 1), self.__handleTrackChoose, [i])

        self.request('Idle')

    def selectCurrentGag(self):
        selected = False

        self.newTrackSound.stop()
        self.keyScrollSound.stop()

        if self.currentGag is not None:
            if base.localAvatar.getEquippedAttack() == self.currentGag.gagId:
                selected = True
            elif (not self.currentGag.locked and self.currentGag.hasAmmo()):
                gagId = self.currentGag.gagId
                base.localAvatar.needsToSwitchToGag = gagId
                if base.localAvatar.gagsTimedOut == False:
                    base.localAvatar.selectGag(gagId)
                    selected = True

        if not selected:
            # Denied!
            self.selectDenySound.play()
            self.resetTimeout()
        else:
            self.selectSound.play()
            self.request('Idle')

    def disableControls(self):
        self.ignore('wheel_up')
        self.ignore('wheel_down')

        for i in xrange(len(self.tracks)):
            self.ignore(str(i + 1))

        self.request('Idle')

    def __maybeDoSelect(self):
        if self.getCurrentOrNextState() == 'Idle':
            self.request('Select')

    def __handleTrackChoose(self, idx):
        if not base.localAvatar.hasAttacks():
            return

        self.__maybeDoSelect()
        self.resetTimeout()

        if self.currentTrack == idx:
            # Scroll through the current track.
            self.tracks[self.currentTrack].selectNextGag()

            self.newTrackSound.stop()
            self.keyScrollSound.play()
        else:
            # Always start from the beginning when using the keys to choose a track.
            self.updateCurrentTrack(idx, 0)
            self.newTrackSound.play()

    def __handleScrollUp(self):
        if not base.localAvatar.hasAttacks():
            return

        self.__maybeDoSelect()
        self.resetTimeout()

        track = self.tracks[self.currentTrack]
        if track.isOnFirstGag():
            self.prevTrack()
        else:
            track.selectPrevGag()

        self.newTrackSound.stop()
        self.keyScrollSound.play()

    def __handleScrollDown(self):
        if not base.localAvatar.hasAttacks():
            return

        self.__maybeDoSelect()
        self.resetTimeout()

        track = self.tracks[self.currentTrack]
        if track.isOnLastGag():
            self.nextTrack()
        else:
            track.selectNextGag()

        self.newTrackSound.stop()
        self.keyScrollSound.play()

    def nextTrack(self):
        newIdx = self.currentTrack + 1
        if newIdx > len(self.tracks) - 1:
            newIdx = 0

        self.updateCurrentTrack(newIdx)

    def prevTrack(self):
        newIdx = self.currentTrack - 1
        if newIdx < 0:
            newIdx = len(self.tracks) - 1

        self.updateCurrentTrack(newIdx)

    def updateCurrentTrack(self, idx, startLoc=None):
        oldTrack = self.tracks[self.currentTrack]
        oldTrack.deselectAll()
        oldTrack.stashContents()

        if idx - self.currentTrack < 0:
            direction = 1
        else:
            direction = 0

        if startLoc is None:
            startLoc = direction

        if direction == 0:
            self.fwdShakeIval.start()
        else:
            self.revShakeIval.start()

        self.currentTrack = idx

        # Resort the tracks
        numTracks = len(self.tracks)
        maxTrack = numTracks - 1
        for i in xrange(len(self.tracks)):
            track = self.tracks[i]

            if i == idx:
                sort = FRAME_FRONT_SORT
            elif i > idx:
                sort = FRAME_SORT_BEGIN + (maxTrack - i) * FRAME_SORT_DISTANCE
            elif i < idx:
                sort = FRAME_SORT_BEGIN + (i * FRAME_SORT_DISTANCE)
            track.setBin('gsg-popup', sort)

            if i == idx:
                track.unstashContents()
                if startLoc == 0:
                    track.selectFirstGag()
                else:
                    track.selectLastGag()
            else:
                track.stashContents()
Esempio n. 27
0
class DistributedDeliveryGame(DistributedMinigame):
    notify = directNotify.newCategory('DistributedDeliveryGame')

    def __init__(self, cr):
        DistributedMinigame.__init__(self, cr)
        self.fsm.addState(
            State.State('announceGameOver', self.enterAnnounceGameOver,
                        self.exitAnnounceGameOver, ['gameOver']))
        self.fsm.getStateNamed('play').addTransition('announceGameOver')
        self.world = None
        self.gagShop = None
        self.olc = None
        base.localAvatar.hasBarrel = False
        self.truckBarrelIsFrom = None
        self.soundPickUpBarrel = None
        self.soundDropOff = None
        self.barrelsByAvId = {}
        self.bsLabel = None
        self.brLabel = None
        self.bdLabel = None
        self.gagShopCollNP = None
        self.barrelsRemaining = 0
        self.barrelsStolen = 0
        self.barrelsDelivered = 0
        self.pies = []

    def allBarrelsGone(self):
        self.fsm.request('announceGameOver')

    def enterAnnounceGameOver(self):
        whistleSfx = base.loadSfx("phase_4/audio/sfx/AA_sound_whistle.ogg")
        whistleSfx.play()
        del whistleSfx
        self.gameOverLbl = DirectLabel(text="GAME\nOVER!",
                                       relief=None,
                                       scale=0.35,
                                       text_font=CIGlobals.getMickeyFont(),
                                       text_fg=(1, 0, 0, 1))

    def exitAnnounceGameOver(self):
        self.gameOverLbl.destroy()
        del self.gameOverLbl

    def setBarrelsRemaining(self, num):
        self.barrelsRemaining = num
        self.__updateLabels()

    def getBarrelsRemaining(self):
        return self.barrelsRemaining

    def setBarrelsStolen(self, num):
        self.barrelsStolen = num
        self.__updateLabels()

    def getBarrelsStolen(self):
        return self.barrelsStolen

    def setBarrelsDelivered(self, num):
        self.barrelsDelivered = num
        self.__updateLabels()

    def getBarrelsDelivered(self):
        return self.barrelsDelivered

    def giveBarrelToSuit(self, suitId):
        suit = self.cr.doId2do.get(suitId)
        if suit:
            barrel = loader.loadModel('phase_4/models/cogHQ/gagTank.bam')
            barrel.reparentTo(suit.find('**/joint_Rhold'))
            barrel.setP(180)
            #barrel.setZ(0.25)
            barrel.setScale(0.2)
            barrel.find('**/gagTankColl').removeNode()
            self.barrelsByAvId[suitId] = barrel

    def giveBarrelToPlayer(self, avId, truckId):
        if avId == self.localAvId:
            if not base.localAvatar.hasBarrel:
                base.localAvatar.hasBarrel = True
                base.playSfx(self.soundPickUpBarrel)
                self.truckBarrelIsFrom = truckId
            else:
                return
        av = self.cr.doId2do.get(avId)
        if av:
            av.setForcedTorsoAnim('catchneutral')
            barrel = loader.loadModel('phase_4/models/cogHQ/gagTank.bam')
            barrel.reparentTo(av.find('**/def_joint_right_hold'))
            barrel.setP(90)
            barrel.setZ(0.35)
            barrel.setScale(0.3)
            barrel.find('**/gagTankColl').removeNode()
            self.barrelsByAvId[avId] = barrel

    def dropOffBarrel(self, avId):
        if avId == self.localAvId:
            if base.localAvatar.hasBarrel:
                base.localAvatar.hasBarrel = False
                base.playSfx(self.soundDropOff)
            else:
                return
        av = self.cr.doId2do.get(avId)
        if av:
            av.clearForcedTorsoAnim()
            barrel = self.barrelsByAvId.get(avId)
            if barrel != None or not barrel.isEmpty():
                barrel.removeNode()
                del self.barrelsByAvId[avId]

    def load(self):
        spawn = random.choice(DGG.SpawnPoints)
        base.localAvatar.setPos(spawn)
        base.localAvatar.setHpr(0, 0, 0)
        self.soundPickUpBarrel = base.loadSfx(
            'phase_6/audio/sfx/SZ_MM_gliss.ogg')
        self.soundDropOff = base.loadSfx(
            'phase_4/audio/sfx/MG_sfx_travel_game_bell_for_trolley.ogg')
        self.soundBeep = base.loadSfx(
            'phase_4/audio/sfx/MG_delivery_truck_beep.ogg')
        self.soundDoorOpen = base.loadSfx(
            "phase_9/audio/sfx/CHQ_VP_door_open.ogg")
        self.setMinigameMusic('phase_4/audio/bgm/MG_Delivery.ogg')
        self.setDescription('A new supply of Gags were just shipped to Toontown! ' + \
            'Run over to a truck with Gag barrels to take a barrel out. Then, carry it over to the Gag Shop. ' + \
            'Try to unload and deliver as many barrels as you can to the Gag Shop. ' + \
            'Watch out for the Cogs - they might try to snatch a barrel!')
        self.setWinnerPrize(100)
        self.setLoserPrize(0)
        self.gagShop = loader.loadModel(
            'phase_4/models/modules/gagShop_TT.bam')
        self.gagShop.reparentTo(base.render)
        self.gagShop.setY(-70)
        sphere = CollisionSphere(0, 0, 0, 3)
        sphere.setTangible(0)
        node = CollisionNode('MGDeliveryGagShop')
        node.addSolid(sphere)
        self.gagShopCollNP = self.gagShop.attachNewNode(node)
        self.world = loader.loadModel(
            'phase_4/models/minigames/delivery_area.egg')
        self.world.setY(-5)
        self.world.reparentTo(base.render)
        self.world.find('**/ground').setBin('ground', 18)
        self.olc = ZoneUtil.getOutdoorLightingConfig(ZoneUtil.ToontownCentral)
        self.olc.setupAndApply()
        base.camera.setPos(20, 50, 30)
        base.camera.lookAt(20, 0, 7.5)
        DistributedMinigame.load(self)

    def enterStart(self):
        DistributedMinigame.enterStart(self)
        base.playSfx(self.soundBeep)

    def enterPlay(self):
        DistributedMinigame.enterPlay(self)
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.startTrackAnimToSpeed()
        base.localAvatar.setWalkSpeedNormalNoJump()
        self.brLabel = OnscreenText(text="",
                                    parent=base.a2dTopRight,
                                    fg=(1, 1, 1, 1),
                                    shadow=(0, 0, 0, 1),
                                    pos=(-0.1, -0.1, 0),
                                    align=TextNode.ARight)
        self.bdLabel = OnscreenText(text="",
                                    parent=base.a2dTopLeft,
                                    fg=(1, 1, 1, 1),
                                    shadow=(0, 0, 0, 1),
                                    pos=(0.1, -0.1, 0),
                                    align=TextNode.ALeft)
        self.bsLabel = OnscreenText(text="",
                                    parent=base.a2dTopLeft,
                                    fg=(1, 1, 1, 1),
                                    shadow=(0, 0, 0, 1),
                                    pos=(0.1, -0.2, 0),
                                    align=TextNode.ALeft)
        self.accept('enterMGDeliveryGagShop', self.__maybeDropOffBarrel)
        self.accept('alt', self.__maybeThrowGag)

    def __maybeThrowGag(self):
        if base.localAvatar.hasBarrel:
            return

        self.b_throwPie()

    def b_throwPie(self):
        self.sendUpdate('throwPie', [base.localAvatar.doId])
        self.throwPie(base.localAvatar.doId)

    def throwPie(self, avId):
        toon = self.cr.doId2do.get(avId)
        if toon:
            pie = DeliveryGamePie(toon, self)
            self.pies.append(pie)

    def pieSplat(self, index):
        pie = self.pies[index]
        pie.splat()

    def __maybeDropOffBarrel(self, entry):
        if base.localAvatar.hasBarrel and self.truckBarrelIsFrom != None:
            self.sendUpdate('requestDropOffBarrel', [self.truckBarrelIsFrom])
            self.truckBarrelIsFrom = None

    def __updateLabels(self):
        if self.brLabel:
            self.brLabel.setText("Barrels Remaining: {0}".format(
                self.getBarrelsRemaining()))
        if self.bdLabel:
            self.bdLabel.setText("Barrels Delivered: {0}".format(
                self.getBarrelsDelivered()))
        if self.bsLabel:
            self.bsLabel.setText("Barrels Stolen: {0}".format(
                self.getBarrelsStolen()))

    def exitPlay(self):
        self.ignore('enterMGDeliveryGagShop')
        base.localAvatar.disableAvatarControls()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.setWalkSpeedNormal()
        self.brLabel.destroy()
        self.brLabel = None
        self.bsLabel.destroy()
        self.bsLabel = None
        self.bdLabel.destroy()
        self.bdLabel = None
        DistributedMinigame.exitPlay(self)

    def announceGenerate(self):
        DistributedMinigame.announceGenerate(self)
        self.load()

    def disable(self):
        if self.world:
            self.world.removeNode()
            self.world = None
        if self.gagShop:
            self.gagShop.removeNode()
            self.gagShop = None
        if self.olc:
            self.olc.cleanup()
            self.olc = None
        if self.gagShopCollNP:
            self.gagShopCollNP.removeNode()
            self.gagShopCollNP = None
        self.soundPickUpBarrel = None
        self.soundDropOff = None
        self.truckBarrelIsFrom = None
        if hasattr(base.localAvatar, 'hasBarrel'):
            del base.localAvatar.hasBarrel
        self.barrelsByAvId = None
        DistributedMinigame.disable(self)
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)
Esempio n. 29
0
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()
Esempio n. 30
0
class World(DirectObject.DirectObject):
    def __init__(self):
        self.creeps = None
        self.open = False
        self.sec = 0
        self.min = 0
        self.pindex = 1  # This is the Pause Index
        self.index = -1  # This is the hero Index
        self.rindex = False  # This is the Repick Index
        self.hpicked = []  # This List Stores All The Heroes Picked and Removes Them
        for i in range(0, 110):
            self.hpicked.append(-1)  # Gotta change and check this
        self.hindex = 0  # When a hero is picked this index saves it and stores it in the list
        self.RND = render.attachNewNode("rend")
        self.LightHandler = None
        self.Players()
        self.LoadTerrain()  # Load the Map
        self.SetupCamera()
        self.SetupLight()
        self.SetupEvents()
        self.SetupTimer()
        self.chooseHero()
        self.SetupMap()
        self.SetupCreeps()
        self.SetupCollision()
        self.displayed = False
        self.keyMap = {"cam-left": 0, "cam-right": 0, "cam-up": 0, "cam-down": 0, "zoom-in": 0, "zoom-out": 0}
        self.chatindex = 0
        self.chat = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
        self.text = ["text1", "text2", "text3", "text4", "text5" "text6" "text7" "text8" "text9", "text10", "text11"]
        self.task = None

    def Players(self):
        self.hero1 = None
        self.hero2 = None
        self.hero3 = None
        self.hero4 = None
        self.hero5 = None
        self.hero6 = None
        self.hero7 = None
        self.hero8 = None
        self.hero9 = None
        self.hero10 = None
        self.player1 = None
        self.player2 = None
        self.player3 = None
        self.player4 = None
        self.player5 = None
        self.player6 = None
        self.player7 = None
        self.player8 = None
        self.player9 = None
        self.player10 = None

    def LoadTerrain(self):
        self.terrain = loader.loadModel("models/environment")
        self.terrain.setTag("Map", "1")
        self.terrain.reparentTo(self.RND)
        self.itmpan1 = OnscreenImage(image=MYDIRIMG + "/3.png", scale=(0.3, 0, 0.09), pos=(0.61, 0, -0.915))
        self.itmpan2 = OnscreenImage(image=MYDIRIMG + "/3.png", scale=(0.3, 0, 0.09), pos=(0.61, 0, -0.740))
        self.t2 = OnscreenImage(image=MYDIRIMG + "/t2.png", scale=(0.25, 0, 0.06), pos=(1.160, 0, -0.71))
        self.t1 = OnscreenImage(image=MYDIRIMG + "/t1.png", scale=(0.25, 0, 0.06), pos=(1.160, 0, -0.83))
        self.end = OnscreenImage(image=MYDIRIMG + "/end.png", scale=(0.1, 0, 0.2), pos=(1.510, 0, -0.80))
        self.back = OnscreenImage(image=MYDIRIMG + "/back.png", scale=(0.57, 0, 0.2), pos=(-0.26, 0, -0.80))

    def SetupCollision(self):
        base.cTrav = CollisionTraverser()
        self.collHandler = CollisionHandlerQueue()
        self.pickerNode = CollisionNode("mouseRay")
        self.pickerNP = camera.attachNewNode(self.pickerNode)
        self.pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask())
        self.pickerRay = CollisionRay()
        self.pickerNode.addSolid(self.pickerRay)
        base.cTrav.addCollider(self.pickerNP, self.collHandler)

    def ObjectClick(self):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
        self.pickerRay.setFromLens(base.camNode, mpos.getX(), mpos.getY())
        base.cTrav.traverse(render)  # Assume for simplicity's sake that myHandler is a CollisionHandlerQueue.
        if self.collHandler.getNumEntries() > 0:  # This is so we get the closest object.
            self.collHandler.sortEntries()
            self.pickedObj = self.collHandler.getEntry(0).getIntoNodePath()
            self.pickedObj1 = self.pickedObj.findNetTag("Unit")
            self.pickedObj2 = self.pickedObj.findNetTag("MyHero")
            self.pickedObj3 = self.pickedObj.findNetTag("Map")
            self.pickedObj4 = self.pickedObj.findNetTag("MyHero")
            if self.pickedObj1 == self.creeps.getModel():
                if self.displayed is False:
                    self.displayed = True
                    self.creeps.display()
            else:
                if self.displayed is True:
                    self.displayed = False
                    self.creeps.displaynot()
            if self.hero != None:
                if self.pickedObj2 == self.hero1.getModel():
                    if self.displayed is False:
                        self.displayed = True
                        self.hero1.display()
                else:
                    if self.displayed is True:
                        self.displayed = False
                        self.hero1.displaynot()

    def SetupCamera(self):
        base.camera.setPos(0, 0, 180)
        base.camera.setP(-30)
        base.camera.lookAt(0, 0, 0)

    def SetupTimer(self):
        self.btn = aspect2d.attachNewNode("btn")
        self.btn.setTransparency(1)
        self.timesec = OnscreenText(text="", pos=(1.3, -0.71), fg=(1, 1, 1, 1), mayChange=1, scale=0.05)
        self.timemin = OnscreenText(text="", pos=(1.1, -0.71), fg=(1, 1, 1, 1), mayChange=1, scale=0.05)
        self.pausebtn = DirectButton(
            text="Pause (%d)" % (self.pindex),
            parent=self.btn,
            text_fg=(0, 0.2, 0, 1),
            text_pos=(0.05, -0.15),
            text_scale=(0.48, 0.53),
            image=(MYDIRIMG + "btnof.png", MYDIRIMG + "btnon.png", MYDIRIMG + "btnon.png", None),
            frameColor=(0, 0, 0, 0),
            pos=(-1.0, 0, -0.81),
            image_scale=(1.0, 0, 0.7),
            scale=(0.15, 0, 0.10),
            command=self.Pause,
        )
        self.infobtn = DirectButton(
            text="Info",
            parent=self.btn,
            text_fg=(0, 0.2, 0, 1),
            text_pos=(0.05, -0.15),
            text_scale=0.6,
            image=(MYDIRIMG + "btnof.png", MYDIRIMG + "btnon.png", MYDIRIMG + "btnon.png", None),
            frameColor=(0, 0, 0, 0),
            pos=(-1.0, 0, -0.68),
            image_scale=(1.0, 0, 0.7),
            scale=(0.15, 0, 0.10),
            command=self.Pause,
        )
        taskMgr.doMethodLater(1, self.Timer, "tickTask")

    def SetupMap(self):
        self.minimap = minimap(None)

    def SetupLight(self):
        self.LightHandler = Lights(None)

    def SetupEvents(self):
        self.DEntry = DirectEntry(
            text="",
            pos=(-0.6, 0.0, -0.7),
            image=MYDIRIMG + "/tooltips9.png",
            frameColor=(0, 0, 0, 1),
            width=27,
            image_pos=(13.5, 0, 0.2),
            image_scale=(15, 0, 0.6),
            scale=0.05,
            initialText="",
            numLines=1,
            focus=1,
            command=self.Parser,
        )
        self.DEntry.setTransparency(1)
        self.DEntry.detachNode()
        taskMgr.add(self.MoveCamera, "CameraControl")
        self.accept("enter", self.MsgBox)
        self.accept("wheel_up", self.setKey, ["zoom-in", 1])
        self.accept("wheel_down", self.setKey, ["zoom-out", 1])
        #   self.accept("wheel_up-up",self.setKey, ["zoom-in",0])
        #    self.accept("wheel_down-up",self.setKey, ["zoom-out",0])
        self.accept("a", self.setKey, ["cam-left", 1])
        self.accept("d", self.setKey, ["cam-right", 1])
        self.accept("w", self.setKey, ["cam-up", 1])
        self.accept("s", self.setKey, ["cam-down", 1])
        self.accept("+", self.setKey, ["zoom-in", 1])
        self.accept("-", self.setKey, ["zoom-out", 1])
        self.accept("a-up", self.setKey, ["cam-left", 0])
        self.accept("d-up", self.setKey, ["cam-right", 0])
        self.accept("w-up", self.setKey, ["cam-up", 0])
        self.accept("s-up", self.setKey, ["cam-down", 0])
        self.accept("+-up", self.setKey, ["zoom-in", 0])
        self.accept("--up", self.setKey, ["zoom-out", 0])
        self.accept("mouse1", self.ObjectClick)

    def UnSetupEvents(self):
        self.ignore("a")
        self.ignore("s")
        self.ignore("w")
        self.ignore("s")
        self.ignore("+")
        self.ignore("-")
        self.ignore("enter")
        self.ignore("wheel_up")
        self.ignore("wheel_down")
        taskMgr.remove("CameraControl")

    def setKey(self, key, value):
        self.keyMap[key] = value

    def MoveCamera(self, task):
        mpos = base.mouseWatcherNode.getMouse()
        elapsed = globalClock.getDt()
        self.dt = elapsed
        self.mx = mpos.getX()
        self.my = mpos.getY()
        if self.keyMap["cam-left"] != 0:
            base.camera.setX(base.camera, -(self.dt * 20))
        if self.keyMap["cam-right"] != 0:
            base.camera.setX(base.camera, +(self.dt * 20))
        if self.keyMap["zoom-in"] != 0:
            base.camera.setY(base.camera, -(self.dt * 20))
        if self.keyMap["zoom-out"] != 0:
            base.camera.setY(base.camera, +(self.dt * 20))
        if self.keyMap["cam-down"] != 0:
            base.camera.setZ(base.camera, -(self.dt * 20))
        if self.keyMap["cam-up"] != 0:
            base.camera.setZ(base.camera, +(self.dt * 20))
        if self.mx > 0.95:
            if base.camera.getX() < MAPLIMIT:
                base.camera.setX(base.camera, +(self.dt * SCROLLSPEED))
        if self.mx < -0.95:
            if base.camera.getX() > -MAPLIMIT:
                base.camera.setX(base.camera, -(self.dt * SCROLLSPEED))
        if self.my > 0.95:
            if base.camera.getY() < MAPLIMIT:
                base.camera.setZ(base.camera, +(self.dt * SCROLLSPEED))
        if self.my < -0.95:
            if base.camera.getY() > -MAPLIMIT:
                base.camera.setZ(base.camera, -(self.dt * SCROLLSPEED))
        return task.cont

    def chooseHero(self):
        if self.hero1 == None:
            self.BTNnode = aspect2d.attachNewNode("buttons")
            for i in range(0, 3):
                for j in range(0, 4):
                    self.index += 1
                    if icons[self.index] == None:
                        continue
                    if self.hpicked[self.index] == self.index:
                        continue
                    self.worldHeroButton(-1.8 + j * 0.1, -i * 0.1, self.index)

    def worldHeroButton(self, x, y, arg):
        DirectButton(
            text="",
            parent=self.BTNnode,
            text_font=font,
            image=MYDIRICONS + icons[arg] + ".tga",
            frameColor=(0, 0, 0, 0),
            pad=(-0.1, -0.1),
            image_scale=(IconSx + 0.2, 0, IconSy + 0.2),
            pos=(posx - 0.5 + x, 0, posy + y),
            scale=(0.20, 0, 0.20),
            command=self.SetupHero,
            extraArgs=[arg],
        )

    def SetupCreeps(self):
        self.creeps = Unit1()

    def SetupHero(self, no):
        self.hpicked.insert(self.hindex, no)
        self.hindex += 1
        self.BTNnode.detachNode()
        self.hero1 = Hero(no)
        self.hero1.getModel().setTag("Hero1", "1")

    def Timer(self, task):
        self.task = task
        self.sec += 1
        if self.hero1 != None:
            self.hero1.sendTime(self.min, self.sec)
        if self.sec >= 60:
            self.sec = 0
            self.min += 1
            self.timemin.setText(str(self.min))
        self.timesec.setText(str(self.sec))
        return task.again

    def MsgBox(self):
        if self.open == False:
            self.DEntry.reparentTo(aspect2d)
            self.open = True
        else:
            self.DEntry.detachNode()
            self.open = False

    def Parser(self, text):
        Text = text
        # Within 120 seconds on the game
        if self.hero1 == None:
            self.BTNnode.detachNode()
            if Text == "-random":
                self.hero1 = Hero(random.randint(0, 96))
            elif Text == "-random int":
                self.hero1 = Hero(random.randint(66, 96))
            elif Text == "-random str":
                self.hero1 = Hero(random.randint(0, 36))
            elif Text == "-random agi":
                self.hero1 == Hero(random.randint(36, 66))
        if Text == "-repick":
            if self.rindex == False:
                if self.hero1 != None:
                    self.hero1.destroy()
                    self.hero1 = None
                    self.index = -1
                    self.chooseHero()
                    self.rindex = True
            else:
                Error("Cannot Repick")
        elif Text == "-":
            pass
        else:
            pass

    #      self.Chat(Text,self.task)
    #     taskMgr.add(self.Chat,"nn",extraArgs=[Text])
    # this sends text to allies

    def ChatTimer(self, task, chat, i):
        chat.destroy()
        self.chat.insert(i, 0)
        self.chatindex -= 1
        return task.done

    def Chat(self, text, task):
        for i in range(1, 15):
            if self.chat[i] == 0:
                self.text[i] = OnscreenText(text=text, pos=(-1.3, -0.4), fg=(0, 0, 0, 1), scale=0.07)
                self.chat.insert(self.chatindex, 1)
                taskMgr.doMethodLater(5, self.ChatTimer, "chat", [task, self.text[i], i])
                self.chatindex += 1
                break
            else:
                self.text[i].setY(-(0.1 * i) + 0.4)
        return task.done

    def Pause(self):
        if self.pindex != 0:
            self.pindex -= 1
            time.sleep(2)
            self.pausebtn["text"] = "Pause (%d)" % (self.pindex)
        else:
            Error("Pause Limits Used")

    def destroy(self):
        if self.hero1 != None:
            self.hero1.destroy()
        self.minimap.destroy()
        self.btn.detachNode()
        self.BTNnode.detachNode()
        taskMgr.remove("timer")
        self.terrain.detachNode()
        del self.LightHandler
        del self.creeps
        self.UnSetupEvents()

    def MousePos(self, task):  # This Took me 1.5 Months to Learn
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()
            self.pos3d = Point3()
            self.nearPoint = Point3()
            self.farPoint = Point3()
            base.camLens.extrude(mpos, self.nearPoint, self.farPoint)
        if self.plane.intersectsLine(
            self.pos3d, render.getRelativePoint(camera, self.nearPoint), render.getRelativePoint(camera, self.farPoint)
        ):
            pass
        return task.again
Esempio n. 31
0
class FriendsList(DirectFrame):
    notify = DirectNotifyGlobal.directNotify.newCategory('FriendsList')

    def __init__(self):
        DirectFrame.__init__(self, parent=base.a2dTopRight, pos=(-0.25, 0.0, -0.46))
        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        self['image'] = gui.find('**/FriendsBox_Open')
        self.headingText = OnscreenText(text='', parent=self, pos=(0.01, 0.2), fg=(0.1, 0.1, 0.4, 1.0), scale=0.04)
        self.frameForNames = DirectScrolledList(frameSize=(0.0, 0.35, 0, 0.35), incButton_geom=(gui.find('**/FndsLst_ScrollUp'),
         gui.find('**/FndsLst_ScrollDN'),
         gui.find('**/FndsLst_ScrollUp_Rllvr'),
         gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_hpr=(0, 0, 180), incButton_pos=(0.17, 0, -0.04), decButton_geom=(gui.find('**/FndsLst_ScrollUp'),
         gui.find('**/FndsLst_ScrollDN'),
         gui.find('**/FndsLst_ScrollUp_Rllvr'),
         gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_pos=(0.17, 0, 0.395), pos=(-0.1625, 0.0, -0.27), parent=self, numItemsVisible=9, forceHeight=0.04, itemFrame_frameSize=(-0.15, 0.15, 0, -0.35), itemFrame_pos=(0, 0, 0.3275), itemFrame_relief=None, relief=None)
        self.fwdBtn = 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.17, 0.0, -0.38), command=self.doState)
        self.backBtn = 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.15, 0.0, -0.38), hpr=(180, 0, 0), command=self.doState)
        self.closeBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(), relief=None, parent=self, command=self.exitClicked)
        self.closeBtn.setPos(0.015, 0.0, -0.375)
        gui.removeNode()
        del gui
        self.hide()
        self.friends = {}
        self.onlineFriends = {}
        self.fsm = ClassicFSM.ClassicFSM('FriendsList', [State.State('off', self.enterOff, self.exitOff), State.State('onlineFriendsList', self.enterOnlineFriendsList, self.exitOnlineFriendsList), State.State('allFriendsList', self.enterAllFriendsList, self.exitAllFriendsList)], 'off', 'off')
        self.fsm.enterInitialState()
        self.accept('gotFriendsList', self.handleFriendsList)
        return

    def destroy(self):
        self.ignore('gotFriendsList')
        self.fsm.requestFinalState()
        del self.fsm
        self.headingText.destroy()
        del self.headingText
        self.frameForNames.destroy()
        del self.frameForNames
        self.fwdBtn.destroy()
        del self.fwdBtn
        self.backBtn.destroy()
        del self.backBtn
        self.closeBtn.destroy()
        del self.closeBtn
        del self.friends
        del self.onlineFriends
        DirectFrame.destroy(self)

    def doState(self, state):
        self.fsm.request(state)

    def exitClicked(self):
        self.fsm.request('off')
        base.localAvatar.showFriendButton()

    def setButtons(self, fwd = None, back = None):
        if fwd:
            self.fwdBtn['extraArgs'] = [fwd]
            self.fwdBtn['state'] = DGG.NORMAL
        else:
            self.fwdBtn['extraArgs'] = []
            self.fwdBtn['state'] = DGG.DISABLED
        if back:
            self.backBtn['extraArgs'] = [back]
            self.backBtn['state'] = DGG.NORMAL
        else:
            self.backBtn['extraArgs'] = []
            self.backBtn['state'] = DGG.DISABLED

    def handleFriendsList(self, friendIdArray, nameArray, flags):
        self.friends = {}
        self.onlineFriends = {}
        for i in xrange(len(friendIdArray)):
            avatarId = friendIdArray[i]
            name = nameArray[i]
            self.friends[avatarId] = name
            if flags[i] == 1:
                self.onlineFriends[avatarId] = name

    def enterOff(self):
        self.hide()

    def exitOff(self):
        self.show()

    def addFriend(self, name, avatarId):
        self.frameForNames.addItem(DirectButton(text=name, extraArgs=[avatarId], command=self.friendClicked, scale=0.035, relief=None, text1_bg=textDownColor, text2_bg=textRolloverColor, text_align=TextNode.ALeft))
        return

    def friendClicked(self, avatarId):
        self.fsm.request('off')
        base.localAvatar.panel.makePanel(avatarId)

    def resetAll(self):
        self.headingText.setText('')
        self.frameForNames.removeAndDestroyAllItems()
        self.setButtons(None, None)
        return

    def sortListItems(self):
        self.frameForNames['items'].sort(key=lambda x: x['text'])
        self.frameForNames.refresh()

    def enterAllFriendsList(self):
        self.headingText.setText('All\nFriends')
        for friendId, name in self.friends.items():
            self.addFriend(name, friendId)

        self.sortListItems()
        self.setButtons(None, 'onlineFriendsList')
        return

    def exitAllFriendsList(self):
        self.resetAll()

    def enterOnlineFriendsList(self):
        self.headingText.setText('Online\nFriends')
        for friendId, name in self.onlineFriends.items():
            self.addFriend(name, friendId)

        self.sortListItems()
        self.setButtons('allFriendsList', None)
        return

    def exitOnlineFriendsList(self):
        self.resetAll()
class DistributedCameraShyGame(DistributedMinigame):
    notify = directNotify.newCategory("DistributedCameraShyGame")

    def __init__(self, cr):
        try:
            self.DistributedCameraShyGame_initialized
            return
        except:
            self.DistributedCameraShyGame_initialized = 1
        DistributedMinigame.__init__(self, cr)
        self.headPanels.delete()
        self.headPanels = CameraShyHeadPanels()
        self.fsm.addState(State('countdown', self.enterCountdown, self.exitCountdown, ['play']))
        self.fsm.addState(State('announceGameOver', self.enterAnnounceGameOver, self.exitAnnounceGameOver, ['showWinner']))
        self.fsm.addState(State('showWinner', self.enterShowWinner, self.exitShowWinner, ['gameOver']))
        self.fsm.getStateNamed('waitForOthers').addTransition('countdown')
        self.fsm.getStateNamed('play').addTransition('announceGameOver')
        self.remoteAvatars = []
        self.myRemoteAvatar = None
        self.thisPlayerWinsLbl = None
        self.sky = None
        self.firstPerson = CameraShyFirstPerson(self)
        self.skyUtil = None
        self.pbpText = None

        self.levelLoader = CameraShyLevelLoader()
        self.spawnPoints = []

    def setLevel(self, level):
        self.levelLoader.setLevel(level)

    def generateOtherPlayerGui(self):
        self.headPanels.generateOtherPlayerGui()

    def updateOtherPlayerHead(self, avId, otherAvId, state):
        self.headPanels.updateOtherPlayerHead(avId, otherAvId, state)

    def getPlayByPlayText(self):
        return OnscreenText(text = "", fg = (1, 1, 1, 1), shadow = (0, 0, 0, 1), pos = (0, 0.75))

    def removePlayByPlay(self):
        if self.pbpText:
            taskMgr.remove('DCameraShyGame-removePlayByPlay')
            self.pbpText.destroy()
            self.pbpText = None

    def removePlayByPlayTask(self, task):
        self.removePlayByPlay()
        return Task.done

    def showPlayByPlay(self, situation, avId):
        self.removePlayByPlay()
        av = self.cr.doId2do.get(avId)
        name = av.getName()
        if situation == 0:
            self.pbpText = self.getPlayByPlayText()
            self.pbpText.setText("{0} took a picture of you!".format(name))
        taskMgr.doMethodLater(3.0, self.removePlayByPlayTask, "DCameraShyGame-removePlayByPlay")

    def tookPictureOfMe(self, avId):
        self.headPanels.hideFrames()
        self.firstPerson.stopCameraFlash()
        base.transitions.setFadeColor(1, 1, 1)
        base.transitions.fadeOut(0.1)
        self.showPlayByPlay(0, avId)
        Sequence(Wait(1), Func(self.respawn)).start()

    def respawn(self):
        base.transitions.fadeIn()
        pos, hpr = self.pickSpawnPoint()
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr - (180, 0, 0))
        base.localAvatar.d_broadcastPositionNow()
        Sequence(Wait(0.6), Func(self.headPanels.showFrames), Func(base.transitions.setFadeColor, 0, 0, 0)).start()

    def announceGameOver(self):
        self.fsm.request('announceGameOver')

    def showWinner(self, avId):
        base.transitions.fadeOut()
        Sequence(Wait(0.51), Func(self.fsm.request, 'showWinner', [avId])).start()
        #self.fsm.request('showWinner', [avId])

    def enterGameOver(self, winner, winnerDoId, allPrize):
        try:
            currentCamPos = base.camera.getPos(render)
            currentCamHpr = base.camera.getHpr(render)
            self.firstPerson.reallyEnd()
            base.camera.setPos(currentCamPos)
            base.camera.setHpr(currentCamHpr)
        except:
            pass
        DistributedMinigame.enterGameOver(self, winner, winnerDoId, allPrize)

    def enterShowWinner(self, winnerId):
        self.firstPerson.reallyEnd()
        avatar = self.getRemoteAvatar(winnerId)
        avatar.avatar.loop('neutral')
        avatar.detachCamera()
        self.thisPlayerWinsLbl = OnscreenText(text = "{0} Wins!".format(avatar.avatar.getName()), fg = (1, 1, 1, 1),
            font = CIGlobals.getMinnieFont(), pos = (0, 0.8), scale = 0.1)
        if winnerId == base.localAvatar.doId:
            self.thisPlayerWinsLbl.setText("You Win!")
        base.camera.reparentTo(avatar.avatar)
        base.camera.setPos(0, 7, 3)
        base.camera.setH(180)
        base.transitions.fadeIn()
        Sequence(Wait(0.5), Func(avatar.doWinDance)).start()

    def exitShowWinner(self):
        pass

    def enterAnnounceGameOver(self):
        whistle = base.loadSfx("phase_4/audio/sfx/AA_sound_whistle.ogg")
        base.playSfx(whistle)
        self.gameOverLbl = OnscreenText(text = 'Game Over!', fg = (1, 1, 1, 1), font = CIGlobals.getMinnieFont(), scale = 0.1)
        self.gameOverScaleIval = LerpScaleInterval(
            self.gameOverLbl,
            duration = 1.0,
            scale = 0.1,
            startScale = 0.0,
            blendType = 'easeOut'
        )
        #self.gameOverScaleIval.start()

    def exitAnnounceGameOver(self):
        self.gameOverScaleIval.finish()
        del self.gameOverScaleIval
        self.gameOverLbl.destroy()
        del self.gameOverLbl

    def remoteAvatarTakePicture(self, avId):
        avatar = self.getRemoteAvatar(avId)
        if avatar:
            avatar.takePicture()

    def createRemoteAvatar(self, avId):
        if avId == base.localAvatar.doId:
            self.myRemoteAvatar = RemoteCameraShyAvatar(self, self.cr, avId)
            self.remoteAvatars.append(self.myRemoteAvatar)
        else:
            av = RemoteCameraShyAvatar(self, self.cr, avId)
            av.stand()
            self.remoteAvatars.append(av)

    def getRemoteAvatar(self, avId):
        for avatar in self.remoteAvatars:
            if avatar.avId == avId:
                return avatar

    def allPlayersReady(self):
        self.fsm.request('countdown')

    def enterCountdown(self):
        base.localAvatar.chatInput.disableKeyboardShortcuts()
        base.localAvatar.disableChatInput()
        base.setBackgroundColor(CIGlobals.DefaultBackgroundColor)
        base.render.show()
        self.playMinigameMusic()
        self.countdownLbl = OnscreenText(text = "", fg = (1, 1, 1, 1), font = CIGlobals.getMinnieFont(), scale = 0.1)
        self.countdownTrack = Sequence(
            Func(self.countdownLbl.setText, "5"),
            Wait(1.0),
            Func(self.countdownLbl.setText, "4"),
            Wait(1.0),
            Func(self.countdownLbl.setText, "3"),
            Wait(1.0),
            Func(self.countdownLbl.setText, "2"),
            Wait(1.0),
            Func(self.countdownLbl.setText, "1"),
            Wait(1.0),
            Func(self.fsm.request, "play")
        )
        self.countdownTrack.start()
        self.firstPerson.start()
        self.firstPerson.disableMouse()

    def exitCountdown(self):
        if hasattr(self, 'countdownTrack'):
            self.countdownTrack.pause()
            del self.countdownTrack
        if hasattr(self, 'countdownLbl'):
            self.countdownLbl.destroy()
            del self.countdownLbl

    def enterPlay(self):
        self.createTimer()
        self.firstPerson.reallyStart()

    def exitPlay(self):
        self.firstPerson.end()
        self.firstPerson.enableMouse()
        self.deleteTimer()
        DistributedMinigame.exitPlay(self)

    def createWorld(self):
        self.levelLoader.load()
        self.spawnPoints = self.levelLoader.getSpawnPoints()

    def pickSpawnPoint(self):
        return random.choice(self.spawnPoints)

    def setSpawnPoint(self, index):
        pos, hpr = self.spawnPoints[index]
        base.localAvatar.setPos(pos)
        base.localAvatar.setHpr(hpr)

    def load(self):
        self.createWorld()
        self.setMinigameMusic("phase_6/audio/bgm/GS_Race_SS.ogg")
        self.setDescription("Be the first to take 3 pictures of all the other Toons with your camera. " + \
            "Use WASD to move and the mouse to look around. Press the left mouse button to take a picture. " + \
            "Your camera takes some time to recharge after taking a picture. " + \
            "You know you have a good shot when the view finder is green!")
        self.setWinnerPrize(150)
        self.setLoserPrize(15)
        base.render.hide()
        base.setBackgroundColor(0, 0, 0)
        DistributedMinigame.load(self)

    def announceGenerate(self):
        base.camLens.setMinFov(CIGlobals.GunGameFOV / (4./3.))
        self.load()
        DistributedMinigame.announceGenerate(self)

    def disable(self):
        if self.thisPlayerWinsLbl:
            self.thisPlayerWinsLbl.destroy()
            self.thisPlayerWinsLbl = None
        base.camera.reparentTo(render)
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        if self.myRemoteAvatar:
            self.myRemoteAvatar.cleanup()
            del self.myRemoteAvatar
        self.firstPerson.cleanup()
        del self.firstPerson
        self.levelLoader.unload()
        self.levelLoader.cleanup()
        del self.levelLoader
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4./3.))
        DistributedMinigame.disable(self)
class Introduction(DirectObject, FSM):
    notify = directNotify.newCategory('Introduction')

    def __init__(self):
        DirectObject.__init__(self)
        FSM.__init__(self, self.__class__.__name__)

        self.label = OnscreenText('',
                                  parent=hidden,
                                  font=ToontownGlobals.getMinnieFont(),
                                  fg=Vec4(1, 1, 1, 1),
                                  scale=0.06,
                                  align=TextNode.ACenter,
                                  wordwrap=35)
        self.label.setColorScale(Vec4(0, 0, 0, 0))

        gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui.bam')
        shuffleUp = gui.find('**/tt_t_gui_mat_shuffleUp')
        shuffleDown = gui.find('**/tt_t_gui_mat_shuffleDown')
        okUp = gui.find('**/tt_t_gui_mat_okUp')
        okDown = gui.find('**/tt_t_gui_mat_okDown')
        closeUp = gui.find('**/tt_t_gui_mat_closeUp')
        closeDown = gui.find('**/tt_t_gui_mat_closeDown')
        gui.removeNode()
        del gui

        self.exitButton = DirectButton(
            parent=hidden,
            relief=None,
            image=(shuffleUp, shuffleDown, shuffleUp),
            image_scale=(0.6, 0.6, 0.6),
            image1_scale=(0.63, 0.6, 0.6),
            image2_scale=(0.63, 0.6, 0.6),
            text=(TTLocalizer.IntroExitButton, TTLocalizer.IntroExitButton,
                  TTLocalizer.IntroExitButton, ''),
            text_font=ToontownGlobals.getInterfaceFont(),
            text_scale=TTLocalizer.SBshuffleBtn,
            text_pos=(0, -0.02),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1))

        self.yesButton = DirectButton(
            parent=hidden,
            relief=None,
            image=(okUp, okDown, okUp, okDown),
            image_scale=(0.6, 0.6, 0.6),
            image1_scale=(0.7, 0.7, 0.7),
            image2_scale=(0.7, 0.7, 0.7),
            text=('', TTLocalizer.IntroYesButton, TTLocalizer.IntroYesButton),
            text_font=ToontownGlobals.getInterfaceFont(),
            text_scale=0.08,
            text_align=TextNode.ACenter,
            text_pos=(0, -0.175),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1))
        self.noButton = DirectButton(
            parent=hidden,
            relief=None,
            image=(closeUp, closeDown, closeUp, closeDown),
            image_scale=(0.6, 0.6, 0.6),
            image1_scale=(0.7, 0.7, 0.7),
            image2_scale=(0.7, 0.7, 0.7),
            text=('', TTLocalizer.IntroNoButton, TTLocalizer.IntroNoButton),
            text_font=ToontownGlobals.getInterfaceFont(),
            text_scale=0.08,
            text_align=TextNode.ACenter,
            text_pos=(0, -0.175),
            text_fg=(1, 1, 1, 1),
            text_shadow=(0, 0, 0, 1))

        self.disclaimerTrack = None
        self.presentsTrack = None

    def delete(self):
        if self.presentsTrack is not None:
            self.presentsTrack.finish()
            self.presentsTrack = None

        if self.disclaimerTrack is not None:
            self.disclaimerTrack.finish()
            self.disclaimerTrack = None

        if self.noButton is not None:
            self.noButton.destroy()
            self.noButton = None

        if self.yesButton is not None:
            self.yesButton.destroy()
            self.yesButton = None

        if self.exitButton is not None:
            self.exitButton.destroy()
            self.exitButton = None

        if self.label is not None:
            self.label.destroy()
            self.label = None

    def calcLabelY(self):
        sy = self.label.getScale()[1]
        height = self.label.textNode.getHeight()
        return (height * sy) / 2.0

    def enterOff(self):
        pass

    def enterDisclaimer(self):
        self.label.setText(TTLocalizer.IntroDisclaimer)
        self.label.setPos(0, self.calcLabelY())
        self.label.reparentTo(aspect2d)

        if self.disclaimerTrack is not None:
            self.disclaimerTrack.finish()
            self.disclaimerTrack = None

        self.disclaimerTrack = Sequence(
            LerpColorScaleInterval(self.label,
                                   2,
                                   Vec4(1, 1, 1, 1),
                                   Vec4(0, 0, 0, 0),
                                   blendType='easeIn'),
            Wait(3),
            LerpColorScaleInterval(self.label,
                                   2,
                                   Vec4(0, 0, 0, 0),
                                   Vec4(1, 1, 1, 1),
                                   blendType='easeOut'),
        )
        self.disclaimerTrack.start()

    def exitDisclaimer(self):
        if self.disclaimerTrack is not None:
            self.disclaimerTrack.finish()
            self.disclaimerTrack = None

        self.label.reparentTo(hidden)
        self.label.setPos(0, 0)
        self.label.setText('')

    def enterPresents(self):
        self.label.setText(TTLocalizer.IntroPresents)
        self.label.setPos(0, self.calcLabelY())
        self.label.reparentTo(aspect2d)

        if self.presentsTrack is not None:
            self.presentsTrack.finish()
            self.presentsTrack = None

        self.presentsTrack = Sequence(
            LerpColorScaleInterval(self.label,
                                   2,
                                   Vec4(1, 1, 1, 1),
                                   Vec4(0, 0, 0, 0),
                                   blendType='easeIn'),
            Wait(3),
            LerpColorScaleInterval(self.label,
                                   2,
                                   Vec4(0, 0, 0, 0),
                                   Vec4(1, 1, 1, 1),
                                   blendType='easeOut'),
        )
        self.presentsTrack.start()

    def exitPresents(self):
        if self.presentsTrack is not None:
            self.presentsTrack.finish()
            self.presentsTrack = None

        self.label.reparentTo(hidden)
        self.label.setPos(0, 0)
        self.label.setText('')

    def enterLabel(self, text):
        self.label.setText(text)
        self.label.setPos(0, self.calcLabelY())
        self.label.reparentTo(aspect2d)
        self.label.setColorScale(Vec4(1, 1, 1, 1))

    def exitLabel(self):
        self.label.setColorScale(Vec4(0, 0, 0, 0))
        self.label.reparentTo(hidden)
        self.label.setPos(0, 0)
        self.label.setText('')

    def enterExitDialog(self,
                        text,
                        exitButtonCommand=None,
                        exitButtonExtraArgs=[]):
        self.label.setText(text)

        sy = self.label.getScale()[1]
        bottom = self.label.textNode.getBottom() * sy
        lineHeight = self.label.textNode.getLineHeight() * sy
        self.exitButton.setPos(0, 0, bottom - (lineHeight * 2))
        self.exitButton['command'] = exitButtonCommand
        self.exitButton['extraArgs'] = exitButtonExtraArgs

        labelY = self.calcLabelY()

        self.label.setPos(0, labelY)

        self.exitButton.setZ(self.exitButton, labelY)

        self.exitButton.reparentTo(aspect2d)
        self.label.reparentTo(aspect2d)

        self.label.setColorScale(Vec4(1, 1, 1, 1))

    def exitExitDialog(self):
        self.label.setColorScale(Vec4(0, 0, 0, 0))

        self.label.reparentTo(hidden)
        self.exitButton.reparentTo(hidden)

        self.label.setPos(0, 0)
        self.label.setText('')

        self.exitButton['command'] = None
        self.exitButton['extraArgs'] = []
        self.exitButton.setPos(0, 0, 0)

    def enterYesNoDialog(self,
                         text,
                         yesButtonCommand=None,
                         yesButtonExtraArgs=[],
                         noButtonCommand=None,
                         noButtonExtraArgs=[]):
        self.label.setText(text)

        sy = self.label.getScale()[1]
        bottom = self.label.textNode.getBottom() * sy
        lineHeight = self.label.textNode.getLineHeight() * sy
        self.yesButton.setPos(-0.1, 0, bottom - (lineHeight * 2))
        self.yesButton['command'] = yesButtonCommand
        self.yesButton['extraArgs'] = yesButtonExtraArgs
        self.noButton.setPos(0.1, 0, bottom - (lineHeight * 2))
        self.noButton['command'] = noButtonCommand
        self.noButton['extraArgs'] = noButtonExtraArgs

        labelY = self.calcLabelY()

        self.label.setPos(0, labelY)

        self.yesButton.setZ(self.yesButton, labelY)
        self.noButton.setZ(self.noButton, labelY)

        self.yesButton.reparentTo(aspect2d)
        self.noButton.reparentTo(aspect2d)
        self.label.reparentTo(aspect2d)

        self.label.setColorScale(Vec4(1, 1, 1, 1))

    def exitYesNoDialog(self):
        self.label.setColorScale(Vec4(0, 0, 0, 0))

        self.label.reparentTo(hidden)
        self.noButton.reparentTo(hidden)
        self.yesButton.reparentTo(hidden)

        self.label.setPos(0, 0)
        self.label.setText('')

        self.noButton['command'] = None
        self.noButton['extraArgs'] = []
        self.noButton.setPos(0, 0, 0)
        self.yesButton['command'] = None
        self.yesButton['extraArgs'] = []
        self.yesButton.setPos(0, 0, 0)

    def enterClickToStart(self):
        base.cr.clickToStart.start()

    def exitClickToStart(self):
        base.cr.clickToStart.stop()
Esempio n. 34
0
class PandaTextureViewer(object):
    def __init__(self, mesh_path, progressive_texture_path):

        resolutions = []
        f = tarfile.open(progressive_texture_path)
        for resolution_name in f.getnames():
            toset = {
                'size': resolution_name[:-4],
                'contents': f.extractfile(resolution_name).read()
            }
            texpnm = PNMImage()
            texpnm.read(StringStream(toset['contents']), 'something.jpg')
            newtex = Texture()
            newtex.load(texpnm)
            toset['texture'] = newtex
            resolutions.append(toset)

        self.resolutions = resolutions

        def aux_loader(fname):
            return resolutions[0]['contents']

        mesh = collada.Collada(mesh_path, aux_file_loader=aux_loader)

        scene_members = getSceneMembers(mesh)

        base = ShowBase()

        rotateNode = GeomNode("rotater")
        rotatePath = render.attachNewNode(rotateNode)
        matrix = numpy.identity(4)
        if mesh.assetInfo.upaxis == collada.asset.UP_AXIS.X_UP:
            r = collada.scene.RotateTransform(0, 1, 0, 90)
            matrix = r.matrix
        elif mesh.assetInfo.upaxis == collada.asset.UP_AXIS.Y_UP:
            r = collada.scene.RotateTransform(1, 0, 0, 90)
            matrix = r.matrix
        rotatePath.setMat(Mat4(*matrix.T.flatten().tolist()))

        geom, renderstate, mat4 = scene_members[0]
        node = GeomNode("primitive")
        node.addGeom(geom)
        if renderstate is not None:
            node.setGeomState(0, renderstate)
        self.geomPath = rotatePath.attachNewNode(node)
        self.geomPath.setMat(mat4)

        wrappedNode = ensureCameraAt(self.geomPath, base.camera)
        base.disableMouse()
        attachLights(render)
        render.setShaderAuto()
        render.setTransparency(TransparencyAttrib.MDual, 1)

        base.render.analyze()
        KeyboardMovement()
        MouseDrag(wrappedNode)
        MouseScaleZoom(wrappedNode)
        MouseCamera()

        num_resolutions = len(resolutions) - 1
        self.slider = DirectSlider(range=(0, num_resolutions),
                                   value=0,
                                   pageSize=1,
                                   command=self.sliderMoved,
                                   pos=(0, 0, -.9),
                                   scale=1)
        for key, val in uiArgs.iteritems():
            self.slider.thumb[key] = val

        self.triText = OnscreenText(text="",
                                    pos=(-1, 0.85),
                                    scale=0.15,
                                    fg=(1, 0.5, 0.5, 1),
                                    align=TextNode.ALeft,
                                    mayChange=1)

        base.run()

    def sliderMoved(self):
        sliderVal = int(self.slider['value'])
        #if self.pm_index != sliderVal:
        #    self.movePmTo(sliderVal)
        np = render.find("**/rotater/collada")
        np.setTextureOff(1)
        np.setTexture(self.resolutions[sliderVal]['texture'], 1)
        self.triText.setText('Resolution: %s' %
                             self.resolutions[sliderVal]['size'])
Esempio n. 35
0
class Navigator3D(DirectObject):
    def __init__(self):
        DirectObject.__init__(self)
        self._prev_mouse_location = np.array([
            0.,
            0.,
        ])
        self._prev_mouse_location_pen = None
        self._buttons_state = {}
        self._define_keymap()
        self._update_location_text()
        self.ground = GroundGen(150)
        taskMgr.add(self._update_camera, "updatecamera")

    def _register_keys(self, key_list):
        for key in key_list:
            self._register_key(key)

    def _register_key(self, key):
        assert isinstance(key, str)
        self._buttons_state[key] = False
        self.accept(key + '-up', self._key_up, [key])
        self.accept(key, self._key_down, [key])

    def _define_keymap(self):
        self._register_keys(
            ['control', 'w', 's', 'a', 'd', 'mouse1', 'mouse3', 'alt'])
        self.accept('r', self._reset_view)
        self.accept('t', self._top_view)
        self.accept('c', self._top_view_centered)
        self.accept('wheel_up', lambda: self._zoom('+z'))
        self.accept('wheel_down', lambda: self._zoom('-z'))

    def _reset_view(self):
        base.camera.setPos(0, -10, 3)
        base.camera.setHpr(0, -9, 0)
        self._update_location_text()

    def _top_view(self):
        base.camera.setPos(0, 7, 30)
        base.camera.setHpr(0, -90, 0)
        self._update_location_text()

    def _top_view_centered(self):
        base.camera.setPos(0, 0, 60)
        base.camera.setHpr(0, -90, 0)
        self._update_location_text()

    def _update_location_text(self):
        pos = base.camera.getPos()
        hpr = base.camera.getHpr()
        if 'title' not in dir(self):
            self.title = OnscreenText(text="".format(tuple(pos), tuple(hpr)),
                                      style=1,
                                      fg=(1, 1, 1, 1),
                                      pos=(-0.1, 0.1),
                                      scale=.05,
                                      parent=base.a2dBottomRight,
                                      align=TextNode.ARight)
        self.title.setText(
            "Position: ({:.2f}, {:.2f}, {:.2f})\n Rotation: ({:.2f}, {:.2f}, {:.2f})"
            .format(pos[0], pos[1], pos[2], hpr[0], hpr[1], hpr[2]))

    def _pan_camera(self, movement):
        camera_pos = base.camera.getPos()
        hpr = base.camera.getHpr()
        rot_mat = lambda angle: np.array([[np.cos(angle), -np.sin(
            angle)], [np.sin(angle), np.cos(angle)]])
        movement_vec_xy = np.dot(rot_mat(hpr[0] / 180. * np.pi),
                                 np.array([movement[0], movement[1]]))
        base.camera.setPos(camera_pos[0] + movement_vec_xy[0],
                           camera_pos[1] + movement_vec_xy[1],
                           camera_pos[2] + movement[2])
        self._update_location_text()

    def _pan_camera_mouse(self, movement):
        camera_transform = np.array(base.camera.getNetTransform().getMat())
        pan_vec = np.array([-movement[0], 0, -movement[1],
                            1]).dot(camera_transform)
        base.camera.setPos(pan_vec[0], pan_vec[1], pan_vec[2])
        self._update_location_text()

    def _zoom(self, value):
        if type(value) is str:
            if value == '-z':
                value = -base.camera.getPos()[2]
            if value == '+z':
                value = base.camera.getPos()[2]
        scale = 0.3
        hpr = base.camera.getHpr()
        rotation_angles = np.array((-hpr[1], 0., -hpr[0])) / 180. * np.pi
        rotation = euler_matrix(rotation_angles[2], rotation_angles[1],
                                rotation_angles[0])
        # inverse
        R = rotation.T
        offset = R.dot(np.array([[0., 1., 0.]]).T)

        new_pos = np.array(
            base.camera.getPos()) + offset.ravel() * scale * value
        new_pos[2] = max(new_pos[2], 0.)
        base.camera.setPos(new_pos[0], new_pos[1], new_pos[2])
        self._update_location_text()

    def _key_down(self, key):
        if key == 'mouse1':
            if base.mouseWatcherNode.hasMouse():
                self._buttons_state[key] = True
                self._prev_mouse_location = np.array(
                    base.mouseWatcherNode.getMouse())
        else:
            self._buttons_state[key] = True

    def _key_up(self, key):
        self._buttons_state[key] = False
        if key == 'mouse1' and base.mouseWatcherNode.hasMouse():
            self._prev_mouse_location = np.array(
                base.mouseWatcherNode.getMouse())

    def _update_camera(self, task):
        scale = 0.3
        if 'w' in self._buttons_state and self._buttons_state['w']:
            if 'control' in self._buttons_state and self._buttons_state[
                    'control']:
                self._pan_camera((0., 0., scale))
            elif 'alt' in self._buttons_state and self._buttons_state['alt']:
                self._zoom(1.)
            else:
                self._pan_camera((0., scale, 0.))
        if 's' in self._buttons_state and self._buttons_state['s']:
            if 'control' in self._buttons_state and self._buttons_state[
                    'control']:
                self._pan_camera((0., 0., -scale))
            elif 'alt' in self._buttons_state and self._buttons_state['alt']:
                self._zoom(-1.)
            else:
                self._pan_camera((0., -scale, 0.))
        if 'a' in self._buttons_state and self._buttons_state['a']:
            self._pan_camera((-scale, 0., 0.))
        if 'd' in self._buttons_state and self._buttons_state['d']:
            self._pan_camera((scale, 0., 0.))

        if 'wheel_up' in self._buttons_state and self._buttons_state[
                'wheel_up']:
            self._zoom(2 ^ base.camera.getPos()[2])
        if 'wheel_down' in self._buttons_state and self._buttons_state[
                'wheel_down']:
            self._zoom(-2 ^ base.camera.getPos()[2])

        if 'mouse1' in self._buttons_state and self._buttons_state[
                'mouse1'] and base.mouseWatcherNode.hasMouse():
            mouse_pos = np.array(base.mouseWatcherNode.getMouse())
            if np.linalg.norm(mouse_pos - self._prev_mouse_location) > 1e-2:
                prev_mouse_location = self._prev_mouse_location.copy()
                self._prev_mouse_location = mouse_pos
                diff = mouse_pos - prev_mouse_location
                self._rotate_camera(diff)

        if 'mouse3' in self._buttons_state and self._buttons_state[
                'mouse3'] and base.mouseWatcherNode.hasMouse():
            mouse_pos = np.array(base.mouseWatcherNode.getMouse())
            if self._prev_mouse_location_pen is None or np.linalg.norm(
                    mouse_pos - self._prev_mouse_location_pen) > 1e-2:
                if self._prev_mouse_location_pen is not None:
                    prev_mouse_location = self._prev_mouse_location_pen.copy()
                else:
                    prev_mouse_location = mouse_pos
                self._prev_mouse_location_pen = mouse_pos
                diff = (mouse_pos - prev_mouse_location) * np.clip(
                    base.camera.getPos()[2], 5, 40)
                self._pan_camera_mouse((diff[0], diff[1]))
        else:
            self._prev_mouse_location_pen = None
        return task.cont

    def _rotate_camera(self, diff):
        rotation_scale = 30
        hpr = base.camera.getHpr()
        hpr[0] += diff[0] * rotation_scale
        hpr[1] -= diff[1] * rotation_scale
        base.camera.setHpr(hpr)
        self._update_location_text()