示例#1
0
        def getToonJumpTrack(av, seatIndex):
            def getJumpDest(av=av, node=self.golfKart):
                dest = Point3(0, 0, 0)
                if hasattr(self, 'golfKart') and self.golfKart:
                    dest = Vec3(self.golfKart.getPos(av.getParent()))
                    seatNode = self.golfKart.find('**/seat' +
                                                  str(seatIndex + 1))
                    dest += seatNode.getPos(self.golfKart)
                    dna = av.getStyle()
                    dest -= hipOffset
                    if seatIndex < 2:
                        dest.setY(dest.getY() + 2 * hipOffset.getY())
                    dest.setZ(dest.getZ() + 0.1)
                else:
                    self.notify.warning(
                        'getJumpDestinvalid golfKart, returning (0,0,0)')
                return dest

            def getJumpHpr(av=av, node=self.golfKart):
                hpr = Point3(0, 0, 0)
                if hasattr(self, 'golfKart') and self.golfKart:
                    hpr = self.golfKart.getHpr(av.getParent())
                    if seatIndex < 2:
                        hpr.setX(hpr.getX() + 180)
                    else:
                        hpr.setX(hpr.getX())
                    angle = PythonUtil.fitDestAngle2Src(av.getH(), hpr.getX())
                    hpr.setX(angle)
                else:
                    self.notify.warning(
                        'getJumpHpr invalid golfKart, returning (0,0,0)')
                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
示例#2
0
 def createOneToonupIval(self, foodNode):
     toonupIndex = self.foodNodes.index(foodNode)
     waitTimeForOne = self.distBetweenFoodNodes / self.ToonupBeltSpeed
     waitTime = waitTimeForOne * toonupIndex
     self.toonupWaitTimes.append(waitTime)
     totalTimeToTraverseBelt = self.beltLength / self.ToonupBeltSpeed
     startPosY = -(self.beltLength / 2.0)
     endPosY = self.beltLength / 2.0
     retval = Sequence(
         Func(self.loadToonup, toonupIndex),
         LerpPosInterval(foodNode,
                         duration=totalTimeToTraverseBelt,
                         startPos=Point3(0, startPosY, self.beltHeight),
                         pos=Point3(0, endPosY, self.beltHeight)),
         ProjectileInterval(foodNode,
                            startPos=Point3(0, endPosY, self.beltHeight),
                            startVel=Point3(0, self.BeltSpeed, 0),
                            endZ=0), Func(self.removeToonup, toonupIndex))
     return retval
示例#3
0
    def getThrowInterval(self, gag, x, y, z, h, p, r):
        toon = self.toon
        flyGag = self.createThrowGag(gag)
        throwSoundIval = self._throwSfx
        if throwSoundIval.isPlaying():
            throwSoundIval.finish()
        throwSoundIval.node = toon
        toonThrowIval1 = ActorInterval(toon,
                                       'throw',
                                       startFrame=Globals.ThrowStartFrame,
                                       endFrame=Globals.ThrowEndFrame,
                                       playRate=Globals.ThrowPlayRate,
                                       partName='torso')
        toss = Track(
            (0,
             Sequence(Func(toon.setPosHpr, x, y, z, h, p, r),
                      Func(gag.reparentTo, toon.rightHand),
                      Func(gag.setPosHpr, 0, 0, 0, 0, 0, 0), toonThrowIval1)),
            (toonThrowIval1.getDuration(),
             Parallel(
                 Func(gag.detachNode),
                 Sequence(
                     ActorInterval(toon,
                                   'throw',
                                   startFrame=Globals.ThrowEndFrame + 1,
                                   playRate=Globals.ThrowPlayRate,
                                   partName='torso'), Func(
                                       self.completeThrow)))))

        def getEndPos(toon=toon):
            return render.getRelativePoint(toon,
                                           Point3(0, Globals.ThrowDistance, 0))

        fly = Track(
            (0, throwSoundIval),
            (toonThrowIval1.getDuration(),
             Sequence(
                 Func(flyGag.reparentTo, render),
                 Func(flyGag.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0),
                 ProjectileInterval(
                     flyGag, endPos=getEndPos, duration=Globals.ThrowDuration),
                 Func(flyGag.detachNode))))
        return (toss, fly, flyGag)
