def enterStunned(self):
     stunSequence = MovieUtil.createSuitStunInterval(
         self, 0, ToontownGlobals.LawbotBossLawyerStunTime)
     seqName = stunSequence.getName()
     stunSequence.append(Func(self.fsm.request, 'neutral'))
     self.activeIntervals[seqName] = stunSequence
     stunSequence.start()
 def enterStunned(self):
     self.loop('lured', 0)
     stunSequence = MovieUtil.createSuitStunInterval(self, 0, ToontownGlobals.LawbotBossLawyerStunTime)
     seqName = stunSequence.getName()
     stunSequence.append(Func(self.fsm.request, 'neutral'))
     self.activeIntervals[seqName] = stunSequence
     stunSequence.start()
def __getSuitTrack(sound, lastSoundThatHit, delay, hitCount, targets, totalDamage, hpbonus, toon, npcs):
    tracks = Parallel()
    attacks = 0
    uberDelay = 0.0
    isUber = 0
    if sound['level'] >= ToontownBattleGlobals.UBER_GAG_LEVEL_INDEX:
        uberDelay = 3.0
        isUber = 1
    for target in targets:
        suit = target['suit']
        if totalDamage > 0 and sound == lastSoundThatHit:
            hp = target['hp']
            died = target['died']
            battle = sound['battle']
            kbbonus = target['kbbonus']
            suitTrack = Sequence()
            showDamage = Func(suit.showHpText, -totalDamage, openEnded=0)
            updateHealthBar = Func(suit.updateHealthBar, totalDamage)
            if isUber:
                breakEffect = BattleParticles.createParticleEffect(file='soundBreak')
                breakEffect.setDepthWrite(0)
                breakEffect.setDepthTest(0)
                breakEffect.setTwoSided(1)
                soundEffect = globalBattleSoundCache.getSound(hitSoundFiles[0])
            suitTrack.append(Wait(delay + tSuitReact))
            if isUber:
                delayTime = random.random()
                suitTrack.append(Wait(delayTime + 2.0))
                suitTrack.append(Func(setPosFromOther, breakEffect, suit, Point3(0, 0.0, suit.getHeight() - 1.0)))
                #suitTrack.append(Parallel(showDamage, updateHealthBar, SoundInterval(soundEffect, node=suit), __getPartTrack(breakEffect, 0.0, 1.0, [breakEffect, suit, 0], softStop=-0.5))) THIS CRASHES PANDA WITH A BOUNDING SPHERE ERROR
                suitTrack.append(Sequence(showDamage, updateHealthBar, SoundInterval(soundEffect, node=suit)))
                if died and not suit.getSkelecog():
                    suitTrack.append(headExplodeTrack(suit, battle))
            else:
                suitTrack.append(showDamage)
                suitTrack.append(updateHealthBar)
            if hitCount == 1:
                suitTrack.append(Parallel(ActorInterval(suit, 'squirt-small-react'), MovieUtil.createSuitStunInterval(suit, 0.5, 1.8)))
            else:
                suitTrack.append(ActorInterval(suit, 'squirt-small-react'))
            if kbbonus == 0:
                suitTrack.append(__createSuitResetPosTrack(suit, battle))
                suitTrack.append(Func(battle.unlureSuit, suit))
            bonusTrack = None
            if hpbonus > 0:
                bonusTrack = Sequence(Wait(delay + tSuitReact + delay + 0.75 + uberDelay), Func(suit.showHpText, -hpbonus, 1, openEnded=0), Func(suit.updateHealthBar, hpbonus))
            suitTrack.append(Func(suit.loop, 'neutral'))
            if bonusTrack == None:
                tracks.append(suitTrack)
            else:
                tracks.append(Parallel(suitTrack, bonusTrack))
        elif totalDamage <= 0:
            tracks.append(Sequence(Wait(2.9), Func(MovieUtil.indicateMissed, suit, 1.0)))
            tracks.append(MovieUtil.createSuitTeaseMultiTrack(suit, delay + tSuitReact))

    return tracks
