Esempio n. 1
0
class FPSCamera(DirectObject):

    MaxP = 90.0
    MinP = -90.0
    PitchUpdateEpsilon = 0.1
    ViewModelFOV = 70.0

    BobCycleMin = 1.0
    BobCycleMax = 0.45
    Bob = 0.002
    BobUp = 0.5

    PunchDamping = 9.0
    PunchSpring = 65.0

    PrintAnimLengths = False

    def __init__(self):
        DirectObject.__init__(self)

        self.mouseEnabled = False

        self.lastCamRoot2Quat = Quat(Quat.identQuat())

        self.punchAngleVel = Vec3(0)
        self.punchAngle = Vec3(0)

        self.lastFacing = Vec3(0)

        self.lastMousePos = Point2(0)
        self.currMousePos = Point2(0)

        self.bobTime = 0
        self.lastBobTime = 0

        self.lastVMPos = Point3(0)

        self.camRoot = NodePath("camRoot")
        self.camRoot2 = self.camRoot.attachNewNode("camRoot2")
        self.lastPitch = 0

        self.lastEyeHeight = 0.0

        # Updates to the transform of camRoot
        self.vmRender = NodePath(
            BSPRender('vmRender', BSPLoader.getGlobalPtr()))
        self.vmRender.setShaderAuto()
        self.vmRoot = self.vmRender.attachNewNode('vmRoot')
        self.vmRoot2 = self.vmRoot.attachNewNode(ModelRoot('vmRoot2'))
        self.viewModel = Actor(
            "phase_14/models/char/v_toon_arms.bam",
            {
                "zero": "phase_14/models/char/v_toon_arms.egg",

                # Squirt gun viewmodel animations
                "sg_draw": "phase_14/models/char/v_toon_arms-draw.egg",
                "sg_idle": "phase_14/models/char/v_toon_arms-idle.egg",
                "sg_inspect": "phase_14/models/char/v_toon_arms-inspect.egg",
                "sg_shoot_begin":
                "phase_14/models/char/v_toon_arms-shoot_begin.egg",
                "sg_shoot_loop":
                "phase_14/models/char/v_toon_arms-shoot_loop.egg",
                "sg_shoot_end":
                "phase_14/models/char/v_toon_arms-shoot_end.egg",
                "pie_draw": "phase_14/models/char/v_toon_arms-pie_draw.egg",
                "pie_idle": "phase_14/models/char/v_toon_arms-pie_idle.egg",
                "button_draw":
                "phase_14/models/char/v_toon_arms-button_draw.egg",
                "button_idle":
                "phase_14/models/char/v_toon_arms-button_idle.egg",
                "button_press":
                "phase_14/models/char/v_toon_arms-button_press.egg",
                "gumball_draw":
                "phase_14/models/char/v_toon_arms-gumball_draw.egg",
                "gumball_idle":
                "phase_14/models/char/v_toon_arms-gumball_idle.egg",
                "gumball_fire":
                "phase_14/models/char/v_toon_arms-gumball_fire.egg",
                "hose_draw": "phase_14/models/char/v_toon_arms-hose_draw.egg",
                "hose_idle": "phase_14/models/char/v_toon_arms-hose_idle.egg",
                "hose_shoot_begin":
                "phase_14/models/char/v_toon_arms-hose_shoot_begin.egg",
                "hose_shoot_loop":
                "phase_14/models/char/v_toon_arms-hose_shoot_loop.egg",
                "hose_shoot_end":
                "phase_14/models/char/v_toon_arms-hose_shoot_end.egg",
                "tnt_draw": "phase_14/models/char/v_toon_arms-tnt_draw.egg",
                "tnt_idle": "phase_14/models/char/v_toon_arms-tnt_idle.egg",
                "tnt_throw": "phase_14/models/char/v_toon_arms-tnt_throw.egg",
                "slap_idle": "phase_14/models/char/v_toon_arms-slap_idle.egg",
                "slap_hit": "phase_14/models/char/v_toon_arms-slap_hit.egg",
                "sound": "phase_14/models/char/v_toon_arms-sound.egg"
            })
        self.viewModel.setBlend(
            frameBlend=base.config.GetBool("interpolate-frames", False))
        self.viewModel.reparentTo(self.vmRoot2)
        self.viewModel.find("**/hands").setTwoSided(True)
        self.viewModel.hide()

        self.defaultViewModel = self.viewModel
        self.idealFov = self.ViewModelFOV

        precacheActor(self.viewModel)
        #self.viewModel.clearMaterial()
        #self.viewModel.setMaterial(CIGlobals.getCharacterMaterial(specular = (0, 0, 0, 1)), 1)
        self.viewportLens = PerspectiveLens()
        self.viewportLens.setMinFov(self.ViewModelFOV / (4. / 3.))
        self.viewportLens.setNear(0.3)
        # Updates to the transform of base.camera
        self.viewportCam = base.makeCamera(base.win,
                                           clearDepth=True,
                                           camName='fpsViewport',
                                           mask=CIGlobals.ViewModelCamMask,
                                           lens=self.viewportLens)
        # Pretend to be the main camera so the viewmodel gets ambient probes updated
        self.viewportCam.node().setTag("__mainpass__", "1")
        self.viewportCam.reparentTo(self.vmRoot)

        self.vmGag = None
        self.vmAnimTrack = None
        self.dmgFade = OnscreenImage(image="phase_14/maps/damage_effect.png",
                                     parent=render2d)
        self.dmgFade.setBin('gui-popup', 100)
        self.dmgFade.setTransparency(1)
        self.dmgFade.setColorScale(1, 1, 1, 0)
        self.dmgFadeIval = None

        #self.accept('v', self.vmRender.ls)

        #base.bspLoader.addDynamicNode(self.vmRoot)

        if self.PrintAnimLengths:
            print "v_toon_arms animation lengths:"
            for anim in self.viewModel.getAnimNames():
                print "\t{0}\t:\t{1}".format(anim,
                                             self.viewModel.getDuration(anim))

        taskMgr.add(self.__vpDebugTask, "vpdebutask", sort=-100)

    def setViewModelFOV(self, fov):
        self.idealFov = fov

    def restoreViewModelFOV(self):
        self.idealFov = self.ViewModelFOV

    def swapViewModel(self, newViewModel, fov=70.0):
        if newViewModel.isEmpty():
            return

        isHidden = False
        if not self.viewModel.isEmpty():
            self.viewModel.reparentTo(hidden)
            isHidden = self.viewModel.isHidden()

        self.viewModel = newViewModel
        self.viewModel.reparentTo(self.vmRoot2)
        if isHidden:
            self.viewModel.hide()
        else:
            self.viewModel.show()

        self.setViewModelFOV(fov)

    def restoreViewModel(self):
        isHidden = False
        if not self.viewModel.isEmpty():
            self.viewModel.reparentTo(hidden)
            isHidden = self.viewModel.isHidden()

        self.viewModel = self.defaultViewModel
        self.viewModel.reparentTo(self.vmRoot2)
        if isHidden:
            self.viewModel.hide()
        else:
            self.viewModel.show()

        self.restoreViewModelFOV()

    def addViewPunch(self, punch):
        self.punchAngleVel += punch * 20

    def resetViewPunch(self, tolerance=0.0):
        if tolerance != 0.0:
            tolerance *= tolerance
            check = self.punchAngleVel.lengthSquared(
            ) + self.punchAngle.lengthSquared()
            if check > tolerance:
                return

        self.punchAngle = Vec3(0)
        self.punchAngleVel = Vec3(0)

    def decayPunchAngle(self):
        if self.punchAngle.lengthSquared(
        ) > 0.001 or self.punchAngleVel.lengthSquared() > 0.001:
            dt = globalClock.getDt()
            self.punchAngle += self.punchAngleVel * dt
            damping = 1 - (self.PunchDamping * dt)

            if damping < 0:
                damping = 0
            self.punchAngleVel *= damping

            # Torsional spring
            springForceMag = self.PunchSpring * dt
            springForceMag = CIGlobals.clamp(springForceMag, 0.0, 2.0)
            self.punchAngleVel -= self.punchAngle * springForceMag

            # Don't wrap around
            self.punchAngle.set(CIGlobals.clamp(self.punchAngle[0], -179, 179),
                                CIGlobals.clamp(self.punchAngle[1], -89, 89),
                                CIGlobals.clamp(self.punchAngle[2], -89, 89))
        else:
            self.punchAngle = Vec3(0)
            self.punchAngleVel = Vec3(0)

    def hideViewModel(self):
        self.viewModel.hide(BitMask32.allOn())

    def showViewModel(self):
        if not base.localAvatar.isFirstPerson():
            return

        self.viewModel.showThrough(CIGlobals.ViewModelCamMask)

    def __vpDebugTask(self, task):
        if self.vmRender.getState() != render.getState():
            # pretend like the view model is part of the main scene
            self.vmRender.setState(render.getState())

        self.viewportLens.setAspectRatio(base.getAspectRatio())
        self.viewportLens.setMinFov(self.idealFov / (4. / 3.))
        self.vmRoot.setTransform(render, self.camRoot.getTransform(render))
        self.viewportCam.setTransform(render, base.camera.getTransform(render))

        # Since the viewmodel is not underneath BSPRender, it's not going to be automatically
        # influenced by the ambient probes. We need to do this explicitly.
        #base.bspLoader.updateDynamicNode(self.vmRoot)

        #self.viewportDebug.setImage(self.viewportCam.node().getDisplayRegion(0).getScreenshot())

        return task.cont

    def handleSuitAttack(self, attack):
        print "FPSCamera handleSuitAttack:", attack

    def doDamageFade(self, r, g, b, severity=1.0):
        if self.dmgFadeIval:
            self.dmgFadeIval.finish()
            self.dmgFadeIval = None
        severity = min(1.0, severity)
        self.dmgFadeIval = Sequence(
            LerpColorScaleInterval(self.dmgFade,
                                   0.25, (r, g, b, severity), (r, g, b, 0),
                                   blendType='easeOut'), Wait(1.0),
            LerpColorScaleInterval(self.dmgFade,
                                   2.0, (r, g, b, 0), (r, g, b, severity),
                                   blendType='easeInOut'))
        self.dmgFadeIval.start()

    def setVMAnimTrack(self, track, loop=False):
        self.clearVMAnimTrack()

        self.vmAnimTrack = track
        if loop:
            self.vmAnimTrack.loop()
        else:
            self.vmAnimTrack.start()

    def clearVMAnimTrack(self):
        if self.vmAnimTrack:
            self.vmAnimTrack.pause()
            self.vmAnimTrack = None

    def setVMGag(self,
                 gag,
                 pos=(0, 0, 0),
                 hpr=(0, 0, 0),
                 scale=(1, 1, 1),
                 hand=0,
                 animate=True):
        self.clearVMGag()

        handNode = NodePath()
        if hand == ATTACK_HOLD_RIGHT:
            handNode = self.getViewModelRightHand()
        elif hand == ATTACK_HOLD_LEFT:
            handNode = self.getViewModelLeftHand()

        if isinstance(gag, Actor) and animate:
            self.vmGag = Actor(other=gag)
            self.vmGag.reparentTo(handNode)
            self.vmGag.loop('chan')
        else:
            self.vmGag = gag.copyTo(handNode)
        self.vmGag.setPos(pos)
        self.vmGag.setHpr(hpr)
        self.vmGag.setScale(scale)

    def clearVMGag(self):
        if self.vmGag:
            if isinstance(self.vmGag, Actor):
                self.vmGag.cleanup()
            self.vmGag.removeNode()
            self.vmGag = None

    def setup(self):
        try:
            # Match the arm color with the torso color of local avatar
            self.viewModel.find("**/arms").setColorScale(
                base.localAvatar.getTorsoColor(), 1)
            # Same with glove cover
            self.viewModel.find("**/hands").setColorScale(
                base.localAvatar.getGloveColor(), 1)
        except:
            pass

        self.attachCamera()

    def attachCamera(self, reset=True):
        if reset:
            self.camRoot.reparentTo(base.localAvatar)
            if base.localAvatar.isFirstPerson():
                self.camRoot.setPos(base.localAvatar.getEyePoint())
            else:
                self.camRoot.setPos(0, 0, max(base.localAvatar.getHeight(),
                                              3.0))
            self.camRoot.setHpr(0, 0, 0)
            self.camRoot2.setPosHpr(0, 0, 0, 0, 0, 0)

        base.camera.reparentTo(self.camRoot2)

        if base.localAvatar.isFirstPerson():
            base.camera.setPosHpr(0, 0, 0, 0, 0, 0)
        elif base.localAvatar.isThirdPerson():
            pos, lookAt = self.getThirdPersonBattleCam()
            base.localAvatar.smartCamera.setIdealCameraPos(pos)
            base.localAvatar.smartCamera.setLookAtPoint(lookAt)

    def getThirdPersonBattleCam(self):
        camHeight = max(base.localAvatar.getHeight(), 3.0)
        heightScaleFactor = camHeight * 0.3333333333

        return ((1, -5 * heightScaleFactor, 0), (1, 10, 0))

    def getViewModelLeftHand(self):
        return self.viewModel.find("**/def_left_hold")

    def getViewModelRightHand(self):
        return self.viewModel.find("**/def_right_hold")

    def getViewModel(self):
        return self.viewModel

    def acceptEngageKeys(self):
        self.acceptOnce("escape", self.__handleEscapeKey)

    def ignoreEngageKeys(self):
        self.ignore("escape")

    def enableMouseMovement(self):
        props = WindowProperties()
        props.setMouseMode(WindowProperties.MConfined)
        props.setCursorHidden(True)
        base.win.requestProperties(props)

        self.attachCamera(False)
        if base.localAvatar.isFirstPerson():
            base.localAvatar.getGeomNode().hide()

        base.win.movePointer(0,
                             base.win.getXSize() / 2,
                             base.win.getYSize() / 2)

        base.taskMgr.add(self.__updateTask, "mouseUpdateFPSCamera", sort=-40)
        self.acceptEngageKeys()

        self.mouseEnabled = True

        base.localAvatar.enableGagKeys()

    def disableMouseMovement(self, allowEnable=False, showAvatar=True):
        props = WindowProperties()
        props.setMouseMode(WindowProperties.MAbsolute)
        props.setCursorHidden(False)
        base.win.requestProperties(props)

        base.taskMgr.remove("mouseUpdateFPSCamera")

        base.localAvatar.disableGagKeys()

        if allowEnable:
            self.acceptEngageKeys()
        else:
            self.ignoreEngageKeys()
            if showAvatar or base.localAvatar.isThirdPerson():
                base.localAvatar.getGeomNode().show()
            else:
                base.localAvatar.getGeomNode().hide()

        self.mouseEnabled = False

    def __handleEscapeKey(self):
        if self.mouseEnabled:
            self.disableMouseMovement(True)
        else:
            self.enableMouseMovement()

    #def doCameraJolt(self, amplitude, horizRange = [-1, 1], vertRange = [1]):
    #h = random.choice(horizRange) * amplitude
    #p = random.choice(vertRange) * amplitude
    #nquat = Quat(Quat.identQuat())
    #nquat.setHpr((h, p, 0))
    #self.lastCamRoot2Quat = self.lastCamRoot2Quat + nquat

    #Effects.createPBounce(self.camRoot2, 3, self.camRoot2.getHpr(), 1, amplitude).start()
    #Effects.createHBounce(self.camRoot2, 3, self.camRoot2.getHpr(), 1, amplitude).start()

    def handleJumpHardLand(self):
        down = Parallel(
            LerpPosInterval(base.cam,
                            0.1, (-0.1, 0, -0.2), (0, 0, 0),
                            blendType='easeOut'),
            LerpHprInterval(base.cam,
                            0.1, (0, 0, -2.5), (0, 0, 0),
                            blendType='easeOut'))
        up = Parallel(
            LerpPosInterval(base.cam,
                            0.7, (0, 0, 0), (-0.1, 0, -0.2),
                            blendType='easeInOut'),
            LerpHprInterval(base.cam,
                            0.7, (0, 0, 0), (0, 0, -2.5),
                            blendType='easeInOut'))
        Sequence(down, up).start()

    def __updateTask(self, task):
        # TODO -- This function does a lot of math, I measured it to take .5 ms on my laptop
        #         That's a lot of time for something miniscule like sway and bob.

        dt = globalClock.getDt()
        time = globalClock.getFrameTime()

        if base.localAvatar.isFirstPerson():
            eyePoint = base.localAvatar.getEyePoint()
            if base.localAvatar.walkControls.crouching:
                eyePoint[2] = eyePoint[2] / 2.0
            eyePoint[2] = CIGlobals.lerpWithRatio(eyePoint[2],
                                                  self.lastEyeHeight, 0.4)
            self.lastEyeHeight = eyePoint[2]

        camRootAngles = Vec3(0)

        # Mouse look around
        mw = base.mouseWatcherNode
        if mw.hasMouse():
            md = base.win.getPointer(0)
            center = Point2(base.win.getXSize() / 2, base.win.getYSize() / 2)

            xDist = md.getX() - center.getX()
            yDist = md.getY() - center.getY()

            sens = self.__getMouseSensitivity()

            angular = -(xDist * sens) / dt
            base.localAvatar.walkControls.controller.setAngularMovement(
                angular)
            camRootAngles.setY(self.lastPitch - yDist * sens)

            if camRootAngles.getY() > FPSCamera.MaxP:
                camRootAngles.setY(FPSCamera.MaxP)
                yDist = 0
            elif camRootAngles.getY() < FPSCamera.MinP:
                yDist = 0
                camRootAngles.setY(FPSCamera.MinP)

            base.win.movePointer(0, int(center.getX()), int(center.getY()))

        if base.localAvatar.isFirstPerson():
            # Camera / viewmodel bobbing
            vmBob = Point3(0)
            vmAngles = Vec3(0)
            vmRaise = Point3(0)
            camBob = Point3(0)

            maxSpeed = base.localAvatar.walkControls.BattleRunSpeed * 16.0

            speed = base.localAvatar.walkControls.speeds.length() * 16.0
            speed = max(-maxSpeed, min(maxSpeed, speed))

            bobOffset = CIGlobals.remapVal(speed, 0, maxSpeed, 0.0, 1.0)

            self.bobTime += (time - self.lastBobTime) * bobOffset
            self.lastBobTime = time

            # Calculate the vertical bob
            cycle = self.bobTime - int(
                self.bobTime / self.BobCycleMax) * self.BobCycleMax
            cycle /= self.BobCycleMax
            if cycle < self.BobUp:
                cycle = math.pi * cycle / self.BobUp
            else:
                cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 -
                                                                    self.BobUp)

            verticalBob = speed * 0.005
            verticalBob = verticalBob * 0.3 + verticalBob * 0.7 * math.sin(
                cycle)
            verticalBob = max(-7.0, min(4.0, verticalBob))
            verticalBob /= 16.0

            # Calculate the lateral bob
            cycle = self.bobTime - int(
                self.bobTime / self.BobCycleMax * 2) * self.BobCycleMax * 2
            cycle /= self.BobCycleMax * 2
            if cycle < self.BobUp:
                cycle = math.pi * cycle / self.BobUp
            else:
                cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 -
                                                                    self.BobUp)

            lateralBob = speed * 0.005
            lateralBob = lateralBob * 0.3 + lateralBob * 0.7 * math.sin(cycle)
            lateralBob = max(-7.0, min(4.0, lateralBob))
            lateralBob /= 16.0

            # Apply bob, but scaled down a bit
            vmBob.set(lateralBob * 0.8, 0, verticalBob * 0.1)
            # Z bob a bit more
            vmBob[2] += verticalBob * 0.1
            # Bob the angles
            vmAngles[2] += verticalBob * 0.5
            vmAngles[1] -= verticalBob * 0.4
            vmAngles[0] -= lateralBob * 0.3

            # ================================================================
            # Viewmodel lag/sway

            angles = self.camRoot.getHpr(render)
            quat = Quat()
            quat.setHpr(angles)
            invQuat = Quat()
            invQuat.invertFrom(quat)

            maxVMLag = 1.5
            lagforward = quat.getForward()
            if dt != 0.0:
                lagdifference = lagforward - self.lastFacing
                lagspeed = 5.0
                lagdiff = lagdifference.length()
                if (lagdiff > maxVMLag) and (maxVMLag > 0.0):
                    lagscale = lagdiff / maxVMLag
                    lagspeed *= lagscale

                self.lastFacing = CIGlobals.extrude(self.lastFacing,
                                                    lagspeed * dt,
                                                    lagdifference)
                self.lastFacing.normalize()
                lfLocal = invQuat.xform(lagdifference)
                vmBob = CIGlobals.extrude(vmBob, 5.0 / 16.0, lfLocal * -1.0)

            pitch = angles[1]
            if pitch > 180:
                pitch -= 360
            elif pitch < -180:
                pitch += 360

            vmBob = CIGlobals.extrude(vmBob, pitch * (0.035 / 16),
                                      Vec3.forward())
            vmBob = CIGlobals.extrude(vmBob, pitch * (0.03 / 16), Vec3.right())
            vmBob = CIGlobals.extrude(vmBob, pitch * (0.02 / 16), Vec3.up())

            # ================================================================

            vmRaise.set(
                0, 0, 0
            )  #(0, abs(camRootAngles.getY()) * -0.002, camRootAngles.getY() * 0.002)
            camBob.set(0, 0, 0)

            # Apply bob, raise, and sway to the viewmodel.
            self.viewModel.setPos(vmBob + vmRaise + self.lastVMPos)
            self.vmRoot2.setHpr(vmAngles)
            self.camRoot.setPos(eyePoint + camBob)

        newPitch = camRootAngles.getY()

        if abs(newPitch - self.lastPitch) > self.PitchUpdateEpsilon:
            # Broadcast where our head is looking
            head = base.localAvatar.getPart("head")
            if head and not head.isEmpty():
                # Constrain the head pitch a little bit so it doesn't look like their head snapped
                headPitch = max(-47, newPitch)
                headPitch = min(75, headPitch)
                base.localAvatar.b_setLookPitch(headPitch)

        self.lastPitch = newPitch

        if base.localAvatar.isFirstPerson():
            # Apply punch angle
            self.decayPunchAngle()
            camRootAngles += self.punchAngle

        self.camRoot.setHpr(camRootAngles)

        return task.cont

    def __getMouseSensitivity(self):
        return CIGlobals.getSettingsMgr().getSetting('fpmgms').getValue()

    def cleanup(self):
        taskMgr.remove("vpdebutask")
        self.disableMouseMovement(False, False)
        self.clearVMAnimTrack()
        self.clearVMGag()
        if self.viewModel:
            self.viewModel.cleanup()
            self.viewModel.removeNode()
        self.viewModel = None
        if self.vmRender:
            self.vmRender.removeNode()
        self.vmRender = None
        self.vmRoot = None
        self.vmRoot2 = None
        self.viewportLens = None
        if self.viewportCam:
            self.viewportCam.removeNode()
        self.viewportCam = None
        if self.camRoot:
            self.camRoot.removeNode()
        self.camRoot = None
        self.camRoot2 = None
        self.lastEyeHeight = None
        self.lastPitch = None
        self.bobTime = None
        self.lastBobTime = None
        self.mouseEnabled = None
        self.lastCamRoot2Quat = None
        self.punchAngleVel = None
        self.punchAngle = None
        self.lastFacing = None
        self.lastMousePos = None
        self.currMousePos = None
        self.lastVMPos = None
        self.defaultViewModel = None
        self.idealFov = None
        self.vmGag = None
        self.vmAnimTrack = None
        self.dmgFade = None
        self.dmgFadeIval = None
        self.ignoreAll()
