toontown-just-works/toontown/estate/PlantingGUI.py
2024-07-07 18:08:39 -05:00

410 lines
18 KiB
Python

from direct.gui.DirectGui import *
from panda3d.core import *
from direct.directnotify import DirectNotifyGlobal
from toontown.toonbase import ToontownGlobals
from toontown.toonbase import TTLocalizer
from direct.task import Task
from toontown.estate import GardenGlobals
from direct.interval.IntervalGlobal import *
from toontown.estate import SpecialsPhoto
USE_SCROLLING_BEAN_BOX = False
JELLY_BEAN_PICKER_HAS_EMPTY_BOX = False
CAN_CHANGE_BEAN_COLOR = True
FORCE_LEFT_TO_RIGHT = True
ONLY_ONE_SPIFFY_BOX_CAN_BE_CLICKED = True
DO_PICKER_INTERVAL = False
PICKER_ALWAYS_UP = True
def loadJellyBean(parent, beanIndex):
gui = loader.loadModel('phase_5.5/models/estate/jellyBean')
newBean = gui.instanceTo(parent)
parent.setScale(0.09)
colors = GardenGlobals.BeanColors[beanIndex]
parent.setColorScale(colors[0] / 255.0 * 1.0, colors[1] / 255.0 * 1.0, colors[2] / 255.0 * 1.0, 1)
class GenericBoxScrollList(DirectScrolledList):
def __init__(self, parent, items, **kw):
gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui')
self.forceHeight = 1
optiondefs = (('parent', parent, None),
('relief', None, None),
('incButton_image', (gui.find('**/FndsLst_ScrollUp'),
gui.find('**/FndsLst_ScrollDN'),
gui.find('**/FndsLst_ScrollUp_Rllvr'),
gui.find('**/FndsLst_ScrollUp')), None),
('incButton_relief', None, None),
('incButton_scale', (1.3, 1.3, -1.3), None),
('incButton_pos', (0, 0, -0.525), None),
('incButton_image3_color', Vec4(0.8, 0.8, 0.8, 0.5), None),
('decButton_image', (gui.find('**/FndsLst_ScrollUp'),
gui.find('**/FndsLst_ScrollDN'),
gui.find('**/FndsLst_ScrollUp_Rllvr'),
gui.find('**/FndsLst_ScrollUp')), None),
('decButton_relief', None, None),
('decButton_scale', (1.3, 1.3, 1.3), None),
('decButton_pos', (0, 0, 0.525), None),
('decButton_image3_color', Vec4(0.8, 0.8, 0.8, 0.5), None),
('numItemsVisible', 1, None),
('items', items, None),
('scrollSpeed', 1.0, None),
('forceHeight', 1, None))
gui.removeNode()
self.defineoptions(kw, optiondefs)
DirectScrolledList.__init__(self, parent, forceHeight=self.forceHeight)
self.initialiseoptions(GenericBoxScrollList)
return None
class BoxItem(NodePath):
def getHeight(self):
return 0.05
JellyBeanPickerEndPos = (0, 0, 0.1)
JellyBeanPickerScale = (1.1, 1.0, 0.13)
if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
JellyBeanPickerGeomScale = (1.0, 1.0, 1.0)
else:
JellyBeanPickerGeomScale = (0.9, 1.0, 1.0)
JellyBeanPickerScaleInverse = (1.0 / JellyBeanPickerScale[0], 1.0 / JellyBeanPickerScale[1], 1.0 / JellyBeanPickerScale[2])
class JellyBeanPicker(DirectFrame):
notify = DirectNotifyGlobal.directNotify.newCategory('PlantingGUI')
def __init__(self, parent, callBack, boxPosition, **kw):
self.index = 0
self.selectedIndex = 0
self.callBack = callBack
self.boxPosition = boxPosition
DirectFrame.__init__(self, relief=None, state='normal', geom=DGG.getDefaultDialogGeom(), geom_color=(0.8, 0.8, 0.8, 1.0), geom_scale=JellyBeanPickerGeomScale, scale=JellyBeanPickerScale, frameSize=(-1, 1, -1, 1), pos=(0, 0, 0))
self.initialiseoptions(JellyBeanPicker)
self.jellyBeanBoxList = []
self.createJellyBeanBoxes()
return
def jellyBeanBoxClicked(self, beanIndex):
if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
self.callBack(self.boxPosition, beanIndex)
else:
self.callBack(self.boxPosition, beanIndex + 1)
def createJellyBeanBox(self, beanIndex, xPos, zPos):
geomColor = (1, 1, 1, 1)
state = DGG.NORMAL
command = self.jellyBeanBoxClicked
newBox = DirectButton(parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(0.1, 1.0, 0.1), geom_color=geomColor, scale=JellyBeanPickerScaleInverse, relief=None, state=state, command=command, extraArgs=[beanIndex], text='', text_pos=(0.0, 0.1), text_scale=0.07, text_fg=Vec4(0, 0, 0, 0), text1_fg=Vec4(0, 0, 0, 0), text2_fg=Vec4(0, 0, 0, 1), text3_fg=Vec4(0, 0, 0, 0))
if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
if beanIndex:
beanParent = newBox.attachNewNode('bean_%d' % (beanIndex - 1))
loadJellyBean(beanParent, beanIndex - 1)
else:
beanParent = newBox.attachNewNode('bean_%d' % beanIndex)
loadJellyBean(beanParent, beanIndex)
self.jellyBeanBoxList.append(newBox)
return
def setColorText(self):
for beanIndex in xrange(len(self.jellyBeanBoxList)):
if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
if beanIndex:
box = self.jellyBeanBoxList[beanIndex]
box['text'] = TTLocalizer.BeanColorWords[beanIndex - 1]
else:
box = self.jellyBeanBoxList[beanIndex]
box['text'] = TTLocalizer.BeanColorWords[beanIndex]
def createJellyBeanBoxes(self):
zCoord = 0
xIncrement = 0.095
xPos = 0
maxBoxes = len(GardenGlobals.BeanColors)
if JELLY_BEAN_PICKER_HAS_EMPTY_BOX:
maxBoxes += 1
startingXCoord = -0.1 * float(maxBoxes) / 2.0 + 0.075
for activeBox in xrange(maxBoxes):
xPos = xIncrement * activeBox + startingXCoord
self.createJellyBeanBox(activeBox, xPos, zCoord)
class SpiffyBeanBox(DirectButton):
def __init__(self, parent, index, **kw):
self.boxIndex = index
self.selectedIndex = 0
optiondefs = ()
self.defineoptions(kw, optiondefs)
DirectButton.__init__(self, parent=parent)
self.initialiseoptions(SpiffyBeanBox)
self.selectedBean = self.attachNewNode('selectedBean')
def getSelectedIndex(self):
if hasattr(self, 'selectedIndex'):
return self.selectedIndex
return 0
def setSelectedIndex(self, newIndex):
self.selectedIndex = newIndex
self.selectedBean.removeNode()
self.selectedBean = self.attachNewNode('selectedBean')
if newIndex:
newIndex -= 1
loadJellyBean(self.selectedBean, newIndex)
class PlantingGUI(DirectFrame):
notify = DirectNotifyGlobal.directNotify.newCategory('PlantingGUI')
def __init__(self, doneEvent, specialBoxActive = False):
if specialBoxActive:
instructions = TTLocalizer.GardeningChooseBeansItem
instructionsPos = (0, 0.4)
else:
instructions = TTLocalizer.GardeningChooseBeans
instructionsPos = (0, 0.35)
DirectFrame.__init__(self, relief=None, state='normal', geom=DGG.getDefaultDialogGeom(), geom_color=ToontownGlobals.GlobalDialogColor, geom_scale=(1.5, 1.0, 1.0), frameSize=(-1, 1, -1, 1), pos=(0, 0, 0), text=instructions, text_wordwrap=20, text_scale=0.08, text_pos=instructionsPos)
self.initialiseoptions(PlantingGUI)
self.doneEvent = doneEvent
buttons = loader.loadModel('phase_3/models/gui/dialog_box_buttons_gui')
okImageList = (buttons.find('**/ChtBx_OKBtn_UP'), buttons.find('**/ChtBx_OKBtn_DN'), buttons.find('**/ChtBx_OKBtn_Rllvr'))
cancelImageList = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr'))
resetImageList = (buttons.find('**/CloseBtn_UP'), buttons.find('**/CloseBtn_DN'), buttons.find('**/CloseBtn_Rllvr'))
self.cancelButton = DirectButton(parent=self, relief=None, image=cancelImageList, pos=(-0.3, 0, -0.35), text=TTLocalizer.PlantingGuiCancel, text_scale=0.06, text_pos=(0, -0.1), command=self.__cancel)
self.okButton = DirectButton(parent=self, relief=None, image=okImageList, pos=(0.3, 0, -0.35), text=TTLocalizer.PlantingGuiOk, text_scale=0.06, text_pos=(0, -0.1), command=self.__doPlant)
self.resetButton = DirectButton(parent=self, relief=None, image=resetImageList, pos=(0.0, 0, -0.35), text=TTLocalizer.PlantingGuiReset, text_scale=0.06, text_pos=(0, -0.1), command=self.__reset)
buttons.removeNode()
self.availableBoxes = base.localAvatar.getBoxCapability()
self.maxBoxes = GardenGlobals.getNumberOfShovelBoxes()
self.activeBoxesList = []
self.specialBox = None
self.specialBoxActive = specialBoxActive
self.boxList = []
self.jellyBeanPicker = None
self.jellyBeanPickerInterval = None
self.createBoxes()
guiItems = loader.loadModel('phase_5.5/models/gui/catalog_gui')
self.beanBank = DirectLabel(self, relief=None, image=guiItems.find('**/bean_bank'), text=str(base.localAvatar.getMoney() + base.localAvatar.getBankMoney()), text_align=TextNode.ARight, text_scale=0.11, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1), text_pos=(0.75, -0.81), text_font=ToontownGlobals.getSignFont(), pos=(-0.85, 0, 0.2), scale=0.5)
self.matchBoxesToAvailableMoney()
if PICKER_ALWAYS_UP:
self.spiffyBeanBoxClicked(0)
return
def destroy(self):
if self.boxList:
for box in self.boxList:
box.destroy()
self.boxList = []
DirectFrame.destroy(self)
self.doneEvent = None
if self.jellyBeanPickerInterval:
self.jellyBeanPickerInterval.finish()
self.jellyBeanPickerInterval = None
if self.jellyBeanPicker:
self.jellyBeanPicker.destroy()
self.jellyBeanPicker = None
if hasattr(self, 'specialPhotoList') and self.specialPhotoList:
for photo in self.specialPhotoList:
photo.destroy()
self.specialPhotoList = []
return
def __cancel(self):
messenger.send(self.doneEvent, [0, '', -1])
messenger.send('wakeup')
def __reset(self):
if self.jellyBeanPicker:
self.jellyBeanPicker.destroy()
for box in self.boxList:
box.setSelectedIndex(0)
self.beanBank['text'] = str(base.localAvatar.getMoney() + base.localAvatar.getBankMoney())
self.matchBoxesToAvailableMoney()
if PICKER_ALWAYS_UP:
self.spiffyBeanBoxClicked(0)
messenger.send('wakeup')
def getRecipeStr(self):
retval = ''
for box in self.boxList:
beanIndex = box.getSelectedIndex()
if beanIndex:
beanIndex -= 1
beanLetter = GardenGlobals.BeanColorLetters[beanIndex]
retval += beanLetter
return retval
def __doPlant(self):
recipeStr = self.getRecipeStr()
selectedSpecial = self.specialButton.getSelectedIndex()
selectedSpecial -= 1
messenger.send(self.doneEvent, [1, recipeStr, selectedSpecial])
messenger.send('wakeup')
def createBoxes(self):
zCoord = -0.15
xIncrement = 0.1
xPos = 0
startingXCoord = -0.1 * float(self.maxBoxes) / 2.0 + 0.05
for activeBox in xrange(self.availableBoxes):
xPos = xIncrement * activeBox + startingXCoord
if USE_SCROLLING_BEAN_BOX:
self.createScrollingBeanBox(activeBox, xPos, zCoord, True)
else:
self.createSpiffyBeanBox(activeBox, xPos, zCoord, True)
for disabledBox in xrange(self.availableBoxes, self.maxBoxes):
xPos = xIncrement * disabledBox + startingXCoord
if USE_SCROLLING_BEAN_BOX:
self.createScrollingBeanBox(disabledBox, xPos, zCoord, False)
else:
self.createSpiffyBeanBox(disabledBox, xPos, zCoord, False)
xPos += xIncrement * 2
self.createSpecialBox(xPos, zCoord)
def createSpecialBox(self, xPos, zPos):
geomColor = (1, 1, 1, 1)
if not self.specialBoxActive:
geomColor = (0.5, 0.5, 0.5, 1)
geomScaleX = 0.2
geomScaleZ = 0.2
self.specialButtonFrame = DirectFrame(parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(geomScaleX, 1.0, geomScaleZ), geom_color=geomColor, relief=None)
items = []
if self.specialBoxActive:
gardenSpecials = base.localAvatar.getGardenSpecials()
tempItem = BoxItem(self.attachNewNode('blankSpecial'))
items.append(tempItem)
self.specialPhotoList = []
for item in gardenSpecials:
tempItem = BoxItem(self.specialButtonFrame.attachNewNode('temp1'))
specialsPhoto = SpecialsPhoto.SpecialsPhoto(item[0], parent=tempItem)
specialsPhoto.setBackBounds(-geomScaleX / 2.0, geomScaleX / 2.0, -geomScaleZ / 2.0, geomScaleZ / 2.0)
specialsPhoto.setBackColor(1.0, 1.0, 1.0, 1.0)
items.append(tempItem)
self.specialPhotoList.append(specialsPhoto)
self.specialButton = GenericBoxScrollList(self.specialButtonFrame, items, incButton_pos=(0, 0, -0.135), incButton_scale=(0.75, 1.0, -1.0), decButton_pos=(0, 0, 0.135), decButton_scale=(0.75, 1.0, 1.0), command=self.photoSpecialChanged)
return
def photoSpecialChanged(self):
if not hasattr(self, 'specialButton'):
return
messenger.send('wakeup')
selectedSpecial = self.specialButton.getSelectedIndex()
if selectedSpecial == 0:
for photo in self.specialPhotoList:
photo.hide()
else:
selectedSpecial -= 1
self.specialPhotoList[selectedSpecial].show()
def showFirstSpecial(self):
if len(self.specialButton['items']) > 1:
self.specialButton.scrollTo(self.specialButton.getSelectedIndex() + 1)
def createScrollingBeanBox(self, index, xPos, zPos, active):
geomColor = (1, 1, 1, 1)
if not active:
geomColor = (0.5, 0.5, 0.5, 1)
boxFrame = DirectFrame(parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(0.1, 1.0, 0.1), geom_color=geomColor, relief=None)
items = []
if active:
tempItem = BoxItem(self.attachNewNode('emptyBean'))
items.append(tempItem)
for curBean in xrange(len(GardenGlobals.BeanColors)):
tempItem = BoxItem(self.attachNewNode('bean-%d-%d' % (index, curBean)))
loadJellyBean(tempItem, curBean)
items.append(tempItem)
box = GenericBoxScrollList(boxFrame, items, incButton_pos=(0, 0, -0.07), incButton_scale=(0.4, 1.0, -1.0), decButton_pos=(0, 0, 0.065), decButton_scale=(0.4, 1.0, 1.0))
self.boxList.append(box)
return
def spiffyBeanBoxClicked(self, index):
if self.jellyBeanPicker:
self.jellyBeanPicker.destroy()
outOfMoney = int(self.beanBank['text']) <= 0
if self.boxList[index].getSelectedIndex() == 0 and outOfMoney:
return
if not CAN_CHANGE_BEAN_COLOR and self.boxList[index].getSelectedIndex():
return
self.jellyBeanPicker = JellyBeanPicker(self, self.selectedNewBeanColor, index)
self.jellyBeanPicker.setPos(*JellyBeanPickerEndPos)
if DO_PICKER_INTERVAL:
boxPos = self.boxList[index].getPos()
self.jellyBeanPicker.setPos(boxPos)
self.jellyBeanPickerInterval = Sequence(Parallel(self.jellyBeanPicker.posInterval(duration=0.3, pos=VBase3(*JellyBeanPickerEndPos)), self.jellyBeanPicker.scaleInterval(duration=0.3, startScale=VBase3(JellyBeanPickerScale[0] / 10.0, JellyBeanPickerScale[1], JellyBeanPickerScale[2]), scale=VBase3(*JellyBeanPickerScale))), Func(self.jellyBeanPicker.setColorText))
self.jellyBeanPickerInterval.start()
else:
self.jellyBeanPicker.setColorText()
def matchBoxesToAvailableMoney(self):
outOfMoney = int(self.beanBank['text']) <= 0
if outOfMoney:
for box in self.boxList:
if box.getSelectedIndex() == 0:
box['state'] = DGG.DISABLED
box.setState()
box.setColorScale(0.5, 0.5, 0.5, 1)
else:
for box in self.boxList:
box['state'] = DGG.NORMAL
box.setState()
box.setColorScale(1, 1, 1, 1)
if FORCE_LEFT_TO_RIGHT:
boxIndexToEnable = len(self.getRecipeStr())
for i in xrange(0, boxIndexToEnable):
box = self.boxList[i]
if ONLY_ONE_SPIFFY_BOX_CAN_BE_CLICKED:
box['state'] = DGG.DISABLED
box.setState()
box.setColorScale(0.875, 0.875, 0.875, 1)
if boxIndexToEnable < self.maxBoxes:
box = self.boxList[boxIndexToEnable]
if boxIndexToEnable >= self.availableBoxes:
box['state'] = DGG.DISABLED
box.setState()
box.setColorScale(0.5, 0.5, 0.5, 1)
for i in xrange(boxIndexToEnable + 1, len(self.boxList)):
box = self.boxList[i]
box['state'] = DGG.DISABLED
box.setState()
box.setColorScale(0.5, 0.5, 0.5, 1)
def selectedNewBeanColor(self, boxPosition, beanIndex):
self.boxList[boxPosition].setSelectedIndex(beanIndex)
if self.jellyBeanPicker:
self.jellyBeanPicker.destroy()
self.jellyBeanPicker = None
cost = len(self.getRecipeStr())
newMoney = base.localAvatar.getMoney() + base.localAvatar.getBankMoney() - cost
self.beanBank['text'] = str(newMoney)
self.matchBoxesToAvailableMoney()
messenger.send('wakeup')
if PICKER_ALWAYS_UP:
numBoxesFilled = len(self.getRecipeStr())
if numBoxesFilled < self.availableBoxes:
self.spiffyBeanBoxClicked(numBoxesFilled)
return
def createSpiffyBeanBox(self, index, xPos, zPos, active):
geomColor = (1, 1, 1, 1)
state = DGG.NORMAL
command = self.spiffyBeanBoxClicked
if not active:
geomColor = (0.5, 0.5, 0.5, 1)
command = None
state = DGG.DISABLED
newBox = SpiffyBeanBox(index=index, parent=self, pos=(xPos, 0, zPos), geom=DGG.getDefaultDialogGeom(), geom_scale=(0.1, 1.0, 0.1), geom_color=geomColor, relief=None, state=state, command=command, extraArgs=[index])
self.boxList.append(newBox)
return