263 lines
12 KiB
Python
263 lines
12 KiB
Python
from pandac.PandaModules import Vec3, Vec4, Point3, TextNode, VBase4, NodePath
|
|
from direct.gui.DirectGui import DirectFrame, DirectButton, DirectLabel, DirectScrolledList, DirectCheckButton
|
|
from direct.gui import DirectGuiGlobals
|
|
from direct.showbase import DirectObject
|
|
from direct.showbase import PythonUtil
|
|
from direct.task.Task import Task
|
|
from toontown.toonbase import ToontownGlobals
|
|
from toontown.toonbase import TTLocalizer
|
|
from toontown.parties import PartyGlobals
|
|
from toontown.parties.PartyInfo import PartyInfo
|
|
from toontown.parties import PartyUtils
|
|
|
|
class PartyEditorGridElement(DirectButton):
|
|
notify = directNotify.newCategory('PartyEditorGridElement')
|
|
|
|
def __init__(self, partyEditor, id, isDecoration, checkSoldOutAndPaidStatusAndAffordability, **kw):
|
|
self.partyEditor = partyEditor
|
|
self.id = id
|
|
self.isDecoration = isDecoration
|
|
self.checkSoldOutAndPaidStatusAndAffordability = checkSoldOutAndPaidStatusAndAffordability
|
|
if self.isDecoration:
|
|
self.name = TTLocalizer.PartyDecorationNameDict[self.id]['editor']
|
|
colorList = ((1.0, 1.0, 1.0, 1.0),
|
|
(0.0, 0.0, 1.0, 1.0),
|
|
(0.0, 1.0, 1.0, 1.0),
|
|
(0.5, 0.5, 0.5, 1.0))
|
|
self.geom = self.partyEditor.partyPlanner.gui.find('**/%s' % PartyGlobals.DecorationInformationDict[self.id]['gridAsset'])
|
|
else:
|
|
self.name = TTLocalizer.PartyActivityNameDict[self.id]['editor']
|
|
colorList = ((1.0, 1.0, 1.0, 1.0),
|
|
(0.0, 1.0, 0.0, 1.0),
|
|
(1.0, 1.0, 0.0, 1.0),
|
|
(0.5, 0.5, 0.5, 1.0))
|
|
self.geom = self.partyEditor.partyPlanner.gui.find('**/%s' % PartyGlobals.ActivityInformationDict[self.id]['gridAsset'])
|
|
optiondefs = (('geom', self.geom, None),
|
|
('geom_scale', 1.0, None),
|
|
('geom_color', colorList[0], None),
|
|
('geom1_color', colorList[0], None),
|
|
('geom2_color', colorList[0], None),
|
|
('geom3_color', colorList[0], None),
|
|
('relief', None, None))
|
|
self.defineoptions(kw, optiondefs)
|
|
DirectButton.__init__(self, self.partyEditor.parent)
|
|
self.initialiseoptions(PartyEditorGridElement)
|
|
self.setName('%sGridElement' % self.name)
|
|
self.bind(DirectGuiGlobals.B1PRESS, self.clicked)
|
|
self.bind(DirectGuiGlobals.B1RELEASE, self.released)
|
|
self.bind(DirectGuiGlobals.ENTER, self.mouseEnter)
|
|
self.bind(DirectGuiGlobals.EXIT, self.mouseExit)
|
|
self.uprightNodePath = NodePath('%sUpright' % self.name)
|
|
self.uprightNodePath.reparentTo(self)
|
|
rollOverZOffset = self.getGridSize()[1] / 30.0
|
|
self.rolloverTitle = DirectLabel(relief=None, parent=self.uprightNodePath, pos=Point3(0.0, 0.0, rollOverZOffset), text=self.name, text_fg=(1.0, 1.0, 1.0, 1.0), text_shadow=(0.0, 0.0, 0.0, 1.0), text_scale=0.075)
|
|
self.rolloverTitle.stash()
|
|
self.stash()
|
|
self.overValidSquare = False
|
|
self.lastValidPosition = None
|
|
self.setColorScale(0.9, 0.9, 0.9, 0.7)
|
|
self.setTransparency(True)
|
|
self.mouseOverTrash = False
|
|
self.centerGridSquare = None
|
|
return
|
|
|
|
def getCorrectRotation(self):
|
|
r = self.getR()
|
|
if r == 90.0:
|
|
r = 270.0
|
|
elif r == 270.0:
|
|
r = 90.0
|
|
if self.id == PartyGlobals.ActivityIds.PartyCannon:
|
|
return PartyUtils.convertDegreesToPartyGrid(r + 180.0)
|
|
return PartyUtils.convertDegreesToPartyGrid(r)
|
|
|
|
def getDecorationTuple(self, x, y):
|
|
return (self.id,
|
|
self.centerGridSquare.x,
|
|
PartyGlobals.PartyEditorGridSize[1] - 1 - self.centerGridSquare.y,
|
|
self.getCorrectRotation())
|
|
|
|
def getActivityTuple(self, x, y):
|
|
return (self.id,
|
|
self.centerGridSquare.x,
|
|
PartyGlobals.PartyEditorGridSize[1] - 1 - self.centerGridSquare.y,
|
|
self.getCorrectRotation())
|
|
|
|
def attach(self, mouseEvent):
|
|
PartyEditorGridElement.notify.debug('attached grid element %s' % self.name)
|
|
taskMgr.remove('gridElementDragTask%s' % self.name)
|
|
vWidget2render2d = self.getPos(render2d)
|
|
vMouse2render2d = Point3(mouseEvent.getMouse()[0], 0, mouseEvent.getMouse()[1])
|
|
taskMgr.add(self.elementDragTask, 'gridElementDragTask%s' % self.name)
|
|
self.unstash()
|
|
self.rolloverTitle.unstash()
|
|
self.uprightNodePath.reparentTo(self)
|
|
self.setPosHprToDefault()
|
|
|
|
def elementDragTask(self, state):
|
|
mwn = base.mouseWatcherNode
|
|
if mwn.hasMouse():
|
|
vMouse2render2d = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1])
|
|
newPos = vMouse2render2d
|
|
if newPos[0] > PartyGlobals.PartyEditorGridBounds[0][0] and newPos[0] < PartyGlobals.PartyEditorGridBounds[1][0] and newPos[2] < PartyGlobals.PartyEditorGridBounds[0][1] and newPos[2] > PartyGlobals.PartyEditorGridBounds[1][1]:
|
|
centerGridSquare = self.snapToGrid(newPos)
|
|
if centerGridSquare is not None:
|
|
self.centerGridSquare = centerGridSquare
|
|
if not self.overValidSquare:
|
|
self.setOverValidSquare(True)
|
|
if self.mouseOverTrash:
|
|
self.setOverTrash(False)
|
|
return Task.cont
|
|
if self.id != PartyGlobals.ActivityIds.PartyClock and newPos[0] > PartyGlobals.PartyEditorTrashBounds[0][0] and newPos[0] < PartyGlobals.PartyEditorTrashBounds[1][0] and newPos[2] < PartyGlobals.PartyEditorTrashBounds[0][1] and newPos[2] > PartyGlobals.PartyEditorTrashBounds[1][1]:
|
|
if not self.mouseOverTrash:
|
|
self.setOverTrash(True)
|
|
elif self.mouseOverTrash:
|
|
self.setOverTrash(False)
|
|
self.setPos(render2d, newPos)
|
|
if self.overValidSquare:
|
|
self.setOverValidSquare(False)
|
|
return Task.cont
|
|
|
|
def setOverTrash(self, value):
|
|
self.mouseOverTrash = value
|
|
if value:
|
|
self.partyEditor.trashCanButton['state'] = DirectGuiGlobals.DISABLED
|
|
self.setColorScale(1.0, 0.0, 0.0, 1.0)
|
|
else:
|
|
self.partyEditor.trashCanButton['state'] = DirectGuiGlobals.NORMAL
|
|
self.setColorScale(0.9, 0.9, 0.9, 0.7)
|
|
|
|
def setOverValidSquare(self, value):
|
|
self.overValidSquare = value
|
|
if value:
|
|
self.setColorScale(1.0, 1.0, 1.0, 1.0)
|
|
else:
|
|
self.setColorScale(0.9, 0.9, 0.9, 0.7)
|
|
|
|
def removeFromGrid(self):
|
|
if self.centerGridSquare is not None:
|
|
self.partyEditor.partyEditorGrid.removeElement(self.centerGridSquare, self.getGridSize())
|
|
self.setOverValidSquare(False)
|
|
self.lastValidPosition = None
|
|
self.stash()
|
|
return
|
|
|
|
def snapToGrid(self, newPos):
|
|
gridSquare = self.getGridSquareFromPosition(newPos)
|
|
if gridSquare == None:
|
|
self.setPosHprToDefault()
|
|
self.setPos(render2d, newPos)
|
|
return
|
|
elif not self.partyEditor.partyEditorGrid.checkGridSquareForAvailability(gridSquare, self.getGridSize()):
|
|
self.setPos(render2d, newPos)
|
|
return
|
|
self.setPosHprBasedOnGridSquare(gridSquare)
|
|
return gridSquare
|
|
|
|
def getGridSize(self):
|
|
if self.isDecoration:
|
|
return PartyGlobals.DecorationInformationDict[self.id]['gridsize']
|
|
else:
|
|
return PartyGlobals.ActivityInformationDict[self.id]['gridsize']
|
|
|
|
def setPosHprToDefault(self):
|
|
self.setR(0.0)
|
|
self.uprightNodePath.setR(0.0)
|
|
|
|
def setPosHprBasedOnGridSquare(self, gridSquare):
|
|
gridPos = gridSquare.getPos()
|
|
if self.getGridSize()[0] % 2 == 0:
|
|
gridPos.setX(gridPos[0] + PartyGlobals.PartyEditorGridSquareSize[0] / 2.0)
|
|
if self.getGridSize()[1] % 2 == 0:
|
|
gridPos.setZ(gridPos[2] + PartyGlobals.PartyEditorGridSquareSize[1] / 2.0)
|
|
if self.id != PartyGlobals.ActivityIds.PartyFireworks:
|
|
if gridPos[0] > PartyGlobals.PartyEditorGridCenter[0] + PartyGlobals.PartyEditorGridRotateThreshold:
|
|
self.setR(90.0)
|
|
self.uprightNodePath.setR(-90.0)
|
|
elif gridPos[0] < PartyGlobals.PartyEditorGridCenter[0] - PartyGlobals.PartyEditorGridRotateThreshold:
|
|
self.setR(270.0)
|
|
self.uprightNodePath.setR(-270.0)
|
|
elif gridPos[2] < PartyGlobals.PartyEditorGridCenter[1] - PartyGlobals.PartyEditorGridRotateThreshold:
|
|
self.setR(180.0)
|
|
self.uprightNodePath.setR(-180.0)
|
|
else:
|
|
self.setR(0.0)
|
|
self.uprightNodePath.setR(0.0)
|
|
else:
|
|
self.setR(270.0)
|
|
self.uprightNodePath.setR(-270.0)
|
|
self.setPos(render2d, gridPos)
|
|
self.lastValidPosition = gridPos
|
|
|
|
def getGridSquareFromPosition(self, newPos):
|
|
localX = newPos[0] - PartyGlobals.PartyEditorGridBounds[0][0]
|
|
localY = newPos[2] - PartyGlobals.PartyEditorGridBounds[1][1]
|
|
x = int(localX / PartyGlobals.PartyEditorGridSquareSize[0])
|
|
y = int(localY / PartyGlobals.PartyEditorGridSquareSize[1])
|
|
y = PartyGlobals.PartyEditorGridSize[1] - 1 - y
|
|
return self.partyEditor.partyEditorGrid.getGridSquare(x, y)
|
|
|
|
def detach(self, mouseEvent):
|
|
taskMgr.remove('gridElementDragTask%s' % self.name)
|
|
self.rolloverTitle.stash()
|
|
if self.overValidSquare:
|
|
self.partyEditor.partyEditorGrid.registerNewElement(self, self.centerGridSquare, self.getGridSize())
|
|
self.partyEditor.updateCostsAndBank()
|
|
self.partyEditor.handleMutuallyExclusiveActivities()
|
|
elif self.lastValidPosition is not None:
|
|
if self.mouseOverTrash:
|
|
self.partyEditor.trashCanButton['state'] = DirectGuiGlobals.NORMAL
|
|
self.lastValidPosition = None
|
|
self.partyEditor.updateCostsAndBank()
|
|
self.stash()
|
|
else:
|
|
self.setPos(render2d, self.lastValidPosition)
|
|
self.setOverValidSquare(True)
|
|
self.partyEditor.partyEditorGrid.registerNewElement(self, self.centerGridSquare, self.getGridSize())
|
|
self.partyEditor.updateCostsAndBank()
|
|
self.partyEditor.handleMutuallyExclusiveActivities()
|
|
else:
|
|
self.stash()
|
|
self.checkSoldOutAndPaidStatusAndAffordability()
|
|
return
|
|
|
|
def placeInPartyGrounds(self, desiredXY = None):
|
|
self.centerGridSquare = self.partyEditor.partyEditorGrid.getClearGridSquare(self.getGridSize(), desiredXY)
|
|
if self.centerGridSquare is not None:
|
|
self.setOverValidSquare(True)
|
|
self.unstash()
|
|
self.setPosHprBasedOnGridSquare(self.centerGridSquare)
|
|
self.partyEditor.partyEditorGrid.registerNewElement(self, self.centerGridSquare, self.getGridSize())
|
|
self.partyEditor.updateCostsAndBank()
|
|
self.partyEditor.partyPlanner.instructionLabel['text'] = TTLocalizer.PartyPlannerEditorInstructionsPartyGrounds
|
|
self.checkSoldOutAndPaidStatusAndAffordability()
|
|
return True
|
|
else:
|
|
return False
|
|
return
|
|
|
|
def clicked(self, mouseEvent):
|
|
PartyEditorGridElement.notify.debug('clicked grid element %s' % self.name)
|
|
if self.centerGridSquare is not None:
|
|
self.attach(mouseEvent)
|
|
self.partyEditor.partyEditorGrid.removeElement(self.centerGridSquare, self.getGridSize())
|
|
return
|
|
|
|
def released(self, mouseEvent):
|
|
PartyEditorGridElement.notify.debug('released grid element %s' % self.name)
|
|
self.detach(mouseEvent)
|
|
|
|
def mouseEnter(self, mouseEvent):
|
|
parent = self.getParent()
|
|
self.reparentTo(parent)
|
|
self.rolloverTitle.unstash()
|
|
|
|
def mouseExit(self, mouseEvent):
|
|
self.rolloverTitle.stash()
|
|
|
|
def destroy(self):
|
|
self.unbind(DirectGuiGlobals.B1PRESS)
|
|
self.unbind(DirectGuiGlobals.B1RELEASE)
|
|
self.unbind(DirectGuiGlobals.ENTER)
|
|
self.unbind(DirectGuiGlobals.EXIT)
|
|
DirectButton.destroy(self)
|