コード例 #1
0
ファイル: CharSelection.py プロジェクト: coginvasion/src
class CharSelection:
    notify = directNotify.newCategory('CharSelection')
    STAGE_TOON_POS = (66.4, 74.47, -25)
    STAGE_TOON_HPR = (227.73, 0, 0)
    NO_TOON = 'Empty Slot'
    PLAY = 'Play'
    CREATE = 'Create'
    TITLE = 'Pick  A  Toon  To  Play'

    def __init__(self, avChooser):
        self.avChooser = avChooser
        self.choice = None
        self.charList = None
        self.charNameLabel = None
        self.charButtons = []
        self.playOrCreateButton = None
        self.deleteButton = None
        self.quitButton = None
        self.world = None
        self.sky = None
        self.fog = None
        self.title = None
        self.stageToon = None
        self.selectionFSM = ClassicFSM.ClassicFSM('CharSelection', [State.State('off', self.enterOff, self.exitOff), State.State('character', self.enterCharSelected, self.exitCharSelected), State.State('empty', self.enterEmptySelected, self.exitEmptySelected)], 'off', 'off')
        self.selectionFSM.enterInitialState()
        return

    def __setupStageToon(self):
        self.stageToon = Toon(base.cr)
        self.stageToon.setPos(self.STAGE_TOON_POS)
        self.stageToon.setHpr(self.STAGE_TOON_HPR)

    def cleanupStageToon(self):
        if self.stageToon != None:
            self.stageToon.disable()
            self.stageToon.delete()
            self.stageToon = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterCharSelected(self, slot):
        self.choice = self.avChooser.getAvChoiceBySlot(slot)
        dna = self.choice.dna
        name = self.choice.name
        self.stageToon.setName(name)
        self.stageToon.setDNAStrand(dna)
        self.stageToon.nameTag.setColorLocal()
        self.stageToon.animFSM.request('neutral')
        self.stageToon.reparentTo(base.render)
        self.charNameLabel.setText(name)
        self.playOrCreateButton['text'] = self.PLAY
        self.playOrCreateButton['extraArgs'] = ['play']
        self.playOrCreateButton.show()
        self.deleteButton.show()

    def exitCharSelected(self):
        self.stageToon.animFSM.requestFinalState()
        self.stageToon.deleteCurrentToon()
        self.stageToon.reparentTo(base.hidden)
        self.playOrCreateButton.hide()
        self.deleteButton.hide()
        self.choice = None
        return

    def enterEmptySelected(self):
        self.charNameLabel.setText(self.NO_TOON)
        self.playOrCreateButton['text'] = self.CREATE
        self.playOrCreateButton['extraArgs'] = ['create']
        self.playOrCreateButton.show()

    def exitEmptySelected(self):
        self.playOrCreateButton.hide()

    def __action(self, action):
        for btn in self.charButtons:
            if btn['state'] == DGG.DISABLED:
                self.slot = btn.getPythonTag('slot')
                break

        func = None
        arg = None
        if action == 'delete':
            func = self.deleteToon
            arg = self.choice.avId
        elif action == 'play':
            func = self.playGame
            arg = self.choice.slot
        elif action == 'create':
            func = self.enterMAT
        elif action == 'quit':
            func = sys.exit
        base.transitions.fadeOut(0.3)
        if arg != None:
            Sequence(Wait(0.31), Func(func, arg)).start()
        else:
            Sequence(Wait(0.31), Func(func)).start()
        return

    def playGame(self, slot):
        messenger.send('avChooseDone', [self.avChooser.getAvChoiceBySlot(slot)])

    def enterMAT(self):
        messenger.send('enterMakeAToon', [self.slot])

    def deleteToon(self, avId):
        self.avChooser.avChooseFSM.request('waitForToonDelResponse', [avId])

    def __handleCharButton(self, slot):
        for btn in self.charButtons:
            if btn.getPythonTag('slot') == slot:
                btn['state'] = DGG.DISABLED
            else:
                btn['state'] = DGG.NORMAL

        if self.avChooser.hasToonInSlot(slot):
            self.selectionFSM.request('character', [slot])
        else:
            self.selectionFSM.request('empty')

    def load(self):
        base.cr.renderFrame()
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4.0 / 3.0))
        self.__setupStageToon()
        self.world = loader.loadModel('phase_9/models/cogHQ/SellbotHQExterior.bam')
        self.world.reparentTo(base.render)
        self.world.setPos(0, 227.09, -25.36)
        self.sky = loader.loadModel('phase_9/models/cogHQ/cog_sky.bam')
        self.sky.setScale(1)
        self.sky.reparentTo(base.render)
        self.sky.find('**/InnerGroup').removeNode()
        self.fog = Fog('charSelectFog')
        self.fog.setColor(0.2, 0.2, 0.2)
        self.fog.setExpDensity(0.003)
        base.render.setFog(self.fog)
        self.title = DirectLabel(text=self.TITLE, text_font=CIGlobals.getMickeyFont(), text_fg=(1, 0.9, 0.1, 1), relief=None, text_scale=0.13, pos=(0, 0, 0.82))
        self.charNameLabel = OnscreenText(text='', font=CIGlobals.getMickeyFont(), pos=(-0.25, 0.5, 0), fg=(1, 0.9, 0.1, 1.0))
        self.charNameLabel.hide()
        self.playOrCreateButton = DirectButton(text='', pos=(0.8125, 0, -0.735), command=self.__action, geom=CIGlobals.getDefaultBtnGeom(), text_scale=0.06, relief=None, text_pos=(0, -0.01))
        self.playOrCreateButton.hide()
        self.deleteButton = DirectButton(text='Delete', pos=(0.8125, 0, -0.835), command=self.__action, extraArgs=['delete'], geom=CIGlobals.getDefaultBtnGeom(), text_scale=0.06, relief=None, text_pos=(0, -0.01))
        self.deleteButton.hide()
        self.quitButton = DirectButton(text='Quit', pos=(-1.1, 0, -0.925), command=self.__action, extraArgs=['quit'], text_scale=0.06, geom=CIGlobals.getDefaultBtnGeom(), relief=None, text_pos=(0, -0.01))
        textRolloverColor = Vec4(1, 1, 0, 1)
        textDownColor = Vec4(0.5, 0.9, 1, 1)
        textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)
        for slot in range(6):
            if self.avChooser.hasToonInSlot(slot):
                choice = self.avChooser.getAvChoiceBySlot(slot)
                text = choice.name
            else:
                text = self.NO_TOON
            btn = DirectButton(relief=None, text=text, text_scale=0.06, text_align=TextNode.ALeft, text1_bg=textDownColor, text2_bg=textRolloverColor, text3_fg=textDisabledColor, textMayChange=0, command=self.__handleCharButton, extraArgs=[slot], text_pos=(0, 0, 0.0))
            btn.setPythonTag('slot', slot)
            self.charButtons.append(btn)
            btn['state'] = DGG.NORMAL

        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        listXorigin = -0.02
        listFrameSizeX = 0.625
        listZorigin = -0.96
        listFrameSizeZ = 1.04
        arrowButtonScale = 1.3
        itemFrameXorigin = -0.237
        itemFrameZorigin = 0.365
        buttonXstart = itemFrameXorigin + 0.293
        self.charList = DirectScrolledList(relief=None, pos=(0.75, 0, 0.08), incButton_image=(gui.find('**/FndsLst_ScrollUp'),
         gui.find('**/FndsLst_ScrollDN'),
         gui.find('**/FndsLst_ScrollUp_Rllvr'),
         gui.find('**/FndsLst_ScrollUp')), incButton_relief=None, incButton_scale=(arrowButtonScale, arrowButtonScale, -arrowButtonScale), incButton_pos=(buttonXstart, 0, itemFrameZorigin - 0.999), incButton_image3_color=Vec4(1, 1, 1, 0.2), decButton_image=(gui.find('**/FndsLst_ScrollUp'),
         gui.find('**/FndsLst_ScrollDN'),
         gui.find('**/FndsLst_ScrollUp_Rllvr'),
         gui.find('**/FndsLst_ScrollUp')), decButton_relief=None, decButton_scale=(arrowButtonScale, arrowButtonScale, arrowButtonScale), decButton_pos=(buttonXstart, 0, itemFrameZorigin + 0.125), decButton_image3_color=Vec4(1, 1, 1, 0.2), itemFrame_pos=(itemFrameXorigin, 0, itemFrameZorigin), itemFrame_scale=1.0, itemFrame_relief=DGG.SUNKEN, itemFrame_frameSize=(listXorigin,
         listXorigin + listFrameSizeX,
         listZorigin,
         listZorigin + listFrameSizeZ), itemFrame_frameColor=(0.85, 0.95, 1, 1), itemFrame_borderWidth=(0.01, 0.01), numItemsVisible=15, forceHeight=0.075, items=self.charButtons)
        base.camera.setPos(75.12, 63.22, -23)
        base.camera.setHpr(26.57, 9.62, 0)
        return

    def unload(self):
        self.selectionFSM.requestFinalState()
        self.cleanupStageToon()
        self.choice = None
        if self.charButtons:
            for btn in self.charButtons:
                btn.destroy()

            self.charButtons = None
        if self.charList:
            self.charList.destroy()
            self.charList = None
        if self.charNameLabel:
            self.charNameLabel.destroy()
            self.charNameLabel = None
        if self.playOrCreateButton:
            self.playOrCreateButton.destroy()
            self.playOrCreateButton = None
        if self.deleteButton:
            self.deleteButton.destroy()
            self.deleteButton = None
        if self.quitButton:
            self.quitButton.destroy()
            self.quitButton = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.world:
            self.world.removeNode()
            self.world = None
        if self.title:
            self.title.destroy()
            self.title = None
        base.render.clearFog()
        self.fog = None
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        base.transitions.noTransitions()
        del self.selectionFSM
        return
