Fork of Poseidon providing Bukkit #1060 to older Beta versions (b1.0-b1.7.3)
1package org.bukkit.craftbukkit.block;
2
3import net.minecraft.server.BiomeBase;
4import net.minecraft.server.BlockRedstoneWire;
5import uk.betacraft.uberbukkit.Uberbukkit;
6
7import org.bukkit.Chunk;
8import org.bukkit.Location;
9import org.bukkit.Material;
10import org.bukkit.World;
11import org.bukkit.block.*;
12import org.bukkit.craftbukkit.CraftChunk;
13import org.bukkit.util.BlockVector;
14
15public class CraftBlock implements Block {
16 private final CraftChunk chunk;
17 private final int x;
18 private final int y;
19 private final int z;
20
21 public CraftBlock(CraftChunk chunk, int x, int y, int z) {
22 this.x = x;
23 this.y = y;
24 this.z = z;
25 this.chunk = chunk;
26 }
27
28 public World getWorld() {
29 return chunk.getWorld();
30 }
31
32 public Location getLocation() {
33 return new Location(getWorld(), x, y, z);
34 }
35
36 public BlockVector getVector() {
37 return new BlockVector(x, y, z);
38 }
39
40 public int getX() {
41 return x;
42 }
43
44 public int getY() {
45 return y;
46 }
47
48 public int getZ() {
49 return z;
50 }
51
52 public Chunk getChunk() {
53 return chunk;
54 }
55
56 public void setData(final byte data) {
57 chunk.getHandle().world.setData(x, y, z, data);
58 }
59
60 public void setData(final byte data, boolean applyPhysics) {
61 if (applyPhysics) {
62 chunk.getHandle().world.setData(x, y, z, data);
63 } else {
64 chunk.getHandle().world.setRawData(x, y, z, data);
65 }
66 }
67
68 public byte getData() {
69 return (byte) chunk.getHandle().getData(this.x & 0xF, this.y & 0x7F, this.z & 0xF);
70 }
71
72 public void setType(final Material type) {
73 setTypeId(type.getId());
74 }
75
76 public boolean setTypeId(final int type) {
77 // uberbukkit
78 if (!Uberbukkit.getProtocolHandler().canReceiveBlockItem(type)) {
79 return false;
80 }
81
82 return chunk.getHandle().world.setTypeId(x, y, z, type);
83 }
84
85 public boolean setTypeId(final int type, final boolean applyPhysics) {
86 if (applyPhysics) {
87 return setTypeId(type);
88 } else {
89 // uberbukkit
90 if (!Uberbukkit.getProtocolHandler().canReceiveBlockItem(type)) {
91 return false;
92 }
93
94 return chunk.getHandle().world.setRawTypeId(x, y, z, type);
95 }
96 }
97
98 public boolean setTypeIdAndData(final int type, final byte data, final boolean applyPhysics) {
99 // uberbukkit
100 if (!Uberbukkit.getProtocolHandler().canReceiveBlockItem(type)) {
101 return false;
102 }
103
104 if (applyPhysics) {
105 return chunk.getHandle().world.setTypeIdAndData(x, y, z, type, data);
106 } else {
107 boolean success = chunk.getHandle().world.setRawTypeIdAndData(x, y, z, type, data);
108 if (success) {
109 chunk.getHandle().world.notify(x, y, z);
110 }
111 return success;
112 }
113 }
114
115 public Material getType() {
116 return Material.getMaterial(getTypeId());
117 }
118
119 public int getTypeId() {
120 return chunk.getHandle().getTypeId(this.x & 0xF, this.y & 0x7F, this.z & 0xF);
121 }
122
123 public byte getLightLevel() {
124 return (byte) chunk.getHandle().world.getLightLevel(this.x, this.y, this.z);
125 }
126
127 public Block getFace(final BlockFace face) {
128 return getRelative(face, 1);
129 }
130
131 public Block getFace(final BlockFace face, final int distance) {
132 return getRelative(face, distance);
133 }
134
135 public Block getRelative(final int modX, final int modY, final int modZ) {
136 return getWorld().getBlockAt(getX() + modX, getY() + modY, getZ() + modZ);
137 }
138
139 public Block getRelative(BlockFace face) {
140 return getRelative(face, 1);
141 }
142
143 public Block getRelative(BlockFace face, int distance) {
144 return getRelative(face.getModX() * distance, face.getModY() * distance, face.getModZ() * distance);
145 }
146
147 public BlockFace getFace(final Block block) {
148 BlockFace[] values = BlockFace.values();
149
150 for (BlockFace face : values) {
151 if ((this.getX() + face.getModX() == block.getX()) && (this.getY() + face.getModY() == block.getY()) && (this.getZ() + face.getModZ() == block.getZ())) {
152 return face;
153 }
154 }
155
156 return null;
157 }
158
159 @Override
160 public String toString() {
161 return "CraftBlock{" + "chunk=" + chunk + "x=" + x + "y=" + y + "z=" + z + '}';
162 }
163
164 /**
165 * Notch uses a 0-5 to mean DOWN, UP, EAST, WEST, NORTH, SOUTH
166 * in that order all over. This method is convenience to convert for us.
167 *
168 * @return BlockFace the BlockFace represented by this number
169 */
170 public static BlockFace notchToBlockFace(int notch) {
171 switch (notch) {
172 case 0:
173 return BlockFace.DOWN;
174 case 1:
175 return BlockFace.UP;
176 case 2:
177 return BlockFace.EAST;
178 case 3:
179 return BlockFace.WEST;
180 case 4:
181 return BlockFace.NORTH;
182 case 5:
183 return BlockFace.SOUTH;
184 default:
185 return BlockFace.SELF;
186 }
187 }
188
189 public static int blockFaceToNotch(BlockFace face) {
190 switch (face) {
191 case DOWN:
192 return 0;
193 case UP:
194 return 1;
195 case EAST:
196 return 2;
197 case WEST:
198 return 3;
199 case NORTH:
200 return 4;
201 case SOUTH:
202 return 5;
203 default:
204 return 7; // Good as anything here, but technically invalid
205 }
206 }
207
208 public BlockState getState() {
209 Material material = getType();
210
211 switch (material) {
212 case SIGN:
213 case SIGN_POST:
214 case WALL_SIGN:
215 return new CraftSign(this);
216 case CHEST:
217 return new CraftChest(this);
218 case BURNING_FURNACE:
219 case FURNACE:
220 return new CraftFurnace(this);
221 case DISPENSER:
222 return new CraftDispenser(this);
223 case MOB_SPAWNER:
224 return new CraftCreatureSpawner(this);
225 case NOTE_BLOCK:
226 return new CraftNoteBlock(this);
227 default:
228 return new CraftBlockState(this);
229 }
230 }
231
232 public Biome getBiome() {
233 return biomeBaseToBiome(chunk.getHandle().world.getWorldChunkManager().getBiome(x, z));
234 }
235
236 public static final Biome biomeBaseToBiome(BiomeBase base) {
237 if (base == BiomeBase.RAINFOREST) {
238 return Biome.RAINFOREST;
239 } else if (base == BiomeBase.SWAMPLAND) {
240 return Biome.SWAMPLAND;
241 } else if (base == BiomeBase.SEASONAL_FOREST) {
242 return Biome.SEASONAL_FOREST;
243 } else if (base == BiomeBase.FOREST) {
244 return Biome.FOREST;
245 } else if (base == BiomeBase.SAVANNA) {
246 return Biome.SAVANNA;
247 } else if (base == BiomeBase.SHRUBLAND) {
248 return Biome.SHRUBLAND;
249 } else if (base == BiomeBase.TAIGA) {
250 return Biome.TAIGA;
251 } else if (base == BiomeBase.DESERT) {
252 return Biome.DESERT;
253 } else if (base == BiomeBase.PLAINS) {
254 return Biome.PLAINS;
255 } else if (base == BiomeBase.ICE_DESERT) {
256 return Biome.ICE_DESERT;
257 } else if (base == BiomeBase.TUNDRA) {
258 return Biome.TUNDRA;
259 } else if (base == BiomeBase.HELL) {
260 return Biome.HELL;
261 } else if (base == BiomeBase.SKY) {
262 return Biome.SKY;
263 }
264
265 return null;
266 }
267
268 public double getTemperature() {
269 return getWorld().getTemperature(x, z);
270 }
271
272 public double getHumidity() {
273 return getWorld().getHumidity(x, z);
274 }
275
276 public boolean isBlockPowered() {
277 return chunk.getHandle().world.isBlockPowered(x, y, z);
278 }
279
280 public boolean isBlockIndirectlyPowered() {
281 return chunk.getHandle().world.isBlockIndirectlyPowered(x, y, z);
282 }
283
284 @Override
285 public boolean equals(Object o) {
286 return this == o;
287 }
288
289 public boolean isBlockFacePowered(BlockFace face) {
290 return chunk.getHandle().world.isBlockFacePowered(x, y, z, blockFaceToNotch(face));
291 }
292
293 public boolean isBlockFaceIndirectlyPowered(BlockFace face) {
294 return chunk.getHandle().world.isBlockFaceIndirectlyPowered(x, y, z, blockFaceToNotch(face));
295 }
296
297 public int getBlockPower(BlockFace face) {
298 int power = 0;
299 BlockRedstoneWire wire = (BlockRedstoneWire) net.minecraft.server.Block.REDSTONE_WIRE;
300 net.minecraft.server.World world = chunk.getHandle().world;
301 if ((face == BlockFace.DOWN || face == BlockFace.SELF) && world.isBlockFacePowered(x, y - 1, z, 0))
302 power = wire.getPower(world, x, y - 1, z, power);
303 if ((face == BlockFace.UP || face == BlockFace.SELF) && world.isBlockFacePowered(x, y + 1, z, 1))
304 power = wire.getPower(world, x, y + 1, z, power);
305 if ((face == BlockFace.EAST || face == BlockFace.SELF) && world.isBlockFacePowered(x, y, z - 1, 2))
306 power = wire.getPower(world, x, y, z - 1, power);
307 if ((face == BlockFace.WEST || face == BlockFace.SELF) && world.isBlockFacePowered(x, y, z + 1, 3))
308 power = wire.getPower(world, x, y, z + 1, power);
309 if ((face == BlockFace.NORTH || face == BlockFace.SELF) && world.isBlockFacePowered(x - 1, y, z, 4))
310 power = wire.getPower(world, x - 1, y, z, power);
311 if ((face == BlockFace.SOUTH || face == BlockFace.SELF) && world.isBlockFacePowered(x + 1, y, z, 5))
312 power = wire.getPower(world, x + 1, y, z, power);
313 return power > 0 ? power : (face == BlockFace.SELF ? isBlockIndirectlyPowered() : isBlockFaceIndirectlyPowered(face)) ? 15 : 0;
314 }
315
316 public int getBlockPower() {
317 return getBlockPower(BlockFace.SELF);
318 }
319
320 public boolean isEmpty() {
321 return getType() == Material.AIR;
322 }
323
324 public boolean isLiquid() {
325 return (getType() == Material.WATER) || (getType() == Material.STATIONARY_WATER) || (getType() == Material.LAVA) || (getType() == Material.STATIONARY_LAVA);
326 }
327
328 public PistonMoveReaction getPistonMoveReaction() {
329 return PistonMoveReaction.getById(net.minecraft.server.Block.byId[this.getTypeId()].material.j());
330
331 }
332}