Poodletooth-iLand/toontown/parties/PartyPlanner.py

734 lines
41 KiB
Python

import calendar
from datetime import datetime
from datetime import timedelta
from direct.directnotify import DirectNotifyGlobal
from direct.fsm.FSM import FSM
from direct.gui import DirectGuiGlobals
from direct.gui.DirectGui import DirectFrame, DirectButton, DirectLabel, DirectScrolledList, DirectCheckButton
from direct.showbase import DirectObject
from direct.showbase import PythonUtil
from panda3d.core import *
from otp.otpbase import OTPGlobals
from otp.otpbase import OTPLocalizer
from otp.nametag.NametagGroup import NametagGroup
from otp.nametag.Nametag import Nametag
from otp.nametag.NametagFloat2d import *
from toontown.parties import PartyGlobals
from toontown.parties import PartyUtils
from toontown.parties.CalendarGuiMonth import CalendarGuiMonth
from toontown.parties.InviteVisual import InviteVisual
from toontown.parties.PartyEditor import PartyEditor
from toontown.parties.PartyInfo import PartyInfo
from toontown.parties.ScrolledFriendList import ScrolledFriendList
from toontown.toon import ToonHead
from toontown.toonbase import TTLocalizer
from toontown.toonbase import ToontownGlobals
from toontown.toontowngui import TTDialog
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', skip over the Guests state.
'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 base.cr.newsManager.isHolidayRunning(ToontownGlobals.VICTORY_PARTY_HOLIDAY):
defaultInviteTheme = PartyGlobals.InviteTheme.VictoryParty
elif base.cr.newsManager.isHolidayRunning(ToontownGlobals.KARTING_TICKETS_HOLIDAY) or base.cr.newsManager.isHolidayRunning(ToontownGlobals.GRAND_PRIX):
defaultInviteTheme = PartyGlobals.InviteTheme.Racing
elif base.cr.newsManager.isHolidayRunning(ToontownGlobals.VALENTOONS_DAY):
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(ToontownGlobals.getToonFont())
self.nametagGroup.setSpeechFont(ToontownGlobals.getToonFont())
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)
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)
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)
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.destroy()
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 friendId in base.localAvatar.friendsList:
self.friendList.addFriend(friendId)
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 not base.cr.newsManager.isHolidayRunning(ToontownGlobals.VALENTOONS_DAY):
self.inviteThemes.remove(PartyGlobals.InviteTheme.Valentoons)
if not base.cr.newsManager.isHolidayRunning(ToontownGlobals.VICTORY_PARTY_HOLIDAY):
self.inviteThemes.remove(PartyGlobals.InviteTheme.VictoryParty)
if not base.cr.newsManager.isHolidayRunning(ToontownGlobals.CHRISTMAS):
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))