def presentQuestGiven(self, quest):
        self.resetBranch = None
        if self.resetBranch:
            container = localAvatar.questStatus.getContainer(quest.getQuestId())
            if container.parent and container.parent.getFirstQuestId() == quest.getQuestId():
                self.presentBranchReset(False)
                return None
            else:
                self.resetBranch = None
        
        
        def handleOption(option):
            if len(localAvatar.currentStoryQuests):
                self.cleanUpQuestDetails(hide = True)
                while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
                    localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])
            
            if len(localAvatar.currentStoryQuests):
                storyQuest = localAvatar.currentStoryQuests[0]
                self.presentQuestGiven(storyQuest)
                localAvatar.currentStoryQuests.remove(storyQuest)
            elif hasattr(quest, 'questDNA') and quest.questDNA.getTimeLimit():
                quest.startTimer()
            
            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, quest)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)
        base.questdet = self.questDetailGUI
        self.ignore('doneChatPage')
 def displayBranchDetails(offer):
     self.selectedOffer = offer
     self.cleanUpQuestDetails()
     self.questDetailGUI = QuestDetailGUI(offer, None)
     self.questDetailGUI.showPanel()
     base.questdet = self.questDetailGUI
     return
 def displayBranchDetails(offer):
     self.selectedOffer = offer
     self.cleanUpQuestDetails()
     self.questDetailGUI = QuestDetailGUI(offer, None)
     self.questDetailGUI.showPanel()
     base.questdet = self.questDetailGUI
     subtitleOptions = [
         PLocalizer.Accept]
     if declineOption:
         subtitleOptions = [
             PLocalizer.Decline,
             PLocalizer.Accept]
     
     localAvatar.guiMgr.subtitler.setPageChat('Is that your choice?', options = subtitleOptions, callback = handleBranchOption)
    def presentQuestReset(self):
        if not self.resetQuest:
            return None
        
        
        def handleOption(option):
            if option == PLocalizer.Accept:
                self.resetQuest.startTimer()
            
            self.resetQuest = None
            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, self.resetQuest.questDNA)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)
 def __init__(self):
     InventoryPage.InventoryPage.__init__(self)
     self.initialiseoptions(QuestPage)
     self.detailId = None
     self.titleBorder = BorderFrame.BorderFrame(parent = self, frameSize = (-0.02, 0.96999999999999997, -0.02, 0.56000000000000005))
     self.titleBorder.setPos(0.065000000000000002, 0, -0.01)
     self.titleBorder.background.setColor(0, 0, 0, 1)
     self.titleBorder.resetDecorations()
     self.titleList = QuestTitleList.QuestTitleList()
     self.titleList.reparentTo(self.titleBorder)
     self.titleList.setPos(0.0050000000000000001, 0, 0)
     self.detailFrame = QuestDetailGUI(parent = self, pos = (0.54000000000000004, 0, 1.006))
     self.dropButton = GuiButton.GuiButton(parent = self, state = DGG.DISABLED, text = PLocalizer.DropQuest, textMayChange = 0, text_scale = PiratesGuiGlobals.TextScaleLarge, text_pos = (0, -0.014), pos = (0.91000000000000003, 0, 0.60499999999999998), image = GuiButton.GuiButton.redGenericButton, image_scale = 0.59999999999999998, command = self.dropQuest, helpText = PLocalizer.DropQuestHelp, helpDelay = PiratesGuiGlobals.HelpPopupTime, helpPos = (-0.33500000000000002, 0, 0.125))
     gui = loader.loadModel('models/gui/compass_main')
     objectiveGrey = gui.find('**/icon_objective_grey')
     self.trackButton = GuiButton.GuiButton(parent = self, state = DGG.DISABLED, text = PLocalizer.TrackQuest, textMayChange = 0, text_pos = (0.035000000000000003, -0.014), text_scale = PiratesGuiGlobals.TextScaleLarge, pos = (0.66000000000000003, 0, 0.60499999999999998), command = self.trackQuest, helpText = PLocalizer.TrackQuestHelp, helpDelay = PiratesGuiGlobals.HelpPopupTime, helpPos = (-0.080000000000000002, 0, 0.125), image = GuiButton.GuiButton.redGenericButton, image_scale = 0.59999999999999998, geom = objectiveGrey, geom_color = Vec4(1, 1, 0, 1), geom_scale = 0.20000000000000001, geom_pos = (-0.070000000000000007, 0, -0.002))
     self.specialInfoPanel = { }
     self.specialButton = GuiButton.GuiButton(parent = self, state = DGG.NORMAL, text = '', textMayChange = 1, text_scale = PiratesGuiGlobals.TextScaleLarge, text_pos = (0, -0.014), pos = (0.17000000000000001, 0, 0.60499999999999998), image = GuiButton.GuiButton.redGenericButton, image_scale = 0.59999999999999998, command = self.showSpecialInfo, helpText = PLocalizer.DropQuestHelp, helpDelay = PiratesGuiGlobals.HelpPopupTime, helpPos = (-0.33500000000000002, 0, 0.125))
     self.specialButton.hide()
     self.accept('questGuiSelect', self.showQuestDetails)
     self.accept('localAvatarQuestComplete', self.updateQuestDetails)
     self.accept('localAvatarQuestUpdate', self.updateQuestDetails)
     self.accept('localAvatarQuestItemUpdate', self.updateQuestDetails)
     self.accept('inventoryAddDoId-%s-%s' % (localAvatar.getInventoryId(), InventoryCategory.QUESTS), self.updateQuestTitlesNewQuest)
     self.accept('inventoryRemoveDoId-%s-%s' % (localAvatar.getInventoryId(), InventoryCategory.QUESTS), self.updateQuestTitles)
     self.invRequest = None
     self.tmButtonQuick = None
     self.tmButtonSearch = None
     self.tmReadyDialog = None
    def presentQuestGiven(self, quest):
        self.resetBranch = None
        if self.resetBranch:
            container = localAvatar.questStatus.getContainer(quest.getQuestId())
            if container.parent and container.parent.getFirstQuestId() == quest.getQuestId():
                self.presentBranchReset(False)
                return None
            else:
                self.resetBranch = None


        def handleOption(option):
            if len(localAvatar.currentStoryQuests):
                self.cleanUpQuestDetails(hide = True)
                while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
                    localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])

            if len(localAvatar.currentStoryQuests):
                storyQuest = localAvatar.currentStoryQuests[0]
                self.presentQuestGiven(storyQuest)
                localAvatar.currentStoryQuests.remove(storyQuest)
            elif hasattr(quest, 'questDNA') and quest.questDNA.getTimeLimit():
                quest.startTimer()

            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, quest)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)
        base.questdet = self.questDetailGUI
        self.ignore('doneChatPage')
        def displayBranchDetails(offer):
            self.selectedOffer = offer
            self.cleanUpQuestDetails()
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI
            subtitleOptions = [
                PLocalizer.Accept]
            if declineOption:
                subtitleOptions = [
                    PLocalizer.Decline,
                    PLocalizer.Accept]

            localAvatar.guiMgr.subtitler.setPageChat('Is that your choice?', options = subtitleOptions, callback = handleBranchOption)
 def __init__(self):
     InventoryPage.InventoryPage.__init__(self)
     self.initialiseoptions(QuestPage)
     self.detailId = None
     self.titleBorder = BorderFrame.BorderFrame(parent=self, frameSize=(-0.02, 0.97, -0.02, 0.56))
     self.titleBorder.setPos(0.065, 0, -0.01)
     self.titleBorder.background.setColor(0, 0, 0, 1)
     self.titleBorder.resetDecorations()
     self.titleList = QuestTitleList.QuestTitleList()
     self.titleList.reparentTo(self.titleBorder)
     self.titleList.setPos(0.005, 0, 0)
     self.detailFrame = QuestDetailGUI(parent=self, pos=(0.54, 0, 1.006))
     self.dropButton = GuiButton.GuiButton(parent=self, state=DGG.DISABLED, text=PLocalizer.DropQuest, textMayChange=0, text_scale=PiratesGuiGlobals.TextScaleLarge, text_pos=(0, -0.014), pos=(0.91,
                                                                                                                                                                                                0,
                                                                                                                                                                                                0.605), image=GuiButton.GuiButton.redGenericButton, image_scale=0.6, command=self.dropQuest, helpText=PLocalizer.DropQuestHelp, helpDelay=PiratesGuiGlobals.HelpPopupTime, helpPos=(-0.335, 0, 0.125))
     gui = loader.loadModel('models/gui/compass_main')
     objectiveGrey = gui.find('**/icon_objective_grey')
     self.trackButton = GuiButton.GuiButton(parent=self, state=DGG.DISABLED, text=PLocalizer.TrackQuest, textMayChange=0, text_pos=(0.035, -0.014), text_scale=PiratesGuiGlobals.TextScaleLarge, pos=(0.66,
                                                                                                                                                                                                      0,
                                                                                                                                                                                                      0.605), command=self.trackQuest, helpText=PLocalizer.TrackQuestHelp, helpDelay=PiratesGuiGlobals.HelpPopupTime, helpPos=(-0.08, 0, 0.125), image=GuiButton.GuiButton.redGenericButton, image_scale=0.6, geom=objectiveGrey, geom_color=Vec4(1, 1, 0, 1), geom_scale=0.2, geom_pos=(-0.07, 0, -0.002))
     self.specialInfoPanel = {}
     self.specialButton = GuiButton.GuiButton(parent=self, state=DGG.NORMAL, text='', textMayChange=1, text_scale=PiratesGuiGlobals.TextScaleLarge, text_pos=(0, -0.014), pos=(0.17,
                                                                                                                                                                               0,
                                                                                                                                                                               0.605), image=GuiButton.GuiButton.redGenericButton, image_scale=0.6, command=self.showSpecialInfo, helpText=PLocalizer.DropQuestHelp, helpDelay=PiratesGuiGlobals.HelpPopupTime, helpPos=(-0.335, 0, 0.125))
     self.specialButton.hide()
     self.accept('questGuiSelect', self.showQuestDetails)
     self.accept('localAvatarQuestComplete', self.updateQuestDetails)
     self.accept('localAvatarQuestUpdate', self.updateQuestDetails)
     self.accept('localAvatarQuestItemUpdate', self.updateQuestDetails)
     self.accept('inventoryAddDoId-%s-%s' % (localAvatar.getInventoryId(), InventoryCategory.QUESTS), self.updateQuestTitlesNewQuest)
     self.accept('inventoryRemoveDoId-%s-%s' % (localAvatar.getInventoryId(), InventoryCategory.QUESTS), self.updateQuestTitles)
     self.invRequest = None
     self.tmButtonQuick = None
     self.tmButtonSearch = None
     self.tmReadyDialog = None
     return
    def presentQuestReset(self):
        if not self.resetQuest:
            return None


        def handleOption(option):
            if option == PLocalizer.Accept:
                self.resetQuest.startTimer()

            self.resetQuest = None
            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, self.resetQuest.questDNA)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)
