class ModPanelButton:
    def __init__(self, menu, name, command, register):
        self.menu = menu
        self.name = name
        
        self.command = command
        if type(command) == types.StringType:
            command = self.call_word

        self.button = DirectButton(frameSize=None, text=name, 
            image=(ModPanelGlobals.Button.find('**/QuitBtn_UP'),
            ModPanelGlobals.Button.find('**/QuitBtn_DN'),
            ModPanelGlobals.Button.find('**/QuitBtn_RLVR')),
            relief=None, command=command, text_pos=(0, -0.015),
            geom=None, pad=(0.01, 0.01), suppressKeys=0, pos=(0, 0, 0), 
            text_scale=0.059, borderWidth=(0.015, 0.01), scale=.7
        )
        
        self.button.reparent_to(menu)
        
        if register:
            self.button.bind(DirectGuiGlobals.B2PRESS, self.delete_button)
            self.button.bind(DirectGuiGlobals.B3PRESS, self.button.editStart)
            self.button.bind(DirectGuiGlobals.B3RELEASE, self.edit_stop)
            self.menu.buttons.append(self)
            messenger.send('save-file')
        
    def call_word(self):
        messenger.send('magicWord', [self.command])
        
    def hide(self):
        self.button.hide()
        
    def show(self):
        self.button.show()
        
    def place(self):
        self.button.place()
        
    def set_pos(self, x, y, z):
        self.button.set_pos(x, y, z)
        
    def destroy(self):
        self.button.destroy()
        
    def edit_stop(self, dispatch):
        self.button.editStop(dispatch)
        
        messenger.send('save-file')

    def delete_button(self, dispatch):
        self.button.destroy()
        if self in self.menu.buttons:
            self.menu.buttons.remove(self)
            
        messenger.send('save-file')
        
    def get_data(self):
        return (self.name, self.command, self.button.get_pos())
Ejemplo n.º 2
0
class connectGUI():
    def __init__(self, _client):
        # Ref
        self.client = _client

        # create a host button
        self.btnConnect = DirectButton(
            # Scale and position
            scale=0.25,
            pos=(0, 0, 0),
            # Text
            text="Connect",
            # Frame
            # Functionality
            command=self.connect)

        # create the IP input field
        self.txtIP = DirectEntry(
            # scale and position
            pos=(0, 0, -.35),
            scale=0.25,
            width=9,
            # Text
            text="",
            text_align=TextNode.ACenter,
            initialText="127.0.0.1",
            numLines=1,
            # Functionality
            command=self.connect,
            focusInCommand=self.clearText)

        self.hide()

    def show(self):
        self.btnConnect.show()
        self.txtIP.show()

    def hide(self):
        self.btnConnect.hide()
        self.txtIP.hide()

    def clearText(self):
        """Function to clear the text that was previously entered in the
        IP input field"""
        self.txtIP.enterText("")
        #TODO: Do something with the ip

    def connect(self, ip=None):
        """Function which will be called by pressing the connect button
        or hit enter while the focus is on the inut field"""
        if ip == None: ip = self.txtIP.get(True)
        if ip != "":
            if self.client.connectionMgr.connectToServer(ip, 5001):
                gui = lobbyGUI(self.client)
                self.client.gui.hide()
                gui.show()
            else:
                return
Ejemplo n.º 3
0
class Menu:
    def __init__(self):
        self.loadStartMenu()

    def loadStartMenu(self):
        base.setBackgroundColor(0, 0.25, 0.4)

        self.title = OnscreenImage(image=str(MAINDIR) +
                                   '/assets/gui/title.png',
                                   pos=(0, 0, 0.20),
                                   scale=(0.5, 0.5, 0.125))
        self.title.setTransparency(1)

        mapsworld = loader.loadModel("assets/gui/world_maps")
        mapsranking = loader.loadModel("assets/gui/classement_maps")

        self.world_button = DirectButton(
            geom=(mapsworld.find("**/world_ready"),
                  mapsworld.find("**/world_over")),
            frameColor=(0, 0, 0, 0),
            pos=(0.0, 0, -0.40),
            command=base.messenger.send,
            scale=0.35,
            extraArgs=["Menu-Start-World"])
        self.ranking_button = DirectButton(
            geom=(mapsranking.find("**/classement_ready"),
                  mapsranking.find("**/classement_over")),
            frameColor=(0, 0, 0, 0),
            pos=(0, 0, -0.80),
            command=base.messenger.send,
            scale=0.25,
            extraArgs=["Menu-Start-Ranking"])

    def hideStartMenu(self):
        self.world_button.hide()
        self.ranking_button.hide()
        self.title.hide()

    def showStartMenu(self):
        self.world_button.show()
        self.ranking_button.show()
        self.title.show()
Ejemplo n.º 4
0
 def MakeButton(self, egg, up, over, x, y, cmd, parent):
     maps = loader.loadModel("Assets/Images/Inventory/%s" % (egg))
     b = DirectButton(geom = (maps.find('**/%s' % (up)),
                      maps.find('**/%s' % (over)),
                      maps.find('**/%s' % (over)),
                      maps.find('**/%s' % (up))),
                      command = cmd,
                      pressEffect = 0,
                      relief = None,
                      rolloverSound = None, 
                      clickSound = None,
                      scale = (150./1024.0, 1, 75.0/1024.0))
     b.reparentTo(parent)
     b.hide()
     
     diff = Settings.WIDTH - Settings.HEIGHT
     xOff = 0
     yOff = 0
     if(diff > 0):
         xOff = diff / 2
     else:
         yOff = diff / 2
     
     x = Settings.Transpose(x + 50, 1024) + xOff
     y = Settings.Transpose(y + 25, 1024) + yOff
         
     centerX = Settings.WIDTH / 2
     centerY = Settings.HEIGHT / 2
     
     newX = 1.0 * (x - centerX) / (centerX - xOff)
     newY = 1.0 * (centerY - y) / (centerY - yOff)
     
     b.setX(newX)
     b.setZ(newY)
     
     return b
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))
Ejemplo n.º 6
0
class GroupTrackerPlayer(DirectButton):
    def __init__(self, parent, avId, name, isLeader, **kw):
        self.avId = avId
        self.name = name
        self.isLeader = isLeader
        self.leaderImage = None

        if parent is None:
            parent = aspect2d

        text = self.getName()

        optiondefs = (('text', text, None), ('text_fg', (0.0, 0.0, 0.0, 1.0),
                                             None), ('text_align',
                                                     TextNode.ALeft, None),
                      ('text_pos', (-0.2, 0.0, 0.0), None),
                      ('relief', None, None), ('text_scale', 0.05, None),
                      ('command', self.loadPlayerDetails, None))

        self.defineoptions(kw, optiondefs)
        DirectButton.__init__(self, parent)
        self.initialiseoptions(GroupTrackerPlayer)

        boardingGroupIcons = loader.loadModel(
            'phase_9/models/gui/tt_m_gui_brd_status')
        self.leaderButtonImage = boardingGroupIcons.find(
            '**/tt_t_gui_brd_statusLeader')
        self.leaderImage = DirectButton(parent=self,
                                        relief=None,
                                        state=DGG.DISABLED,
                                        image=(self.leaderButtonImage),
                                        image_scale=(0.06, 1.0, 0.06),
                                        pos=(-0.26, 0, 0.02),
                                        command=None)

        self.setLeaderStatus(self.isLeader)
        boardingGroupIcons.removeNode()

    def destroy(self):
        if hasattr(self, 'playerCount'):
            if self.leaderImage:
                self.leaderImage.destroy()
                del self.leaderImage

        DirectButton.destroy(self)

    def setLeaderStatus(self, isLeader):
        self.isLeader = isLeader

        if self.isLeader:
            self.leaderImage.show()
        if not self.isLeader:
            self.leaderImage.hide()

    def getLeader(self):
        return self.isLeader

    def getName(self):
        # Lets cap a length so we dont have too long of names
        name = self.name
        if len(name) > 15:
            name = name[:16] + '...'  # Chop the first x characters
        return name

    def getId(self):
        return self.avId

    def loadPlayerDetails(self):
        # TODO: Load player details based off avId for localAvatar
        pass
Ejemplo n.º 7
0
class NamePage(StateData):
    notify = directNotify.newCategory('NamePage')

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

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

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

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

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

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

        self.loadingLabel.hide()
        return

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

    def acceptName(self):
        pass

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

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

        self.requestsContainer = {}
        return

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

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

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

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

    def enterOff(self):
        pass

    def exitOff(self):
        pass
Ejemplo n.º 8
0
class MainScreen():
    def __init__(self):

        self.txtPlayerName = DirectEntry(
            text="",
            scale=0.08,
            pos=(-0.15, 0, 0.6),
            initialText="Name",
            numLines = 1,
            width = 4,
            focus=False,
            focusInCommand=self.__clearText,
            focusOutCommand=self.__checkText)

        self.btnStart = DirectButton(
            text = "Start",
            # size of the button
            scale = (0.25, 0.25, 0.25),
            # set no relief
            relief = 1,
            frameColor = (0,0,0,0),
            # No sink in when press
            pressEffect = False,
            # position on the window
            pos = (0, 0, .3),
            # the event which is thrown on clickSound
            command = self.btnStart_Click,
            # sounds that should be played
            rolloverSound = None,
            clickSound = None)
        self.btnStart.setTransparency(1)

        self.btnHighscore = DirectButton(
            text = "Highscore",
            # size of the button
            scale = (0.25, 0.25, 0.25),
            # set no relief
            relief = 1,
            frameColor = (0,0,0,0),
            # No sink in when press
            pressEffect = False,
            # position on the window
            pos = (0, 0, 0),
            # the event which is thrown on clickSound
            command = self.btnHighscore_Click,
            # sounds that should be played
            rolloverSound = None,
            clickSound = None)
        self.btnHighscore.setTransparency(1)

        self.btnQuit = DirectButton(
            text = "Quit",
            # size of the button
            scale = (0.25, 0.25, 0.25),
            # set no relief
            relief = 1,
            frameColor = (0,0,0,0),
            # No sink in when press
            pressEffect = False,
            # position on the window
            pos = (0, 0, -.3),
            # the event which is thrown on clickSound
            command = self.btnQuit_Click,
            # sounds that should be played
            rolloverSound = None,
            clickSound = None)
        self.btnQuit.setTransparency(1)

    def show(self):
        self.txtPlayerName.show()
        self.btnStart.show()
        self.btnHighscore.show()
        self.btnQuit.show()

    def hide(self):
        self.txtPlayerName.hide()
        self.btnStart.hide()
        self.btnHighscore.hide()
        self.btnQuit.hide()


    def __clearText(self):
        if self.txtPlayerName.get() == "" or \
               self.txtPlayerName.get() == "Name":
            self.txtPlayerName.enterText("")

    def __checkText(self):
        if self.txtPlayerName.get() == "":
            self.txtPlayerName.enterText("Name")

    def btnStart_Click(self):
        self.hide()
        base.messenger.send("MainMenu_start")

    def btnHighscore_Click(self):
        self.hide()
        base.messenger.send("Highscore_show")

    def btnQuit_Click(self):
        base.messenger.send("MainMenu_quit")

    def getPlayername(self):
        return self.txtPlayerName.get()
