gpt4 book ai didi

java - 如何在 Bukkit 模组中使用 Minecraft 的 WorldEdit 撤消堆栈

转载 作者:搜寻专家 更新时间:2023-10-31 20:31:49 26 4
gpt4 key购买 nike

我正在尝试在 Bukkit 模组中更新 Minecraft 中的方 block ,并能够//undo Minecraft 中的这些更改。我可以更改 block ,但无法//undo 更改。

我一定是遗漏了一些简单的东西,因为 Google 没有帮助我找到解决方案。

这是我的模组。它将当前选定区域的单个 block 设置为空气。注释掉的行是我尝试过但对我不起作用的内容。

public class Main extends JavaPlugin implements Listener
{
// ... //

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
{
if (command.getName().equalsIgnoreCase("setair"))
{
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) sender;

WorldEditPlugin worldEditPlugin = null;
worldEditPlugin = (WorldEditPlugin) Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
if(worldEditPlugin == null){
bukkitPlayer.sendMessage("Error: WorldEdit is null.");
}
else
{
com.sk89q.worldedit.bukkit.selections.Selection s = worldEditPlugin.getSelection(bukkitPlayer);
com.sk89q.worldedit.LocalSession localSession = worldEditPlugin.getSession(bukkitPlayer);
com.sk89q.worldedit.world.World localWorld = localSession.getSelectionWorld();
com.sk89q.worldedit.bukkit.BukkitPlayer wrappedPlayer = worldEditPlugin.wrapPlayer(bukkitPlayer);
com.sk89q.worldedit.LocalPlayer localPlayer = wrappedPlayer;
//com.sk89q.worldedit.world.World localWorld2 = localPlayer.getWorld();

com.sk89q.worldedit.EditSession editSession = worldEditPlugin.getWorldEdit().getEditSessionFactory().getEditSession(localWorld, -1, localPlayer);
//com.sk89q.worldedit.EditSession editSession = worldEditPlugin.createEditSession(bukkitPlayer);

//localSession.remember(editSession);

Vector minV = s.getNativeMinimumPoint();
try {
editSession.setBlock(minV, new com.sk89q.worldedit.blocks.BaseBlock(0,0));
} catch (MaxChangedBlocksException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

//try {
// localWorld.setBlock(minV, new com.sk89q.worldedit.blocks.BaseBlock(0,0));
//} catch (WorldEditException e) {
// TODO Auto-generated catch block
// e.printStackTrace();
//}


localSession.getRegionSelector(localWorld).learnChanges();
localSession.getRegionSelector(localWorld).explainRegionAdjust(localPlayer, localSession);

bukkitPlayer.performCommand("tellraw @p \"Done setair\"");
}

return true;
}
}
}

编辑:这是有效的。感谢 sorifiend 在下面的回答。为了让它工作,我还必须将 localSession.remember(editSession) 移动到 setBlock 调用之后。

@Override
public boolean onCommand(CommandSender sender, Command command, String label, String[] args)
{
if (command.getName().equalsIgnoreCase("setair"))
{
org.bukkit.entity.Player bukkitPlayer = (org.bukkit.entity.Player) sender;

WorldEditPlugin worldEditPlugin = null;
worldEditPlugin = (WorldEditPlugin) Bukkit.getServer().getPluginManager().getPlugin("WorldEdit");
if(worldEditPlugin == null){
bukkitPlayer.sendMessage("Error: WorldEdit is null.");
}
else
{
com.sk89q.worldedit.bukkit.selections.Selection s = worldEditPlugin.getSelection(bukkitPlayer);
com.sk89q.worldedit.LocalSession localSession = worldEditPlugin.getSession(bukkitPlayer);

com.sk89q.worldedit.EditSession editSession = worldEditPlugin.createEditSession(bukkitPlayer);

Vector minV = s.getNativeMinimumPoint();
try {
editSession.setBlock(minV, new com.sk89q.worldedit.blocks.BaseBlock(0,0));
} catch (MaxChangedBlocksException e) {
e.printStackTrace();
}

localSession.remember(editSession);

bukkitPlayer.performCommand("tellraw @p \"Done setair\"");
}

return true;
}
}

现在我可以用 WorldEdit 选择一些东西,运行 /setair 将其中一个 block 设置为空气。而 //undo 会做你期望的事情。

最佳答案

我不明白为什么这不起作用 editSession = worldEditPlugin.createEditSession(bukkitPlayer);,但是因为您选择了更长的方式 worldEditPlugin.getWorldEdit() .getEditSessionFactory().getEditSession(bukkitPlayer) 您还需要使用:editSession.enableQueue(); 之后。


下一个问题可能是如何设置 block 。快速浏览一下 source code 中的 setBlock 方法.有一个数字表示:

/**
* Set a block, bypassing history but still utilizing block re-ordering.
*
* @param position the position to set the block at
* @param block the block
* @return whether the block changed
*/
public boolean setBlock(Vector position, BlockStateHolder block) {

注意它是怎么说的“设置一个 block ,绕过历史和 block 重新排序”。

因此,如果您想记住 block 更改,您将需要自己跟踪它,或者使用不同的 setBlock 方法:

/**
* Sets the block at a position, subject to both history and block re-ordering.
*
* @param position the position
* @param pattern a pattern to use
* @return Whether the block changed -- not entirely dependable
* @throws MaxChangedBlocksException thrown if too many blocks are changed
*/
public boolean setBlock(Vector position, Pattern pattern)

注意它是怎么说的“将 block 设置在一个位置,历史和 block 重新排序”。

例如,这会将一个区 block 设置为空气并且还将保留区 block 历史:

Pattern pattern = new BlockPattern(BlockTypes.AIR.getDefaultState());
editSession.setBlock(minV, pattern);

现在您可以稍后像这样使用撤消方法:

//use a different EditSession to perform the undo in:
EditSession undoSession = ......;
editSession.undo(undoSession);

请注意,undoSession 不应与您要撤消的 session 相同。

编辑:源代码目前正在进行大量编辑/更改以支持 1.13 版(EditSession 类在 23 小时前更新)。因此,在您继续之前,您的 WorldEdit 库/插件可能需要更新。

关于java - 如何在 Bukkit 模组中使用 Minecraft 的 WorldEdit 撤消堆栈,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51939352/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com