Esempio n. 4
0
    def enterStunned(self):
        assert(self.notify.debug('enterStunned'))

        stunSequence = MovieUtil.createSuitStunInterval(self, 0, ToontownGlobals.LawbotBossLawyerStunTime)
        #seqName = self.uniqueName('stunSequence')
        seqName = stunSequence.getName()
        stunSequence.append(Func(self.fsm.request,'neutral'))
        self.activeIntervals[seqName] = stunSequence
        stunSequence.start()

        return
Esempio n. 5
0
def __getSuitTrack(suit,
                   tContact,
                   tDodge,
                   hp,
                   hpbonus,
                   kbbonus,
                   anim,
                   died,
                   leftSuits,
                   rightSuits,
                   battle,
                   toon,
                   fShowStun,
                   beforeStun=0.5,
                   afterStun=1.8,
                   geyser=0,
                   uberRepeat=0,
                   revived=0):
    if hp > 0:
        suitTrack = Sequence()
        sival = ActorInterval(suit, anim)
        sival = []
        if kbbonus > 0 and not geyser:
            suitPos, suitHpr = battle.getActorPosHpr(suit)
            suitType = getSuitBodyType(suit.getStyleName())
            animTrack = Sequence()
            animTrack.append(ActorInterval(suit, anim, duration=0.2))
            if suitType == 'a':
                animTrack.append(
                    ActorInterval(suit, 'slip-forward', startTime=2.43))
            elif suitType == 'b':
                animTrack.append(
                    ActorInterval(suit, 'slip-forward', startTime=1.94))
            elif suitType == 'c':
                animTrack.append(
                    ActorInterval(suit, 'slip-forward', startTime=2.58))
            animTrack.append(Func(battle.unlureSuit, suit))
            moveTrack = Sequence(
                Wait(0.2), LerpPosInterval(suit,
                                           0.6,
                                           pos=suitPos,
                                           other=battle))
            sival = Parallel(animTrack, moveTrack)
        elif geyser:
            suitStartPos = suit.getPos()
            suitFloat = Point3(0, 0, 14)
            suitEndPos = Point3(suitStartPos[0] + suitFloat[0],
                                suitStartPos[1] + suitFloat[1],
                                suitStartPos[2] + suitFloat[2])
            suitType = getSuitBodyType(suit.getStyleName())
            if suitType == 'a':
                startFlailFrame = 16
                endFlailFrame = 16
            elif suitType == 'b':
                startFlailFrame = 15
                endFlailFrame = 15
            else:
                startFlailFrame = 15
                endFlailFrame = 15
            sival = Sequence(
                ActorInterval(suit,
                              'slip-backward',
                              playRate=0.5,
                              startFrame=0,
                              endFrame=startFlailFrame - 1),
                Func(suit.pingpong,
                     'slip-backward',
                     fromFrame=startFlailFrame,
                     toFrame=endFlailFrame), Wait(0.5),
                ActorInterval(suit,
                              'slip-backward',
                              playRate=1.0,
                              startFrame=endFlailFrame))
            sUp = LerpPosInterval(suit,
                                  1.1,
                                  suitEndPos,
                                  startPos=suitStartPos,
                                  fluid=1)
            sDown = LerpPosInterval(suit,
                                    0.6,
                                    suitStartPos,
                                    startPos=suitEndPos,
                                    fluid=1)
        elif fShowStun == 1:
            sival = Parallel(
                ActorInterval(suit, anim),
                MovieUtil.createSuitStunInterval(suit, beforeStun, afterStun))
        else:
            sival = ActorInterval(suit, anim)
        showDamage = Func(suit.showHpText,
                          -hp,
                          openEnded=0,
                          attackTrack=SQUIRT_TRACK)
        updateHealthBar = Func(suit.updateHealthBar, hp)
        suitTrack.append(Wait(tContact))
        suitTrack.append(showDamage)
        suitTrack.append(updateHealthBar)
        if not geyser:
            suitTrack.append(sival)
        elif not uberRepeat:
            geyserMotion = Sequence(sUp, Wait(0.0), sDown)
            suitLaunch = Parallel(sival, geyserMotion)
            suitTrack.append(suitLaunch)
        else:
            suitTrack.append(Wait(5.5))
        bonusTrack = Sequence(Wait(tContact))
        if kbbonus > 0:
            bonusTrack.append(Wait(0.75))
            bonusTrack.append(
                Func(suit.showHpText,
                     -kbbonus,
                     2,
                     openEnded=0,
                     attackTrack=SQUIRT_TRACK))
            bonusTrack.append(Func(suit.updateHealthBar, kbbonus))
        if hpbonus > 0:
            bonusTrack.append(Wait(0.75))
            bonusTrack.append(
                Func(suit.showHpText,
                     -hpbonus,
                     1,
                     openEnded=0,
                     attackTrack=SQUIRT_TRACK))
            bonusTrack.append(Func(suit.updateHealthBar, hpbonus))
        if died != 0:
            suitTrack.append(MovieUtil.createSuitDeathTrack(
                suit, toon, battle))
        else:
            suitTrack.append(Func(suit.loop, 'neutral'))
        if revived != 0:
            suitTrack.append(
                MovieUtil.createSuitReviveTrack(suit, toon, battle))
        return Parallel(suitTrack, bonusTrack)
    else:
        return MovieUtil.createSuitDodgeMultitrack(tDodge, suit, leftSuits,
                                                   rightSuits)