Ejemplo n.º 9
0
class SimulatorConfig(DirectObject):
    __services: Services
    __base: ShowBase
    __window: Window

    __animations = {
        "None": (0, 0),
        "Normal": (np.finfo(float).eps, 0),
        "Slow": (0.5, 0),
        "Fast": (np.finfo(float).eps, 20)
    }

    def __init__(self, services: Services,
                 mouse1_press_callbacks: List[Callable[[], None]]):
        self.__services = services
        self.__services.ev_manager.register_listener(self)
        self.__base = self.__services.graphics.window
        self.__text = " t - find the path between the agent and goal\n\n" \
                      " mouse click - moves agent to mouse location \n\n mouse right click - moves goal to" \
                      " mouse location\n\n arrow keys, PgUp, PgDn - move agent / goal (Alt down)\n\n x - toggle trace" \
                      " animation (animations required)\n\n m - toggle map between Sparse and Dense\n\n o - take a " \
                      "default screenshot of the map\n\n p - take a custom screenshot of the scene\n\n w, a, s, d " \
                      "- orbit around the map\n\n q - top view of the map\n\n c, v - toggle Simulator Configuration /" \
                      " View Editor\n\n i - toggle Debug Overlay"

        self.__algorithms = self.__services.settings.algorithms
        self.__maps = self.__services.settings.maps

        self.__map_keys = list(self.__maps.keys())
        self.__algorithm_keys = list(self.__algorithms.keys())
        self.__animation_keys = list(self.__animations.keys())

        self.__window = Window(self.__base,
                               "simulator_config",
                               mouse1_press_callbacks,
                               borderWidth=(0.0, 0.0),
                               frameColor=WINDOW_BG_COLOUR,
                               pos=(-1, 0.5, 0.5),
                               frameSize=(-1.7, 1.3, -5.68, 0.85))
        # spacer #
        DirectFrame(parent=self.__window.frame,
                    borderWidth=(.0, .0),
                    frameColor=WIDGET_BG_COLOUR,
                    frameSize=(-1.4, 1.4, -0.011, 0.011),
                    pos=(-0.2, 0.0, 0.4))

        DirectFrame(parent=self.__window.frame,
                    borderWidth=(.0, .0),
                    frameColor=WIDGET_BG_COLOUR,
                    frameSize=(-1.4, 1.4, -0.01, 0.01),
                    pos=(-0.2, 0.0, -2.96))

        self.sim_config = DirectLabel(parent=self.__window.frame,
                                      text="Simulator Configuration",
                                      text_fg=WHITE,
                                      text_bg=WINDOW_BG_COLOUR,
                                      frameColor=WINDOW_BG_COLOUR,
                                      borderWidth=(.0, .0),
                                      pos=(-0.53, 0.0, 0.56),
                                      scale=(0.2, 3, 0.2))
        # Zoom buttons
        self.btn_zoom_out = DirectButton(text="-",
                                         text_fg=WHITE,
                                         pressEffect=1,
                                         command=self.__window.zoom_out,
                                         pos=(0.71, 0., 0.55),
                                         parent=self.__window.frame,
                                         scale=(0.3, 4.15, 0.35),
                                         frameColor=TRANSPARENT)

        self.btn_zoom_in = DirectButton(text="+",
                                        text_fg=WHITE,
                                        pressEffect=1,
                                        command=self.__window.zoom_in,
                                        pos=(0.92, 0., 0.56),
                                        parent=self.__window.frame,
                                        scale=(0.3, 4.15, 0.35),
                                        frameColor=TRANSPARENT)

        # Quit button
        self.btn = DirectButton(text='x',
                                text_fg=WHITE,
                                command=self.__window.toggle_visible,
                                pos=(1.12, 0., 0.576),
                                parent=self.__window.frame,
                                scale=(0.3, 2.9, 0.2),
                                pressEffect=1,
                                frameColor=TRANSPARENT)

        self.user_information = DirectLabel(parent=self.__window.frame,
                                            text=self.__text,
                                            text_fg=WHITE,
                                            text_bg=WINDOW_BG_COLOUR,
                                            frameColor=WINDOW_BG_COLOUR,
                                            text_align=TextNode.ALeft,
                                            borderWidth=(.0, .0),
                                            pos=(-1.55, 0.0, -3.2),
                                            scale=(0.11, 1.1, 0.11))

        self.map_label = DirectLabel(parent=self.__window.frame,
                                     text="Map:",
                                     text_fg=WHITE,
                                     text_bg=WINDOW_BG_COLOUR,
                                     text_align=TextNode.ALeft,
                                     frameColor=WINDOW_BG_COLOUR,
                                     borderWidth=(.0, .0),
                                     pos=(-1.52, 0.4, 0.),
                                     scale=(0.17, 1.09, 0.13))

        self.algo_label = DirectLabel(parent=self.__window.frame,
                                      text="Algorithm:",
                                      text_fg=WHITE,
                                      text_bg=WINDOW_BG_COLOUR,
                                      frameColor=WINDOW_BG_COLOUR,
                                      text_align=TextNode.ALeft,
                                      borderWidth=(.0, .0),
                                      pos=(-1.52, 0.4, -0.5),
                                      scale=(0.17, 1.09, 0.13))

        self.animation_label = DirectLabel(parent=self.__window.frame,
                                           text="Animation:",
                                           text_fg=WHITE,
                                           text_bg=WINDOW_BG_COLOUR,
                                           frameColor=WINDOW_BG_COLOUR,
                                           text_align=TextNode.ALeft,
                                           borderWidth=(.0, .0),
                                           pos=(-1.52, 0.4, -1),
                                           scale=(0.17, 1.09, 0.13))

        self.agent_label = DirectLabel(parent=self.__window.frame,
                                       text="Agent:",
                                       text_fg=WHITE,
                                       text_bg=WINDOW_BG_COLOUR,
                                       frameColor=WINDOW_BG_COLOUR,
                                       text_align=TextNode.ALeft,
                                       borderWidth=(.0, .0),
                                       pos=(-1.52, 0.4, -1.5),
                                       scale=(0.17, 1.09, 0.13))

        self.goal_label = DirectLabel(parent=self.__window.frame,
                                      text="Goal:",
                                      text_fg=WHITE,
                                      text_bg=WINDOW_BG_COLOUR,
                                      frameColor=WINDOW_BG_COLOUR,
                                      text_align=TextNode.ALeft,
                                      borderWidth=(.0, .0),
                                      pos=(-1.52, 0.4, -2),
                                      scale=(0.17, 1.09, 0.13))

        # Creating goal and agent's entry fields
        self.__entries = []
        self.__entry_hovered = False
        mouse1_press_callbacks.append(self.__entry_mouse_click_callback)
        for i in range(0, 6):
            e = DirectEntry(parent=self.__window.frame,
                            scale=0.12,
                            pos=(-0.24 + (i % 3) * 0.57, 0.4,
                                 -1.5 - 0.5 * (i // 3)),
                            numLines=1,
                            width=3,
                            suppressKeys=True,
                            text_align=TextNode.ACenter,
                            focusInCommand=self.clear_text,
                            focusInExtraArgs=[i])
            self.__entries.append(e)
            e.bind(DGG.EXIT, self.__entry_exit_callback)
            e.bind(DGG.ENTER, self.__entry_enter_callback)
            e.bind(DGG.B1PRESS, self.__entry_mouse_click_callback)
            self.accept("mouse1", self.__entry_mouse_click_callback)

        self.__agent_disable_overlay = DirectButton(parent=self.__window.frame,
                                                    frameColor=TRANSPARENT,
                                                    borderWidth=(0.0, 0.0),
                                                    frameSize=(-0.6, 1.4, -0.2,
                                                               0.2),
                                                    pos=(-0.24, 0.4, -1.5),
                                                    suppressMouse=True)
        self.__agent_disable_overlay.hide()

        self.__maps_option = DirectOptionMenu(
            text="options",
            scale=0.14,
            parent=self.__window.frame,
            initialitem=self.__map_keys.index("Labyrinth")
            if "Labyrinth" in self.__map_keys else 0,
            items=self.__map_keys,
            pos=(-0.65, 0.4, 0.),
            highlightColor=(0.65, 0.65, 0.65, 1),
            textMayChange=1,
            command=self.__use_default_map_positions)

        self.__algorithms_option = DirectOptionMenu(
            text="options",
            scale=0.14,
            parent=self.__window.frame,
            initialitem=self.__algorithm_keys.index("A*")
            if "A*" in self.__algorithm_keys else 0,
            items=self.__algorithm_keys,
            pos=(-0.46, 0.4, -0.5),
            highlightColor=(0.65, 0.65, 0.65, 1),
            textMayChange=1)

        self.__animations_option = DirectOptionMenu(
            text="options",
            scale=0.14,
            parent=self.__window.frame,
            initialitem=self.__animation_keys.index("Fast"),
            items=self.__animation_keys,
            pos=(-0.45, 0.4, -1),
            highlightColor=(0.65, 0.65, 0.65, 1),
            textMayChange=1)

        self._update_frame = DirectFrame(parent=self.__window.frame,
                                         frameColor=WHITE,
                                         pos=(-1, 0.4, -2.6),
                                         borderWidth=(0.25, 0.15),
                                         frameSize=(-0.5, 0.95, -0.54, 0.54),
                                         scale=(0.50, 3.1, 0.25))

        self._reset_frame = DirectFrame(parent=self.__window.frame,
                                        frameColor=WHITE,
                                        pos=(0.412, 0.4, -2.6),
                                        borderWidth=(0.25, 0.15),
                                        frameSize=(-0.5, 0.92, -0.54, 0.54),
                                        scale=(0.50, 3.1, 0.25))

        self.btn_update = DirectButton(
            text="Update",
            text_fg=(0.3, 0.3, 0.3, 1.0),
            pressEffect=1,
            command=self.__update_simulator_callback,
            pos=(-0.9, 0.4, -2.65),
            parent=self.__window.frame,
            scale=(0.20, 2.1, 0.15),
            frameColor=TRANSPARENT)

        self.btn_reset = DirectButton(text="Reset",
                                      text_fg=(0.4, 0.3, 0.3, 1.0),
                                      pressEffect=1,
                                      command=self.__reset_simulator_callback,
                                      pos=(0.51, 0.4, -2.65),
                                      parent=self.__window.frame,
                                      scale=(0.20, 2.1, 0.15),
                                      frameColor=TRANSPARENT)

        # setup state & use saved state if possible
        self.__state = None
        for so in self.__services.state.objects:
            if isinstance(so, SimulatorConfigState):
                self.__state = so
                cmd = self.__maps_option['command']
                try:
                    self.__maps_option.set(self.__map_keys.index(so.mp))
                    self.__algorithms_option.set(
                        self.__algorithm_keys.index(so.algo))
                    self.__animations_option.set(
                        self.__animation_keys.index(so.ani))
                    self.__update_position_entries()
                except:
                    msg = "Failed to load Simulator Config state:\n{}".format(
                        traceback.format_exc())
                    self.__services.debug.write(msg, DebugLevel.NONE)
                    break
                finally:
                    self.__maps_option['command'] = cmd
                return
        new_state = self.__state is None
        if new_state:
            self.__state = SimulatorConfigState(self.__services.state)
        self.__state.mp = self.__maps_option.get()
        self.__state.algo = self.__algorithms_option.get()
        self.__state.ani = self.__animations_option.get()
        self.__use_default_map_positions()
        if new_state:
            self.__services.state.add(self.__state)
        else:
            self.__services.state.save()

    def __entry_exit_callback(self, *discard) -> None:
        self.__entry_hovered = False

    def __entry_enter_callback(self, *discard) -> None:
        self.__entry_hovered = True

    def __entry_mouse_click_callback(self, *discard) -> None:
        if self.__entry_hovered:
            self.__window.focus()
        else:
            for e in self.__entries:
                e['focus'] = False

    def __get_map(self) -> Map:
        name = self.__maps_option.get()
        data = self.__maps[name]

        if isinstance(data, str):
            data = self.__services.resources.maps_dir.load(data)
            self.__maps[name] = data

        assert isinstance(data, Map), "Map failed to load"
        return data

    def __update_simulator_callback(self) -> None:
        agent_mutable = (not self.__services.settings.get_agent_position)

        mp = self.__get_map()
        algo = self.__algorithms[self.__algorithms_option.get()]
        ani = self.__animations[self.__animations_option.get()]

        # update state
        self.__state.mp = self.__maps_option.get()
        self.__state.algo = self.__algorithms_option.get()
        self.__state.ani = self.__animations_option.get()

        def deduce_pos(default, entries) -> Point:
            nonlocal mp
            vs = []
            for i in range(default.n_dim):
                try:
                    vs.append(int(entries[i].get()))
                except:
                    vs.append(default[i])
            p = Point(*vs)
            return p if mp.is_agent_valid_pos(p) else default

        if agent_mutable:
            self.__state.agent = deduce_pos(mp.agent.position,
                                            self.__entries[:3])
        self.__state.goal = deduce_pos(mp.goal.position, self.__entries[3:])
        self.__update_position_entries(
        )  # update if user-provided point was invalid

        # save state
        self.__services.state.save()

        # launch simulation
        config = self.__services.settings
        config.algorithm_name = self.__algorithms_option.get()
        old_map_name = config.map_name
        config.map_name = self.__maps_option.get()

        refresh_map = (old_map_name != config.map_name) or \
                      (mp != config.simulator_initial_map) or \
                      (agent_mutable and self.__state.agent != mp.agent.position) or \
                      (self.__state.goal != mp.goal.position)

        if refresh_map:
            if agent_mutable:
                mp.move(mp.agent, self.__state.agent, True)
            mp.move(mp.goal, self.__state.goal, True)

        config.simulator_initial_map = mp
        config.simulator_algorithm_type, config.simulator_testing_type, config.simulator_algorithm_parameters = algo
        config.simulator_key_frame_speed, config.simulator_key_frame_skip = ani
        self.__services.reinit(refresh_map=refresh_map)

    def __reset_simulator_callback(self) -> None:
        self.__maps_option.set(self.__map_keys.index(self.__state.mp))
        self.__algorithms_option.set(
            self.__algorithm_keys.index(self.__state.algo))
        self.__animations_option.set(
            self.__animation_keys.index(self.__state.ani))
        self.__services.ev_manager.post(ResetEvent())

    def __use_default_map_positions(self, *discard) -> None:
        m = self.__get_map()

        self.__state.agent = m.agent.position
        self.__state.goal = m.goal.position
        self.__update_position_entries()

    def __update_position_entries(self) -> None:
        def update_entries(entries, pos, mutable=True):
            dim = pos.n_dim
            if not mutable:
                pos = ['-' for _ in range(dim)]

            entries[0].enterText(str(pos[0]))
            entries[1].enterText(str(pos[1]))
            if dim == 3:
                entries[2].enterText(str(pos[2]))
                entries[2].show()
            else:
                entries[2].hide()

        # agent may be externally set
        agent_mutable = (not self.__services.settings.get_agent_position)
        update_entries(self.__entries[:3],
                       self.__state.agent,
                       mutable=agent_mutable)
        update_entries(self.__entries[3:], self.__state.goal)

        if agent_mutable:
            self.__agent_disable_overlay.hide()
        else:
            self.__agent_disable_overlay.show()

        # user has performed an action such as pressing a
        # button, therefore all entries should lose focus
        for e in self.__entries:
            e['focus'] = False

    def notify(self, event: Event) -> None:
        if isinstance(event, ToggleSimulatorConfigEvent):
            self.__window.toggle_visible()

    def clear_text(self, i):
        self.__entries[i].enterText('')
Ejemplo n.º 10
0
class multiplayerGUI():
    def __init__(self, _mainmenu):
        # Ref
        self.mainmenu = _mainmenu

        # create a singlePlayer button
        self.menubtn0 = DirectButton(
            # Scale and position
            scale=0.10,
            pos=(0, 0, 0.5),
            # Text
            text="Host Game",
            # Frame
            # Functionality
            command='')

        # create a Lan button
        self.menubtn1 = DirectButton(
            # Scale and position
            scale=0.10,
            pos=(0, 0, 0.3),
            # Text
            text="Join Game",
            # Frame
            # Functionality
            command='')

        # create a Exit button
        self.menubtn3 = DirectButton(
            # Scale and position
            scale=0.10,
            pos=(0, 0, -0.1),
            # Text
            text="Back",
            # Frame
            # Functionality
            command=self.handleBack)

        self.hide()

    def show(self):
        self.menubtn0.show()
        self.menubtn1.show()
        self.menubtn3.show()

    def hide(self):
        self.menubtn0.hide()
        self.menubtn1.hide()
        self.menubtn3.hide()

    def handleHost(self):
        pass

    def handleJoin(self):
        # Move to Host / Join-Find games screen
        pass

    def handleOptions(self):
        pass

    def handleBack(self):
        self.hide()
        self.mainmenu.show()


# TESTING
#import direct.directbase.DirectStart
#gui = menuGUI()
#gui.show()
#base.run()
Ejemplo n.º 11
0
class QuestMap(DirectFrame):
    def __init__(self, av, **kw):
        DirectFrame.__init__(self, relief=None, sortOrder=50)
        self.initialiseoptions(QuestMap)
        self.container = DirectFrame(parent=self, relief=None)
        self.marker = DirectFrame(parent=self.container, relief=None)
        self.cogInfoFrame = DirectFrame(parent=self.container, relief=None)
        cm = CardMaker('bg')
        cm.setFrame(-0.5, 0.5, -0.5, 0.5)
        bg = self.cogInfoFrame.attachNewNode(cm.generate())
        bg.setTransparency(1)
        bg.setColor(0.5, 0.5, 0.5, 0.5)
        bg.setBin('fixed', 0)
        self.cogInfoFrame['geom'] = bg
        self.cogInfoFrame['geom_pos'] = (0, 0, 0)
        self.cogInfoFrame['geom_scale'] = (6, 1, 2)
        self.cogInfoFrame.setScale(0.05)
        self.cogInfoFrame.setPos(0, 0, 0.6)
        self.buildingMarkers = []
        self.av = av
        self.wantToggle = False
        if base.config.GetBool('want-toggle-quest-map', True):
            self.wantToggle = True
        self.updateMarker = True
        self.cornerPosInfo = None
        self.hqPosInfo = None
        self.fishingSpotInfo = None
        self.load()
        self.setScale(1.5)
        bg.removeNode()
        self.hoodId = None
        self.zoneId = None
        self.suitPercentage = {}
        for currHoodInfo in SuitPlannerBase.SuitPlannerBase.SuitHoodInfo:
            tracks = currHoodInfo[
                SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK]
            self.suitPercentage[currHoodInfo[
                SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks

        return

    def load(self):
        gui = loader.loadModel('phase_4/models/questmap/questmap_gui')
        icon = gui.find('**/tt_t_gui_qst_arrow')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setR(90)
        self.marker['geom'] = iconNP
        self.marker['image'] = iconNP
        self.marker.setScale(0.05)
        iconNP.removeNode()
        self.mapOpenButton = DirectButton(
            image=(gui.find('**/tt_t_gui_qst_mapClose'),
                   gui.find('**/tt_t_gui_qst_mapClose'),
                   gui.find('**/tt_t_gui_qst_mapTryToOpen')),
            relief=None,
            pos=(-0.084, 0, 0.37),
            parent=base.a2dBottomRight,
            scale=0.205,
            command=self.show)
        self.mapCloseButton = DirectButton(
            image=(gui.find('**/tt_t_gui_qst_mapOpen'),
                   gui.find('**/tt_t_gui_qst_mapOpen'),
                   gui.find('**/tt_t_gui_qst_mapTryToClose')),
            relief=None,
            pos=(-0.084, 0, 0.37),
            parent=base.a2dBottomRight,
            scale=0.205,
            command=self.hide)
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()
        gui.removeNode()
        icons = loader.loadModel('phase_3/models/gui/cog_icons')
        cIcon = icons.find('**/CorpIcon')
        lIcon = icons.find('**/LegalIcon')
        mIcon = icons.find('**/MoneyIcon')
        sIcon = icons.find('**/SalesIcon')
        cogInfoTextColor = (0.2, 0.2, 0.2, 1)
        textPos = (1.2, -0.2)
        textScale = 0.8
        self.cInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text='',
                                 text_fg=cogInfoTextColor,
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=cIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.cInfo.setPos(-2.2, 0, 0.5)
        self.lInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text_fg=cogInfoTextColor,
                                 text='',
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=lIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.lInfo.setPos(-2.2, 0, -0.5)
        self.mInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text_fg=cogInfoTextColor,
                                 text='',
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=mIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.mInfo.setPos(0.8, 0, 0.5)
        self.sInfo = DirectLabel(parent=self.cogInfoFrame,
                                 text_fg=cogInfoTextColor,
                                 text='',
                                 text_pos=textPos,
                                 text_scale=textScale,
                                 geom=sIcon,
                                 geom_pos=(-0.2, 0, 0),
                                 geom_scale=0.8,
                                 relief=None)
        self.sInfo.setPos(0.8, 0, -0.5)
        icons.removeNode()
        return

    def updateCogInfo(self):
        currPercentage = self.suitPercentage.get(self.zoneId)
        if currPercentage is None:
            return
        self.cInfo['text'] = '%s%%' % currPercentage[0]
        self.lInfo['text'] = '%s%%' % currPercentage[1]
        self.mInfo['text'] = '%s%%' % currPercentage[2]
        self.sInfo['text'] = '%s%%' % currPercentage[3]
        return

    def destroy(self):
        self.ignore('questPageUpdated')
        self.mapOpenButton.destroy()
        self.mapCloseButton.destroy()
        del self.mapOpenButton
        del self.mapCloseButton
        DirectFrame.destroy(self)

    def putBuildingMarker(self, pos, hpr=(0, 0, 0), mapIndex=None):
        marker = DirectLabel(parent=self.container,
                             text='',
                             text_pos=(-0.05, -0.15),
                             text_fg=(1, 1, 1, 1),
                             relief=None)
        gui = loader.loadModel(
            'phase_4/models/parties/schtickerbookHostingGUI')
        icon = gui.find('**/startPartyButton_inactive')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setX(-12.0792 / 30.48)
        icon.setZ(-9.7404 / 30.48)
        marker['text'] = '%s' % mapIndex
        marker['text_scale'] = 0.7
        marker['image'] = iconNP
        marker['image_color'] = (1, 0, 0, 1)
        marker['image_scale'] = 6
        marker.setScale(0.05)
        relX, relY = self.transformAvPos(pos)
        marker.setPos(relX, 0, relY)
        self.buildingMarkers.append(marker)
        iconNP.removeNode()
        gui.removeNode()
        return

    def updateQuestInfo(self):
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []
        dnaStore = base.cr.playGame.dnaStore
        for questIndex in self.av.questPage.quests.keys():
            questDesc = self.av.questPage.quests.get(questIndex)
            if questDesc is None:
                continue
            mapIndex = questIndex + 1
            questId, fromNpcId, toNpcId, rewardId, toonProgress = questDesc
            quest = Quests.getQuest(questId)
            fComplete = quest.getCompletionStatus(self.av,
                                                  questDesc) == Quests.COMPLETE
            if not fComplete:
                if quest.getType() == Quests.RecoverItemQuest:
                    if quest.getHolder() == Quests.AnyFish:
                        self.putBuildingMarker(self.fishingSpotInfo,
                                               mapIndex=mapIndex)
                    continue
                elif quest.getType(
                ) != Quests.DeliverGagQuest and quest.getType(
                ) != Quests.DeliverItemQuest and quest.getType(
                ) != Quests.VisitQuest and quest.getType(
                ) != Quests.TrackChoiceQuest:
                    continue
            if toNpcId == Quests.ToonHQ:
                self.putBuildingMarker(self.hqPosInfo, mapIndex=mapIndex)
            else:
                npcZone = NPCToons.getNPCZone(toNpcId)
                hoodId = ZoneUtil.getCanonicalHoodId(npcZone)
                branchId = ZoneUtil.getCanonicalBranchZone(npcZone)
                if self.hoodId == hoodId and self.zoneId == branchId:
                    for blockIndex in xrange(dnaStore.getNumBlockTitles()):
                        blockNumber = dnaStore.getTitleBlockAt(blockIndex)
                        zone = dnaStore.getZoneFromBlockNumber(blockNumber)
                        branchZone = zone - zone % 100
                        finalZone = branchZone + 500 + blockNumber
                        buildingType = dnaStore.getBlockBuildingType(
                            blockNumber)
                        if npcZone == finalZone:
                            self.putBuildingMarker(
                                dnaStore.getDoorPosHprFromBlockNumber(
                                    blockNumber).getPos(),
                                dnaStore.getDoorPosHprFromBlockNumber(
                                    blockNumber).getHpr(),
                                mapIndex=mapIndex)

        return

    def transformAvPos(self, pos):
        if self.cornerPosInfo is None:
            return (0, 0)
        topRight = self.cornerPosInfo[0]
        bottomLeft = self.cornerPosInfo[1]
        relativeX = (pos.getX() - bottomLeft.getX()) / (
            topRight.getX() - bottomLeft.getX()) - 0.5
        relativeY = (pos.getY() - bottomLeft.getY()) / (
            topRight.getY() - bottomLeft.getY()) - 0.5
        return (relativeX, relativeY)

    def update(self, task):
        if self.av:
            if self.updateMarker:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
        i = 0
        for buildingMarker in self.buildingMarkers:
            buildingMarker.setScale(
                (math.sin(task.time * 16.0 + i * math.pi / 3.0) + 1) * 0.005 +
                0.04)
            i = i + 1

        return Task.cont

    def updateMap(self):
        if self.av:
            try:
                hoodId = ZoneUtil.getCanonicalHoodId(self.av.getLocation()[1])
                zoneId = ZoneUtil.getCanonicalBranchZone(
                    self.av.getLocation()[1])
                mapsGeom = loader.loadModel('phase_4/models/questmap/%s_maps' %
                                            ToontownGlobals.dnaMap[hoodId])
                mapImage = mapsGeom.find(
                    '**/%s_%s_english' %
                    (ToontownGlobals.dnaMap[hoodId], zoneId))
                if not mapImage.isEmpty():
                    self.container['image'] = mapImage
                    self.resetFrameSize()
                    self.cornerPosInfo = QuestMapGlobals.CornerPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.hqPosInfo = QuestMapGlobals.HQPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.fishingSpotInfo = QuestMapGlobals.FishingSpotPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.cogInfoPos = QuestMapGlobals.CogInfoPosTable.get(
                        '%s_%s_english' %
                        (ToontownGlobals.dnaMap[hoodId], zoneId))
                    self.cogInfoFrame.setPos(self.cogInfoPos)
                    self.hide()
                    self.hoodId = hoodId
                    self.zoneId = zoneId
                    self.updateQuestInfo()
                    self.updateCogInfo()
                    taskMgr.add(self.update, 'questMapUpdate')
                else:
                    self.stop()
                mapsGeom.removeNode()
            except:
                self.stop()

    def start(self):
        self.container.show()
        self.accept('questPageUpdated', self.updateMap)
        self.handleMarker()
        self.updateMap()

    def initMarker(self, task):
        if self.av:
            if not hasattr(base.cr.playGame.getPlace(), 'isInterior'
                           ) or not base.cr.playGame.getPlace().isInterior:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
            self.marker['geom_scale'] = 1.4 * task.time % 0.5 * 10 + 1
            self.marker['geom_color'] = (1, 1, 1, 0.8 -
                                         1.4 * task.time % 0.5 * 2 / 0.8 + 0.2)
        if task.time < 1:
            return Task.cont
        else:
            self.marker['geom_color'] = (1, 1, 1, 0)
            return Task.done

    def show(self):
        taskMgr.add(self.initMarker, 'questMapInit')
        DirectFrame.show(self)
        self.mapOpenButton.hide()
        if self.container['image']:
            self.mapCloseButton.show()

    def hide(self):
        taskMgr.remove('questMapInit')
        DirectFrame.hide(self)
        if self.container['image']:
            self.mapOpenButton.show()
        self.mapCloseButton.hide()

    def toggle(self):
        if self.isHidden():
            self.show()
        else:
            self.hide()

    def obscureButton(self):
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()

    def stop(self):
        self.container['image'] = None
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []
        self.container.hide()
        self.hide()
        self.obscureButton()
        self.ignore('questPageUpdated')
        taskMgr.remove('questMapUpdate')
        return

    def handleMarker(self):
        if hasattr(base.cr.playGame.getPlace(),
                   'isInterior') and base.cr.playGame.getPlace().isInterior:
            self.updateMarker = False
        else:
            self.updateMarker = True

    def acceptOnscreenHooks(self):
        if self.wantToggle:
            self.accept(ToontownGlobals.MapHotkey, self.toggle)
        else:
            self.accept(ToontownGlobals.MapHotkeyOn, self.show)
            self.accept(ToontownGlobals.MapHotkeyOff, self.hide)
        self.updateMap()

    def ignoreOnscreenHooks(self):
        self.ignore(ToontownGlobals.MapHotkey)
        self.ignore(ToontownGlobals.MapHotkeyOn)
        self.ignore(ToontownGlobals.MapHotkeyOff)
        self.obscureButton()
Ejemplo n.º 12
0
class ShopWindow(OnscreenImage):

    def __init__(self, shop, image):
        OnscreenImage.__init__(self, image = image, scale = (0.9, 1, 0.7))
        self.shop = shop
        self.title = None
        self.okBtn = None
        self.clBtn = None
        self.infoLbl = None
        self.nPage = -1
        self.nPages = 0
        self.nextPage = 1
        self.prevPage = 0
        self.pages = []
        self.isSetup = False

    def setup(self, title = 'CHOOSE WHAT YOU WANT TO BUY'):
        font = CIGlobals.getMickeyFont()
        txtFg = (0, 0, 0, 1)
        txtScale = 0.05
        txtPos = (0, -0.1)
        buttons = loader.loadModel('phase_3.5/models/gui/QT_buttons.bam')
        self.title = DirectLabel(text = title, relief = None, pos = (0, 0, 0.5), text_wordwrap = 10, text_font = font,
                                 text_fg = (1, 1, 0, 1), scale = 0.1, parent = self)
        self.infoLbl = DirectLabel(text = 'Welcome!', relief = None, text_scale = 0.075, text_fg = txtFg, text_shadow = (0, 0, 0, 1),
                                   pos = (0, 0, 0.225))
        self.okBtn = DirectButton(geom = CIGlobals.getOkayBtnGeom(), relief = None, text = 'OK', text_fg = txtFg,
                                  text_scale = txtScale, text_pos = txtPos, pos = (-0.1, 0, -0.5), parent = self)
        self.clBtn = DirectButton(geom = CIGlobals.getCancelBtnGeom(), relief = None, text = 'Cancel', text_fg = txtFg,
                                  text_scale = txtScale, text_pos = txtPos, pos = (0.1, 0, -0.5), parent = self)
        buttonGeom = (buttons.find('**/QT_back'), buttons.find('**/QT_back'), buttons.find('**/QT_back'), buttons.find('**/QT_back'))
        self.backBtn = DirectButton(geom = buttonGeom, relief = None, scale = 0.05, pos = (-0.3, 0, -0.25), parent = self, command = self.setPage, extraArgs = [self.prevPage])
        self.nextBtn = DirectButton(geom = buttonGeom, relief = None, scale = 0.05, pos = (0.3, 0, -0.25), hpr = (0, 0, 180), command = self.setPage, extraArgs = [self.nextPage], parent = self)
        self.hideInfo()

    def makePages(self, items):
        if self.isSetup: return
        self.nPages = int(math.ceil((len(items) / 4)))
        print "%s pages are needed." % (self.nPages)
        if len(items) % 4 != 0:
            self.nPages += 1
        itemPos = [(-0.45, 0, 0), (-0.15, 0, 0), (0.15, 0, 0), (0.45, 0, 0)]
        pageIndex = 0
        itemIndex = 0
        index = 1
        for _ in range(self.nPages):
            page = Page(self)
            self.pages.append(page)
        for item, values in items.iteritems():
            pos = itemPos[itemIndex]
            itemImage = values.get('image')
            page = self.pages[pageIndex]
            itemType = values.get('type')
            supply = 0
            maxSupply = 0
            if itemType == ItemType.GAG:
                button = DirectButton(
                        geom = (itemImage), scale = 1.3, pos = pos,
                        relief = None, parent = page,
                        command = self.shop.purchaseItem, extraArgs = [item]
                )
                supply = base.localAvatar.getBackpack().getSupply(item().getName())
                maxSupply = base.localAvatar.getBackpack().getMaxSupply(item().getName())
                buttonLabel = DirectLabel(
                        text = '%s/%s\n%s JBS' % (str(supply), str(maxSupply),
                        str(values.get('price'))), relief = None,
                        parent = button, text_scale = 0.05, pos = (0, 0, -0.11)
                )
            elif itemType == ItemType.UPGRADE:
                button = DirectButton(
                        image = (itemImage), scale = 0.15, pos = pos, relief = None,
                        parent = page, command = self.shop.purchaseItem,
                        extraArgs = [item]
                )
                button.setTransparency(TransparencyAttrib.MAlpha)
                upgradeID = values.get('upgradeID')
                supply = base.localAvatar.getPUInventory()[upgradeID]
                maxSupply = values.get('maxUpgrades')
                if upgradeID == 0 and base.localAvatar.getMyBattle().getTurretManager().myTurret:
                    supply = 1
                buttonLabel = DirectLabel(
                         text = '%s/%s\n%s JBS' % (str(supply), str(maxSupply),
                         str(values.get('price'))), relief = None,
                         parent = button, text_scale = 0.5, pos = (0, 0, -1.2)
                )
            elif itemType == ItemType.HEAL:
                label = '%s' % (item)
                if 'showTitle' in values:
                    label = '%s\n%s JBS' % (item, values.get('price'))
                button = DirectButton(
                          image = (itemImage), scale = 0.105, pos = pos,
                          relief = None, parent = page,
                          command = self.shop.purchaseItem, extraArgs = [item]
                )
                button.setTransparency(TransparencyAttrib.MAlpha)
                buttonLabel = DirectLabel(
                          text = label, relief = None, parent = button,
                          text_scale = 0.75, pos = (0, 0, -1.6)
                )
            page.addItemEntry(item, [button, buttonLabel])
            page.addItem({item : values})
            if index % 4 == 0:
                index = 1
                pageIndex += 1
                itemIndex = 0
            else:
                itemIndex = itemIndex + 1
                index += 1
        if self.nPages == 1:
            self.backBtn.hide()
            self.nextBtn.hide()
        for page in self.pages:
            page.hide()
            page.update()
        self.isSetup = True

    def updatePages(self):
        for page in self.pages:
            page.update()

    def setPage(self, page):
        if page < 0 or page > self.nPages: return
        if self.nPage != -1:
            self.pages[self.nPage].hide()
        if page == 0:
            self.backBtn.setColorScale(GRAYED_OUT_COLOR)
        if (page + 1) > self.nPages:
            self.nextBtn.setColorScale(GRAYED_OUT_COLOR)
        else:
            self.nextBtn.setColorScale(NORMAL_COLOR)
        if (page - 1) > -1:
            self.backBtn.setColorScale(NORMAL_COLOR)
        self.nPage = page
        self.prevPage = (page - 1)
        self.nextPage = (page + 1)
        self.pages[page].show()

    def setBackBtn(self, enabled):
        if self.backBtn:
            if not enabled:
                self.backBtn['frameColor'] = GRAYED_OUT_COLOR
                self.backBtn['state'] = DGG.DISABLED
            else:
                self.backBtn['frameColor'] = NORMAL_COLOR
                self.backBtn['state'] = DGG.NORMAL

    def setNextBtn(self, enabled):
        if self.nextBtn:
            if not enabled:
                self.nextBtn['frameColor'] = GRAYED_OUT_COLOR
                self.nextBtn['state'] = DGG.DISABLED
            else:
                self.nextBtn['frameColor'] = NORMAL_COLOR
                self.nextBtn['state'] = DGG.NORMAL

    def setOKCommand(self, command):
        if self.okBtn: self.okBtn['command'] = command

    def setCancelCommand(self, command):
        if self.clBtn: self.clBtn['command'] = command

    def showInfo(self, text, negative = 0, duration = -1):
        self.infoLbl.show()
        if negative:
            self.infoLbl['text_fg'] = (0.9, 0, 0, 1)
        else: self.infoLbl['text_fg'] = (0, 0, 0, 1)
        self.infoLbl['text'] = text
        if duration > -1: Sequence(Wait(duration), Func(self.hideInfo)).start()

    def hideInfo(self):
        if self.infoLbl: self.infoLbl.hide()

    def delete(self):
        elements = [self.title, self.okBtn, self.clBtn, self.infoLbl, self.backBtn, self.nextBtn]
        for element in elements:
            element.destroy()
        del elements
        for page in self.pages:
            page.destroy()
            self.pages.remove(page)
        self.title = None
        self.okBtn = None
        self.clBtn = None
        self.infoLbl = None
        self.backBtn = None
        self.nextBtn = None
        self.destroy()
Ejemplo n.º 13
0
class ControlSettingsScreenHelper(object):

    COLOUR_VALID = (1, 1, 1, 1)
    COLOUR_SELECTED = (0.75, 0.75, 1, 1)
    COLOUR_INVALID = (1, 0.75, 0.75, 1)

    def __init__(self, app, scene, parent):
        self.app = app
        self.scene = scene
        self.parent = parent
        self.keymap = self.app.keymap
        self.do = DirectObject()

        self.saveButton = None
        self.finishButton = None
        self.pendingChanges = False

        # The KeyboadMapping provides a dict of keys to actions: this member
        # does the opposite (provides a dict to actions to keys)
        self.keys = {}

        self.selectedAction = None
        self.inputLookup = {}
        self.layout = []

    def show(self):
        self.keys = dict((v, k) for k, v in self.keymap.actions.items())

        for column in self.layout:
            for category in column:
                for action in category:
                    if action in self.keys:
                        self.inputLookup[action]['text'] = self.keys[action]
                        self.inputLookup[action]['frameColor'] = self.COLOUR_VALID
                    else:
                        self.inputLookup[action]['frameColor'] = self.COLOUR_INVALID
                        self.keys[action] = None

    def setup(self, node):
        colours = self.app.theme.colours

        TEXT_PROPERTIES = {
            'parent': node,
            'text_scale': 0.038,
            'text_fg': colours.listboxButtons,
            'text_align': TextNode.A_right,
            'relief': None,
        }

        KEY_PROPERTIES = {
            'parent': node,
            'scale': 0.038,
            'frameColor': self.COLOUR_VALID,
            'frameSize': (-3.0, 3.0, -0.7, 0.7),
            'text_align': TextNode.A_center,
            'text_scale': 0.9,
            'text_pos': (0, -0.18),
            'relief': DGG.FLAT,
            'textMayChange': True,
            'command': self.actionSelected,
        }

        movement = [ACTION_JUMP, ACTION_DOWN, ACTION_LEFT, ACTION_RIGHT]
        menus = [ACTION_MAIN_MENU, ACTION_MORE_MENU]
        actions = [
            ACTION_UPGRADE_MENU, ACTION_USE_UPGRADE,
            ACTION_ABANDON_UPGRADE, ACTION_EDIT_PLAYER_INFO, ACTION_READY,
            ACTION_PAUSE_GAME, ACTION_EMOTE,
        ]
        misc = [ACTION_CHAT, ACTION_FOLLOW]
        upgrades = [
            upgradeClass.action for upgradeClass in sorted(
                allUpgrades, key=lambda upgradeClass: upgradeClass.order)]
        upgrades.append(ACTION_CLEAR_UPGRADE)

        display = [
            ACTION_LEADERBOARD_TOGGLE, ACTION_HUD_TOGGLE,
            ACTION_TERMINAL_TOGGLE]

        actionNames = {
            ACTION_ABANDON_UPGRADE: 'Abandon upgrade',
            ACTION_UPGRADE_MENU: 'Select upgrade',
            ACTION_USE_UPGRADE: 'Activate upgrade',
            ACTION_EDIT_PLAYER_INFO: 'Change nick / hat',
            ACTION_CHAT: 'Chat',
            ACTION_DOWN: 'Drop down',
            ACTION_EMOTE: 'Emote',
            ACTION_FOLLOW: 'Auto pan (replay)',
            ACTION_JUMP: 'Jump',
            ACTION_LEADERBOARD_TOGGLE: 'Show leaderboard',
            ACTION_LEFT: 'Move left',
            ACTION_MAIN_MENU: 'Main menu',
            ACTION_MORE_MENU: 'Advanced',
            ACTION_CLEAR_UPGRADE: 'Deselect upgrade',
            ACTION_READY: 'Toggle ready',
            ACTION_PAUSE_GAME: 'Pause/resume',
            ACTION_RIGHT: 'Move right',
            ACTION_HUD_TOGGLE: 'Toggle HUD',
            ACTION_TERMINAL_TOGGLE: 'Toggle terminal',
        }
        actionNames.update((upgradeClass.action, upgradeClass.name) for
                           upgradeClass in allUpgrades)

        # Organise the categories by column
        self.layout = [
            [movement, menus],
            [actions, display],
            [upgrades, misc],
        ]

        xPos = -0.68

        for column in self.layout:          # Each column
            yPos = 0.30
            for category in column:         # Each category
                for action in category:     # Each action
                    # Draw action name (eg. Respawn)
                    label = DirectLabel(
                        text=actionNames[action],
                        **TEXT_PROPERTIES
                    )
                    align(label, right=xPos, midZ=yPos)

                    # Create input box
                    box = DirectButton(
                        text='',
                        extraArgs=[action],
                        **KEY_PROPERTIES
                    )
                    align(box, left=xPos + 0.03, midZ=yPos)
                    self.inputLookup[action] = box

                    yPos -= 0.07  # Between items
                yPos -= 0.08      # Between categories
            xPos += 0.65          # Between columns

        BUTTON_PROPERTIES = {
            'scale': 0.04,
            'frameSize': (-5.0, 5.0, -1.0, 1.5),
            'parent': node,
        }

        self.restoreDefaultButton = DirectButton(
            text='Restore defaults',
            # scale=0.04,
            # parent=node,
            command=self.restoreDefaults,
            # text_align=TextNode.A_left,
            # pad=(0.5, 0.2)
            **BUTTON_PROPERTIES
        )
        align(self.restoreDefaultButton, midX=0, z=-0.63)

        self.saveButton = DirectButton(
            text='Save',
            command=self.save,
            **BUTTON_PROPERTIES
        )
        align(self.saveButton, left=-0.87, z=-0.63)
        self.saveButton.hide()

        self.finishButton = DirectButton(
            text='Back',
            command=self.cancelPressed,
            **BUTTON_PROPERTIES
        )
        align(self.finishButton, right=0.87, z=-0.63)

    def cancelPressed(self):
        self.deselectAction()
        if self.pendingChanges:
            self.keymap.reset()
            self.show()
            self.hideSaveButton()
        else:
            self.parent.showMainButtons()

    def save(self):
        self.keymap.apply()
        self.keymap.save()
        self.hideSaveButton()

    def showSaveButton(self):
        self.pendingChanges = True
        self.saveButton.show()
        self.finishButton['text'] = 'Cancel'

    def hideSaveButton(self):
        self.pendingChanges = False
        self.saveButton.hide()
        self.finishButton['text'] = 'Back'

    def restoreDefaults(self):
        self.deselectAction()
        self.keymap.revertToDefault()
        self.show()
        self.showSaveButton()

    def deselectAction(self):
        if self.selectedAction:
            self.inputLookup[self.selectedAction]['frameColor'] = self.COLOUR_VALID
        self.selectedAction = None
        self.do.ignoreAll()

    def actionSelected(self, action):
        self.deselectAction()
        self.selectedAction = action
        button = self.inputLookup[action]
        button['frameColor'] = self.COLOUR_SELECTED
        log.debug('Changing key for %s' % action)

        self.app.panda.buttonThrowers[0].node().setButtonDownEvent('button')
        self.do.accept('button', self.keyPressed, [action])

    def keyPressed(self, action, key):
        self.deselectAction()

        oldKey = self.keys[action]

        if oldKey == key:
            return

        # Remove the old key from the keymap
        if oldKey is not None:
            del self.keymap.actions[oldKey]

        self.inputLookup[action]['text'] = key

        # If there's a conflict, remove the conflicting action from the keymap
        if key in self.keymap.actions:
            secondAction = self.keymap.actions[key]
            log.debug('Overwriting conflicting key for %s' % secondAction)

            self.inputLookup[secondAction]['text'] = ''
            self.inputLookup[secondAction]['frameColor'] = self.COLOUR_INVALID
            self.keys[secondAction] = None

        # Update the keymap with the new key
        self.keys[action] = key
        self.keymap.actions[key] = action
        log.debug('New key for %s is %s' % (action, key))

        self.showSaveButton()
Ejemplo n.º 14
0
class Lobby(DirectObject):
    def __init__(self, main):
        DirectObject.__init__(self)

        self.showbase = main

        self.status = OnscreenText(text="",
                                   pos=Vec3(0, -0.35, 0),
                                   scale=0.05,
                                   fg=(1, 0, 0, 1),
                                   align=TextNode.ACenter,
                                   mayChange=True)

        self.background = DirectFrame(
            frameSize=(-1, 1, -1, 1),
            frameTexture='media/gui/mainmenu/menu.png',
            parent=self.showbase.render2d,
        )

        self.title = OnscreenText(text='Main Menu',
                                  fg=(1, 1, 1, 1),
                                  parent=self.background,
                                  pos=(-0.6, 0.1),
                                  scale=0.06)

        self.buttons = []
        controlButtons = Vec3(-0.60, 0, -0.79)
        # Toggle ready
        p = controlButtons + Vec3(-0.25, 0, 0)
        self.toggleReadyButton = DirectButton(
            text='Ready/Unready',
            pos=p,
            scale=0.048,
            relief=DGG.GROOVE,
            command=self.toggleReady,
        )

        self.ready = False

        self.showbase.users = []

    def updateLobby(self, task):
        temp = self.showbase.client.getData()
        for package in temp:
            if len(package) == 2:
                print 'Received: ', str(package)
                if package[0] == 'reset':
                    self.showbase.users = []
                    print 'cleared users'
                elif package[0] == 'client':
                    self.showbase.users.append(User(package[1]))
                    for user in self.showbase.users:
                        print user.name, user.ready
                    print 'all users'
                elif package[0] == 'ready':
                    for user in self.showbase.users:
                        if user.name == package[1][0]:
                            user.ready = package[1][1]
                    for user in self.showbase.users:
                        print user.name, user.ready
                    print 'all users'
                elif package[0] == 'disconnect':
                    for user in self.showbase.users:
                        if user.name == package[1]:
                            self.showbase.users.remove(user)
                    for user in self.showbase.users:
                        print user.name, user.ready
                    print 'all users'
                elif package[0] == 'gamedata':
                    self.showbase.gameData = GameData()
                    self.showbase.gameData.unpackageData(package[1])
                elif package[0] == 'state':
                    print 'state: ', package[1]
                    if package[1] == 'preround':
                        self.showbase.startRound()
                        return task.done
        return task.again

    def toggleReady(self):
        self.ready = not self.ready
        self.showbase.client.sendData(('ready', self.ready))

    def hide(self):
        self.background.hide()
        for b in self.buttons:
            b.hide()
        self.status.hide()
        self.toggleReadyButton.hide()

        self.showbase.taskMgr.remove('Update Lobby')

    def show(self):
        self.background.show()
        for b in self.buttons:
            b.show()
        self.status.show()
        self.toggleReadyButton.show()

        # Add the game loop procedure to the task manager.
        self.showbase.taskMgr.add(self.updateLobby, 'Update Lobby')
Ejemplo n.º 15
0
class DisplaySettingsScreenHelper(object):

    DISPLAY_MODE_OPTIONS = [WINDOWED, NO_BORDER, FULL_SCREEN]
    DETAIL_LEVEL_OPTIONS = OrderedDict([
        ('Ultra', 'full'),
        ('High', 'default'),
        ('Medium', 'low'),
        ('Low', 'shrunk'),
        ('Toaster', 'lowest')
    ])

    def __init__(self, app, scene, parent):
        self.app = app
        self.scene = scene
        self.settings = app.displaySettings
        self.parent = parent

        self.pendingChanges = False
        self.saveButton = None
        self.finishButton = None

        self.resolutionMenu = None
        self.displayModeMenu = None
        self.detailMenu = None
        self.showFPS = None

    def show(self):
        # Fetch the list of available resolutions.
        resolutions = set()
        displayInfo = self.app.panda.pipe.getDisplayInformation()
        for index in range(displayInfo.getTotalDisplayModes()):
            mode = displayInfo.getDisplayMode(index)
            resolutions.add((mode.width, mode.height))

        resolutions = ['%d x %d' % (r[0], r[1]) for r in sorted(resolutions)]

        currentSize = '%d x %d' % self.settings.size
        if currentSize not in resolutions:
            resolutions.append(currentSize)
        self.resolutionMenu['items'] = resolutions
        self.resolutionMenu['extraArgs'] = [currentSize]
        self.resolutionMenu.set(currentSize)

        self.displayModeMenu['extraArgs'] = [self.settings.displayMode]
        self.displayModeMenu.set(self.settings.displayMode)

        # This finds the key in the detail dict from the value
        d = self.DETAIL_LEVEL_OPTIONS
        currentDetail = list(d.keys())[list(d.values()).index(self.settings.detailLevel)]
        self.detailMenu['extraArgs'] = [currentDetail]
        self.detailMenu.set(currentDetail)

        self.showFPS['extraArgs'] = [self.settings.showTimings]
        self.showFPS['indicatorValue'] = self.settings.showTimings
        self.showFPS.setIndicatorValue()

    def setup(self, node):
        colours = self.app.theme.colours
        TEXT_PROPERTIES = {
            'parent': node,
            'text_scale': 0.08,
            'text_fg': colours.listboxButtons,
            'text_align': TextNode.A_left,
            'relief': None,
        }

        DROPDOWN_PROPERTIES = {
            'parent': node,
            'scale': 0.06,
            'textMayChange': True,
            'frameSize': (-0.5, 12, -0.7, 1.05),
            'command': self.optionChanged,
        }

        label = DirectLabel(
            text='Screen resolution',
            **TEXT_PROPERTIES
        )
        align(label, left=-0.85, midZ=0.25)

        self.resolutionMenu = DirectOptionMenu(
            # If there isn't at least one item by default, the text alignment
            # will be all messed up when adding the resolutions.
            items=[''],
            **DROPDOWN_PROPERTIES
        )
        align(self.resolutionMenu, left=0, midZ=0.25)

        label = DirectLabel(
            text='Display mode',
            **TEXT_PROPERTIES
        )
        align(label, left=-0.85, midZ=0.10)

        self.displayModeMenu = DirectOptionMenu(
            items=self.DISPLAY_MODE_OPTIONS,
            **DROPDOWN_PROPERTIES
        )
        align(self.displayModeMenu, left=0, midZ=0.10)

        label = DirectLabel(
            text='Detail level',
            **TEXT_PROPERTIES
        )
        align(label, left=-0.85, midZ=-0.05)

        self.detailMenu = DirectOptionMenu(
            items=list(self.DETAIL_LEVEL_OPTIONS.keys()),
            **DROPDOWN_PROPERTIES
        )
        align(self.detailMenu, left=0, midZ=-0.05)

        label = DirectLabel(
            text='Show FPS',
            **TEXT_PROPERTIES
        )
        align(label, left=-0.85, midZ=-0.20)

        self.showFPS = DirectCheckButton(
            scale=0.06,
            parent=node,
            pos=(0, 0, -0.20),
            command=self.optionChanged
        )
        align(self.showFPS, left=0, midZ=-0.20)

        BUTTON_PROPERTIES = {
            'scale': 0.04,
            'frameSize': (-5.0, 5.0, -1.0, 1.5),
            'parent': node,
        }

        self.saveButton = DirectButton(
            text='Save',
            command=self.saveSettings,
            **BUTTON_PROPERTIES
        )
        align(self.saveButton, left=-0.87, z=-0.63)
        self.saveButton.hide()

        self.finishButton = DirectButton(
            text='Back',
            command=self.cancelPressed,
            **BUTTON_PROPERTIES
        )
        align(self.finishButton, right=0.87, z=-0.63)

    def saveSettings(self):
        resolution = self.resolutionMenu.get()
        width, height = resolution.split(' x ')

        s = self.settings
        s.size = (int(width), int(height))
        s.displayMode = self.displayModeMenu.get()
        s.detailLevel = self.DETAIL_LEVEL_OPTIONS[self.detailMenu.get()]
        s.showTimings = self.showFPS['indicatorValue']
        s.apply()
        s.save()

        self.show()
        self.hideSaveButton()

    def showSaveButton(self):
        self.pendingChanges = True
        self.saveButton.show()
        self.finishButton['text'] = 'Cancel'

    def hideSaveButton(self):
        self.pendingChanges = False
        self.saveButton.hide()
        self.finishButton['text'] = 'Back'

    def optionChanged(self, newValue, initialValue):
        log.debug(newValue)
        if newValue != initialValue:
            self.showSaveButton()

    def cancelPressed(self):
        if self.pendingChanges:
            self.show()
            self.hideSaveButton()
        else:
            self.parent.showMainButtons()
Ejemplo n.º 16
0
class CalendarGuiMonth(DirectFrame):
    """A class to represent the gui for one month.
    Do not put references to the shtiker page or book,  so this
    class may be extended later."""

    notify = directNotify.newCategory("CalendarGuiMonth")

    def __init__(self,
                 parent,
                 startingDateTime,
                 scale=1.0,
                 pos=(0, 0, -0.1),
                 dayClickCallback=None,
                 onlyFutureDaysClickable=False):
        """Construct ourself."""
        self.startDate = startingDateTime
        self.curDate = startingDateTime
        self.dayClickCallback = dayClickCallback
        self.onlyFutureDaysClickable = onlyFutureDaysClickable
        # sticker book is shifted up by 0.1, so default pos counteracts that
        # as the gui was made assuming 0,0 is center of the screen
        DirectFrame.__init__(self, parent=parent, scale=scale, pos=pos)

        # for debugging, show red dots for locators
        self.showMarkers = base.config.GetBool('show-calendar-markers', 0)

        # WARNING debug only, remove this or else we leak
        # base.cgm = self

        # self.createDummyLocators()
        self.load()
        self.createGuiObjects()
        self.lastSelectedDate = None
        self.accept('clickedOnDay', self.clickedOnDay)

    def createDummyLocators(self):
        """Put some programming locators until we get the real art assets."""
        self.monthLocator = self.attachNewNode('monthLocator')
        self.monthLocator.setZ(0.6)

        self.weekDayLocators = []
        for i in range(7):
            self.weekDayLocators.append(
                self.attachNewNode('weekDayLocator-%d' % i))
            self.weekDayLocators[i].setZ(0.5)
            self.weekDayLocators[i].setX(i * (0.24) + -0.75)

        dayTopLeftX = -0.8
        dayTopLeftZ = 0.4
        self.dayLocators = []
        for row in range(6):
            oneWeek = []
            for col in range(7):
                newDayLoc = self.attachNewNode('dayLocator-row-%d-col-%d' %
                                               (row, col))
                newDayLoc.setX(col * 0.24 + dayTopLeftX)
                newDayLoc.setZ(row * -0.18 + dayTopLeftZ)
                oneWeek.append(newDayLoc)
            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.attachNewNode('monthLeft')
        self.monthLeftLocator.setPos(-0.3, 0, 0.65)

        self.monthRightLocator = self.attachNewNode('monthRight')
        self.monthRightLocator.setPos(0.3, 0, 0.65)

    def attachMarker(self, parent, scale=0.01, color=(1, 0, 0)):
        """Attach a marker to the parent to aid in visual debugging."""
        if self.showMarkers:
            marker = loader.loadModel("phase_3/models/misc/sphere")
            marker.reparentTo(parent)
            marker.setScale(scale)
            marker.setColor(*color)

    def load(self):
        """Load our assets, make sure we have correct locators."""
        monthAsset = loader.loadModel(
            'phase_4/models/parties/tt_m_gui_sbk_calendar')
        monthAsset.reparentTo(self)
        self.monthLocator = self.find('**/locator_month/locator_month')
        self.attachMarker(self.monthLocator)

        self.weekDayLocators = []
        for weekday in ('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'):
            weekDayLoc = self.find('**/loc_%s' % weekday)
            self.weekDayLocators.append(weekDayLoc)
            self.attachMarker(weekDayLoc)

        self.dayLocators = []
        for row in range(6):
            oneWeek = []
            for col in range(7):
                newDayLoc = self.find('**/loc_box_%s_%s' % (row, col))
                oneWeek.append(newDayLoc)
            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.find('**/locator_month_arrowL')
        self.monthRightLocator = self.find('**/locator_month_arrowR')

        self.filterLocator = self.find('**/locator_filter')
        self.filterLocatorArrowUp = self.find('**/locator_filter_arrowTop')
        self.filterLocatorArrowDown = self.find(
            '**/locator_filter_arrowBottom')

        self.yearLocator = self.attachNewNode("yearLocator")
        self.yearLocator.setPos(self.monthLocator, 0, 0, -0.03)

    def createGuiObjects(self):
        """Create the other gui objects in the month, assumes we have proper locators."""
        self.monthLabel = DirectLabel(
            parent=self.monthLocator,
            relief=None,
            text=TTLocalizer.Months[self.startDate.month],
            text_scale=0.075,
            text_font=ToontownGlobals.getMinnieFont(),
            text_fg=(40 / 255.0, 140 / 255.0, 246 / 255.0, 1.0),
        )
        self.yearLabel = DirectLabel(
            parent=self.yearLocator,
            relief=None,
            text=str(self.startDate.year),
            text_scale=0.03,
            text_font=ToontownGlobals.getMinnieFont(),
            #text_fg = (40/255.0, 140/255.0, 246/255.0, 1.0),
            text_fg=(140 / 255.0, 140 / 255.0, 246 / 255.0, 1.0),
        )

        self.weekdayLabels = []
        for posIndex in range(7):
            # Sunday is the usual first day of the week, but
            # self.startDate.weekDay() reports 0 for Monday
            adjustedNameIndex = (posIndex - 1) % 7
            self.weekdayLabels.append(
                DirectLabel(parent=self.weekDayLocators[posIndex],
                            relief=None,
                            text=TTLocalizer.DayNamesAbbrev[adjustedNameIndex],
                            text_font=ToontownGlobals.getInterfaceFont(),
                            text_fg=(255 / 255.0, 146 / 255.0, 113 / 255.0,
                                     1.0),
                            text_scale=0.05))
        self.createGuiDays()

        arrowUp = self.find("**/month_arrowR_up")
        arrowDown = self.find("**/month_arrowR_down")
        arrowHover = self.find("**/month_arrowR_hover")
        self.monthLeftArrow = DirectButton(
            parent=self.monthLeftLocator,
            relief=None,
            image=(
                arrowUp,
                arrowDown,
                arrowHover,
                arrowUp,
            ),
            # make the disabled color more transparent
            image3_color=Vec4(1, 1, 1, 0.5),
            scale=(-1.0, 1.0, 1.0),  # make the arrow point left
            #pos = (0.25, 0, buttonbase_ycoord - textRowHeight * 4),
            command=self.__doMonthLeft,
        )
        if self.onlyFutureDaysClickable:
            self.monthLeftArrow.hide()
        self.monthRightArrow = DirectButton(
            parent=self.monthRightLocator,
            relief=None,
            image=(
                arrowUp,
                arrowDown,
                arrowHover,
                arrowUp,
            ),
            # make the disabled color more transparent
            image3_color=Vec4(1, 1, 1, 0.5),
            #pos = (0.65, 0, buttonbase_ycoord - textRowHeight * 4),
            command=self.__doMonthRight,
        )

        def makeLabel(itemName, itemNum, *extraArgs):

            return DirectLabel(
                text=itemName,
                frameColor=(0, 0, 0, 0),
                #scale = 0.1,
                #relief = DGG.RAISED,
                #frameSize = (-3.5, 3.5, -0.2, 0.8),
                text_scale=0.04)

        gui = loader.loadModel(
            'phase_4/models/parties/tt_m_gui_sbk_calendar_box')
        arrowUp = gui.find("**/downScroll_up")
        arrowDown = gui.find("**/downScroll_down")
        arrowHover = gui.find("**/downScroll_hover")

        filterLocatorUpPos = self.filterLocatorArrowUp.getPos(
            self.filterLocator)
        filterLocatorDownPos = self.filterLocatorArrowDown.getPos(
            self.filterLocator)
        self.filterList = DirectScrolledList(
            parent=self.filterLocator,
            relief=None,
            pos=(0, 0, 0),  #(0.65, 0, 0.7),
            image=None,  #DGG.getDefaultDialogGeom(),
            text_scale=0.025,
            incButton_image=(
                arrowUp,
                arrowDown,
                arrowHover,
                arrowUp,
            ),
            incButton_relief=None,
            incButton_pos=filterLocatorDownPos,  #(0.0, 0.0, -0.035),
            # Make the disabled button fade out
            incButton_image3_color=Vec4(1, 1, 1, 0.2),
            incButtonCallback=self.filterChanged,
            # Same for the decrement button
            decButton_image=(
                arrowUp,
                arrowDown,
                arrowHover,
                arrowUp,
            ),
            decButton_relief=None,
            decButton_pos=filterLocatorUpPos,  #(0.0, 0.0, 0.07),
            decButton_scale=(1, 1, -1),
            # Make the disabled button fade out
            decButton_image3_color=Vec4(1, 1, 1, 0.2),
            decButtonCallback=self.filterChanged,
            # each item is a button with text on it
            numItemsVisible=1,
            itemMakeFunction=makeLabel,
            # note ordering is very important, should match ToontownGlobals
            items=[
                TTLocalizer.CalendarShowAll,
                TTLocalizer.CalendarShowOnlyHolidays,
                TTLocalizer.CalendarShowOnlyParties,
            ],
            # itemFrame is a DirectFrame
            itemFrame_frameSize=(-.2, .2, -.02, .05),
            itemFrame_frameColor=(0, 0, 0, 0),
        )
        gui.removeNode()

    def getTopLeftDate(self):
        """Return the top left date. Will probably be a date in the previous month."""
        # for the current month figure out how many days
        # we subtract to get to Sunday
        firstOfTheMonth = self.curDate.replace(day=1)
        daysAwayFromSunday = (firstOfTheMonth.weekday() - 6) % 7
        topLeftDate = firstOfTheMonth + timedelta(days=-daysAwayFromSunday)
        return topLeftDate

    def createGuiDays(self):
        """Create the day guis for the whole month."""
        topLeftDate = self.getTopLeftDate()
        curDate = topLeftDate
        self.guiDays = []
        for row in self.dayLocators:
            for oneLocator in row:
                self.guiDays.append(
                    CalendarGuiDay(oneLocator, curDate, self.curDate,
                                   self.dayClickCallback,
                                   self.onlyFutureDaysClickable))
                curDate += timedelta(days=1)

    def changeDateForGuiDays(self):
        """Change the date for all our gui days.

        This should be much faster then our current tearing down and loading up again.
        """
        topLeftDate = self.getTopLeftDate()
        guiDayDate = topLeftDate
        for guiDay in self.guiDays:
            guiDay.changeDate(self.curDate, guiDayDate)
            guiDayDate += timedelta(days=1)

    def changeMonth(self, monthChange):
        """Change the month we are displaying."""
        # monthChange should be able to handle bigger values now
        if monthChange != 0:
            # if it's March 1, make sure we dont skip February going back 31 days
            newMonth = self.curDate.month + monthChange
            newYear = self.curDate.year
            # make sure we have a valid month 1..12
            while newMonth > 12:
                newYear += 1
                newMonth -= 12
            while newMonth < 1:
                if newYear - 1 > 1899:
                    newMonth += 12
                    newYear -= 1
                else:
                    newMonth += 1
            self.curDate = datetime(newYear, newMonth, 1,
                                    self.curDate.time().hour,
                                    self.curDate.time().minute,
                                    self.curDate.time().second,
                                    self.curDate.time().microsecond,
                                    self.curDate.tzinfo)

        self.monthLabel['text'] = TTLocalizer.Months[self.curDate.month],
        self.yearLabel['text'] = str(self.curDate.year),
        startTime = globalClock.getRealTime()
        self.changeDateForGuiDays()
        endTime = globalClock.getRealTime()
        self.notify.debug('changeDate took %f seconds' % (endTime - startTime))
        # if we have a selected date, it probably changed box
        self.updateSelectedDate()
        if self.onlyFutureDaysClickable and (newMonth == self.startDate.month
                                             and newYear
                                             == self.startDate.year):
            self.monthLeftArrow.hide()

    def __doMonthLeft(self):
        """Handle left month arrrow being pressed."""
        self.changeMonth(-1)

    def __doMonthRight(self):
        """Handle right month arrow being pressed."""
        self.monthLeftArrow.show()
        self.changeMonth(1)

    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)

    def clickedOnDay(self, dayDate):
        """Handle one of our child day squares getting clicked on."""
        self.lastSelectedDate = dayDate
        self.updateSelectedDate()

    def updateSelectedDate(self):
        if self.lastSelectedDate:
            for oneGuiDay in self.guiDays:
                if oneGuiDay.myDate.date() == self.lastSelectedDate:
                    oneGuiDay.updateSelected(True)
                else:
                    oneGuiDay.updateSelected(False)

    def clearSelectedDay(self):
        for oneGuiDay in self.guiDays:
            oneGuiDay.updateSelected(False)

    def filterChanged(self):
        """Refresh our days since the filter has changed."""
        newFilter = self.filterList.getSelectedIndex()
        for guiDay in self.guiDays:
            guiDay.changeFilter(newFilter)
Ejemplo n.º 17
0
class DMenuScreen(DirectObject):
    notify = directNotify.newCategory('DMenuScreen')

    def __init__(self):#, avatarList, parentFSM, doneEvent):
        DirectObject.__init__(self)
        base.disableMouse()
        #base.cr.avChoice = None
        fadeSequence = Sequence(
            Wait(.5),
            Func(base.transitions.fadeIn, .5),
            Wait(1)).start()#,
            #base.camera.posHprInterval(1, Point3(MAIN_POS), VBase3(MAIN_HPR), blendType = 'easeInOut')).start()
        #self.background = loader.loadModel('phase_4/models/neighborhoods/toontown_central_full')
        #self.background.reparentTo(render)
        #for frame in render.findAllMatches('*/doorFrame*'):
        #    frame.removeNode()
        #self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
        #SkyUtil.startCloudSky(self)

        #base.camera.setPosHpr(INIT_POS, INIT_HPR)
        self.background = OnscreenImage(image = DMenuResources.MenuBackground, parent = aspect2d)
        self.background.setBin('background', 1)
        self.background.reparentTo(aspect2d)
        self.background.setScale(2, 1, 1)
        
        self.logo = OnscreenImage(image = DMenuResources.GameLogo, scale = (1, 1, .5))
        self.logo.reparentTo(aspect2d)
        self.logo.setTransparency(TransparencyAttrib.MAlpha)
        scale = self.logo.getScale()
        self.logo.setPos(0, 0, .5)
        self.logo.setColorScale(Vec4(0, 0, 0, 0))

        #fadeInBackground = (LerpColorScaleInterval(self.background, 1, Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 0))).start()
        fadeInLogo = (LerpColorScaleInterval(self.logo, 1, Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 0))).start()

        self.createButtons()

        self.fadeOut = None
        self.optionsMgr = DMenuOptions.DMenuOptions()
        self.quitConfirmation = DMenuQuit.DMenuQuit()

        # TT: We need these to run the Pick A Toon screen
        #self.patAvList = avatarList
        #self.patFSM = parentFSM
        #self.patDoneEvent = doneEvent
        
        self.transcircle = Resources.transcircle
        self.transcircle.setTransparency(TransparencyAttrib.MAlpha)
        self.transcircle.setScale(VBase3(0.01, 0.01, 0.01))
        self.transcircle.setBin('background', 3)
        
        self.savemgr = LOTASaveMgr.LOTASaveMgr()
        
        # Get the save data
        self.savePos = self.savemgr.loadSaveData()
        
        self.titleMusic = Resources.titleMusic
        self.titleMusic.setLoop(1)
        self.setMusicNormal()

    def skyTrack(self, task):
    #    return SkyUtil.cloudSkyTrack(task)
        pass

    def createButtons(self):
        self.PlayButton = DirectButton(relief = None, text_style = 3, text_fg = (1, 1, 1, 1), text = DMenuLocalizer.PlayGame, text_scale = .1, scale = 0.95, command = self.playGame)
        self.PlayButton.reparentTo(aspect2d)
        self.PlayButton.setPos(PlayBtnHidePos)
        self.PlayButton.show()

        self.OptionsButton = DirectButton(relief = None, text_style = 3, text_fg = (1, 1, 1, 1), text = DMenuLocalizer.Options, text_scale = .1, scale = 0.95, command = self.openOptions)
        self.OptionsButton.reparentTo(aspect2d)
        self.OptionsButton.setPos(OptionsBtnHidePos)
        self.OptionsButton.show()

        self.QuitButton = DirectButton(relief = None, text_style = 3, text_fg = (1, 1, 1, 1), text = DMenuLocalizer.Quit, text_scale = .1, scale = 0.95, command = self.quitGame)
        self.QuitButton.reparentTo(aspect2d)
        self.QuitButton.setPos(QuitBtnHidePos)
        self.QuitButton.show()


        # self.BRButton = DirectButton(text = 'REPORT BUG', text_scale = .1, scale=0.95)
        # self.BRButton.reparentTo(aspect2d)
        # self.BRButton.setPos(-.9, 0, -.9)
        # self.BRButton.show()
        
        self.buttonInAnimation()
        
        # Slap on the saves menu from the old main menu until a proper implementation to DMENU is made
        self.SavesButton = DirectButton(relief = None, text = AmdLocalizerEnglish.LOTA_SAVES, image_scale = 2, text_scale = .1, scale = 0.95, command = self.openSavesMenu)
        self.SavesButton.reparentTo(aspect2d)
        self.SavesButton.setPos(0, 0, -.5)
        self.SavesButton.show()

    def murder(self):
        if self.logo is not None:
            self.logo.destroy()
            self.logo = None

        if self.background is not None:
            self.background.hide()
            self.background.reparentTo(hidden)
            self.background.removeNode()
            self.background = None

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

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

        if self.QuitButton is not None:
            self.QuitButton.destroy()
            self.QuitButton = None
            
        if self.SavesButton is not None:
            self.SavesButton.destroy()
            self.SavesButton = None
            
        if self.titleMusic is not None:
            self.titleMusic.stop()

        #taskMgr.remove('skyTrack')
        #self.sky.reparentTo(hidden)

    def openOptions(self):
        self.optionsMgr.showOptions()
        self.closeOptionsButton = DirectButton(relief = None, text = "< Back", text_fg = (0.977, 0.816, 0.133, 1), text_pos = (0, -0.035), scale = .1, command = self.hideOptions)
        self.closeOptionsButton.reparentTo(base.a2dTopLeft)
        self.closeOptionsButton.setPos(0.5, 0, -0.07)
        Parallel(
            self.PlayButton.posInterval(.5, Point3(PlayBtnHidePos), blendType = 'easeInOut'),
            self.OptionsButton.posInterval(.5, Point3(OptionsBtnHidePos), blendType = 'easeInOut'),
            self.QuitButton.posInterval(.5, Point3(QuitBtnHidePos), blendType = 'easeInOut'),
            self.logo.posInterval(0.5, Point3(0, 0, 2.5), blendType = 'easeInOut')).start()
        #base.camera.posHprInterval(0.5, Point3(HQ_POS), VBase3(HQ_HPR), blendType = 'easeInOut').start()
        #self.setMusicCalm()

    def hideOptions(self):
        self.optionsMgr.hideOptions()
        self.closeOptionsButton.hide()
        Parallel(
            self.PlayButton.posInterval(.5, Point3(PlayBtnPos), blendType = 'easeInOut'),
            self.OptionsButton.posInterval(.5, Point3(OptionsBtnPos), blendType = 'easeInOut'),
            self.QuitButton.posInterval(.5, Point3(QuitBtnPos), blendType = 'easeInOut'),
            self.logo.posInterval(.5, Point3(0, 0, .5), blendType = 'easeInOut')).start()
        base.camera.posHprInterval(0.5, Point3(MAIN_POS), VBase3(MAIN_HPR), blendType = 'easeInOut').start()
        #self.setMusicNormal()

    def playGame(self):
        if self.fadeOut is not None:
            self.fadeOut.finish()
            self.fadeOut = None
        self.fadeOut = base.transitions.getFadeOutIval(t = 1)
        #base.camera.posHprInterval(1, Point3(TOON_HALL_POS), VBase3(TOON_HALL_HPR), blendType = 'easeInOut').start()
        Sequence(
            Func(self.doPlayButton),
            #Func(self.fadeOut.start),
            Wait(1),
            Func(self.murder),
            Wait(1),
            Func(self.enterGame)).start()#,
            #Func(base.transitions.fadeIn, 1)).start()

    def enterOptions(self):
        pass

    def enterGame(self):
        #base.cr.avChoice = AvatarChooser.AvatarChooser(self.patAvList, self.patFSM, self.patDoneEvent)
        #base.cr.avChoice.load(1)
        #base.cr.avChoice.enter()
        from Game.NewGame.Scenes import SceneOne
        # Hamburger Menu Button
        #self.hbButton = DirectButton(image = "phase_3/maps/dmenu/dmhbmenu.png", relief = None, text = ' ', command=self.showHamburgerMenu)
        #self.hbButton.reparentTo(base.a2dTopLeft)
        #self.hbButton.setPos(0.05, 0, -0.05)
        #self.hbButton.setScale(0.04)

        # Hamburger Menu Hide Button
        #self.hbHideButton = DirectButton(image = "phase_3/maps/dmenu/close_window.png", relief = None, text = ' ', command=self.hideHamburgerMenu)
        #self.hbHideButton.reparentTo(base.a2dTopLeft)
        #self.hbHideButton.setPos(0.05, 0, -0.05)
        #self.hbHideButton.setScale(0.04)
        #self.hbHideButton.hide()

        # TODO: Add options and stuff to the hamburger menu

    def doPlayButton(self):
        Parallel(
            self.PlayButton.posInterval(1, Point3(PlayBtnHidePos), blendType = 'easeInOut'),
            self.OptionsButton.posInterval(1, Point3(OptionsBtnHidePos), blendType = 'easeInOut'),
            self.QuitButton.posInterval(1, Point3(QuitBtnHidePos), blendType = 'easeInOut'),
            self.logo.posInterval(0.5, Point3(0, 0, 2.5), blendType = 'easeInOut')).start()

    def quitGame(self):
        self.showQuitConfirmation()

    def showQuitConfirmation(self):
        self.quitConfirmation.showConfirmation()
        #base.exitFunc()

    def setMusicNormal(self):
        #LerpFunctionInterval(base.cr.music.setVolume, fromData = 0, toData = .9, duration = 1).start()
        #LerpFunctionInterval(base.cr.musicCalm.setVolume, fromData = .9, toData = 0, duration = 1).start()
        self.titleMusic.play()

    def setMusicCalm(self):
        LerpFunctionInterval(base.cr.music.setVolume, fromData = .9, toData = 0, duration = 1).start()
        LerpFunctionInterval(base.cr.musicCalm.setVolume, fromData = 0, toData = .9, duration = 1).start()

    def openSavesMenu(self):
        self.saveOne = DirectButton(relief=None, text = 'Save One: ' + '(Scene ' + str(self.savePos) + ')', scale=0.3, command=self.saveLoader, parent=aspect2d, pos=(0, 0, -.6), text_scale = .5)
        self.saveOne.hide()
        self.transcircle.show()
        self.exitLoadButton = DirectButton(relief=None, text = '< Back', scale=0.3, command=self.closeSavesMenu, parent=base.a2dBottomCenter, pos=(0, 0, -.4), text_scale = .5)
        self.exitLoadButton.show()

        
        self.openSavesMenuSequence = Parallel(
            self.transcircle.scaleInterval(0.5, VBase3(3, 3, 3), blendType = 'easeInOut'),
            self.exitLoadButton.posInterval(0.5, Point3(0, 0, .4), blendType = 'easeInOut'),
            Func(self.saveOne.show),
            self.saveOne.posInterval(0.5, Point3(0, 0, .2), blendType = 'easeInOut'))
        self.openSavesMenuSequence.start()
        
    def closeSavesMenu(self):
        self.hideThings = Sequence(
            Wait(0.5),
            Func(self.saveOne.hide),
            Func(self.transcircle.hide))
    
        self.closeSavesMenuSequence = Parallel(
            self.saveOne.posInterval(0.5, Point3(0, 0, -.6), blendType = 'easeInOut'),
            self.transcircle.scaleInterval(0.5, VBase3(0.01, 0.01, 0.01), blendType = 'easeInOut'),
            self.exitLoadButton.posInterval(0.5, Point3(0, 0, -.4), blendType = 'easeInOut'),
            Func(self.hideThings.start))
        self.closeSavesMenuSequence.start()
        self.exitLoadButton.removeNode()
        del self.exitLoadButton
        
    def saveLoader(self):
        # this was thrown together in like 10 seconds. how the f**k does this work
        # TODO: Make this save to a file thats not easily editable
        self.saveOne.hide()
        self.background.hide()
        self.transcircle.hide()
        if self.savePos == '1':
            from Game.NewGame.Scenes import SceneOne
        elif self.savePos == '2':
            from Game import SceneTwo
        elif self.savePos == '3':
            from Game import SceneThree
        elif self.savePos == '4':
            from Game import SceneFour
        elif self.savePos == '5':
            from Game import SceneFive
        else:
            print ("\n\n Save data is set to an unknown scene!!\n\n")
            
    def buttonInAnimation(self):
        logo = self.logo.posInterval(.5, Point3(0, 0, .5), blendType = 'easeInOut')
        play = self.PlayButton.posInterval(.5, Point3(PlayBtnPos), blendType = 'easeInOut')
        opt = self.OptionsButton.posInterval(.5, Point3(OptionsBtnPos), blendType = 'easeInOut')
        quit = self.QuitButton.posInterval(.5, Point3(QuitBtnPos), blendType = 'easeInOut')
        
        Sequence(
                 Func(logo.start),
                 Wait(0.1),
                 Func(play.start),
                 Wait(0.2),
                 Func(opt.start),
                 Wait(0.2),
                 Func(quit.start)).start()
                 
    def showHamburgerMenu(self):
        self.hbButton.hide()
        self.hbHideButton.show()
        
    def hideHamburgerMenu(self):
        self.hbButton.show()
        self.hbHideButton.hide()
Ejemplo n.º 18
0
class CharSelection:
    notify = directNotify.newCategory('CharSelection')
    STAGE_TOON_POS = (66.4, 74.47, -25)
    STAGE_TOON_HPR = (227.73, 0, 0)
    NO_TOON = 'Empty Slot'
    PLAY = 'Play'
    CREATE = 'Create'
    TITLE = 'Pick  A  Toon  To  Play'

    def __init__(self, avChooser):
        self.avChooser = avChooser
        self.choice = None
        self.charList = None
        self.charNameLabel = None
        self.charButtons = []
        self.playOrCreateButton = None
        self.deleteButton = None
        self.quitButton = None
        self.world = None
        self.sky = None
        self.fog = None
        self.title = None
        self.stageToon = None
        self.selectionFSM = ClassicFSM.ClassicFSM('CharSelection', [State.State('off', self.enterOff, self.exitOff), State.State('character', self.enterCharSelected, self.exitCharSelected), State.State('empty', self.enterEmptySelected, self.exitEmptySelected)], 'off', 'off')
        self.selectionFSM.enterInitialState()
        return

    def __setupStageToon(self):
        self.stageToon = Toon(base.cr)
        self.stageToon.setPos(self.STAGE_TOON_POS)
        self.stageToon.setHpr(self.STAGE_TOON_HPR)

    def cleanupStageToon(self):
        if self.stageToon != None:
            self.stageToon.disable()
            self.stageToon.delete()
            self.stageToon = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterCharSelected(self, slot):
        self.choice = self.avChooser.getAvChoiceBySlot(slot)
        dna = self.choice.dna
        name = self.choice.name
        self.stageToon.setName(name)
        self.stageToon.setDNAStrand(dna)
        self.stageToon.nameTag.setColorLocal()
        self.stageToon.animFSM.request('neutral')
        self.stageToon.reparentTo(base.render)
        self.charNameLabel.setText(name)
        self.playOrCreateButton['text'] = self.PLAY
        self.playOrCreateButton['extraArgs'] = ['play']
        self.playOrCreateButton.show()
        self.deleteButton.show()

    def exitCharSelected(self):
        self.stageToon.animFSM.requestFinalState()
        self.stageToon.deleteCurrentToon()
        self.stageToon.reparentTo(base.hidden)
        self.playOrCreateButton.hide()
        self.deleteButton.hide()
        self.choice = None
        return

    def enterEmptySelected(self):
        self.charNameLabel.setText(self.NO_TOON)
        self.playOrCreateButton['text'] = self.CREATE
        self.playOrCreateButton['extraArgs'] = ['create']
        self.playOrCreateButton.show()

    def exitEmptySelected(self):
        self.playOrCreateButton.hide()

    def __action(self, action):
        for btn in self.charButtons:
            if btn['state'] == DGG.DISABLED:
                self.slot = btn.getPythonTag('slot')
                break

        func = None
        arg = None
        if action == 'delete':
            func = self.deleteToon
            arg = self.choice.avId
        elif action == 'play':
            func = self.playGame
            arg = self.choice.slot
        elif action == 'create':
            func = self.enterMAT
        elif action == 'quit':
            func = sys.exit
        base.transitions.fadeOut(0.3)
        if arg != None:
            Sequence(Wait(0.31), Func(func, arg)).start()
        else:
            Sequence(Wait(0.31), Func(func)).start()
        return

    def playGame(self, slot):
        messenger.send('avChooseDone', [self.avChooser.getAvChoiceBySlot(slot)])

    def enterMAT(self):
        messenger.send('enterMakeAToon', [self.slot])

    def deleteToon(self, avId):
        self.avChooser.avChooseFSM.request('waitForToonDelResponse', [avId])

    def __handleCharButton(self, slot):
        for btn in self.charButtons:
            if btn.getPythonTag('slot') == slot:
                btn['state'] = DGG.DISABLED
            else:
                btn['state'] = DGG.NORMAL

        if self.avChooser.hasToonInSlot(slot):
            self.selectionFSM.request('character', [slot])
        else:
            self.selectionFSM.request('empty')

    def load(self):
        base.cr.renderFrame()
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4.0 / 3.0))
        self.__setupStageToon()
        self.world = loader.loadModel('phase_9/models/cogHQ/SellbotHQExterior.bam')
        self.world.reparentTo(base.render)
        self.world.setPos(0, 227.09, -25.36)
        self.sky = loader.loadModel('phase_9/models/cogHQ/cog_sky.bam')
        self.sky.setScale(1)
        self.sky.reparentTo(base.render)
        self.sky.find('**/InnerGroup').removeNode()
        self.fog = Fog('charSelectFog')
        self.fog.setColor(0.2, 0.2, 0.2)
        self.fog.setExpDensity(0.003)
        base.render.setFog(self.fog)
        self.title = DirectLabel(text=self.TITLE, text_font=CIGlobals.getMickeyFont(), text_fg=(1, 0.9, 0.1, 1), relief=None, text_scale=0.13, pos=(0, 0, 0.82))
        self.charNameLabel = OnscreenText(text='', font=CIGlobals.getMickeyFont(), pos=(-0.25, 0.5, 0), fg=(1, 0.9, 0.1, 1.0))
        self.charNameLabel.hide()
        self.playOrCreateButton = DirectButton(text='', pos=(0.8125, 0, -0.735), command=self.__action, geom=CIGlobals.getDefaultBtnGeom(), text_scale=0.06, relief=None, text_pos=(0, -0.01))
        self.playOrCreateButton.hide()
        self.deleteButton = DirectButton(text='Delete', pos=(0.8125, 0, -0.835), command=self.__action, extraArgs=['delete'], geom=CIGlobals.getDefaultBtnGeom(), text_scale=0.06, relief=None, text_pos=(0, -0.01))
        self.deleteButton.hide()
        self.quitButton = DirectButton(text='Quit', pos=(-1.1, 0, -0.925), command=self.__action, extraArgs=['quit'], text_scale=0.06, geom=CIGlobals.getDefaultBtnGeom(), relief=None, text_pos=(0, -0.01))
        textRolloverColor = Vec4(1, 1, 0, 1)
        textDownColor = Vec4(0.5, 0.9, 1, 1)
        textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
        for slot in range(6):
            if self.avChooser.hasToonInSlot(slot):
                choice = self.avChooser.getAvChoiceBySlot(slot)
                text = choice.name
            else:
                text = self.NO_TOON
            btn = DirectButton(relief=None, text=text, text_scale=0.06, text_align=TextNode.ALeft, text1_bg=textDownColor, text2_bg=textRolloverColor, text3_fg=textDisabledColor, textMayChange=0, command=self.__handleCharButton, extraArgs=[slot], text_pos=(0, 0, 0.0))
            btn.setPythonTag('slot', slot)
            self.charButtons.append(btn)
            btn['state'] = DGG.NORMAL

        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        listXorigin = -0.02
        listFrameSizeX = 0.625
        listZorigin = -0.96
        listFrameSizeZ = 1.04
        arrowButtonScale = 1.3
        itemFrameXorigin = -0.237
        itemFrameZorigin = 0.365
        buttonXstart = itemFrameXorigin + 0.293
        self.charList = DirectScrolledList(relief=None, pos=(0.75, 0, 0.08), incButton_image=(gui.find('**/FndsLst_ScrollUp'),
         gui.find('**/FndsLst_ScrollDN'),
         gui.find('**/FndsLst_ScrollUp_Rllvr'),
         gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_scale=(arrowButtonScale, arrowButtonScale, -arrowButtonScale), incButton_pos=(buttonXstart, 0, itemFrameZorigin - 0.999), incButton_image3_color=Vec4(1, 1, 1, 0.2), decButton_image=(gui.find('**/FndsLst_ScrollUp'),
         gui.find('**/FndsLst_ScrollDN'),
         gui.find('**/FndsLst_ScrollUp_Rllvr'),
         gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_scale=(arrowButtonScale, arrowButtonScale, arrowButtonScale), decButton_pos=(buttonXstart, 0, itemFrameZorigin + 0.125), decButton_image3_color=Vec4(1, 1, 1, 0.2), itemFrame_pos=(itemFrameXorigin, 0, itemFrameZorigin), itemFrame_scale=1.0, itemFrame_relief=DGG.SUNKEN, itemFrame_frameSize=(listXorigin,
         listXorigin + listFrameSizeX,
         listZorigin,
         listZorigin + listFrameSizeZ), itemFrame_frameColor=(0.85, 0.95, 1, 1), itemFrame_borderWidth=(0.01, 0.01), numItemsVisible=15, forceHeight=0.075, items=self.charButtons)
        base.camera.setPos(75.12, 63.22, -23)
        base.camera.setHpr(26.57, 9.62, 0)
        return

    def unload(self):
        self.selectionFSM.requestFinalState()
        self.cleanupStageToon()
        self.choice = None
        if self.charButtons:
            for btn in self.charButtons:
                btn.destroy()

            self.charButtons = None
        if self.charList:
            self.charList.destroy()
            self.charList = None
        if self.charNameLabel:
            self.charNameLabel.destroy()
            self.charNameLabel = None
        if self.playOrCreateButton:
            self.playOrCreateButton.destroy()
            self.playOrCreateButton = None
        if self.deleteButton:
            self.deleteButton.destroy()
            self.deleteButton = None
        if self.quitButton:
            self.quitButton.destroy()
            self.quitButton = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.world:
            self.world.removeNode()
            self.world = None
        if self.title:
            self.title.destroy()
            self.title = None
        base.render.clearFog()
        self.fog = None
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        base.transitions.noTransitions()
        del self.selectionFSM
        return
Ejemplo n.º 19
0
class GUI:
    def __init__(self, mainClass):
        self.unitFrame = DirectFrame(frameColor=(0, 0, 0, 0.5),
                                     frameSize=(-0.25, 0.25, -1, 1),
                                     pos=(0.8, 0, 0))
        self.unitFrame.reparentTo(render2d)
        self.unitFrame.hide()

        self.wallFrame = DirectFrame(frameColor=(0, 0, 0, 0.5),
                                     frameSize=(-0.25, 0.25, -1, 1),
                                     pos=(0.8, 0, 0))
        self.wallFrame.reparentTo(render2d)
        #	self.wallFrame.hide()

        #	self.drillWall = DirectButton(text = ('drill wall'), scale = 0.1, command = mainClass.cameraClass.mineWall, extraArgs = [mainClass])
        #	self.drillWall.reparentTo(self.wallFrame)
        #	self.drillWall.setPos(0,0,0.9)

        self.drillWall = DirectButton(text='Hi',
                                      scale=0.1,
                                      command=self.queueMine,
                                      extraArgs=[mainClass])
        #	self.drillWall.reparentTo(self.wallFrame)
        self.drillWall.setPos(0, 0, 0.5)
        self.drillWall.hide()

    def hi(self):
        print 'HIII'

    def showWall(self, wall, mainClass):
        if (wall.selectable == True):

            self.hideUIs()
            self.drillWall.show()

        #	if (wall.dig != None):
        #		self.

#		uButton1 = DirectButton(text = ('need'), scale = 0.1)
#		uButton1.reparentTo(self.unitFrame)
#		uButton1.setPos(0,0,0.9)
#
#		uButton2 = DirectButton(text = ('to'), scale = 0.1)
#		uButton2.reparentTo(self.unitFrame)
#		uButton2.setPos(0,0,0.7)
#
#		uButton3 = DirectButton(text = ('finish'), scale = 0.1)
#		uButton3.reparentTo(self.unitFrame)
#		uButton3.setPos(0,0,0.5)
#
#		uButton4 = DirectButton(text = ('GUI'), scale = 0.1)
#		uButton4.reparentTo(self.unitFrame)
#		uButton4.setPos(0,0,0.3)

    def unitGUI(self, mainClass, unitnumber):
        self.hideUIs()
        self.unitFrame.show()

    #	if (mainClass.parserClass.unit

    def wallGUI(self, mainClass, wallPos):
        pass

    #	self.unitFrame.hide()
    #	self.wallFrame.show()
    #	if (mainClass.mapLoaderClass.tileArray[wallPos[1]][wallPos[0]].drillTime != None):
    #		self.drillWall.show()

    def hideUIs(self):
        self.unitFrame.hide()

    def queueMine(self, mainClass):
        #	mainClass.cameraClass.clearSelection(mainClass)
        mainClass.priorities.queueMine(mainClass.mouseClass.tileSelected)
Ejemplo n.º 20
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 = list(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 ShopWindow(DirectFrame):
    def __init__(self, shop, image, wantTurretCount):
        DirectFrame.__init__(self)
        self.shop = shop
        self.wantTurretCount = wantTurretCount
        self.bgImage = image
        self.title = None
        self.okBtn = None
        self.clBtn = None
        self.infoLbl = None
        self.turretLabel = None
        self.turretImg = None
        self.nPage = -1
        self.nPages = 0
        self.nextPage = 0
        self.prevPage = -1
        self.pages = []
        self.isSetup = False
        self.turretCount = 0

    def setup(self, title='CHOOSE WHAT YOU WANT TO BUY'):
        font = CIGlobals.getMickeyFont()
        txtFg = (0, 0, 0, 1)
        txtScale = 0.05
        txtPos = (0, -0.1)
        buttons = loader.loadModel('phase_3.5/models/gui/QT_buttons.bam')
        self.window = OnscreenImage(image=self.bgImage,
                                    scale=(0.9, 1, 0.7),
                                    parent=self)
        self.title = DirectLabel(text=title,
                                 relief=None,
                                 pos=(0, 0, 0.5),
                                 text_wordwrap=10,
                                 text_font=font,
                                 text_fg=(1, 1, 0, 1),
                                 scale=0.1,
                                 parent=self)

        # Let's update the turret count.
        self.updateTurretCount()

        self.infoLbl = DirectLabel(text='Welcome!',
                                   relief=None,
                                   text_scale=0.075,
                                   text_fg=txtFg,
                                   text_shadow=(0, 0, 0, 0),
                                   pos=(0, 0, 0.215))
        self.okBtn = DirectButton(geom=CIGlobals.getOkayBtnGeom(),
                                  relief=None,
                                  text='OK',
                                  text_fg=txtFg,
                                  text_scale=txtScale,
                                  text_pos=txtPos,
                                  pos=(-0.1, 0, -0.5),
                                  parent=self)
        self.clBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(),
                                  relief=None,
                                  text='Cancel',
                                  text_fg=txtFg,
                                  text_scale=txtScale,
                                  text_pos=txtPos,
                                  pos=(0.1, 0, -0.5),
                                  parent=self)
        buttonGeom = (buttons.find('**/QT_back'), buttons.find('**/QT_back'),
                      buttons.find('**/QT_back'), buttons.find('**/QT_back'))
        self.backBtn = DirectButton(geom=buttonGeom,
                                    relief=None,
                                    scale=0.05,
                                    pos=(-0.3, 0, -0.25),
                                    parent=self,
                                    command=self.changePage,
                                    extraArgs=[0])
        self.nextBtn = DirectButton(geom=buttonGeom,
                                    relief=None,
                                    scale=0.05,
                                    pos=(0.3, 0, -0.25),
                                    hpr=(0, 0, 180),
                                    command=self.changePage,
                                    extraArgs=[1],
                                    parent=self)
        self.hideInfo()

    def setTurrets(self, amount):
        if self.shop.upgradesPurchased:
            amount += 1
        self.turretCount = amount
        self.updatePages()

    def updateTurretCount(self):
        if self.turretLabel:
            self.turretLabel.destroy()

        if self.wantTurretCount:
            maxTurrets = CogBattleGlobals.MAX_TURRETS

            if not self.turretImg:
                self.turretImg = OnscreenImage(
                    image="phase_3.5/maps/cannon-icon.png",
                    scale=(0.05, 1, 0.05),
                    pos=(-0.22, 0, 0.275))
                self.turretImg.setTransparency(TransparencyAttrib.MAlpha)

            self.turretLabel = DirectLabel(
                text='Turrets: %s/%s' %
                (str(self.turretCount), str(maxTurrets)),
                relief=None,
                text_scale=0.07,
                text_fg=(0, 0, 0, 1),
                text_shadow=(0, 0, 0, 0),
                pos=(0, 0, 0.265))

    def changePage(self, direction):
        var = self.prevPage
        if direction == 1:
            var = self.nextPage
        self.setPage(var)

    def __makeGagEntry(self, pos, item, values, page):
        itemImage = values.get('image')
        button = DirectButton(geom=(itemImage),
                              scale=1.3,
                              pos=pos,
                              relief=None,
                              parent=page,
                              command=self.shop.purchaseItem,
                              extraArgs=[item, page])
        supply = base.localAvatar.getBackpack().getSupply(item().getName())
        maxSupply = base.localAvatar.getBackpack().getMaxSupply(
            item().getName())
        buttonLabel = DirectLabel(
            text='%s/%s\n%s JBS' %
            (str(supply), str(maxSupply), str(values.get('price'))),
            relief=None,
            parent=button,
            text_scale=0.05,
            pos=(0, 0, -0.11))
        self.addEntryToPage(page, item, values, button, buttonLabel)

    def __makeUpgradeEntry(self, pos, item, values, page):
        itemImage = values.get('image')
        button = DirectButton(image=(itemImage),
                              scale=0.15,
                              pos=pos,
                              relief=None,
                              parent=page,
                              command=self.shop.purchaseItem,
                              extraArgs=[item, page])
        button.setTransparency(TransparencyAttrib.MAlpha)
        upgradeID = values.get('upgradeID')
        avID = base.localAvatar.getPUInventory()[1]
        supply = 0

        battle = base.localAvatar.getMyBattle()
        if battle and battle.getTurretManager():
            turret = battle.getTurretManager().getTurret()
            if turret and turret.getGagID() == upgradeID:
                supply = 1

        if avID == upgradeID:
            dataSupply = base.localAvatar.getPUInventory()[0]
            if dataSupply > 0:
                supply = dataSupply

        maxSupply = values.get('maxUpgrades')
        buttonLabel = DirectLabel(
            text='%s\n%s/%s\n%s JBS' %
            (item, str(supply), str(maxSupply), str(values.get('price'))),
            relief=None,
            parent=button,
            text_scale=0.3,
            pos=(0, 0, -1.2))
        self.addEntryToPage(page, item, values, button, buttonLabel)

    def __makeHealEntry(self, pos, item, values, page):
        label = '%s' % (item)
        itemImage = values.get('image')
        if 'showTitle' in values:
            label = '%s\n%s JBS' % (item, values.get('price'))
        button = DirectButton(image=(itemImage),
                              scale=0.105,
                              pos=pos,
                              relief=None,
                              parent=page,
                              command=self.shop.purchaseItem,
                              extraArgs=[item, page])
        button.setTransparency(TransparencyAttrib.MAlpha)
        buttonLabel = DirectLabel(text=label,
                                  relief=None,
                                  parent=button,
                                  text_scale=0.55,
                                  pos=(0, 0, -1.6))
        self.addEntryToPage(page, item, values, button, buttonLabel)

    def addEntryToPage(self, page, item, values, button, buttonLabel):
        page.addItemEntry(item, [button, buttonLabel])
        page.addItem({item: values})

    def makePages(self, items):
        newItems = dict(items)
        loadout = base.localAvatar.getBackpack().getLoadoutInIds()

        # Let's show the loadout gags first in a full shop.
        if self.shop.wantFullShop:
            crcGags = OrderedDict(newItems)
            for item, values in newItems.items():
                if values.get('type') == ItemType.GAG:
                    gag = item()
                    hasGag = base.localAvatar.getBackpack().hasGag(gag.getID())
                    if gag.getID() not in loadout or not hasGag:
                        del crcGags[item]
                        if not hasGag:
                            del newItems[item]
                    else:
                        del newItems[item]
            # Let's add back the other gags.
            crcGags.update(newItems)
            newItems = crcGags
            print len(newItems)
        else:
            for item, values in newItems.items():
                if values.get('type') == ItemType.GAG:
                    gag = item()
                    if gag.getID(
                    ) not in loadout or not base.localAvatar.getBackpack(
                    ).hasGag(gag.getID()):
                        del newItems[item]

        self.nPages = int(math.ceil((float(len(newItems)) / float(4))))
        if self.nPages % 4 != 0 and len(newItems) > 4:
            self.nPages += 1
        elif self.nPages == 0:
            self.nPages = 1
        itemPos = [(-0.45, 0, 0), (-0.15, 0, 0), (0.15, 0, 0), (0.45, 0, 0)]
        pageIndex = 0
        itemIndex = 0
        index = 0
        for _ in range(self.nPages):
            page = Page(self.shop, self)
            self.pages.append(page)
        for item, values in newItems.iteritems():
            pos = itemPos[itemIndex]
            page = self.pages[pageIndex]
            itemType = values.get('type')
            if itemType == ItemType.GAG:
                self.__makeGagEntry(pos, item, values, page)
            elif itemType == ItemType.UPGRADE:
                self.__makeUpgradeEntry(pos, item, values, page)
            elif itemType == ItemType.HEAL:
                self.__makeHealEntry(pos, item, values, page)
            if index == 3:
                pageIndex += 1
                itemIndex = 0
                index = 0
            else:
                itemIndex += 1
                index += 1
        if self.nPages == 1:
            self.backBtn.hide()
            self.nextBtn.hide()
        for page in self.pages:
            if len(page.getItems()) == 0:
                page.destroy()
                self.pages.remove(page)
            else:
                page.hide()
                page.update()
        self.nPages = len(self.pages)
        self.isSetup = True

    def updatePage(self, page):
        battle = base.localAvatar.getMyBattle()

        if battle and self.wantTurretCount:
            self.shop.distShop.sendUpdate('requestTurretCount', [])
            self.updateTurretCount()

        page.update()

    def updatePages(self):
        battle = base.localAvatar.getMyBattle()

        if battle and self.wantTurretCount:
            self.shop.distShop.sendUpdate('requestTurretCount', [])
            self.updateTurretCount()

        for page in self.pages:
            page.update()

    def setPage(self, page):
        if self.nPage > -1:
            self.pages[self.nPage].hide()
        self.setBackBtn(True)
        self.setNextBtn(True)
        if (page - 1) < 0:
            self.setBackBtn(False)
        elif (page + 1) == self.nPages:
            self.setNextBtn(False)
        if page < 0 or page > self.nPages: return
        self.prevPage = (page - 1)
        self.nextPage = (page + 1)
        self.nPage = page
        self.pages[page].show()

    def getPage(self, index):
        return self.pages[index]

    def setBackBtn(self, enabled):
        if self.backBtn:
            if enabled == False:
                self.backBtn.setColorScale(GRAYED_OUT_COLOR)
                self.backBtn['state'] = DGG.DISABLED
            else:
                self.backBtn.setColorScale(NORMAL_COLOR)
                self.backBtn['state'] = DGG.NORMAL

    def setNextBtn(self, enabled):
        if self.nextBtn:
            if enabled == False:
                self.nextBtn.setColorScale(GRAYED_OUT_COLOR)
                self.nextBtn['state'] = DGG.DISABLED
            else:
                self.nextBtn.setColorScale(NORMAL_COLOR)
                self.nextBtn['state'] = DGG.NORMAL

    def setOKCommand(self, command):
        if self.okBtn: self.okBtn['command'] = command

    def setCancelCommand(self, command):
        if self.clBtn: self.clBtn['command'] = command

    def showInfo(self, text, negative=0, duration=-1):
        self.infoLbl.show()
        if negative:
            self.infoLbl['text_fg'] = (0.9, 0, 0, 1)
            self.infoLbl['text_shadow'] = (0, 0, 0, 1)
        else:
            self.infoLbl['text_fg'] = (0, 0, 0, 1)
            self.infoLbl['text_shadow'] = (0, 0, 0, 0)
        self.infoLbl['text'] = text
        if duration > -1: Sequence(Wait(duration), Func(self.hideInfo)).start()

    def hideInfo(self):
        if self.infoLbl: self.infoLbl.hide()

    def delete(self):
        elements = [
            self.title, self.okBtn, self.clBtn, self.infoLbl, self.backBtn,
            self.nextBtn, self.turretLabel, self.turretImg
        ]
        for element in elements:
            if element:
                element.destroy()
        del elements
        for page in self.pages:
            page.destroy()
            self.pages.remove(page)
        self.title = None
        self.okBtn = None
        self.clBtn = None
        self.infoLbl = None
        self.backBtn = None
        self.nextBtn = None
        self.bgImage = None
        self.turretLabel = None
        self.turretCount = None
        if self.window:
            self.window.destroy()
            self.window = None
        self.destroy()
class GroupTrackerPlayer(DirectButton):
    def __init__(self, parent, avId, name, isLeader, **kw):
        self.avId = avId
        self.name = name
        self.isLeader = isLeader
        self.leaderImage = None
        
        if parent is None:
            parent = aspect2d

        text=self.getName()
        
        optiondefs = (
            ('text', text, None),
            ('text_fg', (0.0, 0.0, 0.0, 1.0), None),
            ('text_align', TextNode.ALeft, None),
            ('text_pos', (-0.2, 0.0, 0.0), None),
            ('relief', None, None),
            ('text_scale', 0.05, None),
            ('command', self.loadPlayerDetails, None)
        )

        self.defineoptions(kw, optiondefs)
        DirectButton.__init__(self, parent)
        self.initialiseoptions(GroupTrackerPlayer)
        
        boardingGroupIcons = loader.loadModel('phase_9/models/gui/tt_m_gui_brd_status')
        self.leaderButtonImage = boardingGroupIcons.find('**/tt_t_gui_brd_statusLeader')
        self.leaderImage = DirectButton(parent=self, relief=None, state=DGG.DISABLED, image=(self.leaderButtonImage), image_scale=(0.06, 1.0, 0.06), pos=(-0.26, 0, 0.02), command=None)
        
        self.setLeaderStatus(self.isLeader)
        boardingGroupIcons.removeNode()
    
    def destroy(self):
        if hasattr(self, 'playerCount'):
            if self.leaderImage:
                self.leaderImage.destroy()
                del self.leaderImage
        
        DirectButton.destroy(self)
    
    def setLeaderStatus(self, isLeader):
        self.isLeader = isLeader
        
        if self.isLeader:
            self.leaderImage.show()
        if not self.isLeader:
            self.leaderImage.hide()
    
    def getLeader(self):
        return self.isLeader
    
    def getName(self):
        # Lets cap a length so we dont have too long of names
        name = self.name
        if len(name) > 15:
            name = name[:16] + '...' # Chop the first x characters
        return name
    
    def getId(self):
        return self.avId
        
    def loadPlayerDetails(self):
        # TODO: Load player details based off avId for localAvatar
        pass
Ejemplo n.º 23
0
class DirectWindow(DirectFrame):
    def __init__(
        self,
        pos=(-.5, .5),
        title='Title',
        curSize=(1, 1),
        maxSize=(1, 1),
        minSize=(.5, .5),
        backgroundColor=(1, 1, 1, 1),
        borderColor=(1, 1, 1, 1),
        titleColor=(1, 1, 1, 1),
        borderSize=0.04,
        titleSize=0.06,
        closeButton=False,
        windowParent=aspect2d,
        preserve=True,
        preserveWhole=True,
    ):
        self.preserve = preserve
        self.preserveWhole = preserveWhole
        self.windowParent = windowParent
        self.windowPos = pos
        DirectFrame.__init__(
            self,
            parent=windowParent,
            pos=(self.windowPos[0], 0, self.windowPos[1]),
            frameColor=(0, 0, 0, 0),
            frameTexture=loader.loadTexture(DIRECTORY + 'transparent.png'))
        self.setTransparency(True)

        # the title part of the window, drag around to move the window
        self.headerHeight = titleSize
        h = -self.headerHeight
        self.windowHeaderLeft = DirectButton(
            parent=self,
            frameTexture=DEFAULT_TITLE_GEOM_LEFT,
            frameSize=(-.5, .5, -.5, .5),
            borderWidth=(0, 0),
            relief=DGG.FLAT,
            frameColor=titleColor,
        )
        self.windowHeaderCenter = DirectButton(
            parent=self,
            frameTexture=DEFAULT_TITLE_GEOM_CENTER,
            frameSize=(-.5, .5, -.5, .5),
            borderWidth=(0, 0),
            relief=DGG.FLAT,
            frameColor=titleColor,
        )
        if closeButton:
            rightTitleGeom = DEFAULT_TITLE_GEOM_RIGHT_CLOSE
            command = self.destroy
        else:
            rightTitleGeom = DEFAULT_TITLE_GEOM_RIGHT
            command = None
        self.windowHeaderRight = DirectButton(parent=self,
                                              frameTexture=rightTitleGeom,
                                              frameSize=(-.5, .5, -.5, .5),
                                              borderWidth=(0, 0),
                                              relief=DGG.FLAT,
                                              frameColor=titleColor,
                                              command=command)

        self.windowHeaderLeft.setTransparency(True)
        self.windowHeaderCenter.setTransparency(True)
        self.windowHeaderRight.setTransparency(True)

        self.windowHeaderLeft.bind(DGG.B1PRESS, self.startWindowDrag)
        self.windowHeaderCenter.bind(DGG.B1PRESS, self.startWindowDrag)
        self.windowHeaderRight.bind(DGG.B1PRESS, self.startWindowDrag)

        # this is not handled correctly, if a window is dragged which has been
        # created before another it will not be released
        # check the bugfixed startWindowDrag function
        #self.windowHeader.bind(DGG.B1RELEASE,self.stopWindowDrag)

        text = TextNode('WindowTitleTextNode')
        text.setText(title)
        text.setAlign(TextNode.ACenter)
        text.setTextColor(0, 0, 0, 1)
        text.setShadow(0.05, 0.05)
        text.setShadowColor(1, 1, 1, 1)
        self.textNodePath = self.attachNewNode(text)
        self.textNodePath.setScale(self.headerHeight * 0.8)

        # the content part of the window, put stuff beneath
        # contentWindow.getCanvas() to put it into it
        self.maxVirtualSize = maxSize
        self.minVirtualSize = minSize
        self.resizeSize = borderSize
        self.contentWindow = DirectScrolledFrame(
            parent=self,
            pos=(0, 0, -self.headerHeight),
            canvasSize=(0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1]),
            frameColor=(
                0, 0, 0,
                0),  # defines the background color of the resize-button
            relief=DGG.FLAT,
            borderWidth=(0, 0),
            verticalScroll_frameSize=[0, self.resizeSize, 0, 1],
            horizontalScroll_frameSize=[0, 1, 0, self.resizeSize],

            # resize the scrollbar according to window size
            verticalScroll_resizeThumb=False,
            horizontalScroll_resizeThumb=False,
            # define the textures for the scrollbars
            verticalScroll_frameTexture=VERTICALSCROLL_FRAMETEXTURE,
            verticalScroll_incButton_frameTexture=
            VERTICALSCROLL_INCBUTTON_FRAMETEXTURE,
            verticalScroll_decButton_frameTexture=
            VERTICALSCROLL_DECBUTTON_FRAMETEXTURE,
            verticalScroll_thumb_frameTexture=VERTICALSCROLL_TUMB_FRAMETEXTURE,
            horizontalScroll_frameTexture=HORIZONTALSCROLL_FRAMETEXTURE,
            horizontalScroll_incButton_frameTexture=
            HORIZONTALSCROLL_INCBUTTON_FRAMETEXTURE,
            horizontalScroll_decButton_frameTexture=
            HORIZONTALSCROLL_DECBUTTON_FRAMETEXTURE,
            horizontalScroll_thumb_frameTexture=
            HORIZONTALSCROLL_TUMB_FRAMETEXTURE,
            # make all flat, so the texture is as we want it
            verticalScroll_relief=DGG.FLAT,
            verticalScroll_thumb_relief=DGG.FLAT,
            verticalScroll_decButton_relief=DGG.FLAT,
            verticalScroll_incButton_relief=DGG.FLAT,
            horizontalScroll_relief=DGG.FLAT,
            horizontalScroll_thumb_relief=DGG.FLAT,
            horizontalScroll_decButton_relief=DGG.FLAT,
            horizontalScroll_incButton_relief=DGG.FLAT,
            # colors
            verticalScroll_frameColor=borderColor,
            verticalScroll_incButton_frameColor=borderColor,
            verticalScroll_decButton_frameColor=borderColor,
            verticalScroll_thumb_frameColor=borderColor,
            horizontalScroll_frameColor=borderColor,
            horizontalScroll_incButton_frameColor=borderColor,
            horizontalScroll_decButton_frameColor=borderColor,
            horizontalScroll_thumb_frameColor=borderColor,
        )
        self.contentWindow.setTransparency(True)

        # background color
        self.backgroundColor = DirectFrame(
            parent=self.contentWindow.getCanvas(),
            frameSize=(0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1]),
            frameColor=backgroundColor,
            relief=DGG.FLAT,
            borderWidth=(.01, .01),
        )
        self.backgroundColor.setTransparency(True)

        # Add a box
        self.box = boxes.VBox(parent=self.getCanvas())

        # is needed for some nicer visuals of the resize button (background)
        self.windowResizeBackground = DirectButton(
            parent=self,
            frameSize=(-.5, .5, -.5, .5),
            borderWidth=(0, 0),
            scale=(self.resizeSize, 1, self.resizeSize),
            relief=DGG.FLAT,
            frameColor=backgroundColor,
        )

        # the resize button of the window
        self.windowResize = DirectButton(
            parent=self,
            frameSize=(-.5, .5, -.5, .5),
            borderWidth=(0, 0),
            scale=(self.resizeSize, 1, self.resizeSize),
            relief=DGG.FLAT,
            frameTexture=DEFAULT_RESIZE_GEOM,
            frameColor=borderColor,
        )
        self.windowResize.setTransparency(True)
        self.windowResize.bind(DGG.B1PRESS, self.startResizeDrag)
        self.windowResize.bind(DGG.B1RELEASE, self.stopResizeDrag)

        # offset then clicking on the resize button from the mouse to the resizebutton
        # position, required to calculate the position / scaling
        self.offset = None
        self.taskName = "resizeTask-%s" % str(hash(self))

        # do sizing of the window (minimum)
        #self.resize( Vec3(0,0,0), Vec3(0,0,0) )
        # maximum
        #self.resize( Vec3(100,0,-100), Vec3(0,0,0) )
        self.resize(Vec3(curSize[0], 0, -curSize[1]), Vec3(0, 0, 0))

    def getCanvas(self):
        return self.contentWindow.getCanvas()

    # dragging functions
    def startWindowDrag(self, param):
        self.wrtReparentTo(aspect2dMouseNode)
        self.ignoreAll()
        self.accept('mouse1-up', self.stopWindowDrag)

    def stopWindowDrag(self, param=None):
        # this is called 2 times (bug), so make sure it's not already parented to aspect2d
        if self.getParent() != self.windowParent:
            self.wrtReparentTo(self.windowParent)
        if self.preserve:
            if self.preserveWhole:
                if self.getZ() > 1:
                    self.setZ(1)
                elif self.getZ() < -1 - self.getHeight():
                    self.setZ(-1 - self.getHeight())
                if self.getX() > base.a2dRight - self.getWidth():
                    self.setX(base.a2dRight - self.getWidth())
                elif self.getX() < base.a2dLeft:
                    self.setX(base.a2dLeft)
            else:
                if self.getZ() > 1:
                    self.setZ(1)
                elif self.getZ() < -1 + self.headerHeight:
                    self.setZ(-1 + self.headerHeight)
                if self.getX() > base.a2dRight - self.headerHeight:
                    self.setX(base.a2dRight - self.headerHeight)
                elif self.getX(
                ) < base.a2dLeft + self.headerHeight - self.getWidth():
                    self.setX(base.a2dLeft + self.headerHeight -
                              self.getWidth())
        #else: #Window moved beyond reach. Destroy window?

    # resize functions
    def resize(self, mPos, offset):
        mXPos = max(min(mPos.getX(), self.maxVirtualSize[0]),
                    self.minVirtualSize[0])
        mZPos = max(min(mPos.getZ(), -self.minVirtualSize[1]),
                    -self.maxVirtualSize[1] - self.headerHeight)
        self.windowResize.setPos(mXPos - self.resizeSize / 2., 0,
                                 mZPos + self.resizeSize / 2.)
        self.windowResizeBackground.setPos(mXPos - self.resizeSize / 2., 0,
                                           mZPos + self.resizeSize / 2.)
        self['frameSize'] = (0, mXPos, 0, mZPos)
        self.windowHeaderLeft.setPos(self.headerHeight / 2., 0,
                                     -self.headerHeight / 2.)
        self.windowHeaderLeft.setScale(self.headerHeight, 1, self.headerHeight)
        self.windowHeaderCenter.setPos(mXPos / 2., 0, -self.headerHeight / 2.)
        self.windowHeaderCenter.setScale(mXPos - self.headerHeight * 2., 1,
                                         self.headerHeight)
        self.windowHeaderRight.setPos(mXPos - self.headerHeight / 2., 0,
                                      -self.headerHeight / 2.)
        self.windowHeaderRight.setScale(self.headerHeight, 1,
                                        self.headerHeight)
        self.contentWindow['frameSize'] = (0, mXPos, mZPos + self.headerHeight,
                                           0)
        self.textNodePath.setPos(mXPos / 2., 0, -self.headerHeight / 3. * 2.)
        # show and hide that small background for the window sizer
        if mXPos == self.maxVirtualSize[0] and \
           mZPos == -self.maxVirtualSize[1]-self.headerHeight:
            self.windowResizeBackground.hide()
        else:
            self.windowResizeBackground.show()

    def resizeTask(self, task=None):
        mPos = aspect2dMouseNode.getPos(self) + self.offset
        self.resize(mPos, self.offset)
        return task.cont

    def startResizeDrag(self, param):
        self.offset = self.windowResize.getPos(aspect2dMouseNode)
        taskMgr.remove(self.taskName)
        taskMgr.add(self.resizeTask, self.taskName)

    def stopResizeDrag(self, param):
        taskMgr.remove(self.taskName)
        # get the window to the front
        self.wrtReparentTo(self.windowParent)

    def addHorizontal(self, widgets):
        """
      Accepts a list of directgui objects which are added to a horizontal box, which is then added to the vertical stack.
      """
        hbox = boxes.HBox()
        for widget in widgets:
            hbox.pack(widget)
        self.box.pack(hbox)
        self.updateMaxSize()

    def addVertical(self, widgets):
        """
      Accepts a list of directgui objects which are added to a vertical box, which is then added to the vertical stack.
      May cause funky layout results.
      """
        #vbox = boxes.VBox()
        for widget in widgets:
            self.box.pack(widget)
        self.updateMaxSize()

    def add(self, widgets):
        """Shortcut function for addVertical"""
        self.addVertical(widgets)

    def updateMaxSize(self):
        """Updates the max canvas size to include all items packed.
      Window is resized to show all contents."""
        bottomLeft, topRight = self.box.getTightBounds()
        self.maxVirtualSize = (topRight[0], -bottomLeft[2])
        self.contentWindow['canvasSize'] = (0, self.maxVirtualSize[0],
                                            -self.maxVirtualSize[1], 0)
        self.backgroundColor['frameSize'] = (0, self.maxVirtualSize[0],
                                             -self.maxVirtualSize[1], 0)

        #perhaps this should be optional -- automatically resize for new elements
        self.reset()

    def reset(self):
        """Poorly named function that resizes window to fit all contents"""
        self.resize(
            Vec3(self.maxVirtualSize[0], 0,
                 -self.maxVirtualSize[1] - self.headerHeight), Vec3(0, 0, 0))
