Exemplo n.º 1
0
class ChatBubble:
    def __init__(self, text, unit):
        self.creation_time = datetime.now()
        font = MainFont()
        frame_padding = 0.3
        half_frame_length = len(text) * 0.1 + frame_padding
        self.bubble_text = DirectLabel(
            text=text,
            pos=(0, 0, 0.66),
            scale=0.04,
            parent=unit.base_node,
            text_bg=(0, 0, 0, 0),
            text_fg=(1, 1, 1, 1),
            frameColor=(0, 0, 0, 0),
            text_font=font,
        )
        self.bubble_frame = DirectFrame(pos=(0, 0.01, 0.67),
                                        scale=0.1,
                                        parent=unit.base_node,
                                        frameColor=(0, 0, 0, 0.5),
                                        frameSize=(-half_frame_length,
                                                   half_frame_length, -0.5,
                                                   0.5))

        self.bubble_text.set_compass(core.instance.camera)
        self.bubble_frame.set_compass(core.instance.camera)

    def destroy(self):
        self.bubble_text.destroy()
        self.bubble_frame.destroy()
Exemplo n.º 2
0
 def destroy(self):
     if self.av:
         ToontownIntervals.cleanup(self.av.uniqueName('laffMeterBoing') + '-' + str(self.this))
         ToontownIntervals.cleanup(self.av.uniqueName('laffMeterBoing') + '-' + str(self.this) + '-play')
         self.ignore(self.av.uniqueName('hpChange'))
     
     del self.style
     del self.av
     del self.hp
     del self.maxHp
     if self.isToon:
         del self.frown
         del self.smile
         del self.openSmile
         del self.tooth1
         del self.tooth2
         del self.tooth3
         del self.tooth4
         del self.tooth5
         del self.tooth6
         del self.teeth
         del self.fractions
         del self.maxLabel
         del self.hpLabel
     
     DirectFrame.destroy(self)
Exemplo n.º 3
0
 def destroy(self):
     ToontownIntervals.cleanup('memocount_pulse')
     self._countLabel.removeNode()
     del self._countLabel
     self._memoIcon.removeNode()
     del self._memoIcon
     DirectFrame.destroy(self)
 def destroy(self):
     if self.av:
         ToontownIntervals.cleanup(
             self.av.uniqueName('laffMeterBoing') + '-' + str(self.this))
         ToontownIntervals.cleanup(
             self.av.uniqueName('laffMeterBoing') + '-' + str(self.this) +
             '-play')
         self.ignore(self.av.uniqueName('hpChange'))
     del self.style
     del self.av
     del self.hp
     del self.maxHp
     if self.isToon:
         del self.frown
         del self.smile
         del self.openSmile
         del self.tooth1
         del self.tooth2
         del self.tooth3
         del self.tooth4
         del self.tooth5
         del self.tooth6
         del self.teeth
         del self.fractions
         del self.maxLabel
         del self.hpLabel
     DirectFrame.destroy(self)
    def destroy(self):
        if self.dayClickCallback is not None:
            self.numberWidget.destroy()

        self.dayClickCallback = None
        self.notify.debug('desroying %s' % self.myDate)

        try:
            for item in self.scrollList['items']:
                if hasattr(item,
                           'description') and item.description and hasattr(
                               item.description, 'destroy'):
                    self.notify.debug('desroying description of item %s' %
                                      item)
                    item.unbind(DGG.ENTER)
                    item.unbind(DGG.EXIT)
                    item.description.destroy()
                    continue
        except e:
            self.notify.debug('pass %s' % self.myDate)

        self.scrollList.removeAndDestroyAllItems()
        self.scrollList.destroy()
        self.dayButton.destroy()
        DirectFrame.destroy(self)
Exemplo n.º 6
0
 def destroy(self):
     if self.av:
         taskMgr.remove(
             self.av.uniqueName('laffMeterBoing') + '-' + str(self.this))
         taskMgr.remove(
             self.av.uniqueName('laffMeterBoing') + '-' + str(self.this) +
             '-play')
         self.ignore(self.av.uniqueName("hpChange"))
     del self.style
     del self.av
     del self.hp
     del self.maxHp
     if self.isToon:
         del self.frown
         del self.smile
         del self.openSmile
         del self.tooth1
         del self.tooth2
         del self.tooth3
         del self.tooth4
         del self.tooth5
         del self.tooth6
         del self.teeth
         del self.fractions
         del self.maxLabel
         del self.hpLabel
     DirectFrame.destroy(self)
 def destroy(self):
     ToontownIntervals.cleanup('memocount_pulse')
     self._countLabel.removeNode()
     del self._countLabel
     self._memoIcon.removeNode()
     del self._memoIcon
     DirectFrame.destroy(self)
Exemplo n.º 8
0
 def destroy(self):
     self.ignore('questPageUpdated')
     self.mapOpenButton.destroy()
     self.mapCloseButton.destroy()
     del self.mapOpenButton
     del self.mapCloseButton
     DirectFrame.destroy(self)
Exemplo n.º 9
0
 def destroy(self):
     self.ignore('questPageUpdated')
     self.mapOpenButton.destroy()
     self.mapCloseButton.destroy()
     del self.mapOpenButton
     del self.mapCloseButton
     DirectFrame.destroy(self)
Exemplo n.º 10
0
class Alert(Notifier):
    def __init__(self, reason):
        Notifier.__init__(self, "alert")
        VirtualFileSystem.getGlobalPtr().mount(Filename("mf/alert.mf"), ".",
                                               VirtualFileSystem.MFReadOnly)
        ok = loader.loadModel("alert.egg")

        if reason not in LOCAL_EN:
            reason = GENERAL

        self.reason = reason

        self.bg_frame = DirectFrame(frameColor=(0, 0, 0, 0),
                                    frameSize=(-1, 1, -1, 1),
                                    suppressMouse=1,
                                    state=DGG.NORMAL,
                                    sortOrder=1000)
        self.frame = DirectFrame(frameSize=(1, 1, 1, 1),
                                 image=ok.find('**/alert'),
                                 image_scale=(1, 0, 0.6),
                                 state=DGG.NORMAL,
                                 parent=self.bg_frame)
        self.text = OnscreenText(text=LOCAL_EN[reason],
                                 fg=(1, 1, 1, 1),
                                 pos=(0, 0.15, 0),
                                 align=TextNode.ACenter,
                                 wordwrap=13,
                                 parent=self.frame)
        self.button = DirectButton(geom=(ok.find('**/ok-ready'),
                                         ok.find('**/ok-click'),
                                         ok.find('**/ok-hover'),
                                         ok.find('**/ok-click')),
                                   relief=None,
                                   geom_scale=(0.3, 0, 0.15),
                                   geom_pos=(0, 0, -0.175),
                                   pressEffect=0,
                                   command=self.destroy,
                                   parent=self.frame)

        self.notify.debug(
            f"[__init__] Created Alert with reason {self.reason}")

        loader.unloadModel(ok)

    def __repr__(self):
        return str(self.reason)

    def destroy(self):
        VirtualFileSystem.getGlobalPtr().unmount("mf/alert.mf")
        VirtualFileSystem.getGlobalPtr().unmount("mf/ok_small.mf")
        self.bg_frame.destroy()
        self.frame.destroy()
        self.button.destroy()
        self.text.cleanup()
        self.text.destroy()
        del self.frame
        del self.button
        del self.text
        del self
Exemplo n.º 11
0
class EnemyDesc:
    """Enemy class/object description.

    A teaching note about enemy class/object. Is shown on
    player's screen, when a new enemy class/object is added
    into the list of attacking enemy units.
    """
    def __init__(self, class_):
        self._fr = DirectFrame(
            frameSize=(-0.5, 0.5, -0.5, 0.5),
            frameColor=(0.14, 0.14, 0.14, 0.82),
            state=DGG.NORMAL,
        )
        DirectLabel(  # the note title
            parent=self._fr,
            text=base.labels.CLASS_DESCS[class_]["title"],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_fg=RUST_COL,
            text_scale=0.038,
            pos=(0, 0, 0.44),
            frameColor=(0, 0, 0, 0),
        )
        # an image on the note (usually demonstrates
        # the new enemy class/object representer)
        DirectFrame(
            parent=self._fr,
            frameTexture="teach_shots/{}.png".format(
                base.labels.CLASS_DESCS[class_]["preview"]  # noqa: F821
            ),
            pos=(0, 0, 0.15),
            frameSize=(-0.39, 0.39, -0.24, 0.24),
        ).setTransparency(TransparencyAttrib.MAlpha)

        DirectLabel(  # the enemy class/object description
            parent=self._fr,
            pos=(0, 0, -0.18),
            frameColor=(0, 0, 0, 0),
            text_fg=SILVER_COL,
            text_scale=0.035,
            text=base.labels.CLASS_DESCS[class_]["desc"],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
        )
        base.main_menu.bind_button(  # noqa: F821
            DirectButton(
                parent=self._fr,
                text=base.labels.CLASS_DESCS[class_]["but_text"],  # noqa: F821
                text_font=base.main_font,  # noqa: F821
                text_scale=0.04,
                relief=None,
                pos=(0, 0, -0.45),
                text_fg=RUST_COL,
                command=self._hide,
                clickSound=base.main_menu.click_snd,  # noqa: F821
            ))
        base.main_menu.new_enemy_snd.play()  # noqa: F821

    def _hide(self):
        """Destroy the teaching note."""
        self._fr.destroy()
 def destroy(self):
     self.items = {}
     del self.items
     for key, entry in self.itemEntries.iteritems():
         entry[0].destroy()
         entry[1].destroy()
         self.itemEntries[key] = None
     DirectFrame.destroy(self)
Exemplo n.º 13
0
    def destroy(self):
        self.ignoreAll()

        if self.timer:
            self.timer.destroy()

        taskMgr.remove(self.taskName('runLaffCounter'))
        DirectFrame.destroy(self)
 def destroy(self):
     taskMgr.remove('RepairGameGUIUpdate')
     DirectFrame.destroy(self)
     for b in self.buttons:
         self.buttons[b].destroy()
     
     del self.buttons
     del self.repairGame
Exemplo n.º 15
0
    def destroy(self):
        self.ignoreAll()

        if self.timer:
            self.timer.destroy()

        taskMgr.remove(self.taskName('runLaffCounter'))
        DirectFrame.destroy(self)
Exemplo n.º 16
0
    def destroy(self):
        taskMgr.remove('RepairGameGUIUpdate')
        DirectFrame.destroy(self)
        for b in self.buttons:
            self.buttons[b].destroy()

        del self.buttons
        del self.repairGame
Exemplo n.º 17
0
 def destroy(self):
     self.movie.finish()
     del self.movie
     del self.winVoteSfx
     del self.noVoteSfx
     del self.upArrowSfx
     del self.loseVoteSfx
     del self.downArrowSfx
     DirectFrame.destroy(self)
Exemplo n.º 18
0
 def destroy(self):
     del self.checkedHeight
     del self.partyInfo
     del self.parent
     del self.background
     del self.whosePartyLabel
     del self.whenTextLabel
     del self.partyStatusLabel
     DirectFrame.destroy(self)
Exemplo n.º 19
0
 def destroy(self):
     del self.checkedHeight
     del self.partyInfo
     del self.parent
     del self.background
     del self.whosePartyLabel
     del self.whenTextLabel
     del self.partyStatusLabel
     DirectFrame.destroy(self)
Exemplo n.º 20
0
class DistributedHQNPCToon(DistributedNPCToon.DistributedNPCToon):
    notify = directNotify.newCategory("DistributedHQNPCToon")

    def __init__(self, cr):
        DistributedNPCToon.DistributedNPCToon.__init__(self, cr)
        self.questFrame = None
        self.questBtns = None
        self.questNotes = None

    def makePickableQuests(self, list):
        quests = []
        for questId in list:
            quests.append(Quests.Quest(questId, 0, 0, list.index(questId)))
        positions = [(0, 0, 0.6), (0, 0, 0), (0, 0, -0.6)]
        self.questNotes = base.localAvatar.questManager.makeQuestNotes(quests = quests)
        self.questFrame = DirectFrame(parent = base.a2dLeftCenter, relief = None, pos = (0.5, 0, 0),
            geom = DGG.getDefaultDialogGeom(), geom_color=Vec4(0.8, 0.6, 0.4, 1),
            geom_scale=(1.85, 1, 0.9), geom_hpr=(0, 0, -90))
        self.questBtns = []
        for i in xrange(len(self.questNotes)):
            note = self.questNotes[i]
            note.setPos(0, 0, 0)
            if quests[i].currentObjective.type in Quests.DefeatObjectives:
                note.progressText.hide()
            btn = DirectButton(geom = note, parent = self.questFrame,
                pos = positions[i], command = self.d_pickedQuest, extraArgs = [quests[i]], relief = None)
            btn.setScale(1.15)
            note.reparentTo(btn.stateNodePath[0], 20)
            note.instanceTo(btn.stateNodePath[1], 20)
            note.instanceTo(btn.stateNodePath[2], 20)
            note.show()
            self.questBtns.append(btn)

    def removePickableQuests(self):
        if self.questNotes:
            for note in self.questNotes:
                note.destroy()
            self.questNotes = None
        if self.questBtns:
            for btn in self.questBtns:
                btn.destroy()
            self.questBtns = None
        if self.questFrame:
            self.questFrame.destroy()
            self.questFrame = None

    def d_pickedQuest(self, quest):
        self.removePickableQuests()
        self.sendUpdate('pickedQuest', [quest.questId])
        self.currentQuestId = quest.questId
        self.currentQuestObjective = 0
        self.currentChatIndex = 0
        self.doNPCChat(Quests.QuestHQOfficerDialogue)

    def disable(self):
        self.removePickableQuests()
        DistributedNPCToon.DistributedNPCToon.disable(self)