Esempio n. 2
0
ConfigVariableDouble('decompressor-step-time').setValue(0.01)
ConfigVariableDouble('extractor-step-time').setValue(0.01)

# loading screen
backgroundNodePath = aspect2d.attachNewNode(backgroundNode, 0)
backgroundNodePath.setPos(0.0, 0.0, 0.0)
backgroundNodePath.setScale(render2d, VBase3(1))
backgroundNodePath.find('**/bg').setBin('fixed', 10)

# change the logo
backgroundNodePath.find('**/fg').stash()

from direct.gui.DirectGui import OnscreenImage
logo = OnscreenImage('phase_3/maps/toontown-logo-new.png')
logo.reparentTo(backgroundNodePath)
logo.setBin('fixed', 20)
logo.setTransparency(TransparencyAttrib.MAlpha)
logo.setScale(.8, 1, .7)
logo.setZ(.3)

base.graphicsEngine.renderFrame()

# default DGG stuff
DirectGuiGlobals.setDefaultRolloverSound(
    base.loadSfx('phase_3/audio/sfx/GUI_rollover.ogg'))
DirectGuiGlobals.setDefaultClickSound(
    base.loadSfx('phase_3/audio/sfx/GUI_create_toon_fwd.ogg'))
DirectGuiGlobals.setDefaultDialogGeom(
    loader.loadModel('phase_3/models/gui/dialog_box_gui'))

