class QuestPoster(DirectFrame): notify = directNotify.newCategory('QuestPoster') # We need to declare and initialize these variables here # because some methods use them as default arguments. auxIcon = None # Requires one parameter, quest, this must be a Quest instance. # The next argument, parent, is where to reparent the DirectFrame to. # The next arguments are simply additional options when setting up the DirectFrame. def __init__(self, quest, parent=aspect2d, **kw): # The quest this poster is representing. self.quest = quest self.accessibleObjectives = quest.accessibleObjectives if quest else [] self.viewObjective = quest.accessibleObjectives.seek( ) if quest else None isObjComplete = False if not quest else ( self.accessibleObjectives.isComplete() or quest.isComplete()) # Let's define our options for the DirectFrame. bookModel = loader.loadModel( 'phase_3.5/models/gui/stickerbook_gui.bam') optiondefs = (('relief', None, None), ('image', bookModel.find('**/questCard'), None), ('image_scale', (0.8, 1.0, 0.58), None), ('image_color', (1.0, 1.0, 1.0, 1.0) if not isObjComplete else Vec4( *QuestGlobals.LIGHT_GREEN), None), ('state', DGG.NORMAL, None)) self.defineoptions(kw, optiondefs) # Finally, initialize the DirectFrame. DirectFrame.__init__(self, parent, relief=None) self.initialiseoptions(QuestPoster) # Let's declare and initialize our barebone GUI element variables. questTitle = '' if not self.quest else self.quest.name self.titleLabel = DirectLabel(parent=self, relief=None, text=questTitle, text_font=CIGlobals.getMinnieFont(), text_fg=QuestGlobals.TEXT_COLOR, text_scale=0.05, text_align=TextNode.ACenter, text_wordwrap=25.0, textMayChange=1, pos=(0, 0, 0.23)) ########################################################################## # THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER # ########################################################################## # The background frame where the objective image is displayed. # This is the colored background frame. circleGui = loader.loadModel( 'phase_4/models/gui/CircleIconBackgroundGui.bam') self.auxFrame = DirectFrame( parent=self, relief=None, image=circleGui.find('**/circle_display_interior'), image_scale=0.18, text='', text_pos=(0, -0.11), text_fg=QuestGlobals.TEXT_COLOR, text_scale=QuestGlobals.QPtextScale, text_align=TextNode.ACenter, text_wordwrap=11.0, pos=QuestGlobals.DEFAULT_LEFT_PICTURE_POS) if self.quest and len( self.quest.accessibleObjectives) > 1 and not isObjComplete: # We can only use arrows when we have more than one objective available. arrowGui = loader.loadModel('phase_4/models/gui/QuestArrowGui.bam') self.prevObjArrow = DirectButton( parent=self.auxFrame, relief=None, geom=((arrowGui.find('**/quest_arrow_enabled'), arrowGui.find('**/quest_arrow_click'), arrowGui.find('**/quest_arrow_mouseover'), arrowGui.find('**/quest_arrow_disabled'))), scale=0.08, command=self.switchObjective, extraArgs=[0], hpr=(180, 0, 0), pos=QuestGlobals.DEFAULT_LEFT_ARROW_POS) self.nextObjArrow = DirectButton( parent=self.auxFrame, relief=None, geom=((arrowGui.find('**/quest_arrow_enabled'), arrowGui.find('**/quest_arrow_click'), arrowGui.find('**/quest_arrow_mouseover'), arrowGui.find('**/quest_arrow_disabled'))), scale=0.08, command=self.switchObjective, pos=QuestGlobals.DEFAULT_RIGHT_ARROW_POS) # The icon that goes on top of the aux frame. self.auxIcon = DirectFrame(parent=self.auxFrame, relief=None, text=' ', text_font=CIGlobals.getSuitFont(), text_pos=(0, -0.03), text_fg=QuestGlobals.TEXT_COLOR, text_scale=0.13, text_align=TextNode.ACenter, text_wordwrap=13.0, textMayChange=1) self.auxIcon.setColorOff(-1) self.auxOutline = DirectLabel( parent=self.auxFrame, relief=None, image=circleGui.find('**/circle_display_outline'), image_scale=0.18) # The aux text saying: DEFEAT, RECOVER, etc. self.auxText = DirectLabel(parent=self, relief=None, text=QuestGlobals.RECOVER, text_font=CIGlobals.getToonFont(), text_scale=QuestGlobals.QPauxText, text_fg=QuestGlobals.TEXT_COLOR, text_align=TextNode.ACenter, textMayChange=1, pos=QuestGlobals.DEFAULT_AUX_POS) self.auxText.hide() ########################################################################## # Information displayed about the objective. self.objectiveInfo = DirectLabel( parent=self, relief=None, text='', text_font=CIGlobals.getToonFont(), text_fg=QuestGlobals.TEXT_COLOR, text_scale=0.04, text_align=TextNode.ACenter, text_wordwrap=QuestGlobals.QPtextWordwrap, textMayChange=1, pos=(QuestGlobals.DEFAULT_INFO_POS)) self.objectiveInfo.hide() # Information displayed showing the location. self.locationInfo = DirectLabel( parent=self, relief=None, text='N/A', text_font=CIGlobals.getToonFont(), text_fg=QuestGlobals.TEXT_COLOR, text_scale=QuestGlobals.QPtextScale, text_align=TextNode.ACenter, text_wordwrap=QuestGlobals.QPtextWordwrap, textMayChange=1, pos=(0, 0, -0.115)) self.locationInfo.hide() # The progress bar showing the objective's progress self.progressBar = DirectWaitBar(parent=self, relief=DGG.SUNKEN, frameSize=(-0.95, 0.95, -0.1, 0.12), borderWidth=(0.025, 0.025), scale=0.2, frameColor=(0.945, 0.875, 0.706, 1.0), barColor=(0.5, 0.7, 0.5, 1), text='0/0', text_font=CIGlobals.getToonFont(), text_scale=0.19, text_fg=(0.05, 0.14, 0.4, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05), pos=(0, 0, -0.2425)) self.progressBar.hide() # The wood panel at the bottom where rewards are displayed. rewardFrameGeom = loader.loadModel( 'phase_4/models/gui/gag_shop_purchase_gui.bam') self.rewardFrame = DirectFrame( parent=self, relief=None, geom=rewardFrameGeom.find('**/Goofys_Sign'), geom_scale=(0.62, 0, 0.4), pos=(-0.015, 0, -0.25)) # Let's setup our reward frames. reward = None if self.quest and len(self.quest.rewards) > 0: reward = self.quest.rewards[0] self.lReward = QuestRewardFrame(self, reward) # The text displayed on the right side of the frame with additional information, if necessary. self.sideInfo = DirectLabel(parent=self, relief=None, text=QuestGlobals.JUST_FOR_FUN, text_fg=(0.0, 0.439, 1.0, 1.0), text_shadow=(0, 0, 0, 1), pos=(-0.2825, 0, 0.2), scale=0.03) self.sideInfo.setR(-30) # This side information is usually not needed, let's hide it. self.sideInfo.hide() # Remove the nodes of the loaded models we no longer need. circleGui.removeNode() bookModel.removeNode() rewardFrameGeom.removeNode() # We are only removing this node if we generated arrows. if hasattr(self, 'arrowGui'): arrowGui.removeNode() # Let's hide this until it is needed. self.hide() return def switchObjective(self, forward=1): if forward: self.accessibleObjectives.nextObjective() else: self.accessibleObjectives.lastObjective() self.viewObjective = self.accessibleObjectives.seek() self.setup() def setup(self): if self.quest: objective = self.viewObjective complete = self.accessibleObjectives.isComplete() # Let's reset our positioning of elements. self.auxFrame.setPos(QuestGlobals.DEFAULT_LEFT_PICTURE_POS) self.auxText.setPos(QuestGlobals.DEFAULT_AUX_POS) self.objectiveInfo.setPos(QuestGlobals.DEFAULT_INFO_POS) # Let's reset our icon. self.auxIcon.setScale(1, 1, 1) self.auxIcon.setPos(0, 0, 0) self.auxIcon.setHpr(0, 0, 0) self.objectiveInfo.show() self.auxFrame.show() # Let's setup the quest progress bar progress = objective.progress if hasattr(objective, 'progress') else None if objective.goal > 1: self.progressBar['range'] = objective.goal self.progressBar['value'] = progress & pow(2, 16) - 1 if objective.HasProgress and objective.goal > 1 and not complete: self.progressBar.show() self.auxText.show() # Let's handle the objectives. if not complete: if objective.__class__ == CogObjective: self.handleCogObjective() elif objective.__class__ == CogBuildingObjective: self.handleCogBuildingObjective() elif objective.__class__ == MinigameObjective: self.handleMinigameObjective() elif objective.__class__ == VisitNPCObjective: self.handleNPCObjective() else: bgColor = QuestGlobals.RED if objective.type in DefeatObjectives: bgColor = QuestGlobals.BLUE self.handleNPCObjective(auxText=QuestGlobals.RETURN + ' to', frameColor=bgColor) self.lReward.setup() newLineInObjInfo = '\n' in self.objectiveInfo['text'] isShopLoc = QuestGlobals.isShopLocation( objective.area) if not complete else True if complete: locationText = QuestGlobals.getLocationText(None, objective) else: locationText = QuestGlobals.getLocationText(objective.area) self.locationInfo['text'] = locationText self.locationInfo['text_pos'] = (0.0, (0.025 if isShopLoc else ( -0.025 if newLineInObjInfo else 0.0))) self.locationInfo.show() else: # We want to be able to show empty quest posters. self.titleLabel.hide() self.auxFrame.hide() self.auxIcon.hide() self.titleLabel.initialiseoptions(DirectLabel) self.auxIcon.initialiseoptions(DirectFrame) self.auxText.initialiseoptions(DirectLabel) self.objectiveInfo.initialiseoptions(DirectLabel) self.locationInfo.initialiseoptions(DirectLabel) self.rewardFrame.initialiseoptions(DirectFrame) self.sideInfo.initialiseoptions(DirectLabel) self.lReward.initialiseoptions(DirectFrame) # Handle arrow stuff if necessary. if hasattr(self, 'prevObjArrow'): index = self.accessibleObjectives.seeker self.prevObjArrow['state'] = DGG.NORMAL self.nextObjArrow['state'] = DGG.NORMAL self.prevObjArrow.setPos(QuestGlobals.DEFAULT_LEFT_ARROW_POS) self.nextObjArrow.setPos(QuestGlobals.DEFAULT_RIGHT_ARROW_POS) if index == 0: self.prevObjArrow['state'] = DGG.DISABLED elif index == len(self.accessibleObjectives) - 1: self.nextObjArrow['state'] = DGG.DISABLED self.prevObjArrow.initialiseoptions(DirectButton) self.nextObjArrow.initialiseoptions(DirectButton) # Changes geometry and scale of an icon. def handleSimpleIcon(self, geom, scale, icon): icon['geom'] = geom icon['geom_scale'] = scale def handleComplexIcon(self, geom, icon, scale=QuestGlobals.IMAGE_SCALE_SMALL): geom.setDepthWrite(1) geom.setDepthTest(1) self.fitGeometry(geom, fFlip=1) self.handleSimpleIcon(geom, scale, icon) # We have to rotate the head and set the scale of the icon. if CIGlobals.Suit in geom.getName(): cogName = geom.getPythonTag('Settings') data = QuestGlobals.Suit2PosterZNDScale.get(cogName) zOffset = data[0] headScale = data[1] icon.setScale(headScale) icon.setZ(icon.getZ() + zOffset) icon.setH(180) else: icon.setZ(icon.getZ() - 0.01) def handleCogObjective(self, iconElement=auxIcon, auxText=QuestGlobals.DEFEAT, frameColor=QuestGlobals.BLUE): objective = self.viewObjective infoText = objective.getTaskInfo() if objective.__class__ == RecoverItemObjective: infoText = CIGlobals.makePlural(objective.cog) if not iconElement: iconElement = self.auxIcon # Let's make sure we have a current objective that is # an instance of the CogObjective class and this poster isn't destroyed. if not objective or not hasattr(self, 'titleLabel') or not isinstance( objective, CogObjective): return if objective.dept: icons = loader.loadModel('phase_3/models/gui/cog_icons.bam') deptIcon = None if objective.dept == Dept.BOSS: deptIcon = icons.find('**/CorpIcon') else: deptIcon = icons.find('**/%sIcon' % objective.dept.getTie().title()) # Correct the medallion color. deptIcon.setColor(SuitGlobals.medallionColors[objective.dept]) # Setup the icon and remove the icons node. self.handleSimpleIcon(deptIcon, 0.13, iconElement) icons.removeNode() elif objective.cog == QuestGlobals.Any: # We aren't fighting a Cog in particular. cogIcon = QuestGlobals.getCogIcon() self.handleSimpleIcon(cogIcon, 0.13, iconElement) # We're fighting a Cog in particular. if not objective.cog == QuestGlobals.Any: cogHeadInstance = SuitBank.getSuitByName(objective.cog).getHead() cogHead = cogHeadInstance.generate() cogHead.setName('%sHead' % CIGlobals.Suit) cogHead.setPythonTag('Settings', cogHeadInstance.head) cogHead.setScale(2) cogHead.setLightOff() self.handleComplexIcon(cogHead, iconElement) # HACK FIX: Corrects the buggy Flunky glasses. glasses = cogHead.find('**/glasses') if glasses and not glasses.isEmpty(): glasses.setScale(1) glasses.reparentTo(cogHead) if not iconElement is self.auxIcon: if hasattr(self, 'goalInfo'): # We're working with the second frame, on the right. # Let's update the information pertaining to this side. self.goalInfo['text'] = infoText self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS) self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS) else: raise AttributeError( 'Attempted to setup DoubleFrame information for poster using default style.' ) else: self.objectiveInfo['text'] = infoText # Let's set the progress bar text pgBarText = '%d of %d %s' % (objective.progress, objective.goal, CIGlobals.makePastTense(auxText)) self.progressBar['text'] = pgBarText self.auxText['text'] = auxText # Let's set the color of the poster. frame = self.auxFrame if iconElement is self.auxIcon else self.goalFrame frame['image_color'] = Vec4(*frameColor) def handleCogBuildingObjective(self, iconElement=auxIcon, auxText=QuestGlobals.DEFEAT, frameColor=QuestGlobals.BLUE): objective = self.viewObjective infoText = objective.getTaskInfo() if not iconElement: iconElement = self.auxIcon # Let's make sure we have a current objective that is # an instance of the CogBuildingObjective class and this poster isn't destroyed. if not objective or not hasattr(self, 'titleLabel') or not isinstance( objective, CogBuildingObjective): return # If we aren't looking for any specific department of building. if objective.dept == QuestGlobals.Any: # Let's just use the good ol' generic building icon. self.handleSimpleIcon(QuestGlobals.getCogBuildingIcon(), QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement) else: # Ah geez, we're looking for a specific department. # Bossbot tie names are messed up, so we need this if statement. dept = objective.dept.getTie( ) if not objective.dept == Dept.BOSS else 'corp' bldgMdl = loader.loadModel( 'phase_4/models/modules/suit_landmark_%s.bam' % dept) # Next, we need to load the building elevator. elevator = loader.loadModel('phase_4/models/modules/elevator.bam') elevator.reparentTo(bldgMdl.find('**/*_door_origin')) self.handleComplexIcon(bldgMdl, iconElement) # Let's set the progress bar text pgBarText = '%d of %d %s' % (objective.progress, objective.goal, CIGlobals.makePastTense(auxText)) self.progressBar['text'] = pgBarText self.objectiveInfo['text'] = infoText self.auxText['text'] = auxText self.auxFrame['image_color'] = Vec4(*frameColor) def handleMinigameObjective(self, iconElement=auxIcon, auxText=QuestGlobals.PLAY, frameColor=QuestGlobals.RED): objective = self.viewObjective infoText = objective.getTaskInfo() if not iconElement: iconElement = self.auxIcon # Let's make sure we have a current objective that is # an instance of the MinigameObjective class and this poster isn't destroyed. if not objective or not hasattr(self, 'titleLabel') or not isinstance( objective, MinigameObjective): return # Let's set the icon to the minigame icon. self.handleSimpleIcon(QuestGlobals.getTrolleyIcon(), QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement) # Let's set the progress bar text pgBarText = '%d of %d %s' % (objective.progress, objective.goal, CIGlobals.makePastTense(auxText)) self.progressBar['text'] = pgBarText self.objectiveInfo['text'] = infoText self.auxText['text'] = auxText self.auxFrame['image_color'] = Vec4(*frameColor) def handleNPCObjective(self, iconElement=auxIcon, auxText=QuestGlobals.VISIT, frameColor=QuestGlobals.BROWN): objective = self.viewObjective npcId = 0 if self.accessibleObjectives.isComplete() and not hasattr( objective, 'npcId'): npcId = objective.assigner elif hasattr(objective, 'npcId'): npcId = objective.npcId if npcId == 0: infoText = 'A %s' % NPCGlobals.lHQOfficerF else: infoText = NPCGlobals.NPCToonNames[npcId] if not iconElement: iconElement = self.auxIcon # Let's generate the head. if not npcId == 0: dna = ToonDNA() dna.setDNAStrand(NPCGlobals.NPCToonDict.get(npcId)[2]) head = ToonGlobals.generateGuiHead(dna) self.handleComplexIcon(head, iconElement, scale=QuestGlobals.IMAGE_SCALE_SMALL - 0.01) else: self.handleSimpleIcon(QuestGlobals.getHQIcon(), QuestGlobals.SIMPLE_IMAGE_SCALE, iconElement) self.auxText['text'] = auxText if not iconElement is self.auxIcon: if hasattr(self, 'goalInfo'): # We're working with the second frame, on the right. # Let's update the information pertaining to this side. self.goalInfo['text'] = infoText self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS) self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS) self.goalFrame['image_color'] = frameColor else: raise AttributeError( 'Attempted to setup DoubleFrame information for poster using default style.' ) else: self.objectiveInfo['text'] = infoText self.auxFrame['image_color'] = frameColor def fitGeometry(self, geom, fFlip=0, dimension=0.8): p1 = Point3() p2 = Point3() geom.calcTightBounds(p1, p2) if fFlip: t = p1[0] p1.setX(-p2[0]) p2.setX(-t) d = p2 - p1 biggest = max(d[0], d[2]) s = dimension / biggest mid = (p1 + d / 2.0) * s geomXform = hidden.attachNewNode('geomXform') for child in geom.getChildren(): child.reparentTo(geomXform) geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s, s, s) geomXform.reparentTo(geom) def destroy(self): if hasattr(self, 'titleLabel'): self.titleLabel.destroy() self.auxFrame.destroy() self.auxIcon.destroy() self.auxOutline.destroy() self.auxText.destroy() self.objectiveInfo.destroy() self.locationInfo.destroy() self.progressBar.destroy() self.rewardFrame.destroy() self.sideInfo.destroy() self.lReward.destroy() # We need to cleanup our arrows if they were created. if hasattr(self, 'prevObjArrow'): self.prevObjArrow.destroy() self.nextObjArrow.destroy() del self.prevObjArrow del self.nextObjArrow del self.titleLabel del self.auxFrame del self.auxIcon del self.auxOutline del self.auxText del self.objectiveInfo del self.locationInfo del self.progressBar del self.rewardFrame del self.sideInfo del self.lReward del self.accessibleObjectives del self.viewObjective DirectFrame.destroy(self) self.notify.debug('Destroyed all elements.')
class QuestPoster(DirectFrame): notify = directNotify.newCategory('QuestPoster') def __init__(self, quest, parent=aspect2d, **kw): DirectFrame.__init__(self, relief=None) self.quest = quest # Let's begin building the quest poster. bookModel = loader.loadModel( 'phase_3.5/models/gui/stickerbook_gui.bam') questCard = bookModel.find('**/questCard') optiondefs = (('relief', None, None), ('image', questCard, None), ('image_scale', (0.8, 1.0, 0.58), None), ('state', DGG.NORMAL, None)) self.defineoptions(kw, optiondefs) self._deleteCallback = None self.questFrame = DirectFrame(parent=self, relief=None) self.headline = DirectLabel(parent=self.questFrame, relief=None, text='', text_font=CIGlobals.getMinnieFont(), text_fg=self.normalTextColor, text_scale=0.05, text_align=TextNode.ACenter, text_wordwrap=12.0, textMayChange=1, pos=(0, 0, 0.23)) self.questInfo = DirectLabel(parent=self.questFrame, relief=None, text='', text_fg=self.normalTextColor, text_scale=TEXT_SCALE, text_align=TextNode.ACenter, text_wordwrap=TEXT_WORDWRAP, textMayChange=1, pos=(0, 0, -0.0625)) self.rewardText = DirectLabel(parent=self.questFrame, relief=None, text='', text_fg=self.colors['rewardRed'], text_scale=0.0425, text_align=TextNode.ALeft, text_wordwrap=17.0, textMayChange=1, pos=(-0.36, 0, -0.26)) self.rewardText.hide() self.lPictureFrame = DirectFrame( parent=self.questFrame, relief=None, image=bookModel.find('**/questPictureFrame'), image_scale=IMAGE_SCALE_SMALL, text='', text_pos=(0, -0.11), text_fg=self.normalTextColor, text_scale=TEXT_SCALE, text_align=TextNode.ACenter, text_wordwrap=11.0, textMayChange=1) self.lPictureFrame.hide() self.rPictureFrame = DirectFrame( parent=self.questFrame, relief=None, image=bookModel.find('**/questPictureFrame'), image_scale=IMAGE_SCALE_SMALL, text='', text_pos=(0, -0.11), text_fg=self.normalTextColor, text_scale=TEXT_SCALE, text_align=TextNode.ACenter, text_wordwrap=11.0, textMayChange=1, pos=(0.18, 0, 0.13)) self.rPictureFrame.hide() self.lQuestIcon = DirectFrame(parent=self.lPictureFrame, relief=None, text=' ', text_font=CIGlobals.getSuitFont(), text_pos=(0, -0.03), text_fg=self.normalTextColor, text_scale=0.13, text_align=TextNode.ACenter, text_wordwrap=13.0, textMayChange=1) self.lQuestIcon.setColorOff(-1) self.rQuestIcon = DirectFrame(parent=self.rPictureFrame, relief=None, text=' ', text_font=CIGlobals.getSuitFont(), text_pos=(0, -0.03), text_fg=self.normalTextColor, text_scale=0.13, text_align=TextNode.ACenter, text_wordwrap=13.0, textMayChange=1) self.rQuestIcon.setColorOff(-1) self.auxText = DirectLabel(parent=self.questFrame, relief=None, text='', text_scale=QuestGlobals.QPauxText, text_fg=self.normalTextColor, text_align=TextNode.ACenter, textMayChange=1) self.auxText.hide() self.questProgress = DirectWaitBar(parent=self.questFrame, relief=DGG.SUNKEN, frameSize=(-0.95, 0.95, -0.1, 0.12), borderWidth=(0.025, 0.025), scale=0.2, frameColor=(0.945, 0.875, 0.706, 1.0), barColor=(0.5, 0.7, 0.5, 1), text='0/0', text_scale=0.19, text_fg=(0.05, 0.14, 0.4, 1), text_align=TextNode.ACenter, text_pos=(0, -0.04), pos=(0, 0, -0.195)) self.questProgress.hide() # This is the rotated text on the side. self.sideInfo = DirectLabel(parent=self.questFrame, relief=None, text=QuestGlobals.JUST_FOR_FUN, text_fg=(0.0, 0.439, 1.0, 1.0), text_shadow=(0, 0, 0, 1), pos=(-0.2825, 0, 0.2), scale=0.03) self.sideInfo.setR(-30) self.sideInfo.hide() bookModel.removeNode() self.laffMeter = None return def destroy(self): self._deleteGeoms() DirectFrame.destroy(self) def _deleteGeoms(self): for icon in (self.lQuestIcon, self.rQuestIcon): geom = icon['geom'] if geom: if hasattr(geom, 'delete'): geom.delete()
class QuestPoster(DirectFrame): notify = directNotify.newCategory('QuestPoster') def __init__(self, quest, parent = aspect2d, **kw): self.quest = quest # Let's begin building the quest poster. bookModel = loader.loadModel('phase_3.5/models/gui/stickerbook_gui.bam') questCard = bookModel.find('**/questCard') optiondefs = (('relief', None, None), ('image', questCard, None), ('image_scale', (0.8, 1.0, 0.58), None), ('state', DGG.NORMAL, None)) self.defineoptions(kw, optiondefs) DirectFrame.__init__(self, relief = None) self.initialiseoptions(QuestPoster) self.questFrame = DirectFrame(parent = self, relief = None) # Quest title text self.headline = DirectLabel(parent = self.questFrame, relief = None, text = self.quest.getName(), text_font = CIGlobals.getMinnieFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.05, text_align = TextNode.ACenter, text_wordwrap = 25.0, textMayChange = 1, pos = (0, 0, 0.23)) # Quest information self.questInfo = DirectLabel(parent = self.questFrame, relief = None, text = '', text_font = CIGlobals.getToonFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.04, text_align = TextNode.ACenter, text_wordwrap = TEXT_WORDWRAP, textMayChange = 1, pos = (QuestGlobals.DEFAULT_INFO_POS)) self.questInfo.hide() self.questInfo02 = DirectLabel(parent = self.questFrame, relief = None, text = '', text_font = CIGlobals.getToonFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.04, text_align = TextNode.ACenter, text_wordwrap = TEXT_WORDWRAP, textMayChange = 1, pos = (QuestGlobals.DEFAULT_INFO2_POS)) self.questInfo02.hide() self.locationInfo = DirectLabel(parent = self.questFrame, relief = None, text = 'N/A', text_font = CIGlobals.getToonFont(), text_fg = QuestGlobals.TEXT_COLOR, text_scale = TEXT_SCALE, text_align = TextNode.ACenter, text_wordwrap = TEXT_WORDWRAP, textMayChange = 1, pos = (0, 0, -0.115)) self.locationInfo.hide() # C'mon Brian this one is obvious self.rewardText = DirectLabel(parent = self.questFrame, relief = None, text = '', text_fg = QuestGlobals.REWARD_RED, text_scale = 0.0425, text_align = TextNode.ALeft, text_wordwrap = 17.0, textMayChange = 1, pos = (-0.36, 0, -0.26)) self.rewardText.hide() self.lPictureFrame = DirectFrame(parent = self.questFrame, relief = None, image = bookModel.find('**/questPictureFrame'), image_scale = QuestGlobals.IMAGE_SCALE_SMALL, text = '', text_pos = (0, -0.11), text_fg = QuestGlobals.TEXT_COLOR, text_scale = TEXT_SCALE, text_align = TextNode.ACenter, text_wordwrap = 11.0, pos = (QuestGlobals.DEFAULT_LEFT_PICTURE_POS), textMayChange = 1) self.lPictureFrame.hide() self.rPictureFrame = DirectFrame(parent = self.questFrame, relief = None, image = bookModel.find('**/questPictureFrame'), image_scale = QuestGlobals.IMAGE_SCALE_SMALL, text = '', text_pos = (0, -0.11), text_fg = QuestGlobals.TEXT_COLOR, text_scale = TEXT_SCALE, text_align = TextNode.ACenter, text_wordwrap = 11.0, textMayChange = 1, pos = (QuestGlobals.DEFAULT_RIGHT_PICTURE_POS)) self.rPictureFrame['image_color'] = Vec4(*QuestGlobals.GREEN) self.rPictureFrame.hide() self.lQuestIcon = DirectFrame(parent = self.lPictureFrame, relief = None, text = ' ', text_font = CIGlobals.getSuitFont(), text_pos = (0, -0.03), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.13, text_align = TextNode.ACenter, text_wordwrap = 13.0, textMayChange = 1) self.lQuestIcon.setColorOff(-1) self.rQuestIcon = DirectFrame(parent = self.rPictureFrame, relief = None, text = ' ', text_font = CIGlobals.getSuitFont(), text_pos = (0, -0.03), text_fg = QuestGlobals.TEXT_COLOR, text_scale = 0.13, text_align = TextNode.ACenter, text_wordwrap = 13.0, textMayChange = 1) self.rQuestIcon.setColorOff(-1) head = SuitBank.PennyPincher.getHead().generate() head.setDepthTest(True) head.setDepthWrite(True) head.setScale(0.25) for part in head.getChildren(): part.setDepthTest(True) part.setDepthWrite(True) self.fitGeometry(head, fFlip = 1) self.rQuestIcon['geom'] = head self.rQuestIcon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL self.rQuestIcon['geom_pos'] = Point3(0, 10, -0.05) self.rQuestIcon['geom_hpr'] = Point3(180, 0, 0) self.rQuestIcon.initialiseoptions(DirectFrame) self.auxText = DirectLabel(parent = self.questFrame, relief = None, text = 'Recover', text_font = CIGlobals.getToonFont(), text_scale = QuestGlobals.QPauxText, text_fg = QuestGlobals.TEXT_COLOR, text_align = TextNode.ACenter, pos = (QuestGlobals.DEFAULT_AUX_POS), textMayChange=1) self.auxText.hide() self.middleText = DirectLabel(parent = self.questFrame, relief = None, text = 'from:', text_font = CIGlobals.getToonFont(), text_scale = QuestGlobals.QPauxText, text_fg = QuestGlobals.TEXT_COLOR, text_align = TextNode.ACenter, pos = (QuestGlobals.DEFAULT_MIDDLE_POS), textMayChange=1) self.middleText.hide() self.questProgress = DirectWaitBar(parent = self.questFrame, relief = DGG.SUNKEN, frameSize=(-0.95, 0.95, -0.1, 0.12), borderWidth = (0.025, 0.025), scale = 0.2, frameColor = (0.945, 0.875, 0.706, 1.0), barColor=(0.5, 0.7, 0.5, 1), text='0/0', text_font = CIGlobals.getToonFont(), text_scale = 0.19, text_fg = (0.05, 0.14, 0.4, 1), text_align = TextNode.ACenter, text_pos = (0, -0.05), #-0.02 pos = (0, 0, -0.2425)) self.questProgress.hide() rewardFrameGeom = loader.loadModel('phase_4/models/gui/gag_shop_purchase_gui.bam') self.rewardFrame = DirectFrame(parent = self.questFrame, relief = None, geom = rewardFrameGeom.find('**/Goofys_Sign'), geom_scale = (0.615, 0, 0.4), pos = (-0.01, 0, -0.25) ) jellybeanJar = QuestGlobals.getFilmIcon() self.lRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None, geom = jellybeanJar, geom_scale = QuestGlobals.TP_ACCESS_SCALE, sortOrder = 1, pos = (QuestGlobals.LEFT_TP_ACCESS_POS)) self.lRewardFrame.setBin('gui-popup', 30) self.lRewardAmt = DirectFrame(parent = self.questFrame, relief = None, geom = rewardFrameGeom.find('**/Char_Pnl'), geom_scale = (0.15, 0, 0.1275), text = '#1', text_font = CIGlobals.getToonFont(), text_scale = 0.04, text_fg = (0, 0, 0, 1), text_align = TextNode.ACenter, text_pos = (0, -0.01), sortOrder = 2, pos = (-0.285, 0, -0.255)) self.lRewardAmt.setBin('gui-popup', 40) self.rRewardFrame = DirectFrame(parent = self.rewardFrame, relief = None, geom = QuestGlobals.getJBIcon(), geom_scale = QuestGlobals.JB_JAR_SCALE, pos = QuestGlobals.RIGHT_JB_JAR_POS) self.rRewardAmt = DirectFrame(parent = self.questFrame, relief = None, geom = rewardFrameGeom.find('**/Char_Pnl'), geom_scale = (0.15, 0, 0.1275), text = '25', text_font = CIGlobals.getToonFont(), text_scale = 0.04, text_fg = (0, 0, 0, 1), text_align = TextNode.ACenter, text_pos = (0, -0.01), pos = (0.2725, 0, -0.255)) self.rRewardAmt.setBin('gui-popup', 40) rewardFrameGeom.removeNode() # This is the rotated text on the side. self.sideInfo = DirectLabel(parent = self.questFrame, relief = None, text = QuestGlobals.JUST_FOR_FUN, text_fg = (0.0, 0.439, 1.0, 1.0), text_shadow = (0, 0, 0, 1), pos = (-0.2825, 0, 0.2), scale = 0.03) self.sideInfo.setR(-30) self.sideInfo.hide() bookModel.removeNode() self.laffMeter = None self.hide() return def handleIcon(self, objective, geom, scale, icon): isHead = True if type(geom) == ToonHead else geom.getName() == ('%sHead' % CIGlobals.Suit) if isHead: geom.setDepthWrite(1) geom.setDepthTest(1) self.fitGeometry(geom, fFlip = 1) if isinstance(objective, VisitNPCObjective) and icon == self.rQuestIcon: icon.setPos(icon.getX(), icon.getY(), icon.getZ() + 0.05) icon.setH(180) elif isinstance(objective, CogObjective): icon.setScale(QuestGlobals.IMAGE_SCALE_SMALL) icon.setPos(icon.getX(), icon.getY(), icon.getZ() - 0.04) if icon == self.lQuestIcon: icon.setH(180) icon['geom'] = geom icon['geom_scale'] = QuestGlobals.IMAGE_SCALE_SMALL else: icon['geom'] = geom icon['geom_scale'] = scale def update(self): objective = self.quest.getCurrentObjective() objective.updateInfo() # Let's setup the quest info. self.questInfo.setPos(self.quest.getInfoPos()) self.questInfo['text'] = self.quest.getInfoText() self.questInfo02.setPos(self.quest.getInfo02Pos()) self.questInfo02['text'] = self.quest.getInfo02Text() # Let's move the picture frames to the positions we want them in. self.lPictureFrame.setPos(self.quest.getLeftPicturePos()) self.rPictureFrame.setPos(self.quest.getRightPicturePos()) editLeftAtr = isinstance(objective, VisitNPCObjective) or isinstance(objective, CogObjective) if editLeftAtr and objective.getDidEditLeft() or not editLeftAtr: geom = self.quest.getLeftIconGeom() scale = self.quest.getLeftIconScale() icon = self.lQuestIcon self.handleIcon(objective, geom, scale, icon) self.handleIcon(objective, self.quest.getRightIconGeom(), self.quest.getRightIconScale(), self.rQuestIcon) else: geom = self.quest.getRightIconGeom() scale = self.quest.getRightIconScale() icon = self.rQuestIcon self.handleIcon(objective, geom, scale, icon) self.handleIcon(objective, self.quest.getLeftIconGeom(), self.quest.getLeftIconScale(), self.lQuestIcon) if self.questInfo02['text'] == '': self.rPictureFrame.hide() self.questInfo02.hide() else: self.rPictureFrame.show() self.questInfo02.show() self.middleText['text'] = self.quest.getMiddleText() if not self.middleText['text'] == '': self.middleText.show() self.questInfo.show() self.lPictureFrame.show() # Let's set the location text. self.locationInfo['text'] = self.quest.getLocationText() self.locationInfo['text_pos'] = (0, self.quest.getLocationY()) self.locationInfo.show() # Let's set the progress bar up. self.questProgress['text'] = self.quest.getProgressText() if len(self.questProgress['text']) > 0 and not objective.finished(): self.questProgress.show() self.questProgress['range'] = objective.getNeededAmount() self.questProgress['value'] = objective.getProgress() & pow(2, 16) - 1 else: self.questProgress.hide() # Let's setup the aux text. self.auxText.setPos(self.quest.getAuxPos()) self.auxText['text'] = self.quest.getAuxText() self.auxText.show() maxHP = base.localAvatar.getMaxHealth() # Let's setup the rewards. for i in xrange(0, len(self.quest.getRewards())): reward = self.quest.getRewards()[i] frame = self.lRewardFrame if (i == 0) else self.rRewardFrame info = self.lRewardAmt if (i == 0) else self.rRewardAmt rType = reward.getType() if(rType == RewardType.JELLYBEANS): frame['pos'] = QuestGlobals.LEFT_JB_JAR_POS if (i == 0) else QuestGlobals.RIGHT_JB_JAR_POS frame['geom'] = QuestGlobals.getJBIcon() frame['geom_scale'] = QuestGlobals.JB_JAR_SCALE info['text'] = str(reward.getModifier()) elif(rType == RewardType.TELEPORT_ACCESS or rType == RewardType.GAG_FRAME): frame['pos'] = QuestGlobals.LEFT_TP_ACCESS_POS if(i == 0) else QuestGlobals.RIGHT_TP_ACCESS_POS frame['geom'] = QuestGlobals.getTPAccessIcon() if(rType == RewardType.TELEPORT_ACCESS) else QuestGlobals.getFilmIcon() frame['geom_scale'] = QuestGlobals.TP_ACCESS_SCALE info['text'] = 'N/A' if(rType == RewardType.TELEPORT_ACCESS) else '#%s' % (str(reward.getModifier())) elif(rType == RewardType.LAFF_POINTS): frame.initialiseoptions(DirectFrame) r, g, b, _ = base.localAvatar.getHeadColor() pos = QuestGlobals.LEFT_LAFF_METER_POS if(i == 0) else QuestGlobals.RIGHT_LAFF_METER_POS # Create the laff meter with the new health. hp = maxHP + reward.getModifier() laffMeter = LaffOMeter() laffMeter.generate(r, g, b, base.localAvatar.getAnimal(), maxHP = hp, initialHP = hp) # Let's position the laff meter. frame['geom'] = laffMeter frame['geom_scale'] = QuestGlobals.LAFF_METER_SCALE frame.setPos(pos) info['text'] = '+%s' % (str(reward.getModifier())) laffMeter.destroy() laffMeter = None # Hide or show the other reward depending on if there's 2 rewards. if(len(self.quest.getRewards()) == 1): self.rRewardFrame.hide() self.rRewardAmt.hide() else: self.rRewardFrame.show() self.rRewardAmt.show() if objective.finished(): self.setColor(Vec4(*QuestGlobals.LIGHT_GREEN)) self.sideInfo['text'] = 'Completed!' self.sideInfo.show() self.questInfo.initialiseoptions(DirectLabel) self.questInfo02.initialiseoptions(DirectLabel) self.locationInfo.initialiseoptions(DirectLabel) self.lPictureFrame.initialiseoptions(DirectFrame) self.rPictureFrame.initialiseoptions(DirectFrame) self.lQuestIcon.initialiseoptions(DirectFrame) self.rQuestIcon.initialiseoptions(DirectFrame) self.auxText.initialiseoptions(DirectLabel) self.middleText.initialiseoptions(DirectLabel) self.sideInfo.initialiseoptions(DirectLabel) self.lPictureFrame['image_color'] = self.quest.getPictureFrameColor() self.rPictureFrame['image_color'] = self.quest.getPictureFrameColor() def fitGeometry(self, geom, fFlip = 0, dimension = 0.8): p1 = Point3() p2 = Point3() geom.calcTightBounds(p1, p2) if fFlip: t = p1[0] p1.setX(-p2[0]) p2.setX(-t) d = p2 - p1 biggest = max(d[0], d[2]) s = dimension / biggest mid = (p1 + d / 2.0) * s geomXform = hidden.attachNewNode('geomXform') for child in geom.getChildren(): child.reparentTo(geomXform) geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s, s, s) geomXform.reparentTo(geom) def destroy(self): self._deleteGeoms() DirectFrame.destroy(self) def _deleteGeoms(self): for icon in (self.lQuestIcon, self.rQuestIcon): geom = icon['geom'] if geom and hasattr(geom, 'delete'): geom.delete() def getQuest(self): return self.quest
class DirectSidebar(DirectFrame): def __init__( self, parent=None, frameSize=(1, 1), dragbarSize=0.05, align=ALIGN_LEFT | ALIGN_TOP, orientation=HORIZONTAL, opendir=RIGHT_OR_DOWN, pos=Vec3(0, 0, 0), text='', toggleFunc=None, frameColor=(1, 1, 1, 1), ): if parent is None: parent = aspect2d self.dragbarSize = dragbarSize self.align = align self.orientation = orientation self.opendir = opendir self.pos = pos self.frameSize = frameSize self.toggleFunc = toggleFunc self.collapsed = False DirectFrame.__init__( self, parent=parent, frameSize=(0, frameSize[0], 0, frameSize[1]), frameColor=frameColor, suppressMouse=1, ) self.initialiseoptions(DirectSidebar) self.resetFrameSize() self.collapseButton = DirectButton( parent=parent, borderWidth=(0, 0), relief=DGG.FLAT, command=self.toggleCollapsed, ) self.label = DirectLabel(parent=self.collapseButton, scale=0.04, text=text, text_align=TextNode.ACenter, frameColor=(0, 0, 0, 0)) if self.orientation == HORIZONTAL: self.label.setPos(Vec3(frameSize[0] / 2., 0, 0.015)) if self.orientation == VERTICAL: self.label.setPos(Vec3(0.035, 0, frameSize[1] / 2.)) self.label.setR(-90) self.accept('window-event', self.update) self.update() def destroy(self): self.label.detachNode() self.collapseButton.detachNode() self.detachNode() self.ignoreAll() #'window-event', self.update) def __del__(self): self.destroy() def update(self, args=None): aspectRatio = base.getAspectRatio() framePos = Vec3(self.pos[0], 0, self.pos[2]) if self.align & ALIGN_LEFT: framePos += Vec3(-aspectRatio, 0, 0) if self.align & ALIGN_RIGHT: framePos += Vec3(aspectRatio, 0, 0) if self.align & ALIGN_TOP: framePos += Vec3(0, 0, 1 - self.frameSize[1]) if self.align & ALIGN_BOTTOM: framePos += Vec3(0, 0, -1) if self.orientation == HORIZONTAL: if self.align & ALIGN_RIGHT: # a small help for the user framePos -= Vec3(self.frameSize[0], 0, 0) buttonSize = (0, self.frameSize[0], 0, self.dragbarSize) if self.opendir == RIGHT_OR_DOWN: # correct if self.collapsed: buttonPos = framePos + Vec3( 0, 0, self.frameSize[1] - self.dragbarSize) else: buttonPos = framePos + Vec3(0, 0, -self.dragbarSize) elif self.opendir == LEFT_OR_UP: if self.collapsed: buttonPos = framePos else: buttonPos = framePos + Vec3(0, 0, self.frameSize[1]) elif self.orientation == VERTICAL: buttonSize = (0, self.dragbarSize, 0, self.frameSize[1]) if self.opendir == RIGHT_OR_DOWN: if self.collapsed: buttonPos = framePos else: buttonPos = framePos + Vec3(self.frameSize[0], 0, 0) elif self.opendir == LEFT_OR_UP: framePos -= Vec3(self.frameSize[0], 0, 0) # a small help for the user if self.collapsed: buttonPos = framePos + Vec3( self.frameSize[0] - self.dragbarSize, 0, 0) else: buttonPos = framePos if self.collapsed: self.hide() else: self.show() self.setPos(framePos) self.collapseButton.setPos(buttonPos) self.collapseButton['frameSize'] = buttonSize def toggleCollapsed(self, state=None): if state is None: state = not self.collapsed self.collapsed = state if self.toggleFunc: try: self.toggleFunc(state) except: traceback.print_exc() self.update()
class QuestPoster(DirectFrame): notify = directNotify.newCategory('QuestPoster') # We need to declare and initialize these variables here # because some methods use them as default arguments. auxIcon = None # Requires one parameter, quest, this must be a Quest instance. # The next argument, parent, is where to reparent the DirectFrame to. # The next arguments are simply additional options when setting up the DirectFrame. def __init__(self, quest, parent=aspect2d, **kw): # The quest this poster is representing. self.quest = quest # Let's define our options for the DirectFrame. bookModel = loader.loadModel( 'phase_3.5/models/gui/stickerbook_gui.bam') optiondefs = (('relief', None, None), ('image', bookModel.find('**/questCard'), None), ('image_scale', (0.8, 1.0, 0.58), None), ('state', DGG.NORMAL, None)) self.defineoptions(kw, optiondefs) # Finally, initialize the DirectFrame. DirectFrame.__init__(self, relief=None) self.initialiseoptions(QuestPoster) # Let's declare and initialize our barebone GUI element variables. self.titleLabel = DirectLabel(parent=self, relief=None, text=self.quest.getName(), text_font=CIGlobals.getMinnieFont(), text_fg=QuestGlobals.TEXT_COLOR, text_scale=0.05, text_align=TextNode.ACenter, text_wordwrap=25.0, textMayChange=1, pos=(0, 0, 0.23)) ########################################################################## # THE FOLLOWING ELEMENTS BELOW ARE GROUPED TOGETHER # ########################################################################## # The background frame where the objective image is displayed. # This is the colored background frame. self.auxFrame = DirectFrame( parent=self, relief=None, image=bookModel.find('**/questPictureFrame'), image_scale=QuestGlobals.IMAGE_SCALE_SMALL, text='', text_pos=(0, -0.11), text_fg=QuestGlobals.TEXT_COLOR, text_scale=QuestGlobals.QPtextScale, text_align=TextNode.ACenter, text_wordwrap=11.0, pos=QuestGlobals.DEFAULT_LEFT_PICTURE_POS) # The icon that goes on top of the aux frame. self.auxIcon = DirectFrame(parent=self.auxFrame, relief=None, text=' ', text_font=CIGlobals.getSuitFont(), text_pos=(0, -0.03), text_fg=QuestGlobals.TEXT_COLOR, text_scale=0.13, text_align=TextNode.ACenter, text_wordwrap=13.0, textMayChange=1) self.auxIcon.setColorOff(-1) # The aux text saying: DEFEAT, RECOVER, etc. self.auxText = DirectLabel(parent=self, relief=None, text=QuestGlobals.RECOVER, text_font=CIGlobals.getToonFont(), text_scale=QuestGlobals.QPauxText, text_fg=QuestGlobals.TEXT_COLOR, text_align=TextNode.ACenter, textMayChange=1, pos=QuestGlobals.DEFAULT_AUX_POS) self.auxText.hide() ########################################################################## # Information displayed about the objective. self.objectiveInfo = DirectLabel( parent=self, relief=None, text='', text_font=CIGlobals.getToonFont(), text_fg=QuestGlobals.TEXT_COLOR, text_scale=0.04, text_align=TextNode.ACenter, text_wordwrap=QuestGlobals.QPtextWordwrap, textMayChange=1, pos=(QuestGlobals.DEFAULT_INFO_POS)) self.objectiveInfo.hide() # Information displayed showing the location. self.locationInfo = DirectLabel( parent=self, relief=None, text='N/A', text_font=CIGlobals.getToonFont(), text_fg=QuestGlobals.TEXT_COLOR, text_scale=QuestGlobals.QPtextScale, text_align=TextNode.ACenter, text_wordwrap=QuestGlobals.QPtextWordwrap, textMayChange=1, pos=(0, 0, -0.115)) self.locationInfo.hide() # The progress bar showing the objective's progress self.progressBar = DirectWaitBar(parent=self, relief=DGG.SUNKEN, frameSize=(-0.95, 0.95, -0.1, 0.12), borderWidth=(0.025, 0.025), scale=0.2, frameColor=(0.945, 0.875, 0.706, 1.0), barColor=(0.5, 0.7, 0.5, 1), text='0/0', text_font=CIGlobals.getToonFont(), text_scale=0.19, text_fg=(0.05, 0.14, 0.4, 1), text_align=TextNode.ACenter, text_pos=(0, -0.05), pos=(0, 0, -0.2425)) self.progressBar.hide() # The wood panel at the bottom where rewards are displayed. rewardFrameGeom = loader.loadModel( 'phase_4/models/gui/gag_shop_purchase_gui.bam') self.rewardFrame = DirectFrame( parent=self, relief=None, geom=rewardFrameGeom.find('**/Goofys_Sign'), geom_scale=(0.615, 0, 0.4), pos=(-0.01, 0, -0.25)) # The text displayed on the right side of the frame with additional information, if necessary. self.sideInfo = DirectLabel(parent=self, relief=None, text=QuestGlobals.JUST_FOR_FUN, text_fg=(0.0, 0.439, 1.0, 1.0), text_shadow=(0, 0, 0, 1), pos=(-0.2825, 0, 0.2), scale=0.03) self.sideInfo.setR(-30) # This side information is usually not needed, let's hide it. self.sideInfo.hide() # Remove the nodes of the loaded models we no longer need. bookModel.removeNode() rewardFrameGeom.removeNode() # Let's hide this until it is needed. self.hide() return def setup(self): objective = self.quest.currentObjective objective.updateInfo() self.objectiveInfo.show() self.auxFrame.show() self.locationInfo['text'] = QuestGlobals.getLocationText( objective.location) self.locationInfo['text_pos'] = (0, 0 if not QuestGlobals.isShopLocation( objective.location) else 0.025) self.locationInfo.show() # Let's setup the quest progress bar progress = objective.amount if hasattr(objective, 'amount') else None if progress and objective.neededAmount > 0: self.progressBar['range'] = objective.getNeededAmount() self.progressBar['value'] = progress & pow(2, 16) - 1 if objective.__class__ in [ DeliverItemObjective, CogObjective, RecoverItemObjective ]: self.progressBar.show() self.auxText.show() # Let's handle the objectives. if objective.__class__ == CogObjective: self.handleCogObjective() elif objective.__class__ == VisitNPCObjective: self.handleNPCObjective() self.titleLabel.initialiseoptions(DirectLabel) self.auxIcon.initialiseoptions(DirectFrame) self.auxText.initialiseoptions(DirectLabel) self.objectiveInfo.initialiseoptions(DirectLabel) self.locationInfo.initialiseoptions(DirectLabel) self.rewardFrame.initialiseoptions(DirectFrame) self.sideInfo.initialiseoptions(DirectLabel) # Changes geometry and scale of an icon. def handleSimpleIcon(self, geom, scale, icon): icon['geom'] = geom icon['geom_scale'] = scale def handleComplexIcon(self, geom, icon, scale=QuestGlobals.IMAGE_SCALE_SMALL): isHead = True if type(geom) == ToonHead else geom.getName() == ( '%sHead' % CIGlobals.Suit) if isHead: geom.setDepthWrite(1) geom.setDepthTest(1) self.fitGeometry(geom, fFlip=1) self.handleSimpleIcon(geom, scale, icon) # We have to rotate the head and set the scale of the icon. if CIGlobals.Suit in geom.getName(): cogName = geom.getPythonTag('Settings') data = QuestGlobals.Suit2PosterZNDScale.get(cogName) zOffset = data[0] headScale = data[1] icon.setScale(headScale) icon.setZ(icon.getZ() + zOffset) geom.setH(180) else: raise ValueError( 'Tried to use #handleComplexIcon() on a non-complex icon. Use this method for 3D geometry.' ) def handleCogObjective(self, iconElement=auxIcon, auxText=QuestGlobals.DEFEAT, frameColor=QuestGlobals.BLUE): objective = self.quest.currentObjective infoText = objective.getTaskInfo(speech=False) if objective.__class__ == RecoverItemObjective: infoText = QuestGlobals.makePlural(objective.name) print 'Yep' if not iconElement: iconElement = self.auxIcon # Let's make sure we have a current objective that is # an instance of the CogObjective class and this poster isn't destroyed. if not objective or not hasattr(self, 'titleLabel') or not isinstance( objective, CogObjective): return if objective.dept: icons = loader.loadModel('phase_3/models/gui/cog_icons.bam') deptIcon = None if objective.dept == Dept.BOSS: deptIcon = icons.find('**/CorpIcon') else: deptIcon = icons.find('**/%sIcon' % objective.dept.getTie().title()) # Correct the medallion color. deptIcon.setColor(SuitGlobals.medallionColors[objective.dept]) # Setup the icon and remove the icons node. self.handleSimpleIcon(deptIcon, 0.13, iconElement) icons.removeNode() elif not objective.name: # We aren't fighting a Cog in particular. cogIcon = QuestGlobals.getCogIcon() self.handleSimpleIcon(cogIcon, cogIcon.getScale(), iconElement) # We're fighting a Cog in particular. if objective.name: cogHeadInstance = SuitBank.getSuitByName(objective.name).getHead() cogHead = cogHeadInstance.generate() cogHead.setName('%sHead' % CIGlobals.Suit) cogHead.setPythonTag('Settings', cogHeadInstance.head) cogHeadInstance.setScale(2) self.handleComplexIcon(cogHead, iconElement) if not iconElement is self.auxIcon: if hasattr(self, 'goalInfo'): # We're working with the second frame, on the right. # Let's update the information pertaining to this side. self.goalInfo['text'] = infoText self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS) self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS) else: raise AttributeError( 'Attempted to setup DoubleFrame information for poster using default style.' ) else: self.objectiveInfo['text'] = infoText self.auxText['text'] = auxText # Let's set the progress bar text pgBarText = '%d of %d %s' % (objective.amount, objective.neededAmount, QuestGlobals.makePastTense(auxText)) self.progressBar['text'] = pgBarText # Let's set the color of the poster. frame = self.auxFrame if iconElement is self.auxIcon else self.goalFrame frame['image_color'] = Vec4(*frameColor) def handleNPCObjective(self, iconElement=auxIcon, auxText=QuestGlobals.VISIT, frameColor=QuestGlobals.BROWN): objective = self.quest.currentObjective infoText = CIGlobals.NPCToonNames[objective.npcId] if not iconElement: iconElement = self.auxIcon # Let's make sure we have a current objective that is # an instance of the CogObjective class and this poster isn't destroyed. if not objective or not hasattr(self, 'titleLabel') or not isinstance( objective, VisitNPCObjective): return # Let's generate the head. dna = ToonDNA() dna.setDNAStrand(CIGlobals.NPCToonDict.get(objective.npcId)[2]) head = ToonHead(base.cr) head.generateHead(dna.getGender(), dna.getAnimal(), dna.getHead(), forGui=1) head.setHeadColor(dna.getHeadColor()) self.handleComplexIcon(head, iconElement) self.auxText['text'] = auxText if not iconElement is self.auxIcon: if hasattr(self, 'goalInfo'): # We're working with the second frame, on the right. # Let's update the information pertaining to this side. self.goalInfo['text'] = infoText self.goalInfo.setPos(QuestGlobals.RECOVER_INFO2_POS) self.auxText.setPos(QuestGlobals.RECOVER_AUX_POS) self.goalFrame['image_color'] = frameColor else: raise AttributeError( 'Attempted to setup DoubleFrame information for poster using default style.' ) else: self.objectiveInfo['text'] = infoText self.auxFrame['image_color'] = frameColor def fitGeometry(self, geom, fFlip=0, dimension=0.8): p1 = Point3() p2 = Point3() geom.calcTightBounds(p1, p2) if fFlip: t = p1[0] p1.setX(-p2[0]) p2.setX(-t) d = p2 - p1 biggest = max(d[0], d[2]) s = dimension / biggest mid = (p1 + d / 2.0) * s geomXform = hidden.attachNewNode('geomXform') for child in geom.getChildren(): child.reparentTo(geomXform) geomXform.setPosHprScale(-mid[0], -mid[1] + 1, -mid[2], 180, 0, 0, s, s, s) geomXform.reparentTo(geom) def destroy(self): if hasattr(self, 'titleLabel'): self.titleLabel.destroy() self.auxFrame.destroy() self.auxIcon.destroy() self.auxText.destroy() self.objectiveInfo.destroy() self.locationInfo.destroy() self.progressBar.destroy() self.rewardFrame.destroy() self.sideInfo.destroy() del self.titleLabel del self.auxFrame del self.auxIcon del self.auxText del self.objectiveInfo del self.locationInfo del self.progressBar del self.rewardFrame del self.sideInfo DirectFrame.destroy(self) self.notify.debug('Destroyed all elements.')
class DirectSidebar(DirectFrame): def __init__( self, parent=None, frameSize=(1, 1), dragbarSize=0.05, align=ALIGN_LEFT|ALIGN_TOP, orientation=HORIZONTAL, opendir=RIGHT_OR_DOWN, pos=Vec3(0,0,0), text='', toggleFunc=None, frameColor=(1,1,1,1), ): if parent is None: parent=aspect2d self.dragbarSize=dragbarSize self.align=align self.orientation=orientation self.opendir=opendir self.pos=pos self.frameSize=frameSize self.toggleFunc=toggleFunc self.collapsed=False DirectFrame.__init__( self, parent=parent, frameSize=(0,frameSize[0],0,frameSize[1]), frameColor=frameColor, suppressMouse=1, ) self.initialiseoptions(DirectSidebar) self.resetFrameSize() self.collapseButton = DirectButton( parent=parent, borderWidth=(0, 0), relief=DGG.FLAT, command=self.toggleCollapsed, ) self.label = DirectLabel( parent=self.collapseButton, scale=0.04, text=text, text_align=TextNode.ACenter, frameColor=(0,0,0,0) ) if self.orientation == HORIZONTAL: self.label.setPos(Vec3(frameSize[0]/2.,0,0.015)) if self.orientation == VERTICAL: self.label.setPos(Vec3(0.035,0,frameSize[1]/2.)) self.label.setR(-90) self.accept('window-event', self.update) self.update() def destroy(self): self.label.detachNode() self.collapseButton.detachNode() self.detachNode() self.ignoreAll()#'window-event', self.update) def __del__(self): self.destroy() def update(self, args=None): aspectRatio=base.getAspectRatio() framePos=Vec3(self.pos[0],0,self.pos[2]) if self.align & ALIGN_LEFT: framePos+=Vec3(-aspectRatio,0,0) if self.align & ALIGN_RIGHT: framePos+=Vec3(aspectRatio,0,0) if self.align & ALIGN_TOP: framePos+=Vec3(0,0,1-self.frameSize[1]) if self.align & ALIGN_BOTTOM: framePos+=Vec3(0,0,-1) if self.orientation == HORIZONTAL: if self.align & ALIGN_RIGHT: # a small help for the user framePos-=Vec3(self.frameSize[0],0,0) buttonSize=(0,self.frameSize[0],0,self.dragbarSize) if self.opendir == RIGHT_OR_DOWN: # correct if self.collapsed: buttonPos=framePos+Vec3(0,0,self.frameSize[1]-self.dragbarSize) else: buttonPos=framePos+Vec3(0,0,-self.dragbarSize) elif self.opendir == LEFT_OR_UP: if self.collapsed: buttonPos=framePos else: buttonPos=framePos+Vec3(0,0,self.frameSize[1]) elif self.orientation == VERTICAL: buttonSize=(0,self.dragbarSize,0,self.frameSize[1]) if self.opendir == RIGHT_OR_DOWN: if self.collapsed: buttonPos=framePos else: buttonPos=framePos+Vec3(self.frameSize[0],0,0) elif self.opendir == LEFT_OR_UP: framePos-=Vec3(self.frameSize[0],0,0) # a small help for the user if self.collapsed: buttonPos=framePos+Vec3(self.frameSize[0]-self.dragbarSize,0,0) else: buttonPos=framePos if self.collapsed: self.hide() else: self.show() self.setPos(framePos) self.collapseButton.setPos(buttonPos) self.collapseButton['frameSize']=buttonSize def toggleCollapsed(self,state=None): if state is None: state=not self.collapsed self.collapsed=state if self.toggleFunc: try: self.toggleFunc(state) except: traceback.print_exc() self.update()