Exemplo n.º 21
0
 def destroy(self):
     self.movie.finish()
     del self.movie
     del self.winVoteSfx
     del self.noVoteSfx
     del self.upArrowSfx
     del self.loseVoteSfx
     del self.downArrowSfx
     DirectFrame.destroy(self)
Exemplo n.º 22
0
class Layout(object):
    def __init__(self, width, height, parent=None, frameColor=(1, 1, 1, 1), frameSize=(0, 0.5, -0.5, 0)):
        self.width = width
        self.height = height
        if parent is None:
            parent = aspect2d
        self.parent = parent
        self.frame = DirectFrame(parent=parent, frameColor=frameColor, frameSize=frameSize, state=DGG.DISABLED)
        self.frame.setPos(0, 0, 0)
        self.children = [[None for y in range(self.height)] for x in range(self.width)]
        self.children_width = [[0.0 for y in range(self.height)] for x in range(self.width)]
        self.children_height = [[0.0 for y in range(self.height)] for x in range(self.width)]

    def set_child(self, x, y, child):
        if x >= self.width or y >= self.height: return
        child.reparent_to(self.frame)
        self.children[x][y] = child
        bounds = child.getBounds()
        if bounds is not None:
            width = bounds[1] - bounds[0]
            height = bounds[3] - bounds[2]
            self.children_width[x][y] = width
            self.children_height[x][y] = height
        else:
            self.children_width[x][y] = 0
            self.children_height[x][y] = 0

    def recalc_positions(self):
        max_widths = []
        for x in range(self.width):
            max_width = 0.0
            for y in range(self.height):
                max_width = max(max_width, self.children_width[x][y])
            max_widths.append(max_width)
        max_heights = []
        for y in range(self.height):
            max_height = 0.0
            for x in range(self.width):
                max_height = max(max_height, self.children_height[x][y])
            max_heights.append(max_height)
        pos_x = 0.0
        for x in range(self.width):
            pos_y = 0.0
            for y in range(self.height):
                pos_y -= max_heights[y]
                child = self.children[x][y]
                if child is not None:
                    child.setPos(pos_x, 0, pos_y)
            pos_x += max_widths[x]
        self.frame['frameSize']= [0, pos_x, 0, pos_y]

    def destroy(self):
        self.frame.destroy()

    def reparent_to(self, parent):
        self.frame.reparent_to(parent)
 def destroy(self):
     taskMgr.remove('JellybeanRewardGuiTransferOneJellybean')
     del self.countSound
     del self.overMaxSound
     self.frame.destroy()
     self.earnedLabel.destroy()
     self.jarLabel.destroy()
     self.messageLabel.destroy()
     self.closeButton.destroy()
     DirectFrame.destroy(self)
 def destroy(self):
     self.disable()
     self.buffer.destroy()
     self.stopLocalAvShipPosHprTask()
     self.mapBall.removeNode()
     del self.mapBall
     self.worldRoot.removeNode()
     del self.render
     del self.worldRoot
     DirectFrame.destroy(self)
Exemplo n.º 25
0
 def destroy(self):
     taskMgr.remove('JellybeanRewardGuiTransferOneJellybean')
     del self.countSound
     del self.overMaxSound
     self.frame.destroy()
     self.earnedLabel.destroy()
     self.jarLabel.destroy()
     self.messageLabel.destroy()
     self.closeButton.destroy()
     DirectFrame.destroy(self)
Exemplo n.º 26
0
 def destroy(self):
     self.disable()
     self.buffer.destroy()
     self.stopLocalAvShipPosHprTask()
     self.mapBall.removeNode()
     del self.mapBall
     self.worldRoot.removeNode()
     del self.render
     del self.worldRoot
     DirectFrame.destroy(self)
Exemplo n.º 27
0
    def destroy(self):
        self.items = {}
        del self.items
        for key, entry in self.itemEntries.iteritems():
            entry[0].destroy()
            entry[1].destroy()
            self.itemEntries[key] = None

        DirectFrame.destroy(self)
        return
Exemplo n.º 28
0
class AlertPopup(DirectObject):
    
    def __init__(self, title, message, okayFunction, cancelFunction):
        self.okayFunction = okayFunction
        self.cancelFunction = cancelFunction
        self.node = aspect2d.attachNewNode('alertPopup')
        self.frame = DirectFrame()
        self.LoadContent(title, message)
        self.frame.reparentTo(self.node)
        
    def LoadContent(self, title, message):
        bg = OnscreenImage(image = 'Assets/Images/Inventory/BlackScreen.png', scale = (2, 1, 1))
        bg.setTransparency(TransparencyAttrib.MAlpha)
        bg.reparentTo(self.node)
        
        popup = OnscreenImage(image = 'Assets/Images/Menus/Popups/popup.png')
        popup.setTransparency(TransparencyAttrib.MAlpha)
        popup.reparentTo(self.node)
        
        titleText = OnscreenText(text = title, pos = (-0.29, 0.51), scale = 0.07, fg = (1, 1, 1, 1))
        titleText.reparentTo(self.node)
        
        self.LoadButton('Button_Okay', 'okay', 'okay_over', -0.27, -0.13, self.OnButtonClicked, ['okay'])
        self.LoadButton('Button_Cancel', 'cancel', 'cancel_over', 0.27, -0.13, self.OnButtonClicked, ['cancel'])
        
        messageText = OnscreenText(text = message, pos = (0, 0.2), scale = 0.07, fg = (1, 1, 1, 1))
        messageText.reparentTo(self.node)
        
    def LoadButton(self, egg, up, over, x, y, cmd, args):
        maps = loader.loadModel("Assets/Images/Menus/Popups/%s" % (egg))
        b = DirectButton(geom = (maps.find('**/%s' % (up)),
                         maps.find('**/%s' % (over)),
                         maps.find('**/%s' % (over)),
                         maps.find('**/%s' % (up))),
                         command = cmd,
                         extraArgs = args,
                         pressEffect = 0,
                         relief = None,
                         rolloverSound = None, 
                         clickSound = None,
                         pos = (x, 1, y),
                         scale = (0.5, 1, 60.0/400.0))
        b.reparentTo(self.frame)
        
    def Destroy(self):
        self.frame.destroy()
        self.node.removeNode()
        
    def OnButtonClicked(self, buttonText):
        if(buttonText == 'okay'):
            self.okayFunction(self)
        elif(buttonText == 'cancel'):
            self.cancelFunction(self)
            
            
    def destroy(self):
        ToontownIntervals.cleanup('bosscodedoor')
        self._model.removeNode()
        del self._model
        self._titleLabel.removeNode()
        del self._titleLabel
        for marker in self._markers:
            marker.destroy()

        del self._markers
        DirectFrame.destroy(self)
Exemplo n.º 30
0
    def destroy(self):
        ToontownIntervals.cleanup('bosscodedoor')
        self._model.removeNode()
        del self._model
        self._titleLabel.removeNode()
        del self._titleLabel
        for marker in self._markers:
            marker.destroy()

        del self._markers
        DirectFrame.destroy(self)
    def destroy(self):
        self.ignoreAll()
        self.dayClickCallback = None
        self.monthLeftArrow.destroy()
        self.monthRightArrow.destroy()
        for day in self.guiDays:
            if day is not None:
                day.destroy()
            day = None

        self.filterList.destroy()
        DirectFrame.destroy(self)
Exemplo n.º 32
0
class GameGuide():
    """
        A display container for the instructions to the game.
    """
    def __init__(self):
        self._root = None
        self._font = loader.loadFont(PIERCEROMAN_FONT)
        self._draw()

    def _draw(self):
        # Draw fade frame (translucent screen covering):
        winWidth = base.getAspectRatio()
        winHeight = 2
        fColor = (0, 0, 0, 0.5)
        self._root = DirectFrame(pos=(0, 0, 0),
                                 frameSize=(-winWidth, winWidth, -winHeight,
                                            winHeight),
                                 frameColor=fColor)

        contentHeight = GAMEGUIDE_CONTENT_HEIGHT_PERCENTAGE * winHeight
        contentWidth = GAMEGUIDE_CONTENT_WIDTH_PERCENTAGE * winWidth
        contentText = GAMEGUIDE_TEXT
        guideText = DirectLabel(parent=self._root,
                                pos=(0, 0, 0),
                                frameSize=(-contentWidth, contentWidth,
                                           -contentHeight / 2,
                                           contentHeight / 2),
                                text=contentText,
                                text_scale=GAMEGUIDE_FONT_SIZE,
                                text_font=self._font,
                                text_align=TextNode.ACenter,
                                text_pos=GAMEGUIDE_TEXT_OFFSET,
                                frameTexture=UI_WINDOW,
                                frameColor=(1, 1, 1, 1))
        guideText.setTransparency(TransparencyAttrib.MAlpha)

        cBOffset = GAMEGUIDE_CLOSE_BUTTON_OFFSET
        cbWidth = GAMEGUIDE_CLOSE_BUTTON_SIZE_X
        cbHeight = GAMEGUIDE_CLOSE_BUTTON_SIZE_Y
        closeButton = DirectButton(parent=self._root,
                                   pos=(cBOffset[0], 0, cBOffset[1]),
                                   frameSize=(-cbWidth, cbWidth, -cbHeight,
                                              cbHeight),
                                   text="Close Guide",
                                   text_scale=GAMEGUIDE_FONT_SIZE,
                                   text_font=self._font,
                                   text_pos=GAMEGUIDE_CLOSE_BUTTON_TEXT_OFFSET,
                                   command=self.close,
                                   borderWidth=GAMEGUIDE_BUTTON_BORDER_WIDTH)

    def close(self):
        self._root.destroy()
        del self
Exemplo n.º 33
0
    def destroy(self):
        self.ignoreAll()
        self.dayClickCallback = None
        self.monthLeftArrow.destroy()
        self.monthRightArrow.destroy()
        for day in self.guiDays:
            if day is not None:
                day.destroy()
            day = None

        self.filterList.destroy()
        DirectFrame.destroy(self)
Exemplo n.º 34
0
 def destroy(self):
     """Clean ourself up."""
     self.ignoreAll()
     # these 2 lines get rid of party planner leaks
     self.dayClickCallback = None
     self.monthLeftArrow.destroy()
     self.monthRightArrow.destroy()
     for day in self.guiDays:
         if day is not None:
             day.destroy()
         day = None
     self.filterList.destroy()
     DirectFrame.destroy(self)
Exemplo n.º 35
0
 def delete(self):
     DirectFrame.destroy(self)
     self.disable()
     self.gui.removeNode()
     self.gui = None
     self.cards = None
     self.title = None
     self.container = None
     self.cardBtns = None
     self.numCards = None
     self.unoGame = None
     self.deck = None
     return
Exemplo n.º 36
0
 def destroy(self):
     if self.titlePanel:
         self.titlePanel.destroy()
     if self.avatarText:
         self.avatarText.destroy()
     if self.avatarNamePanel:
         self.avatarNamePanel.destroy()
     if self.panelContentsTitle:
         self.panelContentsTitle.destroy()
     if self.favoriteGag:
         self.favoriteGag.destroy()
     if self.favoriteGagGlow:
         self.favoriteGagGlow.destroy()
     if self.favoriteGagName:
         self.favoriteGagName.destroy()
     if self.playerInfo:
         self.playerInfo.destroy()
     if self.trackLabels:
         for label in self.trackLabels:
             label.destroy()
     if self.trackIncLabels:
         for label in self.trackIncLabels:
             label.destroy()
     if self.trackBars:
         for bar in self.trackBars:
             bar.destroy()
     if self.congratsLeft:
         self.congratsLeft.destroy()
     if self.congratsRight:
         self.congratsRight.destroy()
     if self.gagExpFrame:
         self.gagExpFrame.destroy()
     if self.panelData:
         self.panelData = None
     del self.titlePanel
     del self.avatarText
     del self.avatarNamePanel
     del self.panelContentsTitle
     del self.favoriteGag
     del self.favoriteGagGlow
     del self.favoriteGagName
     del self.playerInfo
     del self.trackLabels
     del self.trackIncLabels
     del self.trackBars
     del self.gagExpFrame
     del self.congratsLeft
     del self.congratsRight
     del self.panelData
     DirectFrame.destroy(self)
 def destroy(self):
     self.title.destroy()
     self.amt_label.destroy()
     self.info.destroy()
     self.bg.destroy()
     self.title = None
     self.amt_label = None
     self.info = None
     self.bg = None
     self.pointsSfx.stop()
     self.pointsSfx = None
     self.points = None
     DirectFrame.destroy(self)
     return