# localizer
class Slot(DirectFrame):
    def __init__(self, baseGui, index, pos, parent):
        DirectFrame.__init__(
            self,
            pos=pos,
            parent=parent,
            image=loader.loadTexture('phase_3.5/maps/slot_%s_%s.png' %
                                     (str(index), 'idle')),
            scale=0.15,
            frameSize=(-1, 1, -1, 1),
            frameColor=(0, 0, 0, 0),
            sortOrder=0)
        self.initialiseoptions(Slot)
        self.gui = baseGui
        self.index = index
        self.hoverObj = None
        self.gagImage = None
        self.gag = None
        self.mouseRlvrSfx = base.loadSfx('phase_3/audio/sfx/GUI_rollover.ogg')
        self.soundRecharged = base.loadSfx(
            'phase_3.5/audio/sfx/tt_s_gui_sbk_cdrSuccess.ogg')
        self.infoText = OnscreenText(text='No\nAmmo',
                                     fg=(1, 0, 0, 1),
                                     parent=self,
                                     scale=0.5,
                                     shadow=(0, 0, 0, 1),
                                     align=TextNode.ACenter,
                                     pos=(0, 0.1))
        self.infoText.setBin('unsorted', 100)
        self.infoText.hide()
        self.rechargeBar = DirectWaitBar(value=0,
                                         range=100,
                                         frameColor=(1, 1, 1, 1),
                                         barColor=(0.286, 0.901, 1, 1),
                                         relief=DGG.RAISED,
                                         borderWidth=(0.04, 0.04),
                                         pos=(-1.25, 0, 0),
                                         hpr=(0, 0, -90),
                                         parent=self,
                                         frameSize=(-0.85, 0.85, -0.12, 0.12))
        self.rechargeBar.setBin('fixed', 60)
        self.rechargeBar.hide()
        self.gagLabel = OnscreenText(text='Birthday Cake',
                                     fg=(1, 1, 1, 1),
                                     parent=self,
                                     scale=0.25,
                                     shadow=(0, 0, 0, 1),
                                     align=TextNode.ACenter,
                                     pos=(0, -0.9),
                                     mayChange=1)
        self.gagLabel.setBin('fixed', 50)
        self.gagLabel.hide()
        battleGui = loader.loadModel('phase_3.5/models/gui/battle_gui.bam')
        arrow = battleGui.find('**/PckMn_BackBtn')
        arrowRlvr = battleGui.find('**/PckMn_BackBtn_Rlvr')
        arrowDn = battleGui.find('**/PckMn_BackBtn_Dn')
        self.leftArrow = DirectButton(geom=(arrow, arrowDn, arrowRlvr, arrow),
                                      parent=self,
                                      pos=(-0.925, -2.0, -1.02),
                                      relief=None,
                                      scale=2,
                                      command=self.updateLoadout,
                                      extraArgs=[0],
                                      geom3_color=(0.5, 0.5, 0.5, 1.0))
        self.leftArrow.setBin('fixed', 60)
        self.rightArrow = DirectButton(geom=(arrow, arrowDn, arrowRlvr, arrow),
                                       parent=self,
                                       pos=(0.925, -2.0, -1.02),
                                       hpr=(180, 0, 0),
                                       relief=None,
                                       scale=2,
                                       command=self.updateLoadout,
                                       extraArgs=[1],
                                       geom3_color=(0.5, 0.5, 0.5, 1.0))
        self.rightArrow.setBin('fixed', 60)
        self.hoverObj = DirectButton(relief=None,
                                     parent=self,
                                     frameSize=self['frameSize'])
        self.setBin('transparent', 30)
        self.setOutlineImage('idle')
        self.hoverObj.guiItem.setActive(True)
        self.hoverObj.bind(DGG.WITHIN, self.mouseEntered)
        self.hoverObj.bind(DGG.WITHOUT, self.mouseExited)
        self.hoverObj.bind(DGG.B1CLICK, self.gui.click_setWeapon, [self])
        return

    def toggleArrows(self, left, right):
        if left:
            self.leftArrow['state'] = DGG.NORMAL
        else:
            self.leftArrow['state'] = DGG.DISABLED
        if right:
            self.rightArrow['state'] = DGG.NORMAL
        else:
            self.rightArrow['state'] = DGG.DISABLED

    def updateArrows(self):
        if not self.gag:
            self.toggleArrows(False, False)
        else:
            track = GagGlobals.TrackGagNamesByTrackName.get(
                GagGlobals.getTrackOfGag(self.gag.getID()))
            index = None
            useTrack = []
            for name in track:
                gag = self.gui.backpack.getGagByID(
                    GagGlobals.getIDByName(name))
                if gag == self.gag or gag not in self.gui.backpack.getLoadout(
                ):
                    useTrack.append(name)

            index = useTrack.index(self.gag.getName())
            if index == 0:
                self.toggleArrows(False, True)
            else:
                if index > 0 and index < len(useTrack) - 1:
                    gagId = GagGlobals.getIDByName(useTrack[index + 1])
                    if not self.gui.backpack.hasGag(gagId):
                        self.toggleArrows(True, False)
                else:
                    if index == len(useTrack) - 1:
                        self.toggleArrows(True, False)
                    else:
                        self.toggleArrows(True, True)
        return

    def updateLoadout(self, forward):
        if self.gag and self.gag.getState() in [
                GagState.RECHARGING, GagState.LOADED
        ]:
            track = GagGlobals.TrackGagNamesByTrackName.get(
                GagGlobals.getTrackOfGag(self.gag.getID()))
            index = None
            useTrack = []
            for name in track:
                gag = self.gui.backpack.getGagByID(
                    GagGlobals.getIDByName(name))
                if gag == self.gag or gag not in self.gui.backpack.getLoadout(
                ):
                    useTrack.append(name)

            index = useTrack.index(self.gag.getName())
            if forward == 1:
                nextGagIndex = index + 1
            else:
                nextGagIndex = index - 1
            if nextGagIndex < 0 or nextGagIndex >= len(useTrack):
                return
            gagId = GagGlobals.getIDByName(useTrack[nextGagIndex])
            loadout = self.gui.backpack.getLoadout()
            if self.gui.backpack.hasGag(gagId) and self.gag in loadout:
                self.hideInfoText()
                if self.gag not in loadout:
                    return
                loadout[loadout.index(
                    self.gag)] = self.gui.backpack.getGagByID(gagId)
                self.gui.backpack.setLoadout(loadout)
        return

    def showNoAmmo(self):
        self.infoText['text'] = 'No\nAmmo'
        self.infoText['scale'] = 0.5
        self.infoText['fg'] = (1, 0, 0, 1)
        self.infoText['pos'] = (0, 0.1)
        self.infoText.show()
        if self.gag and self.gag.getState() == GagState.RECHARGING:
            self.rechargeBar.show()

    def showRecharging(self):
        self.infoText['text'] = 'Recharging...'
        self.infoText['scale'] = 0.315
        self.infoText['fg'] = (0.286, 0.901, 1, 1)
        self.infoText['pos'] = (0, 0)
        self.infoText.show()
        self.rechargeBar.show()

    def __tickRecharge(self):
        if not self.gag:
            self.ignoreAll()
        else:
            elapsedTime = float(self.gag.getRechargeElapsedTime())
            totalTime = float(self.gag.getRechargeTime())
            barValue = int(
                float(elapsedTime / totalTime) * self.rechargeBar['range'])
            self.rechargeBar['value'] = barValue
            if barValue == 0:
                self.gui.setWeapon(self, playSound=False)
                self.setOutlineImage('no_ammo')
                self.showRecharging()
            else:
                if barValue >= 100:
                    base.playSfx(self.soundRecharged)
                    slotImage = 'idle'
                    if base.localAvatar.getBackpack().getSupply(
                            self.gag.getID()) <= 0:
                        slotImage = 'no_ammo'
                    else:
                        if self.gui.getActiveSlot() == self:
                            slotImage = 'selected'
                    Sequence(Wait(0.5), Func(self.setOutlineImage,
                                             slotImage)).start()

    def hideInfoText(self):
        self.infoText.hide()
        self.rechargeBar.hide()

    def setSlotImage(self, gagImage):
        if self.gagImage:
            self.gagImage.destroy()
            self.gagImage = None
        self.gagImage = OnscreenImage(image=gagImage, parent=self)
        self.gagImage.setTransparency(TransparencyAttrib.MAlpha)
        return

    def setOutline(self):
        self.setTransparency(TransparencyAttrib.MAlpha)

    def setOutlineImage(self, image):
        phase = 'phase_3.5/maps/'
        if hasattr(self, '_optionInfo'):
            self['image'] = loader.loadTexture(phase + 'slot_%s_%s.png' %
                                               (str(self.index), image))
            self.setOutline()
            if image != 'no_ammo':
                if self.gag and base.localAvatar.getBackpack().getSupply(
                        self.gag.getID(
                        )) == 0 or self.gag and self.gag.getState(
                        ) == GagState.RECHARGING:
                    image = 'no_ammo'
            if image == 'no_ammo':
                if self.gag and self.gag.getState() == GagState.RECHARGING:
                    self.showRecharging()
                else:
                    self.showNoAmmo()
                    self.rechargeBar.hide()
                self.setBin('fixed', 40)
                if self.gagImage:
                    self.gagImage.setBin('transparent', 30)
            else:
                self.hideInfoText()
                if self.gagImage:
                    self.gagImage.setBin('fixed', 40)
                self.setBin('transparent', 30)

    def getOutline(self):
        return self.outline

    def mouseEntered(self, cmd):
        if self.gag:
            self.gagLabel.show()
            self.mouseRlvrSfx.play()

    def mouseExited(self, cmd):
        self.gagLabel.hide()

    def setGag(self, gag):
        if type(gag) == types.IntType:
            gag = self.gui.backpack.getGagByID(gag)
        self.ignoreAll()
        self.gag = gag
        if gag:
            self.show()
            self.setSlotImage(self.gag.getImage())
            self.gagLabel['text'] = self.gag.getName()
            self.accept('%s-Recharge-Tick' % str(self.gag.getID()),
                        self.__tickRecharge)
        else:
            self.hide()
            self.gagLabel['text'] = ''
        self.updateArrows()

    def getGag(self):
        return self.gag
