예제 #1
0
class DistributedPartyDanceActivityBase(DistributedPartyActivity):
    notify = directNotify.newCategory('DistributedPartyDanceActivity')

    def __init__(self,
                 cr,
                 actId,
                 dancePatternToAnims,
                 model='phase_13/models/parties/danceFloor'):
        DistributedPartyActivity.__init__(self, cr, actId,
                                          ActivityTypes.Continuous)
        self.model = model
        self.danceFloor = None
        self.localToonDancing = False
        self.keyCodes = None
        self.gui = None
        self.currentCameraMode = None
        self.orthoWalk = None
        self.cameraParallel = None
        self.localToonDanceSequence = None
        self.localPatternsMatched = []
        self.dancePatternToAnims = dancePatternToAnims
        self.dancingToonFSMs = {}
        return

    def generateInit(self):
        self.notify.debug('generateInit')
        DistributedPartyActivity.generateInit(self)
        self.keyCodes = KeyCodes(patterns=self.dancePatternToAnims.keys())
        self.gui = KeyCodesGui(self.keyCodes)
        self.__initOrthoWalk()
        self.activityFSM = DanceActivityFSM(self)

    def announceGenerate(self):
        DistributedPartyActivity.announceGenerate(self)
        self.activityFSM.request('Active')

    def load(self):
        DistributedPartyActivity.load(self)
        self.danceFloor = loader.loadModel(self.model)
        self.danceFloor.reparentTo(self.getParentNodePath())
        self.danceFloor.setPos(self.x, self.y, 0.0)
        self.danceFloor.setH(self.h)
        self.danceFloor.wrtReparentTo(render)
        self.sign.setPos(22, -22, 0)
        floor = self.danceFloor.find('**/danceFloor_mesh')
        self.danceFloorSequence = Sequence(Wait(0.3),
                                           Func(floor.setH, floor, 36))
        discoBall = self.danceFloor.find('**/discoBall_mesh')
        self.discoBallSequence = Parallel(
            discoBall.hprInterval(6.0, Vec3(360, 0, 0)),
            Sequence(
                discoBall.posInterval(3,
                                      Point3(0, 0, 1),
                                      blendType='easeInOut'),
                discoBall.posInterval(3,
                                      Point3(0, 0, 0),
                                      blendType='easeInOut')))

    def unload(self):
        DistributedPartyActivity.unload(self)
        self.activityFSM.request('Disabled')
        if self.localToonDanceSequence is not None:
            self.localToonDanceSequence.finish()
        if self.localToonDancing:
            self.__localStopDancing()
        self.ignoreAll()
        if self.discoBallSequence is not None:
            self.discoBallSequence.finish()
        if self.danceFloorSequence is not None:
            self.danceFloorSequence.finish()
        del self.danceFloorSequence
        del self.discoBallSequence
        del self.localToonDanceSequence
        if self.danceFloor is not None:
            self.danceFloor.removeNode()
            self.danceFloor = None
        self.__destroyOrthoWalk()
        for toonId in self.dancingToonFSMs.keys():
            self.dancingToonFSMs[toonId].destroy()
            del self.dancingToonFSMs[toonId]

        del self.dancingToonFSMs
        del self.cameraParallel
        del self.currentCameraMode
        if self.keyCodes is not None:
            self.keyCodes.destroy()
            del self.keyCodes
        del self.activityFSM
        del self.gui
        del self.localPatternsMatched
        return

    def handleToonDisabled(self, toonId):
        self.notify.debug('handleToonDisabled avatar ' + str(toonId) +
                          ' disabled')
        if toonId in self.dancingToonFSMs:
            self.dancingToonFSMs[toonId].request('cleanup')
            self.dancingToonFSMs[toonId].destroy()
            del self.dancingToonFSMs[toonId]

    def getTitle(self):
        self.notify.warning('define title for this dance activity')
        return TTLocalizer.PartyDanceActivityTitle

    def getInstructions(self):
        self.notify.warning('define instructions for this dance activity')
        return TTLocalizer.PartyDanceActivityInstructions

    def startActive(self):
        self.accept('enter' + DANCE_FLOOR_COLLISION,
                    self.__handleEnterDanceFloor)
        self.accept('exit' + DANCE_FLOOR_COLLISION,
                    self.__handleExitDanceFloor)
        self.danceFloorSequence.loop()
        self.discoBallSequence.loop()

    def finishActive(self):
        pass

    def startDisabled(self):
        self.ignore('enter' + DANCE_FLOOR_COLLISION)
        self.ignore('exit' + DANCE_FLOOR_COLLISION)
        self.discoBallSequence.pause()
        self.danceFloorSequence.pause()

    def finishDisabled(self):
        pass

    def __initOrthoWalk(self):
        self.notify.debug('Initialize Ortho Walk')
        orthoDrive = OrthoDrive(9.778)
        self.orthoWalk = OrthoWalk(orthoDrive, broadcast=True)

    def __destroyOrthoWalk(self):
        self.notify.debug('Destroy Ortho Walk')
        self.orthoWalk.stop()
        self.orthoWalk.destroy()
        del self.orthoWalk

    def __disableLocalControl(self):
        self.orthoWalk.stop()
        self.keyCodes.disable()
        self.keyCodesGui.disable()

    def __enableLocalControl(self):
        self.orthWalk.start()
        self.keyCodes.enable()
        self.keyCodesGui.enable()
        self.keyCodesGui.hideAll()

    def __handleEnterDanceFloor(self, collEntry):
        if not self.isLocalToonInActivity() and not self.localToonDancing:
            self.notify.debug('Toon enters dance floor collision area.')
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, 'fsm'):
                place.fsm.request('activity')
            self.d_toonJoinRequest()
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, 'fsm'):
                place.fsm.request('activity')

    def joinRequestDenied(self, reason):
        DistributedPartyActivity.joinRequestDenied(self, reason)
        self.showMessage(TTLocalizer.PartyActivityDefaultJoinDeny)
        place = base.cr.playGame.getPlace()
        if place and hasattr(place, 'fsm'):
            place.fsm.request('walk')

    def setToonsPlaying(self, toonIds, toonHeadings):
        self.notify.debug('setToonsPlaying')
        self.notify.debug('\ttoonIds: %s' % toonIds)
        self.notify.debug('\ttoonHeadings: %s' % toonHeadings)
        exitedToons, joinedToons = self.getToonsPlayingChanges(
            self.toonIds, toonIds)
        self.notify.debug('\texitedToons: %s' % exitedToons)
        self.notify.debug('\tjoinedToons: %s' % joinedToons)
        self.setToonIds(toonIds)
        self._processExitedToons(exitedToons)
        for toonId in joinedToons:
            if toonId != base.localAvatar.doId or toonId == base.localAvatar.doId and self.isLocalToonRequestStatus(
                    PartyGlobals.ActivityRequestStatus.Joining):
                self._enableHandleToonDisabled(toonId)
                self.handleToonJoined(toonId,
                                      toonHeadings[toonIds.index(toonId)])
                if toonId == base.localAvatar.doId:
                    self._localToonRequestStatus = None

        return

    def handleToonJoined(self, toonId, h):
        self.notify.debug('handleToonJoined( toonId=%d, h=%.2f )' %
                          (toonId, h))
        if toonId in base.cr.doId2do:
            toonFSM = PartyDanceActivityToonFSM(toonId, self, h)
            toonFSM.request('Init')
            self.dancingToonFSMs[toonId] = toonFSM
            if toonId == base.localAvatar.doId:
                self.__localStartDancing(h)

    def __localStartDancing(self, h):
        if not self.localToonDancing:
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, 'fsm'):
                self.localToonDancing = True
                place.fsm.request('activity')
                self.__updateLocalToonState(ToonDancingStates.Run)
                self.__setViewMode(DanceViews.Dancing)
                self.gui.load()
                self.startRules()
                self.__localEnableControls()
            else:
                self.notify.warning(
                    '__localStartDancing, failed in playGame.getPlace()')

    def handleRulesDone(self):
        self.finishRules()

    def __localEnableControls(self):
        if base.localAvatar.doId not in self.dancingToonFSMs:
            self.notify.debug(
                'no dancing FSM for local avatar, not enabling controls')
            return
        self.accept(KeyCodes.PATTERN_MATCH_EVENT, self.__doDanceMove)
        self.accept(KeyCodes.PATTERN_NO_MATCH_EVENT, self.__noDanceMoveMatch)
        self.acceptOnce(KeyCodes.KEY_DOWN_EVENT, self._handleKeyDown)
        self.accept(KeyCodes.KEY_UP_EVENT, self._handleKeyUp)
        self.keyCodes.enable()
        self.orthoWalk.start()
        self.gui.enable()
        self.gui.hideAll()

    def __localDisableControls(self):
        self.orthoWalk.stop()
        self.keyCodes.disable()
        self.gui.disable()
        self.ignore(KeyCodes.PATTERN_MATCH_EVENT)
        self.ignore(KeyCodes.PATTERN_NO_MATCH_EVENT)
        self.ignore(KeyCodes.KEY_DOWN_EVENT)
        self.ignore(KeyCodes.KEY_UP_EVENT)

    def __handleExitDanceFloor(self, collEntry):
        if self.localToonDanceSequence is not None:
            self.notify.debug('finishing %s' % self.localToonDanceSequence)
            self.localToonDanceSequence.finish()
            self.localToonDanceSequence = None
        self.finishRules()
        self.notify.debug('Toon exits dance floor collision area.')
        self.d_toonExitRequest()
        return

    def exitRequestDenied(self, reason):
        DistributedPartyActivity.exitRequestDenied(self, reason)
        if reason != PartyGlobals.DenialReasons.SilentFail:
            self.showMessage(TTLocalizer.PartyActivityDefaultExitDeny)

    def handleToonExited(self, toonId):
        self.notify.debug('exitDanceFloor %s' % toonId)
        if toonId == base.localAvatar.doId:
            self.__localStopDancing()

    def __localStopDancing(self):
        if self.localToonDancing:
            self.__localDisableControls()
            self.gui.unload()
            self.__setViewMode(DanceViews.Normal)
            self.__updateLocalToonState(ToonDancingStates.Cleanup)
            if base.cr.playGame.getPlace():
                if hasattr(base.cr.playGame.getPlace(), 'fsm'):
                    base.cr.playGame.getPlace().fsm.request('walk')
            self.localToonDancing = False

    def __doDanceMove(self, pattern):
        self.notify.debug('Dance move! %s' % pattern)
        anim = self.dancePatternToAnims.get(pattern)
        if anim:
            self.__updateLocalToonState(ToonDancingStates.DanceMove, anim)
            self.gui.setColor(0, 1, 0)
            self.gui.showText(DanceAnimToName.get(anim, anim))
            self.finishRules()
            if pattern not in self.localPatternsMatched:
                camNode = NodePath(self.uniqueName('danceCamNode'))
                camNode.reparentTo(base.localAvatar)
                camNode.lookAt(camera)
                camNode.setHpr(camNode.getH(), 0, 0)
                node2 = NodePath('tempCamNode')
                node2.reparentTo(camNode)
                node2.setPos(Point3(0, 15, 10))
                node2.lookAt(camNode)
                h = node2.getH() * (camera.getH(camNode) /
                                    abs(camera.getH(camNode)))
                node2.removeNode
                del node2
                hpr = camera.getHpr()
                pos = camera.getPos()
                camParent = camera.getParent()
                camera.wrtReparentTo(camNode)
                self.localToonDanceSequence = Sequence(
                    Func(self.__localDisableControls),
                    Parallel(
                        camera.posInterval(0.5,
                                           Point3(0, 15, 10),
                                           blendType='easeIn'),
                        camera.hprInterval(0.5,
                                           Point3(h, -20, 0),
                                           blendType='easeIn')),
                    camNode.hprInterval(4.0, Point3(camNode.getH() - 360, 0,
                                                    0)),
                    Func(camera.wrtReparentTo, camParent),
                    Func(camNode.removeNode),
                    Parallel(camera.posInterval(0.5, pos, blendType='easeOut'),
                             camera.hprInterval(0.5, hpr,
                                                blendType='easeOut')),
                    Func(self.__localEnableControls))
            else:
                self.localToonDanceSequence = Sequence(
                    Func(self.__localDisableControls), Wait(2.0),
                    Func(self.__localEnableControls))
            self.localToonDanceSequence.start()
            self.localPatternsMatched.append(pattern)

    def __noDanceMoveMatch(self):
        self.gui.setColor(1, 0, 0)
        self.gui.showText('No Match!')
        self.__updateLocalToonState(ToonDancingStates.DanceMove)
        self.localToonDanceSequence = Sequence(
            Func(self.__localDisableControls), Wait(1.0),
            Func(self.__localEnableControls))
        self.localToonDanceSequence.start()

    def _handleKeyDown(self, key, index):
        self.__updateLocalToonState(ToonDancingStates.Run)

    def _handleKeyUp(self, key):
        if not self.keyCodes.isAnyKeyPressed():
            self.__updateLocalToonState(ToonDancingStates.DanceMove)
            self.acceptOnce(KeyCodes.KEY_DOWN_EVENT, self._handleKeyDown)

    def __updateLocalToonState(self, state, anim=''):
        self._requestToonState(base.localAvatar.doId, state, anim)
        self.d_updateDancingToon(state, anim)

    def d_updateDancingToon(self, state, anim):
        self.sendUpdate('updateDancingToon', [state, anim])

    def setDancingToonState(self, toonId, state, anim):
        if toonId != base.localAvatar.doId and toonId in self.dancingToonFSMs:
            self._requestToonState(toonId, state, anim)

    def _requestToonState(self, toonId, state, anim):
        if toonId in self.dancingToonFSMs:
            state = ToonDancingStates.getString(state)
            curState = self.dancingToonFSMs[toonId].getCurrentOrNextState()
            try:
                self.dancingToonFSMs[toonId].request(state, anim)
            except FSM.RequestDenied:
                self.notify.warning('could not go from state=%s to state %s' %
                                    (curState, state))

            if state == ToonDancingStates.getString(ToonDancingStates.Cleanup):
                self.notify.debug('deleting this fsm %s' %
                                  self.dancingToonFSMs[toonId])
                del self.dancingToonFSMs[toonId]
                if self.localToonDanceSequence:
                    self.notify.debug(
                        'forcing a finish of localToonDanceSequence')
                    self.localToonDanceSequence.finish()
                    self.localToonDanceSequence = None
        return

    def __setViewMode(self, mode):
        toon = base.localAvatar
        if mode == DanceViews.Normal:
            if self.cameraParallel is not None:
                self.cameraParallel.pause()
                self.cameraParallel = None
            camera.reparentTo(toon)
            base.localAvatar.startUpdateSmartCamera()
        elif mode == DanceViews.Dancing:
            base.localAvatar.stopUpdateSmartCamera()
            camera.wrtReparentTo(self.danceFloor)
            node = NodePath('temp')
            node.reparentTo(toon.getParent())
            node.setPos(Point3(0, -40, 20))
            node2 = NodePath('temp2')
            node2.reparentTo(self.danceFloor)
            node.reparentTo(node2)
            node2.setH(render, toon.getParent().getH())
            pos = node.getPos(self.danceFloor)
            node2.removeNode()
            node.removeNode()
            self.cameraParallel = Parallel(
                camera.posInterval(0.5, pos, blendType='easeIn'),
                camera.hprInterval(0.5,
                                   Point3(0, -27, 0),
                                   other=toon.getParent(),
                                   blendType='easeIn'))
            self.cameraParallel.start()
        self.currentCameraMode = mode
        return