Exemplo n.º 38
0
 def destroy(self):
     if self.av:
         self.ignore(self.av.uniqueName('toonExpChange'))
     del self.av
     del self.exp
     del self.maxExp
     if self.bgBar:
         self.bgBar.destroy()
         del self.bgBar
     if self.expBar:
         self.expBar.destroy()
     if self.levelLabel:
         self.levelLabel.destroy()
     DirectFrame.destroy(self)
 def destroy(self):
     DirectFrame.destroy(self)
     self.countDownLabel.destroy()
     del self.countDownLabel
     self.winLabel.destroy()
     del self.winLabel
     self.introSequence.clearToInitial()
     del self.introSequence
     self.outroSequence.clearToInitial()
     del self.outroSequence
     self.cleanupSequence.clearToInitial()
     del self.cleanupSequence
     del self.repairGame
     self.cleanup()
 def destroy(self):
     self.bladeNumberLabel.removeNode()
     self.bladeNumberLabel = None
     self._healthIval.clearToInitial()
     del self._healthIval
     self.healthBar = None
     self.fuelLowIndicator = None
     self.fuelVeryLowIndicator = None
     self.propellerMain = None
     self.propellerHead = None
     del self.blades[:]
     del self.activeBlades[:]
     self.gui.detachNode()
     self.gui = None
     DirectFrame.destroy(self)
 def destroy(self):
     self.bladeNumberLabel.removeNode()
     self.bladeNumberLabel = None
     self._healthIval.clearToInitial()
     del self._healthIval
     self.healthBar = None
     self.fuelLowIndicator = None
     self.fuelVeryLowIndicator = None
     self.propellerMain = None
     self.propellerHead = None
     del self.blades[:]
     del self.activeBlades[:]
     self.gui.detachNode()
     self.gui = None
     DirectFrame.destroy(self)
Exemplo n.º 42
0
class ColourView():
    __frame: DirectFrame
    __view: DirectFrame
    __colour: Union[Colour, None]

    def __init__(self,
                 parent: DirectFrame,
                 colour: Union[Colour, None] = None):
        bg_filename = os.path.join(GUI_DATA_PATH, "colour_bg.png")

        self.__frame = DirectFrame(parent=parent,
                                   relief=DGG.SUNKEN,
                                   image=bg_filename,
                                   image_scale=(0.465, 1.0, 0.39),
                                   borderWidth=(0.05, 0.05),
                                   frameSize=(-0.52, 0.52, -0.44, 0.44),
                                   scale=(0.5, 1.0, 0.5))
        self.__view = DirectFrame(
            parent=self.__frame,
            frameColor=colour if colour != None else TRANSPARENT,
            frameSize=(-0.47, 0.47, -0.39, 0.39))
        self.__colour = colour

    @property
    def colour(self) -> str:
        return 'colour'

    @colour.getter
    def colour(self) -> Union[Colour, None]:
        return self.__colour

    @colour.setter
    def colour(self, value) -> None:
        self.__colour = value
        self.__view[
            'frameColor'] = value if value != None else WINDOW_BG_COLOUR

    @property
    def frame(self) -> DirectFrame:
        return self.__frame

    @property
    def view(self) -> DirectFrame:
        return self.__view

    def destroy(self) -> None:
        self.__view.destroy()
        self.__frame.destroy()
    def destroy(self):
        self.title.destroy()
        self.amt_label.destroy()
        self.info.destroy()
        self.bg.destroy()
        self.title = None
        self.amt_label = None
        self.info = None
        self.bg = None

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

        self.points = None
        DirectFrame.destroy(self)
Exemplo n.º 44
0
 def destroy(self):
     # Let's stop the sequence.
     if self.pointsSeq:
         self.pointsSeq.finish()
     self.pointsSeq = None
     
     # Let's stop and destroy all the sounds.
     if self.zeroPointsSfx:
         self.zeroPointsSfx.stop()
         self.poorScoreSfx.stop()
         self.goodScoreSfx.stop()
         self.stomperSfx.stop()
         self.fireworkSfx.stop()
         self.perfectSfx.stop()
         self.tick_fastSfx.stop()
         self.tick_slowSfx.stop()
         self.easterEggSfx.stop()
     self.zeroPointsSfx = None
     self.poorScoreSfx = None
     self.goodScoreSfx = None
     self.stomperSfx = None
     self.fireworkSfx = None
     self.perfectSfx = None
     self.tick_fastSfx = None
     self.tick_slowSfx = None
     self.easterEggSfx = None
     
     # Let's destroy all the variables.
     self.points = None
     self.easterEgg = None
     self.seqLevel = None
     self.fakeNumber = None
     self.kingId = None
     self.mg = None
     
     # Let's destroy all the frames.
     if self.bg:
         self.bg.destroy()
         self.title.destroy()
         self.amt_label.destroy()
         self.motivator.destroy()
     self.bg = None
     self.title = None
     self.amt_label = None
     self.motivator = None
     
     DirectFrame.destroy(self)
Exemplo n.º 45
0
 def destroy(self):
     self.ignore('gotFriendsList')
     self.fsm.requestFinalState()
     del self.fsm
     self.headingText.destroy()
     del self.headingText
     self.frameForNames.destroy()
     del self.frameForNames
     self.fwdBtn.destroy()
     del self.fwdBtn
     self.backBtn.destroy()
     del self.backBtn
     self.closeBtn.destroy()
     del self.closeBtn
     del self.friends
     del self.onlineFriends
     DirectFrame.destroy(self)
    def destroy(self):
        self.activityIconsModel.removeNode()
        del self.activityIconsModel
        self.partyList.removeAndDestroyAllItems()
        try:
            for item in self.partyList['items']:
                item.actLabel = None
                item.numLabel = None
                item.minLabel = None

        except:
            pass

        self.activityList.removeAndDestroyAllItems()
        del self.partyList
        del self.activityList
        self.ignoreAll()
        DirectFrame.destroy(self)
Exemplo n.º 47
0
    def destroy(self):
        if self.dayClickCallback is not None:
            self.numberWidget.destroy()
        self.dayClickCallback = None
        try:
            for item in self.scrollList["items"]:
                if hasattr(item, "description") and item.description and hasattr(item.description, "destroy"):
                    item.unbind(DGG.ENTER)
                    item.unbind(DGG.EXIT)
                    item.description.destroy()

        except e:
            pass

        self.scrollList.removeAndDestroyAllItems()
        self.scrollList.destroy()
        self.dayButton.destroy()
        DirectFrame.destroy(self)
 def destroy(self):
     if self.currentShake is not None:
         self.currentShake.clearToInitial()
         self.currentShake = None
     
     del self.currentShake
     if self.fallingAnim is not None:
         self.fallingAnim.clearToInitial()
         self.fallingAnim = None
     
     del self.fallingAnim
     self.cleanup()
     if self.config.showBarnacleHP:
         self.hpLabel.destroy()
         del self.hpLabel
     
     DirectFrame.destroy(self)
     self.barnacleGeom.removeNode()
     del self.barnacleGeom
Exemplo n.º 49
0
 def destroy(self):
     del self.style
     del self.av
     del self.hp
     del self.maxHp
     del self.frown
     del self.smile
     del self.openSmile
     del self.tooth1
     del self.tooth2
     del self.tooth3
     del self.tooth4
     del self.tooth5
     del self.tooth6
     del self.teeth
     del self.fractions
     del self.maxLabel
     del self.hpLabel
     DirectFrame.destroy(self)
 def destroy(self):
     self._unloadSfx()
     self.panel.detachNode()
     self.tabHandle.destroy()
     self.msgMgr.destroy()
     self.cannon.setAmmoSkillId(self.oldAmmoSkillId)
     PiratesGlobals.CANNON_DEFENSE_SKILLS = []
     self.ignore('onSellClick')
     self.ignore('incBankNotes')
     self.ignore('defenseCannonLevelUp')
     self.ignore('unlockAmmo')
     self.ignore('cdUnlockAll')
     self.ignore('endOfWave')
     self.ignore('flashHandleStart')
     self.ignore('flashHandleStop')
     for i in range(4):
         self.ignore('%d' % (i + 1))
     
     DirectFrame.destroy(self)
 def destroy(self):
     taskMgr.remove(self.uniqueName('RepairGridPiece.updateTask'))
     taskMgr.remove(DGG.B1PRESS)
     taskMgr.remove(DGG.B1RELEASE)
     taskMgr.remove(DGG.B2PRESS)
     taskMgr.remove(DGG.B2RELEASE)
     taskMgr.remove(DGG.B3PRESS)
     taskMgr.remove(DGG.B3RELEASE)
     self.idleGeom.detachNode()
     self.idleGeom = None
     self.highlightedGeom.detachNode()
     self.highlightedGeom = None
     self.ignore(self.guiItem.getEnterEvent())
     self.ignore(self.guiItem.getExitEvent())
     self.moveInterval.clearToInitial()
     del self.moveInterval
     DirectFrame.destroy(self)
     self.clearPiece()
     self.allWoodSquaresGeom.removeNode()
     del self.allWoodSquaresGeom
    def destroy(self):
        if self.dayClickCallback is not None:
            self.numberWidget.destroy()
        self.dayClickCallback = None
        self.notify.debug('desroying %s' % self.myDate)
        try:
            for item in self.scrollList['items']:
                if hasattr(item, 'description') and item.description and hasattr(item.description, 'destroy'):
                    self.notify.debug('desroying description of item %s' % item)
                    item.unbind(DGG.ENTER)
                    item.unbind(DGG.EXIT)
                    item.description.destroy()

        except e:
            self.notify.debug('pass %s' % self.myDate)

        self.scrollList.removeAndDestroyAllItems()
        self.scrollList.destroy()
        self.dayButton.destroy()
        DirectFrame.destroy(self)
Exemplo n.º 53
0
 def destroy(self):
     del self._mazeCollTable
     del self._maskResolution
     del self._radius
     del self._revealedCells
     del self._revealFunctions
     del self._revealFunction
     self.map.removeNode()
     del self.map
     self.mask.removeNode()
     del self.mask
     self.maskedLayer.removeNode()
     del self.maskedLayer
     self.visibleLayer.removeNode()
     del self.visibleLayer
     self._maskImage.clear()
     del self._maskImage
     self.maskTexture.clear()
     del self.maskTexture
     self._laffMeterModel.removeNode()
     del self._laffMeterModel
     DirectFrame.destroy(self)