Ejemplo n.º 24
0
class CharSelection(DirectObject):
    notify = directNotify.newCategory('CharSelection')

    NO_TOON = "Empty Slot"
    PLAY = "Play"
    CREATE = "Create"
    TITLE = "Pick  A  Toon  To  Play"

    def __init__(self, avChooser):
        self.avChooser = avChooser
        self.choice = None
        self.charList = None
        self.charNameLabel = None
        self.charButtons = []
        self.playOrCreateButton = None
        self.deleteButton = None
        self.quitButton = None
        self.title = None
        self.stageToon = None
        self.stageToonRoot = None
        self.deleteConf = None
        self.frame = None
        self.stageFSM = ClassicFSM.ClassicFSM('StageFSM', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('loadSZ', self.enterLoadSZ, self.exitLoadSZ),
            State.State('onStage', self.enterOnStage, self.exitOnStage)
        ], 'off', 'off')
        self.stageFSM.enterInitialState()
        self.selectionFSM = ClassicFSM.ClassicFSM('CharSelection', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('character', self.enterCharSelected,
                        self.exitCharSelected),
            State.State('empty', self.enterEmptySelected,
                        self.exitEmptySelected)
        ], 'off', 'off')
        self.selectionFSM.enterInitialState()

        self.szGeom = None
        self.olc = None
        self.asyncSZLoadStatus = False
        self.isNewToon = False
        self.newToonSlot = None
        self.camIval = None
        self.stAnimSeq = None
        self.newToonAnnounceSfx = base.loadSfx(
            "phase_4/audio/sfx/King_Crab.ogg")
        self.newToonDrumrollSfx = base.loadSfx(
            "phase_5/audio/sfx/SZ_MM_drumroll.ogg")
        self.newToonRevealSfx = base.loadSfx(
            "phase_5/audio/sfx/SZ_MM_fanfare.ogg")

        self.dnaStore = DNAStorage()
        loader.loadDNAFile(self.dnaStore,
                           'phase_4/dna/pickatoon/storage_pickatoon.pdna')

    def __setupStageToon(self):
        self.stageToonRoot = render.attachNewNode('stageToonRoot')
        self.stageToon = Toon(base.cr)
        self.stageToon.setPosHpr(0, 0, 0, 0, 0, 0)
        self.stageToon.reparentTo(self.stageToonRoot)

    def cleanupStageToon(self):
        if self.stageToon != None:
            self.stageToon.disable()
            self.stageToon.delete()
            self.stageToon = None
        if self.stageToonRoot != None:
            self.stageToonRoot.removeNode()
            self.stageToonRoot = None

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def __async_loadSZTask(self, task=None):
        dnas = HOOD_ID_2_DNA[self.choice.lastHood]
        for i in xrange(len(dnas)):
            dnaFile = dnas[i]
            if i == len(dnas) - 1:
                node = loader.loadDNAFile(self.dnaStore, dnaFile)
                if node.getNumParents() == 1:
                    self.szGeom = NodePath(node.getParent(0))
                    self.szGeom.reparentTo(render)
                else:
                    self.szGeom = render.attachNewNode(node)

                # The 2D trees should not be flattened, to do that, we're going to traverse
                # the scene graph for all trees, use #wrtReparentTo(render) on them, flatten
                # the scene with #flattenStrong(), and finally #wrtReparentTo(self.szGeom)
                # the trees back to the main scene node so they get cleaned up properly.
                trees = self.szGeom.findAllMatches('**/*tree*')
                #self.szGeom.find("**/shadow").removeNode()

                #from panda3d.core import CullBinAttrib
                #self.szGeom.find("**/shadow_crack").setAttrib(CullBinAttrib.make("foreground", 10), 10)
                #shs = self.szGeom.findAllMatches("**/*shadow*")
                #for sh in shs:
                #    sh.removeNode()

                # self.szGeom.ls()

                for tree in trees:
                    tree.wrtReparentTo(render)

                self.szGeom.flattenStrong()

                for tree in trees:
                    tree.wrtReparentTo(self.szGeom)

            else:
                loader.loadDNAFile(self.dnaStore, dnaFile)

        self.olc = ZoneUtil.getOutdoorLightingConfig(self.choice.lastHood)
        self.olc.setup()
        self.olc.apply()

        CIGlobals.preRenderScene(render)

        self.asyncSZLoadStatus = True

        #base.accept('l', render.ls)

        if task:
            return task.done

    def enterLoadSZ(self):
        self.loadingDlg = Dialog.GlobalDialog("Loading...")
        self.loadingDlg.show()

        base.cr.renderFrame()
        base.cr.renderFrame()

        self.notify.info("Polling for SZ to load")
        self.asyncSZLoadStatus = False
        self.__async_loadSZTask()

        base.doNextFrame(self.stageFSM.request, ['onStage'])

    def exitLoadSZ(self):
        if hasattr(self, 'loadingDlg'):
            self.loadingDlg.cleanup()
            del self.loadingDlg

    def __changeCamFOV(self, val):
        base.camLens.setMinFov(val / (4. / 3.))

    def enterOnStage(self):
        dna = self.choice.dna
        name = self.choice.name
        self.stageToon.setName(name)
        self.stageToon.setDNAStrand(dna)
        self.stageToon.nametag.setNametagColor(
            NametagGlobals.NametagColors[NametagGlobals.CCLocal])
        self.stageToon.nametag.setActive(0)
        self.stageToon.nametag.nametag3d.request('Rollover')
        self.stageToon.nametag.unmanage(base.marginManager)
        self.stageToon.nametag.updateAll()
        self.stageToon.animFSM.request('neutral')
        self.stageToon.setPosHpr(0, 0, 0, 10, 0, 0)
        self.stageToon.show()

        dat = HOOD_STAGE_DATA[self.choice.lastHood]

        self.stageToonRoot.setPos(dat[2])
        self.stageToonRoot.setHpr(dat[3])

        camera.reparentTo(self.stageToonRoot)

        camera.setPos(dat[0])
        camera.lookAt(self.stageToonRoot, 0, 0, 3)
        startHpr = camera.getHpr()
        camera.setPos(dat[1])
        camera.lookAt(self.stageToonRoot, 0, 0, 3)
        endHpr = camera.getHpr()

        self.camIval = Parallel(
            LerpPosInterval(camera,
                            5.0,
                            dat[1] - (1.6, 0, 0),
                            dat[0] - (1.6, 0, 0),
                            blendType='easeInOut'),
            LerpQuatInterval(camera,
                             5.0,
                             hpr=endHpr,
                             startHpr=startHpr,
                             blendType='easeInOut'),
            LerpFunc(self.__changeCamFOV,
                     duration=5.0,
                     fromData=80.0,
                     toData=CIGlobals.DefaultCameraFov,
                     blendType='easeInOut'))
        if self.isNewToon:
            self.camIval.append(
                Sequence(
                    Func(self.stageToon.hide), Func(base.stopMusic),
                    SoundInterval(self.newToonAnnounceSfx,
                                  startTime=1.674,
                                  duration=4.047),
                    SoundInterval(self.newToonDrumrollSfx),
                    Func(self.stageToon.pose, 'tele',
                         self.stageToon.getNumFrames('tele')),
                    Func(self.newToonAppear), Func(self.stageToon.show),
                    SoundInterval(self.newToonRevealSfx),
                    Func(base.cr.playTheme)))
        else:
            self.camIval.append(
                Sequence(Func(self.showActionButtons),
                         Func(self.enableAllCharButtons), Wait(5.0),
                         Func(self.beginRandomAnims)))

        self.camIval.start()

    def hideActionButtons(self):
        self.playOrCreateButton.hide()
        self.deleteButton.hide()

    def showActionButtons(self):
        self.playOrCreateButton.show()
        self.deleteButton.show()

    def newToonAppear(self):
        self.stopSTAnimSeq()

        self.stAnimSeq = Sequence(
            Func(self.stageToon.animFSM.request, 'teleportIn'), Wait(2.0),
            ActorInterval(self.stageToon, 'wave'),
            Func(self.stageToon.loop, 'neutral'), Func(self.beginRandomAnims),
            Func(self.enableAllCharButtons), Func(self.showActionButtons))
        self.stAnimSeq.start()

    def stopSTAnimSeq(self):
        if self.stAnimSeq:
            self.stAnimSeq.finish()
            self.stAnimSeq = None

    def unloadSZGeom(self):
        if self.szGeom:
            self.szGeom.removeNode()
            self.szGeom = None
        if self.olc:
            self.olc.cleanup()
            self.olc = None

    def beginRandomAnims(self):
        self.stageToon.startLookAround()
        taskMgr.doMethodLater(random.uniform(*ST_ANIM_IVAL),
                              self.__doRandomSTAnim, "doRandomSTAnim")

    def __doRandomSTAnim(self, task):
        anim = random.choice(ST_RANDOM_ANIMS)

        self.stopSTAnimSeq()

        self.stageToon.stopLookAround()

        head = self.stageToon.getPart('head')

        if anim == 'read':
            self.stAnimSeq = Sequence(
                Func(self.stageToon.lerpLookAt, head, (0, -15, 0)),
                Func(self.stageToon.animFSM.request, 'openBook'), Wait(0.5),
                Func(self.stageToon.animFSM.request, 'readBook'), Wait(2.0),
                Func(self.stageToon.lerpLookAt, head, (0, 0, 0)),
                Func(self.stageToon.animFSM.request, 'closeBook'), Wait(1.75),
                Func(self.stageToon.loop, 'neutral'),
                Func(self.stageToon.startLookAround))
        else:
            self.stageToon.lerpLookAt(head, (0, 0, 0))
            self.stAnimSeq = Sequence(ActorInterval(self.stageToon, anim),
                                      Func(self.stageToon.loop, 'neutral'),
                                      Func(self.stageToon.startLookAround))

        self.stAnimSeq.start()

        task.delayTime = random.uniform(*ST_ANIM_IVAL)
        return task.again

    def endRandomAnims(self):
        taskMgr.remove("doRandomSTAnim")
        self.stopSTAnimSeq()

    def exitOnStage(self):
        self.isNewToon = False
        if self.camIval:
            self.camIval.finish()
            self.camIval = None
        self.endRandomAnims()
        self.stopSTAnimSeq()
        camera.reparentTo(render)
        camera.setPosHpr(0, 0, 0, 0, 0, 0)
        #base.transitions.fadeScreen(1.0)
        self.unloadSZGeom()
        self.stageToon.hide()

    def enterCharSelected(self):
        self.playOrCreateButton['text'] = self.PLAY
        self.playOrCreateButton['extraArgs'] = ['play']
        #aspect2d.hide()

    def exitCharSelected(self):
        self.playOrCreateButton.hide()
        self.deleteButton.hide()

    def enterEmptySelected(self):
        self.charNameLabel.setText(self.NO_TOON)
        self.playOrCreateButton['text'] = self.CREATE
        self.playOrCreateButton['extraArgs'] = ['create']
        self.playOrCreateButton.show()

    def exitEmptySelected(self):
        self.playOrCreateButton.hide()

    def __action(self, action):
        for btn in self.charButtons:
            if btn['state'] == DGG.DISABLED:
                self.slot = btn.getPythonTag('slot')
                break
        func = None
        arg = None
        doFade = True
        if action == 'delete':
            func = self.deleteToon
            arg = self.choice.avId
            doFade = False
        elif action == 'play':
            func = self.playGame
            arg = self.choice.slot
        elif action == 'create':
            func = self.enterMAT
        elif action == 'quit':
            func = sys.exit
            doFade = False
        if doFade:
            base.transitions.fadeOut(0.3)
            if arg != None:
                Sequence(Wait(0.31), Func(func, arg)).start()
            else:
                Sequence(Wait(0.31), Func(func)).start()
        else:
            if arg != None:
                func(arg)
            else:
                func()

    def playGame(self, slot):
        messenger.send("avChooseDone",
                       [self.avChooser.getAvChoiceBySlot(slot)])

    def enterMAT(self):
        messenger.send("enterMakeAToon", [self.slot])

    def deleteToon(self, avId):
        # Show a confirmation message
        self.deleteConf = Dialog.GlobalDialog(
            message='This will delete {0} forever.\n\nAre you sure?'.format(
                self.avChooser.getNameFromAvId(avId)),
            style=Dialog.YesNo,
            doneEvent='deleteConfResponse',
            extraArgs=[avId])
        self.acceptOnce('deleteConfResponse', self.__handleDeleteConfResponse)
        self.deleteConf.show()

    def __handleDeleteConfResponse(self, avId):
        doneStatus = self.deleteConf.getValue()
        if doneStatus:
            # Alright, they pressed yes. No complaining to us.
            self.avChooser.avChooseFSM.request("waitForToonDelResponse",
                                               [avId])
        else:
            self.deleteConf.cleanup()
            self.deleteConf = None

    def __handleCharButton(self, slot):
        for btn in self.charButtons:
            if btn.getPythonTag('slot') == slot:
                btn['state'] = DGG.DISABLED
            else:
                btn['state'] = DGG.NORMAL
        if self.avChooser.hasToonInSlot(slot):
            self.choice = self.avChooser.getAvChoiceBySlot(slot)
            self.selectionFSM.request('character')
            self.stageFSM.request('loadSZ')
        else:
            self.selectionFSM.request('empty')
            self.stageFSM.request('off')

    def disableAllCharButtons(self):
        for btn in self.charButtons:
            btn['state'] = DGG.DISABLED

    def enableAllCharButtons(self):
        for btn in self.charButtons:
            if not self.choice or btn.getPythonTag('slot') != self.choice.slot:
                btn['state'] = DGG.NORMAL

    def load(self, newToonSlot=None):
        self.isNewToon = newToonSlot is not None
        self.newToonSlot = newToonSlot

        base.transitions.noTransitions()

        base.cr.renderFrame()
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4. / 3.))

        self.__setupStageToon()

        self.title = DirectLabel(text=self.TITLE,
                                 text_font=CIGlobals.getMickeyFont(),
                                 text_fg=(1, 0.9, 0.1, 1),
                                 relief=None,
                                 text_scale=0.13,
                                 pos=(0, 0, 0.82))
        self.charNameLabel = OnscreenText(text="",
                                          font=CIGlobals.getMickeyFont(),
                                          pos=(-0.25, 0.5, 0),
                                          fg=(1, 0.9, 0.1, 1.0))
        self.charNameLabel.hide()
        self.frame = DirectFrame()
        self.frame['image'] = DGG.getDefaultDialogGeom()
        self.frame['image_color'] = CIGlobals.DialogColor
        self.frame['image_scale'] = (-0.9, -0.9, 0.8)
        self.frame['image_pos'] = (0.82, 0, -0.125)
        self.playOrCreateButton = DirectButton(
            text="",
            pos=(0.8125, 0, -0.35),
            command=self.__action,
            geom=CIGlobals.getDefaultBtnGeom(),
            text_scale=0.06,
            relief=None,
            text_pos=(0, -0.01))
        self.playOrCreateButton.hide()
        self.deleteButton = DirectButton(text="Delete",
                                         pos=(0.8125, 0, -0.45),
                                         command=self.__action,
                                         extraArgs=['delete'],
                                         geom=CIGlobals.getDefaultBtnGeom(),
                                         text_scale=0.06,
                                         relief=None,
                                         text_pos=(0, -0.01))
        self.deleteButton.hide()
        self.quitButton = DirectButton(text="Quit",
                                       pos=(-1.10, 0, -0.925),
                                       command=self.__action,
                                       extraArgs=['quit'],
                                       text_scale=0.06,
                                       geom=CIGlobals.getDefaultBtnGeom(),
                                       relief=None,
                                       text_pos=(0, -0.01))

        for slot in range(6):
            if self.avChooser.hasToonInSlot(slot):
                choice = self.avChooser.getAvChoiceBySlot(slot)
                text = choice.name
            else:
                text = self.NO_TOON
            btn = CIGlobals.makeDefaultScrolledListBtn(
                text=text,
                text_scale=0.06,
                command=self.__handleCharButton,
                extraArgs=[slot])
            btn.setPythonTag('slot', slot)
            self.charButtons.append(btn)
            btn['state'] = DGG.NORMAL

        self.charList = CIGlobals.makeDefaultScrolledList(
            pos=(0.75, 0, -0.225),
            listZorigin=-0.43,
            listFrameSizeZ=0.51,
            arrowButtonScale=0.0,
            items=self.charButtons,
            parent=self.frame)

        if self.isNewToon:
            self.__handleCharButton(self.newToonSlot)
            self.disableAllCharButtons()

    def unload(self):
        self.selectionFSM.requestFinalState()
        self.stageFSM.requestFinalState()
        self.cleanupStageToon()
        self.choice = None
        if self.frame:
            self.frame.destroy()
            self.frame = None
        if self.charButtons:
            for btn in self.charButtons:
                btn.destroy()
            self.charButtons = None
        if self.deleteConf:
            self.deleteConf.cleanup()
            self.deleteConf = None
        if self.charList:
            self.charList.destroy()
            self.charList = None
        if self.charNameLabel:
            self.charNameLabel.destroy()
            self.charNameLabel = None
        if self.playOrCreateButton:
            self.playOrCreateButton.destroy()
            self.playOrCreateButton = None
        if self.deleteButton:
            self.deleteButton.destroy()
            self.deleteButton = None
        if self.quitButton:
            self.quitButton.destroy()
            self.quitButton = None
        if self.title:
            self.title.destroy()
            self.title = None
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        base.transitions.noTransitions()
        del self.selectionFSM
