コード例 #1
0
class QuestPoster(DirectFrame):
    notify = directNotify.newCategory('QuestPoster')

    # We need to declare and initialize these variables here
    # because some methods use them as default arguments.
    auxIcon = None

    # Requires one parameter, quest, this must be a Quest instance.
    # The next argument, parent, is where to reparent the DirectFrame to.
    # The next arguments are simply additional options when setting up the DirectFrame.
    def __init__(self, quest, parent=aspect2d, **kw):
        # The quest this poster is representing.
        self.quest = quest
        self.accessibleObjectives = quest.accessibleObjectives if quest else []
        self.viewObjective = quest.accessibleObjectives.seek(
        ) if quest else None

        isObjComplete = False if not quest else (
            self.accessibleObjectives.isComplete() or quest.isComplete())

        # Let's define our options for the DirectFrame.
        bookModel = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')
        optiondefs = (('relief', None,
                       None), ('image', bookModel.find('**/questCard'),
                               None), ('image_scale', (0.8, 1.0, 0.58), None),
                      ('image_color', (1.0, 1.0, 1.0,
                                       1.0) if not isObjComplete else Vec4(
                                           *QuestGlobals.LIGHT_GREEN),
                       None), ('state', DGG.NORMAL, None))
        self.defineoptions(kw, optiondefs)

        # Finally, initialize the DirectFrame.
        DirectFrame.__init__(self, parent, relief=None)
        self.initialiseoptions(QuestPoster)

        # Let's declare and initialize our barebone GUI element variables.
        questTitle = '' if not self.quest else self.quest.name
        self.titleLabel = DirectLabel(parent=self,
                                      relief=None,
                                      text=questTitle,
                                      text_font=CIGlobals.getMinnieFont(),
                                      text_fg=QuestGlobals.TEXT_COLOR,
                                      text_scale=0.05,
                                      text_align=TextNode.ACenter,
                                      text_wordwrap=25.0,
                                      textMayChange=1,
                                      pos=(0, 0, 0.23))

        ##########################################################################
        #           THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER            #
        ##########################################################################

        # The background frame where the objective image is displayed.
        # This is the colored background frame.

        circleGui = loader.loadModel(
            'phase_4/models/gui/CircleIconBackgroundGui.bam')
        self.auxFrame = DirectFrame(
            parent=self,
            relief=None,
            image=circleGui.find('**/circle_display_interior'),
            image_scale=0.18,
            text='',
            text_pos=(0, -0.11),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=11.0,
            pos=QuestGlobals.DEFAULT_LEFT_PICTURE_POS)

        if self.quest and len(
                self.quest.accessibleObjectives) > 1 and not isObjComplete:
            # We can only use arrows when we have more than one objective available.
            arrowGui = loader.loadModel('phase_4/models/gui/QuestArrowGui.bam')
            self.prevObjArrow = DirectButton(
                parent=self.auxFrame,
                relief=None,
                geom=((arrowGui.find('**/quest_arrow_enabled'),
                       arrowGui.find('**/quest_arrow_click'),
                       arrowGui.find('**/quest_arrow_mouseover'),
                       arrowGui.find('**/quest_arrow_disabled'))),
                scale=0.08,
                command=self.switchObjective,
                extraArgs=[0],
                hpr=(180, 0, 0),
                pos=QuestGlobals.DEFAULT_LEFT_ARROW_POS)

            self.nextObjArrow = DirectButton(
                parent=self.auxFrame,
                relief=None,
                geom=((arrowGui.find('**/quest_arrow_enabled'),
                       arrowGui.find('**/quest_arrow_click'),
                       arrowGui.find('**/quest_arrow_mouseover'),
                       arrowGui.find('**/quest_arrow_disabled'))),
                scale=0.08,
                command=self.switchObjective,
                pos=QuestGlobals.DEFAULT_RIGHT_ARROW_POS)

        # The icon that goes on top of the aux frame.
        self.auxIcon = DirectFrame(parent=self.auxFrame,
                                   relief=None,
                                   text=' ',
                                   text_font=CIGlobals.getSuitFont(),
                                   text_pos=(0, -0.03),
                                   text_fg=QuestGlobals.TEXT_COLOR,
                                   text_scale=0.13,
                                   text_align=TextNode.ACenter,
                                   text_wordwrap=13.0,
                                   textMayChange=1)
        self.auxIcon.setColorOff(-1)

        self.auxOutline = DirectLabel(
            parent=self.auxFrame,
            relief=None,
            image=circleGui.find('**/circle_display_outline'),
            image_scale=0.18)

        # The aux text saying: DEFEAT, RECOVER, etc.
        self.auxText = DirectLabel(parent=self,
                                   relief=None,
                                   text=QuestGlobals.RECOVER,
                                   text_font=CIGlobals.getToonFont(),
                                   text_scale=QuestGlobals.QPauxText,
                                   text_fg=QuestGlobals.TEXT_COLOR,
                                   text_align=TextNode.ACenter,
                                   textMayChange=1,
                                   pos=QuestGlobals.DEFAULT_AUX_POS)
        self.auxText.hide()

        ##########################################################################

        # Information displayed about the objective.
        self.objectiveInfo = DirectLabel(
            parent=self,
            relief=None,
            text='',
            text_font=CIGlobals.getToonFont(),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=0.04,
            text_align=TextNode.ACenter,
            text_wordwrap=QuestGlobals.QPtextWordwrap,
            textMayChange=1,
            pos=(QuestGlobals.DEFAULT_INFO_POS))
        self.objectiveInfo.hide()

        # Information displayed showing the location.
        self.locationInfo = DirectLabel(
            parent=self,
            relief=None,
            text='N/A',
            text_font=CIGlobals.getToonFont(),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=QuestGlobals.QPtextWordwrap,
            textMayChange=1,
            pos=(0, 0, -0.115))
        self.locationInfo.hide()

        # The progress bar showing the objective's progress
        self.progressBar = DirectWaitBar(parent=self,
                                         relief=DGG.SUNKEN,
                                         frameSize=(-0.95, 0.95, -0.1, 0.12),
                                         borderWidth=(0.025, 0.025),
                                         scale=0.2,
                                         frameColor=(0.945, 0.875, 0.706, 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),
                                         pos=(0, 0, -0.2425))
        self.progressBar.hide()

        # The wood panel at the bottom where rewards are displayed.
        rewardFrameGeom = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        self.rewardFrame = DirectFrame(
            parent=self,
            relief=None,
            geom=rewardFrameGeom.find('**/Goofys_Sign'),
            geom_scale=(0.62, 0, 0.4),
            pos=(-0.015, 0, -0.25))

        # Let's setup our reward frames.
        reward = None

        if self.quest and len(self.quest.rewards) > 0:
            reward = self.quest.rewards[0]
        self.lReward = QuestRewardFrame(self, reward)

        # The text displayed on the right side of the frame with additional information, if necessary.
        self.sideInfo = DirectLabel(parent=self,
                                    relief=None,
                                    text=QuestGlobals.JUST_FOR_FUN,
                                    text_fg=(0.0, 0.439, 1.0, 1.0),
                                    text_shadow=(0, 0, 0, 1),
                                    pos=(-0.2825, 0, 0.2),
                                    scale=0.03)
        self.sideInfo.setR(-30)

        # This side information is usually not needed, let's hide it.
        self.sideInfo.hide()

        # Remove the nodes of the loaded models we no longer need.
        circleGui.removeNode()
        bookModel.removeNode()
        rewardFrameGeom.removeNode()

        # We are only removing this node if we generated arrows.
        if hasattr(self, 'arrowGui'):
            arrowGui.removeNode()

        # Let's hide this until it is needed.
        self.hide()
        return

    def switchObjective(self, forward=1):
        if forward:
            self.accessibleObjectives.nextObjective()
        else:
            self.accessibleObjectives.lastObjective()
        self.viewObjective = self.accessibleObjectives.seek()
        self.setup()

    def setup(self):
        if self.quest:
            objective = self.viewObjective
            complete = self.accessibleObjectives.isComplete()

            # Let's reset our positioning of elements.
            self.auxFrame.setPos(QuestGlobals.DEFAULT_LEFT_PICTURE_POS)
            self.auxText.setPos(QuestGlobals.DEFAULT_AUX_POS)
            self.objectiveInfo.setPos(QuestGlobals.DEFAULT_INFO_POS)

            # Let's reset our icon.
            self.auxIcon.setScale(1, 1, 1)
            self.auxIcon.setPos(0, 0, 0)
            self.auxIcon.setHpr(0, 0, 0)

            self.objectiveInfo.show()
            self.auxFrame.show()

            # Let's setup the quest progress bar
            progress = objective.progress if hasattr(objective,
                                                     'progress') else None

            if objective.goal > 1:
                self.progressBar['range'] = objective.goal
                self.progressBar['value'] = progress & pow(2, 16) - 1

            if objective.HasProgress and objective.goal > 1 and not complete:
                self.progressBar.show()

            self.auxText.show()

            # Let's handle the objectives.
            if not complete:
                if objective.__class__ == CogObjective:
                    self.handleCogObjective()
                elif objective.__class__ == CogBuildingObjective:
                    self.handleCogBuildingObjective()
                elif objective.__class__ == MinigameObjective:
                    self.handleMinigameObjective()
                elif objective.__class__ == VisitNPCObjective:
                    self.handleNPCObjective()
            else:
                bgColor = QuestGlobals.RED

                if objective.type in DefeatObjectives:
                    bgColor = QuestGlobals.BLUE

                self.handleNPCObjective(auxText=QuestGlobals.RETURN + ' to',
                                        frameColor=bgColor)

            self.lReward.setup()

            newLineInObjInfo = '\n' in self.objectiveInfo['text']
            isShopLoc = QuestGlobals.isShopLocation(
                objective.area) if not complete else True

            if complete:
                locationText = QuestGlobals.getLocationText(None, objective)
            else:
                locationText = QuestGlobals.getLocationText(objective.area)

            self.locationInfo['text'] = locationText
            self.locationInfo['text_pos'] = (0.0, (0.025 if isShopLoc else (
                -0.025 if newLineInObjInfo else 0.0)))
            self.locationInfo.show()
        else:
            # We want to be able to show empty quest posters.
            self.titleLabel.hide()
            self.auxFrame.hide()
            self.auxIcon.hide()

        self.titleLabel.initialiseoptions(DirectLabel)
        self.auxIcon.initialiseoptions(DirectFrame)
        self.auxText.initialiseoptions(DirectLabel)
        self.objectiveInfo.initialiseoptions(DirectLabel)
        self.locationInfo.initialiseoptions(DirectLabel)
        self.rewardFrame.initialiseoptions(DirectFrame)
        self.sideInfo.initialiseoptions(DirectLabel)
        self.lReward.initialiseoptions(DirectFrame)

        # Handle arrow stuff if necessary.
        if hasattr(self, 'prevObjArrow'):
            index = self.accessibleObjectives.seeker
            self.prevObjArrow['state'] = DGG.NORMAL
            self.nextObjArrow['state'] = DGG.NORMAL
            self.prevObjArrow.setPos(QuestGlobals.DEFAULT_LEFT_ARROW_POS)
            self.nextObjArrow.setPos(QuestGlobals.DEFAULT_RIGHT_ARROW_POS)

            if index == 0:
                self.prevObjArrow['state'] = DGG.DISABLED
            elif index == len(self.accessibleObjectives) - 1:
                self.nextObjArrow['state'] = DGG.DISABLED

            self.prevObjArrow.initialiseoptions(DirectButton)
            self.nextObjArrow.initialiseoptions(DirectButton)

    # Changes geometry and scale of an icon.
    def handleSimpleIcon(self, geom, scale, icon):
        icon['geom'] = geom
        icon['geom_scale'] = scale

    def handleComplexIcon(self,
                          geom,
                          icon,
                          scale=QuestGlobals.IMAGE_SCALE_SMALL):
        geom.setDepthWrite(1)
        geom.setDepthTest(1)
        self.fitGeometry(geom, fFlip=1)
        self.handleSimpleIcon(geom, scale, icon)

        # We have to rotate the head and set the scale of the icon.
        if CIGlobals.Suit in geom.getName():
            cogName = geom.getPythonTag('Settings')
            data = QuestGlobals.Suit2PosterZNDScale.get(cogName)
            zOffset = data[0]
            headScale = data[1]
            icon.setScale(headScale)
            icon.setZ(icon.getZ() + zOffset)
            icon.setH(180)
        else:
            icon.setZ(icon.getZ() - 0.01)

    def handleCogObjective(self,
                           iconElement=auxIcon,
                           auxText=QuestGlobals.DEFEAT,
                           frameColor=QuestGlobals.BLUE):
        objective = self.viewObjective
        infoText = objective.getTaskInfo()

        if objective.__class__ == RecoverItemObjective:
            infoText = CIGlobals.makePlural(objective.cog)

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the CogObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, CogObjective):
            return

        if objective.dept:
            icons = loader.loadModel('phase_3/models/gui/cog_icons.bam')
            deptIcon = None

            if objective.dept == Dept.BOSS:
                deptIcon = icons.find('**/CorpIcon')
            else:
                deptIcon = icons.find('**/%sIcon' %
                                      objective.dept.getTie().title())

            # Correct the medallion color.
            deptIcon.setColor(SuitGlobals.medallionColors[objective.dept])

            # Setup the icon and remove the icons node.
            self.handleSimpleIcon(deptIcon, 0.13, iconElement)
            icons.removeNode()
        elif objective.cog == QuestGlobals.Any:
            # We aren't fighting a Cog in particular.
            cogIcon = QuestGlobals.getCogIcon()
            self.handleSimpleIcon(cogIcon, 0.13, iconElement)

        # We're fighting a Cog in particular.
        if not objective.cog == QuestGlobals.Any:
            cogHeadInstance = SuitBank.getSuitByName(objective.cog).getHead()
            cogHead = cogHeadInstance.generate()
            cogHead.setName('%sHead' % CIGlobals.Suit)
            cogHead.setPythonTag('Settings', cogHeadInstance.head)
            cogHead.setScale(2)
            cogHead.setLightOff()
            self.handleComplexIcon(cogHead, iconElement)

            # HACK FIX: Corrects the buggy Flunky glasses.
            glasses = cogHead.find('**/glasses')
            if glasses and not glasses.isEmpty():
                glasses.setScale(1)
                glasses.reparentTo(cogHead)

        if not iconElement is self.auxIcon:
            if hasattr(self, 'goalInfo'):
                # We're working with the second frame, on the right.
                # Let's update the information pertaining to this side.
                self.goalInfo['text'] = infoText
                self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS)
                self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS)
            else:
                raise AttributeError(
                    'Attempted to setup DoubleFrame information for poster using default style.'
                )
        else:
            self.objectiveInfo['text'] = infoText

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        self.auxText['text'] = auxText

        # Let's set the color of the poster.
        frame = self.auxFrame if iconElement is self.auxIcon else self.goalFrame
        frame['image_color'] = Vec4(*frameColor)

    def handleCogBuildingObjective(self,
                                   iconElement=auxIcon,
                                   auxText=QuestGlobals.DEFEAT,
                                   frameColor=QuestGlobals.BLUE):
        objective = self.viewObjective
        infoText = objective.getTaskInfo()

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the CogBuildingObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, CogBuildingObjective):
            return

        # If we aren't looking for any specific department of building.
        if objective.dept == QuestGlobals.Any:
            # Let's just use the good ol' generic building icon.
            self.handleSimpleIcon(QuestGlobals.getCogBuildingIcon(),
                                  QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement)
        else:
            # Ah geez, we're looking for a specific department.
            # Bossbot tie names are messed up, so we need this if statement.
            dept = objective.dept.getTie(
            ) if not objective.dept == Dept.BOSS else 'corp'
            bldgMdl = loader.loadModel(
                'phase_4/models/modules/suit_landmark_%s.bam' % dept)

            # Next, we need to load the building elevator.
            elevator = loader.loadModel('phase_4/models/modules/elevator.bam')
            elevator.reparentTo(bldgMdl.find('**/*_door_origin'))

            self.handleComplexIcon(bldgMdl, iconElement)

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        self.objectiveInfo['text'] = infoText
        self.auxText['text'] = auxText
        self.auxFrame['image_color'] = Vec4(*frameColor)

    def handleMinigameObjective(self,
                                iconElement=auxIcon,
                                auxText=QuestGlobals.PLAY,
                                frameColor=QuestGlobals.RED):
        objective = self.viewObjective
        infoText = objective.getTaskInfo()

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the MinigameObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, MinigameObjective):
            return

        # Let's set the icon to the minigame icon.
        self.handleSimpleIcon(QuestGlobals.getTrolleyIcon(),
                              QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement)

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        self.objectiveInfo['text'] = infoText
        self.auxText['text'] = auxText
        self.auxFrame['image_color'] = Vec4(*frameColor)

    def handleNPCObjective(self,
                           iconElement=auxIcon,
                           auxText=QuestGlobals.VISIT,
                           frameColor=QuestGlobals.BROWN):
        objective = self.viewObjective
        npcId = 0

        if self.accessibleObjectives.isComplete() and not hasattr(
                objective, 'npcId'):
            npcId = objective.assigner
        elif hasattr(objective, 'npcId'):
            npcId = objective.npcId

        if npcId == 0:
            infoText = 'A %s' % NPCGlobals.lHQOfficerF
        else:
            infoText = NPCGlobals.NPCToonNames[npcId]

        if not iconElement:
            iconElement = self.auxIcon

        # Let's generate the head.
        if not npcId == 0:
            dna = ToonDNA()
            dna.setDNAStrand(NPCGlobals.NPCToonDict.get(npcId)[2])
            head = ToonGlobals.generateGuiHead(dna)
            self.handleComplexIcon(head,
                                   iconElement,
                                   scale=QuestGlobals.IMAGE_SCALE_SMALL - 0.01)
        else:
            self.handleSimpleIcon(QuestGlobals.getHQIcon(),
                                  QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement)

        self.auxText['text'] = auxText

        if not iconElement is self.auxIcon:
            if hasattr(self, 'goalInfo'):
                # We're working with the second frame, on the right.
                # Let's update the information pertaining to this side.
                self.goalInfo['text'] = infoText
                self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS)
                self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS)
                self.goalFrame['image_color'] = frameColor
            else:
                raise AttributeError(
                    'Attempted to setup DoubleFrame information for poster using default style.'
                )
        else:
            self.objectiveInfo['text'] = infoText
            self.auxFrame['image_color'] = frameColor

    def fitGeometry(self, geom, fFlip=0, dimension=0.8):
        p1 = Point3()
        p2 = Point3()
        geom.calcTightBounds(p1, p2)
        if fFlip:
            t = p1[0]
            p1.setX(-p2[0])
            p2.setX(-t)
        d = p2 - p1
        biggest = max(d[0], d[2])
        s = dimension / biggest
        mid = (p1 + d / 2.0) * s
        geomXform = hidden.attachNewNode('geomXform')
        for child in geom.getChildren():
            child.reparentTo(geomXform)

        geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s,
                                 s, s)
        geomXform.reparentTo(geom)

    def destroy(self):
        if hasattr(self, 'titleLabel'):
            self.titleLabel.destroy()
            self.auxFrame.destroy()
            self.auxIcon.destroy()
            self.auxOutline.destroy()
            self.auxText.destroy()
            self.objectiveInfo.destroy()
            self.locationInfo.destroy()
            self.progressBar.destroy()
            self.rewardFrame.destroy()
            self.sideInfo.destroy()
            self.lReward.destroy()

            # We need to cleanup our arrows if they were created.
            if hasattr(self, 'prevObjArrow'):
                self.prevObjArrow.destroy()
                self.nextObjArrow.destroy()
                del self.prevObjArrow
                del self.nextObjArrow

            del self.titleLabel
            del self.auxFrame
            del self.auxIcon
            del self.auxOutline
            del self.auxText
            del self.objectiveInfo
            del self.locationInfo
            del self.progressBar
            del self.rewardFrame
            del self.sideInfo
            del self.lReward
            del self.accessibleObjectives
            del self.viewObjective
            DirectFrame.destroy(self)
            self.notify.debug('Destroyed all elements.')