Exemplo n.º 54
0
class DistributedMaze(DistributedNodePathEntity):
    notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMaze')
    ScheduleTaskName = 'mazeScheduler'
    RemoveBlocksDict = {2: ('HedgeBlock_0_1',),
     4: (('HedgeBlock_0_1', 'HedgeBlock_1_3', 'HedgeBlock_2_3'), ('HedgeBlock_0_2', 'HedgeBlock_2_3', 'HedgeBlock_1_3'), ('HedgeBlock_0_1', 'HedgeBlock_0_2', 'HedgeBlock_1_3', 'HedgeBlock_2_3'))}

    def __init__(self, cr):
        DistributedNodePathEntity.__init__(self, cr)
        self.numSections = 0
        self.GameDuration = 35.0 + self.numSections * 15.0
        self.timer = None
        self.frame2D = None
        self.gameLabel = None
        self.gameStarted = 0
        self.finished = 0
        self.timedOut = 0
        self.toonFinishedText = TTLocalizer.toonFinishedHedgeMaze
        self.toonEnteredText = TTLocalizer.enterHedgeMaze
        return

    def announceGenerate(self):
        DistributedNodePathEntity.announceGenerate(self)
        self.addHints(self.roomHold)
        self.loadGui()

    def disable(self):
        DistributedNodePathEntity.disable(self)
        self.unloadGui()
        self.cleanupTimer()
        self.ignoreAll()

    def delete(self):
        self.cleanupTimer()
        DistributedNodePathEntity.delete(self)

    def setRoomDoId(self, roomDoId):
        self.roomDoId = roomDoId
        room = self.cr.doId2do.get(roomDoId)
        if room:
            self.gotRoom([room])
        else:
            self.roomRequest = self.cr.relatedObjectMgr.requestObjects([roomDoId], allCallback=self.gotRoom, timeout=5)

    def gotRoom(self, rooms):
        self.roomRequest = None
        room = rooms[0]
        self.roomHold = room
        rotations = [0,
         0,
         90,
         90,
         180,
         180,
         270,
         270]
        self.getRng().shuffle(rotations)
        self.numSections = 0
        for i in xrange(0, 4):
            maze = room.getGeom().find('**/Maze_Inside_%d' % i)
            if not maze.isEmpty():
                self.numSections += 1
                if rotations:
                    maze.setH(rotations.pop())

        self.GameDuration = 35.0 + self.numSections * 15.0
        self.removeHedgeBlocks(room)
        return

    def addHints(self, room):
        self.focusPoint = self.attachNewNode('GolfGreenGameFrame')
        hintList = room.getGeom().findAllMatches('**/dead*')
        for hint in hintList:
            self.actSphere = CollisionSphere(0, 0, 0, 7.0)
            self.actSphereNode = CollisionNode('mazegame_hint-%s-%s' % (self.level.getLevelId(), self.entId))
            self.actSphereNode.addSolid(self.actSphere)
            self.actSphereNodePath = hint.attachNewNode(self.actSphereNode)
            self.actSphereNode.setCollideMask(WallBitmask)
            self.actSphere.setTangible(0)
            self.enterEvent = 'enter' + self.actSphereNode.getName()
            self.accept(self.enterEvent, self.__handleToonEnterHint)
            self.exitEvent = 'exit' + self.actSphereNode.getName()
            self.accept(self.exitEvent, self.__handleToonExitHint)

        enterance = room.getGeom().find('**/ENTRANCE')
        self.enterSphere = CollisionSphere(0, 0, 0, 8.0)
        self.enterSphereNode = CollisionNode('mazegame_enter-%s-%s' % (self.level.getLevelId(), self.entId))
        self.enterSphereNode.addSolid(self.enterSphere)
        self.enterSphereNodePath = enterance.attachNewNode(self.enterSphereNode)
        self.enterSphereNode.setCollideMask(WallBitmask)
        self.enterSphere.setTangible(0)
        self.enteranceEvent = 'enter' + self.enterSphereNode.getName()
        self.accept(self.enteranceEvent, self.__handleToonEnterance)
        finish = room.getGeom().find('**/finish')
        self.finishSphere = CollisionSphere(0, 0, 0, 15.0)
        self.finishSphereNode = CollisionNode('mazegame_finish-%s-%s' % (self.level.getLevelId(), self.entId))
        self.finishSphereNode.addSolid(self.finishSphere)
        self.finishSphereNodePath = finish.attachNewNode(self.finishSphereNode)
        self.finishSphereNode.setCollideMask(WallBitmask)
        self.finishSphere.setTangible(0)
        self.finishEvent = 'enter' + self.finishSphereNode.getName()
        self.accept(self.finishEvent, self.__handleToonFinish)

    def __handleToonEnterance(self, collEntry):
        if not self.gameStarted:
            self.notify.debug('sending clientTriggered for %d' % self.doId)
            self.sendUpdate('setClientTriggered', [])
            self.level.countryClub.showInfoText(self.toonEnteredText)

    def __handleToonFinish(self, collEntry):
        self.sendUpdate('setFinishedMaze', [])
        self.finished = 1

    def __handleToonEnterHint(self, collEntry):
        camHeight = base.localAvatar.getClampedAvatarHeight()
        heightScaleFactor = camHeight * 0.3333333333
        defLookAt = Point3(0.0, 1.5, camHeight)
        cameraPoint = Point3(0.0, -22.0 * heightScaleFactor, camHeight + 54.0)
        base.localAvatar.stopUpdateSmartCamera()
        base.localAvatar.startUpdateSmartCamera(push=0)
        base.localAvatar.setIdealCameraPos(cameraPoint)

    def __handleToonExitHint(self, collEntry):
        base.localAvatar.stopUpdateSmartCamera()
        base.localAvatar.startUpdateSmartCamera()
        base.localAvatar.setCameraPositionByIndex(base.localAvatar.cameraIndex)
        self.cameraHold = None
        return

    def getRng(self):
        return random.Random(self.entId * self.doId)

    def removeHedgeBlocks(self, room):
        if self.numSections in self.RemoveBlocksDict:
            blocksToRemove = self.getRng().choice(self.RemoveBlocksDict[self.numSections])
            for blockName in blocksToRemove:
                block = room.getGeom().find('**/%s' % blockName)
                if not block.isEmpty():
                    block.removeNode()

    def setGameStart(self, timestamp):
        self.notify.debug('%d setGameStart: Starting game' % self.doId)
        self.gameStartTime = globalClockDelta.networkToLocalTime(timestamp)
        self.gameStarted = True
        curGameTime = self.getCurrentGameTime()
        timeLeft = self.GameDuration - curGameTime
        self.cleanupTimer()
        self.timer = ToontownTimer.ToontownTimer()
        self.timer.posBelowTopRightCorner()
        self.timer.setTime(timeLeft)
        self.timer.countdown(timeLeft, self.timerExpired)
        self.startScheduleTask()
        self.frame2D.show()

    def setGameOver(self):
        self.timedOut = 1
        if not self.finished:
            self.sendUpdate('damageMe', [])
            roomNum = self.level.roomNum
            club = self.level.countryClub
            self.gameOverTrack = Sequence()
            self.gameOverTrack.append(localAvatar.getTeleportOutTrack())
            self.gameOverTrack.append(Func(localAvatar.setPos, self.finishSphereNodePath.getPos(render)))
            self.gameOverTrack.append(Func(localAvatar.play, 'jump'))
            self.gameOverTrack.append(Func(self.level.countryClub.camEnterRoom, roomNum))
            self.gameOverTrack.start()
        self.timerExpired()

    def local2GameTime(self, timestamp):
        return timestamp - self.gameStartTime

    def game2LocalTime(self, timestamp):
        return timestamp + self.gameStartTime

    def getCurrentGameTime(self):
        return self.local2GameTime(globalClock.getFrameTime())

    def startScheduleTask(self):
        taskMgr.add(self.scheduleTask, self.ScheduleTaskName)

    def stopScheduleTask(self):
        taskMgr.remove(self.ScheduleTaskName)

    def scheduleTask(self, task):
        curTime = self.getCurrentGameTime()

    def cleanupTimer(self):
        if self.timer:
            self.timer.stop()
            self.timer.destroy()
            self.timer = None
        return

    def timerExpired(self):
        self.cleanupTimer()
        self.unloadGui()

    def loadGui(self):
        self.frame2D = DirectFrame(scale=1.0, pos=(0.0, 0, 0.9), relief=DGG.FLAT, parent=aspect2d, frameSize=(-0.3,
         0.3,
         -0.05,
         0.05), frameColor=(0.737, 0.573, 0.345, 0.3))
        self.frame2D.hide()
        self.gameLabel = DirectLabel(parent=self.frame2D, relief=None, pos=(0, 0, 0), scale=1.0, text=TTLocalizer.mazeLabel, text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text_scale=0.075, text_pos=(0, -0.02))
        return

    def unloadGui(self):
        if self.frame2D:
            self.frame2D.destroy()
        self.frame2D = None
        if self.gameLabel:
            self.gameLabel.destroy()
        self.gameLabel = None
        return

    def toonFinished(self, avId, place, lastToon):
        toon = base.cr.doId2do.get(avId)
        if toon and not self.timedOut:
            self.level.countryClub.showInfoText(self.toonFinishedText % (toon.getName(), TTLocalizer.hedgeMazePlaces[place]))
        if lastToon:
            self.setGameOver()
