I have rewritten the block scan function to instead create a hashmap of list of hashmap and then sort lists by closest block of said type
basically this allows the turtle/computer/etc to get a list of UNIQUE block names in its area so that it can lookup a block by key using its identifier name, such as minecraft:grass, in which that will return a sorted list of all of that type of block in its area. this makes the list much smaller to iterate for Lua programs that know exactly what they're looking for and about the same for ones that are just looking at everything.
but most of all it makes it so fast to check which blocks are closest to the scanner. for instance want the closest minecraft:stone? it will always be the first one on the minecraft:stone list
This seems to cause computers to be a lot faster as they don't need to preform sorting on the Lua end and also the table returns to a variable much faster too. I have tested this with 32 block scan range and have found it to be infinitely faster.
from my understanding the reason the scan function takes so long with large scan radius is the transfer of the huge single table to lua, and not the actual processing time, so by splitting the table up and sorting it in java, it seems to make it alot faster on the Lua end.
Please let me know if I was not clear enough with my explanation and I will be happy to clarify, as I'd really like to improve plethora as its one of my favorite mods ever for CC.
import java.util.*;
import java.lang.Math;
private static HashMap<String,List<Map<String, ?>>> scan(World world, int x, int y, int z, int radius) {
HashMap<String,List<Map<String, ?>>> result = new HashMap<>();
for (int oX = x - radius; oX <= x + radius; oX++) {
for (int oY = y - radius; oY <= y + radius; oY++) {
for (int oZ = z - radius; oZ <= z + radius; oZ++) {
BlockPos subPos = BlockPos.ofFloored(oX, oY, oZ);
BlockState block = world.getBlockState(subPos);
Identifier name = Registries.BLOCK.getId(block.getBlock());
// Find name if it already exists within result
List<Map<String, ?>> blockList;
int indexOfRepeat = -1;
for (int it = 0; it < result.size(); it++)
{
if (result.containsKey(name.toString()))
indexOfRepeat = it;
}
if (indexOfRepeat == -1)
{
List<Map<String, ?>> blockListsub = new ArrayList<>();
result.put(name.toString(),blockListsub);
blockList = blockListsub;
} else {
blockList = (List<Map<String, ?>>)result.get(name.toString());
}
HashMap<String, Object> data = new HashMap<>(6);
data.put("x", oX - x);
data.put("y", oY - y);
data.put("z", oZ - z);
data.put("name", name.toString());
BlockStateMeta.fillBasicMeta(data, block);
blockList.add(data);
}
}
}
for(int i = 0;i<result.size();i++)
{
List<Map<String, ?>> list = (List<Map<String, ?>>)result.get(result.keySet().toArray()[i]);
Collections.sort(list, new Comparator<Map<String, ?>>() {
@Override
public int compare(Map<String, ?> m1,Map<String, ?> m2) {
double val = (getDistance3D(Double.valueOf((Integer)m1.get("x")),Double.valueOf((Integer)m1.get("y")),Double.valueOf((Integer)m1.get("z"))) - getDistance3D(Double.valueOf((Integer)m2.get("x")),Double.valueOf((Integer)m2.get("y")),Double.valueOf((Integer)m2.get("z"))));
if (val < 0)
return -1;
if (val>0)
return 1;
return 0;
}
});
}
return result;
}
//Implies origin is 0,0,0
public static double getDistance3D(double x,double y,double z)
{
return Math.sqrt(Math.pow(x,2)+Math.pow(y,2)+Math.pow(z,2));
}
edit: for some reason my implementation causes turtles to not immediately move after using scan till a bit later. i am unsure why this would be if the code has already completed execution
edit 2: it seems to be related to the execution settings within CC:Tweaked config, allowing more time remedies this issue. I am unsure if theres a better fix tho.
edit 3: i have noticed that lowering the range to 20 speeds this up alot too.
I have rewritten the block scan function to instead create a hashmap of list of hashmap and then sort lists by closest block of said type
basically this allows the turtle/computer/etc to get a list of UNIQUE block names in its area so that it can lookup a block by key using its identifier name, such as minecraft:grass, in which that will return a sorted list of all of that type of block in its area. this makes the list much smaller to iterate for Lua programs that know exactly what they're looking for and about the same for ones that are just looking at everything.
but most of all it makes it so fast to check which blocks are closest to the scanner. for instance want the closest minecraft:stone? it will always be the first one on the minecraft:stone list
This seems to cause computers to be a lot faster as they don't need to preform sorting on the Lua end and also the table returns to a variable much faster too. I have tested this with 32 block scan range and have found it to be infinitely faster.
from my understanding the reason the scan function takes so long with large scan radius is the transfer of the huge single table to lua, and not the actual processing time, so by splitting the table up and sorting it in java, it seems to make it alot faster on the Lua end.
Please let me know if I was not clear enough with my explanation and I will be happy to clarify, as I'd really like to improve plethora as its one of my favorite mods ever for CC.
edit: for some reason my implementation causes turtles to not immediately move after using scan till a bit later. i am unsure why this would be if the code has already completed execution
edit 2: it seems to be related to the execution settings within CC:Tweaked config, allowing more time remedies this issue. I am unsure if theres a better fix tho.
edit 3: i have noticed that lowering the range to 20 speeds this up alot too.