コード例 #2
0
class QuestPoster(DirectFrame):
    notify = directNotify.newCategory('QuestPoster')

    def __init__(self, quest, parent = aspect2d, **kw):
        self.quest = quest

        # Let's begin building the quest poster.
        bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui.bam')
        questCard = bookModel.find('**/questCard')
        optiondefs = (('relief', None, None),
         ('image', questCard, None),
         ('image_scale', (0.8, 1.0, 0.58), None),
         ('state', DGG.NORMAL, None))
        self.defineoptions(kw, optiondefs)
        DirectFrame.__init__(self, relief = None)
        self.initialiseoptions(QuestPoster)

        self.questFrame = DirectFrame(parent = self, relief = None)

        # Quest title text
        self.headline = DirectLabel(parent = self.questFrame, relief = None,
            text = self.quest.getName(),
            text_font = CIGlobals.getMinnieFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.05,
            text_align = TextNode.ACenter,
            text_wordwrap = 25.0, textMayChange = 1,
        pos = (0, 0, 0.23))

        # Quest information
        self.questInfo = DirectLabel(parent = self.questFrame, relief = None,
            text = '',
            text_font = CIGlobals.getToonFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.04,
            text_align = TextNode.ACenter,
            text_wordwrap = TEXT_WORDWRAP,
            textMayChange = 1,
        pos = (QuestGlobals.DEFAULT_INFO_POS))
        self.questInfo.hide()

        self.questInfo02 = DirectLabel(parent = self.questFrame, relief = None,
            text = '',
            text_font = CIGlobals.getToonFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.04,
            text_align = TextNode.ACenter,
            text_wordwrap = TEXT_WORDWRAP,
            textMayChange = 1,
        pos = (QuestGlobals.DEFAULT_INFO2_POS))
        self.questInfo02.hide()

        self.locationInfo = DirectLabel(parent = self.questFrame, relief = None,
            text = 'N/A',
            text_font = CIGlobals.getToonFont(),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = TEXT_SCALE,
            text_align = TextNode.ACenter,
            text_wordwrap = TEXT_WORDWRAP,
            textMayChange = 1,
        pos = (0, 0, -0.115))
        self.locationInfo.hide()

        # C'mon Brian this one is obvious
        self.rewardText = DirectLabel(parent = self.questFrame, relief = None,
            text = '',
            text_fg = QuestGlobals.REWARD_RED,
            text_scale = 0.0425,
            text_align = TextNode.ALeft,
            text_wordwrap = 17.0,
            textMayChange = 1,
        pos = (-0.36, 0, -0.26))
        self.rewardText.hide()

        self.lPictureFrame = DirectFrame(parent = self.questFrame, relief = None,
            image = bookModel.find('**/questPictureFrame'),
            image_scale = QuestGlobals.IMAGE_SCALE_SMALL,
            text = '',
            text_pos = (0, -0.11),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = TEXT_SCALE,
            text_align = TextNode.ACenter,
            text_wordwrap = 11.0,
            pos = (QuestGlobals.DEFAULT_LEFT_PICTURE_POS),
        textMayChange = 1)
        self.lPictureFrame.hide()

        self.rPictureFrame = DirectFrame(parent = self.questFrame, relief = None,
            image = bookModel.find('**/questPictureFrame'),
            image_scale = QuestGlobals.IMAGE_SCALE_SMALL,
            text = '', text_pos = (0, -0.11),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = TEXT_SCALE,
            text_align = TextNode.ACenter,
            text_wordwrap = 11.0,
            textMayChange = 1,
        pos = (QuestGlobals.DEFAULT_RIGHT_PICTURE_POS))
        self.rPictureFrame['image_color'] = Vec4(*QuestGlobals.GREEN)
        self.rPictureFrame.hide()

        self.lQuestIcon = DirectFrame(parent = self.lPictureFrame, relief = None,
            text = ' ', text_font = CIGlobals.getSuitFont(),
            text_pos = (0, -0.03),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.13,
            text_align = TextNode.ACenter,
            text_wordwrap = 13.0,
        textMayChange = 1)
        self.lQuestIcon.setColorOff(-1)

        self.rQuestIcon = DirectFrame(parent = self.rPictureFrame, relief = None,
            text = ' ',
            text_font = CIGlobals.getSuitFont(),
            text_pos = (0, -0.03),
            text_fg = QuestGlobals.TEXT_COLOR,
            text_scale = 0.13,
            text_align = TextNode.ACenter,
            text_wordwrap = 13.0,
        textMayChange = 1)
        self.rQuestIcon.setColorOff(-1)

        head = SuitBank.PennyPincher.getHead().generate()
        head.setDepthTest(True)
        head.setDepthWrite(True)
        head.setScale(0.25)
        for part in head.getChildren():
            part.setDepthTest(True)
            part.setDepthWrite(True)
        self.fitGeometry(head, fFlip = 1)
        self.rQuestIcon['geom'] = head
        self.rQuestIcon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL
        self.rQuestIcon['geom_pos'] = Point3(0, 10, -0.05)
        self.rQuestIcon['geom_hpr'] = Point3(180, 0, 0)
        self.rQuestIcon.initialiseoptions(DirectFrame)

        self.auxText = DirectLabel(parent = self.questFrame, relief = None,
            text = 'Recover',
            text_font = CIGlobals.getToonFont(),
            text_scale = QuestGlobals.QPauxText,
            text_fg = QuestGlobals.TEXT_COLOR,
            text_align = TextNode.ACenter,
            pos = (QuestGlobals.DEFAULT_AUX_POS),
        textMayChange=1)
        self.auxText.hide()

        self.middleText = DirectLabel(parent = self.questFrame, relief = None,
            text = 'from:',
            text_font = CIGlobals.getToonFont(),
            text_scale = QuestGlobals.QPauxText,
            text_fg = QuestGlobals.TEXT_COLOR,
            text_align = TextNode.ACenter,
            pos = (QuestGlobals.DEFAULT_MIDDLE_POS),
        textMayChange=1)
        self.middleText.hide()

        self.questProgress = DirectWaitBar(parent = self.questFrame, relief = DGG.SUNKEN,
            frameSize=(-0.95, 0.95, -0.1, 0.12),
            borderWidth = (0.025, 0.025),
            scale = 0.2,
            frameColor = (0.945, 0.875, 0.706, 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 = (0, 0, -0.2425))
        self.questProgress.hide()

        rewardFrameGeom = loader.loadModel('phase_4/models/gui/gag_shop_purchase_gui.bam')
        self.rewardFrame = DirectFrame(parent = self.questFrame, relief = None,
            geom = rewardFrameGeom.find('**/Goofys_Sign'),
            geom_scale = (0.615, 0, 0.4),
            pos = (-0.01, 0, -0.25)
        )

        jellybeanJar = QuestGlobals.getFilmIcon()
        self.lRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None,
            geom = jellybeanJar,
            geom_scale = QuestGlobals.TP_ACCESS_SCALE,
            sortOrder = 1,
        pos = (QuestGlobals.LEFT_TP_ACCESS_POS))
        self.lRewardFrame.setBin('gui-popup', 30)

        self.lRewardAmt = DirectFrame(parent = self.questFrame, relief = None,
            geom = rewardFrameGeom.find('**/Char_Pnl'),
            geom_scale = (0.15, 0, 0.1275),
            text = '#1',
            text_font = CIGlobals.getToonFont(),
            text_scale = 0.04,
            text_fg = (0, 0, 0, 1),
            text_align = TextNode.ACenter,
            text_pos = (0, -0.01),
            sortOrder = 2,
        pos = (-0.285, 0, -0.255))
        self.lRewardAmt.setBin('gui-popup', 40)

        self.rRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None,
            geom = QuestGlobals.getJBIcon(),
            geom_scale = QuestGlobals.JB_JAR_SCALE,
        pos = QuestGlobals.RIGHT_JB_JAR_POS)

        self.rRewardAmt = DirectFrame(parent = self.questFrame, relief = None,
            geom = rewardFrameGeom.find('**/Char_Pnl'),
            geom_scale = (0.15, 0, 0.1275),
            text = '25',
            text_font = CIGlobals.getToonFont(),
            text_scale = 0.04,
            text_fg = (0, 0, 0, 1),
            text_align = TextNode.ACenter,
            text_pos = (0, -0.01),
        pos = (0.2725, 0, -0.255))
        self.rRewardAmt.setBin('gui-popup', 40)

        rewardFrameGeom.removeNode()

        # This is the rotated text on the side.
        self.sideInfo = DirectLabel(parent = self.questFrame, relief = None,
            text = QuestGlobals.JUST_FOR_FUN,
            text_fg = (0.0, 0.439, 1.0, 1.0),
            text_shadow = (0, 0, 0, 1),
            pos = (-0.2825, 0, 0.2),
        scale = 0.03)
        self.sideInfo.setR(-30)
        self.sideInfo.hide()

        bookModel.removeNode()
        self.laffMeter = None
        
        self.hide()
        return
    
    def handleIcon(self, objective, geom, scale, icon):
        isHead = True if type(geom) == ToonHead else geom.getName() == ('%sHead' % CIGlobals.Suit)

        if isHead:
            geom.setDepthWrite(1)
            geom.setDepthTest(1)
            self.fitGeometry(geom, fFlip = 1)
            
            if isinstance(objective, VisitNPCObjective) and icon == self.rQuestIcon:
                icon.setPos(icon.getX(), icon.getY(), icon.getZ() + 0.05)
                icon.setH(180)
            elif isinstance(objective, CogObjective):
                icon.setScale(QuestGlobals.IMAGE_SCALE_SMALL)
                icon.setPos(icon.getX(), icon.getY(), icon.getZ() - 0.04)
                if icon == self.lQuestIcon:
                    icon.setH(180)
            
            icon['geom'] = geom
            icon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL
        else:
            icon['geom'] = geom
            icon['geom_scale'] = scale

    def update(self):
        objective = self.quest.getCurrentObjective()
        objective.updateInfo()

        # Let's setup the quest info.
        self.questInfo.setPos(self.quest.getInfoPos())
        self.questInfo['text'] = self.quest.getInfoText()
        self.questInfo02.setPos(self.quest.getInfo02Pos())
        self.questInfo02['text'] = self.quest.getInfo02Text()
        
        # Let's move the picture frames to the positions we want them in.
        self.lPictureFrame.setPos(self.quest.getLeftPicturePos())
        self.rPictureFrame.setPos(self.quest.getRightPicturePos())
        
        editLeftAtr = isinstance(objective, VisitNPCObjective) or isinstance(objective, CogObjective)
        if editLeftAtr and objective.getDidEditLeft() or not editLeftAtr:
            geom = self.quest.getLeftIconGeom()
            scale = self.quest.getLeftIconScale()
            icon = self.lQuestIcon
            self.handleIcon(objective, geom, scale, icon)
            self.handleIcon(objective, self.quest.getRightIconGeom(), self.quest.getRightIconScale(), self.rQuestIcon)
        else:
            geom = self.quest.getRightIconGeom()
            scale = self.quest.getRightIconScale()
            icon = self.rQuestIcon
            self.handleIcon(objective, geom, scale, icon)
            self.handleIcon(objective, self.quest.getLeftIconGeom(), self.quest.getLeftIconScale(), self.lQuestIcon)

        if self.questInfo02['text'] == '':
            self.rPictureFrame.hide()
            self.questInfo02.hide()
        else:
            self.rPictureFrame.show()
            self.questInfo02.show()

        self.middleText['text'] = self.quest.getMiddleText()
        if not self.middleText['text'] == '':
            self.middleText.show()

        self.questInfo.show()
        self.lPictureFrame.show()

        # Let's set the location text.
        self.locationInfo['text'] = self.quest.getLocationText()
        self.locationInfo['text_pos'] = (0, self.quest.getLocationY())
        self.locationInfo.show()

        # Let's set the progress bar up.
        self.questProgress['text'] = self.quest.getProgressText()
        if len(self.questProgress['text']) > 0 and not objective.finished():
            self.questProgress.show()
            self.questProgress['range'] = objective.getNeededAmount()
            self.questProgress['value'] = objective.getProgress() & pow(2, 16) - 1
        else:
            self.questProgress.hide()

        # Let's setup the aux text.
        self.auxText.setPos(self.quest.getAuxPos())
        self.auxText['text'] = self.quest.getAuxText()
        self.auxText.show()

        maxHP = base.localAvatar.getMaxHealth()
        
        # Let's setup the rewards.
        for i in xrange(0, len(self.quest.getRewards())):
            reward = self.quest.getRewards()[i]
            frame = self.lRewardFrame if (i == 0) else self.rRewardFrame
            info = self.lRewardAmt if (i == 0) else self.rRewardAmt
            rType = reward.getType()
            if(rType == RewardType.JELLYBEANS):
                frame['pos'] = QuestGlobals.LEFT_JB_JAR_POS if (i == 0) else QuestGlobals.RIGHT_JB_JAR_POS
                frame['geom'] = QuestGlobals.getJBIcon()
                frame['geom_scale'] = QuestGlobals.JB_JAR_SCALE
                info['text'] = str(reward.getModifier())
            elif(rType == RewardType.TELEPORT_ACCESS or rType == RewardType.GAG_FRAME):
                frame['pos'] = QuestGlobals.LEFT_TP_ACCESS_POS if(i == 0) else QuestGlobals.RIGHT_TP_ACCESS_POS
                frame['geom'] = QuestGlobals.getTPAccessIcon() if(rType == RewardType.TELEPORT_ACCESS) else QuestGlobals.getFilmIcon()
                frame['geom_scale'] = QuestGlobals.TP_ACCESS_SCALE
                info['text'] = 'N/A' if(rType == RewardType.TELEPORT_ACCESS) else '#%s' % (str(reward.getModifier()))
            elif(rType == RewardType.LAFF_POINTS):
                frame.initialiseoptions(DirectFrame)
                r, g, b, _ = base.localAvatar.getHeadColor()
                pos = QuestGlobals.LEFT_LAFF_METER_POS if(i == 0) else QuestGlobals.RIGHT_LAFF_METER_POS

                # Create the laff meter with the new health.
                hp = maxHP + reward.getModifier()
                laffMeter = LaffOMeter()
                laffMeter.generate(r, g, b, base.localAvatar.getAnimal(), maxHP = hp, initialHP = hp)

                # Let's position the laff meter.
                frame['geom'] = laffMeter
                frame['geom_scale'] = QuestGlobals.LAFF_METER_SCALE
                frame.setPos(pos)
                info['text'] = '+%s' % (str(reward.getModifier()))
                laffMeter.destroy()
                laffMeter = None

        # Hide or show the other reward depending on if there's 2 rewards.
        if(len(self.quest.getRewards()) == 1):
            self.rRewardFrame.hide()
            self.rRewardAmt.hide()
        else:
            self.rRewardFrame.show()
            self.rRewardAmt.show()

        if objective.finished():
            self.setColor(Vec4(*QuestGlobals.LIGHT_GREEN))
            self.sideInfo['text'] = 'Completed!'
            self.sideInfo.show()
            
        self.questInfo.initialiseoptions(DirectLabel)
        self.questInfo02.initialiseoptions(DirectLabel)
        self.locationInfo.initialiseoptions(DirectLabel)
        self.lPictureFrame.initialiseoptions(DirectFrame)
        self.rPictureFrame.initialiseoptions(DirectFrame)
        self.lQuestIcon.initialiseoptions(DirectFrame)
        self.rQuestIcon.initialiseoptions(DirectFrame)
        self.auxText.initialiseoptions(DirectLabel)
        self.middleText.initialiseoptions(DirectLabel)
        self.sideInfo.initialiseoptions(DirectLabel)
        self.lPictureFrame['image_color'] = self.quest.getPictureFrameColor()
        self.rPictureFrame['image_color'] = self.quest.getPictureFrameColor()

    def fitGeometry(self, geom, fFlip = 0, dimension = 0.8):
        p1 = Point3()
        p2 = Point3()
        geom.calcTightBounds(p1, p2)
        if fFlip:
            t = p1[0]
            p1.setX(-p2[0])
            p2.setX(-t)
        d = p2 - p1
        biggest = max(d[0], d[2])
        s = dimension / biggest
        mid = (p1 + d / 2.0) * s
        geomXform = hidden.attachNewNode('geomXform')
        for child in geom.getChildren():
            child.reparentTo(geomXform)

        geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s, s, s)
        geomXform.reparentTo(geom)

    def destroy(self):
        self._deleteGeoms()
        DirectFrame.destroy(self)

    def _deleteGeoms(self):
        for icon in (self.lQuestIcon, self.rQuestIcon):
            geom = icon['geom']
            if geom and hasattr(geom, 'delete'):
                geom.delete()
                
    def getQuest(self):
        return self.quest
