572 lines
23 KiB
Python
572 lines
23 KiB
Python
from panda3d.core import *
|
|
from direct.distributed.ClockDelta import *
|
|
from direct.task.Task import Task
|
|
from direct.interval.IntervalGlobal import *
|
|
from TrolleyConstants import *
|
|
from toontown.golf import GolfGlobals
|
|
from toontown.toonbase import ToontownGlobals
|
|
from direct.distributed import DistributedObject
|
|
from direct.directnotify import DirectNotifyGlobal
|
|
from direct.fsm import ClassicFSM, State
|
|
from direct.fsm import State
|
|
from toontown.distributed import DelayDelete
|
|
from toontown.toonbase.ToontownTimer import ToontownTimer
|
|
from direct.task.Task import Task
|
|
from direct.showbase import PythonUtil
|
|
from toontown.toon import ToonDNA
|
|
from direct.showbase import RandomNumGen
|
|
from toontown.battle.BattleSounds import *
|
|
|
|
class DistributedPicnicBasket(DistributedObject.DistributedObject):
|
|
seatState = Enum('Empty, Full, Eating')
|
|
notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPicnicBasket')
|
|
|
|
def __init__(self, cr):
|
|
DistributedObject.DistributedObject.__init__(self, cr)
|
|
self.localToonOnBoard = 0
|
|
self.seed = 0
|
|
self.random = None
|
|
self.picnicCountdownTime = base.config.GetFloat('picnic-countdown-time', ToontownGlobals.PICNIC_COUNTDOWN_TIME)
|
|
self.picnicBasketTrack = None
|
|
self.fsm = ClassicFSM.ClassicFSM('DistributedTrolley', [State.State('off', self.enterOff, self.exitOff, ['waitEmpty', 'waitCountdown']), State.State('waitEmpty', self.enterWaitEmpty, self.exitWaitEmpty, ['waitCountdown']), State.State('waitCountdown', self.enterWaitCountdown, self.exitWaitCountdown, ['waitEmpty'])], 'off', 'off')
|
|
self.fsm.enterInitialState()
|
|
self.__toonTracks = {}
|
|
return
|
|
|
|
def generate(self):
|
|
DistributedObject.DistributedObject.generate(self)
|
|
self.loader = self.cr.playGame.hood.loader
|
|
self.foodLoader = ['phase_6/models/golf/picnic_sandwich.bam',
|
|
'phase_6/models/golf/picnic_apple.bam',
|
|
'phase_6/models/golf/picnic_cupcake.bam',
|
|
'phase_6/models/golf/picnic_chocolate_cake.bam']
|
|
self.fullSeat = []
|
|
self.food = []
|
|
for i in xrange(4):
|
|
self.food.append(None)
|
|
self.fullSeat.append(self.seatState.Empty)
|
|
|
|
self.picnicItem = 0
|
|
return
|
|
|
|
def announceGenerate(self):
|
|
self.picnicTable = self.loader.geom.find('**/*picnic_table_' + str(self.tableNumber))
|
|
self.picnicTableSphereNodes = []
|
|
self.numSeats = 4
|
|
self.seats = []
|
|
self.jumpOffsets = []
|
|
self.basket = None
|
|
for i in xrange(self.numSeats):
|
|
self.seats.append(self.picnicTable.find('**/*seat%d' % (i + 1)))
|
|
self.jumpOffsets.append(self.picnicTable.find('**/*jumpOut%d' % (i + 1)))
|
|
|
|
self.tablecloth = self.picnicTable.find('**/basket_locator')
|
|
DistributedObject.DistributedObject.announceGenerate(self)
|
|
for i in xrange(self.numSeats):
|
|
self.picnicTableSphereNodes.append(self.seats[i].attachNewNode(CollisionNode('picnicTable_sphere_%d_%d' % (self.getDoId(), i))))
|
|
self.picnicTableSphereNodes[i].node().addSolid(CollisionSphere(0, 0, 0, 2))
|
|
|
|
self.tableclothSphereNode = self.tablecloth.attachNewNode(CollisionNode('tablecloth_sphere'))
|
|
self.tableclothSphereNode.node().addSolid(CollisionSphere(0, 0, -1, 4))
|
|
angle = self.startingHpr[0]
|
|
angle -= 90
|
|
radAngle = deg2Rad(angle)
|
|
unitVec = Vec3(math.cos(radAngle), math.sin(radAngle), 0)
|
|
unitVec *= 30.0
|
|
self.endPos = self.startingPos + unitVec
|
|
dist = Vec3(self.endPos - self.enteringPos).length()
|
|
wheelAngle = dist / (0.5 * 1.4 * math.pi) * 360
|
|
self.seatNumber = 0
|
|
self.clockNode = ToontownTimer()
|
|
self.clockNode.setPos(1.16, 0, -0.83)
|
|
self.clockNode.setScale(0.3)
|
|
self.clockNode.hide()
|
|
return
|
|
|
|
def disable(self):
|
|
DistributedObject.DistributedObject.disable(self)
|
|
self.fsm.request('off')
|
|
self.clearToonTracks()
|
|
for i in xrange(self.numSeats):
|
|
del self.picnicTableSphereNodes[0]
|
|
|
|
del self.picnicTableSphereNodes
|
|
self.notify.debug('Deleted self loader ' + str(self.getDoId()))
|
|
self.picnicTable.removeNode()
|
|
self.picnicBasketTrack = None
|
|
return
|
|
|
|
def delete(self):
|
|
self.notify.debug('Golf kart getting deleted: %s' % self.getDoId())
|
|
DistributedObject.DistributedObject.delete(self)
|
|
del self.fsm
|
|
|
|
def setState(self, state, seed, timestamp):
|
|
self.seed = seed
|
|
if not self.random:
|
|
self.random = RandomNumGen.RandomNumGen(seed)
|
|
self.fsm.request(state, [globalClockDelta.localElapsedTime(timestamp)])
|
|
|
|
def handleEnterPicnicTableSphere(self, i, collEntry):
|
|
self.seatNumber = i
|
|
self.notify.debug('Entering Picnic Table Sphere.... %s' % self.getDoId())
|
|
self.loader.place.detectedPicnicTableSphereCollision(self)
|
|
|
|
def handleEnterPicnicTable(self, i):
|
|
toon = base.localAvatar
|
|
self.sendUpdate('requestBoard', [i])
|
|
|
|
def fillSlot0(self, avId):
|
|
self.fillSlot(0, avId)
|
|
|
|
def fillSlot1(self, avId):
|
|
self.fillSlot(1, avId)
|
|
|
|
def fillSlot2(self, avId):
|
|
self.fillSlot(2, avId)
|
|
|
|
def fillSlot3(self, avId):
|
|
self.fillSlot(3, avId)
|
|
|
|
def fillSlot(self, index, avId):
|
|
self.notify.debug('fill Slot: %d for %d' % (index, avId))
|
|
if avId == 0:
|
|
pass
|
|
else:
|
|
self.fullSeat[index] = self.seatState.Full
|
|
if avId == base.localAvatar.getDoId():
|
|
self.clockNode.show()
|
|
if index == 0 or index == 3:
|
|
side = -1
|
|
else:
|
|
side = 1
|
|
if hasattr(self.loader.place, 'trolley'):
|
|
self.loader.place.trolley.fsm.request('boarding', [self.tablecloth, side])
|
|
else:
|
|
self.notify.warning('fillSlot no trolley in place')
|
|
self.localToonOnBoard = 1
|
|
if avId == base.localAvatar.getDoId():
|
|
if hasattr(self.loader.place, 'trolley'):
|
|
self.loader.place.trolley.fsm.request('boarded')
|
|
self.loader.place.trolley.exitButton.hide()
|
|
if avId in self.cr.doId2do:
|
|
toon = self.cr.doId2do[avId]
|
|
toon.stopSmooth()
|
|
toon.wrtReparentTo(self.tablecloth)
|
|
sitStartDuration = toon.getDuration('sit-start')
|
|
jumpTrack = self.generateToonJumpTrack(toon, index)
|
|
track = Sequence(jumpTrack, Func(toon.setAnimState, 'Sit', 1.0))
|
|
self.notify.debug('### fillSlot: fullSeat = %s' % self.fullSeat)
|
|
if self.fullSeat.count(0) == 3:
|
|
self.notify.debug('### fillSlot: adding basketAppear')
|
|
if self.picnicBasketTrack:
|
|
self.picnicBasketTrack.finish()
|
|
waitDuration = track.getDuration()
|
|
self.picnicBasketTrack = Sequence(Wait(waitDuration), self.generateBasketAppearTrack())
|
|
self.picnicBasketTrack.start()
|
|
track.append(self.generateFoodAppearTrack(index))
|
|
track.append(Sequence(Func(self.clearToonTrack, avId), name=toon.uniqueName('fillTrolley'), autoPause=1))
|
|
if avId == base.localAvatar.getDoId():
|
|
if hasattr(self.loader.place, 'trolley'):
|
|
track.append(Func(self.loader.place.trolley.exitButton.show))
|
|
track.delayDelete = DelayDelete.DelayDelete(toon, 'PicnicBasket.fillSlot')
|
|
self.storeToonTrack(avId, track)
|
|
track.start()
|
|
|
|
def emptySlot0(self, avId, timestamp):
|
|
self.emptySlot(0, avId, timestamp)
|
|
|
|
def emptySlot1(self, avId, timestamp):
|
|
self.emptySlot(1, avId, timestamp)
|
|
|
|
def emptySlot2(self, avId, timestamp):
|
|
self.emptySlot(2, avId, timestamp)
|
|
|
|
def emptySlot3(self, avId, timestamp):
|
|
self.emptySlot(3, avId, timestamp)
|
|
|
|
def notifyToonOffTrolley(self, toon):
|
|
toon.setAnimState('neutral', 1.0)
|
|
if hasattr(base, 'localAvatar') and toon == base.localAvatar:
|
|
if hasattr(self.loader.place, 'trolley'):
|
|
self.loader.place.trolley.handleOffTrolley()
|
|
self.localToonOnBoard = 0
|
|
else:
|
|
toon.startSmooth()
|
|
|
|
def emptySlot(self, index, avId, timestamp):
|
|
|
|
def emptySeat(index):
|
|
self.notify.debug('### seat %s now empty' % index)
|
|
self.fullSeat[index] = self.seatState.Empty
|
|
|
|
if avId == 0:
|
|
pass
|
|
elif avId == 1:
|
|
self.fullSeat[index] = self.seatState.Empty
|
|
track = Sequence(self.generateFoodDisappearTrack(index))
|
|
self.notify.debug('### empty slot - unexpetected: fullSeat = %s' % self.fullSeat)
|
|
if self.fullSeat.count(0) == 4:
|
|
self.notify.debug('### empty slot - unexpected: losing basket')
|
|
if self.picnicBasketTrack:
|
|
self.picnicBasketTrack.finish()
|
|
waitDuration = track.getDuration()
|
|
self.picnicBasketTrack = Sequence(Wait(waitDuration), self.generateBasketDisappearTrack())
|
|
self.picnicBasketTrack.start()
|
|
track.start()
|
|
else:
|
|
self.fullSeat[index] = self.seatState.Empty
|
|
if avId in self.cr.doId2do:
|
|
if avId == base.localAvatar.getDoId():
|
|
if self.clockNode:
|
|
self.clockNode.hide()
|
|
toon = self.cr.doId2do[avId]
|
|
toon.stopSmooth()
|
|
sitStartDuration = toon.getDuration('sit-start')
|
|
jumpOutTrack = self.generateToonReverseJumpTrack(toon, index)
|
|
track = Sequence(jumpOutTrack)
|
|
track.append(self.generateFoodDisappearTrack(index))
|
|
self.notify.debug('### empty slot: fullSeat = %s' % self.fullSeat)
|
|
if self.fullSeat.count(0) == 4:
|
|
self.notify.debug('### empty slot: losing basket')
|
|
if self.picnicBasketTrack:
|
|
self.picnicBasketTrack.finish()
|
|
waitDuration = track.getDuration()
|
|
self.picnicBasketTrack = Sequence(Wait(waitDuration), self.generateBasketDisappearTrack())
|
|
self.picnicBasketTrack.start()
|
|
track.append(Sequence(Func(self.notifyToonOffTrolley, toon), Func(self.clearToonTrack, avId), Func(self.doneExit, avId), Func(emptySeat, index), name=toon.uniqueName('emptyTrolley'), autoPause=1))
|
|
track.delayDelete = DelayDelete.DelayDelete(toon, 'PicnicBasket.emptySlot')
|
|
self.storeToonTrack(avId, track)
|
|
track.start()
|
|
|
|
def rejectBoard(self, avId):
|
|
self.loader.place.trolley.handleRejectBoard()
|
|
|
|
def __enableCollisions(self):
|
|
for i in xrange(self.numSeats):
|
|
self.accept('enterpicnicTable_sphere_%d_%d' % (self.getDoId(), i), self.handleEnterPicnicTableSphere, [i])
|
|
self.accept('enterPicnicTableOK_%d_%d' % (self.getDoId(), i), self.handleEnterPicnicTable, [i])
|
|
self.picnicTableSphereNodes[i].setCollideMask(ToontownGlobals.WallBitmask)
|
|
|
|
def __disableCollisions(self):
|
|
for i in xrange(self.numSeats):
|
|
self.ignore('enterpicnicTable_sphere_%d_%d' % (self.getDoId(), i))
|
|
self.ignore('enterPicnicTableOK_%d_%d' % (self.getDoId(), i))
|
|
|
|
for i in xrange(self.numSeats):
|
|
self.picnicTableSphereNodes[i].setCollideMask(BitMask32(0))
|
|
|
|
def enterOff(self):
|
|
return None
|
|
|
|
def exitOff(self):
|
|
return None
|
|
|
|
def enterWaitEmpty(self, ts):
|
|
self.__enableCollisions()
|
|
|
|
def exitWaitEmpty(self):
|
|
self.__disableCollisions()
|
|
|
|
def enterWaitCountdown(self, ts):
|
|
self.__enableCollisions()
|
|
self.accept('trolleyExitButton', self.handleExitButton)
|
|
self.clockNode.countdown(self.picnicCountdownTime, self.handleExitButton)
|
|
|
|
def handleExitButton(self):
|
|
self.sendUpdate('requestExit')
|
|
self.clockNode.hide()
|
|
|
|
def exitWaitCountdown(self):
|
|
self.__disableCollisions()
|
|
self.ignore('trolleyExitButton')
|
|
self.clockNode.reset()
|
|
|
|
def getStareAtNodeAndOffset(self):
|
|
return (self.tablecloth, Point3(0, 0, 4))
|
|
|
|
def storeToonTrack(self, avId, track):
|
|
self.clearToonTrack(avId)
|
|
self.__toonTracks[avId] = track
|
|
|
|
def clearToonTrack(self, avId):
|
|
oldTrack = self.__toonTracks.get(avId)
|
|
if oldTrack:
|
|
oldTrack.pause()
|
|
DelayDelete.cleanupDelayDeletes(oldTrack)
|
|
del self.__toonTracks[avId]
|
|
|
|
def clearToonTracks(self):
|
|
keyList = []
|
|
for key in self.__toonTracks:
|
|
keyList.append(key)
|
|
|
|
for key in keyList:
|
|
if key in self.__toonTracks:
|
|
self.clearToonTrack(key)
|
|
|
|
def doneExit(self, avId):
|
|
if avId == base.localAvatar.getDoId():
|
|
self.sendUpdate('doneExit')
|
|
|
|
def setPosHpr(self, x, y, z, h, p, r):
|
|
self.startingPos = Vec3(x, y, z)
|
|
self.enteringPos = Vec3(x, y, z - 10)
|
|
self.startingHpr = Vec3(h, 0, 0)
|
|
|
|
def setTableNumber(self, tn):
|
|
self.tableNumber = tn
|
|
|
|
def generateToonJumpTrack(self, av, seatIndex):
|
|
av.pose('sit', 47)
|
|
hipOffset = av.getHipsParts()[2].getPos(av)
|
|
|
|
def getToonJumpTrack(av, seatIndex):
|
|
|
|
def getJumpDest(av = av, node = self.tablecloth):
|
|
dest = Vec3(self.tablecloth.getPos(av.getParent()))
|
|
seatNode = self.picnicTable.find('**/seat' + str(seatIndex + 1))
|
|
dest += seatNode.getPos(self.tablecloth)
|
|
dna = av.getStyle()
|
|
dest -= hipOffset
|
|
if seatIndex == 2 or seatIndex == 3:
|
|
dest.setY(dest.getY() + 2 * hipOffset.getY())
|
|
dest.setZ(dest.getZ() + 0.2)
|
|
return dest
|
|
|
|
def getJumpHpr(av = av, node = self.tablecloth):
|
|
hpr = self.seats[seatIndex].getHpr(av.getParent())
|
|
angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX())
|
|
hpr.setX(angle)
|
|
return hpr
|
|
|
|
toonJumpTrack = Parallel(ActorInterval(av, 'jump'), Sequence(Wait(0.43), Parallel(LerpHprInterval(av, hpr=getJumpHpr, duration=0.9), ProjectileInterval(av, endPos=getJumpDest, duration=0.9))))
|
|
return toonJumpTrack
|
|
|
|
def getToonSitTrack(av):
|
|
toonSitTrack = Sequence(ActorInterval(av, 'sit-start'), Func(av.loop, 'sit'))
|
|
return toonSitTrack
|
|
|
|
toonJumpTrack = getToonJumpTrack(av, seatIndex)
|
|
toonSitTrack = getToonSitTrack(av)
|
|
jumpTrack = Sequence(Parallel(toonJumpTrack, Sequence(Wait(1), toonSitTrack)), Func(av.wrtReparentTo, self.tablecloth))
|
|
return jumpTrack
|
|
|
|
def generateToonReverseJumpTrack(self, av, seatIndex):
|
|
self.notify.debug('av.getH() = %s' % av.getH())
|
|
|
|
def getToonJumpTrack(av, destNode):
|
|
|
|
def getJumpDest(av = av, node = destNode):
|
|
dest = node.getPos(self.tablecloth)
|
|
dest += self.jumpOffsets[seatIndex].getPos(self.tablecloth)
|
|
return dest
|
|
|
|
def getJumpHpr(av = av, node = destNode):
|
|
hpr = node.getHpr(av.getParent())
|
|
hpr.setX(hpr.getX() + 180)
|
|
angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX())
|
|
hpr.setX(angle)
|
|
return hpr
|
|
|
|
toonJumpTrack = Parallel(ActorInterval(av, 'jump'), Sequence(Wait(0.1), Parallel(ProjectileInterval(av, endPos=getJumpDest, duration=0.9))))
|
|
return toonJumpTrack
|
|
|
|
toonJumpTrack = getToonJumpTrack(av, self.tablecloth)
|
|
jumpTrack = Sequence(toonJumpTrack, Func(av.loop, 'neutral'), Func(av.wrtReparentTo, render))
|
|
return jumpTrack
|
|
|
|
def generateBasketAppearTrack(self):
|
|
if self.basket == None:
|
|
self.basket = loader.loadModel('phase_6/models/golf/picnic_basket.bam')
|
|
self.basket.setScale(0.1)
|
|
basketTrack = Sequence(
|
|
Func(self.basket.show),
|
|
SoundInterval(
|
|
globalBattleSoundCache.getSound('GUI_balloon_popup.ogg'),
|
|
node=self.basket),
|
|
Func(self.basket.reparentTo, self.tablecloth),
|
|
Func(self.basket.setPos, 0, 0, 0.2),
|
|
Func(self.basket.setHpr, 45, 0, 0),
|
|
Func(self.basket.wrtReparentTo, render),
|
|
Func(self.basket.setShear, 0, 0, 0),
|
|
Sequence(
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(1.1, 1.1, 0.1),
|
|
duration=0.2),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(1.6, 1.6, 0.2),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(1.0, 1.0, 0.4),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(1.5, 1.5, 2.5),
|
|
duration=0.2),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(2.5, 2.5, 1.5),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(2.0, 2.0, 2.0),
|
|
duration=0.1),
|
|
Func(self.basket.wrtReparentTo, self.tablecloth),
|
|
Func(self.basket.setPos, 0, 0, 0)))
|
|
return basketTrack
|
|
|
|
def generateBasketDisappearTrack(self):
|
|
if not self.basket:
|
|
return Sequence()
|
|
pos = self.basket.getPos()
|
|
pos.addZ(-1)
|
|
basketTrack = Sequence(
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(2.0, 2.0, 1.8),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(1.0, 1.0, 2.5),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(2.0, 2.0, 0.5),
|
|
duration=0.2),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(0.5, 0.5, 1.0),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(1.1, 1.1, 0.1),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.basket,
|
|
scale=Point3(0.1, 0.1, 0.1),
|
|
duration=0.2),
|
|
SoundInterval(
|
|
globalBattleSoundCache.getSound('GUI_balloon_popup.ogg'),
|
|
node=self.basket),
|
|
Wait(0.2),
|
|
LerpPosInterval(
|
|
self.basket,
|
|
pos=pos,
|
|
duration=0.2),
|
|
Func(self.basket.hide))
|
|
return basketTrack
|
|
|
|
def generateFoodAppearTrack(self, seat):
|
|
if self.fullSeat[seat] == self.seatState.Full:
|
|
self.notify.debug('### food appear: self.fullSeat = %s' % self.fullSeat)
|
|
if not self.food[seat]:
|
|
self.food[seat] = loader.loadModel(self.random.choice(self.foodLoader))
|
|
self.notify.debug('### food appear: self.food = %s' % self.food)
|
|
self.food[seat].setScale(0.1)
|
|
self.food[seat].reparentTo(self.tablecloth)
|
|
self.food[seat].setPos(self.seats[seat].getPos(self.tablecloth)[0] / 2, self.seats[seat].getPos(self.tablecloth)[1] / 2, 0)
|
|
foodTrack = Sequence(
|
|
Func(self.food[seat].show),
|
|
SoundInterval(
|
|
globalBattleSoundCache.getSound('GUI_balloon_popup.ogg'),
|
|
node=self.food[seat]),
|
|
Func(self.food[seat].reparentTo, self.tablecloth),
|
|
Func(self.food[seat].setHpr, 45, 0, 0),
|
|
Func(self.food[seat].wrtReparentTo, render),
|
|
Func(self.food[seat].setShear, 0, 0, 0),
|
|
Sequence(
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(1.1, 1.1, 0.1),
|
|
duration=0.2),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(1.6, 1.6, 0.2),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(1.0, 1.0, 0.4),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(1.5, 1.5, 2.5),
|
|
duration=0.2),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(2.5, 2.5, 1.5),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(2.0, 2.0, 2.0),
|
|
duration=0.1),
|
|
Func(self.food[seat].wrtReparentTo, self.tablecloth)))
|
|
return foodTrack
|
|
else:
|
|
return Sequence()
|
|
|
|
def generateFoodDisappearTrack(self, seat):
|
|
if not self.food[seat]:
|
|
return Sequence()
|
|
pos = self.food[seat].getPos()
|
|
pos.addZ(-1.0)
|
|
foodTrack = Sequence(
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(2.0, 2.0, 1.8),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(1.0, 1.0, 2.5),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(2.0, 2.0, 0.5),
|
|
duration=0.2),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(0.5, 0.5, 1.0),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(1.1, 1.1, 0.1),
|
|
duration=0.1),
|
|
LerpScaleInterval(
|
|
self.food[seat],
|
|
scale=Point3(0.1, 0.1, 0.1),
|
|
duration=0.2),
|
|
SoundInterval(
|
|
globalBattleSoundCache.getSound('GUI_balloon_popup.ogg'),
|
|
node=self.food[seat]),
|
|
Wait(0.2),
|
|
LerpPosInterval(
|
|
self.food[seat],
|
|
pos=pos,
|
|
duration=0.2),
|
|
Func(self.food[seat].hide))
|
|
return foodTrack
|
|
|
|
def destroy(self, node):
|
|
node.removeNode()
|
|
node = None
|
|
self.basket.removeNode()
|
|
self.basket = None
|
|
for food in self.food:
|
|
food.removeNode()
|
|
|
|
self.food = None
|
|
self.clockNode.removeNode()
|
|
del self.clockNode
|
|
self.clockNode = None
|
|
return
|
|
|
|
def setPicnicDone(self):
|
|
if self.localToonOnBoard:
|
|
if hasattr(self.loader.place, 'trolley'):
|
|
self.loader.place.trolley.fsm.request('final')
|
|
self.loader.place.trolley.fsm.request('start')
|
|
self.localToonOnBoard = 0
|
|
messenger.send('picnicDone')
|