class CalendarGuiMonth(DirectFrame):
    notify = directNotify.newCategory('CalendarGuiMonth')

    def __init__(self, parent, startingDateTime, scale = 1.0, pos = (0, 0, -0.1), dayClickCallback = None, onlyFutureDaysClickable = False, onlyFutureMonthsClickable = False):
        self.startDate = startingDateTime
        self.curDate = startingDateTime
        self.dayClickCallback = dayClickCallback
        self.onlyFutureDaysClickable = onlyFutureDaysClickable
        self.onlyFutureMonthsClickable = onlyFutureMonthsClickable
        if self.onlyFutureDaysClickable:
            self.onlyFutureMonthsClickable = True
        DirectFrame.__init__(self, parent=parent, scale=scale, pos=pos)
        self.showMarkers = config.GetBool('show-calendar-markers', 0)
        self.load()
        self.createGuiObjects()
        self.lastSelectedDate = None
        self.accept('clickedOnDay', self.clickedOnDay)

    def createDummyLocators(self):
        self.monthLocator = self.attachNewNode('monthLocator')
        self.monthLocator.setZ(0.6)
        self.weekDayLocators = []
        for i in xrange(7):
            self.weekDayLocators.append(self.attachNewNode('weekDayLocator-%d' % i))
            self.weekDayLocators[i].setZ(0.5)
            self.weekDayLocators[i].setX(i * 0.24 + -0.75)

        dayTopLeftX = -0.8
        dayTopLeftZ = 0.4
        self.dayLocators = []
        for row in xrange(6):
            oneWeek = []
            for col in xrange(7):
                newDayLoc = self.attachNewNode('dayLocator-row-%d-col-%d' % (row, col))
                newDayLoc.setX(col * 0.24 + dayTopLeftX)
                newDayLoc.setZ(row * -0.18 + dayTopLeftZ)
                oneWeek.append(newDayLoc)

            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.attachNewNode('monthLeft')
        self.monthLeftLocator.setPos(-0.3, 0, 0.65)
        self.monthRightLocator = self.attachNewNode('monthRight')
        self.monthRightLocator.setPos(0.3, 0, 0.65)

    def attachMarker(self, parent, scale = 0.01, color = (1, 0, 0)):
        if self.showMarkers:
            marker = loader.loadModel('phase_3/models/misc/sphere')
            marker.reparentTo(parent)
            marker.setScale(scale)
            marker.setColor(*color)

    def load(self):
        monthAsset = loader.loadModel('phase_4/models/parties/tt_m_gui_sbk_calendar')
        monthAsset.reparentTo(self)
        self.monthLocator = self.find('**/locator_month/locator_month')
        self.attachMarker(self.monthLocator)
        self.weekDayLocators = []
        for weekday in ('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'):
            weekDayLoc = self.find('**/loc_%s' % weekday)
            self.weekDayLocators.append(weekDayLoc)
            self.attachMarker(weekDayLoc)

        self.dayLocators = []
        for row in xrange(6):
            oneWeek = []
            for col in xrange(7):
                newDayLoc = self.find('**/loc_box_%s_%s' % (row, col))
                oneWeek.append(newDayLoc)

            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.find('**/locator_month_arrowL')
        self.monthRightLocator = self.find('**/locator_month_arrowR')
        self.filterLocator = self.find('**/locator_filter')
        self.filterLocatorArrowUp = self.find('**/locator_filter_arrowTop')
        self.filterLocatorArrowDown = self.find('**/locator_filter_arrowBottom')
        self.yearLocator = self.attachNewNode('yearLocator')
        self.yearLocator.setPos(self.monthLocator, 0, 0, -0.03)

    def createGuiObjects(self):
        self.monthLabel = DirectLabel(parent=self.monthLocator, relief=None, text=TTLocalizer.Months[self.startDate.month], text_scale=0.075, text_font=ToontownGlobals.getMinnieFont(), text_fg=(40 / 255.0,
         140 / 255.0,
         246 / 255.0,
         1.0))
        self.yearLabel = DirectLabel(parent=self.yearLocator, relief=None, text=str(self.startDate.year), text_scale=0.03, text_font=ToontownGlobals.getMinnieFont(), text_fg=(140 / 255.0,
         140 / 255.0,
         246 / 255.0,
         1.0))
        self.weekdayLabels = []
        for posIndex in xrange(7):
            adjustedNameIndex = (posIndex - 1) % 7
            self.weekdayLabels.append(DirectLabel(parent=self.weekDayLocators[posIndex], relief=None, text=TTLocalizer.DayNamesAbbrev[adjustedNameIndex], text_font=ToontownGlobals.getInterfaceFont(), text_fg=(255 / 255.0,
             146 / 255.0,
             113 / 255.0,
             1.0), text_scale=0.05))

        self.createGuiDays()
        arrowUp = self.find('**/month_arrowR_up')
        arrowDown = self.find('**/month_arrowR_down')
        arrowHover = self.find('**/month_arrowR_hover')
        self.monthLeftArrow = DirectButton(parent=self.monthLeftLocator, relief=None, image=(arrowUp,
         arrowDown,
         arrowHover,
         arrowUp), image3_color=Vec4(1, 1, 1, 0.5), scale=(-1.0, 1.0, 1.0), command=self.__doMonthLeft)
        if self.onlyFutureMonthsClickable:
            self.monthLeftArrow.hide()
        self.monthRightArrow = DirectButton(parent=self.monthRightLocator, relief=None, image=(arrowUp,
         arrowDown,
         arrowHover,
         arrowUp), image3_color=Vec4(1, 1, 1, 0.5), command=self.__doMonthRight)

        def makeLabel(itemName, itemNum, *extraArgs):
            return DirectLabel(text=itemName, frameColor=(0, 0, 0, 0), text_scale=0.04)

        gui = loader.loadModel('phase_4/models/parties/tt_m_gui_sbk_calendar_box')
        arrowUp = gui.find('**/downScroll_up')
        arrowDown = gui.find('**/downScroll_down')
        arrowHover = gui.find('**/downScroll_hover')
        filterLocatorUpPos = self.filterLocatorArrowUp.getPos(self.filterLocator)
        filterLocatorDownPos = self.filterLocatorArrowDown.getPos(self.filterLocator)
        self.filterList = DirectScrolledList(parent=self.filterLocator, relief=None, pos=(0, 0, 0), image=None, text_scale=0.025, incButton_image=(arrowUp,
         arrowDown,
         arrowHover,
         arrowUp), incButton_relief=None, incButton_pos=filterLocatorDownPos, incButton_image3_color=Vec4(1, 1, 1, 0.2), incButtonCallback=self.filterChanged, decButton_image=(arrowUp,
         arrowDown,
         arrowHover,
         arrowUp), decButton_relief=None, decButton_pos=filterLocatorUpPos, decButton_scale=(1, 1, -1), decButton_image3_color=Vec4(1, 1, 1, 0.2), decButtonCallback=self.filterChanged, numItemsVisible=1, itemMakeFunction=makeLabel, items=[TTLocalizer.CalendarShowAll, TTLocalizer.CalendarShowOnlyHolidays, TTLocalizer.CalendarShowOnlyParties], itemFrame_frameSize=(-0.2, 0.2, -0.02, 0.05), itemFrame_frameColor=(0, 0, 0, 0))
        gui.removeNode()

    def getTopLeftDate(self):
        firstOfTheMonth = self.curDate.replace(day=1)
        daysAwayFromSunday = (firstOfTheMonth.weekday() - 6) % 7
        topLeftDate = firstOfTheMonth + timedelta(days=-daysAwayFromSunday)
        return topLeftDate

    def createGuiDays(self):
        topLeftDate = self.getTopLeftDate()
        curDate = topLeftDate
        self.guiDays = []
        for row in self.dayLocators:
            for oneLocator in row:
                self.guiDays.append(CalendarGuiDay(oneLocator, curDate, self.curDate, self.dayClickCallback, self.onlyFutureDaysClickable))
                curDate += timedelta(days=1)

    def changeDateForGuiDays(self):
        topLeftDate = self.getTopLeftDate()
        guiDayDate = topLeftDate
        for guiDay in self.guiDays:
            guiDay.changeDate(self.curDate, guiDayDate)
            guiDayDate += timedelta(days=1)

    def changeMonth(self, monthChange):
        if monthChange != 0:
            newMonth = self.curDate.month + monthChange
            newYear = self.curDate.year
            while newMonth > 12:
                newYear += 1
                newMonth -= 12

            while newMonth < 1:
                if newYear - 1 > 1899:
                    newMonth += 12
                    newYear -= 1
                else:
                    newMonth += 1

            self.curDate = datetime(newYear, newMonth, 1, self.curDate.time().hour, self.curDate.time().minute, self.curDate.time().second, self.curDate.time().microsecond, self.curDate.tzinfo)
        self.monthLabel['text'] = (TTLocalizer.Months[self.curDate.month],)
        self.yearLabel['text'] = (str(self.curDate.year),)
        startTime = globalClock.getRealTime()
        self.changeDateForGuiDays()
        endTime = globalClock.getRealTime()
        self.notify.debug('changeDate took %f seconds' % (endTime - startTime))
        self.updateSelectedDate()
        if monthChange != 0:
            if self.onlyFutureMonthsClickable and newMonth == self.startDate.month and newYear == self.startDate.year:
                self.monthLeftArrow.hide()

    def __doMonthLeft(self):
        self.changeMonth(-1)

    def __doMonthRight(self):
        self.monthLeftArrow.show()
        self.changeMonth(1)

    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)

    def clickedOnDay(self, dayDate):
        self.lastSelectedDate = dayDate
        self.updateSelectedDate()

    def updateSelectedDate(self):
        if self.lastSelectedDate:
            for oneGuiDay in self.guiDays:
                if oneGuiDay.myDate.date() == self.lastSelectedDate:
                    oneGuiDay.updateSelected(True)
                else:
                    oneGuiDay.updateSelected(False)

    def clearSelectedDay(self):
        for oneGuiDay in self.guiDays:
            oneGuiDay.updateSelected(False)

    def filterChanged(self):
        newFilter = self.filterList.getSelectedIndex()
        for guiDay in self.guiDays:
            guiDay.changeFilter(newFilter)
