13
0
geforkt von Mirrors/Paper

[Bleeding] MaterialData fixes. Addresses BUKKIT-842

By: Celtic Minstrel <celtic.minstrel.ca@some.place>
Dieser Commit ist enthalten in:
Bukkit/Spigot 2012-02-26 22:07:26 -05:00
Ursprung a6d03a475c
Commit fb55ed2a78
9 geänderte Dateien mit 631 neuen und 48 gelöschten Zeilen

Datei anzeigen

@ -7,7 +7,9 @@ import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.commons.lang.Validate;
import org.bukkit.map.MapView;
import org.bukkit.material.*;
import org.bukkit.potion.Potion;
import org.bukkit.util.Java15Compat;
import com.google.common.collect.Maps;
@ -115,26 +117,26 @@ public enum Material {
TRAP_DOOR(96, TrapDoor.class),
MONSTER_EGGS(97, MonsterEggs.class),
SMOOTH_BRICK(98, SmoothBrick.class),
HUGE_MUSHROOM_1(99),
HUGE_MUSHROOM_2(100),
HUGE_MUSHROOM_1(99, Mushroom.class),
HUGE_MUSHROOM_2(100, Mushroom.class),
IRON_FENCE(101),
THIN_GLASS(102),
MELON_BLOCK(103),
PUMPKIN_STEM(104),
MELON_STEM(105),
VINE(106),
FENCE_GATE(107),
BRICK_STAIRS(108),
SMOOTH_STAIRS(109),
PUMPKIN_STEM(104, MaterialData.class),
MELON_STEM(105, MaterialData.class),
VINE(106, Vine.class),
FENCE_GATE(107, Gate.class),
BRICK_STAIRS(108, Stairs.class),
SMOOTH_STAIRS(109, Stairs.class),
MYCEL(110),
WATER_LILY(111),
NETHER_BRICK(112),
NETHER_FENCE(113),
NETHER_BRICK_STAIRS(114),
NETHER_WARTS(115),
NETHER_BRICK_STAIRS(114, Stairs.class),
NETHER_WARTS(115, MaterialData.class),
ENCHANTMENT_TABLE(116),
BREWING_STAND(117),
CAULDRON(118),
BREWING_STAND(117, MaterialData.class),
CAULDRON(118, Cauldron.class),
ENDER_PORTAL(119),
ENDER_PORTAL_FRAME(120),
ENDER_STONE(121),
@ -242,6 +244,9 @@ public enum Material {
BED(355, 1),
DIODE(356),
COOKIE(357),
/**
* @see MapView
*/
MAP(358, 1, MaterialData.class),
SHEARS(359, 1, 238),
MELON(360),
@ -257,7 +262,10 @@ public enum Material {
GHAST_TEAR(370),
GOLD_NUGGET(371),
NETHER_STALK(372),
POTION(373, 1),
/**
* @see Potion
*/
POTION(373, 1, MaterialData.class),
GLASS_BOTTLE(374),
SPIDER_EYE(375),
FERMENTED_SPIDER_EYE(376),
@ -267,7 +275,7 @@ public enum Material {
CAULDRON_ITEM(380),
EYE_OF_ENDER(381),
SPECKLED_MELON(382),
MONSTER_EGG(383, 1),
MONSTER_EGG(383, 1, SpawnEgg.class),
GOLD_RECORD(2256, 1),
GREEN_RECORD(2257, 1),
RECORD_3(2258, 1),

Datei anzeigen

@ -0,0 +1,51 @@
package org.bukkit.material;
import org.bukkit.Material;
/**
* Represents a cauldron
*/
public class Cauldron extends MaterialData {
private static final int CAULDRON_FULL = 3;
private static final int CAULDRON_EMPTY = 0;
public Cauldron() {
super(Material.CAULDRON);
}
public Cauldron(int type, byte data){
super(type, data);
}
public Cauldron(byte data) {
super(Material.CAULDRON, data);
}
/**
* Check if the cauldron is full.
*
* @return True if it is full.
*/
public boolean isFull() {
return getData() >= CAULDRON_FULL;
}
/**
* Check if the cauldron is empty.
*
* @return True if it is empty.
*/
public boolean isEmpty() {
return getData() <= CAULDRON_EMPTY;
}
@Override
public String toString() {
return (isEmpty() ? "EMPTY" : (isFull() ? "FULL" : getData() + "/3 FULL")) + " CAULDRON";
}
@Override
public Cauldron clone() {
return (Cauldron) super.clone();
}
}

Datei anzeigen

@ -6,7 +6,7 @@ import org.bukkit.block.BlockFace;
/**
* Represents a door.
*/
public class Door extends MaterialData implements Directional {
public class Door extends MaterialData implements Directional, Openable {
public Door() {
super(Material.WOODEN_DOOR);
}
@ -27,20 +27,10 @@ public class Door extends MaterialData implements Directional {
super(type, data);
}
/**
* Check to see if the door is open.
*
* @return true if the door has swung counterclockwise around its hinge.
*/
public boolean isOpen() {
return ((getData() & 0x4) == 0x4);
}
/**
* Configure this door to be either open or closed;
*
* @param isOpen True to open the door.
*/
public void setOpen(boolean isOpen) {
setData((byte) (isOpen ? (getData() | 0x4) : (getData() & ~0x4)));
}

Datei anzeigen

@ -0,0 +1,91 @@
package org.bukkit.material;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
/**
* Represents a fence gate
*/
public class Gate extends MaterialData implements Directional, Openable {
private static final byte OPEN_BIT = 0x4;
private static final byte DIR_BIT = 0x3;
private static final byte GATE_SOUTH = 0x0;
private static final byte GATE_WEST = 0x1;
private static final byte GATE_NORTH = 0x2;
private static final byte GATE_EAST = 0x3;
public Gate() {
super(Material.FENCE_GATE);
}
public Gate(int type, byte data){
super(type, data);
}
public Gate(byte data) {
super(Material.FENCE_GATE, data);
}
public void setFacingDirection(BlockFace face) {
byte data = (byte) (getData() &~ DIR_BIT);
switch (face) {
default:
case SOUTH:
data |= GATE_SOUTH;
break;
case WEST:
data |= GATE_WEST;
break;
case NORTH:
data |= GATE_NORTH;
break;
case EAST:
data |= GATE_EAST;
break;
}
setData(data);
}
public BlockFace getFacing() {
switch (getData() & DIR_BIT) {
case GATE_SOUTH:
return BlockFace.SOUTH;
case GATE_WEST:
return BlockFace.WEST;
case GATE_NORTH:
return BlockFace.NORTH;
case GATE_EAST:
return BlockFace.EAST;
}
return BlockFace.SOUTH;
}
public boolean isOpen() {
return (getData() & OPEN_BIT) > 0;
}
public void setOpen(boolean isOpen) {
byte data = getData();
if (isOpen) {
data |= OPEN_BIT;
} else {
data &= ~OPEN_BIT;
}
setData(data);
}
@Override
public String toString() {
return (isOpen() ? "OPEN " : "CLOSED ") + " facing and opening " + getFacing();
}
@Override
public Gate clone() {
return (Gate) super.clone();
}
}

Datei anzeigen

@ -0,0 +1,182 @@
package org.bukkit.material;
import java.util.EnumSet;
import java.util.Set;
import org.apache.commons.lang.Validate;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
/**
* Represents a huge mushroom block
*/
public class Mushroom extends MaterialData {
private static final byte SHROOM_NONE = 0;
private static final byte SHROOM_STEM = 10;
private static final byte NORTH_LIMIT = 4;
private static final byte SOUTH_LIMIT = 6;
private static final byte EAST_WEST_LIMIT = 3;
private static final byte EAST_REMAINDER = 0;
private static final byte WEST_REMAINDER = 1;
private static final byte NORTH_SOUTH_MOD = 3;
private static final byte EAST_WEST_MOD = 1;
public Mushroom(Material shroom) {
super(shroom);
Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!");
}
public Mushroom(Material shroom, byte data) {
super(shroom, data);
Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!");
}
public Mushroom(int type, byte data){
super(type, data);
Validate.isTrue(type == Material.HUGE_MUSHROOM_1.getId() || type == Material.HUGE_MUSHROOM_2.getId(), "Not a mushroom!");
}
/**
* @return Whether this is a mushroom stem.
*/
public boolean isStem() {
return getData() == SHROOM_STEM;
}
/**
* Sets this to be a mushroom stem.
*/
public void setStem() {
setData((byte) 10);
}
/**
* Checks whether a face of the block is painted.
* @param face The face to check.
* @return True if it is painted.
*/
public boolean isFacePainted(BlockFace face) {
byte data = getData();
if (data == SHROOM_NONE || data == SHROOM_STEM) {
return false;
}
switch (face) {
case NORTH:
return data < NORTH_LIMIT;
case SOUTH:
return data > SOUTH_LIMIT;
case EAST:
return data % EAST_WEST_LIMIT == EAST_REMAINDER;
case WEST:
return data % EAST_WEST_LIMIT == WEST_REMAINDER;
case UP:
return true;
default:
return false;
}
}
/**
* Set a face of the block to be painted or not. Note that due to the nature of how the data is stored,
* setting a face painted or not is not guaranteed to leave the other faces unchanged.
* @param face The face to paint or unpaint.
* @param painted True if you want to paint it, false if you want the pores to show.
*/
public void setFacePainted(BlockFace face, boolean painted) {
if (painted == isFacePainted(face)) {
return;
}
byte data = getData();
if (data == SHROOM_STEM) {
data = 5;
}
switch (face) {
case NORTH:
if (painted) {
data -= NORTH_SOUTH_MOD;
} else {
data += NORTH_SOUTH_MOD;
}
break;
case SOUTH:
if (painted) {
data += NORTH_SOUTH_MOD;
} else {
data -= NORTH_SOUTH_MOD;
}
break;
case EAST:
if (painted) {
data += EAST_WEST_MOD;
} else {
data -= EAST_WEST_MOD;
}
break;
case WEST:
if (painted) {
data -= EAST_WEST_MOD;
} else {
data += EAST_WEST_MOD;
}
break;
case UP:
if (!painted) {
data = 0;
}
break;
default:
throw new IllegalArgumentException("Can't paint that face of a mushroom!");
}
setData(data);
}
/**
* @return A set of all faces that are currently painted (an empty set if it is a stem)
*/
public Set<BlockFace> getPaintedFaces() {
EnumSet<BlockFace> faces = EnumSet.noneOf(BlockFace.class);
if (isFacePainted(BlockFace.NORTH)) {
faces.add(BlockFace.NORTH);
}
if (isFacePainted(BlockFace.EAST)) {
faces.add(BlockFace.EAST);
}
if (isFacePainted(BlockFace.WEST)) {
faces.add(BlockFace.WEST);
}
if (isFacePainted(BlockFace.SOUTH)) {
faces.add(BlockFace.SOUTH);
}
if (isFacePainted(BlockFace.UP)) {
faces.add(BlockFace.UP);
}
return faces;
}
@Override
public String toString() {
return Material.getMaterial(getItemTypeId()).toString() + (isStem() ? "{STEM}" : getPaintedFaces());
}
@Override
public Mushroom clone() {
return (Mushroom) super.clone();
}
}

Datei anzeigen

@ -0,0 +1,17 @@
package org.bukkit.material;
public interface Openable {
/**
* Check to see if the door is open.
*
* @return true if the door has swung counterclockwise around its hinge.
*/
boolean isOpen();
/**
* Configure this door to be either open or closed;
*
* @param isOpen True to open the door.
*/
void setOpen(boolean isOpen);
}

Datei anzeigen

@ -0,0 +1,52 @@
package org.bukkit.material;
import org.bukkit.Material;
import org.bukkit.entity.EntityType;
/**
* Represents a spawn egg that can be used to spawn mobs
*/
public class SpawnEgg extends MaterialData {
public SpawnEgg() {
super(Material.MONSTER_EGG);
}
public SpawnEgg(int type, byte data){
super(type, data);
}
public SpawnEgg(byte data) {
super(Material.MONSTER_EGG, data);
}
public SpawnEgg(EntityType type) {
this();
setSpawnedType(type);
}
/**
* Get the type of entity this egg will spawn.
* @return The entity type.
*/
public EntityType getSpawnedType() {
return EntityType.fromId(getData());
}
/**
* Set the type of entity this egg will spawn.
* @param type The entity type.
*/
public void setSpawnedType(EntityType type) {
setData((byte) type.getTypeId());
}
@Override
public String toString() {
return "SPAWN EGG{" + getSpawnedType() + "}";
}
@Override
public SpawnEgg clone() {
return (SpawnEgg) super.clone();
}
}

Datei anzeigen

@ -6,7 +6,7 @@ import org.bukkit.block.BlockFace;
/**
* Represents a trap door
*/
public class TrapDoor extends SimpleAttachableMaterialData {
public class TrapDoor extends SimpleAttachableMaterialData implements Openable {
public TrapDoor() {
super(Material.TRAP_DOOR);
}
@ -27,15 +27,22 @@ public class TrapDoor extends SimpleAttachableMaterialData {
super(type, data);
}
/**
* Check to see if the trap door is open.
*
* @return true if the trap door is open.
*/
public boolean isOpen() {
return ((getData() & 0x4) == 0x4);
}
public void setOpen(boolean isOpen) {
byte data = getData();
if (isOpen) {
data |= 0x4;
} else {
data &= ~0x4;
}
setData(data);
}
public BlockFace getAttachedFace() {
byte data = (byte) (getData() & 0x3);

Datei anzeigen

@ -0,0 +1,185 @@
package org.bukkit.material;
import java.util.Arrays;
import java.util.EnumSet;
import org.bukkit.Material;
import org.bukkit.block.BlockFace;
/**
* Represents a vine
*/
public class Vine extends MaterialData {
private static final int VINE_NORTH = 0x4;
private static final int VINE_EAST = 0x8;
private static final int VINE_WEST = 0x2;
private static final int VINE_SOUTH = 0x1;
EnumSet<BlockFace> possibleFaces = EnumSet.of(BlockFace.NORTH, BlockFace.EAST, BlockFace.WEST, BlockFace.SOUTH);
public Vine() {
super(Material.VINE);
}
public Vine(int type, byte data){
super(type, data);
}
public Vine(byte data) {
super(Material.VINE, data);
}
public Vine(BlockFace... faces) {
this(EnumSet.copyOf(Arrays.asList(faces)));
}
public Vine(EnumSet<BlockFace> faces) {
this((byte) 0);
faces.retainAll(possibleFaces);
byte data = 0;
if (faces.contains(BlockFace.NORTH)) {
data |= VINE_NORTH;
}
if (faces.contains(BlockFace.EAST)) {
data |= VINE_EAST;
}
if (faces.contains(BlockFace.WEST)) {
data |= VINE_WEST;
}
if (faces.contains(BlockFace.SOUTH)) {
data |= VINE_SOUTH;
}
setData(data);
}
/**
* Check if the vine is attached to the specified face of an adjacent block. You can
* check two faces at once by passing eg {@link BlockFace#NORTH_EAST}.
*
* @param face The face to check.
* @return Whether it is attached to that face.
*/
public boolean isOnFace(BlockFace face) {
switch (face) {
case NORTH:
return (getData() & VINE_NORTH) > 0;
case EAST:
return (getData() & VINE_EAST) > 0;
case WEST:
return (getData() & VINE_WEST) > 0;
case SOUTH:
return (getData() & VINE_SOUTH) > 0;
case NORTH_EAST:
return isOnFace(BlockFace.NORTH) && isOnFace(BlockFace.EAST);
case NORTH_WEST:
return isOnFace(BlockFace.NORTH) && isOnFace(BlockFace.WEST);
case SOUTH_EAST:
return isOnFace(BlockFace.SOUTH) && isOnFace(BlockFace.EAST);
case SOUTH_WEST:
return isOnFace(BlockFace.SOUTH) && isOnFace(BlockFace.WEST);
case UP: // It's impossible to be accurate with this since it's contextual
return true;
default:
return false;
}
}
/**
* Attach the vine to the specified face of an adjacent block.
*
* @param face The face to attach.
*/
public void putOnFace(BlockFace face) {
switch(face) {
case NORTH:
setData((byte) (getData() | VINE_NORTH));
break;
case EAST:
setData((byte) (getData() | VINE_EAST));
break;
case WEST:
setData((byte) (getData() | VINE_WEST));
break;
case SOUTH:
setData((byte) (getData() | VINE_SOUTH));
break;
case NORTH_EAST:
putOnFace(BlockFace.NORTH);
putOnFace(BlockFace.EAST);
break;
case NORTH_WEST:
putOnFace(BlockFace.NORTH);
putOnFace(BlockFace.WEST);
break;
case SOUTH_EAST:
putOnFace(BlockFace.SOUTH);
putOnFace(BlockFace.EAST);
break;
case SOUTH_WEST:
putOnFace(BlockFace.SOUTH);
putOnFace(BlockFace.WEST);
break;
case UP:
break;
default:
throw new IllegalArgumentException("Vines can't go on face " + face.toString());
}
}
/**
* Detach the vine from the specified face of an adjacent block.
*
* @param face The face to detach.
*/
public void removeFromFace(BlockFace face) {
switch(face) {
case NORTH:
setData((byte) (getData() &~ VINE_NORTH));
break;
case EAST:
setData((byte) (getData() &~ VINE_EAST));
break;
case WEST:
setData((byte) (getData() &~ VINE_WEST));
break;
case SOUTH:
setData((byte) (getData() &~ VINE_SOUTH));
break;
case NORTH_EAST:
removeFromFace(BlockFace.NORTH);
removeFromFace(BlockFace.EAST);
break;
case NORTH_WEST:
removeFromFace(BlockFace.NORTH);
removeFromFace(BlockFace.WEST);
break;
case SOUTH_EAST:
removeFromFace(BlockFace.SOUTH);
removeFromFace(BlockFace.EAST);
break;
case SOUTH_WEST:
removeFromFace(BlockFace.SOUTH);
removeFromFace(BlockFace.WEST);
break;
case UP:
break;
default:
throw new IllegalArgumentException("Vines can't go on face " + face.toString());
}
}
@Override
public String toString() {
return "VINE";
}
@Override
public Vine clone() {
return (Vine) super.clone();
}
}