Add support for skull blocks.

This commit is contained in:
Wizjany 2012-12-24 01:11:38 -05:00
parent f2d561dae1
commit 57327fd37f
4 changed files with 420 additions and 0 deletions

View File

@ -32,6 +32,7 @@ import com.sk89q.worldedit.blocks.FurnaceBlock;
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.blocks.SignBlock;
import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.foundation.Block;
import com.sk89q.worldedit.foundation.World;
import com.sk89q.worldedit.regions.Region;
@ -591,6 +592,12 @@ public abstract class LocalWorld implements World {
return block;
}
case BlockID.HEAD: {
SkullBlock block = new SkullBlock(data);
copyFromWorld(pt, block);
return block;
}
default:
return new BaseBlock(type, data);
}

View File

@ -59,6 +59,7 @@ import com.sk89q.worldedit.blocks.ItemType;
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.blocks.SignBlock;
import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.commands.BiomeCommands;
import com.sk89q.worldedit.commands.ChunkCommands;
import com.sk89q.worldedit.commands.ClipboardCommands;
@ -540,6 +541,43 @@ public class WorldEdit {
return new NoteBlock(data, (byte) 0);
}
case HEAD:
// allow setting type/player/rotation
if (blockAndExtraData.length > 1) {
// and thus, the format shall be "|type|rotation" or "|type" or "|rotation"
byte rot = 0;
String type = "";
try {
rot = Byte.parseByte(blockAndExtraData[1]);
} catch (NumberFormatException e) {
type = blockAndExtraData[1];
if (blockAndExtraData.length > 2) {
try {
rot = Byte.parseByte(blockAndExtraData[2]);
} catch (NumberFormatException e2) {
throw new InvalidItemException(arg, "Second part of skull metadata should be a number.");
}
}
}
byte skullType = 0;
// type is either the mob type or the player name
// sorry for the four minecraft accounts named "skeleton", "wither", "zombie", or "creeper"
if (!type.isEmpty()) {
if (type.equalsIgnoreCase("skeleton")) skullType = 0;
else if (type.equalsIgnoreCase("wither")) skullType = 1;
else if (type.equalsIgnoreCase("zombie")) skullType = 2;
else if (type.equalsIgnoreCase("creeper")) skullType = 4;
else skullType = 3;
}
if (skullType == 3) {
return new SkullBlock(data, rot, type);
} else {
return new SkullBlock(data, skullType, rot);
}
} else {
return new SkullBlock(data);
}
default:
return new BaseBlock(blockId, data);
}

View File