Ejemplo n.º 26
0
class Classement:
    def __init__(self, ranking):
        self.ranking = ranking
        self.loadMenu()

    def loadMenu(self):
        base.setBackgroundColor(0, 0.25, 0.4)

        self.font = loader.loadFont(
            str(MAINDIR) + '/assets/fonts/allerdisplay.ttf')
        self.font.setPixelsPerUnit(150)
        self.title = OnscreenText(text="Classement",
                                  pos=(0, 0.75),
                                  scale=0.25,
                                  fg=(1, 1, 1, 1),
                                  align=TextNode.ACenter,
                                  font=self.font)

        mapsparkour = loader.loadModel("assets/gui/retour_maps")
        self.retour_button = DirectButton(
            geom=(mapsparkour.find("**/retour_ready"),
                  mapsparkour.find("**/retour_ready")),
            frameColor=(0, 0, 0, 0),
            pos=(-1.5, -1, -0.90),
            command=base.messenger.send,
            scale=0.25,
            extraArgs=["Menu-Ranking-Return"])

        self.createPlayerRankingDisplay()

    def createPlayerRankingDisplay(self):
        self.ranking_plates = []
        z = 0.70
        for r in self.ranking:
            z -= 0.32
            ranking = OnscreenImage(image=str(MAINDIR) +
                                    '/assets/gui/classement_template.png',
                                    pos=(0, 0, z),
                                    scale=(1.5, 1, 0.15))
            ranking.setTransparency(1)
            nametext = OnscreenText(text=r[0],
                                    pos=(-1.15, z - 0.035),
                                    scale=0.1,
                                    fg=(1, 1, 1, 1),
                                    align=TextNode.ACenter,
                                    font=self.font)
            scoretext = OnscreenText(text="Score: {}".format(r[1]),
                                     pos=(-0.1, z - 0.035),
                                     scale=0.1,
                                     fg=(1, 1, 1, 1),
                                     align=TextNode.ACenter,
                                     font=self.font)
            datetext = OnscreenText(text=''.join(r[2]),
                                    pos=(1, z - 0.035),
                                    scale=0.1,
                                    fg=(1, 1, 1, 1),
                                    align=TextNode.ACenter,
                                    font=self.font)
            self.ranking_plates.append(
                [ranking, nametext, scoretext, datetext])

    def hideMenu(self):
        self.title.hide()
        self.retour_button.hide()
        for r in self.ranking_plates:
            for i in r:
                i.hide()

    def showMenu(self):
        self.title.show()
        self.retour_button.show()
        for r in self.ranking_plates:
            for i in r:
                i.show()
Ejemplo n.º 27
0
class ColourChannel(DirectObject):
    __slider_edit_callback: Callable[['ColourChannel', float], None]
    __entry_edit_callback: Callable[['ColourChannel', float], None]

    __frame: DirectFrame
    __label: DirectLabel
    __slider: DirectSlider
    __entry: DirectEntry
    __disable_frame_overlay: DirectButton
    __enabled: bool

    def __init__(self, parent: DirectFrame, text: str, value: float,
                 slider_edit_callback: Callable[['ColourChannel', float],
                                                None],
                 entry_edit_callback: Callable[['ColourChannel', float], None],
                 mouse1_press_callbacks: List[Callable[[], None]]):
        self.__frame = DirectFrame(parent=parent)
        self.__slider_edit_callback = slider_edit_callback
        self.__entry_edit_callback = entry_edit_callback

        self.__label = DirectLabel(parent=self.__frame,
                                   text=text,
                                   text_fg=WHITE,
                                   text_bg=WINDOW_BG_COLOUR,
                                   pos=(-0.5, 0.0, 0.0),
                                   scale=(0.1, 1.0, 0.1))

        self.__slider = DirectSlider(parent=self.__frame,
                                     orientation=DGG.HORIZONTAL,
                                     borderWidth=(0.0, 0.0),
                                     frameColor=WIDGET_BG_COLOUR,
                                     frameSize=(-1.0, 1.0, -0.4, 0.4),
                                     thumb_frameSize=(-0.075, 0.075, -0.2,
                                                      0.2),
                                     value=value,
                                     pos=(0.05, 0.0, 0.0255),
                                     scale=(0.45, 1.0, 0.5))

        self.__entry_hovered = False
        mouse1_press_callbacks.append(self.__entry_mouse_click_callback)
        self.__entry = DirectEntry(parent=self.__frame,
                                   frameColor=WIDGET_BG_COLOUR,
                                   text_fg=WHITE,
                                   initialText=str(value),
                                   scale=0.1,
                                   width=3,
                                   suppressKeys=True,
                                   pos=(0.55, 0.0, -0.01105))
        self.__entry.bind(DGG.EXIT, self.__entry_exit_callback)
        self.__entry.bind(DGG.ENTER, self.__entry_enter_callback)
        self.__entry.bind(DGG.B1PRESS, self.__entry_mouse_click_callback)
        self.accept("mouse1", self.__entry_mouse_click_callback)

        self.__disable_frame_overlay = DirectButton(parent=self.__frame,
                                                    frameColor=TRANSPARENT,
                                                    borderWidth=(0.0, 0.0),
                                                    frameSize=(-0.6, 0.9, -0.2,
                                                               0.2),
                                                    suppressMouse=True)
        self.__disable_frame_overlay.hide()
        self.__enabled = True

        self.__set_callbacks()

    def __entry_exit_callback(self, *discard) -> None:
        self.__entry_hovered = False

    def __entry_enter_callback(self, *discard) -> None:
        self.__entry_hovered = True

    def __entry_mouse_click_callback(self, *discard) -> None:
        if self.__entry_hovered:
            s = self.__entry.get()
            try:
                f = float(s)
            except:
                return
            self.__entry_edit_callback(self, f)
        else:
            self.__entry['focus'] = False

    def __unset_callbacks(self):
        self.__slider['command'] = None
        self.__entry['command'] = None

    def __set_callbacks(self):
        def slider_callback() -> None:
            self.__slider_edit_callback(self, self.__slider['value'])

        def entry_callback(s) -> None:
            try:
                f = float(s)
            except:
                return
            self.__entry_edit_callback(self, f)

        self.__slider['command'] = slider_callback
        self.__entry['command'] = entry_callback

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

    def update_slider(self, value: float):
        if not self.__enabled:
            return
        self.__unset_callbacks()
        self.__slider['value'] = value
        self.__set_callbacks()

    def update_entry(self, value: float):
        if not self.__enabled:
            return
        self.__unset_callbacks()
        self.__entry.enterText(f'{value:.3f}')
        self.__set_callbacks()

    def update(self, value: float):
        self.update_slider(value)
        self.update_entry(value)

    @property
    def value(self) -> float:
        return self.__slider['value']

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

    @enabled.setter
    def enabled(self, enabled: bool) -> None:
        if self.__enabled == enabled:
            return
        self.__enabled = enabled
        if enabled:
            self.__disable_frame_overlay.hide()
        else:
            self.__disable_frame_overlay.show()

    @enabled.getter
    def enabled(self) -> bool:
        return self.__enabled
Ejemplo n.º 28
0
class Highscore():
    def __init__(self):

        home = os.path.expanduser("~")
        quickJNRDir = os.path.join(home, ".quickShooter")
        if not os.path.exists(quickJNRDir): os.makedirs(quickJNRDir)
        self.highscorefile = os.path.join(quickJNRDir, "highscore.txt")

        self.highscore = []

        if not os.path.exists(self.highscorefile):
            with open(self.highscorefile, "w") as f:
                f.write("""Foxy;4000
Wolf;3500
Coon;3000
Kitty;2020
Ferret;2000
Lynx;1700
Lion;1280
Tiger;800
Birdy;450
Fishy;250""")


        with open(self.highscorefile, "r+") as f:
            data = f.readlines()
            for line in data:
                name = line.split(";")[0]
                pts = line.split(";")[1]
                self.highscore.append([name, pts])


        self.lstHighscore = DirectScrolledList(
            frameSize = (-1, 1, -0.6, 0.6),
            frameColor = (0,0,0,0.5),
            pos = (0, 0, 0),
            numItemsVisible = 10,
            itemMakeFunction = self.__makeListItem,
            itemFrame_frameSize = (-0.9, 0.9, 0.0, -1),
            itemFrame_color = (1, 1, 1, 0),
            itemFrame_pos = (0, 0, 0.5))

        self.btnBack = DirectButton(
            # size of the button
            scale = (0.15, 0.15, 0.15),
            text = "Back",
            # set no relief
            relief = None,
            frameColor = (0,0,0,0),
            # No sink in when press
            pressEffect = False,
            # position on the window
            pos = (0.2, 0, 0.1),
            # the event which is thrown on clickSound
            command = self.btnBack_Click,
            # sounds that should be played
            rolloverSound = None,
            clickSound = None)
        self.btnBack.setTransparency(1)
        self.btnBack.reparentTo(base.a2dBottomLeft)

        self.refreshList()
        self.hide()

    def show(self):
        self.lstHighscore.show()
        self.btnBack.show()

    def hide(self):
        self.lstHighscore.hide()
        self.btnBack.hide()

    def writeHighscore(self):
        self.__sortHigscore()
        with open(self.highscorefile, "w") as f:
            for entry in self.highscore:
                f.write("{0};{1}".format(entry[0], entry[1]))

    def refreshList(self):
        self.__sortHigscore()
        self.lstHighscore.removeAllItems()
        for entry in self.highscore:
            self.lstHighscore.addItem("{0};{1}".format(entry[0], entry[1]))

    def __makeListItem(self, highscoreItem, stuff, morestuff):
        name = highscoreItem.split(";")[0]
        pts = highscoreItem.split(";")[1]
        # left
        l = -0.9
        # right
        r = 0.9
        itemFrame = DirectFrame(
            frameColor=(1, 1, 1, 0.5),
            frameSize=(l, r, -0.1, 0),
            relief=DGG.SUNKEN,
            borderWidth=(0.01, 0.01),
            pos=(0, 0, 0))
        lblName = DirectLabel(
            pos=(l + 0.01, 0, -0.07),
            text=name,
            text_align=TextNode.ALeft,
            scale=0.07,
            frameColor=(0, 0, 0, 0))
        lblPts = DirectLabel(
            pos=(r - 0.01, 0, -0.07),
            text=pts,
            text_align=TextNode.ARight,
            scale=0.07,
            frameColor=(0, 0, 0, 0))
        lblName.reparentTo(itemFrame)
        lblPts.reparentTo(itemFrame)
        return itemFrame


    def __sortHigscore(self):
        self.highscore = sorted(
            self.highscore,
            key=lambda score: int(score[1]),
            reverse=True)[:10]

    def setPoints(self, name, points):
        self.highscore.append([name, str(points) + "\n"])
        self.refreshList()
        self.writeHighscore()

    def btnBack_Click(self):
        self.hide()
        base.messenger.send("Highscore_back")
Ejemplo n.º 29
0
class menuGUI():
    def __init__(self, _client=None):
        # Ref
        self.client = _client

        # create a singlePlayer button
        self.menubtn0 = DirectButton(
            # Scale and position
            scale = 0.10,
            pos = (0,0,0.5),
            # Text
            text = "Single-Player",
            # Frame
            # Functionality
            command = '')

       	# create a Lan button
        self.menubtn1 = DirectButton(
            # Scale and position
            scale = 0.10,
            pos = (0,0,0.3),
            # Text
            text = "Multi-Player",
            # Frame
            # Functionality
            command = self.handleMultiPlayer)

        # create a Options button
        self.menubtn2 = DirectButton(
            # Scale and position
            scale = 0.10,
            pos = (0,0,0.1),
            # Text
            text = "Options",
            # Frame
            # Functionality
            command = '')

        # create a Exit button
        self.menubtn3 = DirectButton(
            # Scale and position
            scale = 0.10,
            pos = (0,0,-0.1),
            # Text
            text = "Exit",
            # Frame
            # Functionality
            command = self.handleExit)

        self.hide()

    def show(self):
        self.menubtn0.show()
        self.menubtn1.show()
        self.menubtn2.show()
        self.menubtn3.show()

    def hide(self):
        self.menubtn0.hide()
        self.menubtn1.hide()
        self.menubtn2.hide()
        self.menubtn3.hide()


    def handleSinglePlayer(self):
        pass

    def handleMultiPlayer(self):
        # Move to Host / Join-Find games screen
        mGUI = multiplayerGUI(self)
        self.hide()
        mGUI.show()

    def handleOptions(self):
        pass

    def handleExit(self):
        sys.exit()



# TESTING
#import direct.directbase.DirectStart
#gui = menuGUI()
#gui.show()
#base.run()
Ejemplo n.º 30
0
class lobbyGUI():
    def __init__(self, _client):

        self.client = _client
        self.playerList = []

        # Visuals
        self.lstLobby = DirectScrolledList(
            decButton_pos= (1.1, 0, -0.45),
            decButton_text = "up",
            decButton_text_scale = 0.06,
            decButton_borderWidth = (0.005, 0.005),

            incButton_pos= (1.1, 0, -0.55),
            incButton_text = "down",
            incButton_text_scale = 0.06,
            incButton_borderWidth = (0.005, 0.005),

            frameSize = (-1.05, 1.20, -1.16, 0.16),
            frameColor = (1,0,0,0.5),
            pos = (-0.075, 0, 0.5),
            numItemsVisible = 10,
            forceHeight = 0.11,
            itemFrame_frameSize = (-1, 1, -1.11, 0.11),
            itemFrame_pos = (0, 0, 0),
            )

        # create a start button
        self.btnStart = DirectButton(
            # Scale and position
            scale = 0.15,
            pos = (1,0,-0.90),
            # Text
            text = "Start",
            # Frame
            # Functionality
            command = self.start)

        # create a back button
        self.btnBack = DirectButton(
            # Scale and position
            scale = 0.15,
            pos = (-1,0,-0.90),
            # Text
            text = "back",
            # Frame
            # Functionality
            command = self.back)
        self.hide()

    def show(self):
        self.lstLobby.show()
        self.btnStart.show()
        self.btnBack.show()

    def hide(self):
        self.lstLobby.hide()
        self.btnStart.hide()
        self.btnBack.hide()

    def start(self):
        #TODO: Send event or whatever to let the other parts know we can
        #      start the game
        pass

    def back(self):
        #TODO: Send event or whatever to let the other parts know we
        #      want to move to the previous menu
        pass

    def updateList(self, newList):
        for item in newList:
            l = DirectLabel(text = item, text_scale=0.1)
            self.lstLobby.addItem(l)
Ejemplo n.º 31
0
class GUI:
	def __init__(self, mainClass):
		self.unitFrame = DirectFrame(frameColor = (0,0,0,0.5), frameSize = (-0.25, 0.25, -1, 1), pos = (0.8, 0, 0))
		self.unitFrame.reparentTo(render2d)
		self.unitFrame.hide()
		
		self.wallFrame = DirectFrame(frameColor = (0,0,0,0.5), frameSize = (-0.25, 0.25, -1, 1), pos = (0.8, 0, 0))
		self.wallFrame.reparentTo(render2d)
	#	self.wallFrame.hide()
		
	#	self.drillWall = DirectButton(text = ('drill wall'), scale = 0.1, command = mainClass.cameraClass.mineWall, extraArgs = [mainClass])
	#	self.drillWall.reparentTo(self.wallFrame)
	#	self.drillWall.setPos(0,0,0.9)
		
		self.drillWall = DirectButton(text = 'Hi', scale = 0.1, command = self.queueMine, extraArgs = [mainClass])
	#	self.drillWall.reparentTo(self.wallFrame)
		self.drillWall.setPos(0,0,0.5)
		self.drillWall.hide()
		
	def hi(self):
		print 'HIII'
		
	def showWall(self, wall, mainClass):
		if (wall.selectable == True):
			
			self.hideUIs()
			self.drillWall.show()
			
		#	if (wall.dig != None):
		#		self.
		
#		uButton1 = DirectButton(text = ('need'), scale = 0.1)
#		uButton1.reparentTo(self.unitFrame)
#		uButton1.setPos(0,0,0.9)
#		
#		uButton2 = DirectButton(text = ('to'), scale = 0.1)
#		uButton2.reparentTo(self.unitFrame)
#		uButton2.setPos(0,0,0.7)
#		
#		uButton3 = DirectButton(text = ('finish'), scale = 0.1)
#		uButton3.reparentTo(self.unitFrame)
#		uButton3.setPos(0,0,0.5)
#		
#		uButton4 = DirectButton(text = ('GUI'), scale = 0.1)
#		uButton4.reparentTo(self.unitFrame)
#		uButton4.setPos(0,0,0.3)
		
		
	
	def unitGUI(self, mainClass, unitnumber):
		self.hideUIs()
		self.unitFrame.show()
	#	if (mainClass.parserClass.unit
	
	def wallGUI(self, mainClass, wallPos):
		pass
	#	self.unitFrame.hide()
	#	self.wallFrame.show()
	#	if (mainClass.mapLoaderClass.tileArray[wallPos[1]][wallPos[0]].drillTime != None):
	#		self.drillWall.show()
	
	def hideUIs(self):
		self.unitFrame.hide()
		
	def queueMine(self, mainClass):
	#	mainClass.cameraClass.clearSelection(mainClass)
		mainClass.priorities.queueMine(mainClass.mouseClass.tileSelected)
Ejemplo n.º 32
0
class CalendarGuiMonth(DirectFrame):
    notify = directNotify.newCategory("CalendarGuiMonth")

    def __init__(
        self,
        parent,
        startingDateTime,
        scale=1.0,
        pos=(0, 0, -0.1),
        dayClickCallback=None,
        onlyFutureDaysClickable=False,
        onlyFutureMonthsClickable=False,
    ):
        self.startDate = startingDateTime
        self.curDate = startingDateTime
        self.dayClickCallback = dayClickCallback
        self.onlyFutureDaysClickable = onlyFutureDaysClickable
        self.onlyFutureMonthsClickable = onlyFutureMonthsClickable
        if self.onlyFutureDaysClickable:
            self.onlyFutureMonthsClickable = True
        DirectFrame.__init__(self, parent=parent, scale=scale, pos=pos)
        self.load()
        self.createGuiObjects()
        self.lastSelectedDate = None
        self.accept("clickedOnDay", self.clickedOnDay)

    def load(self):
        monthAsset = loader.loadModel("phase_4/models/parties/tt_m_gui_sbk_calendar")
        monthAsset.reparentTo(self)
        self.monthLocator = self.find("**/locator_month/locator_month")
        self.weekDayLocators = []
        for weekday in ("sun", "mon", "tue", "wed", "thu", "fri", "sat"):
            weekDayLoc = self.find("**/loc_%s" % weekday)
            self.weekDayLocators.append(weekDayLoc)

        self.dayLocators = []
        for row in xrange(6):
            oneWeek = []
            for col in xrange(7):
                newDayLoc = self.find("**/loc_box_%s_%s" % (row, col))
                oneWeek.append(newDayLoc)

            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.find("**/locator_month_arrowL")
        self.monthRightLocator = self.find("**/locator_month_arrowR")
        self.filterLocator = self.find("**/locator_filter")
        self.filterLocatorArrowUp = self.find("**/locator_filter_arrowTop")
        self.filterLocatorArrowDown = self.find("**/locator_filter_arrowBottom")
        self.yearLocator = self.attachNewNode("yearLocator")
        self.yearLocator.setPos(self.monthLocator, 0, 0, -0.03)

    def createGuiObjects(self):
        self.monthLabel = DirectLabel(
            parent=self.monthLocator,
            relief=None,
            text=TTLocalizer.Months[self.startDate.month],
            text_scale=0.075,
            text_font=ToontownGlobals.getMinnieFont(),
            text_fg=(40 / 255.0, 140 / 255.0, 246 / 255.0, 1.0),
        )
        self.yearLabel = DirectLabel(
            parent=self.yearLocator,
            relief=None,
            text=str(self.startDate.year),
            text_scale=0.03,
            text_font=ToontownGlobals.getMinnieFont(),
            text_fg=(140 / 255.0, 140 / 255.0, 246 / 255.0, 1.0),
        )
        self.weekdayLabels = []
        for posIndex in xrange(7):
            adjustedNameIndex = (posIndex - 1) % 7
            self.weekdayLabels.append(
                DirectLabel(
                    parent=self.weekDayLocators[posIndex],
                    relief=None,
                    text=TTLocalizer.DayNamesAbbrev[adjustedNameIndex],
                    text_font=ToontownGlobals.getInterfaceFont(),
                    text_fg=(255 / 255.0, 146 / 255.0, 113 / 255.0, 1.0),
                    text_scale=0.05,
                )
            )

        self.createGuiDays()
        arrowUp = self.find("**/month_arrowR_up")
        arrowDown = self.find("**/month_arrowR_down")
        arrowHover = self.find("**/month_arrowR_hover")
        self.monthLeftArrow = DirectButton(
            parent=self.monthLeftLocator,
            relief=None,
            image=(arrowUp, arrowDown, arrowHover, arrowUp),
            image3_color=(1, 1, 1, 0.5),
            scale=(-1.0, 1.0, 1.0),
            command=self.__doMonthLeft,
        )
        if self.onlyFutureMonthsClickable:
            self.monthLeftArrow.hide()
        self.monthRightArrow = DirectButton(
            parent=self.monthRightLocator,
            relief=None,
            image=(arrowUp, arrowDown, arrowHover, arrowUp),
            image3_color=(1, 1, 1, 0.5),
            command=self.__doMonthRight,
        )

        def makeLabel(itemName, itemNum, *extraArgs):
            return DirectLabel(text=itemName, frameColor=(0, 0, 0, 0), text_scale=0.04)

        gui = loader.loadModel("phase_4/models/parties/tt_m_gui_sbk_calendar_box")
        arrowUp = gui.find("**/downScroll_up")
        arrowDown = gui.find("**/downScroll_down")
        arrowHover = gui.find("**/downScroll_hover")
        filterLocatorUpPos = self.filterLocatorArrowUp.getPos(self.filterLocator)
        filterLocatorDownPos = self.filterLocatorArrowDown.getPos(self.filterLocator)
        self.filterList = DirectScrolledList(
            parent=self.filterLocator,
            relief=None,
            pos=(0, 0, 0),
            image=None,
            text_scale=0.025,
            incButton_image=(arrowUp, arrowDown, arrowHover, arrowUp),
            incButton_relief=None,
            incButton_pos=filterLocatorDownPos,
            incButton_image3_color=(1, 1, 1, 0.2),
            incButtonCallback=self.filterChanged,
            decButton_image=(arrowUp, arrowDown, arrowHover, arrowUp),
            decButton_relief=None,
            decButton_pos=filterLocatorUpPos,
            decButton_scale=(1, 1, -1),
            decButton_image3_color=(1, 1, 1, 0.2),
            decButtonCallback=self.filterChanged,
            numItemsVisible=1,
            itemMakeFunction=makeLabel,
            items=[
                TTLocalizer.CalendarShowAll,
                TTLocalizer.CalendarShowOnlyHolidays,
                TTLocalizer.CalendarShowOnlyParties,
            ],
            itemFrame_frameSize=(-0.2, 0.2, -0.02, 0.05),
            itemFrame_frameColor=(0, 0, 0, 0),
        )
        gui.removeNode()

    def getTopLeftDate(self):
        firstOfTheMonth = self.curDate.replace(day=1)
        daysAwayFromSunday = (firstOfTheMonth.weekday() - 6) % 7
        topLeftDate = firstOfTheMonth + timedelta(days=-daysAwayFromSunday)
        return topLeftDate

    def createGuiDays(self):
        topLeftDate = self.getTopLeftDate()
        curDate = topLeftDate
        self.guiDays = []
        for row in self.dayLocators:
            for oneLocator in row:
                self.guiDays.append(
                    CalendarGuiDay(
                        oneLocator, curDate, self.curDate, self.dayClickCallback, self.onlyFutureDaysClickable
                    )
                )
                curDate += timedelta(days=1)

    def changeDateForGuiDays(self):
        topLeftDate = self.getTopLeftDate()
        guiDayDate = topLeftDate
        for guiDay in self.guiDays:
            guiDay.changeDate(self.curDate, guiDayDate)
            guiDayDate += timedelta(days=1)

    def changeMonth(self, monthChange):
        if monthChange != 0:
            newMonth = self.curDate.month + monthChange
            newYear = self.curDate.year
            while newMonth > 12:
                newYear += 1
                newMonth -= 12

            while newMonth < 1:
                if newYear - 1 > 2002:
                    newMonth += 12
                    newYear -= 1
                else:
                    newMonth += 1

            self.curDate = datetime(
                newYear,
                newMonth,
                1,
                self.curDate.time().hour,
                self.curDate.time().minute,
                self.curDate.time().second,
                self.curDate.time().microsecond,
                self.curDate.tzinfo,
            )
        self.monthLabel["text"] = (TTLocalizer.Months[self.curDate.month],)
        self.yearLabel["text"] = (str(self.curDate.year),)
        startTime = globalClock.getRealTime()
        self.changeDateForGuiDays()
        endTime = globalClock.getRealTime()
        self.notify.debug("changeDate took %f seconds" % (endTime - startTime))
        self.updateSelectedDate()
        if monthChange != 0:
            if self.onlyFutureMonthsClickable and newMonth == self.startDate.month and newYear == self.startDate.year:
                self.monthLeftArrow.hide()

    def __doMonthLeft(self):
        self.changeMonth(-1)

    def __doMonthRight(self):
        self.monthLeftArrow.show()
        self.changeMonth(1)

    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)

    def clickedOnDay(self, dayDate):
        self.lastSelectedDate = dayDate
        self.updateSelectedDate()

    def updateSelectedDate(self):
        if self.lastSelectedDate:
            for oneGuiDay in self.guiDays:
                oneGuiDay.updateSelected(oneGuiDay.myDate.date() == self.lastSelectedDate)

    def clearSelectedDay(self):
        for oneGuiDay in self.guiDays:
            oneGuiDay.updateSelected(False)

    def filterChanged(self):
        newFilter = self.filterList.getSelectedIndex()
        for guiDay in self.guiDays:
            guiDay.changeFilter(newFilter)
class ExperienceBar(DirectFrame):
    def __init__(self, exp, level, avdna):
        DirectFrame.__init__(self, relief=None, sortOrder=50)
        self.av = None
        self.style = avdna
        if self.style.type == 't':
            self.isToon = 1
        else:
            self.isToon = 0

        self.exp = exp
        self.level = level
        self.maxExp = ToonExperience.ToonExperience().getLevelMaxExp(
            self.level)
        self.expBar = None
        self.__obscured = 0
        self.bgBar = None
        self.levelLabel = None
        self.visToggle = None
        self.levelUpSfx = loader.loadSfx('phase_3.5/audio/sfx/AV_levelup.ogg')
        self.load()

    def load(self):
        if self.isToon:
            self.barGeom = loader.loadModel('phase_3.5/models/gui/exp_bar')
            self.color = self.style.getHeadColor()
            self.bgBar = DirectFrame(parent=base.a2dBottomLeft,
                                     relief=None,
                                     geom=self.barGeom,
                                     pos=(.6, 0, .3),
                                     geom_scale=(0.3, 0.25, 0.1),
                                     geom_color=self.color)
            self.expBar = DirectWaitBar(parent=self.bgBar,
                                        guiId='expBar',
                                        pos=(0.0, 0, 0),
                                        relief=DGG.SUNKEN,
                                        frameSize=(-2.0, 2.0, -0.1, 0.1),
                                        borderWidth=(0.01, 0.01),
                                        scale=0.25,
                                        range=self.maxExp,
                                        sortOrder=50,
                                        frameColor=(0.5, 0.5, 0.5, 0.5),
                                        barColor=(0.0, 1.0, 0.0, 0.5),
                                        text=str(self.exp) + '/' +
                                        str(self.maxExp),
                                        text_scale=0.2,
                                        text_fg=(1, 1, 1, 1),
                                        text_align=TextNode.ACenter,
                                        text_pos=(0, -0.05))
            self.expBar['value'] = self.exp
            if self.level == ToontownGlobals.MaxToonLevel:
                self.expBar['range'] = 1
                self.expBar['value'] = 1
                self.expBar['text'] = 'MAX'
            self.levelLabel = OnscreenText(
                parent=self.bgBar,
                text=TTLocalizer.ExpBarLevel + str(self.level + 1),
                pos=(0.0, 0.05),
                scale=0.05,
                font=ToontownGlobals.getBuildingNametagFont(),
                fg=(1, 1, 1, 1))
            self.levelLabel.hide()
            gui = loader.loadModel('phase_3/models/gui/tt_m_gui_mat_mainGui')
            arrowImage = (gui.find('**/tt_t_gui_mat_shuffleArrowUp'),
                          gui.find('**/tt_t_gui_mat_shuffleArrowDown'),
                          gui.find('**/tt_t_gui_mat_shuffleArrowUp'),
                          gui.find('**/tt_t_gui_mat_shuffleArrowDisabled'))
            self.visToggle = DirectButton(parent=self.bgBar,
                                          relief=None,
                                          geom=arrowImage,
                                          hpr=(0, 0, 0),
                                          pos=(.53, 0, 0),
                                          scale=(0.4, 0.4, 0.4),
                                          command=self.toggleVis)
            if not settings.get('experienceBarMode'):
                self.hide()

    def destroy(self):
        if self.av:
            self.ignore(self.av.uniqueName('toonExpChange'))

        del self.av
        del self.exp
        del self.maxExp
        if self.visToggle:
            self.visToggle.destroy()
            del self.visToggle

        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 updateBar(self, exp, level):
        if level >= ToontownGlobals.MaxToonLevel:
            self.hide()
            return

        if self.__obscured:
            Sequence(Func(self.show), Wait(3), Func(self.hide)).start()

        currExp = self.exp
        self.exp = exp
        currMax = self.maxExp
        currLevel = self.level
        self.level = level
        self.maxExp = ToonExperience.ToonExperience().getLevelMaxExp(
            self.level)
        name = self.av.uniqueName('laffMeterBoing') + '-' + str(self.this)
        if currLevel != self.level:
            self.levelLabel['text'] = TTLocalizer.ExpBarLevel + str(
                self.level + 1)

        if currMax != self.maxExp:
            self.expBar['range'] = self.maxExp
            base.playSfx(self.levelUpSfx)

        self.expBar['range'] = self.maxExp
        self.expBar['value'] = exp
        self.expBar['text'] = str(exp) + '/' + str(self.maxExp)
        ToontownIntervals.start(
            ToontownIntervals.getPulseLargerIval(self.bgBar, name))

    def start(self):
        if self.isToon:
            if self.bgBar:
                self.bgBar.show()

            if self.levelLabel:
                self.levelLabel.show()

            if self.visToggle:
                self.visToggle.show()

            if self.av:
                self.accept(self.av.uniqueName('toonExpChange'),
                            self.updateBar)

    def stop(self):
        if self.isToon:
            if self.bgBar:
                self.bgBar.hide()
            if self.levelLabel:
                self.levelLabel.hide()
            if self.visToggle:
                self.visToggle.hide()
            if self.av:
                self.ignore(self.av.uniqueName('toonExpChange'))

    def setAvatar(self, av):
        if self.av:
            self.ignore(self.av.uniqueName('toonExpChange'))

        self.av = av

    def toggleVis(self):
        if self.__obscured:
            self.show()
        else:
            self.hide()

    def hide(self):
        if self.bgBar:
            self.bgBar.posInterval(0.2,
                                   Point3(-.5, 0, .3),
                                   blendType='easeInOut').start()

        if self.levelLabel:
            self.levelLabel.hide()

        self.visToggle.setHpr(0, 0, 180)
        self.__obscured = 1
        settings['experienceBarMode'] = False

    def show(self):
        if self.bgBar:
            self.bgBar.posInterval(0.2,
                                   Point3(.6, 0, .3),
                                   blendType='easeInOut').start()

        if self.levelLabel:
            self.levelLabel.show()

        self.visToggle.setHpr(0, 0, 0)
        self.__obscured = 0
        settings['experienceBarMode'] = True