示例#4
0
 def attackTarget(self, task):
     if (self.hp > 0):
         if (self.target != None):
             cog = self.target.getPythonTag('Cog')
             if (cog.getHealth() > 0):
                 self.gagProp.hide()
                 gag = copy.copy(self.gagProp)
                 gag.reparentTo(render)
                 gag.setPos(self.gagProp.getPos(render))
                 gag.setHpr(self.gagProp.getHpr(render))
                 endPos = self.target.find('**/Head').getPos(render)
                 self.projectile = ProjectileInterval(
                     gag,
                     startPos=gag.getPos(render),
                     endPos=endPos,
                     gravityMult=1,
                     duration=1)
                 gag.show()
                 self.projectile.start()
                 self.fireSound.play()
                 self.whizzSound.play()
                 render.getPythonTag('WorldCollisions').addGagCollision(gag)
                 self.target = None
                 self.firing = False
                 base.taskMgr.doMethodLater(
                     2,
                     self.removeGag,
                     'Remove Gag',
                     extraArgs=[gag, self.projectile],
                     appendTask=True)
                 base.taskMgr.doMethodLater(2, self.resetCannon,
                                            'Reset Cannon')
                 self.cannon.find('**/cannon').setHpr(0, 0, 0)
                 self.setSupply(self.getSupply() - 1)
             else:
                 self.target = None
                 self.firing = False
                 base.taskMgr.doMethodLater(2, self.resetCannon,
                                            'Reset Cannon')
                 self.cannon.find('**/cannon').setHpr(0, 0, 0)
     return Task.done
示例#5
0
 def releaseProj(task):
     if (cog.getHealth() > 0):
         attackRange = ent.find(
             '**/joint_nameTag').attachNewNode("Attack Range")
         attackRange.setPos(0, 50, -5)
         self.projectile.setBillboardPointEye()
         wc = render.getPythonTag('WorldCollisions')
         wc.addAttackCollision(self.projectile)
         self.projectile.reparentTo(render)
         projTrack = ProjectileInterval(
             self.projectile,
             endPos=Point3(attackRange.getPos(render)),
             startPos=(handJoint.getPos(render)),
             gravityMult=0.7,
             duration=1)
         projTrack.start()
         if (self.throwSound != None):
             SoundBank.getSound(self.throwSound).play()
         ent.play('neutral')
         Sequence(Wait(2), Func(destroy, range))
     return Task.done
示例#6
0
        def getToonJumpTrack(av, destNode):
            def getJumpDest(av=av, node=destNode):
                dest = node.getPos(av.getParent())
                dest += Vec3(*self.JumpOutOffsets[seatIndex])
                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
示例#7
0
 def throw(self):
     if not self.gag and not self.isLocal():
         self.setHandJoint()
         self.build()
     if self.gag and self.getLocation():
         self.startEntity()
     else:
         if self.gag and self.trapMode == 1:
             throwPath = NodePath('ThrowPath')
             throwPath.reparentTo(self.avatar)
             throwPath.setScale(render, 1)
             throwPath.setPos(0, 160, -120)
             throwPath.setHpr(0, 90, 0)
             self.gag.setScale(self.gag.getScale(render))
             self.gag.reparentTo(render)
             self.gag.setHpr(throwPath.getHpr(render))
             self.setHandJoint()
             self.track = ProjectileInterval(self.gag, startPos=self.handJoint.getPos(render), endPos=throwPath.getPos(render), gravityMult=0.9, duration=3)
             self.track.start()
             self.buildProjCollisions()
             self.reset()
             self.avatar.acceptOnce('projSensor-into', self.onProjCollision)
    def throw(self, p):
        if not self.owner or not CIGlobals.isNodePathOk(self.owner.avatar):
            return

        self.isAirborne = True
        self.owner.avatar.play('pie', partName='torso', fromFrame=62)
        base.playSfx(self.owner.throwSound, node=self.owner.avatar)

        start = NodePath('StartPath')
        start.reparentTo(self.owner.avatar)
        start.setScale(render, 1)
        start.setPos(0, 0, 0)
        start.setP(p)

        end = NodePath('ThrowPath')
        end.reparentTo(start)
        end.setScale(render, 1)
        end.setPos(0, 160, -35)
        end.setHpr(90, -90, 90)

        self.wrtReparentTo(render)
        self.setScale(1.0)

        self.throwIval = ProjectileInterval(
            self,
            startPos=self.owner.avatar.find('**/def_joint_right_hold').getPos(
                render),
            endPos=end.getPos(render),
            gravityMult=0.9,
            duration=2)
        self.throwIval.start()
        if self.owner.avId == base.localAvatar.doId:
            self.accept('snowball-coll-' + str(id(self)) + '-into',
                        self.__handleSnowballCollision)

        start.removeNode()
        del start
        end.removeNode()
        del end
