そこで、マインクラフトの地形操作プログラム MCEdit 用のフィルターを作成しています。フィルターは Python 2 で書かれています (MCEdit が読み取るのは Python 2 だけです)。MCEdit は、変数 level (タイプ MCLevel)、ボックス、およびオプションをユーザー定義関数 perform(level, box, options) に渡すことによってフィルターを呼び出します。これに関するドキュメントはこちら >> 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に渡されたレベルのインスタンスにアクセスしようとすることしかできませんその他の機能。そこでグローバルな要素が登場しますが、これは明らかに機能しません。レベルを関数引数として getBlock と setBlock に渡さずにこれを機能させる方法を知っている人はいますか? グローバルを使用するかどうかは気にしません。それは私の考えでした。