예제 #2
0
class DistributedPartyDanceActivityBase(DistributedPartyActivity):
    notify = directNotify.newCategory("DistributedPartyDanceActivity")

    def __init__(self, cr, actId, dancePatternToAnims):
        DistributedPartyActivity.__init__(self, cr, actId,
                                          ActivityTypes.Continuous)
        self.danceFloor = None

        self.localToonDancing = False
        self.keyCodes = None
        self.gui = None
        self.currentCameraMode = None
        self.orthoWalk = None
        self.cameraParallel = None
        self.localToonDanceSequence = None
        self.localPatternsMatched = []
        self.dancePatternToAnims = dancePatternToAnims
        # Map of toonIds to PartyDanceActivityToonFSMs
        self.dancingToonFSMs = {}

    def generateInit(self):
        self.notify.debug("generateInit")
        DistributedPartyActivity.generateInit(self)

        self.keyCodes = KeyCodes(
            patterns=list(self.dancePatternToAnims.keys()))
        self.gui = KeyCodesGui(self.keyCodes)
        self.__initOrthoWalk()
        self.activityFSM = DanceActivityFSM(self)

    def announceGenerate(self):
        DistributedPartyActivity.announceGenerate(self)
        self.activityFSM.request("Active")

    def load(self):
        """
        Loads the dance floor and place it in the right spot.
        """
        DistributedPartyActivity.load(self)

        self.danceFloor = loader.loadModel(
            "phase_13/models/parties/danceFloor")
        self.danceFloor.reparentTo(self.getParentNodePath())
        self.danceFloor.setPos(self.x, self.y, 0.0)
        self.danceFloor.setH(self.h)

        # Reparent to render so that when the fireworks are on, it "glows" in the dark
        self.danceFloor.wrtReparentTo(render)

        self.sign.setPos(22, -22, 0)

        # Initialize programatic animation sequences
        floor = self.danceFloor.find("**/danceFloor_mesh")
        self.danceFloorSequence = Sequence(Wait(0.3),
                                           Func(floor.setH, floor, 36))

        # Spin the ball around while bobbing up and down
        # (since it's being held by balloons!)
        # spinning the disco ball moved to the child classes,
        # to deal with 10 and 20 on the ball
        discoBall = self.danceFloor.find("**/discoBall_mesh")
        self.discoBallSequence = Parallel(
            discoBall.hprInterval(6.0, Vec3(360, 0, 0)),
            Sequence(
                discoBall.posInterval(3,
                                      Point3(0, 0, 1),
                                      blendType="easeInOut"),
                discoBall.posInterval(3,
                                      Point3(0, 0, 0),
                                      blendType="easeInOut")),
        )

    def unload(self):
        """
        Unloads the dance floor.
        """
        DistributedPartyActivity.unload(self)
        self.activityFSM.request("Disabled")

        if self.localToonDanceSequence is not None:
            self.localToonDanceSequence.finish()

        if self.localToonDancing:
            self.__localStopDancing()

        self.ignoreAll()

        if self.discoBallSequence is not None:
            self.discoBallSequence.finish()

        if self.danceFloorSequence is not None:
            self.danceFloorSequence.finish()

        del self.danceFloorSequence
        del self.discoBallSequence
        del self.localToonDanceSequence

        if self.danceFloor is not None:
            self.danceFloor.removeNode()
            self.danceFloor = None

        self.__destroyOrthoWalk()

        for toonId in list(self.dancingToonFSMs.keys()):
            self.dancingToonFSMs[toonId].destroy()
            del self.dancingToonFSMs[toonId]
        del self.dancingToonFSMs

        del self.cameraParallel
        del self.currentCameraMode

        if self.keyCodes is not None:
            self.keyCodes.destroy()
            del self.keyCodes

        del self.activityFSM
        del self.gui

        del self.localPatternsMatched

    def handleToonDisabled(self, toonId):
        """This will be called if an avatar exits unexpectedly"""
        self.notify.debug("handleToonDisabled avatar " + str(toonId) +
                          " disabled")
        # clean up any references to the disabled avatar before he disappears
        if toonId in self.dancingToonFSMs:
            self.dancingToonFSMs[toonId].request("cleanup")
            self.dancingToonFSMs[toonId].destroy()
            del self.dancingToonFSMs[toonId]

    def getTitle(self):
        self.notify.warning("define title for this dance activity")
        return TTLocalizer.PartyDanceActivityTitle

    def getInstructions(self):
        self.notify.warning("define instructions for this dance activity")
        return TTLocalizer.PartyDanceActivityInstructions