Esempio n. 4
0
ConfigVariableDouble('decompressor-step-time').setValue(0.01)
ConfigVariableDouble('extractor-step-time').setValue(0.01)

# loading screen
backgroundNodePath = aspect2d.attachNewNode(backgroundNode, 0)
backgroundNodePath.setPos(0.0, 0.0, 0.0)
backgroundNodePath.setScale(render2d, VBase3(1))
backgroundNodePath.find('**/bg').setBin('fixed', 10)

# change the logo
backgroundNodePath.find('**/fg').stash()

from direct.gui.DirectGui import OnscreenImage
logo = OnscreenImage('phase_3/maps/toontown-logo-new.png')
logo.reparentTo(backgroundNodePath)
logo.setBin('fixed', 20)
logo.setTransparency(TransparencyAttrib.MAlpha)

base.graphicsEngine.renderFrame()

# default DGG stuff
DirectGuiGlobals.setDefaultRolloverSound(base.loadSfx('phase_3/audio/sfx/GUI_rollover.ogg'))
DirectGuiGlobals.setDefaultClickSound(base.loadSfx('phase_3/audio/sfx/GUI_create_toon_fwd.ogg'))
DirectGuiGlobals.setDefaultDialogGeom(loader.loadModel('phase_3/models/gui/dialog_box_gui'))

# localizer
import TTLocalizer
from otp.otpbase import OTPGlobals
OTPGlobals.setDefaultProductPrefix(TTLocalizer.ProductPrefix)