コード例 #3
0
class QuestPoster(DirectFrame):
    notify = directNotify.newCategory('QuestPoster')

    # We need to declare and initialize these variables here
    # because some methods use them as default arguments.
    auxIcon = None

    # Requires one parameter, quest, this must be a Quest instance.
    # The next argument, parent, is where to reparent the DirectFrame to.
    # The next arguments are simply additional options when setting up the DirectFrame.
    def __init__(self, quest, parent=aspect2d, **kw):
        # The quest this poster is representing.
        self.quest = quest

        # Let's define our options for the DirectFrame.
        bookModel = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')
        optiondefs = (('relief', None,
                       None), ('image', bookModel.find('**/questCard'),
                               None), ('image_scale', (0.8, 1.0, 0.58), None),
                      ('state', DGG.NORMAL, None))
        self.defineoptions(kw, optiondefs)

        # Finally, initialize the DirectFrame.
        DirectFrame.__init__(self, relief=None)
        self.initialiseoptions(QuestPoster)

        # Let's declare and initialize our barebone GUI element variables.
        self.titleLabel = DirectLabel(parent=self,
                                      relief=None,
                                      text=self.quest.getName(),
                                      text_font=CIGlobals.getMinnieFont(),
                                      text_fg=QuestGlobals.TEXT_COLOR,
                                      text_scale=0.05,
                                      text_align=TextNode.ACenter,
                                      text_wordwrap=25.0,
                                      textMayChange=1,
                                      pos=(0, 0, 0.23))

        ##########################################################################
        #           THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER            #
        ##########################################################################

        # The background frame where the objective image is displayed.
        # This is the colored background frame.
        self.auxFrame = DirectFrame(
            parent=self,
            relief=None,
            image=bookModel.find('**/questPictureFrame'),
            image_scale=QuestGlobals.IMAGE_SCALE_SMALL,
            text='',
            text_pos=(0, -0.11),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=11.0,
            pos=QuestGlobals.DEFAULT_LEFT_PICTURE_POS)

        # The icon that goes on top of the aux frame.
        self.auxIcon = DirectFrame(parent=self.auxFrame,
                                   relief=None,
                                   text=' ',
                                   text_font=CIGlobals.getSuitFont(),
                                   text_pos=(0, -0.03),
                                   text_fg=QuestGlobals.TEXT_COLOR,
                                   text_scale=0.13,
                                   text_align=TextNode.ACenter,
                                   text_wordwrap=13.0,
                                   textMayChange=1)
        self.auxIcon.setColorOff(-1)

        # The aux text saying: DEFEAT, RECOVER, etc.
        self.auxText = DirectLabel(parent=self,
                                   relief=None,
                                   text=QuestGlobals.RECOVER,
                                   text_font=CIGlobals.getToonFont(),
                                   text_scale=QuestGlobals.QPauxText,
                                   text_fg=QuestGlobals.TEXT_COLOR,
                                   text_align=TextNode.ACenter,
                                   textMayChange=1,
                                   pos=QuestGlobals.DEFAULT_AUX_POS)
        self.auxText.hide()

        ##########################################################################

        # Information displayed about the objective.
        self.objectiveInfo = DirectLabel(
            parent=self,
            relief=None,
            text='',
            text_font=CIGlobals.getToonFont(),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=0.04,
            text_align=TextNode.ACenter,
            text_wordwrap=QuestGlobals.QPtextWordwrap,
            textMayChange=1,
            pos=(QuestGlobals.DEFAULT_INFO_POS))
        self.objectiveInfo.hide()

        # Information displayed showing the location.
        self.locationInfo = DirectLabel(
            parent=self,
            relief=None,
            text='N/A',
            text_font=CIGlobals.getToonFont(),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=QuestGlobals.QPtextWordwrap,
            textMayChange=1,
            pos=(0, 0, -0.115))
        self.locationInfo.hide()

        # The progress bar showing the objective's progress
        self.progressBar = DirectWaitBar(parent=self,
                                         relief=DGG.SUNKEN,
                                         frameSize=(-0.95, 0.95, -0.1, 0.12),
                                         borderWidth=(0.025, 0.025),
                                         scale=0.2,
                                         frameColor=(0.945, 0.875, 0.706, 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),
                                         pos=(0, 0, -0.2425))
        self.progressBar.hide()

        # The wood panel at the bottom where rewards are displayed.
        rewardFrameGeom = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        self.rewardFrame = DirectFrame(
            parent=self,
            relief=None,
            geom=rewardFrameGeom.find('**/Goofys_Sign'),
            geom_scale=(0.615, 0, 0.4),
            pos=(-0.01, 0, -0.25))

        # The text displayed on the right side of the frame with additional information, if necessary.
        self.sideInfo = DirectLabel(parent=self,
                                    relief=None,
                                    text=QuestGlobals.JUST_FOR_FUN,
                                    text_fg=(0.0, 0.439, 1.0, 1.0),
                                    text_shadow=(0, 0, 0, 1),
                                    pos=(-0.2825, 0, 0.2),
                                    scale=0.03)
        self.sideInfo.setR(-30)

        # This side information is usually not needed, let's hide it.
        self.sideInfo.hide()

        # Remove the nodes of the loaded models we no longer need.
        bookModel.removeNode()
        rewardFrameGeom.removeNode()

        # Let's hide this until it is needed.
        self.hide()
        return

    def setup(self):
        objective = self.quest.currentObjective
        objective.updateInfo()

        self.objectiveInfo.show()
        self.auxFrame.show()

        self.locationInfo['text'] = QuestGlobals.getLocationText(
            objective.location)
        self.locationInfo['text_pos'] = (0,
                                         0 if not QuestGlobals.isShopLocation(
                                             objective.location) else 0.025)
        self.locationInfo.show()

        # Let's setup the quest progress bar
        progress = objective.amount if hasattr(objective, 'amount') else None

        if progress and objective.neededAmount > 0:
            self.progressBar['range'] = objective.getNeededAmount()
            self.progressBar['value'] = progress & pow(2, 16) - 1

        if objective.__class__ in [
                DeliverItemObjective, CogObjective, RecoverItemObjective
        ]:
            self.progressBar.show()

        self.auxText.show()

        # Let's handle the objectives.
        if objective.__class__ == CogObjective:
            self.handleCogObjective()
        elif objective.__class__ == VisitNPCObjective:
            self.handleNPCObjective()

        self.titleLabel.initialiseoptions(DirectLabel)
        self.auxIcon.initialiseoptions(DirectFrame)
        self.auxText.initialiseoptions(DirectLabel)
        self.objectiveInfo.initialiseoptions(DirectLabel)
        self.locationInfo.initialiseoptions(DirectLabel)
        self.rewardFrame.initialiseoptions(DirectFrame)
        self.sideInfo.initialiseoptions(DirectLabel)

    # Changes geometry and scale of an icon.
    def handleSimpleIcon(self, geom, scale, icon):
        icon['geom'] = geom
        icon['geom_scale'] = scale

    def handleComplexIcon(self,
                          geom,
                          icon,
                          scale=QuestGlobals.IMAGE_SCALE_SMALL):
        isHead = True if type(geom) == ToonHead else geom.getName() == (
            '%sHead' % CIGlobals.Suit)

        if isHead:
            geom.setDepthWrite(1)
            geom.setDepthTest(1)
            self.fitGeometry(geom, fFlip=1)
            self.handleSimpleIcon(geom, scale, icon)

            # We have to rotate the head and set the scale of the icon.
            if CIGlobals.Suit in geom.getName():
                cogName = geom.getPythonTag('Settings')
                data = QuestGlobals.Suit2PosterZNDScale.get(cogName)
                zOffset = data[0]
                headScale = data[1]
                icon.setScale(headScale)
                icon.setZ(icon.getZ() + zOffset)
                geom.setH(180)
        else:
            raise ValueError(
                'Tried to use #handleComplexIcon() on a non-complex icon. Use this method for 3D geometry.'
            )

    def handleCogObjective(self,
                           iconElement=auxIcon,
                           auxText=QuestGlobals.DEFEAT,
                           frameColor=QuestGlobals.BLUE):
        objective = self.quest.currentObjective
        infoText = objective.getTaskInfo(speech=False)

        if objective.__class__ == RecoverItemObjective:
            infoText = QuestGlobals.makePlural(objective.name)
            print 'Yep'

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the CogObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, CogObjective):
            return

        if objective.dept:
            icons = loader.loadModel('phase_3/models/gui/cog_icons.bam')
            deptIcon = None

            if objective.dept == Dept.BOSS:
                deptIcon = icons.find('**/CorpIcon')
            else:
                deptIcon = icons.find('**/%sIcon' %
                                      objective.dept.getTie().title())

            # Correct the medallion color.
            deptIcon.setColor(SuitGlobals.medallionColors[objective.dept])

            # Setup the icon and remove the icons node.
            self.handleSimpleIcon(deptIcon, 0.13, iconElement)
            icons.removeNode()
        elif not objective.name:
            # We aren't fighting a Cog in particular.
            cogIcon = QuestGlobals.getCogIcon()
            self.handleSimpleIcon(cogIcon, cogIcon.getScale(), iconElement)

        # We're fighting a Cog in particular.
        if objective.name:
            cogHeadInstance = SuitBank.getSuitByName(objective.name).getHead()
            cogHead = cogHeadInstance.generate()
            cogHead.setName('%sHead' % CIGlobals.Suit)
            cogHead.setPythonTag('Settings', cogHeadInstance.head)
            cogHeadInstance.setScale(2)
            self.handleComplexIcon(cogHead, iconElement)

        if not iconElement is self.auxIcon:
            if hasattr(self, 'goalInfo'):
                # We're working with the second frame, on the right.
                # Let's update the information pertaining to this side.
                self.goalInfo['text'] = infoText
                self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS)
                self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS)
            else:
                raise AttributeError(
                    'Attempted to setup DoubleFrame information for poster using default style.'
                )
        else:
            self.objectiveInfo['text'] = infoText
            self.auxText['text'] = auxText

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.amount, objective.neededAmount,
                                     QuestGlobals.makePastTense(auxText))
        self.progressBar['text'] = pgBarText

        # Let's set the color of the poster.
        frame = self.auxFrame if iconElement is self.auxIcon else self.goalFrame
        frame['image_color'] = Vec4(*frameColor)

    def handleNPCObjective(self,
                           iconElement=auxIcon,
                           auxText=QuestGlobals.VISIT,
                           frameColor=QuestGlobals.BROWN):
        objective = self.quest.currentObjective
        infoText = CIGlobals.NPCToonNames[objective.npcId]

        if not iconElement:
            iconElement = self.auxIcon

        # Let's make sure we have a current objective that is
        # an instance of the CogObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, VisitNPCObjective):
            return

        # Let's generate the head.
        dna = ToonDNA()
        dna.setDNAStrand(CIGlobals.NPCToonDict.get(objective.npcId)[2])
        head = ToonHead(base.cr)
        head.generateHead(dna.getGender(),
                          dna.getAnimal(),
                          dna.getHead(),
                          forGui=1)
        head.setHeadColor(dna.getHeadColor())
        self.handleComplexIcon(head, iconElement)

        self.auxText['text'] = auxText

        if not iconElement is self.auxIcon:
            if hasattr(self, 'goalInfo'):
                # We're working with the second frame, on the right.
                # Let's update the information pertaining to this side.
                self.goalInfo['text'] = infoText
                self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS)
                self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS)
                self.goalFrame['image_color'] = frameColor
            else:
                raise AttributeError(
                    'Attempted to setup DoubleFrame information for poster using default style.'
                )
        else:
            self.objectiveInfo['text'] = infoText
            self.auxFrame['image_color'] = frameColor

    def fitGeometry(self, geom, fFlip=0, dimension=0.8):
        p1 = Point3()
        p2 = Point3()
        geom.calcTightBounds(p1, p2)
        if fFlip:
            t = p1[0]
            p1.setX(-p2[0])
            p2.setX(-t)
        d = p2 - p1
        biggest = max(d[0], d[2])
        s = dimension / biggest
        mid = (p1 + d / 2.0) * s
        geomXform = hidden.attachNewNode('geomXform')
        for child in geom.getChildren():
            child.reparentTo(geomXform)

        geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s,
                                 s, s)
        geomXform.reparentTo(geom)

    def destroy(self):
        if hasattr(self, 'titleLabel'):
            self.titleLabel.destroy()
            self.auxFrame.destroy()
            self.auxIcon.destroy()
            self.auxText.destroy()
            self.objectiveInfo.destroy()
            self.locationInfo.destroy()
            self.progressBar.destroy()
            self.rewardFrame.destroy()
            self.sideInfo.destroy()
            del self.titleLabel
            del self.auxFrame
            del self.auxIcon
            del self.auxText
            del self.objectiveInfo
            del self.locationInfo
            del self.progressBar
            del self.rewardFrame
            del self.sideInfo
            DirectFrame.destroy(self)
            self.notify.debug('Destroyed all elements.')
