def _startFog(self): if not hasattr(self, '_fog'): self._fog = RingOfFog() self._fog.reparentTo(render) self._fog.setEffectColor(Vec4(0.2, 0.3, 0.5, 1)) self._fog.startLoop() self._moveFogDownEvent = 'moveFogDown' taskMgr.add(self._fogPositionTask, self._moveFogDownEvent, priority=49)
def _startFog(self): if not hasattr(self, '_fog'): self._fog = RingOfFog() self._fog.reparentTo(render) self._fog.setEffectColor(Vec4(0.20000000000000001, 0.29999999999999999, 0.5, 1)) self._fog.startLoop() self._moveFogDownEvent = 'moveFogDown' taskMgr.add(self._fogPositionTask, self._moveFogDownEvent, priority = 49)
class DistributedPiratesTutorial(DistributedObject.DistributedObject, FSM.FSM): notify = directNotify.newCategory('DistributedPiratesTutorial') PRELOADED_CUTSCENES = [] def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedPiratesTutorial') self.active = 1 self.JackSparrowPos = Point3(0, 0, 0) self.JackSparrowHpr = Point3(200, 0, 0) self.NPCDoIds = [] self.ShipDoIds = [] self.pendingJackRequest = None self.pendingNavyBoatRequest = None self.pendingDanRequest = None self.pendingStumpyRequest = None self.pendingIslandRequest = None self.BoatStumpyDoId = None self.island = None self.shipWreck = None self.loggingCannonDone = False self.debugTutorial = base.config.GetBool('debug-tutorial', 0) self.noJailLight = base.config.GetBool('no-jail-light', 0) self._leftJail = 0 self.map = 0 base.cr.tutorialObject = self self.enemyBoatHidden = True def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) if localAvatar.style.getTutorial() == 0: self.map = MakeAPirate.MakeAPirate([base.localAvatar], 'makeAPirateComplete') self.map.load() localAvatar.b_setGameState('LandRoam') self.acceptOnce('localAvTeleportFinished', self.getStarted) base.setOverrideShipVisibility(True) self.acceptOnce('localPirateDisabled', self.localPlayerLeft) base.cr.timeOfDayManager.enableSync(False) def localPlayerLeft(self): self.cleanup() def getStarted(self, task=None): if self.state == 'Off': self.request('Act0Tutorial') def cleanup(self): if self.pendingJackRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingJackRequest) self.pendingJackRequest = None if self.pendingNavyBoatRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingNavyBoatRequest) self.pendingNavyBoatRequest = None if self.pendingDanRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingDanRequest) self.pendingDanRequest = None if self.pendingStumpyRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingStumpyRequest) self.pendingStumpyRequest = None if self.pendingIslandRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingIslandRequest) self.pendingIslandRequest = None taskMgr.remove(self.taskName('handleAct0Tutorial')) self._stopFog() self._stopInteriorCannonballHitEffects() self._stopTutorialInteriorEffects() if hasattr(self, '_phantomCannon'): self._phantomCannon.destroy() del self._phantomCannon for pcs in self.PRELOADED_CUTSCENES: for currCutscene in pcs: base.cr.cleanupPreloadedCutscene(currCutscene) self.PRELOADED_CUTSCENES = [] if self.island is not None: self.island.stopCustomEffects() self.island = None self.ignoreAll() def disable(self): self.cleanup() if base.cr and base.cr.timeOfDayManager: base.cr.timeOfDayManager.enableSync(True) DistributedObject.DistributedObject.disable(self) def preloadCutscene(self, pcs): if pcs in self.PRELOADED_CUTSCENES: return None self.PRELOADED_CUTSCENES.append(pcs) for currCutscene in pcs: base.cr.preloadCutscene(currCutscene) def inventoryFailed(self): if localAvatar: localAvatar.b_setLocation(0, 0) if self.map: self.map.exit() self.map.unload() self.map = 0 base.cr.gameFSM.request('closeShard', ['waitForAvatarList']) def enterAct0Tutorial(self): self.notify.debug('starting tutorial') QuestParser.init() if self.noJailLight: render.setLightOff() self.JackDoId = None self.DanDoId = None self.StumpyDoId = None self.IslandDoId = None def stumpyHere(stumpyId): self.StumpyDoId = stumpyId def stumpyBoatHere(stumpyBoatId): self.BoatStumpyDoId = stumpyBoatId self.pendingStumpyBoatRequest = base.cr.relatedObjectMgr.requestObjects( [self.BoatStumpyDoId], eachCallback=self.doStumpyBoatIntro) def navyBoatHere(navyBoatId): self.BoatNavyDoId = navyBoatId self.pendingNavyBoatRequest = base.cr.relatedObjectMgr.requestObjects( [self.BoatNavyDoId], eachCallback=self.setupNavyBoat) def islandHere(islandId): self.IslandDoId = islandId self.pendingIslandRequest = base.cr.relatedObjectMgr.requestObjects( [self.IslandDoId], eachCallback=self.handleIslandGenerate) self.cr.uidMgr.addUidCallback(TutorialGlobals.STUMPY_UID, stumpyHere) self.cr.uidMgr.addUidCallback(TutorialGlobals.STUMPY_BOAT_UID, stumpyBoatHere, onlyOnce=False) self.cr.uidMgr.addUidCallback(TutorialGlobals.ENEMY_BOAT_UID, navyBoatHere, onlyOnce=False) self.cr.uidMgr.addUidCallback(LocationIds.RAMBLESHACK_ISLAND, islandHere) self.accept('doneJackIntro', self.doneJackIntro) self.accept('fadeInExteriorDoor', self.handleGoOutside) self.accept('fadeInInteriorDoor', self.handleGoInside) self.acceptOnce('beginSeachest', self.beginSeachest) if localAvatar.style.getTutorial() > 0: self.ignore('doneJackIntro') localAvatar.openJailDoor() localAvatar.style.setName(localAvatar.getName()) localAvatar.guiMgr.showTrays() base.transitions.fadeIn() self.sendUpdate('clientEnterAct0Tutorial') def _startTutorialInteriorEffects(self, startFire, cannonDelay=None): base.ambientMgr.requestFadeIn( SoundGlobals.AMBIENT_JAIL, finalVolume=PiratesGlobals.DEFAULT_AMBIENT_VOLUME) def _stopTutorialInteriorEffects(self): base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_JAIL) def handleIslandGenerate(self, island): self.island = island def handleWalkedOutToIsland(self): if not self._leftJail: self._leftJail = 1 base.cr.centralLogger.writeClientEvent('LEAVING_JAIL') UserFunnel.logSubmit(0, 'LEAVING_JAIL') UserFunnel.logSubmit(1, 'LEAVING_JAIL') self._stopTutorialInteriorEffects() self.island.setZoneLevel(0) localAvatar.bindAnim( ['sword_draw', 'sword_idle', 'cutlass_combo', 'cutlass_sweep']) self._targetNps = self.island.findAllMatches('**/TorchFire') self._phantomCannon = PhantomCannon(self.cr, self.island, CannonDistance, 50, self._targetNps, self.island) self._phantomCannon.start() def generateShipWreck(self, island): objNP = island.find('**/=uid=%s' % TutorialGlobals.SHIP_WRECK_UID) self.shipWreck = ShipWreck.ShipWreck(objNP, TutorialGlobals.SHIP_WRECK_UID) self.shipWreck.tutorial = self self.shipWreck.makeTargetableCollision(island.doId) island.shipWreck = self.shipWreck def removeShipWreck(self): if self.shipWreck: self.shipWreck.delete() self.shipWreck.removeNode() def doStumpyBoatIntro(self, object): stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] def setupTalkToDan(talkToDan): stumpyBoat.setZoneLevel(0) if talkToDan == False: self.notify.debug('stumpyBoat: talkToDan is False') self.accept(stumpyBoat.proximityCollisionEnterEvent, self.triggerBoBeckCut) self.acceptOnce('sendToBoat', self.sendToBoat) self.notify.debug('stumpyBoat:waiting for stumpy %s' % self.StumpyDoId) self.pendingStumpyRequest = base.cr.relatedObjectMgr.requestObjects( [self.StumpyDoId], eachCallback=self.doStumpyIntro) else: self.notify.debug('stumpyBoat:talkToDan is True') setupTalkToDan(False) stumpyBoat.hideName() def triggerBoBeckCut(self, collEntry): self.notify.debug('triggerBoBeckCut') stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] self.ignore(stumpyBoat.proximityCollisionEnterEvent) self.sendUpdate('autoVisit', [self.BoatStumpyDoId]) base.avatarPhysicsMgr.removePhysicalNode(stumpyBoat.actorNode) def exitAct0Tutorial(self): pass def doneJackIntro(self): self.notify.debug('Done Introducing Jack Sparrow') localAvatar.unstash() self.request('Act1MakeAPirate') def enterAct1MakeAPirate(self): base.disableMouse() localAvatar.gameFSM.request('MakeAPirate') localAvatar.gameFSM.lockFSM = True localAvatar.guiMgr.hideTrays() self.avHpr = VBase3(180, 0, 0) ga = localAvatar.getParentObj() ga.builder.turnOffLights() self.jail = ga.find('**/*navy_jail_interior*') self.map.enter() self.accept('makeAPirateComplete', self.handleMakeAPirate) UserFunnel.logSubmit(1, 'CREATE_PIRATE_LOADS') UserFunnel.logSubmit(0, 'CREATE_PIRATE_LOADS') base.cr.centralLogger.writeClientEvent('CREATE_PIRATE_LOADS') def handleMakeAPirate(self, clothing=[]): self.notify.debug('done make-a-pirate') done = self.map.getDoneStatus() if done == 'cancel': localAvatar.b_setLocation(0, 0) self.map.exit() self.map.unload() self.map = 0 base.cr.closeShard() base.cr.logout() elif done == 'created': dna = self.map.pirate.style localAvatar.setDNA(dna) localAvatar.generateHuman(dna.gender, base.cr.humanHigh) localAvatar.motionFSM.off() localAvatar.motionFSM.on() if clothing: clothes = [] for clothId in clothing: clothType = None if clothId == 'HAT': clothType = ItemGlobals.HAT elif clothId == 'SHIRT': clothType = ItemGlobals.SHIRT elif clothId == 'VEST': clothType = ItemGlobals.VEST elif clothId == 'COAT': clothType = ItemGlobals.COAT elif clothId == 'PANT': clothType = ItemGlobals.PANT elif clothId == 'BELT': clothType = ItemGlobals.BELT elif clothId == 'SHOE': clothType = ItemGlobals.SHOE if clothType and clothing[clothId][0]: clothes.append([ clothType, clothing[clothId][0], clothing[clothId][2] ]) continue if clothes: localAvatar.sendRequestMAPClothes(clothes) self.acceptOnce('avatarPopulated', self.avatarPopulated) if self.map.nameGui.customName: localAvatar.setWishName() base.cr.avatarManager.sendRequestPopulateAvatar( localAvatar.doId, localAvatar.style, 0, 0, 0, 0, 0) else: name = self.map.nameGui.getNumericName() base.cr.avatarManager.sendRequestPopulateAvatar( localAvatar.doId, localAvatar.style, 1, name[0], name[1], name[2], name[3]) self.map.exit() self.map.unload() self.map = 0 else: self.notify.error('Invalid doneStatus from MakeAPirate: ' + str(done)) localAvatar.gameFSM.lockFSM = False ga = localAvatar.getParentObj() if ga is not None: ga.builder.turnOnLights() def avatarPopulated(self): self.request('EscapeFromLA') localAvatar.b_setGameState('LandRoam') self.sendUpdate('makeAPirateComplete') def makeAPirateCompleteResp(self): base.transitions.fadeIn(1.0) def handleGoOutside(self, uid): base.loadingScreen.tick() if uid == LocationIds.RAMBLESHACK_INSIDE: self.preloadCutscene(CutsceneData.PRELOADED_CUTSCENE_STAGE4) base.loadingScreen.tick() self._stopTutorialInteriorEffects() base.loadingScreen.tick() if hasattr(self, '_phantomCannon'): self._phantomCannon.start() self.ignore(CannonballHitEvent) base.cr.timeOfDayManager.setEnvironment(TODGlobals.ENV_EVER_NIGHT, {}) base.loadingScreen.tick() self._startFog() base.loadingScreen.tick() self.handleWalkedOutToIsland() base.loadingScreen.tick() def handleGoInside(self, uid): base.loadingScreen.tick() if uid == LocationIds.RAMBLESHACK_INSIDE: self.preloadCutscene(CutsceneData.PRELOADED_CUTSCENE_STAGE3) base.loadingScreen.tick() self._phantomCannon.stop() self._stopFog() isJail = False self.accept(CannonballHitEvent, Functor(self._handleInteriorCannonballHit, isJail)) def _handleInteriorCannonballHit(self, isJail): return None if isJail: offset = 0 else: offset = 3 self._dustEffect = CeilingDust.getEffect() if self._dustEffect: self._dustEffect.reparentTo(base.localAvatar) self._dustEffect.setPos(0, 0, 12 + offset) self._dustEffect.play() self._debrisEffect = CeilingDebris.getEffect() if self._debrisEffect: self._debrisEffect.reparentTo(base.localAvatar) self._debrisEffect.setPos(0, 0, 22 + offset) self._debrisEffect.play() def _stopInteriorCannonballHitEffects(self): self.ignore(CannonballHitEvent) if hasattr(self, '_dustEffect'): self._dustEffect.finish() del self._dustEffect if hasattr(self, '_debrisEffect'): self._debrisEffect.finish() del self._debrisEffect def _startFog(self): if not hasattr(self, '_fog'): self._fog = RingOfFog() self._fog.reparentTo(render) self._fog.setEffectColor( Vec4(0.20000000000000001, 0.29999999999999999, 0.5, 1)) self._fog.startLoop() self._moveFogDownEvent = 'moveFogDown' taskMgr.add(self._fogPositionTask, self._moveFogDownEvent, priority=49) def _stopFog(self): if hasattr(self, '_fog'): taskMgr.remove(self._moveFogDownEvent) del self._moveFogDownEvent self._fog.stopLoop() self._fog.destroy() del self._fog def _tuneFog(self, alpha): if hasattr(self, '_fog'): self._fog.tuneFog(alpha) def _fogPositionTask(self, task): self._fog.setX(localAvatar, 0) self._fog.setY(localAvatar, 0) return task.cont def exitAct1MakeAPirate(self): base.enableMouse() base.localAvatar.setHpr(self.avHpr) localAvatar.b_setTutorial(PiratesGlobals.TUT_GOT_SEACHEST) def enterEscapeFromLA(self): UserFunnel.logSubmit(1, 'CUTSCENE_ONE_END') UserFunnel.logSubmit(0, 'CUTSCENE_ONE_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_ONE_END') self.acceptOnce('startTutorialCannons', Functor(self._startTutorialInteriorEffects, False)) def exitEscapeFromLA(self): pass def setupNavyBoat(self, object): if self.enemyBoatHidden: object.hideName() object.hide() def beginSeachest(self): self.notify.debug('beginSeachest') localAvatar.gameFSM.lockFSM = False localAvatar.b_setGameState('Dialog') localAvatar.gameFSM.lockFSM = True localAvatar.guiMgr.request('Interface', [False, True]) localAvatar.guiMgr.chestTray.show() localAvatar.cameraFSM.request('Control') stage = localAvatar.getParent().getParent() base.camera.reparentTo(stage) base.camera.setPos(9.5609999999999999, 26.215, 5.2549999999999999) base.camera.setHpr(-2.9990000000000001, 5.2930000000000001, 2.2959999999999998) localAvatar.setPos(stage, 9.5609999999999999, 26.215, 1.0) self._seachest = localAvatar.tutObject localAvatar.tutObject = None t = Parallel( Sequence(LerpPosInterval(self._seachest, 10, VBase3(15, -10, 3.0)), Func(self._seachest.removeNode)), Sequence( LerpScaleInterval( self._seachest, 1, VBase3(0.10000000000000001, 0.10000000000000001, 0.10000000000000001)))) t.start() def assignStumpyQuest(self): self.notify.debug('assignStumpyQuest') self.accept('removeDanAndNell', self.removeDanAndNell) def removeDanAndNell(self): UserFunnel.logSubmit(1, 'CUTSCENE_TWO_END') UserFunnel.logSubmit(0, 'CUTSCENE_TWO_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_TWO_END') self.notify.debug('removeDanAndNell') localAvatar.setTutorial(PiratesGlobals.TUT_GOT_SEACHEST) localAvatar.gameFSM.lockFSM = False localAvatar.b_setGameState('LandRoam') localAvatar.guiMgr.chestTray.show() def stageStumpyPositionOnBoat(self): self.NPCStumpy.motionFSM.request('Off') self.NPCStumpy.loop('wheel_idle') def sendToBoat(self): if self.island is not None: self.island.stopCustomEffects() stumpyBoat = base.cr.getDo(self.BoatStumpyDoId) self.sendUpdate('teleportToShip') self.stageStumpyPositionOnBoat() self.acceptOnce('usedCannon', self.startShipMovement) stumpyBoat.cannons.values()[0][1].setIgnoreProximity(False) dialogue = loadSfx(SoundGlobals.BBD_TELL_SHOOT) localAvatar.guiMgr.subtitler.showText( PLocalizer.QuestScriptTutorialStumpy_1, sfx=dialogue, timeout=dialogue.length() + 1.0) localAvatar.guiMgr.subtitler.clearTextOverride = True def doStumpyIntro(self, object): self.notify.debug('doStumpyIntro') self.NPCStumpy = object dnaDict = NPCList.NPC_LIST['1153439632.21darren'] customDNA = HumanDNA.HumanDNA() customDNA.loadFromNPCDict(dnaDict) self.NPCStumpy.setDNA(customDNA) self.NPCStumpy.generateHuman('m', base.cr.humanHigh) self.NPCStumpy.setInteractOptions(allowInteract=False) self.NPCStumpy.setIgnoreProximity(True) self.NPCStumpy.disableBodyCollisions() self.NPCStumpy.setZ(9) self.notify.debug('collision event for Stumpy %s' % self.NPCStumpy.proximityCollisionEvent) stumpyBoat = base.cr.getDo(self.BoatStumpyDoId) self.acceptOnce(stumpyBoat.uniqueName('localAvBoardedShip'), self.doneStumpyIntro) def doneStumpyIntro(self, task=None): self.notify.debug('Done Introducing Stumpy McGee') self.enemyBoatHidden = False localAvatar.gameFSM.lockFSM = False localAvatar.b_setGameState('LandRoam') localAvatar.gameFSM.lockFSM = True self.sendUpdate('boardedTutorialShip') self.acceptOnce('showCannonExitPanel', self.showCannonExitPanel) self.accept('targetPracticeDone', self.targetPracticeDone) UserFunnel.logSubmit(1, 'CUTSCENE_THREE_START') UserFunnel.logSubmit(0, 'CUTSCENE_THREE_START') base.cr.centralLogger.writeClientEvent('CUTSCENE_THREE_START') if self.BoatStumpyDoId: stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] stumpyBoat.ignoreFloors() self.ignore(stumpyBoat.uniqueName('localAvBoardedShip')) navyBoat = base.cr.doId2do[self.BoatNavyDoId] navyBoat.show() navyBoat.hideName() base.cr.relatedObjectMgr.abortRequest(self.pendingStumpyRequest) def startShipMovement(self): if self.island is not None: self.island.stopCustomEffects() self._phantomCannon.stop() localAvatar.guiMgr.setIgnoreAllKeys(True) localAvatar.guiMgr.setIgnoreMainMenuHotKey(True) localAvatar.guiMgr.chestTray.hide() self.sendUpdate('startSailingStumpy') UserFunnel.logSubmit(1, 'CUTSCENE_THREE_END') UserFunnel.logSubmit(0, 'CUTSCENE_THREE_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_THREE_END') def targetPracticeDone(self): localAvatar.guiMgr.setIgnoreMainMenuHotKey(False) localAvatar.guiMgr.chestTray.show() def enemyShipSunk(self): localAvatar.gameFSM.lockFSM = False self.showCannonExitPanel() dialogue = loadSfx(SoundGlobals.BBD_GIVE_PRAISE) localAvatar.guiMgr.subtitler.showText( PLocalizer.QuestScriptTutorialStumpy_6, sfx=dialogue, timeout=dialogue.length() + 1.0) def showCannonExitPanel(self): self.notify.debug('showCannonExitPanel') localAvatar.cannon.showExitCannonPanel() localAvatar.cannon.setIgnoreProximity(True) self.acceptOnce('exitedCannon', self.cannonDoneShooting) def cannonDoneShooting(self): if not self.loggingCannonDone: UserFunnel.logSubmit(1, 'ACCESS_CANNON') UserFunnel.logSubmit(0, 'ACCESS_CANNON') base.cr.centralLogger.writeClientEvent('ACCESS_CANNON') self.loggingCannonDone = True self.sendUpdate('targetPracticeDone') self.request('Act2TargetSunk') def enterAct2TargetSunk(self): self.notify.debug('Sunk the target') self.accept('introduceJR', self.introduceJR) def exitAct2TargetSunk(self): pass def introduceJR(self): if localAvatar.cannon: localAvatar.cannon.handleEndInteractKey() if localAvatar.ship and localAvatar.ship.gameFSM: localAvatar.ship.gameFSM.stopCurrentMusic() localAvatar.setPos(0, 0, 0) localAvatar.nametag3d.hide() self.notify.debug('introduceJR') self.request('Act3IntroduceJR') self.removeShipWreck() if self.island is not None: self.island.stopCustomEffects() self.island.stash() def enterAct3IntroduceJR(self): self.notify.debug('Here comes Jolly Roger') self.accept('JRAttackShip', self.JRAttackShip) UserFunnel.logSubmit(1, 'CUTSCENE_FOUR_START') UserFunnel.logSubmit(0, 'CUTSCENE_FOUR_START') base.cr.centralLogger.writeClientEvent('CUTSCENE_FOUR_START') def exitAct3IntroduceJR(self): pass def JRAttackShip(self): self.notify.debug('JR Attacking Ship') self.accept('JRDestroyShip', self.JRDestroyShip) def JRDestroyShip(self): self.notify.debug('JR Destroying Ship') self.request('Act4BackToMain') UserFunnel.logSubmit(1, 'CUTSCENE_FOUR_END') UserFunnel.logSubmit(0, 'CUTSCENE_FOUR_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_FOUR_END') def enterAct4BackToMain(self): taskMgr.doMethodLater(0.0001, self.goBackToMain, self.taskName('goBackToMain')) def exitAct4BackToMain(self): pass def goBackToMain(self, task): self.request('Act4DoneTutorial') return Task.done def enterAct4DoneTutorial(self): base.transitions.fadeOut(1.0) base.cr.loadingScreen.showHint(LocationIds.PORT_ROYAL_ISLAND) base.cr.loadingScreen.showTarget(LocationIds.PORT_ROYAL_ISLAND) base.cr.loadingScreen.show() localAvatar.guiMgr.ignoreAllKeys = False localAvatar.guiMgr.showTrays() localAvatar.show() if base.downloadWatcher and hasattr(base.downloadWatcher, 'setStatusBarLocation'): base.downloadWatcher.setStatusBarLocation(2) if base.launcher.getPhaseComplete(4): self.leaveTutorial() else: base.cr.centralLogger.writeClientEvent( 'Player encountered phase 4 blocker after JR cutscene') base.downloadWatcher.foreground() self.acceptOnce('phaseComplete-4', self.leaveTutorial) def skipTutorial(self): def initDefQuest(inventory): self.pendingInitQuest = None if inventory: localAvatar.sendUpdate('giveDefaultQuest') localAvatar.b_setTutorial(PiratesGlobals.TUT_GOT_COMPASS) if base.launcher.getPhaseComplete(4): self.leaveTutorial() else: base.downloadWatcher.foreground() self.acceptOnce('phaseComplete-4', self.leaveTutorial) self.pendingInitQuest = DistributedInventoryBase.getInventory( localAvatar.getInventoryId(), initDefQuest) base.transitions.fadeOut(1.0) base.cr.loadingScreen.showHint(LocationIds.PORT_ROYAL_ISLAND) base.cr.loadingScreen.showTarget(LocationIds.PORT_ROYAL_ISLAND) base.cr.loadingScreen.show() localAvatar.guiMgr.ignoreAllKeys = False localAvatar.guiMgr.showTrays() localAvatar.show() if base.downloadWatcher and hasattr(base.downloadWatcher, 'setStatusBarLocation'): base.downloadWatcher.setStatusBarLocation(2) def leaveTutorial(self): if base.downloadWatcher and hasattr(base.downloadWatcher, 'background'): base.downloadWatcher.background() base.cr.tutorial = 0 base.cr.tutorialObject = None base.setOverrideShipVisibility(False) localAvatar.clearTeleportFlag(PiratesGlobals.TFInTutorial) localAvatar.b_setLocation(self.cr.distributedDistrict.doId, PiratesGlobals.QuietZone) self.sendUpdate('tutorialComplete') UserFunnel.logSubmit(1, 'STARTGAME_DOCK') UserFunnel.logSubmit(0, 'STARTGAME_DOCK') base.cr.centralLogger.writeClientEvent('STARTGAME_DOCK')
class DistributedPiratesTutorial(DistributedObject.DistributedObject, FSM.FSM): notify = directNotify.newCategory('DistributedPiratesTutorial') PRELOADED_CUTSCENES = [] def __init__(self, cr): DistributedObject.DistributedObject.__init__(self, cr) FSM.FSM.__init__(self, 'DistributedPiratesTutorial') self.active = 1 self.JackSparrowPos = Point3(0, 0, 0) self.JackSparrowHpr = Point3(200, 0, 0) self.NPCDoIds = [] self.ShipDoIds = [] self.pendingJackRequest = None self.pendingNavyBoatRequest = None self.pendingDanRequest = None self.pendingStumpyRequest = None self.pendingIslandRequest = None self.tutorialInstance = None self.BoatStumpyDoId = None self.island = None self.shipWreck = None self.loggingCannonDone = False self.debugTutorial = base.config.GetBool('debug-tutorial', 0) self.noJailLight = base.config.GetBool('no-jail-light', 0) self._leftJail = 0 self.map = 0 base.cr.tutorialObject = self def generate(self): DistributedObject.DistributedObject.generate(self) self.notify.debug('generate') def announceGenerate(self): DistributedObject.DistributedObject.announceGenerate(self) if localAvatar.style.getTutorial() == 0: self.map = MakeAPirate.MakeAPirate([ base.localAvatar], 'makeAPirateComplete') self.map.load() self.acceptOnce('localAvTeleportFinished', self.getStarted) messenger.send('localAvTeleportFinishedRequest') base.setOverrideShipVisibility(True) self.acceptOnce('localPirateDisabled', self.localPlayerLeft) base.cr.timeOfDayManager.enableSync(False) def localPlayerLeft(self): self.cleanup() def getStarted(self, task = None): if self.state == 'Off': self.request('Act0Tutorial') def cleanup(self): if self.pendingJackRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingJackRequest) self.pendingJackRequest = None if self.pendingNavyBoatRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingNavyBoatRequest) self.pendingNavyBoatRequest = None if self.pendingDanRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingDanRequest) self.pendingDanRequest = None if self.pendingStumpyRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingStumpyRequest) self.pendingStumpyRequest = None if self.pendingIslandRequest: base.cr.relatedObjectMgr.abortRequest(self.pendingIslandRequest) self.pendingIslandRequest = None taskMgr.remove(self.taskName('handleAct0Tutorial')) self._stopFog() self._stopInteriorCannonballHitEffects() self._stopTutorialInteriorEffects() if hasattr(self, '_phantomCannon'): self._phantomCannon.destroy() del self._phantomCannon for pcs in self.PRELOADED_CUTSCENES: for currCutscene in pcs: base.cr.cleanupPreloadedCutscene(currCutscene) self.PRELOADED_CUTSCENES = [] if self.island is not None: self.island.stopCustomEffects() self.island = None localAvatar.clearTutorialHandlerZone() self.ignoreAll() def disable(self): self.cleanup() if base.cr and base.cr.timeOfDayManager: base.cr.timeOfDayManager.enableSync(True) DistributedObject.DistributedObject.disable(self) def setInstance(self, instance): self.tutorialInstance = instance if localAvatar.style.getTutorial() == 0: self.preloadCutscene(CutsceneData.PRELOADED_CUTSCENE_STAGE1) def preloadCutscene(self, pcs): if pcs in self.PRELOADED_CUTSCENES: return None self.PRELOADED_CUTSCENES.append(pcs) for currCutscene in pcs: base.cr.preloadCutscene(currCutscene) def inventoryFailed(self): if localAvatar: localAvatar.b_setLocation(0, 0) if self.map: self.map.exit() self.map.unload() self.map = 0 base.cr.gameFSM.request('closeShard', [ 'waitForAvatarList']) def enterAct0Tutorial(self): self.notify.debug('starting tutorial') QuestParser.init() if self.noJailLight: render.setLightOff() self.JackDoId = None self.DanDoId = None self.StumpyDoId = None self.IslandDoId = None def stumpyHere(stumpyId): self.StumpyDoId = stumpyId def stumpyBoatHere(stumpyBoatId): self.BoatStumpyDoId = stumpyBoatId self.pendingStumpyBoatRequest = base.cr.relatedObjectMgr.requestObjects([ self.BoatStumpyDoId], eachCallback = self.doStumpyBoatIntro) def navyBoatHere(navyBoatId): self.BoatNavyDoId = navyBoatId self.pendingNavyBoatRequest = base.cr.relatedObjectMgr.requestObjects([ self.BoatNavyDoId], eachCallback = self.setupNavyBoat) def danHere(danId): self.DanDoId = danId self.pendingDanRequest = base.cr.relatedObjectMgr.requestObjects([ self.DanDoId], eachCallback = self.doDanIntro) def nellHere(nellId): self.NellDoId = nellId self.pendingNellRequest = base.cr.relatedObjectMgr.requestObjects([ self.NellDoId], eachCallback = self.doNellIntro) def islandHere(islandId): self.IslandDoId = islandId self.pendingIslandRequest = base.cr.relatedObjectMgr.requestObjects([ self.IslandDoId], eachCallback = self.handleIslandGenerate) self.cr.uidMgr.addUidCallback(TutorialGlobals.STUMPY_UID, stumpyHere) self.cr.uidMgr.addUidCallback(TutorialGlobals.NELL_UID, nellHere, onlyOnce = False) self.cr.uidMgr.addUidCallback(TutorialGlobals.DAN_UID, danHere, onlyOnce = False) self.cr.uidMgr.addUidCallback(TutorialGlobals.STUMPY_BOAT_UID, stumpyBoatHere, onlyOnce = False) self.cr.uidMgr.addUidCallback(TutorialGlobals.ENEMY_BOAT_UID, navyBoatHere) self.cr.uidMgr.addUidCallback(TutorialGlobals.RAMBLESHACK_ISLE_UID, islandHere) self.accept('doneJackIntro', self.doneJackIntro) self.accept('doorToExteriorFadeIn', self.handleGoOutside) self.accept('doorToInteriorFadeIn', self.handleGoInside) self.acceptOnce('beginSeachest', self.beginSeachest) if localAvatar.style.getTutorial() > 0: self.ignore('doneJackIntro') localAvatar.openJailDoor() localAvatar.style.setName(localAvatar.getName()) localAvatar.guiMgr.showTrays() base.transitions.fadeIn() self.sendUpdate('clientEnterAct0Tutorial') def _startTutorialInteriorEffects(self, startFire, cannonDelay = None): base.ambientMgr.requestFadeIn(SoundGlobals.AMBIENT_JAIL, finalVolume = PiratesGlobals.DEFAULT_AMBIENT_VOLUME) def _stopTutorialInteriorEffects(self): base.ambientMgr.requestFadeOut(SoundGlobals.AMBIENT_JAIL) def handleIslandGenerate(self, island): self.island = island def handleWalkedOutToIsland(self): if not self._leftJail: self._leftJail = 1 base.cr.centralLogger.writeClientEvent('LEAVING_JAIL') UserFunnel.logSubmit(0, 'LEAVING_JAIL') UserFunnel.logSubmit(1, 'LEAVING_JAIL') self._stopTutorialInteriorEffects() self.island.setZoneLevel(0) localAvatar.bindAnim([ 'sword_draw', 'sword_idle', 'cutlass_combo', 'cutlass_sweep']) self._targetNps = self.island.findAllMatches('**/TorchFire') self._phantomCannon = PhantomCannon(self.cr, self.island, CannonDistance, 50, self._targetNps, self.island) self._phantomCannon.start() def generateShipWreck(self, island): objNP = island.find('**/=uid=%s' % TutorialGlobals.SHIP_WRECK_UID) self.shipWreck = ShipWreck.ShipWreck(objNP, TutorialGlobals.SHIP_WRECK_UID) self.shipWreck.tutorial = self self.shipWreck.makeTargetableCollision(island.doId) island.shipWreck = self.shipWreck def removeShipWreck(self): if self.shipWreck: self.shipWreck.delete() self.shipWreck.removeNode() def doStumpyBoatIntro(self, object): stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] def setupTalkToDan(talkToDan): stumpyBoat.setZoneLevel(0) if talkToDan == False: self.notify.debug('stumpyBoat: talkToDan is False') self.accept(stumpyBoat.proximityCollisionEnterEvent, self.triggerBoBeckCut) self.acceptOnce('enableBoatBoarding', self.enableBoatBoarding) self.notify.debug('stumpyBoat:waiting for stumpy %s' % self.StumpyDoId) self.pendingStumpyRequest = base.cr.relatedObjectMgr.requestObjects([ self.StumpyDoId], eachCallback = self.doStumpyIntro) else: self.notify.debug('stumpyBoat:talkToDan is True') self.playerNeedsToTalkToDan(setupTalkToDan) stumpyBoat.hideName() def triggerBoBeckCut(self, collEntry): self.notify.debug('triggerBoBeckCut') stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] self.ignore(stumpyBoat.proximityCollisionEnterEvent) self.sendUpdate('autoVisit', [ self.BoatStumpyDoId]) base.avatarPhysicsMgr.removePhysicalNode(stumpyBoat.actorNode) def exitAct0Tutorial(self): pass def doneJackIntro(self): self.notify.debug('Done Introducing Jack Sparrow') localAvatar.unstash() self.request('Act1MakeAPirate') def enterAct1MakeAPirate(self): base.disableMouse() localAvatar.gameFSM.request('MakeAPirate') localAvatar.gameFSM.lockFSM = True localAvatar.guiMgr.hideTrays() self.avHpr = VBase3(180, 0, 0) ga = localAvatar.getParentObj() ga.builder.turnOffLights() self.jail = ga.find('**/*navy_jail_interior*') self.map.enter() self.accept('makeAPirateComplete', self.handleMakeAPirate) UserFunnel.logSubmit(1, 'CREATE_PIRATE_LOADS') UserFunnel.logSubmit(0, 'CREATE_PIRATE_LOADS') base.cr.centralLogger.writeClientEvent('CREATE_PIRATE_LOADS') def handleMakeAPirate(self, clothing = []): self.notify.debug('done make-a-pirate') done = self.map.getDoneStatus() if done == 'cancel': localAvatar.b_setLocation(0, 0) self.map.exit() self.map.unload() self.map = 0 base.cr.gameFSM.request('closeShard', [ 'waitForAvatarList']) elif done == 'created': dna = self.map.pirate.style localAvatar.setDNA(dna) localAvatar.generateHuman(dna.gender, base.cr.humanHigh) localAvatar.motionFSM.off() localAvatar.motionFSM.on() if clothing: clothes = [] for clothId in clothing: clothType = None if clothId == 'HAT': clothType = ItemGlobals.HAT elif clothId == 'SHIRT': clothType = ItemGlobals.SHIRT elif clothId == 'VEST': clothType = ItemGlobals.VEST elif clothId == 'COAT': clothType = ItemGlobals.COAT elif clothId == 'PANT': clothType = ItemGlobals.PANT elif clothId == 'BELT': clothType = ItemGlobals.BELT elif clothId == 'SHOE': clothType = ItemGlobals.SHOE if clothType and clothing[clothId][0]: clothes.append([ clothType, clothing[clothId][0], clothing[clothId][2]]) continue if clothes: localAvatar.sendRequestMAPClothes(clothes) self.acceptOnce('avatarPopulated', self.avatarPopulated) if self.map.nameGui.customName: localAvatar.setWishName() base.cr.avatarManager.sendRequestPopulateAvatar(localAvatar.doId, localAvatar.style, 0, 0, 0, 0, 0) else: name = self.map.nameGui.getNumericName() base.cr.avatarManager.sendRequestPopulateAvatar(localAvatar.doId, localAvatar.style, 1, name[0], name[1], name[2], name[3]) self.map.exit() self.map.unload() self.map = 0 else: self.notify.error('Invalid doneStatus from MakeAPirate: ' + str(done)) localAvatar.gameFSM.lockFSM = False ga = localAvatar.getParentObj() if ga is not None: ga.builder.turnOnLights() def avatarPopulated(self): self.request('EscapeFromLA') localAvatar.b_setGameState('LandRoam') self.sendUpdate('makeAPirateComplete') def makeAPirateCompleteResp(self): base.transitions.fadeIn(1.0) def handleGoOutside(self, uid): base.loadingScreen.tick() if uid == '1159905354.84jubutler': self.preloadCutscene(CutsceneData.PRELOADED_CUTSCENE_STAGE4) base.loadingScreen.tick() self._stopTutorialInteriorEffects() base.loadingScreen.tick() if hasattr(self, '_phantomCannon'): self._phantomCannon.start() self.ignore(CannonballHitEvent) base.cr.timeOfDayManager.setEnvironment(TODGlobals.ENV_EVER_NIGHT, { }) base.loadingScreen.tick() self._startFog() base.loadingScreen.tick() self.handleWalkedOutToIsland() base.loadingScreen.tick() def handleGoInside(self, uid): base.loadingScreen.tick() if uid == '1159905354.84jubutler': self.preloadCutscene(CutsceneData.PRELOADED_CUTSCENE_STAGE3) base.loadingScreen.tick() self._phantomCannon.stop() self._stopFog() isJail = False self.accept(CannonballHitEvent, Functor(self._handleInteriorCannonballHit, isJail)) def _handleInteriorCannonballHit(self, isJail): return None if isJail: offset = 0 else: offset = 3 self._dustEffect = CeilingDust.getEffect() if self._dustEffect: self._dustEffect.reparentTo(base.localAvatar) self._dustEffect.setPos(0, 0, 12 + offset) self._dustEffect.play() self._debrisEffect = CeilingDebris.getEffect() if self._debrisEffect: self._debrisEffect.reparentTo(base.localAvatar) self._debrisEffect.setPos(0, 0, 22 + offset) self._debrisEffect.play() def _stopInteriorCannonballHitEffects(self): self.ignore(CannonballHitEvent) if hasattr(self, '_dustEffect'): self._dustEffect.finish() del self._dustEffect if hasattr(self, '_debrisEffect'): self._debrisEffect.finish() del self._debrisEffect def _startFog(self): if not hasattr(self, '_fog'): self._fog = RingOfFog() self._fog.reparentTo(render) self._fog.setEffectColor(Vec4(0.20000000000000001, 0.29999999999999999, 0.5, 1)) self._fog.startLoop() self._moveFogDownEvent = 'moveFogDown' taskMgr.add(self._fogPositionTask, self._moveFogDownEvent, priority = 49) def _stopFog(self): if hasattr(self, '_fog'): taskMgr.remove(self._moveFogDownEvent) del self._moveFogDownEvent self._fog.stopLoop() self._fog.destroy() del self._fog def _tuneFog(self, alpha): if hasattr(self, '_fog'): self._fog.tuneFog(alpha) def _fogPositionTask(self, task): self._fog.setX(localAvatar, 0) self._fog.setY(localAvatar, 0) return task.cont def exitAct1MakeAPirate(self): base.enableMouse() base.localAvatar.setHpr(self.avHpr) localAvatar.b_setTutorial(PiratesGlobals.TUT_GOT_SEACHEST) def enterEscapeFromLA(self): UserFunnel.logSubmit(1, 'CUTSCENE_ONE_END') UserFunnel.logSubmit(0, 'CUTSCENE_ONE_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_ONE_END') self.acceptOnce('startTutorialCannons', Functor(self._startTutorialInteriorEffects, False)) def exitEscapeFromLA(self): pass def doDanIntro(self, object): self.notify.debug('doDanIntro') self.NPCDan = object if localAvatar.style.getTutorial() > PiratesGlobals.TUT_GOT_SEACHEST: if not self.debugTutorial: self.NPCDan.stash() self.NPCDan.setInteractOptions(allowInteract = False) return None dnaDict = NPCList.NPC_LIST[TutorialGlobals.DAN_UID] customDNA = HumanDNA.HumanDNA() customDNA.loadFromNPCDict(dnaDict) self.NPCDan.setDNA(customDNA) self.NPCDan.generateHuman('m', base.cr.humanHigh, useFaceTex = True) self.NPCDan.hideName() self.NPCDan.setPurgeInteractGui(1) self.NPCDan.disableBodyCollisions() self.NPCDan.loop('tut_1_1_5_a_idle_dan') self.NPCDan.setInteractOptions(allowInteract = False) self.NPCDan.tutorialCharacter = 1 def setupTalkToDan(talkToDan): if talkToDan: self.doneDanIntro(None) else: self.NPCDan.setAllowInteract(False) self.playerNeedsToTalkToDan(setupTalkToDan) def doNellIntro(self, object): self.notify.debug('doNellIntro') self.NPCNell = object if localAvatar.style.getTutorial() > 1: if not self.debugTutorial: self.NPCNell.stash() self.NPCNell.setInteractOptions(allowInteract = False) return None dnaDict = NPCList.NPC_LIST[TutorialGlobals.NELL_UID] customDNA = HumanDNA.HumanDNA() customDNA.loadFromNPCDict(dnaDict) self.NPCNell.setDNA(customDNA) self.NPCNell.generateHuman('f', base.cr.humanHigh) self.NPCNell.hideName() self.NPCNell.setPurgeInteractGui(1) self.NPCNell.loop('tut_1_1_5_a_idle_dan') self.NPCNell.setInteractOptions(allowInteract = False) self.accept('playNellAnimationDan_a', self.playNellAnimationDan_a) UserFunnel.logSubmit(1, 'CUTSCENE_TWO_START') UserFunnel.logSubmit(0, 'CUTSCENE_TWO_START') base.cr.centralLogger.writeClientEvent('CUTSCENE_TWO_START') def loopNellAnimationDan_a_idle(self): self.notify.debug('startNellAnimationDan_a_idle') self.NPCNell.loop('tut_1_1_5_a_idle_dan') def playNellAnimationDan_a(self): self.notify.debug('startNellAnimationDan_a') self.NPCNell.play('tut_1_1_5_a_dan') self.accept('loopNellAnimationDan_a_idle', self.loopNellAnimationDan_a_idle) self.accept('playNellAnimationDan_b', self.playNellAnimationDan_b) def playNellAnimationDan_b(self): self.notify.debug('startNellAnimationDan_b') self.NPCNell.play('tut_1_1_5_b_dan') self.accept('assignStumpyQuest', self.assignStumpyQuest) def setupNavyBoat(self, object): object.hideName() object.hide() def playerNeedsToTalkToDan(self, callback): if localAvatar.style.getTutorial() >= 2: callback(False) return None def talkToDanCallback(inventory): if not inventory: callback(False) talkToDan = False for currQuest in inventory.getQuestList(): if currQuest.questId == TutorialGlobals.SECOND_QUEST: talkToDan = True break continue callback(talkToDan) DistributedInventoryBase.DistributedInventoryBase.getInventory(localAvatar.inventoryId, talkToDanCallback) def doneDanIntro(self, collEntry): self.notify.debug('Done Introducing Doggerel Dan') self.NPCDan.setAllowInteract(False) self.request('Act2FindDan') def enterAct2FindDan(self): self.notify.debug('found Dan') self.sendUpdate('autoVisit', [ self.NPCDan.getDoId()]) self.accept('assignStumpyQuest', self.assignStumpyQuest) def exitAct2FindDan(self): pass def beginSeachest(self): self.notify.debug('beginSeachest') localAvatar.gameFSM.lockFSM = False localAvatar.b_setGameState('Dialog') localAvatar.gameFSM.lockFSM = True localAvatar.guiMgr.request('Interface', [ False, True]) localAvatar.guiMgr.chestTray.show() localAvatar.cameraFSM.request('Control') stage = localAvatar.getParent().getParent() base.camera.reparentTo(stage) base.camera.setPos(9.5609999999999999, 26.215, 5.2549999999999999) base.camera.setHpr(-2.9990000000000001, 5.2930000000000001, 2.2959999999999998) self.NPCDan.setHpr(-180, 0, 0) localAvatar.setPos(stage, 9.5609999999999999, 26.215, 1.0) self._seachest = localAvatar.tutObject localAvatar.tutObject = None t = Parallel(Sequence(LerpPosInterval(self._seachest, 10, VBase3(15, -10, 3.0)), Func(self._seachest.removeNode)), Sequence(LerpScaleInterval(self._seachest, 1, VBase3(0.10000000000000001, 0.10000000000000001, 0.10000000000000001)))) t.start() def assignStumpyQuest(self): self.notify.debug('assignStumpyQuest') self.accept('removeDanAndNell', self.removeDanAndNell) def removeDanAndNell(self): UserFunnel.logSubmit(1, 'CUTSCENE_TWO_END') UserFunnel.logSubmit(0, 'CUTSCENE_TWO_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_TWO_END') self.notify.debug('removeDanAndNell') localAvatar.setTutorial(PiratesGlobals.TUT_GOT_SEACHEST) localAvatar.gameFSM.lockFSM = False localAvatar.b_setGameState('LandRoam') localAvatar.guiMgr.chestTray.show() def stageStumpyPositionOnBoat(self): self.NPCStumpy.motionFSM.request('Off') self.NPCStumpy.loop('wheel_idle') def enableBoatBoarding(self): self.notify.debug('enableBoatBoarding') if self.BoatStumpyDoId: stumpyBoat = base.cr.doId2do.get(self.BoatStumpyDoId) if not stumpyBoat: self.notify.warning('tutorial interceptor %s not found!' % self.BoatStumpyDoId) return None if self.island is not None: self.island.stopCustomEffects() localAvatar.placeOnShip(stumpyBoat) localAvatar.setH(90) self.stageStumpyPositionOnBoat() self.acceptOnce('usedCannon', self.startShipMovement) stumpyBoat.cannons.values()[0][1].setIgnoreProximity(False) dialogue = loadSfx(SoundGlobals.BBD_TELL_SHOOT) localAvatar.guiMgr.subtitler.showText(PLocalizer.QuestScriptTutorialStumpy_1, sfx = dialogue, timeout = dialogue.length() + 1.0) localAvatar.guiMgr.subtitler.clearTextOverride = True def doStumpyIntro(self, object): self.notify.debug('doStumpyIntro') self.NPCStumpy = object dnaDict = NPCList.NPC_LIST['1153439632.21darren'] customDNA = HumanDNA.HumanDNA() customDNA.loadFromNPCDict(dnaDict) self.NPCStumpy.setDNA(customDNA) self.NPCStumpy.generateHuman('m', base.cr.humanHigh) self.NPCStumpy.setInteractOptions(allowInteract = False) self.NPCStumpy.setIgnoreProximity(True) self.NPCStumpy.disableBodyCollisions() self.NPCStumpy.setZ(9) self.notify.debug('collision event for Stumpy %s' % self.NPCStumpy.proximityCollisionEvent) if self.BoatStumpyDoId: stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] self.acceptOnce(stumpyBoat.uniqueName('localAvBoardedShip'), self.doneStumpyIntro) navyBoat = base.cr.doId2do[self.BoatNavyDoId] navyBoat.hide() def doneStumpyIntro(self, task = None): self.notify.debug('Done Introducing Stumpy McGee') localAvatar.gameFSM.lockFSM = False localAvatar.b_setGameState('LandRoam') localAvatar.gameFSM.lockFSM = True self.sendUpdate('boardedTutorialShip') self.acceptOnce('showCannonExitPanel', self.showCannonExitPanel) self.accept('targetPracticeDone', self.targetPracticeDone) UserFunnel.logSubmit(1, 'CUTSCENE_THREE_START') UserFunnel.logSubmit(0, 'CUTSCENE_THREE_START') base.cr.centralLogger.writeClientEvent('CUTSCENE_THREE_START') if self.BoatStumpyDoId: stumpyBoat = base.cr.doId2do[self.BoatStumpyDoId] stumpyBoat.ignoreFloors() self.ignore(stumpyBoat.uniqueName('localAvBoardedShip')) navyBoat = base.cr.doId2do[self.BoatNavyDoId] navyBoat.show() navyBoat.hideName() def startShipMovement(self): if self.island is not None: self.island.stopCustomEffects() self._phantomCannon.stop() localAvatar.guiMgr.setIgnoreAllKeys(True) localAvatar.guiMgr.setIgnoreMainMenuHotKey(True) localAvatar.guiMgr.chestTray.hide() self.sendUpdate('startSailingStumpy') UserFunnel.logSubmit(1, 'CUTSCENE_THREE_END') UserFunnel.logSubmit(0, 'CUTSCENE_THREE_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_THREE_END') def targetPracticeDone(self): localAvatar.guiMgr.setIgnoreMainMenuHotKey(False) localAvatar.guiMgr.chestTray.show() def enemyShipSunk(self): localAvatar.gameFSM.lockFSM = False self.showCannonExitPanel() dialogue = loadSfx(SoundGlobals.BBD_GIVE_PRAISE) localAvatar.guiMgr.subtitler.showText(PLocalizer.QuestScriptTutorialStumpy_6, sfx = dialogue, timeout = dialogue.length() + 1.0) def showCannonExitPanel(self): self.notify.debug('showCannonExitPanel') localAvatar.cannon.showExitCannonPanel() localAvatar.cannon.setIgnoreProximity(True) self.acceptOnce('exitedCannon', self.cannonDoneShooting) def cannonDoneShooting(self): if base.cr.gameFSM.getCurrentState().getName() != 'playGame': return None if not self.loggingCannonDone: UserFunnel.logSubmit(1, 'ACCESS_CANNON') UserFunnel.logSubmit(0, 'ACCESS_CANNON') base.cr.centralLogger.writeClientEvent('ACCESS_CANNON') self.loggingCannonDone = True self.sendUpdate('targetPracticeDone') self.request('Act2TargetSunk') def enterAct2TargetSunk(self): self.notify.debug('Sunk the target') self.accept('introduceJR', self.introduceJR) def exitAct2TargetSunk(self): pass def introduceJR(self): if localAvatar.cannon: localAvatar.cannon.handleEndInteractKey() if localAvatar.ship and localAvatar.ship.gameFSM: localAvatar.ship.gameFSM.stopCurrentMusic() localAvatar.setPos(0, 0, 0) localAvatar.nametag3d.hide() self.notify.debug('introduceJR') self.request('Act3IntroduceJR') self.removeShipWreck() if self.island is not None: self.island.stopCustomEffects() self.island.stash() def enterAct3IntroduceJR(self): self.notify.debug('Here comes Jolly Roger') self.accept('JRAttackShip', self.JRAttackShip) UserFunnel.logSubmit(1, 'CUTSCENE_FOUR_START') UserFunnel.logSubmit(0, 'CUTSCENE_FOUR_START') base.cr.centralLogger.writeClientEvent('CUTSCENE_FOUR_START') def exitAct3IntroduceJR(self): pass def JRAttackShip(self): self.notify.debug('JR Attacking Ship') self.accept('JRDestroyShip', self.JRDestroyShip) def JRDestroyShip(self): self.notify.debug('JR Destroying Ship') self.request('Act4BackToMain') UserFunnel.logSubmit(1, 'CUTSCENE_FOUR_END') UserFunnel.logSubmit(0, 'CUTSCENE_FOUR_END') base.cr.centralLogger.writeClientEvent('CUTSCENE_FOUR_END') def enterAct4BackToMain(self): taskMgr.doMethodLater(0.0001, self.goBackToMain, self.taskName('goBackToMain')) def exitAct4BackToMain(self): pass def goBackToMain(self, task): self.request('Act4DoneTutorial') return Task.done def enterAct4DoneTutorial(self): base.transitions.fadeOut(1.0) base.cr.tutorial = 0 base.cr.tutorialObject = None base.cr.loadingScreen.showHint('1150922126.8dzlu') base.cr.loadingScreen.showTarget('1150922126.8dzlu') base.cr.loadingScreen.show() localAvatar.setupAutoShipBoarding() localAvatar.removeFromShip(localAvatar.ship) localAvatar.guiMgr.ignoreAllKeys = False localAvatar.guiMgr.showTrays() if base.launcher.getPhaseComplete(4): self.teleportToPR() else: base.cr.centralLogger.writeClientEvent('Player encountered phase 4 blocker after JR cutscene') base.downloadWatcher.foreground() self.accept('phaseComplete-4', self.teleportToPR) def teleportToPR(self): if base.downloadWatcher: base.downloadWatcher.background() if config.GetBool('want-welcome-worlds', 0): base.cr.teleportMgr.initiateTeleport(PiratesGlobals.INSTANCE_WELCOME, 'welcomeWorld', doneCallback = self.handleBackToMain) else: base.cr.teleportMgr.initiateTeleport(PiratesGlobals.INSTANCE_MAIN, 'mainWorld', doneCallback = self.handleBackToMain) def exitAct4DoneTutorial(self): pass def handleBackToMain(self, object): base.setOverrideShipVisibility(False) messenger.send('stopTutorial') localAvatar.show() UserFunnel.logSubmit(1, 'STARTGAME_DOCK') UserFunnel.logSubmit(0, 'STARTGAME_DOCK') base.cr.centralLogger.writeClientEvent('STARTGAME_DOCK')