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())
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
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()
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))
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
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
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()
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('')
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()
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()
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()
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()
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')
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()
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)
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()
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
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)
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
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))
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)
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()
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
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")
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()
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)
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)
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
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
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()
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)
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))
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()
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()
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)
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()
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()
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