#===============================================================================
# FSM States
#===============================================================================

    def startActive(self):
        self.accept('enter' + DANCE_FLOOR_COLLISION,
                    self.__handleEnterDanceFloor)
        self.accept('exit' + DANCE_FLOOR_COLLISION,
                    self.__handleExitDanceFloor)

        self.danceFloorSequence.loop()
        self.discoBallSequence.loop()

    def finishActive(self):
        pass

    def startDisabled(self):
        self.ignore('enter' + DANCE_FLOOR_COLLISION)
        self.ignore('exit' + DANCE_FLOOR_COLLISION)
        self.discoBallSequence.pause()
        self.danceFloorSequence.pause()

    def finishDisabled(self):
        pass

#===============================================================================
# Ortho movement
#===============================================================================

# Orthowalk init/shutdown

    def __initOrthoWalk(self):
        """
        Initializes ortho walk movement for the local toon.
        Orthowalk is movement where up is +y and right is +x in relation to the toon's parent
        """
        self.notify.debug("Initialize Ortho Walk")

        orthoDrive = OrthoDrive(
            9.778
        )  # run speed = run frames (15) / fps (24fps) * avg. run speed (14.667 ft./s)
        self.orthoWalk = OrthoWalk(orthoDrive, broadcast=True)

    def __destroyOrthoWalk(self):
        self.notify.debug("Destroy Ortho Walk")
        self.orthoWalk.stop()
        self.orthoWalk.destroy()
        del self.orthoWalk

    def __disableLocalControl(self):
        self.orthoWalk.stop()
        self.keyCodes.disable()
        self.keyCodesGui.disable()

    def __enableLocalControl(self):
        self.orthWalk.start()
        self.keyCodes.enable()
        self.keyCodesGui.enable()
        self.keyCodesGui.hideAll()

#===============================================================================
# Enter / Exit Dance Floor
#===============================================================================

    def __handleEnterDanceFloor(self, collEntry):
        """
        Triggered when the local toon enters the dance floor collision.
        """
        if not self.isLocalToonInActivity() and not self.localToonDancing:
            self.notify.debug("Toon enters dance floor collision area.")
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, "fsm"):
                place.fsm.request("activity")
            self.d_toonJoinRequest()
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, "fsm"):
                place.fsm.request("activity")

    def joinRequestDenied(self, reason):
        DistributedPartyActivity.joinRequestDenied(self, reason)

        self.showMessage(TTLocalizer.PartyActivityDefaultJoinDeny)
        place = base.cr.playGame.getPlace()
        if place and hasattr(place, "fsm"):
            place.fsm.request("walk")

    # Distributed (broadcast ram)
    def setToonsPlaying(self, toonIds, toonHeadings):
        """
        Overrides DistributedPartyActivity's setToonsPlaying because it needs
        heading information for each toon.
        """
        self.notify.debug("setToonsPlaying")
        self.notify.debug("\ttoonIds: %s" % toonIds)
        self.notify.debug("\ttoonHeadings: %s" % toonHeadings)

        (exitedToons,
         joinedToons) = self.getToonsPlayingChanges(self.toonIds, toonIds)
        self.notify.debug("\texitedToons: %s" % exitedToons)
        self.notify.debug("\tjoinedToons: %s" % joinedToons)

        self.setToonIds(toonIds)
        self._processExitedToons(exitedToons)

        # Handle the joining toons
        for toonId in joinedToons:

            # Only trigger handleToonJoined if it isn't the local Toon
            # or if the local Toon is joining this activity.
            if (toonId != base.localAvatar.doId
                    or (toonId == base.localAvatar.doId
                        and self.isLocalToonRequestStatus(
                            PartyGlobals.ActivityRequestStatus.Joining))):

                self._enableHandleToonDisabled(toonId)
                self.handleToonJoined(toonId,
                                      toonHeadings[toonIds.index(toonId)])

                if toonId == base.localAvatar.doId:
                    self._localToonRequestStatus = None

    def handleToonJoined(self, toonId, h):
        """
        Called when toon is allowed to enter dance floor.
        """
        self.notify.debug("handleToonJoined( toonId=%d, h=%.2f )" %
                          (toonId, h))
        if toonId in base.cr.doId2do:
            toonFSM = PartyDanceActivityToonFSM(toonId, self, h)
            toonFSM.request("Init")
            self.dancingToonFSMs[toonId] = toonFSM

            if toonId == base.localAvatar.doId:
                self.__localStartDancing(h)

    def __localStartDancing(self, h):
        """
        Local toon is entering dance floor. Listen for extra events and enable
        ortho movement.
        """
        if not self.localToonDancing:
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, "fsm"):
                self.localToonDancing = True
                place.fsm.request("activity")
                self.__updateLocalToonState(ToonDancingStates.Run)
                self.__setViewMode(DanceViews.Dancing)
                self.gui.load()

                self.startRules()
                self.__localEnableControls()
            else:
                self.notify.warning(
                    "__localStartDancing, failed in playGame.getPlace()")

    def handleRulesDone(self):
        self.finishRules()

    def __localEnableControls(self):
        if base.localAvatar.doId not in self.dancingToonFSMs:
            self.notify.debug(
                "no dancing FSM for local avatar, not enabling controls")
            return
        self.accept(KeyCodes.PATTERN_MATCH_EVENT, self.__doDanceMove)
        self.accept(KeyCodes.PATTERN_NO_MATCH_EVENT, self.__noDanceMoveMatch)
        self.acceptOnce(KeyCodes.KEY_DOWN_EVENT, self._handleKeyDown)
        self.accept(KeyCodes.KEY_UP_EVENT, self._handleKeyUp)

        self.keyCodes.enable()
        self.orthoWalk.start()
        self.gui.enable()
        self.gui.hideAll()

    def __localDisableControls(self):
        self.orthoWalk.stop()
        self.keyCodes.disable()
        self.gui.disable()

        self.ignore(KeyCodes.PATTERN_MATCH_EVENT)
        self.ignore(KeyCodes.PATTERN_NO_MATCH_EVENT)
        self.ignore(KeyCodes.KEY_DOWN_EVENT)
        self.ignore(KeyCodes.KEY_UP_EVENT)

    def __handleExitDanceFloor(self, collEntry):
        """
        Triggered when the local toon exits the dance floor collision.
        """
        if self.localToonDanceSequence is not None:
            self.notify.debug("finishing %s" % self.localToonDanceSequence)
            self.localToonDanceSequence.finish()
            self.localToonDanceSequence = None
        self.finishRules()
        self.notify.debug("Toon exits dance floor collision area.")
        self.d_toonExitRequest()

    def exitRequestDenied(self, reason):
        DistributedPartyActivity.exitRequestDenied(self, reason)
        if reason != PartyGlobals.DenialReasons.SilentFail:
            self.showMessage(TTLocalizer.PartyActivityDefaultExitDeny)

    def handleToonExited(self, toonId):
        """
        Stops the local toon from dancing.
        Called when when the client gets an exit response from the server.
        """
        self.notify.debug("exitDanceFloor %s" % toonId)
        if toonId == base.localAvatar.doId:
            self.__localStopDancing()

    def __localStopDancing(self):
        """
        Cleans up local dancing toon and broadcasts final state to all clients
        """
        if self.localToonDancing:
            self.__localDisableControls()
            self.gui.unload()
            self.__setViewMode(DanceViews.Normal)

            self.__updateLocalToonState(ToonDancingStates.Cleanup)
            if base.cr.playGame.getPlace():
                if hasattr(base.cr.playGame.getPlace(), 'fsm'):
                    base.cr.playGame.getPlace().fsm.request("walk")
            self.localToonDancing = False

