def test_windows_setup(self): self.store.storeNode('files/node.bam', '', 'window_r') self.store.storeNode('files/hood_node.bam', '', 'window_l') windows = DNAWindows('windows') x = .1 y = .4 np = NodePath('window_root') code = 'window_l' scale = 1.25 color = Vec4(.842, .167, .361, 1) windows.makeWindows(x, y, np, code, scale, color, self.store, False) # Check if the nodes attributes are correct model = np.find('**/node') self.assertFalse(model.isEmpty()) self.assertEqual(model.getPos(np), Point3(x, 0, y)) self.assertEqual(model.getScale(np), Vec3(scale)) # Now test with flip = True np.removeNode() np = NodePath('window_root') windows.makeWindows(x, y, np, code, scale, color, self.store, True) # Check if the nodes attributes are correct model = np.find('**/hood_node') self.assertFalse(model.isEmpty()) self.assertEqual(model.getPos(np), Point3(x, 0, y)) self.assertEqual(model.getScale(np), Vec3(scale))
def changeModel(newmodel): tempParent=NodePath('') newModel=loader.loadModel(newmodel) newModel.findAllMatches('**/+GeomNode').reparentTo(tempParent) tempParent.setScale(1.5/tempParent.getBounds().getRadius()) tempParent.setPos(-tempParent.getBounds().getCenter()) tempParent.flattenStrong() tempParent.find('**/+GeomNode').node().replaceNode(model.node())
def load_layer(self, layer): layer_node = NodePath(layer.get("name")) static_tiles = NodePath("static") # Static tiles to flatten flat_animated_tiles = NodePath("animated") # Animated tiles to flatten dynamic_tiles = NodePath( "dynamic") # All tiles unless otherwise specified (don't flatten) tile_groups = {} # should we flatten this layer store_data = flatten = False properties = layer.find("properties") if properties: for property in properties: if property.get("name") == "flatten": flatten = True if property.get("name") == "store_data": store_data = True # build all tiles in data as a grid of cards data = layer.find("data").text data = data.replace('\n', '') data = data.split(",") collumns = int(layer.get("width")) rows = int(layer.get("height")) self.size = [collumns, rows] for y in range(rows): for x in range(collumns): id = int(data[(y * collumns) + (x % collumns)]) data[(y * collumns) + (x % collumns)] = id if id > 0: tile = NodePath("tile") self.get_tile(id).copy_to(tile) if flatten: if tile.find("**/+SequenceNode"): tile.reparent_to(flat_animated_tiles) else: tile.reparent_to(static_tiles) else: tile.reparent_to(layer_node) tile.set_pos(x, -y, 0) if flatten: if static_tiles.get_num_children() > 0: clear_all_tags(static_tiles) static_tiles.flatten_strong() if flat_animated_tiles.get_num_children() > 0: clear_all_tags(flat_animated_tiles) flat_animated_tiles = self.flatten_animated_tiles( flat_animated_tiles) for t in (static_tiles, flat_animated_tiles): t.reparent_to(layer_node) if store_data: layer_node.set_python_tag("data", data) self.append_layer(layer_node, properties)
def initBodyShader(self): rig = NodePath('rig') buffer = base.win.makeCubeMap('env', 64, rig) rig.reparentTo(self.model) lens = rig.find('**/+Camera').node().getLens() lens.setNearFar(30, 1000) ts = TextureStage('env') self.model.setTexGen(ts, TexGenAttrib.MWorldCubeMap) self.model.setTexture(buffer.getTexture()) self.refreshBodyShader()
def handleNode(self, dgi, target=None): if target is None: return numNodes = dgi.getUint16() for _ in xrange(numNodes): code = DNAUtil.dgiExtractString8(dgi) file = DNAUtil.dgiExtractString8(dgi) node = DNAUtil.dgiExtractString8(dgi) np = NodePath(loader.jazzModel(file)) if node: newNode = np.find('**/' + node).copyTo(NodePath()) np.removeNode() np = newNode np.setTag('DNACode', code) np.setTag('DNARoot', node) target(np, code) return
class PopupMenu(DirectObject): ''' A class to create a popup or context menu. Features : [1] it's destroyed by pressing ESCAPE, or LMB/RMB click outside of it [2] menu item's command is executed by pressing ENTER/RETURN or SPACE when it's hilighted [3] you can use arrow UP/DOWN to navigate [4] separator lines [5] menu item image [6] menu item hotkey If there are more than 1 item using the same hotkey, those items will be hilighted in cycle when the hotkey is pressed. [7] shortcut key text at the right side of menu item [8] multiple lines item text [9] menu item can have sub menus [10] it's offscreen-proof, try to put your pointer next to screen edge or corner before creating it ''' grayImages = {} # storage of grayed images, # so the same image will be converted to grayscale only once def __init__(self, items, parent=None, buttonThrower=None, onDestroy=None, font=None, baselineOffset=.0, scale=.05, itemHeight=1., leftPad=.0, separatorHeight=.5, underscoreThickness=1, BGColor=(0, 0, 0, .7), BGBorderColor=(1, .85, .4, 1), separatorColor=(1, 1, 1, 1), frameColorHover=(1, .85, .4, 1), frameColorPress=(0, 1, 0, 1), textColorReady=(1, 1, 1, 1), textColorHover=(0, 0, 0, 1), textColorPress=(0, 0, 0, 1), textColorDisabled=(.5, .5, .5, 1), minZ=None, useMouseZ=True): ''' items : a collection of menu items Item format : ( 'Item text', 'path/to/image', command ) OR ( 'Item text', 'path/to/image', command, arg1,arg2,.... ) If you don't want to use an image, pass 0. To create disabled item, pass 0 for the command : ( 'Item text', 'path/to/image', 0 ) so, you can easily switch between enabled or disabled : ( 'Item text', 'path/to/image', command if commandEnabled else 0 ) OR ( 'Item text', 'path/to/image', (0,command)[commandEnabled] ) To create submenu, pass a sequence of submenu items for the command. To create disabled submenu, pass an empty sequence for the command. To enable hotkey, insert an underscore before the character, e.g. hotkey of 'Item te_xt' is 'x' key. To add shortcut key text at the right side of the item, append it at the end of the item text, separated by "more than" sign, e.g. 'Item text>Ctrl-T'. To insert separator line, pass 0 for the whole item. parent : where to attach the menu, defaults to aspect2d buttonThrower : button thrower whose thrown events are blocked temporarily when the menu is displayed. If not given, the default button thrower is used onDestroy : user function which will be called after the menu is fully destroyed font : text font baselineOffset : text's baseline Z offset scale : text scale itemHeight : spacing between items, defaults to 1 leftPad : blank space width before text separatorHeight : separator line height, relative to itemHeight underscoreThickness : underscore line thickness BGColor, BGBorderColor, separatorColor, frameColorHover, frameColorPress, textColorReady, textColorHover, textColorPress, textColorDisabled are some of the menu components' color minZ : minimum Z position to restrain menu's bottom from going offscreen (-1..1). If it's None, it will be set a little above the screen's bottom. ''' self.parent = parent if parent else aspect2d self.onDestroy = onDestroy self.BT = buttonThrower if buttonThrower else base.buttonThrowers[ 0].node() self.menu = NodePath('menu-%s' % id(self)) self.parentMenu = None self.submenu = None self.BTprefix = self.menu.getName() + '>' self.submenuCreationTaskName = 'createSubMenu-' + self.BTprefix self.submenuRemovalTaskName = 'removeSubMenu-' + self.BTprefix self.font = font if font else TextNode.getDefaultFont() self.baselineOffset = baselineOffset if isinstance(scale, (float, int)): scale = (scale, 1.0, scale) self.scale = scale self.itemHeight = itemHeight self.leftPad = leftPad self.separatorHeight = separatorHeight self.underscoreThickness = underscoreThickness self.BGColor = BGColor self.BGBorderColor = BGBorderColor self.separatorColor = separatorColor self.frameColorHover = frameColorHover self.frameColorPress = frameColorPress self.textColorReady = textColorReady self.textColorHover = textColorHover self.textColorPress = textColorPress self.textColorDisabled = textColorDisabled self.minZ = minZ self.mpos = Point2(base.mouseWatcherNode.getMouse()) self.itemCommand = [] self.hotkeys = {} self.numItems = 0 self.sel = -1 self.selByKey = False bgPad = self.bgPad = .0125 texMargin = self.font.getTextureMargin() * self.scale[0] * .25 b = DirectButton(parent=NodePath(''), text='^|g_', text_font=self.font, scale=self.scale) fr = b.node().getFrame() b.getParent().removeNode() baselineToCenter = (fr[2] + fr[3]) * self.scale[0] LH = (fr[3] - fr[2]) * self.itemHeight * self.scale[2] imageHalfHeight = .5 * (fr[3] - fr[2]) * self.itemHeight * .85 arrowHalfHeight = .5 * (fr[3] - fr[2]) * self.itemHeight * .5 baselineToTop = (fr[3] * self.itemHeight * self.scale[2] / LH) / (1. + self.baselineOffset) baselineToBot = LH / self.scale[2] - baselineToTop itemZcenter = (baselineToTop - baselineToBot) * .5 separatorHalfHeight = .5 * separatorHeight * LH LSseparator = LineSegs() LSseparator.setColor(.5, .5, .5, .2) arrowVtx = [ (0, itemZcenter), (-2 * arrowHalfHeight, itemZcenter + arrowHalfHeight), (-arrowHalfHeight, itemZcenter), (-2 * arrowHalfHeight, itemZcenter - arrowHalfHeight), ] tri = Triangulator() vdata = GeomVertexData('trig', GeomVertexFormat.getV3(), Geom.UHStatic) vwriter = GeomVertexWriter(vdata, 'vertex') for x, z in arrowVtx: vi = tri.addVertex(x, z) vwriter.addData3f(x, 0, z) tri.addPolygonVertex(vi) tri.triangulate() prim = GeomTriangles(Geom.UHStatic) for i in range(tri.getNumTriangles()): prim.addVertices(tri.getTriangleV0(i), tri.getTriangleV1(i), tri.getTriangleV2(i)) prim.closePrimitive() geom = Geom(vdata) geom.addPrimitive(prim) geomNode = GeomNode('arrow') geomNode.addGeom(geom) realArrow = NodePath(geomNode) z = -baselineToTop * self.scale[2] - bgPad maxWidth = .1 / self.scale[0] shortcutTextMaxWidth = 0 anyImage = False anyArrow = False anyShortcut = False arrows = [] shortcutTexts = [] loadPrcFileData('', 'text-flatten 0') for item in items: if item: t, imgPath, f = item[:3] haveSubmenu = type(f) in SEQUENCE_TYPES anyArrow |= haveSubmenu anyImage |= isinstance(imgPath, bool) or bool(imgPath) disabled = not len(f) if haveSubmenu else not callable(f) args = item[3:] underlinePos = t.find('_') t = t.replace('_', '') shortcutSepPos = t.find('>') if shortcutSepPos > -1: if haveSubmenu: print( "\nA SHORTCUT KEY POINTING TO A SUBMENU IS NON-SENSE, DON'T YOU AGREE ?" ) else: shortcutText = NodePath( OnscreenText( parent=self.menu, text=t[shortcutSepPos + 1:], font=self.font, scale=1, fg=(1, 1, 1, 1), align=TextNode.ARight, )) shortcutTextMaxWidth = max( shortcutTextMaxWidth, abs(shortcutText.getTightBounds()[0][0])) anyShortcut = True t = t[:shortcutSepPos] else: shortcutText = '' EoLcount = t.count('\n') arrowZpos = -self.font.getLineHeight() * EoLcount * .5 if disabled: b = NodePath( OnscreenText( parent=self.menu, text=t, font=self.font, scale=1, fg=textColorDisabled, align=TextNode.ALeft, )) # don't pass the scale and position to OnscreenText constructor, # to maintain correctness between the OnscreenText and DirectButton items # due to the new text generation implementation b.setScale(self.scale) b.setZ(z) maxWidth = max(maxWidth, b.getTightBounds()[1][0] / self.scale[0]) if shortcutText: shortcutText.reparentTo(b) shortcutText.setColor(Vec4(*textColorDisabled), 1) shortcutText.setZ(arrowZpos) shortcutTexts.append(shortcutText) else: b = DirectButton( parent=self.menu, text=t, text_font=self.font, scale=self.scale, pos=(0, 0, z), text_fg=textColorReady, # text color when mouse over text2_fg=textColorHover, # text color when pressed text1_fg=textColorHover if haveSubmenu else textColorPress, # framecolor when pressed frameColor=frameColorHover if haveSubmenu else frameColorPress, commandButtons=[DGG.LMB, DGG.RMB], command=(lambda: 0) if haveSubmenu else self.__runCommand, extraArgs=[] if haveSubmenu else [f, args], text_align=TextNode.ALeft, relief=DGG.FLAT, rolloverSound=0, clickSound=0, pressEffect=0) b.stateNodePath[2].setColor( *frameColorHover) # framecolor when mouse over b.stateNodePath[0].setColor(0, 0, 0, 0) # framecolor when ready bframe = Vec4(b.node().getFrame()) if EoLcount: bframe.setZ(EoLcount * 10) b['frameSize'] = bframe maxWidth = max(maxWidth, bframe[1]) if shortcutText: for snpi, col in ((0, textColorReady), (1, textColorPress), (2, textColorHover)): sct = shortcutText.copyTo(b.stateNodePath[snpi], sort=10) sct.setColor(Vec4(*col), 1) sct.setZ(arrowZpos) shortcutTexts.append(sct) shortcutText.removeNode() if isinstance(imgPath, bool): if imgPath: if disabled: fg = textColorDisabled else: fg = textColorReady tick = NodePath( OnscreenText( parent=b, text=u"\u2714", font=self.font, scale=1, fg=fg, align=TextNode.ALeft, )) tick.setX(-2 * imageHalfHeight - leftPad) elif imgPath: img = loader.loadTexture(imgPath, okMissing=True) if img is not None: if disabled: if imgPath in PopupMenu.grayImages: img = PopupMenu.grayImages[imgPath] else: pnm = PNMImage() img.store(pnm) pnm.makeGrayscale(.2, .2, .2) img = Texture() img.load(pnm) PopupMenu.grayImages[imgPath] = img img.setMinfilter(Texture.FTLinearMipmapLinear) img.setWrapU(Texture.WMClamp) img.setWrapV(Texture.WMClamp) CM = CardMaker('') CM.setFrame(-2 * imageHalfHeight - leftPad, -leftPad, itemZcenter - imageHalfHeight, itemZcenter + imageHalfHeight) imgCard = b.attachNewNode(CM.generate()) imgCard.setTexture(img) if underlinePos > -1: oneLineText = t[:underlinePos + 1] oneLineText = oneLineText[oneLineText.rfind('\n') + 1:] tn = TextNode('') tn.setFont(self.font) tn.setText(oneLineText) tnp = NodePath(tn.getInternalGeom()) underlineXend = tnp.getTightBounds()[1][0] tnp.removeNode() tn.setText(t[underlinePos]) tnp = NodePath(tn.getInternalGeom()) b3 = tnp.getTightBounds() underlineXstart = underlineXend - (b3[1] - b3[0])[0] tnp.removeNode() underlineZpos = -.7 * baselineToBot - self.font.getLineHeight( ) * t[:underlinePos].count('\n') LSunder = LineSegs() LSunder.setThickness(underscoreThickness) LSunder.moveTo(underlineXstart + texMargin, 0, underlineZpos) LSunder.drawTo(underlineXend - texMargin, 0, underlineZpos) if disabled: underline = b.attachNewNode(LSunder.create()) underline.setColor(Vec4(*textColorDisabled), 1) else: underline = b.stateNodePath[0].attachNewNode( LSunder.create()) underline.setColor(Vec4(*textColorReady), 1) underline.copyTo(b.stateNodePath[1], 10).setColor( Vec4(*textColorHover if haveSubmenu else textColorPress), 1) underline.copyTo(b.stateNodePath[2], 10).setColor(Vec4(*textColorHover), 1) hotkey = t[underlinePos].lower() if hotkey in self.hotkeys: self.hotkeys[hotkey].append(self.numItems) else: self.hotkeys[hotkey] = [self.numItems] self.accept(self.BTprefix + hotkey, self.__processHotkey, [hotkey]) self.accept(self.BTprefix + 'alt-' + hotkey, self.__processHotkey, [hotkey]) if haveSubmenu: if disabled: arrow = realArrow.instanceUnderNode(b, '') arrow.setColor(Vec4(*textColorDisabled), 1) arrow.setZ(arrowZpos) else: arrow = realArrow.instanceUnderNode( b.stateNodePath[0], 'r') arrow.setColor(Vec4(*textColorReady), 1) arrow.setZ(arrowZpos) arrPress = realArrow.instanceUnderNode( b.stateNodePath[1], 'p') arrPress.setColor(Vec4(*textColorHover), 1) arrPress.setZ(arrowZpos) arrHover = realArrow.instanceUnderNode( b.stateNodePath[2], 'h') arrHover.setColor(Vec4(*textColorHover), 1) arrHover.setZ(arrowZpos) # weird, if sort order is 0, it's obscured by the frame for a in (arrPress, arrHover): a.reparentTo(a.getParent(), sort=10) if not disabled: extraArgs = [self.numItems, f if haveSubmenu else 0] self.accept(DGG.ENTER + b.guiId, self.__hoverOnItem, extraArgs) self.accept(DGG.EXIT + b.guiId, self.__offItem) #~ self.itemCommand.append((None,0) if haveSubmenu else (f,args)) self.itemCommand.append((f, args)) if self.numItems == 0: self.firstButtonIdx = int(b.guiId[2:]) self.numItems += 1 z -= LH + self.font.getLineHeight() * self.scale[2] * EoLcount else: # SEPARATOR LINE z += LH - separatorHalfHeight - baselineToBot * self.scale[2] LSseparator.moveTo(0, 0, z) LSseparator.drawTo(self.scale[0] * .5, 0, z) LSseparator.drawTo(self.scale[0], 0, z) z -= separatorHalfHeight + baselineToTop * self.scale[2] maxWidth += 7 * arrowHalfHeight * ( anyArrow or anyShortcut) + .2 + shortcutTextMaxWidth arrowXpos = maxWidth - arrowHalfHeight realArrow.setX(arrowXpos) if anyImage: leftPad += 2 * imageHalfHeight + leftPad for sct in shortcutTexts: sct.setX(maxWidth - 2 * (arrowHalfHeight * anyArrow + .2)) for c in asList(self.menu.findAllMatches('**/DirectButton*')): numLines = c.node().getFrame()[2] c.node().setFrame( Vec4( -leftPad, maxWidth, -baselineToBot - (numLines * .1 * self.itemHeight if numLines >= 10 else 0), baselineToTop)) loadPrcFileData('', 'text-flatten 1') try: minZ = self.menu.getChild(0).getRelativePoint( b, Point3(0, 0, b.node().getFrame()[2]))[2] except: minZ = self.menu.getChild(0).getRelativePoint( self.menu, Point3( 0, 0, b.getTightBounds()[0][2]))[2] - baselineToBot * .5 try: top = self.menu.getChild(0).node().getFrame()[3] except: top = self.menu.getChild(0).getZ() + baselineToTop l, r, b, t = -leftPad - bgPad / self.scale[ 0], maxWidth + bgPad / self.scale[0], minZ - bgPad / self.scale[ 2], top + bgPad / self.scale[2] menuBG = DirectFrame(parent=self.menu.getChild(0), frameSize=(l, r, b, t), frameColor=BGColor, state=DGG.NORMAL, suppressMouse=1) menuBorder = self.menu.getChild(0).attachNewNode('border') borderVtx = ( (l, 0, b), (l, 0, .5 * (b + t)), (l, 0, t), (.5 * (l + r), 0, t), (r, 0, t), (r, 0, .5 * (b + t)), (r, 0, b), (.5 * (l + r), 0, b), (l, 0, b), ) LSborderBG = LineSegs() LSborderBG.setThickness(4) LSborderBG.setColor(0, 0, 0, .7) LSborderBG.moveTo(*(borderVtx[0])) for v in borderVtx[1:]: LSborderBG.drawTo(*v) # fills the gap at corners for v in range(0, 7, 2): LSborderBG.moveTo(*(borderVtx[v])) menuBorder.attachNewNode(LSborderBG.create()) LSborder = LineSegs() LSborder.setThickness(2) LSborder.setColor(*BGBorderColor) LSborder.moveTo(*(borderVtx[0])) for v in borderVtx[1:]: LSborder.drawTo(*v) menuBorder.attachNewNode(LSborder.create()) for v in range(1, 8, 2): LSborderBG.setVertexColor(v, Vec4(0, 0, 0, .1)) LSborder.setVertexColor(v, Vec4(.3, .3, .3, .5)) menuBorderB3 = menuBorder.getTightBounds() menuBorderDims = menuBorderB3[1] - menuBorderB3[0] menuBG.wrtReparentTo(self.menu, sort=-1) self.menu.reparentTo(self.parent) x = -menuBorderB3[0][0] * self.scale[0] for c in asList(self.menu.getChildren()): c.setX(x) self.maxWidth = maxWidth = menuBorderDims[0] self.height = menuBorderDims[2] maxWidthR2D = maxWidth * self.menu.getChild(0).getSx(render2d) separatorLines = self.menu.attachNewNode(LSseparator.create(), 10) separatorLines.setSx(maxWidth) for v in range(1, LSseparator.getNumVertices(), 3): LSseparator.setVertexColor(v, Vec4(*separatorColor)) x = clamp(-.98, .98 - maxWidthR2D, self.mpos[0] - maxWidthR2D * .5) minZ = (-.98 if self.minZ is None else self.minZ) z = clamp( minZ + menuBorderDims[2] * self.scale[2] * self.parent.getSz(render2d), .98, self.mpos[1] if useMouseZ else -1000) self.menu.setPos(render2d, x, 0, z) self.menu.setTransparency(1) self.origBTprefix = self.BT.getPrefix() self.BT.setPrefix(self.BTprefix) self.accept(self.BTprefix + 'escape', self.destroy) for e in ('mouse1', 'mouse3'): self.accept(self.BTprefix + e, self.destroy, [True]) self.accept(self.BTprefix + 'arrow_down', self.__nextItem) self.accept(self.BTprefix + 'arrow_down-repeat', self.__nextItem) self.accept(self.BTprefix + 'arrow_up', self.__prevItem) self.accept(self.BTprefix + 'arrow_up-repeat', self.__prevItem) self.accept(self.BTprefix + 'enter', self.__runSelItemCommand) self.accept(self.BTprefix + 'space', self.__runSelItemCommand) def __offItem(self, crap): self.sel = -1 self.__cancelSubmenuCreation() def __hoverOnItem(self, idx, menu, crap): self.sel = idx self.__cancelSubmenuCreation() if self.BT.getPrefix()==self.BTprefix or \ (self.submenu and self.submenuIdx==idx): self.__cancelSubmenuRemoval() if menu: if not (self.submenu and self.submenuIdx == idx): #~ if self.selByKey: #~ self.selByKey=False #~ self.__createSubmenu(idx,menu) #~ else: taskMgr.doMethodLater(.3, self.__createSubmenu, self.submenuCreationTaskName, extraArgs=[idx, menu]) else: taskMgr.doMethodLater(.5, self.__removeSubmenu, self.submenuRemovalTaskName, extraArgs=[]) def __cancelSubmenuCreation(self): taskMgr.removeTasksMatching('createSubMenu-*') def __createSubmenu(self, idx, menu): self.__cancelSubmenuCreation() self.__removeSubmenu() self.submenu = PopupMenu(items=menu, parent=self.parent, buttonThrower=self.BT, font=self.font, baselineOffset=self.baselineOffset, scale=self.scale, itemHeight=self.itemHeight, leftPad=self.leftPad, separatorHeight=self.separatorHeight, underscoreThickness=self.underscoreThickness, BGColor=self.BGColor, BGBorderColor=self.BGBorderColor, separatorColor=self.separatorColor, frameColorHover=self.frameColorHover, frameColorPress=self.frameColorPress, textColorReady=self.textColorReady, textColorHover=self.textColorHover, textColorPress=self.textColorPress, textColorDisabled=self.textColorDisabled, minZ=self.minZ, useMouseZ=False) self.submenuIdx = idx self.submenu.parentMenu = self if self.menu.getBinName(): self.submenu.menu.setBin(self.menu.getBinName(), self.menu.getBinDrawOrder() + 1) sb3 = self.submenu.menu.getTightBounds() sb = sb3[1] - sb3[0] b3 = self.menu.getTightBounds() x = b3[1][0] if render2d.getRelativePoint(self.parent, Point3(x + sb[0], 0, 0))[0] > .98: x = b3[0][0] - sb[0] if render2d.getRelativePoint(self.parent, Point3(x, 0, 0))[0] < -.98: x = self.parent.getRelativePoint(render2d, Point3(-.98, 0, 0))[0] item = self.menu.find('**/*-pg%s' % (self.firstButtonIdx + idx)) z = self.parent.getRelativePoint( item, Point3(0, 0, item.node().getFrame()[3]))[2] + self.bgPad self.submenu.menu.setPos(x, 0, max(z, self.submenu.menu.getZ())) # self.submenu.menu.setPos(x,0,z) def __nextItem(self): if self.numItems: self.sel = clamp(0, self.numItems - 1, self.sel + 1) self.__putPointerAtItem() self.selByKey = True def __prevItem(self): if self.numItems: self.sel = clamp(0, self.numItems - 1, (self.sel - 1) if self.sel > -1 else self.numItems - 1) self.__putPointerAtItem() self.selByKey = True def __putPointerAtItem(self): item = self.menu.find('**/*-pg%s' % (self.firstButtonIdx + self.sel)) fr = item.node().getFrame() c = Point3(.5 * (fr[0] + fr[1]), 0, .5 * (fr[2] + fr[3])) cR2D = render2d.getRelativePoint(item, c) x, y = int(base.win.getXSize() * .5 * (cR2D[0] + 1)), int( base.win.getYSize() * .5 * (-cR2D[2] + 1)) if '__origmovePointer' in base.win.DtoolClassDict: base.win.DtoolClassDict['__origmovePointer'](base.win, 0, x, y) else: base.win.movePointer(0, x, y) def __processHotkey(self, hotkey): itemsIdx = self.hotkeys[hotkey] if len(itemsIdx) == 1 and type( self.itemCommand[itemsIdx[0]][0]) not in SEQUENCE_TYPES: self.__runCommand(*self.itemCommand[itemsIdx[0]]) else: if self.sel in itemsIdx: idx = itemsIdx.index(self.sel) + 1 idx %= len(itemsIdx) self.sel = itemsIdx[idx] else: self.sel = itemsIdx[0] self.selByKey = True # if it's already there, putting the pointer doesn't trigger the 'enter' # event, so just bypass it if not (self.submenu and self.submenuIdx==self.sel) and\ type(self.itemCommand[itemsIdx[0]][0]) in SEQUENCE_TYPES: self.__createSubmenu(self.sel, self.itemCommand[itemsIdx[0]][0]) self.__putPointerAtItem() def __doRunCommand(self, f, args): self.destroy(delParents=True) f(*args) def __runCommand(self, f, args): if callable(f): # must be done at next frame, so shortcut key event won't bleed to the scene taskMgr.doMethodLater(.01, self.__doRunCommand, 'run menu command', extraArgs=[f, args]) def __runSelItemCommand(self): if self.sel == -1: return self.__runCommand(*self.itemCommand[self.sel]) def __cancelSubmenuRemoval(self): taskMgr.removeTasksMatching('removeSubMenu-*') def __removeSubmenu(self): self.__cancelSubmenuRemoval() if self.submenu: self.submenu.destroy() def destroy(self, delParents=False): self.__cancelSubmenuCreation() self.__removeSubmenu() self.subMenu = None self.ignoreAll() self.menu.removeNode() # if self.origBTprefix.find('menu-')==-1: # taskMgr.step() self.BT.setPrefix(self.origBTprefix) messenger.send(self.BTprefix + 'destroyed') if delParents and self.parentMenu: parent = self.parentMenu while parent.parentMenu: parent = parent.parentMenu parent.destroy() if self.parentMenu: self.parentMenu.submenuIdx = None self.parentMenu = None if callable(self.onDestroy): self.onDestroy()
class RigidBodyRig: def __init__(self): self.root = NodePath('root') def createColliders(self, pose_rig): self.colliders = list(create_colliders(self.root, pose_rig, joints_config)) def createConstraints(self, offset_scale): self.constraints = list(create_constraints(self.root, get_joint_pairs(self.root, joints_config), offset_scale)) def clearMasses(self): [collider.node().setMass(0) for collider in self.colliders] def attachCubes(self, loader): for collider in self.colliders: for i in range(collider.node().getNumShapes()): shape = collider.node().getShape(i) mat = collider.node().getShapeMat(i) scale = shape.getHalfExtentsWithMargin() transform = TransformState.makeMat(mat) cube = loader.loadModel("cube.egg") cube.setTransform(transform) cube.setScale(scale) cube.reparentTo(collider) def setScale(self, *scale): self.root.setScale(*scale) def setPos(self, *pos): self.root.setPos(*pos) def babble(self): F_all = [] for collider in self.colliders: collider_name = collider.getName() if collider_name == "Hips": continue F = random.uniform(-1.0, 1.0) * joints_config[collider_name].get("F_max", 4000.0) F_all.append(F) r = Vec3(*joints_config[collider_name].get("axis", (1, 0, 0))) r_world = collider.getQuat(self.root).xform(r) T = r_world * F collider.node().applyTorqueImpulse(T) return np.array(F_all) def apply_forces(self, F_all): i = 0 for collider in self.colliders: if collider.getName() == "Hips": continue F = F_all[i] r = Vec3(1, 0, 0) r_world = collider.getQuat(self.root).xform(r) T = r_world * F collider.node().applyTorqueImpulse(T) i += 1 def compareTo(self, target): positions = self.getJointPositions() rotations = self.getJointRotations() target_positions = target.getJointPositions() target_rotations = target.getJointRotations() err_pos = np.abs((positions - target_positions) / 200.0).sum() err_hpr = np.abs((rotations - target_rotations) / 180.0).sum() return err_pos + err_hpr def matchPose(self, pose_rig): for node, parent in pose_rig.exposed_joints: if node.getName() not in joints_config: continue joint_config = joints_config[node.getName()] if 'joints' not in joint_config: continue joints = joint_config['joints'] if len(joints) == 0: continue box_np = self.root.find(node.getName()) if len(joints) > 1: pos = node.getPos(pose_rig.actor) hpr = node.getHpr(pose_rig.actor) box_np.setPosHpr(self.root, pos, hpr) else: joint = joints.keys()[0] child_node, child_parent = next((child_node, child_parent) for child_node, child_parent in pose_rig.exposed_joints if child_node.getName() == joint) box_np.setPos(child_parent, child_node.getPos(child_parent) / 2.0) quat = Quat() lookAt(quat, child_node.getPos(child_parent), Vec3.up()) box_np.setQuat(child_parent, quat) box_np.node().clearForces() def clearForces(self): for collider in self.colliders: collider.node().clearForces() def setPos(self, *pos): self.root.setPos(*pos) def reparentTo(self, other): self.root.reparentTo(other) def setCollideMask(self, mask): for child in self.root.getChildren(): child.setCollideMask(mask) def attachRigidBodies(self, world): for collider in self.colliders: world.attachRigidBody(collider.node()) def attachConstraints(self, world): for constraint in self.constraints: world.attachConstraint(constraint, linked_collision=True) def getJointPositions(self): return np.concatenate([collider.getPos(self.root) for collider in self.colliders]) # TODO: is root necessary? def getJointRotations(self): return np.concatenate([collider.getHpr(self.root) for collider in self.colliders]) # TODO: is root necessary? def getLinearVelocities(self): return np.concatenate([collider.node().getLinearVelocity() for collider in self.colliders]) def getAngularVelocities(self): return get_angle_vec(np.concatenate([collider.node().getAngularVelocity() for collider in self.colliders]))
class Client(DirectObject): def __init__(self, parent, player, player_id, type="ContGame", game_id = TEST_GAME_ID ): self.parent = parent self.player = player self.player_id = player_id self.game_id = game_id self.type = type # Flags self._game_initialized = False # This handles message queue - we will process messages in sync one by one self._message_in_process = False # This handles interface interactions - we will not allow interaction if current animation is not done self._anim_in_process = False self.fsm = ClientFSM(self, 'ClientFSM') self.rRegion = RocketRegion.make('squad_select', base.win) self.rContext = self.rRegion.getContext() ih = RocketInputHandler() base.mouseWatcher.attachNewNode(ih) self.rRegion.setInputHandler(ih) # Initialize game mode (network) base.accept('n', render.setShaderAuto) base.accept('m', render.setShaderOff) self.net = Net(self) self.net.startNet() ClientMsg.getMyGames() if type == "ContGame": ClientMsg.enterGame( game_id ) taskMgr.doMethodLater(1, ClientMsg.forceFirstTurn, 'ForceTurn', extraArgs = []) elif type == 'NewGame': ClientMsg.startNewGame('base2', 1000, [17, 19]) def newGameStarted(self, game_id): print "aaaaaaaaaa", game_id ClientMsg.enterGame( game_id ) ClientMsg.forceFirstTurn() def getPlayerName(self, player_id): for p in self.players: if p['id'] == player_id: return p['name'] def deselectUnit(self): self.movement.deleteUnitAvailMove() self.sgm.hideVisibleEnemies() self.interface.clearUnitData() if self.sel_unit_id != None: self.sgm.unit_np_dict[self.sel_unit_id].clearAllFlags() self.sel_unit_id = None def selectUnit(self, unit_id): if self._anim_in_process == True: return if not self.units.has_key(unit_id): return if self.sel_unit_id != unit_id: self.deselectUnit() self.sel_unit_id = unit_id self.interface.processUnitData(unit_id) self.interface.printUnitData(unit_id) self.interface.refreshUnitInfo(unit_id) # If it is our turn, display available move tiles if self.player == self.turn_player: self.sgm.unit_np_dict[unit_id].setSelected() self.movement.calcUnitAvailMove(unit_id) self.sgm.showVisibleEnemies(unit_id) def selectNextUnit(self): if self.sel_unit_id == None: last = 0 else: last = self.sel_unit_id d = {} for unit_id in self.units.iterkeys(): if self.isThisMyUnit(unit_id): d[unit_id] = self.units[unit_id] l = sorted(d.iterkeys()) if len(l) <= 1: return else: if l[-1] == last: new_unit_id = l[0] else: for i in l: if i > last: new_unit_id = i break self.selectUnit(new_unit_id) def selectPrevUnit(self): if self.sel_unit_id == None: # TODO: ogs: Kaj fakat? last = 9999999 else: last = self.sel_unit_id d = {} for unit_id in self.units.iterkeys(): if self.isThisMyUnit(unit_id): d[unit_id] = self.units[unit_id] l = sorted(d.iterkeys()) l.reverse() if len(l) <= 1: return else: if l[-1] == last: new_unit_id = l[0] else: for i in l: if i < last: new_unit_id = i break self.selectUnit(new_unit_id) def refreshUnit(self, unit): if unit['alive'] == False: if self.sel_unit_id == unit['id']: self.sel_unit_id = None if self.sgm.unit_np_dict.has_key(unit['id']): self.sgm.hideUnit(unit['id']) if self.units.has_key(unit['id']): if self.isThisMyUnit(unit['id']): self.inactive_units[unit['id']] = unit self.deleteUnit(unit['id']) self.level.removeUnitDict(unit) else: self.units[unit['id']] = unit self.level.removeUnitId(unit['id']) self.level.putUnitDict(unit) def deleteUnit(self, unit_id): self.level.removeUnitId(unit_id) self.units.pop(unit_id) def getUnitData(self, unit_id): if self.units.has_key(unit_id): return self.units[unit_id] def isThisMyUnit(self, unit_id): if self.units.has_key(unit_id): if self.units[unit_id]['owner_id'] == self.player_id: return True else: return False else: return False def isThisEnemyUnit(self, unit_id): if self.units.has_key(unit_id): if self.units[unit_id]['owner_id'] != self.player_id: return True else: return False else: return False def isUnitAlive(self, unit_id): return self.units[unit_id]['alive'] def getCoordsByUnit(self, unit_id): if self.units.has_key(unit_id): unit = self.units[unit_id] return Point2(unit['pos'][0], unit['pos'][1]) def getUnitByCoords(self, pos): for u in self.units.itervalues(): if u['pos'][0] == pos.getX() and u['pos'][1] == pos.getY(): return u['id'] return None def beforeAnimHook(self): self._anim_in_process = True self.movement.deleteUnitAvailMove() self.sgm.hideVisibleEnemies() for u in self.sgm.unit_np_dict.itervalues(): u.clearTargeted() self.movement.hovered_unit_id = None def afterAnimHook(self): self._anim_in_process = False self._message_in_process = False #======================================================================== # Client animation handler methods def handleMove(self, move_msg): move = self.buildMove(move_msg) s = Sequence(Func(self.beforeAnimHook), move, Func(self.afterAnimHook)) s.start() def buildMove(self, move_msg): unit_id = move_msg[0] action_list = move_msg[1] pos = None heading = None unit_model = None s = Sequence() d = 0.0 if self.units.has_key(unit_id): pos = Point3(utils.TILE_SIZE*(self.units[unit_id]['pos'][0] + 0.5), utils.TILE_SIZE*(self.units[unit_id]['pos'][1] + 0.5), utils.GROUND_LEVEL) heading = utils.getHeadingAngle(self.units[unit_id]['heading']) if self.sgm.unit_np_dict.has_key(unit_id): unit_model = self.sgm.unit_np_dict[unit_id] else: # This is the first time we see this unit, we have no record of it in client.units dict or sgm nodepath list and dict # First action we MUST receive here is 'spot', otherwise client will break as we dont have unit_model defined None for idx, action in enumerate(action_list): action_type = action[0] if action_type == "move": end_pos = Point3(utils.TILE_SIZE*(action[1][0] + 0.5), utils.TILE_SIZE*(action[1][1] + 0.5), utils.GROUND_LEVEL) i, duration, pos, heading = self.buildMoveAnim(unit_model, pos, end_pos, heading) d += duration s.append(i) elif action_type == "rotate": end_pos = Point3(utils.TILE_SIZE*(action[1][0] + 0.5), utils.TILE_SIZE*(action[1][1] + 0.5), utils.GROUND_LEVEL) i, duration, pos, heading = self.buildRotateAnim(unit_model, pos, end_pos, heading) d += duration s.append(i) elif action_type == "spot": spotted_unit = action[1] self.units[spotted_unit['id']] = spotted_unit # Check if we have this unit in our scene graph records if self.sgm.unit_np_dict.has_key(spotted_unit['id']): spotted_unit_model = self.sgm.unit_np_dict[spotted_unit['id']] # This is the first time we see this unit, fill out starting variables for move and rotate actions else: wpn_list = utils.getUnitWeapons(spotted_unit) spotted_unit_model = self.sgm.loadUnit(spotted_unit['id'], wpn_list) # If this is our move message, means we spotted an enemy, and he will not be moving # If this is enemy move message, means we have spotted a moving enemy and we will set unit_model variable if self.isThisEnemyUnit(unit_id): unit_model = spotted_unit_model pos = Point3(utils.TILE_SIZE*(self.units[spotted_unit['id']]['pos'][0] + 0.5), utils.TILE_SIZE*(self.units[spotted_unit['id']]['pos'][1] + 0.5), utils.GROUND_LEVEL ) heading = utils.getHeadingAngle(self.units[spotted_unit['id']]['heading']) spotted_pos = pos spotted_h = heading else: spotted_pos = None spotted_h = None i = self.buildSpotAnim(spotted_unit_model, spotted_pos, spotted_h) s.append(i) elif action_type == "vanish": vanish_unit_id = action[1] spotted_later = False for a in action_list[idx:]: if a[0] == "spot": spotted_later = True break if spotted_later: i = self.buildDetachAnim(vanish_unit_id) else: i = self.buildDeleteAnim(vanish_unit_id) s.append(i) elif action_type == "overwatch": action_list = action[1] i = self.buildOverwatchAnim(action_list) s.append(i) if unit_model.fsm.state == 'Overwatch': #move = Sequence(unit_model.model.actorInterval('stand_up'), Func(unit_model.fsm.request, 'Walk'), s, Func(unit_model.fsm.request, 'Idle')) move = Sequence(unit_model.model.actorInterval('stand_up'), Func(unit_model.fsm.request, 'Walk'), s, Func(unit_model.fsm.request, 'Idle')) else: move = Sequence(Func(unit_model.fsm.request, 'Walk'), s, Func(unit_model.fsm.request, 'Idle')) return move def buildMoveAnim(self, unit_model, start_pos, end_pos, start_h): dummy_start = NodePath("dummy_start") dummy_end = NodePath("dummy_end") duration = 0.0 p = None dummy_start.setPos(start_pos) dummy_end.setPos(end_pos) dummy_start.lookAt(dummy_end) end_h = dummy_start.getH(render) # Model heading is different than movement heading, first create animation that turns model to his destination i_h = None if end_h != start_h: i_h = unit_model.model.quatInterval(0.2, hpr = Point3(end_h, 0, 0), startHpr = Point3(start_h, 0, 0)) i = unit_model.node.posInterval(0.5, end_pos, start_pos) duration += 0.5 if i_h: p = Parallel(i, i_h) else: p = i return p, duration, end_pos, end_h def buildRotateAnim(self, unit_model, start_pos, end_pos, start_h, heading=None): if heading == None: dummy_start = NodePath("dummy_start") dummy_end = NodePath("dummy_end") dummy_start.setPos(start_pos) dummy_end.setPos(end_pos) dummy_start.lookAt(dummy_end) end_h = dummy_start.getH(render) else: end_h = utils.getHeadingAngle(heading) interval = unit_model.model.quatInterval(0.2, hpr = Point3(end_h, 0, 0), startHpr = Point3(start_h, 0, 0)) duration = 0.2 return interval, duration, start_pos, end_h def buildSpotAnim(self, unit_model, pos, heading): return Sequence(Func(self.sgm.showUnit, unit_model, pos, None) ,Wait(0.2) ,Func(self.interface.setMarker, unit_model.id) ,Func(self.interface.console.consoleOutput, 'Unit spotted!', utils.CONSOLE_SYSTEM_MESSAGE) ,Func(self.interface.console.show) ) def buildDeleteAnim(self, unit_id): return Sequence(Func(self.interface.clearMarker, unit_id), Func(self.sgm.hideUnit, unit_id), Func(self.deleteUnit, unit_id), Wait(0.2)) def buildDetachAnim(self, unit_id): return Sequence(Func(self.sgm.detachUnit, unit_id), Wait(0.2)) def buildOverwatchAnim(self, action_list): i = self.buildShoot(action_list) return i def handleShoot(self, action_list): shoot = self.buildShoot(action_list) s = Sequence(Func(self.beforeAnimHook), Wait(0.2), shoot, Func(self.afterAnimHook)) s.start() def buildShoot(self, action_list): s = Sequence() d = 0.0 for action in action_list: action_type = action[0] if action_type == "shoot": shooter_id = action[1] # unit_id of the shooter shoot_tile = action[2] # (x,y) pos of targeted tile weapon = action[3] # weapon id damage_list = action[4] # list of all damaged/missed/bounced/killed units if shooter_id >= 0: shooter_model = self.sgm.unit_np_dict[shooter_id] a = self.buildShootAnim(shooter_model, weapon) shooter_pos = Point3(utils.TILE_SIZE*(self.units[shooter_id]['pos'][0] + 0.5), utils.TILE_SIZE*(self.units[shooter_id]['pos'][1] + 0.5), utils.GROUND_LEVEL ) b = self.buildBulletAnim(shooter_pos, shoot_tile) i = self.buildDamageAnim(damage_list) bi = Sequence(b, i) s.append(Parallel(a, bi)) #if action_type == "shoot": # shooter_id = action[1] # unit_id of the shooter # shoot_tile = action[2] # (x,y) pos of targeted tile # weapon = action[3] # weapon id # damage_list = action[4] # list of all damaged/missed/bounced/killed units # if shooter_id >= 0: # shooter_model = self.sgm.unit_np_dict[shooter_id] # a = self.buildShootAnim(shooter_model, weapon) # b = Sequence(Func(self.buildLaserAnim, shooter_model.node, self.sgm.unit_np_dict[damage_list[0][1]].node)) # i = self.buildDamageAnim(damage_list) # bi = Sequence(b, i) # s.append(Parallel(a, bi)) elif action_type == "melee": shooter_id = action[1] # unit_id of the shooter shoot_tile = action[2] # (x,y) pos of targeted tile weapon = action[3] # weapon id damage_list = action[4] # list of all damaged/missed/bounced/killed units shooter_model = self.sgm.unit_np_dict[shooter_id] i = self.buildMeleeAnim(shooter_model, shoot_tile, weapon) s.append(i) i = self.buildDamageAnim(damage_list) s.append(i) elif action_type == "rotate": unit_id = action[1] heading = action[2] unit_model = self.sgm.unit_np_dict[unit_id] start_h = utils.getHeadingAngle(self.units[unit_id]['heading']) i, duration, pos, h = self.buildRotateAnim(unit_model, None, None, start_h, heading) s.append(i) elif action_type == "overwatch": action_list = action[1] i = self.buildOverwatchAnim(action_list) s.append(i) # Start our shoot sequence return s def buildShootAnim(self, unit_model, weapon): # Unit shooting animation shoot_anim = Func(unit_model.fsm.request, 'Shoot') return shoot_anim def buildBulletAnim(self, start_pos, target_tile): # We create the bullet and its animation self.bullet = loader.loadModel("sphere") self.bullet.setScale(0.05) start_pos = Point3(start_pos.getX(), start_pos.getY(), 0.9) end_pos = Point3(utils.TILE_SIZE*(target_tile[0] + 0.5), utils.TILE_SIZE*(target_tile[1] + 0.5), 0.9) dest_node = NodePath("dest_node") dest_node.setPos(end_pos) start_node = NodePath("start_node") start_node.setPos(start_pos) time = round(start_node.getDistance(dest_node) / utils.BULLET_SPEED, 2) bullet_sequence = Sequence(Func(self.sgm.setBullet, self.bullet), self.bullet.posInterval(time, end_pos, start_pos), Func(self.sgm.deleteBullet, self.bullet) ) return bullet_sequence def buildLaserAnim(self, source, target): self.combat.source = source self.combat.target = target taskMgr.add(self.combat.drawBeam, 'beamtask') def buildMeleeAnim(self, unit_model, target_tile, weapon): # Unit melee animation melee_anim = Func(unit_model.fsm.request, 'Melee') return melee_anim def buildDamageAnim(self, damage_list): # Find all damaged units and play their damage/kill/miss animation damage_parallel = Parallel() for action in damage_list: damage_type = action[0] target_unit_id = action[1] target_unit = self.sgm.unit_np_dict[target_unit_id] t = TextNode('dmg') if damage_type == "bounce": target_anim = Func(target_unit.fsm.request, 'GetHit') dmg = 'bounce' elif damage_type == "miss": target_anim = Func(target_unit.fsm.request, 'GetHit') dmg = 'miss' elif damage_type == "damage": color_interval = Sequence(LerpColorScaleInterval(target_unit.model, 0.2, (10,10,10,1)) ,LerpColorScaleInterval(target_unit.model, 0.2, (1,1,1,1))) target_anim = Sequence(Func(target_unit.fsm.request, 'GetHit') , color_interval) dmg = str(action[2]) elif damage_type == "kill": color_interval = Sequence(LerpColorScaleInterval(target_unit.model, 0.2, (10,10,10,1)) ,LerpColorScaleInterval(target_unit.model, 0.2, (1,1,1,1))) target_anim = Parallel(Func(target_unit.fsm.request, 'Die') , color_interval) dmg = str(action[2]) t.setText( "%s" % dmg) t.setTextColor(1, 0, 0, 1) t.setAlign(TextNode.ACenter) textNodePath = NodePath("textnp") textNodePath.attachNewNode(t) textNodePath.setScale(0.35) textNodePath.setBillboardPointEye() textNodePath.setLightOff() # textNodePath will be reparented to unitmodel, so set start and end pos relative to the unit start_pos = Point3(0, 0, 0.9) end_pos = start_pos + Point3(0, 0, 3) damage_text_sequence = Sequence(Func(self.sgm.setDamageNode, textNodePath, target_unit.node), textNodePath.posInterval(1, end_pos, start_pos), Func(self.sgm.deleteDamageNode, textNodePath) ) damage_parallel = Parallel(damage_text_sequence, target_anim) return damage_parallel def handleVanish(self, unit_id): i = self.buildDeleteAnim(unit_id) s = Sequence(i, Func(self.afterAnimHook)) s.start() def handleSpot(self, unit): self.units[unit['id']] = unit # This is the first time we see this unit, fill out starting variables for move and rotate actions wpn_list = utils.getUnitWeapons(unit) spotted_unit_model = self.sgm.loadUnit(unit['id'], wpn_list) pos = Point3(utils.TILE_SIZE*(self.units[unit['id']]['pos'][0] + 0.5), utils.TILE_SIZE*(self.units[unit['id']]['pos'][1] + 0.5), utils.GROUND_LEVEL ) heading = utils.getHeadingAngle(self.units[unit['id']]['heading']) i = self.buildSpotAnim(spotted_unit_model, pos, heading) s = Sequence(i, Func(self.afterAnimHook)) s.start() def handleNewTurn(self): text = TextNode('new turn node') text.setText("TURN: "+self.turn_player) textnp = NodePath("textnp") textNodePath = textnp.attachNewNode(text) textNodePath.setColor(1, 0, 0) textNodePath.setScale(0.01, 0.01, 0.01) textNodePath.setPos(-0.7, 0, 0) textNodePath.reparentTo(aspect2d) s = Sequence(textNodePath.scaleInterval(.3, textNodePath.getScale()*20,blendType='easeIn'), Wait(1.0), textNodePath.scaleInterval(.3, textNodePath.getScale()*0.05,blendType='easeIn'), Func(self.sgm.deleteTurnNode, textNodePath), Func(self.afterAnimHook) ) s.start() def setCamPoss(self, off): self.altCam.setPos(self.altCam.getPos() + Point3(0, 0, 0.1)*off) print self.altCam.getPos() def setCamLook(self, off): self.altCam.setP(self.altCam.getP() + 0.5*off) print self.altCam.getP() def deploySquadScreen(self): self.dr2 = base.win.makeDisplayRegion(0.0, 0.5, 0.65, 1.0) self.dr2.setClearColor(VBase4(0, 0, 0, 0.3)) self.dr2.setClearColorActive(False) self.dr2.setClearDepthActive(True) self.render2 = NodePath('render2') self.cam2 = self.render2.attachNewNode(Camera('cam2')) self.cam2.node().getLens().setAspectRatio(1.8) self.dr2.setCamera(self.cam2) self.floor2np = self.render2.attachNewNode('floor2') tex = loader.loadTexture('scifi_floor.png') tex.setMagfilter(Texture.FTLinearMipmapLinear) tex.setMinfilter(Texture.FTLinearMipmapLinear) cm = CardMaker('cm_floor') cm.setFrame(0, 1, 0, 1) for x in xrange(10): for y in xrange(10): cpos = self.floor2np.attachNewNode(cm.generate()) cpos.setPos(x-5, y-5, 0) cpos.setP(-90) cpos.setTexture(tex) self.floor2np.flattenStrong() self.cam2.setPos(0, -10, 5) self.cam2.setP(-20) for idx, u in enumerate(self.deploy_queue): unit = utils.loadUnit('marine', u.lower(), self.player_id) unit.reparentTo(self.render2) unit.setScale(1) if idx == 0: unit.setPos(0, 0, 0) elif idx == 1: unit.setPos(1.5, 1.5, 0) unit.setH(-20) elif idx == 2: unit.setPos(-1.5, 1.8, 0) unit.setH(-10) elif idx == 3: unit.setPos(2.2, 2.5, 0) unit.setH(-20) elif idx == 4: unit.setPos(-1.4, 3.5, 0) elif idx == 5: unit.setPos(3.5, -0.5, 0) unit.setH(-35) elif idx == 6: unit.setPos(-2.6, 2.5, 0) unit.setH(30) elif idx == 7: unit.setPos(-4.5, 0, 0) unit.setH(40) unit.setTag('id', str(idx)) unit.setTag('type', u.lower()) self.altalight = AmbientLight("alight") self.altalight.setColor(VBase4(0.2, 0.2, 0.2, 1.0)) self.altalnp = self.render2.attachNewNode(self.altalight) self.render2.setLight(self.altalnp) self.altalight2 = AmbientLight("alight2") self.altalight2.setColor(VBase4(0.4, 0.4, 0.4, 1.0)) self.altalnp2 = self.render2.attachNewNode(self.altalight2) self.altslight = Spotlight('slight') self.altslight.setColor(VBase4(0.6, 0.6, 0.6, 1)) self.altslnp = self.render2.attachNewNode(self.altslight) self.altslnp.setPos(5, 1, 15) self.altslnp.lookAt(0, 0, 0) self.render2.setLight(self.altslnp) self.render2.setShaderAuto() self.deploy_index = 0 self.deploy_unit_np = render.attachNewNode('deploy_unit_np') self.getDeployee() def getDeployee(self): if len(self.deploy_queue) > self.deploy_index: self.deploy_unit = self.render2.find('=id='+str(self.deploy_index)) self.deploy_unit.setLight(self.altalnp2) self.deploy_index += 1 else: self.deploy_unit = None def deployUnit(self): if self.deploy_unit != None: if base.mouseWatcherNode.hasMouse(): mpos = base.mouseWatcherNode.getMouse() pos3d = Point3() nearPoint = Point3() farPoint = Point3() base.camLens.extrude(mpos, nearPoint, farPoint) if self.plane.intersectsLine(pos3d, render.getRelativePoint(camera, nearPoint), render.getRelativePoint(camera, farPoint)): pos = (int(pos3d.getX()), int(pos3d.getY())) if self.deploy_dict.has_key(pos) and self.deploy_dict[pos] == None: unit = self.deploy_unit unit.reparentTo(self.deploy_unit_np) unit.setScale(0.3) unit.setPos(int(pos3d.getX()) + 0.5, int(pos3d.getY()) + 0.5, utils.GROUND_LEVEL) self.deploy_dict[pos] = unit.getTag('type') self.deploy_unit.setLightOff() self.getDeployee() def endDeploy(self): if len(self.deploy_queue) > self.deploy_index: print "You must deploy all units" else: army_list = [] for key in self.deploy_dict: if self.deploy_dict[key] != None: tup = (key[0], key[1], 'marine_'+self.deploy_dict[key]) army_list.append(tup) ClientMsg.armyList(army_list) @pstat def getInvisibleTiles(self): a = [] for u in self.units: if self.isThisMyUnit(u): a.append(self.units[u]) t = time.clock() l = levelVisibilityDict(a, self.level) print "tiles timer:::", (time.clock()-t)*1000 return l @pstat def getInvisibleWalls(self): a = [] for u in self.units: if self.isThisMyUnit(u): a.append(self.units[u]) t = time.clock() l = visibleWalls(a, self.level) print "walls timer:::", (time.clock()-t)*1000 return l
class TownLoader(StateData): notify = directNotify.newCategory("TownLoader") def __init__(self, hood, parentFSMState, doneEvent): self.hood = hood self.parentFSMState = parentFSMState StateData.__init__(self, doneEvent) self.fsm = ClassicFSM('TownLoader', [ State('start', self.enterStart, self.exitStart, ['quietZone', 'street', 'toonInterior']), State('street', self.enterStreet, self.exitStreet, ['quietZone']), State('toonInterior', self.enterToonInterior, self.exitToonInterior, ['quietZone']), State('suitInterior', self.enterSuitInterior, self.exitSuitInterior, ['quietZone']), State('quietZone', self.enterQuietZone, self.exitQuietZone, ['street', 'toonInterior', 'suitInterior']), State('final', self.enterFinal, self.exitFinal, ['start']) ], 'start', 'final') self.branchZone = None self.canonicalBranchZone = None self.placeDoneEvent = 'placeDone' self.streetSong = '' self.interiorSong = '' self.linkTunnels = [] self.place = None return def findAndMakeLinkTunnels(self, requestStatus): for tunnel in self.geom.findAllMatches('**/*linktunnel*'): dnaRootStr = tunnel.getName() zone = LinkTunnel.getZoneFromDNARootStr(dnaRootStr) zone = LinkTunnel.maybeFixZone(zone) tunnelClass = LinkTunnel.getRecommendedTunnelClassFromZone(zone) link = tunnelClass(tunnel, dnaRootStr) self.linkTunnels.append(link) def load(self, zoneId): StateData.load(self) self.zoneId = zoneId self.branchZone = ZoneUtil.getBranchZone(zoneId) self.canonicalBranchZone = ZoneUtil.getCanonicalBranchZone(zoneId) def unload(self): self.parentFSMState.removeChild(self.fsm) del self.parentFSMState del self.fsm del self.streetClass base.disablePhysicsNodes(self.landmarkBlocks) self.landmarkBlocks.removeNode() del self.landmarkBlocks self.hood.dnaStore.resetSuitPoints() self.hood.dnaStore.resetBattleCells() del self.hood del self.nodeDict del self.zoneDict del self.fadeInDict del self.fadeOutDict del self.nodeList del self.zoneVisDict base.disablePhysicsNodes(self.geom) self.geom.removeNode() del self.geom del self.streetSong del self.interiorSong #CIGlobals.doSceneCleanup() StateData.unload(self) def enter(self, requestStatus): StateData.enter(self) self.findAndMakeLinkTunnels(requestStatus) self.fsm.enterInitialState() self.setState(requestStatus['where'], requestStatus) def exit(self): self.fsm.requestFinalState() self.ignoreAll() ModelPool.garbageCollect() TexturePool.garbageCollect() StateData.exit(self) def setState(self, state, requestStatus): self.fsm.request(state, [requestStatus]) def enterStart(self): pass def exitStart(self): pass def enterStreet(self, requestStatus): self.acceptOnce(self.placeDoneEvent, self.streetDone) self.place = self.streetClass(self, self.fsm, self.placeDoneEvent) self.place.load() def exitStreet(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) return def streetDone(self): self.requestStatus = self.place.doneStatus status = self.place.doneStatus if (status['loader'] == 'townLoader' and ZoneUtil.getBranchZone(status['zoneId']) == self.branchZone and status['shardId'] is None or status['how'] == 'doorOut' or status['where'] == 'suitInterior'): self.fsm.request('quietZone', [status]) else: self.doneStatus = status messenger.send(self.doneEvent) def enterToonInterior(self, requestStatus): self.acceptOnce(self.placeDoneEvent, self.handleToonInteriorDone) self.place = ToonInterior.ToonInterior(self, self.fsm, self.placeDoneEvent) self.place.load() def exitToonInterior(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) return def enterSuitInterior(self, requestStatus): self.acceptOnce(self.placeDoneEvent, self.handleSuitInteriorDone) self.place = CogOfficeInterior.CogOfficeInterior( self, self.fsm, self.placeDoneEvent) self.place.load() def exitSuitInterior(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) def enterThePlace(self, requestStatus): base.cr.playGame.setPlace(self.place) if self.place is not None: self.place.enter(requestStatus) def handleToonInteriorDone(self): status = self.place.doneStatus if (status['loader'] == 'townLoader' and ZoneUtil.getBranchZone(status['zoneId']) == self.branchZone and status['shardId'] is None or status['how'] == 'doorOut'): self.fsm.request('quietZone', [status]) else: self.doneStatus = status messenger.send(self.doneEvent) return def handleSuitInteriorDone(self): self.handleToonInteriorDone() def enterQuietZone(self, requestStatus): self.fsm.request(requestStatus['where'], [requestStatus], exitCurrent=0) self.quietZoneDoneEvent = uniqueName('quietZoneDone') self.acceptOnce(self.quietZoneDoneEvent, self.handleQuietZoneDone) self.quietZoneStateData = QuietZoneState(self.quietZoneDoneEvent) self.quietZoneStateData.load() self.quietZoneStateData.enter(requestStatus) def exitQuietZone(self): self.ignore(self.quietZoneDoneEvent) del self.quietZoneDoneEvent self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None return def handleQuietZoneDone(self): status = self.quietZoneStateData.getRequestStatus() self.exitQuietZone() self.enterThePlace(status) def enterFinal(self): pass def exitFinal(self): pass def createHood(self, dnaFile, loadStorage=1, flattenNow=True): if loadStorage: loader.loadDNAFile(self.hood.dnaStore, 'phase_5/dna/storage_town.pdna') loader.loadDNAFile(self.hood.dnaStore, self.townStorageDNAFile) node = loader.loadDNAFile(self.hood.dnaStore, dnaFile) if node.getNumParents() == 1: self.geom = NodePath(node.getParent(0)) self.geom.reparentTo(hidden) else: self.geom = hidden.attachNewNode(node) if flattenNow: self.doFlatten() self.geom.setName('town_top_level') def doFlatten(self): self.makeDictionaries(self.hood.dnaStore) self.reparentLandmarkBlockNodes() base.createPhysicsNodes(self.geom) self.renameFloorPolys(self.nodeList) self.geom.flattenLight() CIGlobals.preRenderScene(self.geom) def reparentLandmarkBlockNodes(self): bucket = self.landmarkBlocks = hidden.attachNewNode('landmarkBlocks') npc = self.geom.findAllMatches('**/sb*:*_landmark_*_DNARoot') for i in xrange(npc.getNumPaths()): nodePath = npc.getPath(i) nodePath.wrtReparentTo(bucket) npc = self.geom.findAllMatches('**/sb*:*animated_building*_DNARoot') for i in xrange(npc.getNumPaths()): nodePath = npc.getPath(i) nodePath.wrtReparentTo(bucket) def makeDictionaries(self, dnaStore): self.nodeDict = {} self.zoneDict = {} self.zoneVisDict = {} self.nodeList = [] self.fadeInDict = {} self.fadeOutDict = {} a1 = Vec4(1, 1, 1, 1) a0 = Vec4(1, 1, 1, 0) numVisGroups = dnaStore.getNumDNAVisGroupsAI() for i in xrange(numVisGroups): groupFullName = dnaStore.getDNAVisGroupName(i) visGroup = dnaStore.getDNAVisGroupAI(i) groupName = base.cr.hoodMgr.extractGroupName(groupFullName) zoneId = int(groupName) zoneId = ZoneUtil.getTrueZoneId(zoneId, self.zoneId) groupNode = self.geom.find('**/' + groupFullName) if groupNode.isEmpty(): continue else: if ':' in groupName: groupName = '%s%s' % (zoneId, groupName[groupName.index(':'):]) else: groupName = '%s' % zoneId groupNode.setName(groupName) CIGlobals.replaceDecalEffectsWithDepthOffsetAttrib(groupNode) #group all the flat walls block2flatwall = {} flatwalls = groupNode.findAllMatches("**/tb*:*_DNARoot;+s") for flatwall in flatwalls: if "toon_landmark" in flatwall.getName(): print "Skipping", flatwall.getName() continue if flatwall.hasTag("DNACode") and flatwall.hasMat(): continue block = int(flatwall.getName().split(":")[0][2:]) if not block2flatwall.has_key(block): block2flatwall[block] = groupNode.attachNewNode( ModelNode('toonBuildingsBlock' + str(block))) flatwall.wrtReparentTo(block2flatwall[block]) for node in block2flatwall.values(): for child in node.findAllMatches("**"): child.clearEffect(DecalEffect.getClassType()) child.clearTag("DNACode") child.clearTag("cam") CIGlobals.clearModelNodesBelow(node) node.flattenStrong() flattenGroup = groupNode.attachNewNode('optim') flattens = ['street*_DNARoot'] removes = ['interactive_prop*_DNARoot'] for remove in removes: for np in groupNode.findAllMatches("**/" + remove): np.removeNode() for flatten in flattens: for np in groupNode.findAllMatches("**/" + flatten): if np.hasTag("DNACode") and np.hasMat(): continue for child in np.findAllMatches("**"): child.clearEffect(DecalEffect.getClassType()) child.clearTag("DNACode") child.clearTag("cam") np.wrtReparentTo(flattenGroup) flattenGroup.clearModelNodes() flattenGroup.flattenStrong() CIGlobals.flattenModelNodes(groupNode) groupNode.flattenStrong() #groupNode.ls() self.nodeDict[zoneId] = [] self.nodeList.append(groupNode) self.zoneDict[zoneId] = groupNode visibles = [] for i in xrange(visGroup.getNumVisibles()): visibles.append(int(visGroup.get_visible(i))) visibles.append(ZoneUtil.getBranchZone(zoneId)) self.zoneVisDict[zoneId] = visibles fadeDuration = 0.5 self.fadeOutDict[groupNode] = Sequence( Func(groupNode.setTransparency, 1), LerpColorScaleInterval(groupNode, fadeDuration, a0, startColorScale=a1), Func(groupNode.clearColorScale), Func(groupNode.clearTransparency), Func(groupNode.stash), Func(base.disablePhysicsNodes, groupNode), name='fadeZone-' + str(zoneId), autoPause=1) self.fadeInDict[groupNode] = Sequence( Func(base.enablePhysicsNodes, groupNode), Func(groupNode.unstash), Func(groupNode.setTransparency, 1), LerpColorScaleInterval(groupNode, fadeDuration, a1, startColorScale=a0), Func(groupNode.clearColorScale), Func(groupNode.clearTransparency), name='fadeZone-' + str(zoneId), autoPause=1) for i in xrange(numVisGroups): groupFullName = dnaStore.getDNAVisGroupName(i) zoneId = int(base.cr.hoodMgr.extractGroupName(groupFullName)) zoneId = ZoneUtil.getTrueZoneId(zoneId, self.zoneId) for j in xrange(dnaStore.getNumVisiblesInDNAVisGroup(i)): visName = dnaStore.getVisibleName(i, j) groupName = base.cr.hoodMgr.extractGroupName(visName) nextZoneId = int(groupName) nextZoneId = ZoneUtil.getTrueZoneId(nextZoneId, self.zoneId) visNode = self.zoneDict[nextZoneId] self.nodeDict[zoneId].append(visNode) self.hood.dnaStore.resetPlaceNodes() self.hood.dnaStore.resetDNAGroups() self.hood.dnaStore.resetDNAVisGroups() self.hood.dnaStore.resetDNAVisGroupsAI() def renameFloorPolys(self, nodeList): for i in nodeList: collNodePaths = i.findAllMatches('**/+BulletRigidBodyNode') numCollNodePaths = collNodePaths.getNumPaths() visGroupName = i.node().getName() for j in xrange(numCollNodePaths): collNodePath = collNodePaths.getPath(j) bitMask = collNodePath.node().getIntoCollideMask() if bitMask == CIGlobals.FloorGroup: collNodePath.node().setName(visGroupName) collNodePath.setCollideMask(CIGlobals.StreetVisGroup)
class GunGameLevelLoader: notify = directNotify.newCategory('GunGameLevelLoader') LevelData = {'momada': {'name': CIGlobals.ToonBattleOriginalLevel, 'camera': ( Point3(0.0, -25.8, 7.59), Vec3(0.0, 0.0, 0.0)), 'models': [ 'phase_11/models/lawbotHQ/LB_Zone03a.bam', 'phase_11/models/lawbotHQ/LB_Zone04a.bam', 'phase_11/models/lawbotHQ/LB_Zone7av2.bam', 'phase_11/models/lawbotHQ/LB_Zone08a.bam', 'phase_11/models/lawbotHQ/LB_Zone13a.bam', 'phase_10/models/cashbotHQ/ZONE17a.bam', 'phase_10/models/cashbotHQ/ZONE18a.bam', 'phase_11/models/lawbotHQ/LB_Zone22a.bam'], 'parents': [ render, 'EXIT', 'EXIT', 'EXIT', 'ENTRANCE', 'ENTRANCE', 'ENTRANCE', 'EXIT'], 'model_positions': [ Point3(0.0, 0.0, 0.0), Point3(-1.02, 59.73, 0.0), Point3(0.0, 74.77, 0.0), Point3(0.0, 89.37, -13.5), Point3(16.33, -136.53, 0.0), Point3(-1.01, -104.4, 0.0), Point3(0.65, -23.86, 0.0), Point3(-55.66, -29.01, 0.0)], 'model_orientations': [ Vec3(0.0, 0.0, 0.0), Vec3(0.0, 0.0, 0.0), Vec3(90.0, 0.0, 0.0), Vec3(180.0, 0.0, 0.0), Vec3(97.0, 0.0, 0.0), Vec3(359.95, 0.0, 0.0), Vec3(90.0, 0.0, 0.0), Vec3(270.0, 0.0, 0.0)], 'spawn_points': [ ( Point3(0, 0, 0), Vec3(0, 0, 0)), ( Point3(-20, 50, 0), Vec3(0, 0, 0)), ( Point3(20, 50, 0), Vec3(0, 0, 0)), ( Point3(0, 120, 0), Vec3(0, 0, 0)), ( Point3(0, 100, 0), Vec3(180, 0, 0)), ( Point3(-90, 0, 0), Vec3(0, 0, 0)), ( Point3(-170, 0, 0), Vec3(0, 0, 0)), ( Point3(-90, 50, 0), Vec3(0, 0, 0)), ( Point3(-170, 50, 0), Vec3(0, 0, 0)), ( Point3(35, 250, 0), Vec3(-90, 0, 0)), ( Point3(0, 285, 0), Vec3(180, 0, 0)), ( Point3(-185, 250, 0), Vec3(90, 0, 0))]}, 'dg': {'name': CIGlobals.DaisyGardens, 'camera': ( Point3(-33.13, -3.2, 48.62), Vec3(326.31, 332.68, 0.0)), 'dna': [ 'phase_8/dna/storage_DG.pdna', 'phase_8/dna/storage_DG_sz.pdna', 'phase_8/dna/daisys_garden_sz.pdna'], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[CIGlobals.DaisyGardens]}, 'mml': {'name': CIGlobals.MinniesMelodyland, 'camera': ( Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.8, 0.0)), 'dna': [ 'phase_6/dna/storage_MM.pdna', 'phase_6/dna/storage_MM_sz.pdna', 'phase_6/dna/minnies_melody_land_sz.pdna'], 'sky': 'MM', 'spawn_points': hoodMgr.dropPoints[CIGlobals.MinniesMelodyland]}, 'oz': {'name': CIGlobals.OutdoorZone, 'camera': ( Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.8, 0.0)), 'dna': [ 'phase_6/dna/storage_OZ.pdna', 'phase_6/dna/storage_OZ_sz.pdna', 'phase_6/dna/outdoor_zone_sz.pdna'], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[CIGlobals.OutdoorZone]}, 'cbhq': {'name': CIGlobals.CashbotHQ, 'camera': ( Point3(302.64, 5.0, 15.2), Vec3(135.0, 341.57, 0.0)), 'model': 'phase_10/models/cogHQ/CashBotShippingStation.bam', 'sky': None, 'spawn_points': hoodMgr.dropPoints[CIGlobals.CashbotHQ]}, 'sbf': {'name': CIGlobals.SellbotFactory, 'camera': ( Point3(0, 0, 0), Vec3(0, 0, 0)), 'model': 'phase_9/models/cogHQ/SelbotLegFactory.bam', 'sky': 'cog', 'sky_scale': 10.0, 'occluders': 'phase_9/models/cogHQ/factory_sneak_occluders.egg', 'spawn_points': {GGG.Teams.BLUE: [ ( Point3(13, 30, 3.73), Point3(0, 0, 0)), (Point3(21, 30, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0)), ( Point3(13, 20, 3.73), Point3(0, 0, 0)), (Point3(21, 20, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0))], GGG.Teams.RED: [ ( Point3(-644.43, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 363.22, 8.73), Point3(270, 0, 0)), ( Point3(-659.05, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 363.22, 8.73), Point3(270, 0, 0))]}, 'flag_points': {GGG.Teams.BLUE: [Point3(213.23, 340.59, 19.73), Point3(90, 0, 0)], GGG.Teams.RED: [ Point3(-543.6, 595.79, 9.73), Point3(270, 0, 0)]}, 'flagpoint_points': {GGG.Teams.BLUE: [Point3(-543.6, 595.79, 9.73), Point3(270, 0, 0)], GGG.Teams.RED: [ Point3(213.23, 340.59, 19.73), Point3(0, 0, 0)]}}, 'ttc': {'name': CIGlobals.ToontownCentral, 'dna': [ 'phase_4/dna/storage_TT.pdna', 'phase_4/dna/storage_TT_sz.pdna', 'phase_4/dna/new_ttc_sz.pdna'], 'sky': 'TT', 'spawn_points': [ (9.90324401855, 91.9139556885, 8.0364112854, -545.909545898, 0.0, 0.0), (77.9181442261, 50.953086853, 7.52815723419, -598.509460449, 0.0, 0.0), (93.7379760742, 6.37303066254, 7.99749088287, -626.209533691, 0.0, 0.0), (39.0383415222, -81.5989837646, 8.01874637604, -694.309265137, 0.0, 0.0), (-19.2093048096, -95.1359481812, 8.07303524017, -731.409240723, 0.0, 0.0), (-84.4093933105, -45.4780502319, 8.06541728973, -781.809143066, 0.0, 0.0), (-92.2512283325, 2.41426730156, 8.03108692169, -811.70916748, 0.0, 0.0), (46.8868179321, 81.3593673706, 8.04793071747, -955.309509277, 0.0, 0.0), (32.3203735352, 90.0017929077, 8.06353855133, -884.409301758, 0.0, 0.0)], 'cap_point': Point3(-1.5, 0, 0)}} SkyData = {'TT': 'phase_3.5/models/props', 'MM': 'phase_6/models/props', 'cog': 'phase_9/models/cogHQ', 'MovingSkies': [ 'TT']} def __init__(self, mg): self.mg = mg self.levelName = None self.dnaStore = DNAStorage() self.loadingText = None self.levelGeom = None self.skyUtil = None self.skyModel = None self.occluders = None self.momadaAreas = [] self.momadaAreaName2areaModel = {} return def getFlagPoint_Point(self, team): return self.LevelData[self.levelName]['flagpoint_points'][team] def getFlagPoint(self, team): return self.LevelData[self.levelName]['flag_points'][team] def getCapturePoint(self): return self.LevelData[self.levelName]['cap_point'] def setLevel(self, level): self.levelName = level def getLevel(self): return self.levelName def getCameraOfCurrentLevel(self): return self.LevelData[self.getLevel()]['camera'] def getSpawnPoints(self): pointData = self.LevelData[self.levelName]['spawn_points'] if self.levelName == 'momada': return pointData if self.mg.gameMode in [GGG.GameModes.CASUAL, GGG.GameModes.KOTH]: array = [] for posAndHpr in pointData: array.append(( Point3(posAndHpr[0], posAndHpr[1], posAndHpr[2]), Vec3(posAndHpr[3], posAndHpr[4], posAndHpr[5]))) else: if self.mg.gameMode == GGG.GameModes.CTF: array = pointData[self.mg.team] return array def getNameOfCurrentLevel(self): return self.LevelData[self.getLevel()]['name'] def load(self): self.unload() if self.loadingText: self.loadingText.destroy() self.loadingText = None self.loadingText = OnscreenText(text='', font=CIGlobals.getMinnieFont(), fg=(1, 1, 1, 1)) self.loadingText.setBin('gui-popup', 0) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() if self.levelName == 'momada': self.__momadaLoad() else: if self.levelName in ('cbhq', 'sbf'): modelPath = self.LevelData[self.levelName]['model'] self.levelGeom = loader.loadModel(modelPath) self.levelGeom.flattenMedium() self.levelGeom.reparentTo(render) if self.LevelData[self.levelName]['sky'] != None: self.skyModel = loader.loadModel(self.SkyData['cog'] + '/cog_sky.bam') self.skyUtil = SkyUtil() self.skyUtil.startSky(self.skyModel) self.skyModel.reparentTo(render) self.skyModel.setScale(self.LevelData[self.levelName].get('sky_scale', 1.0)) if self.LevelData[self.levelName].get('occluders'): self.occluders = loader.loadModel(self.LevelData[self.levelName]['occluders']) for occluderNode in self.occluders.findAllMatches('**/+OccluderNode'): base.render.setOccluder(occluderNode) occluderNode.node().setDoubleSided(True) if self.levelName == 'sbf': base.camLens.setFar(250) else: dnaFiles = self.LevelData[self.levelName]['dna'] skyType = self.LevelData[self.levelName]['sky'] skyPhase = self.SkyData[skyType] loadDNAFile(self.dnaStore, 'phase_4/dna/storage.pdna') for index in range(len(dnaFiles)): if index == len(dnaFiles) - 1: node = loadDNAFile(self.dnaStore, dnaFiles[index]) if node.getNumParents() == 1: self.levelGeom = NodePath(node.getParent(0)) self.levelGeom.reparentTo(hidden) else: self.levelGeom = hidden.attachNewNode(node) if self.levelName == 'ttc' and dnaFiles[index] == 'phase_4/dna/new_ttc_sz.pdna': self.levelGeom.find('**/prop_gazebo_DNARoot').removeNode() else: self.levelGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.levelGeom.prepareScene(gsg) self.levelGeom.reparentTo(render) else: loadDNAFile(self.dnaStore, dnaFiles[index]) children = self.levelGeom.findAllMatches('**/*doorFrameHole*') for child in children: child.hide() self.skyModel = loader.loadModel(skyPhase + '/' + skyType + '_sky.bam') self.skyUtil = SkyUtil() self.skyUtil.startSky(self.skyModel) self.skyModel.reparentTo(camera) ce = CompassEffect.make(NodePath(), CompassEffect.PRot | CompassEffect.PZ) self.skyModel.node().setEffect(ce) if self.loadingText: self.loadingText.destroy() self.loadingText = None return def __momadaLoad(self): def attachArea(itemNum): name = 'MomadaArea-%s' % itemNum area = self.momadaAreaName2areaModel.get(name) parents = self.LevelData['momada']['parents'] parent = parents[itemNum] if type(parent) == type(''): parent = self.momadaAreas[itemNum - 1].find('**/' + parent) pos = self.LevelData['momada']['model_positions'][itemNum] hpr = self.LevelData['momada']['model_orientations'][itemNum] area.reparentTo(parent) area.setPos(pos) area.setHpr(hpr) _numItems = 0 name = None for item in self.LevelData['momada']['models']: name = 'MomadaArea-%s' % _numItems area = loader.loadModel(item) self.momadaAreas.append(area) self.momadaAreaName2areaModel[name] = area attachArea(_numItems) _numItems += 1 self.notify.info('Loaded and attached %s momada areas.' % _numItems) return def unload(self): render.clearOccluder() if self.levelName == 'sbf': base.camLens.setFar(CIGlobals.DefaultCameraFar) if self.levelName == 'momada': for area in self.momadaAreas: self.momadaAreas.remove(area) area.removeNode() del area self.momadaAreas = [] self.momadaAreaName2areaModel = {} else: if self.occluders: self.occluders.removeNode() self.occluders = None if self.skyUtil: self.skyUtil.stopSky() self.skyUtil = None if self.skyModel: self.skyModel.removeNode() self.skyModel = None if self.levelGeom: self.levelGeom.removeNode() self.levelGeom = None return def cleanup(self): self.momadaAreas = None self.momadaAreaName2areaModel = None if self.dnaStore: self.dnaStore.reset_nodes() self.dnaStore.reset_hood_nodes() self.dnaStore.reset_place_nodes() self.dnaStore.reset_hood() self.dnaStore.reset_fonts() self.dnaStore.reset_DNA_vis_groups() self.dnaStore.reset_textures() self.dnaStore.reset_block_numbers() self.dnaStore.reset_block_zones() self.dnaStore.reset_suit_points() self.dnaStore = None return
class SafeZoneLoader(StateData): notify = directNotify.newCategory('SafeZoneLoader') def __init__(self, hood, parentFSMState, doneEvent): StateData.__init__(self, doneEvent) self.hood = hood self.parentFSMState = parentFSMState self.fsm = ClassicFSM('safeZoneLoader', [ State('off', self.enterOff, self.exitOff), State('playground', self.enterPlayground, self.exitPlayground, ['quietZone']), State('toonInterior', self.enterToonInterior, self.exitToonInterior, ['quietZone']), State('quietZone', self.enterQuietZone, self.exitQuietZone, ['playground', 'toonInterior']) ], 'off', 'off') self.placeDoneEvent = 'placeDone' self.place = None self.playground = None self.battleMusic = None self.invasionMusic = None self.invasionMusicFiles = None self.interiorMusic = None self.bossBattleMusic = None self.music = None self.tournamentMusic = None self.linkTunnels = [] self.szHolidayDNAFile = None self.animatedFish = None return def findAndMakeLinkTunnels(self): for tunnel in self.geom.findAllMatches('**/*linktunnel*'): dnaRootStr = tunnel.getName() link = LinkTunnel.SafeZoneLinkTunnel(tunnel, dnaRootStr) self.linkTunnels.append(link) def load(self): StateData.load(self) if self.pgMusicFilename: if type(self.pgMusicFilename) == types.ListType: filename = random.choice(self.pgMusicFilename) else: filename = self.pgMusicFilename self.music = base.loadMusic(filename) if self.battleMusicFile: self.battleMusic = base.loadMusic(self.battleMusicFile) if self.invasionMusicFiles: self.invasionMusic = None if self.bossBattleMusicFile: self.bossBattleMusic = base.loadMusic(self.bossBattleMusicFile) if self.interiorMusicFilename: self.interiorMusic = base.loadMusic(self.interiorMusicFilename) if self.tournamentMusicFiles: self.tournamentMusic = None self.createSafeZone(self.dnaFile) children = self.geom.findAllMatches('**/*doorFrameHole*') for child in children: child.hide() self.parentFSMState.addChild(self.fsm) _, _, _, _, _, _, _, _, af = SettingsManager().getSettings( 'settings.json') if af == 'on': self.notify.info( 'Anisotropic Filtering is on, applying to textures.') for nodepath in self.geom.findAllMatches('*'): try: for node in nodepath.findAllMatches('**'): try: node.findTexture('*').setAnisotropicDegree(8) except: pass except: continue return def unload(self): StateData.unload(self) if self.animatedFish: self.animatedFish.cleanup() self.animatedFish.removeNode() self.animatedFish = None self.parentFSMState.removeChild(self.fsm) del self.parentFSMState del self.animatedFish self.geom.removeNode() del self.geom del self.fsm del self.hood del self.playground del self.music del self.interiorMusic del self.battleMusic del self.bossBattleMusic del self.tournamentMusic self.ignoreAll() ModelPool.garbageCollect() TexturePool.garbageCollect() return def enter(self, requestStatus): StateData.enter(self) if base.localAvatar.zoneId < CIGlobals.DynamicZonesBegin: self.findAndMakeLinkTunnels() self.fsm.enterInitialState() messenger.send('enterSafeZone') self.setState(requestStatus['where'], requestStatus) partyGate = self.geom.find('**/prop_party_gate_DNARoot') if not partyGate.isEmpty(): partyGate.removeNode() del partyGate petShop = self.geom.find('**/*pet_shop_DNARoot*') if not petShop.isEmpty(): fish = petShop.find( '**/animated_prop_PetShopFishAnimatedProp_DNARoot') if fish: self.animatedFish = Actor( 'phase_4/models/props/exteriorfish-zero.bam', {'chan': 'phase_4/models/props/exteriorfish-swim.bam'}) self.animatedFish.reparentTo(petShop) self.animatedFish.setPos(fish.getPos()) self.animatedFish.loop('chan') fish.removeNode() def exit(self): StateData.exit(self) messenger.send('exitSafeZone') for link in self.linkTunnels: link.cleanup() if self.animatedFish: self.animatedFish.stop('chan') self.linkTunnels = [] def setState(self, stateName, requestStatus): self.fsm.request(stateName, [requestStatus]) def createSafeZone(self, dnaFile): if self.szStorageDNAFile: loader.loadDNAFile(self.hood.dnaStore, self.szStorageDNAFile) if self.szHolidayDNAFile: loader.loadDNAFile(self.hood.dnaStore, self.szHolidayDNAFile) node = loader.loadDNAFile(self.hood.dnaStore, dnaFile) if node.getNumParents() == 1: self.geom = NodePath(node.getParent(0)) self.geom.reparentTo(hidden) else: self.geom = hidden.attachNewNode(node) self.makeDictionaries(self.hood.dnaStore) if self.__class__.__name__ not in ('TTSafeZoneLoader', ): self.geom.flattenMedium() gsg = base.win.getGsg() if gsg: self.geom.prepareScene(gsg) def makeDictionaries(self, dnaStore): self.nodeList = [] for i in xrange(dnaStore.getNumDNAVisGroups()): groupFullName = dnaStore.getDNAVisGroupName(i) groupNode = self.geom.find('**/' + groupFullName) if groupNode.isEmpty(): self.notify.error('Could not find visgroup') if self.__class__.__name__ not in ('TTSafeZoneLoader', ): groupNode.flattenMedium() self.nodeList.append(groupNode) self.hood.dnaStore.resetPlaceNodes() self.hood.dnaStore.resetDNAGroups() self.hood.dnaStore.resetDNAVisGroups() self.hood.dnaStore.resetDNAVisGroupsAI() def enterPlayground(self, requestStatus): try: self.hood.stopSuitEffect() except: pass self.acceptOnce(self.placeDoneEvent, self.handlePlaygroundDone) self.place = self.playground(self, self.fsm, self.placeDoneEvent) self.place.load() def exitPlayground(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) return def handlePlaygroundDone(self): status = self.place.doneStatus if self.hood.isSameHood(status) and status[ 'loader'] == 'safeZoneLoader' and status['where'] not in ( 'minigame', ): self.fsm.request('quietZone', [status]) else: self.doneStatus = status messenger.send(self.doneEvent) def enterToonInterior(self, requestStatus): self.acceptOnce(self.placeDoneEvent, self.handleToonInteriorDone) self.place = ToonInterior.ToonInterior(self, self.fsm, self.placeDoneEvent) self.place.load() def enterThePlace(self, requestStatus): base.cr.playGame.setPlace(self.place) if self.place is not None: self.place.enter(requestStatus) return def exitToonInterior(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) return def handleToonInteriorDone(self): status = self.place.doneStatus if status['loader'] == 'safeZoneLoader' and self.hood.isSameHood( status ) and status['shardId'] == None or status['how'] == 'doorOut': self.fsm.request('quietZone', [status]) else: self.doneStatus = status messenger.send(self.doneEvent) return def enterQuietZone(self, requestStatus): self.fsm.request(requestStatus['where'], [requestStatus], exitCurrent=0) self.quietZoneDoneEvent = uniqueName('quietZoneDone') self.acceptOnce(self.quietZoneDoneEvent, self.handleQuietZoneDone) self.quietZoneStateData = QuietZoneState(self.quietZoneDoneEvent) self.quietZoneStateData.load() self.quietZoneStateData.enter(requestStatus) def exitQuietZone(self): self.ignore(self.quietZoneDoneEvent) del self.quietZoneDoneEvent self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None return def handleQuietZoneDone(self): status = self.quietZoneStateData.getDoneStatus() self.exitQuietZone() if status['where'] == 'estate' or status['loader'] == 'townLoader': self.doneStatus = status messenger.send(self.doneEvent) else: self.enterThePlace(status) def enterOff(self): pass def exitOff(self): pass
class Builder(object): def __init__(self,environment,nodes,lights,cameras,entities,animations,staticGeoms,yamlList): self.node = NodePath('fred') self.reset() self.environment = environment self.nodes = nodes self.lights = lights self.cameras = cameras self.entities = entities self.animations = animations self.staticGeoms = staticGeoms self.yamlList = yamlList self.initManagers() def initManagers(self): from pandark.managers.physicsmanager import PhysicsManager self.physicsMgr = PhysicsManager() from pandark.managers.lightsmanager import LightsManager self.lightsMgr = LightsManager() from pandark.managers.camerasmanager import CamerasManager self.camerasMgr = CamerasManager() from pandark.managers.animationsmanager import AnimationsManager self.animsMgr = AnimationsManager() def begin(self): base.setBackgroundColor( self.environment['colourBackground'] ) alight = AmbientLight('AmbientLight') alight.setColor(self.environment['colourAmbient'] ) alnp = self.node.attachNewNode(alight) self.node.setLight(alnp) if self.environment['fog']: fog = Fog( 'sceneName' ) fog.setColor( self.environment['fog']['color'] ) if self.environment['fog']['mode'] == "linear": fog.setLinearRange(self.environment['fog']['linearStart']*1000,self.environment['fog']['linearEnd']*1000) else: fog.setExpDensity( self.environment['fog']['expDensity'] ) self.node.setFog(fog) [self.createNode(props) for props in self.nodes] [self.createLight(props) for props in self.lights] [self.createCamera(props) for props in self.cameras] [self.createEntity(props) for props in self.entities] [self.createStaticGeoms(props) for props in self.staticGeoms] #self.animsMgr.play('Camera01', 'idle', True) def reset(self): self.__nodesDict = {} self.__lightsDict = {} self.__camerasDict = {} self.__entitiesDict = {} self.__nodesDict[''] = self.node def getEnt(self,name): return self.__entitiesDict[name] def createNode(self,props): parent = self.node.find('**/'+props['groupName']) or self.node node = NodePath(props['name']) node.setPos(props['pos']) node.setQuat(props['quat']) node.setScale(props['scale']) node.reparentTo(parent) self.animsMgr.createAnimation(node, self.animations[ props['name'] ] ) #self.__nodesDict[props['name']] = node def createLight(self,props): light = self.lightsMgr.createLight[props['type'] ](props) self.animsMgr.createAnimation(light, self.animations[ props['name'] ] ) def createCamera(self,props): cam = self.camerasMgr.createCamera(props) #self.camerasMgr.active( props['name'] ) self.animsMgr.createAnimation(cam, self.animations[ props['name'] ] ) def createEntity(self,props): props['parent'] = self.__nodesDict[props['groupName']] name = props['name'] ent = yaml.load( self.yamlList[name] ) model = loader.loadModel( ent.model_path ) body = self.physicsMgr.createRigidBody(ent.physics['shapetype'],model,ent.physics) ent.init(model,body,props) self.__entitiesDict[name] = ent self.animsMgr.createAnimation(ent.getNode(), self.animations[name]) def createStaticGeoms(self,props): path = props['configFile'] stream = file('assets/classes/' + path + '.class', 'r') ent = yaml.load( stream ) ent.init(props) def __del__(self): print 'del scene'
class GunGameLevelLoader: notify = directNotify.newCategory("GunGameLevelLoader") LevelData = { # momada means: Mix Of Mint And District Attorney's 'momada': { 'name': ZoneUtil.ToonBattleOriginalLevel, 'camera': (Point3(0.0, -25.80, 7.59), Vec3(0.00, 0.00, 0.00)), 'models': [ "phase_11/models/lawbotHQ/LB_Zone03a.bam", "phase_11/models/lawbotHQ/LB_Zone04a.bam", "phase_11/models/lawbotHQ/LB_Zone7av2.bam", "phase_11/models/lawbotHQ/LB_Zone08a.bam", "phase_11/models/lawbotHQ/LB_Zone13a.bam", "phase_10/models/cashbotHQ/ZONE17a.bam", "phase_10/models/cashbotHQ/ZONE18a.bam", "phase_11/models/lawbotHQ/LB_Zone22a.bam" ], 'parents': [ render, "EXIT", "EXIT", "EXIT", "ENTRANCE", "ENTRANCE", "ENTRANCE", "EXIT" ], 'model_positions': [ Point3(0.00, 0.00, 0.00), Point3(-1.02, 59.73, 0.00), Point3(0.00, 74.77, 0.00), Point3(0.00, 89.37, -13.50), Point3(16.33, -136.53, 0.00), Point3(-1.01, -104.40, 0.00), Point3(0.65, -23.86, 0.00), Point3(-55.66, -29.01, 0.00) ], 'model_orientations': [ Vec3(0.00, 0.00, 0.00), Vec3(0.00, 0.00, 0.00), Vec3(90.00, 0.00, 0.00), Vec3(180.00, 0.00, 0.00), Vec3(97.00, 0.00, 0.00), Vec3(359.95, 0.00, 0.00), Vec3(90.00, 0.00, 0.00), Vec3(270.00, 0.00, 0.00) ], 'spawn_points': [ (Point3(0, 0, 0), Vec3(0, 0, 0)), (Point3(-20, 50, 0), Vec3(0, 0, 0)), (Point3(20, 50, 0), Vec3(0, 0, 0)), (Point3(0, 120, 0), Vec3(0, 0, 0)), (Point3(0, 100, 0), Vec3(180, 0, 0)), (Point3(-90, 0, 0), Vec3(0, 0, 0)), (Point3(-170, 0, 0), Vec3(0, 0, 0)), (Point3(-90, 50, 0), Vec3(0, 0, 0)), (Point3(-170, 50, 0), Vec3(0, 0, 0)), (Point3(35, 250, 0), Vec3(-90, 0, 0)), (Point3(0, 285, 0), Vec3(180, 0, 0)), (Point3(-185, 250, 0), Vec3(90, 0, 0)) ] }, 'dg': { 'name': ZoneUtil.DaisyGardens, 'camera': (Point3(-33.13, -3.20, 48.62), Vec3(326.31, 332.68, 0.00)), 'dna': [ 'phase_8/dna/storage_DG.pdna', 'phase_8/dna/storage_DG_sz.pdna', 'phase_8/dna/daisys_garden_sz.pdna' ], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[ZoneUtil.DaisyGardens] }, 'mml': { 'name': ZoneUtil.MinniesMelodyland, 'camera': (Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.80, 0.00)), 'dna': [ 'phase_6/dna/storage_MM.pdna', 'phase_6/dna/storage_MM_sz.pdna', 'phase_6/dna/minnies_melody_land_sz.pdna' ], 'sky': 'MM', 'spawn_points': hoodMgr.dropPoints[ZoneUtil.MinniesMelodyland] }, 'oz': { 'name': ZoneUtil.OutdoorZone, 'camera': (Point3(-54.42, -91.05, 34.89), Vec3(315.29, 336.80, 0.00)), 'dna': [ 'phase_6/dna/storage_OZ.pdna', 'phase_6/dna/storage_OZ_sz.pdna', 'phase_6/dna/outdoor_zone_sz.pdna' ], 'sky': 'TT', 'spawn_points': hoodMgr.dropPoints[ZoneUtil.OutdoorZone] }, 'cbhq': { 'name': ZoneUtil.CashbotHQ, 'camera': (Point3(302.64, 5.00, 15.20), Vec3(135.00, 341.57, 0.00)), 'model': 'phase_10/models/cogHQ/CashBotShippingStation.bam', 'sky': None, 'spawn_points': hoodMgr.dropPoints[ZoneUtil.CashbotHQ] }, 'sbf': { 'name': ZoneUtil.SellbotFactory, 'camera': (Point3(0, 0, 0), Vec3(0, 0, 0)), 'model': "phase_9/models/cogHQ/SelbotLegFactory.bam", 'sky': 'cog', 'sky_scale': 10.0, 'occluders': 'phase_9/models/cogHQ/factory_sneak_occluders.egg', 'spawn_points': {GGG.Teams.BLUE: [ (Point3(13, 30, 3.73), Point3(0, 0, 0)), (Point3(21, 30, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0)), (Point3(13, 20, 3.73), Point3(0, 0, 0)), (Point3(21, 20, 3.73), Point3(0, 0, 0)), (Point3(29, 30, 3.73), Point3(0, 0, 0))], GGG.Teams.RED: [ (Point3(-644.43, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-644.43, 363.22, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 378.12, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 370.75, 8.73), Point3(270, 0, 0)), (Point3(-659.05, 363.22, 8.73), Point3(270, 0, 0))] }, 'flag_points': {GGG.Teams.BLUE: [Point3(213.23, 340.59, 19.73), Point3(90, 0, 0)], GGG.Teams.RED: [Point3(-543.60, 595.79, 9.73), Point3(270, 0, 0)]}, 'flagpoint_points': {GGG.Teams.BLUE: [Point3(-543.60, 595.79, 9.73), Point3(270, 0, 0)], GGG.Teams.RED: [Point3(213.23, 340.59, 19.73), Point3(0, 0, 0)]} }, 'ttc' : { 'name' : ZoneUtil.ToontownCentral, 'dna' : [ 'phase_4/dna/storage_TT.pdna', 'phase_4/dna/storage_TT_sz.pdna', 'phase_4/dna/new_ttc_sz.pdna', ], 'sky' : 'TT', 'spawn_points' : [ (9.90324401855, 91.9139556885, 8.0364112854, -545.909545898, 0.0, 0.0), (77.9181442261, 50.953086853, 7.52815723419, -598.509460449, 0.0, 0.0), (93.7379760742, 6.37303066254, 7.99749088287, -626.209533691, 0.0, 0.0), (39.0383415222, -81.5989837646, 8.01874637604, -694.309265137, 0.0, 0.0), (-19.2093048096, -95.1359481812, 8.07303524017, -731.409240723, 0.0, 0.0), (-84.4093933105, -45.4780502319, 8.06541728973, -781.809143066, 0.0, 0.0), (-92.2512283325, 2.41426730156, 8.03108692169, -811.70916748, 0.0, 0.0), (46.8868179321, 81.3593673706, 8.04793071747, -955.309509277, 0.0, 0.0), (32.3203735352, 90.0017929077, 8.06353855133, -884.409301758, 0.0, 0.0) ], 'cap_point' : Point3(-1.5, 0, 0) } } SkyData = { 'TT': 'phase_3.5/models/props', 'MM': 'phase_6/models/props', 'cog': 'phase_9/models/cogHQ', 'MovingSkies': ['TT'] } def __init__(self, mg): self.mg = mg self.levelName = None self.dnaStore = DNAStorage() self.loadingText = None # for not momada only: self.levelGeom = None self.olc = None self.occluders = None # for momada only: self.momadaAreas = [] self.momadaAreaName2areaModel = {} def getFlagPoint_Point(self, team): return self.LevelData[self.levelName]['flagpoint_points'][team] def getFlagPoint(self, team): return self.LevelData[self.levelName]['flag_points'][team] def getCapturePoint(self): return self.LevelData[self.levelName]['cap_point'] def setLevel(self, level): self.levelName = level def getLevel(self): return self.levelName def getCameraOfCurrentLevel(self): return self.LevelData[self.getLevel()]['camera'] def getSpawnPoints(self): # Return the spawn points for this level. pointData = self.LevelData[self.levelName]['spawn_points'] if self.levelName == "momada": return pointData else: if self.mg.gameMode in [GGG.GameModes.CASUAL, GGG.GameModes.KOTH]: # These points come from src.coginvasion.distributed.HoodMgr, # which is a tuple of a bunch of arrays with pos as first # 3, and hpr as last 3 list elements. # # Disect the arrays and return a tuple holding a Point3 pos, and a Vec3 hpr. array = [] for posAndHpr in pointData: array.append( ( Point3( posAndHpr[0], posAndHpr[1], posAndHpr[2] ), Vec3( posAndHpr[3], posAndHpr[4], posAndHpr[5] ) ) ) elif self.mg.gameMode == GGG.GameModes.CTF: array = pointData[self.mg.team] return array def getNameOfCurrentLevel(self): return self.LevelData[self.getLevel()]['name'] def load(self): self.unload() if self.loadingText: self.loadingText.destroy() self.loadingText = None self.loadingText = OnscreenText(text = "", font = CIGlobals.getMinnieFont(), fg = (1, 1, 1, 1)) self.loadingText.setBin('gui-popup', 0) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() if self.levelName == "momada": # momada is completely different from the other levels, # so it has it's own separate method for loading. self.__momadaLoad() elif self.levelName in ['cbhq', 'sbf']: # Cog hqs are just one model with everything in it. no dna loading needed. modelPath = self.LevelData[self.levelName]['model'] self.levelGeom = loader.loadModel(modelPath) self.levelGeom.flattenMedium() self.levelGeom.reparentTo(render) if self.LevelData[self.levelName].get('occluders'): self.occluders = loader.loadModel(self.LevelData[self.levelName]['occluders']) for occluderNode in self.occluders.findAllMatches('**/+OccluderNode'): base.render.setOccluder(occluderNode) occluderNode.node().setDoubleSided(True) if self.levelName == 'sbf': base.camLens.setFar(250) else: # It's a playground with dna and stuff. Just do the # normal loading procedure. dnaFiles = self.LevelData[self.levelName]['dna'] loadDNAFile(self.dnaStore, 'phase_4/dna/storage.pdna') for index in range(len(dnaFiles)): if index == len(dnaFiles) - 1: node = loadDNAFile(self.dnaStore, dnaFiles[index]) if node.getNumParents() == 1: self.levelGeom = NodePath(node.getParent(0)) self.levelGeom.reparentTo(hidden) else: self.levelGeom = hidden.attachNewNode(node) if self.levelName == 'ttc' and dnaFiles[index] == 'phase_4/dna/new_ttc_sz.pdna': self.levelGeom.find('**/prop_gazebo_DNARoot').removeNode() else: self.levelGeom.flattenMedium() gsg = base.win.getGsg() if gsg: self.levelGeom.prepareScene(gsg) self.levelGeom.reparentTo(render) else: loadDNAFile(self.dnaStore, dnaFiles[index]) children = self.levelGeom.findAllMatches('**/*doorFrameHole*') for child in children: child.hide() self.olc = ZoneUtil.getOutdoorLightingConfig(self.LevelData[self.levelName].get('name')) self.olc.setupAndApply() if self.loadingText: self.loadingText.destroy() self.loadingText = None def __momadaLoad(self): def attachArea(itemNum): name = 'MomadaArea-%s' % itemNum area = self.momadaAreaName2areaModel.get(name) parents = self.LevelData['momada']['parents'] parent = parents[itemNum] if type(parent) == type(""): parent = self.momadaAreas[itemNum - 1].find('**/' + parent) pos = self.LevelData['momada']['model_positions'][itemNum] hpr = self.LevelData['momada']['model_orientations'][itemNum] area.reparentTo(parent) area.setPos(pos) area.setHpr(hpr) _numItems = 0 name = None for item in self.LevelData['momada']['models']: name = 'MomadaArea-%s' % _numItems area = loader.loadModel(item) self.momadaAreas.append(area) self.momadaAreaName2areaModel[name] = area attachArea(_numItems) _numItems += 1 self.notify.info("Loaded and attached %s momada areas." % _numItems) def unload(self): render.clearOccluder() if self.olc: self.olc.cleanup() self.olc = None if self.levelName == "sbf": base.camLens.setFar(CIGlobals.DefaultCameraFar) if self.levelName == "momada": for area in self.momadaAreas: self.momadaAreas.remove(area) area.removeNode() del area self.momadaAreas = [] self.momadaAreaName2areaModel = {} else: if self.occluders: self.occluders.removeNode() self.occluders = None if self.levelGeom: self.levelGeom.removeNode() self.levelGeom = None def cleanup(self): self.momadaAreas = None self.momadaAreaName2areaModel = None if self.dnaStore: self.dnaStore.reset_nodes() self.dnaStore.reset_hood_nodes() self.dnaStore.reset_place_nodes() self.dnaStore.reset_hood() self.dnaStore.reset_fonts() self.dnaStore.reset_DNA_vis_groups() self.dnaStore.reset_materials() self.dnaStore.reset_block_numbers() self.dnaStore.reset_block_zones() self.dnaStore.reset_suit_points() self.dnaStore = None
class TTCHood: def __init__(self, cr): self.cr = cr self.dnaStore = DNAStorage() self.isLoaded = 0 self.suitEffectEnabled = False self.amblight = None self.ambNode = None self.sky = None self.skyTrack = None self.skySeq = None self.lightTrack = None self.skyUtil = SkyUtil() def createHood(self, loadStorage = 1, AI = 0): if loadStorage: loadDNAFile(self.dnaStore, "phase_4/dna/storage.dna") loadDNAFile(self.dnaStore, "phase_4/dna/storage_TT.dna") loadDNAFile(self.dnaStore, "phase_4/dna/storage_TT_sz.dna") loadDNAFile(self.dnaStore, "phase_5/dna/storage_town.dna") loadDNAFile(self.dnaStore, "phase_5/dna/storage_TT_town.dna") self.node = loadDNAFile(self.dnaStore, "phase_4/dna/toontown_central_sz.dna") if self.node.getNumParents() == 1: self.geom = NodePath(self.node.getParent(0)) self.geom.reparentTo(hidden) else: self.geom = hidden.attachNewNode(self.node) gsg = base.win.getGsg() if gsg: self.geom.prepareScene(gsg) self.geom.setName('toontown_central') self.geom.find('**/hill').setTransparency(TransparencyAttrib.MBinary, 1) self.createSky("tt") base.hoodBGM = base.loadMusic("phase_4/audio/bgm/TC_nbrhood.ogg") base.hoodBGM.setVolume(0.25) base.hoodBGM.setLoop(True) base.hoodBGM.play() self.clerk_node = render.attach_new_node('clerk_node') self.clerk_node.set_pos(-80, -85.57, 0.5) self.clerk_node.set_h(165.07) self.geom.find('**/toontown_central').setCollideMask(BitMask32.allOff()) self.geom.find('**/coll_sidewalk').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/collision_1').node().setIntoCollideMask(CIGlobals.WallBitmask) self.geom.find('**/coll_mainFoolr').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/left_ear').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/right_ear').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_bridge_floor').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_bridge').node().setIntoCollideMask(CIGlobals.WallBitmask) self.geom.find('**/coll_r_stair').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_l_stair_2').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_l_stairend_1').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_r_satirend_1').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_plaza').node().setIntoCollideMask(CIGlobals.FloorBitmask) self.geom.find('**/coll_hedges').node().setIntoCollideMask(CIGlobals.WallBitmask) self.coll_list = ['coll_sidewalk', 'collision_1', 'coll_mainFoolr', 'left_ear', 'right_ear', 'coll_bridge_floor', 'coll_bridge', 'coll_r_stair', 'coll_l_stair_2', 'coll_l_stairend_1', 'coll_r_stairend_1', 'coll_plaza', 'coll_hedges'] self.geom.reparentTo(render) self.telescope = Actor(self.geom.find('**/*animated_prop_HQTelescopeAnimatedProp*'), {"chan": "phase_3.5/models/props/HQ_telescope-chan.bam"}, copy=0) self.telescope.reparentTo(self.geom.find('**/*toon_landmark_hqTT*')) self.createLights(1, 1, 1) #if AI: # self.createTrolley() taskMgr.add(self.telescopeTask, "telescopeTask") self.isLoaded = 1 messenger.send("loadedHood") def createLights(self, r, g, b, startColor=1, fade=0): self.deleteLights() self.amblight = AmbientLight("amblight") self.amblight.setColor(VBase4(r, g, b, 1)) self.ambNode = render.attachNewNode(self.amblight) render.setLight(self.ambNode) if fade: self.lightTrack = LerpFunc(self.setLightColor, fromData=startColor, toData=r, duration=2.5, blendType="easeInOut") self.lightTrack.start() self.skyTrack = LerpColorInterval(self.sky, color=VBase4(r + 0.4, g + 0.4, b + 0.4, 1.0), startColor=VBase4(startColor, startColor, startColor, 1.0), duration=1.5) self.skyTrack.start() sky = "tt" if r < 0.6: sky = "br" self.skySeq = Sequence(Wait(1.5), Func(self.createSky, sky)) self.skySeq.start() def createSky(self, sky): self.deleteSky() skyPath = "phase_3.5/models/props/" + sky.upper() + "_sky.bam" self.sky = loader.loadModel(skyPath) self.sky.reparentTo(self.geom) self.sky.setPos(9.15527e-005, -1.90735e-006, 2.6226e-006) self.sky.setH(-90) if sky == "tt": self.skyUtil.startSky(self.sky) def deleteSky(self): self.skyUtil.stopSky() if self.sky: self.sky.removeNode() self.sky = None if self.lightTrack: self.lightTrack.pause() self.lightTrack = None if self.skyTrack: self.skyTrack.pause() self.skyTrack = None if self.skySeq: self.skySeq.pause() self.skySeq = None def setLightColor(self, color): self.amblight.setColor(VBase4(color, color, color, 1)) def deleteLights(self): if self.ambNode: render.clearLight(self.ambNode) self.ambNode.removeNode() self.ambNode = None def telescopeTask(self, task): if not self.isLoaded: return task.done self.telescope.play("chan") task.delayTime = 12 return task.again def enableSuitEffect(self, size): self.createLights(0.4, 0.4, 0.4, startColor=1, fade=1) self.fogNode = Fog("fog") self.fogNode.setColor(0.3, 0.3, 0.3) self.fogNode.setExpDensity(0.0025) render.setFog(self.fogNode) base.hoodBGM.stop() song = random.randint(1, 4) base.hoodBGM = base.loadMusic("phase_3.5/audio/bgm/encntr_general_bg.ogg") base.hoodBGM.setVolume(0.7) base.hoodBGM.setLoop(True) base.hoodBGM.play() self.suitEffectEnabled = True def bossSpawned(self): base.hoodBGM.stop() base.hoodBGM = base.loadMusic("phase_7/audio/bgm/encntr_suit_winning_indoor.ogg") base.hoodBGM.setVolume(0.7) base.hoodBGM.setLoop(True) Sequence(Wait(0.5), Func(base.hoodBGM.play)).start() def disableSuitEffect(self): self.createLights(1, 1, 1) self.createSky("tt") #render.clearFog() base.hoodBGM.stop() base.hoodBGM = base.loadMusic("phase_4/audio/bgm/TC_nbrhood.ogg") base.hoodBGM.setVolume(0.25) base.hoodBGM.setLoop(True) base.hoodBGM.play() self.suitEffectEnabled = False def unloadHood(self): self.isLoaded = 0 if self.suitEffectEnabled: self.disableSuitEffect() self.deleteSky() self.deleteLights() self.geom.remove() self.clerk_node.remove_node() base.hoodBGM.stop()
class HomeHood: dnaStore = DNAStorage() def createHood(self, loadStorage=1): self.isLoaded = 0 if loadStorage: loadDNAFile(self.dnaStore, "phase_5.5/dna/storage_estate.dna") node = loadDNAFile(self.dnaStore, "phase_5.5/dna/estate_1.dna") if node.getNumParents() == 1: self.geom = NodePath(node.getParent(0)) self.geom.reparentTo(hidden) else: self.geom = hidden.attachNewNode(self.node) gsg = base.win.getGsg() if gsg: self.geom.prepareScene(gsg) self.geom.setName('home') self.geom.find('**/Path').setTransparency(TransparencyAttrib.MBinary, 1) self.sky = loader.loadModel("phase_3.5/models/props/TT_sky.bam") self.sky.reparentTo(self.geom) self.sky.setPos(-4.99989, -0.000152588, 2.28882e-005) self.geom.find('**/terrain').setCollideMask(BitMask32.allOff()) self.geom.find('**/terrain_barrier').node().setIntoCollideMask( CIGlobals.WallBitmask) self.geom.find("**/collision_fence").node().setIntoCollideMask( CIGlobals.WallBitmask) self.geom.find('**/collision4').node().setIntoCollideMask( CIGlobals.FloorBitmask) self.geom.find("**/collision3").node().setIntoCollideMask( CIGlobals.FloorBitmask) self.geom.find("**/collision1").node().setIntoCollideMask( CIGlobals.FloorBitmask) self.geom.reparentTo(render) messenger.send("loadedHood") self.skyUtil = SkyUtil() self.skyUtil.startSky(self.sky) self.isLoaded = 1 def unloadHood(self): self.skyUtil.stopSky() self.geom.remove() self.isLoaded = 0
class SafeZoneLoader(StateData): notify = directNotify.newCategory("SafeZoneLoader") def __init__(self, hood, parentFSMState, doneEvent): StateData.__init__(self, doneEvent) self.hood = hood self.parentFSMState = parentFSMState self.fsm = ClassicFSM('safeZoneLoader', [ State('off', self.enterOff, self.exitOff), State('playground', self.enterPlayground, self.exitPlayground, ['quietZone']), State('toonInterior', self.enterToonInterior, self.exitToonInterior, ['quietZone']), State('quietZone', self.enterQuietZone, self.exitQuietZone, ['playground', 'toonInterior']) ], 'off', 'off') self.placeDoneEvent = 'placeDone' self.place = None self.playground = None self.nodeList = [] self.linkTunnels = [] self.szHolidayDNAFile = None self.animatedFish = None self.safeZoneSong = '' self.interiorSong = '' return def doBaseOptimizations(self): # Performs base optimizations that all playgrounds can benefit from. # Combines all flat walls together, optimizes all landmark buildings, # tunnels, trees, fishing docks. # # Any optimizations for a specific playground should be done in # doFlatten() in that playground's SafeZoneLoader. flats = self.geom.attachNewNode('flats') for np in self.geom.findAllMatches("**/sz0:*_DNARoot"): np.wrtReparentTo(flats) for np in self.geom.findAllMatches("**/tb0:*_DNARoot"): np.wrtReparentTo(flats) for np in self.geom.findAllMatches("**/*random*_DNARoot"): np.wrtReparentTo(flats) CIGlobals.removeDNACodes(flats) flats.clearModelNodes() flats.flattenStrong() CIGlobals.moveChildren(flats, self.geom) tunnels = self.geom.findAllMatches("**/*linktunnel*") for tunnel in tunnels: tunnel.flattenStrong() for landmark in self.geom.findAllMatches("**/*toon_landmark*_DNARoot"): CIGlobals.removeDNACodes(landmark) landmark.flattenStrong() signs = self.geom.attachNewNode("signs") CIGlobals.moveNodes(self.geom, "*neighborhood_sign*_DNARoot", signs) #for sign in signs.getChildren(): #sign.clearTransform() CIGlobals.removeDNACodes(signs) signs.clearModelNodes() signs.flattenStrong() CIGlobals.moveChildren(signs, self.geom) fish = self.geom.attachNewNode("fishspots") CIGlobals.moveNodes(self.geom, "fishing_spot_DNARoot", fish) CIGlobals.removeDNACodes(fish) fish.clearModelNodes() fish.flattenStrong() CIGlobals.moveChildren(fish, self.geom) trees = self.geom.attachNewNode("trees") for np in self.geom.findAllMatches("**/*prop_tree*_DNARoot"): np.wrtReparentTo(trees) CIGlobals.removeDNACodes(trees) trees.clearModelNodes() trees.flattenStrong() CIGlobals.moveChildren(trees, self.geom) def findAndMakeLinkTunnels(self): for tunnel in self.geom.findAllMatches('**/*linktunnel*'): dnaRootStr = tunnel.getName() link = LinkTunnel.SafeZoneLinkTunnel(tunnel, dnaRootStr) self.linkTunnels.append(link) def load(self, flattenNow=True): StateData.load(self) self.createSafeZone(self.dnaFile, flattenNow) children = self.geom.findAllMatches('**/*doorFrameHole*') for child in children: child.hide() self.parentFSMState.addChild(self.fsm) def unload(self): StateData.unload(self) base.waterReflectionMgr.clearWaterNodes() if self.animatedFish: self.animatedFish.cleanup() self.animatedFish.removeNode() self.animatedFish = None if self.linkTunnels is not None: for link in self.linkTunnels: link.cleanup() self.linkTunnels = None if self.nodeList is not None: for node in self.nodeList: node.removeNode() self.nodeList = None self.parentFSMState.removeChild(self.fsm) del self.parentFSMState del self.animatedFish base.disableAndRemovePhysicsNodes(self.geom) self.geom.removeNode() del self.geom del self.fsm del self.hood del self.playground del self.safeZoneSong del self.interiorSong self.ignoreAll() #CIGlobals.doSceneCleanup() def enter(self, requestStatus): StateData.enter(self) if base.localAvatar.zoneId < ZoneUtil.DynamicZonesBegin: self.findAndMakeLinkTunnels() self.fsm.enterInitialState() messenger.send('enterSafeZone') self.setState(requestStatus['where'], requestStatus) # Delete party gate partyGate = self.geom.find('**/prop_party_gate_DNARoot') if not partyGate.isEmpty(): partyGate.removeNode() del partyGate # Delete pet shop petShop = self.geom.find('**/*pet_shop_DNARoot*') if not petShop.isEmpty(): fish = petShop.find( '**/animated_prop_PetShopFishAnimatedProp_DNARoot') if fish: """ self.animatedFish = Actor('phase_4/models/props/exteriorfish-zero.bam', {'chan' : 'phase_4/models/props/exteriorfish-swim.bam'}) #self.animatedFish.reparentTo(hidden)#petShop) #self.animatedFish.setPos(fish.getPos()) #self.animatedFish.loop('chan') #self.animatedFish.cleanup() """ fish.removeNode() #petShop.removeNode() #del petShop CIGlobals.preRenderScene(self.geom) def exit(self): StateData.exit(self) messenger.send('exitSafeZone') for link in self.linkTunnels: link.cleanup() if self.animatedFish: self.animatedFish.stop('chan') self.linkTunnels = [] def setState(self, stateName, requestStatus): self.fsm.request(stateName, [requestStatus]) def createSafeZone(self, dnaFile, flattenNow=True): if self.szStorageDNAFile: if isinstance(self.szStorageDNAFile, list): # We are loading multiple sz storages. for i in xrange(len(self.szStorageDNAFile)): loader.loadDNAFile(self.hood.dnaStore, self.szStorageDNAFile[i]) else: loader.loadDNAFile(self.hood.dnaStore, self.szStorageDNAFile) if self.szHolidayDNAFile: loader.loadDNAFile(self.hood.dnaStore, self.szHolidayDNAFile) node = loader.loadDNAFile(self.hood.dnaStore, dnaFile) if node.getNumParents() == 1: self.geom = NodePath(node.getParent(0)) self.geom.reparentTo(hidden) else: self.geom = hidden.attachNewNode(node) CIGlobals.replaceDecalEffectsWithDepthOffsetAttrib(self.geom) if flattenNow: self.doFlatten() base.createPhysicsNodes(self.geom) CIGlobals.preRenderScene(self.geom) def doFlatten(self): self.doBaseOptimizations() self.makeDictionaries(self.hood.dnaStore) self.geom.flattenMedium() def makeDictionaries(self, dnaStore): self.nodeList = [] for i in xrange(dnaStore.getNumDNAVisGroups()): groupFullName = dnaStore.getDNAVisGroupName(i) #groupName = base.cr.hoodMgr.extractGroupName(groupFullName) groupNode = self.geom.find('**/' + groupFullName) if groupNode.isEmpty(): self.notify.error('Could not find visgroup') groupNode.flattenMedium() self.nodeList.append(groupNode) self.hood.dnaStore.resetPlaceNodes() self.hood.dnaStore.resetDNAGroups() self.hood.dnaStore.resetDNAVisGroups() self.hood.dnaStore.resetDNAVisGroupsAI() def enterPlayground(self, requestStatus): try: self.hood.stopSuitEffect() except: pass self.acceptOnce(self.placeDoneEvent, self.handlePlaygroundDone) self.place = self.playground(self, self.fsm, self.placeDoneEvent) self.place.load() def exitPlayground(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) return def handlePlaygroundDone(self): status = self.place.doneStatus if self.hood.isSameHood(status) and status[ 'loader'] == 'safeZoneLoader' and not status['where'] in [ 'minigame' ]: self.fsm.request('quietZone', [status]) else: self.doneStatus = status messenger.send(self.doneEvent) return def enterToonInterior(self, requestStatus): self.acceptOnce(self.placeDoneEvent, self.handleToonInteriorDone) self.place = ToonInterior.ToonInterior(self, self.fsm, self.placeDoneEvent) self.place.load() def enterThePlace(self, requestStatus): base.cr.playGame.setPlace(self.place) if self.place is not None: self.place.enter(requestStatus) def exitToonInterior(self): self.ignore(self.placeDoneEvent) self.place.exit() self.place.unload() self.place = None base.cr.playGame.setPlace(self.place) return def handleToonInteriorDone(self): status = self.place.doneStatus if (status['loader'] == 'safeZoneLoader' and self.hood.isSameHood(status) and status['shardId'] is None or status['how'] == 'doorOut'): self.fsm.request('quietZone', [status]) else: self.doneStatus = status messenger.send(self.doneEvent) return def enterQuietZone(self, requestStatus): self.fsm.request(requestStatus['where'], [requestStatus], exitCurrent=0) self.quietZoneDoneEvent = uniqueName('quietZoneDone') self.acceptOnce(self.quietZoneDoneEvent, self.handleQuietZoneDone) self.quietZoneStateData = QuietZoneState(self.quietZoneDoneEvent) self.quietZoneStateData.load() self.quietZoneStateData.enter(requestStatus) def exitQuietZone(self): self.ignore(self.quietZoneDoneEvent) del self.quietZoneDoneEvent self.quietZoneStateData.exit() self.quietZoneStateData.unload() self.quietZoneStateData = None return def handleQuietZoneDone(self): status = self.quietZoneStateData.getDoneStatus() self.exitQuietZone() if status['where'] == 'estate' or status['loader'] == 'townLoader': self.doneStatus = status messenger.send(self.doneEvent) else: self.enterThePlace(status) def enterOff(self): pass def exitOff(self): pass
class EnemySegment(): def __init__(self, geometry, length=0, x=0, y=0, following=None): self.node = NodePath("segment") geometry.copy_to(self.node) self.node.reparent_to(render) self.node.set_y(100 + y) self.node.set_x(x) self.following = following self.follower = None if length > 0: self.follower = EnemySegment(geometry, length=length - 1, x=x, y=y + 1, following=self) base.segments.append(self.follower) self.angle = 180 self.head = self.node.find("**/head*") self.mid = self.node.find("**/mid*") self.tail = self.node.find("**/tail*") self.ouch = 0 def destroy(self, zapped=False): Explosion(base.models["misc"]["explosion_a"], self.node.get_pos(), speed=uniform(1, 2)) if self.following: if not zapped: Mine(self.node.get_pos()) self.following.follower = None if self.follower: if base.flower_time[0] >= base.flower_time[1]: if not base.player.flowerpower > 0: Flower(self.node.get_pos()) base.flower_time[0] = 0 if not self.following: self.follower.ouch = 0.3 else: self.follower.angle += randint(-45, 45) self.follower.following = None base.segments.remove(self) self.node.remove_node() def update(self): dt = globalClock.get_dt() if self.ouch > 0: self.ouch -= dt self.head.hide() self.mid.hide() self.tail.hide() if self.following: self.node.set_pos(self.following.node.get_pos()) if self.follower: self.mid.show() else: self.tail.show() self.angle = self.following.angle self.node.set_h(self.following.angle) else: self.head.show() if randint(0, 16) == 0 and self.ouch <= 0: self.angle += randint(-45, 45) self.node.set_h(self.angle) self.node.set_pos(self.node, (0, 1, 0)) x, y, z = self.node.get_pos() xsize, ysize = base.map_size if x < -xsize or x > xsize or y < 0 or y > ysize: base.sounds["2d"]["bounce"].play() self.angle += 180 + randint(-45, 45) limit_node(self.node) vector = base.player.node.getPos() - self.node.getPos() distance = vector.get_xy().length() if distance < 0.8: base.player.die()