class CogdoFlyingLevelFog: def __init__(self, level, color=Globals.Level.FogColor): self._level = level self.color = color fogDistance = self._level.quadLengthUnits * max( 1, self._level.quadVisibiltyAhead * 0.2) self.fog = Fog('RenderFog') self.fog.setColor(self.color) self.fog.setLinearRange( fogDistance * Globals.Level.RenderFogStartFactor, fogDistance) self._visible = False self._clearColor = Vec4(base.win.getClearColor()) self._clearColor.setW(1.0) def destroy(self): self.setVisible(False) if hasattr(self, 'fog'): del self.fog def isVisible(self): return self._visible def setVisible(self, visible): self._visible = visible if self._visible: base.win.setClearColor(self.color) render.setFog(self.fog) else: base.win.setClearColor(self._clearColor) render.clearFog()
def init(self): """setup calls that can be repeated on code reload""" self.resetNodes() self.base.setBackgroundColor(0, 0, 0) self.base.render.setShaderAuto() # pp shading self.base.render.setAttrib( AntialiasAttrib.make(AntialiasAttrib.MMultisample)) if 1: cam = self.base.render.find("camera") # I don't know how to set cam position f = Fog("fog") f.setColor(0,0,0) f.setLinearRange(18, 25) self.base.render.setFog(f) import videowall reload(videowall) self.videoWall = videowall.VideoWall(self.base.loader, self.base.render) self.cubes = self.base.render.attachNewNode(ModelNode("cubes")) self.cubes.setPos(-4.3, 18, -3) ground = self.makeGround(self.cubes) lights = self.base.render.attachNewNode("lights") self.makeLights(lights) self.centerMessageNode, self.cornerMessageNode = self.makeMessages() self.setLighting(self.currentLighting) self.base.render.ls()
class CogdoFlyingLevelFog: def __init__(self, level, color = Globals.Level.FogColor): self._level = level self.color = color fogDistance = self._level.quadLengthUnits * max(1, self._level.quadVisibiltyAhead * 0.2) self.fog = Fog('RenderFog') self.fog.setColor(self.color) self.fog.setLinearRange(fogDistance * Globals.Level.RenderFogStartFactor, fogDistance) self._visible = False self._clearColor = Vec4(base.win.getClearColor()) self._clearColor.setW(1.0) def destroy(self): self.setVisible(False) if hasattr(self, 'fog'): del self.fog def isVisible(self): return self._visible def setVisible(self, visible): self._visible = visible if self._visible: base.win.setClearColor(self.color) render.setFog(self.fog) else: base.win.setClearColor(self._clearColor) render.clearFog()
def init(self): """setup calls that can be repeated on code reload""" self.resetNodes() self.base.setBackgroundColor(0, 0, 0) self.base.render.setShaderAuto() # pp shading self.base.render.setAttrib( AntialiasAttrib.make(AntialiasAttrib.MMultisample)) if 1: cam = self.base.render.find("camera") # I don't know how to set cam position f = Fog("fog") f.setColor(0, 0, 0) f.setLinearRange(18, 25) self.base.render.setFog(f) import videowall reload(videowall) self.videoWall = videowall.VideoWall(self.base.loader, self.base.render) self.cubes = self.base.render.attachNewNode(ModelNode("cubes")) self.cubes.setPos(-4.3, 18, -3) ground = self.makeGround(self.cubes) lights = self.base.render.attachNewNode("lights") self.makeLights(lights) self.centerMessageNode, self.cornerMessageNode = self.makeMessages() self.setLighting(self.currentLighting) self.base.render.ls()
def begin(self): base.setBackgroundColor( self.environment['colourBackground'] ) alight = AmbientLight('AmbientLight') alight.setColor(self.environment['colourAmbient'] ) alnp = self.sceneNode.attachNewNode(alight) self.sceneNode.setLight(alnp) if self.environment['fog']: fog = Fog( 'sceneName' ) fog.setColor( self.environment['fog']['color'] ) if self.environment['fog']['mode'] == "linear": fog.setLinearRange(self.environment['fog']['linearStart']*1000,self.environment['fog']['linearEnd']*1000) else: fog.setExpDensity( self.environment['fog']['expDensity'] ) self.sceneNode.setFog(fog) [self.createNode(props) for props in self.nodes] [self.createLight(props) for props in self.lights] [self.createCamera(props) for props in self.cameras] [self.createEntity(props) for props in self.entities] # [self.createStaticGeoms(props) for props in self.staticGeoms] self.sceneNode.clearModelNodes() self.sceneNode.flattenStrong() self.sceneNode.setShaderAuto()
class Scene(NodePath): def __init__(self): super().__init__('scene') self.render = None self.world = None self.camera = None self.ui_camera = None self.entities = [] self.hidden = NodePath('hidden') self.reflection_map = 'reflection_map_3' def set_up(self): from ursina.entity import Entity self.reparent_to(render) self.reflection_map = load_texture(self.reflection_map) self.fog = Fog('fog') self.setFog(self.fog) self.fog_color = color.light_gray self.fog_density = 0 def clear(self): from ursina.ursinastuff import destroy to_destroy = [e for e in self.entities if not e.eternal] to_keep = [e for e in self.entities if e.eternal] for d in to_destroy: try: print('destroying:', d.name) destroy(d) except Exception as e: print('failed to destroy entity', e) self.entities = to_keep from ursina import application application.sequences.clear() @property def fog_color(self): return self.fog.getColor() @fog_color.setter def fog_color(self, value): self.fog.setColor(value) @property def fog_density(self): return self._fog_density @fog_density.setter # set to a number for exponential density or (start, end) for linear. def fog_density(self, value): self._fog_density = value if isinstance(value, tuple): # linear fog self.fog.setLinearRange(value[0], value[1]) else: self.fog.setExpDensity(value)
def __init__(self, *args, **kwargs): template.Panda.__init__(self, *args, **kwargs) print "Hurray!" self.cube = self.loader.loadModel("models/low-cube") self.cube.reparentTo(self.render) self.cube2 = self.loader.loadModel("models/low-cube") self.cube2.reparentTo(self.render) self.cube2.setPos(self.cube, 10,20,30) self.cube2.setHpr(175,3,45) self.taskMgr.add(self.update, "update") self.taskMgr.add(self.move, "move") self._dir = 1 colour = (0.5,0.8,0.8) linfog = Fog("A linear-mode Fog node") linfog.setColor(*colour) linfog.setLinearRange(0,320) linfog.setLinearFallback(45,160,320) render.attachNewNode(linfog) render.setFog(linfog)
def test2(): startup = PandaStartup() PLight(color=(1, 1, 1, 1), position=vec3(3, -1, 4), size=0.1).apply(startup.render) PLight(color=(1, 1, 1, 1), position=vec3(0, -1, 4), size=0.1).apply(startup.render) fog = Fog('Fog') fog.setColor(0.2, 0.2, 0.2) fog.setLinearRange(0, 30) startup.render.setFog(fog) size = nar([7, 7, 0.01]) ModelBox("floorBox", nar([-0.5, -2, -size[2]]), size, (0.4, 0.4, 0.4, 1), startup.render) models = world_model() for data in models: if 'box' in data['tag']: model = data['model'] # type: CollideBox ModelBox(data['id'], model.org, model.size, (0.7, 0.7, 0.7, 1), startup.render) def spinCameraTask(task): self = startup angleDegrees = task.time * 30.0 angleRadians = angleDegrees * (pi / 180.0) self.camera.setPos(40 * sin(angleRadians), -40.0 * cos(angleRadians), 3) self.camera.setHpr(angleDegrees, 0, 0) self.camera.look_at(0, 0, 3) # self.plight.setPos(10*sin(angleRadians), -10.0*cos(angleRadians), 3) time.sleep(1.0 / 80.0) return Task.cont # startup.task_mgr.add(spinCameraTask, 'spinCameraTask') startup.run()
class Estate(Place.Place): notify = DirectNotifyGlobal.directNotify.newCategory('Estate') def __init__(self, loader, avId, zoneId, parentFSMState, doneEvent): Place.Place.__init__(self, None, doneEvent) self.id = MyEstate self.avId = avId self.zoneId = zoneId self.loader = loader self.cameraSubmerged = -1 self.toonSubmerged = -1 self.fsm = ClassicFSM.ClassicFSM('Estate', [ State.State('init', self.enterInit, self.exitInit, ['final', 'teleportIn', 'doorIn', 'walk']), State.State('petTutorial', self.enterPetTutorial, self.exitPetTutorial, ['walk']), State.State('walk', self.enterWalk, self.exitWalk, [ 'final', 'sit', 'stickerBook', 'options', 'quest', 'fishing', 'mailbox', 'stopped', 'DFA', 'trialerFA', 'doorOut', 'push', 'pet', 'purchase' ]), State.State('stopped', self.enterStopped, self.exitStopped, ['walk', 'teleportOut']), State.State('sit', self.enterSit, self.exitSit, ['walk']), State.State('push', self.enterPush, self.exitPush, ['walk']), State.State( 'stickerBook', self.enterStickerBook, self.exitStickerBook, [ 'walk', 'sit', 'quest', 'fishing', 'mailbox', 'stopped', 'doorOut', 'push', 'pet', 'DFA', 'trialerFA' ]), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk', 'petTutorial']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn', 'walk', 'final']), State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['final', 'walk']), State.State('final', self.enterFinal, self.exitFinal, ['teleportIn']), State.State('quest', self.enterQuest, self.exitQuest, ['walk']), State.State('fishing', self.enterFishing, self.exitFishing, ['walk', 'stopped']), State.State('mailbox', self.enterMailbox, self.exitMailbox, ['walk', 'stopped']), State.State('stopped', self.enterStopped, self.exitStopped, ['walk']), State.State('pet', self.enterPet, self.exitPet, ['walk', 'trialerFA']), State.State('trialerFA', self.enterTrialerFA, self.exitTrialerFA, ['trialerFAReject', 'DFA']), State.State('trialerFAReject', self.enterTrialerFAReject, self.exitTrialerFAReject, ['walk']), State.State('DFA', self.enterDFA, self.exitDFA, ['DFAReject', 'teleportOut']), State.State('purchase', self.enterPurchase, self.exitPurchase, ['walk']), State.State('DFAReject', self.enterDFAReject, self.exitDFAReject, ['walk']) ], 'init', 'final') self.fsm.enterInitialState() self.doneEvent = doneEvent self.parentFSMState = parentFSMState return def delete(self): self.unload() def load(self): Place.Place.load(self) self.fog = Fog('EstateFog') taskMgr.add(self.__checkCameraUnderwater, 'estate-check-cam-underwater') path = self.loader.geom.find('**/Path') path.setBin('ground', 10, 1) self.parentFSMState.addChild(self.fsm) def unload(self): self.ignoreAll() self.notify.info( 'remove estate-check-toon-underwater to TaskMgr in unload()') taskMgr.remove('estate-check-toon-underwater') taskMgr.remove('estate-check-cam-underwater') self.parentFSMState.removeChild(self.fsm) del self.fsm self.fog = None Place.Place.unload(self) return def enter(self, requestStatus): hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] newsManager = base.cr.newsManager if config.GetBool('want-estate-telemetry-limiter', 1): limiter = TLGatherAllAvs('Estate', RotationLimitToH) else: limiter = TLNull() self._telemLimiter = limiter if newsManager: holidayIds = base.cr.newsManager.getDecorationHolidayId() if (ToontownGlobals.HALLOWEEN_COSTUMES in holidayIds or ToontownGlobals.SPOOKY_COSTUMES in holidayIds) and self.loader.hood.spookySkyFile: lightsOff = Sequence( LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(0.55, 0.55, 0.65, 1)), Func(self.loader.hood.startSpookySky)) lightsOff.start() else: self.loader.hood.startSky() lightsOn = LerpColorScaleInterval( base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() else: self.loader.hood.startSky() lightsOn = LerpColorScaleInterval( base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() self.loader.hood.sky.setFogOff() self.__setFaintFog() for i in self.loader.nodeList: self.loader.enterAnimatedProps(i) self.loader.geom.reparentTo(render) # The client April Toons Manager is currently broken, so we have to do this hacky thing instead. :( #if hasattr(base.cr, 'aprilToonsMgr'): #if self.isEventActive(AprilToonsGlobals.EventEstateGravity): #base.localAvatar.startAprilToonsControls() if base.config.GetBool('want-april-toons'): base.localAvatar.startAprilToonsControls() self.accept('doorDoneEvent', self.handleDoorDoneEvent) self.accept('DistributedDoor_doorTrigger', self.handleDoorTrigger) self.fsm.request(requestStatus['how'], [requestStatus]) def exit(self): base.localAvatar.stopChat() if base.config.GetBool('want-april-toons'): base.localAvatar.stopAprilToonsControls() self._telemLimiter.destroy() del self._telemLimiter if hasattr(self, 'fsm'): self.fsm.requestFinalState() self.loader.geom.reparentTo(hidden) for i in self.loader.nodeList: self.loader.exitAnimatedProps(i) self.loader.hood.stopSky() render.setFogOff() base.cr.cache.flush() def __setZoneId(self, zoneId): self.zoneId = zoneId def detectedMailboxCollision(self): self.fsm.request('mailbox') def detectedGardenPlotUse(self): if hasattr(self, 'fsm'): self.fsm.request('stopped') def detectedGardenPlotDone(self): if hasattr(self, 'fsm'): self.fsm.request('walk') def detectedFlowerSellUse(self): if hasattr(self, 'fsm'): self.fsm.request('stopped') def detectedFlowerSellDone(self): if hasattr(self, 'fsm'): self.fsm.request('walk') def doRequestLeave(self, requestStatus): self.fsm.request('trialerFA', [requestStatus]) def enterInit(self): pass def exitInit(self): pass def enterPurchase(self): Place.Place.enterPurchase(self) def exitPurchase(self): Place.Place.exitPurchase(self) def enterPetTutorial(self, bDummy=True): self.notify.info( 'remove estate-check-toon-underwater to TaskMgr in enterPetTutorial()' ) taskMgr.remove('estate-check-toon-underwater') self.petTutorialDoneEvent = 'PetTutorialDone' self.acceptOnce(self.petTutorialDoneEvent, self.petTutorialDone) self.petTutorial = PetTutorial.PetTutorial(self.petTutorialDoneEvent) def exitPetTutorial(self): self.notify.info( 'add estate-check-toon-underwater to TaskMgr in exitPetTutorial()') if hasattr(self, 'fsm'): taskMgr.add(self.__checkToonUnderwater, 'estate-check-toon-underwater') if hasattr(self, 'petTutorial') and self.petTutorial is not None: self.petTutorial.destroy() return def petTutorialDone(self): self.ignore(self.petTutorialDoneEvent) self.petTutorial.destroy() self.petTutorial = None self.fsm.request('walk', [1]) return def enterMailbox(self): Place.Place.enterPurchase(self) base.localAvatar.startSleepWatch(self.__handleFallingAsleepMailbox) self.enablePeriodTimer() def __handleFallingAsleepMailbox(self, arg): if hasattr(self, 'fsm'): self.fsm.request('walk') messenger.send('mailboxAsleep') base.localAvatar.forceGotoSleep() def exitMailbox(self): Place.Place.exitPurchase(self) base.localAvatar.stopSleepWatch() self.disablePeriodTimer() def enterTeleportIn(self, requestStatus): self._etiToken = self.addSetZoneCompleteCallback( Functor(self._teleportToHouse, requestStatus)) Place.Place.enterTeleportIn(self, requestStatus) def _teleportToHouse(self, requestStatus): try: houseDo = base.cr.doId2do.get(base.localAvatar.houseId) house = houseDo.house pos = house.getPos(render) base.localAvatar.detachNode() base.localAvatar.setPosHpr(house, 17, 3, 0, 125, 0, 0) except: x, y, z, h, p, r = HouseGlobals.defaultEntryPoint base.localAvatar.detachNode() base.localAvatar.setPosHpr(render, x, y, z, h, p, r) base.localAvatar.setScale(1, 1, 1) self.toonSubmerged = -1 self.notify.info( 'remove estate-check-toon-underwater to TaskMgr in enterTeleportIn()' ) taskMgr.remove('estate-check-toon-underwater') if base.wantPets: if base.localAvatar.hasPet( ) and not base.localAvatar.bPetTutorialDone: self.nextState = 'petTutorial' def teleportInDone(self): self.notify.debug('teleportInDone') self.toonSubmerged = -1 if self.nextState is not 'petTutorial': self.notify.info( 'add estate-check-toon-underwater to TaskMgr in teleportInDone()' ) if hasattr(self, 'fsm'): taskMgr.add(self.__checkToonUnderwater, 'estate-check-toon-underwater') Place.Place.teleportInDone(self) def exitTeleportIn(self): self.removeSetZoneCompleteCallback(self._etiToken) Place.Place.exitTeleportIn(self) def enterTeleportOut(self, requestStatus): Place.Place.enterTeleportOut(self, requestStatus, self.__teleportOutDone) def __teleportOutDone(self, requestStatus): if hasattr(self, 'fsm'): self.fsm.requestFinalState() hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] avId = requestStatus['avId'] shardId = requestStatus['shardId'] if hoodId == ToontownGlobals.MyEstate and zoneId == self.getZoneId( ) and shardId == None: self.fsm.request('teleportIn', [requestStatus]) elif hoodId == ToontownGlobals.MyEstate and shardId == None: self.doneStatus = requestStatus self.getEstateZoneAndGoHome(requestStatus) else: self.doneStatus = requestStatus messenger.send(self.doneEvent, [self.doneStatus]) return def goHomeFailed(self, task): self.notifyUserGoHomeFailed() self.ignore('setLocalEstateZone') self.doneStatus['avId'] = -1 self.doneStatus['zoneId'] = self.getZoneId() self.fsm.request('teleportIn', [self.doneStatus]) return Task.done def exitTeleportOut(self): Place.Place.exitTeleportOut(self) def exitDoorIn(self): self.toonSubmerged = -1 self.notify.info( 'add estate-check-toon-underwater to TaskMgr in exitDoorIn()') if hasattr(self, 'fsm'): taskMgr.add(self.__checkToonUnderwater, 'estate-check-toon-underwater') Place.Place.exitDoorIn(self) def getZoneId(self): if self.zoneId: return self.zoneId else: self.notify.warning('no zone id available') def __checkCameraUnderwater(self, task): if base.camera.getZ(render) < -1.2: self.__submergeCamera() else: self.__emergeCamera() return Task.cont def __checkToonUnderwater(self, task): if base.localAvatar.getZ() < -4.0: self.__submergeToon() else: self.__emergeToon() return Task.cont def __submergeCamera(self): if self.cameraSubmerged == 1: return self.__setUnderwaterFog() base.playSfx(self.loader.underwaterSound, looping=1, volume=0.8) self.cameraSubmerged = 1 self.walkStateData.setSwimSoundAudible(1) def __emergeCamera(self): if self.cameraSubmerged == 0: return self.loader.underwaterSound.stop() self.loader.hood.sky.setFogOff() self.__setFaintFog() self.cameraSubmerged = 0 self.walkStateData.setSwimSoundAudible(0) def forceUnderWater(self): self.toonSubmerged = 0 self.__submergeToon() def __submergeToon(self): if self.toonSubmerged == 1: return self.notify.debug('continuing in __submergeToon') if hasattr(self, 'loader') and self.loader: base.playSfx(self.loader.submergeSound) if base.config.GetBool('disable-flying-glitch') == 0: self.fsm.request('walk') self.walkStateData.fsm.request('swimming', [self.loader.swimSound]) pos = base.localAvatar.getPos(render) base.localAvatar.d_playSplashEffect(pos[0], pos[1], -2.3) self.toonSubmerged = 1 def __emergeToon(self): if self.toonSubmerged == 0: return self.notify.debug('continuing in __emergeToon') if hasattr(self, 'walkStateData'): self.walkStateData.fsm.request('walking') self.toonSubmerged = 0 # The client April Toons Manager is currently broken, so we have to do this hacky thing instead. :( #if hasattr(base.cr, 'aprilToonsMgr'): #if self.isEventActive(AprilToonsGlobals.EventEstateGravity): #base.localAvatar.startAprilToonsControls() if base.config.GetBool('want-april-toons'): base.localAvatar.startAprilToonsControls() def __setUnderwaterFog(self): if base.wantFog: self.fog.setColor(Vec4(0.0, 0.0, 0.6, 1.0)) self.fog.setLinearRange(0.1, 100.0) render.setFog(self.fog) self.loader.hood.sky.setFog(self.fog) def __setWhiteFog(self): if base.wantFog: self.fog.setColor(Vec4(0.8, 0.8, 0.8, 1.0)) self.fog.setLinearRange(0.0, 400.0) render.setFog(self.fog) self.loader.hood.sky.setFog(self.fog) def __setFaintFog(self): if base.wantFog: self.fog.setColor(Vec4(0.8, 0.8, 0.8, 1.0)) self.fog.setLinearRange(0.0, 700.0) render.setFog(self.fog)
class Estate(Place.Place): notify = DirectNotifyGlobal.directNotify.newCategory('Estate') def __init__(self, loader, avId, zoneId, parentFSMState, doneEvent): Place.Place.__init__(self, None, doneEvent) self.id = MyEstate self.avId = avId self.zoneId = zoneId self.loader = loader self.cameraSubmerged = -1 self.toonSubmerged = -1 self.fsm = ClassicFSM.ClassicFSM('Estate', [State.State('init', self.enterInit, self.exitInit, ['final', 'teleportIn', 'doorIn', 'walk']), State.State('petTutorial', self.enterPetTutorial, self.exitPetTutorial, ['walk']), State.State('walk', self.enterWalk, self.exitWalk, ['final', 'sit', 'stickerBook', 'options', 'quest', 'fishing', 'mailbox', 'stopped', 'DFA', 'trialerFA', 'doorOut', 'push', 'pet', 'purchase']), State.State('stopped', self.enterStopped, self.exitStopped, ['walk', 'teleportOut']), State.State('sit', self.enterSit, self.exitSit, ['walk']), State.State('push', self.enterPush, self.exitPush, ['walk']), State.State('stickerBook', self.enterStickerBook, self.exitStickerBook, ['walk', 'sit', 'quest', 'fishing', 'mailbox', 'stopped', 'doorOut', 'push', 'pet', 'DFA', 'trialerFA']), State.State('teleportIn', self.enterTeleportIn, self.exitTeleportIn, ['walk', 'petTutorial']), State.State('teleportOut', self.enterTeleportOut, self.exitTeleportOut, ['teleportIn', 'walk', 'final']), State.State('doorIn', self.enterDoorIn, self.exitDoorIn, ['walk']), State.State('doorOut', self.enterDoorOut, self.exitDoorOut, ['final', 'walk']), State.State('final', self.enterFinal, self.exitFinal, ['teleportIn']), State.State('quest', self.enterQuest, self.exitQuest, ['walk']), State.State('fishing', self.enterFishing, self.exitFishing, ['walk', 'stopped']), State.State('mailbox', self.enterMailbox, self.exitMailbox, ['walk', 'stopped']), State.State('stopped', self.enterStopped, self.exitStopped, ['walk']), State.State('pet', self.enterPet, self.exitPet, ['walk', 'trialerFA']), State.State('trialerFA', self.enterTrialerFA, self.exitTrialerFA, ['trialerFAReject', 'DFA']), State.State('trialerFAReject', self.enterTrialerFAReject, self.exitTrialerFAReject, ['walk']), State.State('DFA', self.enterDFA, self.exitDFA, ['DFAReject', 'teleportOut']), State.State('purchase', self.enterPurchase, self.exitPurchase, ['walk']), State.State('DFAReject', self.enterDFAReject, self.exitDFAReject, ['walk'])], 'init', 'final') self.fsm.enterInitialState() self.doneEvent = doneEvent self.parentFSMState = parentFSMState return def delete(self): self.unload() def load(self): Place.Place.load(self) self.fog = Fog('EstateFog') taskMgr.add(self.__checkCameraUnderwater, 'estate-check-cam-underwater') path = self.loader.geom.find('**/Path') path.setBin('ground', 10, 1) self.parentFSMState.addChild(self.fsm) def unload(self): self.ignoreAll() self.notify.info('remove estate-check-toon-underwater to TaskMgr in unload()') taskMgr.remove('estate-check-toon-underwater') taskMgr.remove('estate-check-cam-underwater') self.parentFSMState.removeChild(self.fsm) del self.fsm self.fog = None Place.Place.unload(self) return def enter(self, requestStatus): hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] newsManager = base.cr.newsManager if config.GetBool('want-estate-telemetry-limiter', 1): limiter = TLGatherAllAvs('Estate', RotationLimitToH) else: limiter = TLNull() self._telemLimiter = limiter if newsManager: holidayIds = base.cr.newsManager.getDecorationHolidayId() if (ToontownGlobals.HALLOWEEN_COSTUMES in holidayIds or ToontownGlobals.SPOOKY_COSTUMES in holidayIds) and self.loader.hood.spookySkyFile: lightsOff = Sequence(LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(0.55, 0.55, 0.65, 1)), Func(self.loader.hood.startSpookySky)) lightsOff.start() else: self.loader.hood.startSky() lightsOn = LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() else: self.loader.hood.startSky() lightsOn = LerpColorScaleInterval(base.cr.playGame.hood.loader.geom, 0.1, Vec4(1, 1, 1, 1)) lightsOn.start() self.loader.hood.sky.setFogOff() self.__setFaintFog() for i in self.loader.nodeList: self.loader.enterAnimatedProps(i) self.loader.geom.reparentTo(render) # The client April Toons Manager is currently broken, so we have to do this hacky thing instead. :( #if hasattr(base.cr, 'aprilToonsMgr'): #if self.isEventActive(AprilToonsGlobals.EventEstateGravity): #base.localAvatar.startAprilToonsControls() if base.config.GetBool('want-april-toons'): base.localAvatar.startAprilToonsControls() self.accept('doorDoneEvent', self.handleDoorDoneEvent) self.accept('DistributedDoor_doorTrigger', self.handleDoorTrigger) self.fsm.request(requestStatus['how'], [requestStatus]) def exit(self): base.localAvatar.stopChat() if base.config.GetBool('want-april-toons'): base.localAvatar.stopAprilToonsControls() self._telemLimiter.destroy() del self._telemLimiter if hasattr(self, 'fsm'): self.fsm.requestFinalState() self.loader.geom.reparentTo(hidden) for i in self.loader.nodeList: self.loader.exitAnimatedProps(i) self.loader.hood.stopSky() render.setFogOff() base.cr.cache.flush() def __setZoneId(self, zoneId): self.zoneId = zoneId def detectedMailboxCollision(self): self.fsm.request('mailbox') def detectedGardenPlotUse(self): if hasattr(self, 'fsm'): self.fsm.request('stopped') def detectedGardenPlotDone(self): if hasattr(self, 'fsm'): self.fsm.request('walk') def detectedFlowerSellUse(self): if hasattr(self, 'fsm'): self.fsm.request('stopped') def detectedFlowerSellDone(self): if hasattr(self, 'fsm'): self.fsm.request('walk') def doRequestLeave(self, requestStatus): self.fsm.request('trialerFA', [requestStatus]) def enterInit(self): pass def exitInit(self): pass def enterPurchase(self): Place.Place.enterPurchase(self) def exitPurchase(self): Place.Place.exitPurchase(self) def enterPetTutorial(self, bDummy = True): self.notify.info('remove estate-check-toon-underwater to TaskMgr in enterPetTutorial()') taskMgr.remove('estate-check-toon-underwater') self.petTutorialDoneEvent = 'PetTutorialDone' self.acceptOnce(self.petTutorialDoneEvent, self.petTutorialDone) self.petTutorial = PetTutorial.PetTutorial(self.petTutorialDoneEvent) def exitPetTutorial(self): self.notify.info('add estate-check-toon-underwater to TaskMgr in exitPetTutorial()') if hasattr(self, 'fsm'): taskMgr.add(self.__checkToonUnderwater, 'estate-check-toon-underwater') if hasattr(self, 'petTutorial') and self.petTutorial is not None: self.petTutorial.destroy() return def petTutorialDone(self): self.ignore(self.petTutorialDoneEvent) self.petTutorial.destroy() self.petTutorial = None self.fsm.request('walk', [1]) return def enterMailbox(self): Place.Place.enterPurchase(self) base.localAvatar.startSleepWatch(self.__handleFallingAsleepMailbox) self.enablePeriodTimer() def __handleFallingAsleepMailbox(self, arg): if hasattr(self, 'fsm'): self.fsm.request('walk') messenger.send('mailboxAsleep') base.localAvatar.forceGotoSleep() def exitMailbox(self): Place.Place.exitPurchase(self) base.localAvatar.stopSleepWatch() self.disablePeriodTimer() def enterTeleportIn(self, requestStatus): self._etiToken = self.addSetZoneCompleteCallback(Functor(self._teleportToHouse, requestStatus)) Place.Place.enterTeleportIn(self, requestStatus) def _teleportToHouse(self, requestStatus): try: houseDo = base.cr.doId2do.get(base.localAvatar.houseId) house = houseDo.house pos = house.getPos(render) base.localAvatar.detachNode() base.localAvatar.setPosHpr(house, 17, 3, 0, 125, 0, 0) except: x, y, z, h, p, r = HouseGlobals.defaultEntryPoint base.localAvatar.detachNode() base.localAvatar.setPosHpr(render, x, y, z, h, p, r) base.localAvatar.setScale(1, 1, 1) self.toonSubmerged = -1 self.notify.info('remove estate-check-toon-underwater to TaskMgr in enterTeleportIn()') taskMgr.remove('estate-check-toon-underwater') if base.wantPets: if base.localAvatar.hasPet() and not base.localAvatar.bPetTutorialDone: self.nextState = 'petTutorial' def teleportInDone(self): self.notify.debug('teleportInDone') self.toonSubmerged = -1 if self.nextState is not 'petTutorial': self.notify.info('add estate-check-toon-underwater to TaskMgr in teleportInDone()') if hasattr(self, 'fsm'): taskMgr.add(self.__checkToonUnderwater, 'estate-check-toon-underwater') Place.Place.teleportInDone(self) def exitTeleportIn(self): self.removeSetZoneCompleteCallback(self._etiToken) Place.Place.exitTeleportIn(self) def enterTeleportOut(self, requestStatus): Place.Place.enterTeleportOut(self, requestStatus, self.__teleportOutDone) def __teleportOutDone(self, requestStatus): if hasattr(self, 'fsm'): self.fsm.requestFinalState() hoodId = requestStatus['hoodId'] zoneId = requestStatus['zoneId'] avId = requestStatus['avId'] shardId = requestStatus['shardId'] if hoodId == ToontownGlobals.MyEstate and zoneId == self.getZoneId() and shardId == None: self.fsm.request('teleportIn', [requestStatus]) elif hoodId == ToontownGlobals.MyEstate and shardId == None: self.doneStatus = requestStatus self.getEstateZoneAndGoHome(requestStatus) else: self.doneStatus = requestStatus messenger.send(self.doneEvent, [self.doneStatus]) return def goHomeFailed(self, task): self.notifyUserGoHomeFailed() self.ignore('setLocalEstateZone') self.doneStatus['avId'] = -1 self.doneStatus['zoneId'] = self.getZoneId() self.fsm.request('teleportIn', [self.doneStatus]) return Task.done def exitTeleportOut(self): Place.Place.exitTeleportOut(self) def exitDoorIn(self): self.toonSubmerged = -1 self.notify.info('add estate-check-toon-underwater to TaskMgr in exitDoorIn()') if hasattr(self, 'fsm'): taskMgr.add(self.__checkToonUnderwater, 'estate-check-toon-underwater') Place.Place.exitDoorIn(self) def getZoneId(self): if self.zoneId: return self.zoneId else: self.notify.warning('no zone id available') def __checkCameraUnderwater(self, task): if base.camera.getZ(render) < -1.2: self.__submergeCamera() else: self.__emergeCamera() return Task.cont def __checkToonUnderwater(self, task): if base.localAvatar.getZ() < -4.0: self.__submergeToon() else: self.__emergeToon() return Task.cont def __submergeCamera(self): if self.cameraSubmerged == 1: return self.__setUnderwaterFog() base.playSfx(self.loader.underwaterSound, looping=1, volume=0.8) self.cameraSubmerged = 1 self.walkStateData.setSwimSoundAudible(1) def __emergeCamera(self): if self.cameraSubmerged == 0: return self.loader.underwaterSound.stop() self.loader.hood.sky.setFogOff() self.__setFaintFog() self.cameraSubmerged = 0 self.walkStateData.setSwimSoundAudible(0) def forceUnderWater(self): self.toonSubmerged = 0 self.__submergeToon() def __submergeToon(self): if self.toonSubmerged == 1: return self.notify.debug('continuing in __submergeToon') if hasattr(self, 'loader') and self.loader: base.playSfx(self.loader.submergeSound) if base.config.GetBool('disable-flying-glitch') == 0: self.fsm.request('walk') self.walkStateData.fsm.request('swimming', [self.loader.swimSound]) pos = base.localAvatar.getPos(render) base.localAvatar.d_playSplashEffect(pos[0], pos[1], -2.3) self.toonSubmerged = 1 def __emergeToon(self): if self.toonSubmerged == 0: return self.notify.debug('continuing in __emergeToon') if hasattr(self, 'walkStateData'): self.walkStateData.fsm.request('walking') self.toonSubmerged = 0 # The client April Toons Manager is currently broken, so we have to do this hacky thing instead. :( #if hasattr(base.cr, 'aprilToonsMgr'): #if self.isEventActive(AprilToonsGlobals.EventEstateGravity): #base.localAvatar.startAprilToonsControls() if base.config.GetBool('want-april-toons'): base.localAvatar.startAprilToonsControls() def __setUnderwaterFog(self): if base.wantFog: self.fog.setColor(Vec4(0.0, 0.0, 0.6, 1.0)) self.fog.setLinearRange(0.1, 100.0) render.setFog(self.fog) self.loader.hood.sky.setFog(self.fog) def __setWhiteFog(self): if base.wantFog: self.fog.setColor(Vec4(0.8, 0.8, 0.8, 1.0)) self.fog.setLinearRange(0.0, 400.0) render.setFog(self.fog) self.loader.hood.sky.setFog(self.fog) def __setFaintFog(self): if base.wantFog: self.fog.setColor(Vec4(0.8, 0.8, 0.8, 1.0)) self.fog.setLinearRange(0.0, 700.0) render.setFog(self.fog)
class World(DirectObject): def __init__(self): self.last_mousex = 0 self.last_mousey = 0 self.zone = None self.zone_reload_name = None self.winprops = WindowProperties( ) # simple console output self.consoleNode = NodePath(PandaNode("console_root")) self.consoleNode.reparentTo(aspect2d) self.console_num_lines = 24 self.console_cur_line = -1 self.console_lines = [] for i in range(0, self.console_num_lines): self.console_lines.append(OnscreenText(text='', style=1, fg=(1,1,1,1), pos=(-1.3, .4-i*.05), align=TextNode.ALeft, scale = .035, parent = self.consoleNode)) # Configuration self.consoleOut('zonewalk v.%s loading configuration' % VERSION) self.configurator = Configurator(self) cfg = self.configurator.config resaveRes = False if 'xres' in cfg: self.xres = int(cfg['xres']) else: self.xres = 1024 resaveRes = True if 'yres' in cfg: self.yres = int(cfg['yres']) else: self.yres = 768 resaveRes = True if resaveRes: self.saveDefaultRes() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.mouse_accum = MouseAccume( lambda: (self.xres_half,self.yres_half)) self.eyeHeight = 7.0 self.rSpeed = 80 self.flyMode = 1 # application window setup base.win.setClearColor(Vec4(0,0,0,1)) self.winprops.setTitle( 'zonewalk') self.winprops.setSize(self.xres, self.yres) base.win.requestProperties( self.winprops ) base.disableMouse() # network test stuff self.login_client = None if 'testnet' in cfg: if cfg['testnet'] == '1': self.doLogin() # Post the instructions self.title = addTitle('zonewalk v.' + VERSION) self.inst0 = addInstructions(0.95, "[FLYMODE][1]") self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.") self.inst2 = addInstructions(0.9, "Loc:") self.inst3 = addInstructions(0.85, "Hdg:") self.error_inst = addInstructions(0, '') self.kh = [] self.campos = Point3(155.6, 41.2, 4.93) base.camera.setPos(self.campos) # Accept the application control keys: currently just esc to exit navgen self.accept("escape", self.exitGame) self.accept("window-event", self.resizeGame) # Create some lighting ambient_level = .6 ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0)) render.setLight(render.attachNewNode(ambientLight)) direct_level = 0.8 directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0.0, 0.0, -1.0)) directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1)) directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1)) render.setLight(render.attachNewNode(directionalLight)) # create a point light that will follow our view point (the camera for now) # attenuation is set so that this point light has a torch like effect self.plight = PointLight('plight') self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002)) self.plnp = base.camera.attachNewNode(self.plight) self.plnp.setPos(0, 0, 0) render.setLight(self.plnp) self.cam_light = 1 self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, \ "cam-right":0, "mouse3":0, "flymode":1 } # setup FOG self.fog_colour = (0.8,0.8,0.8,1.0) self.linfog = Fog("A linear-mode Fog node") self.linfog.setColor(self.fog_colour) self.linfog.setLinearRange(700, 980) # onset, opaque distances as params # linfog.setLinearFallback(45,160,320) base.camera.attachNewNode(self.linfog) render.setFog(self.linfog) self.fog = 1 # camera control self.campos = Point3(0, 0, 0) self.camHeading = 0.0 self.camPitch = 0.0 base.camLens.setFov(65.0) base.camLens.setFar(1200) self.cam_speed = 0 # index into self.camp_speeds self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0] # Collision Detection for "WALKMODE" # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. The ray will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0.0, 0.0, 0.0) self.camGroundRay.setDirection(0,0,-1) # straight down self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) # attach the col node to the camCollider dummy node self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays # self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring # self.cTrav.showCollisions(render) # Add the spinCameraTask procedure to the task manager. # taskMgr.add(self.spinCameraTask, "SpinCameraTask") taskMgr.add(self.camTask, "camTask") self.toggleControls(1) # need to step the task manager once to make our fake console work taskMgr.step() # CONSOLE --------------------------------------------------------------------- def consoleScroll(self): for i in range(0, self.console_num_lines-1): self.console_lines[i].setText(self.console_lines[i+1].getText()) def consoleOut(self, text): print text # output to stdout/log too if self.console_cur_line == self.console_num_lines-1: self.consoleScroll() elif self.console_cur_line < self.console_num_lines-1: self.console_cur_line += 1 self.console_lines[self.console_cur_line].setText(text) taskMgr.step() def consoleOn(self): self.consoleNode.show() def consoleOff(self): self.consoleNode.hide() # User controls ----------------------------------------------------------- def toggleControls(self, on): cfg = self.configurator.config if on == 1: self.accept("escape", self.exitGame) self.accept("1", self.setSpeed, ["speed", 0]) self.accept("2", self.setSpeed, ["speed", 1]) self.accept("3", self.setSpeed, ["speed", 2]) self.accept("4", self.setSpeed, ["speed", 3]) self.accept("5", self.setSpeed, ["speed", 4]) self.accept("alt-f", self.fogToggle) self.accept(cfg['control_lighting'], self.camLightToggle) self.accept(cfg['control_help'], self.displayKeyHelp) self.accept(cfg['control_flymode'], self.toggleFlymode) self.accept(cfg['control_reload-zone'], self.reloadZone) # Deactivate this for now #self.accept("z", self.saveDefaultZone) self.accept(cfg['control_cam-left'], self.setKey, ["cam-left",1]) self.accept(cfg['control_cam-right'], self.setKey, ["cam-right",1]) self.accept(cfg['control_forward'], self.setKey, ["forward",1]) # Mouse1 should be for clicking on objects #self.accept("mouse1", self.setKey, ["forward",1]) self.accept("mouse3", self.setKey, ["mouse3",1]) self.accept(cfg['control_backward'], self.setKey, ["backward",1]) self.accept("k-up", self.hideKeyHelp) self.accept(cfg['control_cam-left']+"-up", self.setKey, ["cam-left",0]) self.accept(cfg['control_cam-right']+"-up", self.setKey, ["cam-right",0]) self.accept(cfg['control_forward']+"-up", self.setKey, ["forward",0]) # Mouse1 should be for clicking on objects #self.accept("mouse1-up", self.setKey, ["forward",0]) self.accept("mouse3-up", self.setKey, ["mouse3",0]) self.accept(cfg['control_backward']+"-up", self.setKey, ["backward",0]) else: messenger.clear() def setSpeed(self, key, value): self.cam_speed = value self.setFlymodeText() def fogToggle(self): if self.fog == 1: render.clearFog() base.camLens.setFar(100000) self.fog = 0 else: render.setFog(self.linfog) base.camLens.setFar(1200) self.fog = 1 def camLightToggle(self): if self.cam_light == 0: render.setLight(self.plnp) self.cam_light = 1 else: render.clearLight(self.plnp) self.cam_light = 0 def displayKeyHelp(self): self.kh = [] msg = 'HOTKEYS:' pos = 0.75 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '------------------' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '1-5: set camera movement speed' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'F: toggle Flymode/Walkmode' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'L: load a zone' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ALT-F: toggle FOG and FAR plane on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'T: toggle additional camera "torch" light on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'Z: set currently loaded zone as new startup default' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ESC: exit zonewalk' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) def hideKeyHelp(self): for n in self.kh: n.removeNode() def setFlymodeText(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed+1, zname)) else: self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed+1, zname)) def toggleFlymode(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.flyMode = 1 else: self.flyMode = 0 self.setFlymodeText() # Define a procedure to move the camera. def spinCameraTask(self, task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) base.camera.setHpr(angleDegrees, 0, 0) return task.cont def camTask(self, task): # query the mouse mouse_dx = 0 mouse_dy = 0 # if we have a mouse and the right button is depressed if base.mouseWatcherNode.hasMouse(): if self.keyMap["mouse3"] != 0: self.mouse_accum.update() else: self.mouse_accum.reset() mouse_dx = self.mouse_accum.dx mouse_dy = self.mouse_accum.dy self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed+1) * max(5 * 1000/self.xres,3) self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed+1) * max(3 * 1000/self.yres,1) if (self.keyMap["cam-left"]!=0 or mouse_dx < 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading += self.rXSpeed * globalClock.getDt() else: self.camHeading += self.rSpeed * globalClock.getDt() if self.camHeading > 360.0: self.camHeading = self.camHeading - 360.0 elif (self.keyMap["cam-right"]!=0 or mouse_dx > 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading -= self.rXSpeed * globalClock.getDt() else: self.camHeading -= self.rSpeed * globalClock.getDt() if self.camHeading < 0.0: self.camHeading = self.camHeading + 360.0 else: self.rSpeed = 80 if mouse_dy > 0: self.camPitch += self.rYSpeed * globalClock.getDt() elif mouse_dy < 0: self.camPitch -= self.rYSpeed * globalClock.getDt() # set camera heading and pitch base.camera.setHpr(self.camHeading, self.camPitch, 0) # viewer position (camera) movement control v = render.getRelativeVector(base.camera, Vec3.forward()) if not self.flyMode: v.setZ(0.0) move_speed = self.cam_speeds[self.cam_speed] if self.keyMap["forward"] == 1: self.campos += v * move_speed * globalClock.getDt() if self.keyMap["backward"] == 1: self.campos -= v * move_speed * globalClock.getDt() # actually move the camera lastPos = base.camera.getPos() base.camera.setPos(self.campos) # self.plnp.setPos(self.campos) # move the point light with the viewer position # WALKMODE: simple collision detection # we simply check a ray from slightly below the "eye point" straight down # for geometry collisions and if there are any we detect the point of collision # and adjust the camera's Z accordingly if self.flyMode == 0: # move the camera to where it would be if it made the move # the colliderNode moves with it # base.camera.setPos(self.campos) # check for collissons self.cTrav.traverse(render) entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) # print 'collision' entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if (len(entries) > 0): # and (entries[0].getIntoNode().getName() == "terrain"): # print len(entries) self.campos.setZ(entries[0].getSurfacePoint(render).getZ()+self.eyeHeight) else: self.campos = lastPos base.camera.setPos(self.campos) #if (base.camera.getZ() < self.player.getZ() + 2.0): # base.camera.setZ(self.player.getZ() + 2.0) # update loc and hpr display pos = base.camera.getPos() hpr = base.camera.getHpr() self.inst2.setText('Loc: %.2f, %.2f, %.2f' % (pos.getX(), pos.getY(), pos.getZ())) self.inst3.setText('Hdg: %.2f, %.2f, %.2f' % (hpr.getX(), hpr.getY(), hpr.getZ())) return task.cont def exitGame(self): sys.exit(0) def resizeGame(self,win): props = base.win.getProperties() self.xres = props.getXSize() self.yres = props.getYSize() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.saveDefaultRes() #Records the state of the arrow keys # this is used for camera control def setKey(self, key, value): self.keyMap[key] = value # ------------------------------------------------------------------------- # this is the mythical MAIN LOOP :) def update(self): if self.zone_reload_name != None: self.doReload(self.zone_reload_name) self.zone_reload_name = None if self.zone != None: self.zone.update() taskMgr.step() if self.login_client != None: self.login_client.update() # ZONE loading ------------------------------------------------------------ # general zone loader driver # removes existing zone (if any) and load the new one def loadZone(self, name, path): if path[len(path)-1] != '/': path += '/' if self.zone: self.zone.rootNode.removeNode() self.zone = Zone(self, name, path) error = self.zone.load() if error == 0: self.consoleOff() self.setFlymodeText() base.setBackgroundColor(self.fog_colour) def saveDefaultRes(self): cfg = self.configurator.config cfg['xres'] = str(self.xres) cfg['yres'] = str(self.yres) #self.configurator.saveConfig() # initial world load after bootup def load(self): cfg = self.configurator.config if self.login_client != None: return zone_name = cfg['default_zone'] basepath = cfg['basepath'] self.loadZone(zone_name, basepath) # config save user interfacce def saveDefaultZone(self): if self.zone: cfg = self.configurator.config cfg['default_zone'] = self.zone.name #self.configurator.saveConfig() # zone reload user interface # this gets called from our update loop when it detects that zone_reload_name has been set # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking # because otherwise our status console output at various stages during the zone load would not # be displayed. Yes, this is hacky. def doReload(self, name): cfg = self.configurator.config basepath = cfg['basepath'] self.loadZone(name, basepath) # form dialog callback # this gets called from the form when the user has entered a something # (hopefully a correct zone short name) def reloadZoneDialogCB(self, name): self.frmDialog.end() self.zone_reload_name = name self.toggleControls(1) # this is called when the user presses "l" # it disables normal controls and fires up our query form dialog def reloadZone(self): base.setBackgroundColor((0,0,0)) self.toggleControls(0) self.consoleOn() self.frmDialog = FileDialog( "Please enter the shortname of the zone you wish to load:", "Examples: qrg, blackburrow, freportn, crushbone etc.", self.reloadZoneDialogCB) self.frmDialog.activate() # relies on the main update loop to run ############################### # EXPERIMENTAL def doLogin(self): self.login_client = UDPClientStream('127.0.0.1', 5998) ##################################### # Custom methods ##################################### # What happens when a user clicks on a model def onModelClick(): # Code adapted freely from http://www.panda3d.org/forums/viewtopic.php?t=12717 global picker, selected_model namedNode, thePoint, rawNode = picker.pick() if namedNode: if "_mesh" not in namedNode.getName(): # rough test to avoid printing infos on global zone mesh (ie: "freporte_mesh") name = namedNode.getName() p = namedNode.getParent() pos = p.getPos() selected_model = namedNode print namedNode.getName() print "Collision Point: ", thePoint namedNode.ls() else: print "Clicked location point (y, x, z):", thePoint #selected_model.setPos(thePoint.getX(), thePoint.getY(), thePoint.getZ()) m.setPos(thePoint.getX(), thePoint.getY(), thePoint.getZ()) print "Moved !" # Handles populating the zone with spawn data from the EQEmu DB # also makes each spawner model pickable def PopulateSpawns(self, cursor, numrows): spawn_coords = list() globals.model_list = list() for x in range(0, numrows): row = cursor.fetchone() point = Point3(long(row["Spawn2Y"]), long(row["Spawn2X"]), long(row["Spawn2Z"])) if point not in spawn_coords: s = loader.loadModel("models/cube.egg") s.reparentTo(render) s.setPos(row["Spawn2Y"], row["Spawn2X"], row["Spawn2Z"]) min,macks= s.getTightBounds() radius = max([macks.getY() - min.getY(), macks.getX() - min.getX()])/2 cs = CollisionSphere(row["Spawn2X"], row["Spawn2Y"], row["Spawn2Z"], radius) csNode = s.attachNewNode(CollisionNode("modelCollide")) csNode.node().addSolid(cs) s.setTag("name", row["name"]) picker.makePickable(s) globals.model_list.append(s) spawn_coords.append(point) # Establishes a connection to the EQEmu database def ConnectToDatabase(self): configurator = Configurator(world) cfg = configurator.config conn = MySQLdb.Connection( host=cfg['host'], user=cfg['user'], passwd=cfg['password'], db=cfg['db']) return conn # Queries the Database in order to get spawn data # (this should be refactored at some point) def GetDbSpawnData(self, connection): cursor = connection.cursor(MySQLdb.cursors.DictCursor) query = """SELECT nt.name, s2.zone, s2.x as Spawn2X, s2.y as Spawn2Y, s2.z as Spawn2Z, sg.name as spawngroup_name,sg.id as Spawngroup_id, sg.min_x as Spawngroup_minX, sg.max_x as Spawngroup_maxX, sg.min_y as Spawngroup_minY, sg.max_y as Spawngroup_maxY, sg.dist as Spawngroup_dist, sg.mindelay as Spawngroup_mindelay, sg.delay as Spawngroup_delay FROM spawn2 s2 JOIN spawngroup sg ON sg.id = s2.spawngroupid JOIN spawnentry se ON se.spawngroupid = sg.id JOIN npc_types nt ON nt.id = se.npcid WHERE s2.zone = 'freporte'""" cursor.execute(query) return cursor # Initializes the camera position upon startup def InitCameraPosition(self): world.campos = Point3(-155.6, 41.2, 4.9 + world.eyeHeight) world.camHeading = 270.0 base.camera.setPos(world.campos) def GetCamera(self): return base.camera
class CogdoBarrelRoom: notify = DirectNotifyGlobal.directNotify.newCategory('DistributedCogdoBarrelRoom') def __init__(self): self.timer = None self.model = None self._isLoaded = False self.dummyElevInNode = None self.cogdoBarrelsNode = None self.entranceNode = None self.nearBattleNode = None self.rewardUi = None self.rewardUiTaskName = 'CogdoBarrelRoom-RewardUI' self.rewardCameraTaskName = 'CogdoBarrelRoom-RewardCamera' self.fog = None self.defaultFar = None self.stomperSfx = None return def destroy(self): self.unload() def load(self): if self._isLoaded: return self.timer = ToontownTimer.ToontownTimer() self.timer.stash() self.model = loader.loadModel(CogdoBarrelRoomConsts.BarrelRoomModel) self.model.setPos(*CogdoBarrelRoomConsts.BarrelRoomModelPos) self.model.reparentTo(render) self.model.stash() self.dummyElevInNode = self.model.attachNewNode('elevator-in') self.dummyElevInNode.hide() self.entranceNode = self.model.attachNewNode('door-entrance') self.entranceNode.setPos(0, -65, 0) self.nearBattleNode = self.model.attachNewNode('near-battle') self.nearBattleNode.setPos(0, -25, 0) self.rewardUi = CogdoBarrelRoomRewardPanel.CogdoBarrelRoomRewardPanel() self.hideRewardUi() self.stomperSfx = base.loadSfx(CogdoBarrelRoomConsts.StomperSound) self.fog = Fog('barrel-room-fog') self.fog.setColor(CogdoBarrelRoomConsts.BarrelRoomFogColor) self.fog.setLinearRange(*CogdoBarrelRoomConsts.BarrelRoomFogLinearRange) self._isLoaded = True def unload(self): if self.model: self.model.removeNode() self.model = None if self.timer: self.timer.destroy() self.timer = None if self.rewardUi: self.rewardUi.destroy() self.rewardUi = None if self.fog: render.setFogOff() del self.fog taskMgr.remove(self.rewardUiTaskName) taskMgr.remove(self.rewardCameraTaskName) self._isLoaded = False return def isLoaded(self): return self._isLoaded def show(self): if not self.cogdoBarrelsNode: self.cogdoBarrelsNode = render.find('**/@@CogdoBarrels') self.cogdoBarrelsNode.reparentTo(self.model) self.cogdoBarrelsNode.unstash() self.defaultFar = base.camLens.getFar() base.camLens.setFar(CogdoBarrelRoomConsts.BarrelRoomCameraFar) self.showBattleAreaLight(True) render.setFog(self.fog) self.model.unstash() def hide(self): self.model.stash() render.setFogOff() if self.defaultFar is not None: base.camLens.setFar(self.defaultFar) return def activate(self): self.notify.info('Activating barrel room: %d sec timer.' % CogdoBarrelRoomConsts.CollectionTime) self.timer.unstash() self.timer.posAboveShtikerBook() self.timer.countdown(CogdoBarrelRoomConsts.CollectionTime) base.cr.playGame.getPlace().fsm.request('walk') def deactivate(self): self.notify.info('Deactivating barrel room.') self.timer.stop() self.timer.stash() def placeToonsAtEntrance(self, toons): for i in xrange(len(toons)): toons[i].setPosHpr(self.entranceNode, *CogdoBarrelRoomConsts.BarrelRoomPlayerSpawnPoints[i]) def placeToonsNearBattle(self, toons): for i in xrange(len(toons)): toons[i].setPosHpr(self.nearBattleNode, *CogdoBarrelRoomConsts.BarrelRoomPlayerSpawnPoints[i]) def showBattleAreaLight(self, visible = True): lightConeNode = self.model.find('**/battleCone') if lightConeNode != None and not lightConeNode.isEmpty(): if visible: lightConeNode.show() else: lightConeNode.hide() return def getIntroInterval(self): avatar = base.localAvatar trackName = '__introBarrelRoom-%d' % avatar.doId track = Parallel(name=trackName) track.append(self.__stomperIntervals()) track.append(Sequence(Func(base.camera.reparentTo, render), Func(base.camera.setPosHpr, self.model, -20.0, -87.9, 12.0, -30, 0, 0), Func(base.transitions.irisIn, 0.5), Wait(1.0), LerpHprInterval(base.camera, duration=2.0, startHpr=Vec3(-30, 0, 0), hpr=Vec3(0, 0, 0), blendType='easeInOut'), Wait(2.5), LerpHprInterval(base.camera, duration=3.0, startHpr=Vec3(0, 0, 0), hpr=Vec3(-45, 0, 0), blendType='easeInOut'), Wait(2.5))) track.delayDelete = DelayDelete.DelayDelete(avatar, 'introBarrelRoomTrack') track.setDoneEvent(trackName) return (track, trackName) def __stomperIntervals(self): ivals = [SoundInterval(self.stomperSfx)] i = 0 for stomperDef in CogdoBarrelRoomConsts.StomperProps: stomperNode = render.find(stomperDef['path']) if stomperNode: maxZ = random.uniform(10, 20) minZ = maxZ - 10 if stomperDef['motion'] == 'up': startZ, destZ = minZ, maxZ else: startZ, destZ = maxZ, minZ stomperNode.setPos(Point3(0, 0, startZ)) ivals.append(LerpPosInterval(stomperNode, CogdoBarrelRoomConsts.StomperHaltTime, Point3(0, 0, destZ), blendType='easeOut')) i += 1 return Parallel(*tuple(ivals)) def __rewardUiTimeout(self, callback): self.hideRewardUi() if callback is not None: callback() return def __rewardCamera(self): trackName = 'cogdoBarrelRoom-RewardCamera' track = Sequence(Func(base.camera.reparentTo, render), Func(base.camera.setPosHpr, self.model, 0, 0, 11.0, 0, -14, 0), Func(self.showBattleAreaLight, False), name=trackName) return (track, trackName) def showRewardUi(self, results, callback = None): track, trackName = self.__rewardCamera() if CogdoBarrelRoomConsts.ShowRewardUI: self.rewardUi.setRewards(results) self.rewardUi.unstash() taskMgr.doMethodLater(CogdoBarrelRoomConsts.RewardUiTime, self.__rewardUiTimeout, self.rewardUiTaskName, extraArgs=[callback]) return (track, trackName) def setRewardResults(self, results): self.rewardUi.setRewards(results) def hideRewardUi(self): self.rewardUi.stash() taskMgr.remove(self.rewardUiTaskName)
class VisualTest(ShowBase): def __init__(self): super().__init__(self) self.var1 = 0 self.scene = loader.loadModel("models/world") playerTexture = loader.loadTexture("models/starfoxShip.jpg") self.player = self.scene.find("player") self.player.setTexture(playerTexture) base.setBackgroundColor(0.1, 0.1, 0.1, 1) enemyTexture = loader.loadTexture("models/enemyShip.jpg") self.enemy = self.scene.find("enemy1") self.enemy.setTexture(enemyTexture) self.basePlane = self.scene.find("basePlane") self.scene.reparentTo(self.render) self.player.setPos(50, 50, 3) self.enemy.setPos(50, 55, 0) self.ambient = AmbientLight("ambient") self.ambient.color = (0.1, 0.1, 0.1, 1) self.ambientPath = self.render.attachNewNode(self.ambient) render.setLight(self.ambientPath) self.dirLight = DirectionalLight("dir light") self.dirLight.color = (1, 1, 1, 1) self.dirLightPath = self.render.attachNewNode(self.dirLight) self.dirLightPath.setHpr(0, -90, 0) self.dirLight.setShadowCaster(True, 512, 512) render.setLight(self.dirLightPath) self.pointLight = PointLight("point light") self.pointLight.color = (1, 1, 1, 1) self.pointLightPath = self.render.attachNewNode(self.pointLight) self.pointLightPath.setPos(50, 52.5, 4) self.pointLight.attenuation = (.5, 0, 0) self.pointLight.setShadowCaster(True, 1024, 1024) self.render.setLight(self.pointLightPath) self.fog = Fog("fog") self.fog.setColor(0.1, 0.1, 0.1) self.fog.setExpDensity(.3) self.fog.setLinearRange(150, 300) self.fog.setLinearFallback(45, 160, 320) self.render.setFog(self.fog) self.render.setShaderAuto() self.render.setAntialias(AntialiasAttrib.MAuto) filters = CommonFilters(base.win, base.cam) filters.setBloom(size="large") filters.setAmbientOcclusion(strength=0.6, falloff=0.0005, radius=0.1) filters.setCartoonInk(separation=2, color=(0, 0, 0, 1)) self.taskMgr.add(self.update, "update") def update(self, evt): self.var1 = self.var1 + 0.1 #self.dirLight.color = (self.var1,0,1,1) #self.dirLightPath.setHpr(self.var1,-self.var1,0) self.camera.setPos(60 + self.var1, 60 + self.var1, 20) #self.pointLightPath.setPos(30+self.var1 ,52.5,4) self.camera.lookAt(self.player) return Task.cont
class DistributedRace(DistributedObject.DistributedObject): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedRace') ReadyPost = 'RaceReady' WinEvent = 'RaceWinEvent' BGM_BaseDir = 'phase_6/audio/bgm/' SFX_BaseDir = 'phase_6/audio/sfx/' SFX_StartBoop = SFX_BaseDir + 'KART_raceStart1.ogg' SFX_StartBoop2 = SFX_BaseDir + 'KART_raceStart2.ogg' SFX_Applause = SFX_BaseDir + 'KART_Applause_%d.ogg' def __init__(self, cr): self.qbox = loader.loadModel('phase_6/models/karting/qbox') self.boostArrowTexture = loader.loadTexture('phase_6/maps/boost_arrow.jpg', 'phase_6/maps/boost_arrow_a.rgb') self.boostArrowTexture.setMinfilter(Texture.FTLinear) DistributedObject.DistributedObject.__init__(self, cr) self.kartMap = {} self.fsm = ClassicFSM.ClassicFSM('Race', [State.State('join', self.enterJoin, self.exitJoin, ['prep', 'leave']), State.State('prep', self.enterPrep, self.exitPrep, ['tutorial', 'leave']), State.State('tutorial', self.enterTutorial, self.exitTutorial, ['start', 'waiting', 'leave']), State.State('waiting', self.enterWaiting, self.exitWaiting, ['start', 'leave']), State.State('start', self.enterStart, self.exitStart, ['racing', 'leave']), State.State('racing', self.enterRacing, self.exitRacing, ['finished', 'leave']), State.State('finished', self.enterFinished, self.exitFinished, ['leave']), State.State('leave', self.enterLeave, self.exitLeave, [])], 'join', 'leave') self.gui = RaceGUI(self) base.race = self self.currT = 0 self.currLapT = 0 self.currGag = 0 self.tdelay = 0 self.finished = False self.thrownGags = [] self.effectManager = EffectManager.EffectManager() self.piejectileManager = PiejectileManager.PiejectileManager() self.lastTimeUpdate = globalClock.getFrameTime() self.initGags() self.canShoot = True self.isUrbanTrack = False self.hasFog = False self.dummyNode = None self.fog = None self.bananaSound = base.loadSfx('phase_6/audio/sfx/KART_tossBanana.ogg') self.anvilFall = base.loadSfx('phase_6/audio/sfx/KART_Gag_Hit_Anvil.ogg') self.accept('leaveRace', self.leaveRace) self.toonsToLink = [] self.curveTs = [] self.curvePoints = [] self.localKart = None self.musicTrack = None self.victory = None self.miscTaskNames = [] self.boostDir = {} self.knownPlace = {} self.placeFixup = [] self.curve = None self.barricadeSegments = 100.0 self.outerBarricadeDict = {} self.innerBarricadeDict = {} self.maxLap = 0 self.oldT = 0 self.debugIt = 0 self.startPos = None return def generate(self): self.notify.debug('generate: %s' % self.doId) DistributedObject.DistributedObject.generate(self) bboard.post('race', self) self.roomWatcher = None self.cutoff = 0.01 self.startBoopSfx = base.loadSfx(self.SFX_StartBoop) self.startBoop2Sfx = base.loadSfx(self.SFX_StartBoop2) return def announceGenerate(self): self.notify.debug('announceGenerate: %s' % self.doId) DistributedObject.DistributedObject.announceGenerate(self) musicFile = self.BGM_BaseDir + RaceGlobals.TrackDict[self.trackId][7] self.raceMusic = base.loadMusic(musicFile) base.playMusic(self.raceMusic, looping=1, volume=0.8) base.camera.reparentTo(render) if self.trackId in (RaceGlobals.RT_Urban_1, RaceGlobals.RT_Urban_1_rev, RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.isUrbanTrack = True self.oldFarPlane = base.camLens.getFar() base.camLens.setFar(12000) localAvatar.startPosHprBroadcast() localAvatar.d_broadcastPositionNow() DistributedSmoothNode.activateSmoothing(1, 1) self.reversed = self.trackId / 2.0 > int(self.trackId / 2.0) for i in xrange(3): base.loader.tick() self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') self.sky.setPos(0, 0, 0) self.sky.setScale(20.0) self.sky.setFogOff() if self.trackId in (RaceGlobals.RT_Urban_1, RaceGlobals.RT_Urban_1_rev, RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.loadFog() self.setupGeom() self.startSky() for i in xrange(5): base.loader.tick() def disable(self): self.notify.debug('disable %s' % self.doId) if self.musicTrack: self.musicTrack.finish() self.raceMusic.stop() self.stopSky() if self.sky is not None: self.sky.removeNode() if self.dummyNode: self.dummyNode.removeNode() self.dummyNode = None for taskName in self.miscTaskNames: taskMgr.remove(taskName) taskMgr.remove('raceWatcher') self.ignoreAll() DistributedSmoothNode.activateSmoothing(1, 0) if self.isUrbanTrack: self.unloadUrbanTrack() if self.fog: render.setFogOff() del self.fog self.fog = None if self.geom is not None: self.geom.hide() base.camLens.setFar(self.oldFarPlane) DistributedObject.DistributedObject.disable(self) return def delete(self): self.notify.debug('delete %s' % self.doId) if self.gui: self.gui.destroy() self.gui = None if self.geom is not None: self.geom.removeNode() self.geom = None for i in self.gags: i.delete() del i self.piejectileManager.delete() if self.curveTs: del self.curveTs if self.curvePoints: del self.curvePoints if self.curve: del self.curve if self.victory: del self.victory del self.fsm del self.anvilFall del self.bananaSound del self.localKart DistributedObject.DistributedObject.delete(self) taskMgr.remove(self.uniqueName('countdownTimerTask')) taskMgr.remove('raceWatcher') bboard.remove('race') self.ignoreAll() del base.race return def d_requestThrow(self, x, y, z): self.sendUpdate('requestThrow', [x, y, z]) def d_requestKart(self): self.sendUpdate('requestKart', []) def waitingForJoin(self): self.notify.debug('I got the barrier') self.fsm.enterInitialState() def racerDisconnected(self, avId): self.notify.debug('lost racer: %s' % avId) if avId in self.kartMap: if avId in self.toonsToLink: self.toonsToLink.remove(avId) toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) self.avIds.remove(avId) del self.kartMap[avId] self.gui.racerLeft(avId, unexpected=True) if kart: kart.reparentTo(hidden) if toon: toon.reparentTo(hidden) if len(self.toonsToLink) == 0: self.doneBarrier('waitingForPrep') return def setPlace(self, avId, totalTime, place, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): if self.fsm.getCurrentState().getName() == 'leaving': return if avId == localAvatar.doId: cheerToPlay = place + (4 - self.numRacers) if cheerToPlay > 4: cheerToPlay = 4 self.victory = base.loadSfx(self.SFX_Applause % cheerToPlay) self.victory.play() self.knownPlace[avId] = place kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) avatar = base.cr.doId2do.get(avId, None) if avatar: self.gui.racerFinished(avId, self.trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime) taskName = 'hideAv: %s' % avId taskMgr.doMethodLater(6, avatar.reparentTo, taskName, extraArgs=[hidden]) self.miscTaskNames.append(taskName) if kart: taskName = 'hideKart: %s' % self.localKart.doId taskMgr.doMethodLater(6, kart.reparentTo, taskName, extraArgs=[hidden]) self.miscTaskNames.append(taskName) return def setCircuitPlace(self, avId, place, entryFee, winnings, bonus, trophies): print 'setting cicruit place' if self.fsm.getCurrentState().getName() == 'leaving': return if avId == localAvatar.doId: cheerToPlay = place + (4 - self.numRacers) self.victory = base.loadSfx(self.SFX_Applause % cheerToPlay) self.victory.play() oldPlace = 0 if self.knownPlace.get(avId): oldPlace = self.knownPlace[avId] self.placeFixup.append([oldPlace - 1, place - 1]) avatar = base.cr.doId2do.get(avId, None) if avatar: print 'circuit trophies %s' % trophies print 'winnings %s' % winnings self.gui.racerFinishedCircuit(avId, oldPlace, entryFee, winnings, bonus, trophies) return def endCircuitRace(self): print self.placeFixup self.gui.circuitFinished(self.placeFixup) def prepForRace(self): self.fsm.request('prep') def startRace(self, startTime = 0): self.baseTime = globalClockDelta.networkToLocalTime(startTime) self.fsm.request('start') def startTutorial(self): self.fsm.request('tutorial') def genGag(self, slot, number, type): self.notify.debug('making gag...') if not self.gags[slot].isActive(): self.gags[slot].genGag(number, type) def dropAnvilOn(self, ownerId, avId, timeStamp): kart = base.cr.doId2do.get(self.kartMap.get(avId, None), None) if kart: if avId != ownerId: if avId == localAvatar.doId: self.anvilFall.play() kart.dropOnMe(timeStamp) else: kart.dropOnHim(timeStamp) return def shootPiejectile(self, sourceId, targetId, type = 0): kart = base.cr.doId2do.get(self.kartMap.get(sourceId, None), None) if kart: self.piejectileManager.addPiejectile(sourceId, targetId, type) return def goToSpeedway(self, avIds, reason = RaceGlobals.Exit_UserReq): self.notify.debug('goToSpeedway %s %s' % (avIds, reason)) if localAvatar.doId in avIds: base.loader.endBulkLoad('atRace') self.kartCleanup() self.doneBarrier('waitingForExit') self.sendUpdate('racerLeft', [localAvatar.doId]) out = {'loader': 'safeZoneLoader', 'where': 'playground', 'how': 'teleportIn', 'hoodId': localAvatar.lastHood, 'zoneId': localAvatar.lastHood, 'shardId': None, 'avId': -1, 'reason': reason} base.cr.playGame.fsm.request('quietZone', [out]) return def kartCleanup(self): kart = self.localKart if kart: kart.setState('P', 0) for i in self.avIds: if i != localAvatar.doId: toon = base.cr.doId2do.get(i, None) if toon: toon.stopSmooth() toon.setScale(1) toon.setShear(0, 0, 0) toon.reparentTo(render) kart.doHeadScale(toon, None) localAvatar.setPos(0, 14, 0) localAvatar.sendCurrentPosition() return def heresMyT(self, avId, avNumLaps, avTime, timestamp): self.gui.updateRacerInfo(avId, curvetime=avNumLaps + avTime) def setZoneId(self, zoneId): self.zoneId = zoneId def setRaceType(self, raceType): self.raceType = raceType def setCircuitLoop(self, circuitLoop): self.circuitLoop = circuitLoop def setTrackId(self, id): DistributedRace.notify.debug('setTrackId: %s' % id) self.trackId = id def setAvatars(self, avIds): ids = '' for i in avIds: ids += str(i) + ' ' DistributedRace.notify.debug('setAvatars: %s' % ids) self.avIds = avIds self.avT = [0] * len(self.avIds) def setLapCount(self, lapCount): self.lapCount = lapCount def setStartingPlaces(self, startList): self.startingPlaces = startList def enterJoin(self): self.doneBarrier('waitingForJoin') self.notify.debug('entering Join') def exitJoin(self): pass def setEnteredRacers(self, avAndKarts): self.notify.debug('setEnteredRacers %s' % avAndKarts) avatarsGone = [] avatarsLeft = [] self.numRacers = len(avAndKarts) for i in avAndKarts: if i[0] in self.avIds: self.kartMap[i[0]] = i[1] avatarsLeft.append(i[0]) for i in self.avIds: if i not in avatarsLeft: avatarsGone.append(i) base.loader.tick() for i in avatarsGone: self.avIds.remove(i) self.toonsToLink = list(self.avIds) for i in avAndKarts: self.cr.relatedObjectMgr.requestObjects(i, allCallback=self.__gotKartAvatarLink) def __gotKartAvatarLink(self, avAndKart): self.notify.debug('got a Link') toon = avAndKart[0] kart = avAndKart[1] base.loader.tick() if toon.doId in self.toonsToLink: self.toonsToLink.remove(toon.doId) if toon.doId == localAvatar.doId: self.localKart = kart if len(self.toonsToLink) == 0: self.doneBarrier('waitingForPrep') def enterPrep(self): self.d_requestKart() self.notify.debug('entering Prep State') if self.reversed: self.spin = Vec3(180, 0, 0) else: self.spin = Vec3(0, 0, 0) for i in xrange(4): base.loader.tick() self.gui.initRaceMode() self.gui.initResultMode() self.myPos = self.startingPos[self.startingPlaces[self.avIds.index(localAvatar.doId)]] self.localKart.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) self.localKart.setupLapCollisions() if self.dummyNode: self.dummyNode.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) self.currentPole = self.findSegmentStart() self.rabbitPoint = Vec3(0, 0, 0) self.doneBarrier('waitingForReady') def exitPrep(self): pass def enterTutorial(self): self.notify.debug('entering Tutorial State') base.loader.endBulkLoad('atRace') self.localKart.setPosHpr(self.myPos[0], self.myPos[1] + self.spin) base.transitions.irisIn() self.rulesDoneEvent = 'finishedRules' self.accept(self.rulesDoneEvent, self.handleRulesDone) self.rulesPanel = MinigameRulesPanel.MinigameRulesPanel('RacingRulesPanel', self.getTitle(), self.getInstructions(), self.rulesDoneEvent, 10) self.rulesPanel.load() self.rulesPanel.frame.setPos(0, 0, -0.6667) self.rulesPanel.enter() def exitTutorial(self): self.ignore(self.rulesDoneEvent) self.rulesPanel.exit() self.rulesPanel.unload() del self.rulesPanel def getTitle(self): return TTLocalizer.KartRace_TitleInfo def getInstructions(self): return TTLocalizer.KartRace_TrackInfo[self.trackId] def handleRulesDone(self): self.doneBarrier('readRules') self.fsm.request('waiting') def enterWaiting(self): self.waitingLabel = DirectLabel() self.waitingLabel['text'] = TTLocalizer.BuildingWaitingForVictors self.waitingLabel.setScale(TTLocalizer.DRenterWaiting) def exitWaiting(self): self.waitingLabel.removeNode() def enterStart(self): waitTime = self.baseTime - globalClock.getFrameTime() taskName = 'enableRaceModeLater' taskMgr.doMethodLater(1, self.gui.enableRaceMode, taskName, extraArgs=[]) self.miscTaskNames.append(taskName) for i in self.avIds: self.gui.racerEntered(i) self.startCountdownClock(waitTime, 0) taskMgr.doMethodLater(waitTime, self.fsm.request, 'goToRacing', extraArgs=['racing']) def exitStart(self): pass def enterRacing(self): self.localKart.setInput(1) self.gui.setTimerEnabled(True) self.raceTask = taskMgr.add(self.raceWatcher, 'raceWatcher') def exitRacing(self): pass def raceWatcher(self, task): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) if self.localKart.amIClampingPosition(): self.notify.debug('teleporting kart %d back to main track' % localAvatar.doId) self.localKart.setPos(self.curvePoints[self.currentPole]) kartPoint = self.localKart.getPos() direction = 0 while True: currPoint = self.curvePoints[self.currentPole] nextPole = (self.currentPole + 1) % len(self.curvePoints) nextPoint = self.curvePoints[nextPole] segment = nextPoint - currPoint segment.setZ(0) segLength2 = segment.lengthSquared() kartVector = kartPoint - currPoint kartVector.setZ(0) project = segment * (segment.dot(kartVector) / segLength2) projLength2 = project.lengthSquared() if project.dot(segment) < 0: if direction == 1: break prevPole = (self.currentPole - 1) % len(self.curvePoints) self.currentPole = prevPole direction = -1 elif projLength2 > segLength2: if direction == -1: break self.currentPole = nextPole direction = 1 else: break if self.dummyNode: self.dummyNode.setPos(kartPoint[0], kartPoint[1], 0) self.dummyNode.setHpr(self.localKart.getH(), 0, 0) t = projLength2 / segLength2 if self.debugIt: self.notify.debug('self.debugIt = %d' % self.debugIt) import pdb pdb.set_trace() if nextPole < self.currentPole: newT = self.curveTs[self.currentPole] * (1 - t) + self.curve.getMaxT() * t else: newT = self.curveTs[self.currentPole] * (1 - t) + self.curveTs[nextPole] * t kartDirection = self.localKart.forward.getPos(render) - self.localKart.getPos(render) kartDirection.normalize() project.normalize() globalDirection = kartDirection.dot(project) if globalDirection < 0: self.wrongWay = True elif globalDirection > 0.1: self.wrongWay = False newLapT = (newT - self.startT) / self.curve.getMaxT() % 1.0 if newLapT - self.currLapT < -0.5: self.laps += 1 self.changeMusicTempo(1 + self.laps * 0.5) self.notify.debug('crossed the start line: %s, %s, %s, %s' % (self.laps, self.startT, self.currT, newT)) elif newLapT - self.currLapT > 0.5: self.laps -= 1 self.changeMusicTempo(1 + self.laps * 0.5) self.notify.debug('crossed the start line - wrong way: %s, %s, %s, %s' % (self.laps, self.startT, self.currT, newT)) self.currT = newT self.currLapT = newLapT if self.isUrbanTrack: self.showBuildings(self.currT) now = globalClock.getFrameTime() timestamp = globalClockDelta.localToNetworkTime(now) if self.laps == self.lapCount: self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) self.fsm.request('finished') if self.laps > self.maxLap: self.maxLap = self.laps self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) if now - self.lastTimeUpdate > 0.5: self.lastTimeUpdate = now self.sendUpdate('heresMyT', [localAvatar.doId, self.laps, self.currLapT, timestamp]) self.gui.updateRacerInfo(localAvatar.doId, curvetime=self.currLapT + self.laps) self.gui.update(now) return Task.cont def enterFinished(self): taskMgr.remove('raceWatcher') self.fadeOutMusic() self.localKart.interruptTurbo() self.localKart.disableControls() taskName = 'parkIt' taskMgr.doMethodLater(2, self.stopDriving, taskName, extraArgs=[]) self.miscTaskNames.append(taskName) self.finished = True base.camera.reparentTo(render) base.camera.setPos(self.localKart.getPos(render) + Vec3(0, 0, 10)) base.camera.setH(self.localKart.getH(render) + 180) self.gui.disableRaceMode() self.gui.enableResultMode() localAvatar.reparentTo(hidden) self.localKart.reparentTo(hidden) def exitFinished(self): pass def stopDriving(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) cpos = base.camera.getPos() chpr = base.camera.getHpr() localAvatar.reparentTo(hidden) self.localKart.reparentTo(hidden) self.localKart.stopSmooth() self.localKart.stopPosHprBroadcast() base.camera.setPos(cpos) base.camera.setHpr(chpr) return def enterLeave(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) taskMgr.remove('raceWatcher') self.gui.disable() if self.localKart: self.localKart.disableControls() base.transitions.irisOut() if self.raceType == RaceGlobals.Circuit and not len(self.circuitLoop) == 0: self.sendUpdate('racerLeft', [localAvatar.doId]) else: taskMgr.doMethodLater(1, self.goToSpeedway, 'leaveRace', extraArgs=[[localAvatar.doId], RaceGlobals.Exit_UserReq]) if self.victory: self.victory.stop() self.bananaSound.stop() self.anvilFall.stop() return def exitLeave(self): pass def getCountdownColor(self, countdownTimeInt): clockNodeColors = [Vec4(0, 1, 0, 1), Vec4(1, 1, 0, 1), Vec4(1, 0.5, 0, 1), Vec4(1, 0, 0, 1)] i = max(min(countdownTimeInt, len(clockNodeColors) - 1), 0) return clockNodeColors[i] def startCountdownClock(self, countdownTime, ts): self.clockNode = TextNode('k') self.clockNode.setFont(ToontownGlobals.getSignFont()) self.clockNode.setAlign(TextNode.ACenter) countdownInt = int(countdownTime) self.clockNode.setTextColor(self.getCountdownColor(countdownInt)) self.clockNode.setText(str(countdownInt)) self.clock = render2d.attachNewNode(self.clockNode) rs = TTLocalizer.DRrollScale self.clock.setPosHprScale(0, 0, 0, 0, 0, 0, rs, rs, rs) self.clock.hide() if ts < countdownTime: self.countdown(countdownTime - ts) def timerTask(self, task): countdownTime = int(task.duration - task.time) timeStr = str(countdownTime + 1) if self.clock.isHidden(): if task.duration - task.time <= task.maxCount: self.clock.show() if self.clockNode.getText() != timeStr: self.startBoopSfx.play() self.clockNode.setText(timeStr) self.clockNode.setTextColor(self.getCountdownColor(countdownTime + 1)) if task.time >= task.duration: self.startBoop2Sfx.play() self.clockNode.setText(TTLocalizer.KartRace_Go) self.clockNode.setTextColor(self.getCountdownColor(-1)) taskMgr.doMethodLater(1, self.endGoSign, 'removeGoSign') return Task.done else: return Task.cont def endGoSign(self, t): self.clock.removeNode() def countdown(self, duration): countdownTask = Task(self.timerTask) countdownTask.duration = duration countdownTask.maxCount = RaceGlobals.RaceCountdown taskMgr.remove(self.uniqueName('countdownTimerTask')) return taskMgr.add(countdownTask, self.uniqueName('countdownTimerTask')) def initGags(self): self.banana = globalPropPool.getProp('banana') self.banana.setScale(2) self.pie = globalPropPool.getProp('creampie') self.pie.setScale(1) def makeCheckPoint(self, trigger, location, event): cs = CollisionSphere(0, 0, 0, 140) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(self.geom) cnp.setPos(location) self.accept(triggerEvent, event) def loadUrbanTrack(self): self.dnaStore = DNAStorage() files = ('phase_4/dna/storage.pdna', 'phase_5/dna/storage_town.pdna', 'phase_4/dna/storage_TT.pdna', 'phase_5/dna/storage_TT_town.pdna', 'phase_8/dna/storage_BR.pdna', 'phase_8/dna/storage_BR_town.pdna', 'phase_8/dna/storage_DL.pdna', 'phase_8/dna/storage_DL_town.pdna') dnaBulk = DNABulkLoader(self.dnaStore, files) dnaBulk.loadDNAFiles() dnaFile = 'phase_6/dna/urban_track_town.pdna' if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): dnaFile = 'phase_6/dna/urban_track_town_B.pdna' node = loader.loadDNAFile(self.dnaStore, dnaFile) self.townGeom = self.geom.attachNewNode(node) self.townGeom.findAllMatches('**/+CollisionNode').stash() self.buildingGroups = {} self.currBldgInd = {} self.currBldgGroups = {} bgGeom = self.geom.find('**/polySurface8') if self.dummyNode: bgGeom.reparentTo(self.dummyNode) else: bgGeom.reparentTo(localAvatar) bgGeom.setScale(0.1) ce = CompassEffect.make(NodePath(), CompassEffect.PRot) bgGeom.node().setEffect(ce) bgGeom.setDepthTest(0) bgGeom.setDepthWrite(0) bgGeom.setBin('background', 102) bgGeom.setZ(-1) self.bgGeom = bgGeom l = self.geom.findAllMatches('**/+ModelNode') for n in l: n.node().setPreserveTransform(0) self.geom.flattenLight() maxNum = 0 for side in ['inner', 'outer']: self.buildingGroups[side] = [] self.currBldgInd[side] = None self.currBldgGroups[side] = None i = 0 while 1: bldgGroup = self.townGeom.find('**/Buildings_' + side + '-' + str(i)) if bldgGroup.isEmpty(): break l = bldgGroup.findAllMatches('**/+ModelNode') for n in l: n2 = n.getParent().attachNewNode(n.getName()) n.getChildren().reparentTo(n2) n.removeNode() bldgGroup.flattenStrong() if not bldgGroup.getNode(0).getBounds().isEmpty(): self.buildingGroups[side].append(bldgGroup) i += 1 if i > maxNum: maxNum = i for side in ['innersidest', 'outersidest']: self.buildingGroups[side] = [] self.currBldgInd[side] = None self.currBldgGroups[side] = None for i in xrange(maxNum): for barricade in ('innerbarricade', 'outerbarricade'): bldgGroup = self.townGeom.find('**/Buildings_' + side + '-' + barricade + '_' + str(i)) if bldgGroup.isEmpty(): continue l = bldgGroup.findAllMatches('**/+ModelNode') for n in l: n2 = n.getParent().attachNewNode(n.getName()) n.getChildren().reparentTo(n2) n.removeNode() self.buildingGroups[side].append(bldgGroup) treeNodes = self.townGeom.findAllMatches('**/prop_tree_*') for tree in treeNodes: tree.flattenStrong() snowTreeNodes = self.townGeom.findAllMatches('**/prop_snow_tree_*') for snowTree in snowTreeNodes: snowTree.flattenStrong() for side in ['inner', 'outer', 'innersidest', 'outersidest']: for grp in self.buildingGroups[side]: grp.stash() self.showBuildings(0) def unloadUrbanTrack(self): del self.buildingGroups self.townGeom.removeNode() def loadFog(self): self.hasFog = True if self.isUrbanTrack: base.camLens.setFar(650) else: base.camLens.setFar(650) self.dummyNode = render.attachNewNode('dummyNode') if base.wantFog: self.fog = Fog('TrackFog') self.fog.setColor(Vec4(0.6, 0.7, 0.8, 1.0)) if self.isUrbanTrack: self.fog.setLinearRange(200.0, 650.0) else: self.fog.setLinearRange(200.0, 800.0) render.setFog(self.fog) self.sky.setScale(1.725) self.sky.reparentTo(self.dummyNode) def showBuildings(self, t, forceRecompute = False): firstTimeCalled = 0 if self.curve: t = t / self.curve.getMaxT() else: firstTimeCalled = 1 if self.reversed: t = 1.0 - t numGroupsShown = 5 for side in ['inner', 'outer']: numBldgGroups = len(self.buildingGroups[side]) bldgInd = int(t * numBldgGroups) bldgInd = bldgInd % numBldgGroups if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): oldBldgInd = int(self.oldT * numBldgGroups) newBldgInd = int(t * numBldgGroups) kartPoint = self.startPos kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) if kart: kartPoint = self.localKart.getPos() if not self.currBldgInd[side]: self.currBldgInd[side] = 0 curInd = self.currBldgInd[side] myCurGroup = self.buildingGroups[side][curInd] prevGrp = (curInd - 1) % numBldgGroups myPrevGroup = self.buildingGroups[side][prevGrp] nextGrp = (curInd + 1) % numBldgGroups myNextGroup = self.buildingGroups[side][nextGrp] curVector = myCurGroup.getNode(0).getBounds().getCenter() - kartPoint curDistance = curVector.lengthSquared() prevVector = myPrevGroup.getNode(0).getBounds().getCenter() - kartPoint prevDistance = prevVector.lengthSquared() nextVector = myNextGroup.getNode(0).getBounds().getCenter() - kartPoint nextDistance = nextVector.lengthSquared() if curDistance <= prevDistance and curDistance <= nextDistance: bldgInd = self.currBldgInd[side] elif prevDistance <= curDistance and prevDistance <= nextDistance: bldgInd = prevGrp elif nextDistance <= curDistance and nextDistance <= prevDistance: bldgInd = nextGrp else: self.notify.warning('unhandled case!!!!') bldgInd = self.currBldgInd[side] if bldgInd != self.currBldgInd[side]: currBldgGroups = self.currBldgGroups[side] if currBldgGroups: for i in currBldgGroups: self.buildingGroups[side][i].stash() prevGrp2 = (bldgInd - 2) % numBldgGroups prevGrp = (bldgInd - 1) % numBldgGroups currGrp = bldgInd % numBldgGroups nextGrp = (bldgInd + 1) % numBldgGroups nextGrp2 = (bldgInd + 2) % numBldgGroups self.currBldgGroups[side] = [prevGrp2, prevGrp, currGrp, nextGrp, nextGrp2] for i in self.currBldgGroups[side]: self.buildingGroups[side][i].unstash() self.currBldgInd[side] = bldgInd if self.currBldgGroups['inner'] != self.currBldgGroups['outer']: pass if t != self.oldT: self.oldT = t if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): if self.reversed: t = 1.0 - t for side in ['innersidest', 'outersidest']: segmentInd = int(t * self.barricadeSegments) seglmentInd = segmentInd % self.barricadeSegments if segmentInd != self.currBldgInd[side] or forceRecompute: currBldgGroups = self.currBldgGroups[side] if currBldgGroups: for i in currBldgGroups: self.buildingGroups[side][i].stash() self.currBldgGroups[side] = [] if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict if segmentInd in dict: self.currBldgGroups[side] = dict[segmentInd] for i in self.currBldgGroups[side]: self.buildingGroups[side][i].unstash() self.currBldgInd[side] = segmentInd return def setupGeom(self): trackFilepath = RaceGlobals.TrackDict[self.trackId][0] self.geom = loader.loadModel(trackFilepath) for i in xrange(10): base.loader.tick() self.geom.reparentTo(render) if self.reversed: lapStartPos = self.geom.find('**/lap_start_rev').getPos() else: lapStartPos = self.geom.find('**/lap_start').getPos() self.startPos = lapStartPos lapMidPos = self.geom.find('**/lap_middle').getPos() for i in xrange(5): base.loader.tick() self.startingPos = [] posLocators = self.geom.findAllMatches('**/start_pos*') for i in xrange(posLocators.getNumPaths()): base.loader.tick() self.startingPos.append([posLocators[i].getPos(), posLocators[i].getHpr()]) self.notify.debug('self.startingPos: %s' % self.startingPos) self.wrongWay = False self.laps = 0 if self.isUrbanTrack: self.loadUrbanTrack() self.genArrows() if self.reversed: self.curve = self.geom.find('**/curve_reverse').node() else: self.curve = self.geom.find('**/curve_forward').node() for i in xrange(4000): self.curvePoints.append(Point3(0, 0, 0)) self.curve.getPoint(i / 4000.0 * (self.curve.getMaxT() - 1e-11), self.curvePoints[-1]) self.curveTs.append(i / 4000.0 * (self.curve.getMaxT() - 1e-11)) if self.trackId in (RaceGlobals.RT_Urban_2, RaceGlobals.RT_Urban_2_rev): self.precomputeSideStreets() for i in xrange(10): base.loader.tick() self.startT = self.getNearestT(lapStartPos) self.midT = self.getNearestT(lapMidPos) self.gags = [] gagList = RaceGlobals.TrackDict[self.trackId][4] for i in xrange(len(gagList)): self.notify.debug('generating gag: %s' % i) self.gags.append(RaceGag(self, i, Vec3(*gagList[i]) + Vec3(0, 0, 3))) for i in xrange(5): base.loader.tick() def precomputeSideStreets(self): farDist = base.camLens.getFar() + 300 farDistSquared = farDist * farDist for i in xrange(int(self.barricadeSegments)): testPoint = Point3(0, 0, 0) self.curve.getPoint(i / self.barricadeSegments * (self.curve.getMaxT() - 1e-11), testPoint) for side in ('innersidest', 'outersidest'): for bldgGroupIndex in xrange(len(self.buildingGroups[side])): bldgGroup = self.buildingGroups[side][bldgGroupIndex] if not bldgGroup.getNode(0).getBounds().isEmpty(): bldgPoint = bldgGroup.getNode(0).getBounds().getCenter() vector = testPoint - bldgPoint if vector.lengthSquared() < farDistSquared: if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict else: self.notify.error('unhandled side') if i in dict: if bldgGroupIndex not in dict[i]: dict[i].append(bldgGroupIndex) else: dict[i] = [bldgGroupIndex] for childIndex in (0,): if childIndex >= bldgGroup.getNumChildren(): continue childNodePath = bldgGroup.getChild(childIndex) bldgPoint = childNodePath.node().getBounds().getCenter() vector = testPoint - bldgPoint if vector.lengthSquared() < farDistSquared: if side == 'innersidest': dict = self.innerBarricadeDict elif side == 'outersidest': dict = self.outerBarricadeDict else: self.notify.error('unhandled side') if i in dict: if bldgGroupIndex not in dict[i]: dict[i].append(bldgGroupIndex) else: dict[i] = [bldgGroupIndex] for side in ('innersidest', 'outersidest'): for bldgGroup in self.buildingGroups[side]: bldgGroup.flattenStrong() if self.isUrbanTrack: self.showBuildings(0, forceRecompute=True) def findSegmentStart(self): kart = base.cr.doId2do.get(self.kartMap.get(localAvatar.doId, None), None) minLength2 = 1000000 minIndex = -1 currPoint = Point3(0, 0, 0) kartPoint = self.localKart.getPos() for i in xrange(len(self.curvePoints)): currPoint = self.curvePoints[i] currLength2 = (kartPoint - currPoint).lengthSquared() if currLength2 < minLength2: minLength2 = currLength2 minIndex = i currPoint = self.curvePoints[minIndex] if minIndex + 1 == len(self.curvePoints): nextPoint = self.curvePoints[0] else: nextPoint = self.curvePoints[minIndex + 1] if minIndex - 1 < 0: prevIndex = len(self.curvePoints) - 1 else: prevIndex = minIndex - 1 forwardSegment = nextPoint - currPoint if (kartPoint - currPoint).dot(forwardSegment) > 0: return minIndex else: return prevIndex return def getNearestT(self, pos): minLength2 = 1000000 minIndex = -1 currPoint = Point3(0, 0, 0) for i in xrange(len(self.curvePoints)): currPoint = self.curvePoints[i] currLength2 = (pos - currPoint).lengthSquared() if currLength2 < minLength2: minLength2 = currLength2 minIndex = i currPoint = self.curvePoints[minIndex] if minIndex + 1 == len(self.curvePoints): nextPoint = self.curvePoints[0] else: nextPoint = self.curvePoints[minIndex + 1] if minIndex - 1 < 0: prevIndex = len(self.curvePoints) - 1 else: prevIndex = minIndex - 1 forwardSegment = nextPoint - currPoint if (pos - currPoint).dot(forwardSegment) > 0: pole = minIndex else: pole = prevIndex currPoint = self.curvePoints[pole] nextPole = (pole + 1) % len(self.curvePoints) nextPoint = self.curvePoints[nextPole] segment = nextPoint - currPoint segment.setZ(0) segLength2 = segment.lengthSquared() posVector = pos - currPoint posVector.setZ(0) project = segment * (segment.dot(posVector) / segLength2) percent = project.lengthSquared() / segLength2 if nextPole < pole: t = self.curveTs[pole] * (1 - percent) + self.curve.getMaxT() * percent else: t = self.curveTs[pole] * (1 - percent) + self.curveTs[nextPole] * percent return t def hasGag(self, slot, type, index): if self.gags[slot].isActive(): self.gags[slot].disableGag() def leaveRace(self): self.fsm.request('leave') def racerLeft(self, avId): if avId != localAvatar.doId: self.gui.racerLeft(avId, unexpected=False) def skyTrack(self, task): return SkyUtil.cloudSkyTrack(task) def startSky(self): if self.hasFog: SkyUtil.startCloudSky(self, parent=self.dummyNode, effects=CompassEffect.PRot) else: SkyUtil.startCloudSky(self, parent=render) def stopSky(self): taskMgr.remove('skyTrack') def pickupGag(self, slot, index): self.canShoot = False standing = self.gui.racerDict[localAvatar.doId].place - 1 self.currGag = RaceGlobals.GagFreq[standing][index] cycleTime = 2 self.gui.waitingOnGag(cycleTime) taskMgr.doMethodLater(cycleTime, self.enableShoot, 'enableShoot') self.sendUpdate('hasGag', [slot, self.currGag, index]) def shootGag(self): if self.canShoot: if self.currGag == 1: self.bananaSound.play() self.shootBanana() elif self.currGag == 2: self.d_requestThrow(0, 0, 0) self.localKart.startTurbo() elif self.currGag == 3: self.d_requestThrow(0, 0, 0) elif self.currGag == 4: self.bananaSound.play() self.shootPie() self.currGag = 0 self.gui.updateGag(0) def enableShoot(self, t): self.canShoot = True if self.gui: self.gui.updateGag(self.currGag) def shootBanana(self): pos = self.localKart.getPos(render) banana = self.banana.copyTo(self.geom) banana.setPos(pos) self.thrownGags.append(banana) self.d_requestThrow(pos[0], pos[1], pos[2]) def shootPie(self): pos = self.localKart.getPos(render) self.d_requestThrow(pos[0], pos[1], pos[2]) def genArrows(self): base.arrows = [] arrowId = 0 for boost in RaceGlobals.TrackDict[self.trackId][5]: self.genArrow(boost[0], boost[1], arrowId) arrowId += 1 def genArrow(self, pos, hpr, id): factory = CardMaker('factory') factory.setFrame(-.5, 0.5, -.5, 0.5) arrowNode = factory.generate() arrowRoot = NodePath('root') baseArrow = NodePath(arrowNode) baseArrow.setTransparency(1) baseArrow.setTexture(self.boostArrowTexture) baseArrow.reparentTo(arrowRoot) arrow2 = baseArrow.copyTo(baseArrow) arrow2.setPos(0, 0, 1) arrow3 = arrow2.copyTo(arrow2) arrowRoot.setPos(*pos) arrowRoot.setHpr(*hpr) baseArrow.setHpr(0, -90, 0) baseArrow.setScale(24) arrowRoot.reparentTo(self.geom) trigger = 'boostArrow' + str(id) cs = CollisionTube(Point3(0.6, -6, 0), Point3(0.6, 54, 0), 4.8) cs.setTangible(0) triggerEvent = 'imIn-' + trigger cn = CollisionNode(trigger) cn.addSolid(cs) cn.setIntoCollideMask(BitMask32(32768)) cn.setFromCollideMask(BitMask32(32768)) cnp = NodePath(cn) cnp.reparentTo(arrowRoot) self.accept(triggerEvent, self.hitBoostArrow) arrowVec = arrow2.getPos(self.geom) - baseArrow.getPos(self.geom) arrowVec.normalize() idStr = str(id) cnp.setTag('boostId', idStr) self.boostDir[idStr] = arrowVec base.arrows.append(arrowRoot) def hitBoostArrow(self, cevent): into = cevent.getIntoNodePath() idStr = into.getTag('boostId') arrowVec = self.boostDir.get(idStr) if arrowVec == None: print 'Unknown boost arrow %s' % idStr return fvec = self.localKart.forward.getPos(self.geom) - self.localKart.getPos(self.geom) fvec.normalize() dotP = arrowVec.dot(fvec) if dotP > 0.7: self.localKart.startTurbo() return def fadeOutMusic(self): if self.musicTrack: self.musicTrack.finish() curVol = self.raceMusic.getVolume() interval = LerpFunctionInterval(self.raceMusic.setVolume, fromData=curVol, toData=0, duration=3) self.musicTrack = Sequence(interval) self.musicTrack.start() def changeMusicTempo(self, newPR): return # TODO: Reenable when we have music change support. if self.musicTrack: self.musicTrack.finish() curPR = self.raceMusic.getPlayRate() interval = LerpFunctionInterval(self.raceMusic.setPlayRate, fromData=curPR, toData=newPR, duration=3) self.musicTrack = Sequence(interval) self.musicTrack.start() def setRaceZone(self, zoneId, trackId): hoodId = self.cr.playGame.hood.hoodId base.loader.endBulkLoad('atRace') self.kartCleanup() self.doneBarrier('waitingForExit') self.sendUpdate('racerLeft', [localAvatar.doId]) out = {'loader': 'racetrack', 'where': 'racetrack', 'hoodId': hoodId, 'zoneId': zoneId, 'trackId': trackId, 'shardId': None, 'reason': RaceGlobals.Exit_UserReq} base.cr.playGame.hood.loader.fsm.request('quietZone', [out]) return
class ToontownFogManager: def __init__(self): self.fog = None self.fogMode = None print("Initialized Fog Manager") self.fog = Fog("ActiveFog") self.fog.setColor(1, 1, 1) self.fogTypes = { 0: Fog.MExponential, 1: Fog.MExponentialSquared, 2: Fog.MLinear } def setFog(self, np): np.setFog(self.fog) def setColor(self, r, g, b): self.fog.setColor(r, g, b) def clearFog(self): return render.clearFog() def getFogMode(self): self.fogMode = self.fog.getMode() def setFogMode(self, id): mode = self.fog.setMode(self.fogTypes[id]) self.fogMode = mode ## For Exponential Fog def setDensity(self, density): """ Determines the density value used for exponential fog calculations. :param float density: A value between [0, 1] """ self.fog.setExpDensity(density) ## For Linear Fog def setLinearRange(self, range, opacity): """ Specifies the effects of the fog in linear distance units. This is only used if the mode is M_linear. This specifies a fog that begins at distance onset units from the origin, and becomes totally opaque at distance <opaque units> from the origin, along the forward axis (usually Y). This function also implicitly sets the mode the M_linear, if it is not already set. :param float opacity: [0, 1] """ self.fog.setLinearRange(range, opacity) def setLinearFallback(self, angle, onset, opaque): """ :param float angle: the minimum viewing angle (angle between the camera direction and fog direction) at which the fallback effect will be employed. :type onset: float :param float opaque: [0, 1] Defines how the fog should be rendered when the fog effect is diminished in this way. Onset and opaque specify camera-relative onset and opaque distances that will be fallen back on, overriding the Fog node's own onset and opaque distances. The linear fallback workaround will only look good in certain situations, for example when the fog is deep inside a dark cave. So in general, exponential mode fog is more useful than the default linear mode fog. """ self.fog.setLinearFallback(angle, onset, opaque)
class World(DirectObject): cfg = None def __init__(self): self.last_mousex = 0 self.last_mousey = 0 self.zone = None self.zone_reload_name = None self.winprops = WindowProperties( ) # simple console output self.consoleNode = NodePath(PandaNode("console_root")) self.consoleNode.reparentTo(aspect2d) self.console_num_lines = 24 self.console_cur_line = -1 self.console_lines = [] for i in range(0, self.console_num_lines): self.console_lines.append(OnscreenText(text='', style=1, fg=(1,1,1,1), pos=(-1.3, .4-i*.05), align=TextNode.ALeft, scale = .035, parent = self.consoleNode)) # Configuration self.consoleOut('World Forge v.%s loading configuration' % VERSION) self.configurator = Configurator(self) cfg = self.configurator.config resaveRes = False if 'xres' in cfg: self.xres = int(cfg['xres']) else: self.xres = 1024 resaveRes = True if 'yres' in cfg: self.yres = int(cfg['yres']) else: self.yres = 768 resaveRes = True if resaveRes: self.saveDefaultRes() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.mouse_accum = MouseAccume( lambda: (self.xres_half,self.yres_half)) self.eyeHeight = 7.0 self.rSpeed = 80 self.flyMode = 1 # application window setup base.win.setClearColor(Vec4(0,0,0,1)) self.winprops.setTitle( 'World Forge') self.winprops.setSize(self.xres, self.yres) base.win.requestProperties( self.winprops ) base.disableMouse() # Post the instructions self.title = addTitle('World Forge v.' + VERSION) self.inst0 = addInstructions(0.95, "[FLYMODE][1]") self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.") self.inst2 = addInstructions(0.9, "Loc:") self.inst3 = addInstructions(0.85, "Hdg:") self.error_inst = addInstructions(0, '') self.kh = [] self.campos = Point3(155.6, 41.2, 4.93) base.camera.setPos(self.campos) # Accept the application control keys: currently just esc to exit navgen self.accept("escape", self.exitGame) self.accept("window-event", self.resizeGame) # Create some lighting ambient_level = .6 ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0)) render.setLight(render.attachNewNode(ambientLight)) direct_level = 0.8 directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0.0, 0.0, -1.0)) directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1)) directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1)) render.setLight(render.attachNewNode(directionalLight)) # create a point light that will follow our view point (the camera for now) # attenuation is set so that this point light has a torch like effect self.plight = PointLight('plight') self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002)) self.plnp = base.camera.attachNewNode(self.plight) self.plnp.setPos(0, 0, 0) render.setLight(self.plnp) self.cam_light = 1 self.keyMap = {"left":0, "right":0, "forward":0, "backward":0, "cam-left":0, \ "cam-right":0, "mouse3":0, "flymode":1 } # setup FOG self.fog_colour = (0.8,0.8,0.8,1.0) self.linfog = Fog("A linear-mode Fog node") self.linfog.setColor(self.fog_colour) self.linfog.setLinearRange(700, 980) # onset, opaque distances as params # linfog.setLinearFallback(45,160,320) base.camera.attachNewNode(self.linfog) render.setFog(self.linfog) self.fog = 1 # camera control self.campos = Point3(0, 0, 0) self.camHeading = 0.0 self.camPitch = 0.0 base.camLens.setFov(65.0) base.camLens.setFar(1200) self.cam_speed = 0 # index into self.camp_speeds self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0] # Collision Detection for "WALKMODE" # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. The ray will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0.0, 0.0, 0.0) self.camGroundRay.setDirection(0,0,-1) # straight down self.camGroundCol = CollisionNode('camRay') self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) # attach the col node to the camCollider dummy node self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays # self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring # self.cTrav.showCollisions(render) # Add the spinCameraTask procedure to the task manager. # taskMgr.add(self.spinCameraTask, "SpinCameraTask") globals.hasClickedSpawn = False; globals.hasClickedGrid = False; taskMgr.add(self.camTask, "camTask") self.toggleControls(1) # need to step the task manager once to make our fake console work taskMgr.step() # CONSOLE --------------------------------------------------------------------- def consoleScroll(self): for i in range(0, self.console_num_lines-1): self.console_lines[i].setText(self.console_lines[i+1].getText()) def consoleOut(self, text): print text # output to stdout/log too if self.console_cur_line == self.console_num_lines-1: self.consoleScroll() elif self.console_cur_line < self.console_num_lines-1: self.console_cur_line += 1 self.console_lines[self.console_cur_line].setText(text) taskMgr.step() def consoleOn(self): self.consoleNode.show() def consoleOff(self): self.consoleNode.hide() # User controls ----------------------------------------------------------- def toggleControls(self, on): cfg = self.configurator.config if on == 1: self.accept("escape", self.exitGame) self.accept("1", self.setSpeed, ["speed", 0]) self.accept("2", self.setSpeed, ["speed", 1]) self.accept("3", self.setSpeed, ["speed", 2]) self.accept("4", self.setSpeed, ["speed", 3]) self.accept("5", self.setSpeed, ["speed", 4]) self.accept("alt-f", self.fogToggle) self.accept(cfg['control_lighting'], self.camLightToggle) self.accept(cfg['control_help'], self.displayKeyHelp) self.accept(cfg['control_flymode'], self.toggleFlymode) self.accept(cfg['control_reload-zone'], self.reloadZone) self.accept(cfg['control_cam-left'], self.setKey, ["cam-left",1]) self.accept(cfg['control_cam-right'], self.setKey, ["cam-right",1]) self.accept(cfg['control_forward'], self.setKey, ["forward",1]) self.accept("mouse3", self.setKey, ["mouse3",1]) self.accept(cfg['control_backward'], self.setKey, ["backward",1]) self.accept("k-up", self.hideKeyHelp) self.accept(cfg['control_cam-left']+"-up", self.setKey, ["cam-left",0]) self.accept(cfg['control_cam-right']+"-up", self.setKey, ["cam-right",0]) self.accept(cfg['control_forward']+"-up", self.setKey, ["forward",0]) self.accept("mouse3-up", self.setKey, ["mouse3",0]) self.accept(cfg['control_backward']+"-up", self.setKey, ["backward",0]) self.accept(cfg['toggle_edit-mode'], self.toggleEditMode) self.accept(cfg['toggle_insert-mode'], self.toggleInsertMode) self.accept(cfg['toggle_explore-mode'], self.toggleExploreMode) self.accept(cfg['toggle_grid-mode'], self.toggleGridMode) # Accept both single-presses and long presses for rotating models self.accept(cfg['rotate-right'] + "-repeat", self.rotateModelRight) self.accept(cfg['rotate-left'] + "-repeat", self.rotateModelLeft) self.accept(cfg['rotate-right'], self.rotateModelRight) self.accept(cfg['rotate-left'], self.rotateModelLeft) self.accept(cfg['clear-selection'], self.clearSelection) else: messenger.clear() def rotateModelRight(self): if globals.editMode == True: if globals.selectedSpawn: cfg = self.configurator.config globals.selectedSpawn.model.setH(globals.selectedSpawn.model.getH() + int(cfg['rotation-amount'])) # Really not sure about that... if globals.selectedSpawn.model.getH() > 360: globals.selectedSpawn.model.setH(0) print globals.selectedSpawn.model.getH() globals.selectedSpawn.setheadingfromworld(globals.selectedSpawn.model.getH()) globals.spawndialog.m_spawnEntryHeadingTextCtrl.SetValue(str(globals.selectedSpawn.spawnentry_heading)) if globals.config['autosave_edit-mode'] == 'True': globals.database.UpdateSpawn(globals.selectedSpawn) print globals.selectedSpawn.spawnentry_heading def rotateModelLeft(self): if globals.editMode == True: if globals.selectedSpawn: cfg = self.configurator.config globals.selectedSpawn.model.setH(globals.selectedSpawn.model.getH() - int(cfg['rotation-amount'])) # Really not sure about that either... if globals.selectedSpawn.model.getH() < -360: globals.selectedSpawn.model.setH(0) print globals.selectedSpawn.model.getH() globals.selectedSpawn.setheadingfromworld(globals.selectedSpawn.model.getH()) globals.spawndialog.m_spawnEntryHeadingTextCtrl.SetValue(str(globals.selectedSpawn.spawnentry_heading)) if globals.config['autosave_edit-mode'] == 'True': globals.database.UpdateSpawn(globals.selectedSpawn) print globals.selectedSpawn.spawnentry_heading def clearSelection(self, eraseNpcId = True): globals.selectedspawn = None globals.selectedgrid = None globals.picker.lastSelectedObject = None if self.inst6: self.inst6.destroy() self.inst6 = addInstructions(0.7, "Current selection: None") npcid = globals.spawndialog.m_spawnEntryNpcIdTextCtrl.Value globals.spawndialog.Reset() # f*****g hacky shit man if eraseNpcId == False: globals.spawndialog.m_spawnEntryNpcIdTextCtrl.SetValue(npcid) gridmanager = GridpointManager() gridmanager.ResetGridList() print "Cleared all selections !" def toggleDefaultMode(self): globals.editMode = False globals.insertMode = False globals.exploreMode = True globals.gridMode = False print "STARTUP Explore mode ACTIVATED" print "STARTUP Grid mode DEACTIVATED" self.inst4 = addInstructions(0.8, "Explore mode ON") self.inst5 = addInstructions(0.75, "Grid mode OFF") self.inst6 = addInstructions(0.7, "Current selection: None") def toggleEditMode(self): globals.editMode = True globals.insertMode = False globals.exploreMode = False print "Edit mode ACTIVATED" if self.inst4: self.inst4.destroy() self.inst4 = addInstructions(0.8, "Edit mode ON") def toggleInsertMode(self): globals.editMode = False globals.insertMode = True globals.exploreMode = False print "Insert mode ACTIVATED" if self.inst4: self.inst4.destroy() self.inst4 = addInstructions(0.8, "Insert mode ON") def toggleExploreMode(self): globals.editMode = False globals.insertMode = False globals.exploreMode = True print "Explore mode ACTIVATED" if self.inst4: self.inst4.destroy() self.inst4 = addInstructions(0.8, "Explore mode ON") def toggleGridMode(self): if globals.gridMode == False: globals.gridMode = True print "Grid mode ACTIVATED" if self.inst5: self.inst5.destroy() self.inst5 = addInstructions(0.75, "Grid mode ON") else: globals.gridMode = False print "Grid mode DEACTIVATED" if self.inst5: self.inst5.destroy() self.inst5 = addInstructions(0.75, "Grid mode OFF") def setSpeed(self, key, value): self.cam_speed = value self.setFlymodeText() def fogToggle(self): if self.fog == 1: render.clearFog() base.camLens.setFar(100000) self.fog = 0 else: render.setFog(self.linfog) base.camLens.setFar(1200) self.fog = 1 def camLightToggle(self): if self.cam_light == 0: render.setLight(self.plnp) self.cam_light = 1 else: render.clearLight(self.plnp) self.cam_light = 0 def displayKeyHelp(self): self.kh = [] msg = 'HOTKEYS:' pos = 0.75 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '------------------' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = '1-5: set camera movement speed' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'F: toggle Flymode/Walkmode' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'L: load a zone' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ALT-F: toggle FOG and FAR plane on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'T: toggle additional camera "torch" light on/off' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'Z: set currently loaded zone as new startup default' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) msg = 'ESC: exit World Forge' pos -= 0.05 self.kh.append(OnscreenText(text=msg, style=1, fg=(1,1,1,1), pos=(-0.5, pos), align=TextNode.ALeft, scale = .04)) def hideKeyHelp(self): for n in self.kh: n.removeNode() def setFlymodeText(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed+1, zname)) else: self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed+1, zname)) def toggleFlymode(self): zname = '' if self.zone: zname = self.zone.name if self.flyMode == 0: self.flyMode = 1 else: self.flyMode = 0 self.setFlymodeText() # Define a procedure to move the camera. def spinCameraTask(self, task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) base.camera.setHpr(angleDegrees, 0, 0) return task.cont def camTask(self, task): if globals.hasClickedSpawn: base.camera.setPos(globals.selectedSpawnPoint3D) self.campos = globals.selectedSpawnPoint3D globals.hasClickedSpawn = False elif globals.hasClickedGrid: base.camera.setPos(globals.selectedGridPoint3D) self.campos = globals.selectedGridPoint3D globals.hasClickedGrid = False else: # query the mouse mouse_dx = 0 mouse_dy = 0 # if we have a mouse and the right button is depressed if base.mouseWatcherNode.hasMouse(): if self.keyMap["mouse3"] != 0: self.mouse_accum.update() else: self.mouse_accum.reset() mouse_dx = self.mouse_accum.dx mouse_dy = self.mouse_accum.dy self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed+1) * max(5 * 1000/self.xres,3) self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed+1) * max(3 * 1000/self.yres,1) if (self.keyMap["cam-left"]!=0 or mouse_dx < 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading += self.rXSpeed * globalClock.getDt() else: self.camHeading += self.rSpeed * globalClock.getDt() if self.camHeading > 360.0: self.camHeading = self.camHeading - 360.0 elif (self.keyMap["cam-right"]!=0 or mouse_dx > 0): if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading -= self.rXSpeed * globalClock.getDt() else: self.camHeading -= self.rSpeed * globalClock.getDt() if self.camHeading < 0.0: self.camHeading = self.camHeading + 360.0 else: self.rSpeed = 80 if mouse_dy > 0: self.camPitch += self.rYSpeed * globalClock.getDt() elif mouse_dy < 0: self.camPitch -= self.rYSpeed * globalClock.getDt() # set camera heading and pitch base.camera.setHpr(self.camHeading, self.camPitch, 0) # viewer position (camera) movement control v = render.getRelativeVector(base.camera, Vec3.forward()) if not self.flyMode: v.setZ(0.0) move_speed = self.cam_speeds[self.cam_speed] if self.keyMap["forward"] == 1: self.campos += v * move_speed * globalClock.getDt() if self.keyMap["backward"] == 1: self.campos -= v * move_speed * globalClock.getDt() # actually move the camera lastPos = base.camera.getPos() base.camera.setPos(self.campos) # self.plnp.setPos(self.campos) # move the point light with the viewer position # WALKMODE: simple collision detection # we simply check a ray from slightly below the "eye point" straight down # for geometry collisions and if there are any we detect the point of collision # and adjust the camera's Z accordingly if self.flyMode == 0: # move the camera to where it would be if it made the move # the colliderNode moves with it # base.camera.setPos(self.campos) # check for collissons self.cTrav.traverse(render) entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) # print 'collision' entries.sort(lambda x,y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if (len(entries) > 0): # and (entries[0].getIntoNode().getName() == "terrain"): # print len(entries) self.campos.setZ(entries[0].getSurfacePoint(render).getZ()+self.eyeHeight) else: self.campos = lastPos base.camera.setPos(self.campos) #if (base.camera.getZ() < self.player.getZ() + 2.0): # base.camera.setZ(self.player.getZ() + 2.0) # update loc and hpr display pos = base.camera.getPos() hpr = base.camera.getHpr() self.inst2.setText('Loc: %.2f, %.2f, %.2f' % (pos.getX(), pos.getY(), pos.getZ())) self.inst3.setText('Hdg: %.2f, %.2f, %.2f' % (hpr.getX(), hpr.getY(), hpr.getZ())) return task.cont def exitGame(self): globals.database.conn.close() print "DB connection closed !" sys.exit(0) def resizeGame(self,win): props = base.win.getProperties() self.xres = props.getXSize() self.yres = props.getYSize() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.saveDefaultRes() #Records the state of the arrow keys # this is used for camera control def setKey(self, key, value): self.keyMap[key] = value # ------------------------------------------------------------------------- # this is the mythical MAIN LOOP :) def update(self): if self.zone_reload_name != None: self.doReload(self.zone_reload_name) self.zone_reload_name = None if self.zone != None: self.zone.update() taskMgr.step() # ZONE loading ------------------------------------------------------------ # general zone loader driver # removes existing zone (if any) and load the new one def loadZone(self, name, path): if path[len(path)-1] != '/': path += '/' if self.zone: self.zone.rootNode.removeNode() self.zone = Zone(self, name, path) error = self.zone.load() if error == 0: self.consoleOff() self.setFlymodeText() base.setBackgroundColor(self.fog_colour) def saveDefaultRes(self): cfg = self.configurator.config cfg['xres'] = str(self.xres) cfg['yres'] = str(self.yres) # initial world load after bootup def load(self): cfg = self.configurator.config zone_name = cfg['default_zone'] globals.currentZone = zone_name basepath = cfg['basepath'] self.loadZone(zone_name, basepath) # zone reload user interface # this gets called from our update loop when it detects that zone_reload_name has been set # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking # because otherwise our status console output at various stages during the zone load would not # be displayed. Yes, this is hacky. def doReload(self, name): cfg = self.configurator.config basepath = cfg['basepath'] self.loadZone(name, basepath) # form dialog callback # this gets called from the form when the user has entered a something # (hopefully a correct zone short name) def reloadZoneDialogCB(self, name): self.frmDialog.end() self.zone_reload_name = name self.toggleControls(1) # this is called when the user presses "l" # it disables normal controls and fires up our query form dialog def reloadZone(self): base.setBackgroundColor((0,0,0)) self.toggleControls(0) self.consoleOn() self.frmDialog = FileDialog( "Please enter the shortname of the zone you wish to load:", "Examples: qrg, blackburrow, freportn, crushbone etc.", self.reloadZoneDialogCB) self.frmDialog.activate() # relies on the main update loop to run ##################################### # Custom methods ##################################### # Handles populating the zone with spawn data from the EQEmu DB # also makes each spawner model pickable def PopulateSpawns(self, cursor, numrows): spawn_coords = list() globals.spawn_list = list() cfg = self.configurator.config for x in range(0, numrows): row = cursor.fetchone() point = Point3(long(row["Spawn2Y"]), long(row["Spawn2X"]), long(row["Spawn2Z"])) if cfg['ignore_duplicate_spawns'] == 'True': if point not in spawn_coords: self.PlaceSpawnPointOn3dMap(row) spawn_coords.append(point) else: self.PlaceSpawnPointOn3dMap(row) def PlaceSpawnPointOn3dMap(self, row): spawn = Spawn() self.InitSpawnData(spawn, row) spawn.model = loader.loadModel(spawn.modelname) spawn.initmodel() spawn.model.reparentTo(render) spawn.initheadingfromdb(row["Spawn2Heading"]) spawn.placeintoworld(row["Spawn2Y"], row["Spawn2X"], row["Spawn2Z"]) min, macks = spawn.model.getTightBounds() radius = max([macks.getY() - min.getY(), macks.getX() - min.getX()]) / 2 cs = CollisionSphere(row["Spawn2X"], row["Spawn2Y"], row["Spawn2Z"], radius) csNode = spawn.model.attachNewNode(CollisionNode("modelCollide")) csNode.node().addSolid(cs) # TODO: ADD MORE TAGS?? spawn.model.setTag("name", row["NpcName"]) spawn.model.setTag("spawngroup_name", row["spawngroup_name"]) spawn.model.setTag("spawn2id", str(row["Spawn2Id"])) spawn.model.setTag("type", "spawn") globals.picker.makePickable(spawn.model) globals.spawn_list.append(spawn) # Initializes a spawn object with database values def InitSpawnData(self, spawn, row): spawn.spawngroup_id = row["Spawngroup_id"] spawn.spawngroup_name = row["spawngroup_name"] spawn.spawngroup_minx = row["Spawngroup_minX"] spawn.spawngroup_maxx= row["Spawngroup_maxX"] spawn.spawngroup_miny = row["Spawngroup_minY"] spawn.spawngroup_maxy = row["Spawngroup_maxY"] spawn.spawngroup_dist = row["Spawngroup_dist"] spawn.spawngroup_mindelay = row["Spawngroup_mindelay"] spawn.spawngroup_delay = row["Spawngroup_delay"] spawn.spawngroup_despawn = row["Spawngroup_despawntimer"] spawn.spawngroup_despawntimer = row["Spawngroup_despawntimer"] spawn.spawngroup_spawnlimit = row["Spawngroup_spawnlimit"] spawn.spawnentry_id = row["Spawn2Id"] spawn.spawnentry_npcid = row["NpcId"] spawn.spawnentry_npcname = row["NpcName"] spawn.spawnentry_chance = row["Spawnentry_chance"] spawn.spawnentry_x = row["Spawn2X"] spawn.spawnentry_y = row["Spawn2Y"] spawn.spawnentry_z = row["Spawn2Z"] spawn.spawnentry_heading = row["Spawn2Heading"] spawn.spawnentry_respawn = row["Spawn2Respawn"] spawn.spawnentry_variance = row["Spawn2Variance"] spawn.spawnentry_pathgrid = row["Spawn2Grid"] spawn.spawnentry_condition = row["Spawn2Condition"] spawn.spawnentry_condvalue = row["Spawn2CondValue"] spawn.spawnentry_version = row["Spawn2Version"] spawn.spawnentry_enabled = row["Spawn2Enabled"] spawn.spawnentry_animation = row["Spawn2Animation"] spawn.spawnentry_zone = row["Spawn2Zone"] spawn.spawnentry_originalx = row["Spawn2X"] spawn.spawnentry_originaly = row["Spawn2Y"] spawn.spawnentry_originalz = row["Spawn2Z"] spawn.spawnentry_originalheading = row["Spawn2Heading"] # Initializes the camera position upon startup def InitCameraPosition(self): world.campos = Point3(-155.6, 41.2, 4.9 + world.eyeHeight) world.camHeading = 270.0 base.camera.setPos(world.campos) def GetCamera(self): return base.camera
class Starfox(ShowBase): def __init__(self): self.height = 500 super().__init__(self) self.scene = self.loader.loadModel("./models/world.egg") playerTexture = loader.loadTexture("models/starfoxShip.jpg") enemyTexture = loader.loadTexture("models/enemyShip.jpg") bulletTexture = loader.loadTexture("models/shot.png") self.scene.reparentTo(self.render) base.setBackgroundColor(0.1, 0.1, 0.1, 1) self.player = self.scene.find("player") self.player.setPythonTag("ObjectController", Player(self.player)) self.player.setTexture(playerTexture) self.building_enemy = self.scene.find("building_enemy") self.dynamic_enemy = self.scene.find("enemy1") self.dynamic_enemy.setTexture(enemyTexture) self.bullet = self.scene.find("bullet") self.bullet.setTexture(bulletTexture) base.cTrav = CollisionTraverser() self.CollisionHandlerEvent = CollisionHandlerEvent() base.enableParticles() self.CollisionHandlerEvent.addInPattern('into-%in') self.CollisionHandlerEvent.addOutPattern('out-%in') self.accept('into-collision_player', self.crash) self.accept('into-collision_plane', self.crash) self.accept('into-collision_enemy', self.crash) base.cTrav.addCollider(self.scene.find("player/collision**"), self.CollisionHandlerEvent) base.cTrav.addCollider(self.scene.find("basePlane/collision**"), self.CollisionHandlerEvent) self.player.find("**collision**").node().setFromCollideMask(0x3) self.player.find("**collision**").node().setIntoCollideMask(0x3) self.dynamic_enemy.find("**collision**").node().setFromCollideMask(0x5) self.dynamic_enemy.find("**collision**").node().setIntoCollideMask(0x5) self.building_enemy.find("**collision**").node().setFromCollideMask( 0x5) self.building_enemy.find("**collision**").node().setIntoCollideMask( 0x5) #base.cTrav.showCollisions(self.render) self.taskMgr.add(self.update, "update") InputManager.initWith(self, [ InputManager.arrowUp, InputManager.arrowDown, InputManager.arrowLeft, InputManager.arrowRight, InputManager.space, InputManager.keyX, InputManager.keyV ]) self.rails = self.scene.attachNewNode("rails") self.scene.find("basePlane").setHpr(70, 0, 0) self.rails.setPos(self.scene, 0, 0, 0) self.player.reparentTo(self.rails) self.player.setPos(self.rails, 0, 0, 0) self.rails_y = -50 self.createStaticEnemy(self.building_enemy, 0, 50, 0) self.createStaticEnemy(self.building_enemy, -50, 50, 0) self.createStaticEnemy(self.building_enemy, -100, 50, 0) self.createStaticEnemy(self.building_enemy, -70, 130, 0) self.createStaticEnemy(self.building_enemy, -120, 80, 0) self.createStaticEnemy(self.building_enemy, -220, 130, 0) DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-230, 140, 10), base.cTrav, self.CollisionHandlerEvent, type=ENEMY_TYPE.CHASER) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-240,160,10) , base.cTrav, self.CollisionHandlerEvent) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-250,200,10) , base.cTrav, self.CollisionHandlerEvent) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-270,160,10) , base.cTrav, self.CollisionHandlerEvent) #DynamicEnemy(self.dynamic_enemy, self.scene, Vec3(-250,200,10) , base.cTrav, self.CollisionHandlerEvent) self.building_enemy.hide() self.dynamic_enemy.hide() self.fog = Fog("fog") self.fog.setColor(0.1, 0.1, 0.1) self.fog.setExpDensity(.3) self.fog.setLinearRange(50, 150) self.fog.setLinearFallback(45, 160, 320) self.render.setFog(self.fog) self.dirLight = DirectionalLight("dir light") self.dirLight.color = (0.7, 0.7, 1, 1) self.dirLightPath = self.render.attachNewNode(self.dirLight) self.dirLightPath.setHpr(45, -45, 0) self.dirLight.setShadowCaster(True, 512, 512) render.setLight(self.dirLightPath) filters = CommonFilters(base.win, base.cam) filters.setBloom(size="large", mintrigger=0.2) self.render.setShaderAuto() self.initSounds() self.initUI() self.onGame = False def initUI(self): self.font = loader.loadFont('./fonts/Magenta.ttf') self.lifes = [ OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(1.1, 0, 0.8), scale=0.05), OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(1.2, 0, 0.8), scale=0.05) ] self.lifes[0].setTransparency(True) self.lifes[1].setTransparency(True) self.dialogScreen = DirectDialog(frameSize=(-0.7, 0.7, -0.7, 0.7), relief=DGG.FLAT) s = OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(0, 0, -0.2), scale=0.20, parent=self.dialogScreen) s.setTransparency(True) self.titleUI = DirectLabel(text="Starfox Region 4", parent=self.dialogScreen, scale=0.1, pos=(0, 0, .2), text_font=self.font) self.btn = DirectButton(text="Start", command=self.startGame, pos=(0, 0, 0), parent=self.dialogScreen, scale=0.07) def startGame(self): self.dialogScreen.hide() self.flyingSound.play() self.onGame = True self.btn.hide() def initSounds(self): self.audio3d = Audio3DManager.Audio3DManager(base.sfxManagerList[0], self.camera) self.flyingSound = self.audio3d.loadSfx( "./sounds/great fox flying.mp3") self.flyingSound.setLoop(True) self.audio3d.attachSoundToObject(self.flyingSound, self.player) self.audio3d.setSoundVelocityAuto(self.flyingSound) self.audio3d.setListenerVelocityAuto() #self.audio3d.setDistanceFactor(100) self.audio3d.setDropOffFactor(0) self.fireSound = self.audio3d.loadSfx( "./sounds/arwing double laser one shot.mp3") self.crashSound = self.audio3d.loadSfx("./sounds/break.mp3") def createStaticEnemy(self, original, px, py, pz): be = original.copyTo(self.scene) be.setPos(px, py, pz) base.cTrav.addCollider(be.find("**collision**"), self.CollisionHandlerEvent) """ self.pointLight = PointLight("point light") self.pointLight.color = (1,1,1,1) self.pointLightPath = self.render.attachNewNode(self.pointLight) self.pointLightPath.setPos(px,py,pz) self.pointLight.attenuation = (1,0,0) #self.pointLight.setShadowCaster(True,1024,1024) self.render.setLight(self.pointLightPath) """ def crash(self, evt): self.crashSound.play() objectInto = evt.getIntoNodePath().node().getParent(0).getPythonTag( "ObjectController") objectFrom = evt.getFromNodePath().node().getParent(0).getPythonTag( "ObjectController") if (objectInto != None): objectInto.crash(objectFrom) if (objectFrom != None): objectFrom.crash(objectInto) lifes = self.player.getPythonTag("ObjectController").getLifes() if (lifes <= 0): self.onGame = False self.dialogScreen.show() self.flyingSound.stop() def update(self, evt): #self.camera.setPos(0,-100,100) lifes = self.player.getPythonTag("ObjectController").getLifes() if (lifes > 2): self.lifes[0].show() self.lifes[1].show() elif (lifes > 1): self.lifes[0].show() self.lifes[1].hide() elif (lifes > 0): self.lifes[0].hide() self.lifes[1].hide() self.camera.lookAt(self.player) self.rails.setPos(self.scene, Path.getXOfY(self.rails_y), self.rails_y, 12.4) self.rails.setHpr(Path.getHeading(self.rails_y), 0, 0) self.dirLight.color = (self.rails_y / 600, 0.7, 1, 1) self.camera.setHpr(Path.getHeading(self.rails_y), 0, 0) if (self.onGame): self.rails_y = self.rails_y + globalClock.getDt() * 10 #self.player.setPos(self.rails, 0, 0, sin(self.z/10.0)*40 ) relX, relZ, isShooting = self.player.getPythonTag( "ObjectController").update(self.rails, globalClock.getDt()) self.camera.setPos(self.rails, relX, -30, relZ) if (isShooting): self.fireSound.play() b = Bullet( self.bullet, self.scene, self.player.getPos(self.scene), base.cTrav, self.CollisionHandlerEvent, self.scene.getRelativeVector(self.player, Vec3(0, 1, 0)), 40, 0x4) enemies = self.scene.findAllMatches("dynamicEnemy") for e in enemies: enemy = e.getPythonTag("ObjectController") enemy.update(self.scene, globalClock.getDt(), self.player, self.bullet) bullets = self.scene.findAllMatches("bulletC") for b in bullets: bullet = b.getPythonTag("ObjectController") bullet.update(self.scene, globalClock.getDt(), self.player) return Task.cont
class CogdoBarrelRoom: notify = DirectNotifyGlobal.directNotify.newCategory( 'DistributedCogdoBarrelRoom') def __init__(self): self.timer = None self.model = None self._isLoaded = False self.dummyElevInNode = None self.cogdoBarrelsNode = None self.entranceNode = None self.nearBattleNode = None self.rewardUi = None self.rewardUiTaskName = 'CogdoBarrelRoom-RewardUI' self.rewardCameraTaskName = 'CogdoBarrelRoom-RewardCamera' self.fog = None self.defaultFar = None self.stomperSfx = None return def destroy(self): self.unload() def load(self): if self._isLoaded: return self.timer = ToontownTimer.ToontownTimer() self.timer.stash() self.model = loader.loadModel(CogdoBarrelRoomConsts.BarrelRoomModel) self.model.setPos(*CogdoBarrelRoomConsts.BarrelRoomModelPos) self.model.reparentTo(render) self.model.stash() self.dummyElevInNode = self.model.attachNewNode('elevator-in') self.dummyElevInNode.hide() self.entranceNode = self.model.attachNewNode('door-entrance') self.entranceNode.setPos(0, -65, 0) self.nearBattleNode = self.model.attachNewNode('near-battle') self.nearBattleNode.setPos(0, -25, 0) self.rewardUi = CogdoBarrelRoomRewardPanel.CogdoBarrelRoomRewardPanel() self.hideRewardUi() self.stomperSfx = base.loadSfx(CogdoBarrelRoomConsts.StomperSound) self.fog = Fog('barrel-room-fog') self.fog.setColor(CogdoBarrelRoomConsts.BarrelRoomFogColor) self.fog.setLinearRange( *CogdoBarrelRoomConsts.BarrelRoomFogLinearRange) self._isLoaded = True def unload(self): if self.model: self.model.removeNode() self.model = None if self.timer: self.timer.destroy() self.timer = None if self.rewardUi: self.rewardUi.destroy() self.rewardUi = None if self.fog: render.setFogOff() del self.fog taskMgr.remove(self.rewardUiTaskName) taskMgr.remove(self.rewardCameraTaskName) self._isLoaded = False return def isLoaded(self): return self._isLoaded def show(self): if not self.cogdoBarrelsNode: self.cogdoBarrelsNode = render.find('**/@@CogdoBarrels') self.cogdoBarrelsNode.reparentTo(self.model) self.cogdoBarrelsNode.unstash() self.defaultFar = base.camLens.getFar() base.camLens.setFar(CogdoBarrelRoomConsts.BarrelRoomCameraFar) self.showBattleAreaLight(True) render.setFog(self.fog) self.model.unstash() def hide(self): self.model.stash() render.setFogOff() if self.defaultFar is not None: base.camLens.setFar(self.defaultFar) return def activate(self): self.notify.info('Activating barrel room: %d sec timer.' % CogdoBarrelRoomConsts.CollectionTime) self.timer.unstash() self.timer.posAboveShtikerBook() self.timer.countdown(CogdoBarrelRoomConsts.CollectionTime) base.cr.playGame.getPlace().fsm.request('walk') def deactivate(self): self.notify.info('Deactivating barrel room.') self.timer.stop() self.timer.stash() def placeToonsAtEntrance(self, toons): for i in xrange(len(toons)): toons[i].setPosHpr( self.entranceNode, *CogdoBarrelRoomConsts.BarrelRoomPlayerSpawnPoints[i]) def placeToonsNearBattle(self, toons): for i in xrange(len(toons)): toons[i].setPosHpr( self.nearBattleNode, *CogdoBarrelRoomConsts.BarrelRoomPlayerSpawnPoints[i]) def showBattleAreaLight(self, visible=True): lightConeNode = self.model.find('**/battleCone') if lightConeNode != None and not lightConeNode.isEmpty(): if visible: lightConeNode.show() else: lightConeNode.hide() return def getIntroInterval(self): avatar = base.localAvatar trackName = '__introBarrelRoom-%d' % avatar.doId track = Parallel(name=trackName) track.append(self.__stomperIntervals()) track.append( Sequence( Func(base.camera.reparentTo, render), Func(base.camera.setPosHpr, self.model, -20.0, -87.9, 12.0, -30, 0, 0), Func(base.transitions.irisIn, 0.5), Wait(1.0), LerpHprInterval(base.camera, duration=2.0, startHpr=Vec3(-30, 0, 0), hpr=Vec3(0, 0, 0), blendType='easeInOut'), Wait(2.5), LerpHprInterval(base.camera, duration=3.0, startHpr=Vec3(0, 0, 0), hpr=Vec3(-45, 0, 0), blendType='easeInOut'), Wait(2.5))) track.delayDelete = DelayDelete.DelayDelete(avatar, 'introBarrelRoomTrack') track.setDoneEvent(trackName) return (track, trackName) def __stomperIntervals(self): ivals = [SoundInterval(self.stomperSfx)] i = 0 for stomperDef in CogdoBarrelRoomConsts.StomperProps: stomperNode = render.find(stomperDef['path']) if stomperNode: maxZ = random.uniform(10, 20) minZ = maxZ - 10 if stomperDef['motion'] == 'up': startZ, destZ = minZ, maxZ else: startZ, destZ = maxZ, minZ stomperNode.setPos(Point3(0, 0, startZ)) ivals.append( LerpPosInterval(stomperNode, CogdoBarrelRoomConsts.StomperHaltTime, Point3(0, 0, destZ), blendType='easeOut')) i += 1 return Parallel(*tuple(ivals)) def __rewardUiTimeout(self, callback): self.hideRewardUi() if callback is not None: callback() return def __rewardCamera(self): trackName = 'cogdoBarrelRoom-RewardCamera' track = Sequence(Func(base.camera.reparentTo, render), Func(base.camera.setPosHpr, self.model, 0, 0, 11.0, 0, -14, 0), Func(self.showBattleAreaLight, False), name=trackName) return (track, trackName) def showRewardUi(self, results, callback=None): track, trackName = self.__rewardCamera() if CogdoBarrelRoomConsts.ShowRewardUI: self.rewardUi.setRewards(results) self.rewardUi.unstash() taskMgr.doMethodLater(CogdoBarrelRoomConsts.RewardUiTime, self.__rewardUiTimeout, self.rewardUiTaskName, extraArgs=[callback]) return (track, trackName) def setRewardResults(self, results): self.rewardUi.setRewards(results) def hideRewardUi(self): self.rewardUi.stash() taskMgr.remove(self.rewardUiTaskName)
class VisualTest(ShowBase): def __init__(self): super().__init__(self) self.scene = loader.loadModel("models/world") self.player = self.scene.find("player") self.basePlane = self.scene.find("basePlane") self.player.reparentTo(self.render) self.basePlane.reparentTo(self.render) self.scene.remove_node() self.taskMgr.add(self.update, "update") self.camera.setPos(self.render, 0, -100, 70) base.setBackgroundColor(0.1, 0.1, 0.1, 1) self.dirLight = DirectionalLight("dir light") self.dirLight.setShadowCaster(True, 512, 512) self.dirLight.color = (1, 0, 1, 1) self.dirLightPath = self.render.attachNewNode(self.dirLight) self.dirLightPath.setHpr(45, -60, 0) render.setLight(self.dirLightPath) self.angleTime = 0.0 self.totalAngleTime = 10.0 self.hAngle = 0 self.ambientLight = AmbientLight("ambient") self.ambientLight.color = (0.1, 0.1, 0.1, 1) self.ambLightPath = self.render.attachNewNode(self.ambientLight) render.setLight(self.ambLightPath) self.pointLight = PointLight("point") self.pointLight.color = (1, 1, 1, 1) self.pointLightPath = self.render.attachNewNode(self.pointLight) self.pointLightPath.setPos(0, 5, 5) self.pointLight.setShadowCaster(True, 512, 512) self.render.setLight(self.pointLightPath) self.fog = Fog("fog") self.fog.setColor(.1, .1, .1) self.fog.setExpDensity(.3) self.fog.setLinearRange(150, 200) self.fog.setLinearFallback(45, 160, 320) render.setFog(self.fog) self.render.setShaderAuto() self.p = self.render.attachNewNode("particles") base.enableParticles() p = ParticleEffect() p.loadConfig('./mysmoke.ptf') p.start(parent=self.p, renderParent=render) self.p.setPos(self.player, 0, 0, 2) self.font = loader.loadFont('./fonts/Magenta.ttf') self.sceneName = DirectLabel(text="Starfox visual test", parent=self.aspect2d, scale=0.07, pos=(-1.2, 0, 0.85), text_font=self.font, relief=None, text_fg=(1, 1, 1, 1), textMayChange=True, text_align=TextNode.ALeft) self.foxy = OnscreenImage(image='./UI/fox-icon-png-8.png', pos=(1.2, 9, 0.85), scale=0.1) self.foxy.setTransparency(True) self.controlsPanel = DirectDialog(frameSize=(-1.1, 1.1, -0.9, -0.7), relief=DGG.FLAT) btn = DirectButton(text="Rotate", command=self.doRotate, image='./UI/fox-icon-png-8.png', pos=(-0.9, 0, -0.8), parent=self.controlsPanel, scale=0.07, relief=None) btn2 = DirectButton(text="Anin Light", command=self.doLight, image='./UI/fox-icon-png-8.png', pos=(-0.7, 0, -0.8), parent=self.controlsPanel, scale=0.07, relief=None) self.camera.lookAt(self.player) self.makeRotation = False self.rotateAngles = 0 self.animLight = False filter = CommonFilters(base.win, base.cam) filter.setBloom(size="large", intensity=2) #filter.setAmbientOcclusion(strength = 5, radius = 3) filter.setCartoonInk(separation=4) def doRotate(self): self.makeRotation = True return 0 def doLight(self): self.animLight = True return 0 def update(self, evt): ang = (self.angleTime / self.totalAngleTime) #self.camera.setPos(self.player, ang*100,ang*100,ang*100) self.player.setPos(self.render, 0, 0, 1) #self.camera.lookAt( Vec3(0,300,0) ) #self.p.setPos(self.player, 0,0,0,) # self.dirLightPath.setHpr(ang*360.0 ,-60,0) if (self.makeRotation): self.makeRotation = False self.rotateAngles = (self.rotateAngles + 90) % 360 self.player.setHpr(self.rotateAngles, 0, 0) self.sceneName[ "text"] = f"Starfox visual test ({self.rotateAngles})" self.camera.setPos(self.render, 10, 10, 10) self.camera.lookAt(self.player) if (ang >= 1): self.angleTime = 0 self.angleTime = self.angleTime + globalClock.getDt() self.dirLight.color = (ang, 0, 1, 1) if self.animLight: self.pointLightPath.setPos(ang * 10 - 5, ang * 10 - 5, ang * 5) return Task.cont
class World(DirectObject): def __init__(self): self.last_mousex = 0 self.last_mousey = 0 self.zone = None self.zone_reload_name = None self.winprops = WindowProperties() # simple console output self.consoleNode = NodePath(PandaNode("console_root")) self.consoleNode.reparentTo(aspect2d) self.console_num_lines = 24 self.console_cur_line = -1 self.console_lines = [] for i in range(0, self.console_num_lines): self.console_lines.append( OnscreenText( text="", style=1, fg=(1, 1, 1, 1), pos=(-1.3, 0.4 - i * 0.05), align=TextNode.ALeft, scale=0.035, parent=self.consoleNode, ) ) # Configuration self.consoleOut("zonewalk v.%s loading configuration" % VERSION) self.configurator = Configurator(self) cfg = self.configurator.config resaveRes = False if "xres" in cfg: self.xres = int(cfg["xres"]) else: self.xres = 1024 resaveRes = True if "yres" in cfg: self.yres = int(cfg["yres"]) else: self.yres = 768 resaveRes = True if resaveRes: self.saveDefaultRes() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.mouse_accum = MouseAccume(lambda: (self.xres_half, self.yres_half)) self.eyeHeight = 7.0 self.rSpeed = 80 self.flyMode = 1 # application window setup base.win.setClearColor(Vec4(0, 0, 0, 1)) self.winprops.setTitle("zonewalk") self.winprops.setSize(self.xres, self.yres) base.win.requestProperties(self.winprops) base.disableMouse() # network test stuff self.login_client = None if "testnet" in cfg: if cfg["testnet"] == "1": self.doLogin() # Post the instructions self.title = addTitle("zonewalk v." + VERSION) self.inst0 = addInstructions(0.95, "[FLYMODE][1]") self.inst1 = addInstructions(-0.95, "Camera control with WSAD/mouselook. Press K for hotkey list, ESC to exit.") self.inst2 = addInstructions(0.9, "Loc:") self.inst3 = addInstructions(0.85, "Hdg:") self.error_inst = addInstructions(0, "") self.kh = [] self.campos = Point3(155.6, 41.2, 4.93) base.camera.setPos(self.campos) # Accept the application control keys: currently just esc to exit navgen self.accept("escape", self.exitGame) self.accept("window-event", self.resizeGame) # Create some lighting ambient_level = 0.6 ambientLight = AmbientLight("ambientLight") ambientLight.setColor(Vec4(ambient_level, ambient_level, ambient_level, 1.0)) render.setLight(render.attachNewNode(ambientLight)) direct_level = 0.8 directionalLight = DirectionalLight("directionalLight") directionalLight.setDirection(Vec3(0.0, 0.0, -1.0)) directionalLight.setColor(Vec4(direct_level, direct_level, direct_level, 1)) directionalLight.setSpecularColor(Vec4(direct_level, direct_level, direct_level, 1)) render.setLight(render.attachNewNode(directionalLight)) # create a point light that will follow our view point (the camera for now) # attenuation is set so that this point light has a torch like effect self.plight = PointLight("plight") self.plight.setColor(VBase4(0.8, 0.8, 0.8, 1.0)) self.plight.setAttenuation(Point3(0.0, 0.0, 0.0002)) self.plnp = base.camera.attachNewNode(self.plight) self.plnp.setPos(0, 0, 0) render.setLight(self.plnp) self.cam_light = 1 self.keyMap = { "left": 0, "right": 0, "forward": 0, "backward": 0, "cam-left": 0, "cam-right": 0, "mouse3": 0, "flymode": 1, } # setup FOG self.fog_colour = (0.8, 0.8, 0.8, 1.0) self.linfog = Fog("A linear-mode Fog node") self.linfog.setColor(self.fog_colour) self.linfog.setLinearRange(700, 980) # onset, opaque distances as params # linfog.setLinearFallback(45,160,320) base.camera.attachNewNode(self.linfog) render.setFog(self.linfog) self.fog = 1 # camera control self.campos = Point3(0, 0, 0) self.camHeading = 0.0 self.camPitch = 0.0 base.camLens.setFov(65.0) base.camLens.setFar(1200) self.cam_speed = 0 # index into self.camp_speeds self.cam_speeds = [40.0, 80.0, 160.0, 320.0, 640.0] # Collision Detection for "WALKMODE" # We will detect the height of the terrain by creating a collision # ray and casting it downward toward the terrain. The ray will start above the camera. # A ray may hit the terrain, or it may hit a rock or a tree. If it # hits the terrain, we can detect the height. If it hits anything # else, we rule that the move is illegal. self.cTrav = CollisionTraverser() self.camGroundRay = CollisionRay() self.camGroundRay.setOrigin(0.0, 0.0, 0.0) self.camGroundRay.setDirection(0, 0, -1) # straight down self.camGroundCol = CollisionNode("camRay") self.camGroundCol.addSolid(self.camGroundRay) self.camGroundCol.setFromCollideMask(BitMask32.bit(0)) self.camGroundCol.setIntoCollideMask(BitMask32.allOff()) # attach the col node to the camCollider dummy node self.camGroundColNp = base.camera.attachNewNode(self.camGroundCol) self.camGroundHandler = CollisionHandlerQueue() self.cTrav.addCollider(self.camGroundColNp, self.camGroundHandler) # Uncomment this line to see the collision rays # self.camGroundColNp.show() # Uncomment this line to show a visual representation of the # collisions occuring # self.cTrav.showCollisions(render) # Add the spinCameraTask procedure to the task manager. # taskMgr.add(self.spinCameraTask, "SpinCameraTask") taskMgr.add(self.camTask, "camTask") self.toggleControls(1) # need to step the task manager once to make our fake console work taskMgr.step() # CONSOLE --------------------------------------------------------------------- def consoleScroll(self): for i in range(0, self.console_num_lines - 1): self.console_lines[i].setText(self.console_lines[i + 1].getText()) def consoleOut(self, text): print text # output to stdout/log too if self.console_cur_line == self.console_num_lines - 1: self.consoleScroll() elif self.console_cur_line < self.console_num_lines - 1: self.console_cur_line += 1 self.console_lines[self.console_cur_line].setText(text) taskMgr.step() def consoleOn(self): self.consoleNode.show() def consoleOff(self): self.consoleNode.hide() # User controls ----------------------------------------------------------- def toggleControls(self, on): if on == 1: self.accept("escape", self.exitGame) self.accept("1", self.setSpeed, ["speed", 0]) self.accept("2", self.setSpeed, ["speed", 1]) self.accept("3", self.setSpeed, ["speed", 2]) self.accept("4", self.setSpeed, ["speed", 3]) self.accept("5", self.setSpeed, ["speed", 4]) self.accept("alt-f", self.fogToggle) self.accept("t", self.camLightToggle) self.accept("k", self.displayKeyHelp) self.accept("f", self.toggleFlymode) self.accept("l", self.reloadZone) self.accept("z", self.saveDefaultZone) self.accept("a", self.setKey, ["cam-left", 1]) self.accept("d", self.setKey, ["cam-right", 1]) self.accept("w", self.setKey, ["forward", 1]) self.accept("mouse1", self.setKey, ["forward", 1]) self.accept("mouse3", self.setKey, ["mouse3", 1]) self.accept("s", self.setKey, ["backward", 1]) self.accept("k-up", self.hideKeyHelp) self.accept("a-up", self.setKey, ["cam-left", 0]) self.accept("d-up", self.setKey, ["cam-right", 0]) self.accept("w-up", self.setKey, ["forward", 0]) self.accept("mouse1-up", self.setKey, ["forward", 0]) self.accept("mouse3-up", self.setKey, ["mouse3", 0]) self.accept("s-up", self.setKey, ["backward", 0]) else: messenger.clear() def setSpeed(self, key, value): self.cam_speed = value self.setFlymodeText() def fogToggle(self): if self.fog == 1: render.clearFog() base.camLens.setFar(100000) self.fog = 0 else: render.setFog(self.linfog) base.camLens.setFar(1200) self.fog = 1 def camLightToggle(self): if self.cam_light == 0: render.setLight(self.plnp) self.cam_light = 1 else: render.clearLight(self.plnp) self.cam_light = 0 def displayKeyHelp(self): self.kh = [] msg = "HOTKEYS:" pos = 0.75 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "------------------" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "W: camera fwd, S: camera bck, A: rotate view left, D: rotate view right" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "1-5: set camera movement speed" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "F: toggle Flymode/Walkmode" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "L: load a zone" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "ALT-F: toggle FOG and FAR plane on/off" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = 'T: toggle additional camera "torch" light on/off' pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "Z: set currently loaded zone as new startup default" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) msg = "ESC: exit zonewalk" pos -= 0.05 self.kh.append( OnscreenText(text=msg, style=1, fg=(1, 1, 1, 1), pos=(-0.5, pos), align=TextNode.ALeft, scale=0.04) ) def hideKeyHelp(self): for n in self.kh: n.removeNode() def setFlymodeText(self): zname = "" if self.zone: zname = self.zone.name if self.flyMode == 0: self.inst0.setText("[WALKMODE][%i] %s" % (self.cam_speed + 1, zname)) else: self.inst0.setText("[FLYMODE][%i] %s " % (self.cam_speed + 1, zname)) def toggleFlymode(self): zname = "" if self.zone: zname = self.zone.name if self.flyMode == 0: self.flyMode = 1 else: self.flyMode = 0 self.setFlymodeText() # Define a procedure to move the camera. def spinCameraTask(self, task): angleDegrees = task.time * 6.0 angleRadians = angleDegrees * (pi / 180.0) base.camera.setPos(20 * sin(angleRadians), -20.0 * cos(angleRadians), 3) base.camera.setHpr(angleDegrees, 0, 0) return task.cont def camTask(self, task): # query the mouse mouse_dx = 0 mouse_dy = 0 # if we have a mouse and the right button is depressed if base.mouseWatcherNode.hasMouse(): if self.keyMap["mouse3"] != 0: self.mouse_accum.update() else: self.mouse_accum.reset() mouse_dx = self.mouse_accum.dx mouse_dy = self.mouse_accum.dy self.rXSpeed = fabs(self.mouse_accum.dx) * (self.cam_speed + 1) * max(5 * 1000 / self.xres, 3) self.rYSpeed = fabs(self.mouse_accum.dy) * (self.cam_speed + 1) * max(3 * 1000 / self.yres, 1) if self.keyMap["cam-left"] != 0 or mouse_dx < 0: if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading += self.rXSpeed * globalClock.getDt() else: self.camHeading += self.rSpeed * globalClock.getDt() if self.camHeading > 360.0: self.camHeading = self.camHeading - 360.0 elif self.keyMap["cam-right"] != 0 or mouse_dx > 0: if self.rSpeed < 160: self.rSpeed += 80 * globalClock.getDt() if mouse_dx != 0: self.camHeading -= self.rXSpeed * globalClock.getDt() else: self.camHeading -= self.rSpeed * globalClock.getDt() if self.camHeading < 0.0: self.camHeading = self.camHeading + 360.0 else: self.rSpeed = 80 if mouse_dy > 0: self.camPitch += self.rYSpeed * globalClock.getDt() elif mouse_dy < 0: self.camPitch -= self.rYSpeed * globalClock.getDt() # set camera heading and pitch base.camera.setHpr(self.camHeading, self.camPitch, 0) # viewer position (camera) movement control v = render.getRelativeVector(base.camera, Vec3.forward()) if not self.flyMode: v.setZ(0.0) move_speed = self.cam_speeds[self.cam_speed] if self.keyMap["forward"] == 1: self.campos += v * move_speed * globalClock.getDt() if self.keyMap["backward"] == 1: self.campos -= v * move_speed * globalClock.getDt() # actually move the camera lastPos = base.camera.getPos() base.camera.setPos(self.campos) # self.plnp.setPos(self.campos) # move the point light with the viewer position # WALKMODE: simple collision detection # we simply check a ray from slightly below the "eye point" straight down # for geometry collisions and if there are any we detect the point of collision # and adjust the camera's Z accordingly if self.flyMode == 0: # move the camera to where it would be if it made the move # the colliderNode moves with it # base.camera.setPos(self.campos) # check for collissons self.cTrav.traverse(render) entries = [] for i in range(self.camGroundHandler.getNumEntries()): entry = self.camGroundHandler.getEntry(i) entries.append(entry) # print 'collision' entries.sort(lambda x, y: cmp(y.getSurfacePoint(render).getZ(), x.getSurfacePoint(render).getZ())) if len(entries) > 0: # and (entries[0].getIntoNode().getName() == "terrain"): # print len(entries) self.campos.setZ(entries[0].getSurfacePoint(render).getZ() + self.eyeHeight) else: self.campos = lastPos base.camera.setPos(self.campos) # if (base.camera.getZ() < self.player.getZ() + 2.0): # base.camera.setZ(self.player.getZ() + 2.0) # update loc and hpr display pos = base.camera.getPos() hpr = base.camera.getHpr() self.inst2.setText("Loc: %.2f, %.2f, %.2f" % (pos.getX(), pos.getY(), pos.getZ())) self.inst3.setText("Hdg: %.2f, %.2f, %.2f" % (hpr.getX(), hpr.getY(), hpr.getZ())) return task.cont def exitGame(self): sys.exit(0) def resizeGame(self, win): props = base.win.getProperties() self.xres = props.getXSize() self.yres = props.getYSize() self.xres_half = self.xres / 2 self.yres_half = self.yres / 2 self.saveDefaultRes() # Records the state of the arrow keys # this is used for camera control def setKey(self, key, value): self.keyMap[key] = value # ------------------------------------------------------------------------- # this is the mythical MAIN LOOP :) def update(self): if self.zone_reload_name != None: self.doReload(self.zone_reload_name) self.zone_reload_name = None if self.zone != None: self.zone.update() taskMgr.step() if self.login_client != None: self.login_client.update() # ZONE loading ------------------------------------------------------------ # general zone loader driver # removes existing zone (if any) and load the new one def loadZone(self, name, path): if path[len(path) - 1] != "/": path += "/" if self.zone: self.zone.rootNode.removeNode() self.zone = Zone(self, name, path) error = self.zone.load() if error == 0: self.consoleOff() self.setFlymodeText() base.setBackgroundColor(self.fog_colour) def saveDefaultRes(self): cfg = self.configurator.config cfg["xres"] = str(self.xres) cfg["yres"] = str(self.yres) self.configurator.saveConfig() # initial world load after bootup def load(self): cfg = self.configurator.config if self.login_client != None: return zone_name = cfg["default_zone"] basepath = cfg["basepath"] self.loadZone(zone_name, basepath) # config save user interfacce def saveDefaultZone(self): if self.zone: cfg = self.configurator.config cfg["default_zone"] = self.zone.name self.configurator.saveConfig() # zone reload user interface # this gets called from our update loop when it detects that zone_reload_name has been set # we do this in this convoluted fashion in order to keep the main loop taskMgr updates ticking # because otherwise our status console output at various stages during the zone load would not # be displayed. Yes, this is hacky. def doReload(self, name): cfg = self.configurator.config basepath = cfg["basepath"] self.loadZone(name, basepath) # form dialog callback # this gets called from the form when the user has entered a something # (hopefully a correct zone short name) def reloadZoneDialogCB(self, name): self.frmDialog.end() self.zone_reload_name = name self.toggleControls(1) # this is called when the user presses "l" # it disables normal controls and fires up our query form dialog def reloadZone(self): base.setBackgroundColor((0, 0, 0)) self.toggleControls(0) self.consoleOn() self.frmDialog = FileDialog( "Please enter the shortname of the zone you wish to load:", "Examples: qrg, blackburrow, freportn, crushbone etc.", self.reloadZoneDialogCB, ) self.frmDialog.activate() # relies on the main update loop to run ############################### # EXPERIMENTAL def doLogin(self): self.login_client = UDPClientStream("127.0.0.1", 5998)