def register(self, render, camera, keys): State.register(self, render, camera, keys) cm = CardMaker('CardMaker-Pause') cm.setFrame(0.5, -0.5, 0.5, -0.5) cm.setColor(0,0,0, 0.1) self.bg = self.node.attachNewNode(cm.generate()) self.bg.setPos(0, 0, 0) menuActions = {'up': (Menu.previousOpt, self.menu), 'down': (Menu.nextOpt, self.menu), 'action': (self.selectOption, None), 'cancel': (self.selectOption, 0) } self.menu.registerKeys(keys, menuActions) self.title = OnscreenText(text="Game Paused", mayChange = True , style=1, fg=(1,1,1,1), pos=(0,0.35), scale = .1) self.text = {} id=0 for opt in self.menu.options: self.text[opt] = OnscreenText(text=opt, mayChange = True , style=1, fg=(1,1,1,1), pos=(0,0.1 - 0.1*id), scale = .06) id+=1 self.title.reparentTo(self.node) for opt in self.text.keys(): self.text[opt].reparentTo(self.node)
def loadFlatQuad(self, fullFilename): cm = CardMaker('cm-%s' % fullFilename) cm.setColor(1.0, 1.0, 1.0, 1.0) aspect = base.camLens.getAspectRatio() htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH) htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT) cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0) bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1) bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1) cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1)) card = cm.generate() quad = NodePath(card) jpgFile = PNMImage(WEB_WIDTH, WEB_HEIGHT) smallerJpgFile = PNMImage() readFile = smallerJpgFile.read(Filename(fullFilename)) if readFile: jpgFile.copySubImage(smallerJpgFile, 0, 0) guiTex = Texture('guiTex') guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba) guiTex.setMinfilter(Texture.FTLinear) guiTex.load(jpgFile) guiTex.setWrapU(Texture.WMClamp) guiTex.setWrapV(Texture.WMClamp) ts = TextureStage('webTS') quad.setTexture(ts, guiTex) quad.setTransparency(0) quad.setTwoSided(True) quad.setColor(1.0, 1.0, 1.0, 1.0) result = quad else: result = None Texture.setTexturesPower2(1) return result
def setupTexture(self): cm = CardMaker('quadMaker') cm.setColor(1.0, 1.0, 1.0, 1.0) aspect = base.camLens.getAspectRatio() htmlWidth = 2.0 * aspect * WEB_WIDTH_PIXELS / float(WIN_WIDTH) htmlHeight = 2.0 * float(WEB_HEIGHT_PIXELS) / float(WIN_HEIGHT) cm.setFrame(-htmlWidth / 2.0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0) bottomRightX = WEB_WIDTH_PIXELS / float(WEB_WIDTH + 1) bottomRightY = WEB_HEIGHT_PIXELS / float(WEB_HEIGHT + 1) cm.setUvRange(Point2(0, 1 - bottomRightY), Point2(bottomRightX, 1)) card = cm.generate() self.quad = NodePath(card) self.quad.reparentTo(self.parent_) self.guiTex = Texture('guiTex') self.guiTex.setupTexture(Texture.TT2dTexture, WEB_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba) self.guiTex.setMinfilter(Texture.FTLinear) self.guiTex.setKeepRamImage(True) self.guiTex.makeRamImage() self.guiTex.setWrapU(Texture.WMRepeat) self.guiTex.setWrapV(Texture.WMRepeat) ts = TextureStage('webTS') self.quad.setTexture(ts, self.guiTex) self.quad.setTexScale(ts, 1.0, -1.0) self.quad.setTransparency(0) self.quad.setTwoSided(True) self.quad.setColor(1.0, 1.0, 1.0, 1.0) self.calcMouseLimits()
def generateAnalysis(self): if self.analyzeMode: self.cleanupAnalysis() self.analyzeMode = True cm = CardMaker('cm') self.analysisBar.show() loadingTime = self.loadingEnd - self.loadingStart for stepName in self.stepInfo: (startTime, duration, color, ticks, startPercent, percent, expectedTicks) = self.stepInfo[stepName] cm.setName(stepName) cm.setColor(color) cm.setFrame((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001) self.analysisBarRoot.attachNewNode(cm.generate()) button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001)) button.bind(DGG.ENTER, self.showInfo, extraArgs = [ stepName]) self.analysisButtons.append(button) button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startPercent / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, ((startPercent + percent) / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, 0.10000000000000001, 0.5)) button.bind(DGG.ENTER, self.showInfo, extraArgs = [ stepName]) self.analysisButtons.append(button) for tick in ticks: self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5)) self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004)) for tick in self.unmappedTicks: self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5)) self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004)) self.analysisSegs = self.analysisBarRoot.attachNewNode(self.line.create())
def create_instance(self): #print("Create label for", self.get_name()) self.label = TextNode(self.parent.get_ascii_name() + '-label') if not self.font_init: self.load_font() if self.font is not None: self.label.set_font(self.font) name = bayer.decode_name(self.parent.get_label_text()) self.label.setText(name) self.label.setTextColor(*self.parent.get_label_color()) #node=label.generate() #self.instance = self.context.annotation.attachNewNode(node) #self.instance.setBillboardPointEye() #node.setIntoCollideMask(GeomNode.getDefaultCollideMask()) #node.setPythonTag('owner', self.parent) cardMaker = CardMaker(self.get_ascii_name() + '-labelcard') cardMaker.setFrame(self.label.getFrameActual()) cardMaker.setColor(0, 0, 0, 0) card_node = cardMaker.generate() self.label_instance = NodePath(card_node) tnp = self.label_instance.attachNewNode(self.label) self.label_instance.setTransparency(TransparencyAttrib.MAlpha) #card.setEffect(DecalEffect.make()) #Using look_at() instead of billboard effect to also rotate the collision solid #card.setBillboardPointEye() #Using a card holder as look_at() is changing the hpr parameters self.instance = NodePath('label-holder') self.label_instance.reparentTo(self.instance) self.instance.reparentTo(self.context.annotation_shader) self.instance.setCollideMask(GeomNode.getDefaultCollideMask()) self.instance.set_depth_write(False) card_node.setPythonTag('owner', self.parent) self.look_at = self.instance.attachNewNode("dummy")
def makeCube(geom, x, y, z, scale=1.0, texpos=None, colors=False): """ Function that adds six cards to a GeomNode to form a cube geom: GeomNode to add cards to x, y, z: Position offset scale: Optional, Scale factor, cube is 1x1x1 by default texpos: Optional, Dictionary of tuples with texture co-ordinates Tuple has Point2 for top-left and Point2 for bottom-right Faces are "front", "back", "left", "right", "top", "bottom" colors: Optional, if True set different color for each face for debugging (see cardcolors) """ cardmaker = CardMaker("cardmaker") mycards = deepcopy(CARDS) for k, i in mycards.iteritems(): points = i for j in points: j += Point3(x, y, z) j *= scale cardmaker.setFrame(*points) if texpos: cardmaker.setUvRange(*texpos[k]) if colors: cardmaker.setColor(*CARDCOLORS[k]) geom.addGeomsFrom(cardmaker.generate())
def create_geom(self, loader): """Creates self.geom_node from self.terrain_map.""" # geom_builder = GeomBuilder('floor') map_size = len(self.terrain_map) unit_size = map_params.unit_size start_pos = -map_size*unit_size/2 # colors = map_params.colors # geom_builder.add_rect( # colors.floor, # start_pos, start_pos, 0, # -start_pos, -start_pos, 0 # ) card_maker = CardMaker("cm") card_maker.setFrame( Point3(-start_pos, -start_pos, 0), Point3(+start_pos, -start_pos, 0), Point3(+start_pos, +start_pos, 0), Point3(-start_pos, +start_pos, 0) ) card_maker.setColor(map_params.colors.floor) floor_node = NodePath(card_maker.generate()) floor_node.reparentTo(self.geom_node) # floor_node.setHpr(0, 90, 0) # floor_node.setPos(0, 0, 0) tex = loader.loadTexture('models/floor.png') floor_node.setTexture(tex, 1) floor_node.setTexScale(TextureStage.getDefault(), map_size, map_size) def get(i, j): return isinstance(self.get_tile(i, j), Wall) wall_count = 0 for i in range(map_size-1): for j in range(map_size-1): if any([get(i, j), get(i+1, j), get(i+1, j+1), get(i, j+1)]): wall_count += 1 def callback(): self.geom_node.clearModelNodes() self.geom_node.flattenStrong() threads = Threads(wall_count, callback) for i in range(map_size-1): for j in range(map_size-1): current_position = ( start_pos+i*unit_size, start_pos+j*unit_size, 0 ) render_wall( current_position, [get(i, j), get(i+1, j), get(i+1, j+1), get(i, j+1)], ((i+j) & 1)+1, self.geom_node, loader, threads )
def generate_map(self, pos): usz = map_params.unit_size msz = (map_params.field_size * map_params.cell_size + (map_params.field_size - 1) * map_params.wall_width) pos = (-msz * usz / 2 + pos[0] * usz, -msz * usz / 2 + pos[1] * usz) card_maker = CardMaker("cm") card_maker.setFrame(Point3(pos[0], pos[1], 0), Point3(pos[0] + usz, pos[1], 0), Point3(pos[0] + usz, pos[1] + usz, 0), Point3(pos[0], pos[1] + usz, 0)) card_maker.setColor(self.color) self.node = NodePath(card_maker.generate()) return self.node
def initSwitchSigns(self): self.switchSigns = [] for i in range(11): cm = CardMaker('card%d'%i) cm.setColor(0,0,0,0) cm.setFrame(-0.5, 0.5, -0.5, 0.5) card = self.level.attachNewNode(cm.generate()) card.setAttrib(TransparencyAttrib.make(TransparencyAttrib.M_alpha)) tex = loader.loadTexture('%d.png'%i) ts = TextureStage('ts') ts.setMode(TextureStage.MReplace) card.setTexture(ts, tex) card.setEffect(BillboardEffect.makePointEye()) card.hide() self.switchSigns.append(card)
def __init__(self, loader, parent): card_maker = CardMaker("cm") pos = map_params.unit_size // 2 card_maker.setFrame(Point3(-pos, -pos, 0), Point3(+pos, -pos, 0), Point3(+pos, +pos, 0), Point3(-pos, +pos, 0)) card_maker.setColor(map_params.colors.floor) self.model = NodePath(card_maker.generate()) self.model.reparentTo(parent) self.model.setPos(Vec3(0, 0, -1)) # floor_node.setHpr(0, 90, 0) # floor_node.setPos(0, 0, 0) tex = loader.loadTexture('models/floor.png') self.model.setTexture(tex, 1) self.model.setTexScale(TextureStage.getDefault(), 1, 1) self.model.setShaderAuto() self.select = None self.tower = None self.tower_class = Empty self.tower_no = 0
def setupRightTexture(self): cm = CardMaker('quadMaker') cm.setColor(1.0, 1.0, 1.0, 1.0) aspect = base.camLens.getAspectRatio() htmlWidth = 2.0 * aspect * WEB_WIDTH / float(WIN_WIDTH) htmlHeight = 2.0 * float(WEB_HEIGHT) / float(WIN_HEIGHT) cm.setFrame(0, htmlWidth / 2.0, -htmlHeight / 2.0, htmlHeight / 2.0) card = cm.generate() self.rightQuad = NodePath(card) self.rightQuad.reparentTo(self.parent_) self.rightGuiTex = Texture('guiTex') self.rightGuiTex.setupTexture(Texture.TT2dTexture, WEB_HALF_WIDTH, WEB_HEIGHT, 1, Texture.TUnsignedByte, Texture.FRgba) self.rightGuiTex.setKeepRamImage(True) self.rightGuiTex.makeRamImage() self.rightGuiTex.setWrapU(Texture.WMClamp) self.rightGuiTex.setWrapV(Texture.WMClamp) ts = TextureStage('rightWebTS') self.rightQuad.setTexture(ts, self.rightGuiTex) self.rightQuad.setTexScale(ts, 1.0, -1.0) self.rightQuad.setTransparency(0) self.rightQuad.setTwoSided(True) self.rightQuad.setColor(1.0, 1.0, 1.0, 1.0)
class main(ShowBase): def __init__(self): ShowBase.__init__(self) # Disable the default camera movements self.disableMouse() # # VIEW SETTINGS # self.win.setClearColor((0.16, 0.16, 0.16, 1)) render.setAntialias(AntialiasAttrib.MAuto) render2d.setAntialias(AntialiasAttrib.MAuto) # # NODE VIEW # self.viewNP = aspect2d.attachNewNode("viewNP") self.viewNP.setScale(0.5) # # NODE MANAGER # self.nodeMgr = NodeManager(self.viewNP) # # NODE RELATED EVENTS # # Add nodes self.accept("addNode", self.nodeMgr.addNode) # Remove nodes self.accept("removeNode", self.nodeMgr.removeNode) self.accept("x", self.nodeMgr.removeNode) self.accept("delete", self.nodeMgr.removeNode) # Selecting self.accept("selectNode", self.nodeMgr.selectNode) # Deselecting self.accept("mouse3", self.nodeMgr.deselectAll) # Node Drag and Drop self.accept("dragNodeStart", self.setDraggedNode) self.accept("dragNodeMove", self.updateNodeMove) self.accept("dragNodeStop", self.updateNodeStop) # Duplicate/Copy nodes self.accept("shift-d", self.nodeMgr.copyNodes) self.accept("copyNodes", self.nodeMgr.copyNodes) # Refresh node logics self.accept("ctlr-r", self.nodeMgr.updateAllLeaveNodes) self.accept("refreshNodes", self.nodeMgr.updateAllLeaveNodes) # # SOCKET RELATED EVENTS # self.accept("updateConnectedNodes", self.nodeMgr.updateConnectedNodes) # Socket connection with drag and drop self.accept("startPlug", self.nodeMgr.setStartPlug) self.accept("endPlug", self.nodeMgr.setEndPlug) self.accept("connectPlugs", self.nodeMgr.connectPlugs) self.accept("cancelPlug", self.nodeMgr.cancelPlug) # Draw line while connecting sockets self.accept("startLineDrawing", self.startLineDrawing) self.accept("stopLineDrawing", self.stopLineDrawing) # # PROJECT MANAGEMENT # self.accept("new", self.newProject) self.accept("save", self.saveProject) self.accept("load", self.loadProject) self.accept("quit", exit) # # EDITOR VIEW # # Zooming self.accept("zoom", self.zoom) self.accept("zoom_reset", self.zoomReset) self.accept("wheel_up", self.zoom, [True]) self.accept("wheel_down", self.zoom, [False]) # Drag view self.mouseSpeed = 1 self.mousePos = None self.startCameraMovement = False self.accept("mouse2", self.setMoveCamera, [True]) self.accept("mouse2-up", self.setMoveCamera, [False]) # Box select # accept the 1st mouse button events to start and stop the draw self.accept("mouse1", self.startBoxDraw) self.accept("mouse1-up", self.stopBoxDraw) # variables to store the start and current pos of the mousepointer self.startPos = LPoint2f(0, 0) self.lastPos = LPoint2f(0, 0) # variables for the to be drawn box self.boxCardMaker = CardMaker("SelectionBox") self.boxCardMaker.setColor(1, 1, 1, 0.25) self.box = None # # WINDOW RELATED EVENTS # self.screenSize = base.getSize() self.accept("window-event", self.windowEventHandler) # # MENU BAR # self.menuBar = MenuBar() # # TASKS # # Task for handling dragging of the camera/view self.taskMgr.add(self.updateCam, "task_camActualisation", priority=-4) # ------------------------------------------------------------------ # PROJECT FUNCTIONS # ------------------------------------------------------------------ def newProject(self): self.nodeMgr.cleanup() def saveProject(self): Save(self.nodeList, self.connections) def loadProject(self): self.nodeMgr.cleanup() Load(self.nodeMgr) # ------------------------------------------------------------------ # CAMERA SPECIFIC FUNCTIONS # ------------------------------------------------------------------ def setMoveCamera(self, moveCamera): """Start dragging around the editor area/camera""" # store the mouse position if weh have a mouse if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() self.mousePos = Point2(x, y) # set the variable according to if we want to move the camera or not self.startCameraMovement = moveCamera def updateCam(self, task): """Task that will move the editor area/camera around according to mouse movements""" # variables to store the mouses current x and y position x = 0.0 y = 0.0 if base.mouseWatcherNode.hasMouse(): # get the mouse position x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if base.mouseWatcherNode.hasMouse() \ and self.mousePos is not None \ and self.startCameraMovement: # Move the viewer node aspect independent wp = self.win.getProperties() aspX = 1.0 aspY = 1.0 wpXSize = wp.getXSize() wpYSize = wp.getYSize() if wpXSize > wpYSize: aspX = wpXSize / float(wpYSize) else: aspY = wpYSize / float(wpXSize) mouseMoveX = (self.mousePos.getX() - x) / self.viewNP.getScale( ).getX() * self.mouseSpeed * aspX mouseMoveY = (self.mousePos.getY() - y) / self.viewNP.getScale( ).getZ() * self.mouseSpeed * aspY self.mousePos = Point2(x, y) self.viewNP.setX(self.viewNP, -mouseMoveX) self.viewNP.setZ(self.viewNP, -mouseMoveY) self.nodeMgr.updateConnections() # continue the task until it got manually stopped return task.cont def zoom(self, zoomIn): """Zoom the editor in or out dependent on the value in zoomIn""" zoomFactor = 0.05 maxZoomIn = 2 maxZoomOut = 0.1 if zoomIn: s = self.viewNP.getScale() if s.getX() - zoomFactor < maxZoomIn and s.getY( ) - zoomFactor < maxZoomIn and s.getZ() - zoomFactor < maxZoomIn: self.viewNP.setScale(s.getX() + zoomFactor, s.getY() + zoomFactor, s.getZ() + zoomFactor) else: s = self.viewNP.getScale() if s.getX() - zoomFactor > maxZoomOut and s.getY( ) - zoomFactor > maxZoomOut and s.getZ() - zoomFactor > maxZoomOut: self.viewNP.setScale(s.getX() - zoomFactor, s.getY() - zoomFactor, s.getZ() - zoomFactor) self.nodeMgr.updateConnections() def zoomReset(self): """Set the zoom level back to the default""" self.viewNP.setScale(0.5) self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # DRAG LINE # ------------------------------------------------------------------ def startLineDrawing(self, startPos): """Start a task that will draw a line from the given start position to the cursor""" self.line = LineNodePath(render2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.line.moveTo(startPos) t = self.taskMgr.add(self.drawLineTask, "drawLineTask") t.startPos = startPos def drawLineTask(self, task): """Draws a line from a given start position to the cursor""" mwn = base.mouseWatcherNode if mwn.hasMouse(): pos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) self.line.reset() self.line.moveTo(task.startPos) self.line.drawTo(pos) self.line.create() return task.cont def stopLineDrawing(self): """Stop the task that draws a line to the cursor""" taskMgr.remove("drawLineTask") if self.line is not None: self.line.reset() self.line = None # ------------------------------------------------------------------ # EDITOR NODE DRAGGING UPDATE # ------------------------------------------------------------------ def setDraggedNode(self, node): """This will set the node that is currently dragged around as well as update other selected nodes which will be moved in addition to the main dragged node""" self.draggedNode = node self.tempNodePositions = {} for node in self.nodeMgr.selectedNodes: self.tempNodePositions[node] = node.frame.getPos(render2d) def updateNodeMove(self, mouseA, mouseB): """Will be called as long as a node is beeing dragged around""" for node in self.nodeMgr.selectedNodes: if node is not self.draggedNode and node in self.tempNodePositions.keys( ): editVec = Vec3(self.tempNodePositions[node] - mouseA) newPos = mouseB + editVec node.frame.setPos(render2d, newPos) self.nodeMgr.updateConnections() def updateNodeStop(self, node=None): """Will be called when a node dragging stopped""" self.draggedNode = None self.tempNodePositions = {} self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # BASIC WINDOW HANDLING # ------------------------------------------------------------------ def windowEventHandler(self, window=None): """Custom handler for window events. We mostly use this for resizing.""" # call showBase windowEvent which would otherwise get overridden and breaking the app self.windowEvent(window) if window != self.win: # This event isn't about our window. return if window is not None: # window is none if panda3d is not started if self.screenSize == base.getSize(): return self.screenSize = base.getSize() # Resize all editor frames self.menuBar.resizeFrame() # ------------------------------------------------------------------ # SELECTION BOX # ------------------------------------------------------------------ def startBoxDraw(self): """Start drawing the box""" if self.mouseWatcherNode.hasMouse(): # get the mouse position self.startPos = LPoint2f(self.mouseWatcherNode.getMouse()) taskMgr.add(self.dragBoxDrawTask, "dragBoxDrawTask") def stopBoxDraw(self): """Stop the draw box task and remove the box""" if not taskMgr.hasTaskNamed("dragBoxDrawTask"): return taskMgr.remove("dragBoxDrawTask") if self.startPos is None or self.lastPos is None: return self.nodeMgr.deselectAll() if self.box is not None: for node in self.nodeMgr.getAllNodes(): # store some view scales for calculations viewXScale = self.viewNP.getScale().getX() viewZScale = self.viewNP.getScale().getZ() # calculate the node edges nodeLeft = node.getLeft() * viewXScale nodeRight = node.getRight() * viewXScale nodeBottom = node.getBottom() * viewZScale nodeTop = node.getTop() * viewZScale # calculate bounding box edges left = min(self.lastPos.getX(), self.startPos.getX()) right = max(self.lastPos.getX(), self.startPos.getX()) top = max(self.lastPos.getY(), self.startPos.getY()) bottom = min(self.lastPos.getY(), self.startPos.getY()) # check for hits xGood = yGood = False if left < nodeLeft and right > nodeLeft: xGood = True elif left < nodeRight and right > nodeRight: xGood = True if top > nodeTop and bottom < nodeTop: yGood = True elif top > nodeBottom and bottom < nodeBottom: yGood = True # check if we have any hits if xGood and yGood: self.nodeMgr.selectNode(node, True, True) # Cleanup the selection box self.box.removeNode() self.startPos = None self.lastPos = None def dragBoxDrawTask(self, task): """This task will track the mouse position and actualize the box's size according to the first click position of the mouse""" if self.mouseWatcherNode.hasMouse(): if self.startPos is None: self.startPos = LPoint2f(self.mouseWatcherNode.getMouse()) # get the current mouse position self.lastPos = LPoint2f(self.mouseWatcherNode.getMouse()) else: return task.cont # check if we already have a box if self.box != None: # if so, remove that old box self.box.removeNode() # set the box's size self.boxCardMaker.setFrame(self.lastPos.getX(), self.startPos.getX(), self.startPos.getY(), self.lastPos.getY()) # generate, setup and draw the box node = self.boxCardMaker.generate() self.box = render2d.attachNewNode(node) self.box.setBin("gui-popup", 25) self.box.setTransparency(TransparencyAttrib.M_alpha) # run until the task is manually stopped return task.cont
def __init__(self): # Initialize the ShowBase class from which we inherit, which will # create a window and set up everything we need for rendering into it. ShowBase.__init__(self) self.disableMouse() self.camera.setPos(0, -26, 4) self.setBackgroundColor(0, 0, 0) # Create a texture into which we can copy the main window. # We set it to RTMTriggeredCopyTexture mode, which tells it that we # want it to copy the window contents into a texture every time we # call self.win.triggerCopy(). self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) self.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) # Set the initial color to clear the texture to, before rendering it. # This is necessary because we don't clear the texture while rendering, # and otherwise the user might see garbled random data from GPU memory. self.tex.setClearColor((0, 0, 0, 1)) self.tex.clearImage() # Create another 2D camera. Tell it to render before the main camera. self.backcam = self.makeCamera2d(self.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) # Obtain two texture cards. One renders before the dragon, the other # after. self.bcard = self.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = self.win.getTextureCard() self.fcard.reparentTo(self.render2d) self.fcard.setTransparency(1) # Initialize one of the nice effects. self.chooseEffectGhost() # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") # Create some black squares on top of which we will # place the instructions. blackmaker = CardMaker("blackmaker") blackmaker.setColor(0, 0, 0, 1) blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(self.render2d) blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85) titlecard = NodePath(blackmaker.generate()) titlecard.reparentTo(self.render2d) # Panda does its best to hide the differences between DirectX and # OpenGL. But there are a few differences that it cannot hide. # One such difference is that when OpenGL copies from a # visible window to a texture, it gets it right-side-up. When # DirectX does it, it gets it upside-down. There is nothing panda # can do to compensate except to expose a flag and let the # application programmer deal with it. You should only do this # in the rare event that you're copying from a visible window # to a texture. if self.win.getGsg().getCopyTextureInverted(): print("Copy texture is inverted.") self.bcard.setScale(1, 1, -1) self.fcard.setScale(1, 1, -1) # Put up the instructions title = OnscreenText(text="Panda3D: Tutorial - Motion Trails", fg=(1, 1, 1, 1), parent=base.a2dBottomCenter, pos=(0, 0.1), scale=.08) instr0 = addInstructions(0.06, "Press ESC to exit") instr1 = addInstructions(0.12, "Press 1: Ghost effect") instr2 = addInstructions(0.18, "Press 2: PaintBrush effect") instr3 = addInstructions(0.24, "Press 3: Double Vision effect") instr4 = addInstructions(0.30, "Press 4: Wings of Blue effect") instr5 = addInstructions(0.36, "Press 5: Whirlpool effect") # Enable the key events self.accept("escape", sys.exit, [0]) self.accept("1", self.chooseEffectGhost) self.accept("2", self.chooseEffectPaintBrush) self.accept("3", self.chooseEffectDoubleVision) self.accept("4", self.chooseEffectWingsOfBlue) self.accept("5", self.chooseEffectWhirlpool)
def generateWater(self, style): print "Generate Water:", self.waterXMin, self.waterXMax, self.waterYMin, self.waterYMax '''Generates water style 0: blue card style 1: reflective card style 2: reflective card with shaders ''' self.waterHeight = 22.0 if self.water: self.water.removeNode() if style is 0: cm = CardMaker("water") #cm.setFrame(-1, 1, -1, 1) cm.setFrame(self.waterXMin, self.waterXMax, self.waterYMin, self.waterYMax) cm.setColor(0, 0, 1, 0.9) self.water = render.attachNewNode(cm.generate()) if self.waterYMax > self.waterXMax: size = self.waterYMax else: size = self.waterXMax self.water.lookAt(0, 0, -1) self.water.setZ(self.waterHeight) messenger.send('makePickable', [self.water]) elif style is 1: # From Prosoft's super awesome terrain demo cm = CardMaker("water") #cm.setFrame(-1, 1, -1, 1) cm.setFrame(self.waterXMin, self.waterXMax, self.waterYMin, self.waterYMax) self.water = render.attachNewNode(cm.generate()) if self.waterYMax > self.waterXMax: size = self.waterYMax else: size = self.waterXMax #self.water.setScale(size) self.water.lookAt(0, 0, -1) self.water.setZ(self.waterHeight) self.water.setShaderOff(1) self.water.setLightOff(1) self.water.setAlphaScale(0.5) self.water.setTransparency(TransparencyAttrib.MAlpha) wbuffer = base.win.makeTextureBuffer("water", 512, 512) wbuffer.setClearColorActive(True) wbuffer.setClearColor(base.win.getClearColor()) self.wcamera = base.makeCamera(wbuffer) self.wcamera.reparentTo(render) self.wcamera.node().setLens(base.camLens) self.wcamera.node().setCameraMask(BitMask32.bit(1)) self.water.hide(BitMask32.bit(1)) wtexture = wbuffer.getTexture() wtexture.setWrapU(Texture.WMClamp) wtexture.setWrapV(Texture.WMClamp) wtexture.setMinfilter(Texture.FTLinearMipmapLinear) self.wplane = Plane(Vec3(0, 0, 1), Point3(0, 0, self.water.getZ())) wplanenp = render.attachNewNode(PlaneNode("water", self.wplane)) tmpnp = NodePath("StateInitializer") tmpnp.setClipPlane(wplanenp) tmpnp.setAttrib(CullFaceAttrib.makeReverse()) self.wcamera.node().setInitialState(tmpnp.getState()) self.water.projectTexture(TextureStage("reflection"), wtexture, self.wcamera) messenger.send('makePickable', [self.water]) elif style is 2: # From Clcheung just as super awesome demomaster self.water_level = Vec4(0.0, 0.0, self.waterHeight, 1.0) self.water = water.WaterNode(self.waterXMin, self.waterYMin, self.waterXMax, self.waterYMax, self.water_level.getZ()) self.water.setStandardControl() self.water.changeParams(None) wl = self.water_level wl.setZ(wl.getZ() - 0.05) #root.setShaderInput('waterlevel', self.water_level) render.setShaderInput('time', 0) messenger.send('makePickable', [self.water.waterNP])
def __init__(self): # create a texture into which we can copy the main window. self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) base.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) # Create another 2D camera. Tell it to render before the main camera. self.backcam = base.makeCamera2d(base.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) # Obtain two texture cards. One renders before the dragon, the other after. self.bcard = base.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = base.win.getTextureCard() self.fcard.reparentTo(render2d) self.fcard.setTransparency(1) # Initialize one of the nice effects. self.chooseEffectGhost() # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") # Create some black squares on top of which we will # place the instructions. blackmaker = CardMaker("blackmaker") blackmaker.setColor(0, 0, 0, 1) blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(render2d) blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85) titlecard = NodePath(blackmaker.generate()) titlecard.reparentTo(render2d) # Panda does its best to hide the differences between DirectX and # OpenGL. But there are a few differences that it cannot hide. # One such difference is that when OpenGL copies from a # visible window to a texture, it gets it right-side-up. When # DirectX does it, it gets it upside-down. There is nothing panda # can do to compensate except to expose a flag and let the # application programmer deal with it. You should only do this # in the rare event that you're copying from a visible window # to a texture. if (base.win.getGsg().getCopyTextureInverted()): print "Copy texture is inverted." self.bcard.setScale(1, 1, -1) self.fcard.setScale(1, 1, -1) # Put up the instructions title = OnscreenText(text="Panda3D: Tutorial - Motion Trails", style=1, fg=(1, 1, 1, 1), pos=(0, -0.95), scale=.07) instr0 = addInstructions(0.95, "Press ESC to exit") instr1 = addInstructions(0.90, "Press 1: Ghost effect") instr2 = addInstructions(0.85, "Press 2: PaintBrush effect") instr3 = addInstructions(0.80, "Press 3: Double Vision effect") instr4 = addInstructions(0.75, "Press 4: Wings of Blue effect") instr5 = addInstructions(0.70, "Press 5: Whirlpool effect") # enable the key events self.accept("escape", sys.exit, [0]) self.accept("1", self.chooseEffectGhost) self.accept("2", self.chooseEffectPaintBrush) self.accept("3", self.chooseEffectDoubleVision) self.accept("4", self.chooseEffectWingsOfBlue) self.accept("5", self.chooseEffectWhirlpool)
def __init__(self): # Create a texture into which we can copy the main window. # We set it to RTMTriggeredCopyTexture mode, which tells it that we # want it to copy the window contents into a texture every time we # call self.win.triggerCopy(). self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) self.win = GraphicsOutput() self.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) # Set the initial color to clear the texture to, before rendering it. # This is necessary because we don't clear the texture while rendering, # and otherwise the user might see garbled random data from GPU memory. self.tex.setClearColor((0, 0, 0, 1)) self.tex.clearImage() # Create another 2D camera. Tell it to render before the main camera. self.backcam = self.makeCamera2d(self.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) # Obtain two texture cards. One renders before the dragon, the other # after. self.bcard = self.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = self.win.getTextureCard() self.fcard.reparentTo(self.render2d) self.fcard.setTransparency(1) # Initialize one of the nice effects. self.chooseEffectGhost() # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") # Create some black squares on top of which we will # place the instructions. blackmaker = CardMaker("blackmaker") blackmaker.setColor(0, 0, 0, 1) blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(self.render2d) blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85) titlecard = NodePath(blackmaker.generate()) titlecard.reparentTo(self.render2d) # Panda does its best to hide the differences between DirectX and # OpenGL. But there are a few differences that it cannot hide. # One such difference is that when OpenGL copies from a # visible window to a texture, it gets it right-side-up. When # DirectX does it, it gets it upside-down. There is nothing panda # can do to compensate except to expose a flag and let the # application programmer deal with it. You should only do this # in the rare event that you're copying from a visible window # to a texture. if self.win.getGsg().getCopyTextureInverted(): print("Copy texture is inverted.") self.bcard.setScale(1, 1, -1) self.fcard.setScale(1, 1, -1) # Put up the instructions title = OnscreenText(text="Panda3D: Tutorial - Motion Trails", fg=(1, 1, 1, 1), parent=base.a2dBottomCenter, pos=(0, 0.1), scale=.08) self.accept("5", self.chooseEffectWhirlpool)
def placePlantOnTerrain(self, itemStr, itemCnt, Mode, typItemWidth, typItemHeight, trrHorzSc, trrVertSc, numTxtTypes, txtList, planFileName): # Billboarding plants crd = CardMaker('mycard') crd.setColor(0.5, 0.5, 0.5, 1) ll = Point3(-0.5 * typItemWidth, 0, 0) lr = Point3(0.5 * typItemWidth, 0, 0) ur = Point3(0.5 * typItemWidth, 0, typItemHeight) ul = Point3(-0.5 * typItemWidth, 0, typItemHeight) crd.setFrame(ll, lr, ur, ul) crd.setHasNormals(False) crd.setHasUvs(True) # generate/save/load locations try: plan_data_fp = open(planFileName, 'r') item_list = [] for line in plan_data_fp: toks = line.split(',') px = float(toks[0].strip(' ')) py = float(toks[1].strip(' ')) ang = float(toks[2].strip(' ')) dht = float(toks[3].strip(' ')) scl = float(toks[4].strip(' ')) idx = int(toks[5].strip(' ')) item_list.append((px, py, ang, dht, scl, idx)) plan_data_fp.close() print 'loaded ', itemStr, ' data file of size:', len(item_list) except IOError: # generate list and try to save item_list = [] for a in range(itemCnt): px = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) py = random.randrange(-self.trrHorzSc * 64, self.trrHorzSc * 64) ang = 180 * random.random() dht = 0.0 scl = 0.75 + 0.25 * (random.random() + random.random()) idx = random.randrange(0, numTxtTypes) item_list.append([px, py, ang, dht, scl, idx]) try: plan_data_fp = open(planFileName, 'w') for c in item_list: print >> plan_data_fp, c[0], ',', c[1], ',', c[2], ',', c[ 3], ',', c[4], ',', c[5] plan_data_fp.close() print 'saved ', itemStr, ' data of size: ', len(item_list) except IOError: print 'unable to store ', itemStr, ' data of size: ', len( item_list) # define each plant for c in item_list: px = c[0] py = c[1] ang = c[2] dht = c[3] scl = c[4] idx = c[5] if idx >= numTxtTypes: idx = 0 if Mode > 0: for b in range(Mode): crdNP = self.render.attachNewNode(crd.generate()) crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) crdNP.setTwoSided(True) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc + dht) crdNP.setHpr(ang + (180 / Mode) * b, 0, 0) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff() else: # set up item as defined crd.setUvRange(txtList[idx]) crdNP = self.render.attachNewNode(crd.generate()) crdNP.setBillboardAxis() crdNP.setTexture(txtList[idx]) crdNP.setScale(scl) ht = self.terrain.getElevation(px / trrHorzSc, py / trrHorzSc) crdNP.setPos(px, py, ht * trrVertSc) crdNP.setTransparency(TransparencyAttrib.MAlpha) crdNP.setLightOff()
class RaceGUI: GagPie = 0 gagRoot = 'phase_3.5/maps/inventory_' class RacerInfo: def __init__(self, face, mapSpot): self.curvetime = 0 self.maxlaphit = 0 self.face = face self.mapspot = mapSpot self.place = 1 self.enabled = True self.finished = False self.gag = None return def update(self, curvetime=None, maxlaphit=None, faceX=None, mapspotPt=None, place=None, finished=None): if self.enabled: if not curvetime == None: self.curvetime = curvetime if not maxlaphit == None: self.maxlaphit = maxlaphit if not faceX == None: self.face.setX(faceX) if not mapspotPt == None: self.mapspot.setPos(mapspotPt) if not place == None: self.place = place if not finished == None: self.finished = finished return def disable(self): self.enabled = False if not self.finished: self.face.hide() self.mapspot.hide() def enable(self): self.enabled = True self.face.show() self.mapspot.show() def __init__(self, distRace): self.race = distRace self.timerEnabled = False self.maxLapHit = 0 self.photoFinish = False toonInteriorTextures = loader.loadModel( 'phase_3.5/models/modules/toon_interior_textures') invTextures = loader.loadModel('phase_3.5/models/gui/inventory_icons') racingTextures = loader.loadModel( 'phase_6/models/karting/racing_textures') self.gagTextures = [ toonInteriorTextures.find('**/couch'), invTextures.find('**/inventory_bannana_peel'), racingTextures.find('**/boost_arrow'), invTextures.find('**/inventory_anvil'), invTextures.find('**/inventory_creampie') ] self.gagTextures[1].setScale(7.5) self.gagTextures[3].setScale(7.5) self.gagTextures[4].setScale(7.5) self.cardMaker = CardMaker('card') self.racerDict = {} self.render2dRoot = render2d.attachNewNode('RaceGuiRender2dRoot') self.render2dRoot.setDepthWrite(1) self.directObjList = [] self.aspect2dRoot = aspect2d.attachNewNode('RaceGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.raceModeRoot = self.aspect2dRoot.attachNewNode('RaceModeRoot') gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=1.05, text=TTLocalizer.KartRace_Leave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(-0.99, 0, 0.925), command=self.race.leaveRace) self.closeButton.reparentTo(self.aspect2dRoot) self.directObjList.append(self.closeButton) self.raceTimeDelta = 0 self.raceModeReady = False self.resultModeReady = False self.gagCycleSound = base.loader.loadSfx( 'phase_3.5/audio/sfx/tick_counter.ogg') if hasattr(self.gagCycleSound, 'setPlayRate'): self.gagCycleSound.setPlayRate(0.2) self.gagCycleSound.setLoop(1) self.gagAcquireSound = base.loader.loadSfx( 'phase_6/audio/sfx/SZ_MM_gliss.ogg') self.disable() return def initRaceMode(self): self.mapScene = base.a2dTopRight.attachNewNode('MapScene') self.mapScene.setPos(-0.2, 0, -0.2) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in range(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel( relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.5), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel( relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel( relief=None, pos=(-0.22, 0, -0.2), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence( self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4( 1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4( 1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * ( 1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in range(self.race.lapCount): minLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel( relief=None, pos=(interpolateFacePos( (2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame( parent=base.a2dBottomLeft, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(0.2, 0, 0.55)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in range(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos( self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return def initResultMode(self): self.endPanel = RaceEndPanel(len(self.race.avIds), self.race) self.endPanel.reparentTo(self.aspect2dRoot) self.directObjList.append(self.endPanel) self.resultModeReady = True self.disable() def showGag(self, gagIndex): if gagIndex < len(self.gagTextures): for gag in self.gagTextures: gag.hide() self.gagTextures[gagIndex].show() def updateGag(self, gagIndex): if self.gag: if hasattr(self, 'gagCycleInterval'): self.gagCycleInterval.finish() del self.gagCycleInterval self.gag.setHpr(0, 0, 0) self.showGag(gagIndex) if gagIndex == 0: self.gag.hide() else: self.gag.show() self.gagAcquireSound.play() self.gagAcquireInterval = LerpHprInterval(self.gag, duration=0.5, blendType='easeOut', startHpr=Point3( 0, -90, 0), hpr=Point3(0, 0, 0)) self.gagAcquireInterval.start() def waitingOnGag(self, cycleTime): if self.gag: numTextures = len(self.gagTextures) startOffset = random.choice(range(0, numTextures)) self.gag.show() self.gagCycleInterval = Parallel( LerpFunc(self.showNextGag, fromData=startOffset, toData=numTextures * 2 * cycleTime + startOffset, blendType='easeOut', duration=cycleTime), LerpHprInterval(self.gag, duration=cycleTime, hpr=Point3( 0, 180 * numTextures * 2 * cycleTime - 90, 0), blendType='easeOut', startHpr=Point3(0, 0, 0)), SoundInterval(self.gagCycleSound, loop=1, duration=cycleTime, startTime=0), name='gagCycleInterval') self.gagCycleInterval.start() def showNextGag(self, t): if self.gag: currGagIndex = int(t % (len(self.gagTextures) - 1)) + 1 self.showGag(currGagIndex) def enableSpeedometer(self): self.race.localKart.showSpeedometer() def disableSpeedometer(self): self.race.localKart.hideSpeedometer() def disableRaceMode(self): self.disableSpeedometer() self.render2dRoot.hide() self.raceModeRoot.hide() for x in self.timeLabels: for y in x: y.hide() self.setTimerEnabled(False) def disableResultMode(self): self.endPanel.disable() def disable(self): self.closeButton.hide() taskMgr.removeTasksMatching('clearRaceEndPanel') if self.raceModeReady: self.disableRaceMode() if self.resultModeReady: self.disableResultMode() def enableRaceMode(self): self.enableSpeedometer() self.render2dRoot.show() self.raceModeRoot.show() self.maxLapHit = min(self.maxLapHit, self.race.lapCount - 1) for x in range(self.maxLapHit + 1): for y in self.timeLabels[x]: y.configure(text_font=ToontownGlobals.getSignFont()) y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) def enableResultMode(self): self.endPanel.enable() if not self.race.circuitLoop: taskMgr.doMethodLater(180, self.endPanel.closeButtonPressed, 'clearRaceEndPanel', extraArgs=[]) def destroy(self): self.disable() if hasattr(self, 'wrongWaySeq'): self.wrongWaySeq.finish() self.wrongWaySeq = None taskMgr.removeTasksMatching('removeIt') taskMgr.removeTasksMatching('removeCam*') taskMgr.removeTasksMatching('clearRaceEndPanel') for obj in self.directObjList: obj.destroy() if hasattr(self, 'mapScene'): self.mapScene.removeNode() self.mapScene = None self.aspect2dRoot.removeNode() self.aspect2dRoot = None self.raceModeRoot.removeNode() self.raceModeRoot = None self.render2dRoot.removeNode() self.render2dRoot = None self.closeButton = None self.gag = None self.lapLabel = None self.timeLabels = None self.placeLabelStr = None self.placeLabelNum = None self.photoFinishLabel = None self.mapScene = None self.race = None return def setSpotAsymptotic(self, diffT, spot): p = (-1, 1)[(diffT > 0)] * (1 - 1 / pow(abs(diffT) / self.cutoff + 1, 2)) spot.setX(p) def setSpotRaceLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t / self.lapCount)) def setSpotLapLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t - int(t))) def update(self, time): placeSorter = [] placeCount = 0 for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = clampScalar(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[(self.maxLapHit - 1)]: y.configure( text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure( text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime( ) - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice[ 'text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice[ 'text'] = TTLocalizer.KartRace_LapText % str( self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str( clampScalar(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str( self.race.lapCount) suffix = { 1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix } placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[ 0] - localRacer.face.getX() < nearDiff: for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX( ) >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str( self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[ localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() else: if not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish() def updateRacerInfo(self, avId, curvetime=None, maxlaphit=None): if avId in self.racerDict.keys(): self.racerDict[avId].update(curvetime=curvetime, maxlaphit=maxlaphit) def racerEntered(self, avId): toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.race.kartMap.get(avId, None), None) if not toon or not kart: return if kart.getBodyColor() == InvalidEntry: bodyColor = getDefaultColor() else: bodyColor = getAccessory(kart.getBodyColor()) headframe = RaceHeadFrame(av=toon, color=bodyColor) eyes = headframe.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) headframe.configure(geom_scale=(0.5, 0.5, 0.5)) headframe.setZ(self.faceStartPos[2]) headframe.setDepthWrite(True) headframe.setDepthTest(True) headframe.reparentTo(self.raceModeRoot) self.directObjList.append(headframe) mapspot = loader.loadModel('phase_6/models/karting/race_mapspot') mapspot.setColor(bodyColor) mapspot.reparentTo(self.mapLines) mapspot.setHpr(self.mapScene, 0, 0, 0) self.racerDict[avId] = self.RacerInfo(headframe, mapspot) for key, i in zip(self.racerDict.keys(), range(len(self.racerDict.keys()))): face = self.racerDict[key].face mapspot = self.racerDict[key].mapspot face.setX(self.faceStartPos[0]) face.setY(-1 - 5 * (i + 1)) face.setScale(0.15) mapspot.getChild(0).setY((-5 - 5 * (i + 1)) * 1000) mapspot.setScale(self.mapScene, 0.15) mapspot.setPos(self.race.startingPos[0][0]) if key == localAvatar.doId: face.setY(-1) face.setScale(face.getScale() * 1.25) mapspot.getChild(0).setY(-5000) mapspot.setScale(mapspot.getScale() * 1.25) self.face = face self.mapspot = mapspot return def racerLeft(self, avId, unexpected=False): racer = self.racerDict.get(avId, None) if racer: racer.disable() return def racerFinished(self, avId, trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): racer = self.racerDict.get(avId, None) if racer: racer.update(finished=True) racer.disable() self.endPanel.displayRacer(place, entryFee, qualify, winnings, trackId, bonus, trophies, racer.face, base.cr.doId2do[avId].getName(), totalTime, circuitPoints, circuitTime) if racer.face in self.directObjList: self.directObjList.remove(racer.face) if avId == localAvatar.doId: self.disableRaceMode() self.enableResultMode() self.endPanel.startWinningsPanel(entryFee, winnings, trackId, bonus, trophies) return def racerFinishedCircuit(self, avId, place, entryFee, winnings, bonus, trophies): racer = self.racerDict.get(avId, None) if racer: newTotalTickets = winnings + entryFee + bonus self.endPanel.updateWinnings(place, newTotalTickets) if avId == localAvatar.doId: self.endPanel.updateWinningsFromCircuit( place, entryFee, winnings, bonus, trophies) return def circuitFinished(self, placeFixup): self.endPanel.circuitFinished(placeFixup) def setTimerEnabled(self, enabled): self.timerEnabled = enabled
def generateWater(self, style): print "Generate Water:", self.waterXMin, self.waterXMax, self.waterYMin, self.waterYMax '''Generates water style 0: blue card style 1: reflective card style 2: reflective card with shaders ''' self.waterHeight = 22.0 if self.water: self.water.removeNode() if style is 0: cm = CardMaker("water") #cm.setFrame(-1, 1, -1, 1) cm.setFrame(self.waterXMin, self.waterXMax, self.waterYMin, self.waterYMax) cm.setColor(0, 0, 1, 0.9) self.water = render.attachNewNode(cm.generate()) if self.waterYMax > self.waterXMax: size = self.waterYMax else: size = self.waterXMax self.water.lookAt(0, 0, -1) self.water.setZ(self.waterHeight) messenger.send('makePickable', [self.water]) elif style is 1: # From Prosoft's super awesome terrain demo cm = CardMaker("water") #cm.setFrame(-1, 1, -1, 1) cm.setFrame(self.waterXMin, self.waterXMax, self.waterYMin, self.waterYMax) self.water = render.attachNewNode(cm.generate()) if self.waterYMax > self.waterXMax: size = self.waterYMax else: size = self.waterXMax #self.water.setScale(size) self.water.lookAt(0, 0, -1) self.water.setZ(self.waterHeight) self.water.setShaderOff(1) self.water.setLightOff(1) self.water.setAlphaScale(0.5) self.water.setTransparency(TransparencyAttrib.MAlpha) wbuffer = base.win.makeTextureBuffer("water", 512, 512) wbuffer.setClearColorActive(True) wbuffer.setClearColor(base.win.getClearColor()) self.wcamera = base.makeCamera(wbuffer) self.wcamera.reparentTo(render) self.wcamera.node().setLens(base.camLens) self.wcamera.node().setCameraMask(BitMask32.bit(1)) self.water.hide(BitMask32.bit(1)) wtexture = wbuffer.getTexture() wtexture.setWrapU(Texture.WMClamp) wtexture.setWrapV(Texture.WMClamp) wtexture.setMinfilter(Texture.FTLinearMipmapLinear) self.wplane = Plane(Vec3(0, 0, 1), Point3(0, 0, self.water.getZ())) wplanenp = render.attachNewNode(PlaneNode("water", self.wplane)) tmpnp = NodePath("StateInitializer") tmpnp.setClipPlane(wplanenp) tmpnp.setAttrib(CullFaceAttrib.makeReverse()) self.wcamera.node().setInitialState(tmpnp.getState()) self.water.projectTexture(TextureStage("reflection"), wtexture, self.wcamera) messenger.send('makePickable', [self.water]) elif style is 2: # From Clcheung just as super awesome demomaster self.water_level = Vec4(0.0, 0.0, self.waterHeight, 1.0) self.water = water.WaterNode(self.waterXMin, self.waterYMin, self.waterXMax, self.waterYMax, self.water_level.getZ()) self.water.setStandardControl() self.water.changeParams(None) wl=self.water_level wl.setZ(wl.getZ()-0.05) #root.setShaderInput('waterlevel', self.water_level) render.setShaderInput('time', 0) messenger.send('makePickable', [self.water.waterNP])
def __init__(self, parent=None, pos=(0, 0, 0), fading=False, fading_position_offset=(0, 0, 0), fading_duration=0.5, backgroundImage=None, backgroundColor=None, enableMask=False, noFocus=False, shownFunc=None, hiddenFunc=None, funcExtraArgs=[], sort=None): '''if fading enabled, it will apply a fading effect on show()&hide() Important Attributes: enableMask: This creates a big transparent plane (DirectButton) off screen so the directGui below won't be clicked (However due to this trick we won't be able to accept mouse events (I have paid back 'mouse3' by self.__maskClick)) noFocus: if it is true, it doesn't need SogalBase to manage its focus state (it will not affect other Sogalforms' focus state ''' self.__fading = fading self.__fadingPositionOffset = fading_position_offset self.__fadingDuration = fading_duration self.__originPos = pos self.__currentInterval = None self.__maskEnabled = enableMask self.__noFocus = noFocus self.__shownFunc = shownFunc self.__hiddenFunc = hiddenFunc self.__eventExtraArgs = funcExtraArgs self.__mask = None if self.__maskEnabled: self.__mask = DialogMask() #self.__mask = DirectButton(parent = aspect2d, frameColor =(1,1,1,0.1), relief = DGG.FLAT,commandButtons = [DGG.RMB],command = self.__maskClick) self.__mask.hide() self.__backgroundImage = backgroundImage self.__backgroundColor = backgroundColor self.__bgPath = None self.__imagePath = None self.__hidden = True NodePath.__init__(self, self.__class__.__name__) parent = parent or aspect2d if sort: self.reparentTo(parent, sort=sort) else: self.reparentTo(parent) self.setPos(pos) if self.__backgroundColor: self.__bgPath = NodePath('bgPath') self.__bgPath.setTransparency(TransparencyAttrib.MAlpha) cm = CardMaker('cm') cm.setFrameFullscreenQuad() cm.setColor(self.__backgroundColor) self.__bgPath.attachNewNode(cm.generate()) self.__bgPath.reparentTo(aspect2d, self.getSort()) self.__bgPath.hide() #TODO: backgroundImage self.setTransparency(TransparencyAttrib.MAlpha) self.accept('window-event', self.windowResize) self.windowResize(None) NodePath.hide(self)
class FancyLoadingScreen(DirectObject.DirectObject): notify = DirectNotifyGlobal.directNotify.newCategory('LoadingScreen') def __init__(self, parent): DirectObject.DirectObject.__init__(self) self.debugMode = config.GetInt('loading-screen') == 2 self.parent = parent self.state = False self.currScreenshot = None self.snapshot = None self.snapshotFrame = None self.snapshotFrameBasic = None self.currentTime = 0 self.analyzeMode = False self.loadScale = 1.0 self.unmappedTicks = [] self.stepInfo = { } self.accept(base.win.getWindowEvent(), self.adjustSize) self.accept('tick', self.tick) self.currStage = 'unmapped' self.stagePercent = 0 self.numObjects = 0 self.currPercent = 0.0 self.line = LineSegs() self.line.setColor((0, 0, 0, 1)) self.line.setThickness(1) self.stageLabel = None self.currNum = 0 self.overallPercent = 0 self.lastPercent = 0 self.topLock = aspect2dp.attachNewNode('topShift') self.root = self.topLock.attachNewNode('loadingScreenRoot') self.root.setZ(-1) self.root.stash() self.model = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen.bam') self.model.setP(90) self.model.reparentTo(self.root) cm = CardMaker('backdrop') cm.setFrame(-10, 10, -10, 10) if self.debugMode: self.backdrop = self.root.attachNewNode(cm.generate()) self.backdrop.setX(-1.5) self.backdrop.setZ(-1) self.backdrop.setScale(4) self.backdrop.setColor(0.5, 0.5, 0.5, 1) cm = CardMaker('loadingBarBase') cm.setFrame(-0.90000000000000002, 0.90000000000000002, 0.10000000000000001, 0.5) self.loadingBarBacking = self.root.attachNewNode(cm.generate()) self.loadingBarRoot = self.root.attachNewNode('loadingBarRoot') cm.setName('analysisBarBase') cm.setFrame(-0.90000000000000002, 0.90000000000000002, -0.5, -0.10000000000000001) self.analysisBar = self.root.attachNewNode(cm.generate()) self.analysisBarRoot = self.root.attachNewNode('analysisBarRoot') self.analysisBar.hide() self.analysisButtons = [] self.enterToContinue = DirectLabel(parent = self.root, text = 'Press Shift To Continue', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.90000000000000002), text_align = TextNode.ACenter) self.enterToContinue.hide() self.stageLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (-1.25, 0, 0.75), text_align = TextNode.ALeft, textMayChange = 1) self.tickLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0.75, 0, 0.75), textMayChange = 1) self.overallLabel = DirectLabel(parent = self.root, text = '', relief = None, text_scale = 0.10000000000000001, pos = (0, 0, -0.75), textMayChange = 1) else: self.backdrop = loader.loadModel('models/gui/pir_m_gui_gen_loadScreen') self.backdrop.reparentTo(self.root) bg = self.backdrop.find('**/expandable_bg') bg.setScale(1000, 1, 1000) bg.flattenStrong() self.backdrop.find('**/loadbar_grey').setColorScale(0.14999999999999999, 0.14999999999999999, 0.14999999999999999, 0.10000000000000001) self.loadingBar = self.backdrop.find('**/loadbar') self.loadingBar.setColorScale(0.20000000000000001, 0.59999999999999998, 0.5, 1) self.loadingPlank = NodePathCollection() self.loadingPlank.addPath(self.backdrop.find('**/plank_loading_bar')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar_frame')) self.loadingPlank.addPath(self.backdrop.find('**/loadbar_grey')) self.titlePlank = self.backdrop.find('**/plank_title') self.percentLabel = DirectLabel(text = '0%', parent = self.root, relief = None, text_font = PiratesGlobals.getPirateFont(), text_fg = PiratesGuiGlobals.TextFG2, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = 0.031, pos = (0, 0, -0.44450000000000001), textMayChange = 1) self.loadingPlank.addPath(self.percentLabel) self.screenshot = self.backdrop.find('**/screenshot') copyGeom = self.loadingBar.find('**/+GeomNode').node().getGeom(0) format = copyGeom.getVertexData().getFormat() primitive = copyGeom.getPrimitive(0) data = GeomVertexData(self.screenshot.node().getGeom(0).getVertexData()) data.setFormat(format) writer = GeomVertexWriter(data, 'texcoord') writer.setData2f(0, 0) writer.setData2f(1, 0) writer.setData2f(1, 1) writer.setData2f(0, 1) geom = Geom(data) geom.addPrimitive(primitive) self.screenshot.node().removeGeom(0) self.screenshot.node().addGeom(geom) self.titlePlankMiddle = self.backdrop.find('**/plank_title_middle_box') self.titlePlankLeft = self.backdrop.find('**/plank_title_left') self.titlePlankRight = self.backdrop.find('**/plank_title_right') self.loadingBarColors = [ (((i % 10) / 10.0 + 0.5) / 2.0, ((i % 100) / 10 / 10.0 + 0.5) / 2.0, (i / 100 / 10.0 + 0.5) / 2.0, 1) for i in range(1000) ] random.shuffle(self.loadingBarColors) self.lastUpdateTime = globalClock.getRealTime() self.locationLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.69999999999999996, text_align = TextNode.ACenter, pos = (0.0, 0.0, 0.51500000000000001), textMayChange = 1) self.locationText = None self.hintLabel = DirectLabel(parent = self.root, relief = None, text = '', text_font = PiratesGlobals.getPirateOutlineFont(), text_fg = PiratesGuiGlobals.TextFG1, text_shadow = PiratesGuiGlobals.TextShadow, text_scale = PiratesGuiGlobals.TextScaleTitleJumbo * 0.5, text_align = TextNode.ACenter, pos = (0.0, 0.0, -0.62), text_wordwrap = 30, textMayChange = 1) self.hintText = None self.adImage = None self.allowLiveFlatten = ConfigVariableBool('allow-live-flatten') self.title_art = [] self.tempVolume = [] self.adjustSize(base.win) gsg = base.win.getGsg() if gsg: self.root.prepareScene(gsg) def startLoading(self, expectedLoadScale): if not self.debugMode: self.loadingBar.setSx(0) self.loadScale = float(expectedLoadScale) self.currStage = 'unmapped' self.stagePercent = 0 self.numObjects = 0 self.currPercent = 0.0 self.loadingStart = globalClock.getRealTime() self.currNum = 0 self.overallPercent = 0 self.lastPercent = 0 self.stepNum = 0 if self.debugMode: self.overallLabel['text'] = '0.0' self.stageLabel['text'] = self.currStage self.update() def beginStep(self, stageName, amt = 0, percent = 0.001): if not self.state: return None if self.currStage != 'unmapped' and stageName != self.currStage: if __dev__ and self.debugMode: self.notify.error('step %s not finished when step %s was started!' % (self.currStage, stageName)) else: self.notify.warning('step %s not finished when step %s was started!' % (self.currStage, stageName)) return None self.stepNum += 1 if self.debugMode: stageColor = self.loadingBarColors[self.stepNum] self.stepInfo[stageName] = [ globalClock.getRealTime() - self.loadingStart, 0.0, stageColor, [], self.lastPercent + self.stagePercent, percent, amt] self.stepCard = CardMaker('step-%s' % stageName) self.stepCard.setColor(stageColor) self.currPoly = NodePath('empty') self.stageLabel['text'] = stageName self.tickLabel['text'] = '0.0' self.currPercent = 0.0 self.overallPercent = min(100.0 * self.loadScale, self.lastPercent + self.stagePercent) self.lastPercent = self.overallPercent self.currStage = stageName self.stagePercent = percent self.numObjects = amt self.currNum = 0 base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() def endStep(self, stageName): if self.currStage == 'unmapped': self.notify.warning('step %s was started before loading screen was enabled' % stageName) return None if stageName != self.currStage: if __dev__ and self.debugMode: self.notify.error('step %s was active while step %s was trying to end!' % (self.currStage, stageName)) else: return None self.tick() if self.debugMode: stageInfo = self.stepInfo[self.currStage] stageInfo[1] = globalClock.getRealTime() - self.loadingStart - stageInfo[0] self.currPoly.detachNode() self.stepCard.setFrame((self.lastPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, ((self.lastPercent + self.stagePercent) / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, 0.10000000000000001, 0.5) self.loadingBarRoot.attachNewNode(self.stepCard.generate()) self.stageLabel['text'] = 'unmapped' self.currStage = 'unmapped' self.currPercent = 0.0 def tick(self): if self.state == False or self.analyzeMode: return None if self.debugMode: if self.currStage == 'unmapped': self.unmappedTicks.append(globalClock.getRealTime() - self.loadingStart) else: self.stepInfo[self.currStage][3].append(globalClock.getRealTime() - self.loadingStart) self.currNum += 1 self.currPercent = min(1.0, self.currNum / float(self.numObjects + 1)) self.overallPercent = min(100.0 * self.loadScale, self.lastPercent + self.currPercent * self.stagePercent) self.update() def destroy(self): taskMgr.remove('updateLoadingScreen') for part in (self.model, self.snapshot): if part is not None: tex = part.findTexture('*') if tex: tex.releaseAll() part.removeNode() self.model = None self.snapshot = None if self.snapshotFrame: self.snapshotFrame.destroy() if self.snapshotFrameBasic: self.snapshotFrameBasic.destroy() if self.locationLabel: self.locationLabel.destroy() if self.hintLabel: self.hintLabel.destroy() if self.debugMode: self.stageLabel.destroy() self.tickLabel.destroy() self.overallLabel.destroy() self.enterToContinue.destroy() self.stageLabel = None self.tickLabel = None self.overallLabel = None self.enterToContinue = None self.ignoreAll() def showTitleFrame(self): if base.config.GetBool('no-loading-screen', 0): return None for part in self.title_art: part.show() def hideTitleFrame(self): for part in self.title_art: part.hide() def show(self, waitForLocation = False, disableSfx = True, expectedLoadScale = 1.0): if self.state and base.config.GetBool('no-loading-screen', 0) or not (self.locationLabel): return None render.hide() render2d.hide() render2dp.hide() if not self.debugMode: self.loadingPlank.hide() self.root.unstash() self.root.showThrough() self.state = True gsg = base.win.getGsg() if gsg: gsg.setIncompleteRender(False) base.setTaskChainNetNonthreaded() self.allowLiveFlatten.setValue(1) self.startLoading(expectedLoadScale) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() base.refreshAds() taskMgr.add(self.update, 'updateLoadingScreen', priority = -100) if base.sfxManagerList and disableSfx: index = 0 while index < len(base.sfxManagerList): sfx_manager = base.sfxManagerList[index] sfx_manager.setVolume(0.0) index += 1 if base.appRunner: base.appRunner.notifyRequest('onLoadingMessagesStart') self._FancyLoadingScreen__setLocationText(self.locationText) self._FancyLoadingScreen__setHintText(self.hintText) if not waitForLocation: screenshot = random.choice(tutorialShots_MoveAim) self._FancyLoadingScreen__setLoadingArt(screenshot) def showHint(self, destId = None, ocean = False): if base.config.GetBool('no-loading-screen', 0) or not (self.locationLabel): return None if ocean: hint = getOceanHint() elif hasattr(base, 'localAvatar'): totalReputation = 0 level = base.localAvatar.getLevel() if totalReputation: hint = getHint(destId, level) else: hint = getHint(destId) else: hint = getHint() shipPVPIslands = [ '1196970035.53sdnaik', '1196970080.56sdnaik'] if (destId in shipPVPIslands or ocean) and base.localAvatar.getCurrentIsland() in shipPVPIslands: hint = getPrivateeringHint() if self.parent and base.localAvatar.style.getTutorial() == PiratesGlobals.TUT_MET_JOLLY_ROGER: hint = '%s: %s' % (PLocalizer.LoadingScreen_Hint, PLocalizer.GeneralTip7) self._FancyLoadingScreen__setHintText(hint) def update(self, task = None): if not (self.state) or self.analyzeMode: return Task.cont realTime = globalClock.getRealTime() if realTime - self.lastUpdateTime < 0.10000000000000001: return Task.cont self.currentTime += min(10, (realTime - self.lastUpdateTime) * 250) self.lastUpdateTime = realTime if self.debugMode: self.overallLabel['text'] = '%3.1f' % (self.overallPercent / self.loadScale) self.tickLabel['text'] = '%3.1f' % (self.currPercent * 100.0) else: self.percentLabel['text'] = '%d%%' % (self.overallPercent / self.loadScale) if self.currStage != 'unmapped': if self.debugMode: self.currPoly.detachNode() self.stepCard.setFrame((self.lastPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, (self.overallPercent / self.loadScale) * 0.017999999999999999 - 0.90000000000000002, 0.20000000000000001, 0.40000000000000002) self.currPoly = self.loadingBarRoot.attachNewNode(self.stepCard.generate()) if not self.debugMode: self.loadingBar.setSx((self.overallPercent / self.loadScale) * 3.3999999999999999) if self.overallPercent > 0: self.loadingPlank.show() base.eventMgr.doEvents() base.graphicsEngine.renderFrame() return Task.cont def hide(self, reallyHide = not (config.GetInt('loading-screen', 0) == 2)): if not self.state: return None if not reallyHide: if not self.analyzeMode: self.loadingEnd = globalClock.getRealTime() self.accept('shift', self.hide, extraArgs = [ 1]) self.enterToContinue.show() self.generateAnalysis() return None self.cleanupLoadingScreen() if self.debugMode: self.enterToContinue.hide() self.ignore('shift') self.root.hide() self.root.stash() render2d.show() render2dp.show() render.show() base.graphicsEngine.renderFrame() self.state = False self.currentTime = 0 self.locationText = None self.hintText = None self.currScreenshot = None gsg = base.win.getGsg() if gsg: gsg.setIncompleteRender(True) render.prepareScene(gsg) render2d.prepareScene(gsg) taskMgr.remove('updateLoadingScreen') self.allowLiveFlatten.clearValue() base.setTaskChainNetThreaded() if base.sfxManagerList: index = 0 while index < len(base.sfxManagerList): sfx_manager = base.sfxManagerList[index] sfx_manager.setVolume(base.options.sound_volume) index += 1 messenger.send('texture_state_changed') if base.appRunner: base.appRunner.notifyRequest('onLoadingMessagesStop') def showTarget(self, targetId = None, ocean = False, jail = False, pickapirate = False, exit = False, potionCrafting = False, benchRepair = False, shipRepair = False, cannonDefense = False, fishing = False): if base.config.GetBool('no-loading-screen', 0): return None if pickapirate: screenshot = screenShot_EnterGame elif exit: screenshot = screenShot_ExitGame elif ocean: screenshot = screenShot_Dinghy elif jail: screenshot = screenShot_Jail elif potionCrafting: screenshot = screenShot_Potions elif benchRepair: screenshot = screenShot_BenchRepair elif shipRepair: screenshot = screenShot_ShipRepair elif cannonDefense: screenshot = screenShot_CannonDefense elif fishing: screenshot = screenShot_Fishing elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_GOT_CUTLASS: screenshot = screenShot_Weapon elif base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_MET_JOLLY_ROGER: screenshot = screenShot_Cutlass elif base.cr.newsManager and base.cr.newsManager.getHoliday(21): screenshot = screenShots_WinterHolidayLocations.get(targetId) if not screenshot: screenshot = screenShots_Locations.get(targetId) else: screenshot = screenShots_Locations.get(targetId) if not screenshot: if areaType_Jungles.has_key(targetId): screenshot = random.choice(screenShots_Jungles) elif areaType_Swamps.has_key(targetId): screenshot = random.choice(screenShots_Swamps) elif areaType_Caves.has_key(targetId): screenshot = random.choice(screenShots_Caves) else: island = getParentIsland(targetId) screenshot = screenShots_Locations.get(island, [ random.choice(screenShots)])[0] if isinstance(screenshot, list): screenshot = random.choice(screenshot) self._FancyLoadingScreen__setLoadingArt(screenshot) if pickapirate: targetName = PLocalizer.LoadingScreen_PickAPirate elif exit: targetName = None elif ocean: targetName = PLocalizer.LoadingScreen_Ocean elif jail: targetName = PLocalizer.LoadingScreen_Jail else: targetName = PLocalizer.LocationNames.get(targetId) base.setLocationCode('Loading: %s' % targetName) if targetName is None: return None if len(targetName): self._FancyLoadingScreen__setLocationText(targetName) def _FancyLoadingScreen__setLoadingArt(self, screenshot): if self.currScreenshot: return None if self.parent and hasattr(base, 'localAvatar') and base.localAvatar.style.getTutorial() < PiratesGlobals.TUT_MET_JOLLY_ROGER and screenshot not in tutorialShots: screenshot = random.choice(tutorialShots) try: self.currScreenshot = loader.loadModel(screenshot).findAllTextures()[0] except: self.currScreenshot = loader.loadModel(random.choice(screenshot)).findAllTextures()[0] if not self.debugMode: self.screenshot.setTexture(self.currScreenshot) def _FancyLoadingScreen__setLocationText(self, locationText): if self.debugMode: return None self.locationText = locationText if not self.locationText: self.locationText = '' self.titlePlank.hide() if len(self.locationText) > 12: scaleFactor = len(self.locationText) / 12.0 self.titlePlankMiddle.setSx(scaleFactor) self.titlePlankRight.setX(0.215 * scaleFactor - 0.215) self.titlePlankLeft.setX(-1 * (0.215 * scaleFactor - 0.215)) else: self.titlePlankMiddle.setSx(1) self.titlePlankRight.setX(0) self.titlePlankLeft.setX(0) self.locationLabel['text'] = self.locationText if self._FancyLoadingScreen__isVisible() and len(self.locationText): self.locationLabel.show() self.titlePlank.show() else: self.locationLabel.hide() self.titlePlank.hide() launcher.setValue('gameLocation', self.locationText) def _FancyLoadingScreen__setHintText(self, hintText): self.hintText = hintText if not self.hintText: self.hintText = '' self.hintLabel['text'] = self.hintText if self._FancyLoadingScreen__isVisible(): self.hintLabel.show() def _FancyLoadingScreen__isVisible(self): return self.state def scheduleHide(self, function): base.cr.queueAllInterestsCompleteEvent() self.acceptOnce(function, self.interestComplete) def interestComplete(self): self.endStep('scheduleHide') self.hide() def _FancyLoadingScreen__setAdArt(self): return None imageFrame = self.model.find('**/frame') randomImageNumber = random.randint(0, len(screenShots) - 1) imageFileName = screenShots[randomImageNumber] self.adImage = loader.loadModel(imageFileName) self.adImage.reparentTo(imageFrame) self.adImage.setScale(2.1499999999999999 * 5, 1, 1.2 * 5) self.adImage.setPos(0, 0, 2.2999999999999998) self.adImage.setBin('fixed', 1) if randomImageNumber == 0: urlToGet = 'http://log.go.com/log?srvc=dis&guid=951C36F8-3ACD-4EB2-9F02-8E8A0A217AF5&drop=0&addata=3232:64675:408091:64675&a=0' self.httpSession = HTTPClient() self.nonBlockHTTP = self.httpSession.makeChannel(False) self.nonBlockHTTP.beginGetDocument(DocumentSpec(urlToGet)) instanceMarker = 'FunnelLoggingRequest-%s' % str(random.randint(1, 1000)) self.startCheckingAsyncRequest(instanceMarker) def startCheckingAsyncRequest(self, name): taskMgr.remove(name) taskMgr.doMethodLater(0.5, self.pollAdTask, name) def pollAdTask(self, task): result = self.nonBlockHTTP.run() if result == 0: self.stopCheckingAdTask(task) else: return Task.again def stopCheckingAdTask(self, name): taskMgr.remove(name) def cleanupLoadingScreen(self): if self.debugMode: self.loadingBarRoot.removeChildren() self.cleanupAnalysis() self.stepInfo = { } self.unmappedTicks = [] def showInfo(self, stepName, pos): self.stageLabel['text'] = stepName info = self.stepInfo[stepName] self.tickLabel['text'] = '%s ticks(%s)' % (len(info[3]), info[6]) self.overallLabel['text'] = '%3.2f seconds (%d%%)' % (info[1], 100 * info[1] / (self.loadingEnd - self.loadingStart)) def generateAnalysis(self): if self.analyzeMode: self.cleanupAnalysis() self.analyzeMode = True cm = CardMaker('cm') self.analysisBar.show() loadingTime = self.loadingEnd - self.loadingStart for stepName in self.stepInfo: (startTime, duration, color, ticks, startPercent, percent, expectedTicks) = self.stepInfo[stepName] cm.setName(stepName) cm.setColor(color) cm.setFrame((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001) self.analysisBarRoot.attachNewNode(cm.generate()) button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startTime / loadingTime) * 1.8 - 0.90000000000000002, ((startTime + duration) / loadingTime) * 1.8 - 0.90000000000000002, -0.5, -0.10000000000000001)) button.bind(DGG.ENTER, self.showInfo, extraArgs = [ stepName]) self.analysisButtons.append(button) button = DirectFrame(parent = self.analysisBarRoot, geom = NodePath('empty'), image = NodePath('empty'), state = DGG.NORMAL, relief = None, frameSize = ((startPercent / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, ((startPercent + percent) / self.loadScale / 100.0) * 1.8 - 0.90000000000000002, 0.10000000000000001, 0.5)) button.bind(DGG.ENTER, self.showInfo, extraArgs = [ stepName]) self.analysisButtons.append(button) for tick in ticks: self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5)) self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004)) for tick in self.unmappedTicks: self.line.moveTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.5)) self.line.drawTo(VBase3((tick / loadingTime) * 1.8 - 0.90000000000000002, 0, -0.55000000000000004)) self.analysisSegs = self.analysisBarRoot.attachNewNode(self.line.create()) def cleanupAnalysis(self): for button in self.analysisButtons: button.destroy() self.analysisButtons = [] self.analysisBarRoot.removeChildren() self.analysisBar.hide() self.analyzeMode = False self.analysisSegs = None def adjustSize(self, window): x = max(1, window.getXSize()) y = max(1, window.getYSize()) minSz = min(x, y) aspect = float(x) / y if x > y: self.topLock.setZ(1) else: self.topLock.setZ(float(y) / x) if minSz > IDEALX: self.topLock.setScale(IDEALX / float(x)) elif minSz > IDEALY: self.topLock.setScale(IDEALY / float(y)) else: self.topLock.setScale(1.0)
class NodeEditor(DirectObject): def __init__(self, parent, customNodeMap={}, customExporterMap={}): DirectObject.__init__(self) fn = Filename.fromOsSpecific(os.path.dirname(__file__)) fn.makeTrueCase() self.icon_dir = str(fn) + "/" loadPrcFileData("", f"model-path {self.icon_dir}") # # NODE VIEW # self.viewNP = aspect2d.attachNewNode("viewNP") self.viewNP.setScale(0.5) # # NODE MANAGER # self.nodeMgr = NodeManager(self.viewNP, customNodeMap) # Drag view self.mouseSpeed = 1 self.mousePos = None self.startCameraMovement = False # Box select # variables to store the start and current pos of the mousepointer self.startPos = LPoint2f(0, 0) self.lastPos = LPoint2f(0, 0) # variables for the to be drawn box self.boxCardMaker = CardMaker("SelectionBox") self.boxCardMaker.setColor(1, 1, 1, 0.25) self.box = None # # MENU BAR # self.mainView = MainView(parent, customNodeMap, customExporterMap) self.enable_editor() # ------------------------------------------------------------------ # FRAME COMPATIBILITY FUNCTIONS # ------------------------------------------------------------------ def is_dirty(self): """ This method returns True if an unsaved state of the editor is given """ return len(self.nodeMgr.getAllNodes()) > 0 def enable_editor(self): """ Enable the editor. """ self.enable_events() # Task for handling dragging of the camera/view taskMgr.add(self.updateCam, "NodeEditor_task_camActualisation", priority=-4) self.viewNP.show() self.nodeMgr.showConnections() def disable_editor(self): """ Disable the editor. """ self.ignore_all() taskMgr.remove("NodeEditor_task_camActualisation") self.viewNP.hide() self.nodeMgr.hideConnections() def do_exception_save(self): """ Save content of editor if the application crashes """ Save(self.nodeMgr.nodeList, self.nodeMgr.connections, True) # ------------------------------------------------------------------ # NODE EDITOR RELATED EVENTS # ------------------------------------------------------------------ def enable_events(self): # Add nodes self.accept("addNode", self.nodeMgr.addNode) # Remove nodes self.accept("NodeEditor_removeNode", self.nodeMgr.removeNode) self.accept("x", self.nodeMgr.removeNode) self.accept("delete", self.nodeMgr.removeNode) # Selecting self.accept("selectNode", self.nodeMgr.selectNode) # Deselecting self.accept("mouse3", self.nodeMgr.deselectAll) # Node Drag and Drop self.accept("dragNodeStart", self.setDraggedNode) self.accept("dragNodeMove", self.updateNodeMove) self.accept("dragNodeStop", self.updateNodeStop) # Duplicate/Copy nodes self.accept("shift-d", self.nodeMgr.copyNodes) self.accept("NodeEditor_copyNodes", self.nodeMgr.copyNodes) # Refresh node logics self.accept("ctlr-r", self.nodeMgr.updateAllLeaveNodes) self.accept("NodeEditor_refreshNodes", self.nodeMgr.updateAllLeaveNodes) # # SOCKET RELATED EVENTS # self.accept("updateConnectedNodes", self.nodeMgr.updateConnectedNodes) # Socket connection with drag and drop self.accept("startPlug", self.nodeMgr.setStartPlug) self.accept("endPlug", self.nodeMgr.setEndPlug) self.accept("connectPlugs", self.nodeMgr.connectPlugs) self.accept("cancelPlug", self.nodeMgr.cancelPlug) # Draw line while connecting sockets self.accept("startLineDrawing", self.startLineDrawing) self.accept("stopLineDrawing", self.stopLineDrawing) # # CONNECTION RELATED EVENTS # self.accept("NodeEditor_updateConnections", self.nodeMgr.updateConnections) # # PROJECT MANAGEMENT # self.accept("NodeEditor_new", self.newProject) self.accept("NodeEditor_save", self.saveProject) self.accept("NodeEditor_load", self.loadProject) self.accept("quit_app", exit) # # EXPORTERS # self.accept("NodeEditor_customSave", self.customExport) # # EDITOR VIEW # # Zooming self.accept("NodeEditor_zoom", self.zoom) self.accept("NodeEditor_zoom_reset", self.zoomReset) self.accept("wheel_up", self.zoom, [True]) self.accept("wheel_down", self.zoom, [False]) # Drag view self.accept("mouse2", self.setMoveCamera, [True]) self.accept("mouse2-up", self.setMoveCamera, [False]) # Box select # accept the 1st mouse button events to start and stop the draw self.accept("mouse1", self.startBoxDraw) self.accept("mouse1-up", self.stopBoxDraw) # ------------------------------------------------------------------ # PROJECT FUNCTIONS # ------------------------------------------------------------------ def newProject(self): self.nodeMgr.cleanup() def saveProject(self): Save(self.nodeMgr.nodeList, self.nodeMgr.connections) def loadProject(self): self.nodeMgr.cleanup() Load(self.nodeMgr) def customExport(self, exporter): exporter(self.nodeMgr.nodeList, self.nodeMgr.connections) # ------------------------------------------------------------------ # CAMERA SPECIFIC FUNCTIONS # ------------------------------------------------------------------ def setMoveCamera(self, moveCamera): """Start dragging around the editor area/camera""" # store the mouse position if weh have a mouse if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() self.mousePos = Point2(x, y) # set the variable according to if we want to move the camera or not self.startCameraMovement = moveCamera def updateCam(self, task): """Task that will move the editor area/camera around according to mouse movements""" # variables to store the mouses current x and y position x = 0.0 y = 0.0 if base.mouseWatcherNode.hasMouse(): # get the mouse position x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if base.mouseWatcherNode.hasMouse() \ and self.mousePos is not None \ and self.startCameraMovement: # Move the viewer node aspect independent wp = base.win.getProperties() aspX = 1.0 aspY = 1.0 wpXSize = wp.getXSize() wpYSize = wp.getYSize() if wpXSize > wpYSize: aspX = wpXSize / float(wpYSize) else: aspY = wpYSize / float(wpXSize) mouseMoveX = (self.mousePos.getX() - x) / self.viewNP.getScale( ).getX() * self.mouseSpeed * aspX mouseMoveY = (self.mousePos.getY() - y) / self.viewNP.getScale( ).getZ() * self.mouseSpeed * aspY self.mousePos = Point2(x, y) self.viewNP.setX(self.viewNP, -mouseMoveX) self.viewNP.setZ(self.viewNP, -mouseMoveY) self.nodeMgr.updateConnections() # continue the task until it got manually stopped return task.cont def zoom(self, zoomIn): """Zoom the editor in or out dependent on the value in zoomIn""" zoomFactor = 0.05 maxZoomIn = 2 maxZoomOut = 0.1 if zoomIn: s = self.viewNP.getScale() if s.getX() - zoomFactor < maxZoomIn and s.getY( ) - zoomFactor < maxZoomIn and s.getZ() - zoomFactor < maxZoomIn: self.viewNP.setScale(s.getX() + zoomFactor, s.getY() + zoomFactor, s.getZ() + zoomFactor) else: s = self.viewNP.getScale() if s.getX() - zoomFactor > maxZoomOut and s.getY( ) - zoomFactor > maxZoomOut and s.getZ() - zoomFactor > maxZoomOut: self.viewNP.setScale(s.getX() - zoomFactor, s.getY() - zoomFactor, s.getZ() - zoomFactor) self.nodeMgr.updateConnections() def zoomReset(self): """Set the zoom level back to the default""" self.viewNP.setScale(0.5) self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # DRAG LINE # ------------------------------------------------------------------ def startLineDrawing(self, startPos): """Start a task that will draw a line from the given start position to the cursor""" self.line = LineNodePath(render2d, thickness=2, colorVec=(0.8, 0.8, 0.8, 1)) self.line.moveTo(startPos) t = taskMgr.add(self.drawLineTask, "drawLineTask") t.startPos = startPos def drawLineTask(self, task): """Draws a line from a given start position to the cursor""" mwn = base.mouseWatcherNode if mwn.hasMouse(): pos = Point3(mwn.getMouse()[0], 0, mwn.getMouse()[1]) self.line.reset() self.line.moveTo(task.startPos) self.line.drawTo(pos) self.line.create() return task.cont def stopLineDrawing(self): """Stop the task that draws a line to the cursor""" taskMgr.remove("drawLineTask") if self.line is not None: self.line.reset() self.line = None # ------------------------------------------------------------------ # EDITOR NODE DRAGGING UPDATE # ------------------------------------------------------------------ def setDraggedNode(self, node): """This will set the node that is currently dragged around as well as update other selected nodes which will be moved in addition to the main dragged node""" self.draggedNode = node self.draggedNode.disable() self.tempNodePositions = {} for node in self.nodeMgr.selectedNodes: self.tempNodePositions[node] = node.frame.getPos(render2d) def updateNodeMove(self, mouseA, mouseB): """Will be called as long as a node is beeing dragged around""" for node in self.nodeMgr.selectedNodes: if node is not self.draggedNode and node in self.tempNodePositions.keys( ): editVec = Vec3(self.tempNodePositions[node] - mouseA) newPos = mouseB + editVec node.frame.setPos(render2d, newPos) self.nodeMgr.updateConnections() def updateNodeStop(self, node=None): """Will be called when a node dragging stopped""" self.draggedNode.enable() self.draggedNode = None self.tempNodePositions = {} self.nodeMgr.updateConnections() # ------------------------------------------------------------------ # SELECTION BOX # ------------------------------------------------------------------ def startBoxDraw(self): """Start drawing the box""" if base.mouseWatcherNode.hasMouse(): # get the mouse position self.startPos = LPoint2f(base.mouseWatcherNode.getMouse()) taskMgr.add(self.dragBoxDrawTask, "dragBoxDrawTask") def stopBoxDraw(self): """Stop the draw box task and remove the box""" if not taskMgr.hasTaskNamed("dragBoxDrawTask"): return taskMgr.remove("dragBoxDrawTask") if self.startPos is None or self.lastPos is None: return self.nodeMgr.deselectAll() if self.box is not None: for node in self.nodeMgr.getAllNodes(): # store some view scales for calculations viewXScale = self.viewNP.getScale().getX() viewZScale = self.viewNP.getScale().getZ() # calculate the node edges nodeLeft = node.getLeft() * viewXScale nodeRight = node.getRight() * viewXScale nodeBottom = node.getBottom() * viewZScale nodeTop = node.getTop() * viewZScale # calculate bounding box edges left = min(self.lastPos.getX(), self.startPos.getX()) right = max(self.lastPos.getX(), self.startPos.getX()) top = max(self.lastPos.getY(), self.startPos.getY()) bottom = min(self.lastPos.getY(), self.startPos.getY()) # check for hits xGood = yGood = False if left < nodeLeft and right > nodeLeft: xGood = True elif left < nodeRight and right > nodeRight: xGood = True if top > nodeTop and bottom < nodeTop: yGood = True elif top > nodeBottom and bottom < nodeBottom: yGood = True # check if we have any hits if xGood and yGood: self.nodeMgr.selectNode(node, True, True) # Cleanup the selection box self.box.removeNode() self.startPos = None self.lastPos = None def dragBoxDrawTask(self, task): """This task will track the mouse position and actualize the box's size according to the first click position of the mouse""" if base.mouseWatcherNode.hasMouse(): if self.startPos is None: self.startPos = LPoint2f(base.mouseWatcherNode.getMouse()) # get the current mouse position self.lastPos = LPoint2f(base.mouseWatcherNode.getMouse()) else: return task.cont # check if we already have a box if self.box != None: # if so, remove that old box self.box.removeNode() # set the box's size self.boxCardMaker.setFrame(self.lastPos.getX(), self.startPos.getX(), self.startPos.getY(), self.lastPos.getY()) # generate, setup and draw the box node = self.boxCardMaker.generate() self.box = render2d.attachNewNode(node) self.box.setBin("gui-popup", 25) self.box.setTransparency(TransparencyAttrib.M_alpha) # run until the task is manually stopped return task.cont
def __init__(self, parent = None, pos = (0,0,0), fading = False, fading_position_offset = (0,0,0), fading_duration = 0.5, backgroundImage = None, backgroundColor = None, enableMask = False, noFocus = False, shownFunc = None, hiddenFunc = None, funcExtraArgs = [], sort = None ): '''if fading enabled, it will apply a fading effect on show()&hide() Important Attributes: enableMask: This creates a big transparent plane (DirectButton) off screen so the directGui below won't be clicked (However due to this trick we won't be able to accept mouse events (I have paid back 'mouse3' by self.__maskClick)) noFocus: if it is true, it doesn't need SogalBase to manage its focus state (it will not affect other Sogalforms' focus state ''' self.__fading = fading self.__fadingPositionOffset = fading_position_offset self.__fadingDuration = fading_duration self.__originPos = pos self.__currentInterval = None self.__maskEnabled = enableMask self.__noFocus = noFocus self.__shownFunc = shownFunc self.__hiddenFunc = hiddenFunc self.__eventExtraArgs = funcExtraArgs self.__mask = None if self.__maskEnabled: self.__mask = DialogMask() #self.__mask = DirectButton(parent = aspect2d, frameColor =(1,1,1,0.1), relief = DGG.FLAT,commandButtons = [DGG.RMB],command = self.__maskClick) self.__mask.hide() self.__backgroundImage = backgroundImage self.__backgroundColor = backgroundColor self.__bgPath = None self.__imagePath = None self.__hidden = True NodePath.__init__(self,self.__class__.__name__) parent = parent or aspect2d if sort: self.reparentTo(parent, sort = sort) else: self.reparentTo(parent) self.setPos(pos) if self.__backgroundColor: self.__bgPath = NodePath('bgPath') self.__bgPath.setTransparency(TransparencyAttrib.MAlpha) cm = CardMaker('cm') cm.setFrameFullscreenQuad() cm.setColor(self.__backgroundColor) self.__bgPath.attachNewNode(cm.generate()) self.__bgPath.reparentTo(aspect2d,self.getSort()) self.__bgPath.hide() #TODO: backgroundImage self.setTransparency(TransparencyAttrib.MAlpha) self.accept('window-event', self.windowResize) self.windowResize(None) NodePath.hide(self)
def __init__(self): # create a texture into which we can copy the main window. self.tex = Texture() self.tex.setMinfilter(Texture.FTLinear) base.win.addRenderTexture(self.tex, GraphicsOutput.RTMTriggeredCopyTexture) # Create another 2D camera. Tell it to render before the main camera. self.backcam = base.makeCamera2d(base.win, sort=-10) self.background = NodePath("background") self.backcam.reparentTo(self.background) self.background.setDepthTest(0) self.background.setDepthWrite(0) self.backcam.node().getDisplayRegion(0).setClearDepthActive(0) # Obtain two texture cards. One renders before the dragon, the other after. self.bcard = base.win.getTextureCard() self.bcard.reparentTo(self.background) self.bcard.setTransparency(1) self.fcard = base.win.getTextureCard() self.fcard.reparentTo(render2d) self.fcard.setTransparency(1) # Initialize one of the nice effects. self.chooseEffectGhost() # Add the task that initiates the screenshots. taskMgr.add(self.takeSnapShot, "takeSnapShot") # Create some black squares on top of which we will # place the instructions. blackmaker = CardMaker("blackmaker") blackmaker.setColor(0,0,0,1) blackmaker.setFrame(-1.00, -0.50, 0.65, 1.00) instcard = NodePath(blackmaker.generate()) instcard.reparentTo(render2d) blackmaker.setFrame(-0.5, 0.5, -1.00, -0.85) titlecard = NodePath(blackmaker.generate()) titlecard.reparentTo(render2d) # Panda does its best to hide the differences between DirectX and # OpenGL. But there are a few differences that it cannot hide. # One such difference is that when OpenGL copies from a # visible window to a texture, it gets it right-side-up. When # DirectX does it, it gets it upside-down. There is nothing panda # can do to compensate except to expose a flag and let the # application programmer deal with it. You should only do this # in the rare event that you're copying from a visible window # to a texture. if (base.win.getGsg().getCopyTextureInverted()): print "Copy texture is inverted." self.bcard.setScale(1,1,-1) self.fcard.setScale(1,1,-1) # Put up the instructions title = OnscreenText(text="Panda3D: Tutorial - Motion Trails", style=1, fg=(1,1,1,1), pos=(0,-0.95), scale = .07) instr0 = addInstructions(0.95, "Press ESC to exit") instr1 = addInstructions(0.90, "Press 1: Ghost effect") instr2 = addInstructions(0.85, "Press 2: PaintBrush effect") instr3 = addInstructions(0.80, "Press 3: Double Vision effect") instr4 = addInstructions(0.75, "Press 4: Wings of Blue effect") instr5 = addInstructions(0.70, "Press 5: Whirlpool effect") # enable the key events self.accept("escape", sys.exit, [0]) self.accept("1", self.chooseEffectGhost) self.accept("2", self.chooseEffectPaintBrush) self.accept("3", self.chooseEffectDoubleVision) self.accept("4", self.chooseEffectWingsOfBlue) self.accept("5", self.chooseEffectWhirlpool)
class RaceGUI: GagPie = 0 gagRoot = 'phase_3.5/maps/inventory_' class RacerInfo: def __init__(self, face, mapSpot): self.curvetime = 0 self.maxlaphit = 0 self.face = face self.mapspot = mapSpot self.place = 1 self.enabled = True self.finished = False self.gag = None return def update(self, curvetime = None, maxlaphit = None, faceX = None, mapspotPt = None, place = None, finished = None): if self.enabled: if not curvetime == None: self.curvetime = curvetime if not maxlaphit == None: self.maxlaphit = maxlaphit if not faceX == None: self.face.setX(faceX) if not mapspotPt == None: self.mapspot.setPos(mapspotPt) if not place == None: self.place = place if not finished == None: self.finished = finished return def disable(self): self.enabled = False if not self.finished: self.face.hide() self.mapspot.hide() def enable(self): self.enabled = True self.face.show() self.mapspot.show() def __init__(self, distRace): self.race = distRace self.timerEnabled = False self.maxLapHit = 0 self.photoFinish = False toonInteriorTextures = loader.loadModel('phase_3.5/models/modules/toon_interior_textures') invTextures = loader.loadModel('phase_3.5/models/gui/inventory_icons') racingTextures = loader.loadModel('phase_6/models/karting/racing_textures') self.gagTextures = [toonInteriorTextures.find('**/couch'), invTextures.find('**/inventory_bannana_peel'), racingTextures.find('**/boost_arrow'), invTextures.find('**/inventory_anvil'), invTextures.find('**/inventory_creampie')] self.gagTextures[1].setScale(7.5) self.gagTextures[3].setScale(7.5) self.gagTextures[4].setScale(7.5) self.cardMaker = CardMaker('card') self.racerDict = {} self.render2dRoot = render2d.attachNewNode('RaceGuiRender2dRoot') self.render2dRoot.setDepthWrite(1) self.directObjList = [] self.aspect2dRoot = aspect2d.attachNewNode('RaceGuiAspect2dRoot') self.aspect2dRoot.setDepthWrite(1) self.raceModeRoot = self.aspect2dRoot.attachNewNode('RaceModeRoot') gui = loader.loadModel('phase_3.5/models/gui/avatar_panel_gui') self.closeButton = DirectButton(image=(gui.find('**/CloseBtn_UP'), gui.find('**/CloseBtn_DN'), gui.find('**/CloseBtn_Rllvr'), gui.find('**/CloseBtn_UP')), relief=None, scale=1.05, text=TTLocalizer.KartRace_Leave, text_scale=0.04, text_pos=(0, -0.07), text_fg=VBase4(1, 1, 1, 1), pos=(-0.99, 0, 0.925), command=self.race.leaveRace) self.closeButton.reparentTo(self.aspect2dRoot) self.directObjList.append(self.closeButton) self.raceTimeDelta = 0 self.raceModeReady = False self.resultModeReady = False self.gagCycleSound = base.loader.loadSfx('phase_3.5/audio/sfx/tick_counter.ogg') if hasattr(self.gagCycleSound, 'setPlayRate'): self.gagCycleSound.setPlayRate(0.2) self.gagCycleSound.setLoop(1) self.gagAcquireSound = base.loader.loadSfx('phase_6/audio/sfx/SZ_MM_gliss.ogg') self.disable() return def initRaceMode(self): self.mapScene = base.a2dTopRight.attachNewNode('MapScene') self.mapScene.setPos(-0.2, 0, -0.2) self.mapScene.setScale(0.25, 0.001, 0.25) maxT = self.race.curve.getMaxT() pt = Vec3(0, 0, 0) ls = LineSegs('MapLines') ls.setColor(1, 1, 1, 1) ls.setThickness(2) for x in xrange(101): self.race.curve.getPoint(x / 100.0 * maxT, pt) if x == 0: ls.moveTo(pt[0], pt[1], pt[2]) else: ls.drawTo(pt[0], pt[1], pt[2]) self.mapLines = self.mapScene.attachNewNode(ls.create()) self.mapLines.setScale(0.00025 * RaceGlobals.TrackDict[self.race.trackId][6]) self.mapLines.setP(90) self.faceStartPos = Vec3(-0.8, 0, 0.93) self.faceEndPos = Vec3(0.8, 0, 0.93) self.placeLabelNum = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelNumPos, text='1', text_scale=0.35, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelNum.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelNum) self.placeLabelStr = DirectLabel(relief=None, pos=TTLocalizer.RGUIplaceLabelStrPos, text=TTLocalizer.KartRace_FirstSuffix, text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.placeLabelStr.reparentTo(base.a2dBottomLeft) self.directObjList.append(self.placeLabelStr) self.lapLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.5), text='1/' + str(self.race.lapCount), text_scale=0.1, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.lapLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.lapLabel) self.photoFinishLabel = DirectLabel(relief=None, pos=(0, 0, -0.1), text=TTLocalizer.KartRace_PhotoFinish, text_scale=TTLocalizer.RGUIphotoFinish, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont()) self.photoFinishLabel.hide() self.directObjList.append(self.photoFinishLabel) self.wrongWayLabel = DirectLabel(relief=None, pos=(-0.22, 0, -0.2), text=TTLocalizer.KartRace_WrongWay, text_scale=0.1, text_fg=(0.95, 0, 0, 1), text_font=ToontownGlobals.getSignFont()) self.wrongWayLabel.reparentTo(base.a2dTopRight) self.directObjList.append(self.wrongWayLabel) self.wrongWayLabel.setColorScale(Vec4(1, 1, 1, 0)) self.wrongWaySeq = Sequence(self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 1), startColorScale=Vec4(1, 1, 1, 0)), self.wrongWayLabel.colorScaleInterval(0.25, colorScale=Vec4(1, 1, 1, 0), startColorScale=Vec4(1, 1, 1, 1))) interpolateFacePos = lambda x: self.faceStartPos * (1.0 - x) + self.faceEndPos * x self.timeLabels = [] for x in xrange(self.race.lapCount): minLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] - 0.06, 0, 0.84), text="0'", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) minLabel.reparentTo(self.raceModeRoot) self.directObjList.append(minLabel) secLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.06, 0, 0.84), text="00''", text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) secLabel.reparentTo(self.raceModeRoot) self.directObjList.append(secLabel) fractionLabel = DirectLabel(relief=None, pos=(interpolateFacePos((2.0 * x + 1) / (self.race.lapCount * 2))[0] + 0.14, 0, 0.84), text='00', text_scale=0.06, text_fg=(0.95, 0.95, 0, 1), text_font=ToontownGlobals.getSignFont(), text_align=TextNode.ARight) fractionLabel.reparentTo(self.raceModeRoot) self.directObjList.append(fractionLabel) self.timeLabels.append((minLabel, secLabel, fractionLabel)) self.cardMaker.reset() self.cardMaker.setName('GagIndicator') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) self.cardMaker.setColor(1, 1, 1, 1) self.gagPanel = DirectFrame(parent=base.a2dBottomLeft, relief=None, image=loader.loadModel('phase_6/models/karting/gag_panel'), image_scale=0.25, pos=(0.2, 0, 0.55)) self.directObjList.append(self.gagPanel) self.gag = self.gagPanel.attachNewNode('gag') self.gag.setScale(0.2) for gag in self.gagTextures: gag.reparentTo(self.gag) gag.hide() self.cardMaker.reset() self.cardMaker.setName('RaceProgressLine') self.cardMaker.setFrame(-0.5, 0.5, -0.5, 0.5) line = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) line.setScale(self.faceEndPos[0] - self.faceStartPos[0], 1, 0.01) line.setPos(0, 0, self.faceStartPos[2]) self.cardMaker.setName('RaceProgressLineHash') for n in xrange(self.race.lapCount + 1): hash = self.raceModeRoot.attachNewNode(self.cardMaker.generate()) hash.setScale(line.getScale()[2], 1, line.getScale()[2] * 5) t = float(n) / self.race.lapCount hash.setPos(self.faceStartPos[0] * (1 - t) + self.faceEndPos[0] * t, self.faceStartPos[1], self.faceStartPos[2]) self.raceModeReady = True self.disable() return def initResultMode(self): self.endPanel = RaceEndPanel(len(self.race.avIds), self.race) self.endPanel.reparentTo(self.aspect2dRoot) self.directObjList.append(self.endPanel) self.resultModeReady = True self.disable() def showGag(self, gagIndex): if gagIndex < len(self.gagTextures): for gag in self.gagTextures: gag.hide() self.gagTextures[gagIndex].show() def updateGag(self, gagIndex): if self.gag: if hasattr(self, 'gagCycleInterval'): self.gagCycleInterval.finish() del self.gagCycleInterval self.gag.setHpr(0, 0, 0) self.showGag(gagIndex) if gagIndex == 0: self.gag.hide() else: self.gag.show() self.gagAcquireSound.play() self.gagAcquireInterval = LerpHprInterval(self.gag, duration=0.5, blendType='easeOut', startHpr=Point3(0, -90, 0), hpr=Point3(0, 0, 0)) self.gagAcquireInterval.start() def waitingOnGag(self, cycleTime): if self.gag: numTextures = len(self.gagTextures) startOffset = random.choice(range(0, numTextures)) self.gag.show() self.gagCycleInterval = Parallel(LerpFunc(self.showNextGag, fromData=startOffset, toData=numTextures * 2 * cycleTime + startOffset, blendType='easeOut', duration=cycleTime), LerpHprInterval(self.gag, duration=cycleTime, hpr=Point3(0, 180 * numTextures * 2 * cycleTime - 90, 0), blendType='easeOut', startHpr=Point3(0, 0, 0)), SoundInterval(self.gagCycleSound, loop=1, duration=cycleTime, startTime=0), name='gagCycleInterval') self.gagCycleInterval.start() def showNextGag(self, t): if self.gag: currGagIndex = int(t % (len(self.gagTextures) - 1)) + 1 self.showGag(currGagIndex) def enableSpeedometer(self): self.race.localKart.showSpeedometer() def disableSpeedometer(self): self.race.localKart.hideSpeedometer() def disableRaceMode(self): self.disableSpeedometer() self.render2dRoot.hide() self.raceModeRoot.hide() for x in self.timeLabels: for y in x: y.hide() self.setTimerEnabled(False) def disableResultMode(self): self.endPanel.disable() def disable(self): self.closeButton.hide() taskMgr.removeTasksMatching('clearRaceEndPanel') if self.raceModeReady: self.disableRaceMode() if self.resultModeReady: self.disableResultMode() def enableRaceMode(self): self.enableSpeedometer() self.render2dRoot.show() self.raceModeRoot.show() self.maxLapHit = min(self.maxLapHit, self.race.lapCount - 1) for x in xrange(self.maxLapHit + 1): for y in self.timeLabels[x]: y.configure(text_font=ToontownGlobals.getSignFont()) y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) def enableResultMode(self): self.endPanel.enable() if not self.race.circuitLoop: taskMgr.doMethodLater(180, self.endPanel.closeButtonPressed, 'clearRaceEndPanel', extraArgs=[]) def destroy(self): self.disable() if hasattr(self, 'wrongWaySeq'): self.wrongWaySeq.finish() self.wrongWaySeq = None taskMgr.removeTasksMatching('removeIt') taskMgr.removeTasksMatching('removeCam*') taskMgr.removeTasksMatching('clearRaceEndPanel') for obj in self.directObjList: obj.destroy() if hasattr(self, 'mapScene'): self.mapScene.removeNode() self.mapScene = None self.aspect2dRoot.removeNode() self.aspect2dRoot = None self.raceModeRoot.removeNode() self.raceModeRoot = None self.render2dRoot.removeNode() self.render2dRoot = None self.closeButton = None self.gag = None self.lapLabel = None self.timeLabels = None self.placeLabelStr = None self.placeLabelNum = None self.photoFinishLabel = None self.mapScene = None self.race = None return def setSpotAsymptotic(self, diffT, spot): p = (-1, 1)[diffT > 0] * (1 - 1 / pow(abs(diffT) / self.cutoff + 1, 2)) spot.setX(p) def setSpotRaceLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t / self.lapCount)) def setSpotLapLinear(self, t, spot): spot.setX(-1.0 + 2.0 * (t - int(t))) def update(self, time): placeSorter = [] placeCount = 0 for key in self.racerDict.keys(): racer = self.racerDict[key] curvetime = racer.curvetime face = racer.face mapspot = racer.mapspot maxlaphit = racer.maxlaphit if not racer.finished and racer.enabled: placeSorter.append((curvetime, key)) if racer.finished or racer.enabled: placeCount += 1 pt = Vec3(0, 0, 0) mapT = (curvetime % 1 + self.race.startT / self.race.curve.getMaxT()) % 1 * self.race.curve.getMaxT() self.race.curve.getPoint(mapT, pt) self.race.curve.getPoint(mapT % self.race.curve.getMaxT(), pt) lapT = bound(curvetime / self.race.lapCount, 0.0, 1.0) faceX = self.faceStartPos[0] * (1 - lapT) + self.faceEndPos[0] * lapT racer.update(faceX=faceX, mapspotPt=pt) t = time - self.race.baseTime - self.raceTimeDelta if key == localAvatar.doId: if self.race.laps > maxlaphit: racer.update(maxlaphit=self.race.laps) self.maxLapHit = racer.maxlaphit if self.maxLapHit < self.race.lapCount: for y in self.timeLabels[self.maxLapHit - 1]: y.configure(text_font=ToontownGlobals.getSignFont()) for y in self.timeLabels[self.maxLapHit]: y.show() for y in self.timeLabels[self.maxLapHit]: y.configure(text_font=ToontownGlobals.getSignFont()) self.raceTimeDelta = globalClock.getFrameTime() - self.race.baseTime lapNotice = DirectLabel() lapNotice.setScale(0.1) if self.maxLapHit == self.race.lapCount - 1: lapNotice['text'] = TTLocalizer.KartRace_FinalLapText else: lapNotice['text'] = TTLocalizer.KartRace_LapText % str(self.maxLapHit + 1) taskMgr.doMethodLater(2, lapNotice.remove, 'removeIt', extraArgs=[]) self.lapLabel['text'] = str(bound(self.maxLapHit + 1, 1, self.race.lapCount)) + '/' + str(self.race.lapCount) suffix = {1: TTLocalizer.KartRace_FirstSuffix, 2: TTLocalizer.KartRace_SecondSuffix, 3: TTLocalizer.KartRace_ThirdSuffix, 4: TTLocalizer.KartRace_FourthSuffix} placeSorter.sort() for x, p in zip(placeSorter, xrange(len(placeSorter), 0, -1)): self.racerDict[x[1]].update(place=p + placeCount - len(placeSorter)) localRacer = self.racerDict[localAvatar.doId] nearDiff, farDiff = RaceGlobals.TrackDict[self.race.trackId][8] if not localRacer.finished and self.faceEndPos[0] - localRacer.face.getX() < nearDiff: for racerId in self.racerDict.keys(): racer = self.racerDict[racerId] if not racer.enabled or racerId == localAvatar.doId or racer.face.getX() >= self.faceEndPos[0]: continue if self.faceEndPos[0] - racer.face.getX() < farDiff: self.photoFinish = True if self.photoFinish: self.photoFinishLabel.show() self.placeLabelNum['text'] = '' self.placeLabelStr['text'] = '' else: self.photoFinishLabel.hide() self.placeLabelNum['text'] = str(self.racerDict[localAvatar.doId].place) self.placeLabelStr['text'] = suffix[self.racerDict[localAvatar.doId].place] minutes = int(t / 60) t -= minutes * 60 seconds = int(t) padding = (seconds < 10 and ['0'] or [''])[0] t -= seconds fraction = str(t)[2:4] fraction = fraction + '0' * (2 - len(fraction)) if self.timerEnabled and self.maxLapHit < self.race.lapCount: self.timeLabels[self.maxLapHit][0]['text'] = "%d'" % minutes self.timeLabels[self.maxLapHit][1]['text'] = "%s%d''" % (padding, seconds) self.timeLabels[self.maxLapHit][2]['text'] = '%s' % fraction if self.race.wrongWay and not self.wrongWaySeq.isPlaying(): self.wrongWaySeq.loop() elif not self.race.wrongWay and self.wrongWaySeq.isPlaying(): self.wrongWaySeq.finish() def updateRacerInfo(self, avId, curvetime = None, maxlaphit = None): if avId in self.racerDict.keys(): self.racerDict[avId].update(curvetime=curvetime, maxlaphit=maxlaphit) def racerEntered(self, avId): toon = base.cr.doId2do.get(avId, None) kart = base.cr.doId2do.get(self.race.kartMap.get(avId, None), None) if not toon or not kart: return if kart.getBodyColor() == InvalidEntry: bodyColor = getDefaultColor() else: bodyColor = getAccessory(kart.getBodyColor()) headframe = RaceHeadFrame(av=toon, color=bodyColor) eyes = headframe.head.find('**/eyes*') eyes.setDepthTest(1) eyes.setDepthWrite(1) headframe.configure(geom_scale=(0.5, 0.5, 0.5)) headframe.setZ(self.faceStartPos[2]) headframe.setDepthWrite(True) headframe.setDepthTest(True) headframe.reparentTo(self.raceModeRoot) self.directObjList.append(headframe) mapspot = loader.loadModel('phase_6/models/karting/race_mapspot') mapspot.setColor(bodyColor) mapspot.reparentTo(self.mapLines) mapspot.setHpr(self.mapScene, 0, 0, 0) self.racerDict[avId] = self.RacerInfo(headframe, mapspot) for key, i in zip(self.racerDict.keys(), range(len(self.racerDict.keys()))): face = self.racerDict[key].face mapspot = self.racerDict[key].mapspot face.setX(self.faceStartPos[0]) face.setY(-1 - 5 * (i + 1)) face.setScale(0.15) mapspot.getChild(0).setY((-5 - 5 * (i + 1)) * 1000) mapspot.setScale(self.mapScene, 0.15) mapspot.setPos(self.race.startingPos[0][0]) if key == localAvatar.doId: face.setY(-1) face.setScale(face.getScale() * 1.25) mapspot.getChild(0).setY(-5 * 1000) mapspot.setScale(mapspot.getScale() * 1.25) self.face = face self.mapspot = mapspot return def racerLeft(self, avId, unexpected = False): racer = self.racerDict.get(avId, None) if racer: racer.disable() return def racerFinished(self, avId, trackId, place, totalTime, entryFee, qualify, winnings, bonus, trophies, circuitPoints, circuitTime): racer = self.racerDict.get(avId, None) if racer: racer.update(finished=True) racer.disable() self.endPanel.displayRacer(place, entryFee, qualify, winnings, trackId, bonus, trophies, racer.face, base.cr.doId2do[avId].getName(), totalTime, circuitPoints, circuitTime) if racer.face in self.directObjList: self.directObjList.remove(racer.face) if avId == localAvatar.doId: self.disableRaceMode() self.enableResultMode() self.endPanel.startWinningsPanel(entryFee, winnings, trackId, bonus, trophies) return def racerFinishedCircuit(self, avId, place, entryFee, winnings, bonus, trophies): racer = self.racerDict.get(avId, None) if racer: newTotalTickets = winnings + entryFee + bonus self.endPanel.updateWinnings(place, newTotalTickets) if avId == localAvatar.doId: self.endPanel.updateWinningsFromCircuit(place, entryFee, winnings, bonus, trophies) return def circuitFinished(self, placeFixup): self.endPanel.circuitFinished(placeFixup) def setTimerEnabled(self, enabled): self.timerEnabled = enabled