#===============================================================================
# Dance!
#===============================================================================

    def __doDanceMove(self, pattern):
        """
        Handler called when there is a pattern match
        """
        self.notify.debug("Dance move! %s" % pattern)

        anim = self.dancePatternToAnims.get(pattern)
        if anim:
            self.__updateLocalToonState(ToonDancingStates.DanceMove, anim)

            self.gui.setColor(0, 1, 0)
            self.gui.showText(DanceAnimToName.get(anim, anim))

            # Local toon just matched this pattern for the first time
            # play fancier animation.
            self.finishRules()
            if pattern not in self.localPatternsMatched:
                camNode = NodePath(self.uniqueName("danceCamNode"))
                camNode.reparentTo(base.localAvatar)
                camNode.lookAt(camera)
                camNode.setHpr(camNode.getH(), 0, 0)

                node2 = NodePath("tempCamNode")
                node2.reparentTo(camNode)
                node2.setPos(Point3(0, 15, 10))
                node2.lookAt(camNode)
                h = node2.getH() * (camera.getH(camNode) /
                                    abs(camera.getH(camNode)))
                node2.removeNode
                del node2

                hpr = camera.getHpr()
                pos = camera.getPos()
                camParent = camera.getParent()

                camera.wrtReparentTo(camNode)
                self.localToonDanceSequence = Sequence(
                    Func(self.__localDisableControls),
                    Parallel(
                        camera.posInterval(0.5,
                                           Point3(0, 15, 10),
                                           blendType="easeIn"),
                        camera.hprInterval(0.5,
                                           Point3(h, -20, 0),
                                           blendType="easeIn"),
                    ),
                    camNode.hprInterval(4.0, Point3(camNode.getH() - 360, 0,
                                                    0)),
                    Func(camera.wrtReparentTo, camParent),
                    Func(camNode.removeNode),
                    Parallel(camera.posInterval(0.5, pos, blendType="easeOut"),
                             camera.hprInterval(0.5, hpr,
                                                blendType="easeOut")),
                    Func(self.__localEnableControls))
            else:
                self.localToonDanceSequence = Sequence(
                    Func(self.__localDisableControls),
                    Wait(2.0),
                    Func(self.__localEnableControls),
                )

            self.localToonDanceSequence.start()
            self.localPatternsMatched.append(pattern)

    def __noDanceMoveMatch(self):
        """
        Called when a match fails.
        """
        self.gui.setColor(1, 0, 0)
        self.gui.showText("No Match!")

        self.__updateLocalToonState(ToonDancingStates.DanceMove)
        self.localToonDanceSequence = Sequence(
            Func(self.__localDisableControls),
            Wait(1.0),
            Func(self.__localEnableControls),
        )

        self.localToonDanceSequence.start()

    def _handleKeyDown(self, key, index):
        """
        Called when a key in KeyCodes is pressed down.
        """
        self.__updateLocalToonState(ToonDancingStates.Run)

    def _handleKeyUp(self, key):
        """
        Called when a key in KeyCodes is pressed up.
        """
        if not self.keyCodes.isAnyKeyPressed():
            self.__updateLocalToonState(ToonDancingStates.DanceMove)
            self.acceptOnce(KeyCodes.KEY_DOWN_EVENT, self._handleKeyDown)

#===============================================================================
# Dancing Toon State
#===============================================================================

    def __updateLocalToonState(self, state, anim=""):
        """
        Sets the dancing toon's local and remote fsm. This is done immediately
        in the local side, while the state is sent to the AI for the other clients.
        """
        self._requestToonState(base.localAvatar.doId, state, anim)
        self.d_updateDancingToon(state, anim)

    # Distributed (clsend airecv)
    def d_updateDancingToon(self, state, anim):
        self.sendUpdate("updateDancingToon", [state, anim])

    # Distributed (broadcast ram)
    def setDancingToonState(self, toonId, state, anim):
        """
        From AI, it sets a dancing toon's FSM
        """
        if toonId != base.localAvatar.doId and toonId in self.dancingToonFSMs:
            self._requestToonState(toonId, state, anim)

    def _requestToonState(self, toonId, state, anim):
        if toonId in self.dancingToonFSMs:
            state = ToonDancingStates.getString(state)
            curState = self.dancingToonFSMs[toonId].getCurrentOrNextState()
            assert (self.notify.debug(
                "requestToonState toonId=%s, state=%s, anim=%s" %
                (toonId, state, anim)))
            try:
                self.dancingToonFSMs[toonId].request(state, anim)
            except FSM.RequestDenied:
                self.notify.warning("could not go from state=%s to state %s" %
                                    (curState, state))
            if state == ToonDancingStates.getString(ToonDancingStates.Cleanup):
                self.notify.debug("deleting this fsm %s" %
                                  (self.dancingToonFSMs[toonId]))
                del self.dancingToonFSMs[toonId]
                # the local Toon dance sequence has camera reparents, which is bad if
                # we're not in the dance floor anymore.
                if self.localToonDanceSequence:
                    self.notify.debug(
                        "forcing a finish of localToonDanceSequence")
                    self.localToonDanceSequence.finish()
                    self.localToonDanceSequence = None

#===============================================================================
# Camera
#===============================================================================

    def __setViewMode(self, mode):
        """
        Changes the camera mode and controls according to the camera.
        Called typically when toon enters/exits the dance floor.
        """
        assert (self.notify.debug("Set camera mode to %d" % mode))
        toon = base.localAvatar

        if mode == DanceViews.Normal:
            """
            if self.currentCameraMode == DanceViews.Isometric:
                base.cam.node().setLens(self.clens)
            """

            if self.cameraParallel is not None:
                self.cameraParallel.pause()
                self.cameraParallel = None

            camera.reparentTo(toon)
            base.localAvatar.startUpdateSmartCamera()

        elif mode == DanceViews.Dancing:
            base.localAvatar.stopUpdateSmartCamera()
            camera.wrtReparentTo(self.danceFloor)

            # Get the destination of the camera
            # based on the orientation of the toon parent dance node.
            node = NodePath("temp")
            node.reparentTo(toon.getParent())
            node.setPos(Point3(0, -40, 20))

            node2 = NodePath("temp2")
            node2.reparentTo(self.danceFloor)
            node.reparentTo(node2)
            node2.setH(render, toon.getParent().getH())
            pos = node.getPos(self.danceFloor)

            node2.removeNode()
            node.removeNode()

            self.cameraParallel = Parallel(
                camera.posInterval(0.5, pos, blendType="easeIn"),
                camera.hprInterval(0.5,
                                   Point3(0, -27, 0),
                                   other=toon.getParent(),
                                   blendType="easeIn"))
            self.cameraParallel.start()
        """
        if mode == DanceViews.Isometric:
            if not hasattr(self, 'olens'):
                self.olens = OrthographicLens()
                self.olens.setFilmSize(20, 15)  # or whatever is appropriate for your scene
                self.clens = base.cam.node().getLens()
            base.cam.node().setLens(self.olens)

            def handleF1Pressed(self):
                if base.cam.node().getLens() == self.clens:
                    base.cam.node().setLens(self.olens)
                else:
                    base.cam.node().setLens(self.clens)
            self.accept('f1', handleF1Pressed)
        """

        self.currentCameraMode = mode
