PageRenderTime 58ms CodeModel.GetById 23ms RepoModel.GetById 1ms app.codeStats 0ms

/src/net/edoxile/bettermechanics/utils/BlockMapper.java

https://github.com/GuntherDW/BetterMechanics
Java | 372 lines | 346 code | 21 blank | 5 comment | 110 complexity | c4f35d3a9b542242218e038b353dfb58 MD5 | raw file
  1. package net.edoxile.bettermechanics.utils;
  2. import net.edoxile.bettermechanics.MechanicsType;
  3. import net.edoxile.bettermechanics.exceptions.BlockNotFoundException;
  4. import net.edoxile.bettermechanics.exceptions.InvalidDirectionException;
  5. import net.edoxile.bettermechanics.exceptions.OutOfBoundsException;
  6. import org.bukkit.Location;
  7. import org.bukkit.Material;
  8. import org.bukkit.block.Block;
  9. import org.bukkit.block.BlockFace;
  10. import org.bukkit.material.Sign;
  11. import java.util.HashSet;
  12. import java.util.logging.Logger;
  13. /**
  14. * Created by IntelliJ IDEA.
  15. * User: Edoxile
  16. */
  17. public class BlockMapper {
  18. private static final Logger log = Logger.getLogger("Minecraft");
  19. private static HashSet<Block> recursiveSet = new HashSet<Block>();
  20. private static int maxTraverse = 128;
  21. public static HashSet<Block> mapHorizontal(BlockFace direction, Block start, Block end, boolean small) throws InvalidDirectionException {
  22. HashSet<Block> blockSet = new HashSet<Block>();
  23. int traversed = 0;
  24. switch (direction) {
  25. case WEST: {
  26. Location startLoc = start.getLocation();
  27. Location endLoc = end.getLocation();
  28. if (startLoc.getBlockX() != endLoc.getBlockX() || startLoc.getBlockY() != endLoc.getBlockY() || startLoc.getBlockZ() > endLoc.getBlockZ()) {
  29. throw new InvalidDirectionException();
  30. } else {
  31. Block tempBlock = start;
  32. while (!tempBlock.getLocation().equals(end.getLocation()) && traversed < maxTraverse) {
  33. blockSet.add(tempBlock);
  34. if (!small) {
  35. blockSet.add(tempBlock.getRelative(BlockFace.NORTH));
  36. blockSet.add(tempBlock.getRelative(BlockFace.SOUTH));
  37. }
  38. tempBlock = tempBlock.getRelative(direction);
  39. traversed++;
  40. }
  41. if(traversed>=maxTraverse) {
  42. log.severe("[BetterMechanics] MaxTraverse hit on "+start.getLocation());
  43. }
  44. }
  45. }
  46. break;
  47. case EAST: {
  48. Location startLoc = start.getLocation();
  49. Location endLoc = end.getLocation();
  50. if (startLoc.getBlockX() != endLoc.getBlockX() || startLoc.getBlockY() != endLoc.getBlockY() || endLoc.getBlockZ() > startLoc.getBlockZ()) {
  51. throw new InvalidDirectionException();
  52. } else {
  53. Block tempBlock = start;
  54. while (!tempBlock.getLocation().equals(end.getLocation()) && traversed < maxTraverse) {
  55. blockSet.add(tempBlock);
  56. if (!small) {
  57. blockSet.add(tempBlock.getRelative(BlockFace.NORTH));
  58. blockSet.add(tempBlock.getRelative(BlockFace.SOUTH));
  59. }
  60. tempBlock = tempBlock.getRelative(direction);
  61. traversed++;
  62. }
  63. if(traversed>=maxTraverse) {
  64. log.severe("[BetterMechanics] MaxTraverse hit on "+start.getLocation());
  65. }
  66. }
  67. }
  68. break;
  69. case SOUTH: {
  70. Location startLoc = start.getLocation();
  71. Location endLoc = end.getLocation();
  72. if (startLoc.getBlockZ() != endLoc.getBlockZ() || startLoc.getBlockY() != endLoc.getBlockY() || startLoc.getBlockX() > endLoc.getBlockX()) {
  73. throw new InvalidDirectionException();
  74. } else {
  75. Block tempBlock = start;
  76. while (!tempBlock.getLocation().equals(end.getLocation()) && traversed < maxTraverse) {
  77. blockSet.add(tempBlock);
  78. if (!small) {
  79. blockSet.add(tempBlock.getRelative(BlockFace.WEST));
  80. blockSet.add(tempBlock.getRelative(BlockFace.EAST));
  81. }
  82. tempBlock = tempBlock.getRelative(direction);
  83. traversed++;
  84. }
  85. if(traversed>=maxTraverse) {
  86. log.severe("[BetterMechanics] MaxTraverse hit on "+start.getLocation());
  87. }
  88. }
  89. }
  90. break;
  91. case NORTH: {
  92. Location startLoc = start.getLocation();
  93. Location endLoc = end.getLocation();
  94. if (startLoc.getBlockZ() != endLoc.getBlockZ() || startLoc.getBlockY() != endLoc.getBlockY() || endLoc.getBlockX() > startLoc.getBlockX()) {
  95. throw new InvalidDirectionException();
  96. } else {
  97. Block tempBlock = start;
  98. while (!tempBlock.getLocation().equals(end.getLocation()) && traversed < maxTraverse) {
  99. blockSet.add(tempBlock);
  100. if (!small) {
  101. blockSet.add(tempBlock.getRelative(BlockFace.WEST));
  102. blockSet.add(tempBlock.getRelative(BlockFace.EAST));
  103. }
  104. tempBlock = tempBlock.getRelative(direction);
  105. traversed++;
  106. }
  107. if(traversed>=maxTraverse) {
  108. log.severe("[BetterMechanics] MaxTraverse hit on "+start.getLocation());
  109. }
  110. }
  111. }
  112. break;
  113. default:
  114. throw new InvalidDirectionException();
  115. }
  116. return blockSet;
  117. }
  118. public static HashSet<Block> mapHiddenSwitch(Block start) {
  119. // if(!(start.getState() instanceof Sign)) return null;
  120. HashSet<Block> blockSet = new HashSet<Block>();
  121. HashSet<Block> tempBlocks = new HashSet<Block>();
  122. if(start.getType() != org.bukkit.Material.WALL_SIGN) return blockSet;
  123. BlockFace signface = ((Sign) start.getState().getData()).getAttachedFace();
  124. tempBlocks.add(start.getRelative(BlockFace.UP));
  125. tempBlocks.add(start.getRelative(BlockFace.DOWN));
  126. switch(signface) {
  127. case NORTH:
  128. case SOUTH:
  129. tempBlocks.add(start.getRelative(BlockFace.WEST));
  130. tempBlocks.add(start.getRelative(BlockFace.EAST));
  131. break;
  132. case EAST:
  133. case WEST:
  134. tempBlocks.add(start.getRelative(BlockFace.NORTH));
  135. tempBlocks.add(start.getRelative(BlockFace.SOUTH));
  136. break;
  137. }
  138. for(Block b : tempBlocks) {
  139. if(b.getType()==Material.LEVER)
  140. blockSet.add(b);
  141. }
  142. return blockSet;
  143. }
  144. public static HashSet<Block> mapVertical(BlockFace direction, BlockFace orientation, Block start, Block end, boolean small) throws InvalidDirectionException {
  145. HashSet<Block> blockSet = new HashSet<Block>();
  146. int traversed = 0;
  147. switch (direction) {
  148. case UP: {
  149. Location startLoc = start.getLocation();
  150. Location endLoc = end.getLocation();
  151. if (startLoc.getBlockX() != endLoc.getBlockX() || startLoc.getBlockZ() != endLoc.getBlockZ()) {
  152. throw new InvalidDirectionException();
  153. } else {
  154. Block tempBlock = start;
  155. while (!tempBlock.getLocation().equals(end.getLocation()) && traversed < maxTraverse) {
  156. blockSet.add(tempBlock);
  157. if (!small) {
  158. switch (orientation) {
  159. case NORTH:
  160. case SOUTH: {
  161. blockSet.add(tempBlock.getRelative(BlockFace.WEST));
  162. blockSet.add(tempBlock.getRelative(BlockFace.EAST));
  163. }
  164. break;
  165. case EAST:
  166. case WEST: {
  167. blockSet.add(tempBlock.getRelative(BlockFace.NORTH));
  168. blockSet.add(tempBlock.getRelative(BlockFace.SOUTH));
  169. }
  170. break;
  171. }
  172. }
  173. tempBlock = tempBlock.getRelative(direction);
  174. traversed++;
  175. }
  176. if(traversed>=maxTraverse) {
  177. log.severe("[BetterMechanics] MaxTraverse hit on "+start.getLocation());
  178. }
  179. }
  180. }
  181. break;
  182. case DOWN: {
  183. Location startLoc = start.getLocation();
  184. Location endLoc = end.getLocation();
  185. if (startLoc.getBlockZ() != endLoc.getBlockZ() || startLoc.getBlockX() != endLoc.getBlockX()) {
  186. throw new InvalidDirectionException();
  187. } else {
  188. Block tempBlock = start;
  189. while (!tempBlock.getLocation().equals(end.getLocation()) && traversed < maxTraverse) {
  190. blockSet.add(tempBlock);
  191. switch (orientation) {
  192. case NORTH:
  193. case SOUTH: {
  194. blockSet.add(tempBlock.getRelative(BlockFace.WEST));
  195. blockSet.add(tempBlock.getRelative(BlockFace.EAST));
  196. }
  197. break;
  198. case EAST:
  199. case WEST: {
  200. blockSet.add(tempBlock.getRelative(BlockFace.NORTH));
  201. blockSet.add(tempBlock.getRelative(BlockFace.SOUTH));
  202. }
  203. break;
  204. }
  205. tempBlock = tempBlock.getRelative(direction);
  206. traversed++;
  207. }
  208. if(traversed>=maxTraverse) {
  209. log.severe("[BetterMechanics] MaxTraverse hit on "+start.getLocation());
  210. }
  211. }
  212. }
  213. break;
  214. default:
  215. throw new InvalidDirectionException();
  216. }
  217. return blockSet;
  218. }
  219. public static Block mapColumn(Block start, int sw, int h, Material m) {
  220. Block tempBlock;
  221. int nsw = ~sw + 1; // Negative search Width
  222. int nh = ~h + 1;
  223. for (int dy = nh; dy <= h; dy++) {
  224. for (int dx = nsw; dx <= sw; dx++) {
  225. tempBlock = start.getRelative(dx, dy, 0);
  226. if (tempBlock.getType() == m) {
  227. return getUpperBlock(tempBlock);
  228. }
  229. }
  230. for (int dz = nsw; dz <= sw; dz++) {
  231. tempBlock = start.getRelative(0, dy, dz);
  232. if (tempBlock.getType() == m) {
  233. return getUpperBlock(tempBlock);
  234. }
  235. }
  236. }
  237. return null;
  238. }
  239. public static Block mapCuboidRegion(Block start, int sw, Material m) {
  240. for (int dy = 0; dy <= sw; dy++) {
  241. for (int dx = 0; dx <= sw; dx++) {
  242. for (int dz = 0; dz <= sw; dz++) {
  243. HashSet<Block> blockSet = new HashSet<Block>();
  244. blockSet.add(start.getRelative(dx, dy, dz));
  245. blockSet.add(start.getRelative(-dx, dy, dz));
  246. blockSet.add(start.getRelative(dx, dy, -dz));
  247. blockSet.add(start.getRelative(-dx, dy, -dz));
  248. blockSet.add(start.getRelative(dx, -dy, dz));
  249. blockSet.add(start.getRelative(-dx, -dy, dz));
  250. blockSet.add(start.getRelative(dx, -dy, -dz));
  251. blockSet.add(start.getRelative(-dx, -dy, -dz));
  252. for (Block b : blockSet) {
  253. if (b.getType() == m) {
  254. return b;
  255. }
  256. }
  257. }
  258. }
  259. }
  260. return null;
  261. }
  262. public static HashSet<Block> mapAllInCuboidRegion(Block start, int sw, Material m) {
  263. Block tempBlock;
  264. HashSet<Block> blockSet = new HashSet<Block>();
  265. int nsw = ~sw + 1;
  266. for (int dx = nsw; dx <= sw; dx++) {
  267. for (int dy = nsw; dy <= sw; dy++) {
  268. for (int dz = nsw; dz <= sw; dz++) {
  269. tempBlock = start.getRelative(dx, dy, dz);
  270. if (tempBlock.getType() == m) {
  271. blockSet.add(tempBlock);
  272. }
  273. }
  274. }
  275. }
  276. return blockSet;
  277. }
  278. private static Block getUpperBlock(Block block) {
  279. while (block.getRelative(BlockFace.UP).getType() == block.getType()) {
  280. block = block.getRelative(BlockFace.UP);
  281. }
  282. return block;
  283. }
  284. public static HashSet<Block> mapFlatRegion(Block start, Material m, int w, int l) throws OutOfBoundsException {
  285. Block tempBlock = start;
  286. int west = 0, east = 0, south = 0, north = 0, width, length;
  287. while (checkInColumn(tempBlock.getRelative(BlockFace.WEST), m, 1) != null) {
  288. tempBlock = tempBlock.getRelative(BlockFace.WEST);
  289. west++;
  290. }
  291. tempBlock = start;
  292. while (checkInColumn(tempBlock.getRelative(BlockFace.EAST), m, 1) != null) {
  293. tempBlock = tempBlock.getRelative(BlockFace.EAST);
  294. east++;
  295. }
  296. tempBlock = start;
  297. while (checkInColumn(tempBlock.getRelative(BlockFace.NORTH), m, 1) != null) {
  298. tempBlock = tempBlock.getRelative(BlockFace.NORTH);
  299. north++;
  300. }
  301. tempBlock = start;
  302. while (checkInColumn(tempBlock.getRelative(BlockFace.SOUTH), m, 1) != null) {
  303. tempBlock = tempBlock.getRelative(BlockFace.SOUTH);
  304. south++;
  305. }
  306. if ((north + south) > (east + west)) {
  307. width = (east + west);
  308. length = (north + south);
  309. } else {
  310. length = (east + west);
  311. width = (north + south);
  312. }
  313. if (width > w || length > l) {
  314. throw new OutOfBoundsException();
  315. }
  316. start = start.getRelative((~north + 1), 0, (~east + 1));
  317. HashSet<Block> blockSet = new HashSet<Block>();
  318. for (int dx = 0; dx <= (north + south); dx++) {
  319. for (int dz = 0; dz <= (east + west); dz++) {
  320. tempBlock = checkInColumn(start.getRelative(dx, 0, dz), m, 1);
  321. if (tempBlock != null) {
  322. blockSet.add(getUpperBlock(tempBlock));
  323. }
  324. }
  325. }
  326. return blockSet;
  327. }
  328. private static Block checkInColumn(Block start, Material m, int h) {
  329. int nh = ~h + 1;
  330. for (int dy = nh; dy <= h; dy++) {
  331. if (start.getRelative(0, dy, 0).getType() == m) {
  332. return start.getRelative(0, dy, 0);
  333. }
  334. }
  335. return null;
  336. }
  337. public static org.bukkit.block.Sign findMechanicsSign(Block block, BlockFace direction, MechanicsType type, int maxBlockDistance) throws BlockNotFoundException {
  338. for (int d = 0; d < maxBlockDistance; d++) {
  339. block = block.getRelative(direction);
  340. if (SignUtil.isSign(block)) {
  341. org.bukkit.block.Sign s = SignUtil.getSign(block);
  342. if (s != null) {
  343. if (SignUtil.getMechanicsType(s) == type) {
  344. return s;
  345. }
  346. }
  347. }
  348. }
  349. throw new BlockNotFoundException();
  350. }
  351. }