コード例 #2
0
ファイル: DistributedShop.py プロジェクト: coginvasion/src
class DistributedShop(DistributedNode):
    notify = directNotify.newCategory("DistributedShop")

    def __init__(self, cr):
        try:
            self.DistributedShop_initialized
            return
        except:
            self.DistributedShop_initialized = 1

        DistributedNode.__init__(self, cr)
        NodePath.__init__(self, "shop")
        self.inShop = False
        self.snp = None
        self.clerk = None
        return

    def announceGenerate(self):
        DistributedNode.announceGenerate(self)
        self.__initCollisions("shopSphere" + str(self.doId))
        self.setupClerk()
        self.setParent(CIGlobals.SPRender)

    def disable(self):
        self.inShop = False
        self.snp = None
        self.removeClerk()
        DistributedNode.disable(self)
        return

    def delete(self):
        self.inShop = None
        DistributedNode.delete(self)
        return

    def enterAccepted(self):
        pass

    def __deleteCollisions(self):
        self.ignore("enter" + self.snp.node().getName())
        self.snp.removeNode()
        del self.snp

    def __handleEnterCollisionSphere(self, entry):
        self.notify.debug("Entering collision sphere...")
        self.d_requestEnter()

    def d_requestEnter(self):
        self.cr.playGame.getPlace().fsm.request("stop")
        self.sendUpdate("requestEnter", [])

    def d_requestExit(self):
        self.cr.playGame.getPlace().fsm.request("stop")
        self.sendUpdate("requestExit", [])

    def exitAccepted(self):
        self.cr.playGame.getPlace().fsm.request("walk")
        self.acceptOnce("enter" + self.snp.node().getName(), self.__handleEnterCollisionSphere)
        if self.inShop:
            self.inShop = False

    def _destroyDO(self):
        self.destroyDoStackTrace = StackTrace()
        if hasattr(self, "_cachedData"):
            for name, cachedData in self._cachedData.iteritems():
                self.notify.warning("flushing unretrieved cached data: %s" % name)
                cachedData.flush()

            del self._cachedData

    def setupClerk(self):
        self.clerk = Toon(self.cr)
        self.clerk.setDNAStrand(NPCGlobals.NPC_DNA["Professor Pete"])
        self.clerk.generateToon()
        self.clerk.reparentTo(self)
        self.clerk.animFSM.request("neutral")

    def removeClerk(self):
        self.clerk.disable()
        self.clerk.delete()
        self.clerk = None
        return

    def setChat(self, msgId):
        msgs = [CIGlobals.ShopGoodbye, CIGlobals.ShopNoMoney]
        self.clerk.setChat(msgs[msgId])

    def __initCollisions(self, name):
        self.notify.debug("Initializing collision sphere...")
        ss = CollisionSphere(0, 0, 0, 5)
        ss.setTangible(0)
        snode = CollisionNode(name)
        snode.add_solid(ss)
        snode.set_collide_mask(CIGlobals.WallBitmask)
        self.snp = self.attach_new_node(snode)
        self.snp.setZ(3)
        self.acceptOnce("enter" + self.snp.node().getName(), self.__handleEnterCollisionSphere)
class DistributedWinterCoachActivity(DistributedNode):
    notify = directNotify.newCategory('DistributedWinterCoachActivity')

    def __init__(self, cr):
        DistributedNode.__init__(self, cr)
        NodePath.__init__(self, 'winter_coach')
        self.cr = cr
        self.coach = None
        self.wheelBarrow = None
        self.coachNP = None
        return

    def announceGenerate(self):
        DistributedNode.announceGenerate(self)
        self.__initInteractCollisions('coachSphere' + str(self.doId))
        self.buildCoach()
        self.setParent(CIGlobals.SPRender)

    def greetAvatar(self, avatarName):
        self.coach.setChat(HolidayGlobals.COACH_GREETING % avatarName)

    def buildCoach(self):
        self.coach = Toon(self.cr)
        self.coach.setName('Coach')
        self.coach.setDNAStrand(NPC_DNA['Coach'])
        self.coach.reparentTo(self)
        self.coach.animFSM.request('neutral')
        self.wheelBarrow = loader.loadModel(
            'phase_5.5/models/estate/wheelbarrel.bam')
        self.wheelBarrow.find('**/dirt').setTexture(
            loader.loadTexture('winter/maps/sbhq_snow.png'), 1)
        self.wheelBarrow.reparentTo(self.coach)
        self.wheelBarrow.setX(-3.5)
        self.wheelBarrow.setH(90)

    def deleteCoach(self):
        if self.coach:
            self.coach.disable()
            self.coach.delete()
            self.coach = None
            self.wheelBarrow.removeNode()
            self.wheelBarrow = None
        return

    def __initInteractCollisions(self, colName):
        self.notify.debug('Setting up Coach collisions')
        collSphere = CollisionSphere(0, 0, 0, 5)
        collSphere.setTangible(0)
        collNode = CollisionNode(colName)
        collNode.addSolid(collSphere)
        collNode.setCollideMask(CIGlobals.WallBitmask)
        self.coachNP = self.attachNewNode(collNode)
        self.coachNP.setZ(3)
        self.acceptOnce('enter' + self.coachNP.node().getName(),
                        self.__handleCollision)

    def __handleCollision(self, entry):
        self.notify.debug('Entered collision sphere.')
        self.d_requestEnter()

    def d_requestEnter(self):
        self.cr.playGame.getPlace().fsm.request('stop')
        self.sendUpdate('requestEnter', [])

    def d_requestExit(self):
        self.cr.playGame.getPlace().fsm.request('stop')
        self.sendUpdate('requestExit', [])

    def enterAccepted(self):
        self.d_requestExit()
        base.localAvatar.updateSnowballButton()

    def exitAccepted(self):
        self.cr.playGame.getPlace().fsm.request('walk')
        self.acceptOnce('enter' + self.coachNP.node().getName(),
                        self.__handleCollision)

    def destroy(self):
        self.deleteCoach()
        self.coachNP = None
        return

    def disable(self):
        DistributedNode.disable(self)
        self.destroy()

    def delete(self):
        DistributedNode.delete(self)
        self.destroy()