Esempio n. 6
0
def __throwPie(throw, i, delay, hitCount, showCannon=1):
    toon = throw['toon']
    if 'npc' in throw:
        toon = throw['npc']
    hpbonus = throw['hpbonus']
    target = throw['target']
    try:
        target = target[i]
    except:
        pass

    suit = target['suit']
    hp = target['hp']
    kbbonus = target['kbbonus']
    sidestep = throw['sidestep']
    died = target['died']
    revived = target['revived']
    leftSuits = target['leftSuits']
    rightSuits = target['rightSuits']
    level = throw['level']
    battle = throw['battle']
    suitPos = suit.getPos(battle)
    origHpr = toon.getHpr(battle)
    notify.debug('toon: %s throws tart at suit: %d for hp: %d died: %d' %
                 (toon.getName(), suit.doId, hp, died))
    pieName = pieNames[0]
    hitSuit = hp > 0
    button = globalPropPool.getProp('button')
    buttonType = globalPropPool.getPropType('button')
    button2 = MovieUtil.copyProp(button)
    buttons = [button, button2]
    hands = toon.getLeftHands()
    toonTrack = Sequence()
    toonFace = Func(toon.headsUp, battle, suitPos)
    toonTrack.append(Wait(delay))
    toonTrack.append(toonFace)
    toonTrack.append(ActorInterval(toon, 'pushbutton'))
    toonTrack.append(ActorInterval(toon, 'wave', duration=2.0))
    toonTrack.append(ActorInterval(toon, 'duck'))
    toonTrack.append(Func(toon.loop, 'neutral'))
    toonTrack.append(Func(toon.setHpr, battle, origHpr))
    buttonTrack = Sequence()
    buttonShow = Func(MovieUtil.showProps, buttons, hands)
    buttonScaleUp = LerpScaleInterval(button,
                                      1.0,
                                      button.getScale(),
                                      startScale=Point3(0.01, 0.01, 0.01))
    buttonScaleDown = LerpScaleInterval(button,
                                        1.0,
                                        Point3(0.01, 0.01, 0.01),
                                        startScale=button.getScale())
    buttonHide = Func(MovieUtil.removeProps, buttons)
    buttonTrack.append(Wait(delay))
    buttonTrack.append(buttonShow)
    buttonTrack.append(buttonScaleUp)
    buttonTrack.append(Wait(2.5))
    buttonTrack.append(buttonScaleDown)
    buttonTrack.append(buttonHide)
    soundTrack = __getSoundTrack(level, hitSuit, toon)
    suitResponseTrack = Sequence()
    reactIval = Sequence()
    if showCannon:
        showDamage = Func(suit.showHpText, -hp, openEnded=0)
        updateHealthBar = Func(suit.updateHealthBar, hp)
        cannon = loader.loadModel('phase_4/models/minigames/toon_cannon')
        barrel = cannon.find('**/cannon')
        barrel.setHpr(0, 90, 0)
        cannonHolder = render.attachNewNode('CannonHolder')
        cannon.reparentTo(cannonHolder)
        cannon.setPos(0, 0, -8.6)
        cannonHolder.setPos(suit.getPos(render))
        cannonHolder.setHpr(suit.getHpr(render))
        cannonAttachPoint = barrel.attachNewNode('CannonAttach')
        kapowAttachPoint = barrel.attachNewNode('kapowAttach')
        scaleFactor = 1.6
        iScale = 1 / scaleFactor
        barrel.setScale(scaleFactor, 1, scaleFactor)
        cannonAttachPoint.setScale(iScale, 1, iScale)
        cannonAttachPoint.setPos(0, 6.7, 0)
        kapowAttachPoint.setPos(0, -0.5, 1.9)
        suit.reparentTo(cannonAttachPoint)
        suit.setPos(0, 0, 0)
        suit.setHpr(0, -90, 0)
        suitLevel = suit.getActualLevel()
        if suitLevel > 12:
            suitLevel = 12
        deep = 2.5 + suitLevel * 0.2
        suitScale = 0.9
        import math
        suitScale = 0.9 - math.sqrt(suitLevel) * 0.1
        sival = []
        posInit = cannonHolder.getPos()
        posFinal = Point3(posInit[0] + 0.0, posInit[1] + 0.0, posInit[2] + 7.0)
        kapow = globalPropPool.getProp('kapow')
        kapow.reparentTo(kapowAttachPoint)
        kapow.hide()
        kapow.setScale(0.25)
        kapow.setBillboardPointEye()
        smoke = loader.loadModel('phase_4/models/props/test_clouds')
        smoke.reparentTo(cannonAttachPoint)
        smoke.setScale(0.5)
        smoke.hide()
        smoke.setBillboardPointEye()
        soundBomb = base.loader.loadSfx(
            'phase_4/audio/sfx/MG_cannon_fire_alt.ogg')
        playSoundBomb = SoundInterval(soundBomb, node=cannonHolder)
        soundFly = base.loader.loadSfx(
            'phase_4/audio/sfx/firework_whistle_01.ogg')
        playSoundFly = SoundInterval(soundFly, node=cannonHolder)
        soundCannonAdjust = base.loader.loadSfx(
            'phase_4/audio/sfx/MG_cannon_adjust.ogg')
        playSoundCannonAdjust = SoundInterval(soundCannonAdjust,
                                              duration=0.6,
                                              node=cannonHolder)
        soundCogPanic = base.loader.loadSfx(
            'phase_5/audio/sfx/ENC_cogafssm.ogg')
        playSoundCogPanic = SoundInterval(soundCogPanic, node=cannonHolder)
        reactIval = Parallel(
            ActorInterval(suit, 'pie-small-react'),
            Sequence(
                Wait(0.0),
                LerpPosInterval(cannonHolder,
                                2.0,
                                posFinal,
                                startPos=posInit,
                                blendType='easeInOut'),
                Parallel(
                    LerpHprInterval(barrel,
                                    0.6,
                                    Point3(0, 45, 0),
                                    startHpr=Point3(0, 90, 0),
                                    blendType='easeIn'),
                    playSoundCannonAdjust), Wait(2.0),
                Parallel(
                    LerpHprInterval(barrel,
                                    0.6,
                                    Point3(0, 90, 0),
                                    startHpr=Point3(0, 45, 0),
                                    blendType='easeIn'),
                    playSoundCannonAdjust),
                LerpPosInterval(cannonHolder,
                                1.0,
                                posInit,
                                startPos=posFinal,
                                blendType='easeInOut')),
            Sequence(
                Wait(0.0),
                Parallel(
                    ActorInterval(suit, 'flail'),
                    suit.scaleInterval(1.0, suitScale),
                    LerpPosInterval(suit, 0.25, Point3(0, -1.0, 0.0)),
                    Sequence(
                        Wait(0.25),
                        Parallel(
                            playSoundCogPanic,
                            LerpPosInterval(suit,
                                            1.5,
                                            Point3(0, -deep, 0.0),
                                            blendType='easeIn')))), Wait(2.5),
                Parallel(
                    playSoundBomb, playSoundFly,
                    Sequence(
                        Func(smoke.show),
                        Parallel(
                            LerpScaleInterval(smoke, 0.5, 3),
                            LerpColorScaleInterval(smoke, 0.5,
                                                   Vec4(2, 2, 2, 0))),
                        Func(smoke.hide)),
                    Sequence(Func(kapow.show), ActorInterval(kapow, 'kapow'),
                             Func(kapow.hide)),
                    LerpPosInterval(suit, 3.0, Point3(0, 150.0, 0.0)),
                    suit.scaleInterval(3.0, 0.01)), Func(suit.hide)))
        if hitCount == 1:
            sival = Sequence(
                Parallel(reactIval,
                         MovieUtil.createSuitStunInterval(suit, 0.3, 1.3)),
                Wait(0.0), Func(cannonHolder.remove))
        else:
            sival = reactIval
        suitResponseTrack.append(Wait(delay + tPieHitsSuit))
        suitResponseTrack.append(showDamage)
        suitResponseTrack.append(updateHealthBar)
        suitResponseTrack.append(sival)
        bonusTrack = Sequence(Wait(delay + tPieHitsSuit))
        if kbbonus > 0:
            bonusTrack.append(Wait(0.75))
            bonusTrack.append(Func(suit.showHpText, -kbbonus, 2, openEnded=0))
        if hpbonus > 0:
            bonusTrack.append(Wait(0.75))
            bonusTrack.append(Func(suit.showHpText, -hpbonus, 1, openEnded=0))
        suitResponseTrack = Parallel(suitResponseTrack, bonusTrack)
    return [toonTrack, soundTrack, buttonTrack, suitResponseTrack]