Example #10
0
class QuestPage(InventoryPage.InventoryPage):
    notify = directNotify.newCategory('QuestPage')
    specialInfoData = {
        'Chapter 3': {
            'class': BlackPearlCrew,
            'buttonOn': PLocalizer.ShowBlackPearlCrew,
            'buttonOff': PLocalizer.HideBlackPearlCrew
        }
    }

    def __init__(self):
        InventoryPage.InventoryPage.__init__(self)
        self.initialiseoptions(QuestPage)
        self.detailId = None
        self.titleBorder = BorderFrame.BorderFrame(
            parent=self,
            frameSize=(-0.02, 0.96999999999999997, -0.02, 0.56000000000000005))
        self.titleBorder.setPos(0.065000000000000002, 0, -0.01)
        self.titleBorder.background.setColor(0, 0, 0, 1)
        self.titleBorder.resetDecorations()
        self.titleList = QuestTitleList.QuestTitleList()
        self.titleList.reparentTo(self.titleBorder)
        self.titleList.setPos(0.0050000000000000001, 0, 0)
        self.detailFrame = QuestDetailGUI(parent=self,
                                          pos=(0.54000000000000004, 0, 1.006))
        self.dropButton = GuiButton.GuiButton(
            parent=self,
            state=DGG.DISABLED,
            text=PLocalizer.DropQuest,
            textMayChange=0,
            text_scale=PiratesGuiGlobals.TextScaleLarge,
            text_pos=(0, -0.014),
            pos=(0.91000000000000003, 0, 0.60499999999999998),
            image=GuiButton.GuiButton.redGenericButton,
            image_scale=0.59999999999999998,
            command=self.dropQuest,
            helpText=PLocalizer.DropQuestHelp,
            helpDelay=PiratesGuiGlobals.HelpPopupTime,
            helpPos=(-0.33500000000000002, 0, 0.125))
        gui = loader.loadModel('models/gui/compass_main')
        objectiveGrey = gui.find('**/icon_objective_grey')
        self.trackButton = GuiButton.GuiButton(
            parent=self,
            state=DGG.DISABLED,
            text=PLocalizer.TrackQuest,
            textMayChange=0,
            text_pos=(0.035000000000000003, -0.014),
            text_scale=PiratesGuiGlobals.TextScaleLarge,
            pos=(0.66000000000000003, 0, 0.60499999999999998),
            command=self.trackQuest,
            helpText=PLocalizer.TrackQuestHelp,
            helpDelay=PiratesGuiGlobals.HelpPopupTime,
            helpPos=(-0.080000000000000002, 0, 0.125),
            image=GuiButton.GuiButton.redGenericButton,
            image_scale=0.59999999999999998,
            geom=objectiveGrey,
            geom_color=Vec4(1, 1, 0, 1),
            geom_scale=0.20000000000000001,
            geom_pos=(-0.070000000000000007, 0, -0.002))
        self.specialInfoPanel = {}
        self.specialButton = GuiButton.GuiButton(
            parent=self,
            state=DGG.NORMAL,
            text='',
            textMayChange=1,
            text_scale=PiratesGuiGlobals.TextScaleLarge,
            text_pos=(0, -0.014),
            pos=(0.17000000000000001, 0, 0.60499999999999998),
            image=GuiButton.GuiButton.redGenericButton,
            image_scale=0.59999999999999998,
            command=self.showSpecialInfo,
            helpText=PLocalizer.DropQuestHelp,
            helpDelay=PiratesGuiGlobals.HelpPopupTime,
            helpPos=(-0.33500000000000002, 0, 0.125))
        self.specialButton.hide()
        self.accept('questGuiSelect', self.showQuestDetails)
        self.accept('localAvatarQuestComplete', self.updateQuestDetails)
        self.accept('localAvatarQuestUpdate', self.updateQuestDetails)
        self.accept('localAvatarQuestItemUpdate', self.updateQuestDetails)
        self.accept(
            'inventoryAddDoId-%s-%s' %
            (localAvatar.getInventoryId(), InventoryCategory.QUESTS),
            self.updateQuestTitlesNewQuest)
        self.accept(
            'inventoryRemoveDoId-%s-%s' %
            (localAvatar.getInventoryId(), InventoryCategory.QUESTS),
            self.updateQuestTitles)
        self.invRequest = None
        self.tmButtonQuick = None
        self.tmButtonSearch = None
        self.tmReadyDialog = None

    def destroy(self):
        self.trackButton.command = None
        self.specialButton.command = None
        self.dropButton.command = None
        self.titleList.destroy()
        del self.titleList
        if self.tmReadyDialog:
            self.tmReadyDialog.destroy()

        InventoryPage.InventoryPage.destroy(self)
        self.ignoreAll()

    def show(self):
        InventoryPage.InventoryPage.show(self)
        localAvatar.guiMgr.removeNewQuestIndicator()

    def dropQuest(self):
        if self.detailId:
            self.dropButton['state'] = DGG.DISABLED
            localAvatar.requestDropQuest(self.detailId)

    def trackQuest(self):
        questId = self.detailId
        if questId == localAvatar.activeQuestId or questId == None:
            localAvatar.b_requestActiveQuest('')
            self.titleList.showTracked('')
            localAvatar.guiMgr.hideTrackedQuestInfo()
            localAvatar.guiMgr.mapPage.worldMap.mapBall.removeDart()
        else:
            localAvatar.b_requestActiveQuest(questId, localSet=True)
            self.titleList.showTracked(questId)
            quest = localAvatar.getQuestById(questId)
            if quest is None:
                print 'Tracked quest not found on avatar!\n  Tracked quest: %s\n  Current quests: %s' % (
                    questId,
                    map(lambda q: q.getQuestId(), localAvatar.getQuests()))
                localAvatar.guiMgr.hideTrackedQuestInfo()
            elif localAvatar.questStep:
                mapPage = localAvatar.guiMgr.mapPage
                doId = base.cr.uidMgr.uid2doId.get(
                    localAvatar.questStep.getIsland())
                island = base.cr.doId2do.get(doId)
                if island:
                    pos = island.getPos()
                    if mapPage.worldMap.mapBall.questDartPlaced:
                        localAvatar.guiMgr.mapPage.worldMap.mapBall.updateDart(
                            'questStep', pos)
                    else:
                        localAvatar.guiMgr.mapPage.addQuestDart(
                            'questStep', pos)
                else:
                    localAvatar.guiMgr.mapPage.removeQuestDart('questStep')

    def findNewActiveQuest(self, oldQuestId):
        localAvatar.d_findNewActiveQuest(oldQuestId)
        localAvatar.l_requestActiveQuest('')
        self.titleList.showTracked('')
        localAvatar.guiMgr.setQuestStatusText('')
        localAvatar.guiMgr.setQuestHintText('')
        localAvatar.guiMgr.hideTrackedQuestInfo()
        localAvatar.guiMgr.mapPage.worldMap.mapBall.removeDart()

    def updateQuestTitlesNewQuest(self, quest):
        self.updateQuestTitles(quest, newQuest=True)

    def updateQuestTitles(self,
                          quest=None,
                          newQuest=False,
                          findNewTrackable=True):
        questIds = map(lambda q: q.getQuestId(), localAvatar.getQuests())
        self.titleList.update(questIds, quest, newQuest)
        if localAvatar.activeQuestId:
            self.titleList.showTracked(localAvatar.activeQuestId)
            localAvatar.guiMgr.showTrackedQuestInfo()

        if not (self.detailId) and localAvatar.activeQuestId:
            self.detailId = localAvatar.activeQuestId

        if self.detailId not in questIds:
            if questIds:
                self.detailId = None
                self.detailFrame.clearQuestDetails()
            else:
                self.showQuestDetails(None)
                self.dropButton['state'] = DGG.DISABLED
                self.trackButton['state'] = DGG.DISABLED
        elif (not self.detailFrame.hasQuestDetails()
              or localAvatar.activeQuestId
              ) and self.detailId != localAvatar.activeQuestId:
            self.titleList.select(localAvatar.activeQuestId)

        localAvatar.chatMgr.emoteEntry.updateEmoteList()
        localAvatar.l_setActiveQuest(localAvatar.activeQuestId)

    def showQuestDetails(self, questId):
        self.hideSpecialInfo()
        if questId in self.specialInfoData.keys():
            self.specialButton['text'] = self.specialInfoData[questId].get(
                'buttonOn')
            self.specialButton['command'] = self.showSpecialInfo
            self.specialButton['extraArgs'] = [questId]
            self.specialButton.show()
        else:
            self.specialButton.hide()
        self.detailId = questId
        self.updateQuestIdDetails(questId)

    def updateQuestDetails(self, quest, item=None, note=None):
        questId = quest.getQuestId()
        self.updateQuestIdDetails(questId)
        self.updateQuestTitles(quest)
        messenger.send('localAvatarActiveQuestId',
                       sentArgs=[localAvatar.activeQuestId])

    def updateQuestIdDetails(self, questId):
        self.removeTreasureMapButtons()
        if not questId:
            self.detailFrame.clearQuestDetails()
            return None

        if self.detailId != questId:
            return None

        quest = localAvatar.getQuestById(questId)
        if not quest:
            self.dropButton['state'] = DGG.DISABLED
            self.trackButton['state'] = DGG.DISABLED
            self.detailFrame.setQuestInfoFromQuestId(questId)
        else:
            self.detailFrame.setQuestInfoFromQuest(quest)
            self.checkButtonDisplay(quest)
            trackableQuestId = base.cr.questChoiceSibsMap.getTrackableQuest(
                localAvatar, quest.questId)
            if trackableQuestId == quest.questId or trackableQuestId == None:
                self.trackButton['state'] = DGG.NORMAL
            else:
                self.trackButton['state'] = DGG.DISABLED
                if self.detailId == localAvatar.activeQuestId:
                    self.findNewActiveQuest(quest.questId)

            if quest.isDroppable():
                self.dropButton['state'] = DGG.NORMAL
            else:
                self.dropButton['state'] = DGG.DISABLED

    def checkButtonDisplay(self, quest):
        questDNA = quest.getQuestDNA()
        if questDNA == None:
            return None

        questTasks = questDNA.getTasks()
        for currQuestTask in questTasks:
            if not hasattr(currQuestTask, 'getTreasureMapId'):
                continue

            tmId = currQuestTask.getTreasureMapId()
            if tmId != None:

                def inventoryReceived(inventory):
                    if inventory:
                        self.invRequest = None
                        tms = inventory.getTreasureMapsList()
                        for currTm in tms:
                            if currTm.mapId == tmId:
                                currTm.sendUpdate('requestIsEnabled')
                                self.addTreasureMapButtons(
                                    currTm, 0.60199999999999998)
                                break
                                continue

                self.invRequest = DistributedInventoryBase.DistributedInventoryBase.getInventory(
                    localAvatar.getInventoryId(), inventoryReceived)
                continue

    def addTreasureMapButtons(self, tm, buttonOffset):
        self.removeTreasureMapButtons()
        helpPos = (-0.26000000000000001, 0, 0.095000000000000001)
        if __debug__ and base.config.GetBool('enable-bp-solo', False):
            self.tmButtonQuick = GuiButton.GuiButton(
                parent=self,
                text=PLocalizer.PlayTMNow,
                text_align=TextNode.ACenter,
                text_scale=PiratesGuiGlobals.TextScaleLarge,
                text_pos=(0.0, -0.01),
                text_fg=PiratesGuiGlobals.TextFG1,
                text_shadow=PiratesGuiGlobals.TextShadow,
                text_wordwrap=40,
                image_scale=(0.45000000000000001, 1, 0.23999999999999999),
                command=self.startTreasureMap,
                extraArgs=[tm],
                pos=(0.29999999999999999, 0, buttonOffset),
                helpText=PLocalizer.PlayTMNowHelp,
                helpPos=helpPos)
            searchPos = (0.77500000000000002, 0, buttonOffset)
        else:
            searchPos = (0.55000000000000004, 0, buttonOffset)
        self.tmButtonSearch = GuiButton.GuiButton(
            parent=self,
            text=PLocalizer.PlayTMLookout,
            text_align=TextNode.ACenter,
            text_scale=PiratesGuiGlobals.TextScaleLarge,
            text_pos=(0.0, -0.01),
            text_fg=PiratesGuiGlobals.TextFG1,
            text_shadow=PiratesGuiGlobals.TextShadow,
            text_wordwrap=40,
            image_scale=(0.45000000000000001, 1, 0.23999999999999999),
            command=self.startTreasureMap,
            extraArgs=[tm, False],
            pos=searchPos,
            helpText=PLocalizer.PlayTMLookoutHelp,
            helpPos=helpPos)
        if base.cr.teleportMgr.inInstanceType == PiratesGlobals.INSTANCE_TM:
            self.disableTreasureMapButtons()
        else:
            self.enableTreasureMapButtons()

    def removeTreasureMapButtons(self):
        self.trackButton.show()
        self.dropButton.show()
        if self.tmButtonQuick:
            self.tmButtonQuick.removeNode()
            self.tmButtonQuick = None

        if self.tmButtonSearch:
            self.tmButtonSearch.removeNode()
            self.tmButtonSearch = None

    def enableTreasureMapButtons(self):
        if self.tmButtonQuick:
            self.tmButtonQuick['state'] = 'normal'

        if self.tmButtonSearch:
            self.tmButtonSearch['state'] = 'normal'

        self.trackButton.hide()
        self.dropButton.hide()

    def disableTreasureMapButtons(self):
        if self.tmButtonQuick:
            self.tmButtonQuick['state'] = 'disabled'

        if self.tmButtonSearch:
            self.tmButtonSearch['state'] = 'disabled'

        self.trackButton.hide()
        self.dropButton.hide()

    def startTreasureMap(self, tm, quick=True):
        if localAvatar.getAccess() != OTPGlobals.AccessFull:
            self.tmReadyDialog = PDialog.PDialog(
                text=PLocalizer.PlayTMVelvetRope,
                style=OTPDialog.Acknowledge,
                giveMouse=False,
                command=self.notReadyCallback)
            self.tmReadyDialog.show()
            return None

        if tm.getIsEnabled() or base.config.GetBool('black-pearl-ready', 0):
            DistributedBandMember = DistributedBandMember
            import pirates.band.DistributedBandMember
            if not DistributedBandMember.getBandMember(
                    localAvatar.doId) and quick == False:
                localAvatar.guiMgr.messageStack.addTextMessage(
                    PLocalizer.LookoutInviteNeedCrew, icon=('lookout', None))
                return None

            if localAvatar.testTeleportFlag(
                    PiratesGlobals.TFNoTeleport) == False:
                if base.cr.teleportMgr.inInstanceType == PiratesGlobals.INSTANCE_MAIN:
                    tm.requestTreasureMapGo(quick)
                elif base.cr.teleportMgr.inInstanceType == PiratesGlobals.INSTANCE_TM:
                    tm.requestTreasureMapLeave()

        else:
            self.tmReadyDialog = PDialog.PDialog(
                text=PLocalizer.PlayTMBlackPearlNotReady,
                style=OTPDialog.Acknowledge,
                giveMouse=False,
                command=self.notReadyCallback)
            self.tmReadyDialog.show()

    def notReadyCallback(self, args):
        self.tmReadyDialog.hide()

    def showSpecialInfo(self, containerId=None):
        if not self.specialInfoPanel.has_key(containerId):
            panelClass = self.specialInfoData[containerId].get('class')
            self.specialInfoPanel[containerId] = panelClass()
            self.specialInfoPanel[containerId].reparentTo(self.detailFrame)

        self.specialButton['text'] = self.specialInfoData[containerId].get(
            'buttonOff')
        self.specialButton['command'] = self.hideSpecialInfo
        self.specialInfoPanel[containerId].update()
        self.specialInfoPanel[containerId].show()
        self.detailFrame.setQuestTitleOnly(containerId)

    def hideSpecialInfo(self, containerId=None):
        for specialPanelId in self.specialInfoPanel.keys():
            self.specialInfoPanel[specialPanelId].hide()

        if containerId:
            self.showQuestDetails(containerId)
 def showDialogQuestOffer(self):
     if self.dialogQuestOffer:
         self.questDetailGUI = QuestDetailGUI(self.dialogQuestOffer, None)
         self.questDetailGUI.showPanel()
