- 欢迎来到Minecraft插件百科!
- 对百科编辑一脸懵逼?帮助:快速入门带您快速熟悉百科编辑!
- 因近日遭受攻击,百科现已限制编辑,有意编辑请加入插件百科企鹅群:223812289
WorldEdit/CraftScript
- 点击此处开始翻译。
- 如本模板出现在原文存档页面,请注意更新主页面后,仍需要去除此处该模板。
- 如当前页面已经没有需要翻译的内容,请删去待翻译模板。
- 有标题的大篇幅文章,如果短时间内无法全部翻译,请先把所有的标题翻译出来,以便之后的贡献者选择与翻译章节内容。
WorldEdit里的脚本可以让你不用Java和编译你的代码,方便地写一个操控世界的代码。这个脚本在WorldEdit中被称作CraftScripts,并且这一切都基于JavaScript和你的craftscripts/ 文件. 使用基于WorldEdit写的脚本有这些优点:
- 能够与WorldEdit的 undo(撤销)/redo(反撤销) 功能对接
- 能够使用WorldEdit来优化编辑方块的操作
- 允许使用WorldEdit强大的方块类型语法 //set sign:3|How|are|you?
- 能够轻易获取用户选择的区域空间
此脚本需要通过Mozilla Rhino JavaScript在Java 6 或更高版本上运行。但是,如果WorldEdit的路径下有一个独立的Rhino版本,它会被优先使用。为了最大化的兼容性,请在Rhino的Java稳定版本上编写脚本。 脚本支持在v0.8时曾被移除。在v2.13后,脚本支持被重新加入。然而v0.8或更低的版本的脚本并不能兼容。 请不要运行来自不受信任的来源的脚本。
请查看 WorldEdit的API文档.
介绍
脚本有以下在他们的命名空间中的三个变量:
context
is an instance of CraftScriptContextplayer
is a copy of the player, an instance of LocalPlayerargv
是一个String类型的Java数组
想要运行一个脚本,请使用指令 /cs YourScript.js
在方块上工作
在WorldEdit中所有的方块编辑操作都基于一个 EditSession
. 这个对象会自动处理历史和方块放置的顺序。为了得到你自己的脚本的一个编辑样本,请使用:
var sess = context.remember();
任何时候你调用这个方法,你都会得到一个新的 EditSession
, 所以一定要保持一个左右。要设置一个方块,而不是给一个方块的物品ID。你给一个BaseBlock
. 这是因为方块包含各种各样的数据(如箱子方块里面的物品),如果只有方块类型ID的话,很多数据就会被丢失。 BaseBlock
is an independent representation of a block; it doesn't know where it is in the world. 这意味着你可以传递一个BaseBlock
到任何地方并重复使用他。 BaseBlock
s remember block type and block data. For more complex blocks such as signs and chests, you will use a BaseBlock
derivative such as SignBlock
.
举个例子:
设置一个带有4号颜色的羊毛方块
importPackage(Packages.com.sk89q.worldedit.blocks);
var sess = context.remember();
sess.setBlock(player.getBlockOn(), new BaseBlock(BlockID.CLOTH, 4));
标记这个是因为 BaseBlock
是在com.sk89q.worldedit.blocks 的命名空间,它必须被引入先. BlockID
有一个方块类型的列表. The first argument for setBlock()
is a Vector
indicating the position in the world.
想要得到方块,使用基于EditSession
的getBlock()
函数。你将也能得到一个BaseBlock
。
处理参数
Arguments由argv
变量传递。如果你需要去检查用户提供的参数是不是正确的,你可以用 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]);
如果用户输入的是一个无效的方块的话,将会抛出一个异常。并且,抛出异常后如果你没有去捕捉他,用户就会被提示这个异常,然后这个脚本就会被终止,就不会再进行下去。
配合使用Java包
你可以通过使用以下的语法来引入一个Java包:
importPackage(Packages.package.name.here);
注意:如果你安装了Mozilla's Rhino库,则不需要"Packages."前缀,但为了保持在默认的Java Rhino上运行的稳定性,"Packages."前缀是推荐的。 当安装了以后,你可以使用所有Java的扩展库,以及所有WorldEdit的类。
例程
例子:设置附近的发射器装满箭
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);
}
}
}
}
例子: 迷宫生成脚本
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);
}
}