Faster Waterremover
Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Ursprung
2aabded41e
Commit
727129fe8e
@ -176,7 +176,6 @@ public class FightSystem extends JavaPlugin {
|
|||||||
mainCountdown = new EnternCountdown();
|
mainCountdown = new EnternCountdown();
|
||||||
|
|
||||||
FightStatistics.start();
|
FightStatistics.start();
|
||||||
WaterRemover.init();
|
|
||||||
Bukkit.broadcastMessage(PREFIX + "§aArena freigegeben!");
|
Bukkit.broadcastMessage(PREFIX + "§aArena freigegeben!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,106 +1,57 @@
|
|||||||
package de.steamwar.fightsystem.utils;
|
package de.steamwar.fightsystem.utils;
|
||||||
|
|
||||||
import de.steamwar.core.Core;
|
import de.steamwar.core.Core;
|
||||||
import de.steamwar.fightsystem.FightSystem;
|
|
||||||
import org.bukkit.Bukkit;
|
|
||||||
import org.bukkit.Location;
|
|
||||||
import org.bukkit.Material;
|
import org.bukkit.Material;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
import org.bukkit.block.BlockFace;
|
import org.bukkit.block.BlockFace;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.List;
|
||||||
|
|
||||||
public class WaterRemover {
|
public class WaterRemover {
|
||||||
|
|
||||||
private WaterRemover(){}
|
private WaterRemover(){}
|
||||||
|
|
||||||
private static final Map<Location, Integer> explodedBlocks = Collections.synchronizedMap(new HashMap<>());
|
|
||||||
private static Set<Block> waterList = new HashSet<>();
|
|
||||||
private static boolean isRunning = false;
|
|
||||||
private static int steps = 1;
|
|
||||||
|
|
||||||
public static void init() {
|
|
||||||
Bukkit.getScheduler().runTaskTimerAsynchronously(FightSystem.getPlugin(), () -> {
|
|
||||||
if(isRunning){
|
|
||||||
steps++;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
isRunning = true;
|
|
||||||
wateredCheck();
|
|
||||||
removeWater();
|
|
||||||
isRunning = false;
|
|
||||||
}, 0, 20);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void add(List<Block> l) {
|
public static void add(List<Block> l) {
|
||||||
l.forEach((Block b) -> explodedBlocks.put(b.getLocation(), 0));
|
for(Block b : l){
|
||||||
}
|
//b cannot be water or air due to current explosion
|
||||||
|
|
||||||
private static void wateredCheck() {
|
int startX = b.getX();
|
||||||
|
int startY = b.getY();
|
||||||
|
int startZ = b.getZ();
|
||||||
try{
|
try{
|
||||||
Iterator<Map.Entry<Location, Integer>> it = explodedBlocks.entrySet().iterator();
|
checkBlock(b.getRelative(BlockFace.EAST), startX, startY, startZ);
|
||||||
while (it.hasNext()) {
|
checkBlock(b.getRelative(BlockFace.WEST), startX, startY, startZ);
|
||||||
Map.Entry<Location, Integer> e = it.next();
|
checkBlock(b.getRelative(BlockFace.NORTH), startX, startY, startZ);
|
||||||
Block b = e.getKey().getBlock();
|
checkBlock(b.getRelative(BlockFace.SOUTH), startX, startY, startZ);
|
||||||
if (isWater(b))
|
checkBlock(b.getRelative(BlockFace.UP), startX, startY, startZ);
|
||||||
waterList.add(b);
|
}catch(IsAnOcean e){
|
||||||
|
//ignore
|
||||||
if(b.getType() != Material.AIR){
|
|
||||||
it.remove();
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
e.setValue(e.getValue() + steps);
|
|
||||||
|
|
||||||
if(e.getValue() > 3)
|
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
steps = 1;
|
|
||||||
}catch(ConcurrentModificationException e){
|
|
||||||
steps++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void removeWater() {
|
private static void checkBlock(Block b, int startX, int startY, int startZ) throws IsAnOcean {
|
||||||
List<Block> blocksToRemove = new LinkedList<>();
|
|
||||||
Iterator<Block> it = waterList.iterator();
|
|
||||||
while(it.hasNext()){
|
|
||||||
Block b = it.next();
|
|
||||||
blocksToRemove.addAll(getSourceBlocksOfWater(b));
|
|
||||||
if(!isWater(b))
|
if(!isWater(b))
|
||||||
it.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
Bukkit.getScheduler().runTask(FightSystem.getPlugin(), () -> blocksToRemove.forEach((Block b) -> b.setType(Material.AIR)));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Set<Block> getSourceBlocksOfWater(Block startBlock) {
|
|
||||||
Set<Block> water = new HashSet<>();
|
|
||||||
collectBlocks(startBlock, water, new HashSet<>());
|
|
||||||
return water;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void collectBlocks(Block anchor, Set<Block> collected, Set<Block> visitedBlocks) {
|
|
||||||
if(
|
|
||||||
!isWater(anchor) ||
|
|
||||||
visitedBlocks.contains(anchor)
|
|
||||||
)
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
visitedBlocks.add(anchor);
|
// If distance to original block is greater than 20
|
||||||
if (isWater(anchor))
|
if(Math.abs(startX - b.getX()) + Math.abs(startY - b.getY() + Math.abs(startZ - b.getZ())) >= 20)
|
||||||
collected.add(anchor);
|
throw new IsAnOcean();
|
||||||
|
|
||||||
if(visitedBlocks.size() > 100) {
|
b.setType(Material.AIR);
|
||||||
collected.clear();
|
try{
|
||||||
return;
|
checkBlock(b.getRelative(BlockFace.EAST), startX, startY, startZ);
|
||||||
|
checkBlock(b.getRelative(BlockFace.WEST), startX, startY, startZ);
|
||||||
|
checkBlock(b.getRelative(BlockFace.NORTH), startX, startY, startZ);
|
||||||
|
checkBlock(b.getRelative(BlockFace.SOUTH), startX, startY, startZ);
|
||||||
|
checkBlock(b.getRelative(BlockFace.UP), startX, startY, startZ);
|
||||||
|
}catch(IsAnOcean e){
|
||||||
|
b.setType(Material.WATER);
|
||||||
|
throw e;
|
||||||
}
|
}
|
||||||
collectBlocks(anchor.getRelative(BlockFace.UP), collected, visitedBlocks);
|
|
||||||
collectBlocks(anchor.getRelative(BlockFace.NORTH), collected, visitedBlocks);
|
|
||||||
collectBlocks(anchor.getRelative(BlockFace.EAST), collected, visitedBlocks);
|
|
||||||
collectBlocks(anchor.getRelative(BlockFace.SOUTH), collected, visitedBlocks);
|
|
||||||
collectBlocks(anchor.getRelative(BlockFace.WEST), collected, visitedBlocks);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class IsAnOcean extends Throwable{}
|
||||||
|
|
||||||
public static boolean isWater(Block block){
|
public static boolean isWater(Block block){
|
||||||
switch(Core.getVersion()){
|
switch(Core.getVersion()){
|
||||||
case 15:
|
case 15:
|
||||||
|
In neuem Issue referenzieren
Einen Benutzer sperren