Skip to content

Instantly share code, notes, and snippets.

@Deamon5550
Created August 27, 2014 22:36
Show Gist options
  • Save Deamon5550/39531cd094282e955dc7 to your computer and use it in GitHub Desktop.
Save Deamon5550/39531cd094282e955dc7 to your computer and use it in GitHub Desktop.
package com.budgiehouse.minecraft.world;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.log4j.Logger;
import org.bukkit.Material;
import org.bukkit.Note;
import org.bukkit.SkullType;
import org.bukkit.World;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BrewingStand;
import org.bukkit.block.Chest;
import org.bukkit.block.CommandBlock;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.Dispenser;
import org.bukkit.block.Dropper;
import org.bukkit.block.Furnace;
import org.bukkit.block.Hopper;
import org.bukkit.block.Jukebox;
import org.bukkit.block.NoteBlock;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.inventory.ItemStack;
import com.budgiehouse.minecraft.jnbt.ByteTag;
import com.budgiehouse.minecraft.jnbt.CompoundTag;
import com.budgiehouse.minecraft.jnbt.IntTag;
import com.budgiehouse.minecraft.jnbt.ListTag;
import com.budgiehouse.minecraft.jnbt.ShortTag;
import com.budgiehouse.minecraft.jnbt.StringTag;
import com.budgiehouse.minecraft.jnbt.Tag;
/**
* Utility class for creating tile entities based off of Maps of NBT Tags such as would be loaded from a schematic.
*
* @author Deamon
*/
public class TileEntityHelper
{
protected static Logger logger = Logger.getLogger(TileEntityHelper.class.getSimpleName());
/**
* Helper function for converting a numeric id into the correct SkullType enum value
*
* @param id
* @return
*/
private static SkullType getSkullType(int id)
{
if (id == 0)
{
return SkullType.SKELETON;
}
else if (id == 1)
{
return SkullType.WITHER;
}
else if (id == 2)
{
return SkullType.ZOMBIE;
}
else if (id == 3)
{
return SkullType.PLAYER;
}
else if (id == 4)
{
return SkullType.CREEPER;
}
else
{
return SkullType.PLAYER;
}
}
private static int getSkullType(SkullType sk)
{
if (sk == SkullType.SKELETON)
{
return 0;
}
else if (sk == SkullType.WITHER)
{
return 1;
}
else if (sk == SkullType.ZOMBIE)
{
return 2;
}
else if (sk == SkullType.PLAYER)
{
return 3;
}
else if (sk == SkullType.CREEPER)
{
return 4;
}
else
{
return 3;
}
}
/**
* Utility function to create a TileEntity at the specified Location with the given NBT values
*
* @param world
* @param x
* @param y
* @param z
* @param nbtValues
* @param blockID
* @param blockData
*/
@SuppressWarnings("deprecation")
public static void createTileEntity(World world, int x, int y, int z, Map<String, Tag> nbtValues, short blockID, byte blockData)
{
try
{
String entityName = "";
if (nbtValues.containsKey("id"))
{
entityName = ((StringTag) nbtValues.get("id")).getValue();
if (entityName.equals("Cauldron")) // Actually a brewing
// stand...
{
// Start by setting the block to the correct blockID and
// data value
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
// fetch the TileEntityClass
BrewingStand brewingStand = (BrewingStand) block.getState();
// brewing stands have inventories so load the list of items
// to place into it
List<Tag> itemsList = ((ListTag) nbtValues.get("Items")).getValue();
for (Tag item: itemsList)
{
// fetch the sub-map of values about the this item
Map<String, Tag> itemValues = ((CompoundTag) item).getValue();
short type = ((ShortTag) itemValues.get("id")).getValue();
short damage = ((ShortTag) itemValues.get("Damage")).getValue();
byte amount = ((ByteTag) itemValues.get("Count")).getValue();
// create the item
ItemStack itemObject = new ItemStack(type, amount, damage);
int slot = ((ByteTag) itemValues.get("Slot")).getValue();
// place it into the inventory
brewingStand.getInventory().setItem(slot, itemObject);
}
int time = ((IntTag) nbtValues.get("BrewTime")).getValue();
brewingStand.setBrewingTime(time);
// Update this Tile Entity so changes are recorded and
// pushed to the client
brewingStand.update();
}
if (entityName.equals("Chest"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Chest chest = (Chest) block.getState();
List<Tag> itemList = ((ListTag) nbtValues.get("Items")).getValue();
for (Tag item: itemList)
{
Map<String, Tag> itemValues = ((CompoundTag) item).getValue();
short type = ((ShortTag) itemValues.get("id")).getValue();
short damage = ((ShortTag) itemValues.get("Damage")).getValue();
byte amount = ((ByteTag) itemValues.get("Count")).getValue();
ItemStack itemObject = new ItemStack(type, amount, damage);
int slot = ((ByteTag) itemValues.get("Slot")).getValue();
chest.getBlockInventory().setItem(slot, itemObject);
}
chest.update();
}
if (entityName.equals("Control")) // command blocks
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
CommandBlock commandBlock = (CommandBlock) block.getState();
commandBlock.setCommand(((StringTag) nbtValues.get("Command")).getValue());
commandBlock.update();
}
if (entityName.equals("Furnace"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Furnace furnace = (Furnace) block.getState();
List<Tag> itemList = ((ListTag) nbtValues.get("Items")).getValue();
for (Tag item: itemList)
{
Map<String, Tag> itemValues = ((CompoundTag) item).getValue();
short type = ((ShortTag) itemValues.get("id")).getValue();
short damage = ((ShortTag) itemValues.get("Damage")).getValue();
byte amount = ((ByteTag) itemValues.get("Count")).getValue();
ItemStack itemObject = new ItemStack(type, amount, damage);
int slot = ((ByteTag) itemValues.get("Slot")).getValue();
furnace.getInventory().setItem(slot, itemObject);
}
short time = ((ShortTag) nbtValues.get("BurnTime")).getValue();
short time0 = ((ShortTag) nbtValues.get("CookTime")).getValue();
furnace.setBurnTime(time);
furnace.setCookTime(time0);
furnace.update();
}
if (entityName.equals("Hopper"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Hopper hopper = (Hopper) block.getState();
List<Tag> itemList = ((ListTag) nbtValues.get("Items")).getValue();
for (Tag item: itemList)
{
Map<String, Tag> itemValues = ((CompoundTag) item).getValue();
short type = ((ShortTag) itemValues.get("id")).getValue();
short damage = ((ShortTag) itemValues.get("Damage")).getValue();
byte amount = ((ByteTag) itemValues.get("Count")).getValue();
ItemStack itemObject = new ItemStack(type, amount, damage);
int slot = ((ByteTag) itemValues.get("Slot")).getValue();
hopper.getInventory().setItem(slot, itemObject);
}
hopper.update();
}
if (entityName.equals("MobSpawner"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
CreatureSpawner spawner = (CreatureSpawner) block.getState();
spawner.setCreatureTypeByName(((StringTag) nbtValues.get("EntityId")).getValue());
spawner.setDelay(((ShortTag) nbtValues.get("Delay")).getValue());
spawner.update();
}
if (entityName.equals("Music")) // note blocks
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
NoteBlock noteBlock = (NoteBlock) block.getState();
noteBlock.setNote(new Note(((ByteTag) nbtValues.get("note")).getValue()));
noteBlock.update();
}
if (entityName.equals("RecordPlayer"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Jukebox jukebox = (Jukebox) block.getState();
jukebox.setPlaying(Material.getMaterial(((IntTag) nbtValues.get("Record")).getValue()));
jukebox.update();
}
if (entityName.equals("Sign"))
{
Block block = world.getBlockAt(x, y, z);
String line1 = ((StringTag) nbtValues.get("Text1")).getValue();
block.setTypeIdAndData(blockID, blockData, false);
Sign sign = (Sign) block.getState();
sign.setLine(0, line1);
sign.setLine(1, ((StringTag) nbtValues.get("Text2")).getValue());
sign.setLine(2, ((StringTag) nbtValues.get("Text3")).getValue());
sign.setLine(3, ((StringTag) nbtValues.get("Text4")).getValue());
sign.update();
}
if (entityName.equals("Skull"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Skull skull = (Skull) block.getState();
skull.setSkullType(getSkullType(((ByteTag) nbtValues.get("SkullType")).getValue()));
skull.setRotation(getSkullRot(((ByteTag) nbtValues.get("Rot")).getValue()));
String owner = ((StringTag) nbtValues.get("ExtraType")).getValue();
if (owner.equals("")) owner = "Player";
skull.setOwner(owner);
skull.update();
}
if (entityName.equals("Trap")) // Dispensers
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Dispenser dispenser = (Dispenser) block.getState();
List<Tag> itemList = ((ListTag) nbtValues.get("Items")).getValue();
for (Tag item: itemList)
{
Map<String, Tag> itemValues = ((CompoundTag) item).getValue();
short type = ((ShortTag) itemValues.get("id")).getValue();
short damage = ((ShortTag) itemValues.get("Damage")).getValue();
byte amount = ((ByteTag) itemValues.get("Count")).getValue();
ItemStack itemObject = new ItemStack(type, amount, damage);
int slot = ((ByteTag) itemValues.get("Slot")).getValue();
dispenser.getInventory().setItem(slot, itemObject);
}
dispenser.update();
}
if (entityName.equals("Dropper"))
{
Block block = world.getBlockAt(x, y, z);
block.setTypeIdAndData(blockID, blockData, false);
Dropper dropper = (Dropper) block.getState();
List<Tag> itemList = ((ListTag) nbtValues.get("Items")).getValue();
for (Tag item: itemList)
{
Map<String, Tag> itemValues = ((CompoundTag) item).getValue();
short type = ((ShortTag) itemValues.get("id")).getValue();
short damage = ((ShortTag) itemValues.get("Damage")).getValue();
byte amount = ((ByteTag) itemValues.get("Count")).getValue();
ItemStack itemObject = new ItemStack(type, amount, damage);
int slot = ((ByteTag) itemValues.get("Slot")).getValue();
dropper.getInventory().setItem(slot, itemObject);
}
dropper.update();
}
}
}
catch (ClassCastException e)
{
logger.warn("Failed to place TileEntity at " + x + " " + y + " " + z, e);
}
}
@SuppressWarnings("deprecation")
public static boolean isTileEntityBlock(Block b)
{
for (int i: tileBlocks)
{
if (b.getTypeId() == i) return true;
}
return false;
}
@SuppressWarnings("deprecation") private static final int[] tileBlocks = new int[] {
Material.DROPPER.getId(),
Material.DISPENSER.getId(),
Material.SKULL.getId(),
Material.SIGN.getId(),
Material.SIGN_POST.getId(),
Material.JUKEBOX.getId(),
Material.NOTE_BLOCK.getId(),
Material.MOB_SPAWNER.getId(),
Material.FURNACE.getId(),
Material.COMMAND.getId(),
Material.HOPPER.getId(),
Material.CHEST.getId(),
Material.CAULDRON.getId(),
Material.BEACON.getId() };
@SuppressWarnings("deprecation")
public static Map<String, Tag> extract(Block b)
{
Map<String, Tag> tile = new HashMap<String, Tag>();
tile.put("x", new IntTag("x", b.getX()));
tile.put("y", new IntTag("y", b.getY()));
tile.put("z", new IntTag("z", b.getZ()));
if (b.getTypeId() == Material.DROPPER.getId() && b.getState() instanceof Dropper)
{
Dropper dropper = (Dropper) b.getState();
tile.put("id", new StringTag("id", "Dropper"));
List<Tag> items = new ArrayList<Tag>();
int slot = 0;
for (ItemStack i: dropper.getInventory().getContents())
{
slot++;
if (i == null) continue;
Map<String, Tag> item = new HashMap<String, Tag>();
item.put("id", new ShortTag("id", (short) i.getTypeId()));
item.put("Damage", new ShortTag("Damage", i.getDurability()));
item.put("Count", new ByteTag("Count", (byte) i.getAmount()));
item.put("Slot", new ByteTag("Slot", (byte) slot));
items.add(new CompoundTag("item", item));
}
tile.put("Items", new ListTag("Items", CompoundTag.class, items));
}
else if (b.getTypeId() == Material.DISPENSER.getId() && b.getState() instanceof Dispenser)
{
Dispenser dropper = (Dispenser) b.getState();
tile.put("id", new StringTag("id", "Dispenser"));
List<Tag> items = new ArrayList<Tag>();
int slot = 0;
for (ItemStack i: dropper.getInventory().getContents())
{
slot++;
if (i == null) continue;
Map<String, Tag> item = new HashMap<String, Tag>();
item.put("id", new ShortTag("id", (short) i.getTypeId()));
item.put("Damage", new ShortTag("Damage", i.getDurability()));
item.put("Count", new ByteTag("Count", (byte) i.getAmount()));
item.put("Slot", new ByteTag("Slot", (byte) slot));
items.add(new CompoundTag("item", item));
}
tile.put("Items", new ListTag("Items", CompoundTag.class, items));
}
else if (b.getTypeId() == Material.SKULL.getId() && b.getState() instanceof Skull)
{
Skull skull = (Skull) b.getState();
tile.put("id", new StringTag("id", "Skull"));
tile.put("SkullType", new ByteTag("SkullType", (byte) getSkullType(skull.getSkullType())));
tile.put("Rot", new ByteTag("Rot", (byte) getSkullRot(skull.getRotation())));
if (skull.getOwner() == null)
{
tile.put("ExtraType", new StringTag("ExtraType", "Player"));
}
else
{
tile.put("ExtraType", new StringTag("ExtraType", skull.getOwner()));
}
}
else if (b.getTypeId() == Material.SIGN.getId() || b.getTypeId() == Material.SIGN_POST.getId() && b.getState() instanceof Sign)
{
Sign sign = (Sign) b.getState();
tile.put("id", new StringTag("id", "Sign"));
tile.put("Text1", new StringTag("Text1", sign.getLines()[0] == null ? "" : sign.getLines()[0]));
tile.put("Text2", new StringTag("Text2", sign.getLines()[1] == null ? "" : sign.getLines()[1]));
tile.put("Text3", new StringTag("Text3", sign.getLines()[2] == null ? "" : sign.getLines()[2]));
tile.put("Text4", new StringTag("Text4", sign.getLines()[3] == null ? "" : sign.getLines()[3]));
}
else if (b.getTypeId() == Material.JUKEBOX.getId() && b.getState() instanceof Jukebox)
{
Jukebox jukebox = (Jukebox) b.getState();
tile.put("id", new StringTag("id", "RecordPlayer"));
tile.put("Record", new IntTag("Record", jukebox.getPlaying().getId()));
}
else if (b.getTypeId() == Material.NOTE_BLOCK.getId() && b.getState() instanceof NoteBlock)
{
NoteBlock note = (NoteBlock) b.getState();
tile.put("id", new StringTag("id", "Music"));
tile.put("note", new ByteTag("note", (byte) note.getNote().getOctave()));
}
else if (b.getTypeId() == Material.BREWING_STAND.getId() && b.getState() instanceof BrewingStand)
{
BrewingStand stand = (BrewingStand) b.getState();
tile.put("id", new StringTag("id", "Cauldron"));
List<Tag> items = new ArrayList<Tag>();
int slot = 0;
for (ItemStack i: stand.getInventory().getContents())
{
slot++;
if (i == null) continue;
Map<String, Tag> item = new HashMap<String, Tag>();
item.put("id", new ShortTag("id", (short) i.getTypeId()));
item.put("Damage", new ShortTag("Damage", i.getDurability()));
item.put("Count", new ByteTag("Count", (byte) i.getAmount()));
item.put("Slot", new ByteTag("Slot", (byte) slot));
items.add(new CompoundTag("item", item));
}
tile.put("Items", new ListTag("Items", CompoundTag.class, items));
tile.put("BrewTime", new IntTag("BrewTime", stand.getBrewingTime()));
}
else if (b.getTypeId() == Material.CHEST.getId() && b.getState() instanceof Chest)
{
Chest chest = (Chest) b.getState();
tile.put("id", new StringTag("id", "Chest"));
List<Tag> items = new ArrayList<Tag>();
int slot = 0;
for (ItemStack i: chest.getInventory().getContents())
{
slot++;
if (i == null) continue;
Map<String, Tag> item = new HashMap<String, Tag>();
item.put("id", new ShortTag("id", (short) i.getTypeId()));
item.put("Damage", new ShortTag("Damage", i.getDurability()));
item.put("Count", new ByteTag("Count", (byte) i.getAmount()));
item.put("Slot", new ByteTag("Slot", (byte) slot));
items.add(new CompoundTag("item", item));
}
tile.put("Items", new ListTag("Items", CompoundTag.class, items));
}
else if (b.getTypeId() == Material.COMMAND.getId() && b.getState() instanceof CommandBlock)
{
CommandBlock cmd = (CommandBlock) b.getState();
tile.put("id", new StringTag("id", "Control"));
tile.put("Command", new StringTag("Command", cmd.getCommand()));
}
else if (b.getTypeId() == Material.FURNACE.getId() && b.getState() instanceof Furnace)
{
Furnace furnace = (Furnace) b.getState();
tile.put("id", new StringTag("id", "Furnace"));
List<Tag> items = new ArrayList<Tag>();
int slot = 0;
for (ItemStack i: furnace.getInventory().getContents())
{
slot++;
if (i == null) continue;
Map<String, Tag> item = new HashMap<String, Tag>();
item.put("id", new ShortTag("id", (short) i.getTypeId()));
item.put("Damage", new ShortTag("Damage", i.getDurability()));
item.put("Count", new ByteTag("Count", (byte) i.getAmount()));
item.put("Slot", new ByteTag("Slot", (byte) slot));
items.add(new CompoundTag("item", item));
}
tile.put("Items", new ListTag("Items", CompoundTag.class, items));
tile.put("BurnTime", new ShortTag("BurnTime", furnace.getBurnTime()));
tile.put("CookTime", new ShortTag("CookTime", furnace.getCookTime()));
}
else if (b.getTypeId() == Material.HOPPER.getId() && b.getState() instanceof Hopper)
{
Hopper hopper = (Hopper) b.getState();
tile.put("id", new StringTag("id", "Hopper"));
List<Tag> items = new ArrayList<Tag>();
int slot = 0;
for (ItemStack i: hopper.getInventory().getContents())
{
slot++;
if (i == null) continue;
Map<String, Tag> item = new HashMap<String, Tag>();
item.put("id", new ShortTag("id", (short) i.getTypeId()));
item.put("Damage", new ShortTag("Damage", i.getDurability()));
item.put("Count", new ByteTag("Count", (byte) i.getAmount()));
item.put("Slot", new ByteTag("Slot", (byte) slot));
items.add(new CompoundTag("item", item));
}
tile.put("Items", new ListTag("Items", CompoundTag.class, items));
}
else if (b.getTypeId() == Material.MOB_SPAWNER.getId() && b.getState() instanceof CreatureSpawner)
{
CreatureSpawner spawner = (CreatureSpawner) b.getState();
tile.put("id", new StringTag("id", "MobSpawner"));
tile.put("EntityId", new StringTag("EntityId", spawner.getCreatureTypeId()));
tile.put("Delay", new ShortTag("Delay", (short) spawner.getDelay()));
}
return tile;
}
/**
* Helper function for translating a numeric value into a BlockFace enum value
*
* @param rotationValue
* @return
*/
private static BlockFace getSkullRot(Byte rotationValue)
{
if (rotationValue == 0)
{
return BlockFace.SOUTH;
}
else if (rotationValue == 1)
{
return BlockFace.SOUTH_SOUTH_WEST;
}
else if (rotationValue == 2)
{
return BlockFace.SOUTH_WEST;
}
else if (rotationValue == 3)
{
return BlockFace.WEST_SOUTH_WEST;
}
else if (rotationValue == 4)
{
return BlockFace.WEST;
}
else if (rotationValue == 5)
{
return BlockFace.WEST_NORTH_WEST;
}
else if (rotationValue == 6)
{
return BlockFace.NORTH_WEST;
}
else if (rotationValue == 7)
{
return BlockFace.NORTH_NORTH_WEST;
}
else if (rotationValue == 8)
{
return BlockFace.NORTH;
}
else if (rotationValue == 9)
{
return BlockFace.NORTH_NORTH_EAST;
}
else if (rotationValue == 10)
{
return BlockFace.NORTH_EAST;
}
else if (rotationValue == 11)
{
return BlockFace.EAST_NORTH_EAST;
}
else if (rotationValue == 12)
{
return BlockFace.EAST;
}
else if (rotationValue == 13)
{
return BlockFace.EAST_SOUTH_EAST;
}
else if (rotationValue == 14)
{
return BlockFace.SOUTH_EAST;
}
else if (rotationValue == 15)
{
return BlockFace.SOUTH_SOUTH_EAST;
}
return BlockFace.SOUTH; // Arbitrarily default to south...
}
private static int getSkullRot(BlockFace rotationValue)
{
if (rotationValue == BlockFace.SOUTH)
{
return 0;
}
else if (rotationValue == BlockFace.SOUTH_SOUTH_WEST)
{
return 1;
}
else if (rotationValue == BlockFace.SOUTH_WEST)
{
return 2;
}
else if (rotationValue == BlockFace.WEST_SOUTH_WEST)
{
return 3;
}
else if (rotationValue == BlockFace.WEST)
{
return 4;
}
else if (rotationValue == BlockFace.WEST_NORTH_WEST)
{
return 5;
}
else if (rotationValue == BlockFace.NORTH_WEST)
{
return 6;
}
else if (rotationValue == BlockFace.NORTH_NORTH_WEST)
{
return 7;
}
else if (rotationValue == BlockFace.NORTH)
{
return 8;
}
else if (rotationValue == BlockFace.NORTH_NORTH_EAST)
{
return 9;
}
else if (rotationValue == BlockFace.NORTH_EAST)
{
return 10;
}
else if (rotationValue == BlockFace.EAST_NORTH_EAST)
{
return 11;
}
else if (rotationValue == BlockFace.EAST)
{
return 12;
}
else if (rotationValue == BlockFace.EAST_SOUTH_EAST)
{
return 13;
}
else if (rotationValue == BlockFace.SOUTH_EAST)
{
return 14;
}
else if (rotationValue == BlockFace.SOUTH_SOUTH_EAST)
{
return 15;
}
return 0; // Arbitrarily default to south...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment