Greatly improved Vein Miner performance
This commit is contained in:
@ -13,7 +13,9 @@ import wtf.hak.survivalfabric.features.veinminer.VeinMinerSession;
|
||||
import wtf.hak.survivalfabric.utils.Scheduler;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import static wtf.hak.survivalfabric.SurvivalFabric.LOGGER;
|
||||
import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
||||
@ -21,7 +23,6 @@ import static wtf.hak.survivalfabric.config.ConfigManager.getConfig;
|
||||
public class DrillBase implements Drill {
|
||||
|
||||
protected VeinMinerSession session;
|
||||
|
||||
protected TagKey<Block> tag;
|
||||
|
||||
public DrillBase(VeinMinerSession session, TagKey<Block> tag) {
|
||||
@ -36,11 +37,11 @@ public class DrillBase implements Drill {
|
||||
|
||||
@Override
|
||||
public boolean drill(BlockPos startPos) {
|
||||
handleBlock(session.world.getBlockState(startPos).getBlock(), new ArrayList<>(), startPos, 0);
|
||||
handleBlock(session.world.getBlockState(startPos).getBlock(), new HashSet<>(), startPos, 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
private void handleBlock(Block initialBlock, List<BlockPos> history, BlockPos pos, int brokenBlocks) {
|
||||
private void handleBlock(Block initialBlock, Set<BlockPos> history, BlockPos pos, int brokenBlocks) {
|
||||
if (brokenBlocks < getConfig().maxVeinSize) {
|
||||
history.add(pos);
|
||||
if (tryBreakBlock(pos)) {
|
||||
@ -48,30 +49,40 @@ public class DrillBase implements Drill {
|
||||
int finalBrokenBlocks = brokenBlocks;
|
||||
|
||||
// Put everything in a list to avoid scheduling a lot of tasks.
|
||||
// Has the added benefit of only playing one sound
|
||||
|
||||
List<BlockPos> toBreak = new ArrayList<>();
|
||||
forXYZ(pos, 1, newPos -> {
|
||||
if (!history.contains(newPos) && session.world.getBlockState(newPos).getBlock() == initialBlock) {
|
||||
toBreak.add(newPos);
|
||||
}
|
||||
});
|
||||
Set<BlockPos> toBreak = new HashSet<>();
|
||||
collectAdjacentBlocks(pos, history, initialBlock, toBreak);
|
||||
|
||||
long delay = getConfig().veinAnimationTicks;
|
||||
if (delay <= 0)
|
||||
for (BlockPos newPos : toBreak)
|
||||
handleBlock(initialBlock, history, newPos, finalBrokenBlocks);
|
||||
else {
|
||||
Scheduler.get().scheduleTask(() -> {
|
||||
for (BlockPos newPos : toBreak)
|
||||
handleBlock(initialBlock, history, newPos, finalBrokenBlocks);
|
||||
}, delay);
|
||||
}
|
||||
|
||||
// Use final or effectively final variables for lambda
|
||||
final int[] finalBrokenBlocksArr = {finalBrokenBlocks};
|
||||
|
||||
if (delay <= 0) {
|
||||
handleBlocksInBatch(toBreak, initialBlock, history, finalBrokenBlocksArr[0]);
|
||||
} else {
|
||||
Scheduler.get().scheduleTask(() -> handleBlocksInBatch(toBreak, initialBlock, history, finalBrokenBlocksArr[0]), delay);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void collectAdjacentBlocks(BlockPos pos, Set<BlockPos> history, Block initialBlock, Set<BlockPos> toBreak) {
|
||||
forXYZ(pos, 1, new ForXYZHandler() {
|
||||
@Override
|
||||
public void handle(BlockPos newPos) {
|
||||
if (!history.contains(newPos) && session.world.getBlockState(newPos).getBlock() == initialBlock) {
|
||||
toBreak.add(newPos);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void handleBlocksInBatch(Set<BlockPos> toBreak, Block initialBlock, Set<BlockPos> history, int finalBrokenBlocks) {
|
||||
for (BlockPos newPos : toBreak) {
|
||||
handleBlock(initialBlock, history, newPos, finalBrokenBlocks);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRightTool(BlockPos pos) {
|
||||
var blockState = session.world.getBlockState(pos);
|
||||
@ -79,9 +90,12 @@ public class DrillBase implements Drill {
|
||||
}
|
||||
|
||||
protected void forXYZ(BlockPos pos, int max, ForXYZHandler handler) {
|
||||
forXYZ(pos, max, handlerPos -> {
|
||||
handler.handle(handlerPos);
|
||||
return 0;
|
||||
forXYZ(pos, max, new ForXYZCounter() {
|
||||
@Override
|
||||
public int handle(BlockPos pos) {
|
||||
handler.handle(pos);
|
||||
return 1; // Accumulate one count for each position processed
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
|
||||
@ -90,14 +104,17 @@ public class DrillBase implements Drill {
|
||||
}
|
||||
|
||||
protected void forXYZ(BlockPos pos, int max, ForXYZHandler handler, boolean forceVertical) {
|
||||
forXYZ(pos, max, handlerPos -> {
|
||||
handler.handle(handlerPos);
|
||||
return 0;
|
||||
forXYZ(pos, max, new ForXYZCounter() {
|
||||
@Override
|
||||
public int handle(BlockPos pos) {
|
||||
handler.handle(pos);
|
||||
return 1; // Accumulate one count for each position processed
|
||||
}
|
||||
}, forceVertical);
|
||||
}
|
||||
|
||||
protected int forXYZ(BlockPos pos, int max, ForXYZCounter handler, boolean forceVertical) {
|
||||
ArrayList<Integer> offsets = new ArrayList<Integer>();
|
||||
Set<Integer> offsets = new HashSet<>();
|
||||
for (int d = 0; d <= max; ++d) {
|
||||
offsets.add(d);
|
||||
if (d != -d) {
|
||||
@ -105,39 +122,21 @@ public class DrillBase implements Drill {
|
||||
}
|
||||
}
|
||||
|
||||
String[] order = new String[]{"x", "y", "z"};
|
||||
if (forceVertical) {
|
||||
order = new String[]{"y", "x", "z"};
|
||||
} else {
|
||||
ServerPlayerEntity player = session.player;
|
||||
boolean majorPitchChange = player.getPitch() < -45.0 || player.getPitch() > 45.0;
|
||||
boolean majorYawChange = (player.getYaw() > 45.0 && player.getYaw() < 135.0) || (player.getYaw() < -45.0 && player.getYaw() > -135.0);
|
||||
if (majorPitchChange) {
|
||||
if (majorYawChange) {
|
||||
order = new String[]{"y", "z", "x"};
|
||||
} else {
|
||||
order = new String[]{"y", "x", "z"};
|
||||
}
|
||||
} else {
|
||||
if (majorYawChange) {
|
||||
order = new String[]{"z", "y", "x"};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
String[] order = determineOrder(forceVertical);
|
||||
int counter = 0;
|
||||
|
||||
for (int i1 : offsets) {
|
||||
for (int i2 : offsets) {
|
||||
for (int i3 : offsets) {
|
||||
int ix = order[0] == "x" ? i1 : order[1] == "x" ? i2 : i3;
|
||||
int iy = order[0] == "y" ? i1 : order[1] == "y" ? i2 : i3;
|
||||
int iz = order[0] == "z" ? i1 : order[1] == "z" ? i2 : i3;
|
||||
int ix = order[0].equals("x") ? i1 : order[1].equals("x") ? i2 : i3;
|
||||
int iy = order[0].equals("y") ? i1 : order[1].equals("y") ? i2 : i3;
|
||||
int iz = order[0].equals("z") ? i1 : order[1].equals("z") ? i2 : i3;
|
||||
|
||||
int px = pos.getX() + ix;
|
||||
int py = pos.getY() + iy;
|
||||
int pz = pos.getZ() + iz;
|
||||
|
||||
counter += handler.handle(new BlockPos(px, py, pz));
|
||||
counter += handler.handle(new BlockPos(px, py, pz)); // Works with ForXYZCounter, returning an int
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,6 +144,29 @@ public class DrillBase implements Drill {
|
||||
return counter;
|
||||
}
|
||||
|
||||
protected String[] determineOrder(boolean forceVertical) {
|
||||
if (forceVertical) {
|
||||
return new String[]{"y", "x", "z"};
|
||||
} else {
|
||||
ServerPlayerEntity player = session.player;
|
||||
boolean majorPitchChange = player.getPitch() < -45.0 || player.getPitch() > 45.0;
|
||||
boolean majorYawChange = (player.getYaw() > 45.0 && player.getYaw() < 135.0) || (player.getYaw() < -45.0 && player.getYaw() > -135.0);
|
||||
|
||||
if (majorPitchChange) {
|
||||
if (majorYawChange) {
|
||||
return new String[]{"y", "z", "x"};
|
||||
} else {
|
||||
return new String[]{"y", "x", "z"};
|
||||
}
|
||||
} else {
|
||||
if (majorYawChange) {
|
||||
return new String[]{"z", "y", "x"};
|
||||
}
|
||||
}
|
||||
}
|
||||
return new String[]{"x", "y", "z"};
|
||||
}
|
||||
|
||||
protected boolean tryBreakBlock(BlockPos blockPos) {
|
||||
session.addPosition(blockPos);
|
||||
boolean success = isRightTool(blockPos) && session.player.interactionManager.tryBreakBlock(blockPos);
|
||||
@ -168,4 +190,4 @@ public class DrillBase implements Drill {
|
||||
protected interface ForXYZCounter {
|
||||
int handle(BlockPos pos);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user