• 因近日遭受攻击,百科现已限制新用户的编辑权限,一段时间后成为自动确认用户方可编辑。

WorldEdit/CraftScript

From Minecraft插件百科
Revision as of 01:40, 21 December 2015 by LocusAzzurro (talk | contribs)
Jump to: navigation, search
Icon-info.png
本页面已存在其他语言的内容,请协助翻译为本地化的中文。
  • 点击此处开始翻译。
  • 如本模板出现在原文存档页面,请注意更新主页面后,仍需要去除此处该模板
  • 如当前页面已经没有需要翻译的内容,请删去待翻译模板
  • 有标题的大篇幅文章,如果短时间内无法全部翻译,请先把所有的标题翻译出来,以便
  • 之后的贡献者选择与翻译章节内容。


WorldEdit里的脚本可以让你不用Java和编译你的代码,方便地写一个操控世界的代码。这个脚本在WorldEdit中被称作CraftScripts,并且这一切都基于JavaScript and go into your craftscripts/ 文件. 使用基于WorldEdit写的脚本有这些优点:

  • 能够与WorldEdit的 undo(撤销)/redo(反撤销) 功能对接
  • 能够使用WorldEdit来优化编辑方块的操作
  • Accept WorldEdit's powerful block type syntax //set sign:3|How|are|you?
  • 能够轻易获取用户选择的区域空间

Mozilla Rhino JavaScript engine bundled with Java 6 and above is used to evaluate the scripts. However, if an independent version of Rhino is found in WorldEdit's classpath, it will be used instead. For maximum portability, write scripts for Java's built-in version of Rhino.

Scripting support was re-added in v2.13 after having been removed in v0.8. However, scripts written for v0.8 and below are not compatible.

Warning.png Do not run scripts from untrusted sources.

Check out WorldEdit's API documentation.

介绍

脚本有以下在他们的命名空间中的三个变量:

想要运行一个脚本,请使用指令 /cs YourScript.js

在方块上工作

在WorldEdit中所有的方块编辑操作都基于一个 EditSession. This object handles history and block placement order all automatically. To get an edit session for your own script, use:

 var sess = context.remember();

任何时候你调用这个方法,你都会得到一个新的 EditSession, 所以一定要保持一个左右。要设置一个方块,而不是给一个方块的物品ID。你给一个BaseBlock. The reason is that blocks contain data (and in some cases, complex data like chest contents), and if only block types were passed around, a lot of data would be lost. BaseBlock is an independent representation of a block; it doesn't know where it is in the world. That means that you can pass a BaseBlock around everywhere and reuse it. BaseBlocks remember block type and block data. For more complex blocks such as signs and chests, you will use a BaseBlock derivative such as SignBlock.

举个例子:
Setting a cloth block with color value 4

importPackage(Packages.com.sk89q.worldedit.blocks);
var sess = context.remember();
sess.setBlock(player.getBlockOn(), new BaseBlock(BlockID.CLOTH, 4));

Note that because BaseBlock is in the com.sk89q.worldedit.blocks namespace, it had to be imported first. BlockID has a list of block types. The first argument for setBlock() is a Vector indicating the position in the world.

想要得到方块,使用基于EditSessiongetBlock()函数。你将也能得到一个BaseBlock

处理参数

Arguments are passed in under the argv variable. 如果你需要去检查用户提供的参数是不是正确的,你可以用 CraftScriptContext.checkArgs().

举个例子:检查参数

context.checkArgs(1, 3, "<block> [width] [height]");

如果你要去处理一个方块名字使其成为BaseBlock, 你可以使用 CraftScriptContext.getBlock(). 这个方法可以检查方块黑名单, however. 如果你需要一个方块去, 比如说, 替换, 你可以 ignore the blacklist by adding a boolean "true" for a third parameter.

举个例子:Getting the passed in block

context.checkArgs(1, 3, "<block> [width] [height]");
var block = context.getBlock(argv[1]);

如果用户输入的是一个无效的方块会怎么样?会抛出一个异常。并且如果你没有去捕捉他,用户就会被提示这个异常,然后这个脚本就会被终止,不再进行下去。

Working with Java packages

