from otp.level.BasicEntities import DistributedNodePathEntity from pandac.PandaModules import * from direct.interval.IntervalGlobal import * from toontown.toonbase.ToontownGlobals import * import random from direct.directnotify import DirectNotifyGlobal from direct.distributed.ClockDelta import globalClockDelta import DistributedBarrelBase from otp.level.BasicEntities import DistributedNodePathEntity from toontown.toonbase import ToontownGlobals from toontown.toonbase import TTLocalizer from toontown.toonbase import ToontownTimer from direct.task import Task from direct.gui.DirectGui import DGG, DirectFrame, DirectLabel class DistributedMaze(DistributedNodePathEntity): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedMaze') ScheduleTaskName = 'mazeScheduler' RemoveBlocksDict = {2: ('HedgeBlock_0_1',), 4: (('HedgeBlock_0_1', 'HedgeBlock_1_3', 'HedgeBlock_2_3'), ('HedgeBlock_0_2', 'HedgeBlock_2_3', 'HedgeBlock_1_3'), ('HedgeBlock_0_1', 'HedgeBlock_0_2', 'HedgeBlock_1_3', 'HedgeBlock_2_3'))} def __init__(self, cr): DistributedNodePathEntity.__init__(self, cr) self.numSections = 0 self.GameDuration = 35.0 + self.numSections * 15.0 self.timer = None self.frame2D = None self.gameLabel = None self.gameStarted = 0 self.finished = 0 self.timedOut = 0 self.toonFinishedText = TTLocalizer.toonFinishedHedgeMaze self.toonEnteredText = TTLocalizer.enterHedgeMaze return def announceGenerate(self): DistributedNodePathEntity.announceGenerate(self) self.addHints(self.roomHold) self.loadGui() def disable(self): DistributedNodePathEntity.disable(self) self.unloadGui() self.cleanupTimer() self.ignoreAll() def delete(self): self.cleanupTimer() DistributedNodePathEntity.delete(self) def setRoomDoId(self, roomDoId): self.roomDoId = roomDoId room = self.cr.doId2do.get(roomDoId) if room: self.gotRoom([room]) else: self.roomRequest = self.cr.relatedObjectMgr.requestObjects([roomDoId], allCallback=self.gotRoom, timeout=5) def gotRoom(self, rooms): self.roomRequest = None room = rooms[0] self.roomHold = room rotations = [0, 0, 90, 90, 180, 180, 270, 270] self.getRng().shuffle(rotations) self.numSections = 0 for i in xrange(0, 4): maze = room.getGeom().find('**/Maze_Inside_%d' % i) if not maze.isEmpty(): self.numSections += 1 if rotations: maze.setH(rotations.pop()) self.GameDuration = 35.0 + self.numSections * 15.0 self.removeHedgeBlocks(room) return def addHints(self, room): self.focusPoint = self.attachNewNode('GolfGreenGameFrame') hintList = room.getGeom().findAllMatches('**/dead*') for hint in hintList: self.actSphere = CollisionSphere(0, 0, 0, 7.0) self.actSphereNode = CollisionNode('mazegame_hint-%s-%s' % (self.level.getLevelId(), self.entId)) self.actSphereNode.addSolid(self.actSphere) self.actSphereNodePath = hint.attachNewNode(self.actSphereNode) self.actSphereNode.setCollideMask(WallBitmask) self.actSphere.setTangible(0) self.enterEvent = 'enter' + self.actSphereNode.getName() self.accept(self.enterEvent, self.__handleToonEnterHint) self.exitEvent = 'exit' + self.actSphereNode.getName() self.accept(self.exitEvent, self.__handleToonExitHint) enterance = room.getGeom().find('**/ENTRANCE') self.enterSphere = CollisionSphere(0, 0, 0, 8.0) self.enterSphereNode = CollisionNode('mazegame_enter-%s-%s' % (self.level.getLevelId(), self.entId)) self.enterSphereNode.addSolid(self.enterSphere) self.enterSphereNodePath = enterance.attachNewNode(self.enterSphereNode) self.enterSphereNode.setCollideMask(WallBitmask) self.enterSphere.setTangible(0) self.enteranceEvent = 'enter' + self.enterSphereNode.getName() self.accept(self.enteranceEvent, self.__handleToonEnterance) finish = room.getGeom().find('**/finish') self.finishSphere = CollisionSphere(0, 0, 0, 15.0) self.finishSphereNode = CollisionNode('mazegame_finish-%s-%s' % (self.level.getLevelId(), self.entId)) self.finishSphereNode.addSolid(self.finishSphere) self.finishSphereNodePath = finish.attachNewNode(self.finishSphereNode) self.finishSphereNode.setCollideMask(WallBitmask) self.finishSphere.setTangible(0) self.finishEvent = 'enter' + self.finishSphereNode.getName() self.accept(self.finishEvent, self.__handleToonFinish) def __handleToonEnterance(self, collEntry): if not self.gameStarted: self.notify.debug('sending clientTriggered for %d' % self.doId) self.sendUpdate('setClientTriggered', []) self.level.countryClub.showInfoText(self.toonEnteredText) def __handleToonFinish(self, collEntry): self.sendUpdate('setFinishedMaze', []) self.finished = 1 def __handleToonEnterHint(self, collEntry): camHeight = base.localAvatar.getClampedAvatarHeight() heightScaleFactor = camHeight * 0.3333333333 defLookAt = Point3(0.0, 1.5, camHeight) cameraPoint = Point3(0.0, -22.0 * heightScaleFactor, camHeight + 54.0) base.localAvatar.stopUpdateSmartCamera() base.localAvatar.startUpdateSmartCamera(push=0) base.localAvatar.setIdealCameraPos(cameraPoint) def __handleToonExitHint(self, collEntry): base.localAvatar.stopUpdateSmartCamera() base.localAvatar.startUpdateSmartCamera() base.localAvatar.setCameraPositionByIndex(base.localAvatar.cameraIndex) self.cameraHold = None return def getRng(self): return random.Random(self.entId * self.doId) def removeHedgeBlocks(self, room): if self.numSections in self.RemoveBlocksDict: blocksToRemove = self.getRng().choice(self.RemoveBlocksDict[self.numSections]) for blockName in blocksToRemove: block = room.getGeom().find('**/%s' % blockName) if not block.isEmpty(): block.removeNode() def setGameStart(self, timestamp): self.notify.debug('%d setGameStart: Starting game' % self.doId) self.gameStartTime = globalClockDelta.networkToLocalTime(timestamp) self.gameStarted = True curGameTime = self.getCurrentGameTime() timeLeft = self.GameDuration - curGameTime self.cleanupTimer() self.timer = ToontownTimer.ToontownTimer() self.timer.posBelowTopRightCorner() self.timer.setTime(timeLeft) self.timer.countdown(timeLeft, self.timerExpired) self.startScheduleTask() self.frame2D.show() def setGameOver(self): self.timedOut = 1 if not self.finished: self.sendUpdate('damageMe', []) roomNum = self.level.roomNum club = self.level.countryClub self.gameOverTrack = Sequence() self.gameOverTrack.append(localAvatar.getTeleportOutTrack()) self.gameOverTrack.append(Func(localAvatar.setPos, self.finishSphereNodePath.getPos(render))) self.gameOverTrack.append(Func(localAvatar.play, 'jump')) self.gameOverTrack.append(Func(self.level.countryClub.camEnterRoom, roomNum)) self.gameOverTrack.start() self.timerExpired() def local2GameTime(self, timestamp): return timestamp - self.gameStartTime def game2LocalTime(self, timestamp): return timestamp + self.gameStartTime def getCurrentGameTime(self): return self.local2GameTime(globalClock.getFrameTime()) def startScheduleTask(self): taskMgr.add(self.scheduleTask, self.ScheduleTaskName) def stopScheduleTask(self): taskMgr.remove(self.ScheduleTaskName) def scheduleTask(self, task): curTime = self.getCurrentGameTime() def cleanupTimer(self): if self.timer: self.timer.stop() self.timer.destroy() self.timer = None return def timerExpired(self): self.cleanupTimer() self.unloadGui() def loadGui(self): self.frame2D = DirectFrame(scale=1.0, pos=(0.0, 0, 0.9), relief=DGG.FLAT, parent=aspect2d, frameSize=(-0.3, 0.3, -0.05, 0.05), frameColor=(0.737, 0.573, 0.345, 0.3)) self.frame2D.hide() self.gameLabel = DirectLabel(parent=self.frame2D, relief=None, pos=(0, 0, 0), scale=1.0, text=TTLocalizer.mazeLabel, text_font=ToontownGlobals.getSignFont(), text0_fg=(1, 1, 1, 1), text_scale=0.075, text_pos=(0, -0.02)) return def unloadGui(self): if self.frame2D: self.frame2D.destroy() self.frame2D = None if self.gameLabel: self.gameLabel.destroy() self.gameLabel = None return def toonFinished(self, avId, place, lastToon): toon = base.cr.doId2do.get(avId) if toon and not self.timedOut: self.level.countryClub.showInfoText(self.toonFinishedText % (toon.getName(), TTLocalizer.hedgeMazePlaces[place])) if lastToon: self.setGameOver()