class DistributedQuestGiver(Avatar.Avatar):
    notify = directNotify.newCategory('DistributedQuestGiver')
    NoOffer = 0
    LadderOffer = 1
    QuestOffer = 2
    InteractOffer = 3
    BranchOffer = 4
    QuestIconWorkTexture = None
    QuestIconStoryTexture = None
    QuestIconProgressTexture = None
    QuestIconCompleteTexture = None
    QuestIconDontCare = 1
    QuestIconStory = 2
    QuestIconWork = 3
    QuestIconNew = 1
    QuestIconProgress = 2
    QuestIconComplete = 3

    def __init__(self):
        self.playingQuestString = False
        self.dialogOpen = False
        self.newOffer = False
        self.offers = None
        self.offerType = self.NoOffer
        self.dialogFlag = 0
        self.firstDialog = True
        self.newDialog = False
        self.npcMoviePlayer = None
        self.quitButton = 0
        self.nametagIcon = None
        self.nametagIconGlow = None
        self.containerId = None
        self.dialogAnimSet = None
        self.animationIval = None
        self.resetQuest = None
        self.resetBranch = None
        self.selectedOffer = None
        self.dialogProcessMaster = None
        self.dialogQuestOffer = None


    def generate(self):
        DistributedQuestGiver.notify.debug('generate(%s)' % self.doId)
        self.questMenuGUI = None
        self.questDetailGUI = None
        self.questRewardGUI = None
        self.branchMenuGUI = None
        self.questDetailCamera = None


    def announceGenerate(self):
        DistributedQuestGiver.notify.debug('announceGenerate(%s)' % self.doId)


    def disable(self):
        DistributedQuestGiver.notify.debug('disable(%s)' % self.doId)
        if self.npcMoviePlayer:
            self.npcMoviePlayer.cleanup()
            self.npcMoviePlayer = None

        self.cleanUpQuestMenu()
        self.cleanUpQuestDetails()
        self.cleanUpBranchMenu()
        self.ignore('endDialogNPCInteract')
        self.ignore('lastSubtitlePage')


    def cleanUpQuestMenu(self):
        if self.questMenuGUI:
            self.questMenuGUI.destroy()
            self.questMenuGUI = None



    def cleanUpBranchMenu(self):
        self.resetBranch = None
        self.selectedOffer = None
        if self.branchMenuGUI:
            self.branchMenuGUI.destroy()
            self.branchMenuGUI = None



    def cleanUpQuestDetails(self, hide = False):
        if self.questDetailGUI:
            if hide:
                self.questDetailGUI.hidePanelAndDestroy()
            else:
                self.questDetailGUI.destroy()
            self.questDetailGUI = None

        if self.questRewardGUI:
            if hide:
                self.questRewardGUI.hidePanelAndDestroy()
            else:
                self.questRewardGUI.destroy()
            self.questRewardGUI = None

        if not hide and self.questDetailCamera:
            self.questDetailCamera.finish()
            self.questDetailCamera = None



    def delete(self):
        DistributedQuestGiver.notify.debug('delete(%s)' % self.doId)


    def offerOptions(self):
        self.notify.warning('offerOptions() needs override!')


    def cancelInteraction(self, av):
        self.notify.warning('cancelInteraction() needs override!')


    def hasOpenGUI(self):
        self.notify.warning('hasOpenGUI() needs override!')
        return False


    def hasQuestOffers(self):
        AvailableQuests = []
        inventory = localAvatar.getInventory()
        prereqExcludes = base.config.GetString('exclude-prereq-quests', '')
        for (questId, questDNA) in QuestDB.QuestDict.items():
            if len(prereqExcludes):
                if questId in prereqExcludes:
                    continue


            prereqs = questDNA.getPrereqs()
            passed = True
            for prereq in prereqs:
                if not prereq.giverCanGive(self.getUniqueId()):
                    passed = False
                    break

                if not prereq.avIsReady(localAvatar):
                    passed = False
                    break

                if questDNA.minLevel > localAvatar.level:
                    passed = False
                    break

                if not base.cr.questDependency.checkDependency(questId, localAvatar.getQuestLadderHistory(), 1):
                    passed = False
                    break

                boolWeapLvlCheck = (questDNA.weapLvlType != None) & (questDNA.minWeapLevel > 0)
                if boolWeapLvlCheck & (questDNA.minWeapLevel > getLevelFromTotalReputation(questDNA.weapLvlType, inventory.getReputation(questDNA.weapLvlType))[0]):
                    passed = False
                    break

                if questDNA.getVelvetRoped() and not Freebooter.getPaidStatus(localAvatar.getDoId()):
                    passed = False
                    break

                if questDNA.getAcquireOnce():
                    history = localAvatar.getQuestLadderHistory()
                    questLadderId = base.cr.questDynMap.findQuestLadderInt(questId)
                    containsLadderId = history.count(questLadderId)
                    if containsLadderId:
                        passed = False
                        break


                if questDNA.getHoliday() is not None:
                    holidayId = questDNA.getHoliday()
                    if base.cr.newsManager and not base.cr.newsManager.getHoliday(holidayId):
                        passed = False
                        break

                not base.cr.newsManager.getHoliday(holidayId)

            if prereqs and passed:
                AvailableQuests.append(questDNA)
                continue

        if len(AvailableQuests):
            inventory = localAvatar.getInventory()
            if inventory:
                toRemove = []
                questList = inventory.getQuestList()
                for questDNA in AvailableQuests:
                    questId = questDNA.getQuestId()
                    found = False
                    for quest in questList:
                        if questId == quest.getQuestId() or localAvatar.questStatus.hasLadderQuestId(questId):
                            found = True
                            continue

                    if found:
                        toRemove.append(questDNA)
                        continue

                for questDNA in toRemove:
                    AvailableQuests.remove(questDNA)



        for quest in localAvatar.getQuests():
            if quest and quest.getTimeLimit() and quest.canBeReturnedTo(self.getQuestGiverId()):
                return True
                continue

        return len(AvailableQuests) > 0


    def receiveOffer(self, offerType):
        self.newOffer = True
        self.offerType = offerType


    def clearOffer(self):
        self.newOffer = False
        self.offerType = self.NoOffer


    def displayNewQuests(self):
        self.cleanUpQuestDetails()
        while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
            if localAvatar.currentStoryQuests[0].getGiverId() == '0':
                break

            localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])
        if len(localAvatar.currentStoryQuests):
            storyQuest = localAvatar.currentStoryQuests[0]
            self.presentQuestGiven(storyQuest)
            localAvatar.currentStoryQuests.remove(storyQuest)



    def presentOffer(self):
        if self.newOffer == False:
            while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
                localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])
            if len(localAvatar.currentStoryQuests):
                storyQuest = localAvatar.currentStoryQuests[0]
                self.presentQuestGiven(storyQuest)
                localAvatar.currentStoryQuests.remove(storyQuest)

            return None

        if self.offerType == self.QuestOffer:
            self.presentQuestOffer(self.offers)
        elif self.offerType == self.LadderOffer:
            self.presentQuestOffer(self.offers, ladder = True)
        elif self.offerType == self.InteractOffer:
            self.offerOptions(self.dialogFlag)
        elif self.offerType == self.NoOffer:
            self.notify.warning('offerType == No Offer')

        self.clearOffer()


    def setQuestOffer(self, offers):
        self.receiveOffer(self.QuestOffer)
        self.offers = offers
        for quest in localAvatar.getQuests():
            if quest.getTimeLimit() and quest.canBeReturnedTo(self.getQuestGiverId()):
                questOffer = QuestOffer.QuestTimerResetOffer.create(quest.getQuestId(), localAvatar, timerReset = True)
                offers.append(questOffer)

            branchParent = quest.getBranchParent(localAvatar)
            if branchParent and branchParent.getGiverId() == self.getQuestGiverId():
                questOffer = QuestOffer.QuestBranchResetOffer.create(quest.getQuestId(), localAvatar, branchReset = True)
                offers.append(questOffer)
                continue

        if not self.playingQuestString:
            self.presentQuestOffer(self.offers)



    def setQuestLadderOffer(self, offers, quitButton):
        self.receiveOffer(self.LadderOffer)
        self.offers = offers
        self.quitButton = quitButton
        if not self.playingQuestString:
            self.presentQuestOffer(self.offers, ladder = True)



    def presentQuestOffer(self, offers, ladder = False):
        if self.questMenuGUI:
            DistributedQuestGiver.notify.warning('setQuestOffer: old questMenu GUI still around')
            self.cleanUpQuestMenu()

        self.cleanUpQuestDetails()

        def handleSelection(offer, self = self, offers = offers):
            self.cleanUpQuestMenu()
            if offer == QuestConstants.CANCEL_QUEST:
                index = QuestConstants.CANCEL_QUEST
            else:
                index = offers.index(offer)
            self.sendOfferResponse(index, ladder)


        def handleOption(option, offer):
            base.test = self
            self.ignore('lastSubtitlePage')
            self.adjustNPCCamera('back')
            if option == PLocalizer.Accept:
                handleSelection(offer)
            elif self.questMenuGUI:
                self.questMenuGUI.show()

            self.cleanUpQuestDetails(hide = True)


        def displayQuestDetails(offer):
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI


        def displayBranchDetails(offer):
            self.selectedOffer = offer
            self.cleanUpQuestDetails()
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI


        def displayBranchOptions(offer, callback, descCallback):
            self.branchMenuGUI = BranchMenuGUI.BranchMenuGUI(offer, callback, descCallback)


        def handleBranchOption(option):
            if option == PLocalizer.Accept:
                if self.selectedOffer:
                    self.sendOfferResponse(0, ladder, self.selectedOffer)


            self.adjustNPCCamera('back')
            self.cleanUpQuestDetails(hide = True)
            self.cleanUpBranchMenu()
            if self.questMenuGUI:
                self.questMenuGUI.show()



        def describeQuest(offer):
            self.adjustNPCCamera('forward')
            questDNA = offer.getQuestDNA()
            if questDNA:
                if isinstance(offer, QuestOffer.QuestTimerResetOffer):
                    self.requestQuestReset(offer.getQuestId())
                    return None
                elif isinstance(offer, QuestOffer.QuestBranchResetOffer):
                    self.requestBranchReset(offer.getQuestId())
                    return None

                questStr = questDNA.getStringBefore()
                if questDNA.isBranch():
                    self.acceptOnce('lastSubtitlePage', displayBranchOptions, [
                        offer,
                        None,
                        displayBranchDetails])
                    localAvatar.guiMgr.subtitler.setPageChat(questStr, options = [
                        PLocalizer.Decline,
                        PLocalizer.Accept], callback = handleBranchOption)
                else:
                    self.acceptOnce('lastSubtitlePage', displayQuestDetails, [
                        offer])
                    localAvatar.guiMgr.subtitler.setPageChat(questStr, options = [
                        PLocalizer.Decline,
                        PLocalizer.Accept], callback = handleOption, extraArgs = [
                        offer])



        def questFull(arg):
            self.cleanUpQuestMenu()
            self.sendOfferResponse(QuestConstants.CANCEL_QUEST, ladder)

        inv = base.localAvatar.getInventory()
        numWorkQuests = 0
        if inv:
            questList = inv.getQuestList()
            for questId in questList:
                if not QuestLadderDB.getFamePath(questId):
                    numWorkQuests += 1
                    continue


        hasStoryQuest = False
        for offer in offers:
            if QuestLadderDB.getFamePath(offer.getQuestId()):
                hasStoryQuest = True
                continue

        if not hasStoryQuest and numWorkQuests > QuestConstants.MAXIMUM_MERC_WORK:
            self.questMenuGUI = PDialog.PDialog(text = PLocalizer.QuestFull, style = OTPDialog.Acknowledge, command = questFull)
        else:
            self.questMenuGUI = QuestMenuGUI.QuestMenuGUI(offers, handleSelection, describeQuest)
        localAvatar.currentStoryQuests = []
        self.clearOffer()


    def presentBranchReset(self, declineOption = True):
        if not self.resetBranch:
            return None


        def displayBranchOptions(offer, callback, descCallback):
            self.branchMenuGUI = BranchMenuGUI.BranchMenuGUI(offer, callback, descCallback)


        def displayBranchDetails(offer):
            self.selectedOffer = offer
            self.cleanUpQuestDetails()
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI
            subtitleOptions = [
                PLocalizer.Accept]
            if declineOption:
                subtitleOptions = [
                    PLocalizer.Decline,
                    PLocalizer.Accept]

            localAvatar.guiMgr.subtitler.setPageChat('Is that your choice?', options = subtitleOptions, callback = handleBranchOption)


        def handleBranchOption(option):
            if option == PLocalizer.Accept:
                if self.selectedOffer:
                    self.sendOfferResponse(0, offer = self.selectedOffer)

            else:
                self.offerOptions(False)
            self.adjustNPCCamera('back')
            self.cleanUpQuestDetails(hide = True)
            self.cleanUpBranchMenu()
            self.cleanUpQuestMenu()

        offer = QuestOffer.QuestOffer.create(self.resetBranch.getName(), localAvatar)
        if declineOption:
            subtitleOptions = [
                PLocalizer.Decline]
            self.acceptOnce('lastSubtitlePage', displayBranchOptions, [
                offer,
                None,
                displayBranchDetails])
            localAvatar.guiMgr.subtitler.setPageChat('', options = subtitleOptions, callback = handleBranchOption)
        else:
            subtitleOptions = []
            displayBranchOptions(offer, None, displayBranchDetails)
        self.ignore('doneChatPage')


    def presentQuestReset(self):
        if not self.resetQuest:
            return None


        def handleOption(option):
            if option == PLocalizer.Accept:
                self.resetQuest.startTimer()

            self.resetQuest = None
            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, self.resetQuest.questDNA)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)


    def presentQuestGiven(self, quest):
        self.resetBranch = None
        if self.resetBranch:
            container = localAvatar.questStatus.getContainer(quest.getQuestId())
            if container.parent and container.parent.getFirstQuestId() == quest.getQuestId():
                self.presentBranchReset(False)
                return None
            else:
                self.resetBranch = None


        def handleOption(option):
            if len(localAvatar.currentStoryQuests):
                self.cleanUpQuestDetails(hide = True)
                while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
                    localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])

            if len(localAvatar.currentStoryQuests):
                storyQuest = localAvatar.currentStoryQuests[0]
                self.presentQuestGiven(storyQuest)
                localAvatar.currentStoryQuests.remove(storyQuest)
            elif hasattr(quest, 'questDNA') and quest.questDNA.getTimeLimit():
                quest.startTimer()

            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, quest)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)
        base.questdet = self.questDetailGUI
        self.ignore('doneChatPage')


    def adjustNPCCamera(self, direction):
        dummy = NodePath('dummy')
        dummy.reparentTo(camera)
        if direction == 'forward':
            dummy.setH(dummy, -15)
            dummy.setY(dummy, 0.75)
            duration = 0.69999999999999996
        else:
            dummy.setY(dummy, -0.75)
            dummy.setH(dummy, 15)
            duration = 0.5
        dummy.wrtReparentTo(camera.getParent())
        (camH, dummyH) = getShortestRotation(camera.getH(), dummy.getH())
        self.questDetailCamera = Parallel(LerpFunc(camera.setH, duration = duration, fromData = camH, toData = dummyH, blendType = 'easeInOut'), LerpFunc(camera.setY, duration = duration, fromData = camera.getY(), toData = dummy.getY(), blendType = 'easeInOut'))
        dummy.removeNode()
        self.questDetailCamera.start()


    def getOfferedQuests(self):
        return list(self.offers)


    def sendOfferResponse(self, index, ladder = False, offer = None):
        if index == QuestConstants.CANCEL_QUEST:
            self.dialogOpen = False

        if offer:
            self.sendUpdate('assignBranchOffer', [
                offer])
        else:
            self.sendUpdate('setOfferResponse', [
                index,
                ladder])
        self.offers = None
        self.clearOffer()


    def b_setPageNumber(self, paragraph, pageNumber):
        self.setPageNumber(paragraph, pageNumber)
        self.d_setPageNumber(paragraph, pageNumber)


    def d_setPageNumber(self, paragraph, pageNumber):
        pass


    def playQuestString(self, questStr, timeout = False, quitButton = 1, useChatBubble = False, confirm = False, animSet = None):
        self.notify.debug('playQuestString %s, %s, %s, %s' % (timeout, quitButton, useChatBubble, confirm))
        if questStr.find('quest_') == 0:
            nmp = QuestParser.NPCMoviePlayer(questStr, localAvatar, self)
            nmp.play()
            self.npcMoviePlayer = nmp
        else:
            self.firstDialog = False
            self.dialogAnimSet = animSet
            if questStr:
                if timeout:
                    if useChatBubble:
                        self.setPageChat(localAvatar.doId, 0, questStr, 0, extraChatFlags = CFSpeech | CFTimeout, pageButton = False)
                    else:
                        base.localAvatar.guiMgr.subtitler.setPageChat(questStr, timeout = timeout)
                    return None
                else:
                    self.playingQuestString = True
                    base.localAvatar.guiMgr.subtitler.setPageChat(questStr, confirm = confirm)
                    self.dialogOpen = True
                self.playAnimation(0)
                if quitButton == 1 or confirm:
                    self.accept('doneChatPage', self._DistributedQuestGiver__handleDoneChatPage)

                if base.localAvatar.guiMgr.subtitler.getNumChatPages() == 1:
                    self._DistributedQuestGiver__handleNextChatPage(0, 0)
                else:
                    self.accept('nextChatPage', self._DistributedQuestGiver__handleNextChatPage)



    def _DistributedQuestGiver__handleNextChatPage(self, pageNumber, elapsed):
        self.notify.debug('handleNextChatPage pageNumber = %s, elapsed = %s' % (pageNumber, elapsed))
        if pageNumber == base.localAvatar.guiMgr.subtitler.getNumChatPages() - 1:
            self.ignore('nextChatPage')
            self.playingQuestString = False
            self.presentBranchReset()
            self.presentQuestReset()
            self.presentOffer()

        self.playAnimation(pageNumber)


    def _DistributedQuestGiver__handleDoneChatPage(self, elapsed):
        self.ignore('nextChatPage')
        self.ignore('doneChatPage')
        self.playingQuestString = False
        self.dialogOpen = False
        if self.newDialog:
            self.playDialog()

        if not self.hasOpenGUI():
            self.interactMode = 1
            self.cancelInteraction(base.localAvatar)

        self.cancelInteraction(base.localAvatar)


    def playAnimation(self, index):
        if self.animationIval:
            self.animationIval.finish()
            self.animationIval = None

        if self.dialogAnimSet:
            if len(self.dialogAnimSet) > index and self.dialogAnimSet[index]:
                self.animationIval = Sequence(Wait(0.5), Func(self.gameFSM.request, 'Emote'), Func(self.playEmote, self.dialogAnimSet[index]))
                self.animationIval.start()




    def playDialog(self):
        self.notify.warning('playDialog() needs override!')


    def setQuestsCompleted(self, menuFlag, completedContainerIds, completedChainedQuestIds, completedQuestIds, completedQuestDoIds):
        questStr = ''
        self.cleanUpQuestDetails()

        def handleOption(option, questStr, menuFlag, confirm, animSet):
            self.cleanUpQuestDetails(hide = True)
            self.playQuestString(questStr, quitButton = menuFlag, confirm = True, animSet = animSet)

        if len(completedContainerIds):
            if completedContainerIds[0] in [
                'c3visitJack']:
                return None

            if len(completedContainerIds) > 1:
                self.notify.warning('Multiple simultaneous completed quest containers for the same NPC: %s!' % completedContainerIds)

            containerId = completedContainerIds[0]
            self.containerId = containerId
            container = QuestLadderDB.getContainer(containerId)
            if container:
                dialogId = container.getDialogAfter()
                if dialogId:
                    self.requestDialog(dialogId)
                    return None

                questStr = container.getStringAfter()
                animSet = container.getAnimSetAfter()
                localAvatar.b_setGameState('NPCInteract', localArgs = [
                    self,
                    False,
                    False])
                if hasattr(self, '_questRewardsEarned'):
                    self.questRewardGUI = QuestRewardGUI(container, self._questRewardsEarned)
                    localAvatar.guiMgr.subtitler.setPageChat('', options = [
                        PLocalizer.Continue], callback = handleOption, extraArgs = [
                        questStr,
                        menuFlag,
                        True,
                        animSet])
                else:
                    handleOption(questStr, menuFlag, True, animSet)
                return None
            else:
                self.notify.warning('%s not in QuestLadderDB!' % containerId)

        if len(completedChainedQuestIds):
            pass
        1
        if len(completedQuestIds):
            if len(completedContainerIds) == 0:
                questId = completedQuestIds[0]
                quest = QuestDB.QuestDict.get(questId)
                if quest:
                    questStr = quest.getStringAfter()
                    animSet = quest.getAnimSetAfter()
                    self.notify.debug('%s stringAfter: %s' % (questId, questStr))
                    if hasattr(self, '_questRewardsEarned'):
                        print 'GOT questRewardsEarned: %s' % self._questRewardsEarned
                        self.questRewardGUI = QuestRewardGUI(quest, self._questRewardsEarned)
                        localAvatar.guiMgr.subtitler.setPageChat('', options = [
                            PLocalizer.Continue], callback = handleOption, extraArgs = [
                            questStr,
                            menuFlag,
                            True,
                            animSet])
                    else:
                        handleOption(questStr, menuFlag, True, animSet)
                else:
                    self.notify.warning('%s not in QuestDB!' % questId)

            localAvatar.b_setGameState('NPCInteract', localArgs = [
                self,
                True,
                False])

        if len(completedQuestIds) == 0 and len(completedChainedQuestIds) == 0 and len(completedContainerIds) == 0:
            if not self.hasOpenGUI():
                self.cancelInteraction(base.localAvatar)




    def requestQuestReset(self, questId):
        self.resetQuest = localAvatar.getQuestById(questId)
        if self.resetQuest:
            questStr = self.resetQuest.questDNA.getStringBefore()
            self.cleanUpQuestDetails(hide = True)
            self.playQuestString(questStr, quitButton = True, confirm = True)
            localAvatar.b_setGameState('NPCInteract', localArgs = [
                self,
                True,
                False])



    def requestBranchReset(self, questId):
        quest = localAvatar.getQuestById(questId)
        self.resetBranch = quest.getBranchParent(localAvatar)
        resetBranchDNA = QuestLadderDB.getContainer(self.resetBranch.getQuestId())
        questStr = resetBranchDNA.getStringBefore()
        self.cleanUpQuestDetails(hide = True)
        self.playQuestString(questStr, quitButton = False, confirm = True)
        localAvatar.b_setGameState('NPCInteract', localArgs = [
            self,
            True,
            False])


    def requestDialog(self, dialogId = None):
        self.endDialog()
        if not dialogId:
            availableDialogs = []
            npcDialogs = DialogDict.get(self.getUniqueId())
            if npcDialogs:
                for dialogId in npcDialogs:
                    firstDialogProcess = npcDialogs.get(dialogId).get(0)[0]
                    if firstDialogProcess.prereq and firstDialogProcess.avCanParticipate(localAvatar):
                        availableDialogs.append(dialogId)
                        continue


        else:
            availableDialogs = [
                dialogId]
        localAvatar.b_setGameState('NPCInteract', localArgs = [
            self,
            True,
            True])
        self.accept('endDialogNPCInteract', self.endDialog)
        self.dialogProcessMaster = DialogProcessMaster(self, availableDialogs)
        taskMgr.doMethodLater(0.25, self.startDialog, 'startDialogProcessMaster')


    def startDialog(self, task = None):
        if self.dialogProcessMaster:
            self.dialogProcessMaster.start()



    def endDialog(self):
        taskMgr.remove('startDialogProcessMaster')
        self.ignore('endDialogNPCInteract')
        if self.dialogProcessMaster:
            self.dialogProcessMaster.stop()
            self.dialogProcessMaster = None



    def requestDialogInteraction(self, dialogId):
        self.sendUpdate('requestDialogInteraction', [
            dialogId])


    def endDialogInteraction(self, dialogId):
        self.sendUpdate('endDialogInteraction', [
            dialogId])


    def requestDialogQuestAdvancement(self, questId, dialogId):
        self.sendUpdate('requestDialogQuestAdvancement', [
            questId,
            dialogId])


    def requestDialogQuestAssignment(self, questId, dialogId):
        self.sendUpdate('requestDialogQuestAssignment', [
            questId,
            dialogId])


    def requestDialogQuestOffer(self, questId, dialogId):
        self.sendUpdate('requestDialogQuestOffer', [
            questId,
            dialogId])


    def setDialogQuestOffer(self, questOffer):
        self.dialogQuestOffer = questOffer
        messenger.send('setDialogQuestOffer')


    def showDialogQuestOffer(self):
        if self.dialogQuestOffer:
            self.questDetailGUI = QuestDetailGUI(self.dialogQuestOffer, None)
            self.questDetailGUI.showPanel()



    def assignDialogQuestOffer(self):
        if self.dialogQuestOffer:
            self.sendUpdate('assignDialogQuestOffer')



    def showQuestRewards(self):
        if hasattr(self, '_questRewardsEarned') and self.containerId:
            container = QuestLadderDB.getContainer(self.containerId)
            self.questRewardGUI = QuestRewardGUI(container, self._questRewardsEarned)



    def hideQuestRewards(self):
        if self.questRewardGUI:
            self.questRewardGUI.destroy()
            self.questRewardGUI = None



    def requestNPCHostile(self, npcId, dialogId):
        self.sendUpdate('requestNPCHostile', [
            npcId,
            dialogId])


    def playDialogMovie(self, dialogId, doneCallback = None, oldLocalAvState = None):
        movieChoice = InteractGlobals.getNPCTutorial(dialogId)
        if movieChoice == None:
            movieChoice = dialogId

        globalClock.tick()
        self.currentDialogMovie = QuestParser.NPCMoviePlayer(movieChoice, localAvatar, self)
        self.currentDialogMovie.overrideOldAvState(oldLocalAvState)
        self.currentDialogMovie.play()
        self.acceptOnce('dialogFinish', self.stopDialogMovie, extraArgs = [
            doneCallback])


    def stopDialogMovie(self, doneCallback):
        if hasattr(self, 'currentDialogMovie'):
            self.currentDialogMovie.npc.showName()
            self.currentDialogMovie.npc.nametag3d.setZ(0)
            self.currentDialogMovie.finishUpAll()
            del self.currentDialogMovie
            self.sendUpdate('dialogMovieComplete')
            if doneCallback:
                doneCallback()




    def swapCurrentDialogMovie(self, newDialogMovie):
        if hasattr(self, 'currentDialogMovie'):
            if newDialogMovie:
                oldAvState = self.currentDialogMovie.overrideOldAvState(None)
                newDialogMovie.overrideOldAvState(oldAvState)

            self.currentDialogMovie.finishUpAll()

        self.currentDialogMovie = newDialogMovie


    def getQuestGiverId(self):
        return self.getUniqueId()


    def hasQuestOffersForLocalAvatar(self):
        av = localAvatar
        inventory = av.getInventory()
        selfId = self.getQuestGiverId()
        if inventory:
            numInProgress = 0
            for quest in inventory.getQuestList():
                questType = self.QuestIconDontCare
                if quest.tasks is None:
                    self.notify.warning('quest %s: does not contain a dna; potential for crash.' % quest.getQuestId())
                    return False

                for (task, taskState) in zip(quest.tasks, quest.taskStates):
                    if isinstance(task, QuestTaskDNA.VisitTaskDNA):
                        if task.npcId == selfId:
                            questStatus = self.QuestIconComplete
                            return (questType, questStatus)

                    task.npcId == selfId

                if quest.canBeReturnedTo(selfId):
                    isComplete = False
                    if quest.isComplete():
                        container = localAvatar.questStatus.getContainer(quest.getQuestId())
                        if container and container.parent and container.parent.isChoice():
                            isComplete = True
                            for q in container.parent.getContainers():
                                if q.quest and not q.quest.isComplete():
                                    isComplete = False
                                    continue

                        else:
                            isComplete = True

                    if isComplete:
                        questStatus = self.QuestIconComplete
                        return (questType, questStatus)
                    else:
                        numInProgress += 1

        else:
            self.notify.warning('avatar does not have inventory yet')
            return False
        offerDict = { }
        fromQuests = []
        prereqExcludes = base.config.GetString('exclude-prereq-quests', '')
        for (questId, questDNA) in QuestDB.QuestDict.items():
            if prereqExcludes and questId in prereqExcludes:
                continue

            passed = True
            for prereq in questDNA.prereqs:
                if not prereq.giverCanGive(selfId):
                    passed = False
                    break

                if not prereq.avIsReady(localAvatar):
                    passed = False
                    break

                if questDNA.minLevel > localAvatar.level:
                    passed = False
                    break

                if not base.cr.questDependency.checkDependency(questId, localAvatar.getQuestLadderHistory(), 1):
                    passed = False
                    break

                boolWeapLvlCheck = (questDNA.weapLvlType != None) & (questDNA.minWeapLevel > 0)
                if boolWeapLvlCheck & (questDNA.minWeapLevel > getLevelFromTotalReputation(questDNA.weapLvlType, inventory.getReputation(questDNA.weapLvlType))[0]):
                    passed = False
                    break

                if questDNA.getAcquireOnce():
                    history = localAvatar.getQuestLadderHistory()
                    questLadderId = base.cr.questDynMap.findQuestLadderInt(questId)
                    containsLadderId = history.count(questLadderId)
                    if containsLadderId:
                        passed = False
                        break


                if questDNA.getHoliday() is not None:
                    holidayId = questDNA.getHoliday()
                    if base.cr.newsManager and not base.cr.newsManager.getHoliday(holidayId):
                        passed = False
                        break

                not base.cr.newsManager.getHoliday(holidayId)

            if questDNA.prereqs and passed:
                fromQuests.append(questDNA)
                continue

        if len(fromQuests):
            inventory = av.getInventory()
            if inventory:
                questsLeft = []
                questList = inventory.getQuestList()
                for questDNA in fromQuests:
                    questId = questDNA.questId
                    if not av.questStatus.hasLadderQuestId(questId):
                        continue
                        if _[1] not in [ x.questId for x in questList ]:
                            questsLeft.append(questDNA)
                            continue
                    []

                fromQuests = questsLeft


        if fromQuests:
            questType = self.QuestIconWork
            for quest in fromQuests:
                if QuestLadderDB.getFamePath(quest.questId):
                    questType = self.QuestIconStory
                    break
                    continue

            questStatus = self.QuestIconNew
            return (questType, questStatus)

        if numInProgress:
            questStatus = self.QuestIconProgress
            return (questType, questStatus)

        return False


    def loadQuestIcons(self):
        if not DistributedQuestGiver.QuestIconWorkTexture:
            DistributedQuestGiver.QuestIconWorkTexture = loader.loadModel('models/gui/new_work_quest_icon')
            DistributedQuestGiver.QuestIconStoryTexture = loader.loadModel('models/gui/new_story_quest_icon')
            discardNP = DistributedQuestGiver.QuestIconStoryTexture.find('**/pPlane2')
            if not discardNP.isEmpty():
                discardNP.removeNode()

            gui = loader.loadModel('models/gui/toplevel_gui')
            DistributedQuestGiver.QuestIconProgressTexture = gui.find('**/quest_pending_icon')
            DistributedQuestGiver.QuestIconCompleteTexture = gui.find('**/reward_waiting_icon')



    def updateNametagQuestIcon(self, questId = None, item = None, note = None):
        offers = self.hasQuestOffersForLocalAvatar()
        if self.nametagIcon:
            self.nametagIcon.removeNode()

        if self.nametagIconGlow:
            self.nametagIconGlow.removeNode()

        self.loadQuestIcons()
        if offers:
            (type, status) = offers
            if status == DistributedQuestGiver.QuestIconNew:
                if type == DistributedQuestGiver.QuestIconStory:
                    self.nametagIcon = DistributedQuestGiver.QuestIconStoryTexture.copyTo(self.nametag3d)
                else:
                    self.nametagIcon = DistributedQuestGiver.QuestIconStoryTexture.copyTo(self.nametag3d)
                self.nametagIcon.setScale(3.5)
            elif status == DistributedQuestGiver.QuestIconComplete:
                self.nametagIcon = DistributedQuestGiver.QuestIconCompleteTexture.copyTo(self.nametag3d)
                self.nametagIcon.setScale(12)
            elif status == DistributedQuestGiver.QuestIconProgress:
                self.nametagIcon = DistributedQuestGiver.QuestIconProgressTexture.copyTo(self.nametag3d)
                self.nametagIcon.setScale(12)
            else:
                self.notify.error('invalid quest status: %s or type: %s' % (status, type))
        elif self.nametagIcon:
            self.nametagIcon.detachNode()

        if self.nametagIconGlow:
            self.nametagIconGlow.detachNode()

        if self.nametagIcon:
            self.nametagIcon.setPos(0, 0, 3.5)
            if self.getNameText() is None:
                base.cr.centralLogger.writeClientEvent('NPC %s, %s: has no nameText, type = %s, status = %s!' % (self, self.getName(), type, status))
                if self.nametagIcon:
                    self.nametagIcon.detachNode()

                if self.nametagIconGlow:
                    self.nametagIconGlow.detachNode()

                return None

            self.nametagIcon.reparentTo(self.getNameText())
            self.nametagIcon.setDepthWrite(0)
            if status == DistributedQuestGiver.QuestIconComplete or status == DistributedQuestGiver.QuestIconNew:
                self.nametagIconGlow = loader.loadModel('models/effects/lanternGlow')
                self.nametagIconGlow.reparentTo(self.nametag.getNameIcon())
                self.nametagIconGlow.setScale(20.0)
                self.nametagIconGlow.setColorScaleOff()
                self.nametagIconGlow.setFogOff()
                self.nametagIconGlow.setLightOff()
                self.nametagIconGlow.setPos(0, -0.050000000000000003, 3.0)
                self.nametagIconGlow.setDepthWrite(0)
                self.nametagIconGlow.node().setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOne))
                self.nametagIconGlow.setColor(0.84999999999999998, 0.84999999999999998, 0.84999999999999998, 0.84999999999999998)


        self.loadShopCoin()


    def forceDoneChatPage(self):
        self._DistributedQuestGiver__handleDoneChatPage(0)
 def displayQuestDetails(offer):
     self.questDetailGUI = QuestDetailGUI(offer, None)
     self.questDetailGUI.showPanel()
     base.questdet = self.questDetailGUI
 def displayBranchDetails(offer):
     self.selectedOffer = offer
     self.cleanUpQuestDetails()
     self.questDetailGUI = QuestDetailGUI(offer, None)
     self.questDetailGUI.showPanel()
     base.questdet = self.questDetailGUI
 def displayQuestDetails(offer):
     self.questDetailGUI = QuestDetailGUI(offer, None)
     self.questDetailGUI.showPanel()
     base.questdet = self.questDetailGUI