To import a java package, you can use the following syntax:

importPackage(Packages.package.name.here);

Tip: The "Packages." prefix is not required if you installed Mozilla's Rhino library, but to keep portability with the default bundle of Rhino in Java, it is recommended that you use it.

You have access to all of Java's vast library as it is installed. WorldEdit's classes are also fully available.

例程

例子:设置附近的发射器装满箭

importPackage(Packages.com.sk89q.worldedit.blocks);

var session = context.remember();
var origin = player.getPosition();

var arrows = new BaseItemStack(262, 64);

var items = [arrows, arrows, arrows,
             arrows, arrows, arrows,
             arrows, arrows, arrows]

for (var x = -4; x <= 4; x++) {
    for (var y = -4; y <= 4; y++) {
        for (var z = -4; z <= 4; z++) {
            var pt = origin.add(x, y, z);
            var id = session.getBlockType(pt);
            
            if (id == BlockID.DISPENSER) {
                var block = session.getBlock(pt);
                block.setItems(items);
                session.setBlock(pt, block);
                
                player.print("Arrows set @ " + pt);
            }
        }
    }
}

Example: Maze generation script

importPackage(Packages.com.sk89q.worldedit);
importPackage(Packages.com.sk89q.worldedit.blocks);

context.checkArgs(1, 3, "<block> [width] [height]");

var sess = context.remember();

// This may throw an exception that is caught by the script processor
var block = context.getBlock(argv[1]);
var w = argv.length > 2 ? parseInt(argv[2]) : 5;
var h = argv.length > 3 ? parseInt(argv[3]) : 5;

function id(x, y) {
    return y * (w + 1) + x;
}

function $x(i) {
    return i % (w + 1);
}

function $y(i) {
    return Math.floor(i / (w + 1));
}

function shuffle(arr) {
    var i = arr.length;
    if (i == 0) return false;
    while (--i) {
        var j = Math.floor(Math.random() * (i + 1));
        var tempi = arr[i];
        var tempj = arr[j];
        arr[i] = tempj;
        arr[j] = tempi;
    }
}

var stack = [];
var visited = {};
var noWallLeft = new Array(w * h);
var noWallAbove = new Array(w * h);
var current = 0;

stack.push(id(0, 0))

while (stack.length > 0) {
    var cell = stack.pop();
    var x = $x(cell), y = $y(cell);
    visited[cell] = true;
    
    var neighbors = []
    
    if (x > 0) neighbors.push(id(x - 1, y));
    if (x < w - 1) neighbors.push(id(x + 1, y));
    if (y > 0) neighbors.push(id(x, y - 1));
    if (y < h - 1) neighbors.push(id(x, y + 1));
    
    shuffle(neighbors);
    
    while (neighbors.length > 0) {
        var neighbor = neighbors.pop();
        var nx = $x(neighbor), ny = $y(neighbor);
        
        if (visited[neighbor] != true) {
            stack.push(cell);
            
            if (y == ny) {
                if (nx < x) {
                    noWallLeft[cell] = true;
                } else {
                    noWallLeft[neighbor] = true;
                }
            } else {
                if (ny < y) {
                    noWallAbove[cell] = true;
                } else {
                    noWallAbove[neighbor] = true;
                }
            }
            
            stack.push(neighbor);
            break;
        }
    }
}

var origin = player.getBlockIn();

for (var y = 0; y <= h; y++) {
    for (var x = 0; x <= w; x++) {
        var cell = id(x, y)
        if (!noWallLeft[cell] && y < h) {
            sess.setBlock(origin.add(x * 2 - 1, 0, y * 2), block);
            sess.setBlock(origin.add(x * 2 - 1, 1, y * 2), block);
        }
        if (!noWallAbove[cell] && x < w) {
            sess.setBlock(origin.add(x * 2, 0, y * 2 - 1), block);
            sess.setBlock(origin.add(x * 2, 1, y * 2 - 1), block);
        }
        sess.setBlock(origin.add(x * 2 - 1, 0, y * 2 - 1), block);
        sess.setBlock(origin.add(x * 2 - 1, 1, y * 2 - 1), block);
    }
}