407 lines
No EOL
15 KiB
Python
407 lines
No EOL
15 KiB
Python
from toontown.estate import DistributedPlantBase
|
|
from direct.interval.IntervalGlobal import *
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from direct.showbase import PythonUtil
|
|
from toontown.toonbase import ToontownBattleGlobals
|
|
from toontown.toontowngui import TTDialog
|
|
from toontown.toonbase import TTLocalizer
|
|
import GardenGlobals
|
|
import HouseGlobals
|
|
from direct.task import Task
|
|
from panda3d.core import *
|
|
from otp.otpbase import OTPGlobals
|
|
from toontown.estate import DistributedLawnDecor
|
|
DIRT_AS_WATER_INDICATOR = True
|
|
|
|
class DistributedGagTree(DistributedPlantBase.DistributedPlantBase):
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedGagTree')
|
|
|
|
def __init__(self, cr):
|
|
DistributedPlantBase.DistributedPlantBase.__init__(self, cr)
|
|
base.tree = self
|
|
self.collSphereRadius = 4.2
|
|
self.confirmDialog = None
|
|
self.resultDialog = None
|
|
self.dirtMound = None
|
|
self.sandMound = None
|
|
self.needToPlant = 0
|
|
self.needToLoad = 0
|
|
self.backupFruits = []
|
|
self.signHasBeenStuck2Ground = False
|
|
self.setName('DistributedGagTree')
|
|
self.fruiting = 0
|
|
|
|
def delete(self):
|
|
DistributedPlantBase.DistributedPlantBase.delete(self)
|
|
del self.prop
|
|
del self.prop2
|
|
del self.dirtMound
|
|
del self.sandMound
|
|
self.signModel.removeNode()
|
|
self.signModel = None
|
|
return
|
|
|
|
def setTypeIndex(self, typeIndex):
|
|
DistributedPlantBase.DistributedPlantBase.setTypeIndex(self, typeIndex)
|
|
track, level = GardenGlobals.getTreeTrackAndLevel(typeIndex)
|
|
self.gagTrack = track
|
|
self.gagLevel = level
|
|
invModel = loader.loadModel('phase_3.5/models/gui/inventory_icons')
|
|
propName = ToontownBattleGlobals.AvPropsNew[track][level]
|
|
self.prop = invModel.find('**/' + propName)
|
|
self.prop.setScale(7)
|
|
invModel.removeNode()
|
|
invModel2 = loader.loadModel('phase_3.5/models/gui/inventory_icons')
|
|
propName = ToontownBattleGlobals.AvPropsNew[track][level]
|
|
self.prop2 = invModel2.find('**/' + propName)
|
|
self.prop2.setScale(7)
|
|
self.filename = self.attributes['filename']
|
|
self.maxFruit = self.attributes['maxFruit']
|
|
if hasattr(self, 'needToLoad'):
|
|
if self.needToLoad:
|
|
self.loadModel()
|
|
|
|
def loadModel(self):
|
|
if not hasattr(self, 'filename'):
|
|
self.needToLoad = 1
|
|
return
|
|
if not self.rotateNode:
|
|
self.rotateNode = self.plantPath.attachNewNode('rotate')
|
|
all = loader.loadModel(self.filename)
|
|
self.modelName = self.getModelName()
|
|
if self.isWilted():
|
|
self.modelName += '_wilt'
|
|
self.model = all.find('**/' + self.modelName)
|
|
all.detachNode()
|
|
shadow = self.model.find('**/shadow1')
|
|
if shadow:
|
|
shadow.hide()
|
|
self.model.reparentTo(self.rotateNode)
|
|
if self.isFruiting() and not self.isWilted():
|
|
self.fruits = []
|
|
for i in xrange(1, self.maxFruit + 1):
|
|
pos = self.model.find('**/locator' + str(i))
|
|
if pos and not pos.isEmpty():
|
|
fruit = self.prop.copyTo(self.model)
|
|
fruit.setPos(pos, 0, 0, 0)
|
|
fruit.setScale(13)
|
|
self.fruits.append(fruit)
|
|
|
|
self.createBackupFruits()
|
|
if DIRT_AS_WATER_INDICATOR:
|
|
self.dirtMound = loader.loadModel('phase_5.5/models/estate/dirt_mound')
|
|
self.dirtMound.reparentTo(self.model)
|
|
self.sandMound = loader.loadModel('phase_5.5/models/estate/sand_mound')
|
|
self.sandMound.reparentTo(self.model)
|
|
self.adjustGrowth()
|
|
self.signModel = loader.loadModel('phase_5.5/models/estate/garden_sign.bam')
|
|
self.signModel.setPos(3.5, 0, 0.025)
|
|
self.signModel.reparentTo(self.rotateNode)
|
|
owner = self.getOwnerIndex()
|
|
color = HouseGlobals.houseColors[owner]
|
|
for geomName in ('sign', 'sign1'):
|
|
sign = self.signModel.find('**/' + geomName)
|
|
if sign:
|
|
sign.setColor(*color)
|
|
|
|
self.prop.setPos(0.1, -0.17, 1.63)
|
|
self.prop.reparentTo(self.signModel)
|
|
self.prop2.setPos(0.15, 0.17, 1.63)
|
|
self.prop2.setH(self.prop.getH() + 180)
|
|
self.prop2.reparentTo(self.signModel)
|
|
self.needToLoad = 0
|
|
if self.needToPlant:
|
|
self.stickParts()
|
|
|
|
def setupShadow(self):
|
|
DistributedPlantBase.DistributedPlantBase.setupShadow(self)
|
|
self.adjustGrowth()
|
|
|
|
def makeMovieNode(self):
|
|
self.movieNode = self.rotateNode.attachNewNode('moviePos')
|
|
self.movieNode.setPos(0, -5, 0)
|
|
self.createBackupFruits()
|
|
|
|
def handlePicking(self):
|
|
messenger.send('wakeup')
|
|
if self.isFruiting() and self.canBeHarvested():
|
|
self.startInteraction()
|
|
self.doHarvesting()
|
|
return
|
|
fullName = self.name
|
|
text = TTLocalizer.ConfirmRemoveTree % {'tree': fullName}
|
|
if self.hasDependentTrees():
|
|
text += TTLocalizer.ConfirmWontBeAbleToHarvest
|
|
self.confirmDialog = TTDialog.TTDialog(style=TTDialog.YesNo, text=text, command=self.confirmCallback)
|
|
self.confirmDialog.show()
|
|
self.startInteraction()
|
|
return
|
|
|
|
def confirmCallback(self, value):
|
|
self.confirmDialog.destroy()
|
|
self.confirmDialog = None
|
|
if value > 0:
|
|
self.doPicking()
|
|
else:
|
|
self.finishInteraction()
|
|
return
|
|
|
|
def doPicking(self):
|
|
if not self.canBePicked():
|
|
return
|
|
self.sendUpdate('removeItem', [])
|
|
|
|
def createBackupFruits(self):
|
|
if not hasattr(self, 'fruits'):
|
|
return
|
|
if not self.fruits:
|
|
return
|
|
if not hasattr(self, 'movieNode'):
|
|
return
|
|
if not self.movieNode:
|
|
return
|
|
if self.movieNode.isEmpty():
|
|
return
|
|
if not self.signHasBeenStuck2Ground:
|
|
return
|
|
if not self.backupFruits:
|
|
for fruit in self.fruits:
|
|
newFruit = fruit.copyTo(render)
|
|
newFruit.setPos(fruit.getPos(render))
|
|
newFruit.setH(self.movieNode.getH(render))
|
|
newFruit.hide()
|
|
self.backupFruits.append(newFruit)
|
|
|
|
def clearBackupFruits(self):
|
|
if self.fruits:
|
|
for fruit in self.fruits:
|
|
fruit.removeNode()
|
|
|
|
self.fruits = None
|
|
self.backupFruits = []
|
|
|
|
def doHarvesting(self):
|
|
if not self.canBePicked():
|
|
return
|
|
if hasattr(self, 'backupFruits'):
|
|
for fruit in self.backupFruits:
|
|
fruit.show()
|
|
|
|
self.sendUpdate('requestHarvest', [])
|
|
|
|
def getTrack(self):
|
|
return self.gagTrack
|
|
|
|
def getGagLevel(self):
|
|
return self.gagLevel
|
|
|
|
def setWaterLevel(self, waterLevel):
|
|
self.waterLevel = waterLevel
|
|
self.adjustWaterIndicator()
|
|
|
|
def setGrowthLevel(self, growthLevel):
|
|
self.growthLevel = growthLevel
|
|
if self.model:
|
|
newModelName = self.getModelName()
|
|
if True:
|
|
self.model.removeNode()
|
|
self.loadModel()
|
|
self.adjustWaterIndicator()
|
|
self.stick2Ground()
|
|
else:
|
|
self.adjustGrowth()
|
|
|
|
def adjustGrowth(self):
|
|
newScale = self.growthLevel + 1
|
|
if newScale > 1:
|
|
newScale = 1
|
|
shadowScale = 2.5
|
|
collScale = 1.5
|
|
if self.isSeedling():
|
|
shadowScale = 1
|
|
collScale = 1
|
|
if self.shadowJoint:
|
|
self.shadowJoint.setScale(shadowScale)
|
|
if DIRT_AS_WATER_INDICATOR:
|
|
dirtMoundScale = shadowScale * 1.5
|
|
dirtMoundDepth = 2.0
|
|
if self.isEstablished():
|
|
dirtMoundScale = shadowScale * 1.2
|
|
self.dirtMound.setScale(dirtMoundScale, dirtMoundScale, dirtMoundDepth)
|
|
self.sandMound.setScale(dirtMoundScale, dirtMoundScale, dirtMoundDepth)
|
|
self.adjustWaterIndicator()
|
|
|
|
def setWilted(self, wilted):
|
|
self.wilted = wilted
|
|
|
|
def isWilted(self):
|
|
return self.wilted
|
|
|
|
def setMovie(self, mode, avId):
|
|
if mode == GardenGlobals.MOVIE_HARVEST:
|
|
self.doHarvestTrack(avId)
|
|
elif mode == GardenGlobals.MOVIE_WATER:
|
|
self.doWaterTrack(avId)
|
|
elif mode == GardenGlobals.MOVIE_FINISHPLANTING:
|
|
self.doFinishPlantingTrack(avId)
|
|
elif mode == GardenGlobals.MOVIE_REMOVE:
|
|
self.doDigupTrack(avId)
|
|
|
|
def doFinishPlantingTrack(self, avId):
|
|
toon = base.cr.doId2do.get(avId)
|
|
if not toon:
|
|
return
|
|
self.finishMovies()
|
|
self.movie = Sequence()
|
|
if self.model:
|
|
self.model.setTransparency(1)
|
|
self.model.setAlphaScale(0)
|
|
self.movie.append(LerpFunc(self.model.setAlphaScale, fromData=0, toData=1, duration=3))
|
|
if self.signModel:
|
|
self.signModel.hide()
|
|
self.movie.append(Func(self.signModel.show))
|
|
self.movie.append(LerpScaleInterval(self.signModel, 1, 1, 0))
|
|
self.movie.append(Func(toon.loop, 'neutral'))
|
|
if avId == localAvatar.doId:
|
|
self.movie.append(Func(self.finishInteraction))
|
|
self.movie.append(Func(self.movieDone))
|
|
self.movie.append(Func(self.doResultDialog))
|
|
self.movie.start()
|
|
|
|
def doHarvestTrack(self, avId):
|
|
toon = base.cr.doId2do.get(avId)
|
|
if not toon:
|
|
return
|
|
self.finishMovies()
|
|
moveTrack = self.generateToonMoveTrack(toon)
|
|
harvestTrack = self.generateHarvestTrack(toon)
|
|
self.movie = Sequence(self.startCamIval(avId), moveTrack, harvestTrack, self.stopCamIval(avId))
|
|
if avId == localAvatar.doId:
|
|
self.movie.append(Func(self.finishInteraction))
|
|
self.movie.append(Func(self.movieDone))
|
|
self.movie.start()
|
|
|
|
def setupShadow(self):
|
|
if DIRT_AS_WATER_INDICATOR:
|
|
pass
|
|
else:
|
|
DistributedPlantBase.DistributedPlantBase.setupShadow(self)
|
|
|
|
def generateHarvestTrack(self, toon):
|
|
pos = toon.getPos(render)
|
|
pos.setZ(pos.getZ() + 2)
|
|
fruitTrack = Parallel()
|
|
for fruit in self.backupFruits:
|
|
fruitTrack.append(Sequence(Func(fruit.show), LerpPosInterval(fruit, 1.5, pos, startPos=Point3(fruit.getX(), fruit.getY(), fruit.getZ() + self.model.getZ())), Func(fruit.removeNode)))
|
|
|
|
harvestTrack = Sequence(fruitTrack, Func(self.clearBackupFruits))
|
|
return harvestTrack
|
|
|
|
def adjustWaterIndicator(self):
|
|
DistributedPlantBase.DistributedPlantBase.adjustWaterIndicator(self)
|
|
if self.dirtMound:
|
|
curWaterLevel = self.waterLevel
|
|
if curWaterLevel > self.maxWaterLevel:
|
|
curWaterLevel = self.maxWaterLevel
|
|
if curWaterLevel > 0:
|
|
darkestColorScale = 0.4
|
|
lightestColorScale = 1.0
|
|
scaleRange = lightestColorScale - darkestColorScale
|
|
scaleIncrement = scaleRange / self.maxWaterLevel
|
|
darker = lightestColorScale - scaleIncrement * curWaterLevel
|
|
self.dirtMound.setColorScale(darker, darker, darker, 1.0)
|
|
self.sandMound.hide()
|
|
self.dirtMound.show()
|
|
else:
|
|
self.sandMound.show()
|
|
self.dirtMound.hide()
|
|
|
|
def stickParts(self):
|
|
if not hasattr(self, 'signModel'):
|
|
self.needToPlant = 1
|
|
return Task.done
|
|
if self.signModel.isEmpty():
|
|
return Task.done
|
|
testPath = NodePath('testPath')
|
|
testPath.reparentTo(render)
|
|
cRay = CollisionRay(0.0, 0.0, 40000.0, 0.0, 0.0, -1.0)
|
|
cRayNode = CollisionNode(self.uniqueName('estate-FloorRay'))
|
|
cRayNode.addSolid(cRay)
|
|
cRayNode.setFromCollideMask(OTPGlobals.FloorBitmask)
|
|
cRayNode.setIntoCollideMask(BitMask32.allOff())
|
|
cRayNodePath = testPath.attachNewNode(cRayNode)
|
|
queue = CollisionHandlerQueue()
|
|
picker = CollisionTraverser()
|
|
picker.addCollider(cRayNodePath, queue)
|
|
testPath.setPos(self.signModel.getX(render), self.signModel.getY(render), 0)
|
|
picker.traverse(render)
|
|
if queue.getNumEntries() > 0:
|
|
queue.sortEntries()
|
|
for index in xrange(queue.getNumEntries()):
|
|
entry = queue.getEntry(index)
|
|
if DistributedLawnDecor.recurseParent(entry.getIntoNode(), 'terrain_DNARoot'):
|
|
self.signModel.wrtReparentTo(render)
|
|
self.signModel.setZ(entry.getSurfacePoint(render)[2] + self.stickUp + 0.1)
|
|
self.signModel.wrtReparentTo(self.rotateNode)
|
|
self.signHasBeenStuck2Ground = True
|
|
self.createBackupFruits()
|
|
return Task.done
|
|
|
|
return Task.done
|
|
|
|
def canBeHarvested(self):
|
|
return self.isFruiting()
|
|
|
|
def hasDependentTrees(self):
|
|
myTrack, myLevel = GardenGlobals.getTreeTrackAndLevel(self.typeIndex)
|
|
allGagTrees = base.cr.doFindAll('DistributedGagTree')
|
|
for gagTree in allGagTrees:
|
|
if gagTree.getOwnerId() == localAvatar.doId:
|
|
curTrack, curLevel = GardenGlobals.getTreeTrackAndLevel(gagTree.typeIndex)
|
|
if curTrack == myTrack:
|
|
if myLevel < curLevel:
|
|
return True
|
|
|
|
return False
|
|
|
|
def doResultDialog(self):
|
|
self.startInteraction()
|
|
curTrack, curLevel = GardenGlobals.getTreeTrackAndLevel(self.typeIndex)
|
|
species = GardenGlobals.getTreeTypeIndex(curTrack, curLevel)
|
|
treeName = GardenGlobals.PlantAttributes[species]['name']
|
|
stringToShow = TTLocalizer.getResultPlantedSomethingSentence(treeName)
|
|
self.resultDialog = TTDialog.TTDialog(style=TTDialog.Acknowledge, text=stringToShow, command=self.resultsCallback)
|
|
|
|
def resultsCallback(self, value):
|
|
if self.resultDialog:
|
|
self.resultDialog.destroy()
|
|
self.resultDialog = None
|
|
self.finishInteraction()
|
|
return
|
|
|
|
def allowedToPick(self):
|
|
return True
|
|
|
|
def unlockPick(self):
|
|
retval = True
|
|
toon = base.localAvatar
|
|
inventory = toon.inventory
|
|
load = inventory.totalProps
|
|
maxCarry = toon.getMaxCarry()
|
|
if load >= maxCarry and not self.gagLevel > ToontownBattleGlobals.LAST_REGULAR_GAG_LEVEL:
|
|
retval = False
|
|
if inventory.numItem(self.gagTrack, self.gagLevel) >= inventory.getMax(self.gagTrack, self.gagLevel):
|
|
retval = False
|
|
return retval
|
|
|
|
def setFruiting(self, fruiting):
|
|
self.fruiting = fruiting
|
|
if self.model:
|
|
self.model.removeNode()
|
|
self.loadModel()
|
|
self.adjustWaterIndicator()
|
|
self.stick2Ground()
|
|
|
|
def isFruiting(self):
|
|
return self.fruiting
|
|
|