Я создаю плагин для игры под названием Minecraft с Bukkit API
.
У меня есть таблица базы данных с именем Reinforcements
со следующими полями: x integer
, y integer
, z integer
. Армирующий блок - это защищенный блок, то есть он не может быть уничтожен.
Я использую EntityExplodeEvent
для проверки на взрывы TNT.
Я перебираю event.blocklist()
и сравниваю каждый блок с записями в таблице подкреплений. Если он существует, то предотвратите повреждение усиленного блока при взрыве, используя event.blocklist().remove
.
Я могу сделать это, получив наименьшее и наибольшее из каждой координаты (x, y, z), а затем проверив строки базы данных между этими двумя числами. Проблема в том, что это куб. Я должен проверять сферу. Как мне это сделать?
Вот что я получил до сих пор, обратите внимание: я знаю, что это не совсем проблема с оператором select, поскольку я могу сравнить возвращенные строки с event.blocklist()
, но мне нужно знать, как это сделать, когда Я иду, чтобы сделать заявление об обновлении позже.
Причина, по которой мне нужно знать, как проверять строки в сфере, заключается в том, что в конечном итоге я добавлю дополнительное поле в таблицу подкреплений под названием 'durability integer'
, которое будет уменьшаться после каждого взрыва. Поскольку взрыв - это сфера, запрос на обновление должен обновлять только строки в этой сфере, а не куб.
Кто-нибудь?
Спасибо
Текущий 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=?");
Полный код
@EventHandler
public void checkForExplosion(EntityExplodeEvent event){
if(event.isCancelled()){
return;
}
//Store blocks that are inside explosion's 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);
}
}