class DoubleFrameQuestPoster(QuestPoster):
    notify = directNotify.newCategory('DoubleFrameQuestPoster')

    def __init__(self, quest, parent=aspect2d, **kw):
        QuestPoster.__init__(self, quest, parent, **kw)

        # This text is in between the two frames and it usually says
        # either "from:" or "to:"
        self.fromToMiddleText = DirectLabel(
            parent=self,
            relief=None,
            text=QuestGlobals.FROM,
            text_font=CIGlobals.getToonFont(),
            text_scale=QuestGlobals.QPauxText,
            text_fg=QuestGlobals.TEXT_COLOR,
            text_align=TextNode.ACenter,
            textMayChange=1,
            pos=QuestGlobals.DEFAULT_MIDDLE_POS)
        self.fromToMiddleText.hide()

        ##########################################################################
        #           THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER            #
        ##########################################################################
        # We need this again for certain geometry.
        bookModel = loader.loadModel(
            'phase_3.5/models/gui/stickerbook_gui.bam')

        # The background frame where the objective image is displayed.
        # This is the colored background frame.
        self.goalFrame = DirectFrame(
            parent=self,
            relief=None,
            image=bookModel.find('**/questPictureFrame'),
            image_scale=QuestGlobals.IMAGE_SCALE_SMALL,
            text='',
            text_pos=(0, -0.11),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=11.0,
            pos=QuestGlobals.DEFAULT_RIGHT_PICTURE_POS)

        # The icon that goes on top of the goal frame.
        self.goalIcon = DirectFrame(parent=self.goalFrame,
                                    relief=None,
                                    text=' ',
                                    text_font=CIGlobals.getSuitFont(),
                                    text_pos=(0, -0.03),
                                    text_fg=QuestGlobals.TEXT_COLOR,
                                    text_scale=0.13,
                                    text_align=TextNode.ACenter,
                                    text_wordwrap=13.0,
                                    textMayChange=1)
        self.goalIcon.setColorOff(-1)

        # Information displayed about the additional goal.
        self.goalInfo = DirectLabel(parent=self,
                                    relief=None,
                                    text='',
                                    text_font=CIGlobals.getToonFont(),
                                    text_fg=QuestGlobals.TEXT_COLOR,
                                    text_scale=0.04,
                                    text_align=TextNode.ACenter,
                                    text_wordwrap=QuestGlobals.QPtextWordwrap,
                                    textMayChange=1,
                                    pos=(QuestGlobals.DEFAULT_INFO2_POS))
        self.goalInfo.hide()

        bookModel.removeNode()
        return

        ##########################################################################

    def setup(self):
        QuestPoster.setup(self)
        objective = self.quest.currentObjective

        if objective.__class__ == DeliverItemObjective:
            self.handleDeliverItemObjective()
        elif objective.__class__ == RecoverItemObjective:
            self.handleRecoverItemObjective()

        self.goalInfo.show()
        self.fromToMiddleText.show()
        self.goalIcon.initialiseoptions(DirectFrame)
        self.initialiseoptions(DoubleFrameQuestPoster)

    def handleRecoverItemObjective(self):
        objective = self.quest.currentObjective

        # Let's make sure we have a current objective that is
        # an instance of the RecoverItemObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, RecoverItemObjective):
            return

        # Let's make the left icon use the item icon we chose.
        self.handleSimpleIcon(objective.itemIcon, 0.12, self.auxIcon)

        # Handle the objective information.
        infoText = '%d %s' % (objective.neededAmount,
                              QuestGlobals.makePlural(objective.itemName))
        if objective.neededAmount == 1:
            infoText = objective.itemName

        # Update the positions and information regarding the left side.
        self.auxFrame.setPos(QuestGlobals.RECOVER_LEFT_PICTURE_POS)
        self.auxFrame['image_color'] = QuestGlobals.GREEN
        self.objectiveInfo.setPos(QuestGlobals.RECOVER_INFO_POS)
        self.objectiveInfo['text'] = infoText
        self.fromToMiddleText['text'] = QuestGlobals.FROM

        self.handleCogObjective(self.goalIcon, frameColor=QuestGlobals.GREEN)

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.amount, objective.neededAmount,
                                     QuestGlobals.makePastTense(
                                         QuestGlobals.RECOVER))
        self.progressBar['text'] = pgBarText

    def handleDeliverItemObjective(self):
        objective = self.quest.currentObjective

        # Let's make sure we have a current objective that is
        # an instance of the DeliverItemObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, DeliverItemObjective):
            return

        # Correct the scaling if we need to and set the icon.
        scale = 0.12 if objective.itemIcon.getName() == 'package' else 0.85
        self.handleSimpleIcon(objective.itemIcon, scale, self.auxIcon)
        self.auxFrame.setPos(QuestGlobals.RECOVER_LEFT_PICTURE_POS)
        self.auxFrame['image_color'] = QuestGlobals.RED

        infoText = '%d %s' % (objective.neededAmount,
                              QuestGlobals.makePlural(objective.itemName))
        if objective.neededAmount == 1:
            infoText = objective.itemName
        self.objectiveInfo.setPos(QuestGlobals.RECOVER_INFO_POS)
        self.objectiveInfo['text'] = infoText
        self.fromToMiddleText['text'] = QuestGlobals.TO

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.amount, objective.neededAmount,
                                     QuestGlobals.makePastTense(
                                         QuestGlobals.DELIVER))
        self.progressBar['text'] = pgBarText

        self.handleNPCObjective(self.goalIcon,
                                auxText=QuestGlobals.DELIVER,
                                frameColor=QuestGlobals.RED)

    def destroy(self):
        self.fromToMiddleText.destroy()
        self.goalFrame.destroy()
        self.goalIcon.destroy()
        self.goalInfo.destroy()
        del self.fromToMiddleText
        del self.goalFrame
        del self.goalIcon
        del self.goalInfo
        QuestPoster.destroy(self)
