0

そこで、マインクラフトの地形操作プログラム 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 に渡さずにこれを機能させる方法を知っている人はいますか? グローバルを使用するかどうかは気にしません。それは私の考えでした。

4

1 に答える 1