SteamWar/FightSystem
Archiviert
13
1

Faster Waterremover

Signed-off-by: Lixfel <agga-games@gmx.de>
Dieser Commit ist enthalten in:
Lixfel 2020-07-06 17:39:45 +02:00
Ursprung 2aabded41e
Commit 727129fe8e
2 geänderte Dateien mit 31 neuen und 81 gelöschten Zeilen

Datei anzeigen

@ -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!");
} }

Datei anzeigen

@ -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();
try{ int startY = b.getY();
Iterator<Map.Entry<Location, Integer>> it = explodedBlocks.entrySet().iterator(); int startZ = b.getZ();
while (it.hasNext()) { try{
Map.Entry<Location, Integer> e = it.next(); checkBlock(b.getRelative(BlockFace.EAST), startX, startY, startZ);
Block b = e.getKey().getBlock(); checkBlock(b.getRelative(BlockFace.WEST), startX, startY, startZ);
if (isWater(b)) checkBlock(b.getRelative(BlockFace.NORTH), startX, startY, startZ);
waterList.add(b); checkBlock(b.getRelative(BlockFace.SOUTH), startX, startY, startZ);
checkBlock(b.getRelative(BlockFace.UP), startX, startY, startZ);
if(b.getType() != Material.AIR){ }catch(IsAnOcean e){
it.remove(); //ignore
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<>(); if(!isWater(b))
Iterator<Block> it = waterList.iterator();
while(it.hasNext()){
Block b = it.next();
blocksToRemove.addAll(getSourceBlocksOfWater(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: