Merge pull request #671 from CocoTheOwner/betterFind

Improve finding by allowing minimal distance & randomization
This commit is contained in:
Dan 2021-11-11 17:54:25 -05:00 committed by GitHub
commit 6422772530
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 43 additions and 28 deletions

View File

@ -34,7 +34,9 @@ public class CommandFind implements DecreeExecutor {
@Decree(description = "Find a biome") @Decree(description = "Find a biome")
public void biome( public void biome(
@Param(description = "The biome to look for") @Param(description = "The biome to look for")
IrisBiome biome IrisBiome biome,
@Param(description = "The distance away from you to start searching. -1 for random, 0 for closest", defaultValue = "0")
int distance
) { ) {
Engine e = engine(); Engine e = engine();
@ -43,13 +45,15 @@ public class CommandFind implements DecreeExecutor {
return; return;
} }
e.gotoBiome(biome, player()); e.gotoBiome(biome, player(), distance == -1 ? 0 : distance, distance == -1);
} }
@Decree(description = "Find a region") @Decree(description = "Find a region")
public void region( public void region(
@Param(description = "The region to look for") @Param(description = "The region to look for")
IrisRegion region IrisRegion region,
@Param(description = "The distance away from you to start searching. -1 for random, 0 for closest", defaultValue = "0")
int distance
) { ) {
Engine e = engine(); Engine e = engine();
@ -58,13 +62,15 @@ public class CommandFind implements DecreeExecutor {
return; return;
} }
e.gotoRegion(region, player()); e.gotoRegion(region, player(), distance == -1 ? 0 : distance, distance == -1);
} }
@Decree(description = "Find a structure") @Decree(description = "Find a structure")
public void structure( public void structure(
@Param(description = "The structure to look for") @Param(description = "The structure to look for")
IrisJigsawStructure structure IrisJigsawStructure structure,
@Param(description = "The distance away from you to start searching. -1 for random, 0 for closest", defaultValue = "0")
int distance
) { ) {
Engine e = engine(); Engine e = engine();
@ -73,13 +79,15 @@ public class CommandFind implements DecreeExecutor {
return; return;
} }
e.gotoJigsaw(structure, player()); e.gotoJigsaw(structure, player(), distance == -1 ? 0 : distance, distance == -1);
} }
@Decree(description = "Find an object") @Decree(description = "Find an object")
public void object( public void object(
@Param(description = "The object to look for", customHandler = ObjectHandler.class) @Param(description = "The object to look for", customHandler = ObjectHandler.class)
String object String object,
@Param(description = "The distance away from you to start searching. -1 for random, 0 for closest", defaultValue = "0")
int distance
) { ) {
Engine e = engine(); Engine e = engine();
@ -88,6 +96,6 @@ public class CommandFind implements DecreeExecutor {
return; return;
} }
e.gotoObject(object, player()); e.gotoObject(object, player(), distance == -1 ? 0 : distance, distance == -1);
} }
} }

View File