示例#9
0
    def startBallPlayback(self, power, angle, sequenceNum):
        flyBall = self.ballModel.copyTo(NodePath())
        flyBall.setScale(1.0)
        flyBallBubble = self.getFlyBallBubble().instanceTo(NodePath())
        flyBallBubble.reparentTo(flyBall)
        flyBall.setTag('pieSequence', str(sequenceNum))
        flyBall.setTag('throwerId', str(self.avId))
        t = power / 100.0
        t = 1.0 - t
        dist = 300 - 200 * t
        time = 1.5 + 0.5 * t
        proj = ProjectileInterval(None, startPos = Point3(0, 0, 0), endPos = Point3(0, dist, 0), duration = time)
        relVel = proj.startVel
        
        def getVelocity(root = self.root, relVel = relVel):
            return render.getRelativeVector(root, relVel)

        fly = Sequence(Func(flyBall.reparentTo, render), Func(flyBall.setPosHpr, self.root, 0, 0, 0, 0, 0, 0), Func(base.cTrav.addCollider, flyBallBubble, self.flyBallHandler), ProjectileInterval(flyBall, startVel = getVelocity, duration = 3), Func(flyBall.detachNode), Func(base.cTrav.removeCollider, flyBallBubble), Func(self.notify.debug, 'removed collider'), Func(self.flyBallFinishedFlying, sequenceNum))
        flyWithSound = Parallel(fly, SoundInterval(self.hitBallSfx, node = self.root), name = 'flyWithSound')
        self.notify.debug('starting flyball track')
        flyWithSound.start()
        self.flyBallTracks[sequenceNum] = flyWithSound
示例#10
0
 def serveFood(self, food, chairIndex):
     self.removeFoodModel(chairIndex)
     serviceLoc = self.serviceLocs.get(chairIndex)
     if not food or food.isEmpty():
         foodModel = loader.loadModel('phase_12/models/bossbotHQ/canoffood')
         foodModel.setScale(ToontownGlobals.BossbotFoodModelScale)
         foodModel.reparentTo(serviceLoc)
     else:
         food.wrtReparentTo(serviceLoc)
         tray = food.find('**/tray')
         if not tray.isEmpty():
             tray.hide()
         ivalDuration = 1.5
         foodMoveIval = Parallel(
             SoundInterval(self.serveFoodSfx, node=food),
             ProjectileInterval(food,
                                duration=ivalDuration,
                                startPos=food.getPos(serviceLoc),
                                endPos=serviceLoc.getPos(serviceLoc)),
             LerpHprInterval(food, ivalDuration, Point3(0, -360, 0)))
         intervalName = 'serveFood-%d-%d' % (self.index, chairIndex)
         foodMoveIval.start()
         self.activeIntervals[intervalName] = foodMoveIval
    def startProjInterval(self,
                          startX,
                          startY,
                          startZ,
                          endX,
                          endY,
                          endZ,
                          duration,
                          gravityMult,
                          ts=0):
        if isinstance(ts, int) and ts != 0:
            ts = globalClockDelta.localElapsedTime(ts)

        self.disableRay()
        self.stopMoveInterval()
        startPos = Point3(startX, startY, startZ)
        endPos = Point3(endX, endY, endZ)
        oldHpr = self.getHpr(render)
        self.headsUp(endPos)
        newHpr = self.getHpr(render)
        self.setHpr(oldHpr)
        self.moveIval = Parallel(
            LerpHprInterval(self,
                            duration=0.5,
                            hpr=newHpr,
                            startHpr=oldHpr,
                            blendType='easeInOut'),
            Sequence(Func(self.animFSM.request, 'flyAway', [ts]), Wait(3.5),
                     Func(self.animFSM.request, 'flyDown', [1.0])),
            Sequence(
                Wait(2.0), Func(self.headsUp, endPos),
                ProjectileInterval(self,
                                   startPos=startPos,
                                   endPos=endPos,
                                   gravityMult=gravityMult,
                                   duration=duration)))
        self.moveIval.start(ts)
