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