예제 #3
0
class CogdoFlyingLocalPlayer(CogdoFlyingPlayer):
    def __init__(self, game, toon):
        CogdoFlyingPlayer.__init__(self, toon)
        self.velocity = Vec3(0.0, 0.0, 0.0)
        self.lastVelocity = Vec3(0.0, 0.0, 0.0)
        self.instantaneousVelocity = Vec3(0.0, 0.0, 0.0)
        self.oldPos = Vec3(0.0, 0.0, 0.0)
        self.game = game
        self.inputMgr = CogdoFlyingInputManager()
        self.cameraMgr = CogdoFlyingCameraManager(self, camera, render)
        self.guiMgr = CogdoFlyingGuiManager(self)

        self.checkpointPlatform = None

        self.fuel = 0.0
        self.props = {}

        self.initModels()
        self.initIntervals()

        self.propSound = base.loadSfx('phase_4/audio/sfx/TB_propeller.wav')

    def initModels(self):
        # We place the propeller prop on all 3 lod's
        self.placePropeller('1000')
        self.placePropeller('500')
        self.placePropeller('250')

    def placePropeller(self, lod):
        prop = BattleProps.globalPropPool.getProp('propeller')
        prop.setScale(1.1)

        self.props[lod] = prop

        head = base.localAvatar.getPart('head', lod)

        if head.isEmpty():
            return

        prop.reparentTo(head)
        animal = base.localAvatar.style.getAnimal()
        if (animal == 'dog') or (animal == 'bear') or (animal == 'horse'):
            torso = base.localAvatar.style.torso
            legs = base.localAvatar.style.legs
            if ((torso == 'ls') or (torso == 'ld')) and (legs == 'l'):
                prop.setZ(-1.3)
            else:
                prop.setZ(-0.7)
        elif (animal == 'mouse') or (animal == 'duck'):
            prop.setZ(0.5)
        elif (animal == 'cat'):
            prop.setZ(-0.3)
        elif (animal == 'rabbit'):
            prop.setZ(-0.5)
        elif (animal == 'monkey'):
            prop.setZ(0.3)
        elif (animal == 'pig'):
            prop.setZ(-0.7)

    def initIntervals(self):
        self.deathInterval = Sequence(
            Func(self.inputMgr.disable),
            Parallel(
                LerpHprInterval(self.toon, 1.0, Vec3(720, 0, 0)),
                LerpFunctionInterval(self.toon.setScale,
                                     fromData=1.0,
                                     toData=0.0,
                                     duration=1.0)),
            Func(self.resetToon),
            Wait(
                0.5
            ),  # Added this because with no pause here the FreeFly prop sound was attached to the old toon pos
            Func(self.request, "FreeFly"),
            name="%s.deathInterval" % (self.__class__.__name__))

        self.refuelInterval = Sequence(
            Func(self.guiMgr.setRefuelLerpFromData),
            Func(self.guiMgr.messageLabel.unstash),
            Parallel(
                self.guiMgr.refuelLerp,
                Sequence(
                    Func(self.guiMgr.setMessageLabelText, "Refueling"),
                    Wait(0.5),
                    Func(self.guiMgr.setMessageLabelText, "Refueling."),
                    Wait(0.5),
                    Func(self.guiMgr.setMessageLabelText, "Refueling.."),
                    Wait(0.5),
                    Func(self.guiMgr.setMessageLabelText, "Refueling..."),
                    Wait(0.5),
                ),
            ),
            Func(self.resetFuel),
            Func(self.guiMgr.messageLabel.stash),
            Func(self.request, "FreeFly"),
            name="%s.refuelInterval" % (self.__class__.__name__))

        self.waitingForWinInterval = Sequence(
            Func(self.guiMgr.setMessageLabelText, "Waiting for other players"),
            Wait(1.5),
            Func(self.guiMgr.setMessageLabelText,
                 "Waiting for other players."),
            Wait(1.5),
            Func(self.guiMgr.setMessageLabelText,
                 "Waiting for other players.."),
            Wait(1.5),
            Func(self.guiMgr.setMessageLabelText,
                 "Waiting for other players..."),
            Wait(1.5),
            name="%s.waitingForWinInterval" % (self.__class__.__name__))

        self.winInterval = Sequence(Func(self.guiMgr.setMessageLabelText, ""),
                                    Wait(1.0),
                                    Func(self.guiMgr.winLabel.unstash),
                                    Wait(2.0),
                                    Func(self.guiMgr.winLabel.stash),
                                    Wait(0.5),
                                    Func(messenger.send, "escape"),
                                    name="%s.waitingForWinInterval" %
                                    (self.__class__.__name__))

        self.slowPropTrack = Parallel(
            ActorInterval(self.props['1000'],
                          'propeller',
                          startFrame=8,
                          endFrame=23,
                          playRate=1.0),
            ActorInterval(self.props['500'],
                          'propeller',
                          startFrame=8,
                          endFrame=23,
                          playRate=1.0),
            ActorInterval(self.props['250'],
                          'propeller',
                          startFrame=8,
                          endFrame=23,
                          playRate=1.0),
        )
        self.fastPropTrack = Parallel(
            ActorInterval(self.props['1000'],
                          'propeller',
                          startFrame=8,
                          endFrame=23,
                          playRate=2.0),
            ActorInterval(self.props['500'],
                          'propeller',
                          startFrame=8,
                          endFrame=23,
                          playRate=2.0),
            ActorInterval(self.props['250'],
                          'propeller',
                          startFrame=8,
                          endFrame=23,
                          playRate=2.0),
        )

    def onstage(self):
        #        print "local player onstage"
        CogdoFlyingPlayer.onstage(self)
        self.toon.reparentTo(render)
        self.toon.hideName()
        self.toon.setSpeed(0, 0)
        #        self.toon.setAnimState('Happy',1.0)
        self.toon.loop('jump-idle')
        # When we had the toon in anim state swim we needed this so that the
        # player wasn't getting stuck to floors
        self.toon.controlManager.currentControls.setGravity(0)
        #        print "setting gravity to 0"
        self.resetToon()
        self.cameraMgr.enable()
        self.cameraMgr.update()

    def offstage(self):
        #print "local player offstage"
        CogdoFlyingPlayer.offstage(self)
        self.cameraMgr.disable()
        base.localAvatar.controlManager.currentControls.setGravity(32.174 *
                                                                   2.0)
        self.toon.showName()

        #self.unload()

    def unload(self):
        #        print "unloading CogdoFlyingLocalPlayer"
        self.toon.showName()
        CogdoFlyingPlayer.unload(self)

        self.checkpointPlatform = None

        self.cameraMgr.disable()
        del self.cameraMgr

        base.localAvatar.controlManager.currentControls.setGravity(32.174 *
                                                                   2.0)
        del self.game

        self.inputMgr.destroy()
        del self.inputMgr

        self.props['1000'].detachNode()
        self.props['500'].detachNode()
        self.props['250'].detachNode()
        self.props.clear()

        self.slowPropTrack.clearToInitial()
        del self.slowPropTrack

        self.fastPropTrack.clearToInitial()
        del self.fastPropTrack

        del self.propSound

        self.deathInterval.clearToInitial()
        del self.deathInterval

        self.refuelInterval.clearToInitial()
        del self.refuelInterval

        self.guiMgr.destroy()
        self.guiMgr = None

    def setCheckpointPlatform(self, platform):
        self.checkpointPlatform = platform

    def resetToon(self):
        #        print "Reset toon"
        #        print "------------------------"
        #        self.checkpointPlatform.ls()
        self.toon.setPos(
            render,
            self.checkpointPlatform.find("**/start_p1").getPos(render))
        self.toon.setHpr(render, 0, 0, 0)
        self.toon.setScale(1.0)
        #        self.toon.loop('jump-idle')
        self.toon.collisionsOn()
        #        self.toon.stopBobSwimTask()
        #        self.toon.getGeomNode().setZ(1.0)
        self.resetFuel()

    def resetFuel(self):
        self.fuel = CogdoFlyingGameGlobals.FlyingGame.FUEL_START_AMT

    def isFuelLeft(self):
        return self.fuel > 0.0

    def __updateToonMovement(self):
        # move the local toon
        dt = globalClock.getDt()
        leftPressed = self.inputMgr.arrowKeys.leftPressed()
        rightPressed = self.inputMgr.arrowKeys.rightPressed()
        upPressed = self.inputMgr.arrowKeys.upPressed()
        downPressed = self.inputMgr.arrowKeys.downPressed()
        jumpPressed = self.inputMgr.arrowKeys.jumpPressed()

        #        print leftPressed,rightPressed,upPressed,downPressed,jumpPressed
        self.instantaneousVelocity = (self.toon.getPos() - self.oldPos) / dt
        self.oldPos = self.toon.getPos()
        toonPos = self.toon.getPos()

        self.lastVelocity = Vec3(self.velocity)

        # Adds boost to velocity values and calculates toon pos changes
        if leftPressed:
            self.velocity[
                0] -= CogdoFlyingGameGlobals.FlyingGame.TOON_ACCELERATION[
                    "turning"] * dt
        if rightPressed:
            self.velocity[
                0] += CogdoFlyingGameGlobals.FlyingGame.TOON_ACCELERATION[
                    "turning"] * dt
        if upPressed:
            self.velocity[
                1] += CogdoFlyingGameGlobals.FlyingGame.TOON_ACCELERATION[
                    "forward"] * dt
        if downPressed:
            self.velocity[
                1] -= CogdoFlyingGameGlobals.FlyingGame.TOON_ACCELERATION[
                    "backward"] * dt

