I am making a plugin for a game called Minecraft with the Bukkit API .
I have a database table called Reinforcements with the following fields: x integer , y integer , z integer . The reinforcement block is a protected block, that is, it cannot be destroyed.
I use EntityExplodeEvent to test TNT explosions.
I go through event.blocklist() and compare each block with the entries in the Reinforcements table. If it exists, then prevent damage to the reinforced block in the explosion using event.blocklist().remove .
I can do this by getting the smallest and largest of each coordinate (x, y, z), and then checking the database rows between the two numbers. The problem is that it is a cube. I have to check the scope. How to do it?
Here is what I got so far, note: I know that this is not really a problem with the select expression, since I can compare the returned strings with event.blocklist() , but I will need to know how to do this when I go later, to make an expression to update.
The reason I need to know how to check rows in a sphere is because I will eventually add an extra field to the reinforcement table called 'durability integer' , which will decrease after each explosion. Since an explosion is a sphere, an update request should update rows only in this sphere, and not in a cube.
Is anyone Thanks you
Current MySQL query
"SELECT X, Y, Z FROM REINFORCEMENTS WHERE DURABILITY >= 1 " + "AND x<=? AND x>=? AND y<=? AND y>=? AND z<=? AND z>=? AND world=?");
Full code
@EventHandler public void checkForExplosion(EntityExplodeEvent event){ if(event.isCancelled()){ return; } //Store blocks that are inside explosion blast radius List<Block> blastRadiusBlocks = event.blockList(); //If explosion occurs in mid air it returns 0 so no need to go any //further since there are no blocks inside the explosions radius if(blastRadiusBlocks.size() < 1){ return; } HashMap<Coordinate, Block> affectedBlocks = new HashMap<Coordinate, Block>(); //Initialize min & max X,Y,Z coordinates int smallestX = blastRadiusBlocks.get(0).getX(); int largestX = smallestX; int smallestY = blastRadiusBlocks.get(0).getY(); int largestY = smallestY; int smallestZ = blastRadiusBlocks.get(0).getZ(); int largestZ = smallestZ; //World Name String worldName = blastRadiusBlocks.get(0).getWorld().getName(); World world = this.myPlugin.getServer().getWorld(worldName); //Find min & max X,Y,Z coordinates for(int i = 0; i < blastRadiusBlocks.size(); i++){ Block block = blastRadiusBlocks.get(i); int blockX = block.getX(); int blockY = block.getY(); int blockZ = block.getZ(); if(blockX < smallestX){ smallestX = blockX; } if(blockX > largestX){ largestX = blockX; } if(blockY < smallestY){ smallestY = blockY; } if(blockY > largestY){ largestY = blockY; } if(blockZ < smallestZ){ smallestZ = blockZ; } if(blockZ > largestZ){ largestZ = blockZ; } //Instantiate Coordinate class passing in parameters Coordinate coordinate = new Coordinate(world, blockX, blockY, blockZ); //Put a new entry of type Coordinate as key and type Block as value affectedBlocks.put(coordinate, block); } try { //Query database for any reinforced blocks that may be in the blast radius //Reinforced blocks should have a durability > 0 (aka >= 1) PreparedStatement ask = this.conn.prepareStatement( "SELECT X, Y, Z FROM REINFORCEMENTS WHERE DURABILITY >= 1 " + "AND x<=? AND x>=? AND y<=? AND y>=? AND z<=? AND z>=? AND world=?"); ask.setInt(1, largestX); ask.setInt(2, smallestX); ask.setInt(3, largestY); ask.setInt(4, smallestY); ask.setInt(5, largestZ); ask.setInt(6, smallestZ); ask.setString(7, worldName); ask.execute(); ResultSet result = ask.getResultSet(); //If there was some found, loop through each one while(result.next()){ //Get X,Y,Z coords of reinforced block int x = result.getInt(1); int y = result.getInt(2); int z = result.getInt(3); //Pass in x, y, z of reinforced block into affectedBlocks HashMap to instantiate a Block Block protectedBlock = affectedBlocks.get(new Coordinate(world, x, y, z)); //Then remove the protectedBlock from explosion list event.blockList().remove(protectedBlock); } result.close(); ask.close(); } catch (SQLException e) { System.err.println("Citadel - Select Reinforcement can't keep up (possibly too many explosions):\n" + e); } }