001 import java.util.HashMap; 002 import java.util.Map; 003 004 /** 005 * Block.java - Provides some way of making/editing blocks 006 * 007 * @author James 008 */ 009 public class Block { 010 /** 011 * Type - Used to identify blocks 012 */ 013 public enum Type { 014 Air(0), 015 Stone(1), 016 Grass(2), 017 Dirt(3), 018 Cobblestone(4), 019 Wood(5), 020 Sapling(6), 021 Bedrock(7), 022 Water(8), 023 StationaryWater(9), 024 Lava(10), 025 StationaryLava(11), 026 Sand(12), 027 Gravel(13), 028 GoldOre(14), 029 IronOre(15), 030 CoalOre(16), 031 Log(17), 032 Leaves(18), 033 Sponge(19), 034 Glass(20), 035 Cloth(35), 036 YellowFlower(37), 037 RedRose(38), 038 BrownMushroom(39), 039 RedMushroom(40), 040 GoldBlock(41), 041 IronBlock(42), 042 DoubleStep(43), 043 Step(44), 044 Brick(45), 045 TNT(46), 046 BookShelf(47), 047 MossyCobblestone(48), 048 Obsidian(49), 049 Torch(50), 050 Fire(51), 051 MobSpawner(52), 052 WoodStairs(53), 053 Chest(54), 054 RedstoneWire(55), 055 DiamondOre(56), 056 Workbench(58), 057 Crops(59), 058 Soil(60), 059 Furnace(61), 060 BurningFurnace(62), 061 SignPost(63), 062 WoodDoor(64), 063 Ladder(65), 064 Rails(66), 065 CobblestoneStairs(67), 066 WallSign(68), 067 Lever(69), 068 StonePlate(70), 069 IronDoor(71), 070 WoodPlate(72), 071 RedstoneOre(73), 072 GlowingRedstoneOre(74), 073 RedstoneTorchOff(75), 074 RedstoneTorchOn(76), 075 StoneButton(77), 076 Snow(78), 077 Ice(79), 078 SnowBlock(80), 079 Cactus(81), 080 Clay(82), 081 Reed(83), 082 Jukebox(84), 083 Fence(85), 084 Pumpkin(86), 085 Netherstone(87), 086 SlowSand(88), 087 LightStone(89), 088 Portal(90), 089 JackOLantern(91) 090 ; 091 092 private int id; 093 private static Map<Integer, Type> map; 094 095 private Type(int id){ 096 this.id = id; 097 add( id, this ); 098 } 099 100 private static void add( int type, Type name ) { 101 if (map == null) { 102 map = new HashMap<Integer, Type>(); 103 } 104 105 map.put(type, name); 106 } 107 108 public int getType() { 109 return id; 110 } 111 112 public static Type fromId(final int type) { 113 return map.get(type); 114 } 115 } 116 117 /** 118 * Face - Used for what face of the block was clicked 119 */ 120 public enum Face { 121 122 /** 123 * The top of the block 124 */ 125 Top(1), 126 /** 127 * The bottom of the block 128 */ 129 Bottom(0), 130 /** 131 * The left (Z-wise) of the block (Faces west) 132 */ 133 Left(3), 134 /** 135 * The right (Z-wise) of the block (Faces east) 136 */ 137 Right(2), 138 /** 139 * The front (X-wise) of the block (Faces south) 140 */ 141 Front(5), 142 /** 143 * The back (X-wise) of the block (Faces north) 144 */ 145 Back(4); 146 private final int id; 147 148 private Face(int id) { 149 this.id = id; 150 } 151 152 /** 153 * Returns a Face according to the specified ID 154 * 155 * @param id 156 * id of face 157 * @return face 158 */ 159 public static Face fromId(final int id) { 160 for (Face e : Face.values()) { 161 if (e.id == id) { 162 return e; 163 } 164 } 165 return null; 166 } 167 } 168 private int type, x, y, z; 169 private Face faceClicked; 170 public Type blockType; 171 private int status, data; 172 173 /** 174 * Create a block with no type, x, y or z. 175 */ 176 public Block() { 177 } 178 179 /** 180 * Creates a block of specified type 181 * 182 * @param type 183 */ 184 public Block(int type) { 185 this.type = type; 186 this.blockType = Type.fromId(type); 187 } 188 189 /** 190 * Creates a block of specified type and specified x, y and z 191 * 192 * @param type 193 * Type of block 194 * @param x 195 * @param y 196 * @param z 197 */ 198 public Block(int type, int x, int y, int z) { 199 this.type = type; 200 this.blockType = Type.fromId(type); 201 this.x = x; 202 this.y = y; 203 this.z = z; 204 } 205 206 /** 207 * Creates a block of specified type and specified x, y and z 208 * 209 * @param type 210 * Type of block 211 * @param x 212 * @param y 213 * @param z 214 * @param data 215 */ 216 public Block(int type, int x, int y, int z, int data) { 217 this.type = type; 218 this.blockType = Type.fromId(type); 219 this.x = x; 220 this.y = y; 221 this.z = z; 222 this.data = data; 223 } 224 225 /** 226 * Type of block 227 * 228 * @return type 229 */ 230 public int getType() { 231 return type; 232 } 233 234 /** 235 * Set type of block 236 * 237 * @param type 238 */ 239 public void setType(int type) { 240 this.blockType = Type.fromId(type); 241 this.type = type; 242 } 243 244 /** 245 * Gets X location 246 * 247 * @return x 248 */ 249 public int getX() { 250 return x; 251 } 252 253 /** 254 * Sets X location 255 * 256 * @param x 257 */ 258 public void setX(int x) { 259 this.x = x; 260 } 261 262 /** 263 * Gets Y location 264 * 265 * @return y 266 */ 267 public int getY() { 268 return y; 269 } 270 271 /** 272 * Sets Y location 273 * 274 * @param y 275 */ 276 public void setY(int y) { 277 this.y = y; 278 } 279 280 /** 281 * Gets Z location 282 * 283 * @return z 284 */ 285 public int getZ() { 286 return z; 287 } 288 289 /** 290 * Sets Z location 291 * 292 * @param z 293 */ 294 public void setZ(int z) { 295 this.z = z; 296 } 297 298 /** 299 * If this block was clicked, this will return the face that was clicked. 300 * 301 * @return face clicked 302 */ 303 public Face getFaceClicked() { 304 return faceClicked; 305 } 306 307 /** 308 * Sets the face that was clicked 309 * 310 * @param faceClicked 311 * face clicked 312 */ 313 public void setFaceClicked(Face faceClicked) { 314 this.faceClicked = faceClicked; 315 } 316 317 /** 318 * Returns the destruction status of this block. 319 * 320 * @return 0 = Started Digging, 1 = Digging, 2 = Stopped digging, 3 = Block 321 * broken. Note: You have to return true for onBlockDestroy for all 322 * of these (except 2) to prevent the block from being destroyed. 323 * Returning false just on block broken will not work. Another note 324 * is that 0 is called often, far less than 1 but is still called. 325 * Good for toggling something. 326 */ 327 public int getStatus() { 328 return status; 329 } 330 331 /** 332 * Sets the current destruction status of this block. 333 * 334 * @param status 335 */ 336 public void setStatus(int status) { 337 this.status = status; 338 } 339 340 /** 341 * Returns this block's data 342 * 343 * @return 344 */ 345 public int getData() { 346 return data; 347 } 348 349 /** 350 * Sets this block's data 351 * 352 * @param data 353 */ 354 public void setData(int data) { 355 this.data = data; 356 } 357 358 /** 359 * Updates this block to the server. 360 */ 361 public void update() { 362 etc.getServer().setBlock(this); 363 } 364 365 /** 366 * Returns the block at the given Face 367 * 368 * @param face the block face of which to return 369 * @return Block at the specified Face 370 */ 371 public Block getFace(Face face) { 372 if (face == null) return null; 373 374 switch (face) { 375 case Front: 376 return getRelative(1, 0, 0); 377 case Back: 378 return getRelative(-1, 0, 0); 379 case Top: 380 return getRelative(0, 1, 0); 381 case Bottom: 382 return getRelative(0, -1, 0); 383 case Left: 384 return getRelative(0, 0, 1); 385 case Right: 386 return getRelative(0, 0, -1); 387 } 388 389 return null; 390 } 391 392 /** 393 * Synchronises this Block with the server, abandoning all local 394 * changes and refreshing the data with the current actual values 395 */ 396 public void refresh() { 397 type = etc.getServer().getBlockIdAt(x, y, z); 398 data = etc.getServer().getBlockData(x, y, z); 399 status = 0; 400 } 401 402 /** 403 * Finds a Block relative to this Block 404 * 405 * @param x amount to shift the x coordinate 406 * @param y amount to shift the y coordinate 407 * @param z amount to shift the z coordinate 408 * 409 * @return Block at the requested location 410 */ 411 public Block getRelative(int x, int y, int z) { 412 return etc.getServer().getBlockAt(this.getX() + x, this.getY() + y, this.getZ() + z); 413 } 414 415 /** 416 * Checks if this block is being powered through redstone 417 * 418 * @return true if the block is being powered 419 */ 420 public boolean isPowered() { 421 return etc.getServer().isBlockPowered(this); 422 } 423 424 /** 425 * Checks if this block is being indirectly powered through redstone 426 * 427 * @return true if the block is being indirectly powered 428 */ 429 public boolean isIndirectlyPowered() { 430 return etc.getServer().isBlockIndirectlyPowered(this); 431 } 432 433 /** 434 * Returns a String value representing this Block 435 * 436 * @return String representation of this block 437 */ 438 @Override 439 public String toString() { 440 return String.format("Block[x=%d, y=%d, z=%d, type=%d]", x, y, z, type); 441 } 442 443 /** 444 * Tests the given object to see if it equals this object 445 * 446 * @param obj the object to test 447 * @return true if the two objects match 448 */ 449 @Override 450 public boolean equals(Object obj) { 451 if (obj == null) { 452 return false; 453 } 454 if (getClass() != obj.getClass()) { 455 return false; 456 } 457 final Block other = (Block) obj; 458 if (this.x != other.x) { 459 return false; 460 } 461 if (this.y != other.y) { 462 return false; 463 } 464 if (this.z != other.z) { 465 return false; 466 } 467 return true; 468 } 469 470 /** 471 * Returns a semi-unique hashcode for this block 472 * 473 * @return hashcode 474 */ 475 @Override 476 public int hashCode() { 477 int hash = 7; 478 hash = 97 * hash + this.x; 479 hash = 97 * hash + this.y; 480 hash = 97 * hash + this.z; 481 return hash; 482 } 483 484 }