Ejemplo n.º 1
0
class GagSelectionGui(DirectFrame, FSM):
    InactivityTime = 5.0

    AmmoZSelect = -0.15
    AmmoZIdle = 0.035

    def __init__(self):
        DirectFrame.__init__(self,
                             parent=aspect2d,
                             pos=(0, 0, 0.93),
                             scale=0.7)
        FSM.__init__(self, 'GagSelectionGui')
        self.setTransparency(TransparencyAttrib.MDual)
        self.tracks = []
        self.currentTrack = 0
        self.currentGag = None
        self.fwdShakeIval = None
        self.revShakeIval = None
        self.newTrackSound = None
        self.keyScrollSound = None
        self.selectSound = None
        self.selectDenySound = None
        self.lastActivityTime = 0.0
        self.activityTask = None
        self.midpoint = 0.0

        self.ammoFrame = DirectFrame(parent=self,
                                     pos=(0, 0, -0.2),
                                     image='phase_14/maps/status_bar.png',
                                     image_scale=(0.461 * 0.7, 0, 0.098),
                                     relief=None)
        self.ammoFrame.hide()
        self.ammoTitle = OnscreenText(parent=self.ammoFrame,
                                      text='SUPPLY',
                                      fg=(0, 0, 0, 0.65),
                                      align=TextNode.ALeft,
                                      pos=(-0.37 * 0.7, -0.015, 0))
        self.ammoText = OnscreenText(parent=self.ammoFrame,
                                     text='',
                                     fg=(1, 1, 1, 1),
                                     shadow=(0, 0, 0, 1),
                                     align=TextNode.ARight,
                                     pos=(0.37 * 0.7, -0.015, 0))

    def update(self):
        plyr = base.localAvatar

        if not base.localAvatar.hasAttacks():
            return

        gagId = -1
        if self.getCurrentOrNextState() == 'Idle':
            gagId = plyr.getEquippedAttack()
        elif self.getCurrentOrNextState() == 'Select' and self.currentGag:
            gagId = self.currentGag.gagId

        if gagId != -1:
            self.ammoFrame.showThrough()
            if plyr.hasAttackId(gagId):
                self.ammoText.setText(
                    '%i/%i' %
                    (plyr.getAttackAmmo(gagId), plyr.getAttackMaxAmmo(gagId)))
            else:
                self.ammoText.setText('')
            col = GagGlobals.TrackColorByName[GagGlobals.getTrackOfGag(gagId)]
            self.ammoFrame['image_color'] = (col[0], col[1], col[2], 1.0)
        else:
            self.ammoFrame.hide()

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def hide(self):
        showAmmo = False
        if not self.ammoFrame.isHidden():
            showAmmo = True
        DirectFrame.hide(self)
        if showAmmo:
            self.ammoFrame.showThrough()

    def enterSelect(self):
        base.localAvatar.disableGagKeys()
        self.ammoFrame.setZ(self.AmmoZSelect)
        self.show()
        self.update()
        self.acceptSelectionClick()
        self.resetTimeout()
        self.activityTask = taskMgr.add(self.__activityTask, "activityTask")

    def acceptSelectionClick(self):
        self.accept('mouse1-up', self.selectCurrentGag)

    def ignoreSelectionClick(self):
        self.ignore('mouse1-up')

    def resetTimeout(self):
        self.lastActivityTime = globalClock.getFrameTime()

    def __activityTask(self, task):
        time = globalClock.getFrameTime()
        if time - self.lastActivityTime >= self.InactivityTime:
            self.request('Idle')
            return task.done
        return task.cont

    def exitSelect(self):
        self.activityTask.remove()
        self.activityTask = None
        self.hide()
        self.ignoreSelectionClick()

    def enterIdle(self):
        self.ammoFrame.setZ(self.AmmoZIdle)
        self.hide()
        self.update()
        if base.localAvatar.avatarMovementEnabled:
            base.localAvatar.enableGagKeys()

    def exitIdle(self):
        pass

    def disable(self):
        self.disableControls()
        self.hide()

    def enable(self):
        self.enableControls()
        self.show()

    def cleanup(self):
        self.request('Off')

        self.disableControls()

        self.newTrackSound = None
        self.keyScrollSound = None
        self.selectSound = None
        self.selectDenySound = None

        if self.fwdShakeIval:
            self.fwdShakeIval.finish()
            self.fwdShakeIval = None
        if self.revShakeIval:
            self.revShakeIval.finish()
            self.revShakeIval = None
        self.currentTrack = None
        self.currentGag = None
        if self.tracks:
            for track in self.tracks:
                track.cleanup()
        self.tracks = None

        self.destroy()

    def __accumulateTracks(self):
        tracks = []
        for gagId in base.localAvatar.attacks.keys():
            trackId = GagGlobals.getTrackOfGag(gagId, getId=True)
            if trackId not in tracks:
                tracks.append(trackId)
        tracks.sort()
        return tracks

    def load(self):
        tracks = self.__accumulateTracks()
        for i in xrange(len(tracks)):
            track = GagTrack(self, tracks[i])
            track.load()
            track.reparentTo(self)
            track.setX(FRAME_OFFSET * i)
            self.tracks.append(track)

        self.midpoint = (len(self.tracks) / 2.0) * -FRAME_OFFSET
        # Center the gui horizontally
        self.setX(self.midpoint)
        self.ammoFrame.setX(-self.midpoint)

        if base.config.GetBool('gsg-want-hlsounds', False):
            self.newTrackSound = base.loadSfx(
                "phase_14/audio/sfx/wpn_hudon.ogg")
            self.keyScrollSound = base.loadSfx(
                'phase_14/audio/sfx/wpn_moveselect.ogg')
            self.selectSound = base.loadSfx(
                'phase_14/audio/sfx/wpn_select.ogg')
            self.selectDenySound = base.loadSfx(
                'phase_14/audio/sfx/wpn_denyselect.ogg')
        else:
            self.newTrackSound = base.loadSfx(
                "phase_3/audio/sfx/GUI_create_toon_back.ogg")
            self.keyScrollSound = base.loadSfx(
                'phase_3/audio/sfx/GUI_rollover.ogg')
            self.selectSound = base.loadSfx(
                'phase_3/audio/sfx/GUI_create_toon_fwd.ogg')
            self.selectDenySound = base.loadSfx(
                'phase_4/audio/sfx/ring_miss.ogg')

        self.fwdShakeIval = Effects.createXBounce(self, 1,
                                                  Vec3(self.midpoint, 0, 0.93),
                                                  0.05, 0.05)
        self.revShakeIval = Effects.createXBounce(self, 1,
                                                  Vec3(self.midpoint, 0, 0.93),
                                                  0.05, -0.05)

        if base.localAvatar.hasAttacks():
            self.updateCurrentTrack(0)

    def enableControls(self):
        self.accept('wheel_up', self.__handleScrollUp)
        self.accept('wheel_down', self.__handleScrollDown)

        for i in xrange(len(self.tracks)):
            self.accept(str(i + 1), self.__handleTrackChoose, [i])

        self.request('Idle')

    def selectCurrentGag(self):
        selected = False

        self.newTrackSound.stop()
        self.keyScrollSound.stop()

        if self.currentGag is not None:
            if base.localAvatar.getEquippedAttack() == self.currentGag.gagId:
                selected = True
            elif (not self.currentGag.locked and self.currentGag.hasAmmo()):
                gagId = self.currentGag.gagId
                base.localAvatar.needsToSwitchToGag = gagId
                if base.localAvatar.gagsTimedOut == False:
                    base.localAvatar.selectGag(gagId)
                    selected = True

        if not selected:
            # Denied!
            self.selectDenySound.play()
            self.resetTimeout()
        else:
            self.selectSound.play()
            self.request('Idle')

    def disableControls(self):
        self.ignore('wheel_up')
        self.ignore('wheel_down')

        for i in xrange(len(self.tracks)):
            self.ignore(str(i + 1))

        self.request('Idle')

    def __maybeDoSelect(self):
        if self.getCurrentOrNextState() == 'Idle':
            self.request('Select')

    def __handleTrackChoose(self, idx):
        if not base.localAvatar.hasAttacks():
            return

        self.__maybeDoSelect()
        self.resetTimeout()

        if self.currentTrack == idx:
            # Scroll through the current track.
            self.tracks[self.currentTrack].selectNextGag()

            self.newTrackSound.stop()
            self.keyScrollSound.play()
        else:
            # Always start from the beginning when using the keys to choose a track.
            self.updateCurrentTrack(idx, 0)
            self.newTrackSound.play()

    def __handleScrollUp(self):
        if not base.localAvatar.hasAttacks():
            return

        self.__maybeDoSelect()
        self.resetTimeout()

        track = self.tracks[self.currentTrack]
        if track.isOnFirstGag():
            self.prevTrack()
        else:
            track.selectPrevGag()

        self.newTrackSound.stop()
        self.keyScrollSound.play()

    def __handleScrollDown(self):
        if not base.localAvatar.hasAttacks():
            return

        self.__maybeDoSelect()
        self.resetTimeout()

        track = self.tracks[self.currentTrack]
        if track.isOnLastGag():
            self.nextTrack()
        else:
            track.selectNextGag()

        self.newTrackSound.stop()
        self.keyScrollSound.play()

    def nextTrack(self):
        newIdx = self.currentTrack + 1
        if newIdx > len(self.tracks) - 1:
            newIdx = 0

        self.updateCurrentTrack(newIdx)

    def prevTrack(self):
        newIdx = self.currentTrack - 1
        if newIdx < 0:
            newIdx = len(self.tracks) - 1

        self.updateCurrentTrack(newIdx)

    def updateCurrentTrack(self, idx, startLoc=None):
        oldTrack = self.tracks[self.currentTrack]
        oldTrack.deselectAll()
        oldTrack.stashContents()

        if idx - self.currentTrack < 0:
            direction = 1
        else:
            direction = 0

        if startLoc is None:
            startLoc = direction

        if direction == 0:
            self.fwdShakeIval.start()
        else:
            self.revShakeIval.start()

        self.currentTrack = idx

        # Resort the tracks
        numTracks = len(self.tracks)
        maxTrack = numTracks - 1
        for i in xrange(len(self.tracks)):
            track = self.tracks[i]

            if i == idx:
                sort = FRAME_FRONT_SORT
            elif i > idx:
                sort = FRAME_SORT_BEGIN + (maxTrack - i) * FRAME_SORT_DISTANCE
            elif i < idx:
                sort = FRAME_SORT_BEGIN + (i * FRAME_SORT_DISTANCE)
            track.setBin('gsg-popup', sort)

            if i == idx:
                track.unstashContents()
                if startLoc == 0:
                    track.selectFirstGag()
                else:
                    track.selectLastGag()
            else:
                track.stashContents()