示例#12
0
    def getTossPieInterval(self, toon, x, y, z, h, p, r, power, beginFlyIval = Sequence()):
        from toontown.toonbase import ToontownBattleGlobals
        from toontown.battle import BattleProps
        pie = toon.getPieModel()
        pie.setScale(0.9)
        flyPie = pie.copyTo(NodePath('a'))
        pieName = ToontownBattleGlobals.pieNames[toon.pieType]
        pieType = BattleProps.globalPropPool.getPropType(pieName)
        animPie = Sequence()
        if pieType == 'actor':
            animPie = ActorInterval(pie, pieName, startFrame=48)
        sound = loader.loadSfx('phase_3.5/audio/sfx/AA_pie_throw_only.mp3')
        t = power / 100.0
        dist = 100 - 70 * t
        time = 1 + 0.5 * t
        proj = ProjectileInterval(None, startPos=Point3(0, 0, 0), endPos=Point3(0, dist, 0), duration=time)
        relVel = proj.startVel

        def getVelocity(toon = toon, relVel = relVel):
            return render.getRelativeVector(toon, relVel) * 0.6

        toss = Track((0, Sequence(Func(toon.setPosHpr, x, y, z, h, p, r), Func(pie.reparentTo, toon.rightHand), Func(pie.setPosHpr, 0, 0, 0, 0, 0, 0), Parallel(ActorInterval(toon, 'throw', startFrame=48, partName='torso'), animPie), Func(toon.loop, 'neutral'))), (16.0 / 24.0, Func(pie.detachNode)))
        fly = Track((14.0 / 24.0, SoundInterval(sound, node=toon)), (16.0 / 24.0, Sequence(Func(flyPie.reparentTo, render), Func(flyPie.setPosHpr, toon, 0.52, 0.97, 2.24, 0, -45, 0), beginFlyIval, ProjectileInterval(flyPie, startVel=getVelocity, duration=6), Func(flyPie.detachNode))))
        return (toss, fly, flyPie)
示例#13
0
    def createOneToonupIval(self, foodNode):
        """Create and return a toonup Interval for this node.

        This does not include the initial wait for the toonup to appear
        """
        toonupIndex = self.foodNodes.index(foodNode)
        waitTimeForOne = self.distBetweenFoodNodes / self.ToonupBeltSpeed
        waitTime = waitTimeForOne * toonupIndex
        self.toonupWaitTimes.append(waitTime)
        totalTimeToTraverseBelt = self.beltLength / self.ToonupBeltSpeed
        startPosY = -(self.beltLength / 2.0)
        endPosY = (self.beltLength / 2.0)
        retval = Sequence(
            Func(self.loadToonup, toonupIndex),
            LerpPosInterval( foodNode, duration = totalTimeToTraverseBelt,
                             startPos = Point3(0, startPosY, self.beltHeight),
                             pos = Point3(0, endPosY, self.beltHeight)),
            ProjectileInterval( foodNode, startPos = Point3(0, endPosY, self.beltHeight),
                                startVel = Point3(0, self.BeltSpeed,0),
                                endZ = 0),
            Func(self.removeToonup, toonupIndex),
            )

        return retval
