def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: self.redoLevel = self.extractUndo(self.level, self.dirtyBox()) def _undo(): yield 0, 0, "Undoing..." if hasattr(self.level, 'copyChunkFrom'): for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) else: for i in self.level.copyBlocksFromIter(self.undoLevel, self.undoLevel.bounds, self.undoLevel.sourcePoint, biomes=True): yield i, self.undoLevel.chunkCount, "Copying..." if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def perform(self, recordUndo=True): if self.level.saving: alert(_("Cannot perform action while saving is taking place")) return if recordUndo: self.canUndo = True self.undoLevel = self.extractUndo( self.level, BoundingBox(self.destPoint, self.sourceBox.size)) blocksToCopy = None if not (self.copyAir and self.copyWater): blocksToCopy = range(pymclevel.materials.id_limit) if not self.copyAir: blocksToCopy.remove(0) if not self.copyWater: blocksToCopy.remove(8) if not self.copyWater: blocksToCopy.remove(9) with setWindowCaption("Copying - "): i = self.level.copyBlocksFromIter( self.sourceLevel, self.sourceBox, self.destPoint, blocksToCopy, create=True, biomes=self.copyBiomes, staticCommands=self.staticCommands, moveSpawnerPos=self.moveSpawnerPos, regenerateUUID=self.regenerateUUID, first=False) showProgress( _("Copying {0:n} blocks...").format(self.sourceBox.volume), i)
def perform(self, recordUndo=True): sourceBox = self.sourceBox if recordUndo: self.undoLevel = self.extractUndo( self.level, BoundingBox(self.destPoint, self.sourceBox.size)) blocksToCopy = None if not (self.copyAir and self.copyWater): blocksToCopy = range(pymclevel.materials.id_limit) if not self.copyAir: blocksToCopy.remove(0) if not self.copyWater: blocksToCopy.remove(8) if not self.copyWater: blocksToCopy.remove(9) with setWindowCaption("Copying - "): i = self.level.copyBlocksFromIter( self.sourceLevel, self.sourceBox, self.destPoint, blocksToCopy, create=True, biomes=self.copyBiomes, staticCommands=self.staticCommands, first=False) showProgress( _("Copying {0:n} blocks...").format(self.sourceBox.volume), i)
def extractUndoChunks(self, level, chunks, chunkCount = None): if not isinstance(level, pymclevel.MCInfdevOldLevel): chunks = numpy.array(list(chunks)) mincx, mincz = numpy.min(chunks, 0) maxcx, maxcz = numpy.max(chunks, 0) box = BoundingBox((mincx << 4, 0, mincz << 4), (maxcx << 4, level.Height, maxcz << 4)) return self.extractUndoSchematic(level, box) undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, "Copying chunk %s..." % ((cx, cz),) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: showProgress("Recording undo...", _extractUndo()) else: exhaust(_extractUndo()) return undoLevel
def checkForUpdates(): def _check(): yield jarStorage.downloadCurrentServer(panel.snapshot) yield showProgress("Checking for server updates...", _check()) versionChoice.choices = sorted(jarStorage.versions, reverse=True) versionChoice.choiceIndex = 0
def checkForUpdates(): def _check(): yield jarStorage.downloadCurrentServer() yield showProgress("Checking for server updates...", _check()) versionChoice.choices = sorted(jarStorage.versions, reverse=True) versionChoice.choiceIndex = 0
def perform(self, recordUndo=True): if recordUndo: self.undoLevel = self.extractUndo(self.level, self.destBox) destBox = self.destBox if self.level.bounds == self.destBox: destBox = None fill = self.level.fillBlocksIter(destBox, self.blockInfo, blocksToReplace=self.blocksToReplace) showProgress("Replacing blocks...", fill, cancel=True)
def relightChunks(self): def _relightChunks(): for i in self.editor.level.generateLightsIter(self.selectedChunks()): yield i with setWindowCaption("RELIGHTING - "): showProgress(_("Lighting {0} chunks...").format(len(self.selectedChunks())), _relightChunks(), cancel=True) self.editor.invalidateChunks(self.selectedChunks()) self.editor.addUnsavedEdit()
def perform(self, recordUndo=True): if self.level.saving: alert(_("Cannot perform action while saving is taking place")) return if recordUndo: self.undoLevel = self.extractUndo(self.level, self.destBox) destBox = self.destBox if self.level.bounds == self.destBox: destBox = None fill = self.level.fillBlocksIter(destBox, self.blockInfo, blocksToReplace=self.blocksToReplace) showProgress("Replacing blocks...", fill, cancel=True)
def perform(self, recordUndo=True): if self.level.saving: alert("Cannot perform action while saving is taking place") return if recordUndo: self.undoLevel = self.extractUndo(self.level, self.destBox) destBox = self.destBox if self.level.bounds == self.destBox: destBox = None fill = self.level.fillBlocksIter(destBox, self.blockInfo, blocksToReplace=self.blocksToReplace) showProgress("Replacing blocks...", fill, cancel=True) self.canUndo = True
def extractUndoChunks(self, level, chunks, chunkCount=None): if not isinstance(level, pymclevel.MCInfdevOldLevel): chunks = numpy.array(list(chunks)) mincx, mincz = numpy.min(chunks, 0) maxcx, maxcz = numpy.max(chunks, 0) box = BoundingBox((mincx << 4, 0, mincz << 4), (maxcx << 4, level.Height, maxcz << 4)) return self.extractUndoSchematic(level, box) undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, _("Copying chunk %s...") % ((cx, cz),) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: if "Canceled" == showProgress("Recording undo...", _extractUndo(), cancel=True): if albow.ask("Continue with undo disabled?", ["Continue", "Cancel"]) == "Cancel": raise Cancel else: return None else: exhaust(_extractUndo()) return undoLevel
def redo(self): if self.redoLevel: def _redo(): yield 0, 0, "Redoing..." if hasattr(self.level, 'copyChunkFrom'): for i, (cx, cz) in enumerate(self.redoLevel.allChunks): self.level.copyChunkFrom(self.redoLevel, cx, cz) yield i, self.redoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) else: for i in self.level.copyBlocksFromIter(self.redoLevel, self.redoLevel.bounds, self.redoLevel.sourcePoint, biomes=True): yield i, self.undoLevel.chunkCount, "Copying..." if self.redoLevel.chunkCount > 25: showProgress("Redoing...", _redo()) else: exhaust(_redo())
def createChunks(self): panel = GeneratorPanel() col = [panel] label = Label("Create chunks using the settings above? This cannot be undone.") col.append(Row([Label("")])) col.append(label) col = Column(col) if Dialog(client=col, responses=["OK", "Cancel"]).present() == "Cancel": return chunks = self.selectedChunks() createChunks = panel.generate(self.editor.level, chunks) try: with setWindowCaption("CREATING - "): showProgress("Creating {0} chunks...".format(len(chunks)), createChunks, cancel=True) except Exception, e: traceback.print_exc() alert(_("Failed to start the chunk generator. {0!r}").format(e))
def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: def _undo(): yield 0, 0, "Undoing..." for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ((cx, cz),) if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def perform(level, box, options): global GlobalLevel GlobalLevel = level filePath = options["Convert"] if filePath == "n/a": try: filePath = askOpenFile("Select *.txt or *.docx file to convert to Book...", defaults=False, suffixes=["txt", "docx"]) except: try: openFile = win32ui.CreateFileDialog(1, None, None, 0, "All Files (*.*)|*.*|Text Files (*.txt)|*.txt|Word Files (*.docx)|*.docx|") openFile.DoModal() filePath = openFile.GetPathName() except: raise Exception("win32ui could not be imported! Please enter the file path manually.") fileName = filePath while "/" in fileName: fileName = fileName[fileName.find("/")+1:] fileExtension = fileName[fileName.find(".")+1:] if options["as the book title"]: bookTitle = options["Use"] else: bookTitle = fileName if options["Use the file name"] == "with extension": bookTitle += "." + fileExtension if filePath is None or fileName == "": raise Exception("Please select a file!") mceutils.showProgress("Generating Book", progressIter()) totalText = decodeFile(filePath, fileExtension, options) makeBook(level, box, options, totalText, bookTitle)
def undo(self): """ Undo the operation. Ought to leave the Operation in a state where it can be performed again. Default implementation copies all chunks in undoLevel back into level. Non-chunk-based operations should override this.""" if self.undoLevel: def _undo(): yield 0, 0, "Undoing..." for i, (cx, cz) in enumerate(self.undoLevel.allChunks): self.level.copyChunkFrom(self.undoLevel, cx, cz) yield i, self.undoLevel.chunkCount, "Copying chunk %s..." % ( (cx, cz), ) if self.undoLevel.chunkCount > 25: showProgress("Undoing...", _undo()) else: exhaust(_undo()) self.editor.invalidateChunks(self.undoLevel.allChunks)
def perform(self, recordUndo=True): sourceBox = self.sourceBox if recordUndo: self.undoLevel = self.extractUndo(self.level, BoundingBox(self.destPoint, self.sourceBox.size)) blocksToCopy = None if not (self.copyAir and self.copyWater): blocksToCopy = range(pymclevel.materials.id_limit) if not self.copyAir: blocksToCopy.remove(0) if not self.copyWater: blocksToCopy.remove(8) if not self.copyWater: blocksToCopy.remove(9) with setWindowCaption("Copying - "): i = self.level.copyBlocksFromIter(self.sourceLevel, self.sourceBox, self.destPoint, blocksToCopy, create=True, biomes=self.copyBiomes, staticCommands=self.staticCommands, first=False) showProgress(_("Copying {0:n} blocks...").format(self.sourceBox.volume), i)
def perform(self, recordUndo=True): sourceBox = self.sourceBox if recordUndo: self.undoLevel = self.extractUndo(self.level, BoundingBox(self.destPoint, self.sourceBox.size)) blocksToCopy = None if not (self.copyAir and self.copyWater): blocksToCopy = range(256) if not self.copyAir: blocksToCopy.remove(0) if not self.copyWater: blocksToCopy.remove(8) if not self.copyWater: blocksToCopy.remove(9) with setWindowCaption("Copying - "): i = self.level.copyBlocksFromIter(self.sourceLevel, self.sourceBox, self.destPoint, blocksToCopy, create=True) showProgress("Copying {0:n} blocks...".format(self.sourceBox.volume), i)
def extractUndoSchematic(self, level, box): if box.volume > 131072: sch = showProgress("Recording undo...", level.extractZipSchematicIter(box), cancel=True) else: sch = level.extractZipSchematic(box) if sch == "Cancel": raise Cancel if sch: sch.sourcePoint = box.origin return sch
def extractUndoChunks(self, level, chunks, chunkCount=None): undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, "Copying chunk %s..." % ((cx, cz), ) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: showProgress("Recording undo...", _extractUndo()) else: exhaust(_extractUndo()) return undoLevel
def extractUndoChunks(self, level, chunks, chunkCount = None): undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) if not chunkCount: try: chunkCount = len(chunks) except TypeError: chunkCount = -1 def _extractUndo(): yield 0, 0, "Recording undo..." for i, (cx, cz) in enumerate(chunks): undoLevel.copyChunkFrom(level, cx, cz) yield i, chunkCount, "Copying chunk %s..." % ((cx, cz),) undoLevel.saveInPlace() if chunkCount > 25 or chunkCount < 1: showProgress("Recording undo...", _extractUndo()) else: exhaust(_extractUndo()) return undoLevel
def deleteFromWorld(): i = chestWidget.selectedItemIndex item = tileEntityTag["Items"][i] id = item["id"].value Damage = item["Damage"].value deleteSameDamage = mceutils.CheckBoxLabel("Only delete items with the same damage value") deleteBlocksToo = mceutils.CheckBoxLabel("Also delete blocks placed in the world") if id not in (8, 9, 10, 11): # fluid blocks deleteBlocksToo.value = True w = wrapped_label( "WARNING: You are about to modify the entire world. This cannot be undone. Really delete all copies of this item from all land, chests, furnaces, dispensers, dropped items, item-containing tiles, and player inventories in this world?", 60) col = (w, deleteSameDamage) if id < 256: col += (deleteBlocksToo,) d = Dialog(Column(col), ["OK", "Cancel"]) if d.present() == "OK": def deleteItemsIter(): i = 0 if deleteSameDamage.value: def matches(t): return t["id"].value == id and t["Damage"].value == Damage else: def matches(t): return t["id"].value == id def matches_itementity(e): if e["id"].value != "Item": return False if "Item" not in e: return False t = e["Item"] return matches(t) for player in self.editor.level.players: tag = self.editor.level.getPlayerTag(player) l = len(tag["Inventory"]) tag["Inventory"].value = [t for t in tag["Inventory"].value if not matches(t)] for chunk in self.editor.level.getChunks(): if id < 256 and deleteBlocksToo.value: matchingBlocks = chunk.Blocks == id if deleteSameDamage.value: matchingBlocks &= chunk.Data == Damage if any(matchingBlocks): chunk.Blocks[matchingBlocks] = 0 chunk.Data[matchingBlocks] = 0 chunk.chunkChanged() self.editor.invalidateChunks([chunk.chunkPosition]) for te in chunk.TileEntities: if "Items" in te: l = len(te["Items"]) te["Items"].value = [t for t in te["Items"].value if not matches(t)] if l != len(te["Items"]): chunk.dirty = True entities = [e for e in chunk.Entities if matches_itementity(e)] if len(entities) != len(chunk.Entities): chunk.Entities.value = entities chunk.dirty = True yield (i, self.editor.level.chunkCount) i += 1 progressInfo = _("Deleting the item {0} from the entire world ({1} chunks)").format( itemName(chestWidget.id, 0), self.editor.level.chunkCount) mceutils.showProgress(progressInfo, deleteItemsIter(), cancel=True) self.editor.addUnsavedEdit() chestWidget.selectedItemIndex = min(chestWidget.selectedItemIndex, len(tileEntityTag["Items"]) - 1)
class ChunkTool(EditorTool): toolIconName = "chunk" tooltipText = "Chunk Control" @property def statusText(self): return "Click and drag to select chunks. Hold ALT to deselect chunks. Hold SHIFT to select chunks." def toolEnabled(self): return isinstance(self.editor.level, pymclevel.ChunkedLevelMixin) _selectedChunks = None _displayList = None def drawToolMarkers(self): if self._displayList is None: self._displayList = DisplayList(self._drawToolMarkers) #print len(self._selectedChunks) if self._selectedChunks else None, "!=", len(self.editor.selectedChunks) if self._selectedChunks != self.editor.selectedChunks or True: # xxx self._selectedChunks = set(self.editor.selectedChunks) self._displayList.invalidate() self._displayList.call() def _drawToolMarkers(self): lines = ( ((-1, 0), (0, 0, 0, 1), []), ((1, 0), (1, 0, 1, 1), []), ((0, -1), (0, 0, 1, 0), []), ((0, 1), (0, 1, 1, 1), []), ) for ch in self._selectedChunks: cx, cz = ch for (dx, dz), points, positions in lines: n = (cx + dx, cz + dz) if n not in self._selectedChunks: positions.append([ch]) color = self.editor.selectionTool.selectionColor + (0.3, ) GL.glColor(*color) with gl.glEnable(GL.GL_BLEND): import renderer sizedChunks = renderer.chunkMarkers(self._selectedChunks) for size, chunks in sizedChunks.iteritems(): if not len(chunks): continue chunks = numpy.array(chunks, dtype='float32') chunkPosition = numpy.zeros(shape=(chunks.shape[0], 4, 3), dtype='float32') chunkPosition[..., (0, 2)] = numpy.array( ((0, 0), (0, 1), (1, 1), (1, 0)), dtype='float32') chunkPosition[..., (0, 2)] *= size chunkPosition[..., (0, 2)] += chunks[:, newaxis, :] chunkPosition *= 16 chunkPosition[..., 1] = self.editor.level.Height GL.glVertexPointer(3, GL.GL_FLOAT, 0, chunkPosition.ravel()) #chunkPosition *= 8 GL.glDrawArrays(GL.GL_QUADS, 0, len(chunkPosition) * 4) for d, points, positions in lines: if 0 == len(positions): continue vertexArray = numpy.zeros((len(positions), 4, 3), dtype='float32') vertexArray[..., [0, 2]] = positions vertexArray.shape = len(positions), 2, 2, 3 vertexArray[..., 0, 0, 0] += points[0] vertexArray[..., 0, 0, 2] += points[1] vertexArray[..., 0, 1, 0] += points[2] vertexArray[..., 0, 1, 2] += points[3] vertexArray[..., 1, 0, 0] += points[2] vertexArray[..., 1, 0, 2] += points[3] vertexArray[..., 1, 1, 0] += points[0] vertexArray[..., 1, 1, 2] += points[1] vertexArray *= 16 vertexArray[..., 1, :, 1] = self.editor.level.Height GL.glVertexPointer(3, GL.GL_FLOAT, 0, vertexArray) GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_LINE) GL.glDrawArrays(GL.GL_QUADS, 0, len(positions) * 4) GL.glPolygonMode(GL.GL_FRONT_AND_BACK, GL.GL_FILL) with gl.glEnable(GL.GL_BLEND, GL.GL_DEPTH_TEST): GL.glDepthMask(False) GL.glDrawArrays(GL.GL_QUADS, 0, len(positions) * 4) GL.glDepthMask(True) @property def worldTooltipText(self): box = self.editor.selectionTool.selectionBoxInProgress() if box: box = box.chunkBox(self.editor.level) l, w = box.length // 16, box.width // 16 return "%s x %s chunks" % (l, w) def toolSelected(self): self.editor.selectionToChunks() self.panel = ChunkToolPanel(self) self.panel.centery = self.editor.centery self.panel.left = 10 self.editor.add(self.panel) def cancel(self): self.editor.remove(self.panel) def selectedChunks(self): return self.editor.selectedChunks @alertException def extractChunks(self): folder = mcplatform.askSaveFile( mcplatform.docsFolder, title='Export chunks to...', defaultName=self.editor.level.displayName + "_chunks", filetype='Folder\0*.*\0\0', suffix="", ) if not folder: return # TODO: We need a third dimension, Scotty! for cx, cz in self.selectedChunks(): if self.editor.level.containsChunk(cx, cz): self.editor.level.extractChunk(cx, cz, folder) @alertException def destroyChunks(self, chunks=None): if "No" == ask("Really delete these chunks? This cannot be undone.", ("Yes", "No")): return if chunks is None: chunks = self.selectedChunks() chunks = list(chunks) def _destroyChunks(): i = 0 chunkCount = len(chunks) for cx, cz in chunks: i += 1 yield (i, chunkCount) if self.editor.level.containsChunk(cx, cz): try: self.editor.level.deleteChunk(cx, cz) except Exception, e: print "Error during chunk delete: ", e with setWindowCaption("DELETING - "): showProgress("Deleting chunks...", _destroyChunks()) self.editor.renderer.invalidateChunkMarkers() self.editor.renderer.discardChunks(chunks)
self.editor.saveFile() def _pruneChunks(): selectedChunks = self.selectedChunks() for i, cPos in enumerate(list(self.editor.level.allChunks)): if cPos not in selectedChunks: try: self.editor.level.deleteChunk(*cPos) except Exception, e: print "Error during chunk delete: ", e yield i, self.editor.level.chunkCount with setWindowCaption("PRUNING - "): showProgress("Pruning chunks...", _pruneChunks()) self.editor.renderer.invalidateChunkMarkers() self.editor.discardAllChunks() #self.editor.addUnsavedEdit() @alertException def relightChunks(self): def _relightChunks(): for i in self.editor.level.generateLightsIter( self.selectedChunks()): yield i with setWindowCaption("RELIGHTING - "):
def apply(self, op, point): undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) dirtyChunks = set() def saveUndoChunk(cx, cz): if (cx, cz) in dirtyChunks: return dirtyChunks.add((cx, cz)) undoLevel.copyChunkFrom(op.level, cx, cz) doomedBlock = op.level.blockAt(*point) doomedBlockData = op.level.blockDataAt(*point) checkData = (doomedBlock not in (8, 9, 10, 11)) indiscriminate = op.options['Indiscriminate'] if indiscriminate: checkData = False if doomedBlock == 2: # grass doomedBlock = 3 # dirt if doomedBlock == op.options['Block'].ID and ( doomedBlockData == op.options['Block'].blockData or checkData == False): return x, y, z = point saveUndoChunk(x // 16, z // 16) op.level.setBlockAt(x, y, z, op.options['Block'].ID) op.level.setBlockDataAt(x, y, z, op.options['Block'].blockData) def processCoords(coords): newcoords = collections.deque() for (x, y, z) in coords: for _dir, offsets in pymclevel.faceDirections: dx, dy, dz = offsets p = (x + dx, y + dy, z + dz) nx, ny, nz = p b = op.level.blockAt(nx, ny, nz) if indiscriminate: if b == 2: b = 3 if b == doomedBlock: if checkData: if op.level.blockDataAt(nx, ny, nz) != doomedBlockData: continue saveUndoChunk(nx // 16, nz // 16) op.level.setBlockAt(nx, ny, nz, op.options['Block'].ID) op.level.setBlockDataAt(nx, ny, nz, op.options['Block'].blockData) newcoords.append(p) return newcoords def spread(coords): while len(coords): start = datetime.datetime.now() num = len(coords) coords = processCoords(coords) d = datetime.datetime.now() - start progress = "Did {0} coords in {1}".format(num, d) log.info(progress) yield progress showProgress("Flood fill...", spread([point]), cancel=True) op.editor.invalidateChunks(dirtyChunks) op.undoLevel = undoLevel
def apply(self, op, point): undoLevel = pymclevel.MCInfdevOldLevel(mkundotemp(), create=True) dirtyChunks = set() def saveUndoChunk(cx, cz): if (cx, cz) in dirtyChunks: return dirtyChunks.add((cx, cz)) undoLevel.copyChunkFrom(op.level, cx, cz) doomedBlock = op.level.blockAt(*point) doomedBlockData = op.level.blockDataAt(*point) checkData = (doomedBlock not in (8, 9, 10, 11)) indiscriminate = op.options['Indiscriminate'] if indiscriminate: checkData = False if doomedBlock == 2: # grass doomedBlock = 3 # dirt if doomedBlock == op.options['Block'].ID and (doomedBlockData == op.options['Block'].blockData or checkData == False): return x, y, z = point saveUndoChunk(x // 16, z // 16) op.level.setBlockAt(x, y, z, op.options['Block'].ID) op.level.setBlockDataAt(x, y, z, op.options['Block'].blockData) def processCoords(coords): newcoords = collections.deque() for (x, y, z) in coords: for _dir, offsets in pymclevel.faceDirections: dx, dy, dz = offsets p = (x + dx, y + dy, z + dz) nx, ny, nz = p b = op.level.blockAt(nx, ny, nz) if indiscriminate: if b == 2: b = 3 if b == doomedBlock: if checkData: if op.level.blockDataAt(nx, ny, nz) != doomedBlockData: continue saveUndoChunk(nx // 16, nz // 16) op.level.setBlockAt(nx, ny, nz, op.options['Block'].ID) op.level.setBlockDataAt(nx, ny, nz, op.options['Block'].blockData) newcoords.append(p) return newcoords def spread(coords): while len(coords): start = datetime.datetime.now() num = len(coords) coords = processCoords(coords) d = datetime.datetime.now() - start progress = "Did {0} coords in {1}".format(num, d) log.info(progress) yield progress showProgress("Flood fill...", spread([point]), cancel=True) op.editor.invalidateChunks(dirtyChunks) op.undoLevel = undoLevel
def _pruneChunks(): maxChunks = self.editor.level.chunkCount selectedChunks = self.selectedChunks() for i, cPos in enumerate(list(self.editor.level.allChunks)): if cPos not in selectedChunks: try: self.editor.level.deleteChunk(*cPos) except Exception, e: print "Error during chunk delete: ", e yield i, maxChunks with setWindowCaption("PRUNING - "): showProgress("Pruning chunks...", _pruneChunks()) self.editor.renderer.invalidateChunkMarkers() self.editor.discardAllChunks() # self.editor.addUnsavedEdit() @alertException def relightChunks(self): def _relightChunks(): for i in self.editor.level.generateLightsIter(self.selectedChunks()): yield i with setWindowCaption("RELIGHTING - "): showProgress(_("Lighting {0} chunks...").format(len(self.selectedChunks())),