@ -0,0 +1,196 @@
// $Id$
/*
* WorldEdit
* Copyright (C) 2010 sk89q <http://www.sk89q.com> and contributors
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.sk89q.worldedit.blocks;
import java.util.HashMap;
import java.util.Map;
import com.sk89q.jnbt.ByteTag;
import com.sk89q.jnbt.CompoundTag;
import com.sk89q.jnbt.StringTag;
import com.sk89q.jnbt.Tag;
import com.sk89q.worldedit.data.DataException;
/**
* A skull block.
*/
public class SkullBlock extends BaseBlock implements TileEntityBlock {
private String owner = ""; // notchian
private byte skullType; // stored here for block, in damage value for item
private byte rot; // only matters if block data == 0x1 (on floor)
/**
* Construct the skull block with a default type of skelton.
* @param data data value to set, controls placement
*/
public SkullBlock(int data) {
this(data, (byte) 0);
}
/**
* Construct the skull block with a given type.
* 0 - skeleton
* 1 - wither skelly
* 2 - zombie
* 3 - human
* 4 - creeper
* @param data data value to set, controls placement
* @param type type of skull
*/
public SkullBlock(int data, byte type) {
this(data, type, (byte) 0);
}
/**
* Construct the skull block with a given type and rotation.
* @param data data value to set, controls placement
* @param type type of skull
* @param rot rotation (if on floor)
*/
public SkullBlock(int data, byte type, byte rot) {
super(BlockID.HEAD, 1);
if (type < (byte) 0 || type > (byte) 4) {
this.skullType = (byte) 0;
} else {
this.skullType = type;
}
this.rot = rot;
this.owner = "";
}
/**
* Construct the skull block with a given rotation and owner.
* The type is assumed to be player unless owner is null or empty.
* @param data data value to set, controls placement
* @param rot rotation of skull
* @param owner name of player
*/
public SkullBlock(int data, byte rot, String owner) {
super(BlockID.HEAD, 1);
this.rot = rot;
this.setOwner(owner);
if (owner == null || owner.isEmpty()) this.skullType = (byte) 0;
}
/**
* Set the skull's owner. Automatically sets type to player if not empty or null.
* @param owner player name to set the skull to
*/
public void setOwner(String owner) {
if (owner == null) {
this.owner = "";
} else {
if (owner.length() > 16 || owner.isEmpty()) this.owner = "";
else this.owner = owner;
}
if (this.owner != null && !this.owner.isEmpty()) this.skullType = (byte) 3;
}
/**
* Get the skull's owner. Returns null if unset.
* @return player name or null
*/
public String getOwner() {
return owner;
}
/**
* Get the type of skull.
* @return the skullType
*/
public byte getSkullType() {
return skullType;
}
/**
* Set the type of skull;
* @param skullType the skullType to set
*/
public void setSkullType(byte skullType) {
this.skullType = skullType;
}
/**
* Get rotation of skull. This only means anything if the block data is 1.
* @return the rotation
*/
public byte getRot() {
return rot;
}
/**
* Set the rotation of skull.
* @param rot the rotation to set
*/
public void setRot(byte rot) {
this.rot = rot;
}
@Override
public boolean hasNbtData() {
return true;
}
@Override
public String getNbtId() {
return "Skull";
}
@Override
public CompoundTag getNbtData() {
Map<String, Tag> values = new HashMap<String, Tag>();
values.put("SkullType", new ByteTag("SkullType", skullType));
if (owner == null) owner = "";
values.put("ExtraType", new StringTag("ExtraType", owner));
values.put("Rot", new ByteTag("Rot", rot));
return new CompoundTag(getNbtId(), values);
}
@Override
public void setNbtData(CompoundTag rootTag) throws DataException {
if (rootTag == null) {
return;
}
Map<String, Tag> values = rootTag.getValue();
Tag t;
t = values.get("id");
if (!(t instanceof StringTag)
|| !((StringTag) t).getValue().equals("Skull")) {
throw new DataException("'Skull' tile entity expected");
}
t = values.get("SkullType");
if (t instanceof ByteTag) {
skullType = ((ByteTag) t).getValue();
}
t = values.get("ExtraType");
if (t != null && t instanceof StringTag) {
owner = ((StringTag) t).getValue();
}
t = values.get("Rot");
if (t instanceof ByteTag) {
rot = ((ByteTag) t).getValue();
}
}
}

View File