示例#14
0
    def __init__(self, collideEventName, parent, pie, endPos, gravityMult,
                 duration, local, turretClass):
        self.turret = turretClass
        self.collideEventName = collideEventName
        self.pieNp = NodePath('pieNP')
        self.pieNp.reparentTo(parent)
        self.pieNp.setScale(render, 1)
        self.pieNp.setPos(endPos)
        self.pieNp.setHpr(90, -90, 90)

        self.pie = pie
        if local:
            self.pieCollisions()
        self.pie.setScale(self.pie.getScale(render))
        self.pie.setPos(self.pie.getPos(render))
        self.pie.reparentTo(render)
        self.pie.setHpr(self.pieNp.getHpr(render))

        self.trajectory = ProjectileInterval(self.pie,
                                             startPos=self.pie.getPos(render),
                                             endPos=self.pieNp.getPos(render),
                                             gravityMult=gravityMult,
                                             duration=duration,
                                             name='projectilePieTraj' +
                                             str(id(self)))
        self.trajectory.setDoneEvent(self.trajectory.getName())
        self.acceptOnce(self.trajectory.getDoneEvent(), self.handleTrajDone)
        self.trajectory.start()
        sfx = base.localAvatar.audio3d.loadSfx(
            "phase_4/audio/sfx/MG_cannon_fire_alt.mp3")
        base.localAvatar.audio3d.attachSoundToObject(sfx, parent)
        base.playSfx(sfx)

        if local:
            self.acceptOnce('projectilePieSensor' + str(id(self)) + '-into',
                            self.handleCollision)
    def createDinerMoveIval(self, suit, destPos, chairInfo):
        """Return an interval of a diner moving to his destPos."""
        # adapted from  suit.beginSupaFlyMovie

        # calculate some times used to manipulate the suit's landing
        # animation
        #
        dur = suit.getDuration('landing')
        fr = suit.getFrameRate('landing')

        landingDur = dur

        totalDur = 7.3
        # length of time in animation spent in the air
        animTimeInAir = totalDur - dur
        flyingDur = animTimeInAir

        # length of time in animation spent impacting and reacting to
        # the ground
        impactLength = dur - animTimeInAir

        tableIndex = chairInfo[0]
        chairIndex = chairInfo[1]
        table = self.bossCog.tables[tableIndex]
        chairLocator = table.chairLocators[chairIndex]
        chairPos = chairLocator.getPos(self)
        chairHpr = chairLocator.getHpr(self)
        suit.setPos(chairPos)
        table.setDinerStatus(chairIndex, table.HIDDEN)
        suit.setHpr(chairHpr)
        wayPoint = (chairPos + destPos) / 2.0
        wayPoint.setZ(wayPoint.getZ() + 20)

        moveIval = Sequence(
            Func(suit.headsUp, self),
            Func(suit.pose, 'landing', 0),
            ProjectileInterval(suit,
                               duration=flyingDur,
                               startPos=chairPos,
                               endPos=destPos,
                               gravityMult=0.25),
            ActorInterval(suit, 'landing'),
        )

        # now create info for the propeller's animation
        #
        if suit.prop == None:
            suit.prop = BattleProps.globalPropPool.getProp('propeller')
        propDur = suit.prop.getDuration('propeller')
        lastSpinFrame = 8
        fr = suit.prop.getFrameRate('propeller')
        # time from beginning of anim at which propeller plays its spin
        spinTime = lastSpinFrame / fr
        # time from beginning of anim at which propeller starts to close
        openTime = (lastSpinFrame + 1) / fr

        # now create the propeller animation intervals that will go in
        # the third and final track
        #
        suit.attachPropeller()
        propTrack = Parallel(
            SoundInterval(suit.propInSound, duration=flyingDur, node=suit),
            Sequence(
                ActorInterval(suit.prop,
                              'propeller',
                              constrainedLoop=1,
                              duration=flyingDur + 1,
                              startTime=0.0,
                              endTime=spinTime),
                ActorInterval(suit.prop,
                              'propeller',
                              duration=landingDur,
                              startTime=openTime),
                Func(suit.detachPropeller),
            ),
        )

        result = Parallel(
            moveIval,
            propTrack,
        )
        return result
 def makeToonGrabInterval(self, toon):
     toon.pose('leverNeutral', 0)
     toon.update()
     rightHandPos = toon.rightHand.getPos(toon)
     self.toonPitcherPosition = Point3(self.handPos[0] - rightHandPos[0], self.handPos[1] - rightHandPos[1], 0)
     destZScale = rightHandPos[2] / self.handPos[2]
     grabIval = Sequence(Func(toon.wrtReparentTo, self.waterPitcherNode), Func(toon.loop, 'neutral'), Parallel(ActorInterval(toon, 'jump'), Sequence(Wait(0.43), Parallel(ProjectileInterval(toon, duration=0.9, startPos=toon.getPos(self.waterPitcherNode), endPos=self.toonPitcherPosition), LerpHprInterval(toon, 0.9, Point3(0, 0, 0)), LerpScaleInterval(self.waterPitcherModel, 0.9, Point3(1, 1, destZScale))))), Func(toon.setPos, self.toonPitcherPosition), Func(toon.loop, 'leverNeutral'))
     return grabIval
    def makeToonReleaseInterval(self, toon):
        temp1 = self.waterPitcherNode.attachNewNode('temp1')
        temp1.setPos(self.toonPitcherPosition)
        temp2 = self.waterPitcherNode.attachNewNode('temp2')
        temp2.setPos(0, -10, -self.waterPitcherNode.getZ())
        startPos = temp1.getPos(render)
        endPos = temp2.getPos(render)
        temp1.removeNode()
        temp2.removeNode()

        def getSlideToPos(toon = toon):
            return render.getRelativePoint(toon, Point3(0, -10, 0))

        if self.gotHitByBoss:
            self.notify.debug('creating zap interval instead')
            grabIval = Sequence(Func(toon.loop, 'neutral'), Func(toon.wrtReparentTo, render), Parallel(ActorInterval(toon, 'slip-backward'), toon.posInterval(0.5, getSlideToPos, fluid=1)))
        else:
            grabIval = Sequence(Func(toon.loop, 'neutral'), Func(toon.wrtReparentTo, render), Parallel(ActorInterval(toon, 'jump'), Sequence(Wait(0.43), ProjectileInterval(toon, duration=0.9, startPos=startPos, endPos=endPos))))
        return grabIval
 def createDinerMoveIval(self, suit, destPos, chairInfo):
     dur = suit.getDuration('landing')
     fr = suit.getFrameRate('landing')
     landingDur = dur
     totalDur = 7.3
     animTimeInAir = totalDur - dur
     flyingDur = animTimeInAir
     impactLength = dur - animTimeInAir
     tableIndex = chairInfo[0]
     chairIndex = chairInfo[1]
     table = self.bossCog.tables[tableIndex]
     chairLocator = table.chairLocators[chairIndex]
     chairPos = chairLocator.getPos(self)
     chairHpr = chairLocator.getHpr(self)
     suit.setPos(chairPos)
     table.setDinerStatus(chairIndex, table.HIDDEN)
     suit.setHpr(chairHpr)
     wayPoint = (chairPos + destPos) / 2.0
     wayPoint.setZ(wayPoint.getZ() + 20)
     moveIval = Sequence(
         Func(
             suit.headsUp,
             self),
         Func(
             suit.pose,
             'landing',
             0),
         ProjectileInterval(
             suit,
             duration=flyingDur,
             startPos=chairPos,
             endPos=destPos,
             gravityMult=0.25),
         ActorInterval(
             suit,
             'landing'))
     if suit.prop is None:
         suit.prop = BattleProps.globalPropPool.getProp('propeller')
     propDur = suit.prop.getDuration('propeller')
     lastSpinFrame = 8
     fr = suit.prop.getFrameRate('propeller')
     spinTime = lastSpinFrame / fr
     openTime = (lastSpinFrame + 1) / fr
     suit.attachPropeller()
     propTrack = Parallel(
         SoundInterval(
             suit.propInSound,
             duration=flyingDur,
             node=suit),
         Sequence(
             ActorInterval(
                 suit.prop,
                 'propeller',
                 constrainedLoop=1,
                 duration=flyingDur + 1,
                 startTime=0.0,
                 endTime=spinTime),
             ActorInterval(
                 suit.prop,
                 'propeller',
                 duration=landingDur,
                 startTime=openTime),
             Func(
                 suit.detachPropeller)))
     result = Parallel(moveIval, propTrack)
     return result