Exemplo n.º 55
0
class PartyPlanner(DirectFrame, FSM):
    notify = DirectNotifyGlobal.directNotify.newCategory('PartyPlanner')

    def __init__(self, doneEvent = None):
        FSM.__init__(self, 'PartyPlannerFSM')
        DirectFrame.__init__(self)
        self.doneEvent = doneEvent
        self.stateArray = ['Off',
         'Welcome',
         'PartyEditor',
         'Guests',
         'Date',
         'Time',
         'Invitation',
         'Farewell']
        self.partyTime = base.cr.toontownTimeManager.getCurServerDateTime()
        self.partyNowTime = base.cr.toontownTimeManager.getCurServerDateTime()
        minutesToNextFifteen = 15 - self.partyTime.minute % 15
        self.cleanPartyTime = self.partyTime + timedelta(minutes=minutesToNextFifteen, seconds=-self.partyTime.second)
        self.partyTime = self.cleanPartyTime
        self.guests = []
        self.isPrivate = False
        self.selectedCalendarGuiDay = None
        self.gui = loader.loadModel('phase_4/models/parties/partyPlannerGUI')
        self.partyDuration = timedelta(hours=PartyGlobals.DefaultPartyDuration)
        self.timeTypeToMaxValue = {'hour': 23,
         'minute': 59}
        self.timeTypeToChangeAmount = {'hour': (1, -1),
         'minute': (15, -15),
         'ampm': (1, -1)}
        self.partyInfo = None
        self.asapMinuteRounding = base.config.GetInt('party-asap-minute-rounding', PartyGlobals.PartyPlannerAsapMinuteRounding)
        self.load()
        self.request('Welcome')
        return

    def enterWelcome(self, *args):
        self.prevButton['state'] = DirectGuiGlobals.DISABLED
        self.prevButton.hide()
        self.nextButton['state'] = DirectGuiGlobals.NORMAL
        self.welcomePage.show()
        self.partyPlannerHead.reparentTo(self.welcomePage)
        self.partyPlannerHead.startBlink()
        self.partyPlannerHead.startLookAround()
        self.nametagNP.reparentTo(self.welcomePage)
        self.chatNP.reparentTo(self.welcomePage)

    def exitWelcome(self):
        self.welcomePage.hide()
        self.prevButton.show()
        self.partyPlannerHead.stopBlink()
        self.partyPlannerHead.stopLookAround()

    def enterPartyEditor(self, *args):
        self.prevButton['state'] = DirectGuiGlobals.NORMAL
        self.nextButton['state'] = DirectGuiGlobals.DISABLED
        self.nextButton.hide()
        self.partyEditorPage.show()
        self.okWithGroundsGui.doneStatus = ''
        self.partyEditor.request('Idle')

    def exitPartyEditor(self):
        self.partyEditor.request('Hidden')
        self.partyEditorPage.hide()

    def enterGuests(self, *args):
        self.prevButton['state'] = DirectGuiGlobals.NORMAL
        self.nextButton['state'] = DirectGuiGlobals.NORMAL
        self.nextButton.show()
        self.guestPage.show()

    def exitGuests(self):
        self.guests = []
        for friendCheckBox in self.friendList['items']:
            if friendCheckBox['indicatorValue']:
                self.guests.append(friendCheckBox.getPythonTag('id'))

        self.guestPage.hide()

    def enterDate(self, *args):
        self.prevButton.show()
        self.prevButton['state'] = DirectGuiGlobals.NORMAL
        if self.selectedCalendarGuiDay is None:
            self.nextButton['state'] = DirectGuiGlobals.DISABLED
            self.nextButton.hide()
            self.makePartyNowButton.show()
        self.datePage.show()
        return

    def exitDate(self):
        self.datePage.hide()
        self.nextButton.show()
        if self.selectedCalendarGuiDay is not None:
            self.partyTime = self.cleanPartyTime
            self.alterPartyTime(year=self.selectedCalendarGuiDay.myDate.year, month=self.selectedCalendarGuiDay.myDate.month, day=self.selectedCalendarGuiDay.myDate.day)
        else:
            self.partyNowTime = self.calcAsapTime()
            self.partyTime = self.partyNowTime
        return

    def calcAsapTime(self):
        curServerTime = base.cr.toontownTimeManager.getCurServerDateTime()
        baseTime = curServerTime
        baseTime = baseTime.replace(baseTime.year, baseTime.month, baseTime.day, baseTime.hour, baseTime.minute, second=0, microsecond=0)
        minute = curServerTime.minute
        remainder = minute % self.asapMinuteRounding
        if remainder:
            baseTime += timedelta(minutes=self.asapMinuteRounding - remainder)
        else:
            baseTime += timedelta(minutes=self.asapMinuteRounding)
        return baseTime

    def enterTime(self, *args):
        self.prevButton.show()
        self.prevButton['state'] = DirectGuiGlobals.NORMAL
        self.nextButton.show()
        self.timePage.show()
        self.timePageRecapToontownTimeLabel2['text'] = '%s' % PartyUtils.formatDateTime(self.partyTime)
        self.timePageRecapLocalTimeLabel['text'] = '%s%s' % (TTLocalizer.PartyPlannerTimeLocalTime, PartyUtils.formatDateTime(self.partyTime, inLocalTime=True))

    def exitTime(self):
        self.timePage.hide()
        self.nextButton.show()

    def enterInvitation(self, *args):
        self.prevButton['state'] = DirectGuiGlobals.NORMAL
        self.nextButton.hide()
        defaultInviteTheme = PartyGlobals.InviteTheme.GenericMale
        if hasattr(base.cr, 'newsManager') and base.cr.newsManager:
            if ToontownGlobals.VICTORY_PARTY_HOLIDAY in base.cr.newsManager.getHolidayIdList():
                defaultInviteTheme = PartyGlobals.InviteTheme.VictoryParty
            elif ToontownGlobals.KARTING_TICKETS_HOLIDAY in base.cr.newsManager.getHolidayIdList() or ToontownGlobals.CIRCUIT_RACING_EVENT in base.cr.newsManager.getHolidayIdList():
                defaultInviteTheme = PartyGlobals.InviteTheme.Racing
            elif ToontownGlobals.VALENTINES_DAY in base.cr.newsManager.getHolidayIdList():
                defaultInviteTheme = PartyGlobals.InviteTheme.Valentoons
        if self.partyInfo is not None:
            del self.partyInfo
        activityList = self.partyEditor.partyEditorGrid.getActivitiesOnGrid()
        decorationList = self.partyEditor.partyEditorGrid.getDecorationsOnGrid()
        endTime = self.partyTime + self.partyDuration
        self.partyInfo = PartyInfo(0, 0, self.partyTime.year, self.partyTime.month, self.partyTime.day, self.partyTime.hour, self.partyTime.minute, endTime.year, endTime.month, endTime.day, endTime.hour, endTime.minute, self.isPrivate, defaultInviteTheme, activityList, decorationList, 0)
        if self.noFriends or len(self.getInvitees()) == 0:
            self.inviteVisual.setNoFriends(True)
            self.invitationTitleLabel['text'] = TTLocalizer.PartyPlannerConfirmTitleNoFriends
            self.inviteButton['text'] = TTLocalizer.PartyPlannerInviteButtonNoFriends
            self.selectedInviteThemeLabel.stash()
            self.nextThemeButton.stash()
            self.prevThemeButton.stash()
            self.setInviteTheme(defaultInviteTheme)
        else:
            self.inviteVisual.setNoFriends(False)
            self.invitationTitleLabel['text'] = TTLocalizer.PartyPlannerConfirmTitle
            self.inviteButton['text'] = TTLocalizer.PartyPlannerInviteButton
            self.selectedInviteThemeLabel.unstash()
            self.nextThemeButton.unstash()
            self.prevThemeButton.unstash()
            self.setInviteTheme(defaultInviteTheme)
        self.inviteVisual.updateInvitation(base.localAvatar.getName(), self.partyInfo)
        self.invitationPage.show()
        return

    def __prevTheme(self):
        self.nextThemeButton.show()
        prevTheme = self.currentInvitationTheme - 1
        while prevTheme not in self.inviteThemes:
            prevTheme -= 1
            if prevTheme == self.currentInvitationTheme:
                self.notify.warning('No previous invite theme found.')
                break
            elif prevTheme < 0:
                prevTheme = len(self.inviteVisual.inviteThemesIdToInfo) - 1

        self.setInviteTheme(prevTheme)

    def __nextTheme(self):
        self.prevThemeButton.show()
        nextTheme = self.currentInvitationTheme + 1
        while nextTheme not in self.inviteThemes:
            nextTheme += 1
            if nextTheme == self.currentInvitationTheme:
                self.notify.warning('No next invite theme found.')
                break
            elif nextTheme >= len(self.inviteVisual.inviteThemesIdToInfo):
                nextTheme = 0

        self.setInviteTheme(nextTheme)

    def setInviteTheme(self, themeNumber):
        self.currentInvitationTheme = themeNumber
        self.selectedInviteThemeLabel['text'] = '%s %s (%d/%d)' % (self.inviteVisual.inviteThemesIdToInfo[self.currentInvitationTheme][1],
         TTLocalizer.PartyPlannerInvitationTheme,
         self.inviteThemes.index(self.currentInvitationTheme) + 1,
         len(self.inviteThemes))
        self.partyInfo.inviteTheme = self.currentInvitationTheme
        self.inviteVisual.updateInvitation(base.localAvatar.getName(), self.partyInfo)

    def exitInvitation(self):
        self.invitationPage.hide()
        self.nextButton.show()

    def enterFarewell(self, goingBackAllowed):
        self.farewellPage.show()
        if goingBackAllowed:
            self.prevButton.show()
        else:
            self.prevButton.hide()
        self.nextButton.hide()
        self.partyPlannerHead.reparentTo(self.farewellPage)
        self.partyPlannerHead.startBlink()
        self.partyPlannerHead.startLookAround()
        self.nametagNP.reparentTo(self.farewellPage)
        self.chatNP.reparentTo(self.farewellPage)

    def exitFarewell(self):
        self.farewellPage.hide()
        self.nextButton.show()
        self.prevButton.show()
        self.partyPlannerHead.stopBlink()
        self.partyPlannerHead.stopLookAround()

    def load(self):
        self.frame = DirectFrame(parent=aspect2d, geom=self.gui.find('**/background'), relief=None, scale=0.85, pos=(0.05, 0.0, 0.1))
        self.titleScale = TTLocalizer.PPtitleScale
        self._createNavButtons()
        self.welcomePage = self._createWelcomePage()
        self.welcomePage.hide()
        self.datePage = self._createDatePage()
        self.datePage.hide()
        self.timePage = self._createTimePage()
        self.timePage.hide()
        self.guestPage = self._createGuestPage()
        self.guestPage.hide()
        self.partyEditorPage = self._createPartyEditorPage()
        self.partyEditorPage.hide()
        self.invitationPage = self._createInvitationPage()
        self.invitationPage.hide()
        self.farewellPage = self._createFarewellPage()
        self.farewellPage.hide()
        return

    def _createNavButtons(self):
        self.quitButton = DirectButton(parent=self.frame, relief=None, geom=(self.gui.find('**/cancelButton_up'), self.gui.find('**/cancelButton_down'), self.gui.find('**/cancelButton_rollover')), command=self.__acceptExit)
        self.nextButton = DirectButton(parent=self.frame, relief=None, geom=(self.gui.find('**/bottomNext_button/nextButton_up'), self.gui.find('**/bottomNext_button/nextButton_down'), self.gui.find('**/bottomNext_button/nextButton_rollover')), command=self.__nextItem, state=DirectGuiGlobals.DISABLED)
        self.prevButton = DirectButton(parent=self.frame, relief=None, geom=(self.gui.find('**/bottomPrevious_button/previousButton_up'), self.gui.find('**/bottomPrevious_button/previousButton_down'), self.gui.find('**/bottomPrevious_button/previousButton_rollover')), command=self.__prevItem, state=DirectGuiGlobals.DISABLED)
        self.currentItem = None
        return

    def __createNametag(self, parent):
        if self.nametagGroup == None:
            self.nametagGroup = NametagGroup()
            self.nametagGroup.setFont(OTPGlobals.getInterfaceFont())
            self.nametagGroup.setActive(0)
            self.nametagGroup.setAvatar(self.partyPlannerHead)
            self.nametagGroup.manage(base.marginManager)
            self.nametagGroup.setColorCode(self.nametagGroup.CCNonPlayer)
            self.nametagGroup.getNametag2d().setContents(0)
            self.nametagNode = NametagFloat2d()
            self.nametagNode.setContents(Nametag.CName)
            self.nametagGroup.addNametag(self.nametagNode)
            self.nametagGroup.setName(base.cr.partyManager.getPartyPlannerName())
            self.nametagNP = parent.attachNewNode(self.nametagNode.upcastToPandaNode())
            nametagPos = self.gui.find('**/step_01_partymanPeteNametag_locator').getPos()
            self.nametagNP.setPosHprScale(nametagPos[0], 0, nametagPos[2], 0, 0, 0, 0.1, 1, 0.1)
            self.chatNode = NametagFloat2d()
            self.chatNode.setContents(Nametag.CSpeech | Nametag.CThought)
            self.nametagGroup.addNametag(self.chatNode)
            self.nametagGroup.setChat(TTLocalizer.PartyPlannerInstructions, CFSpeech)
            self.chatNP = parent.attachNewNode(self.chatNode.upcastToPandaNode())
            chatPos = self.gui.find('**/step_01_partymanPeteText_locator').getPos()
            self.chatNP.setPosHprScale(chatPos[0], 0, chatPos[2], 0, 0, 0, 0.08, 1, 0.08)
        return

    def clearNametag(self):
        if self.nametagGroup != None:
            self.nametagGroup.unmanage(base.marginManager)
            self.nametagGroup.removeNametag(self.nametagNode)
            self.nametagGroup.removeNametag(self.chatNode)
            self.nametagNP.removeNode()
            self.chatNP.removeNode()
            del self.nametagNP
            del self.chatNP
            del self.nametagNode
            del self.chatNode
            self.nametagGroup.setAvatar(NodePath())
            self.nametagGroup = None
        return

    def _createWelcomePage(self):
        self.nametagGroup = None
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerWelcomePage')
        self.welcomeTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerWelcomeTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale)
        self.partyPlannerHead = ToonHead.ToonHead()
        partyPlannerStyle = base.cr.partyManager.getPartyPlannerStyle()
        self.partyPlannerHead.setupHead(partyPlannerStyle, forGui=True)
        self.partyPlannerHead.setPos(self.gui.find('**/step_01_partymanPete_locator').getPos())
        animal = partyPlannerStyle.getAnimal()
        if animal == 'cat' or animal == 'pig':
            headScale = 0.4
        elif animal == 'dog' or animal == 'bear':
            headScale = 0.45
        elif animal == 'rabbit':
            headScale = 0.35
        else:
            headScale = 0.3
        self.partyPlannerHead.setScale(headScale)
        self.partyPlannerHead.setH(180.0)
        self.partyPlannerHead.reparentTo(page)
        self.__createNametag(page)
        return page

    def _createDatePage(self):
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerDatePage')
        self.createDateTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerDateTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale)
        pos = self.gui.find('**/step_06_sendInvitation_locator').getPos()
        self.makePartyNowButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/send_up'), self.gui.find('**/send_down'), self.gui.find('**/send_rollover')), text=TTLocalizer.PartyPlannerPartyNow, text_pos=(pos[0], pos[2]), text_scale=0.05, command=self.__doMakePartyNow)
        curServerDate = base.cr.toontownTimeManager.getCurServerDateTime()
        self.calendarGuiMonth = CalendarGuiMonth(page, curServerDate, scale=0.95, pos=(-0.05, 0.0, -0.33), dayClickCallback=self._dayClickCallback, onlyFutureDaysClickable=True)
        return page

    def __doMakePartyNow(self):
        self.request('Invitation')

    def _dayClickCallback(self, calendarGuiDay):
        self.selectedCalendarGuiDay = calendarGuiDay
        self.nextButton['state'] = DirectGuiGlobals.NORMAL
        self.makePartyNowButton.hide()
        self.nextButton.show()

    def alterPartyTime(self, year = None, month = None, day = None, hour = None, minute = None):
        self.partyTime = datetime(year=self.positiveTime('year', year), month=self.positiveTime('month', month), day=self.positiveTime('day', day), hour=self.positiveTime('hour', hour), minute=self.positiveTime('minute', minute), tzinfo=self.partyTime.tzinfo)

    def positiveTime(self, type, amount):
        if amount is None:
            return getattr(self.partyTime, type)
        if type == 'hour' or type == 'minute':
            if amount < 0:
                return self.timeTypeToMaxValue[type] + 1 + self.timeTypeToChangeAmount[type][1]
            elif amount > self.timeTypeToMaxValue[type]:
                return 0
        return amount

    def _createTimePage(self):
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerTimePage')
        self.createTimeTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale)
        self.clockImage = DirectFrame(parent=page, relief=None, geom=self.gui.find('**/toontownTime_background'))
        self.timePageToontownLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeToontown, pos=self.gui.find('**/step_03_toontown_locator').getPos(), scale=0.15, text_fg=(1.0, 0.0, 0.0, 1.0), text_font=ToontownGlobals.getSignFont())
        self.timePageTimeLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeTime, pos=self.gui.find('**/step_03_time_locator').getPos(), scale=0.15, text_fg=(1.0, 0.0, 0.0, 1.0), text_font=ToontownGlobals.getSignFont())
        self.timePageRecapLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeRecap, pos=self.gui.find('**/step_03_partyDateAndTime_locator').getPos(), scale=0.09)
        self.timePageRecapToontownTimeLabel1 = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerTimeToontownTime, pos=self.gui.find('**/step_03_toontownTime_locator').getPos(), scale=0.06)
        self.timePageRecapToontownTimeLabel2 = DirectLabel(parent=page, relief=None, text='%s' % PartyUtils.formatDateTime(self.partyTime), pos=self.gui.find('**/step_03_toontownDateAndTime_loactor').getPos(), textMayChange=True, scale=0.06)
        self.timePageRecapLocalTimeLabel = DirectLabel(parent=page, relief=None, text='%s%s' % (TTLocalizer.PartyPlannerTimeLocalTime, PartyUtils.formatDateTime(self.partyTime, inLocalTime=True)), pos=self.gui.find('**/step_03_localDateAndTime_loactor').getPos(), textMayChange=True, scale=0.06, text_fg=(1.0, 0.0, 0.0, 1.0))
        self.timeInputHourLabel, self.timeInputHourUpButton, self.timeInputHourDownButton = self.getTimeWidgets(page, 'hour')
        self.timeInputMinuteLabel, self.timeInputMinuteUpButton, self.timeInputMinuteDownButton = self.getTimeWidgets(page, 'minute')
        self.timeInputAmPmLabel, self.timeInputAmPmUpButton, self.timeInputAmPmDownButton = self.getTimeWidgets(page, 'ampm')
        self.timePagecolonLabel = DirectLabel(parent=page, relief=None, text=':', pos=self.gui.find('**/step_03_colon_locator').getPos(), scale=0.15)
        return page

    def getTimeWidgets(self, page, type):
        if type == 'ampm':
            data = self.getCurrentAmPm()
        else:
            data = getattr(self.partyTime, type)
            if data == 0 and type == 'minute':
                data = '00'
            else:
                if type == 'hour':
                    data = data % 12
                    if data == 0:
                        data = 12
                data = '%d' % data
        label = DirectLabel(parent=page, relief=None, text='%s' % data, textMayChange=True, pos=self.gui.find('**/step_03_%s_locator' % type).getPos(), scale=0.12)

        def changeValue(self, amount):
            if type == 'ampm':
                self.alterPartyTime(hour=(self.partyTime.hour + 12) % 24)
                newAmount = self.getCurrentAmPm()
                label['text'] = newAmount
            else:
                if type == 'hour':
                    newAmount = getattr(self.partyTime, type) + amount
                    newAmount = newAmount % 12
                    if self.timeInputAmPmLabel['text'] == TTLocalizer.PartyTimeFormatMeridiemPM:
                        newAmount = newAmount % 12 + 12
                    self.alterPartyTime(hour=newAmount)
                elif type == 'minute':
                    newAmount = getattr(self.partyTime, type) + amount
                    self.alterPartyTime(minute=newAmount)
                else:
                    PartyPlanner.notify.error('Invalid type for changeValue in PartyPlanner: %s' % type)
                newAmount = getattr(self.partyTime, type)
                if newAmount < 10 and type == 'minute':
                    label['text'] = '0%d' % newAmount
                else:
                    if type == 'hour':
                        newAmount = newAmount % 12
                        if newAmount == 0:
                            newAmount = 12
                    label['text'] = '%d' % newAmount
            self.timePageRecapToontownTimeLabel2['text'] = '%s' % PartyUtils.formatDateTime(self.partyTime)
            self.timePageRecapLocalTimeLabel['text'] = '%s%s' % (TTLocalizer.PartyPlannerTimeLocalTime, PartyUtils.formatDateTime(self.partyTime, inLocalTime=True))

        upButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/%sButtonUp_up' % type), self.gui.find('**/%sButtonUp_down' % type), self.gui.find('**/%sButtonUp_rollover' % type)), command=changeValue, extraArgs=[self, self.timeTypeToChangeAmount[type][0]])
        downButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/%sButtonDown_up' % type), self.gui.find('**/%sButtonDown_down' % type), self.gui.find('**/%sButtonDown_rollover' % type)), command=changeValue, extraArgs=[self, self.timeTypeToChangeAmount[type][1]])
        return (label, upButton, downButton)

    def getCurrentAmPm(self):
        if self.partyTime.hour < 12:
            return TTLocalizer.PartyTimeFormatMeridiemAM
        else:
            return TTLocalizer.PartyTimeFormatMeridiemPM

    def _createGuestPage(self):
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerGuestPage')
        self.guestTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerGuestTitle, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale)
        self.guestBackgroundLabel = DirectLabel(parent=page, relief=None, image=self.gui.find('**/guestListBackground_flat'), scale=(1.2, 1.0, 1.0))
        self.friendList = ScrolledFriendList(page, self.gui, makeItemsCheckBoxes=True)
        if len(base.localAvatar.friendsList) == 0:
            self.noFriends = True
        else:
            self.noFriends = False
            for friendPair in base.localAvatar.friendsList:
                self.friendList.addFriend(determineFriendName(friendPair), friendPair[0])

            self.friendList.scrollTo(0)
        pos = self.gui.find('**/step_04_partyWillBe_locator').getPos()
        self.publicPrivateLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerPublicPrivateLabel, text_align=TextNode.ACenter, text_scale=0.065, pos=pos)
        self.publicDescriptionLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerPublicDescription, text_align=TextNode.ACenter, text_scale=TTLocalizer.PPpbulicDescriptionLabel, pos=(pos[0] - 0.52, pos[1], pos[2]))
        self.publicDescriptionLabel.stash()
        self.privateDescriptionLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerPrivateDescription, text_align=TextNode.ACenter, text_scale=TTLocalizer.PPprivateDescriptionLabel, pos=(pos[0] + 0.55, pos[1], pos[2]))
        self.privateDescriptionLabel.stash()
        pos = self.gui.find('**/step_04_public_locator').getPos()
        self.publicButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/publicButton_up'),
         self.gui.find('**/publicButton_down'),
         self.gui.find('**/publicButton_rollover'),
         self.gui.find('**/publicButton_inactive')), text=TTLocalizer.PartyPlannerPublic, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPpublicButton, command=self.__doTogglePublicPrivate)
        self.publicButton['state'] = DirectGuiGlobals.DISABLED
        self.publicButton.bind(DirectGuiGlobals.ENTER, self.__enterPublic)
        self.publicButton.bind(DirectGuiGlobals.EXIT, self.__exitPublic)
        pos = self.gui.find('**/step_04_private_locator').getPos()
        self.privateButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/privateButton_up'),
         self.gui.find('**/privateButton_down'),
         self.gui.find('**/privateButton_rollover'),
         self.gui.find('**/privateButton_inactive')), text=TTLocalizer.PartyPlannerPrivate, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPprivateButton, command=self.__doTogglePublicPrivate)
        self.privateButton.bind(DirectGuiGlobals.ENTER, self.__enterPrivate)
        self.privateButton.bind(DirectGuiGlobals.EXIT, self.__exitPrivate)
        self.checkAllButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/checkAllButton_up'), self.gui.find('**/checkAllButton_down'), self.gui.find('**/checkAllButton_rollover')), command=self.__doCheckAll)
        self.uncheckAllButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/uncheckAllButton_up'), self.gui.find('**/uncheckAllButton_down'), self.gui.find('**/uncheckAllButton_rollover')), command=self.__doUncheckAll)
        return page

    def __doCheckAll(self):
        for friendBox in self.friendList['items']:
            friendBox['indicatorValue'] = True

    def __doUncheckAll(self):
        for friendBox in self.friendList['items']:
            friendBox['indicatorValue'] = False

    def __enterPrivate(self, mouseEvent):
        self.privateDescriptionLabel.unstash()

    def __exitPrivate(self, mouseEvent):
        self.privateDescriptionLabel.stash()

    def __enterPublic(self, mouseEvent):
        self.publicDescriptionLabel.unstash()

    def __exitPublic(self, mouseEvent):
        self.publicDescriptionLabel.stash()

    def __doTogglePublicPrivate(self):
        if self.isPrivate:
            self.isPrivate = False
            self.privateButton['state'] = DirectGuiGlobals.NORMAL
            self.publicButton['state'] = DirectGuiGlobals.DISABLED
        else:
            self.isPrivate = True
            self.privateButton['state'] = DirectGuiGlobals.DISABLED
            self.publicButton['state'] = DirectGuiGlobals.NORMAL

    def _createPartyEditorPage(self):
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerEditorPage')
        self.LayoutTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerEditorTitle, pos=self.gui.find('**/title_locator').getPos() + Point3(0.0, 0.0, 0.075), scale=self.titleScale)
        self.costLabel = DirectLabel(parent=page, pos=(-0.74, 0.0, 0.17), relief=None, text=TTLocalizer.PartyPlannerTotalCost % 0, text_align=TextNode.ACenter, scale=TTLocalizer.PPcostLabel, textMayChange=True)
        self.partyGridBackground = DirectFrame(parent=page, relief=None, geom=self.gui.find('**/partyGrid_flat'))
        self.partyGroundsLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerPartyGrounds, text_font=ToontownGlobals.getSignFont(), text_fg=VBase4(1.0, 0.0, 0.0, 1.0), text_scale=TTLocalizer.PPpartyGroundsLabel, pos=self.gui.find('**/step_05_partyGrounds_text_locator').getPos(), scale=0.1)
        self.activityBackground = DirectFrame(parent=page, relief=None, geom=self.gui.find('**/activitiesDecorations_flat1'), pos=(0.0, 0.0, 0.04))
        pos = self.gui.find('**/step_05_instructions_locator').getPos()
        self.instructionLabel = DirectLabel(parent=page, relief=None, text=' ', text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPinstructionLabel, textMayChange=True, geom=self.gui.find('**/instructions_flat'))
        self.elementTitleLabel = DirectLabel(parent=page, relief=None, text=' ', pos=self.gui.find('**/step_05_activitiesName_text_locator').getPos() + Point3(0.0, 0.0, 0.04), text_scale=TTLocalizer.PPelementTitleLabel, textMayChange=True)
        self.elementPriceNode = TextNode('ElementPrice')
        self.elementPriceNode.setAlign(TextNode.ALeft)
        self.elementPriceNode.setTextColor(0.0, 0.0, 0.0, 1.0)
        self.elementPriceNode.setFont(ToontownGlobals.getToonFont())
        self.elementPrice = page.attachNewNode(self.elementPriceNode)
        self.elementPrice.setScale(TTLocalizer.PPelementPriceNode)
        self.elementPrice.setPos(self.gui.find('**/step_05_activityPrice_text_locator').getPos() + Point3(-0.02, 0.0, 0.04))
        self.elementDescriptionNode = TextNode('ElementDescription')
        self.elementDescriptionNode.setAlign(TextNode.ACenter)
        self.elementDescriptionNode.setWordwrap(8)
        self.elementDescriptionNode.setFont(ToontownGlobals.getToonFont())
        self.elementDescriptionNode.setTextColor(0.0, 0.0, 0.0, 1.0)
        self.elementDescription = page.attachNewNode(self.elementDescriptionNode)
        self.elementDescription.setScale(TTLocalizer.PPelementDescription)
        self.elementDescription.setPos(self.gui.find('**/step_05_activityDescription_text_locator').getPos() + Point3(0.0, 0.0, 0.04))
        self.totalMoney = base.localAvatar.getTotalMoney()
        catalogGui = loader.loadModel('phase_5.5/models/gui/catalog_gui')
        self.beanBank = DirectLabel(parent=page, relief=None, text=str(self.totalMoney), text_align=TextNode.ARight, text_scale=0.075, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_pos=(0.495, -0.53), text_font=ToontownGlobals.getSignFont(), textMayChange=True, image=catalogGui.find('**/bean_bank'), image_scale=(0.65, 0.65, 0.65), scale=0.9, pos=(-0.75, 0.0, 0.6))
        catalogGui.removeNode()
        del catalogGui
        self.accept(localAvatar.uniqueName('moneyChange'), self.__moneyChange)
        self.accept(localAvatar.uniqueName('bankMoneyChange'), self.__moneyChange)
        self.partyEditor = PartyEditor(self, page)
        self.partyEditor.request('Hidden')
        pos = self.gui.find('**/step_05_add_text_locator').getPos()
        self.elementBuyButton = DirectButton(parent=page, relief=None, text=TTLocalizer.PartyPlannerBuy, text_pos=(pos[0], pos[2]), text_scale=TTLocalizer.PPelementBuyButton, geom=(self.gui.find('**/add_up'), self.gui.find('**/add_down'), self.gui.find('**/add_rollover')), geom3_color=VBase4(0.5, 0.5, 0.5, 1.0), textMayChange=True, pos=(0.0, 0.0, 0.04), command=self.partyEditor.buyCurrentElement)
        self.okWithPartyGroundsLayoutEvent = 'okWithPartyGroundsLayoutEvent'
        self.accept(self.okWithPartyGroundsLayoutEvent, self.okWithPartyGroundsLayout)
        self.okWithGroundsGui = TTDialog.TTGlobalDialog(dialogName=self.uniqueName('PartyEditorOkGui'), doneEvent=self.okWithPartyGroundsLayoutEvent, message=TTLocalizer.PartyPlannerOkWithGroundsLayout, style=TTDialog.YesNo, okButtonText=OTPLocalizer.DialogYes, cancelButtonText=OTPLocalizer.DialogNo)
        self.okWithGroundsGui.doneStatus = ''
        self.okWithGroundsGui.hide()
        return page

    def okWithPartyGroundsLayout(self):
        self.okWithGroundsGui.hide()
        if self.okWithGroundsGui.doneStatus == 'ok':
            self.__nextItem()

    def setNextButtonState(self, enabled):
        if enabled:
            self.nextButton['state'] = DirectGuiGlobals.NORMAL
            self.nextButton.show()
        else:
            self.nextButton['state'] = DirectGuiGlobals.DISABLED
            self.nextButton.hide()

    def _createInvitationPage(self):
        self.__handleHolidays()
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerInvitationPage')
        self.invitationTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerConfirmTitle, textMayChange=True, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale)
        self.invitationBackground = DirectFrame(parent=page, relief=None, geom=self.gui.find('**/invitationBackground'))
        self.inviteVisual = InviteVisual(page)
        self.selectedInviteThemeLabel = DirectLabel(parent=page, relief=None, pos=self.gui.find('**/step_06_theme_locator').getPos(), text='', text_scale=0.06, textMayChange=True)
        self.nextThemeButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/topNext_button/nextButton_up'), self.gui.find('**/topNext_button/nextButton_down'), self.gui.find('**/topNext_button/nextButton_rollover')), command=self.__nextTheme)
        self.prevThemeButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/topPrevious_button/previousButton_up'), self.gui.find('**/topPrevious_button/previousButton_down'), self.gui.find('**/topPrevious_button/previousButton_rollover')), command=self.__prevTheme)
        pos = self.gui.find('**/step_06_sendInvitation_locator').getPos()
        self.inviteButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/send_up'), self.gui.find('**/send_down'), self.gui.find('**/send_rollover')), text=TTLocalizer.PartyPlannerInviteButton, textMayChange=True, text_scale=0.05, text_pos=(pos[0], pos[2]), command=self.__handleComplete)
        return page

    def __handleHolidays(self):
        self.inviteThemes = range(len(PartyGlobals.InviteTheme))
        if hasattr(base.cr, 'newsManager') and base.cr.newsManager:
            holidayIds = base.cr.newsManager.getHolidayIdList()
            if ToontownGlobals.VALENTINES_DAY not in holidayIds:
                self.inviteThemes.remove(PartyGlobals.InviteTheme.Valentoons)
            if ToontownGlobals.VICTORY_PARTY_HOLIDAY not in holidayIds:
                self.inviteThemes.remove(PartyGlobals.InviteTheme.VictoryParty)
            if ToontownGlobals.WINTER_DECORATIONS not in holidayIds and ToontownGlobals.WACKY_WINTER_DECORATIONS not in holidayIds:
                self.inviteThemes.remove(PartyGlobals.InviteTheme.Winter)

    def _createFarewellPage(self):
        page = DirectFrame(self.frame)
        page.setName('PartyPlannerFarewellPage')
        self.confirmTitleLabel = DirectLabel(parent=page, relief=None, text=TTLocalizer.PartyPlannerConfirmationAllOkTitle, textMayChange=True, pos=self.gui.find('**/title_locator').getPos(), scale=self.titleScale)
        pos = self.gui.find('**/step_07_close_text_locator').getPos()
        self.closePlannerButton = DirectButton(parent=page, relief=None, geom=(self.gui.find('**/close_up'), self.gui.find('**/close_down'), self.gui.find('**/close_rollover')), text=TTLocalizer.PartyPlannerClosePlanner, text_scale=0.055, text_pos=(pos[0], pos[2]), command=self.__acceptExit)
        return page

    def close(self):
        self.ignore('addPartyResponseReceived')
        self.ignore(localAvatar.uniqueName('moneyChange'))
        self.ignore(localAvatar.uniqueName('bankMoneyChange'))
        self.timeInputHourUpButton.destroy()
        self.timeInputHourDownButton.destroy()
        self.timeInputMinuteUpButton.destroy()
        self.timeInputMinuteDownButton.destroy()
        self.timeInputAmPmUpButton.destroy()
        self.timeInputAmPmDownButton.destroy()
        self.privateButton.destroy()
        self.publicButton.destroy()
        self.makePartyNowButton.destroy()
        self.checkAllButton.destroy()
        self.uncheckAllButton.destroy()
        self.elementBuyButton.destroy()
        self.nextThemeButton.destroy()
        self.prevThemeButton.destroy()
        self.inviteButton.destroy()
        self.closePlannerButton.destroy()
        self.ignore(self.okWithPartyGroundsLayoutEvent)
        if hasattr(self, 'okWithGroundsGui'):
            self.okWithGroundsGui.cleanup()
            del self.okWithGroundsGui
        if hasattr(self, 'frame') and not self.frame.isEmpty():
            messenger.send(self.doneEvent)
            self.hide()
            self.cleanup()
            self.friendList.removeAndDestroyAllItems()
            self.friendList.destroy()
            self.calendarGuiMonth.destroy()
            self.frame.destroy()
        self.partyPlannerHead.delete()
        self.partyPlannerHead.removeNode()
        self.clearNametag()
        self.partyEditor.request('Cleanup')
        self.partyEditor = None
        self.destroy()
        del self
        return

    def __handleComplete(self):
        self.inviteButton['state'] = DirectGuiGlobals.DISABLED
        self.prevButton['state'] = DirectGuiGlobals.DISABLED
        endTime = self.partyTime + self.partyDuration
        hostId = base.localAvatar.doId
        self.partyActivities = self.partyEditor.partyEditorGrid.getActivitiesOnGrid()
        decorations = self.partyEditor.partyEditorGrid.getDecorationsOnGrid()
        invitees = self.getInvitees()
        self.accept('addPartyResponseReceived', self.processAddPartyResponse)
        base.cr.partyManager.sendAddParty(hostId, self.partyTime.strftime('%Y-%m-%d %H:%M:%S'), endTime.strftime('%Y-%m-%d %H:%M:%S'), self.isPrivate, self.currentInvitationTheme, self.partyActivities, decorations, invitees)

    def getInvitees(self):
        invitees = []
        for friendBox in self.friendList['items']:
            if friendBox['indicatorValue']:
                invitees.append(friendBox.getPythonTag('id'))

        return invitees

    def processAddPartyResponse(self, hostId, errorCode):
        PartyPlanner.notify.debug('processAddPartyResponse : hostId=%d errorCode=%s' % (hostId, PartyGlobals.AddPartyErrorCode.getString(errorCode)))
        goingBackAllowed = False
        if errorCode == PartyGlobals.AddPartyErrorCode.AllOk:
            goingBackAllowed = False
            self.confirmTitleLabel['text'] = TTLocalizer.PartyPlannerConfirmationAllOkTitle
            if self.noFriends or len(self.getInvitees()) == 0:
                confirmRecapText = TTLocalizer.PartyPlannerConfirmationAllOkTextNoFriends
            else:
                confirmRecapText = TTLocalizer.PartyPlannerConfirmationAllOkText
        elif errorCode == PartyGlobals.AddPartyErrorCode.ValidationError:
            self.confirmTitleLabel['text'] = TTLocalizer.PartyPlannerConfirmationErrorTitle
            confirmRecapText = TTLocalizer.PartyPlannerConfirmationValidationErrorText
        elif errorCode == PartyGlobals.AddPartyErrorCode.DatabaseError:
            self.confirmTitleLabel['text'] = TTLocalizer.PartyPlannerConfirmationErrorTitle
            confirmRecapText = TTLocalizer.PartyPlannerConfirmationDatabaseErrorText
        elif errorCode == PartyGlobals.AddPartyErrorCode.TooManyHostedParties:
            goingBackAllowed = False
            self.confirmTitleLabel['text'] = TTLocalizer.PartyPlannerConfirmationErrorTitle
            confirmRecapText = TTLocalizer.PartyPlannerConfirmationTooManyText
        self.nametagGroup.setChat(confirmRecapText, CFSpeech)
        self.request('Farewell', goingBackAllowed)

    def __acceptExit(self):
        PartyPlanner.notify.debug('__acceptExit')
        if hasattr(self, 'frame'):
            self.hide()
            messenger.send(self.doneEvent)

    def __nextItem(self):
        messenger.send('wakeup')
        if self.state == 'PartyEditor' and self.okWithGroundsGui.doneStatus != 'ok':
            self.okWithGroundsGui.show()
            return
        if self.state == 'PartyEditor' and self.noFriends:
            self.request('Date')
            self.selectedCalendarGuiDay = None
            self.calendarGuiMonth.clearSelectedDay()
            return
        if self.state == 'Guests':
            self.selectedCalendarGuiDay = None
            self.calendarGuiMonth.clearSelectedDay()
        if self.state == 'Time':
            if self.partyTime < base.cr.toontownTimeManager.getCurServerDateTime():
                self.okChooseFutureTimeEvent = 'okChooseFutureTimeEvent'
                self.acceptOnce(self.okChooseFutureTimeEvent, self.okChooseFutureTime)
                self.chooseFutureTimeDialog = TTDialog.TTGlobalDialog(dialogName=self.uniqueName('chooseFutureTimeDialog'), doneEvent=self.okChooseFutureTimeEvent, message=TTLocalizer.PartyPlannerChooseFutureTime, style=TTDialog.Acknowledge)
                self.chooseFutureTimeDialog.show()
                return
        self.requestNext()
        return

    def okChooseFutureTime(self):
        if hasattr(self, 'chooseFutureTimeDialog'):
            self.chooseFutureTimeDialog.cleanup()
            del self.chooseFutureTimeDialog
        if hasattr(self, 'okChooseFutureTimeEvent'):
            self.ignore(self.okChooseFutureTimeEvent)

    def __prevItem(self):
        messenger.send('wakeup')
        if self.state == 'Date' and self.noFriends:
            self.request('PartyEditor')
            return
        if self.state == 'Invitation' and self.selectedCalendarGuiDay is None:
            self.request('Guests')
            return
        self.requestPrev()
        return

    def __moneyChange(self, newMoney):
        if hasattr(self, 'totalMoney'):
            self.totalMoney = base.localAvatar.getTotalMoney()
        if hasattr(self, 'beanBank'):
            self.beanBank['text'] = str(int(self.totalMoney))
