PageRenderTime 52ms CodeModel.GetById 27ms RepoModel.GetById 0ms app.codeStats 0ms

/src/main/java/com/edoxile/bukkit/bettermechanics/utils/BlockMapper.java

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