Add slot#
pattern
This commit is contained in:
parent
e27b1d5421
commit
398943b9b0
@ -19,16 +19,23 @@
|
|||||||
|
|
||||||
package com.sk89q.worldedit.bukkit;
|
package com.sk89q.worldedit.bukkit;
|
||||||
|
|
||||||
|
import com.boydti.fawe.Fawe;
|
||||||
|
import com.boydti.fawe.bukkit.FaweBukkit;
|
||||||
|
import com.boydti.fawe.bukkit.util.ItemUtil;
|
||||||
import com.sk89q.worldedit.WorldVector;
|
import com.sk89q.worldedit.WorldVector;
|
||||||
import org.bukkit.entity.Player;
|
|
||||||
import org.bukkit.inventory.ItemStack;
|
|
||||||
import com.sk89q.worldedit.extent.inventory.*;
|
|
||||||
import com.sk89q.worldedit.blocks.BaseItem;
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BaseItemStack;
|
import com.sk89q.worldedit.blocks.BaseItemStack;
|
||||||
import com.sk89q.worldedit.blocks.BlockID;
|
import com.sk89q.worldedit.blocks.BlockID;
|
||||||
import com.sk89q.worldedit.blocks.ItemType;
|
import com.sk89q.worldedit.blocks.ItemType;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.BlockBagException;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.OutOfBlocksException;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.OutOfSpaceException;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.SlottableBlockBag;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.inventory.ItemStack;
|
||||||
|
|
||||||
public class BukkitPlayerBlockBag extends BlockBag {
|
public class BukkitPlayerBlockBag extends BlockBag implements SlottableBlockBag {
|
||||||
|
|
||||||
private Player player;
|
private Player player;
|
||||||
private ItemStack[] items;
|
private ItemStack[] items;
|
||||||
@ -60,6 +67,59 @@ public class BukkitPlayerBlockBag extends BlockBag {
|
|||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BaseItem getItem(int slot) {
|
||||||
|
loadInventory();
|
||||||
|
return toBaseItem(items[slot]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setItem(int slot, BaseItem block) {
|
||||||
|
loadInventory();
|
||||||
|
items[slot] = toItemStack(block);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getSelectedSlot() {
|
||||||
|
return player.getInventory().getHeldItemSlot();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BaseItem toBaseItem(ItemStack item) {
|
||||||
|
if (item == null) return new BaseItemStack(0, 0);
|
||||||
|
int id = item.getTypeId();
|
||||||
|
short data;
|
||||||
|
if (id < 256) {
|
||||||
|
data = item.getData().getData();
|
||||||
|
} else {
|
||||||
|
data = item.getDurability();
|
||||||
|
}
|
||||||
|
BaseItemStack baseItem = new BaseItemStack(id, item.getAmount(), data);
|
||||||
|
ItemUtil itemUtil = Fawe.<FaweBukkit>imp().getItemUtil();
|
||||||
|
if (itemUtil != null && item.hasItemMeta()) {
|
||||||
|
baseItem.setNbtData(itemUtil.getNBT(item));
|
||||||
|
}
|
||||||
|
return baseItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
private ItemStack toItemStack(BaseItem item) {
|
||||||
|
if (item == null) return null;
|
||||||
|
final int id = item.getType();
|
||||||
|
final int damage = item.getData();
|
||||||
|
int amount = (item instanceof BaseItemStack) ? ((BaseItemStack) item).getAmount() : 1;
|
||||||
|
ItemStack bukkitItem;
|
||||||
|
if (id < 256) {
|
||||||
|
bukkitItem = new ItemStack(id, amount, (short) 0, (byte) damage);
|
||||||
|
} else {
|
||||||
|
bukkitItem = new ItemStack(id, amount, (short) damage);
|
||||||
|
}
|
||||||
|
ItemUtil itemUtil = Fawe.<FaweBukkit>imp().getItemUtil();
|
||||||
|
if (itemUtil != null && item.hasNBTData()) {
|
||||||
|
bukkitItem = itemUtil.setNBT(bukkitItem, item.getNbtData());
|
||||||
|
}
|
||||||
|
return bukkitItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void fetchItem(BaseItem item) throws BlockBagException {
|
public void fetchItem(BaseItem item) throws BlockBagException {
|
||||||
final int id = item.getType();
|
final int id = item.getType();
|
||||||
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.Vector;
|
|||||||
import com.sk89q.worldedit.Vector2D;
|
import com.sk89q.worldedit.Vector2D;
|
||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BlockData;
|
import com.sk89q.worldedit.blocks.BlockData;
|
||||||
import com.sk89q.worldedit.command.BiomeCommands;
|
import com.sk89q.worldedit.command.BiomeCommands;
|
||||||
import com.sk89q.worldedit.command.BrushCommands;
|
import com.sk89q.worldedit.command.BrushCommands;
|
||||||
@ -573,6 +574,7 @@ public class Fawe {
|
|||||||
Vector2D.inject(); // Optimizations
|
Vector2D.inject(); // Optimizations
|
||||||
// Block
|
// Block
|
||||||
BaseBlock.inject(); // Optimizations
|
BaseBlock.inject(); // Optimizations
|
||||||
|
BaseItem.inject();
|
||||||
// Biome
|
// Biome
|
||||||
BaseBiome.inject(); // Features
|
BaseBiome.inject(); // Features
|
||||||
// Pattern
|
// Pattern
|
||||||
|
140
core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java
Normal file
140
core/src/main/java/com/sk89q/worldedit/blocks/BaseItem.java
Normal file
@ -0,0 +1,140 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.blocks;
|
||||||
|
|
||||||
|
import com.sk89q.jnbt.CompoundTag;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an item, without an amount value. See {@link BaseItemStack}
|
||||||
|
* for an instance with stack amount information.
|
||||||
|
*
|
||||||
|
* <p>This class may be removed in the future.</p>
|
||||||
|
*/
|
||||||
|
public class BaseItem {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
private short data;
|
||||||
|
private CompoundTag nbt;
|
||||||
|
private final Map<Integer, Integer> enchantments = new HashMap<Integer, Integer>();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the object.
|
||||||
|
*
|
||||||
|
* @param id ID of the item
|
||||||
|
*/
|
||||||
|
public BaseItem(int id) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the object.
|
||||||
|
*
|
||||||
|
* @param id ID of the item
|
||||||
|
* @param data data value of the item
|
||||||
|
*/
|
||||||
|
public BaseItem(int id, short data) {
|
||||||
|
this.id = id;
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of item.
|
||||||
|
*
|
||||||
|
* @return the id
|
||||||
|
*/
|
||||||
|
public int getType() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the type of item.
|
||||||
|
*
|
||||||
|
* @param id the id to set
|
||||||
|
*/
|
||||||
|
public void setType(int id) {
|
||||||
|
this.id = id;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the damage value.
|
||||||
|
*
|
||||||
|
* @return the damage
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public short getDamage() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the data value.
|
||||||
|
*
|
||||||
|
* @return the data
|
||||||
|
*/
|
||||||
|
public short getData() {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data value.
|
||||||
|
*
|
||||||
|
* @param data the damage to set
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
|
public void setDamage(short data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the data value.
|
||||||
|
*
|
||||||
|
* @param data the damage to set
|
||||||
|
*/
|
||||||
|
public void setData(short data) {
|
||||||
|
this.data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasNBTData() {
|
||||||
|
return nbt != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public CompoundTag getNbtData() {
|
||||||
|
return nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setNbtData(CompoundTag nbt) {
|
||||||
|
this.nbt = nbt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the map of enchantments.
|
||||||
|
*
|
||||||
|
* @return map of enchantments
|
||||||
|
*/
|
||||||
|
public Map<Integer, Integer> getEnchantments() {
|
||||||
|
return enchantments;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> inject() {
|
||||||
|
return BaseItem.class;
|
||||||
|
}
|
||||||
|
}
|
@ -31,6 +31,7 @@ import com.sk89q.worldedit.NotABlockException;
|
|||||||
import com.sk89q.worldedit.WorldEdit;
|
import com.sk89q.worldedit.WorldEdit;
|
||||||
import com.sk89q.worldedit.WorldEditException;
|
import com.sk89q.worldedit.WorldEditException;
|
||||||
import com.sk89q.worldedit.blocks.BaseBlock;
|
import com.sk89q.worldedit.blocks.BaseBlock;
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
import com.sk89q.worldedit.blocks.BlockType;
|
import com.sk89q.worldedit.blocks.BlockType;
|
||||||
import com.sk89q.worldedit.blocks.ClothColor;
|
import com.sk89q.worldedit.blocks.ClothColor;
|
||||||
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
|
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
|
||||||
@ -44,6 +45,8 @@ import com.sk89q.worldedit.extension.input.InputParseException;
|
|||||||
import com.sk89q.worldedit.extension.input.NoMatchException;
|
import com.sk89q.worldedit.extension.input.NoMatchException;
|
||||||
import com.sk89q.worldedit.extension.input.ParserContext;
|
import com.sk89q.worldedit.extension.input.ParserContext;
|
||||||
import com.sk89q.worldedit.extension.platform.Actor;
|
import com.sk89q.worldedit.extension.platform.Actor;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.BlockBag;
|
||||||
|
import com.sk89q.worldedit.extent.inventory.SlottableBlockBag;
|
||||||
import com.sk89q.worldedit.internal.registry.InputParser;
|
import com.sk89q.worldedit.internal.registry.InputParser;
|
||||||
import com.sk89q.worldedit.world.World;
|
import com.sk89q.worldedit.world.World;
|
||||||
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
import com.sk89q.worldedit.world.registry.BundledBlockData;
|
||||||
@ -132,93 +135,120 @@ public class DefaultBlockParser extends InputParser<BaseBlock> {
|
|||||||
CompoundTag nbt = null;
|
CompoundTag nbt = null;
|
||||||
|
|
||||||
boolean parseDataValue = true;
|
boolean parseDataValue = true;
|
||||||
|
switch (testId.substring(0, Math.min(testId.length(), 4))) {
|
||||||
if ("hand".equalsIgnoreCase(testId)) {
|
case "pos1": {
|
||||||
// Get the block type from the item in the user's hand.
|
// Get the block type from the "primary position"
|
||||||
final BaseBlock blockInHand = getBlockInHand(context.requireActor());
|
final World world = context.requireWorld();
|
||||||
blockId = blockInHand.getId();
|
final BlockVector primaryPosition;
|
||||||
blockType = BlockType.fromID(blockId);
|
try {
|
||||||
data = blockInHand.getData();
|
primaryPosition = context.requireSession().getRegionSelector(world).getPrimaryPosition();
|
||||||
nbt = blockInHand.getNbtData();
|
} catch (IncompleteRegionException e) {
|
||||||
} else if ("pos1".equalsIgnoreCase(testId)) {
|
throw new InputParseException("Your selection is not complete.");
|
||||||
// Get the block type from the "primary position"
|
}
|
||||||
final World world = context.requireWorld();
|
final BaseBlock block = world.getBlock(primaryPosition);
|
||||||
final BlockVector primaryPosition;
|
blockId = block.getId();
|
||||||
try {
|
|
||||||
primaryPosition = context.requireSession().getRegionSelector(world).getPrimaryPosition();
|
|
||||||
} catch (IncompleteRegionException e) {
|
|
||||||
throw new InputParseException("Your selection is not complete.");
|
|
||||||
}
|
|
||||||
final BaseBlock blockInHand = world.getBlock(primaryPosition);
|
|
||||||
blockId = blockInHand.getId();
|
|
||||||
blockType = BlockType.fromID(blockId);
|
|
||||||
data = blockInHand.getData();
|
|
||||||
nbt = blockInHand.getNbtData();
|
|
||||||
} else {
|
|
||||||
// Attempt to parse the item ID or otherwise resolve an item/block
|
|
||||||
// name to its numeric ID
|
|
||||||
if (MathMan.isInteger(testId)) {
|
|
||||||
blockId = Integer.parseInt(testId);
|
|
||||||
blockType = BlockType.fromID(blockId);
|
blockType = BlockType.fromID(blockId);
|
||||||
} else {
|
data = block.getData();
|
||||||
BundledBlockData.BlockEntry block = BundledBlockData.getInstance().findById(testId);
|
nbt = block.getNbtData();
|
||||||
if (block == null) {
|
break;
|
||||||
BaseBlock baseBlock = BundledBlockData.getInstance().findByState(testId);
|
}
|
||||||
if (baseBlock == null) {
|
case "hand": {
|
||||||
blockType = BlockType.lookup(testId);
|
BaseBlock blockInHand = getBlockInHand(context.requireActor());
|
||||||
if (blockType == null) {
|
blockId = blockInHand.getId();
|
||||||
int t = worldEdit.getServer().resolveItem(testId);
|
blockType = BlockType.fromID(blockId);
|
||||||
if (t == 0 && !testId.contains("air")) {
|
data = blockInHand.getData();
|
||||||
throw new NoMatchException("Invalid block '" + input + "'.");
|
nbt = blockInHand.getNbtData();
|
||||||
}
|
break;
|
||||||
if (t >= 0) {
|
}
|
||||||
blockType = BlockType.fromID(t); // Could be null
|
case "slot": {
|
||||||
blockId = t;
|
try {
|
||||||
} else if (blockLocator.length == 2) { // Block IDs in MC 1.7 and above use mod:name
|
int slot = Integer.parseInt(testId.substring(4)) - 1;
|
||||||
t = worldEdit.getServer().resolveItem(blockAndExtraData[0]);
|
Actor actor = context.requireActor();
|
||||||
|
if (!(actor instanceof Player)) {
|
||||||
|
throw new InputParseException("The user is not a player!");
|
||||||
|
}
|
||||||
|
Player player = (Player) actor;
|
||||||
|
BlockBag bag = player.getInventoryBlockBag();
|
||||||
|
if (bag == null || !(bag instanceof SlottableBlockBag)) {
|
||||||
|
throw new InputParseException("Unsupported!");
|
||||||
|
}
|
||||||
|
SlottableBlockBag slottable = (SlottableBlockBag) bag;
|
||||||
|
BaseItem item = slottable.getItem(slot);
|
||||||
|
|
||||||
|
blockId = item.getType();
|
||||||
|
if (!player.getWorld().isValidBlockType(blockId)) {
|
||||||
|
throw new InputParseException("You're not holding a block!");
|
||||||
|
}
|
||||||
|
blockType = BlockType.fromID(blockId);
|
||||||
|
data = item.getData();
|
||||||
|
nbt = item.getNbtData();
|
||||||
|
break;
|
||||||
|
} catch (NumberFormatException ignore) {}
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
// Attempt to parse the item ID or otherwise resolve an item/block
|
||||||
|
// name to its numeric ID
|
||||||
|
if (MathMan.isInteger(testId)) {
|
||||||
|
blockId = Integer.parseInt(testId);
|
||||||
|
blockType = BlockType.fromID(blockId);
|
||||||
|
} else {
|
||||||
|
BundledBlockData.BlockEntry block = BundledBlockData.getInstance().findById(testId);
|
||||||
|
if (block == null) {
|
||||||
|
BaseBlock baseBlock = BundledBlockData.getInstance().findByState(testId);
|
||||||
|
if (baseBlock == null) {
|
||||||
|
blockType = BlockType.lookup(testId);
|
||||||
|
if (blockType == null) {
|
||||||
|
int t = worldEdit.getServer().resolveItem(testId);
|
||||||
|
if (t == 0 && !testId.contains("air")) {
|
||||||
|
throw new NoMatchException("Invalid block '" + input + "'.");
|
||||||
|
}
|
||||||
if (t >= 0) {
|
if (t >= 0) {
|
||||||
blockType = BlockType.fromID(t); // Could be null
|
blockType = BlockType.fromID(t); // Could be null
|
||||||
blockId = t;
|
blockId = t;
|
||||||
typeAndData = new String[]{blockAndExtraData[0]};
|
} else if (blockLocator.length == 2) { // Block IDs in MC 1.7 and above use mod:name
|
||||||
testId = blockAndExtraData[0];
|
t = worldEdit.getServer().resolveItem(blockAndExtraData[0]);
|
||||||
|
if (t >= 0) {
|
||||||
|
blockType = BlockType.fromID(t); // Could be null
|
||||||
|
blockId = t;
|
||||||
|
typeAndData = new String[]{blockAndExtraData[0]};
|
||||||
|
testId = blockAndExtraData[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
blockId = baseBlock.getId();
|
||||||
|
blockType = BlockType.fromID(blockId);
|
||||||
|
data = baseBlock.getData();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
blockId = baseBlock.getId();
|
blockId = block.legacyId;
|
||||||
blockType = BlockType.fromID(blockId);
|
blockType = BlockType.fromID(blockId);
|
||||||
data = baseBlock.getData();
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
blockId = block.legacyId;
|
|
||||||
blockType = BlockType.fromID(blockId);
|
|
||||||
}
|
}
|
||||||
}
|
if (blockId == -1 && blockType == null) {
|
||||||
if (blockId == -1 && blockType == null) {
|
// Maybe it's a cloth
|
||||||
// Maybe it's a cloth
|
ClothColor col = ClothColor.lookup(testId);
|
||||||
ClothColor col = ClothColor.lookup(testId);
|
if (col == null) {
|
||||||
if (col == null) {
|
throw new NoMatchException("Can't figure out what block '" + input + "' refers to");
|
||||||
throw new NoMatchException("Can't figure out what block '" + input + "' refers to");
|
}
|
||||||
|
|
||||||
|
blockType = BlockType.CLOTH;
|
||||||
|
data = col.getID();
|
||||||
|
|
||||||
|
// Prevent overriding the data value
|
||||||
|
parseDataValue = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
blockType = BlockType.CLOTH;
|
// Read block ID
|
||||||
data = col.getID();
|
if (blockId == -1) {
|
||||||
|
blockId = blockType.getID();
|
||||||
|
}
|
||||||
|
|
||||||
// Prevent overriding the data value
|
if (!context.requireWorld().isValidBlockType(blockId)) {
|
||||||
parseDataValue = false;
|
throw new NoMatchException("Does not match a valid block type: '" + input + "'");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read block ID
|
|
||||||
if (blockId == -1) {
|
|
||||||
blockId = blockType.getID();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!context.requireWorld().isValidBlockType(blockId)) {
|
|
||||||
throw new NoMatchException("Does not match a valid block type: '" + input + "'");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!context.isPreferringWildcard() && data == -1) {
|
if (!context.isPreferringWildcard() && data == -1) {
|
||||||
// No wildcards allowed => eliminate them.
|
// No wildcards allowed => eliminate them.
|
||||||
data = 0;
|
data = 0;
|
||||||
|
@ -0,0 +1,17 @@
|
|||||||
|
package com.sk89q.worldedit.extent.inventory;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.blocks.BaseItem;
|
||||||
|
|
||||||
|
public interface SlottableBlockBag {
|
||||||
|
BaseItem getItem(int slot);
|
||||||
|
|
||||||
|
void setItem(int slot, BaseItem block);
|
||||||
|
|
||||||
|
default int size() {
|
||||||
|
return 36;
|
||||||
|
}
|
||||||
|
|
||||||
|
default int getSelectedSlot() {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user