from direct.directnotify import DirectNotifyGlobal from panda3d.core import * from panda3d.toontown import * from toontown.toonbase.ToonBaseGlobal import * from .DistributedMinigame import * from direct.distributed.ClockDelta import * from direct.interval.IntervalGlobal import * from direct.fsm import ClassicFSM, State from direct.fsm import State from toontown.toonbase import ToontownGlobals from toontown.toonbase import ToontownTimer from direct.task.Task import Task import math from toontown.toon import ToonHead from . import PhotoGameGlobals from direct.gui.DirectGui import * from panda3d.core import * from toontown.toonbase import TTLocalizer from toontown.golf import BuildGeometry from toontown.toon import Toon from toontown.toon import ToonDNA from direct.interval.IntervalGlobal import * import random from direct.showbase import PythonUtil import math import time from toontown.makeatoon import NameGenerator from otp.otpbase import OTPGlobals from toontown.battle import BattleParticles from toontown.minigame import PhotoGameBase from panda3d.otp import * WORLD_SCALE = 2.0 FAR_PLANE_DIST = 600 * WORLD_SCALE STAGE_Z_OFFSET = 7.0 GOODROWS = 13 BADROWS = 4 RAYSPREADX = 0.08 RAYSPREADY = 0.06 ZOOMRATIO = 0.4 ZOOMTIME = 0.5 WANTDOTS = 1 NUMSTARS = PhotoGameGlobals.NUMSTARS STARSIZE = 0.06 VIEWSIZEX = (GOODROWS - BADROWS) * RAYSPREADX VIEWSIZEY = (GOODROWS - BADROWS) * RAYSPREADY def toRadians(angle): return angle * 2.0 * math.pi / 360.0 def toDegrees(angle): return angle * 360.0 / (2.0 * math.pi) class DistributedPhotoGame(DistributedMinigame, PhotoGameBase.PhotoGameBase): notify = DirectNotifyGlobal.directNotify.newCategory('DistributedPhotoGame') font = ToontownGlobals.getToonFont() LOCAL_PHOTO_MOVE_TASK = 'localPhotoMoveTask' FIRE_KEY = 'control' UP_KEY = 'arrow_up' DOWN_KEY = 'arrow_down' LEFT_KEY = 'arrow_left' RIGHT_KEY = 'arrow_right' INTRO_TASK_NAME = 'PhotoGameIntro' INTRO_TASK_NAME_CAMERA_LERP = 'PhotoGameIntroCamera' def __init__(self, cr): DistributedMinigame.__init__(self, cr) PhotoGameBase.PhotoGameBase.__init__(self) self.gameFSM = ClassicFSM.ClassicFSM('DistributedPhotoGame', [State.State('off', self.enterOff, self.exitOff, ['aim']), State.State('aim', self.enterAim, self.exitAim, ['showResults', 'cleanup', 'zoom']), State.State('zoom', self.enterZoom, self.exitZoom, ['showResults', 'cleanup', 'aim']), State.State('showResults', self.enterShowResults, self.exitShowResults, ['cleanup']), State.State('cleanup', self.enterCleanup, self.exitCleanup, [])], 'off', 'cleanup') self.addChildGameFSM(self.gameFSM) self.tripod = None self.leftPressed = 0 self.rightPressed = 0 self.upPressed = 0 self.downPressed = 0 self.photoMoving = 0 self.introSequence = None self.subjects = [] self.scenery = [] self.subjectNode = render.attachNewNode('subjects') self.subjectTracks = {} self.nameCounter = 0 self.zoomedView = 0 self.zoomFlip = 1 self.cameraTrack = None self.assignments = [] self.currentAssignment = 0 self.assignmentPanels = [] self.toonList = [] self.assignmentDataDict = {} self.starDict = {} self.starParentDict = {} self.textureBuffers = [] self.filmCount = 20 self.edgeUp = 0 self.edgeRight = 0 self.edgeDown = 0 self.edgeLeft = 0 self.scorePanel = None return def getTitle(self): return TTLocalizer.PhotoGameTitle def getInstructions(self): return TTLocalizer.PhotoGameInstructions def getMaxDuration(self): return PhotoGameGlobals.GAME_TIME def load(self): self.notify.debug('load') DistributedMinigame.load(self) PhotoGameBase.PhotoGameBase.load(self) self.filmCount = self.data['FILMCOUNT'] self.safeZoneStorageDNAFile = self.data['DNA_TRIO'][0] self.storageDNAFile = self.data['DNA_TRIO'][1] self.dnaFile = self.data['DNA_TRIO'][2] self.dnaStore = DNAStorage() loader.loadDNAFile(self.dnaStore, 'phase_4/dna/storage.dna') loader.loadDNAFile(self.dnaStore, self.storageDNAFile) loader.loadDNAFile(self.dnaStore, self.safeZoneStorageDNAFile) node = loader.loadDNAFile(self.dnaStore, self.dnaFile) self.scene = hidden.attachNewNode(node) self.construct() purchaseModels = loader.loadModel('phase_4/models/gui/purchase_gui') self.filmImage = loader.loadModel('phase_4/models/minigames/photogame_filmroll') self.filmImage.reparentTo(hidden) self.tripodModel = loader.loadModel('phase_4/models/minigames/toon_cannon') self.filmPanel = DirectLabel(parent=hidden, relief=None, pos=(1.16, 0.0, 0.45), scale=0.65, text=str(self.filmCount), text_scale=0.2, text_fg=(0.95, 0.95, 0, 1), text_pos=(0.08, -0.15), text_font=ToontownGlobals.getSignFont(), image=self.filmImage, image_scale=Point3(1.0, 0.0, 0.85)) self.filmPanelTitle = DirectLabel(parent=self.filmPanel, relief=None, pos=(0.08, 0, 0.04), scale=0.08, text=TTLocalizer.PhotoGameFilm, text_fg=(0.95, 0.95, 0, 1), text_shadow=(0, 0, 0, 1)) self.music = base.loader.loadMusic('phase_4/audio/bgm/MG_cannon_game.ogg') self.sndPhotoMove = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_adjust.ogg') self.sndPhotoFire = base.loader.loadSfx('phase_4/audio/sfx/MG_cannon_fire_alt.ogg') self.sndWin = base.loader.loadSfx('phase_4/audio/sfx/MG_win.ogg') self.sndFilmTick = base.loader.loadSfx('phase_4/audio/sfx/Photo_instamatic.ogg') self.timer = ToontownTimer.ToontownTimer() self.timer.posInTopRightCorner() self.timer.hide() self.viewfinderNode = base.aspect2d.attachNewNode('camera node') self.viewfinderNode.setTransparency(TransparencyAttrib.MAlpha) self.viewfinderNode.setDepthWrite(1) self.viewfinderNode.setDepthTest(1) self.viewfinderNode.setY(-1.0) self.screenSizeMult = 0.5 self.screenSizeX = (base.a2dRight - base.a2dLeft) * self.screenSizeMult self.screenSizeZ = (base.a2dTop - base.a2dBottom) * self.screenSizeMult viewfinderImage = loader.loadModel('phase_4/models/minigames/photo_game_viewfinder') viewfinderImage.reparentTo(self.viewfinderNode) viewfinderImage.setScale(0.55, 1.0, 0.55) self.blackoutNode = base.aspect2d.attachNewNode('blackout node') self.blackoutNode.setP(90) BuildGeometry.addSquareGeom(self.blackoutNode, self.screenSizeX * 2.2, self.screenSizeZ * 2.2, Vec4(1.0, 1.0, 1.0, 1.0)) self.blackoutNode.setTransparency(TransparencyAttrib.MAlpha) self.blackoutNode.setColorScale(0.0, 0.0, 0.0, 0.5) self.blackoutNode.setDepthWrite(1) self.blackoutNode.setDepthTest(1) self.blackoutNode.hide() self.subjectToon = Toon.Toon() self.addSound('zoom', 'Photo_zoom.ogg', 'phase_4/audio/sfx/') self.addSound('snap', 'Photo_shutter.ogg', 'phase_4/audio/sfx/') return def __setupCapture(self): self.captureCam = NodePath(Camera('CaptureCamera')) self.captureCam.reparentTo(self.pointer) self.captureLens = PerspectiveLens() self.captureOutFOV = VIEWSIZEX / self.screenSizeX * self.outFov * 0.5 self.captureZoomFOV = VIEWSIZEX / self.screenSizeX * self.zoomFov * 0.5 self.captureLens.setFov(self.captureOutFOV) self.captureLens.setAspectRatio(1.33) self.captureCam.node().setLens(self.captureLens) def __removeCapture(self): del self.captureCam del self.captureLens def unload(self): self.notify.debug('unload') DistributedMinigame.unload(self) if self.cameraTrack: self.cameraTrack.finish() self.cameraTrack = None self.__removeCapture() for textureBuffer in self.textureBuffers: base.graphicsEngine.removeWindow(textureBuffer) del self.textureBuffers self.viewfinderNode.removeNode() self.blackoutNode.removeNode() for key in self.assignmentDataDict: assignmentData = self.assignmentDataDict[key] assignmentData[7].delete() del self.assignmentDataDict self.assignments = [] for subject in self.subjects: subject.delete() self.subjects = [] self.subjectToon.delete() self.destruct() for scenery in self.scenery: scenery.removeNode() self.scenery = None self.subjectNode.removeNode() self.subjectNode = None self.sky.removeNode() del self.sky self.photoRoot = None self.scene.removeNode() del self.scene self.pointer.removeNode() self.tripodModel.removeNode() del self.tripodModel for panel in self.assignmentPanels: panel.destroy() self.assignmentPanels = [] if self.scorePanel: self.scorePanel.destroy() self.starDict = {} self.starParentDict = {} self.filmPanel.destroy() del self.filmPanel self.filmImage.removeNode() del self.filmImage del self.music del self.sndPhotoMove del self.sndPhotoFire del self.sndWin del self.sndFilmTick self.tripod.removeNode() del self.tripod del self.swivel self.timer.destroy() del self.timer self.removeChildGameFSM(self.gameFSM) del self.gameFSM self.ignoreAll() for rayEntry in self.rayArray: rayEntry[3].remove_node() del self.rayArray return def onstage(self): self.notify.debug('Onstage') DistributedMinigame.onstage(self) self.__createTripod() self.tripod.reparentTo(render) self.tripod.hide() self.__loadToonInTripod(self.localAvId) camera.reparentTo(render) self.__oldCamFar = base.camLens.getFar() base.camLens.setFar(FAR_PLANE_DIST) self.__setupSubjects() self.__startIntro() base.transitions.irisIn() base.playMusic(self.music, looping=1, volume=0.8) orgFov = base.camLens.getFov() self.outFov = orgFov.getX() self.zoomFov = orgFov.getX() * ZOOMRATIO self.currentFov = self.outFov self.__setupCapture() def offstage(self): self.notify.debug('offstage') self.sky.reparentTo(hidden) self.scene.reparentTo(hidden) for avId in self.avIdList: av = self.getAvatar(avId) if av: av.dropShadow.show() av.resetLOD() self.__stopIntro() base.camLens.setFar(self.__oldCamFar) self.timer.reparentTo(hidden) self.filmPanel.reparentTo(hidden) DistributedMinigame.offstage(self) for key in self.subjectTracks: track = self.subjectTracks[key][0] track.pause() del track self.subjectTracks = {} base.localAvatar.laffMeter.start() del self.soundTable def __setupCollisions(self): self.queue = CollisionHandlerQueue() self.traverser = CollisionTraverser('traverser name') self.rayArray = [] vRange = (GOODROWS - BADROWS) // 2 for row in range(-(GOODROWS // 2), GOODROWS // 2 + 1): for column in range(-(GOODROWS // 2), GOODROWS // 2 + 1): goodRange = list(range(-((GOODROWS - BADROWS) // 2), (GOODROWS - BADROWS) // 2 + 1)) rayQuality = 'g' if row not in goodRange or column not in goodRange: rayQuality = 'l' if row > vRange: rayQuality = 'r' if column > vRange: rayQuality = 't' if column < -vRange: rayQuality = 'b' columnString = '+%s' % column if column < 0: columnString = '%s' % column rowString = '+%s' % row if row < 0: rowString = '%s' % row pickerNode = CollisionNode('%s %s %s' % (rowString, columnString, rayQuality)) pickerNP = camera.attachNewNode(pickerNode) pickerNode.setFromCollideMask(GeomNode.getDefaultCollideMask()) pickerRay = CollisionRay() pickerNode.addSolid(pickerRay) self.rayArray.append((row, column, pickerNode, pickerNP, pickerRay)) self.traverser.addCollider(pickerNP, self.queue) if WANTDOTS: self.markerDict = {} for rayEntry in self.rayArray: markerNode = self.viewfinderNode.attachNewNode('marker Node') BuildGeometry.addSquareGeom(markerNode, 0.01, 0.01, Vec4(1.0, 1.0, 1.0, 1.0)) markerNode.setX(RAYSPREADX * rayEntry[0]) markerNode.setY(RAYSPREADY * rayEntry[1]) markerNode.setDepthWrite(1) markerNode.setZ(2.0) self.markerDict[rayEntry[0], rayEntry[1]] = markerNode self.lensNode = LensNode('photo taker') self.lensNode.setLens(base.camLens) def __moveViewfinder(self, task): if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() self.viewfinderNode.setX(mpos.getX() * self.screenSizeX) self.viewfinderNode.setZ(mpos.getY() * self.screenSizeZ) horzAngle = self.viewfinderNode.getX() / self.screenSizeX * 0.5 * base.camLens.getFov()[0] vertAngle = self.viewfinderNode.getZ() / self.screenSizeZ * 0.5 * base.camLens.getFov()[1] horzPointFlat = self.viewfinderNode.getX() / self.screenSizeX vertPointFlat = self.viewfinderNode.getZ() / self.screenSizeZ horzLength = base.camLens.getFov()[0] * 0.5 vertLength = base.camLens.getFov()[1] * 0.5 horzRadianLength = toRadians(horzLength) vertRadianLength = toRadians(vertLength) hMRadian = math.atan(horzPointFlat * math.tan(horzRadianLength)) vMRadian = math.atan(vertPointFlat * math.tan(vertRadianLength)) hMDegree = toDegrees(hMRadian) vMDegree = toDegrees(vMRadian) self.pointer.setH(-hMDegree) self.pointer.setP(vMDegree) newRight = 0 newLeft = 0 newUp = 0 newDown = 0 if self.viewfinderNode.getX() > self.screenSizeX * 0.95: newRight = 1 if self.viewfinderNode.getX() < self.screenSizeX * -0.95: newLeft = 1 if self.viewfinderNode.getZ() > self.screenSizeZ * 0.95: newUp = 1 if self.viewfinderNode.getZ() < self.screenSizeZ * -0.95: newDown = 1 if not self.edgeRight and newRight: self.edgeRight = 1 self.__rightPressed() elif self.edgeRight and not newRight: self.edgeRight = 0 self.__rightReleased() if not self.edgeLeft and newLeft: self.edgeLeft = 1 self.__leftPressed() elif self.edgeLeft and not newLeft: self.edgeLeft = 0 self.__leftReleased() if not self.edgeUp and newUp: self.edgeUp = 1 self.__upPressed() elif self.edgeUp and not newUp: self.edgeUp = 0 self.__upReleased() if not self.edgeDown and newDown: self.edgeDown = 1 self.__downPressed() elif self.edgeDown and not newDown: self.edgeDown = 0 self.__downReleased() return task.cont def __testCollisions(self): self.notify.debug('\nSnapping Photo') self.playSound('snap') if self.filmCount <= 0: self.notify.debug('No Film') return for rayEntry in self.rayArray: posX = (self.viewfinderNode.getX() + RAYSPREADX * rayEntry[0]) / self.screenSizeX posY = (self.viewfinderNode.getZ() + RAYSPREADY * rayEntry[1]) / self.screenSizeZ rayEntry[4].setFromLens(self.lensNode, posX, posY) self.traverser.traverse(self.subjectNode) distDict = {} hitDict = {} centerDict = {} for i in range(self.queue.getNumEntries()): entry = self.queue.getEntry(i) object = None objectIndex = None subjectIndexString = entry.getIntoNodePath().getNetTag('subjectIndex') sceneryIndexString = entry.getIntoNodePath().getNetTag('sceneryIndex') if subjectIndexString: objectIndex = int(subjectIndexString) object = self.subjects[objectIndex] elif sceneryIndexString: objectIndex = int(sceneryIndexString) object = self.scenery[objectIndex] marker = 'g' if 'b' in entry.getFromNodePath().getName(): marker = 'b' if 't' in entry.getFromNodePath().getName(): marker = 't' if 'r' in entry.getFromNodePath().getName(): marker = 'r' if 'l' in entry.getFromNodePath().getName(): marker = 'l' if object: newEntry = (entry.getFromNode(), object) distance = Vec3(entry.getSurfacePoint(self.tripod)).lengthSquared() name = entry.getFromNode().getName() if name not in distDict: distDict[name] = distance hitDict[name] = (entry.getFromNode(), object, marker) elif distance < distDict[name]: distDict[name] = distance hitDict[name] = (entry.getFromNode(), object, marker) for key in hitDict: hit = hitDict[key] superParent = hit[1] marker = hit[2] onCenter = 0 overB = 0 overT = 0 overR = 0 overL = 0 quality = -1 if marker == 'b': overB = 1 elif marker == 't': overT = 1 elif marker == 'r': overR = 1 elif marker == 'l': overL = 1 else: quality = 1 onCenter = 1 if superParent not in centerDict: centerDict[superParent] = (onCenter, overB, overT, overR, overL) else: centerDict[superParent] = (onCenter + centerDict[superParent][0], overB + centerDict[superParent][1], overT + centerDict[superParent][2], overR + centerDict[superParent][3], overL + centerDict[superParent][4]) if WANTDOTS: for key in self.markerDict: node = self.markerDict[key] node.setColorScale(Vec4(1, 1, 1, 1)) for key in hitDict: entry = hitDict[key] name = entry[0].getName() xS = int(name[0:2]) yS = int(name[3:5]) node = self.markerDict[xS, yS] node.setColorScale(Vec4(1.0, 0.0, 0.0, 1.0)) centerDictKeys = [] for key in centerDict: centerDictKeys.append(key) for subject in centerDictKeys: score = self.judgePhoto(subject, centerDict) self.notify.debug('Photo is %s / 5 stars' % score) self.notify.debug('assignment compare %s %s' % (self.determinePhotoContent(subject), self.assignments[self.currentAssignment])) content = self.determinePhotoContent(subject) if content: photoAnalysisZero = (content[0], content[1]) if score and photoAnalysisZero in self.assignments: index = self.assignments.index(photoAnalysisZero) assignment = self.assignments[index] self.notify.debug('assignment complete') if score >= self.assignmentDataDict[assignment][0]: subjectIndex = self.subjects.index(subject) texturePanel = self.assignmentDataDict[assignment][5] texture = self.assignmentDataDict[assignment][6] buffer = self.assignmentDataDict[assignment][4] panelToon = self.assignmentDataDict[assignment][7] panelToon.hide() buffer.setActive(1) texturePanel.show() texturePanel.setColorScale(1, 1, 1, 1) taskMgr.doMethodLater(0.2, buffer.setActive, 'capture Image', [0]) if score > self.assignmentDataDict[assignment][0]: self.assignmentDataDict[assignment][0] = score self.updateAssignmentPanels() self.sendUpdate('newClientPhotoScore', [subjectIndex, content[1], score]) else: self.notify.debug('assignment not complete') horzAngle = self.viewfinderNode.getX() / self.screenSizeX * 0.5 * base.camLens.getFov()[0] vertAngle = self.viewfinderNode.getZ() / self.screenSizeZ * 0.5 * base.camLens.getFov()[1] horzPointFlat = self.viewfinderNode.getX() / self.screenSizeX vertPointFlat = self.viewfinderNode.getZ() / self.screenSizeZ horzLength = base.camLens.getFov()[0] * 0.5 vertLength = base.camLens.getFov()[1] * 0.5 horzRadianLength = toRadians(horzLength) vertRadianLength = toRadians(vertLength) hMRadian = math.atan(horzPointFlat * math.tan(horzRadianLength)) vMRadian = math.atan(vertPointFlat * math.tan(vertRadianLength)) hMDegree = toDegrees(hMRadian) vMDegree = toDegrees(vMRadian) self.__decreaseFilmCount() if self.filmCount == 0: self.sendUpdate('filmOut', []) self.notify.debug('Screen angles H:%s V:%s' % (self.swivel.getH(), self.swivel.getP())) self.notify.debug('Viewfinder to screen angles H:%s V:%s' % (horzAngle, vertAngle)) self.notify.debug('Viewfinder to screen angles with math H:%s V:%s' % (hMDegree, vMDegree)) return def newAIPhotoScore(self, playerId, assignmentIndex, score): if len(self.assignments) > assignmentIndex: assignment = self.assignments[assignmentIndex] assignmentData = self.assignmentDataDict[assignment] if score > assignmentData[2]: assignmentData[2] = score assignmentData[3] = playerId self.updateAssignmentPanels() def determinePhotoContent(self, subject): if self.getSubjectTrackState(subject): return [subject, self.getSubjectTrackState(subject)[2]] else: return None return None def judgePhoto(self, subject, centerDict): self.notify.debug('judgePhoto') self.notify.debug(subject.getName()) self.notify.debug(str(centerDict[subject])) a1 = camera.getH(render) % 360 a2 = subject.getH(render) % 360 angle = abs((a1 + 180 - a2) % 360 - 180) self.notify.debug('angle camera:%s subject:%s between:%s' % (camera.getH(render), subject.getH(render), angle)) self.notify.debug(str(angle)) centering = centerDict[subject] if type(subject) == type(self.subjectToon): facing = angle / 180.0 interest = self.getSubjectTrackState(subject)[3] quality = centering[0] - (centering[1] + centering[2] + centering[3] + centering[4]) tooClose = centering[1] and centering[2] or centering[3] and centering[4] portrait = centering[1] and not (centering[2] or centering[3] or centering[4]) self.notify.debug('angle %s facing %s' % (angle, facing)) self.notify.debug('Interest %s' % interest) self.notify.debug('Quality %s' % quality) self.notify.debug('tooClose %s' % tooClose) if quality <= 0: return None else: score = 0 if angle >= 135: score += 2 elif angle >= 90: score += 1 elif angle <= 60: score -= 1 score += interest if quality >= 5 and (not tooClose or portrait): score += 1 if quality >= 10: score += 1 if quality >= 15: score += 1 score -= 2 if score > NUMSTARS: score = float(NUMSTARS) if score <= 0: return 1 else: return score return None def __toggleView(self): self.notify.debug('Toggle View') hCam = self.swivel.getH() vCam = self.swivel.getP() horzPointFlat = self.viewfinderNode.getX() / self.screenSizeX vertPointFlat = self.viewfinderNode.getZ() / self.screenSizeZ horzLength = base.camLens.getFov()[0] * 0.5 vertLength = base.camLens.getFov()[1] * 0.5 horzRadianLength = toRadians(horzLength) vertRadianLength = toRadians(vertLength) hMRadian = math.atan(horzPointFlat * math.tan(horzRadianLength)) vMRadian = math.atan(vertPointFlat * math.tan(vertRadianLength)) hMDegree = toDegrees(hMRadian) vMDegree = toDegrees(vMRadian) if self.zoomedView: self.zoomedView = 0 else: self.zoomedView = 1 if self.zoomedView: self.notify.debug('Zoom In') hMove = hMDegree * (1.0 - ZOOMRATIO) vMove = vMDegree * (1.0 - ZOOMRATIO) self.currentFov = self.zoomFov base.camLens.setFov(self.zoomFov) self.blackoutNode.show() self.swivel.setHpr(self.swivel, hMove * -self.zoomFlip, vMove * self.zoomFlip, 0) else: self.notify.debug('Zoom Out') hMove = hMDegree * ((1.0 - ZOOMRATIO) / ZOOMRATIO) vMove = vMDegree * ((1.0 - ZOOMRATIO) / ZOOMRATIO) self.currentFov = self.outFov base.camLens.setFov(self.outFov) self.blackoutNode.hide() self.swivel.setHpr(self.swivel, hMove * self.zoomFlip, vMove * -self.zoomFlip, 0) def __doZoom(self): self.notify.debug('Toggle View') self.playSound('zoom') hCam = self.swivel.getH() vCam = self.swivel.getP() horzPointFlat = self.viewfinderNode.getX() / self.screenSizeX vertPointFlat = self.viewfinderNode.getZ() / self.screenSizeZ horzLength = base.camLens.getFov()[0] * 0.5 vertLength = base.camLens.getFov()[1] * 0.5 horzRadianLength = toRadians(horzLength) vertRadianLength = toRadians(vertLength) hMRadian = math.atan(horzPointFlat * math.tan(horzRadianLength)) vMRadian = math.atan(vertPointFlat * math.tan(vertRadianLength)) hMDegree = toDegrees(hMRadian) vMDegree = toDegrees(vMRadian) if self.zoomedView: self.zoomedView = 0 else: self.zoomedView = 1 self.cameraTrack = Sequence() if self.zoomedView: self.notify.debug('Zoom In') hMove = hMDegree * (1.0 - ZOOMRATIO) vMove = vMDegree * (1.0 - ZOOMRATIO) self.currentFov = self.zoomFov base.camLens.setFov(self.zoomFov) self.blackoutNode.show() orgQuat = self.swivel.getQuat() self.swivel.setHpr(self.swivel, hMove * -self.zoomFlip, vMove * self.zoomFlip, 0) self.swivel.setR(0.0) newQuat = self.swivel.getQuat() self.swivel.setQuat(orgQuat) zoomTrack = Parallel() zoomTrack.append(LerpQuatInterval(self.swivel, ZOOMTIME, newQuat)) zoomTrack.append(LerpFunc(base.camLens.setFov, fromData=self.outFov, toData=self.zoomFov, duration=ZOOMTIME)) zoomTrack.append(LerpFunc(self.setBlackout, fromData=0.0, toData=0.5, duration=ZOOMTIME)) self.cameraTrack.append(zoomTrack) self.cameraTrack.append(Func(self.finishZoom, 1)) else: self.notify.debug('Zoom Out') hMove = hMDegree * ((1.0 - ZOOMRATIO) / ZOOMRATIO) vMove = vMDegree * ((1.0 - ZOOMRATIO) / ZOOMRATIO) self.currentFov = self.outFov base.camLens.setFov(self.outFov) orgQuat = self.swivel.getQuat() self.swivel.setHpr(self.swivel, hMove * self.zoomFlip, vMove * -self.zoomFlip, 0) self.swivel.setR(0.0) newQuat = self.swivel.getQuat() self.swivel.setQuat(orgQuat) zoomTrack = Parallel() zoomTrack.append(LerpQuatInterval(self.swivel, ZOOMTIME, newQuat)) zoomTrack.append(LerpFunc(base.camLens.setFov, fromData=self.zoomFov, toData=self.outFov, duration=ZOOMTIME)) zoomTrack.append(LerpFunc(self.setBlackout, fromData=0.5, toData=0.0, duration=ZOOMTIME)) self.cameraTrack.append(zoomTrack) self.cameraTrack.append(Func(self.blackoutNode.hide)) self.cameraTrack.append(Func(self.finishZoom, 0)) self.cameraTrack.start() def setBlackout(self, black): self.blackoutNode.setColorScale(0.0, 0.0, 0.0, black) def getSubjectTrackState(self, subject): subjectTrack = self.subjectTracks.get(subject) if subjectTrack: interval = subjectTrack[0] timeline = subjectTrack[1] time = interval.getT() timeCount = time timelineIndex = 0 while timeCount >= 0.0: timeCount -= timeline[timelineIndex][1] if timeCount >= 0.0: timelineIndex += 1 return timeline[timelineIndex] else: return None return None def __setupSubjects(self): self.__setupCollisions() self.subjects = [] self.subjectTracks = {} self.photoRoot.reparentTo(self.subjectNode) self.photoRoot.setTag('sceneryIndex', '%s' % len(self.scenery)) self.scenery.append(self.photoRoot) random.seed(time.time()) namegen = NameGenerator.NameGenerator() for pathIndex in range(len(self.data['PATHS'])): path = self.data['PATHS'][pathIndex] subject = Toon.Toon() gender = random.choice(['m', 'f']) seed = int(random.random() * 571) if gender == 'm': boy = 1 girl = 0 else: boy = 0 girl = 1 subject.setName(namegen.randomNameMoreinfo(boy=boy, girl=girl)[-1]) self.nameCounter += 1 subject.setPickable(0) subject.setPlayerType(NametagGroup.CCNonPlayer) dna = ToonDNA.ToonDNA() dna.newToonRandom(seed, gender, 1) subject.setDNAString(dna.makeNetString()) subject.animFSM.request('neutral') subject.setTag('subjectIndex', '%s' % len(self.subjects)) self.subjects.append(subject) height = subject.getHeight() self.collSphere = CollisionSphere(0, 0, height * 0.5, height * 0.5) self.collSphere.setTangible(1) self.collNode = CollisionNode(self.uniqueName('subject Sphere')) self.collNode.setCollideMask(BitMask32.allOn()) self.collNode.addSolid(self.collSphere) self.collNodePath = subject.attachNewNode(self.collNode) subject.reparentTo(self.subjectNode) subject.setPos(path[0]) subject.lookAt(path[1]) subject.show() subjectTrack = self.generateToonTrack(subject, path, pathIndex) subjectTrack[0].start() self.subjectTracks[subject] = subjectTrack def regenerateToonTrack(self, subject, path, pathIndex): if not hasattr(self, 'swivel'): return subjectTrack = self.generateToonTrack(subject, path, pathIndex) subjectTrack[0].start() self.subjectTracks[subject] = subjectTrack def generateToonTrack(self, subject, path, pathIndex): def getNextIndex(curIndex, path): return (curIndex + 1) % len(path) subjectTrack = Sequence() subjectTimeline = [] timeAccum = 0.0 pathPointIndex = 0 orgPos = subject.getPos() orgQuat = subject.getQuat() while pathPointIndex < len(path): nextIndex = getNextIndex(pathPointIndex, path) curPoint = path[pathPointIndex] nextPoint = path[nextIndex] distance = self.slowDistance(curPoint, nextPoint) pointTime = distance * 0.25 subject.setPos(curPoint) subject.lookAt(nextPoint) nextQuat = subject.getQuat() animSetIndex = self.data['PATHANIMREL'][pathIndex] animChoice = random.choice(self.data['ANIMATIONS'][animSetIndex])[0] movetype = random.choice(self.data['MOVEMODES'][animSetIndex]) turnTime = 0.2 if movetype[0] == 'swim': turnTime = 0.0 nextInterval = LerpQuatInterval(subject, turnTime, quat=nextQuat) subjectTrack.append(nextInterval) subjectTimeline.append((timeAccum, nextInterval.getDuration(), 'turn', 1.0)) timeAccum += nextInterval.getDuration() movetype = random.choice(self.data['MOVEMODES'][animSetIndex]) pointTime = pointTime * movetype[1] if movetype[0] == 'swim': nextInterval = Sequence() startInterval = Func(subject.setP, -60) midInterval = Parallel(LerpPosInterval(subject, pointTime, nextPoint), ActorInterval(subject, movetype[0], loop=1, duration=pointTime)) nextInterval.append(startInterval) nextInterval.append(midInterval) else: nextInterval = Sequence() startInterval = Func(subject.setP, 0) midInterval = Parallel(LerpPosInterval(subject, pointTime, nextPoint), ActorInterval(subject, movetype[0], loop=1, duration=pointTime)) nextInterval.append(startInterval) nextInterval.append(midInterval) subjectTrack.append(nextInterval) subjectTimeline.append((timeAccum, nextInterval.getDuration(), movetype[0], 1.0)) timeAccum += nextInterval.getDuration() if animChoice: nextInterval = ActorInterval(subject, animChoice, loop=0) subjectTrack.append(nextInterval) subjectTimeline.append((timeAccum, nextInterval.getDuration(), animChoice, 2.0)) timeAccum += nextInterval.getDuration() pathPointIndex += 1 subject.setPos(orgPos) subject.setQuat(orgQuat) subjectTrack.append(Func(self.regenerateToonTrack, subject, path, pathIndex)) return (subjectTrack, subjectTimeline) def slowDistance(self, point1, point2): dx = point1[0] - point2[0] dy = point1[1] - point2[1] dz = point1[2] - point2[2] distance = math.sqrt(dx * dx + dy * dy + dz * dz) return distance def getNextPoint(self, pointList, point): pointIndex = 0 length = len(pointList) found = 0 loop = 0 while not found and loop < length: if pointList[index] == point: found = 1 else: index += 1 loop += 1 if not found: return None nextPointIndex = loop + 1 if nextPointIndex >= length: nextPointIndex = 0 return pointList[nextPointIndex] def __createTripod(self): tripod = self.tripodModel.copyTo(hidden) swivel = tripod.find('**/cannon') self.tripod = tripod self.swivel = swivel self.pointer = self.swivel.attachNewNode('pointer') self.tripod.setPos(self.photoRoot.getPos()) self.tripod.setPos(self.tripod.getPos() + self.data['TRIPOD_OFFSET']) def setGameReady(self): if not self.hasLocalToon: return self.notify.debug('setGameReady') if DistributedMinigame.setGameReady(self): return def setGameStart(self, timestamp): if not self.hasLocalToon: return self.notify.debug('setGameStart') DistributedMinigame.setGameStart(self, timestamp) self.__stopIntro() self.__putCameraOnTripod() if not base.config.GetBool('endless-cannon-game', 0): self.timer.show() self.timer.countdown(self.data['TIME'], self.__gameTimerExpired) self.filmPanel.reparentTo(aspect2d) self.scoreMult = MinigameGlobals.getScoreMult(self.cr.playGame.hood.id) self.clockStopTime = None self.gameFSM.request('aim') self.__putCameraOnTripod() self.currentAssignment = 0 assignmentTemplates = self.generateAssignmentTemplates(PhotoGameGlobals.ONSCREENASSIGNMENTS) self.generateAssignments(assignmentTemplates) self.generateAssignmentPanels() self.scorePanel = self.makeScoreFrame() self.scorePanel.reparentTo(aspect2d) self.scorePanel.setPos(1.05, 0.0, -0.725) self.updateAssignmentPanels() for subject in self.subjects: subject.useLOD(1000) return def setGameExit(self): DistributedMinigame.setGameExit(self) self.__gameTimerExpired() def __gameTimerExpired(self): self.notify.debug('game timer expired') self.gameOver() def generateAssignments(self, assignmentTemplates): for template in assignmentTemplates: subject = self.subjects[template[0]] pose = template[1] score = 0.0 panel = None topScore = 0.0 topScorerId = None textureBuffer = None texturePanel = None texture = None panelToon = None assignment = (subject, pose) if assignment not in self.assignments: self.assignments.append(assignment) self.assignmentDataDict[assignment] = [score, panel, topScore, topScorerId, textureBuffer, texturePanel, texture, panelToon] self.notify.debug('assignments') for assignment in self.assignments: self.notify.debug(str(assignment)) return def generateAssignmentPanels(self): self.notify.debug('generateAssignmentPanels') for panel in self.assignmentPanels: panel.destroy() spacing = self.screenSizeX / PhotoGameGlobals.ONSCREENASSIGNMENTS * 1.61 index = 0 Xoff = self.screenSizeX - 0.735 Zoff = -self.screenSizeZ + 0.25 for assignment in self.assignments: self.notify.debug('made assignment panel %s' % str(assignment)) panel, texturePanel, toon = self.makeAssignmentPanel(assignment) panel.setX(Xoff - spacing * index) panel.setZ(Zoff) texturePanel.setZ(0.065) rot = random.choice([0.0, 2.0, -2.0, -4.0, 6.0]) panel.setR(rot) textureBuffer = base.win.makeTextureBuffer('Photo Capture', 128, 128) dr = textureBuffer.makeDisplayRegion() dr.setCamera(self.captureCam) texture = textureBuffer.getTexture() texturePanel.setTexture(texture) texturePanel.setColorScale(0, 0, 0, 0) textureBuffer.setActive(0) self.textureBuffers.append(textureBuffer) texturePanel.hide() self.assignmentPanels.append(panel) self.assignmentDataDict[assignment][1] = panel self.assignmentDataDict[assignment][4] = textureBuffer self.assignmentDataDict[assignment][5] = texturePanel self.assignmentDataDict[assignment][6] = texture self.assignmentDataDict[assignment][7] = toon index += 1 def printAD(self): for assignment in self.assignmentDataDict: data = self.assignmentDataDict[assignment] print('Key:%s\nData:%s\n' % (str(assignment), data)) def updateScorePanel(self): teamScore = 0.0 bonusScore = 0.0 for assignment in self.assignments: data = self.assignmentDataDict[assignment] teamScore += data[2] if data[3] == localAvatar.doId: bonusScore += 1.0 self.scorePanel['text'] = TTLocalizer.PhotoGameScore % (int(teamScore), int(bonusScore), int(teamScore + bonusScore)) def updateAssignmentPanels(self): for assignment in self.assignments: data = self.assignmentDataDict[assignment] leaderName = data[3] leader = base.cr.doId2do.get(data[3]) if not leader: data[1]['text'] = ' ' elif leader.doId == localAvatar.doId: data[1]['text'] = TTLocalizer.PhotoGameScoreYou else: leaderName = leader.getName() data[1]['text'] = TTLocalizer.PhotoGameScoreOther % leaderName starList = self.starDict[data[1]] starParent = self.starParentDict[data[1]] score = int(data[2]) for index in range(NUMSTARS): if index < score: starList[index].show() else: starList[index].hide() starParent.setX(float(NUMSTARS - score) * STARSIZE * 0.5) self.updateScorePanel() def makeAssignmentPanel(self, assignment): if assignment != None: assignedToon = Toon.Toon() assignedToon.setDNA(assignment[0].getStyle()) else: assignedToon = None model, ival = self.makeFrameModel(assignedToon) if assignedToon: assignedToon.loop(assignment[1]) model.reparentTo(aspect2d) assignedToon.setH(172) assignedToon.setZ(-1.2) assignedToon.setY(100.0) if assignment[1] == 'swim': assignedToon.setP(-70) assignedToon.setH(160) assignedToon.setZ(-0.6) model.setH(0) model.setScale(1.0) model['text'] = ' ' assignedToon.setY(-100.0) model.setY(-10.0) screen = model.attachNewNode('screen node') BuildGeometry.addSquareGeom(screen, 0.36, 0.27, Vec4(1.0, 1.0, 1.0, 1.0)) screen.setHpr(0, 90, 0) screen.setDepthTest(1) starImage = loader.loadModel('phase_4/models/minigames/photogame_star') starParent = model.attachNewNode('star parent') self.starDict[model] = [] for index in range(NUMSTARS): star = DirectLabel(parent=starParent, image=starImage, image_color=(1, 1, 1, 1), image_scale=Point3(STARSIZE, 0.0, STARSIZE), relief=None) star.setX(STARSIZE * -0.5 * float(NUMSTARS) + float(index + 0.5) * STARSIZE) star.setZ(-0.05 - STARSIZE) self.starDict[model].append(star) self.starParentDict[model] = starParent star.hide() return (model, screen, assignedToon) def makeFrameModel(self, model): frame = self.makeAssignmentFrame() ival = None if model: model.setDepthTest(1) model.setDepthWrite(1) scale = frame.attachNewNode('scale') model.reparentTo(scale) bMin, bMax = model.getTightBounds() center = (bMin + bMax) / 2.0 model.setPos(-center[0], 2, -center[2]) corner = Vec3(bMax - center) scaleFactor = self.screenSizeX / PhotoGameGlobals.ONSCREENASSIGNMENTS scale.setScale(0.4 * scaleFactor / max(corner[0], corner[1], corner[2])) return (frame, ival) def makeAssignmentFrame(self): from direct.gui.DirectGui import DirectFrame photoImage = loader.loadModel('phase_4/models/minigames/photo_game_pictureframe') size = 1.0 assignmentScale = self.screenSizeX / PhotoGameGlobals.ONSCREENASSIGNMENTS frame = DirectFrame(parent=hidden, image=photoImage, image_color=(1, 1, 1, 1), image_scale=Point3(1.6 * assignmentScale, 0.0, 1.75 * assignmentScale), frameSize=(-size, size, -size, size), text='HC Score', textMayChange=1, text_wordwrap=9, text_pos=Point3(0.0, -0.135, 0.0), text_scale=0.045, relief=None) return frame def makeScoreFrame(self): from direct.gui.DirectGui import DirectFrame size = 1.0 scoreImage = loader.loadModel('phase_4/models/minigames/photogame_camera') frame = DirectFrame(parent=hidden, image=scoreImage, image_color=(1, 1, 1, 1), image_scale=Point3(0.64, 0.0, 0.64), frameSize=(-size, size, -size, size), text='Score Frame', textMayChange=1, text_wordwrap=9, text_pos=Point3(0.0, 0.0, 0.0), text_scale=0.05, relief=None) return frame def enterOff(self): self.notify.debug('enterOff') def exitOff(self): pass def enterAim(self): self.notify.debug('enterAim') self.__enableAimInterface() taskMgr.add(self.__moveViewfinder, 'photo game viewfinder Task') self.accept('mouse1', self.__handleMouseClick) base.localAvatar.laffMeter.stop() base.transitions.noIris() def exitAim(self): self.__disableAimInterface() taskMgr.remove('photo game viewfinder Task') self.ignore('mouse1') def enterZoom(self): self.notify.debug('enterZoom') taskMgr.add(self.__moveViewfinder, 'photo game viewfinder Task') self.__doZoom() def exitZoom(self): taskMgr.remove('photo game viewfinder Task') self.notify.debug('exitZoom') def finishZoom(self, zoomed = None, task = None): if zoomed: self.captureLens.setFov(self.captureZoomFOV) else: self.captureLens.setFov(self.captureOutFOV) self.gameFSM.request('aim') def enterShowResults(self): self.notify.debug('enterShowResults') for subject in self.subjects: subject.resetLOD() def exitShowResults(self): pass def enterCleanup(self): self.notify.debug('enterCleanup') self.music.stop() if hasattr(self, 'jarIval'): self.jarIval.finish() del self.jarIval for avId in self.avIdList: taskMgr.remove('firePhoto' + str(avId)) taskMgr.remove('flyingToon' + str(avId)) def exitCleanup(self): pass def __enableAimInterface(self): self.accept(self.FIRE_KEY, self.__fireKeyPressed) self.accept(self.UP_KEY, self.__upKeyPressed) self.accept(self.DOWN_KEY, self.__downKeyPressed) self.accept(self.LEFT_KEY, self.__leftKeyPressed) self.accept(self.RIGHT_KEY, self.__rightKeyPressed) self.__spawnLocalPhotoMoveTask() def __disableAimInterface(self): self.ignore(self.FIRE_KEY) self.ignore(self.UP_KEY) self.ignore(self.DOWN_KEY) self.ignore(self.LEFT_KEY) self.ignore(self.RIGHT_KEY) self.ignore(self.FIRE_KEY + '-up') self.ignore(self.UP_KEY + '-up') self.ignore(self.DOWN_KEY + '-up') self.ignore(self.LEFT_KEY + '-up') self.ignore(self.RIGHT_KEY + '-up') self.__killLocalPhotoMoveTask() def __fireKeyPressed(self): self.ignore(self.FIRE_KEY) self.accept(self.FIRE_KEY + '-up', self.__fireKeyReleased) self.__firePressed() def __upKeyPressed(self): self.ignore(self.UP_KEY) self.accept(self.UP_KEY + '-up', self.__upKeyReleased) self.__upPressed() def __downKeyPressed(self): self.ignore(self.DOWN_KEY) self.accept(self.DOWN_KEY + '-up', self.__downKeyReleased) self.__downPressed() def __leftKeyPressed(self): self.ignore(self.LEFT_KEY) self.accept(self.LEFT_KEY + '-up', self.__leftKeyReleased) self.__leftPressed() def __rightKeyPressed(self): self.ignore(self.RIGHT_KEY) self.accept(self.RIGHT_KEY + '-up', self.__rightKeyReleased) self.__rightPressed() def __fireKeyReleased(self): self.ignore(self.FIRE_KEY + '-up') self.accept(self.FIRE_KEY, self.__fireKeyPressed) self.__fireReleased() def __leftKeyReleased(self): self.ignore(self.LEFT_KEY + '-up') self.accept(self.LEFT_KEY, self.__leftKeyPressed) self.__leftReleased() def __rightKeyReleased(self): self.ignore(self.RIGHT_KEY + '-up') self.accept(self.RIGHT_KEY, self.__rightKeyPressed) self.__rightReleased() def __upKeyReleased(self): self.ignore(self.UP_KEY + '-up') self.accept(self.UP_KEY, self.__upKeyPressed) self.__upReleased() def __downKeyReleased(self): self.ignore(self.DOWN_KEY + '-up') self.accept(self.DOWN_KEY, self.__downKeyPressed) self.__downReleased() def __firePressed(self): self.notify.debug('fire pressed') def __fireReleased(self): self.gameFSM.request('zoom') def __upPressed(self): self.notify.debug('up pressed') self.upPressed = self.__enterControlActive(self.upPressed) def __downPressed(self): self.notify.debug('down pressed') self.downPressed = self.__enterControlActive(self.downPressed) def __leftPressed(self): self.notify.debug('left pressed') self.leftPressed = self.__enterControlActive(self.leftPressed) def __rightPressed(self): self.notify.debug('right pressed') self.rightPressed = self.__enterControlActive(self.rightPressed) def __upReleased(self): self.notify.debug('up released') self.upPressed = self.__exitControlActive(self.upPressed) def __downReleased(self): self.notify.debug('down released') self.downPressed = self.__exitControlActive(self.downPressed) def __leftReleased(self): self.notify.debug('left released') self.leftPressed = self.__exitControlActive(self.leftPressed) def __rightReleased(self): self.notify.debug('right released') self.rightPressed = self.__exitControlActive(self.rightPressed) def __handleMouseClick(self): self.notify.debug('mouse click') self.__testCollisions() def __enterControlActive(self, control): return control + 1 def __exitControlActive(self, control): return max(0, control - 1) def __spawnLocalPhotoMoveTask(self): self.leftPressed = 0 self.rightPressed = 0 self.upPressed = 0 self.downPressed = 0 self.photoMoving = 0 task = Task(self.__localPhotoMoveTask) task.lastPositionBroadcastTime = 0.0 taskMgr.add(task, self.LOCAL_PHOTO_MOVE_TASK) def __killLocalPhotoMoveTask(self): taskMgr.remove(self.LOCAL_PHOTO_MOVE_TASK) if self.photoMoving: self.sndPhotoMove.stop() def __localPhotoMoveTask(self, task): if not hasattr(self, 'swivel'): return pos = [self.swivel.getHpr()[0], self.swivel.getHpr()[1], self.swivel.getHpr()[2]] oldRot = pos[0] oldAng = pos[1] rotVel = 0 if self.leftPressed: rotVel += PhotoGameGlobals.PHOTO_ROTATION_VEL if self.rightPressed: rotVel -= PhotoGameGlobals.PHOTO_ROTATION_VEL pos[0] += rotVel * globalClock.getDt() angVel = 0 if self.upPressed: angVel += PhotoGameGlobals.PHOTO_ANGLE_VEL if self.downPressed: angVel -= PhotoGameGlobals.PHOTO_ANGLE_VEL pos[1] += angVel * globalClock.getDt() if pos[1] < PhotoGameGlobals.PHOTO_ANGLE_MIN: pos[1] = PhotoGameGlobals.PHOTO_ANGLE_MIN elif pos[1] > PhotoGameGlobals.PHOTO_ANGLE_MAX: pos[1] = PhotoGameGlobals.PHOTO_ANGLE_MAX if oldRot != pos[0] or oldAng != pos[1]: if self.photoMoving == 0: self.photoMoving = 1 base.playSfx(self.sndPhotoMove, looping=1) posVec = Vec3(pos[0], pos[1], pos[2]) self.swivel.setHpr(posVec) elif self.photoMoving: self.photoMoving = 0 self.sndPhotoMove.stop() return Task.cont def __putCameraOnTripod(self): camera.setPosHpr(0, 0.0, 0, 0, 0, 0) camera.reparentTo(self.swivel) self.swivel.setHpr(self.data['START_HPR']) def __loadToonInTripod(self, avId): toon = base.cr.doId2do.get(avId) if toon: toon.reparentTo(self.swivel) def __toRadians(self, angle): return angle * 2.0 * math.pi / 360.0 def __toDegrees(self, angle): return angle * 360.0 / (2.0 * math.pi) def __decreaseFilmCount(self): curTime = self.getCurrentGameTime() score = self.filmCount - 1 if not hasattr(self, 'curScore'): self.curScore = score self.filmPanel['text'] = str(score) if self.curScore != score: if hasattr(self, 'jarIval'): self.jarIval.finish() s = self.filmPanel.getScale() self.jarIval = Parallel(Sequence(self.filmPanel.scaleInterval(0.15, s * 3.0 / 4.0, blendType='easeOut'), self.filmPanel.scaleInterval(0.15, s, blendType='easeIn')), Sequence(Wait(0.25), SoundInterval(self.sndFilmTick)), name='photoGameFilmJarThrob') self.jarIval.start() self.curScore = score self.filmCount = score def __stopIntro(self): taskMgr.remove(self.INTRO_TASK_NAME) taskMgr.remove(self.INTRO_TASK_NAME_CAMERA_LERP) self.__putCameraOnTripod() if self.introSequence: self.introSequence.finish() self.introSequence = None return def __startIntro(self): camera.reparentTo(render) camera.setPos(self.data['CAMERA_INTIAL_POSTION']) camera.setHpr(0, 0, 0) camera.lookAt(self.tripod) lookatHpr = camera.getHpr() self.introSequence = LerpPosHprInterval(camera, 4.0, pos=self.tripod.getPos(render), hpr=lookatHpr, startPos=self.data['CAMERA_INTIAL_POSTION'], blendType='easeInOut') self.introSequence.start() def construct(self): zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.constructTTC() elif zone == ToontownGlobals.DonaldsDock: self.constructDD() elif zone == ToontownGlobals.DaisyGardens: self.constructDG() elif zone == ToontownGlobals.MinniesMelodyland: self.constructMM() elif zone == ToontownGlobals.TheBrrrgh: self.constructBR() elif zone == ToontownGlobals.DonaldsDreamland: self.constructDL() def destruct(self): zone = self.getSafezoneId() if zone == ToontownGlobals.ToontownCentral: self.destructTTC() elif zone == ToontownGlobals.DonaldsDock: self.destructDD() elif zone == ToontownGlobals.DaisyGardens: self.destructDG() elif zone == ToontownGlobals.MinniesMelodyland: self.destructMM() elif zone == ToontownGlobals.TheBrrrgh: self.destructBR() elif zone == ToontownGlobals.DonaldsDreamland: self.destructDL() def constructTTC(self): self.photoRoot = self.scene.find('**/prop_gazebo*') self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') self.sky.reparentTo(render) self.sky.setBin('background', -100) self.sky.find('**/cloud1').setBin('background', -99) self.sky.find('**/cloud2').setBin('background', -98) self.scene.reparentTo(render) self.makeDictionaries(self.dnaStore) self.createAnimatedProps(self.nodeList) self.startAnimatedProps() self.scene.find('**/door_trigger_22*').hide() self.scene.find('**/doorFrameHoleRight_0*').hide() self.scene.find('**/doorFrameHoleLeft_0*').hide() def destructTTC(self): self.stopAnimatedProps() self.deleteAnimatedProps() def constructDD(self): self.photoRoot = self.scene.find('**/center_island*') self.sky = loader.loadModel('phase_3.5/models/props/BR_sky') self.sky.reparentTo(render) self.sky.setBin('background', -100) self.sky.find('**/skypanel1').setBin('background', -98) self.sky.find('**/skypanel2').setBin('background', -97) self.sky.find('**/skypanel3').setBin('background', -96) self.sky.find('**/skypanel4').setBin('background', -95) self.sky.find('**/skypanel5').setBin('background', -94) self.sky.find('**/skypanel6').setBin('background', -93) self.scene.reparentTo(render) self.makeDictionaries(self.dnaStore) self.createAnimatedProps(self.nodeList) self.startAnimatedProps() boatGeom = self.scene.find('**/donalds_boat') self.photoRoot.setPos(-22, 0, 0) self.boat = self.photoRoot.attachNewNode('boat') boatGeom.reparentTo(self.boat) boatGeom.setX(45.0) boatGeom.setY(-5.0) boatGeom.setR(-0.0) boatGeom.setH(-8) self.bg = boatGeom self.boatTrack = Sequence() self.boatTrack.append(LerpHprInterval(self.boat, 90.0, Point3(360, 0, 0))) self.boatTrack.loop() self.boatTrack2 = Sequence() self.boatTrack2.append(LerpPosInterval(self.boat, 5.0, Point3(0, 0, 2.0), Point3(0, 0, 1.0), blendType='easeInOut')) self.boatTrack2.append(LerpPosInterval(self.boat, 5.0, Point3(0, 0, 1.0), Point3(0, 0, 2.0), blendType='easeInOut')) self.boatTrack2.loop() ddFog = Fog('DDFog Photo') ddFog.setColor(Vec4(0.8, 0.8, 0.8, 1.0)) ddFog.setLinearRange(0.0, 400.0) render.setFog(ddFog) water = self.scene.find('**/top_surface') water.setTransparency(TransparencyAttrib.MAlpha) water.setColorScale(1.0, 1.0, 1.0, 0.8) water.setDepthWrite(1) water.setDepthTest(1) water.setBin('transparent', 0) def destructDD(self): self.bg = None self.boatTrack.finish() self.boatTrack2.finish() self.boat.removeNode() render.clearFog() self.stopAnimatedProps() self.deleteAnimatedProps() return def constructDG(self): self.photoRoot = render.attachNewNode('DG PhotoRoot') self.photoRoot.setPos(1.39, 92.91, 2.0) self.bigFlower = loader.loadModel('phase_8/models/props/DG_flower-mod.bam') self.bigFlower.reparentTo(self.photoRoot) self.bigFlower.setScale(2.5) self.sky = loader.loadModel('phase_3.5/models/props/TT_sky') self.sky.reparentTo(render) self.sky.setBin('background', -100) self.sky.find('**/cloud1').setBin('background', -99) self.sky.find('**/cloud2').setBin('background', -98) self.scene.reparentTo(render) self.scene.find('**/door_trigger_5*').hide() self.scene.find('**/doorFrameHoleRight_0*').hide() self.scene.find('**/doorFrameHoleLeft_0*').hide() for name in ['**/o10_2']: maze = self.scene.find(name) maze.reparentTo(self.subjectNode) maze.setTag('sceneryIndex', '%s' % len(self.scenery)) self.scenery.append(maze) self.makeDictionaries(self.dnaStore) self.createAnimatedProps(self.nodeList) self.startAnimatedProps() def destructDG(self): self.bigFlower.removeNode() self.stopAnimatedProps() self.deleteAnimatedProps() def constructMM(self): self.photoRoot = render.attachNewNode('MM PhotoRoot') self.photoRoot.setPos(103.6, -61, -4.497) self.sky = loader.loadModel('phase_6/models/props/MM_sky') self.sky.reparentTo(render) self.sky.setBin('background', -100) self.scene.reparentTo(render) self.scene.find('**/door_trigger_8*').hide() self.scene.find('**/door_trigger_6*').hide() self.scene.find('**/door_trigger_1*').hide() self.scene.find('**/door_trigger_0*').hide() self.scene.find('**/door_trigger_3*').hide() self.scene.find('**/doorFrameHoleRight_0*').hide() self.scene.find('**/doorFrameHoleLeft_0*').hide() self.scene.find('**/doorFrameHoleRight_1*').hide() self.scene.find('**/doorFrameHoleLeft_1*').hide() self.scene.find('**/doorFrameHoleRight').hide() self.scene.find('**/doorFrameHoleLeft').hide() self.makeDictionaries(self.dnaStore) self.createAnimatedProps(self.nodeList) self.startAnimatedProps() lm = self.scene.findAllMatches('**/*landmark*') blocker = lm[2] blocker.reparentTo(self.subjectNode) blocker.setTag('sceneryIndex', '%s' % len(self.scenery)) self.scenery.append(blocker) def destructMM(self): self.stopAnimatedProps() self.deleteAnimatedProps() def constructBR(self): self.photoRoot = render.attachNewNode('BR PhotoRoot') self.photoRoot.setPos(-110, -48, 8.567) self.sky = loader.loadModel('phase_3.5/models/props/BR_sky') self.sky.reparentTo(render) self.sky.setBin('background', -100) self.scene.reparentTo(render) self.scene.find('**/door_trigger_11*').hide() self.scene.find('**/doorFrameHoleRight_0*').hide() self.scene.find('**/doorFrameHoleLeft_0*').hide() self.makeDictionaries(self.dnaStore) self.createAnimatedProps(self.nodeList) self.startAnimatedProps() self.snow = BattleParticles.loadParticleFile('snowdisk.ptf') self.snow.setPos(0, 0, 5) self.snowRender = self.scene.attachNewNode('snowRender') self.snowRender.setDepthWrite(0) self.snowRender.setBin('fixed', 1) self.snowFade = None self.snow.start(camera, self.snowRender) return def destructBR(self): self.snow.cleanup() del self.snow del self.snowRender self.stopAnimatedProps() self.deleteAnimatedProps() def constructDL(self): self.photoRoot = render.attachNewNode('DL PhotoRoot') self.photoRoot.setPos(-70.228, 87.588, 4.397) self.sky = loader.loadModel('phase_8/models/props/DL_sky') self.sky.reparentTo(render) self.sky.setBin('background', -100) self.scene.reparentTo(render) self.scene.find('**/door_trigger_8*').hide() self.scene.find('**/doorFrameHoleRight_0*').hide() self.scene.find('**/doorFrameHoleLeft_0*').hide() self.scene.find('**/doorFrameHoleRight_1*').hide() self.scene.find('**/doorFrameHoleLeft_1*').hide() self.makeDictionaries(self.dnaStore) self.createAnimatedProps(self.nodeList) self.startAnimatedProps() def destructDL(self): self.stopAnimatedProps() self.deleteAnimatedProps() def makeDictionaries(self, dnaStore): self.nodeList = [] for i in range(dnaStore.getNumDNAVisGroups()): groupFullName = dnaStore.getDNAVisGroupName(i) groupName = base.cr.hoodMgr.extractGroupName(groupFullName) groupNode = self.scene.find('**/' + groupFullName) if groupNode.isEmpty(): self.notify.error('Could not find visgroup') self.nodeList.append(groupNode) def startAnimatedProps(self): for animPropListKey in self.animPropDict: animPropList = self.animPropDict[animPropListKey] for animProp in animPropList: animProp.enter() def stopAnimatedProps(self): for animPropListKey in self.animPropDict: animPropList = self.animPropDict[animPropListKey] for animProp in animPropList: animProp.exit() def createAnimatedProps(self, nodeList): self.animPropDict = {} for i in nodeList: animPropNodes = i.findAllMatches('**/animated_prop_*') numAnimPropNodes = animPropNodes.getNumPaths() for j in range(numAnimPropNodes): animPropNode = animPropNodes.getPath(j) if animPropNode.getName().startswith('animated_prop_generic'): className = 'GenericAnimatedProp' else: className = animPropNode.getName()[14:-8] symbols = {} base.cr.importModule(symbols, 'toontown.hood', [className]) classObj = getattr(symbols[className], className) animPropObj = classObj(animPropNode) animPropList = self.animPropDict.setdefault(i, []) animPropList.append(animPropObj) interactivePropNodes = i.findAllMatches('**/interactive_prop_*') numInteractivePropNodes = interactivePropNodes.getNumPaths() for j in range(numInteractivePropNodes): interactivePropNode = interactivePropNodes.getPath(j) className = 'GenericAnimatedProp' symbols = {} base.cr.importModule(symbols, 'toontown.hood', [className]) classObj = getattr(symbols[className], className) interactivePropObj = classObj(interactivePropNode) animPropList = self.animPropDict.get(i) if animPropList is None: animPropList = self.animPropDict.setdefault(i, []) animPropList.append(interactivePropObj) return def deleteAnimatedProps(self): for animPropListKey in self.animPropDict: animPropList = self.animPropDict[animPropListKey] for animProp in animPropList: animProp.delete() del self.animPropDict def addSound(self, name, soundName, path = None): if not hasattr(self, 'soundTable'): self.soundTable = {} if path: self.soundPath = path soundSource = '%s%s' % (self.soundPath, soundName) self.soundTable[name] = loader.loadSfx(soundSource) def playSound(self, name, volume = 1.0): if hasattr(self, 'soundTable'): self.soundTable[name].setVolume(volume) self.soundTable[name].play()