@ -52,7 +52,7 @@ public class INMS {
return "BUKKIT"; return "BUKKIT";
} }
private static final INMSBinding bind() { private static INMSBinding bind() {
String code = getNMSTag(); String code = getNMSTag();
Iris.info("Locating NMS Binding for " + code); Iris.info("Locating NMS Binding for " + code);

View File

@ -771,7 +771,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
return getBiomeOrMantle(l.getBlockX(), l.getBlockY(), l.getBlockZ()); return getBiomeOrMantle(l.getBlockX(), l.getBlockY(), l.getBlockZ());
} }
default void gotoBiome(IrisBiome biome, Player player) { default void gotoBiome(IrisBiome biome, Player player, int distance, boolean random) {
Set<String> regionKeys = getDimension() Set<String> regionKeys = getDimension()
.getAllRegions(this).stream() .getAllRegions(this).stream()
.filter((i) -> i.getAllBiomes(this).contains(biome)) .filter((i) -> i.getAllBiomes(this).contains(biome))
@ -783,13 +783,13 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
&& lb.matches(engine, chunk); && lb.matches(engine, chunk);
if (!regionKeys.isEmpty()) { if (!regionKeys.isEmpty()) {
locator.find(player); locator.find(player, Math.abs(distance), random);
} else { } else {
player.sendMessage(C.RED + biome.getName() + " is not in any defined regions!"); player.sendMessage(C.RED + biome.getName() + " is not in any defined regions!");
} }
} }
default void gotoJigsaw(IrisJigsawStructure s, Player player) { default void gotoJigsaw(IrisJigsawStructure s, Player player, int distance, boolean random) {
if (s.getLoadKey().equals(getDimension().getStronghold())) { if (s.getLoadKey().equals(getDimension().getStronghold())) {
KList<Position2> p = getDimension().getStrongholds(getSeedManager().getSpawn()); KList<Position2> p = getDimension().getStrongholds(getSeedManager().getSpawn());
@ -826,7 +826,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
if (getDimension().getJigsawStructures().stream() if (getDimension().getJigsawStructures().stream()
.map(IrisJigsawStructurePlacement::getStructure) .map(IrisJigsawStructurePlacement::getStructure)
.collect(Collectors.toSet()).contains(s.getLoadKey())) { .collect(Collectors.toSet()).contains(s.getLoadKey())) {
Locator.jigsawStructure(s.getLoadKey()).find(player); Locator.jigsawStructure(s.getLoadKey()).find(player, distance, random);
} else { } else {
Set<String> biomeKeys = getDimension().getAllBiomes(this).stream() Set<String> biomeKeys = getDimension().getAllBiomes(this).stream()
.filter((i) -> i.getJigsawStructures() .filter((i) -> i.getJigsawStructures()
@ -853,7 +853,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
}; };
if (!regionKeys.isEmpty()) { if (!regionKeys.isEmpty()) {
locator.find(player); locator.find(player, distance, random);
} else { } else {
player.sendMessage(C.RED + s.getLoadKey() + " is not in any defined regions, biomes or dimensions!"); player.sendMessage(C.RED + s.getLoadKey() + " is not in any defined regions, biomes or dimensions!");
} }
@ -861,7 +861,7 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
} }
default void gotoObject(String s, Player player) { default void gotoObject(String s, Player player, int distance, boolean random) {
Set<String> biomeKeys = getDimension().getAllBiomes(this).stream() Set<String> biomeKeys = getDimension().getAllBiomes(this).stream()
.filter((i) -> i.getObjects().stream().anyMatch((f) -> f.getPlace().contains(s))) .filter((i) -> i.getObjects().stream().anyMatch((f) -> f.getPlace().contains(s)))
.map(IrisRegistrant::getLoadKey) .map(IrisRegistrant::getLoadKey)
@ -884,19 +884,19 @@ public interface Engine extends DataProvider, Fallible, LootProvider, BlockUpdat
}; };
if (!regionKeys.isEmpty()) { if (!regionKeys.isEmpty()) {
locator.find(player); locator.find(player, distance, random);
} else { } else {
player.sendMessage(C.RED + s + " is not in any defined regions or biomes!"); player.sendMessage(C.RED + s + " is not in any defined regions or biomes!");
} }
} }
default void gotoRegion(IrisRegion r, Player player) { default void gotoRegion(IrisRegion r, Player player, int distance, boolean random) {
if (!getDimension().getAllRegions(this).contains(r)) { if (!getDimension().getAllRegions(this).contains(r)) {
player.sendMessage(C.RED + r.getName() + " is not defined in the dimension!"); player.sendMessage(C.RED + r.getName() + " is not defined in the dimension!");
return; return;
} }
Locator.region(r.getLoadKey()).find(player); Locator.region(r.getLoadKey()).find(player, distance, random);
} }
default void cleanupMantleChunk(int x, int z) { default void cleanupMantleChunk(int x, int z) {

View File

@ -18,6 +18,7 @@
package com.volmit.iris.engine.framework; package com.volmit.iris.engine.framework;
import com.volmit.iris.Iris;
import com.volmit.iris.core.IrisSettings; import com.volmit.iris.core.IrisSettings;
import com.volmit.iris.core.tools.IrisToolbelt; import com.volmit.iris.core.tools.IrisToolbelt;
import com.volmit.iris.engine.object.IrisBiome; import com.volmit.iris.engine.object.IrisBiome;
@ -57,16 +58,17 @@ public interface Locator<T> {
} }
} }
default void find(Player player) { default void find(Player player, int distance, boolean random) {
find(player, 30_000); find(player, 30_000, distance, random);
} }
default void find(Player player, long timeout) { default void find(Player player, long timeout, int distance, boolean random) {
AtomicLong checks = new AtomicLong(); AtomicLong checks = new AtomicLong();
long ms = M.ms(); long ms = M.ms();
new SingleJob("Searching", () -> { new SingleJob("Searching", () -> {
try { try {
Position2 at = find(IrisToolbelt.access(player.getWorld()).getEngine(), new Position2(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4), timeout, checks::set).get(); Position2 from = new Position2(player.getLocation().getBlockX() >> 4, player.getLocation().getBlockZ() >> 4);
Position2 at = find(IrisToolbelt.access(player.getWorld()).getEngine(), from, timeout, checks::set, distance, random).get();
if (at != null) { if (at != null) {
J.s(() -> player.teleport(new Location(player.getWorld(), (at.getX() << 4) + 8, J.s(() -> player.teleport(new Location(player.getWorld(), (at.getX() << 4) + 8,
@ -96,26 +98,31 @@ public interface Locator<T> {
}.execute(new VolmitSender(player)); }.execute(new VolmitSender(player));
} }
default Future<Position2> find(Engine engine, Position2 pos, long timeout, Consumer<Integer> checks) throws WrongEngineBroException { default Future<Position2> find(Engine engine, Position2 location, long timeout, Consumer<Integer> checks, int distance, boolean random) throws WrongEngineBroException {
if (engine.isClosed()) { if (engine.isClosed()) {
throw new WrongEngineBroException(); throw new WrongEngineBroException();
} }
cancelSearch(); cancelSearch();
int fdistance = distance >> 4;
Position2 pos = random ? new Position2(M.irand(-29_000_000, 29_000_000) >> 4, M.irand(-29_000_000, 29_000_000) >> 4) : new Position2(location.getX(), location.getZ());
if (random) {
Iris.info("Randomly finding location from: " + pos);
}
return MultiBurst.burst.completeValue(() -> { return MultiBurst.burst.completeValue(() -> {
int tc = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()) * 17; int tc = IrisSettings.getThreadCount(IrisSettings.get().getConcurrency().getParallelism()) * 17;
MultiBurst burst = MultiBurst.burst; MultiBurst burst = MultiBurst.burst;
AtomicBoolean found = new AtomicBoolean(false); AtomicBoolean found = new AtomicBoolean(false);
Position2 cursor = pos;
AtomicInteger searched = new AtomicInteger(); AtomicInteger searched = new AtomicInteger();
AtomicBoolean stop = new AtomicBoolean(false); AtomicBoolean stop = new AtomicBoolean(false);
AtomicReference<Position2> foundPos = new AtomicReference<>(); AtomicReference<Position2> foundPos = new AtomicReference<>();
PrecisionStopwatch px = PrecisionStopwatch.start(); PrecisionStopwatch px = PrecisionStopwatch.start();
LocatorCanceller.cancel = () -> stop.set(true); LocatorCanceller.cancel = () -> stop.set(true);
AtomicReference<Position2> next = new AtomicReference<>(cursor); AtomicReference<Position2> next = new AtomicReference<>(pos);
Spiraler s = new Spiraler(100000, 100000, (x, z) -> next.set(new Position2(x, z))); Spiraler s = new Spiraler(50000, 50000, (x, z) -> next.set(new Position2(pos.getX() + (M.r(0.5) ? -1 : 1) * (x + fdistance), pos.getZ() + (M.r(0.5) ? -1 : 1) * (z + fdistance))));
s.setOffset(cursor.getX(), cursor.getZ());
s.setOffset(pos.getX(), pos.getZ());
s.next(); s.next();
while (!found.get() && !stop.get() && px.getMilliseconds() < timeout) { while (!found.get() && !stop.get() && px.getMilliseconds() < timeout) {
BurstExecutor e = burst.burst(tc); BurstExecutor e = burst.burst(tc);

View File

@ -80,7 +80,7 @@ public class Position2 {
} }
public double distance(Position2 center) { public double distance(Position2 center) {
return Math.pow(center.getX() - x, 2) + Math.pow(center.getZ() - z, 2); return Math.sqrt(Math.pow(center.getX() - x, 2) + Math.pow(center.getZ() - z, 2));
} }
public Position2 add(int x, int z) { public Position2 add(int x, int z) {