wantSpecial = base.config.GetBool('wantSpecialTheme', 0)
Esempio n. 5
0
class DMenuScreen(DirectObject):
    notify = directNotify.newCategory('DMenuScreen')

    def __init__(self):#, avatarList, parentFSM, doneEvent):
        DirectObject.__init__(self)
        base.disableMouse()
        #base.cr.avChoice = None
        fadeSequence = Sequence(
            Wait(.5),
            Func(base.transitions.fadeIn, .5),
            Wait(1)).start()#,
            #base.camera.posHprInterval(1, Point3(MAIN_POS), VBase3(MAIN_HPR), blendType = 'easeInOut')).start()
        #self.background = loader.loadModel('phase_4/models/neighborhoods/toontown_central_full')
        #self.background.reparentTo(render)
        #for frame in render.findAllMatches('*/doorFrame*'):
        #    frame.removeNode()
        #self.sky = loader.loadModel('phase_3.5/models/props/TT_sky')
        #SkyUtil.startCloudSky(self)

        #base.camera.setPosHpr(INIT_POS, INIT_HPR)
        self.background = OnscreenImage(image = DMenuResources.MenuBackground, parent = aspect2d)
        self.background.setBin('background', 1)
        self.background.reparentTo(aspect2d)
        self.background.setScale(2, 1, 1)
        
        self.logo = OnscreenImage(image = DMenuResources.GameLogo, scale = (1, 1, .5))
        self.logo.reparentTo(aspect2d)
        self.logo.setTransparency(TransparencyAttrib.MAlpha)
        scale = self.logo.getScale()
        self.logo.setPos(0, 0, .5)
        self.logo.setColorScale(Vec4(0, 0, 0, 0))

        #fadeInBackground = (LerpColorScaleInterval(self.background, 1, Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 0))).start()
        fadeInLogo = (LerpColorScaleInterval(self.logo, 1, Vec4(1, 1, 1, 1), Vec4(1, 1, 1, 0))).start()

        self.createButtons()

        self.fadeOut = None
        self.optionsMgr = DMenuOptions.DMenuOptions()
        self.quitConfirmation = DMenuQuit.DMenuQuit()

        # TT: We need these to run the Pick A Toon screen
        #self.patAvList = avatarList
        #self.patFSM = parentFSM
        #self.patDoneEvent = doneEvent
        
        self.transcircle = Resources.transcircle
        self.transcircle.setTransparency(TransparencyAttrib.MAlpha)
        self.transcircle.setScale(VBase3(0.01, 0.01, 0.01))
        self.transcircle.setBin('background', 3)
        
        self.savemgr = LOTASaveMgr.LOTASaveMgr()
        
        # Get the save data
        self.savePos = self.savemgr.loadSaveData()
        
        self.titleMusic = Resources.titleMusic
        self.titleMusic.setLoop(1)
        self.setMusicNormal()

    def skyTrack(self, task):
    #    return SkyUtil.cloudSkyTrack(task)
        pass

    def createButtons(self):
        self.PlayButton = DirectButton(relief = None, text_style = 3, text_fg = (1, 1, 1, 1), text = DMenuLocalizer.PlayGame, text_scale = .1, scale = 0.95, command = self.playGame)
        self.PlayButton.reparentTo(aspect2d)
        self.PlayButton.setPos(PlayBtnHidePos)
        self.PlayButton.show()

        self.OptionsButton = DirectButton(relief = None, text_style = 3, text_fg = (1, 1, 1, 1), text = DMenuLocalizer.Options, text_scale = .1, scale = 0.95, command = self.openOptions)
        self.OptionsButton.reparentTo(aspect2d)
        self.OptionsButton.setPos(OptionsBtnHidePos)
        self.OptionsButton.show()

        self.QuitButton = DirectButton(relief = None, text_style = 3, text_fg = (1, 1, 1, 1), text = DMenuLocalizer.Quit, text_scale = .1, scale = 0.95, command = self.quitGame)
        self.QuitButton.reparentTo(aspect2d)
        self.QuitButton.setPos(QuitBtnHidePos)
        self.QuitButton.show()


        # self.BRButton = DirectButton(text = 'REPORT BUG', text_scale = .1, scale=0.95)
        # self.BRButton.reparentTo(aspect2d)
        # self.BRButton.setPos(-.9, 0, -.9)
        # self.BRButton.show()
        
        self.buttonInAnimation()
        
        # Slap on the saves menu from the old main menu until a proper implementation to DMENU is made
        self.SavesButton = DirectButton(relief = None, text = AmdLocalizerEnglish.LOTA_SAVES, image_scale = 2, text_scale = .1, scale = 0.95, command = self.openSavesMenu)
        self.SavesButton.reparentTo(aspect2d)
        self.SavesButton.setPos(0, 0, -.5)
        self.SavesButton.show()

    def murder(self):
        if self.logo is not None:
            self.logo.destroy()
            self.logo = None

        if self.background is not None:
            self.background.hide()
            self.background.reparentTo(hidden)
            self.background.removeNode()
            self.background = None

        if self.PlayButton is not None:
            self.PlayButton.destroy()
            self.PlayButton = None

        if self.OptionsButton is not None:
            self.OptionsButton.destroy()
            self.OptionsButton = None

        if self.QuitButton is not None:
            self.QuitButton.destroy()
            self.QuitButton = None
            
        if self.SavesButton is not None:
            self.SavesButton.destroy()
            self.SavesButton = None
            
        if self.titleMusic is not None:
            self.titleMusic.stop()

        #taskMgr.remove('skyTrack')
        #self.sky.reparentTo(hidden)

    def openOptions(self):
        self.optionsMgr.showOptions()
        self.closeOptionsButton = DirectButton(relief = None, text = "< Back", text_fg = (0.977, 0.816, 0.133, 1), text_pos = (0, -0.035), scale = .1, command = self.hideOptions)
        self.closeOptionsButton.reparentTo(base.a2dTopLeft)
        self.closeOptionsButton.setPos(0.5, 0, -0.07)
        Parallel(
            self.PlayButton.posInterval(.5, Point3(PlayBtnHidePos), blendType = 'easeInOut'),
            self.OptionsButton.posInterval(.5, Point3(OptionsBtnHidePos), blendType = 'easeInOut'),
            self.QuitButton.posInterval(.5, Point3(QuitBtnHidePos), blendType = 'easeInOut'),
            self.logo.posInterval(0.5, Point3(0, 0, 2.5), blendType = 'easeInOut')).start()
        #base.camera.posHprInterval(0.5, Point3(HQ_POS), VBase3(HQ_HPR), blendType = 'easeInOut').start()
        #self.setMusicCalm()

    def hideOptions(self):
        self.optionsMgr.hideOptions()
        self.closeOptionsButton.hide()
        Parallel(
            self.PlayButton.posInterval(.5, Point3(PlayBtnPos), blendType = 'easeInOut'),
            self.OptionsButton.posInterval(.5, Point3(OptionsBtnPos), blendType = 'easeInOut'),
            self.QuitButton.posInterval(.5, Point3(QuitBtnPos), blendType = 'easeInOut'),
            self.logo.posInterval(.5, Point3(0, 0, .5), blendType = 'easeInOut')).start()
        base.camera.posHprInterval(0.5, Point3(MAIN_POS), VBase3(MAIN_HPR), blendType = 'easeInOut').start()
        #self.setMusicNormal()

    def playGame(self):
        if self.fadeOut is not None:
            self.fadeOut.finish()
            self.fadeOut = None
        self.fadeOut = base.transitions.getFadeOutIval(t = 1)
        #base.camera.posHprInterval(1, Point3(TOON_HALL_POS), VBase3(TOON_HALL_HPR), blendType = 'easeInOut').start()
        Sequence(
            Func(self.doPlayButton),
            #Func(self.fadeOut.start),
            Wait(1),
            Func(self.murder),
            Wait(1),
            Func(self.enterGame)).start()#,
            #Func(base.transitions.fadeIn, 1)).start()

    def enterOptions(self):
        pass

    def enterGame(self):
        #base.cr.avChoice = AvatarChooser.AvatarChooser(self.patAvList, self.patFSM, self.patDoneEvent)
        #base.cr.avChoice.load(1)
        #base.cr.avChoice.enter()
        from Game.NewGame.Scenes import SceneOne
        # Hamburger Menu Button
        #self.hbButton = DirectButton(image = "phase_3/maps/dmenu/dmhbmenu.png", relief = None, text = ' ', command=self.showHamburgerMenu)
        #self.hbButton.reparentTo(base.a2dTopLeft)
        #self.hbButton.setPos(0.05, 0, -0.05)
        #self.hbButton.setScale(0.04)

        # Hamburger Menu Hide Button
        #self.hbHideButton = DirectButton(image = "phase_3/maps/dmenu/close_window.png", relief = None, text = ' ', command=self.hideHamburgerMenu)
        #self.hbHideButton.reparentTo(base.a2dTopLeft)
        #self.hbHideButton.setPos(0.05, 0, -0.05)
        #self.hbHideButton.setScale(0.04)
        #self.hbHideButton.hide()

        # TODO: Add options and stuff to the hamburger menu

    def doPlayButton(self):
        Parallel(
            self.PlayButton.posInterval(1, Point3(PlayBtnHidePos), blendType = 'easeInOut'),
            self.OptionsButton.posInterval(1, Point3(OptionsBtnHidePos), blendType = 'easeInOut'),
            self.QuitButton.posInterval(1, Point3(QuitBtnHidePos), blendType = 'easeInOut'),
            self.logo.posInterval(0.5, Point3(0, 0, 2.5), blendType = 'easeInOut')).start()

    def quitGame(self):
        self.showQuitConfirmation()

    def showQuitConfirmation(self):
        self.quitConfirmation.showConfirmation()
        #base.exitFunc()

    def setMusicNormal(self):
        #LerpFunctionInterval(base.cr.music.setVolume, fromData = 0, toData = .9, duration = 1).start()
        #LerpFunctionInterval(base.cr.musicCalm.setVolume, fromData = .9, toData = 0, duration = 1).start()
        self.titleMusic.play()

    def setMusicCalm(self):
        LerpFunctionInterval(base.cr.music.setVolume, fromData = .9, toData = 0, duration = 1).start()
        LerpFunctionInterval(base.cr.musicCalm.setVolume, fromData = 0, toData = .9, duration = 1).start()

    def openSavesMenu(self):
        self.saveOne = DirectButton(relief=None, text = 'Save One: ' + '(Scene ' + str(self.savePos) + ')', scale=0.3, command=self.saveLoader, parent=aspect2d, pos=(0, 0, -.6), text_scale = .5)
        self.saveOne.hide()
        self.transcircle.show()
        self.exitLoadButton = DirectButton(relief=None, text = '< Back', scale=0.3, command=self.closeSavesMenu, parent=base.a2dBottomCenter, pos=(0, 0, -.4), text_scale = .5)
        self.exitLoadButton.show()

        
        self.openSavesMenuSequence = Parallel(
            self.transcircle.scaleInterval(0.5, VBase3(3, 3, 3), blendType = 'easeInOut'),
            self.exitLoadButton.posInterval(0.5, Point3(0, 0, .4), blendType = 'easeInOut'),
            Func(self.saveOne.show),
            self.saveOne.posInterval(0.5, Point3(0, 0, .2), blendType = 'easeInOut'))
        self.openSavesMenuSequence.start()
        
    def closeSavesMenu(self):
        self.hideThings = Sequence(
            Wait(0.5),
            Func(self.saveOne.hide),
            Func(self.transcircle.hide))
    
        self.closeSavesMenuSequence = Parallel(
            self.saveOne.posInterval(0.5, Point3(0, 0, -.6), blendType = 'easeInOut'),
            self.transcircle.scaleInterval(0.5, VBase3(0.01, 0.01, 0.01), blendType = 'easeInOut'),
            self.exitLoadButton.posInterval(0.5, Point3(0, 0, -.4), blendType = 'easeInOut'),
            Func(self.hideThings.start))
        self.closeSavesMenuSequence.start()
        self.exitLoadButton.removeNode()
        del self.exitLoadButton
        
    def saveLoader(self):
        # this was thrown together in like 10 seconds. how the f**k does this work
        # TODO: Make this save to a file thats not easily editable
        self.saveOne.hide()
        self.background.hide()
        self.transcircle.hide()
        if self.savePos == '1':
            from Game.NewGame.Scenes import SceneOne
        elif self.savePos == '2':
            from Game import SceneTwo
        elif self.savePos == '3':
            from Game import SceneThree
        elif self.savePos == '4':
            from Game import SceneFour
        elif self.savePos == '5':
            from Game import SceneFive
        else:
            print ("\n\n Save data is set to an unknown scene!!\n\n")
            
    def buttonInAnimation(self):
        logo = self.logo.posInterval(.5, Point3(0, 0, .5), blendType = 'easeInOut')
        play = self.PlayButton.posInterval(.5, Point3(PlayBtnPos), blendType = 'easeInOut')
        opt = self.OptionsButton.posInterval(.5, Point3(OptionsBtnPos), blendType = 'easeInOut')
        quit = self.QuitButton.posInterval(.5, Point3(QuitBtnPos), blendType = 'easeInOut')
        
        Sequence(
                 Func(logo.start),
                 Wait(0.1),
                 Func(play.start),
                 Wait(0.2),
                 Func(opt.start),
                 Wait(0.2),
                 Func(quit.start)).start()
                 
    def showHamburgerMenu(self):
        self.hbButton.hide()
        self.hbHideButton.show()
        
    def hideHamburgerMenu(self):
        self.hbButton.show()
        self.hbHideButton.hide()
