def doSounds(sounds): if len(sounds) == 0: return (None, None) npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(sounds) mtrack = Parallel() hitCount = 0 prevLevel = 0 prevSounds = [[], [], [], [], [], [], []] for sound in sounds: level = sound['level'] prevSounds[level].append(sound) for target in sound['target']: if target['hp'] > 0: hitCount += 1 break delay = 0.0 for soundList in prevSounds: if len(soundList) > 0: mtrack.append(__doSoundsLevel(soundList, delay, hitCount, npcs)) delay += TOON_SOUND_DELAY soundTrack = Sequence(npcArrivals, mtrack, npcDepartures) targets = sounds[0]['target'] camDuration = mtrack.getDuration() enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camTrack = MovieCamera.chooseSoundShot(sounds, targets, camDuration, enterDuration, exitDuration) return (soundTrack, camTrack)
def doSOSs(calls): if len(calls) == 0: return (None, None) def callerFunc(toon, handle): toon.setChatAbsolute(TTLocalizer.MovieSOSCallHelp % handle.getName(), CFSpeech | CFTimeout) handle.d_battleSOS(base.localAvatar.doId) def calleeFunc(toon, handle): toon.setChatAbsolute(TTLocalizer.MovieSOSCallHelp % handle.getName(), CFSpeech | CFTimeout) def observerFunc(toon): toon.setChatAbsolute(TTLocalizer.MovieSOSObserverHelp, CFSpeech | CFTimeout) mtrack = Sequence() for c in calls: toon = c['toon'] targetType = c['targetType'] handle = c['target'] mtrack.append(Wait(0.5)) if targetType == 'observer': ival = Func(observerFunc, toon) elif targetType == 'caller': ival = Func(callerFunc, toon, handle) elif targetType == 'callee': ival = Func(calleeFunc, toon, handle) else: notify.error('invalid target type: %s' % targetType) mtrack.append(ival) mtrack.append(Wait(2.0)) notify.debug('toon: %s calls for help' % toon.getName()) camDuration = mtrack.getDuration() camTrack = MovieCamera.chooseSOSShot(toon, camDuration) return (mtrack, camTrack)
def doFires(fires): if len(fires) == 0: return (None, None) suitFiresDict = {} for fire in fires: suitId = fire['target']['suit'].doId if suitFiresDict.has_key(suitId): suitFiresDict[suitId].append(fire) else: suitFiresDict[suitId] = [fire] suitFires = suitFiresDict.values() def compFunc(a, b): if len(a) > len(b): return 1 elif len(a) < len(b): return -1 return 0 suitFires.sort(compFunc) totalHitDict = {} singleHitDict = {} groupHitDict = {} for fire in fires: suitId = fire['target']['suit'].doId if 1: if fire['target']['hp'] > 0: addHit(singleHitDict, suitId, 1) addHit(totalHitDict, suitId, 1) else: addHit(singleHitDict, suitId, 0) addHit(totalHitDict, suitId, 0) notify.debug('singleHitDict = %s' % singleHitDict) notify.debug('groupHitDict = %s' % groupHitDict) notify.debug('totalHitDict = %s' % totalHitDict) delay = 0.0 mtrack = Parallel() firedTargets = [] for sf in suitFires: if len(sf) > 0: ival = __doSuitFires(sf) if ival: mtrack.append(Sequence(Wait(delay), ival)) delay = delay + TOON_FIRE_SUIT_DELAY retTrack = Sequence() retTrack.append(mtrack) camDuration = retTrack.getDuration() camTrack = MovieCamera.chooseFireShot(fires, suitFiresDict, camDuration) return (retTrack, camTrack)
def doZaps(zaps): if len(zaps) == 0: return (None, None) suitZapsDict = {} doneUber = 0 npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(zaps) skip = 0 for zap in zaps: skip = 0 if skip: pass elif type(zap['target']) == type([]): if 1: target = zap['target'][0] suitId = target['suit'].doId if suitId in suitZapsDict: suitZapsDict[suitId].append(zap) else: suitZapsDict[suitId] = [zap] else: suitId = zap['target']['suit'].doId if suitId in suitZapsDict: suitZapsDict[suitId].append(zap) else: suitZapsDict[suitId] = [zap] suitZaps = suitZapsDict.values() def compFunc(a, b): if len(a) > len(b): return 1 elif len(a) < len(b): return -1 return 0 suitZaps.sort(compFunc) delay = 0.0 mtrack = Parallel() for st in suitZaps: if len(st) > 0: ival = __doSuitZaps(st, npcs) if ival: mtrack.append(Sequence(Wait(delay), ival)) delay = delay + TOON_ZAP_SUIT_DELAY zapTrack = Sequence(npcArrivals, mtrack, npcDepartures) enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camDuration = zapTrack.getDuration() camTrack = MovieCamera.chooseLureShot(zaps, camDuration, enterDuration, exitDuration) return (zapTrack, camTrack)
def doHeals(heals, hasInteractivePropHealBonus): if len(heals) == 0: return (None, None) track = Sequence() for h in heals: ival = __doHealLevel(h, hasInteractivePropHealBonus) if ival: track.append(ival) camDuration = track.getDuration() camTrack = MovieCamera.chooseHealShot(heals, camDuration) return (track, camTrack)
def doPetSOSs(PetSOSs): if len(PetSOSs) == 0: return (None, None) track = Sequence() textTrack = Sequence() for p in PetSOSs: ival = __doPetSOS(p) if ival: track.append(ival) camDuration = track.getDuration() camTrack = MovieCamera.chooseHealShot(PetSOSs, camDuration) return (track, camTrack)
def doSquirts(squirts): if len(squirts) == 0: return (None, None) suitSquirtsDict = {} doneUber = 0 skip = 0 for squirt in squirts: skip = 0 if skip: pass elif type(squirt['target']) == type([]): if 1: target = squirt['target'][0] suitId = target['suit'].doId if suitId in suitSquirtsDict: suitSquirtsDict[suitId].append(squirt) else: suitSquirtsDict[suitId] = [squirt] else: suitId = squirt['target']['suit'].doId if suitId in suitSquirtsDict: suitSquirtsDict[suitId].append(squirt) else: suitSquirtsDict[suitId] = [squirt] suitSquirts = suitSquirtsDict.values() def compFunc(a, b): if len(a) > len(b): return 1 elif len(a) < len(b): return -1 return 0 suitSquirts.sort(compFunc) delay = 0.0 mtrack = Parallel() for st in suitSquirts: if len(st) > 0: ival = __doSuitSquirts(st) if ival: mtrack.append(Sequence(Wait(delay), ival)) delay = delay + TOON_SQUIRT_SUIT_DELAY camDuration = mtrack.getDuration() camTrack = MovieCamera.chooseSquirtShot(squirts, suitSquirtsDict, camDuration) return (mtrack, camTrack)
def doLures(lures): if len(lures) == 0: return (None, None) npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(lures) mtrack = Parallel() for l in lures: ival = __doLureLevel(l, npcs) if ival: mtrack.append(ival) lureTrack = Sequence(npcArrivals, mtrack, npcDepartures) camDuration = mtrack.getDuration() enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camTrack = MovieCamera.chooseLureShot(lures, camDuration, enterDuration, exitDuration) return (lureTrack, camTrack)
def doNPCSOSs(NPCSOSs): if len(NPCSOSs) == 0: return (None, None) track = Sequence() textTrack = Sequence() for n in NPCSOSs: ival, textIval = __doNPCSOS(n) if ival: track.append(ival) textTrack.append(textIval) camDuration = track.getDuration() if camDuration > 0.0: camTrack = MovieCamera.chooseHealShot(NPCSOSs, camDuration) else: camTrack = Sequence() return (track, Parallel(camTrack, textTrack))
def doTraps(traps): if len(traps) == 0: return (None, None) npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(traps) hasUberTrapConflict = False suitTrapsDict = {} for trap in traps: targets = trap['target'] if len(targets) == 1: suitId = targets[0]['suit'].doId if suitId in suitTrapsDict: suitTrapsDict[suitId].append(trap) else: suitTrapsDict[suitId] = [trap] else: for target in targets: suitId = target['suit'].doId if suitId not in suitTrapsDict: suitTrapsDict[suitId] = [trap] break if trap['level'] == UBER_GAG_LEVEL_INDEX: if len(traps) > 1: hasUberTrapConflict = True for oneTarget in trap['target']: suit = oneTarget['suit'] if suit.battleTrap != NO_TRAP: hasUberTrapConflict = True suitTrapLists = suitTrapsDict.values() mtrack = Parallel() for trapList in suitTrapLists: trapPropList = [] for i in xrange(len(trapList)): trap = trapList[i] level = trap['level'] if level == 0: banana = globalPropPool.getProp('banana') banana2 = MovieUtil.copyProp(banana) trapPropList.append([banana, banana2]) elif level == 1: rake = globalPropPool.getProp('rake') rake2 = MovieUtil.copyProp(rake) rake.pose('rake', 0) rake2.pose('rake', 0) trapPropList.append([rake, rake2]) elif level == 2: marbles = globalPropPool.getProp('marbles') marbles2 = MovieUtil.copyProp(marbles) trapPropList.append([marbles, marbles2]) elif level == 3: trapPropList.append([globalPropPool.getProp('quicksand')]) elif level == 4: trapPropList.append([globalPropPool.getProp('trapdoor')]) elif level == 5: tnt = globalPropPool.getProp('tnt') tnt2 = MovieUtil.copyProp(tnt) trapPropList.append([tnt, tnt2]) elif level == 6: tnt = globalPropPool.getProp('traintrack') tnt2 = MovieUtil.copyProp(tnt) trapPropList.append([tnt, tnt2]) else: notify.warning( '__doTraps() - Incorrect trap level: %d' % level) if len(trapList) == 1 and not hasUberTrapConflict: ival = __doTrapLevel(trapList[0], trapPropList[0]) if ival: mtrack.append(ival) else: subMtrack = Parallel() for i in xrange(len(trapList)): trap = trapList[i] trapProps = trapPropList[i] ival = __doTrapLevel(trap, trapProps, explode=1) if ival: subMtrack.append(ival) mtrack.append(subMtrack) trapTrack = Sequence(npcArrivals, mtrack, npcDepartures) camDuration = mtrack.getDuration() enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camTrack = MovieCamera.chooseTrapShot(traps, camDuration, enterDuration, exitDuration) return (trapTrack, camTrack)
def doToonVictory(localToonActive, toons, rewardToonIds, rewardDicts, deathList, rpanel, allowGroupShot=1, uberList=[], helpfulToonsList=[], noSkip=False): track = Sequence() if localToonActive == 1: track.append(Func(rpanel.show)) track.append(Func(NametagGlobals.setForceOnscreenChat, True)) camTrack = Sequence() endTrack = Sequence() danceSound = globalBattleSoundCache.getSound('ENC_Win.ogg') toonList = [] countToons = 0 uberListNew = [] for t in toons: if isinstance(t, types.IntType): t = base.cr.doId2do.get(t) if t: toonList.append(t) uberListNew.append(uberList[countToons]) countToons += 1 toonId2toon = {} for toon in toonList: toonId2toon[toon.doId] = toon rewardToonList = [] for id in rewardToonIds: rewardToonList.append(toonId2toon.get(id)) skipper = ToonVictorySkipper(len(toonList), noSkip) lastListenIndex = 0 track.append(skipper.getSetupFunc(lastListenIndex)) for tIndex in xrange(len(toonList)): t = toonList[tIndex] rdict = __findToonReward(rewardDicts, t) if rdict != None: expTrack = rpanel.getExpTrack(t, rdict['origExp'], rdict['earnedExp'], deathList, rdict['origQuests'], rdict['items'], rdict['missedItems'], rdict['origMerits'], rdict['merits'], rdict['parts'], rewardToonList, uberListNew[tIndex], helpfulToonsList, noSkip=noSkip) if expTrack: skipper.setStartTime(tIndex, track.getDuration()) track.append(skipper.getTeardownFunc(lastListenIndex)) lastListenIndex = tIndex track.append(skipper.getSetupFunc(lastListenIndex)) track.append(expTrack) camDuration = expTrack.getDuration() camExpTrack = MovieCamera.chooseRewardShot(t, camDuration) camTrack.append( MovieCamera.chooseRewardShot( t, camDuration, allowGroupShot=allowGroupShot)) track.append(skipper.getTeardownFunc(lastListenIndex)) track.append(Func(skipper.destroy)) if localToonActive == 1: track.append(Func(rpanel.hide)) track.append(Func(NametagGlobals.setForceOnscreenChat, False)) track.append(endTrack) trackdur = track.getDuration() soundTrack = SoundInterval(danceSound, duration=trackdur, loop=1) mtrack = Parallel(track, soundTrack) skipper.setIvals((mtrack, camTrack)) return (mtrack, camTrack, skipper)
def __healDive(heal, hasInteractivePropHealBonus): splash = Splash.Splash(render) splash.reparentTo(render) npcId = 0 if 'npcId' in heal: npcId = heal['npcId'] toon = NPCToons.createLocalNPC(npcId) if toon == None: return None else: toon = heal['toon'] targets = heal['target'] ineffective = heal['sidestep'] level = heal['level'] if npcId != 0: track = Sequence(MovieNPCSOS.teleportIn(heal, toon)) else: track = Sequence(__runToHealSpot(heal)) delay = 7.0 first = 1 targetTrack = Sequence() for target in targets: targetToon = target['toon'] hp = target['hp'] reactIval = Func(__healToon, targetToon, hp, ineffective, hasInteractivePropHealBonus) if first == 1: targetTrack.append(Wait(delay)) first = 0 targetTrack.append(reactIval) thisBattle = heal['battle'] toonsInBattle = thisBattle.toons glass = globalPropPool.getProp('glass') glass.setScale(4.0) glass.setHpr(0.0, 90.0, 0.0) ladder = globalPropPool.getProp('ladder') placeNode = NodePath('lookNode') diveProps = [glass, ladder] ladderScale = toon.getBodyScale() / 0.66 scaleUpPoint = Point3(0.5, 0.5, 0.45) * ladderScale basePos = toon.getPos() glassOffset = Point3(0, 1.1, 0.2) glassToonOffset = Point3(0, 1.2, 0.2) splashOffset = Point3(0, 1.0, 0.4) ladderOffset = Point3(0, 4, 0) ladderToonSep = Point3(0, 1, 0) * ladderScale diveOffset = Point3(0, 0, 10) divePos = add3(add3(ladderOffset, diveOffset), ladderToonSep) ladder.setH(toon.getH()) glassPos = render.getRelativePoint(toon, glassOffset) glassToonPos = render.getRelativePoint(toon, glassToonOffset) ladderPos = render.getRelativePoint(toon, ladderOffset) climbladderPos = render.getRelativePoint(toon, add3(ladderOffset, ladderToonSep)) divePos = render.getRelativePoint(toon, divePos) topDivePos = render.getRelativePoint(toon, diveOffset) lookBase = render.getRelativePoint(toon, ladderOffset) lookTop = render.getRelativePoint(toon, add3(ladderOffset, diveOffset)) LookGlass = render.getRelativePoint(toon, glassOffset) splash.setPos(splashOffset) walkToLadderTime = 1.0 climbTime = 5.0 diveTime = 1.0 ladderGrowTime = 1.5 splash.setPos(glassPos) toonNode = toon.getGeomNode() placeNode.reparentTo(render) placeNode.setScale(5.0) placeNode.setPos(toon.getPos(render)) placeNode.setHpr(toon.getHpr(render)) toonscale = toonNode.getScale() toonFacing = toon.getHpr() propTrack = Sequence(Func(MovieUtil.showProp, glass, render, glassPos), Func(MovieUtil.showProp, ladder, render, ladderPos), Func(toonsLook, toonsInBattle, placeNode, Point3(0, 0, 0)), Func(placeNode.setPos, lookBase), LerpScaleInterval(ladder, ladderGrowTime, scaleUpPoint, startScale=MovieUtil.PNT3_NEARZERO), Func(placeNode.setPos, lookTop), Wait(2.1), MovieCamera.toonGroupHighShot(None, 0), Wait(2.1), Func(placeNode.setPos, LookGlass), Wait(0.4), MovieCamera.allGroupLowShot(None, 0), Wait(1.8), LerpScaleInterval(ladder, ladderGrowTime, MovieUtil.PNT3_NEARZERO, startScale=scaleUpPoint), Func(MovieUtil.removeProps, diveProps)) mtrack = Parallel(propTrack, __getSoundTrack(level, 0.6, duration=9.0, node=toon), Sequence(Parallel(Sequence(ActorInterval(toon, 'walk', loop=0, duration=walkToLadderTime), ActorInterval(toon, 'neutral', loop=0, duration=0.1)), LerpPosInterval(toon, walkToLadderTime, climbladderPos), Wait(ladderGrowTime)), Parallel(ActorInterval(toon, 'climb', loop=0, endFrame=116), Sequence(Wait(4.6), Func(toonNode.setTransparency, 1), LerpColorScaleInterval(toonNode, 0.25, VBase4(1, 1.0, 1, 0.0), blendType='easeInOut'), LerpScaleInterval(toonNode, 0.01, 0.1, startScale=toonscale), LerpHprInterval(toon, 0.01, toonFacing), LerpPosInterval(toon, 0.0, glassToonPos), Func(toonNode.clearTransparency), Func(toonNode.clearColorScale), Parallel(ActorInterval(toon, 'swim', loop=1, startTime=0.0, endTime=1.0), Wait(1.0))), Sequence(Wait(4.6), Func(splash.play), Wait(1.0), Func(splash.destroy))), Wait(0.5), Parallel(ActorInterval(toon, 'jump', loop=0, startTime=0.2), LerpScaleInterval(toonNode, 0.5, toonscale, startScale=0.1), Func(stopLook, toonsInBattle))), targetTrack) track.append(mtrack) if npcId != 0: track.append(MovieNPCSOS.teleportOut(heal, toon)) else: track.append(__returnToBase(heal)) for target in targets: targetToon = target['toon'] track.append(Func(targetToon.clearChat)) return track
def doFires(fires): npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(fires) if len(fires) == 0: return (None, None) suitFiresDict = {} i = 0 try: attempt = fires[0]['target'][i]['suit'] doAdd = True except: doAdd = False for fire in fires: if doAdd: suitId = fire['target'][i]['suit'].doId i = i + 1 else: suitId = fire['target']['suit'].doId if suitId in suitFiresDict: suitFiresDict[suitId].append(fire) else: suitFiresDict[suitId] = [fire] suitFires = suitFiresDict.values() def compFunc(a, b): if len(a) > len(b): return 1 if len(a) < len(b): return -1 return 0 suitFires.sort(compFunc) totalHitDict = {} singleHitDict = {} groupHitDict = {} i = 0 for fire in fires: if doAdd: suitId = fire['target'][i]['suit'].doId else: suitId = fire['target']['suit'].doId if doAdd: if fire['target'][i]['hp'] > 0: addHit(singleHitDict, suitId, 1) addHit(totalHitDict, suitId, 1) else: addHit(singleHitDict, suitId, 0) addHit(totalHitDict, suitId, 0) i = i + 1 elif fire['target']['hp'] > 0: addHit(singleHitDict, suitId, 1) addHit(totalHitDict, suitId, 1) else: addHit(singleHitDict, suitId, 0) addHit(totalHitDict, suitId, 0) notify.debug('singleHitDict = %s' % singleHitDict) notify.debug('groupHitDict = %s' % groupHitDict) notify.debug('totalHitDict = %s' % totalHitDict) delay = 0.0 mtrack = Parallel() firedTargets = [] for sf in suitFires: if len(sf) > 0: ival = __doSuitFires(sf) if ival: mtrack.append(Sequence(Wait(delay), ival)) delay = delay + TOON_FIRE_SUIT_DELAY retTrack = Sequence() retTrack.append(npcArrivals) retTrack.append(mtrack) retTrack.append(npcDepartures) enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camDuration = retTrack.getDuration() camTrack = MovieCamera.chooseFireShot(fires, suitFiresDict, camDuration, enterDuration, exitDuration) return (retTrack, camTrack)
def doThrows(throws): npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(throws) if len(throws) == 0: return (None, None) suitThrowsDict = {} for throw in throws: if attackAffectsGroup(throw['track'], throw['level']): pass else: suitId = throw['target']['suit'].doId if suitId in suitThrowsDict: suitThrowsDict[suitId].append(throw) else: suitThrowsDict[suitId] = [throw] suitThrows = suitThrowsDict.values() def compFunc(a, b): if len(a) > len(b): return 1 if len(a) < len(b): return -1 return 0 suitThrows.sort(compFunc) totalHitDict = {} singleHitDict = {} groupHitDict = {} for throw in throws: if attackAffectsGroup(throw['track'], throw['level']): for i in xrange(len(throw['target'])): target = throw['target'][i] suitId = target['suit'].doId if target['hp'] > 0: addHit(groupHitDict, suitId, 1) addHit(totalHitDict, suitId, 1) else: addHit(groupHitDict, suitId, 0) addHit(totalHitDict, suitId, 0) else: suitId = throw['target']['suit'].doId if throw['target']['hp'] > 0: addHit(singleHitDict, suitId, 1) addHit(totalHitDict, suitId, 1) else: addHit(singleHitDict, suitId, 0) addHit(totalHitDict, suitId, 0) notify.debug('singleHitDict = %s' % singleHitDict) notify.debug('groupHitDict = %s' % groupHitDict) notify.debug('totalHitDict = %s' % totalHitDict) delay = 0.0 mtrack = Parallel() for st in suitThrows: if len(st) > 0: ival = __doSuitThrows(st, npcs) if ival: mtrack.append(Sequence(Wait(delay), ival)) delay = delay + TOON_THROW_SUIT_DELAY retTrack = Sequence() retTrack.append(npcArrivals) retTrack.append(mtrack) groupThrowIvals = Parallel() groupThrows = [] for throw in throws: if attackAffectsGroup(throw['track'], throw['level']): groupThrows.append(throw) for throw in groupThrows: tracks = None tracks = __throwGroupPie(throw, 0, groupHitDict, npcs) if tracks: for track in tracks: groupThrowIvals.append(track) retTrack.append(groupThrowIvals) retTrack.append(npcDepartures) camDuration = retTrack.getDuration() enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camTrack = MovieCamera.chooseThrowShot(throws, suitThrowsDict, camDuration, enterDuration=enterDuration, exitDuration=exitDuration) return (retTrack, camTrack)
def doDrops(drops): if len(drops) == 0: return (None, None) npcArrivals, npcDepartures, npcs = MovieNPCSOS.doNPCTeleports(drops) suitDropsDict = {} groupDrops = [] for drop in drops: track = drop['track'] level = drop['level'] targets = drop['target'] if len(targets) == 1: suitId = targets[0]['suit'].doId if suitId in suitDropsDict: suitDropsDict[suitId].append((drop, targets[0])) else: suitDropsDict[suitId] = [(drop, targets[0])] elif level <= MAX_LEVEL_INDEX and attackAffectsGroup(track, level): groupDrops.append(drop) else: for target in targets: suitId = target['suit'].doId if suitId in suitDropsDict: otherDrops = suitDropsDict[suitId] alreadyInList = 0 for oDrop in otherDrops: if oDrop[0]['toon'] == drop['toon']: alreadyInList = 1 if alreadyInList == 0: suitDropsDict[suitId].append((drop, target)) else: suitDropsDict[suitId] = [(drop, target)] suitDrops = suitDropsDict.values() def compFunc(a, b): if len(a) > len(b): return 1 elif len(a) < len(b): return -1 return 0 suitDrops.sort(compFunc) delay = 0.0 mtrack = Parallel(name='toplevel-drop') npcDrops = {} for st in suitDrops: if len(st) > 0: ival = __doSuitDrops(st, npcs, npcDrops) if ival: mtrack.append(Sequence(Wait(delay), ival)) delay = delay + TOON_DROP_SUIT_DELAY dropTrack = Sequence(npcArrivals, mtrack, npcDepartures) camDuration = mtrack.getDuration() if groupDrops: ival = __doGroupDrops(groupDrops) dropTrack.append(ival) camDuration += ival.getDuration() enterDuration = npcArrivals.getDuration() exitDuration = npcDepartures.getDuration() camTrack = MovieCamera.chooseDropShot(drops, suitDropsDict, camDuration, enterDuration, exitDuration) return (dropTrack, camTrack)