コード例 #5
0
class DoubleFrameQuestPoster(QuestPoster):
    notify = directNotify.newCategory('DoubleFrameQuestPoster')

    def __init__(self, quest, parent=aspect2d, **kw):
        QuestPoster.__init__(self, quest, parent, **kw)

        # This text is in between the two frames and it usually says
        # either "from:" or "to:"
        self.fromToMiddleText = DirectLabel(
            parent=self,
            relief=None,
            text=QuestGlobals.FROM,
            text_font=CIGlobals.getToonFont(),
            text_scale=QuestGlobals.QPauxText,
            text_fg=QuestGlobals.TEXT_COLOR,
            text_align=TextNode.ACenter,
            textMayChange=1,
            pos=QuestGlobals.DEFAULT_MIDDLE_POS)
        self.fromToMiddleText.hide()

        ##########################################################################
        #           THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER            #
        ##########################################################################
        # We need this again for certain geometry.
        circleGui = loader.loadModel(
            'phase_4/models/gui/CircleIconBackgroundGui.bam')

        # The background frame where the objective image is displayed.
        # This is the colored background frame.
        self.goalFrame = DirectFrame(
            parent=self,
            relief=None,
            image=circleGui.find('**/circle_display_interior'),
            image_scale=0.18,
            text='',
            text_pos=(0, -0.11),
            text_fg=QuestGlobals.TEXT_COLOR,
            text_scale=QuestGlobals.QPtextScale,
            text_align=TextNode.ACenter,
            text_wordwrap=11.0,
            pos=QuestGlobals.DEFAULT_RIGHT_PICTURE_POS)
        self.goalFrame.hide()

        # The icon that goes on top of the goal frame.
        self.goalIcon = DirectFrame(parent=self.goalFrame,
                                    relief=None,
                                    text=' ',
                                    text_font=CIGlobals.getSuitFont(),
                                    text_pos=(0, -0.03),
                                    text_fg=QuestGlobals.TEXT_COLOR,
                                    text_scale=0.13,
                                    text_align=TextNode.ACenter,
                                    text_wordwrap=13.0,
                                    textMayChange=1)
        self.goalIcon.setColorOff(-1)
        self.goalIcon.hide()

        self.goalOutline = DirectLabel(
            parent=self.goalFrame,
            relief=None,
            image=circleGui.find('**/circle_display_outline'),
            image_scale=0.18)
        self.goalOutline.hide()

        # Information displayed about the additional goal.
        self.goalInfo = DirectLabel(parent=self,
                                    relief=None,
                                    text='',
                                    text_font=CIGlobals.getToonFont(),
                                    text_fg=QuestGlobals.TEXT_COLOR,
                                    text_scale=0.04,
                                    text_align=TextNode.ACenter,
                                    text_wordwrap=QuestGlobals.QPtextWordwrap,
                                    textMayChange=1,
                                    pos=(QuestGlobals.DEFAULT_INFO2_POS))
        self.goalInfo.hide()

        circleGui.removeNode()
        return

        ##########################################################################

    def setup(self):
        QuestPoster.setup(self)
        objective = self.viewObjective

        # Let's reset our icon.
        self.goalIcon.setScale(1, 1, 1)
        self.goalIcon.setPos(0, 0, 0)
        self.goalIcon.setHpr(0, 0, 0)

        if objective.__class__ in DoubleFrameObjectives:
            if objective.__class__ == DeliverItemObjective:
                # It's kind of hard to return delivered stuff to somebody.
                # We're not handling complete objectives from here.
                self.handleDeliverItemObjective()
            elif objective.__class__ == RecoverItemObjective:
                self.handleRecoverItemObjective()

            if len(self.quest.accessibleObjectives) > 1:
                self.prevObjArrow.setPos(QuestGlobals.SECONDARY_LEFT_ARROW_POS)
                self.nextObjArrow.setPos(
                    QuestGlobals.SECONDARY_RIGHT_ARROW_POS)

            self.goalFrame.show()
            self.goalIcon.show()
            self.goalOutline.show()
            self.goalInfo.show()
            self.fromToMiddleText.show()
        else:
            self.goalFrame.hide()
            self.goalIcon.hide()
            self.goalOutline.hide()
            self.goalInfo.hide()
            self.fromToMiddleText.hide()
        self.goalIcon.initialiseoptions(DirectFrame)
        self.initialiseoptions(DoubleFrameQuestPoster)

    def handleRecoverItemObjective(self):
        objective = self.viewObjective

        # Let's make sure we have a current objective that is
        # an instance of the RecoverItemObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, RecoverItemObjective):
            return

        # Let's make the left icon use the item icon we chose.
        self.handleSimpleIcon(objective.itemIcon, 0.12, self.auxIcon)

        # Handle the objective information.
        infoText = '%d %s' % (objective.goal,
                              CIGlobals.makePlural(objective.itemName))
        if objective.goal == 1:
            infoText = objective.itemName

        # Update the positions and information regarding the left side.
        self.auxFrame.setPos(QuestGlobals.RECOVER_LEFT_PICTURE_POS)
        self.auxFrame['image_color'] = QuestGlobals.GREEN
        self.objectiveInfo.setPos(QuestGlobals.RECOVER_INFO_POS)
        self.objectiveInfo['text'] = infoText
        self.fromToMiddleText[
            'text'] = QuestGlobals.FROM if not objective.isComplete(
            ) else QuestGlobals.TO

        if not objective.isComplete():
            self.handleCogObjective(self.goalIcon,
                                    auxText=QuestGlobals.RECOVER,
                                    frameColor=QuestGlobals.GREEN)

            # Let's set the progress bar text
            pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                         CIGlobals.makePastTense(
                                             QuestGlobals.RECOVER))
            self.progressBar['text'] = pgBarText
            self.progressBar['value'] = objective.progress & pow(2, 16) - 1
        else:
            self.handleNPCObjective(self.goalIcon,
                                    auxText=QuestGlobals.RETURN,
                                    frameColor=QuestGlobals.BLUE)

    def handleDeliverItemObjective(self):
        objective = self.viewObjective

        # Let's make sure we have a current objective that is
        # an instance of the DeliverItemObjective class and this poster isn't destroyed.
        if not objective or not hasattr(self, 'titleLabel') or not isinstance(
                objective, DeliverItemObjective):
            return

        # Correct the scaling if we need to and set the icon.
        scale = 0.12 if objective.itemIcon.getName() == 'package' else 0.85
        self.handleSimpleIcon(objective.itemIcon, scale, self.auxIcon)
        self.auxFrame.setPos(QuestGlobals.RECOVER_LEFT_PICTURE_POS)
        self.auxFrame['image_color'] = QuestGlobals.RED

        infoText = '%d %s' % (objective.goal,
                              CIGlobals.makePlural(objective.itemName))
        if objective.goal == 1:
            infoText = objective.itemName
        self.objectiveInfo.setPos(QuestGlobals.RECOVER_INFO_POS)
        self.objectiveInfo['text'] = infoText
        self.fromToMiddleText['text'] = QuestGlobals.TO

        # Let's set the progress bar text
        pgBarText = '%d of %d %s' % (objective.progress, objective.goal,
                                     CIGlobals.makePastTense(
                                         QuestGlobals.DELIVER))
        self.progressBar['text'] = pgBarText
        self.progressBar['value'] = objective.progress & pow(2, 16) - 1

        self.handleNPCObjective(self.goalIcon,
                                auxText=QuestGlobals.DELIVER,
                                frameColor=QuestGlobals.RED)

    def destroy(self):
        self.fromToMiddleText.destroy()
        self.goalFrame.destroy()
        self.goalIcon.destroy()
        self.goalOutline.destroy()
        self.goalInfo.destroy()
        del self.fromToMiddleText
        del self.goalFrame
        del self.goalIcon
        del self.goalOutline
        del self.goalInfo
        QuestPoster.destroy(self)