class Credits(DirectObject):

    developers = {'Game Development': ['DuckyDuck1553', 'DecodedLogic']}
    webDevelopers = {
        'Web Development': ['totok', 'DuckyDuck1553', 'DecodedLogic']
    }
    artists = {
        'Artists': [
            'John L. (supertricky)', 'DuckyDuck1553', 'DecodedLogic',
            'Baru (fatigue)', 'Isabel (allyjean)', 'Colorblind', 'loonatic'
        ]
    }
    composers = {'Composers': ['Dylan J.', 'Doc. Dynamite', 'CBiard']}
    communityManager = {'Community Manager': ['Leo (Bradley)']}
    moderators = {
        'Moderation Team':
        ['Mark (Black & White)', 'Jackson M.', 'Gabriel A.', 'Davon M.']
    }
    specialThanks = {
        'Special Thanks': [
            'Jesse Schell', 'rdb', 'Baribal', 'ThomasEgi', 'tobspr',
            'jjkoletar', 'mmavipc', 'CFSWorks', 'loblao', 'HarvTarv',
            'Hawkheart', 'TheRandomDog', 'Joey Z. (joey19982)',
            'Disney Interactive', 'Microsoft', 'YorkeTheMouse', 'Disyer',
            '\n\n\nAnd of course, YOU!\n\n\n'
        ]
    }

    def __init__(self):
        DirectObject.__init__(self)

        base.setBackgroundColor(0, 0, 0)

        self.textParent = base.credits2d.attachNewNode('textParent')
        self.textParent.setBin("gui-popup", 61)
        self.textParent.setDepthWrite(False)
        self.textParent.setTransparency(True)

        self.logoImage = OnscreenImage('phase_3/maps/CogInvasion_Logo.png',
                                       parent=self.textParent,
                                       scale=(0.685, 1.0, 0.325))
        self.logoImage.setTransparency(1)

        text = self.buildCreditsText()
        self.creditsText = OnscreenText(parent=self.textParent,
                                        font=CIGlobals.getToonFont(),
                                        fg=(1, 1, 1, 1),
                                        scale=0.065,
                                        pos=(0, -0.5, 0),
                                        text=text,
                                        shadow=(0, 0, 0, 1))

        self.posInterval = None

        self.backgroundImg = OnscreenImage('phase_3/maps/credits_fade.png',
                                           parent=render2d)
        self.backgroundImg.setTransparency(True)
        self.backgroundImg.setColor(0, 0, 0, 1.0)
        self.backgroundImg.setBin("gui-popup", 62)
        self.backgroundImg.setDepthWrite(False)

        self.exitText = OnscreenText(parent=base.credits2d,
                                     font=CIGlobals.getToonFont(),
                                     fg=(1.0, 0, 0, 1.0),
                                     shadow=(0, 0, 0, 1),
                                     scale=0.085,
                                     pos=(0, -0.96, 0),
                                     text='Press any key to exit')
        self.exitText.hide()
        self.exitText.setBin("gui-popup", 63)
        self.exitText.setDepthWrite(False)
        self.exitText.setTransparency(True)

        self.creditsAudioMgr = AudioManager.createAudioManager()
        self.creditsAudioMgr.setVolume(0.65)
        self.bgm = self.creditsAudioMgr.getSound(
            'phase_4/audio/bgm/new_years_fireworks_music.ogg')

    def buildCreditsText(self):
        def writeNames(message, namesList):
            for name in namesList:
                message = '%s%s\n' % (message, name)
            return message

        message = 'Cog Invasion Online\n{0}\n'.format(
            metadata.getBuildInformation())
        message += '\nCREDITS\n\n'

        # Write the game developers' names
        message += 'Programming\n\n'
        message += '%s\n' % self.developers.keys()[0]
        message = writeNames(message, self.developers.values()[0])
        message += '\n\n'

        # Write the web developers' names
        message += '%s\n' % self.webDevelopers.keys()[0]
        message = writeNames(message, self.webDevelopers.values()[0])

        # Let's begin the art section
        message += '\n\nArt\n\n'

        # Write the artists' names
        message += '%s\n' % self.artists.keys()[0]
        message = writeNames(message, self.artists.values()[0])

        message += '\n\n'

        # Write the composers' names
        message += '%s\n' % self.composers.keys()[0]
        message = writeNames(message, self.composers.values()[0])

        ##########################################
        # Let's begin the community section.
        message += '\n\nCommunity\n\n'

        # Write the community manager names
        message += '%s\n' % self.communityManager.keys()[0]
        message = writeNames(message, self.communityManager.values()[0])
        message += '\n\n'

        # Write the moderators' names
        message += '%s\n' % self.moderators.keys()[0]
        message = writeNames(message, self.moderators.values()[0])

        # Let's begin the Special Thanks section.
        message += '\n\n'

        # Write the special thanks' names
        message += '%s\n' % self.specialThanks.keys()[0]
        message = writeNames(message, self.specialThanks.values()[0])
        message += '\nWe thank the original Toontown Online team.\nNot only for the game, but for the memories.'
        message += "\n\n\n\n\"Don't cry because it's over.\nSmile because it happened.\"\n  - Dr. Seuss"

        return message

    def exit(self, key):
        self.__fadeOut()
        base.taskMgr.doMethodLater(1.1, self.__exitTask, "exitTask")

    def __exitTask(self, task):
        messenger.send('credits-Complete')
        self.ignoreAll()
        self.destroy()
        base.unMuteMusic()
        base.unMuteSfx()
        base.setBackgroundColor(0.05, 0.15, 0.4)
        base.transitions.fadeIn(1.0)
        return task.done

    def watchTextPosition(self, task):
        if self.textParent.getZ() >= 5.187:
            self.exitText.show()
            self.acceptOnce('button', self.exit)
            return task.done
        return task.cont

    def __fadeIn(self):
        Parallel(
            LerpColorScaleInterval(self.textParent, 1.0, (1, 1, 1, 1),
                                   (1, 1, 1, 0)),
            LerpColorScaleInterval(self.backgroundImg, 1.0, (1, 1, 1, 1),
                                   (1, 1, 1, 0)),
            LerpColorScaleInterval(self.exitText, 1.0, (1, 1, 1, 1),
                                   (1, 1, 1, 0))).start()

    def __fadeOut(self):
        Parallel(
            LerpColorScaleInterval(self.textParent, 1.0, (1, 1, 1, 0),
                                   (1, 1, 1, 1)),
            LerpColorScaleInterval(self.backgroundImg, 1.0, (1, 1, 1, 0),
                                   (1, 1, 1, 1)),
            LerpColorScaleInterval(self.exitText, 1.0, (1, 1, 1, 0),
                                   (1, 1, 1, 1))).start()

    def setup(self):
        self.__fadeIn()

        b3 = self.textParent.getTightBounds()
        dimensions = b3[1] - b3[0]
        self.posInterval = self.textParent.posInterval(
            50, Point3(0, 0, dimensions[2] + 2), Point3(0, 0, 0))
        self.posInterval.start()

        self.bgm.setLoop(1)
        self.bgm.play()

        base.buttonThrowers[0].node().setButtonDownEvent('button')
        taskMgr.add(self.watchTextPosition, 'Watch Text Position')

    def destroy(self):
        if self.posInterval:
            self.posInterval.pause()
            self.posInterval = None
        if self.bgm:
            self.bgm.stop()
            self.bgm = None
        if self.backgroundImg:
            self.backgroundImg.destroy()
            self.backgroundImg = None
        if self.creditsText:
            self.creditsText.destroy()
            self.creditsText = None
        if self.exitText:
            self.exitText.destroy()
            self.exitText = None
        if self.logoImage:
            self.logoImage.destroy()
            self.logoImage = None
        if self.textParent:
            self.textParent.removeNode()
            self.textParent = None
        if self.creditsAudioMgr:
            self.creditsAudioMgr.stopAllSounds()
            self.creditsAudioMgr = None
        self.developers = None
        self.webDevelopers = None
        self.artists = None
        self.specialThanks = None
        self.composers = None
        self.communityManager = None
        self.moderators = None
        self.prevMusic = None
