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
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
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
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()