#        print jumpPressed
        if jumpPressed and self.isFuelLeft():
            self.velocity[
                2] += CogdoFlyingGameGlobals.FlyingGame.TOON_ACCELERATION[
                    "vertical"] * dt
            if self.state == "FreeFly" and self.isInTransition() == False:
                #print "Going to flying up"
                self.request("FlyingUp")
        else:
            if self.state == "FlyingUp" and self.isInTransition() == False:
                #print "Going to free fly"
                self.request("FreeFly")

        toonPos += self.velocity * dt

        # TODO:flying: death probably needs to happen on the server...
        if (CogdoFlyingGameGlobals.FlyingGame.DISABLE_DEATH) or \
           (base.config.GetBool('cogdo-flying-game-disable-death', 0)):
            pass
        else:
            # Tests to see whether the toon has dropped low enough to die
            if toonPos[2] < 0.0 and self.state in ["FreeFly", "FlyingUp"]:
                self.request("Death")

        toonPos[2] = clamp(toonPos[2], self.game.downLimit, self.game.upLimit)
        toonPos[0] = clamp(toonPos[0], self.game.leftLimit,
                           self.game.rightLimit)

        # Sets toon position based on velocity
        self.toon.setPos(toonPos)

        #print "Before degrades:",self.velocity

        # Degrades left/right velocity values back to normal
        minVal = -CogdoFlyingGameGlobals.FlyingGame.TOON_VEL_MAX["turning"]
        maxVal = CogdoFlyingGameGlobals.FlyingGame.TOON_VEL_MAX["turning"]
        if (not leftPressed
                and not rightPressed) or (self.velocity[0] > maxVal
                                          or self.velocity[0] < minVal):
            if self.velocity[0] > 0.0:
                self.velocity[
                    0] -= CogdoFlyingGameGlobals.FlyingGame.TOON_DECELERATION[
                        "turning"] * dt
                self.velocity[0] = clamp(self.velocity[0], 0.0, maxVal)
            elif self.velocity[0] < 0.0:
                self.velocity[
                    0] += CogdoFlyingGameGlobals.FlyingGame.TOON_DECELERATION[
                        "turning"] * dt
                self.velocity[0] = clamp(self.velocity[0], minVal, 0.0)

        # Degrades forward/backward velocity values back to normal
        minVal = -CogdoFlyingGameGlobals.FlyingGame.TOON_VEL_MAX["backward"]
        maxVal = CogdoFlyingGameGlobals.FlyingGame.TOON_VEL_MAX["forward"]
        if (not upPressed and not downPressed) or (self.velocity[1] > maxVal or
                                                   self.velocity[1] < minVal):
            if self.velocity[1] > 0.0:
                self.velocity[
                    1] -= CogdoFlyingGameGlobals.FlyingGame.TOON_DECELERATION[
                        "forward"] * dt
                self.velocity[1] = clamp(self.velocity[1], 0.0, maxVal)
            elif self.velocity[1] < 0.0:
                self.velocity[
                    1] += CogdoFlyingGameGlobals.FlyingGame.TOON_DECELERATION[
                        "backward"] * dt
                self.velocity[1] = clamp(self.velocity[1], minVal, 0.0)

        # Degrades boost/fall velocity values back to normal
        minVal = -CogdoFlyingGameGlobals.FlyingGame.TOON_VEL_MAX["vertical"]
        maxVal = CogdoFlyingGameGlobals.FlyingGame.TOON_VEL_MAX["vertical"]
        if self.velocity[2] > minVal:
            if not self.inputMgr.arrowKeys.jumpPressed():
                self.velocity[
                    2] -= CogdoFlyingGameGlobals.FlyingGame.TOON_DECELERATION[
                        "vertical"] * dt

            self.velocity[2] = clamp(self.velocity[2], minVal, maxVal)

        #print self.lastVelocity, self.velocity


#        if self.lastVelocity != self.velocity:
#            print "Velocity:",self.velocity

    def __updateFuel(self):
        dt = globalClock.getDt()

        if CogdoFlyingGameGlobals.FlyingGame.INFINITE_FUEL:
            self.fuel = CogdoFlyingGameGlobals.FlyingGame.FUEL_START_AMT
        else:
            if self.fuel > 0.0:
                self.fuel -= CogdoFlyingGameGlobals.FlyingGame.FUEL_BURN_RATE * dt
            elif self.fuel < 0.0:
                self.fuel = 0.0

    def update(self):
        if self.state not in ["Inactive", "Refuel", "WaitingForWin", "Win"]:
            self.__updateToonMovement()
            self.__updateFuel()
            self.cameraMgr.update()
            self.guiMgr.update()

    def enterInactive(self):
        CogdoFlyingPlayer.enterInactive(self)
        self.inputMgr.disable()

    def exitInactive(self):
        CogdoFlyingPlayer.exitInactive(self)
        self.inputMgr.enable()

    def enterRefuel(self):
        CogdoFlyingPlayer.enterInactive(self)
        self.inputMgr.disable()
        self.refuelInterval.start()

    def exitRefuel(self):
        CogdoFlyingPlayer.exitInactive(self)
        self.inputMgr.enable()

    def enterFreeFly(self):
        CogdoFlyingPlayer.enterFreeFly(self)
        self.slowPropTrack.loop()
        base.playSfx(self.propSound, node=self.toon, looping=1)
        self.propSound.setPlayRate(0.9)

    def exitFreeFly(self):
        CogdoFlyingPlayer.exitFreeFly(self)
        self.slowPropTrack.clearToInitial()
        self.propSound.stop()

    def enterFlyingUp(self):
        CogdoFlyingPlayer.enterFlyingUp(self)
        self.fastPropTrack.loop()
        base.playSfx(self.propSound, node=self.toon, looping=1)
        self.propSound.setPlayRate(1.1)

    def exitFlyingUp(self):
        CogdoFlyingPlayer.exitFlyingUp(self)
        self.fastPropTrack.clearToInitial()
        self.propSound.stop()

    def enterDeath(self):
        CogdoFlyingPlayer.enterDeath(self)
        self.inputMgr.disable()
        self.deathInterval.start()

    def exitDeath(self):
        CogdoFlyingPlayer.exitDeath(self)
        self.inputMgr.enable()

    def enterWaitingForWin(self):
        CogdoFlyingPlayer.enterDeath(self)
        self.inputMgr.disable()
        self.guiMgr.messageLabel.unstash()
        self.waitingForWinInterval.loop()

    def exitWaitingForWin(self):
        CogdoFlyingPlayer.exitDeath(self)
        self.waitingForWinInterval.clearToInitial()
        self.guiMgr.messageLabel.stash()
        self.inputMgr.enable()

    def enterWin(self):
        CogdoFlyingPlayer.enterDeath(self)
        self.inputMgr.disable()
        self.winInterval.start()

    def exitWin(self):
        CogdoFlyingPlayer.exitDeath(self)
        self.inputMgr.enable()