Esempio n. 7
0
class RewardPanel(DirectFrame):
    notify = directNotify.newCategory('RewardPanel')

    def __init__(self, panelData):
        dialogBox = loader.loadModel('phase_3/models/gui/dialog_box_gui.bam')
        DirectFrame.__init__(self,
                             relief=None,
                             geom=dialogBox,
                             geom_color=CIGlobals.DialogColor,
                             geom_scale=(1.75, 1, 0.75 * 1.1),
                             geom_pos=Point3(0, 0, -0.05),
                             pos=(0, 0, 0.661))
        self.initialiseoptions(RewardPanel)
        self.setScale(0.8)

        # The data for the reward panel inside of a RPToonData object.
        self.panelData = panelData

        # Top wood panel saying Reward Panel
        gagShopNodes = loader.loadModel(
            'phase_4/models/gui/gag_shop_purchase_gui.bam')
        # Original pos: (-0.02, 0, 0.3) scale = (1.55, 1, 1)
        self.titlePanel = OnscreenImage(
            parent=self,
            image=gagShopNodes.find('**/Goofys_Sign'),
            pos=(0, 0, 0.3),
            hpr=(1, 0, 0),
            scale=(1.3, 1, 0.9))

        self.avatarNamePanel = DirectFrame(parent=self.titlePanel,
                                           pos=(0, 0.005, 0))
        self.avatarText = OnscreenText(parent=self.avatarNamePanel,
                                       text='',
                                       font=CIGlobals.getMickeyFont(),
                                       fg=(0.698, 0.13, 0.13, 1),
                                       mayChange=1,
                                       scale=(0.1, 0.13, 0.1))

        self.panelContentsTitle = OnscreenText(parent=self,
                                               text=GagPanelName,
                                               font=CIGlobals.getMickeyFont(),
                                               pos=(0, 0.24, 0),
                                               fg=(0.3725, 0.619, 0.627, 1),
                                               mayChange=1)

        self.playerInfo = DirectFrame(parent=self,
                                      relief=None,
                                      pos=(-0.5, 0, 0))
        self.playerInfo.setBin('gui-popup', 0)

        self.bonusText = OnscreenText(parent=self.playerInfo,
                                      text='2X Cog Office Bonus!',
                                      font=CIGlobals.getToonFont(),
                                      pos=(0, 0.15, 0),
                                      scale=(0.055, 0.055, 0.055),
                                      align=TextNode.ACenter)
        self.bonusText.hide()

        ##################################################################################
        # GUI Elements relating to the Favorite Gag/Gag Popup Used for showing Gag Unlock#
        ##################################################################################
        self.favoriteGagText = OnscreenText(parent=self.playerInfo,
                                            text=FavoriteGag,
                                            font=CIGlobals.getMickeyFont(),
                                            pos=FavoriteGagTitlePos,
                                            fg=(1, 0.2, 0.2, 1),
                                            sort=0)

        glow = loader.loadModel('phase_4/models/minigames/particleGlow.bam')
        self.favoriteGagGlow = OnscreenImage(parent=self.playerInfo,
                                             image=glow,
                                             pos=FavoriteGagPos,
                                             color=GagGlowColor,
                                             scale=(0.8, 0.8, 0.8))
        self.favoriteGagGlow.setBin('gui-popup', 10)
        # particleGlow.bam uses a material since it's normally part of render, not render2d.
        # Since render2d is still fixed-function, we have to explicitly enable shader generation
        # to correctly display the glow in render2d.
        self.favoriteGagGlow.setShaderAuto()

        invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam')
        gag = invIcons.find(
            GagGlobals.InventoryIconByName.get(GagGlobals.Foghorn))
        self.favoriteGag = OnscreenImage(parent=self.playerInfo,
                                         image=gag,
                                         pos=FavoriteGagPos,
                                         scale=(1.65, 1.65, 1.65))
        self.favoriteGag.setBin('gui-popup', 20)

        self.favoriteGagName = OnscreenText(parent=self.playerInfo,
                                            text=GagGlobals.Foghorn,
                                            font=CIGlobals.getToonFont(),
                                            pos=FavoriteGagNamePos,
                                            mayChange=1)

        ################################################################################
        # GUI elements showing gag experience on the right-side of the gag exp panel   #
        ################################################################################

        self.gagExpFrame = DirectFrame(parent=self,
                                       relief=None,
                                       pos=(0.085, 0, 0.15))
        self.trackLabels = []
        self.trackIncLabels = []
        self.trackBars = []
        self.trackBarsOffset = 0

        for i in range(len(GagGlobals.TrackNameById.values())):
            track = GagGlobals.TrackNameById.values()[i]
            color = GagGlobals.TrackColorByName.get(track)
            label = DirectLabel(parent=self.gagExpFrame,
                                relief=None,
                                text=track.upper(),
                                text_scale=0.05,
                                text_align=TextNode.ARight,
                                pos=(0.13, 0, -0.09 * i),
                                text_pos=(0, -0.02))
            incrementLabel = DirectLabel(parent=self.gagExpFrame,
                                         relief=None,
                                         text='',
                                         text_scale=0.05,
                                         text_align=TextNode.ALeft,
                                         pos=(0.65, 0, -0.09 * i),
                                         text_pos=(0, -0.02))
            progressBar = DirectWaitBar(
                parent=self.gagExpFrame,
                relief=DGG.SUNKEN,
                frameSize=(-1, 1, -0.15, 0.15),
                borderWidth=(0.02, 0.02),
                scale=0.25,
                frameColor=(color[0] * 0.7, color[1] * 0.7, color[2] * 0.7, 1),
                barColor=(color[0], color[1], color[2], 1),
                text='0/0',
                text_scale=0.18,
                text_fg=(0, 0, 0, 1),
                text_align=TextNode.ACenter,
                text_pos=(0, -0.05),
                pos=(0.4, 0, -0.09 * i))
            self.trackLabels.append(label)
            self.trackIncLabels.append(incrementLabel)
            self.trackBars.append(progressBar)

        ################################################################################
        # GUI elements showing progress updates on quests                              #
        ################################################################################

        self.questFrame = DirectFrame(parent=self, relief=None)
        self.questPosters = []

        self.congratsLeft = OnscreenText(parent=self.playerInfo,
                                         pos=(-0.1, 0.125, -0.1),
                                         text='',
                                         scale=0.06,
                                         align=TextNode.ARight)
        self.congratsLeft.setR(-30)
        self.congratsRight = OnscreenText(parent=self.playerInfo,
                                          pos=(0.1, 0.125, 0.1),
                                          text='',
                                          scale=0.06,
                                          align=TextNode.ALeft)
        self.congratsRight.setR(30)

        glow.removeNode()
        invIcons.removeNode()
        gagShopNodes.removeNode()
        dialogBox.removeNode()

    def __getAvatarTextScale(self):
        totalWidth = self.avatarText.node().getWidth()
        panelWidth = 9.2
        defaultTextScale = 1.0

        scale = min(defaultTextScale,
                    defaultTextScale / (totalWidth / panelWidth))
        return (scale, scale, scale)

    def enterOff(self):
        pass

    def exitOff(self):
        pass

    def setPanelData(self, panelData):
        self.panelData = panelData
        self.avatarText['text'] = self.panelData.avatarName
        self.avatarNamePanel.setScale(self.__getAvatarTextScale())

        # Let's set the data for our gag experience here.
        for i in range(len(self.trackLabels)):
            track = self.panelData.getTrackByName(
                GagGlobals.TrackNameById.values()[i])
            bar = self.trackBars[i]
            bar['text'] = '%d/%d' % (track.exp, track.maxExp)

            # When the maximum experience of a track isn't 0, we know it isn't unlocked.
            if track.maxExp == -1:
                bar.hide()

            self.trackIncLabels[i]['text'] = ''
            self.trackIncLabels[i].show()

    def __chooseRewardShot(self, av):
        shotChoices = [(0, 8, av.getHeight() * 0.66, 179, 15, 0),
                       (5.2, 5.45, av.getHeight() * 0.66, 131.5, 3.6, 0)]
        shot = random.choice(shotChoices)
        return shot

    def getQuestsProgressInterval(self):
        avatar = self.panelData.avatar
        intervals = []

        def toggleFavoriteGagItems(visible):
            for item in [
                    self.favoriteGag, self.favoriteGagGlow,
                    self.favoriteGagText, self.favoriteGagName
            ]:
                if not visible:
                    item.hide()
                else:
                    item.show()

        def setupQuestPosters():
            questManager = avatar.questManager
            numQuests = len(questManager.quests.values())

            yPos = 0.47

            displayData = {
                1: [[Point3(0.0, 0.0, yPos)], 0.88],
                2: [[Point3(-0.42, 0.0, yPos),
                     Point3(0.45, 0.0, yPos)], 0.88],
                3: [[
                    Point3(-0.57, 0.0, yPos),
                    Point3(0.0, 0.0, yPos),
                    Point3(0.57, 0.0, yPos)
                ], 0.70],
                4: [[
                    Point3(-0.32, 0.0, 0.62),
                    Point3(-0.32, 0.0, 0.30),
                    Point3(0.32, 0.0, 0.62),
                    Point3(0.32, 0.0, 0.30)
                ], 0.52]
            }

            # A full frame is a frame showing two quests at once.
            howManyFullFrames = math.ceil(numQuests / 2.0)
            howManyRemainderFrames = (numQuests - howManyFullFrames)

            for i, quest in enumerate(questManager.quests.values()):
                poster = QuestGlobals.generatePoster(quest,
                                                     parent=self.questFrame)
                poster.setScale(displayData.get(numQuests)[1])
                poster.setPos(displayData.get(numQuests)[0][i])
                poster.show()
                self.questPosters.append(poster)

        intervals.append(Func(self.gagExpFrame.hide))
        intervals.append(Func(self.playerInfo.show))
        intervals.append(Func(self.panelContentsTitle.setText,
                              QuestsPanelName))
        intervals.append(Func(toggleFavoriteGagItems, False))
        intervals.append(Func(setupQuestPosters))
        #intervals.append(Func(self.playerInfo.initialiseoptions, DirectFrame))

        return intervals

    def getGagExperienceInterval(self):
        avatar = self.panelData.avatar
        intervals = []

        shot = self.__chooseRewardShot(avatar)

        intervals.append(Func(base.camera.reparentTo, avatar))
        intervals.append(Func(base.camera.setPosHpr, *shot))
        intervals.append(Func(self.congratsLeft.hide))
        intervals.append(Func(self.congratsRight.hide))
        intervals.append(Func(self.panelContentsTitle.setText, GagPanelName))
        intervals.append(Func(self.setFavoriteGag, self.panelData.favoriteGag))
        intervals.append(Func(self.gagExpFrame.show))
        intervals.append(Func(self.playerInfo.show))
        intervals.append(Wait(1.0))

        for i in range(len(self.trackLabels)):
            track = self.panelData.getTrackByName(
                GagGlobals.TrackNameById.values()[i])
            intervals.extend(self.getTrackIntervalList(track, i))

        return intervals

    def getNextExpValue(self, newValue, track):
        if newValue < track.maxExp or track.maxExp == 0:
            return track.maxExp
        else:
            levels = GagGlobals.TrackExperienceAmounts[track.name]
            index = levels.index(track.maxExp)

            if index + 1 < len(levels):
                return levels[index + 1]
            return -1

    def incrementExp(self, trackIndex, track, newValue):
        bar = self.trackBars[trackIndex]
        nextExp = GagGlobals.getMaxExperienceValue(newValue, track.name)
        oldValue = bar['value']
        color = GagGlobals.TrackColorByName.get(track.name)

        bar['text'] = '%d/%d' % (newValue, nextExp)
        bar['range'] = nextExp if not nextExp == -1 else newValue
        bar['value'] = newValue
        bar['barColor'] = (color[0], color[1], color[2], 1)

    def resetBarColor(self, trackIndex):
        color = GagGlobals.TrackColorByName.get(
            GagGlobals.TrackNameById.values()[trackIndex])
        self.trackBars[trackIndex]['barColor'] = (color[0] * 0.8,
                                                  color[1] * 0.8,
                                                  color[2] * 0.8, 1)

    def showTrackIncLabel(self, trackIndex, track, increment):
        label = self.trackIncLabels[trackIndex]

        # Only show increments when that track is unlocked.
        if track.exp != -1:
            label['text'] = '+%d' % increment
        label.show()

    def getTrackIntervalList(self, track, trackIndex):
        tickDelay = 1.0 / 60
        intervalList = []

        intervalList.append(
            Func(self.showTrackIncLabel, trackIndex, track, track.increment))

        barTime = 2.0 if track.exp > 0 else 0.25
        numTicks = int(math.ceil(barTime / tickDelay))
        for i in range(numTicks):
            t = (i + 1) / float(numTicks)
            newValue = int(track.exp + t * track.increment + 0.5)
            intervalList.append(
                Func(self.incrementExp, trackIndex, track, newValue))
            intervalList.append(Wait(tickDelay))

        intervalList.append(Func(self.resetBarColor, trackIndex))
        intervalList.append(Wait(0.2))

        if track.maxExp > 0 and (track.maxExp != GagGlobals.MaxedTrackExperiences.get(track.name) \
                    and (track.exp + track.increment) >= track.maxExp):
            gagIndex = GagGlobals.TrackExperienceAmounts.get(track.name).index(
                track.maxExp) + 1
            newGag = GagGlobals.TrackGagNamesByTrackName.get(
                track.name)[gagIndex]
            intervalList.append(
                self.getShowGagUnlockedInterval(track.name, newGag))

        return intervalList

    def getShowGagUnlockedInterval(self, track, gagName):
        seq = Sequence(
            Func(self.gagExpFrame.hide),
            Func(self.panelContentsTitle.setText, 'Gag Unlocked!'),
            Func(self.playerInfo.show), Func(self.setFavoriteGag, gagName),
            Func(self.favoriteGagName.setY, -0.35),
            Func(self.favoriteGagText.setY, 0.105),
            Func(self.favoriteGagText.setText, 'New %s Gag' % track),
            Func(self.bonusText.hide), Func(self.playerInfo.setPos, 0, 0, 0),
            Func(self.playerInfo.initialiseoptions, DirectFrame))
        seq.append(self.getCongratsInterval())
        seq.append(Wait(1.0))
        seq.append(self.getHideGagUnlockedInterval())
        seq.append(Func(self.gagExpFrame.show))
        seq.append(Wait(0.5))
        return seq

    def getHideGagUnlockedInterval(self):
        def correctPositioning(guiElement, pos):
            guiElement['pos'] = pos

        seq = Sequence(
            Func(self.panelContentsTitle.setText, GagPanelName),
            Func(self.setFavoriteGag, self.panelData.favoriteGag),
            Func(self.playerInfo.setX, -0.5),
            Func(correctPositioning, self.favoriteGagName, FavoriteGagNamePos),
            Func(self.favoriteGagText.setText, FavoriteGag),
            Func(correctPositioning, self.favoriteGagText,
                 FavoriteGagTitlePos), Func(self.congratsLeft.hide),
            Func(self.congratsRight.hide))

        return seq

    def __getRandomCongratsPair(self):
        msgs = list(NewGagCongratsMessages)

        msg = msgs[random.randint(0, len(msgs) - 1)]
        msgs.remove(msg)

        return (msg, msgs[random.randint(0, len(msgs) - 1)])

    def getCongratsInterval(self):
        msgs = self.__getRandomCongratsPair()
        self.congratsLeft['text'] = msgs[0]
        self.congratsRight['text'] = msgs[1]

        sfx = loader.loadSfx('phase_3/audio/sfx/GUI_balloon_popup.ogg')
        sfx.setLoop(False)
        sfx.setVolume(1.0)

        def makeSequence(text):
            seq = Sequence(Wait(1.0), Func(text.show))
            seq.append(Func(sfx.play))
            seq.append(
                CIGlobals.makePulseEffectInterval(text, 1.0, 0.01, 1.05, 0.5,
                                                  0.25))
            seq.append(Func(sfx.stop))
            return seq

        return Sequence(makeSequence(self.congratsLeft),
                        makeSequence(self.congratsRight))

    def setFavoriteGag(self, gagName):
        invIcons = loader.loadModel('phase_3.5/models/gui/inventory_icons.bam')
        gag = invIcons.find(GagGlobals.InventoryIconByName.get(gagName))
        self.favoriteGagName.setText(gagName)
        self.favoriteGag['image'] = gag
        invIcons.removeNode()

    def destroy(self):
        if self.titlePanel:
            self.titlePanel.destroy()
        if self.avatarText:
            self.avatarText.destroy()
        if self.avatarNamePanel:
            self.avatarNamePanel.destroy()
        if self.panelContentsTitle:
            self.panelContentsTitle.destroy()
        if self.favoriteGag:
            self.favoriteGag.destroy()
        if self.favoriteGagGlow:
            self.favoriteGagGlow.destroy()
        if self.favoriteGagName:
            self.favoriteGagName.destroy()
        if self.playerInfo:
            self.playerInfo.destroy()
        if self.trackLabels:
            for label in self.trackLabels:
                label.destroy()
        if self.trackIncLabels:
            for label in self.trackIncLabels:
                label.destroy()
        if self.trackBars:
            for bar in self.trackBars:
                bar.destroy()
        if self.congratsLeft:
            self.congratsLeft.destroy()
        if self.congratsRight:
            self.congratsRight.destroy()
        if self.gagExpFrame:
            self.gagExpFrame.destroy()
        if self.panelData:
            self.panelData = None
        del self.titlePanel
        del self.avatarText
        del self.avatarNamePanel
        del self.panelContentsTitle
        del self.favoriteGag
        del self.favoriteGagGlow
        del self.favoriteGagName
        del self.playerInfo
        del self.trackLabels
        del self.trackIncLabels
        del self.trackBars
        del self.gagExpFrame
        del self.congratsLeft
        del self.congratsRight
        del self.panelData
        DirectFrame.destroy(self)