410 lines
18 KiB
Python
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
|