@ -33,15 +33,18 @@ import java.util.logging.Logger;
import org.bukkit.Effect;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.SkullType;
import org.bukkit.TreeType;
import org.bukkit.World;
import org.bukkit.block.Biome;
import org.bukkit.block.Block;
import org.bukkit.block.BlockFace;
import org.bukkit.block.BlockState;
import org.bukkit.block.Chest;
import org.bukkit.block.CreatureSpawner;
import org.bukkit.block.Furnace;
import org.bukkit.block.Sign;
import org.bukkit.block.Skull;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.entity.Ambient;
import org.bukkit.entity.Animals;
@ -82,6 +85,7 @@ import com.sk89q.worldedit.blocks.FurnaceBlock;
import com.sk89q.worldedit.blocks.MobSpawnerBlock;
import com.sk89q.worldedit.blocks.NoteBlock;
import com.sk89q.worldedit.blocks.SignBlock;
import com.sk89q.worldedit.blocks.SkullBlock;
import com.sk89q.worldedit.bukkit.entity.BukkitEntity;
import com.sk89q.worldedit.regions.Region;
import com.sk89q.worldedit.util.TreeGenerator;
@ -360,6 +364,95 @@ public class BukkitWorld extends LocalWorld {
return true;
}
if (block instanceof SkullBlock) {
// Skull block
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof org.bukkit.block.Skull)) return false;
Skull bukkit = (Skull) state;
SkullBlock we = (SkullBlock) block;
// this is dumb
SkullType skullType = SkullType.SKELETON;
switch (we.getSkullType()) {
case 0:
skullType = SkullType.SKELETON;
break;
case 1:
skullType = SkullType.WITHER;
break;
case 2:
skullType = SkullType.ZOMBIE;
break;
case 3:
skullType = SkullType.PLAYER;
break;
case 4:
skullType = SkullType.CREEPER;
break;
}
bukkit.setSkullType(skullType);
BlockFace rotation;
switch (we.getRot()) {
// soooo dumb
case 0:
rotation = BlockFace.NORTH;
break;
case 1:
rotation = BlockFace.NORTH_NORTH_EAST;
break;
case 2:
rotation = BlockFace.NORTH_EAST;
break;
case 3:
rotation = BlockFace.EAST_NORTH_EAST;
break;
case 4:
rotation = BlockFace.EAST;
break;
case 5:
rotation = BlockFace.EAST_SOUTH_EAST;
break;
case 6:
rotation = BlockFace.SOUTH_EAST;
break;
case 7:
rotation = BlockFace.SOUTH_SOUTH_EAST;
break;
case 8:
rotation = BlockFace.SOUTH;
break;
case 9:
rotation = BlockFace.SOUTH_SOUTH_WEST;
break;
case 10:
rotation = BlockFace.SOUTH_WEST;
break;
case 11:
rotation = BlockFace.WEST_SOUTH_WEST;
break;
case 12:
rotation = BlockFace.WEST;
break;
case 13:
rotation = BlockFace.WEST_NORTH_WEST;
break;
case 14:
rotation = BlockFace.NORTH_WEST;
break;
case 15:
rotation = BlockFace.NORTH_NORTH_WEST;
break;
default:
rotation = BlockFace.NORTH;
break;
}
bukkit.setRotation(rotation);
if (we.getOwner() != null && !we.getOwner().isEmpty()) bukkit.setOwner(we.getOwner());
bukkit.update(true);
return true;
}
if (!skipNmsAccess) {
try {
return NmsBlock.set(world, pt, block);
@ -432,6 +525,91 @@ public class BukkitWorld extends LocalWorld {
return true;
}
if (block instanceof SkullBlock) {
// Skull block
Block bukkitBlock = world.getBlockAt(pt.getBlockX(), pt.getBlockY(), pt.getBlockZ());
if (bukkitBlock == null) return false;
BlockState state = bukkitBlock.getState();
if (!(state instanceof org.bukkit.block.Skull)) return false;
Skull bukkit = (Skull) state;
SkullBlock we = (SkullBlock) block;
byte skullType = 0;
switch (bukkit.getSkullType()) {
// this is dumb but whoever wrote the class is stupid
case SKELETON:
skullType = 0;
break;
case WITHER:
skullType = 1;
break;
case ZOMBIE:
skullType = 2;
break;
case PLAYER:
skullType = 3;
break;
case CREEPER:
skullType = 4;
break;
}
we.setSkullType(skullType);
byte rot = 0;
switch (bukkit.getRotation()) {
// this is even more dumb, hurray for copy/paste
case NORTH:
rot = (byte) 0;
break;
case NORTH_NORTH_EAST:
rot = (byte) 1;
break;
case NORTH_EAST:
rot = (byte) 2;
break;
case EAST_NORTH_EAST:
rot = (byte) 3;
break;
case EAST:
rot = (byte) 4;
break;
case EAST_SOUTH_EAST:
rot = (byte) 5;
break;
case SOUTH_EAST:
rot = (byte) 6;
break;
case SOUTH_SOUTH_EAST:
rot = (byte) 7;
break;
case SOUTH:
rot = (byte) 8;
break;
case SOUTH_SOUTH_WEST:
rot = (byte) 9;
break;
case SOUTH_WEST:
rot = (byte) 10;
break;
case WEST_SOUTH_WEST:
rot = (byte) 11;
break;
case WEST:
rot = (byte) 12;
break;
case WEST_NORTH_WEST:
rot = (byte) 13;
break;
case NORTH_WEST:
rot = (byte) 14;
break;
case NORTH_NORTH_WEST:
rot = (byte) 15;
break;
}
we.setRot(rot);
we.setOwner(bukkit.hasOwner() ? bukkit.getOwner() : "");
return true;
}
return false;
}
@ -997,6 +1175,7 @@ public class BukkitWorld extends LocalWorld {
//case BlockID.DISPENSER:
//case BlockID.MOB_SPAWNER:
case BlockID.NOTE_BLOCK:
case BlockID.HEAD:
return super.getBlock(pt);
default:
if (!skipNmsAccess) {