Esempio n. 7
0
def __throwGroupPie(throw, delay, groupHitDict, npcs):
    toon = throw['toon']
    if 'npc' in throw:
        toon = throw['npc']
    battle = throw['battle']
    level = throw['level']
    sidestep = throw['sidestep']
    hpbonus = throw['hpbonus']
    numTargets = len(throw['target'])
    avgSuitPos = calcAvgSuitPos(throw)
    origHpr = toon.getHpr(battle)
    toonTrack = Sequence()
    toonFace = Func(toon.headsUp, battle, avgSuitPos)
    toonTrack.append(Wait(delay))
    toonTrack.append(toonFace)
    toonTrack.append(ActorInterval(toon, 'throw'))
    toonTrack.append(Func(toon.loop, 'neutral'))
    if 'npc' not in throw:
        toonTrack.append(Func(toon.setHpr, battle, origHpr))
    suits = []
    for i in xrange(numTargets):
        suits.append(throw['target'][i]['suit'])

    pieName = pieNames[level]
    pie = globalPropPool.getProp(pieName)
    pieType = globalPropPool.getPropType(pieName)
    pie2 = MovieUtil.copyProp(pie)
    pies = [pie, pie2]
    hands = toon.getRightHands()
    pieShow = Func(MovieUtil.showProps, pies, hands)
    pieAnim = Func(__animProp, pies, pieName, pieType)
    pieScale1 = LerpScaleInterval(pie,
                                  1.0,
                                  pie.getScale() * 1.5,
                                  startScale=MovieUtil.PNT3_NEARZERO)
    pieScale2 = LerpScaleInterval(pie2,
                                  1.0,
                                  pie2.getScale() * 1.5,
                                  startScale=MovieUtil.PNT3_NEARZERO)
    pieScale = Parallel(pieScale1, pieScale2)
    piePreflight = Func(__propPreflightGroup, pies, suits, toon, battle)
    pieTrack = Sequence(Wait(delay), pieShow, pieAnim, pieScale,
                        Func(battle.movie.needRestoreRenderProp, pies[0]),
                        Wait(tPieLeavesHand - 1.0), piePreflight)
    if level == UBER_GAG_LEVEL_INDEX:
        groupPieTracks = __createWeddingCakeFlight(throw, groupHitDict, pie,
                                                   pies)
    else:
        notify.error('unhandled throw level %d' % level)
    pieTrack.append(groupPieTracks)
    didThrowHitAnyone = False
    for i in xrange(numTargets):
        target = throw['target'][i]
        hitSuit = target['hp'] > 0
        if hitSuit:
            didThrowHitAnyone = True

    soundTrack = __getSoundTrack(level, didThrowHitAnyone, toon)
    groupSuitResponseTrack = Parallel()
    for i in xrange(numTargets):
        target = throw['target'][i]
        suit = target['suit']
        hitSuit = target['hp'] > 0
        leftSuits = target['leftSuits']
        rightSuits = target['rightSuits']
        hp = target['hp']
        kbbonus = target['kbbonus']
        died = target['died']
        revived = target['revived']
        if hitSuit:
            singleSuitResponseTrack = Sequence()
            showDamage = Func(suit.showHpText,
                              -hp,
                              openEnded=0,
                              attackTrack=THROW_TRACK)
            updateHealthBar = Func(suit.updateHealthBar, hp)
            sival = []
            if kbbonus > 0:
                suitPos, suitHpr = battle.getActorPosHpr(suit)
                suitType = getSuitBodyType(suit.getStyleName())
                animTrack = Sequence()
                animTrack.append(
                    ActorInterval(suit, 'pie-small-react', duration=0.2))
                if suitType == 'a':
                    animTrack.append(
                        ActorInterval(suit, 'slip-forward', startTime=2.43))
                elif suitType == 'b':
                    animTrack.append(
                        ActorInterval(suit, 'slip-forward', startTime=1.94))
                elif suitType == 'c':
                    animTrack.append(
                        ActorInterval(suit, 'slip-forward', startTime=2.58))
                animTrack.append(Func(battle.unlureSuit, suit))
                moveTrack = Sequence(
                    Wait(0.2),
                    LerpPosInterval(suit, 0.6, pos=suitPos, other=battle))
                sival = Parallel(animTrack, moveTrack)
            elif groupHitDict[suit.doId] == 1:
                sival = Parallel(
                    ActorInterval(suit, 'pie-small-react'),
                    MovieUtil.createSuitStunInterval(suit, 0.3, 1.3))
            else:
                sival = ActorInterval(suit, 'pie-small-react')
            singleSuitResponseTrack.append(Wait(delay + tPieHitsSuit))
            singleSuitResponseTrack.append(showDamage)
            singleSuitResponseTrack.append(updateHealthBar)
            singleSuitResponseTrack.append(sival)
            bonusTrack = Sequence(Wait(delay + tPieHitsSuit))
            if kbbonus > 0:
                bonusTrack.append(Wait(0.75))
                bonusTrack.append(
                    Func(suit.showHpText,
                         -kbbonus,
                         2,
                         openEnded=0,
                         attackTrack=THROW_TRACK))
                bonusTrack.append(Func(suit.updateHealthBar, kbbonus))
            if hpbonus > 0:
                bonusTrack.append(Wait(0.75))
                bonusTrack.append(
                    Func(suit.showHpText,
                         -hpbonus,
                         1,
                         openEnded=0,
                         attackTrack=THROW_TRACK))
                bonusTrack.append(Func(suit.updateHealthBar, hpbonus))
            if revived != 0:
                singleSuitResponseTrack.append(
                    MovieUtil.createSuitReviveTrack(suit, toon, battle, npcs))
            elif died != 0:
                singleSuitResponseTrack.append(
                    MovieUtil.createSuitDeathTrack(suit, toon, battle, npcs))
            else:
                singleSuitResponseTrack.append(Func(suit.loop, 'neutral'))
            singleSuitResponseTrack = Parallel(singleSuitResponseTrack,
                                               bonusTrack)
        else:
            groupHitValues = groupHitDict.values()
            if groupHitValues.count(0) == len(groupHitValues):
                singleSuitResponseTrack = MovieUtil.createSuitDodgeMultitrack(
                    delay + tSuitDodges, suit, leftSuits, rightSuits)
            else:
                singleSuitResponseTrack = Sequence(
                    Wait(tPieHitsSuit - 0.1),
                    Func(MovieUtil.indicateMissed, suit, 1.0))
        groupSuitResponseTrack.append(singleSuitResponseTrack)

    return [toonTrack, pieTrack, soundTrack, groupSuitResponseTrack]
