Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A more efficent block scan function suggestion/rewrite #54

Open
Trickster29 opened this issue May 7, 2023 · 0 comments
Open

A more efficent block scan function suggestion/rewrite #54

Trickster29 opened this issue May 7, 2023 · 0 comments

Comments

@Trickster29
Copy link

Trickster29 commented May 7, 2023

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.

@Trickster29 Trickster29 changed the title A more efficent scan function suggestion/rewrite A more efficent block scan function suggestion/rewrite May 7, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant