001 package org.bukkit.material;
002
003 import java.util.EnumSet;
004 import java.util.Set;
005
006 import org.apache.commons.lang.Validate;
007 import org.bukkit.Material;
008 import org.bukkit.block.BlockFace;
009
010 /**
011 * Represents a huge mushroom block
012 */
013 public class Mushroom extends MaterialData {
014 private static final byte SHROOM_NONE = 0;
015 private static final byte SHROOM_STEM = 10;
016 private static final byte NORTH_LIMIT = 4;
017 private static final byte SOUTH_LIMIT = 6;
018 private static final byte EAST_WEST_LIMIT = 3;
019 private static final byte EAST_REMAINDER = 0;
020 private static final byte WEST_REMAINDER = 1;
021 private static final byte NORTH_SOUTH_MOD = 3;
022 private static final byte EAST_WEST_MOD = 1;
023
024 public Mushroom(Material shroom) {
025 super(shroom);
026 Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!");
027 }
028
029 /**
030 *
031 * @deprecated Magic value
032 */
033 @Deprecated
034 public Mushroom(Material shroom, byte data) {
035 super(shroom, data);
036 Validate.isTrue(shroom == Material.HUGE_MUSHROOM_1 || shroom == Material.HUGE_MUSHROOM_2, "Not a mushroom!");
037 }
038
039 /**
040 *
041 * @deprecated Magic value
042 */
043 @Deprecated
044 public Mushroom(int type, byte data){
045 super(type, data);
046 Validate.isTrue(type == Material.HUGE_MUSHROOM_1.getId() || type == Material.HUGE_MUSHROOM_2.getId(), "Not a mushroom!");
047 }
048
049 /**
050 * @return Whether this is a mushroom stem.
051 */
052 public boolean isStem() {
053 return getData() == SHROOM_STEM;
054 }
055
056 /**
057 * Sets this to be a mushroom stem.
058 */
059 public void setStem() {
060 setData((byte) 10);
061 }
062
063 /**
064 * Checks whether a face of the block is painted.
065 *
066 * @param face The face to check.
067 * @return True if it is painted.
068 */
069 public boolean isFacePainted(BlockFace face) {
070 byte data = getData();
071
072 if (data == SHROOM_NONE || data == SHROOM_STEM) {
073 return false;
074 }
075
076 switch (face) {
077 case WEST:
078 return data < NORTH_LIMIT;
079 case EAST:
080 return data > SOUTH_LIMIT;
081 case NORTH:
082 return data % EAST_WEST_LIMIT == EAST_REMAINDER;
083 case SOUTH:
084 return data % EAST_WEST_LIMIT == WEST_REMAINDER;
085 case UP:
086 return true;
087 default:
088 return false;
089 }
090 }
091
092 /**
093 * Set a face of the block to be painted or not. Note that due to the
094 * nature of how the data is stored, setting a face painted or not is not
095 * guaranteed to leave the other faces unchanged.
096 *
097 * @param face The face to paint or unpaint.
098 * @param painted True if you want to paint it, false if you want the
099 * pores to show.
100 */
101 public void setFacePainted(BlockFace face, boolean painted) {
102 if (painted == isFacePainted(face)) {
103 return;
104 }
105
106 byte data = getData();
107
108 if (data == SHROOM_STEM) {
109 data = 5;
110 }
111
112 switch (face) {
113 case WEST:
114 if (painted) {
115 data -= NORTH_SOUTH_MOD;
116 } else {
117 data += NORTH_SOUTH_MOD;
118 }
119
120 break;
121 case EAST:
122 if (painted) {
123 data += NORTH_SOUTH_MOD;
124 } else {
125 data -= NORTH_SOUTH_MOD;
126 }
127
128 break;
129 case NORTH:
130 if (painted) {
131 data += EAST_WEST_MOD;
132 } else {
133 data -= EAST_WEST_MOD;
134 }
135
136 break;
137 case SOUTH:
138 if (painted) {
139 data -= EAST_WEST_MOD;
140 } else {
141 data += EAST_WEST_MOD;
142 }
143
144 break;
145 case UP:
146 if (!painted) {
147 data = 0;
148 }
149
150 break;
151 default:
152 throw new IllegalArgumentException("Can't paint that face of a mushroom!");
153 }
154
155 setData(data);
156 }
157
158 /**
159 * @return A set of all faces that are currently painted (an empty set if
160 * it is a stem)
161 */
162 public Set<BlockFace> getPaintedFaces() {
163 EnumSet<BlockFace> faces = EnumSet.noneOf(BlockFace.class);
164
165 if (isFacePainted(BlockFace.WEST)) {
166 faces.add(BlockFace.WEST);
167 }
168
169 if (isFacePainted(BlockFace.NORTH)) {
170 faces.add(BlockFace.NORTH);
171 }
172
173 if (isFacePainted(BlockFace.SOUTH)) {
174 faces.add(BlockFace.SOUTH);
175 }
176
177 if (isFacePainted(BlockFace.EAST)) {
178 faces.add(BlockFace.EAST);
179 }
180
181 if (isFacePainted(BlockFace.UP)) {
182 faces.add(BlockFace.UP);
183 }
184
185 return faces;
186 }
187
188 @Override
189 public String toString() {
190 return Material.getMaterial(getItemTypeId()).toString() + (isStem() ? "{STEM}" : getPaintedFaces());
191 }
192
193 @Override
194 public Mushroom clone() {
195 return (Mushroom) super.clone();
196 }
197 }