所以我正在为 Minecraft 地形操作程序 MCEdit 编写一个过滤器。该过滤器是用 Python 2 编写的(这是 MCEdit 将读取的唯一内容)。MCEdit 通过将变量级别(MCLevel 类型)、框和选项传递给用户定义的函数执行(级别、框、选项)来调用过滤器。您可以在此处找到关于此的文档 >> https://github.com/mcedit/pymclevel
我以前写过多个过滤器,所以我知道它是如何工作的。这是我的代码:
from pymclevel import *
import random
inputs = (("Replace", (0, 1, 255)), ("Of Damage", (0, 0, 15)), ("With", (1, 1, 255)), ("Of Damage ", (0, 0, 15)), ("This Percent of the Time", (50, 0, 100)), ("If it is Beside", (False)), ("Or Diagonal", (False)), ("Exclusively", (False)), ("To", (0, 1, 255)), ("Of Damage ", (0, 0, 15)))
def getBlock(x, y, z):
global level
return (level.blockAt(x, y, z), level.blockDataAt(x, y, z))
def setBlock(x, y, z, block, data):
global level
level.setBlockAt(x, y, z, block)
level.setBlockDataAt(x, y, z, data)
def IsBeside(x, y, z, block, data):
return (getBlock(x - 1, y, z) == (block, data) or getBlock(x + 1, y, z) == (block, data) or getBlock(x, y - 1, z) == (block, data) or getBlock(x, y + 1, z) == (block, data) or getBlock(x, y, z - 1) == (block, data) or getBlock(x, y, z + 1) == (block, data))
def IsDiagonal(x, y, z, block, data):
return (getBlock(x - 1, y - 1, z) == (block, data) or getBlock(x - 1, y, z - 1) == (block, data) or getBlock(x, y - 1, z - 1) == (block, data) or getBlock(x + 1, y + 1, z) == (block, data) or getBlock(x + 1, y, z + 1) == (block, data) or getBlock(x, y + 1, z + 1) == (block, data) or getBlock(x + 1, y + 1, z + 1) == (block, data) or getBlock(x - 1, y + 1, z + 1) == (block, data) or getBlock(x + 1, y - 1, z + 1) == (block, data) or getBlock(x + 1, y + 1, z - 1) == (block, data) or getBlock(x - 1, y - 1, z + 1) == (block, data) or getBlock(x - 1, y + 1, z - 1) == (block, data) or getBlock(x + 1, y - 1, z - 1) == (block, data) or getBlock(x - 1, y - 1, z - 1) == (block, data))
def perform(level, box, options):
Replace = options["Replace"]
ReplaceData = options["Of Damage"]
With = options["With"]
WithData = options["Of Damage "]
Percent = options["This Percent of the Time"]
Beside = options["If it is Beside"]
Diagonal = options["Or Diagonal"]
Exclusive = options["Exclusively"]
Check = options["To"]
CheckData = options["Of Damage "]
mark = False
for x in xrange(box.minx, box.maxx + 1):
for z in xrange(box.minz, box.maxz + 1):
for y in xrange(box.miny, box.maxy + 1):
if random.randint(1, 100) <= Percent and getBlock(x, y, z) == (Replace, ReplaceData):
if Beside and not Diagonal and not Exclusive:
if IsBeside(x, y, z, Check, CheckData):
mark = True
elif not Beside and Diagonal and not Exclusive:
if IsDiagonal(x, y, z, Check, CheckData):
mark = True
elif Beside and not Diagonal and Exclusive:
if IsBeside(x, y, z, Check, CheckData) and not IsDiagonal(x, y, z, Check, CheckData):
mark = True
elif not Beside and Diagonal and Exclusive:
if not IsBeside(x, y, z, Check, CheckData) and IsDiagonal(x, y, z, Check, CheckData):
mark = True
elif Beside and Diagonal:
if IsBeside(x, y, z, Check, CheckData) and IsDiagonal(x, y, z, Check, CheckData):
mark = True
else:
mark = True
if mark:
level.setBlock(x, y, z, With, WithData)
mark = False
我的问题是我需要多次调用 getBlock 和 setBlock ,而且很可能该级别将包含大量信息(足以将其复制到函数中需要几秒钟)。通过扩展,这意味着过滤器可以轻松运行数小时,其中大部分时间只是用于复制级别。当然,我不想这样做,而且由于 python 没有按引用传递,而且我无法访问传递给 perform 的原始变量,我只能尝试访问传递给 perform 的 level 的实例其他功能。这就是全局的东西进来的地方,这显然是行不通的。有谁知道在不将 level 作为函数参数传递给 getBlock 和 setBlock 的情况下进行这项工作的方法?我不在乎它是否使用全局,这只是我的想法。