class DistributedPartyDanceActivityBase(DistributedPartyActivity):
    notify = directNotify.newCategory('DistributedPartyDanceActivity')

    def __init__(self, cr, actId, dancePatternToAnims, model = 'phase_13/models/parties/danceFloor'):
        DistributedPartyActivity.__init__(self, cr, actId, ActivityTypes.Continuous)
        self.model = model
        self.danceFloor = None
        self.localToonDancing = False
        self.keyCodes = None
        self.gui = None
        self.currentCameraMode = None
        self.orthoWalk = None
        self.cameraParallel = None
        self.localToonDanceSequence = None
        self.localPatternsMatched = []
        self.dancePatternToAnims = dancePatternToAnims
        self.dancingToonFSMs = {}
        return

    def generateInit(self):
        self.notify.debug('generateInit')
        DistributedPartyActivity.generateInit(self)
        self.keyCodes = KeyCodes(patterns=self.dancePatternToAnims.keys())
        self.gui = KeyCodesGui(self.keyCodes)
        self.__initOrthoWalk()
        self.activityFSM = DanceActivityFSM(self)

    def announceGenerate(self):
        DistributedPartyActivity.announceGenerate(self)
        self.activityFSM.request('Active')

    def load(self):
        DistributedPartyActivity.load(self)
        self.danceFloor = loader.loadModel(self.model)
        self.danceFloor.reparentTo(self.getParentNodePath())
        self.danceFloor.setPos(self.x, self.y, 0.0)
        self.danceFloor.setH(self.h)
        self.danceFloor.wrtReparentTo(render)
        self.sign.setPos(22, -22, 0)
        floor = self.danceFloor.find('**/danceFloor_mesh')
        self.danceFloorSequence = Sequence(Wait(0.3), Func(floor.setH, floor, 36))
        discoBall = self.danceFloor.find('**/discoBall_mesh')
        self.discoBallSequence = Parallel(discoBall.hprInterval(6.0, Vec3(360, 0, 0)), Sequence(discoBall.posInterval(3, Point3(0, 0, 1), blendType='easeInOut'), discoBall.posInterval(3, Point3(0, 0, 0), blendType='easeInOut')))

    def unload(self):
        DistributedPartyActivity.unload(self)
        self.activityFSM.request('Disabled')
        if self.localToonDanceSequence is not None:
            self.localToonDanceSequence.finish()
        if self.localToonDancing:
            self.__localStopDancing()
        self.ignoreAll()
        if self.discoBallSequence is not None:
            self.discoBallSequence.finish()
        if self.danceFloorSequence is not None:
            self.danceFloorSequence.finish()
        del self.danceFloorSequence
        del self.discoBallSequence
        del self.localToonDanceSequence
        if self.danceFloor is not None:
            self.danceFloor.removeNode()
            self.danceFloor = None
        self.__destroyOrthoWalk()
        for toonId in self.dancingToonFSMs.keys():
            self.dancingToonFSMs[toonId].destroy()
            del self.dancingToonFSMs[toonId]

        del self.dancingToonFSMs
        del self.cameraParallel
        del self.currentCameraMode
        if self.keyCodes is not None:
            self.keyCodes.destroy()
            del self.keyCodes
        del self.activityFSM
        del self.gui
        del self.localPatternsMatched
        return

    def handleToonDisabled(self, toonId):
        self.notify.debug('handleToonDisabled avatar ' + str(toonId) + ' disabled')
        if self.dancingToonFSMs.has_key(toonId):
            self.dancingToonFSMs[toonId].request('cleanup')
            self.dancingToonFSMs[toonId].destroy()
            del self.dancingToonFSMs[toonId]

    def getTitle(self):
        self.notify.warning('define title for this dance activity')
        return TTLocalizer.PartyDanceActivityTitle

    def getInstructions(self):
        self.notify.warning('define instructions for this dance activity')
        return TTLocalizer.PartyDanceActivityInstructions

    def startActive(self):
        self.accept('enter' + DANCE_FLOOR_COLLISION, self.__handleEnterDanceFloor)
        self.accept('exit' + DANCE_FLOOR_COLLISION, self.__handleExitDanceFloor)
        self.danceFloorSequence.loop()
        self.discoBallSequence.loop()

    def finishActive(self):
        pass

    def startDisabled(self):
        self.ignore('enter' + DANCE_FLOOR_COLLISION)
        self.ignore('exit' + DANCE_FLOOR_COLLISION)
        self.discoBallSequence.pause()
        self.danceFloorSequence.pause()

    def finishDisabled(self):
        pass

    def __initOrthoWalk(self):
        self.notify.debug('Initialize Ortho Walk')
        orthoDrive = OrthoDrive(9.778)
        self.orthoWalk = OrthoWalk(orthoDrive, broadcast=True)

    def __destroyOrthoWalk(self):
        self.notify.debug('Destroy Ortho Walk')
        self.orthoWalk.stop()
        self.orthoWalk.destroy()
        del self.orthoWalk

    def __disableLocalControl(self):
        self.orthoWalk.stop()
        self.keyCodes.disable()
        self.keyCodesGui.disable()

    def __enableLocalControl(self):
        self.orthWalk.start()
        self.keyCodes.enable()
        self.keyCodesGui.enable()
        self.keyCodesGui.hideAll()

    def __handleEnterDanceFloor(self, collEntry):
        if not self.isLocalToonInActivity() and not self.localToonDancing:
            self.notify.debug('Toon enters dance floor collision area.')
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, 'fsm'):
                place.fsm.request('activity')
            self.d_toonJoinRequest()
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, 'fsm'):
                place.fsm.request('activity')

    def joinRequestDenied(self, reason):
        DistributedPartyActivity.joinRequestDenied(self, reason)
        self.showMessage(TTLocalizer.PartyActivityDefaultJoinDeny)
        place = base.cr.playGame.getPlace()
        if place and hasattr(place, 'fsm'):
            place.fsm.request('walk')

    def setToonsPlaying(self, toonIds, toonHeadings):
        self.notify.debug('setToonsPlaying')
        self.notify.debug('\ttoonIds: %s' % toonIds)
        self.notify.debug('\ttoonHeadings: %s' % toonHeadings)
        exitedToons, joinedToons = self.getToonsPlayingChanges(self.toonIds, toonIds)
        self.notify.debug('\texitedToons: %s' % exitedToons)
        self.notify.debug('\tjoinedToons: %s' % joinedToons)
        self.setToonIds(toonIds)
        self._processExitedToons(exitedToons)
        for toonId in joinedToons:
            if toonId != base.localAvatar.doId or toonId == base.localAvatar.doId and self.isLocalToonRequestStatus(PartyGlobals.ActivityRequestStatus.Joining):
                self._enableHandleToonDisabled(toonId)
                self.handleToonJoined(toonId, toonHeadings[toonIds.index(toonId)])
                if toonId == base.localAvatar.doId:
                    self._localToonRequestStatus = None

        return

    def handleToonJoined(self, toonId, h):
        self.notify.debug('handleToonJoined( toonId=%d, h=%.2f )' % (toonId, h))
        if base.cr.doId2do.has_key(toonId):
            toonFSM = PartyDanceActivityToonFSM(toonId, self, h)
            toonFSM.request('Init')
            self.dancingToonFSMs[toonId] = toonFSM
            if toonId == base.localAvatar.doId:
                self.__localStartDancing(h)

    def __localStartDancing(self, h):
        if not self.localToonDancing:
            place = base.cr.playGame.getPlace()
            if place and hasattr(place, 'fsm'):
                self.localToonDancing = True
                place.fsm.request('activity')
                self.__updateLocalToonState(ToonDancingStates.Run)
                self.__setViewMode(DanceViews.Dancing)
                self.gui.load()
                self.startRules()
                self.__localEnableControls()
            else:
                self.notify.warning('__localStartDancing, failed in playGame.getPlace()')

    def handleRulesDone(self):
        self.finishRules()

    def __localEnableControls(self):
        if not self.dancingToonFSMs.has_key(base.localAvatar.doId):
            self.notify.debug('no dancing FSM for local avatar, not enabling controls')
            return
        self.accept(KeyCodes.PATTERN_MATCH_EVENT, self.__doDanceMove)
        self.accept(KeyCodes.PATTERN_NO_MATCH_EVENT, self.__noDanceMoveMatch)
        self.acceptOnce(KeyCodes.KEY_DOWN_EVENT, self._handleKeyDown)
        self.accept(KeyCodes.KEY_UP_EVENT, self._handleKeyUp)
        self.keyCodes.enable()
        self.orthoWalk.start()
        self.gui.enable()
        self.gui.hideAll()

    def __localDisableControls(self):
        self.orthoWalk.stop()
        self.keyCodes.disable()
        self.gui.disable()
        self.ignore(KeyCodes.PATTERN_MATCH_EVENT)
        self.ignore(KeyCodes.PATTERN_NO_MATCH_EVENT)
        self.ignore(KeyCodes.KEY_DOWN_EVENT)
        self.ignore(KeyCodes.KEY_UP_EVENT)

    def __handleExitDanceFloor(self, collEntry):
        if self.localToonDanceSequence is not None:
            self.notify.debug('finishing %s' % self.localToonDanceSequence)
            self.localToonDanceSequence.finish()
            self.localToonDanceSequence = None
        self.finishRules()
        self.notify.debug('Toon exits dance floor collision area.')
        self.d_toonExitRequest()
        return

    def exitRequestDenied(self, reason):
        DistributedPartyActivity.exitRequestDenied(self, reason)
        if reason != PartyGlobals.DenialReasons.SilentFail:
            self.showMessage(TTLocalizer.PartyActivityDefaultExitDeny)

    def handleToonExited(self, toonId):
        self.notify.debug('exitDanceFloor %s' % toonId)
        if toonId == base.localAvatar.doId:
            self.__localStopDancing()

    def __localStopDancing(self):
        if self.localToonDancing:
            self.__localDisableControls()
            self.gui.unload()
            self.__setViewMode(DanceViews.Normal)
            self.__updateLocalToonState(ToonDancingStates.Cleanup)
            if base.cr.playGame.getPlace():
                if hasattr(base.cr.playGame.getPlace(), 'fsm'):
                    base.cr.playGame.getPlace().fsm.request('walk')
            self.localToonDancing = False

    def __doDanceMove(self, pattern):
        self.notify.debug('Dance move! %s' % pattern)
        anim = self.dancePatternToAnims.get(pattern)
        if anim:
            self.__updateLocalToonState(ToonDancingStates.DanceMove, anim)
            self.gui.setColor(0, 1, 0)
            self.gui.showText(DanceAnimToName.get(anim, anim))
            self.finishRules()
            if pattern not in self.localPatternsMatched:
                camNode = NodePath(self.uniqueName('danceCamNode'))
                camNode.reparentTo(base.localAvatar)
                camNode.lookAt(camera)
                camNode.setHpr(camNode.getH(), 0, 0)
                node2 = NodePath('tempCamNode')
                node2.reparentTo(camNode)
                node2.setPos(Point3(0, 15, 10))
                node2.lookAt(camNode)
                h = node2.getH() * (camera.getH(camNode) / abs(camera.getH(camNode)))
                node2.removeNode
                del node2
                hpr = camera.getHpr()
                pos = camera.getPos()
                camParent = camera.getParent()
                camera.wrtReparentTo(camNode)
                self.localToonDanceSequence = Sequence(Func(self.__localDisableControls), Parallel(camera.posInterval(0.5, Point3(0, 15, 10), blendType='easeIn'), camera.hprInterval(0.5, Point3(h, -20, 0), blendType='easeIn')), camNode.hprInterval(4.0, Point3(camNode.getH() - 360, 0, 0)), Func(camera.wrtReparentTo, camParent), Func(camNode.removeNode), Parallel(camera.posInterval(0.5, pos, blendType='easeOut'), camera.hprInterval(0.5, hpr, blendType='easeOut')), Func(self.__localEnableControls))
            else:
                self.localToonDanceSequence = Sequence(Func(self.__localDisableControls), Wait(2.0), Func(self.__localEnableControls))
            self.localToonDanceSequence.start()
            self.localPatternsMatched.append(pattern)

    def __noDanceMoveMatch(self):
        self.gui.setColor(1, 0, 0)
        self.gui.showText('No Match!')
        self.__updateLocalToonState(ToonDancingStates.DanceMove)
        self.localToonDanceSequence = Sequence(Func(self.__localDisableControls), Wait(1.0), Func(self.__localEnableControls))
        self.localToonDanceSequence.start()

    def _handleKeyDown(self, key, index):
        self.__updateLocalToonState(ToonDancingStates.Run)

    def _handleKeyUp(self, key):
        if not self.keyCodes.isAnyKeyPressed():
            self.__updateLocalToonState(ToonDancingStates.DanceMove)
            self.acceptOnce(KeyCodes.KEY_DOWN_EVENT, self._handleKeyDown)

    def __updateLocalToonState(self, state, anim = ''):
        self._requestToonState(base.localAvatar.doId, state, anim)
        self.d_updateDancingToon(state, anim)

    def d_updateDancingToon(self, state, anim):
        self.sendUpdate('updateDancingToon', [state, anim])

    def setDancingToonState(self, toonId, state, anim):
        if toonId != base.localAvatar.doId and self.dancingToonFSMs.has_key(toonId):
            self._requestToonState(toonId, state, anim)

    def _requestToonState(self, toonId, state, anim):
        if self.dancingToonFSMs.has_key(toonId):
            state = ToonDancingStates.getString(state)
            curState = self.dancingToonFSMs[toonId].getCurrentOrNextState()
            try:
                self.dancingToonFSMs[toonId].request(state, anim)
            except FSM.RequestDenied:
                self.notify.warning('could not go from state=%s to state %s' % (curState, state))

            if state == ToonDancingStates.getString(ToonDancingStates.Cleanup):
                self.notify.debug('deleting this fsm %s' % self.dancingToonFSMs[toonId])
                del self.dancingToonFSMs[toonId]
                if self.localToonDanceSequence:
                    self.notify.debug('forcing a finish of localToonDanceSequence')
                    self.localToonDanceSequence.finish()
                    self.localToonDanceSequence = None
        return

    def __setViewMode(self, mode):
        toon = base.localAvatar
        if mode == DanceViews.Normal:
            if self.cameraParallel is not None:
                self.cameraParallel.pause()
                self.cameraParallel = None
            camera.reparentTo(toon)
            base.localAvatar.startUpdateSmartCamera()
        elif mode == DanceViews.Dancing:
            base.localAvatar.stopUpdateSmartCamera()
            camera.wrtReparentTo(self.danceFloor)
            node = NodePath('temp')
            node.reparentTo(toon.getParent())
            node.setPos(Point3(0, -40, 20))
            node2 = NodePath('temp2')
            node2.reparentTo(self.danceFloor)
            node.reparentTo(node2)
            node2.setH(render, toon.getParent().getH())
            pos = node.getPos(self.danceFloor)
            node2.removeNode()
            node.removeNode()
            self.cameraParallel = Parallel(camera.posInterval(0.5, pos, blendType='easeIn'), camera.hprInterval(0.5, Point3(0, -27, 0), other=toon.getParent(), blendType='easeIn'))
            self.cameraParallel.start()
        self.currentCameraMode = mode
        return