コード例 #4
0
class DistributedTutorial(DistributedObject):
    notify = directNotify.newCategory('DistributedTutorial')
    GUIDE_NAME = 'Professor Prepostera'
    GUIDE_START_POS = (5, 10, -0.5)
    GUIDE_WATCH_POS = (12.4, 27.92, 0)
    GUIDE_WATCH_HPR = (41.63, 0, 0)
    GUIDE_INTRO_SPEECH = [
        'Hey, looks like you made it!', 'So, welcome to OToontown.',
        'OToontown is short for Old Toontown, or Toontown from the past.',
        'Not long ago, Toons used to live in present day Toontown.',
        'Unfortunately, the Cogs planned a mega-invasion that was sure to be a complete takeover of Toontown and make all Toons go sad for good.',
        "There was no way we could have let that happen, so we built a time machine, and sent every Toon back in time to OToontown, where Cogs didn't exist yet.",
        'The Cogs completely took over present day Toontown, and turned it into what they wanted it to be - a business metropolis.',
        'Toons happily live and play in OToontown now, but we want to learn about present day Toontown...',
        ' ...or as we now call it, CogTropolis.',
        "We've built time machines that send Toons back to CogTropolis to fight Cogs and to see what the Cogs have done.",
        "We know that the Cogs took over Toontown and turned it into a grey business city, but we don't know how they did it.",
        'Shopkeepers around OToontown will reward you for finding evidence that may help solve the mystery of how the Cogs turned Toontown into CogTropolis.',
        'Before you are able to head to CogTropolis, you need to be trained for battle.',
        'The Cogs have become much more skilled battlers and no longer wait for you to throw a gag before attacking you.',
        'This is much more difficult for Toons, and it may take some time to get used to.',
        "I'm going to give you 2 gags to start...",
        'A cupcake, and a squirting flower.',
        'Equip Gags in your loadout to use by pressing the corresponding key on your keyboard.',
        'You can use or throw the Gag that you have equipped by pressing the ALT key.',
        'Also, use the Arrow Keys on your keyboard to move, and press CTRL to jump.',
        "I'm going to summon one of our dummy bots for you to practice battling.",
        "Click your mouse when you're ready."
    ]
    GUIDE_PT2_INFO = [
        "Now it'll get a tad bit tougher.",
        'This next dummy bot will be walking around.',
        'This will test your aiming skills.',
        "Click your mouse when you're ready."
    ]
    GUIDE_PT3_INFO = [
        'This final dummy bot will walk around and try to attack you at times.',
        'Defeat this Cog to continue on to the next part of the tutorial.'
    ]
    GUIDE_DONE = [
        'Great!',
        'Did you know that Cog Invasion Online Alpha allows you to use any Gag that you want?',
        'Just use the Gags page in your Shticker Book to swap out the Gags that you want to be able to use!',
        'Also during Alpha testing, your Toon will start off with 5000 jellybeans and 100 Laff points.',
        "If you're looking to fight some Cogs, hop on the Trolley in the playgrounds to be teleported to CogTropolis!",
        'Each playground has a different difficulty of Cogs, so be careful!',
        "You can only fight Cogs in Toontown Central, Minnie's Melodyland, Donald's Dock, and Donald's Dreamland at the moment.",
        'You can also visit the Minigame Area using your Shticker Book to play some fun minigames!',
        'These games are best to play with other Toons!',
        'Remember, if you find any bugs or strange things during gameplay, you can go to the Contact Us page at coginvasion.com to report the issue.',
        'Have fun!'
    ]
    GUIDE_START_TRAINING = "Alright! Let's do this!"

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM.ClassicFSM('TutorialFSM', [
            State.State('off', self.enterOff, self.exitOff),
            State.State('newPlayerEmerge', self.enterPlayerEmerge,
                        self.exitPlayerEmerge, ['off', 'introSpeech']),
            State.State('introSpeech', self.enterGuideIntroSpeech,
                        self.exitGuideIntroSpeech,
                        ['off', 'introSpeech2Training']),
            State.State('introSpeech2Training', self.enterIntroSpeech2Training,
                        self.exitIntroSpeech2Training, ['off', 'training1']),
            State.State('training1', self.enterTrainingPT1,
                        self.exitTrainingPT1, ['off', 'training2info']),
            State.State('training2info', self.enterTraining2Info,
                        self.exitTraining2Info, ['off', 'training2']),
            State.State('training2', self.enterTrainingPT2,
                        self.exitTrainingPT2, ['off', 'training3info']),
            State.State('training3info', self.enterTraining3Info,
                        self.exitTraining3Info, ['off', 'training3']),
            State.State('training3', self.enterTrainingPT3,
                        self.exitTrainingPT3, ['off', 'trainingDone']),
            State.State('trainingDone', self.enterTrainingDone,
                        self.exitTrainingDone, ['off', 'leaveTutorial']),
            State.State('leaveTutorial', self.enterLeaveTutorial,
                        self.exitLeaveTutorial, ['off'])
        ], 'off', 'off')
        self.fsm.enterInitialState()
        self.dnaStore = DNAStorage()
        self.streetGeom = None
        self.sky = None
        self.skyUtil = SkyUtil()
        self.guide = None
        self.music = None
        self.battleMusic = None
        self.playerCamPos = None
        self.playerCamHpr = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def introStuff(self):
        base.localAvatar.getGeomNode().hide()
        base.localAvatar.setPos(0, 0, -0.5)
        base.localAvatar.setHpr(0, 0, 0)
        self.guide.setPos(self.GUIDE_START_POS)
        self.guide.headsUp(base.localAvatar)
        base.localAvatar.attachCamera()

    def enterPlayerEmerge(self):
        self.introStuff()
        self.guide.loop('neutral')
        base.transitions.irisIn()
        base.taskMgr.doMethodLater(1.0, self.__playerEmerge,
                                   'playerEmergeTask')

    def __playerEmerge(self, task):
        base.localAvatar.setAnimState('teleportIn',
                                      callback=self.__playerEmergeFinished)
        return Task.done

    def __playerEmergeFinished(self):
        base.localAvatar.setAnimState('neutral')
        self.fsm.request('introSpeech')

    def exitPlayerEmerge(self):
        base.localAvatar.detachCamera()
        base.taskMgr.remove('playerEmergeTask')
        base.transitions.noTransitions()

    def enterGuideIntroSpeech(self):
        base.localAvatar.attachCamera()
        renderPos = base.camera.getPos(render)
        renderHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        endPos = base.localAvatar.getPos(render) + (0, 0, 4)
        base.camera.setPos(endPos)
        base.camera.lookAt(self.guide, 0, 0, 3)
        endHpr = base.camera.getHpr(render)
        base.camera.setPos(renderPos)
        base.camera.setHpr(renderHpr)
        self.chatIndex = -1
        self.doNextIntroSpeech()
        self.camMoveTrack = Sequence(
            Parallel(
                LerpPosInterval(base.camera,
                                duration=3.0,
                                pos=endPos,
                                startPos=renderPos,
                                blendType='easeOut'),
                LerpQuatInterval(base.camera,
                                 duration=3.0,
                                 hpr=endHpr,
                                 startHpr=renderHpr,
                                 blendType='easeOut')),
            Func(base.localAvatar.getGeomNode().hide))
        self.camMoveTrack.start()

    def __finishedReadingGuideIntroSpeech(self):
        self.guide.autoClearChat = True
        self.guide.setChat(self.GUIDE_START_TRAINING)
        self.fsm.request('introSpeech2Training')

    def doNextIntroSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_INTRO_SPEECH):
            self.__finishedReadingGuideIntroSpeech()
            return
        self.guide.setChat(self.GUIDE_INTRO_SPEECH[self.chatIndex])
        Sequence(Wait(0.1),
                 Func(self.acceptOnce, 'mouse1-up',
                      self.doNextIntroSpeech)).start()

    def exitGuideIntroSpeech(self):
        self.camMoveTrack.finish()
        base.localAvatar.getGeomNode().show()
        del self.camMoveTrack
        del self.chatIndex

    def enterIntroSpeech2Training(self):
        startCamPos = base.camera.getPos(render)
        startCamHpr = base.camera.getHpr(render)
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        base.localAvatar.attachCamera()
        endCamPos = base.camera.getPos(render)
        endCamHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        startHpr = self.guide.getHpr(render)
        self.guide.headsUp(self.GUIDE_WATCH_POS)
        endHpr = self.guide.getHpr(render)
        self.guide.loop('run')
        self.camMoveIval = Parallel(
            LerpPosInterval(base.camera,
                            duration=2.0,
                            pos=endCamPos,
                            startPos=startCamPos,
                            blendType='easeOut'),
            LerpQuatInterval(base.camera,
                             duration=2.0,
                             hpr=endCamHpr,
                             startHpr=startCamHpr,
                             blendType='easeOut'),
            Sequence(
                LerpPosInterval(self.guide,
                                duration=2.0,
                                pos=self.GUIDE_WATCH_POS,
                                startPos=self.guide.getPos(render)),
                Func(self.guide.loop, 'walk'),
                LerpHprInterval(self.guide,
                                duration=1.0,
                                hpr=self.GUIDE_WATCH_HPR,
                                startHpr=endHpr),
                Func(self.guide.loop, 'neutral')),
            LerpHprInterval(self.guide,
                            duration=1.0,
                            hpr=endHpr,
                            startHpr=startHpr))
        self.camMoveIval.setDoneEvent('introSpeech2TrainingDone')
        self.acceptOnce('introSpeech2TrainingDone', self.__handleIS2TDone)
        self.camMoveIval.start()

    def __handleIS2TDone(self):
        self.fsm.request('training1')

    def exitIntroSpeech2Training(self):
        self.ignore('introSpeech2TrainingDone')
        self.camMoveIval.finish()
        del self.camMoveIval

    def makeWhisper(self, msg):
        whisper = WhisperPopup(msg, CIGlobals.getToonFont(),
                               ChatGlobals.WTSystem)
        whisper.manage(base.marginManager)

    def enterTrainingPT1(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [0])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enableGags(1)
        base.localAvatar.showGagButton()
        base.localAvatar.startTrackAnimToSpeed()
        self.makeWhisper(
            'This should be pretty simple. Just throw a gag at this dummy bot to defeat it.'
        )

    def suitNoHealth(self, index):
        if index == 0:
            self.makeWhisper(
                ('Good job, {0}!').format(base.localAvatar.getName()))
        else:
            if index == 1:
                self.makeWhisper("Wow, you're doing very well!")

    def suitExploded(self, index):
        if index == 0:
            self.makeWhisper(
                'Pick up the jellybean that he dropped. You can use them to buy more gags for your Toon.'
            )
        self.battleMusic.stop()
        base.playMusic(self.music, looping=1, volume=0.8)

    def pickedUpJellybean(self):
        if self.fsm.getCurrentState().getName() == 'training1':
            self.fsm.request('training2info')
        else:
            if self.fsm.getCurrentState().getName() == 'training2':
                self.fsm.request('training3info')
            else:
                if self.fsm.getCurrentState().getName() == 'training3':
                    self.fsm.request('trainingDone')

    def exitTrainingPT1(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disableGags()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.hideGagButton()
        return

    def enterTraining2Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining2Speech()

    def __finishedReadingGuideTraining2Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training2')

    def doNextTraining2Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT2_INFO):
            self.__finishedReadingGuideTraining2Speech()
            return
        self.guide.setChat(self.GUIDE_PT2_INFO[self.chatIndex])
        Sequence(
            Wait(0.1),
            Func(self.acceptOnce, 'mouse1-up',
                 self.doNextTraining2Speech)).start()

    def exitTraining2Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT2(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [1])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enableGags(1)
        base.localAvatar.showGagButton()
        base.localAvatar.startTrackAnimToSpeed()

    def exitTrainingPT2(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disableGags()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.hideGagButton()
        return

    def enterTraining3Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining3Speech()

    def __finishedReadingGuideTraining3Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training3')

    def doNextTraining3Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT3_INFO):
            self.__finishedReadingGuideTraining3Speech()
            return
        self.guide.setChat(self.GUIDE_PT3_INFO[self.chatIndex])
        Sequence(
            Wait(0.1),
            Func(self.acceptOnce, 'mouse1-up',
                 self.doNextTraining3Speech)).start()

    def exitTraining3Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT3(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [2])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enableGags(1)
        base.localAvatar.showGagButton()
        base.localAvatar.startTrackAnimToSpeed()

    def exitTrainingPT3(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disableGags()
        base.localAvatar.stopTrackAnimToSpeed()
        base.localAvatar.hideGagButton()
        return

    def enterTrainingDone(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTrainingDoneSpeech()

    def __finishedReadingGuideTrainingDoneSpeech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('leaveTutorial')

    def doNextTrainingDoneSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_DONE):
            self.__finishedReadingGuideTrainingDoneSpeech()
            return
        self.guide.setChat(self.GUIDE_DONE[self.chatIndex])
        Sequence(
            Wait(0.1),
            Func(self.acceptOnce, 'mouse1-up',
                 self.doNextTrainingDoneSpeech)).start()

    def exitTrainingDone(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterLeaveTutorial(self):
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.b_setAnimState('teleportOut',
                                        callback=self.__teleOutDone)

    def __teleOutDone(self):
        zoneId = CIGlobals.ToontownCentralId
        hoodId = CIGlobals.ToontownCentral
        whereName = 'playground'
        avId = base.localAvatar.doId
        loaderName = 'safeZoneLoader'
        self.sendUpdate('finishedTutorial')
        self.cr.playGame.load()
        self.cr.playGame.enter(hoodId, zoneId, base.localAvatar.doId)

    def exitLeaveTutorial(self):
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        base.transitions.fadeScreen(0.0)
        self.guide = Toon(base.cr)
        self.guide.autoClearChat = False
        self.guide.parseDNAStrand(NPCGlobals.NPC_DNA[self.GUIDE_NAME])
        self.guide.setName(self.GUIDE_NAME)
        self.guide.generateToon()
        self.guide.nametag.setNametagColor(
            NametagGlobals.NametagColors[NametagGlobals.CCNPC])
        self.guide.nametag.setActive(0)
        self.guide.nametag.updateAll()
        self.guide.startBlink()
        self.guide.reparentTo(render)
        base.localAvatar.reparentTo(render)
        loader.loadDNAFile(self.dnaStore,
                           'phase_3.5/dna/storage_tutorial.pdna')
        node = loader.loadDNAFile(self.dnaStore,
                                  'phase_3.5/dna/tutorial_street.pdna')
        if node.getNumParents() == 1:
            self.streetGeom = NodePath(node.getParent(0))
            self.streetGeom.reparentTo(hidden)
        else:
            self.streetGeom = hidden.attachNewNode(node)
        self.streetGeom.flattenMedium()
        gsg = base.win.getGsg()
        if gsg:
            self.streetGeom.prepareScene(gsg)
        self.streetGeom.reparentTo(render)
        self.streetGeom.setPos(20.5, -20, 0)
        self.streetGeom.setH(90)
        self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam')
        self.skyUtil.startSky(self.sky)
        self.sky.reparentTo(camera)
        ce = CompassEffect.make(NodePath(),
                                CompassEffect.PRot | CompassEffect.PZ)
        self.sky.node().setEffect(ce)
        self.music = base.loadMusic('phase_3.5/audio/bgm/TC_SZ.mid')
        base.playMusic(self.music, volume=0.8, looping=1)
        self.battleMusic = base.loadMusic(
            'phase_3.5/audio/bgm/encntr_general_bg.mid')
        self.fsm.request('newPlayerEmerge')
        base.localAvatar.inTutorial = True

    def disable(self):
        self.fsm.requestFinalState()
        del self.fsm
        if self.guide:
            self.guide.disable()
            self.guide.delete()
            self.guide = None
        if self.streetGeom:
            self.streetGeom.removeNode()
            self.streetGeom = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.music:
            self.music.stop()
            self.music = None
        if self.battleMusic:
            self.battleMusic.stop()
            self.battleMusic = None
        self.dnaStore.reset_nodes()
        self.dnaStore.reset_hood_nodes()
        self.dnaStore.reset_place_nodes()
        self.dnaStore.reset_hood()
        self.dnaStore.reset_fonts()
        self.dnaStore.reset_DNA_vis_groups()
        self.dnaStore.reset_textures()
        self.dnaStore.reset_block_numbers()
        self.dnaStore.reset_block_zones()
        self.dnaStore.reset_suit_points()
        self.dnaStore = None
        self.skyUtil = None
        base.localAvatar.inTutorial = False
        DistributedObject.disable(self)
        return
コード例 #5
0
class DistributedTutorial(DistributedObject):
    notify = directNotify.newCategory('DistributedTutorial')
    GUIDE_NAME = 'Professor Prepostera'
    GUIDE_START_POS = (5, 10, -0.5)
    GUIDE_WATCH_POS = (12.4, 27.92, 0)
    GUIDE_WATCH_HPR = (41.63, 0, 0)
    GUIDE_INTRO_SPEECH = ['Hey, looks like you made it!',
     'So, welcome to OToontown.',
     'OToontown is short for Old Toontown, or Toontown from the past.',
     'Not long ago, Toons used to live present day Toontown.',
     'Unfortunately, the Cogs planned a mega-invasion that was sure to be a complete takeover of Toontown and make all Toons go sad for good.',
     "There was no way we could have let that happen, so we built a time machine, and sent every Toon back in time to OToontown, where Cogs didn't exist yet.",
     'The Cogs completely took over present day Toontown, and turned it into what they wanted it to be - a business metropolis.',
     'Toons happily live and play in OToontown now, but we want to learn about present day Toontown...',
     ' ...or as we now call it, CogTropolis.',
     "We've built time machines that send Toons back to CogTropolis to fight Cogs and to see what the Cogs have done.",
     "We know that the Cogs took over Toontown and turned it into a grey business city, but we don't know how they did it.",
     'Shopkeepers around OToontown will reward you for finding evidence that may help solve the mystery of how the Cogs turned Toontown into CogTropolis.',
     'Before you are able to head to CogTropolis, you need to be trained for battle.',
     'The Cogs have become much more skilled battlers and no longer wait for you to throw a gag before attacking you.',
     'This is much more difficult for Toons, and it may take some time to get used to.',
     "I'm going to give you 4 gags to start...",
     'A Toon-Up megaphone, a cupcake, a fruit pie slice, and a cream pie slice.',
     'Equip Gags in your loadout to use by pressing the corresponding key on your keyboard.',
     'You can use or throw the Gag that you have equipped by pressing the Delete key...',
     ' ...or by pressing the Throw Gag button at the top of your screen.',
     'Also, use the Arrow Keys on your keyboard to move, and press CTRL to jump.',
     "I'm going to summon one of our dummy bots for you to practice battling.",
     "Click your mouse when you're ready."]
    GUIDE_PT2_INFO = ["Now it'll get a tad bit tougher.",
     'This next dummy bot will be walking around.',
     'This will test your aiming skills.',
     "Click your mouse when you're ready."]
    GUIDE_PT3_INFO = ['This final dummy bot will walk around and try to attack you at times.', 'Defeat this Cog, and you should be ready to go.']
    GUIDE_DONE = ['Wow, you did great!', "You're definitely ready for battle in CogTropolis.", 'Click your mouse to head to OToontown.']
    GUIDE_START_TRAINING = "Alright! Let's do this!"

    def __init__(self, cr):
        DistributedObject.__init__(self, cr)
        self.fsm = ClassicFSM.ClassicFSM('TutorialFSM', [State.State('off', self.enterOff, self.exitOff),
         State.State('newPlayerEmerge', self.enterPlayerEmerge, self.exitPlayerEmerge, ['off', 'introSpeech']),
         State.State('introSpeech', self.enterGuideIntroSpeech, self.exitGuideIntroSpeech, ['off', 'introSpeech2Training']),
         State.State('introSpeech2Training', self.enterIntroSpeech2Training, self.exitIntroSpeech2Training, ['off', 'training1']),
         State.State('training1', self.enterTrainingPT1, self.exitTrainingPT1, ['off', 'training2info']),
         State.State('training2info', self.enterTraining2Info, self.exitTraining2Info, ['off', 'training2']),
         State.State('training2', self.enterTrainingPT2, self.exitTrainingPT2, ['off', 'training3info']),
         State.State('training3info', self.enterTraining3Info, self.exitTraining3Info, ['off', 'training3']),
         State.State('training3', self.enterTrainingPT3, self.exitTrainingPT3, ['off', 'trainingDone']),
         State.State('trainingDone', self.enterTrainingDone, self.exitTrainingDone, ['off', 'leaveTutorial']),
         State.State('leaveTutorial', self.enterLeaveTutorial, self.exitLeaveTutorial, ['off'])], 'off', 'off')
        self.fsm.enterInitialState()
        self.dnaStore = DNAStorage()
        self.streetGeom = None
        self.sky = None
        self.skyUtil = SkyUtil()
        self.guide = None
        self.music = None
        self.battleMusic = None
        self.playerCamPos = None
        self.playerCamHpr = None
        return

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def introStuff(self):
        base.localAvatar.getGeomNode().hide()
        base.localAvatar.setPos(0, 0, -0.5)
        base.localAvatar.setHpr(0, 0, 0)
        self.guide.setPos(self.GUIDE_START_POS)
        self.guide.headsUp(base.localAvatar)
        base.localAvatar.attachCamera()

    def enterPlayerEmerge(self):
        self.introStuff()
        self.guide.loop('neutral')
        base.transitions.irisIn()
        base.taskMgr.doMethodLater(1.0, self.__playerEmerge, 'playerEmergeTask')

    def __playerEmerge(self, task):
        base.localAvatar.setAnimState('teleportIn', callback=self.__playerEmergeFinished)
        return Task.done

    def __playerEmergeFinished(self):
        base.localAvatar.setAnimState('neutral')
        self.fsm.request('introSpeech')

    def exitPlayerEmerge(self):
        base.localAvatar.detachCamera()
        base.taskMgr.remove('playerEmergeTask')
        base.transitions.noTransitions()

    def enterGuideIntroSpeech(self):
        base.localAvatar.attachCamera()
        renderPos = base.camera.getPos(render)
        renderHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        endPos = base.localAvatar.getPos(render) + (0, 0, 4)
        base.camera.setPos(endPos)
        base.camera.lookAt(self.guide, 0, 0, 3)
        endHpr = base.camera.getHpr(render)
        base.camera.setPos(renderPos)
        base.camera.setHpr(renderHpr)
        self.chatIndex = -1
        self.doNextIntroSpeech()
        self.camMoveTrack = Sequence(Parallel(LerpPosInterval(base.camera, duration=3.0, pos=endPos, startPos=renderPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=3.0, hpr=endHpr, startHpr=renderHpr, blendType='easeOut')), Func(base.localAvatar.getGeomNode().hide))
        self.camMoveTrack.start()

    def __finishedReadingGuideIntroSpeech(self):
        self.guide.autoClearChat = True
        self.guide.setChat(self.GUIDE_START_TRAINING)
        self.fsm.request('introSpeech2Training')

    def doNextIntroSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_INTRO_SPEECH):
            self.__finishedReadingGuideIntroSpeech()
            return
        self.guide.setChat(self.GUIDE_INTRO_SPEECH[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextIntroSpeech)).start()

    def exitGuideIntroSpeech(self):
        self.camMoveTrack.finish()
        base.localAvatar.getGeomNode().show()
        del self.camMoveTrack
        del self.chatIndex

    def enterIntroSpeech2Training(self):
        startCamPos = base.camera.getPos(render)
        startCamHpr = base.camera.getHpr(render)
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        base.localAvatar.attachCamera()
        endCamPos = base.camera.getPos(render)
        endCamHpr = base.camera.getHpr(render)
        base.localAvatar.detachCamera()
        startHpr = self.guide.getHpr(render)
        self.guide.headsUp(self.GUIDE_WATCH_POS)
        endHpr = self.guide.getHpr(render)
        self.guide.loop('run')
        self.camMoveIval = Parallel(LerpPosInterval(base.camera, duration=2.0, pos=endCamPos, startPos=startCamPos, blendType='easeOut'), LerpQuatInterval(base.camera, duration=2.0, hpr=endCamHpr, startHpr=startCamHpr, blendType='easeOut'), Sequence(LerpPosInterval(self.guide, duration=2.0, pos=self.GUIDE_WATCH_POS, startPos=self.guide.getPos(render)), Func(self.guide.loop, 'walk'), LerpHprInterval(self.guide, duration=1.0, hpr=self.GUIDE_WATCH_HPR, startHpr=endHpr), Func(self.guide.loop, 'neutral')), LerpHprInterval(self.guide, duration=1.0, hpr=endHpr, startHpr=startHpr))
        self.camMoveIval.setDoneEvent('introSpeech2TrainingDone')
        self.acceptOnce('introSpeech2TrainingDone', self.__handleIS2TDone)
        self.camMoveIval.start()

    def __handleIS2TDone(self):
        self.fsm.request('training1')

    def exitIntroSpeech2Training(self):
        self.ignore('introSpeech2TrainingDone')
        self.camMoveIval.finish()
        del self.camMoveIval

    def enterTrainingPT1(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [0])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enablePies(1)
        Whisper().createSystemMessage('This should be pretty simple. Just throw a gag at this dummy bot to defeat it.')

    def suitNoHealth(self, index):
        if index == 0:
            Whisper().createSystemMessage('Good job, {0}!'.format(base.localAvatar.getName()))
        elif index == 1:
            Whisper().createSystemMessage("Wow, you're doing very well!")

    def suitExploded(self, index):
        if index == 0:
            Whisper().createSystemMessage('Pick up the jellybean that he dropped. You can use them to buy more gags for your Toon.')
        self.battleMusic.stop()
        base.playMusic(self.music, looping=1, volume=0.8)

    def pickedUpJellybean(self):
        if self.fsm.getCurrentState().getName() == 'training1':
            self.fsm.request('training2info')
        elif self.fsm.getCurrentState().getName() == 'training2':
            self.fsm.request('training3info')
        elif self.fsm.getCurrentState().getName() == 'training3':
            self.fsm.request('trainingDone')

    def exitTrainingPT1(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disablePies()
        return

    def enterTraining2Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining2Speech()

    def __finishedReadingGuideTraining2Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training2')

    def doNextTraining2Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT2_INFO):
            self.__finishedReadingGuideTraining2Speech()
            return
        self.guide.setChat(self.GUIDE_PT2_INFO[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining2Speech)).start()

    def exitTraining2Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT2(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [1])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enablePies(1)

    def exitTrainingPT2(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disablePies()
        return

    def enterTraining3Info(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTraining3Speech()

    def __finishedReadingGuideTraining3Speech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('training3')

    def doNextTraining3Speech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_PT3_INFO):
            self.__finishedReadingGuideTraining3Speech()
            return
        self.guide.setChat(self.GUIDE_PT3_INFO[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTraining3Speech)).start()

    def exitTraining3Info(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterTrainingPT3(self):
        self.music.stop()
        base.playMusic(self.battleMusic, volume=0.8, looping=1)
        self.sendUpdate('makeSuit', [2])
        base.localAvatar.startPosHprBroadcast()
        base.localAvatar.d_broadcastPositionNow()
        base.localAvatar.startBlink()
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.collisionsOn()
        base.localAvatar.enableAvatarControls()
        base.localAvatar.enablePies(1)

    def exitTrainingPT3(self):
        base.localAvatar.lastState = None
        base.localAvatar.disableAvatarControls()
        base.localAvatar.detachCamera()
        base.localAvatar.stopSmartCamera()
        base.localAvatar.stopPosHprBroadcast()
        base.localAvatar.stopBlink()
        base.localAvatar.collisionsOff()
        base.localAvatar.controlManager.placeOnFloor()
        base.localAvatar.disablePies()
        return

    def enterTrainingDone(self):
        base.camera.setPos(3.09, 37.16, 3.93)
        base.camera.setHpr(225, 0, 0)
        self.guide.autoClearChat = False
        self.chatIndex = -1
        self.doNextTrainingDoneSpeech()

    def __finishedReadingGuideTrainingDoneSpeech(self):
        self.guide.autoClearChat = True
        self.guide.clearChat()
        self.fsm.request('leaveTutorial')

    def doNextTrainingDoneSpeech(self):
        self.chatIndex += 1
        if self.chatIndex >= len(self.GUIDE_DONE):
            self.__finishedReadingGuideTrainingDoneSpeech()
            return
        self.guide.setChat(self.GUIDE_DONE[self.chatIndex])
        Sequence(Wait(0.1), Func(self.acceptOnce, 'mouse1-up', self.doNextTrainingDoneSpeech)).start()

    def exitTrainingDone(self):
        base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        del self.chatIndex

    def enterLeaveTutorial(self):
        base.localAvatar.attachCamera()
        base.localAvatar.startSmartCamera()
        base.localAvatar.b_setAnimState('teleportOut', callback=self.__teleOutDone)

    def __teleOutDone(self):
        zoneId = CIGlobals.ToontownCentralId
        hoodId = CIGlobals.ToontownCentral
        whereName = 'playground'
        avId = base.localAvatar.doId
        loaderName = 'safeZoneLoader'
        self.sendUpdate('finishedTutorial')
        self.cr.playGame.fsm.request('quietZone', [{'zoneId': zoneId,
          'hoodId': hoodId,
          'where': whereName,
          'how': 'teleportIn',
          'avId': avId,
          'shardId': None,
          'loader': loaderName}])
        return

    def exitLeaveTutorial(self):
        base.localAvatar.stopSmartCamera()
        base.localAvatar.detachCamera()

    def announceGenerate(self):
        DistributedObject.announceGenerate(self)
        base.transitions.fadeScreen(0.0)
        self.guide = Toon(base.cr)
        self.guide.autoClearChat = False
        self.guide.parseDNAStrand(NPCGlobals.NPC_DNA[self.GUIDE_NAME])
        self.guide.setName(self.GUIDE_NAME)
        self.guide.generateToon()
        self.guide.startBlink()
        self.guide.reparentTo(render)
        base.localAvatar.reparentTo(render)
        loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/storage_tutorial.dna')
        node = loader.loadDNAFile(self.dnaStore, 'phase_3.5/dna/tutorial_street.dna')
        if node.getNumParents() == 1:
            self.streetGeom = NodePath(node.getParent(0))
            self.streetGeom.reparentTo(hidden)
        else:
            self.streetGeom = hidden.attachNewNode(node)
        self.streetGeom.flattenMedium()
        gsg = base.win.getGsg()
        if gsg:
            self.streetGeom.prepareScene(gsg)
        self.streetGeom.reparentTo(render)
        self.streetGeom.setPos(20.5, -20, 0)
        self.streetGeom.setH(90)
        self.sky = loader.loadModel('phase_3.5/models/props/TT_sky.bam')
        self.skyUtil.startSky(self.sky)
        self.sky.reparentTo(camera)
        ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ)
        self.sky.node().setEffect(ce)
        self.music = base.loadMusic('phase_3.5/audio/bgm/TC_SZ.mid')
        base.playMusic(self.music, volume=0.8, looping=1)
        self.battleMusic = base.loadMusic('phase_3.5/audio/bgm/encntr_general_bg.mid')
        self.fsm.request('newPlayerEmerge')
        base.localAvatar.inTutorial = True

    def disable(self):
        self.fsm.requestFinalState()
        del self.fsm
        if self.guide:
            self.guide.disable()
            self.guide.delete()
            self.guide = None
        if self.streetGeom:
            self.streetGeom.removeNode()
            self.streetGeom = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.music:
            self.music.stop()
            self.music = None
        if self.battleMusic:
            self.battleMusic.stop()
            self.battleMusic = None
        self.dnaStore = None
        self.skyUtil = None
        base.localAvatar.inTutorial = False
        DistributedObject.disable(self)
        return
コード例 #6
0
class CharSelection(DirectObject):
    notify = directNotify.newCategory('CharSelection')

    STAGE_TOON_POS = (66.4, 74.47, -25)
    STAGE_TOON_HPR = (227.73, 0, 0)

    NO_TOON = "Empty Slot"
    PLAY = "Play"
    CREATE = "Create"
    TITLE = "Pick  A  Toon  To  Play"

    def __init__(self, avChooser):
        self.avChooser = avChooser
        self.choice = None
        self.charList = None
        self.charNameLabel = None
        self.charButtons = []
        self.playOrCreateButton = None
        self.deleteButton = None
        self.quitButton = None
        self.world = None
        self.sky = None
        self.fog = None
        self.title = None
        self.stageToon = None
        self.deleteConf = None
        self.frame = None
        self.selectionFSM = ClassicFSM.ClassicFSM(
            'CharSelection',
            [
                State.State('off', self.enterOff, self.exitOff),
                State.State('character', self.enterCharSelected, self.exitCharSelected),
                State.State('empty', self.enterEmptySelected, self.exitEmptySelected)
            ],
            'off', 'off'
        )
        self.selectionFSM.enterInitialState()

    def __setupStageToon(self):
        self.stageToon = Toon(base.cr)
        self.stageToon.setPos(self.STAGE_TOON_POS)
        self.stageToon.setHpr(self.STAGE_TOON_HPR)

    def cleanupStageToon(self):
        if self.stageToon != None:
            self.stageToon.disable()
            self.stageToon.delete()
            self.stageToon = None

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def enterCharSelected(self, slot):
        self.choice = self.avChooser.getAvChoiceBySlot(slot)
        dna = self.choice.dna
        name = self.choice.name
        self.stageToon.setName(name)
        self.stageToon.setDNAStrand(dna)
        self.stageToon.nametag.setNametagColor(NametagGlobals.NametagColors[NametagGlobals.CCLocal])
        self.stageToon.nametag.setActive(0)
        self.stageToon.nametag.updateAll()
        self.stageToon.nametag.nametag3d.request('Rollover')
        self.stageToon.animFSM.request('neutral')
        self.stageToon.reparentTo(base.render)
        self.charNameLabel.setText(name)
        self.playOrCreateButton['text'] = self.PLAY
        self.playOrCreateButton['extraArgs'] = ['play']
        self.playOrCreateButton.show()
        self.deleteButton.show()

    def exitCharSelected(self):
        self.stageToon.animFSM.requestFinalState()
        self.stageToon.deleteCurrentToon()
        self.stageToon.reparentTo(base.hidden)
        self.playOrCreateButton.hide()
        self.deleteButton.hide()
        self.choice = None

    def enterEmptySelected(self):
        self.charNameLabel.setText(self.NO_TOON)
        self.playOrCreateButton['text'] = self.CREATE
        self.playOrCreateButton['extraArgs'] = ['create']
        self.playOrCreateButton.show()

    def exitEmptySelected(self):
        self.playOrCreateButton.hide()

    def __action(self, action):
        for btn in self.charButtons:
            if btn['state'] == DGG.DISABLED:
                self.slot = btn.getPythonTag('slot')
                break
        func = None
        arg = None
        doFade = True
        if action == 'delete':
            func = self.deleteToon
            arg = self.choice.avId
            doFade = False
        elif action == 'play':
            func = self.playGame
            arg = self.choice.slot
        elif action == 'create':
            func = self.enterMAT
        elif action == 'quit':
            func = sys.exit
        if doFade:
            base.transitions.fadeOut(0.3)
            if arg != None:
                Sequence(Wait(0.31), Func(func, arg)).start()
            else:
                Sequence(Wait(0.31), Func(func)).start()
        else:
            if arg != None:
                func(arg)
            else:
                func()

    def playGame(self, slot):
        messenger.send("avChooseDone", [self.avChooser.getAvChoiceBySlot(slot)])

    def enterMAT(self):
        messenger.send("enterMakeAToon", [self.slot])

    def deleteToon(self, avId):
        # Show a confirmation message
        self.deleteConf = Dialog.GlobalDialog(
            message = 'This will delete {0} forever. Are you sure?'.format(self.avChooser.getNameFromAvId(avId)),
            style = Dialog.YesNo, doneEvent = 'deleteConfResponse', extraArgs = [avId])
        self.acceptOnce('deleteConfResponse', self.__handleDeleteConfResponse)
        self.deleteConf.show()

    def __handleDeleteConfResponse(self, avId):
        doneStatus = self.deleteConf.getValue()
        if doneStatus:
            # Alright, they pressed yes. No complaining to us.
            self.avChooser.avChooseFSM.request("waitForToonDelResponse", [avId])
        else:
            self.deleteConf.cleanup()
            self.deleteConf = None

    def __handleCharButton(self, slot):
        for btn in self.charButtons:
            if btn.getPythonTag('slot') == slot:
                btn['state'] = DGG.DISABLED
            else:
                btn['state'] = DGG.NORMAL
        if self.avChooser.hasToonInSlot(slot):
            self.selectionFSM.request('character', [slot])
        else:
            self.selectionFSM.request('empty')

    def load(self):
        base.cr.renderFrame()
        base.camLens.setMinFov(CIGlobals.DefaultCameraFov / (4./3.))

        self.__setupStageToon()
        holidayMgr = base.cr.holidayManager

        self.props = []
        self.world = loader.loadModel('phase_9/models/cogHQ/SellbotHQExterior.bam')
        self.world.reparentTo(base.render)
        self.world.setPos(0, 227.09, -25.36)
        self.sky = loader.loadModel('phase_9/models/cogHQ/cog_sky.bam')
        self.sky.setScale(1)
        self.sky.reparentTo(base.render)
        self.sky.find('**/InnerGroup').removeNode()
        self.fog = Fog('charSelectFog')
        self.fog.setColor(0.2, 0.2, 0.2)
        self.fog.setExpDensity(0.003)
        base.render.setFog(self.fog)
        
        # Let's fix the flickering doors.
        doors = self.world.find('**/doors').getChildren()
        
        for door in doors:
            for frameHole in door.findAllMatches('**/doorFrameHole*'): frameHole.removeNode()

        if holidayMgr.getHoliday() == HolidayType.CHRISTMAS:
            piles = {
                'half' : {'pos' : (57.28, 86.47, -25.00), 'hpr' : (46.79, 0, 0)},
                'full' : {'pos' : (71.23, 85.2, -25.00), 'hpr' : (290.82, 0, 0)},
                'half_2' : {'pos' : (-15, 128.69, -25), 'hpr' : (60.26, 0, 0)}
            }

            for pileType, info in piles.items():
                if '_' in pileType:
                    pileType = pileType[:-2]
                pile = loader.loadModel('phase_8/models/props/snow_pile_%s.bam' % (pileType))
                pile.reparentTo(render)
                pile.setPos(info['pos'])
                pile.setHpr(info['hpr'])
                self.props.append(pile)

            self.world.find('**/TopRocks').removeNode()

            snowTxt = loader.loadTexture('winter/maps/sbhq_snow.png')
            self.world.find('**/Ground').setTexture(snowTxt, 1)

            self.particles = ParticleLoader.loadParticleEffect('phase_8/etc/snowdisk.ptf')
            self.particles.setPos(0, 0, 5)
            self.particlesRender = self.world.attachNewNode('snowRender')
            self.particlesRender.setDepthWrite(0)
            self.particlesRender.setBin('fixed', 1)
            self.particles.start(parent = camera, renderParent = self.particlesRender)
            self.fog.setColor(0.486, 0.784, 1)
            self.fog.setExpDensity(0.006)
            base.render.setFog(self.fog)


        self.title = DirectLabel(text=self.TITLE, text_font=CIGlobals.getMickeyFont(), text_fg=(1, 0.9, 0.1, 1),
                                relief=None, text_scale=0.13, pos=(0, 0, 0.82))
        self.charNameLabel = OnscreenText(text = "", font = CIGlobals.getMickeyFont(),
                                        pos = (-0.25, 0.5, 0), fg = (1, 0.9, 0.1, 1.0))
        self.charNameLabel.hide()
        self.frame = DirectFrame()
        self.frame['image'] = DGG.getDefaultDialogGeom()
        self.frame['image_color'] = CIGlobals.DialogColor
        self.frame['image_scale'] = (-0.9, -0.9, 0.8)
        self.frame['image_pos'] = (0.82, 0, -0.125)
        self.playOrCreateButton = DirectButton(text = "", pos = (0.8125, 0, -0.35), command = self.__action,
                                            geom = CIGlobals.getDefaultBtnGeom(), text_scale = 0.06,
                                            relief = None, text_pos = (0, -0.01))
        self.playOrCreateButton.hide()
        self.deleteButton = DirectButton(text = "Delete", pos = (0.8125, 0, -0.45),
                                        command = self.__action, extraArgs = ['delete'],
                                        geom = CIGlobals.getDefaultBtnGeom(), text_scale = 0.06,
                                        relief = None, text_pos = (0, -0.01))
        self.deleteButton.hide()
        self.quitButton = DirectButton(text = "Quit", pos = (-1.10, 0, -0.925), command = self.__action,
                                    extraArgs = ['quit'], text_scale = 0.06, geom = CIGlobals.getDefaultBtnGeom(),
                                    relief = None, text_pos = (0, -0.01))

        textRolloverColor = Vec4(1, 1, 0, 1)
        textDownColor = Vec4(0.5, 0.9, 1, 1)
        textDisabledColor = Vec4(0.4, 0.8, 0.4, 1)

        for slot in range(6):
            if self.avChooser.hasToonInSlot(slot):
                choice = self.avChooser.getAvChoiceBySlot(slot)
                text = choice.name
            else:
                text = self.NO_TOON
            btn = DirectButton(
                relief=None, text = text, text_scale=0.06,
                text_align=TextNode.ALeft, text1_bg=textDownColor, text2_bg=textRolloverColor,
                text3_fg=textDisabledColor, textMayChange=0, command=self.__handleCharButton,
                extraArgs=[slot], text_pos = (0, 0, 0.0)
            )
            btn.setPythonTag('slot', slot)
            self.charButtons.append(btn)
            btn['state'] = DGG.NORMAL

        gui = loader.loadModel('phase_3.5/models/gui/friendslist_gui.bam')
        listXorigin = -0.02
        listFrameSizeX = 0.625
        listZorigin = -0.43
        listFrameSizeZ = 0.51
        arrowButtonScale = 0.0
        itemFrameXorigin = -0.237
        itemFrameZorigin = 0.365
        buttonXstart = itemFrameXorigin + 0.293

        self.charList = DirectScrolledList(
            relief=None,
            pos=(0.75, 0, -0.225),
            incButton_image=None,
            #incButton_relief=None,
            incButton_scale=(arrowButtonScale, arrowButtonScale, -arrowButtonScale),
            #incButton_pos=(buttonXstart, 0, itemFrameZorigin - 0.999),
            #incButton_image3_color=Vec4(1, 1, 1, 0.2),
            decButton_image=None,
            #decButton_relief=None,
            decButton_scale=(arrowButtonScale, arrowButtonScale, arrowButtonScale),
            #decButton_pos=(buttonXstart, 0, itemFrameZorigin + 0.125),
            #decButton_image3_color=Vec4(1, 1, 1, 0.2),
            itemFrame_pos=(itemFrameXorigin, 0, itemFrameZorigin),
            itemFrame_scale=1.0,
            itemFrame_relief=DGG.SUNKEN,
            itemFrame_frameSize=(listXorigin,
                listXorigin + listFrameSizeX,
                listZorigin,
                listZorigin + listFrameSizeZ),
            itemFrame_frameColor=(0.85, 0.95, 1, 1),
            itemFrame_borderWidth=(0.01, 0.01),
            numItemsVisible=15,
            forceHeight=0.075,
            items=self.charButtons,
            parent = self.frame
        )

        base.camera.setPos(75.12, 63.22, -23)
        base.camera.setHpr(26.57, 9.62, 0)

    def unload(self):
        self.selectionFSM.requestFinalState()
        self.cleanupStageToon()
        self.choice = None
        if self.frame:
            self.frame.destroy()
            self.frame = None
        if self.charButtons:
            for btn in self.charButtons:
                btn.destroy()
            self.charButtons = None
        if self.deleteConf:
            self.deleteConf.cleanup()
            self.deleteConf = None
        if self.charList:
            self.charList.destroy()
            self.charList = None
        if self.charNameLabel:
            self.charNameLabel.destroy()
            self.charNameLabel = None
        if self.playOrCreateButton:
            self.playOrCreateButton.destroy()
            self.playOrCreateButton = None
        if self.deleteButton:
            self.deleteButton.destroy()
            self.deleteButton = None
        if self.quitButton:
            self.quitButton.destroy()
            self.quitButton = None
        if self.sky:
            self.sky.removeNode()
            self.sky = None
        if self.world:
            self.world.removeNode()
            self.world = None
        if self.title:
            self.title.destroy()
            self.title = None
        for prop in self.props:
            if not prop.isEmpty():
                prop.removeNode()
        self.props = None
        if hasattr(self, 'particles'):
            self.particles.cleanup()
            self.particlesRender.removeNode()
            self.particles = None
            del self.particlesRender
        base.render.clearFog()
        self.fog = None
        base.camera.setPos(0, 0, 0)
        base.camera.setHpr(0, 0, 0)
        base.transitions.noTransitions()
        del self.selectionFSM