Esempio n. 8
0
def __throwPie(throw, delay, hitCount, npcs):
    toon = throw['toon']
    if 'npc' in throw:
        toon = throw['npc']
    hpbonus = throw['hpbonus']
    target = throw['target']
    suit = target['suit']
    hp = target['hp']
    kbbonus = target['kbbonus']
    sidestep = throw['sidestep']
    died = target['died']
    revived = target['revived']
    leftSuits = target['leftSuits']
    rightSuits = target['rightSuits']
    level = throw['level']
    battle = throw['battle']
    suitPos = suit.getPos(battle)
    origHpr = toon.getHpr(battle)
    notify.debug('toon: %s throws tart at suit: %d for hp: %d died: %d' %
                 (toon.getName(), suit.doId, hp, died))
    pieName = pieNames[level]
    hitSuit = hp > 0
    pie = globalPropPool.getProp(pieName)
    pieType = globalPropPool.getPropType(pieName)
    pie2 = MovieUtil.copyProp(pie)
    pies = [pie, pie2]
    hands = toon.getRightHands()
    splatName = 'splat-' + pieName
    if pieName == 'wedding-cake':
        splatName = 'splat-birthday-cake'
    splat = globalPropPool.getProp(splatName)
    splatType = globalPropPool.getPropType(splatName)
    toonTrack = Sequence()
    toonFace = Func(toon.headsUp, battle, suitPos)
    toonTrack.append(Wait(delay))
    toonTrack.append(toonFace)
    toonTrack.append(ActorInterval(toon, 'throw'))
    toonTrack.append(Func(toon.loop, 'neutral'))
    if 'npc' not in throw:
        toonTrack.append(Func(toon.setHpr, battle, origHpr))
    pieShow = Func(MovieUtil.showProps, pies, hands)
    pieAnim = Func(__animProp, pies, pieName, pieType)
    pieScale1 = LerpScaleInterval(pie,
                                  1.0,
                                  pie.getScale(),
                                  startScale=MovieUtil.PNT3_NEARZERO)
    pieScale2 = LerpScaleInterval(pie2,
                                  1.0,
                                  pie2.getScale(),
                                  startScale=MovieUtil.PNT3_NEARZERO)
    pieScale = Parallel(pieScale1, pieScale2)
    piePreflight = Func(__propPreflight, pies, suit, toon, battle)
    pieTrack = Sequence(Wait(delay), pieShow, pieAnim, pieScale,
                        Func(battle.movie.needRestoreRenderProp, pies[0]),
                        Wait(tPieLeavesHand - 1.0), piePreflight)
    soundTrack = __getSoundTrack(level, hitSuit, toon)
    if hitSuit:
        pieFly = LerpPosInterval(pie,
                                 tPieHitsSuit - tPieLeavesHand,
                                 pos=MovieUtil.avatarFacePoint(suit,
                                                               other=battle),
                                 name=pieFlyTaskName,
                                 other=battle)
        pieHide = Func(MovieUtil.removeProps, pies)
        splatShow = Func(__showProp, splat, suit,
                         Point3(0, 0, suit.getHeight()))
        splatBillboard = Func(__billboardProp, splat)
        splatAnim = ActorInterval(splat, splatName)
        splatHide = Func(MovieUtil.removeProp, splat)
        pieTrack.append(pieFly)
        pieTrack.append(pieHide)
        pieTrack.append(Func(battle.movie.clearRenderProp, pies[0]))
        pieTrack.append(splatShow)
        pieTrack.append(splatBillboard)
        pieTrack.append(splatAnim)
        pieTrack.append(splatHide)
    else:
        missDict = {}
        if sidestep:
            suitPoint = MovieUtil.avatarFacePoint(suit, other=battle)
        else:
            suitPoint = __suitMissPoint(suit, other=battle)
        piePreMiss = Func(__piePreMiss, missDict, pie, suitPoint, battle)
        pieMiss = LerpFunctionInterval(
            __pieMissLerpCallback,
            extraArgs=[missDict],
            duration=(tPieHitsSuit - tPieLeavesHand) * ratioMissToHit)
        pieHide = Func(MovieUtil.removeProps, pies)
        pieTrack.append(piePreMiss)
        pieTrack.append(pieMiss)
        pieTrack.append(pieHide)
        pieTrack.append(Func(battle.movie.clearRenderProp, pies[0]))
    if hitSuit:
        suitResponseTrack = Sequence()
        showDamage = Func(suit.showHpText,
                          -hp,
                          openEnded=0,
                          attackTrack=THROW_TRACK)
        updateHealthBar = Func(suit.updateHealthBar, hp)
        sival = []
        if kbbonus > 0:
            suitPos, suitHpr = battle.getActorPosHpr(suit)
            suitType = getSuitBodyType(suit.getStyleName())
            animTrack = Sequence()
            animTrack.append(
                ActorInterval(suit, 'pie-small-react', duration=0.2))
            if suitType == 'a':
                animTrack.append(
                    ActorInterval(suit, 'slip-forward', startTime=2.43))
            elif suitType == 'b':
                animTrack.append(
                    ActorInterval(suit, 'slip-forward', startTime=1.94))
            elif suitType == 'c':
                animTrack.append(
                    ActorInterval(suit, 'slip-forward', startTime=2.58))
            animTrack.append(Func(battle.unlureSuit, suit))
            moveTrack = Sequence(
                Wait(0.2), LerpPosInterval(suit,
                                           0.6,
                                           pos=suitPos,
                                           other=battle))
            sival = Parallel(animTrack, moveTrack)
        elif hitCount == 1:
            sival = Parallel(ActorInterval(suit, 'pie-small-react'),
                             MovieUtil.createSuitStunInterval(suit, 0.3, 1.3))
        else:
            sival = ActorInterval(suit, 'pie-small-react')
        suitResponseTrack.append(Wait(delay + tPieHitsSuit))
        suitResponseTrack.append(showDamage)
        suitResponseTrack.append(updateHealthBar)
        suitResponseTrack.append(sival)
        bonusTrack = Sequence(Wait(delay + tPieHitsSuit))
        if kbbonus > 0:
            bonusTrack.append(Wait(0.75))
            bonusTrack.append(
                Func(suit.showHpText,
                     -kbbonus,
                     2,
                     openEnded=0,
                     attackTrack=THROW_TRACK))
            bonusTrack.append(Func(suit.updateHealthBar, kbbonus))
        if hpbonus > 0:
            bonusTrack.append(Wait(0.75))
            bonusTrack.append(
                Func(suit.showHpText,
                     -hpbonus,
                     1,
                     openEnded=0,
                     attackTrack=THROW_TRACK))
            bonusTrack.append(Func(suit.updateHealthBar, hpbonus))
        if revived != 0:
            suitResponseTrack.append(
                MovieUtil.createSuitReviveTrack(suit, toon, battle, npcs))
        elif died != 0:
            suitResponseTrack.append(
                MovieUtil.createSuitDeathTrack(suit, toon, battle, npcs))
        else:
            suitResponseTrack.append(Func(suit.loop, 'neutral'))
        suitResponseTrack = Parallel(suitResponseTrack, bonusTrack)
    else:
        suitResponseTrack = MovieUtil.createSuitDodgeMultitrack(
            delay + tSuitDodges, suit, leftSuits, rightSuits)
    if not hitSuit and delay > 0:
        return [toonTrack, soundTrack, pieTrack]
    else:
        return [toonTrack, soundTrack, pieTrack, suitResponseTrack]