Ejemplo n.º 34
0
class GroupTrackerPage(ShtikerPage.ShtikerPage):
    notify = directNotify.newCategory('GroupTrackerPage')

    def __init__(self):
        ShtikerPage.ShtikerPage.__init__(self)
        self.groupWidgets = []
        self.playerWidgets = []
        self.images = []  # image nodes: Possible images to apply on groups
        self.scrollList = None  # DirectScrolledList: Holds the GroupTrackerGroup widgets
        self.scrollTitle = None  # DirectLabel: Title of the list that holds the groups
        self.playerList = None  # DirectScrolledList: Holds players when showing a specific group details
        self.playerListTitle = None  # DirectLabel: Title of the playerList
        self.groupInfoTitle = None  # DirectLabel: holds the group detail title to show on the right
        self.groupInfoDistrict = None  # DirectLabel: shows group detail district on the right
        self.statusMessage = None  # DirectLabel: Shows important messages like Loading... or "No boarding groups available"
        self.groupIcon = None  # DirectButton: Icon to associate with the group ex. sellbot icon or cashbot icon depending on group info
        self.wantGroupToggle = None  # DirectButton: Allows the toon to toggle his listing

    def load(self):
        self.listXorigin = -0.02
        self.listFrameSizeX = 0.67
        self.listZorigin = -0.96
        self.listFrameSizeZ = 1.04
        self.arrowButtonScale = 1.3
        self.itemFrameXorigin = -0.237
        self.itemFrameZorigin = 0.365
        self.buttonXstart = self.itemFrameXorigin + 0.293
        self.gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
        guiButton = loader.loadModel('phase_3/models/gui/quit_button')
        self.scrollList = DirectScrolledList(
            parent=self,
            relief=None,
            pos=(-0.5, 0, 0),
            incButton_image=(self.gui.find('**/FndsLst_ScrollUp'),
                             self.gui.find('**/FndsLst_ScrollDN'),
                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
                             self.gui.find('**/FndsLst_ScrollUp')),
            incButton_relief=None,
            incButton_scale=(self.arrowButtonScale, self.arrowButtonScale,
                             -self.arrowButtonScale),
            incButton_pos=(self.buttonXstart, 0,
                           self.itemFrameZorigin - 0.999),
            incButton_image3_color=Vec4(1, 1, 1, 0.2),
            decButton_image=(self.gui.find('**/FndsLst_ScrollUp'),
                             self.gui.find('**/FndsLst_ScrollDN'),
                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
                             self.gui.find('**/FndsLst_ScrollUp')),
            decButton_relief=None,
            decButton_scale=(self.arrowButtonScale, self.arrowButtonScale,
                             self.arrowButtonScale),
            decButton_pos=(self.buttonXstart, 0,
                           self.itemFrameZorigin + 0.227),
            decButton_image3_color=Vec4(1, 1, 1, 0.2),
            itemFrame_pos=(self.itemFrameXorigin, 0, self.itemFrameZorigin),
            itemFrame_scale=1.0,
            itemFrame_relief=DGG.SUNKEN,
            itemFrame_frameSize=(self.listXorigin,
                                 self.listXorigin + self.listFrameSizeX,
                                 self.listZorigin,
                                 self.listZorigin + self.listFrameSizeZ),
            itemFrame_frameColor=(0.85, 0.95, 1, 1),
            itemFrame_borderWidth=(0.01, 0.01),
            numItemsVisible=15,
            forceHeight=0.065,
            items=self.groupWidgets)

        self.scrollTitle = DirectFrame(parent=self.scrollList,
                                       text=TTLocalizer.GroupTrackerListTitle,
                                       text_scale=0.06,
                                       text_align=TextNode.ACenter,
                                       relief=None,
                                       pos=(self.buttonXstart, 0,
                                            self.itemFrameZorigin + 0.127))

        self.playerList = DirectScrolledList(
            parent=self,
            relief=None,
            pos=(0.45, 0, 0.1),
            incButton_image=(self.gui.find('**/FndsLst_ScrollUp'),
                             self.gui.find('**/FndsLst_ScrollDN'),
                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
                             self.gui.find('**/FndsLst_ScrollUp')),
            incButton_relief=None,
            incButton_scale=(1.0, 1.0, -1.0),
            incButton_pos=(0, 0, -0.28),
            incButton_image3_color=Vec4(1, 1, 1, 0.05),
            decButton_image=(self.gui.find('**/FndsLst_ScrollUp'),
                             self.gui.find('**/FndsLst_ScrollDN'),
                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
                             self.gui.find('**/FndsLst_ScrollUp')),
            decButton_relief=None,
            decButton_scale=(1.0, 1.0, 1.0),
            decButton_pos=(0.0, 0, 0.04),
            decButton_image3_color=Vec4(1, 1, 1, 0.25),
            itemFrame_pos=(0, 0, -0.05),
            itemFrame_scale=1.0,
            itemFrame_relief=DGG.SUNKEN,
            itemFrame_frameSize=(
                -0.3,
                0.3,  #x
                -0.2,
                0.06),  #z
            itemFrame_frameColor=(0.85, 0.95, 1, 1),
            itemFrame_borderWidth=(0.01, 0.01),
            numItemsVisible=4,
            forceHeight=0.05,
            items=self.playerWidgets)

        self.playerListTitle = DirectFrame(parent=self.playerList,
                                           text='',
                                           text_scale=0.05,
                                           text_align=TextNode.ACenter,
                                           relief=None,
                                           pos=(0, 0, 0.08))
        self.groupInfoTitle = DirectLabel(parent=self,
                                          text='',
                                          text_scale=0.080,
                                          text_align=TextNode.ACenter,
                                          text_wordwrap=15,
                                          relief=None,
                                          pos=(0.45, 0, 0.5))
        self.groupInfoDistrict = DirectLabel(parent=self,
                                             text='',
                                             text_scale=0.050,
                                             text_align=TextNode.ACenter,
                                             text_wordwrap=15,
                                             relief=None,
                                             pos=(0.45, 0, 0.4))

        self.statusMessage = DirectLabel(parent=self,
                                         text='',
                                         text_scale=0.060,
                                         text_align=TextNode.ACenter,
                                         text_wordwrap=5,
                                         relief=None,
                                         pos=(0.45, 0, 0.1))

        # Group Image:
        self.groupIcon = DirectButton(parent=self,
                                      relief=None,
                                      state=DGG.DISABLED,
                                      image=None,
                                      image_scale=(0.35, 1, 0.35),
                                      image_color=Vec4(1.0, 1.0, 1.0, 0.75),
                                      pos=(0.45, 10, -0.45),
                                      command=self.doNothing)

        # Group Toggle:
        self.wantGroupToggle = DirectButton(
            parent=self,
            relief=None,
            image=(guiButton.find('**/QuitBtn_UP'),
                   guiButton.find('**/QuitBtn_DN'),
                   guiButton.find('**/QuitBtn_RLVR')),
            image_scale=(0.7, 1, 1),
            text='',
            text_scale=0.052,
            text_pos=(0, -0.02),
            pos=(0.2, 0, -0.65),
            command=self.toggleWantGroup)
        self.updateWantGroupButton()

        # Loading possible group icons
        suitIcons = loader.loadModel('phase_3/models/gui/cog_icons')
        bossbotIcon = suitIcons.find('**/CorpIcon')
        bossbotIcon.setColor(SUIT_ICON_COLORS[0])
        self.images.append(bossbotIcon)

        lawbotIcon = suitIcons.find('**/LegalIcon')
        lawbotIcon.setColor(SUIT_ICON_COLORS[1])
        self.images.append(lawbotIcon)

        cashbotIcon = suitIcons.find('**/MoneyIcon')
        cashbotIcon.setColor(SUIT_ICON_COLORS[2])
        self.images.append(cashbotIcon)

        sellbotIcon = suitIcons.find('**/SalesIcon')
        sellbotIcon.setColor(SUIT_ICON_COLORS[3])
        self.images.append(sellbotIcon)

        # Clean up
        self.clearGroupInfo()
        self.statusMessage.hide()

        suitIcons.removeNode()
        self.gui.removeNode()
        guiButton.removeNode()

        self.accept('GroupTrackerResponse', self.updatePage)

    def unload(self):
        self.scrollList.destroy()
        self.groupInfoDistrict.destroy()
        self.playerList.destroy()
        self.groupInfoTitle.destroy()
        self.groupIcon.destroy()
        self.wantGroupToggle.destroy()
        for widget in self.playerWidgets:
            widget.destroy()
        for widget in self.groupWidgets:
            widget.destroy()
        self.playerWidgets = []

        del self.scrollList
        del self.groupInfoDistrict
        del self.playerList
        del self.groupInfoTitle
        del self.groupIcon
        del self.wantGroupToggle
        ShtikerPage.ShtikerPage.unload(self)

    def enter(self):
        ShtikerPage.ShtikerPage.enter(self)
        self.setGroups([])  # CLEAR IT ALL
        self.setPlayers()  # CLEAR IT ALL
        if (self.scrollList['items'] == []):
            self.statusMessage['text'] = TTLocalizer.GroupTrackerLoading
            self.statusMessage.show()
        base.cr.globalGroupTracker.requestGroups()
        taskMgr.doMethodLater(3, self.displayNoGroupsTaskHandler,
                              self.uniqueName('timeout'))

    def displayNoGroups(self):
        self.statusMessage['text'] = TTLocalizer.GroupTrackerEmpty
        self.statusMessage.show()
        self.clearGroupInfo()

    def displayNoGroupsTaskHandler(self, task):
        self.displayNoGroups()
        return task.done

    def updatePage(self):
        taskMgr.remove(self.uniqueName('timeout'))
        groups = base.cr.globalGroupTracker.getGroupInfo()
        self.setGroups(groups)

    def exit(self):
        self.clearGroupInfo()
        ShtikerPage.ShtikerPage.exit(self)
        base.cr.globalGroupTracker.doneRequesting()

    def updateGroupInfoEventHandle(self, groupWidget, mouseEvent):
        self.updateGroupInfo(groupWidget)

    def updateGroupInfo(self, groupWidget):
        ''' Updates the Right Page of the Group Tracker Page with new Info '''
        self.statusMessage.hide()

        # Update the Player List
        self.setPlayers(groupWidget)
        self.playerList.show()

        # Update the Player List Title
        self.playerListTitle['text'] = ('Players ' +
                                        str(groupWidget.getCurrentPlayers()) +
                                        '/' +
                                        str(groupWidget.getMaxPlayers()) + ':')
        self.playerListTitle.show()

        # Update the District
        self.groupInfoDistrict[
            'text'] = TTLocalizer.BoardingGroupDistrictInformation % {
                'district': groupWidget.getDistrict()
            }
        self.groupInfoDistrict.show()

        # Update the Title
        self.groupInfoTitle['text'] = groupWidget.getTitle()
        self.groupInfoTitle.show()

        # Update the Image
        self.groupIcon['image'] = self.images[
            GroupTrackerGlobals.CATEGORY_TO_IMAGE_ID[
                groupWidget.getCategory()]]
        self.groupIcon['image_scale'] = (0.35, 1, 0.35)
        self.groupIcon.show()

    def clearGroupInfo(self):
        self.playerList.hide()
        self.playerListTitle.hide()
        self.groupInfoDistrict.hide()
        self.groupInfoTitle.hide()
        self.groupIcon.hide()

    def setPlayers(self, groupWidget=None):
        ''' Calls updatePlayerList '''

        # Clear the Widgets that were held in the listings
        for playerWidget in self.playerWidgets:
            playerWidget.destroy()
        self.playerWidgets = []

        # Make a player widget for each player
        # TODO: Edit this stuff when avIds come from players
        if groupWidget:
            leaderId = groupWidget.getLeaderId()
            playerNames = groupWidget.getMemberNames()
            playerIds = groupWidget.getMemberIds()
            for playerName in playerNames:
                playerId = playerIds[playerNames.index(playerName)]
                isLeader = playerId == leaderId
                self.playerWidgets.append(
                    GroupTrackerPlayer(parent=self,
                                       avId=playerId,
                                       name=playerName,
                                       isLeader=isLeader))

        self.updatePlayerList()

    def reconsiderGroupInfo(self, groupWidget):
        ''' If someone is viewing this info and it was updated, we also want to update the info being viewed '''
        if self.playerWidgets is None or self.playerList['items'] == []:
            return  # No Info is being viewed at the moment since you cant have an empty group

        # We have to update if this group's leader is the leader in the playerlist being viewed right now
        leaderId = groupWidget.getLeaderId()

        # Check all the players in the playerList being viewed for the same leader
        for playerWidget in self.playerWidgets:
            if playerWidget.getLeader():
                if leaderId == playerWidget.getId():
                    self.updateGroupInfo(groupWidget)
                    return False

        return True

    def setGroups(self, groups):
        ''' Calls updateGroupList '''

        # Clear our Group Widgets
        for group in self.groupWidgets:
            group.destroy()
        self.groupWidgets = []

        wantReconsiderInfo = True

        # Create a new group widget for each group
        for group in groups:
            if not group[GroupTrackerGlobals.SHOW] or len(
                    group[GroupTrackerGlobals.MEMBER_IDS]) == 0:
                continue  # We are using this to see if this group is dead or if someone doesnt want it up
            leaderId = 0
            for i, g in base.cr.globalGroupTracker.leader2Group.items():
                if g == group:
                    leaderId = i
            if not leaderId:
                continue

            leaderName = group[GroupTrackerGlobals.LEADER_NAME]
            shardName = group[GroupTrackerGlobals.SHARD_NAME]
            category = group[GroupTrackerGlobals.CATEGORY]
            memberIds = group[GroupTrackerGlobals.MEMBER_IDS]
            memberNames = group[GroupTrackerGlobals.MEMBER_NAMES]

            groupWidget = GroupTrackerGroup(parent=self,
                                            leaderId=leaderId,
                                            leaderName=leaderName,
                                            shardName=shardName,
                                            category=category,
                                            memberIds=memberIds,
                                            memberNames=memberNames)
            groupWidget.bind(DGG.WITHIN,
                             self.updateGroupInfoEventHandle,
                             extraArgs=[groupWidget])
            self.groupWidgets.append(groupWidget)
            if wantReconsiderInfo:
                wantReconsiderInfo = self.reconsiderGroupInfo(groupWidget)

        # Edge case where a group that was removed, info might remain on the screen if it didn't exist any more
        if wantReconsiderInfo:
            self.clearGroupInfo()

        # There are no groups, hide the information
        if len(self.groupWidgets) == 0:
            self.displayNoGroups()
        self.updateGroupList()

    def updateGroupList(self):
        self.statusMessage.hide()
        if self.scrollList is None:
            return

        # Clear the Group Listing
        for item in self.scrollList['items']:
            if item:
                self.scrollList.removeItem(item, refresh=True)
        self.scrollList['items'] = []

        # Re-populate the Group Listing
        for groupWidget in self.groupWidgets:
            self.scrollList.addItem(groupWidget, refresh=True)

        if len(self.groupWidgets) == 0:
            self.displayNoGroups()

    def updatePlayerList(self):
        if self.playerList is None:
            return

        # Clear the Player Listing
        for item in self.playerList['items']:
            if item:
                self.playerList.removeItem(item)
        self.playerList['items'] = []

        # Re-Populate the List
        for playerWidget in self.playerWidgets:
            self.playerList.addItem(playerWidget)

    def toggleWantGroup(self):
        if settings.get('grouptracker', False):
            settings['grouptracker'] = False
            base.cr.globalGroupTracker.showMe(False)
        else:
            settings['grouptracker'] = True
            base.cr.globalGroupTracker.showMe(True)

        base.localAvatar.wantGroupTracker()

        base.localAvatar.wantGroupTracker(
        )  # Updates the ai toon so the boarding group AI could know what he wants
        self.updateWantGroupButton()

    def updateWantGroupButton(self):
        if settings.get('grouptracker', False):
            self.wantGroupToggle['text'] = 'Hide Me'
        else:
            self.wantGroupToggle['text'] = 'Show Me'

    def doNothing(self):
        pass
Ejemplo n.º 35
0
class Scenario:
    """The game scenario orchestrator.

    Tracks on which part of the scenario the player is, controls
    the next scenario steps and performs choice consequences effects.

    One scenario chapter includes a situation in which the player
    has to make a decision. Decision will have consequences, positive
    or negative, but in any case the player will become one step
    closer to figuring out the way to survive the Stench. After
    every chapter the player will also get a note written in a
    diary fashion. The note will give the player more info about
    the Stench, Captain, the Adjutant and how the cataclysm
    started to destroy the World.

    Args:
        current_chapter (int): The chapter number to start with.
    """
    def __init__(self, current_chapter=None):
        if current_chapter is not None:  # saved game
            self.current_chapter = current_chapter
        else:  # game start
            self.current_chapter = -1

        self._list = DirectFrame(
            frameSize=(-0.73, 0.73, -0.9, 0.9),
            frameTexture=GUI_PIC + "paper1.png",
            state=DGG.NORMAL,
        )
        self._list.setDepthTest(False)
        self._list.setTransparency(TransparencyAttrib.MAlpha)
        self._list.hide()

        self._name = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.05,
            pos=(-0.4, 0, 0.7),
        )
        self._type = DirectLabel(
            parent=self._list,
            text=base.labels.SCENARIO_LABELS[1],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.4, 0.4, 0.4, 0.4),
            text_scale=0.035,
            pos=(-0.13, 0, 0.699),
        )
        self._desc = DirectLabel(
            parent=self._list,
            text="",
            text_font=base.main_font,  # noqa: F821
            frameSize=(0.6, 0.6, 0.6, 0.6),
            text_scale=0.037,
            pos=(0, 0, 0.55),
        )

        self._buts = []
        z_coor = -0.6
        for _ in range(3):
            self._buts.append(
                DirectButton(
                    parent=self._list,
                    text="Text",
                    text_font=base.main_font,  # noqa: F821
                    text_fg=RUST_COL,
                    text_shadow=(0, 0, 0, 1),
                    frameColor=(0, 0, 0, 0),
                    frameSize=(-9, 9, -0.3, 0.7),
                    scale=(0.047, 0, 0.047),
                    clickSound=base.main_menu.click_snd,  # noqa: F821
                    pos=(0, 0, z_coor),
                ))
            z_coor -= 0.08

        self._done_but = DirectButton(
            parent=self._list,
            text=base.labels.DISTINGUISHED[6],  # noqa: F821
            text_font=base.main_font,  # noqa: F821
            text_fg=RUST_COL,
            text_shadow=(0, 0, 0, 1),
            frameColor=(0, 0, 0, 0),
            frameSize=(-9, 9, -0.3, 0.7),
            scale=(0.05, 0, 0.05),
            clickSound=base.main_menu.click_snd,  # noqa: F821
            pos=(0, 0, -0.8),
            command=self.hide_chapter,
        )

    def _choose_variant(self, var):
        """Process the player's choice and do consequences.

        Args:
            var (str): Variant id.
        """
        consequences = base.labels.SCENARIO[
            self.current_chapter][  # noqa: F821
                "variants"][var]
        for but in self._buts:
            but.hide()

        self._desc["text"] = consequences["desc"]
        for effect in consequences["effects"]:
            getattr(self, effect[0])(*effect[1])

        base.journal.add_page(self.current_chapter)  # noqa: F821
        self._done_but.show()
        base.res_gui.update_resource(  # noqa: F821
            "places_of_interest",
            str(self.current_chapter + 1) + "/10")

        base.decisions["decision_" + str(self.current_chapter)] = {  # noqa: F821
            "decision": var,
            "goodness": consequences["goodness"],
        }

    def finish_game(self):
        """Completely finish the game."""
        self.hide_chapter()
        taskMgr.doMethodLater(  # noqa: F821
            1,
            base.effects_mgr.fade_out_screen,
            "fade_out"  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            4,
            base.main_menu.show_credits,
            "show_credits",  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            4.5,
            base.effects_mgr.fade_in_screen,
            "fade_in"  # noqa: F821
        )
        taskMgr.doMethodLater(  # noqa: F821
            76,
            base.restart_game,
            "restart_game",
            extraArgs=[]  # noqa: F821
        )
        base.train.ctrl.unset_controls()  # noqa: F821
        base.effects_mgr.stench_effect.stop()  # noqa: F821

        for task in (
                "update_physics",
                "sun_look_at_train",
                "collide_mouse",
                "move_camera_with_mouse",
                "update_speed_indicator",
                "disease",
                "show_teaching_note",
                "calc_cohesion",
                "track_ambient_sounds",
                "stench_step",
                "check_train_contacts",
                "change_sun_color",
        ):
            base.taskMgr.remove(task)  # noqa: F821

        base.sound_mgr.disable()  # noqa: F821
        base.world.drown_ambient_snds()  # noqa: F821

    def do_build_camp_effect(self):
        """Do effects for building a camp for orphans choice."""
        base.helped_children = True  # noqa: F821

    def do_spend_cohesion(self, value):
        """Do effect of decreasing the crew cohesion.

        Args:
            value (int): The amount of the cohesion change.
        """
        base.team.spend_cohesion(value)  # noqa: F821

    def do_get_money(self, money):
        """Get or lose the given amount of money.

        Args:
            money (int): Money amount to get/lose.
        """
        base.dollars += money  # noqa: F821

    def do_plus_resource(self, name, value):
        """Change the given resource amount.

        Args:
            name (str): Resource name.
            value (int): Amount delta.
        """
        base.plus_resource(name, value)  # noqa: F821

    def do_enemy_inc_effect(self):
        """Make enemy stronger effect."""
        base.world.enemy.score += 3  # noqa: F821

    def do_character_effect(self, char, effect):
        """Do choice consequences effect to the given character.

        Args:
            char (units.crew.character.Character):
                The character to do effect to.
            effect (dict): The effect description.
        """
        for key, value in effect.items():
            setattr(char, key, getattr(char, key) + value)

    def do_characters_effect(self, effect, to_one=False):
        """Do choice consequences effects to the crew.

        Args:
            effect (dict): Effect description.
            to_one (bool): Effect targets only one random character.
        """
        if to_one:
            self.do_character_effect(
                random.choice(list(base.team.chars.values())),
                effect  # noqa: F821
            )
            return

        for char in base.team.chars.values():  # noqa: F821
            self.do_character_effect(char, effect)

    def do_locomotive_damage(self, damage):
        """Do some damage to the Adjutant.

        Args:
            damage (int): Amount of damage to do.
        """
        base.train.get_damage(damage)  # noqa: F821

    def do_no_effect(self):
        """No choice consequences method."""
        pass

    def do_stench_moves_effect(self, steps):
        """Move the Stench frontier several miles deeper into the Silewer.

        Args:
            steps (int): Number of miles to cover with the Stench.
        """
        for _ in range(steps):
            base.world.make_stench_step()  # noqa: F821

    def do_transfusion_effect(self):
        """Do blood transfusion effect of Chapter 9."""
        char = None
        chars = list(base.team.chars.values())  # noqa: F821

        if chars:
            char = take_random(chars)
            char.health -= 30

        if chars:
            take_random(chars).health -= 30
        elif char:
            char.health -= 30

    def do_medicine_save(self):
        """Do save with medicines effect of Chapter 9."""
        if base.resource("medicine_boxes"):  # noqa: F821
            base.plus_resource("medicine_boxes", -1)  # noqa: F821
        else:
            chars = list(base.team.chars.values())  # noqa: F821
            if chars:
                take_random(chars).energy -= 40

    def hide_chapter(self):
        """Hide the scenario GUI."""
        self._list.hide()

    def start_chapter(self, task):
        """Start a new scenario chapter."""
        self.current_chapter += 1

        base.train.ctrl.set_controls(base.train)  # noqa: F821
        base.camera_ctrl.enable_ctrl_keys()  # noqa: F821

        base.world.outings_mgr.hide_outing()  # noqa: F821
        base.traits_gui.hide()  # noqa: F821

        if self.current_chapter <= 9:
            self.show_chapter_situation()  # noqa: F821

            base.world.drop_place_of_interest()  # noqa: F821

        return task.done

    def show_chapter_situation(self):
        """Show the situation description and the possible variants."""
        self._done_but.hide()
        self._name[
            "text"] = base.labels.SCENARIO_LABELS[0] + str(  # noqa: F821
                self.current_chapter + 1)
        self._desc["text"] = base.labels.SCENARIO[
            self.current_chapter][  # noqa: F821
                "intro"]

        if (len(base.labels.SCENARIO[self.current_chapter]
                ["variants"])  # noqa: F821
                == 3):
            for index, var in enumerate(base.labels.SCENARIO[
                    self.current_chapter]["variants"]  # noqa: F821
                                        ):
                self._buts[index]["text"] = var
                self._buts[index]["extraArgs"] = [var]
                self._buts[index]["command"] = self._choose_variant
                self._buts[index].show()
        else:
            self._buts[0].hide()
            self._buts[1].hide()

            for var in base.labels.SCENARIO[
                    self.current_chapter][  # noqa: F821
                        "variants"]:
                self._buts[2]["text"] = var
                self._buts[2]["extraArgs"] = [var]
                self._buts[2]["command"] = self._choose_variant
                self._buts[2].show()

            self._done_but["command"] = self.finish_game

        self._list.show()
Ejemplo n.º 36
0
    def _createButtons(self, cfg):
        '''
        Creates DirectGui elements for displaying the paging and scrolling buttons.
        The sprite names are read from the configuration.
        The create DirectButtons use sprites as images.
        @param cfg: a ConfigVars instance
        '''
        # button to display next page of items
        nxPgBtnSprite = cfg.get(PanoConstants.CVAR_INVENTORY_NEXTPAGE_SPRITE)
        nxPgBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_NEXTPAGE_PRESSED_SPRITE)
        nxPgBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_NEXTPAGE_HOVER_SPRITE)
        nxPgBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_NEXTPAGE_POS)

        # button to display previous page of items
        pvPgBtnSprite = cfg.get(PanoConstants.CVAR_INVENTORY_PREVPAGE_SPRITE)
        pvPgBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_PREVPAGE_PRESSED_SPRITE)
        pvPgBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_PREVPAGE_HOVER_SPRITE)
        pvPgBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_PREVPAGE_POS)

        # button to scroll to next items
        scrNxBtnSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLNEXT_SPRITE)
        scrNxBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLNEXT_PRESSED_SPRITE)
        scrNxBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLNEXT_HOVER_SPRITE)
        scrNxBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_SCROLLNEXT_POS)

        # button to scroll to previous items
        scrPvBtnSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLPREV_SPRITE)
        scrPvBtnPressedSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLPREV_PRESSED_SPRITE)
        scrPvBtnHoverSprite = cfg.get(
            PanoConstants.CVAR_INVENTORY_SCROLLPREV_HOVER_SPRITE)
        scrPvBtnPos = cfg.getVec2(PanoConstants.CVAR_INVENTORY_SCROLLPREV_POS)

        sprites = self.game.getView().getSpritesFactory()
        origin = aspect2d.getRelativePoint(screen2d, VBase3(0, 0, 0))

        # for every button define property name, position, callback, list of sprites for normal, pressed and hover state
        pagingButtons = [
            ('nextPageButton', nxPgBtnPos, self._nextPageCallback,
             [(nxPgBtnSprite, 'next_page_sprite'),
              (nxPgBtnPressedSprite, 'next_page_pressed_sprite'),
              (nxPgBtnHoverSprite, 'next_page_hover_sprite')]),
            ('prevPageButton', pvPgBtnPos, self._previousPageCallback,
             [(pvPgBtnSprite, 'previous_page_sprite'),
              (pvPgBtnPressedSprite, 'previous_page_pressed_sprite'),
              (pvPgBtnHoverSprite, 'previous_page_hover_sprite')]),
            ('scrollNextButton', scrNxBtnPos, self._scrollNextCallback,
             [(scrNxBtnSprite, 'scroll_next_sprite'),
              (scrNxBtnPressedSprite, 'scroll_next_pressed_sprite'),
              (scrNxBtnHoverSprite, 'scroll_next_hover_sprite')]),
            ('scrollPrevButton', scrPvBtnPos, self._scrollPreviousCallback,
             [(scrPvBtnSprite, 'scroll_previous_sprite'),
              (scrPvBtnPressedSprite, 'scroll_previous_pressed_sprite'),
              (scrPvBtnHoverSprite, 'scroll_previous_hover_sprite')]),
        ]

        for buttonName, buttonPos, buttonCallback, spritesList in pagingButtons:
            buttonGeoms = [None, None, None, None]
            btnScrBounds = [0, 0, 0]
            i = 0
            for spriteFile, spriteName in spritesList:
                print 'adding sprite %s' % spriteName
                if spriteFile is not None:
                    spr = None
                    if spriteFile.rindex('.') >= 0:
                        ext = spriteFile[spriteFile.rindex('.'):]
                        print ext
                        if ResourcesTypes.isExtensionOfType(
                                ext, PanoConstants.RES_TYPE_IMAGES):
                            spr = Sprite(spriteName)
                            spr.image = spriteFile
                    else:
                        spr = self.game.getResources().loadSprite(spriteFile)

                    if spr:
                        buttonGeoms[i] = sprites.createSprite(spr).nodepath
                        buttonGeoms[i].setScale(1.0)
                        btnScrBounds = aspect2d.getRelativePoint(
                            screen2d, VBase3(spr.width, 1.0,
                                             spr.height)) - origin
                        btnScrBounds[2] *= -1

                i += 1

            if buttonGeoms[0] is not None:
                b = DirectButton(
                    geom=(buttonGeoms[0],
                          buttonGeoms[1] if buttonGeoms[1] else buttonGeoms[0],
                          buttonGeoms[2] if buttonGeoms[2] else buttonGeoms[0],
                          buttonGeoms[3]
                          if buttonGeoms[3] else buttonGeoms[0]),
                    relief=None)
                b['geom_pos'] = (0, 0, 0)
                b.setTransparency(1)

                # if position is omitted from the configuration, put the button on the upper left corner
                if buttonPos is not None:
                    b.setPos(
                        aspect2d.getRelativePoint(
                            screen2d, VBase3(buttonPos[0], 1.0, buttonPos[1])))
                else:
                    b.setPos(origin[0], 1.0, origin[2])

                b.setScale(btnScrBounds[0], 1.0, btnScrBounds[2])
                b.setFrameSize((0, btnScrBounds[0], 1.0, btnScrBounds[2]))
                b['command'] = buttonCallback
                b['extraArgs'] = (self.msn, )
                b.hide()
            else:
                b = None

            setattr(self, buttonName, b)
Ejemplo n.º 37
0
class DirectWindow( DirectFrame ):
  def __init__( self,
                pos              = ( -.5, .5),
                title            = 'Title',
                curSize          = ( 1, 1),
                maxSize          = ( 1, 1 ),
                minSize          = ( .5, .5 ),
                backgroundColor  = ( 1, 1, 1, 1 ),
                borderColor      = ( 1, 1, 1, 1 ),
                titleColor       = ( 1, 1, 1, 1 ),
                borderSize       = 0.04,
                titleSize        = 0.06,
                closeButton      = False,
                windowParent     = aspect2d,
                preserve         = True,
                preserveWhole      = True,
              ):
    self.preserve = preserve
    self.preserveWhole = preserveWhole
    self.windowParent = windowParent
    self.windowPos = pos
    DirectFrame.__init__( self,
        parent       = windowParent,
        pos          = ( self.windowPos[0], 0, self.windowPos[1] ),
        frameColor  = ( 0, 0, 0, 0 ),
        frameTexture = loader.loadTexture( DIRECTORY+'transparent.png' )
      )
    self.setTransparency(True)
   
    # the title part of the window, drag around to move the window
    self.headerHeight = titleSize
    h = -self.headerHeight
    self.windowHeaderLeft = DirectButton(
        parent       = self,
        frameTexture = DEFAULT_TITLE_GEOM_LEFT,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        relief       = DGG.FLAT,
        frameColor   = titleColor,
      )
    self.windowHeaderCenter = DirectButton(
        parent       = self,
        frameTexture = DEFAULT_TITLE_GEOM_CENTER,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        relief       = DGG.FLAT,
        frameColor   = titleColor,
      )
    if closeButton:
      rightTitleGeom = DEFAULT_TITLE_GEOM_RIGHT_CLOSE
      command = self.destroy
    else:
      rightTitleGeom = DEFAULT_TITLE_GEOM_RIGHT
      command = None
    self.windowHeaderRight = DirectButton(
        parent       = self,
        frameTexture = rightTitleGeom,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        relief       = DGG.FLAT,
        frameColor   = titleColor,
        command      = command
      )
   
    self.windowHeaderLeft.setTransparency(True)
    self.windowHeaderCenter.setTransparency(True)
    self.windowHeaderRight.setTransparency(True)
   
    self.windowHeaderLeft.bind( DGG.B1PRESS, self.startWindowDrag )
    self.windowHeaderCenter.bind( DGG.B1PRESS, self.startWindowDrag )
    self.windowHeaderRight.bind( DGG.B1PRESS, self.startWindowDrag )
   
    # this is not handled correctly, if a window is dragged which has been
    # created before another it will not be released
    # check the bugfixed startWindowDrag function
    #self.windowHeader.bind(DGG.B1RELEASE,self.stopWindowDrag)
   
    text = TextNode('WindowTitleTextNode')
    text.setText(title)
    text.setAlign(TextNode.ACenter)
    text.setTextColor( 0, 0, 0, 1 )
    text.setShadow(0.05, 0.05)
    text.setShadowColor( 1, 1, 1, 1 )
    self.textNodePath = self.attachNewNode(text)
    self.textNodePath.setScale(self.headerHeight*0.8)
   
    # the content part of the window, put stuff beneath
    # contentWindow.getCanvas() to put it into it
    self.maxVirtualSize = maxSize
    self.minVirtualSize = minSize
    self.resizeSize     = borderSize
    self.contentWindow = DirectScrolledFrame(
        parent                                  = self,
        pos                                     = ( 0, 0, -self.headerHeight ),
        canvasSize                              = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
        frameColor                              = ( 0, 0, 0, 0), # defines the background color of the resize-button
        relief                                  = DGG.FLAT,
        borderWidth                             = (0, 0),
        verticalScroll_frameSize                = [0, self.resizeSize, 0, 1],
        horizontalScroll_frameSize              = [0, 1, 0, self.resizeSize],
       
        # resize the scrollbar according to window size
        verticalScroll_resizeThumb              = False,
        horizontalScroll_resizeThumb            = False,
        # define the textures for the scrollbars
        verticalScroll_frameTexture             = VERTICALSCROLL_FRAMETEXTURE,
        verticalScroll_incButton_frameTexture   = VERTICALSCROLL_INCBUTTON_FRAMETEXTURE,
        verticalScroll_decButton_frameTexture   = VERTICALSCROLL_DECBUTTON_FRAMETEXTURE,
        verticalScroll_thumb_frameTexture       = VERTICALSCROLL_TUMB_FRAMETEXTURE,
        horizontalScroll_frameTexture           = HORIZONTALSCROLL_FRAMETEXTURE,
        horizontalScroll_incButton_frameTexture = HORIZONTALSCROLL_INCBUTTON_FRAMETEXTURE,
        horizontalScroll_decButton_frameTexture = HORIZONTALSCROLL_DECBUTTON_FRAMETEXTURE,
        horizontalScroll_thumb_frameTexture     = HORIZONTALSCROLL_TUMB_FRAMETEXTURE,
        # make all flat, so the texture is as we want it
        verticalScroll_relief                   = DGG.FLAT,
        verticalScroll_thumb_relief             = DGG.FLAT,
        verticalScroll_decButton_relief         = DGG.FLAT,
        verticalScroll_incButton_relief         = DGG.FLAT,
        horizontalScroll_relief                 = DGG.FLAT,
        horizontalScroll_thumb_relief           = DGG.FLAT,
        horizontalScroll_decButton_relief       = DGG.FLAT,
        horizontalScroll_incButton_relief       = DGG.FLAT,
        # colors
        verticalScroll_frameColor               = borderColor,
        verticalScroll_incButton_frameColor     = borderColor,
        verticalScroll_decButton_frameColor     = borderColor,
        verticalScroll_thumb_frameColor         = borderColor,
        horizontalScroll_frameColor             = borderColor,
        horizontalScroll_incButton_frameColor   = borderColor,
        horizontalScroll_decButton_frameColor   = borderColor,
        horizontalScroll_thumb_frameColor       = borderColor,
      )
    self.contentWindow.setTransparency(True)


    # background color
    self.backgroundColor = DirectFrame(
        parent       = self.contentWindow.getCanvas(),
        frameSize    = ( 0, self.maxVirtualSize[0], 0, self.maxVirtualSize[1] ),
        frameColor   = backgroundColor,
        relief       = DGG.FLAT,
        borderWidth  = ( .01, .01),
      )
    self.backgroundColor.setTransparency(True)

    # Add a box
    self.box = boxes.VBox(parent = self.getCanvas())

   
    # is needed for some nicer visuals of the resize button (background)
    self.windowResizeBackground = DirectButton(
        parent       = self,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        scale        = ( self.resizeSize, 1, self.resizeSize ),
        relief       = DGG.FLAT,
        frameColor   = backgroundColor,
      )

    # the resize button of the window
    self.windowResize = DirectButton(
        parent       = self,
        frameSize    = ( -.5, .5, -.5, .5 ),
        borderWidth  = ( 0, 0 ),
        scale        = ( self.resizeSize, 1, self.resizeSize ),
        relief       = DGG.FLAT,
        frameTexture = DEFAULT_RESIZE_GEOM,
        frameColor   = borderColor,
      )
    self.windowResize.setTransparency(True)
    self.windowResize.bind(DGG.B1PRESS,self.startResizeDrag)
    self.windowResize.bind(DGG.B1RELEASE,self.stopResizeDrag)
   
    # offset then clicking on the resize button from the mouse to the resizebutton
    # position, required to calculate the position / scaling
    self.offset = None
    self.taskName = "resizeTask-%s" % str(hash(self))
   
    # do sizing of the window (minimum)
    #self.resize( Vec3(0,0,0), Vec3(0,0,0) )
    # maximum
    #self.resize( Vec3(100,0,-100), Vec3(0,0,0) )
    self.resize( Vec3(curSize[0], 0, -curSize[1]), Vec3(0,0,0))
 
  def getCanvas(self):
    return self.contentWindow.getCanvas()
 
  # dragging functions
  def startWindowDrag( self, param ):
    self.wrtReparentTo( aspect2dMouseNode )
    self.ignoreAll()
    self.accept( 'mouse1-up', self.stopWindowDrag )
  def stopWindowDrag( self, param=None ):
    # this is called 2 times (bug), so make sure it's not already parented to aspect2d
    if self.getParent() != self.windowParent:
      self.wrtReparentTo( self.windowParent )
    if self.preserve:
        if self.preserveWhole:
            if self.getZ() > 1:
                self.setZ(1)
            elif self.getZ() < -1 - self.getHeight():
                self.setZ(-1 - self.getHeight())
            if self.getX() > base.a2dRight - self.getWidth():
                self.setX(base.a2dRight - self.getWidth())
            elif self.getX() < base.a2dLeft:
                self.setX(base.a2dLeft)
        else:
            if self.getZ() > 1:
                self.setZ(1)
            elif self.getZ() < -1 + self.headerHeight:
                self.setZ(-1 + self.headerHeight)
            if self.getX() > base.a2dRight - self.headerHeight:
                self.setX(base.a2dRight - self.headerHeight)
            elif self.getX() < base.a2dLeft + self.headerHeight - self.getWidth():
                self.setX(base.a2dLeft + self.headerHeight - self.getWidth())
    #else: #Window moved beyond reach. Destroy window?
  # resize functions
  def resize( self, mPos, offset ):
    mXPos = max( min( mPos.getX(), self.maxVirtualSize[0] ), self.minVirtualSize[0])
    mZPos = max( min( mPos.getZ(), -self.minVirtualSize[1] ), -self.maxVirtualSize[1]-self.headerHeight)
    self.windowResize.setPos( mXPos-self.resizeSize/2., 0, mZPos+self.resizeSize/2. )
    self.windowResizeBackground.setPos( mXPos-self.resizeSize/2., 0, mZPos+self.resizeSize/2. )
    self['frameSize'] = (0, mXPos, 0, mZPos)
    self.windowHeaderLeft.setPos( self.headerHeight/2., 0, -self.headerHeight/2. )
    self.windowHeaderLeft.setScale( self.headerHeight, 1, self.headerHeight )
    self.windowHeaderCenter.setPos( mXPos/2., 0, -self.headerHeight/2. )
    self.windowHeaderCenter.setScale( mXPos - self.headerHeight*2., 1, self.headerHeight )
    self.windowHeaderRight.setPos( mXPos-self.headerHeight/2., 0, -self.headerHeight/2. )
    self.windowHeaderRight.setScale( self.headerHeight, 1, self.headerHeight )
    self.contentWindow['frameSize'] = ( 0, mXPos, mZPos+self.headerHeight, 0)
    self.textNodePath.setPos( mXPos/2., 0, -self.headerHeight/3.*2. )
    # show and hide that small background for the window sizer
    if mXPos == self.maxVirtualSize[0] and \
       mZPos == -self.maxVirtualSize[1]-self.headerHeight:
      self.windowResizeBackground.hide()
    else:
      self.windowResizeBackground.show()
 
  def resizeTask( self, task=None ):
    mPos = aspect2dMouseNode.getPos( self )+self.offset
    self.resize( mPos, self.offset )
    return task.cont
  def startResizeDrag( self, param ):
    self.offset  = self.windowResize.getPos( aspect2dMouseNode )
    taskMgr.remove( self.taskName )
    taskMgr.add( self.resizeTask, self.taskName )
  def stopResizeDrag( self, param ):
    taskMgr.remove( self.taskName )
    # get the window to the front
    self.wrtReparentTo( self.windowParent )
  def addHorizontal(self, widgets):
      """
      Accepts a list of directgui objects which are added to a horizontal box, which is then added to the vertical stack.
      """
      hbox = boxes.HBox()
      for widget in widgets:
          hbox.pack(widget)
      self.box.pack(hbox)
      self.updateMaxSize()
 
  def addVertical(self, widgets):
      """
      Accepts a list of directgui objects which are added to a vertical box, which is then added to the vertical stack.
      May cause funky layout results.
      """
      #vbox = boxes.VBox()
      for widget in widgets:
          self.box.pack(widget)
      self.updateMaxSize()
 
  def add(self, widgets):
      """Shortcut function for addVertical"""
      self.addVertical(widgets)
 
  def updateMaxSize(self):
      """Updates the max canvas size to include all items packed.
      Window is resized to show all contents."""
      bottomLeft, topRight = self.box.getTightBounds()
      self.maxVirtualSize = (topRight[0], -bottomLeft[2])
      self.contentWindow['canvasSize'] = ( 0, self.maxVirtualSize[0], -self.maxVirtualSize[1],  0)
      self.backgroundColor['frameSize'] = ( 0, self.maxVirtualSize[0], -self.maxVirtualSize[1], 0 )

      #perhaps this should be optional -- automatically resize for new elements
      self.reset()
 
  def reset(self):
    """Poorly named function that resizes window to fit all contents"""
    self.resize( Vec3(self.maxVirtualSize[0], 0, -self.maxVirtualSize[1]-self.headerHeight), Vec3(0,0,0))