예제 #5
0
class Parcial(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        self.disableMouse()

        # Instrucciones en pantalla
        self.Salir = addInstructions(.06, "[ESC]: Para Salir")
        self.Camara = addInstructions(.12, "[A]: Para Mover Cabeza")
        self.CabezaL = addInstructions(.18, "[S]: Para Mover Brazo Derecho")
        self.CabezaL = addInstructions(.24, "[D]: Para Mover Brazo Izquierdo")
        self.CaderaL = addInstructions(.30, "[F]: Para Mover Cadera")
        self.CaderaL = addInstructions(.36, "[G]: Para Mover Tronco")
        self.CaderaL = addInstructions(.42, "[H]: Para Girar")
        self.CaderaL = addInstructions(.48, "[Z]: Cabeza Cadera")
        self.CaderaL = addInstructions(.54, "[X]: Brazos")
        self.CaderaL = addInstructions(.60, "[C]: Giro Tronco")
        self.CaderaL = addInstructions(.66, "[V]: Todos a la vez")

        # Carga de un Actor
        self.Ralph = Actor("models/ralph", {
            "run": "models/ralph-run",
            "walk": "models/ralph-walk"
        })

        self.Ralph.setScale(.5, .5, .5)
        self.Ralph.setPos(
            0, 10,
            -1)  #(x   -IZQ  +DER   ,y   PROFUNDIDAD  ,z   +ARRIBA -ABAJO   )
        self.Ralph.reparentTo(self.render)

        # Giro de ralph
        self.GiroTotal = self.Ralph.hprInterval(1.5, Point3(0, 359, 0))

        # Declaración de partes del cuerpo
        self.Cabeza = self.Ralph.controlJoint(None, 'modelRoot', 'Neck')
        self.BrazoDerecho = self.Ralph.controlJoint(None, 'modelRoot',
                                                    'RightShoulder')
        self.BrazoIzquierdo = self.Ralph.controlJoint(None, 'modelRoot',
                                                      'LeftShoulder')
        self.CaderaDerecha = self.Ralph.controlJoint(None, 'modelRoot',
                                                     'RightHip')
        self.CaderaIzquierda = self.Ralph.controlJoint(None, 'modelRoot',
                                                       'LeftHip')
        self.Tronco = self.Ralph.controlJoint(None, 'modelRoot', 'Chest')

        # Movimiento de Cabeza
        self.CabezaAbajo = self.Cabeza.hprInterval(0.5, Point3(0, 0, 0))
        self.CabezaArriba = self.Cabeza.hprInterval(0.5, Point3(20, 0, 0))

        # Movimientos de brazo derecho
        self.BrazoDerechoAbajo = self.BrazoDerecho.hprInterval(
            1.0, Point3(72.2059, 106.186, -45))
        self.BrazoDerechoArriba = self.BrazoDerecho.hprInterval(
            1.0, Point3(72.2059, 76.186, 6.02231))

        # Movimientos de brazo izquierdo
        self.BrazoIzquierdoAbajo = self.BrazoIzquierdo.hprInterval(
            1.0, Point3(160.1401, -22.1706, 6.55722))
        self.BrazoIzquierdoArriba = self.BrazoIzquierdo.hprInterval(
            1.0, Point3(80.1401, -52.1706, 6.55722))

        # Movimientos de cadera derecha
        self.CaderaDerechaDerecha = self.CaderaDerecha.hprInterval(
            0.5, Point3(4.9762, 0, 120))
        self.CaderaDerechaNormal = self.CaderaDerecha.hprInterval(
            0.5, Point3(4.9762, 0, 90))

        # Movimientos de cadera derecha
        self.CaderaIzquierdaIzquierda = self.CaderaIzquierda.hprInterval(
            0.5, Point3(5.02118, -0.862563, 62.9857))
        self.CaderaIzquierdaNormal = self.CaderaIzquierda.hprInterval(
            0.5, Point3(5.02118, -0.862563, 92.9857))

        # Movimientos del tronco
        #self.Tronco.setHpr(0, 50, 0)
        self.TroncoIzquierda = self.Tronco.hprInterval(0.5, Point3(0, 50, 0))
        self.TroncoDerecha = self.Tronco.hprInterval(0.5, Point3(0, -50, 0))
        self.TroncoNormal = self.Tronco.hprInterval(0.5, Point3(0, 0, 0))

        # Secuencias de movimientos
        self.MoverCabeza = Sequence(self.CabezaArriba, self.CabezaAbajo)
        self.MoverBrazoDerecho = Sequence(self.BrazoDerechoAbajo,
                                          self.BrazoDerechoArriba)
        self.MoverBrazoIzquierdo = Sequence(self.BrazoIzquierdoAbajo,
                                            self.BrazoIzquierdoArriba)
        self.MoverCaderaDerechaIzquierda = Sequence(
            self.CaderaDerechaDerecha, self.CaderaDerechaNormal,
            self.CaderaIzquierdaIzquierda, self.CaderaIzquierdaNormal)
        self.MoverTronco = Sequence(self.TroncoDerecha, self.TroncoNormal,
                                    self.TroncoIzquierda)
        self.Giro = Sequence(self.GiroTotal)

        # Paralelos
        self.CaderaCabeza = Parallel(self.MoverCabeza,
                                     self.MoverCaderaDerechaIzquierda)
        self.Brazos = Parallel(self.MoverBrazoDerecho,
                               self.MoverBrazoIzquierdo)
        self.GiroTronco = Parallel(self.Giro, self.MoverTronco)
        self.Todos = Parallel(self.MoverCabeza,
                              self.MoverCaderaDerechaIzquierda,
                              self.MoverBrazoDerecho, self.MoverBrazoIzquierdo,
                              self.Giro, self.MoverTronco)

        self.accept("escape", sys.exit)
        self.accept("a", self.eCabeza)
        self.accept("s", self.eBrazoDerecho)
        self.accept("d", self.eBrazoIzquierdo)
        self.accept("f", self.eCadera)
        self.accept("g", self.eTronco)
        self.accept("h", self.eGiro)
        self.accept("z", self.eCadCab)
        self.accept("x", self.eBrazos)
        self.accept("c", self.eGiroT)
        self.accept("v", self.eTodos)

    def eCabeza(self):
        self.MoverCabeza.start()

    def eBrazoDerecho(self):
        self.MoverBrazoDerecho.start()

    def eBrazoIzquierdo(self):
        self.MoverBrazoIzquierdo.start()

    def eCadera(self):
        self.MoverCaderaDerechaIzquierda.start()

    def eTronco(self):
        self.MoverTronco.start()

    def eGiro(self):
        self.Giro.start()

    def eCadCab(self):
        self.CaderaCabeza.start()

    def eBrazos(self):
        self.Brazos.start()

    def eGiroT(self):
        self.GiroTronco.start()

    def eTodos(self):
        self.Todos.loop()