class DistributedMoleField(DistributedNodePathEntity, MoleFieldBase.MoleFieldBase):
    notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMoleField')
    ScheduleTaskName = 'moleFieldScheduler'

    def __init__(self, cr):
        DistributedNodePathEntity.__init__(self, cr)
        self.gameStarted = False
        self.moleHills = []
        self.numMolesWhacked = 0
        self.timer = None
        self.frame2D = None
        self.isToonInRange = 0
        self.detectCount = 0
        self.cameraHold = None
        self.activeField = 1
        self.dimensionX = 0.0
        self.dimensionY = 0.0
        self.gameText = TTLocalizer.MolesInstruction
        self.winText = TTLocalizer.MolesFinished
        self.pityWinText = TTLocalizer.MolesPityWin
        self.restartedText = TTLocalizer.MolesRestarted
        self.toonHitTracks = {}
        self.hasRestarted = 0
        self.hasEntered = 0
        self.MolesWhackedTarget = 1000
        self.GameDuration = 1000
        return

    def disable(self):
        self.cleanupTimer()
        for ival in self.toonHitTracks.values():
            ival.finish()

        self.toonHitTracks = {}
        DistributedNodePathEntity.disable(self)
        taskMgr.remove(self.detectName)
        self.ignoreAll()

    def delete(self):
        self.soundBomb = None
        self.soundBomb2 = None
        self.soundCog = None
        DistributedNodePathEntity.delete(self)
        self.stopScheduleTask()
        for mole in self.moleHills:
            mole.destroy()

        self.moleHills = []
        self.cleanupTimer()
        self.unloadGui()
        return

    def announceGenerate(self):
        DistributedNodePathEntity.announceGenerate(self)
        self.loadModel()
        self.loadGui()
        self.detectName = 'moleField %s' % self.doId
        taskMgr.doMethodLater(0.1, self.__detect, self.detectName)
        self.calcDimensions()
        self.notify.debug('announceGenerate doId=%d entId=%d' % (self.doId, self.entId))

    def setNumSquaresX(self, num):
        self.numSquaresX = num
        self.calcDimensions()

    def setNumSquaresY(self, num):
        self.numSquaresY = num
        self.calcDimensions()

    def setSpacingX(self, num):
        self.spacingX = num
        self.calcDimensions()

    def setSpacingY(self, num):
        self.spacingY = num
        self.calcDimensions()

    def calcDimensions(self):
        self.dimensionX = self.numSquaresX * self.spacingX
        self.dimensionY = self.numSquaresY * self.spacingY
        self.centerCenterNode()

    def loadModel(self):
        moleIndex = 0
        self.moleHills = []
        for indexY in xrange(self.numSquaresY):
            for indexX in xrange(self.numSquaresX):
                xPos = indexX * self.spacingX
                yPos = indexY * self.spacingY
                newMoleHill = MoleHill.MoleHill(xPos, yPos, 0, self, moleIndex)
                newMoleHill.reparentTo(self)
                self.moleHills.append(newMoleHill)
                moleIndex += 1

        self.numMoles = len(self.moleHills)
        self.centerNode = self.attachNewNode('center')
        self.centerCenterNode()
        self.soundBomb = base.loadSfx('phase_12/audio/sfx/Mole_Surprise.ogg')
        self.soundBomb2 = base.loadSfx('phase_3.5/audio/dial/AV_pig_howl.ogg')
        self.soundCog = base.loadSfx('phase_12/audio/sfx/Mole_Stomp.ogg')
        self.soundUp = base.loadSfx('phase_4/audio/sfx/MG_Tag_C.ogg')
        self.soundDown = base.loadSfx('phase_4/audio/sfx/MG_cannon_whizz.ogg')
        upInterval = SoundInterval(self.soundUp, loop=0)
        downInterval = SoundInterval(self.soundDown, loop=0)
        self.soundIUpDown = Sequence(upInterval, downInterval)

    def centerCenterNode(self):
        self.centerNode.setPos(self.dimensionX * 0.5, self.dimensionY * 0.5, 0.0)

    def loadGui(self):
        self.frame2D = DirectFrame(scale=1.0, pos=(0.0, 0, 0.9), relief=DGG.FLAT, parent=aspect2d, frameSize=(-0.3,
         0.3,
         -0.05,
         0.05), frameColor=(0.737, 0.573, 0.345, 0.3))
        self.scoreLabel = DirectLabel(parent=self.frame2D, relief=None, pos=(0, 0, 0), scale=1.0, text='', text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text_scale=0.075, text_pos=(0, -0.02))
        self.updateGuiScore()
        self.frame2D.hide()
        return

    def unloadGui(self):
        self.frame2D.destroy()
        self.frame2D = None
        return

    def setGameStart(self, timestamp, molesWhackTarget, totalTime):
        self.GameDuration = totalTime
        self.MolesWhackedTarget = molesWhackTarget
        self.activeField = 1
        self.isToonInRange = 0
        self.scheduleMoles()
        self.notify.debug('%d setGameStart: Starting game' % self.doId)
        self.gameStartTime = globalClockDelta.networkToLocalTime(timestamp)
        self.gameStarted = True
        for hill in self.moleHills:
            hill.setGameStartTime(self.gameStartTime)

        curGameTime = self.getCurrentGameTime()
        timeLeft = self.GameDuration - curGameTime
        self.cleanupTimer()
        self.timer = ToontownTimer.ToontownTimer()
        self.timer.posBelowTopRightCorner()
        self.timer.setTime(timeLeft)
        self.timer.countdown(timeLeft, self.timerExpired)
        self.startScheduleTask()
        self.frame2D.show()
        if self.hasRestarted:
            self.level.countryClub.showInfoText(self.restartedText)
            self.sendUpdate('damageMe', [])
        else:
            self.hasRestarted = 1
        self.updateGuiScore()

    def local2GameTime(self, timestamp):
        return timestamp - self.gameStartTime

    def game2LocalTime(self, timestamp):
        return timestamp + self.gameStartTime

    def getCurrentGameTime(self):
        return self.local2GameTime(globalClock.getFrameTime())

    def startScheduleTask(self):
        taskMgr.add(self.scheduleTask, self.ScheduleTaskName)

    def stopScheduleTask(self):
        taskMgr.remove(self.ScheduleTaskName)

    def scheduleTask(self, task):
        curTime = self.getCurrentGameTime()
        while self.schedule and self.schedule[0][0] <= curTime and self.activeField:
            popupInfo = self.schedule[0]
            self.schedule = self.schedule[1:]
            startTime, moleIndex, curMoveUpTime, curStayUpTime, curMoveDownTime, moleType = popupInfo
            hill = self.moleHills[moleIndex]
            hill.doMolePop(startTime, curMoveUpTime, curStayUpTime, curMoveDownTime, moleType)

        if self.schedule:
            return task.cont
        else:
            return task.done

    def handleEnterHill(self, colEntry):
        if not self.gameStarted:
            self.notify.debug('sending clientTriggered for %d' % self.doId)
            self.sendUpdate('setClientTriggered', [])

    def handleEnterMole(self, colEntry):
        if not self.gameStarted:
            self.notify.debug('sending clientTriggered for %d' % self.doId)
            self.sendUpdate('setClientTriggered', [])
        surfaceNormal = colEntry.getSurfaceNormal(render)
        self.notify.debug('surfaceNormal=%s' % surfaceNormal)
        into = colEntry.getIntoNodePath()
        moleIndex = int(into.getName().split('-')[-1])
        self.notify.debug('hit mole %d' % moleIndex)
        moleHill = self.moleHills[moleIndex]
        moleHill.stashMoleCollision()
        popupNum = moleHill.getPopupNum()
        if moleHill.hillType == MoleFieldBase.HILL_MOLE:
            timestamp = globalClockDelta.getFrameNetworkTime()
            moleHill.setHillType(MoleFieldBase.HILL_WHACKED)
            self.sendUpdate('whackedBomb', [moleIndex, popupNum, timestamp])
            self.__showToonHitByBomb(localAvatar.doId, moleIndex, timestamp)
        elif moleHill.hillType == MoleFieldBase.HILL_BOMB:
            moleHill.setHillType(MoleFieldBase.HILL_COGWHACKED)
            self.soundCog.play()
            self.sendUpdate('whackedMole', [moleIndex, popupNum])

    def updateMole(self, moleIndex, status):
        if status == self.WHACKED:
            moleHill = self.moleHills[moleIndex]
            if not moleHill.hillType == MoleFieldBase.HILL_COGWHACKED:
                moleHill.setHillType(MoleFieldBase.HILL_COGWHACKED)
                self.soundCog.play()
            moleHill.doMoleDown()

    def updateGuiScore(self):
        molesLeft = self.MolesWhackedTarget - self.numMolesWhacked
        if self.frame2D and hasattr(self, 'scoreLabel') and molesLeft >= 0:
            newText = TTLocalizer.MolesLeft % molesLeft
            self.scoreLabel['text'] = newText

    def setScore(self, score):
        self.notify.debug('score=%d' % score)
        self.numMolesWhacked = score
        self.updateGuiScore()
        molesLeft = self.MolesWhackedTarget - self.numMolesWhacked
        if molesLeft == 0:
            self.gameWon()

    def cleanupTimer(self):
        if self.timer:
            self.timer.stop()
            self.timer.destroy()
            self.timer = None
        return

    def timerExpired(self):
        self.cleanupTimer()
        self.cleanDetect()

    def gameWon(self):
        for hill in self.moleHills:
            hill.forceMoleDown()

        self.cleanupTimer()
        self.frame2D.hide()
        self.level.countryClub.showInfoText(self.winText)
        self.cleanDetect()

    def setPityWin(self):
        for hill in self.moleHills:
            hill.forceMoleDown()

        self.cleanupTimer()
        self.frame2D.hide()
        self.level.countryClub.showInfoText(self.pityWinText)
        self.cleanDetect()

    def cleanDetect(self):
        self.activeField = 0
        self.doToonOutOfRange()

    def __detect(self, task):
        distance = self.centerNode.getDistance(localAvatar)
        greaterDim = self.dimensionX
        if self.dimensionY > self.dimensionX:
            greaterDim = self.gridScaleY
        self.detectCount += 1
        if self.detectCount > 5:
            self.detectCount = 0
        if distance < greaterDim * 0.75:
            if not self.isToonInRange:
                self.doToonInRange()
        elif self.isToonInRange:
            self.doToonOutOfRange()
        taskMgr.doMethodLater(0.1, self.__detect, self.detectName)
        return Task.done

    def doToonInRange(self):
        if not self.gameStarted:
            self.notify.debug('sending clientTriggered for %d' % self.doId)
            self.sendUpdate('setClientTriggered', [])
        self.isToonInRange = 1
        if self.activeField:
            self.setUpCamera()
            if not self.hasEntered:
                self.level.countryClub.showInfoText(self.gameText)
                self.hasEntered = 1

    def setUpCamera(self):
        camHeight = base.localAvatar.getClampedAvatarHeight()
        heightScaleFactor = camHeight * 0.3333333333
        defLookAt = Point3(0.0, 1.5, camHeight)
        cameraPoint = Point3(0.0, -22.0 * heightScaleFactor, camHeight + 12.0)
        base.localAvatar.setIdealCameraPos(cameraPoint)

    def doToonOutOfRange(self):
        self.isToonInRange = 0
        base.localAvatar.setCameraPositionByIndex(base.localAvatar.cameraIndex)
        self.cameraHold = None
        return

    def reportToonHitByBomb(self, avId, moleIndex, timestamp):
        if avId != localAvatar.doId:
            self.__showToonHitByBomb(avId, moleIndex, timestamp)
            moleHill = self.moleHills[moleIndex]
            if not moleHill.hillType == MoleFieldBase.HILL_WHACKED:
                moleHill.setHillType(MoleFieldBase.HILL_WHACKED)
                self.soundCog.play()
            moleHill.doMoleDown()

    def __showToonHitByBomb(self, avId, moleIndex, timestamp = 0):
        toon = base.cr.doId2do.get(avId)
        moleHill = self.moleHills[moleIndex]
        if toon == None:
            return
        rng = random.Random(timestamp)
        curPos = toon.getPos(render)
        oldTrack = self.toonHitTracks.get(avId)
        if oldTrack:
            if oldTrack.isPlaying():
                oldTrack.finish()
        toon.setPos(curPos)
        toon.setZ(self.getZ())
        parentNode = render.attachNewNode('mazeFlyToonParent-' + `avId`)
        parentNode.setPos(toon.getPos(render))
        toon.reparentTo(parentNode)
        toon.setPos(0, 0, 0)
        startPos = parentNode.getPos()
        dropShadow = toon.dropShadow.copyTo(parentNode)
        dropShadow.setScale(toon.dropShadow.getScale(render))
        trajectory = Trajectory.Trajectory(0, Point3(0, 0, 0), Point3(0, 0, 50), gravMult=1.0)
        flyDur = trajectory.calcTimeOfImpactOnPlane(0.0)
        endTile = [rng.randint(0, self.numSquaresX - 1), rng.randint(0, self.numSquaresY - 1)]
        endWorldCoords = (self.getX(render) + endTile[0] * self.spacingX, self.getY(render) + endTile[1] * self.spacingY)
        endPos = Point3(endWorldCoords[0], endWorldCoords[1], startPos[2])

        def flyFunc(t, trajectory, startPos = startPos, endPos = endPos, dur = flyDur, moveNode = parentNode, flyNode = toon):
            u = t / dur
            moveNode.setX(startPos[0] + u * (endPos[0] - startPos[0]))
            moveNode.setY(startPos[1] + u * (endPos[1] - startPos[1]))
            if flyNode and not flyNode.isEmpty():
                flyNode.setPos(trajectory.getPos(t))

        def safeSetHpr(node, hpr):
            if node and not node.isEmpty():
                node.setHpr(hpr)

        flyTrack = Sequence(LerpFunctionInterval(flyFunc, fromData=0.0, toData=flyDur, duration=flyDur, extraArgs=[trajectory]), name=toon.uniqueName('hitBySuit-fly'))
        if avId != localAvatar.doId:
            cameraTrack = Sequence()
        else:
            base.localAvatar.stopUpdateSmartCamera()
            self.camParentHold = camera.getParent()
            self.camParent = base.localAvatar.attachNewNode('iCamParent')
            self.camParent.setPos(self.camParentHold.getPos())
            self.camParent.setHpr(self.camParentHold.getHpr())
            camera.reparentTo(self.camParent)
            self.camParent.reparentTo(parentNode)
            startCamPos = camera.getPos()
            destCamPos = camera.getPos()
            zenith = trajectory.getPos(flyDur / 2.0)[2]
            destCamPos.setZ(zenith * 1.3)
            destCamPos.setY(destCamPos[1] * 0.3)

            def camTask(task, zenith = zenith, flyNode = toon, startCamPos = startCamPos, camOffset = destCamPos - startCamPos):
                u = flyNode.getZ() / zenith
                camera.lookAt(toon)
                return Task.cont

            camTaskName = 'mazeToonFlyCam-' + `avId`
            taskMgr.add(camTask, camTaskName, priority=20)

            def cleanupCamTask(self = self, toon = toon, camTaskName = camTaskName, startCamPos = startCamPos):
                taskMgr.remove(camTaskName)
                self.camParent.reparentTo(toon)
                camera.setPos(startCamPos)
                camera.lookAt(toon)
                camera.reparentTo(self.camParentHold)
                base.localAvatar.startUpdateSmartCamera()
                self.setUpCamera()

            cameraTrack = Sequence(Wait(flyDur), Func(cleanupCamTask), name='hitBySuit-cameraLerp')
        geomNode = toon.getGeomNode()
        startHpr = geomNode.getHpr()
        destHpr = Point3(startHpr)
        hRot = rng.randrange(1, 8)
        if rng.choice([0, 1]):
            hRot = -hRot
        destHpr.setX(destHpr[0] + hRot * 360)
        spinHTrack = Sequence(LerpHprInterval(geomNode, flyDur, destHpr, startHpr=startHpr), Func(safeSetHpr, geomNode, startHpr), name=toon.uniqueName('hitBySuit-spinH'))
        parent = geomNode.getParent()
        rotNode = parent.attachNewNode('rotNode')
        geomNode.reparentTo(rotNode)
        rotNode.setZ(toon.getHeight() / 2.0)
        oldGeomNodeZ = geomNode.getZ()
        geomNode.setZ(-toon.getHeight() / 2.0)
        startHpr = rotNode.getHpr()
        destHpr = Point3(startHpr)
        pRot = rng.randrange(1, 3)
        if rng.choice([0, 1]):
            pRot = -pRot
        destHpr.setY(destHpr[1] + pRot * 360)
        spinPTrack = Sequence(LerpHprInterval(rotNode, flyDur, destHpr, startHpr=startHpr), Func(safeSetHpr, rotNode, startHpr), name=toon.uniqueName('hitBySuit-spinP'))
        soundTrack = Sequence()

        def preFunc(self = self, avId = avId, toon = toon, dropShadow = dropShadow):
            forwardSpeed = toon.forwardSpeed
            rotateSpeed = toon.rotateSpeed
            if avId == localAvatar.doId:
                toon.stopSmooth()
                base.cr.playGame.getPlace().fsm.request('stopped')
            else:
                toon.stopSmooth()
            if forwardSpeed or rotateSpeed:
                toon.setSpeed(forwardSpeed, rotateSpeed)
            toon.dropShadow.hide()

        def postFunc(self = self, avId = avId, oldGeomNodeZ = oldGeomNodeZ, dropShadow = dropShadow, parentNode = parentNode):
            if avId == localAvatar.doId:
                base.localAvatar.setPos(endPos)
                if hasattr(self, 'orthoWalk'):
                    self.orthoWalk.start()
            dropShadow.removeNode()
            del dropShadow
            if toon and toon.dropShadow:
                toon.dropShadow.show()
            geomNode = toon.getGeomNode()
            rotNode = geomNode.getParent()
            baseNode = rotNode.getParent()
            geomNode.reparentTo(baseNode)
            rotNode.removeNode()
            del rotNode
            geomNode.setZ(oldGeomNodeZ)
            toon.reparentTo(render)
            toon.setPos(endPos)
            parentNode.removeNode()
            del parentNode
            if avId == localAvatar.doId:
                toon.startSmooth()
                place = base.cr.playGame.getPlace()
                if place and hasattr(place, 'fsm'):
                    place.fsm.request('walk')
            else:
                toon.startSmooth()

        preFunc()
        hitTrack = Sequence(Func(toon.setPos, Point3(0.0, 0.0, 0.0)), Wait(0.25), Parallel(flyTrack, cameraTrack, self.soundIUpDown, spinHTrack, spinPTrack, soundTrack), Func(postFunc), name=toon.uniqueName('hitBySuit'))
        self.toonHitTracks[avId] = hitTrack
        hitTrack.start()
        posM = moleHill.getPos(render)
        posN = Point3(posM[0], posM[1], posM[2] + 4.0)
        self.soundBomb.play()
        self.soundBomb2.play()
        return
Exemplo n.º 57
0
 def destroy(self):
     self.reset()
     self.countdownTask = None
     DirectFrame.destroy(self)
     return
Exemplo n.º 58
0
 def destroy(self):
     self.ival.finish()
     self.ival = None
     DirectFrame.destroy(self)
     return
 def destroy(self):
     self.movie.finish()
     DirectFrame.destroy(self)