class DistributedQuestGiver(Avatar.Avatar):
    notify = directNotify.newCategory('DistributedQuestGiver')
    NoOffer = 0
    LadderOffer = 1
    QuestOffer = 2
    InteractOffer = 3
    BranchOffer = 4
    QuestIconWorkTexture = None
    QuestIconStoryTexture = None
    QuestIconProgressTexture = None
    QuestIconCompleteTexture = None
    QuestIconDontCare = 1
    QuestIconStory = 2
    QuestIconWork = 3
    QuestIconNew = 1
    QuestIconProgress = 2
    QuestIconComplete = 3
    
    def __init__(self):
        self.playingQuestString = False
        self.dialogOpen = False
        self.newOffer = False
        self.offers = None
        self.offerType = self.NoOffer
        self.dialogFlag = 0
        self.firstDialog = True
        self.newDialog = False
        self.npcMoviePlayer = None
        self.quitButton = 0
        self.nametagIcon = None
        self.nametagIconGlow = None
        self.containerId = None
        self.dialogAnimSet = None
        self.animationIval = None
        self.resetQuest = None
        self.resetBranch = None
        self.selectedOffer = None
        self.dialogProcessMaster = None
        self.dialogQuestOffer = None

    
    def generate(self):
        DistributedQuestGiver.notify.debug('generate(%s)' % self.doId)
        self.questMenuGUI = None
        self.questDetailGUI = None
        self.questRewardGUI = None
        self.branchMenuGUI = None
        self.questDetailCamera = None

    
    def announceGenerate(self):
        DistributedQuestGiver.notify.debug('announceGenerate(%s)' % self.doId)

    
    def disable(self):
        DistributedQuestGiver.notify.debug('disable(%s)' % self.doId)
        if self.npcMoviePlayer:
            self.npcMoviePlayer.cleanup()
            self.npcMoviePlayer = None
        
        self.cleanUpQuestMenu()
        self.cleanUpQuestDetails()
        self.cleanUpBranchMenu()
        self.ignore('endDialogNPCInteract')
        self.ignore('lastSubtitlePage')

    
    def cleanUpQuestMenu(self):
        if self.questMenuGUI:
            self.questMenuGUI.destroy()
            self.questMenuGUI = None
        

    
    def cleanUpBranchMenu(self):
        self.resetBranch = None
        self.selectedOffer = None
        if self.branchMenuGUI:
            self.branchMenuGUI.destroy()
            self.branchMenuGUI = None
        

    
    def cleanUpQuestDetails(self, hide = False):
        if self.questDetailGUI:
            if hide:
                self.questDetailGUI.hidePanelAndDestroy()
            else:
                self.questDetailGUI.destroy()
            self.questDetailGUI = None
        
        if self.questRewardGUI:
            if hide:
                self.questRewardGUI.hidePanelAndDestroy()
            else:
                self.questRewardGUI.destroy()
            self.questRewardGUI = None
        
        if not hide and self.questDetailCamera:
            self.questDetailCamera.finish()
            self.questDetailCamera = None
        

    
    def delete(self):
        DistributedQuestGiver.notify.debug('delete(%s)' % self.doId)

    
    def offerOptions(self):
        self.notify.warning('offerOptions() needs override!')

    
    def cancelInteraction(self, av):
        self.notify.warning('cancelInteraction() needs override!')

    
    def hasOpenGUI(self):
        self.notify.warning('hasOpenGUI() needs override!')
        return False

    
    def hasQuestOffers(self):
        AvailableQuests = []
        inventory = localAvatar.getInventory()
        prereqExcludes = base.config.GetString('exclude-prereq-quests', '')
        for (questId, questDNA) in QuestDB.QuestDict.items():
            if len(prereqExcludes):
                if questId in prereqExcludes:
                    continue
                
            
            prereqs = questDNA.getPrereqs()
            passed = True
            for prereq in prereqs:
                if not prereq.giverCanGive(self.getUniqueId()):
                    passed = False
                    break
                
                if not prereq.avIsReady(localAvatar):
                    passed = False
                    break
                
                if questDNA.minLevel > localAvatar.level:
                    passed = False
                    break
                
                if not base.cr.questDependency.checkDependency(questId, localAvatar.getQuestLadderHistory(), 1):
                    passed = False
                    break
                
                boolWeapLvlCheck = (questDNA.weapLvlType != None) & (questDNA.minWeapLevel > 0)
                if boolWeapLvlCheck & (questDNA.minWeapLevel > getLevelFromTotalReputation(questDNA.weapLvlType, inventory.getReputation(questDNA.weapLvlType))[0]):
                    passed = False
                    break
                
                if questDNA.getVelvetRoped() and not Freebooter.getPaidStatus(localAvatar.getDoId()):
                    passed = False
                    break
                
                if questDNA.getAcquireOnce():
                    history = localAvatar.getQuestLadderHistory()
                    questLadderId = base.cr.questDynMap.findQuestLadderInt(questId)
                    containsLadderId = history.count(questLadderId)
                    if containsLadderId:
                        passed = False
                        break
                    
                
                if questDNA.getHoliday() is not None:
                    holidayId = questDNA.getHoliday()
                    if base.cr.newsManager and not base.cr.newsManager.getHoliday(holidayId):
                        passed = False
                        break
                    
                not base.cr.newsManager.getHoliday(holidayId)
            
            if prereqs and passed:
                AvailableQuests.append(questDNA)
                continue
        
        if len(AvailableQuests):
            inventory = localAvatar.getInventory()
            if inventory:
                toRemove = []
                questList = inventory.getQuestList()
                for questDNA in AvailableQuests:
                    questId = questDNA.getQuestId()
                    found = False
                    for quest in questList:
                        if questId == quest.getQuestId() or localAvatar.questStatus.hasLadderQuestId(questId):
                            found = True
                            continue
                    
                    if found:
                        toRemove.append(questDNA)
                        continue
                
                for questDNA in toRemove:
                    AvailableQuests.remove(questDNA)
                
            
        
        for quest in localAvatar.getQuests():
            if quest and quest.getTimeLimit() and quest.canBeReturnedTo(self.getQuestGiverId()):
                return True
                continue
        
        return len(AvailableQuests) > 0

    
    def receiveOffer(self, offerType):
        self.newOffer = True
        self.offerType = offerType

    
    def clearOffer(self):
        self.newOffer = False
        self.offerType = self.NoOffer

    
    def displayNewQuests(self):
        self.cleanUpQuestDetails()
        while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
            if localAvatar.currentStoryQuests[0].getGiverId() == '0':
                break
            
            localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])
        if len(localAvatar.currentStoryQuests):
            storyQuest = localAvatar.currentStoryQuests[0]
            self.presentQuestGiven(storyQuest)
            localAvatar.currentStoryQuests.remove(storyQuest)
        

    
    def presentOffer(self):
        if self.newOffer == False:
            while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
                localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])
            if len(localAvatar.currentStoryQuests):
                storyQuest = localAvatar.currentStoryQuests[0]
                self.presentQuestGiven(storyQuest)
                localAvatar.currentStoryQuests.remove(storyQuest)
            
            return None
        
        if self.offerType == self.QuestOffer:
            self.presentQuestOffer(self.offers)
        elif self.offerType == self.LadderOffer:
            self.presentQuestOffer(self.offers, ladder = True)
        elif self.offerType == self.InteractOffer:
            self.offerOptions(self.dialogFlag)
        elif self.offerType == self.NoOffer:
            self.notify.warning('offerType == No Offer')
        
        self.clearOffer()

    
    def setQuestOffer(self, offers):
        self.receiveOffer(self.QuestOffer)
        self.offers = offers
        for quest in localAvatar.getQuests():
            if quest.getTimeLimit() and quest.canBeReturnedTo(self.getQuestGiverId()):
                questOffer = QuestOffer.QuestTimerResetOffer.create(quest.getQuestId(), localAvatar, timerReset = True)
                offers.append(questOffer)
            
            branchParent = quest.getBranchParent(localAvatar)
            if branchParent and branchParent.getGiverId() == self.getQuestGiverId():
                questOffer = QuestOffer.QuestBranchResetOffer.create(quest.getQuestId(), localAvatar, branchReset = True)
                offers.append(questOffer)
                continue
        
        if not self.playingQuestString:
            self.presentQuestOffer(self.offers)
        

    
    def setQuestLadderOffer(self, offers, quitButton):
        self.receiveOffer(self.LadderOffer)
        self.offers = offers
        self.quitButton = quitButton
        if not self.playingQuestString:
            self.presentQuestOffer(self.offers, ladder = True)
        

    
    def presentQuestOffer(self, offers, ladder = False):
        if self.questMenuGUI:
            DistributedQuestGiver.notify.warning('setQuestOffer: old questMenu GUI still around')
            self.cleanUpQuestMenu()
        
        self.cleanUpQuestDetails()
        
        def handleSelection(offer, self = self, offers = offers):
            self.cleanUpQuestMenu()
            if offer == QuestConstants.CANCEL_QUEST:
                index = QuestConstants.CANCEL_QUEST
            else:
                index = offers.index(offer)
            self.sendOfferResponse(index, ladder)

        
        def handleOption(option, offer):
            base.test = self
            self.ignore('lastSubtitlePage')
            self.adjustNPCCamera('back')
            if option == PLocalizer.Accept:
                handleSelection(offer)
            elif self.questMenuGUI:
                self.questMenuGUI.show()
            
            self.cleanUpQuestDetails(hide = True)

        
        def displayQuestDetails(offer):
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI

        
        def displayBranchDetails(offer):
            self.selectedOffer = offer
            self.cleanUpQuestDetails()
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI

        
        def displayBranchOptions(offer, callback, descCallback):
            self.branchMenuGUI = BranchMenuGUI.BranchMenuGUI(offer, callback, descCallback)

        
        def handleBranchOption(option):
            if option == PLocalizer.Accept:
                if self.selectedOffer:
                    self.sendOfferResponse(0, ladder, self.selectedOffer)
                
            
            self.adjustNPCCamera('back')
            self.cleanUpQuestDetails(hide = True)
            self.cleanUpBranchMenu()
            if self.questMenuGUI:
                self.questMenuGUI.show()
            

        
        def describeQuest(offer):
            self.adjustNPCCamera('forward')
            questDNA = offer.getQuestDNA()
            if questDNA:
                if isinstance(offer, QuestOffer.QuestTimerResetOffer):
                    self.requestQuestReset(offer.getQuestId())
                    return None
                elif isinstance(offer, QuestOffer.QuestBranchResetOffer):
                    self.requestBranchReset(offer.getQuestId())
                    return None
                
                questStr = questDNA.getStringBefore()
                if questDNA.isBranch():
                    self.acceptOnce('lastSubtitlePage', displayBranchOptions, [
                        offer,
                        None,
                        displayBranchDetails])
                    localAvatar.guiMgr.subtitler.setPageChat(questStr, options = [
                        PLocalizer.Decline,
                        PLocalizer.Accept], callback = handleBranchOption)
                else:
                    self.acceptOnce('lastSubtitlePage', displayQuestDetails, [
                        offer])
                    localAvatar.guiMgr.subtitler.setPageChat(questStr, options = [
                        PLocalizer.Decline,
                        PLocalizer.Accept], callback = handleOption, extraArgs = [
                        offer])
            

        
        def questFull(arg):
            self.cleanUpQuestMenu()
            self.sendOfferResponse(QuestConstants.CANCEL_QUEST, ladder)

        inv = base.localAvatar.getInventory()
        numWorkQuests = 0
        if inv:
            questList = inv.getQuestList()
            for questId in questList:
                if not QuestLadderDB.getFamePath(questId):
                    numWorkQuests += 1
                    continue
            
        
        hasStoryQuest = False
        for offer in offers:
            if QuestLadderDB.getFamePath(offer.getQuestId()):
                hasStoryQuest = True
                continue
        
        if not hasStoryQuest and numWorkQuests > QuestConstants.MAXIMUM_MERC_WORK:
            self.questMenuGUI = PDialog.PDialog(text = PLocalizer.QuestFull, style = OTPDialog.Acknowledge, command = questFull)
        else:
            self.questMenuGUI = QuestMenuGUI.QuestMenuGUI(offers, handleSelection, describeQuest)
        localAvatar.currentStoryQuests = []
        self.clearOffer()

    
    def presentBranchReset(self, declineOption = True):
        if not self.resetBranch:
            return None
        
        
        def displayBranchOptions(offer, callback, descCallback):
            self.branchMenuGUI = BranchMenuGUI.BranchMenuGUI(offer, callback, descCallback)

        
        def displayBranchDetails(offer):
            self.selectedOffer = offer
            self.cleanUpQuestDetails()
            self.questDetailGUI = QuestDetailGUI(offer, None)
            self.questDetailGUI.showPanel()
            base.questdet = self.questDetailGUI
            subtitleOptions = [
                PLocalizer.Accept]
            if declineOption:
                subtitleOptions = [
                    PLocalizer.Decline,
                    PLocalizer.Accept]
            
            localAvatar.guiMgr.subtitler.setPageChat('Is that your choice?', options = subtitleOptions, callback = handleBranchOption)

        
        def handleBranchOption(option):
            if option == PLocalizer.Accept:
                if self.selectedOffer:
                    self.sendOfferResponse(0, offer = self.selectedOffer)
                
            else:
                self.offerOptions(False)
            self.adjustNPCCamera('back')
            self.cleanUpQuestDetails(hide = True)
            self.cleanUpBranchMenu()
            self.cleanUpQuestMenu()

        offer = QuestOffer.QuestOffer.create(self.resetBranch.getName(), localAvatar)
        if declineOption:
            subtitleOptions = [
                PLocalizer.Decline]
            self.acceptOnce('lastSubtitlePage', displayBranchOptions, [
                offer,
                None,
                displayBranchDetails])
            localAvatar.guiMgr.subtitler.setPageChat('', options = subtitleOptions, callback = handleBranchOption)
        else:
            subtitleOptions = []
            displayBranchOptions(offer, None, displayBranchDetails)
        self.ignore('doneChatPage')

    
    def presentQuestReset(self):
        if not self.resetQuest:
            return None
        
        
        def handleOption(option):
            if option == PLocalizer.Accept:
                self.resetQuest.startTimer()
            
            self.resetQuest = None
            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, self.resetQuest.questDNA)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)

    
    def presentQuestGiven(self, quest):
        self.resetBranch = None
        if self.resetBranch:
            container = localAvatar.questStatus.getContainer(quest.getQuestId())
            if container.parent and container.parent.getFirstQuestId() == quest.getQuestId():
                self.presentBranchReset(False)
                return None
            else:
                self.resetBranch = None
        
        
        def handleOption(option):
            if len(localAvatar.currentStoryQuests):
                self.cleanUpQuestDetails(hide = True)
                while len(localAvatar.currentStoryQuests) and localAvatar.currentStoryQuests[0].getGiverId() != self.uniqueId:
                    localAvatar.currentStoryQuests.remove(localAvatar.currentStoryQuests[0])
            
            if len(localAvatar.currentStoryQuests):
                storyQuest = localAvatar.currentStoryQuests[0]
                self.presentQuestGiven(storyQuest)
                localAvatar.currentStoryQuests.remove(storyQuest)
            elif hasattr(quest, 'questDNA') and quest.questDNA.getTimeLimit():
                quest.startTimer()
            
            self._DistributedQuestGiver__handleDoneChatPage(0)

        self.questDetailGUI = QuestDetailGUI(None, None, quest)
        self.questDetailGUI.showPanel()
        localAvatar.guiMgr.subtitler.setPageChat('', options = [
            PLocalizer.Accept], callback = handleOption)
        base.questdet = self.questDetailGUI
        self.ignore('doneChatPage')

    
    def adjustNPCCamera(self, direction):
        dummy = NodePath('dummy')
        dummy.reparentTo(camera)
        if direction == 'forward':
            dummy.setH(dummy, -15)
            dummy.setY(dummy, 0.75)
            duration = 0.69999999999999996
        else:
            dummy.setY(dummy, -0.75)
            dummy.setH(dummy, 15)
            duration = 0.5
        dummy.wrtReparentTo(camera.getParent())
        (camH, dummyH) = getShortestRotation(camera.getH(), dummy.getH())
        self.questDetailCamera = Parallel(LerpFunc(camera.setH, duration = duration, fromData = camH, toData = dummyH, blendType = 'easeInOut'), LerpFunc(camera.setY, duration = duration, fromData = camera.getY(), toData = dummy.getY(), blendType = 'easeInOut'))
        dummy.removeNode()
        self.questDetailCamera.start()

    
    def getOfferedQuests(self):
        return list(self.offers)

    
    def sendOfferResponse(self, index, ladder = False, offer = None):
        if index == QuestConstants.CANCEL_QUEST:
            self.dialogOpen = False
        
        if offer:
            self.sendUpdate('assignBranchOffer', [
                offer])
        else:
            self.sendUpdate('setOfferResponse', [
                index,
                ladder])
        self.offers = None
        self.clearOffer()

    
    def b_setPageNumber(self, paragraph, pageNumber):
        self.setPageNumber(paragraph, pageNumber)
        self.d_setPageNumber(paragraph, pageNumber)

    
    def d_setPageNumber(self, paragraph, pageNumber):
        pass

    
    def playQuestString(self, questStr, timeout = False, quitButton = 1, useChatBubble = False, confirm = False, animSet = None):
        self.notify.debug('playQuestString %s, %s, %s, %s' % (timeout, quitButton, useChatBubble, confirm))
        if questStr.find('quest_') == 0:
            nmp = QuestParser.NPCMoviePlayer(questStr, localAvatar, self)
            nmp.play()
            self.npcMoviePlayer = nmp
        else:
            self.firstDialog = False
            self.dialogAnimSet = animSet
            if questStr:
                if timeout:
                    if useChatBubble:
                        self.setPageChat(localAvatar.doId, 0, questStr, 0, extraChatFlags = CFSpeech | CFTimeout, pageButton = False)
                    else:
                        base.localAvatar.guiMgr.subtitler.setPageChat(questStr, timeout = timeout)
                    return None
                else:
                    self.playingQuestString = True
                    if self.newOffer == False:
                        questStr += '\x07'
                    
                    base.localAvatar.guiMgr.subtitler.setPageChat(questStr, confirm = confirm)
                    self.dialogOpen = True
                self.playAnimation(0)
                if quitButton == 1 or confirm:
                    self.accept('doneChatPage', self._DistributedQuestGiver__handleDoneChatPage)
                
                if base.localAvatar.guiMgr.subtitler.getNumChatPages() == 1:
                    self._DistributedQuestGiver__handleNextChatPage(0, 0)
                else:
                    self.accept('nextChatPage', self._DistributedQuestGiver__handleNextChatPage)
            

    
    def _DistributedQuestGiver__handleNextChatPage(self, pageNumber, elapsed):
        self.notify.debug('handleNextChatPage pageNumber = %s, elapsed = %s' % (pageNumber, elapsed))
        if pageNumber == base.localAvatar.guiMgr.subtitler.getNumChatPages() - 1:
            self.ignore('nextChatPage')
            self.playingQuestString = False
            self.presentBranchReset()
            self.presentQuestReset()
            self.presentOffer()
        
        self.playAnimation(pageNumber)

    
    def _DistributedQuestGiver__handleDoneChatPage(self, elapsed):
        self.ignore('nextChatPage')
        self.ignore('doneChatPage')
        self.playingQuestString = False
        self.dialogOpen = False
        if self.newDialog:
            self.playDialog()
        
        if not self.hasOpenGUI():
            self.interactMode = 1
            self.cancelInteraction(base.localAvatar)
        
        self.cancelInteraction(base.localAvatar)

    
    def playAnimation(self, index):
        if self.animationIval:
            self.animationIval.finish()
            self.animationIval = None
        
        if self.dialogAnimSet:
            if len(self.dialogAnimSet) > index and self.dialogAnimSet[index]:
                self.animationIval = Sequence(Wait(0.5), Func(self.gameFSM.request, 'Emote'), Func(self.playEmote, self.dialogAnimSet[index]))
                self.animationIval.start()
            
        

    
    def playDialog(self):
        self.notify.warning('playDialog() needs override!')

    
    def setQuestsCompleted(self, menuFlag, completedContainerIds, completedChainedQuestIds, completedQuestIds, completedQuestDoIds):
        questStr = ''
        self.cleanUpQuestDetails()
        
        def handleOption(option, questStr, menuFlag, confirm, animSet):
            self.cleanUpQuestDetails(hide = True)
            self.playQuestString(questStr, quitButton = menuFlag, confirm = True, animSet = animSet)

        if len(completedContainerIds):
            if completedContainerIds[0] in [
                'c3visitJack']:
                return None
            
            if len(completedContainerIds) > 1:
                self.notify.warning('Multiple simultaneous completed quest containers for the same NPC: %s!' % completedContainerIds)
            
            containerId = completedContainerIds[0]
            self.containerId = containerId
            container = QuestLadderDB.getContainer(containerId)
            if container:
                dialogId = container.getDialogAfter()
                if dialogId:
                    self.requestDialog(dialogId)
                    return None
                
                questStr = container.getStringAfter()
                animSet = container.getAnimSetAfter()
                localAvatar.b_setGameState('NPCInteract', localArgs = [
                    self,
                    False,
                    False])
                if hasattr(self, '_questRewardsEarned'):
                    self.questRewardGUI = QuestRewardGUI(container, self._questRewardsEarned)
                    localAvatar.guiMgr.subtitler.setPageChat('', options = [
                        PLocalizer.Continue], callback = handleOption, extraArgs = [
                        questStr,
                        menuFlag,
                        True,
                        animSet])
                else:
                    handleOption(questStr, menuFlag, True, animSet)
                return None
            else:
                self.notify.warning('%s not in QuestLadderDB!' % containerId)
        
        if len(completedChainedQuestIds):
            pass
        1
        if len(completedQuestIds):
            if len(completedContainerIds) == 0:
                questId = completedQuestIds[0]
                quest = QuestDB.QuestDict.get(questId)
                if quest:
                    questStr = quest.getStringAfter()
                    animSet = quest.getAnimSetAfter()
                    self.notify.debug('%s stringAfter: %s' % (questId, questStr))
                    if hasattr(self, '_questRewardsEarned'):
                        print 'GOT questRewardsEarned: %s' % self._questRewardsEarned
                        self.questRewardGUI = QuestRewardGUI(quest, self._questRewardsEarned)
                        localAvatar.guiMgr.subtitler.setPageChat('', options = [
                            PLocalizer.Continue], callback = handleOption, extraArgs = [
                            questStr,
                            menuFlag,
                            True,
                            animSet])
                    else:
                        handleOption(questStr, menuFlag, True, animSet)
                else:
                    self.notify.warning('%s not in QuestDB!' % questId)
            
            localAvatar.b_setGameState('NPCInteract', localArgs = [
                self,
                True,
                False])
        
        if len(completedQuestIds) == 0 and len(completedChainedQuestIds) == 0 and len(completedContainerIds) == 0:
            if not self.hasOpenGUI():
                self.cancelInteraction(base.localAvatar)
            
        

    
    def requestQuestReset(self, questId):
        self.resetQuest = localAvatar.getQuestById(questId)
        if self.resetQuest:
            questStr = self.resetQuest.questDNA.getStringBefore()
            self.cleanUpQuestDetails(hide = True)
            self.playQuestString(questStr, quitButton = True, confirm = True)
            localAvatar.b_setGameState('NPCInteract', localArgs = [
                self,
                True,
                False])
        

    
    def requestBranchReset(self, questId):
        quest = localAvatar.getQuestById(questId)
        self.resetBranch = quest.getBranchParent(localAvatar)
        resetBranchDNA = QuestLadderDB.getContainer(self.resetBranch.getQuestId())
        questStr = resetBranchDNA.getStringBefore()
        self.cleanUpQuestDetails(hide = True)
        self.playQuestString(questStr, quitButton = False, confirm = True)
        localAvatar.b_setGameState('NPCInteract', localArgs = [
            self,
            True,
            False])

    
    def requestDialog(self, dialogId = None):
        self.endDialog()
        if not dialogId:
            availableDialogs = []
            npcDialogs = DialogDict.get(self.getUniqueId())
            if npcDialogs:
                for dialogId in npcDialogs:
                    firstDialogProcess = npcDialogs.get(dialogId).get(0)[0]
                    if firstDialogProcess.prereq and firstDialogProcess.avCanParticipate(localAvatar):
                        availableDialogs.append(dialogId)
                        continue
                
            
        else:
            availableDialogs = [
                dialogId]
        localAvatar.b_setGameState('NPCInteract', localArgs = [
            self,
            True,
            True])
        self.accept('endDialogNPCInteract', self.endDialog)
        self.dialogProcessMaster = DialogProcessMaster(self, availableDialogs)
        taskMgr.doMethodLater(0.25, self.startDialog, 'startDialogProcessMaster')

    
    def startDialog(self, task = None):
        if self.dialogProcessMaster:
            self.dialogProcessMaster.start()
        

    
    def endDialog(self):
        taskMgr.remove('startDialogProcessMaster')
        self.ignore('endDialogNPCInteract')
        if self.dialogProcessMaster:
            self.dialogProcessMaster.stop()
            self.dialogProcessMaster = None
        

    
    def requestDialogInteraction(self, dialogId):
        self.sendUpdate('requestDialogInteraction', [
            dialogId])

    
    def endDialogInteraction(self, dialogId):
        self.sendUpdate('endDialogInteraction', [
            dialogId])

    
    def requestDialogQuestAdvancement(self, questId, dialogId):
        self.sendUpdate('requestDialogQuestAdvancement', [
            questId,
            dialogId])

    
    def requestDialogQuestAssignment(self, questId, dialogId):
        self.sendUpdate('requestDialogQuestAssignment', [
            questId,
            dialogId])

    
    def requestDialogQuestOffer(self, questId, dialogId):
        self.sendUpdate('requestDialogQuestOffer', [
            questId,
            dialogId])

    
    def setDialogQuestOffer(self, questOffer):
        self.dialogQuestOffer = questOffer
        messenger.send('setDialogQuestOffer')

    
    def showDialogQuestOffer(self):
        if self.dialogQuestOffer:
            self.questDetailGUI = QuestDetailGUI(self.dialogQuestOffer, None)
            self.questDetailGUI.showPanel()
        

    
    def assignDialogQuestOffer(self):
        if self.dialogQuestOffer:
            self.sendUpdate('assignDialogQuestOffer')
        

    
    def showQuestRewards(self):
        if hasattr(self, '_questRewardsEarned') and self.containerId:
            container = QuestLadderDB.getContainer(self.containerId)
            self.questRewardGUI = QuestRewardGUI(container, self._questRewardsEarned)
        

    
    def hideQuestRewards(self):
        if self.questRewardGUI:
            self.questRewardGUI.destroy()
            self.questRewardGUI = None
        

    
    def requestNPCHostile(self, npcId, dialogId):
        self.sendUpdate('requestNPCHostile', [
            npcId,
            dialogId])

    
    def playDialogMovie(self, dialogId, doneCallback = None, oldLocalAvState = None):
        movieChoice = InteractGlobals.getNPCTutorial(dialogId)
        if movieChoice == None:
            movieChoice = dialogId
        
        globalClock.tick()
        self.currentDialogMovie = QuestParser.NPCMoviePlayer(movieChoice, localAvatar, self)
        self.currentDialogMovie.overrideOldAvState(oldLocalAvState)
        self.currentDialogMovie.play()
        self.acceptOnce('dialogFinish', self.stopDialogMovie, extraArgs = [
            doneCallback])

    
    def stopDialogMovie(self, doneCallback):
        if hasattr(self, 'currentDialogMovie'):
            self.currentDialogMovie.npc.showName()
            self.currentDialogMovie.npc.nametag3d.setZ(0)
            self.currentDialogMovie.finishUpAll()
            del self.currentDialogMovie
            self.sendUpdate('dialogMovieComplete')
            if doneCallback:
                doneCallback()
            
        

    
    def swapCurrentDialogMovie(self, newDialogMovie):
        if hasattr(self, 'currentDialogMovie'):
            if newDialogMovie:
                oldAvState = self.currentDialogMovie.overrideOldAvState(None)
                newDialogMovie.overrideOldAvState(oldAvState)
            
            self.currentDialogMovie.finishUpAll()
        
        self.currentDialogMovie = newDialogMovie

    
    def getQuestGiverId(self):
        return self.getUniqueId()

    
    def hasQuestOffersForLocalAvatar(self):
        av = localAvatar
        inventory = av.getInventory()
        selfId = self.getQuestGiverId()
        if inventory:
            numInProgress = 0
            for quest in inventory.getQuestList():
                questType = self.QuestIconDontCare
                if quest.tasks is None:
                    self.notify.warning('quest %s: does not contain a dna; potential for crash.' % quest.getQuestId())
                    return False
                
                for (task, taskState) in zip(quest.tasks, quest.taskStates):
                    if isinstance(task, QuestTaskDNA.VisitTaskDNA):
                        if task.npcId == selfId:
                            questStatus = self.QuestIconComplete
                            return (questType, questStatus)
                        
                    task.npcId == selfId
                
                if quest.canBeReturnedTo(selfId):
                    isComplete = False
                    if quest.isComplete():
                        container = localAvatar.questStatus.getContainer(quest.getQuestId())
                        if container and container.parent and container.parent.isChoice():
                            isComplete = True
                            for q in container.parent.getContainers():
                                if q.quest and not q.quest.isComplete():
                                    isComplete = False
                                    continue
                            
                        else:
                            isComplete = True
                    
                    if isComplete:
                        questStatus = self.QuestIconComplete
                        return (questType, questStatus)
                    else:
                        numInProgress += 1
            
        else:
            self.notify.warning('avatar does not have inventory yet')
            return False
        offerDict = { }
        fromQuests = []
        prereqExcludes = base.config.GetString('exclude-prereq-quests', '')
        for (questId, questDNA) in QuestDB.QuestDict.items():
            if prereqExcludes and questId in prereqExcludes:
                continue
            
            passed = True
            for prereq in questDNA.prereqs:
                if not prereq.giverCanGive(selfId):
                    passed = False
                    break
                
                if not prereq.avIsReady(localAvatar):
                    passed = False
                    break
                
                if questDNA.minLevel > localAvatar.level:
                    passed = False
                    break
                
                if not base.cr.questDependency.checkDependency(questId, localAvatar.getQuestLadderHistory(), 1):
                    passed = False
                    break
                
                boolWeapLvlCheck = (questDNA.weapLvlType != None) & (questDNA.minWeapLevel > 0)
                if boolWeapLvlCheck & (questDNA.minWeapLevel > getLevelFromTotalReputation(questDNA.weapLvlType, inventory.getReputation(questDNA.weapLvlType))[0]):
                    passed = False
                    break
                
                if questDNA.getAcquireOnce():
                    history = localAvatar.getQuestLadderHistory()
                    questLadderId = base.cr.questDynMap.findQuestLadderInt(questId)
                    containsLadderId = history.count(questLadderId)
                    if containsLadderId:
                        passed = False
                        break
                    
                
                if questDNA.getHoliday() is not None:
                    holidayId = questDNA.getHoliday()
                    if base.cr.newsManager and not base.cr.newsManager.getHoliday(holidayId):
                        passed = False
                        break
                    
                not base.cr.newsManager.getHoliday(holidayId)
            
            if questDNA.prereqs and passed:
                fromQuests.append(questDNA)
                continue
        
        if len(fromQuests):
            inventory = av.getInventory()
            if inventory:
                questsLeft = []
                questList = inventory.getQuestList()
                for questDNA in fromQuests:
                    questId = questDNA.questId
                    if not av.questStatus.hasLadderQuestId(questId):
                        continue
                        if _[1] not in [ x.questId for x in questList ]:
                            questsLeft.append(questDNA)
                            continue
                    []
                
                fromQuests = questsLeft
            
        
        if fromQuests:
            questType = self.QuestIconWork
            for quest in fromQuests:
                if QuestLadderDB.getFamePath(quest.questId):
                    questType = self.QuestIconStory
                    break
                    continue
            
            questStatus = self.QuestIconNew
            return (questType, questStatus)
        
        if numInProgress:
            questStatus = self.QuestIconProgress
            return (questType, questStatus)
        
        return False

    
    def loadQuestIcons(self):
        if not DistributedQuestGiver.QuestIconWorkTexture:
            DistributedQuestGiver.QuestIconWorkTexture = loader.loadModel('models/gui/new_work_quest_icon')
            DistributedQuestGiver.QuestIconStoryTexture = loader.loadModel('models/gui/new_story_quest_icon')
            discardNP = DistributedQuestGiver.QuestIconStoryTexture.find('**/pPlane2')
            if not discardNP.isEmpty():
                discardNP.removeNode()
            
            gui = loader.loadModel('models/gui/toplevel_gui')
            DistributedQuestGiver.QuestIconProgressTexture = gui.find('**/quest_pending_icon')
            DistributedQuestGiver.QuestIconCompleteTexture = gui.find('**/reward_waiting_icon')
        

    
    def updateNametagQuestIcon(self, questId = None, item = None, note = None):
        offers = self.hasQuestOffersForLocalAvatar()
        if self.nametagIcon:
            self.nametagIcon.removeNode()
        
        if self.nametagIconGlow:
            self.nametagIconGlow.removeNode()
        
        self.loadQuestIcons()
        if offers:
            (type, status) = offers
            if status == DistributedQuestGiver.QuestIconNew:
                if type == DistributedQuestGiver.QuestIconStory:
                    self.nametagIcon = DistributedQuestGiver.QuestIconStoryTexture.copyTo(self.nametag3d)
                else:
                    self.nametagIcon = DistributedQuestGiver.QuestIconStoryTexture.copyTo(self.nametag3d)
                self.nametagIcon.setScale(3.5)
            elif status == DistributedQuestGiver.QuestIconComplete:
                self.nametagIcon = DistributedQuestGiver.QuestIconCompleteTexture.copyTo(self.nametag3d)
                self.nametagIcon.setScale(12)
            elif status == DistributedQuestGiver.QuestIconProgress:
                self.nametagIcon = DistributedQuestGiver.QuestIconProgressTexture.copyTo(self.nametag3d)
                self.nametagIcon.setScale(12)
            else:
                self.notify.error('invalid quest status: %s or type: %s' % (status, type))
        elif self.nametagIcon:
            self.nametagIcon.detachNode()
        
        if self.nametagIconGlow:
            self.nametagIconGlow.detachNode()
        
        if self.nametagIcon:
            self.nametagIcon.setPos(0, 0, 3.5)
            if self.getNameText() is None:
                base.cr.centralLogger.writeClientEvent('NPC %s, %s: has no nameText, type = %s, status = %s!' % (self, self.getName(), type, status))
                if self.nametagIcon:
                    self.nametagIcon.detachNode()
                
                if self.nametagIconGlow:
                    self.nametagIconGlow.detachNode()
                
                return None
            
            self.nametagIcon.reparentTo(self.getNameText())
            self.nametagIcon.setDepthWrite(0)
            if status == DistributedQuestGiver.QuestIconComplete or status == DistributedQuestGiver.QuestIconNew:
                self.nametagIconGlow = loader.loadModel('models/effects/lanternGlow')
                self.nametagIconGlow.reparentTo(self.nametag.getNameIcon())
                self.nametagIconGlow.setScale(20.0)
                self.nametagIconGlow.setColorScaleOff()
                self.nametagIconGlow.setFogOff()
                self.nametagIconGlow.setLightOff()
                self.nametagIconGlow.setPos(0, -0.050000000000000003, 3.0)
                self.nametagIconGlow.setDepthWrite(0)
                self.nametagIconGlow.node().setAttrib(ColorBlendAttrib.make(ColorBlendAttrib.MAdd, ColorBlendAttrib.OIncomingAlpha, ColorBlendAttrib.OOne))
                self.nametagIconGlow.setColor(0.84999999999999998, 0.84999999999999998, 0.84999999999999998, 0.84999999999999998)
            
        
        self.loadShopCoin()

    
    def forceDoneChatPage(self):
        self._DistributedQuestGiver__handleDoneChatPage(0)
 def showDialogQuestOffer(self):
     if self.dialogQuestOffer:
         self.questDetailGUI = QuestDetailGUI(self.dialogQuestOffer, None)
         self.questDetailGUI.showPanel()