Ejemplo n.º 38
0
class QuestMap(DirectFrame):

    def __init__(self, av, **kw):
        DirectFrame.__init__(self, relief=None, sortOrder=50)
        self.initialiseoptions(QuestMap)
        self.container = DirectFrame(parent=self, relief=None)
        self.marker = DirectFrame(parent=self.container, relief=None)
        self.cogInfoFrame = DirectFrame(parent=self.container, relief=None)
        cm = CardMaker('bg')
        cm.setFrame(-0.5, 0.5, -0.5, 0.5)
        bg = self.cogInfoFrame.attachNewNode(cm.generate())
        bg.setTransparency(1)
        bg.setColor(0.5, 0.5, 0.5, 0.5)
        bg.setBin('fixed', 0)
        self.cogInfoFrame['geom'] = bg
        self.cogInfoFrame['geom_pos'] = (0, 0, 0)
        self.cogInfoFrame['geom_scale'] = (6, 1, 2)
        self.cogInfoFrame.setScale(0.05)
        self.cogInfoFrame.setPos(0, 0, 0.6)
        self.buildingMarkers = []
        self.av = av
        self.wantToggle = False
        if base.config.GetBool('want-toggle-quest-map', True):
            self.wantToggle = True
        self.updateMarker = True
        self.cornerPosInfo = None
        self.hqPosInfo = None
        self.fishingSpotInfo = None
        self.load()
        self.setScale(1.5)
        bg.removeNode()
        self.hoodId = None
        self.zoneId = None
        self.suitPercentage = {}
        for currHoodInfo in SuitPlannerBase.SuitPlannerBase.SuitHoodInfo:
            tracks = currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_TRACK]
            self.suitPercentage[currHoodInfo[SuitPlannerBase.SuitPlannerBase.SUIT_HOOD_INFO_ZONE]] = tracks

        return

    def load(self):
        gui = loader.loadModel('phase_4/models/questmap/questmap_gui')
        icon = gui.find('**/tt_t_gui_qst_arrow')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setR(90)
        self.marker['geom'] = iconNP
        self.marker['image'] = iconNP
        self.marker.setScale(0.05)
        iconNP.removeNode()
        self.mapOpenButton = DirectButton(image=(gui.find('**/tt_t_gui_qst_mapClose'), gui.find('**/tt_t_gui_qst_mapClose'), gui.find('**/tt_t_gui_qst_mapTryToOpen')), relief=None, pos=(-0.08, 0, 0.37), parent=base.a2dBottomRight, scale=0.205, command=self.show)
        self.mapCloseButton = DirectButton(image=(gui.find('**/tt_t_gui_qst_mapOpen'), gui.find('**/tt_t_gui_qst_mapOpen'), gui.find('**/tt_t_gui_qst_mapTryToClose')), relief=None, pos=(-0.08, 0, 0.37), parent=base.a2dBottomRight, scale=0.205, command=self.hide)
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()
        gui.removeNode()
        icons = loader.loadModel('phase_3/models/gui/cog_icons')
        cIcon = icons.find('**/CorpIcon')
        lIcon = icons.find('**/LegalIcon')
        mIcon = icons.find('**/MoneyIcon')
        sIcon = icons.find('**/SalesIcon')
        cogInfoTextColor = (0.2, 0.2, 0.2, 1)
        textPos = (1.2, -0.2)
        textScale = 0.8
        self.cInfo = DirectLabel(parent=self.cogInfoFrame, text='', text_fg=cogInfoTextColor, text_pos=textPos, text_scale=textScale, geom=cIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.cInfo.setPos(-2.2, 0, 0.5)
        self.lInfo = DirectLabel(parent=self.cogInfoFrame, text_fg=cogInfoTextColor, text='', text_pos=textPos, text_scale=textScale, geom=lIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.lInfo.setPos(-2.2, 0, -0.5)
        self.mInfo = DirectLabel(parent=self.cogInfoFrame, text_fg=cogInfoTextColor, text='', text_pos=textPos, text_scale=textScale, geom=mIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.mInfo.setPos(0.8, 0, 0.5)
        self.sInfo = DirectLabel(parent=self.cogInfoFrame, text_fg=cogInfoTextColor, text='', text_pos=textPos, text_scale=textScale, geom=sIcon, geom_pos=(-0.2, 0, 0), geom_scale=0.8, relief=None)
        self.sInfo.setPos(0.8, 0, -0.5)
        icons.removeNode()
        return

    def updateCogInfo(self):
        currPercentage = self.suitPercentage.get(self.zoneId)
        if currPercentage is None:
            return
        self.cInfo['text'] = '%s%%' % currPercentage[0]
        self.lInfo['text'] = '%s%%' % currPercentage[1]
        self.mInfo['text'] = '%s%%' % currPercentage[2]
        self.sInfo['text'] = '%s%%' % currPercentage[3]
        return

    def destroy(self):
        self.ignore('questPageUpdated')
        self.mapOpenButton.destroy()
        self.mapCloseButton.destroy()
        del self.mapOpenButton
        del self.mapCloseButton
        DirectFrame.destroy(self)

    def putBuildingMarker(self, pos, hpr = (0, 0, 0), mapIndex = None):
        marker = DirectLabel(parent=self.container, text='', text_pos=(-0.05, -0.15), text_fg=(1, 1, 1, 1), relief=None)
        gui = loader.loadModel('phase_4/models/parties/schtickerbookHostingGUI')
        icon = gui.find('**/startPartyButton_inactive')
        iconNP = aspect2d.attachNewNode('iconNP')
        icon.reparentTo(iconNP)
        icon.setX(-12.0792 / 30.48)
        icon.setZ(-9.7404 / 30.48)
        marker['text'] = '%s' % mapIndex
        marker['text_scale'] = 0.7
        marker['image'] = iconNP
        marker['image_color'] = (1, 0, 0, 1)
        marker['image_scale'] = 6
        marker.setScale(0.05)
        relX, relY = self.transformAvPos(pos)
        marker.setPos(relX, 0, relY)
        self.buildingMarkers.append(marker)
        iconNP.removeNode()
        gui.removeNode()
        return

    def updateQuestInfo(self):
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []

        for (i, questDesc) in enumerate(self.av.quests):
            mapIndex = i + 1
            quest = Quests.getQuest(questDesc[0])
            toNpcId = questDesc[2]

            completed = quest.getCompletionStatus(self.av, questDesc) == Quests.COMPLETE
            if not completed:
                if quest.getType() == Quests.RecoverItemQuest:
                    if quest.getHolder() == Quests.AnyFish:
                        self.putBuildingMarker(self.fishingSpotInfo, mapIndex=mapIndex)
                    continue
                elif quest.getType() not in (
                    Quests.DeliverGagQuest, Quests.DeliverItemQuest,
                    Quests.VisitQuest, Quests.TrackChoiceQuest):
                    continue

            if toNpcId == Quests.ToonHQ:
                self.putBuildingMarker(self.hqPosInfo, mapIndex=mapIndex)
                continue

            npcZoneId = NPCToons.getNPCZone(toNpcId)
            hoodId = ZoneUtil.getCanonicalHoodId(npcZoneId)
            branchId = ZoneUtil.getCanonicalBranchZone(npcZoneId)

            if (self.hoodId != hoodId) or (self.zoneId != branchId):
                continue

            for blockIndex in xrange(base.cr.playGame.dnaStore.getNumBlockNumbers()):
                blockNumber = base.cr.playGame.dnaStore.getBlockNumberAt(blockIndex)
                zoneId = base.cr.playGame.dnaStore.getZoneFromBlockNumber(blockNumber)
                interiorZoneId = (zoneId - (zoneId%100)) + 500 + blockNumber
                if npcZoneId == interiorZoneId:
                    self.putBuildingMarker(
                        base.cr.playGame.dnaStore.getDoorPosHprFromBlockNumber(blockNumber).getPos(render),
                        base.cr.playGame.dnaStore.getDoorPosHprFromBlockNumber(blockNumber).getHpr(render),
                        mapIndex=mapIndex)

    def transformAvPos(self, pos):
        if self.cornerPosInfo is None:
            return (0, 0)
        topRight = self.cornerPosInfo[0]
        bottomLeft = self.cornerPosInfo[1]
        relativeX = (pos.getX() - bottomLeft.getX()) / (topRight.getX() - bottomLeft.getX()) - 0.5
        relativeY = (pos.getY() - bottomLeft.getY()) / (topRight.getY() - bottomLeft.getY()) - 0.5
        return (relativeX, relativeY)

    def update(self, task):
        if self.av:
            if self.updateMarker:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
        i = 0
        for buildingMarker in self.buildingMarkers:
            buildingMarker.setScale((math.sin(task.time * 16.0 + i * math.pi / 3.0) + 1) * 0.005 + 0.04)
            i = i + 1

        return Task.cont

    def updateMap(self):
        if self.av:
            hoodId = ZoneUtil.getCanonicalHoodId(self.av.getLocation()[1])
            zoneId = ZoneUtil.getCanonicalBranchZone(self.av.getLocation()[1])
            try:
                mapsGeom = loader.loadModel('phase_4/models/questmap/%s_maps' % ToontownGlobals.dnaMap[hoodId])
            except:
                self.stop()
                return
            mapImage = mapsGeom.find('**/%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
            if not mapImage.isEmpty():
                self.container['image'] = mapImage
                self.resetFrameSize()
                self.cornerPosInfo = QuestMapGlobals.CornerPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.hqPosInfo = QuestMapGlobals.HQPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.fishingSpotInfo = QuestMapGlobals.FishingSpotPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.cogInfoPos = QuestMapGlobals.CogInfoPosTable.get('%s_%s_english' % (ToontownGlobals.dnaMap[hoodId], zoneId))
                self.cogInfoFrame.setPos(self.cogInfoPos)
                self.hide()
                self.hoodId = hoodId
                self.zoneId = zoneId
                self.updateQuestInfo()
                self.updateCogInfo()
                taskMgr.add(self.update, 'questMapUpdate')
            else:
                self.stop()
                mapsGeom.removeNode()

    def start(self):
        self.container.show()
        self.accept('questPageUpdated', self.updateMap)
        self.handleMarker()
        self.updateMap()

    def initMarker(self, task):
        if self.av:
            if not hasattr(base.cr.playGame.getPlace(), 'isInterior') or not base.cr.playGame.getPlace().isInterior:
                relX, relY = self.transformAvPos(self.av.getPos())
                self.marker.setPos(relX, 0, relY)
                self.marker.setHpr(0, 0, -180 - self.av.getH())
            self.marker['geom_scale'] = 1.4 * task.time % 0.5 * 10 + 1
            self.marker['geom_color'] = (1,
             1,
             1,
             0.8 - 1.4 * task.time % 0.5 * 2 / 0.8 + 0.2)
        if task.time < 1:
            return Task.cont
        else:
            self.marker['geom_color'] = (1, 1, 1, 0)
            return Task.done

    def show(self):
        taskMgr.add(self.initMarker, 'questMapInit')
        DirectFrame.show(self)
        self.mapOpenButton.hide()
        if self.container['image']:
            self.mapCloseButton.show()

    def hide(self):
        taskMgr.remove('questMapInit')
        DirectFrame.hide(self)
        if self.container['image']:
            self.mapOpenButton.show()
        self.mapCloseButton.hide()

    def toggle(self):
        if self.isHidden():
            self.show()
        else:
            self.hide()

    def obscureButton(self):
        self.mapOpenButton.hide()
        self.mapCloseButton.hide()

    def stop(self):
        self.container['image'] = None
        for marker in self.buildingMarkers:
            marker.destroy()

        self.buildingMarkers = []
        self.container.hide()
        self.hide()
        self.obscureButton()
        self.ignore('questPageUpdated')
        taskMgr.remove('questMapUpdate')
        return

    def handleMarker(self):
        if hasattr(base.cr.playGame.getPlace(), 'isInterior') and base.cr.playGame.getPlace().isInterior:
            self.updateMarker = False
        else:
            self.updateMarker = True

    def acceptOnscreenHooks(self):
        if self.wantToggle:
            self.accept(ToontownGlobals.MapHotkey, self.toggle)
        else:
            self.accept(ToontownGlobals.MapHotkeyOn, self.show)
            self.accept(ToontownGlobals.MapHotkeyOff, self.hide)
        self.updateMap()

    def ignoreOnscreenHooks(self):
        self.ignore(ToontownGlobals.MapHotkey)
        self.ignore(ToontownGlobals.MapHotkeyOn)
        self.ignore(ToontownGlobals.MapHotkeyOff)
        self.obscureButton()
Ejemplo n.º 39
0
class DMenuScreen(DirectObject):
    notify = directNotify.newCategory('DMenuScreen')

    def __init__(self):
        DirectObject.__init__(self)
        base.cr.DMENU_SCREEN = self
        self.seq = None
        self.isSeqPlaying = False  # .isPlaying() doesnt want to work
        if DMENU_GAME == 'Toontown':
            base.cr.avChoice = None
        fadeSequence = Sequence(
            Func(base.transitions.fadeOut, .001), Wait(.5),
            Func(base.transitions.fadeIn, .5),
            base.camera.posHprInterval(1,
                                       Point3(MAIN_POS),
                                       VBase3(MAIN_HPR),
                                       blendType='easeInOut')).start()
        if DMENU_GAME == 'Toontown':
            self.background = loader.loadModel(
                'phase_3.5/models/modules/tt_m_ara_int_toonhall')
            self.background.reparentTo(render)
            self.background.setPosHpr(-25, 0, 8.1, -95, 0, 0)
            ropes = loader.loadModel(
                'phase_4/models/modules/tt_m_ara_int_ropes')
            ropes.reparentTo(self.background)
            self.sillyMeter = Actor.Actor(
                'phase_4/models/props/tt_a_ara_ttc_sillyMeter_default', {
                    'arrowTube':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_arrowFluid',
                    'phaseOne':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_phaseOne',
                    'phaseTwo':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_phaseTwo',
                    'phaseThree':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_phaseThree',
                    'phaseFour':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_phaseFour',
                    'phaseFourToFive':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_phaseFourToFive',
                    'phaseFive':
                    'phase_4/models/props/tt_a_ara_ttc_sillyMeter_phaseFive'
                })
            self.sillyMeter.reparentTo(self.background)
            self.sillyMeter.makeSubpart('arrow',
                                        ['uvj_progressBar*', 'def_springA'])
            self.sillyMeter.makeSubpart('meter', ['def_pivot'],
                                        ['uvj_progressBar*', 'def_springA'])
            self.audio3d = Audio3DManager.Audio3DManager(
                base.sfxManagerList[0], camera)

            self.phase3Sfx = self.audio3d.loadSfx(
                'phase_4/audio/sfx/tt_s_prp_sillyMeterPhaseThree.ogg')
            self.phase3Sfx.setLoop(True)
            self.arrowSfx = self.audio3d.loadSfx(
                'phase_4/audio/sfx/tt_s_prp_sillyMeterArrow.ogg')
            self.arrowSfx.setLoop(False)
            self.phase3Sfx.setVolume(0.2)
            self.arrowSfx.setVolume(0.2)

            self.animSeq = Sequence(
                Sequence(
                    ActorInterval(self.sillyMeter,
                                  'arrowTube',
                                  partName='arrow',
                                  constrainedLoop=0,
                                  startFrame=236,
                                  endFrame=247), Func(self.arrowSfx.play)),
                Parallel(
                    ActorInterval(self.sillyMeter,
                                  'arrowTube',
                                  partName='arrow',
                                  duration=604800,
                                  constrainedLoop=1,
                                  startFrame=247,
                                  endFrame=276),
                    Sequence(
                        Func(self.phase3Sfx.play),
                        Func(self.audio3d.attachSoundToObject, self.phase3Sfx,
                             self.sillyMeter))))
            self.animSeq.start()
            self.smPhase2 = self.sillyMeter.find('**/stage2')
            self.smPhase2.show()
            self.sillyMeter.loop('phaseOne', partName='meter')
            self.sillyMeter.setBlend(frameBlend=True)

            self.surlee = Toon.Toon()
            self.surlee.setName('Doctor Surlee')
            self.surlee.setPickable(0)
            self.surlee.setPlayerType(CCNonPlayer)
            dna = ToonDNA.ToonDNA()
            dna.newToonFromProperties('pls', 'ls', 'l', 'm', 9, 0, 9, 9, 98,
                                      27, 86, 27, 38, 27)
            self.surlee.setDNA(dna)
            self.surlee.loop('scientistGame')
            self.surlee.reparentTo(self.background)
            self.surlee.setPosHpr(13, 24, 0.025, -180, 0, 0)

            self.dimm = Toon.Toon()
            self.dimm.setName('Doctor Dimm')
            self.dimm.setPickable(0)
            self.dimm.setPlayerType(CCNonPlayer)
            dna = ToonDNA.ToonDNA()
            dna.newToonFromProperties('fll', 'ss', 's', 'm', 15, 0, 15, 15, 99,
                                      27, 86, 27, 39, 27)
            self.dimm.setDNA(dna)
            self.dimm.loop('scientistGame')
            self.dimm.reparentTo(self.background)
            self.dimm.setPosHpr(16, 24, 0.025, -180, 0, 0)

            surleeHand = self.surlee.find('**/def_joint_right_hold')
            clipBoard = loader.loadModel(
                'phase_4/models/props/tt_m_prp_acs_clipboard')
            surleeHandNode = surleeHand.attachNewNode('ClipBoard')
            clipBoard.instanceTo(surleeHandNode)
            surleeHandNode.setH(180)
            surleeHandNode.setScale(render, 1.0)
            surleeHandNode.setPos(0, 0, 0.1)

            dimmHand = self.dimm.find('**/def_joint_right_hold')
            sillyReader = loader.loadModel(
                'phase_4/models/props/tt_m_prp_acs_sillyReader')
            dimHandNode = dimmHand.attachNewNode('SillyReader')
            sillyReader.instanceTo(dimHandNode)
            dimHandNode.setH(180)
            dimHandNode.setScale(render, 1.0)
            dimHandNode.setPos(0, 0, 0.1)

            self.banana = self.background.find('**/gagBanana')

            self.bananaClicker = CollisionTraverser()
            #self.bananaClicker.showCollisions(render)
            self.collHandlerQueue = CollisionHandlerQueue()

            self.bananaRayNode = CollisionNode('bananaMouseRay')
            self.bananaRayNP = base.camera.attachNewNode(self.bananaRayNode)
            self.bananaRayNode.setIntoCollideMask(BitMask32.bit(0))
            self.bananaRayNode.setFromCollideMask(BitMask32.bit(1))
            self.banana.setCollideMask(BitMask32.bit(1))
            self.ray = CollisionRay()
            self.bananaRayNode.addSolid(self.ray)
            self.bananaClicker.addCollider(self.bananaRayNP,
                                           self.collHandlerQueue)
            self.accept("mouse1", self.slipAndSlideOnThisBananaPeelHaHaHa)

            for frame in render.findAllMatches('*/doorFrame*'):
                frame.removeNode()
            self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
            SkyUtil.startCloudSky(self)
            base.camera.setPosHpr(MAIN_POS, MAIN_HPR)

        self.logo = OnscreenImage(image=GameLogo, scale=(.5, .5, .25))
        self.logo.reparentTo(aspect2d)
        self.logo.setTransparency(TransparencyAttrib.MAlpha)
        scale = self.logo.getScale()
        self.logo.setPos(0, 0, .5)
        self.logo.setColorScale(Vec4(0, 0, 0, 0))
        fadeInLogo = (LerpColorScaleInterval(self.logo, 1, Vec4(1, 1, 1, 1),
                                             Vec4(1, 1, 1, 0))).start()

        self.createButtons()

        self.fadeOut = None
        self.optionsMgr = PickAToonOptions.NewPickAToonOptions()
        #self.quitConfirmation = DMenuQuit()
        self.patNode = None

        if DMENU_GAME == 'Toontown':
            # TT: We need these to run the Pick A Toon screen
            self.patAvList = base.cr.PAT_AVLIST
            self.patFSM = base.cr.PAT_LOGINFSM
            self.patDoneEvent = base.cr.PAT_DONEEVENT

    def slipAndSlideOnThisBananaPeelHaHaHa(self):
        if base.mouseWatcherNode.hasMouse():
            mpos = base.mouseWatcherNode.getMouse()

            def setPlayingStatus(status):
                self.isSeqPlaying = status

            self.ray.setFromLens(base.camNode, mpos.getX(), mpos.getY())
            self.bananaClicker.traverse(render)

            if self.collHandlerQueue.getNumEntries() > 0:
                self.collHandlerQueue.sortEntries()
                pickedObj = self.collHandlerQueue.getEntry(0).getIntoNodePath()
                surleeAnim = random.choice(['slip-backward', 'slip-forward'])
                dimmAnim = random.choice(['slip-backward', 'slip-forward'])
                if pickedObj == self.banana:
                    self.seq = Sequence(
                        Func(setPlayingStatus, True),
                        Func(self.surlee.play, surleeAnim),
                        Func(self.dimm.play, dimmAnim), Wait(3),
                        Func(self.surlee.loop, 'scientistGame'),
                        Func(self.dimm.loop, 'scientistGame'),
                        Func(setPlayingStatus, False))
                    if not self.isSeqPlaying:
                        self.seq.start()

    def skyTrack(self, task):
        return SkyUtil.cloudSkyTrack(task)

    def createButtons(self):
        buttonImage = GuiModel.find('**/QuitBtn_RLVR')

        self.PlayButton = DirectButton(relief=None,
                                       text_style=3,
                                       text_fg=(1, 1, 1, 1),
                                       text=PlayGame,
                                       text_scale=.1,
                                       scale=0.95,
                                       command=self.playGame)
        self.PlayButton.reparentTo(aspect2d)
        self.PlayButton.setPos(PlayBtnHidePos)
        self.PlayButton.show()

        self.OptionsButton = DirectButton(relief=None,
                                          text_style=3,
                                          text_fg=(1, 1, 1, 1),
                                          text=Options,
                                          text_scale=.1,
                                          scale=0.95,
                                          command=self.openOptions)
        self.OptionsButton.reparentTo(aspect2d)
        self.OptionsButton.setPos(OptionsBtnHidePos)
        self.OptionsButton.show()

        self.QuitButton = DirectButton(relief=None,
                                       text_style=3,
                                       text_fg=(1, 1, 1, 1),
                                       text=Quit,
                                       text_scale=.1,
                                       scale=0.95,
                                       command=self.quitGame)
        self.QuitButton.reparentTo(aspect2d)
        self.QuitButton.setPos(QuitBtnHidePos)
        self.QuitButton.show()

        # self.BRButton = DirectButton(text = 'REPORT BUG', text_scale = .1, scale=0.95)
        # self.BRButton.reparentTo(aspect2d)
        # self.BRButton.setPos(-.9, 0, -.9)
        # self.BRButton.show()

        self.buttonInAnimation()

    def murder(self):
        if self.logo is not None:
            self.logo.destroy()
            self.logo = None

        if self.background is not None:
            self.background.hide()
            self.background.reparentTo(hidden)
            self.background.removeNode()
            self.background = None

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

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

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

        if self.phase3Sfx:
            self.phase3Sfx.stop()
            del self.phase3Sfx

        if self.surlee:
            self.surlee.delete()
        if self.dimm:
            self.dimm.delete()

        del self.bananaRayNode
        del self.bananaRayNP
        del self.bananaClicker
        del self.collHandlerQueue
        del self.ray

        self.ignoreAll()

        taskMgr.remove('skyTrack')
        self.sky.reparentTo(hidden)

    def openOptions(self):
        self.optionsMgr.showOptions()
        self.closeOptionsButton = DirectButton(
            relief=None,
            image=(btnUp, btnDn, btnRlvr),
            text="Back",
            text_fg=(0, 0, 0, 1),
            text_scale=TTLocalizer.AClogoutButton,
            text_pos=(0, -0.035),
            image_scale=1,
            image1_scale=1.05,
            image2_scale=1.05,
            scale=0.7,
            command=self.hideOptions)
        self.closeOptionsButton.reparentTo(base.a2dTopLeft)
        self.closeOptionsButton.setPos(0.5, 0, -0.07)
        Parallel(
            self.PlayButton.posInterval(.5,
                                        Point3(PlayBtnHidePos),
                                        blendType='easeInOut'),
            self.OptionsButton.posInterval(.5,
                                           Point3(OptionsBtnHidePos),
                                           blendType='easeInOut'),
            self.QuitButton.posInterval(.5,
                                        Point3(QuitBtnHidePos),
                                        blendType='easeInOut'),
            self.logo.posInterval(0.5,
                                  Point3(0, 0, 2.5),
                                  blendType='easeInOut')).start()

    def hideOptions(self):
        self.optionsMgr.hideOptions()
        self.closeOptionsButton.hide()
        self.buttonInAnimation()

    def playGame(self):
        if self.fadeOut is not None:
            self.fadeOut.finish()
            self.fadeOut = None
        self.fadeOut = base.transitions.getFadeOutIval(t=1)
        #base.camera.posHprInterval(1, Point3(TOON_HALL_POS), VBase3(TOON_HALL_HPR), blendType = 'easeInOut').start()
        Sequence(
            Func(self.doPlayButton),
            Wait(1),
            #Func(self.murder),
            Func(self.enterGame)).start()
        #Func(base.transitions.fadeIn, 1)).start()

    def enterOptions(self):
        pass

    def enterGame(self):
        base.cr.avChoice = PickAToon.PickAToon(self.patAvList, self.patFSM,
                                               self.patDoneEvent)
        base.cr.avChoice.load()
        base.cr.avChoice.enter()

    def doPlayButton(self):
        Parallel(
            self.PlayButton.posInterval(1,
                                        Point3(PlayBtnHidePos),
                                        blendType='easeInOut'),
            self.OptionsButton.posInterval(1,
                                           Point3(OptionsBtnHidePos),
                                           blendType='easeInOut'),
            self.QuitButton.posInterval(1,
                                        Point3(QuitBtnHidePos),
                                        blendType='easeInOut'),
            self.logo.posInterval(0.5,
                                  Point3(0, 0, 2.5),
                                  blendType='easeInOut')).start()

    def quitGame(self):
        self.showQuitConfirmation()

    def showQuitConfirmation(self):
        #self.quitConfirmation.showConfirmation()
        base.exitFunc()

    def buttonInAnimation(self):
        logo = self.logo.posInterval(.5,
                                     Point3(0, 0, .5),
                                     blendType='easeInOut')
        play = self.PlayButton.posInterval(.5,
                                           Point3(PlayBtnPos),
                                           blendType='easeInOut')
        opt = self.OptionsButton.posInterval(.5,
                                             Point3(OptionsBtnPos),
                                             blendType='easeInOut')
        quit = self.QuitButton.posInterval(.5,
                                           Point3(QuitBtnPos),
                                           blendType='easeInOut')

        Sequence(Func(logo.start), Wait(0.1), Func(play.start), Wait(0.2),
                 Func(opt.start), Wait(0.2), Func(quit.start)).start()

    def showHamburgerMenu(self):
        self.hbButton.hide()
        self.hbHideButton.show()

        self.patNode2d = aspect2d.find("**/patNode2d")
        self.patNode2d.posInterval(.5, Point3(.5, 0, 0),
                                   blendType='easeInOut').start()

        self.patNode = render.find("**/patNode")
        self.patNode.posInterval(.5, Point3(0, -3, 0),
                                 blendType='easeInOut').start()

    def hideHamburgerMenu(self):
        self.hbButton.show()
        self.hbHideButton.hide()

        self.patNode2d.posInterval(.5, Point3(0, 0, 0),
                                   blendType='easeInOut').start()

        self.patNode.posInterval(.5, Point3(0, 0, 0),
                                 blendType='easeInOut').start()

    def reportBug(self):
        BugReportGUI.BugReportGUI()

    def createTabs(self):
        self.PlayButton = DirectButton(relief=None,
                                       text_style=3,
                                       text_fg=(1, 1, 1, 1),
                                       text=PlayGame,
                                       text_scale=.1,
                                       scale=0.95,
                                       command=self.playGame)
        self.PlayButton.reparentTo(aspect2d)
        self.PlayButton.setPos(PlayBtnHidePos)
        self.PlayButton.show()

        self.OptionsButton = DirectButton(relief=None,
                                          text_style=3,
                                          text_fg=(1, 1, 1, 1),
                                          text=Options,
                                          text_scale=.1,
                                          scale=0.95,
                                          command=self.openOptions)
        self.OptionsButton.reparentTo(aspect2d)
        self.OptionsButton.setPos(OptionsBtnHidePos)
        self.OptionsButton.show()

        self.QuitButton = DirectButton(relief=None,
                                       text_style=3,
                                       text_fg=(1, 1, 1, 1),
                                       text=Quit,
                                       text_scale=.1,
                                       scale=0.95,
                                       command=self.quitGame)
        self.QuitButton.reparentTo(aspect2d)
        self.QuitButton.setPos(QuitBtnHidePos)
        self.QuitButton.show()
Ejemplo n.º 40
0
class CalendarGuiMonth(DirectFrame):
    __module__ = __name__
    notify = directNotify.newCategory('CalendarGuiMonth')

    def __init__(self,
                 parent,
                 startingDateTime,
                 scale=1.0,
                 pos=(0, 0, -0.1),
                 dayClickCallback=None,
                 onlyFutureDaysClickable=False,
                 onlyFutureMonthsClickable=False):
        self.startDate = startingDateTime
        self.curDate = startingDateTime
        self.dayClickCallback = dayClickCallback
        self.onlyFutureDaysClickable = onlyFutureDaysClickable
        self.onlyFutureMonthsClickable = onlyFutureMonthsClickable
        if self.onlyFutureDaysClickable:
            self.onlyFutureMonthsClickable = True
        DirectFrame.__init__(self, parent=parent, scale=scale, pos=pos)
        self.showMarkers = base.config.GetBool('show-calendar-markers', 0)
        self.load()
        self.createGuiObjects()
        self.lastSelectedDate = None
        self.accept('clickedOnDay', self.clickedOnDay)
        return

    def createDummyLocators(self):
        self.monthLocator = self.attachNewNode('monthLocator')
        self.monthLocator.setZ(0.6)
        self.weekDayLocators = []
        for i in xrange(7):
            self.weekDayLocators.append(
                self.attachNewNode('weekDayLocator-%d' % i))
            self.weekDayLocators[i].setZ(0.5)
            self.weekDayLocators[i].setX(i * 0.24 + -0.75)

        dayTopLeftX = -0.8
        dayTopLeftZ = 0.4
        self.dayLocators = []
        for row in xrange(6):
            oneWeek = []
            for col in xrange(7):
                newDayLoc = self.attachNewNode('dayLocator-row-%d-col-%d' %
                                               (row, col))
                newDayLoc.setX(col * 0.24 + dayTopLeftX)
                newDayLoc.setZ(row * -0.18 + dayTopLeftZ)
                oneWeek.append(newDayLoc)

            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.attachNewNode('monthLeft')
        self.monthLeftLocator.setPos(-0.3, 0, 0.65)
        self.monthRightLocator = self.attachNewNode('monthRight')
        self.monthRightLocator.setPos(0.3, 0, 0.65)

    def attachMarker(self, parent, scale=0.01, color=(1, 0, 0)):
        if self.showMarkers:
            marker = loader.loadModel('phase_3/models/misc/sphere')
            marker.reparentTo(parent)
            marker.setScale(scale)
            marker.setColor(*color)

    def load(self):
        monthAsset = loader.loadModel(
            'phase_4/models/parties/tt_m_gui_sbk_calendar')
        monthAsset.reparentTo(self)
        self.monthLocator = self.find('**/locator_month/locator_month')
        self.attachMarker(self.monthLocator)
        self.weekDayLocators = []
        for weekday in ('sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'):
            weekDayLoc = self.find('**/loc_%s' % weekday)
            self.weekDayLocators.append(weekDayLoc)
            self.attachMarker(weekDayLoc)

        self.dayLocators = []
        for row in xrange(6):
            oneWeek = []
            for col in xrange(7):
                newDayLoc = self.find('**/loc_box_%s_%s' % (row, col))
                oneWeek.append(newDayLoc)

            self.dayLocators.append(oneWeek)

        self.monthLeftLocator = self.find('**/locator_month_arrowL')
        self.monthRightLocator = self.find('**/locator_month_arrowR')
        self.filterLocator = self.find('**/locator_filter')
        self.filterLocatorArrowUp = self.find('**/locator_filter_arrowTop')
        self.filterLocatorArrowDown = self.find(
            '**/locator_filter_arrowBottom')
        self.yearLocator = self.attachNewNode('yearLocator')
        self.yearLocator.setPos(self.monthLocator, 0, 0, -0.03)

    def createGuiObjects(self):
        self.monthLabel = DirectLabel(
            parent=self.monthLocator,
            relief=None,
            text=TTLocalizer.Months[self.startDate.month],
            text_scale=0.075,
            text_font=ToontownGlobals.getMinnieFont(),
            text_fg=(40 / 255.0, 140 / 255.0, 246 / 255.0, 1.0))
        self.yearLabel = DirectLabel(parent=self.yearLocator,
                                     relief=None,
                                     text=str(self.startDate.year),
                                     text_scale=0.03,
                                     text_font=ToontownGlobals.getMinnieFont(),
                                     text_fg=(140 / 255.0, 140 / 255.0,
                                              246 / 255.0, 1.0))
        self.weekdayLabels = []
        for posIndex in xrange(7):
            adjustedNameIndex = (posIndex - 1) % 7
            self.weekdayLabels.append(
                DirectLabel(parent=self.weekDayLocators[posIndex],
                            relief=None,
                            text=TTLocalizer.DayNamesAbbrev[adjustedNameIndex],
                            text_font=ToontownGlobals.getInterfaceFont(),
                            text_fg=(255 / 255.0, 146 / 255.0, 113 / 255.0,
                                     1.0),
                            text_scale=0.05))

        self.createGuiDays()
        arrowUp = self.find('**/month_arrowR_up')
        arrowDown = self.find('**/month_arrowR_down')
        arrowHover = self.find('**/month_arrowR_hover')
        self.monthLeftArrow = DirectButton(parent=self.monthLeftLocator,
                                           relief=None,
                                           image=(arrowUp, arrowDown,
                                                  arrowHover, arrowUp),
                                           image3_color=Vec4(1, 1, 1, 0.5),
                                           scale=(-1.0, 1.0, 1.0),
                                           command=self.__doMonthLeft)
        if self.onlyFutureMonthsClickable:
            self.monthLeftArrow.hide()
        self.monthRightArrow = DirectButton(parent=self.monthRightLocator,
                                            relief=None,
                                            image=(arrowUp, arrowDown,
                                                   arrowHover, arrowUp),
                                            image3_color=Vec4(1, 1, 1, 0.5),
                                            command=self.__doMonthRight)

        def makeLabel(itemName, itemNum, *extraArgs):
            return DirectLabel(text=itemName,
                               frameColor=(0, 0, 0, 0),
                               text_scale=0.04)

        gui = loader.loadModel(
            'phase_4/models/parties/tt_m_gui_sbk_calendar_box')
        arrowUp = gui.find('**/downScroll_up')
        arrowDown = gui.find('**/downScroll_down')
        arrowHover = gui.find('**/downScroll_hover')
        filterLocatorUpPos = self.filterLocatorArrowUp.getPos(
            self.filterLocator)
        filterLocatorDownPos = self.filterLocatorArrowDown.getPos(
            self.filterLocator)
        self.filterList = DirectScrolledList(
            parent=self.filterLocator,
            relief=None,
            pos=(0, 0, 0),
            image=None,
            text_scale=0.025,
            incButton_image=(arrowUp, arrowDown, arrowHover, arrowUp),
            incButton_relief=None,
            incButton_pos=filterLocatorDownPos,
            incButton_image3_color=Vec4(1, 1, 1, 0.2),
            incButtonCallback=self.filterChanged,
            decButton_image=(arrowUp, arrowDown, arrowHover, arrowUp),
            decButton_relief=None,
            decButton_pos=filterLocatorUpPos,
            decButton_scale=(1, 1, -1),
            decButton_image3_color=Vec4(1, 1, 1, 0.2),
            decButtonCallback=self.filterChanged,
            numItemsVisible=1,
            itemMakeFunction=makeLabel,
            items=[
                TTLocalizer.CalendarShowAll,
                TTLocalizer.CalendarShowOnlyHolidays,
                TTLocalizer.CalendarShowOnlyParties
            ],
            itemFrame_frameSize=(-0.2, 0.2, -0.02, 0.05),
            itemFrame_frameColor=(0, 0, 0, 0))
        gui.removeNode()
        return

    def getTopLeftDate(self):
        firstOfTheMonth = self.curDate.replace(day=1)
        daysAwayFromSunday = (firstOfTheMonth.weekday() - 6) % 7
        topLeftDate = firstOfTheMonth + timedelta(days=-daysAwayFromSunday)
        return topLeftDate

    def createGuiDays(self):
        topLeftDate = self.getTopLeftDate()
        curDate = topLeftDate
        self.guiDays = []
        for row in self.dayLocators:
            for oneLocator in row:
                self.guiDays.append(
                    CalendarGuiDay(oneLocator, curDate, self.curDate,
                                   self.dayClickCallback,
                                   self.onlyFutureDaysClickable))
                curDate += timedelta(days=1)

    def changeDateForGuiDays(self):
        topLeftDate = self.getTopLeftDate()
        guiDayDate = topLeftDate
        for guiDay in self.guiDays:
            guiDay.changeDate(self.curDate, guiDayDate)
            guiDayDate += timedelta(days=1)

    def changeMonth(self, monthChange):
        if monthChange != 0:
            newMonth = self.curDate.month + monthChange
            newYear = self.curDate.year
            while newMonth > 12:
                newYear += 1
                newMonth -= 12

            while newMonth < 1:
                if newYear - 1 > 1899:
                    newMonth += 12
                    newYear -= 1
                else:
                    newMonth += 1

            self.curDate = datetime(newYear, newMonth, 1,
                                    self.curDate.time().hour,
                                    self.curDate.time().minute,
                                    self.curDate.time().second,
                                    self.curDate.time().microsecond,
                                    self.curDate.tzinfo)
        self.monthLabel['text'] = (TTLocalizer.Months[self.curDate.month], )
        self.yearLabel['text'] = (str(self.curDate.year), )
        startTime = globalClock.getRealTime()
        self.changeDateForGuiDays()
        endTime = globalClock.getRealTime()
        self.notify.debug('changeDate took %f seconds' % (endTime - startTime))
        self.updateSelectedDate()
        if monthChange != 0:
            if self.onlyFutureMonthsClickable and newMonth == self.startDate.month and newYear == self.startDate.year:
                self.monthLeftArrow.hide()

    def __doMonthLeft(self):
        self.changeMonth(-1)

    def __doMonthRight(self):
        self.monthLeftArrow.show()
        self.changeMonth(1)

    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)
        return

    def clickedOnDay(self, dayDate):
        self.lastSelectedDate = dayDate
        self.updateSelectedDate()

    def updateSelectedDate(self):
        if self.lastSelectedDate:
            for oneGuiDay in self.guiDays:
                if oneGuiDay.myDate.date() == self.lastSelectedDate:
                    oneGuiDay.updateSelected(True)
                else:
                    oneGuiDay.updateSelected(False)

    def clearSelectedDay(self):
        for oneGuiDay in self.guiDays:
            oneGuiDay.updateSelected(False)

    def filterChanged(self):
        newFilter = self.filterList.getSelectedIndex()
        for guiDay in self.guiDays:
            guiDay.changeFilter(newFilter)
Ejemplo n.º 41
0
class LocalToon(DistributedPlayerToon, BaseLocalAvatar):
    neverDisable = 1

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

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

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

        self.clickToonCallback = None

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

        self.jumpHardLandIval = None

        # This is used by CutsceneGUI
        self.allowA2dToggle = True

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

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

        DistributedPlayerToon.primaryFirePress(self)

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

        DistributedPlayerToon.primaryFireRelease(self)

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

        DistributedPlayerToon.secondaryFirePress(self)

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

        DistributedPlayerToon.secondaryFireRelease(self)

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

        self.hideBookButton()
        self.hideFriendButton()

        BaseLocalAvatar.stopPlay(self)

        self.stopTrackAnimToSpeed()

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

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

        self.startTrackAnimToSpeed()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    def checkSuitHealth(self, suit):
        pass

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

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

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

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

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

        BaseLocalAvatar.handleHealthChange(self, hp, oldHp)

        DistributedPlayerToon.handleHealthChange(self, hp, oldHp)

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

        self.handleHealthChange(hp, currHp)

        DistributedPlayerToon.setSessionHealth(self, hp)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        self.createInvGui()

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

    def enterHiddenToonMode(self):
        self.laffMeter.stop()
        self.laffMeter.disable()
        self.laffMeter.destroy()
        self.getGeomNode().hide()
        self.deleteNameTag()
        self.invGui.disable()
        self.hideFriendButton()
        self.hideBookButton()
        self.removeAdminToken()
Ejemplo n.º 42
0
class ShopWindow(DirectFrame):

    def __init__(self, shop, image):
        DirectFrame.__init__(self)
        self.shop = shop
        self.bgImage = image
        self.title = None
        self.okBtn = None
        self.clBtn = None
        self.infoLbl = None
        self.nPage = -1
        self.nPages = 0
        self.nextPage = 0
        self.prevPage = -1
        self.pages = []
        self.isSetup = False
        return

    def setup(self, title = 'CHOOSE WHAT YOU WANT TO BUY'):
        font = CIGlobals.getMickeyFont()
        txtFg = (0, 0, 0, 1)
        txtScale = 0.05
        txtPos = (0, -0.1)
        buttons = loader.loadModel('phase_3.5/models/gui/QT_buttons.bam')
        self.window = OnscreenImage(image=self.bgImage, scale=(0.9, 1, 0.7), parent=self)
        self.title = DirectLabel(text=title, relief=None, pos=(0, 0, 0.5), text_wordwrap=10, text_font=font, text_fg=(1, 1, 0, 1), scale=0.1, parent=self)
        self.infoLbl = DirectLabel(text='Welcome!', relief=None, text_scale=0.075, text_fg=txtFg, text_shadow=(0, 0, 0, 0), pos=(0, 0, 0.215))
        self.okBtn = DirectButton(geom=CIGlobals.getOkayBtnGeom(), relief=None, text='OK', text_fg=txtFg, text_scale=txtScale, text_pos=txtPos, pos=(-0.1, 0, -0.5), parent=self)
        self.clBtn = DirectButton(geom=CIGlobals.getCancelBtnGeom(), relief=None, text='Cancel', text_fg=txtFg, text_scale=txtScale, text_pos=txtPos, pos=(0.1, 0, -0.5), parent=self)
        buttonGeom = (buttons.find('**/QT_back'),
         buttons.find('**/QT_back'),
         buttons.find('**/QT_back'),
         buttons.find('**/QT_back'))
        self.backBtn = DirectButton(geom=buttonGeom, relief=None, scale=0.05, pos=(-0.3, 0, -0.25), parent=self, command=self.changePage, extraArgs=[0])
        self.nextBtn = DirectButton(geom=buttonGeom, relief=None, scale=0.05, pos=(0.3, 0, -0.25), hpr=(0, 0, 180), command=self.changePage, extraArgs=[1], parent=self)
        self.hideInfo()
        return

    def changePage(self, direction):
        var = self.prevPage
        if direction == 1:
            var = self.nextPage
        self.setPage(var)

    def __makeGagEntry(self, pos, item, values, page):
        itemImage = values.get('image')
        button = DirectButton(geom=itemImage, scale=1.3, pos=pos, relief=None, parent=page, command=self.shop.purchaseItem, extraArgs=[item])
        supply = base.localAvatar.getBackpack().getSupply(item().getName())
        maxSupply = base.localAvatar.getBackpack().getMaxSupply(item().getName())
        buttonLabel = DirectLabel(text='%s/%s\n%s JBS' % (str(supply), str(maxSupply), str(values.get('price'))), relief=None, parent=button, text_scale=0.05, pos=(0, 0, -0.11))
        self.addEntryToPage(page, item, values, button, buttonLabel)
        return

    def __makeUpgradeEntry(self, pos, item, values, page):
        itemImage = values.get('image')
        button = DirectButton(image=itemImage, scale=0.15, pos=pos, relief=None, parent=page, command=self.shop.purchaseItem, extraArgs=[item])
        button.setTransparency(TransparencyAttrib.MAlpha)
        upgradeID = values.get('upgradeID')
        supply = base.localAvatar.getPUInventory()[0]
        if supply < 0:
            supply = 0
        maxSupply = values.get('maxUpgrades')
        if upgradeID == 0 and base.localAvatar.getMyBattle().getTurretManager().myTurret:
            supply = 1
        buttonLabel = DirectLabel(text='%s\n%s/%s\n%s JBS' % (item,
         str(supply),
         str(maxSupply),
         str(values.get('price'))), relief=None, parent=button, text_scale=0.3, pos=(0, 0, -1.2))
        self.addEntryToPage(page, item, values, button, buttonLabel)
        return

    def __makeHealEntry(self, pos, item, values, page):
        label = '%s' % item
        itemImage = values.get('image')
        if 'showTitle' in values:
            label = '%s\n%s JBS' % (item, values.get('price'))
        button = DirectButton(image=itemImage, scale=0.105, pos=pos, relief=None, parent=page, command=self.shop.purchaseItem, extraArgs=[item])
        button.setTransparency(TransparencyAttrib.MAlpha)
        buttonLabel = DirectLabel(text=label, relief=None, parent=button, text_scale=0.55, pos=(0, 0, -1.6))
        self.addEntryToPage(page, item, values, button, buttonLabel)
        return

    def addEntryToPage(self, page, item, values, button, buttonLabel):
        page.addItemEntry(item, [button, buttonLabel])
        page.addItem({item: values})

    def makePages(self, items):
        newItems = dict(items)
        loadout = []
        for slot in base.localAvatar.getBackpack().gagGUI.getSlots():
            loadout.append(slot.getGag().getID())

        for item, values in newItems.items():
            if values.get('type') == ItemType.GAG:
                gag = item()
                if gag.getID() not in loadout or not base.localAvatar.getBackpack().isInBackpack(gag.getName()):
                    del newItems[item]

        self.nPages = int(len(newItems) / 4)
        if self.nPages % 4 != 0 and len(newItems) > 4:
            self.nPages += 1
        elif self.nPages == 0:
            self.nPages = 1
        itemPos = [(-0.45, 0, 0),
         (-0.15, 0, 0),
         (0.15, 0, 0),
         (0.45, 0, 0)]
        pageIndex = 0
        itemIndex = 0
        index = 1
        for _ in range(self.nPages):
            page = Page(self.shop, self)
            self.pages.append(page)

        for item, values in newItems.iteritems():
            pos = itemPos[itemIndex]
            page = self.pages[pageIndex]
            itemType = values.get('type')
            if itemType == ItemType.GAG:
                self.__makeGagEntry(pos, item, values, page)
            elif itemType == ItemType.UPGRADE:
                self.__makeUpgradeEntry(pos, item, values, page)
            elif itemType == ItemType.HEAL:
                self.__makeHealEntry(pos, item, values, page)
            if index % 4 == 0:
                index = 1
                pageIndex += 1
                itemIndex = 0
            else:
                itemIndex = itemIndex + 1
                index += 1

        if self.nPages == 1:
            self.backBtn.hide()
            self.nextBtn.hide()
        for page in self.pages:
            page.hide()
            page.update()

        self.isSetup = True

    def updatePages(self):
        for page in self.pages:
            page.update()

    def setPage(self, page):
        if self.nPage > -1:
            self.pages[self.nPage].hide()
        self.setBackBtn(True)
        self.setNextBtn(True)
        if page - 1 < 0:
            self.setBackBtn(False)
        elif page + 1 == self.nPages:
            self.setNextBtn(False)
        if page < 0 or page > self.nPages:
            return
        self.prevPage = page - 1
        self.nextPage = page + 1
        self.nPage = page
        self.pages[page].show()

    def setBackBtn(self, enabled):
        if self.backBtn:
            if enabled == False:
                self.backBtn.setColorScale(GRAYED_OUT_COLOR)
                self.backBtn['state'] = DGG.DISABLED
            else:
                self.backBtn.setColorScale(NORMAL_COLOR)
                self.backBtn['state'] = DGG.NORMAL

    def setNextBtn(self, enabled):
        if self.nextBtn:
            if enabled == False:
                self.nextBtn.setColorScale(GRAYED_OUT_COLOR)
                self.nextBtn['state'] = DGG.DISABLED
            else:
                self.nextBtn.setColorScale(NORMAL_COLOR)
                self.nextBtn['state'] = DGG.NORMAL

    def setOKCommand(self, command):
        if self.okBtn:
            self.okBtn['command'] = command

    def setCancelCommand(self, command):
        if self.clBtn:
            self.clBtn['command'] = command

    def showInfo(self, text, negative = 0, duration = -1):
        self.infoLbl.show()
        if negative:
            self.infoLbl['text_fg'] = (0.9, 0, 0, 1)
            self.infoLbl['text_shadow'] = (0, 0, 0, 1)
        else:
            self.infoLbl['text_fg'] = (0, 0, 0, 1)
            self.infoLbl['text_shadow'] = (0, 0, 0, 0)
        self.infoLbl['text'] = text
        if duration > -1:
            Sequence(Wait(duration), Func(self.hideInfo)).start()

    def hideInfo(self):
        if self.infoLbl:
            self.infoLbl.hide()

    def delete(self):
        elements = [self.title,
         self.okBtn,
         self.clBtn,
         self.infoLbl,
         self.backBtn,
         self.nextBtn]
        for element in elements:
            element.destroy()

        del elements
        for page in self.pages:
            page.destroy()
            self.pages.remove(page)

        self.title = None
        self.okBtn = None
        self.clBtn = None
        self.infoLbl = None
        self.backBtn = None
        self.nextBtn = None
        self.bgImage = None
        if self.window:
            self.window.destroy()
            self.window = None
        self.destroy()
        return
class ModPanelButton:
    def __init__(self, menu, name, command, register):
        self.menu = menu
        self.name = name

        self.command = command
        if type(command) == types.StringType:
            command = self.call_word

        self.button = DirectButton(
            frameSize=None,
            text=name,
            image=(ModPanelGlobals.Button.find('**/QuitBtn_UP'),
                   ModPanelGlobals.Button.find('**/QuitBtn_DN'),
                   ModPanelGlobals.Button.find('**/QuitBtn_RLVR')),
            relief=None,
            command=command,
            text_pos=(0, -0.015),
            geom=None,
            pad=(0.01, 0.01),
            suppressKeys=0,
            pos=(0, 0, 0),
            text_scale=0.059,
            borderWidth=(0.015, 0.01),
            scale=.7)

        self.button.reparent_to(menu)

        if register:
            self.button.bind(DirectGuiGlobals.B2PRESS, self.delete_button)
            self.button.bind(DirectGuiGlobals.B3PRESS, self.button.editStart)
            self.button.bind(DirectGuiGlobals.B3RELEASE, self.edit_stop)
            self.menu.buttons.append(self)
            messenger.send('save-file')

    def call_word(self):
        messenger.send('magicWord', [self.command])

    def hide(self):
        self.button.hide()

    def show(self):
        self.button.show()

    def place(self):
        self.button.place()

    def set_pos(self, x, y, z):
        self.button.set_pos(x, y, z)

    def destroy(self):
        self.button.destroy()

    def edit_stop(self, dispatch):
        self.button.editStop(dispatch)

        messenger.send('save-file')

    def delete_button(self, dispatch):
        self.button.destroy()
        if self in self.menu.buttons:
            self.menu.buttons.remove(self)

        messenger.send('save-file')

    def get_data(self):
        return self.name, self.command, self.button.get_pos()
Ejemplo n.º 44
0
class HostMenu(DirectObject):
    def __init__(self):
        self.defaultBtnMap = base.loader.loadModel("gui/button_map")
        self.buttonGeom = (
            self.defaultBtnMap.find("**/button_ready"),
            self.defaultBtnMap.find("**/button_click"),
            self.defaultBtnMap.find("**/button_rollover"),
            self.defaultBtnMap.find("**/button_disabled"))

        defaultFont = loader.loadFont('gui/eufm10.ttf')

        self.logFrame = DirectScrolledFrame(
            canvasSize = (0, base.a2dRight * 2, -5, 0),
            frameSize = (0, base.a2dRight * 2,
                (base.a2dBottom+.2) * 2, 0),
            frameColor = (0.1, 0.1, 0.1, 1))
        self.logFrame.reparentTo(base.a2dTopLeft)

        # create the info and server debug output
        self.textscale = 0.1
        self.txtinfo = OnscreenText(
            scale = self.textscale,
            pos = (0.1, -0.1),
            text = "",
            align = TextNode.ALeft,
            fg = (0.1,1.0,0.15,1),
            bg = (0, 0, 0, 0),
            shadow = (0, 0, 0, 1),
            shadowOffset = (-0.02, -0.02))
        self.txtinfo.setTransparency(1)
        self.txtinfo.reparentTo(self.logFrame.getCanvas())

        # create a close Server button
        self.btnBackPos = Vec3(0.4, 0, 0.2)
        self.btnBackScale = 0.25
        self.btnBack = DirectButton(
            # Scale and position
            scale = self.btnBackScale,
            pos = self.btnBackPos,
            # Text
            text = "Quit Server",
            text_scale = 0.45,
            text_pos = (0, -0.1),
            text_fg = (0.82,0.85,0.87,1),
            text_shadow = (0, 0, 0, 1),
            text_shadowOffset = (-0.02, -0.02),
            text_font = defaultFont,
            # Frame
            geom = self.buttonGeom,
            frameColor = (0, 0, 0, 0),
            relief = 0,
            pressEffect = False,
            # Functionality
            command = self.back,
            rolloverSound = None,
            clickSound = None)
        self.btnBack.setTransparency(1)
        self.btnBack.reparentTo(base.a2dBottomLeft)

        # catch window resizes and recalculate the aspectration
        self.accept("window-event", self.recalcAspectRatio)
        self.accept("addLog", self.addLog)

    def show(self):
        self.logFrame.show()
        self.btnBack.show()

    def hide(self):
        self.logFrame.hide()
        self.btnBack.hide()

    def back(self):
        self.hide()
        base.messenger.send("stop_server")
        self.addLog("Quit Server!")

    def addLog(self, text):
        self.txtinfo.appendText(text + "\n")
        textbounds = self.txtinfo.getTightBounds()
        self.logFrame["canvasSize"] = (0, textbounds[1].getX(),
                                        textbounds[0].getZ(), 0)

    def recalcAspectRatio(self, window):
        """get the new aspect ratio to resize the mainframe"""
        # set the mainframe size to the window borders again
        self.logFrame["frameSize"] = (
            0, base.a2dRight * 2,
            (base.a2dBottom+.2) * 2, 0)
class GroupTrackerPage(ShtikerPage.ShtikerPage):
    notify = directNotify.newCategory('GroupTrackerPage')

    def __init__(self):
        ShtikerPage.ShtikerPage.__init__(self)
        self.groupWidgets = []
        self.playerWidgets = []
        self.images = []                # image nodes: Possible images to apply on groups
        self.scrollList = None          # DirectScrolledList: Holds the GroupTrackerGroup widgets
        self.scrollTitle = None         # DirectLabel: Title of the list that holds the groups
        self.playerList = None          # DirectScrolledList: Holds players when showing a specific group details
        self.playerListTitle = None     # DirectLabel: Title of the playerList
        self.groupInfoTitle = None      # DirectLabel: holds the group detail title to show on the right
        self.groupInfoDistrict = None   # DirectLabel: shows group detail district on the right
        self.statusMessage = None       # DirectLabel: Shows important messages like Loading... or "No boarding groups available"
        self.groupIcon = None           # DirectButton: Icon to associate with the group ex. sellbot icon or cashbot icon depending on group info
        self.wantGroupToggle = None     # DirectButton: Allows the toon to toggle his listing

    def load(self):
        self.listXorigin = -0.02
        self.listFrameSizeX = 0.67
        self.listZorigin = -0.96
        self.listFrameSizeZ = 1.04
        self.arrowButtonScale = 1.3
        self.itemFrameXorigin = -0.237
        self.itemFrameZorigin = 0.365
        self.buttonXstart = self.itemFrameXorigin + 0.293
        self.gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
        guiButton = loader.loadModel('phase_3/models/gui/quit_button')
        self.scrollList = DirectScrolledList(parent=self, 
                                            relief=None, 
                                            pos=(-0.5, 0, 0), 
                                            incButton_image=(self.gui.find('**/FndsLst_ScrollUp'), 
                                                             self.gui.find('**/FndsLst_ScrollDN'),
                                                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
                                                             self.gui.find('**/FndsLst_ScrollUp')
                                                             ), 
                                            incButton_relief=None, 
                                            incButton_scale=(self.arrowButtonScale, self.arrowButtonScale, -self.arrowButtonScale), 
                                            incButton_pos=(self.buttonXstart, 0, self.itemFrameZorigin - 0.999), 
                                            incButton_image3_color=Vec4(1, 1, 1, 0.2), 
                                            decButton_image=(self.gui.find('**/FndsLst_ScrollUp'), 
                                                             self.gui.find('**/FndsLst_ScrollDN'),
                                                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'), 
                                                             self.gui.find('**/FndsLst_ScrollUp')
                                                             ), 
                                            decButton_relief=None, 
                                            decButton_scale=(self.arrowButtonScale, self.arrowButtonScale, self.arrowButtonScale), 
                                            decButton_pos=(self.buttonXstart, 0, self.itemFrameZorigin + 0.227), 
                                            decButton_image3_color=Vec4(1, 1, 1, 0.2), 
                                            itemFrame_pos=(self.itemFrameXorigin, 0, self.itemFrameZorigin), 
                                            itemFrame_scale=1.0,
                                            itemFrame_relief=DGG.SUNKEN, 
                                            itemFrame_frameSize=(self.listXorigin, self.listXorigin + self.listFrameSizeX,
                                                                 self.listZorigin, self.listZorigin + self.listFrameSizeZ
                                                                 ), 
                                            itemFrame_frameColor=(0.85, 0.95, 1, 1), 
                                            itemFrame_borderWidth=(0.01, 0.01), 
                                            numItemsVisible=15, 
                                            forceHeight=0.065, 
                                            items=self.groupWidgets
                                            )
                                            
        self.scrollTitle = DirectFrame(parent=self.scrollList, 
                                       text=TTLocalizer.GroupTrackerListTitle, 
                                       text_scale=0.06, 
                                       text_align=TextNode.ACenter, 
                                       relief=None,
                                       pos=(self.buttonXstart, 0, self.itemFrameZorigin + 0.127)
                                       )
        
        self.playerList = DirectScrolledList(parent=self, 
                                            relief=None, 
                                            pos=(0.45, 0, 0.1), 
                                            
                                            incButton_image=(self.gui.find('**/FndsLst_ScrollUp'), 
                                                             self.gui.find('**/FndsLst_ScrollDN'),
                                                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'),
                                                             self.gui.find('**/FndsLst_ScrollUp')
                                                             ), 
                                            incButton_relief=None, 
                                            incButton_scale=(1.0, 1.0, -1.0), 
                                            incButton_pos=(0, 0, -0.28), 
                                            incButton_image3_color=Vec4(1, 1, 1, 0.05),
                                            
                                            decButton_image=(self.gui.find('**/FndsLst_ScrollUp'), 
                                                             self.gui.find('**/FndsLst_ScrollDN'),
                                                             self.gui.find('**/FndsLst_ScrollUp_Rllvr'), 
                                                             self.gui.find('**/FndsLst_ScrollUp')
                                                             ), 
                                            decButton_relief=None, 
                                            decButton_scale=(1.0, 1.0, 1.0),
                                            decButton_pos=(0.0, 0, 0.04), 
                                            decButton_image3_color=Vec4(1, 1, 1, 0.25), 
                                            
                                            itemFrame_pos=(0, 0, -0.05), 
                                            itemFrame_scale=1.0,
                                            itemFrame_relief=DGG.SUNKEN, 
                                            itemFrame_frameSize=(-0.3, 0.3,  #x
                                                                 -0.2, 0.06),  #z
                                            itemFrame_frameColor=(0.85, 0.95, 1, 1), 
                                            itemFrame_borderWidth=(0.01, 0.01), 
                                            numItemsVisible=4,
                                            forceHeight=0.05, 
                                            items=self.playerWidgets
                                            )
                                            
        self.playerListTitle = DirectFrame(parent=self.playerList, 
                                       text='', 
                                       text_scale=0.05, 
                                       text_align=TextNode.ACenter, 
                                       relief=None,
                                       pos=(0, 0, 0.08)
                                       )
        self.groupInfoTitle = DirectLabel(parent=self, text='', 
                                          text_scale=0.080, text_align=TextNode.ACenter,
                                          text_wordwrap=15, relief=None, pos=(0.45, 0, 0.5))
        self.groupInfoDistrict = DirectLabel(parent=self,
                                     text='',
                                     text_scale=0.050,
                                     text_align=TextNode.ACenter, 
                                     text_wordwrap=15, 
                                     relief=None, 
                                     pos=(0.45, 0, 0.4)
                                     )
        
        self.statusMessage = DirectLabel(parent=self, text='', text_scale=0.060, text_align=TextNode.ACenter, text_wordwrap=5, relief=None, pos=(0.45,0,0.1))
                                     
        # Group Image:
        self.groupIcon = DirectButton(parent=self, relief=None, state=DGG.DISABLED, image=None, image_scale=(0.35, 1, 0.35), image_color=Vec4(1.0, 1.0, 1.0, 0.75), pos=(0.45, 10, -0.45), command=self.doNothing)
        
        # Group Toggle:
        self.wantGroupToggle = DirectButton(parent=self, relief=None, image=(guiButton.find('**/QuitBtn_UP'), guiButton.find('**/QuitBtn_DN'), guiButton.find('**/QuitBtn_RLVR')), image_scale=(0.7, 1, 1), text='', text_scale=0.052, text_pos=(0, -0.02), pos=(0.2, 0, -0.65), command=self.toggleWantGroup)
        self.updateWantGroupButton()
        
        
        # Loading possible group icons
        suitIcons = loader.loadModel('phase_3/models/gui/cog_icons')     
        bossbotIcon = suitIcons.find('**/CorpIcon')
        bossbotIcon.setColor(SUIT_ICON_COLORS[0])
        self.images.append(bossbotIcon)
        
        lawbotIcon = suitIcons.find('**/LegalIcon')
        lawbotIcon.setColor(SUIT_ICON_COLORS[1])
        self.images.append(lawbotIcon)
        
        cashbotIcon = suitIcons.find('**/MoneyIcon')
        cashbotIcon.setColor(SUIT_ICON_COLORS[2])
        self.images.append(cashbotIcon)
        
        sellbotIcon = suitIcons.find('**/SalesIcon')
        sellbotIcon.setColor(SUIT_ICON_COLORS[3])
        self.images.append(sellbotIcon)
        
        # Clean up
        self.clearGroupInfo()
        self.statusMessage.hide()
        
        suitIcons.removeNode()
        self.gui.removeNode()
        guiButton.removeNode()

        self.accept('GroupTrackerResponse', self.updatePage)

    def unload(self):
        self.scrollList.destroy()
        self.groupInfoDistrict.destroy()
        self.playerList.destroy()
        self.groupInfoTitle.destroy()
        self.groupIcon.destroy()
        self.wantGroupToggle.destroy()
        for widget in self.playerWidgets:
            widget.destroy()
        for widget in self.groupWidgets:
            widget.destroy()
        self.playerWidgets = []
        
        del self.scrollList
        del self.groupInfoDistrict
        del self.playerList
        del self.groupInfoTitle
        del self.groupIcon
        del self.wantGroupToggle
        ShtikerPage.ShtikerPage.unload(self)

    def enter(self):
        ShtikerPage.ShtikerPage.enter(self)
        self.setGroups([]) # CLEAR IT ALL
        self.setPlayers()  # CLEAR IT ALL
        if(self.scrollList['items'] == []):
            self.statusMessage['text'] = TTLocalizer.GroupTrackerLoading
            self.statusMessage.show()
        base.cr.globalGroupTracker.requestGroups()
        taskMgr.doMethodLater(3, self.displayNoGroupsTaskHandler, self.uniqueName('timeout'))

    def displayNoGroups(self):
        self.statusMessage['text'] = TTLocalizer.GroupTrackerEmpty
        self.statusMessage.show()
        self.clearGroupInfo()
    
    def displayNoGroupsTaskHandler(self, task):
        self.displayNoGroups()
        return task.done

    def updatePage(self):
        taskMgr.remove(self.uniqueName('timeout'))
        groups = base.cr.globalGroupTracker.getGroupInfo()
        self.setGroups(groups)
        
    def exit(self):
        self.clearGroupInfo()
        ShtikerPage.ShtikerPage.exit(self)
        base.cr.globalGroupTracker.doneRequesting()
    
    def updateGroupInfoEventHandle(self, groupWidget, mouseEvent):
        self.updateGroupInfo(groupWidget)
        
    def updateGroupInfo(self, groupWidget):
        ''' Updates the Right Page of the Group Tracker Page with new Info '''
        self.statusMessage.hide()

        # Update the Player List
        self.setPlayers(groupWidget)
        self.playerList.show()

        # Update the Player List Title
        self.playerListTitle['text'] = ('Players ' + str(groupWidget.getCurrentPlayers()) + '/' + str(groupWidget.getMaxPlayers()) + ':')
        self.playerListTitle.show()

        # Update the District
        self.groupInfoDistrict['text'] = TTLocalizer.BoardingGroupDistrictInformation % { 'district' : groupWidget.getDistrict() }
        self.groupInfoDistrict.show()

        # Update the Title
        self.groupInfoTitle['text'] = groupWidget.getTitle()
        self.groupInfoTitle.show()

        # Update the Image
        self.groupIcon['image'] = self.images[GroupTrackerGlobals.CATEGORY_TO_IMAGE_ID[groupWidget.getCategory()]]
        self.groupIcon['image_scale'] = (0.35, 1, 0.35)
        self.groupIcon.show()

    def clearGroupInfo(self):
        self.playerList.hide()
        self.playerListTitle.hide()
        self.groupInfoDistrict.hide()
        self.groupInfoTitle.hide()
        self.groupIcon.hide()

    def setPlayers(self, groupWidget=None):
        ''' Calls updatePlayerList '''

        # Clear the Widgets that were held in the listings
        for playerWidget in self.playerWidgets:
            playerWidget.destroy()
        self.playerWidgets = []

        # Make a player widget for each player
        # TODO: Edit this stuff when avIds come from players
        if groupWidget:
            leaderId = groupWidget.getLeaderId()
            playerNames = groupWidget.getMemberNames()
            playerIds = groupWidget.getMemberIds()
            for playerName in playerNames:
                playerId = playerIds[playerNames.index(playerName)]
                isLeader = playerId == leaderId
                self.playerWidgets.append(GroupTrackerPlayer(parent=self, avId=playerId, name=playerName, isLeader=isLeader))

        self.updatePlayerList()

    def reconsiderGroupInfo(self, groupWidget):
        ''' If someone is viewing this info and it was updated, we also want to update the info being viewed '''
        if self.playerWidgets is None or self.playerList['items'] == []:
            return # No Info is being viewed at the moment since you cant have an empty group
        
        # We have to update if this group's leader is the leader in the playerlist being viewed right now
        leaderId = groupWidget.getLeaderId()
        
        # Check all the players in the playerList being viewed for the same leader
        for playerWidget in self.playerWidgets:
            if playerWidget.getLeader():
                if leaderId == playerWidget.getId():
                    self.updateGroupInfo(groupWidget)
                    return False
        
        return True
                
    def setGroups(self, groups):
        ''' Calls updateGroupList '''
        
        # Clear our Group Widgets
        for group in self.groupWidgets:
            group.destroy()
        self.groupWidgets = []
        
        wantReconsiderInfo = True
    
        # Create a new group widget for each group
        for group in groups:
            if not group[GroupTrackerGlobals.SHOW] or len(group[GroupTrackerGlobals.MEMBER_IDS]) == 0:
                continue # We are using this to see if this group is dead or if someone doesnt want it up
            leaderId = 0
            for i, g in base.cr.globalGroupTracker.leader2Group.items():
                if g == group:
                    leaderId = i
            if not leaderId:
                continue
                
            leaderName = group[GroupTrackerGlobals.LEADER_NAME]
            shardName = group[GroupTrackerGlobals.SHARD_NAME]
            category = group[GroupTrackerGlobals.CATEGORY]
            memberIds = group[GroupTrackerGlobals.MEMBER_IDS]
            memberNames = group[GroupTrackerGlobals.MEMBER_NAMES]
            
            groupWidget = GroupTrackerGroup(parent=self, leaderId=leaderId, leaderName=leaderName, shardName=shardName, category=category, memberIds=memberIds, memberNames=memberNames)
            groupWidget.bind(DGG.WITHIN, self.updateGroupInfoEventHandle, extraArgs=[groupWidget])
            self.groupWidgets.append(groupWidget)
            if wantReconsiderInfo:
                wantReconsiderInfo = self.reconsiderGroupInfo(groupWidget)
        
        # Edge case where a group that was removed, info might remain on the screen if it didn't exist any more
        if wantReconsiderInfo:
            self.clearGroupInfo()
        
        # There are no groups, hide the information
        if len(self.groupWidgets) == 0:
            self.displayNoGroups()
        self.updateGroupList()

    def updateGroupList(self): 
        self.statusMessage.hide()
        if self.scrollList is None:
            return
            
        # Clear the Group Listing
        for item in self.scrollList['items']:
            if item:
                self.scrollList.removeItem(item, refresh=True)
        self.scrollList['items'] = []
        
        # Re-populate the Group Listing
        for groupWidget in self.groupWidgets:
            self.scrollList.addItem(groupWidget, refresh=True)
        
        if len(self.groupWidgets) == 0:
            self.displayNoGroups()

    def updatePlayerList(self):
        if self.playerList is None:
            return

        # Clear the Player Listing
        for item in self.playerList['items']:
            if item:
                self.playerList.removeItem(item)
        self.playerList['items'] = []

        # Re-Populate the List
        for playerWidget in self.playerWidgets:
            self.playerList.addItem(playerWidget)

    def toggleWantGroup(self):
        if settings.get('grouptracker', False):
            settings['grouptracker'] = False
            base.cr.globalGroupTracker.showMe(False)
        else:
            settings['grouptracker'] = True
            base.cr.globalGroupTracker.showMe(True)
            
        base.localAvatar.wantGroupTracker()
        
        base.localAvatar.wantGroupTracker() # Updates the ai toon so the boarding group AI could know what he wants
        self.updateWantGroupButton()
    
    def updateWantGroupButton(self):
        if settings.get('grouptracker', False):
            self.wantGroupToggle['text'] = 'Hide Me'
        else:
            self.wantGroupToggle['text'] = 'Show Me'
            
    def doNothing(self):
        pass