class QuestPage(InventoryPage.InventoryPage):
    notify = directNotify.newCategory('QuestPage')
    specialInfoData = {
        'Chapter 3': {
            'class': BlackPearlCrew,
            'buttonOn': PLocalizer.ShowBlackPearlCrew,
            'buttonOff': PLocalizer.HideBlackPearlCrew } }
    
    def __init__(self):
        InventoryPage.InventoryPage.__init__(self)
        self.initialiseoptions(QuestPage)
        self.detailId = None
        self.titleBorder = BorderFrame.BorderFrame(parent = self, frameSize = (-0.02, 0.96999999999999997, -0.02, 0.56000000000000005))
        self.titleBorder.setPos(0.065000000000000002, 0, -0.01)
        self.titleBorder.background.setColor(0, 0, 0, 1)
        self.titleBorder.resetDecorations()
        self.titleList = QuestTitleList.QuestTitleList()
        self.titleList.reparentTo(self.titleBorder)
        self.titleList.setPos(0.0050000000000000001, 0, 0)
        self.detailFrame = QuestDetailGUI(parent = self, pos = (0.54000000000000004, 0, 1.006))
        self.dropButton = GuiButton.GuiButton(parent = self, state = DGG.DISABLED, text = PLocalizer.DropQuest, textMayChange = 0, text_scale = PiratesGuiGlobals.TextScaleLarge, text_pos = (0, -0.014), pos = (0.91000000000000003, 0, 0.60499999999999998), image = GuiButton.GuiButton.redGenericButton, image_scale = 0.59999999999999998, command = self.dropQuest, helpText = PLocalizer.DropQuestHelp, helpDelay = PiratesGuiGlobals.HelpPopupTime, helpPos = (-0.33500000000000002, 0, 0.125))
        gui = loader.loadModel('models/gui/compass_main')
        objectiveGrey = gui.find('**/icon_objective_grey')
        self.trackButton = GuiButton.GuiButton(parent = self, state = DGG.DISABLED, text = PLocalizer.TrackQuest, textMayChange = 0, text_pos = (0.035000000000000003, -0.014), text_scale = PiratesGuiGlobals.TextScaleLarge, pos = (0.66000000000000003, 0, 0.60499999999999998), command = self.trackQuest, helpText = PLocalizer.TrackQuestHelp, helpDelay = PiratesGuiGlobals.HelpPopupTime, helpPos = (-0.080000000000000002, 0, 0.125), image = GuiButton.GuiButton.redGenericButton, image_scale = 0.59999999999999998, geom = objectiveGrey, geom_color = Vec4(1, 1, 0, 1), geom_scale = 0.20000000000000001, geom_pos = (-0.070000000000000007, 0, -0.002))
        self.specialInfoPanel = { }
        self.specialButton = GuiButton.GuiButton(parent = self, state = DGG.NORMAL, text = '', textMayChange = 1, text_scale = PiratesGuiGlobals.TextScaleLarge, text_pos = (0, -0.014), pos = (0.17000000000000001, 0, 0.60499999999999998), image = GuiButton.GuiButton.redGenericButton, image_scale = 0.59999999999999998, command = self.showSpecialInfo, helpText = PLocalizer.DropQuestHelp, helpDelay = PiratesGuiGlobals.HelpPopupTime, helpPos = (-0.33500000000000002, 0, 0.125))
        self.specialButton.hide()
        self.accept('questGuiSelect', self.showQuestDetails)
        self.accept('localAvatarQuestComplete', self.updateQuestDetails)
        self.accept('localAvatarQuestUpdate', self.updateQuestDetails)
        self.accept('localAvatarQuestItemUpdate', self.updateQuestDetails)
        self.accept('inventoryAddDoId-%s-%s' % (localAvatar.getInventoryId(), InventoryCategory.QUESTS), self.updateQuestTitlesNewQuest)
        self.accept('inventoryRemoveDoId-%s-%s' % (localAvatar.getInventoryId(), InventoryCategory.QUESTS), self.updateQuestTitles)
        self.invRequest = None
        self.tmButtonQuick = None
        self.tmButtonSearch = None
        self.tmReadyDialog = None

    
    def destroy(self):
        self.titleList.destroy()
        del self.titleList
        if self.tmReadyDialog:
            self.tmReadyDialog.destroy()
        
        InventoryPage.InventoryPage.destroy(self)
        self.ignoreAll()

    
    def show(self):
        InventoryPage.InventoryPage.show(self)
        localAvatar.guiMgr.removeNewQuestIndicator()

    
    def dropQuest(self):
        if self.detailId:
            self.dropButton['state'] = DGG.DISABLED
            localAvatar.requestDropQuest(self.detailId)
        

    
    def trackQuest(self):
        questId = self.detailId
        if questId == localAvatar.activeQuestId or questId == None:
            localAvatar.b_requestActiveQuest('')
            self.titleList.showTracked('')
            localAvatar.guiMgr.hideTrackedQuestInfo()
            localAvatar.guiMgr.mapPage.worldMap.mapBall.removeDart()
        else:
            localAvatar.b_requestActiveQuest(questId, localSet = True)
            self.titleList.showTracked(questId)
            quest = localAvatar.getQuestById(questId)
            if quest is None:
                print 'Tracked quest not found on avatar!\n  Tracked quest: %s\n  Current quests: %s' % (questId, map(lambda q: q.getQuestId(), localAvatar.getQuests()))
                localAvatar.guiMgr.hideTrackedQuestInfo()
            elif localAvatar.questStep:
                mapPage = localAvatar.guiMgr.mapPage
                doId = base.cr.uidMgr.uid2doId.get(localAvatar.questStep.getIsland())
                island = base.cr.doId2do.get(doId)
                if island:
                    pos = island.getPos()
                    if mapPage.worldMap.mapBall.questDartPlaced:
                        localAvatar.guiMgr.mapPage.worldMap.mapBall.updateDart('questStep', pos)
                    else:
                        localAvatar.guiMgr.mapPage.addQuestDart('questStep', pos)
                else:
                    localAvatar.guiMgr.mapPage.removeQuestDart('questStep')
            

    
    def findNewActiveQuest(self, oldQuestId):
        localAvatar.d_findNewActiveQuest(oldQuestId)
        localAvatar.l_requestActiveQuest('')
        self.titleList.showTracked('')
        localAvatar.guiMgr.setQuestStatusText('')
        localAvatar.guiMgr.setQuestHintText('')
        localAvatar.guiMgr.hideTrackedQuestInfo()
        localAvatar.guiMgr.mapPage.worldMap.mapBall.removeDart()

    
    def updateQuestTitlesNewQuest(self, quest):
        self.updateQuestTitles(quest, newQuest = True)

    
    def updateQuestTitles(self, quest = None, newQuest = False, findNewTrackable = True):
        questIds = map(lambda q: q.getQuestId(), localAvatar.getQuests())
        self.titleList.update(questIds, quest, newQuest)
        if localAvatar.activeQuestId:
            self.titleList.showTracked(localAvatar.activeQuestId)
            localAvatar.guiMgr.showTrackedQuestInfo()
        
        if not (self.detailId) and localAvatar.activeQuestId:
            self.detailId = localAvatar.activeQuestId
        
        if self.detailId not in questIds:
            if questIds:
                self.detailId = None
                self.detailFrame.clearQuestDetails()
            else:
                self.showQuestDetails(None)
                self.dropButton['state'] = DGG.DISABLED
                self.trackButton['state'] = DGG.DISABLED
        elif (not self.detailFrame.hasQuestDetails() or localAvatar.activeQuestId) and self.detailId != localAvatar.activeQuestId:
            self.titleList.select(localAvatar.activeQuestId)
        
        localAvatar.chatMgr.emoteEntry.updateEmoteList()
        localAvatar.l_setActiveQuest(localAvatar.activeQuestId)

    
    def showQuestDetails(self, questId):
        self.hideSpecialInfo()
        if questId in self.specialInfoData.keys():
            self.specialButton['text'] = self.specialInfoData[questId].get('buttonOn')
            self.specialButton['command'] = self.showSpecialInfo
            self.specialButton['extraArgs'] = [
                questId]
            self.specialButton.show()
        else:
            self.specialButton.hide()
        self.detailId = questId
        self.updateQuestIdDetails(questId)

    
    def updateQuestDetails(self, quest, item = None, note = None):
        questId = quest.getQuestId()
        self.updateQuestIdDetails(questId)
        self.updateQuestTitles(quest)
        messenger.send('localAvatarActiveQuestId', sentArgs = [
            localAvatar.activeQuestId])

    
    def updateQuestIdDetails(self, questId):
        self.removeTreasureMapButtons()
        if not questId:
            self.detailFrame.clearQuestDetails()
            return None
        
        if self.detailId != questId:
            return None
        
        quest = localAvatar.getQuestById(questId)
        if not quest:
            self.dropButton['state'] = DGG.DISABLED
            self.trackButton['state'] = DGG.DISABLED
            self.detailFrame.setQuestInfoFromQuestId(questId)
        else:
            self.detailFrame.setQuestInfoFromQuest(quest)
            self.checkButtonDisplay(quest)
            trackableQuestId = base.cr.questChoiceSibsMap.getTrackableQuest(localAvatar, quest.questId)
            if trackableQuestId == quest.questId or trackableQuestId == None:
                self.trackButton['state'] = DGG.NORMAL
            else:
                self.trackButton['state'] = DGG.DISABLED
                if self.detailId == localAvatar.activeQuestId:
                    self.findNewActiveQuest(quest.questId)
                
            if quest.isDroppable():
                self.dropButton['state'] = DGG.NORMAL
            else:
                self.dropButton['state'] = DGG.DISABLED

    
    def checkButtonDisplay(self, quest):
        questDNA = quest.getQuestDNA()
        if questDNA == None:
            return None
        
        questTasks = questDNA.getTasks()
        for currQuestTask in questTasks:
            if not hasattr(currQuestTask, 'getTreasureMapId'):
                continue
            
            tmId = currQuestTask.getTreasureMapId()
            if tmId != None:
                
                def inventoryReceived(inventory):
                    if inventory:
                        self.invRequest = None
                        tms = inventory.getTreasureMapsList()
                        for currTm in tms:
                            if currTm.mapId == tmId:
                                currTm.sendUpdate('requestIsEnabled')
                                self.addTreasureMapButtons(currTm, 0.60199999999999998)
                                break
                                continue
                        
                    

                self.invRequest = DistributedInventoryBase.DistributedInventoryBase.getInventory(localAvatar.getInventoryId(), inventoryReceived)
                continue
        

    
    def addTreasureMapButtons(self, tm, buttonOffset):
        self.removeTreasureMapButtons()
        helpPos = (-0.26000000000000001, 0, 0.095000000000000001)
        if __debug__ and base.config.GetBool('enable-bp-solo', False):
            self.tmButtonQuick = GuiButton.GuiButton(parent = self, text = PLocalizer.PlayTMNow, text_align = TextNode.ACenter, text_scale = PiratesGuiGlobals.TextScaleLarge, text_pos = (0.0, -0.01), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_wordwrap = 40, image_scale = (0.45000000000000001, 1, 0.23999999999999999), command = self.startTreasureMap, extraArgs = [
                tm], pos = (0.29999999999999999, 0, buttonOffset), helpText = PLocalizer.PlayTMNowHelp, helpPos = helpPos)
            searchPos = (0.77500000000000002, 0, buttonOffset)
        else:
            searchPos = (0.55000000000000004, 0, buttonOffset)
        self.tmButtonSearch = GuiButton.GuiButton(parent = self, text = PLocalizer.PlayTMLookout, text_align = TextNode.ACenter, text_scale = PiratesGuiGlobals.TextScaleLarge, text_pos = (0.0, -0.01), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_wordwrap = 40, image_scale = (0.45000000000000001, 1, 0.23999999999999999), command = self.startTreasureMap, extraArgs = [
            tm,
            False], pos = searchPos, helpText = PLocalizer.PlayTMLookoutHelp, helpPos = helpPos)
        if base.cr.teleportMgr.inInstanceType == PiratesGlobals.INSTANCE_TM:
            self.disableTreasureMapButtons()
        else:
            self.enableTreasureMapButtons()

    
    def removeTreasureMapButtons(self):
        self.trackButton.show()
        self.dropButton.show()
        if self.tmButtonQuick:
            self.tmButtonQuick.removeNode()
            self.tmButtonQuick = None
        
        if self.tmButtonSearch:
            self.tmButtonSearch.removeNode()
            self.tmButtonSearch = None
        

    
    def enableTreasureMapButtons(self):
        if self.tmButtonQuick:
            self.tmButtonQuick['state'] = 'normal'
        
        if self.tmButtonSearch:
            self.tmButtonSearch['state'] = 'normal'
        
        self.trackButton.hide()
        self.dropButton.hide()

    
    def disableTreasureMapButtons(self):
        if self.tmButtonQuick:
            self.tmButtonQuick['state'] = 'disabled'
        
        if self.tmButtonSearch:
            self.tmButtonSearch['state'] = 'disabled'
        
        self.trackButton.hide()
        self.dropButton.hide()

    
    def startTreasureMap(self, tm, quick = True):
        if localAvatar.getAccess() != OTPGlobals.AccessFull:
            self.tmReadyDialog = PDialog.PDialog(text = PLocalizer.PlayTMVelvetRope, style = OTPDialog.Acknowledge, giveMouse = False, command = self.notReadyCallback)
            self.tmReadyDialog.show()
            return None
        
        if tm.getIsEnabled() or base.config.GetBool('black-pearl-ready', 0):
            DistributedBandMember = DistributedBandMember
            import pirates.band.DistributedBandMember
            if not DistributedBandMember.getBandMember(localAvatar.doId) and quick == False:
                localAvatar.guiMgr.messageStack.addTextMessage(PLocalizer.LookoutInviteNeedCrew, icon = ('lookout', None))
                return None
            
            if localAvatar.testTeleportFlag(PiratesGlobals.TFNoTeleport) == False:
                if base.cr.teleportMgr.inInstanceType == PiratesGlobals.INSTANCE_MAIN:
                    tm.requestTreasureMapGo(quick)
                elif base.cr.teleportMgr.inInstanceType == PiratesGlobals.INSTANCE_TM:
                    tm.requestTreasureMapLeave()
                
            
        else:
            self.tmReadyDialog = PDialog.PDialog(text = PLocalizer.PlayTMBlackPearlNotReady, style = OTPDialog.Acknowledge, giveMouse = False, command = self.notReadyCallback)
            self.tmReadyDialog.show()

    
    def notReadyCallback(self, args):
        self.tmReadyDialog.hide()

    
    def showSpecialInfo(self, containerId = None):
        if not self.specialInfoPanel.has_key(containerId):
            panelClass = self.specialInfoData[containerId].get('class')
            self.specialInfoPanel[containerId] = panelClass()
            self.specialInfoPanel[containerId].reparentTo(self.detailFrame)
        
        self.specialButton['text'] = self.specialInfoData[containerId].get('buttonOff')
        self.specialButton['command'] = self.hideSpecialInfo
        self.specialInfoPanel[containerId].update()
        self.specialInfoPanel[containerId].show()
        self.detailFrame.setQuestTitleOnly(containerId)

    
    def hideSpecialInfo(self, containerId = None):
        for specialPanelId in self.specialInfoPanel.keys():
            self.specialInfoPanel[specialPanelId].hide()
        
        if containerId:
            self.showQuestDetails(containerId)