diff --git a/common/src/main/java/com/dfsek/terra/api/registry/CheckedRegistry.java b/common/src/main/java/com/dfsek/terra/api/registry/CheckedRegistry.java index d7900cee7..9934c767b 100644 --- a/common/src/main/java/com/dfsek/terra/api/registry/CheckedRegistry.java +++ b/common/src/main/java/com/dfsek/terra/api/registry/CheckedRegistry.java @@ -72,6 +72,11 @@ public class CheckedRegistry implements Registry { return registry.entries(); } + @Override + public Set keys() { + return registry.keys(); + } + @Override public T load(Type t, Object c, ConfigLoader loader) throws LoadException { return registry.load(t, c, loader); diff --git a/common/src/main/java/com/dfsek/terra/api/registry/LockedRegistry.java b/common/src/main/java/com/dfsek/terra/api/registry/LockedRegistry.java index 6c9525e98..227656c4d 100644 --- a/common/src/main/java/com/dfsek/terra/api/registry/LockedRegistry.java +++ b/common/src/main/java/com/dfsek/terra/api/registry/LockedRegistry.java @@ -2,7 +2,6 @@ package com.dfsek.terra.api.registry; import com.dfsek.tectonic.exception.LoadException; import com.dfsek.tectonic.loading.ConfigLoader; -import com.dfsek.terra.registry.OpenRegistry; import java.lang.reflect.Type; import java.util.Set; @@ -46,6 +45,11 @@ public class LockedRegistry implements Registry { return registry.entries(); } + @Override + public Set keys() { + return registry.keys(); + } + @Override public T load(Type t, Object c, ConfigLoader loader) throws LoadException { return registry.load(t, c, loader); diff --git a/common/src/main/java/com/dfsek/terra/api/registry/Registry.java b/common/src/main/java/com/dfsek/terra/api/registry/Registry.java index 41f10379b..773d784ca 100644 --- a/common/src/main/java/com/dfsek/terra/api/registry/Registry.java +++ b/common/src/main/java/com/dfsek/terra/api/registry/Registry.java @@ -43,4 +43,11 @@ public interface Registry extends TypeLoader { * @return Set containing all entries. */ Set entries(); + + /** + * Get all the keys in this registry. + * + * @return Keys in registry + */ + Set keys(); } diff --git a/common/src/main/java/com/dfsek/terra/commands/structure/StructureCommand.java b/common/src/main/java/com/dfsek/terra/commands/structure/StructureCommand.java index c12f021d2..ad095ac70 100644 --- a/common/src/main/java/com/dfsek/terra/commands/structure/StructureCommand.java +++ b/common/src/main/java/com/dfsek/terra/commands/structure/StructureCommand.java @@ -22,6 +22,11 @@ import com.dfsek.terra.config.lang.LangUtil; clazz = SpawnCommand.class, value = "spawn", aliases = "s" + ), + @Subcommand( + clazz = StructureLocateCommand.class, + value = "locate", + aliases = "l" ) }, usage = "/te structure" diff --git a/common/src/main/java/com/dfsek/terra/commands/structure/StructureLocateCommand.java b/common/src/main/java/com/dfsek/terra/commands/structure/StructureLocateCommand.java new file mode 100644 index 000000000..0e04c3ec4 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/commands/structure/StructureLocateCommand.java @@ -0,0 +1,75 @@ +package com.dfsek.terra.commands.structure; + +import com.dfsek.terra.api.TerraPlugin; +import com.dfsek.terra.api.command.CommandTemplate; +import com.dfsek.terra.api.command.annotation.Argument; +import com.dfsek.terra.api.command.annotation.Command; +import com.dfsek.terra.api.command.annotation.Switch; +import com.dfsek.terra.api.command.annotation.inject.ArgumentTarget; +import com.dfsek.terra.api.command.annotation.inject.SwitchTarget; +import com.dfsek.terra.api.command.annotation.type.PlayerCommand; +import com.dfsek.terra.api.command.annotation.type.WorldCommand; +import com.dfsek.terra.api.command.arg.IntegerArgumentParser; +import com.dfsek.terra.api.injection.annotations.Inject; +import com.dfsek.terra.api.math.vector.Location; +import com.dfsek.terra.api.math.vector.Vector3; +import com.dfsek.terra.api.platform.CommandSender; +import com.dfsek.terra.api.platform.entity.Player; +import com.dfsek.terra.api.world.locate.AsyncStructureFinder; +import com.dfsek.terra.commands.structure.argument.StructureArgumentParser; +import com.dfsek.terra.commands.structure.completer.StructureCompleter; +import com.dfsek.terra.config.lang.LangUtil; +import com.dfsek.terra.world.population.items.TerraStructure; + +import java.util.Locale; + +@PlayerCommand +@WorldCommand +@Command( + arguments = { + @Argument( + value = "structure", + tabCompleter = StructureCompleter.class, + argumentParser = StructureArgumentParser.class + ), + @Argument( + value = "radius", + required = false, + defaultValue = "100", + argumentParser = IntegerArgumentParser.class + ) + }, + switches = { + @Switch( + value = "teleport", + aliases = {"t", "tp"} + ) + } +) +public class StructureLocateCommand implements CommandTemplate { + @Inject + private TerraPlugin main; + + @ArgumentTarget("structure") + private TerraStructure structure; + + @ArgumentTarget("radius") + private Integer radius; + + @SwitchTarget("teleport") + private boolean teleport; + + @Override + public void execute(CommandSender sender) { + Player player = (Player) sender; + + new Thread(new AsyncStructureFinder(main.getWorld(player.getWorld()).getBiomeProvider(), structure, player.getLocation().clone().multiply((1D / main.getTerraConfig().getBiomeSearchResolution())), 0, radius, location -> { + if(location != null) { + sender.sendMessage(String.format("The nearest %s is at [%d, ~, %d] (%.1f blocks away)", structure.getTemplate().getID().toLowerCase(Locale.ROOT), location.getBlockX(), location.getBlockZ(), location.add(new Vector3(0, player.getLocation().getY(), 0)).distance(player.getLocation().toVector()))); + if(teleport) { + main.runPossiblyUnsafeTask(() -> player.setLocation(new Location(player.getWorld(), location.getX(), player.getLocation().getY(), location.getZ()))); + } + } else LangUtil.send("command.biome.unable-to-locate", sender); + }, main), "Biome Location Thread").start(); + } +} diff --git a/common/src/main/java/com/dfsek/terra/commands/structure/argument/StructureArgumentParser.java b/common/src/main/java/com/dfsek/terra/commands/structure/argument/StructureArgumentParser.java new file mode 100644 index 000000000..dce50ac65 --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/commands/structure/argument/StructureArgumentParser.java @@ -0,0 +1,18 @@ +package com.dfsek.terra.commands.structure.argument; + +import com.dfsek.terra.api.TerraPlugin; +import com.dfsek.terra.api.command.arg.ArgumentParser; +import com.dfsek.terra.api.injection.annotations.Inject; +import com.dfsek.terra.api.platform.CommandSender; +import com.dfsek.terra.api.platform.entity.Player; +import com.dfsek.terra.world.population.items.TerraStructure; + +public class StructureArgumentParser implements ArgumentParser { + @Inject + private TerraPlugin main; + + @Override + public TerraStructure parse(CommandSender sender, String arg) { + return main.getWorld(((Player) sender).getWorld()).getConfig().getStructureRegistry().get(arg); + } +} diff --git a/common/src/main/java/com/dfsek/terra/commands/structure/completer/StructureCompleter.java b/common/src/main/java/com/dfsek/terra/commands/structure/completer/StructureCompleter.java new file mode 100644 index 000000000..a2b5b1dad --- /dev/null +++ b/common/src/main/java/com/dfsek/terra/commands/structure/completer/StructureCompleter.java @@ -0,0 +1,21 @@ +package com.dfsek.terra.commands.structure.completer; + +import com.dfsek.terra.api.TerraPlugin; +import com.dfsek.terra.api.command.tab.TabCompleter; +import com.dfsek.terra.api.injection.annotations.Inject; +import com.dfsek.terra.api.platform.CommandSender; +import com.dfsek.terra.api.platform.entity.Player; + +import java.util.ArrayList; +import java.util.List; + +public class StructureCompleter implements TabCompleter { + @Inject + private TerraPlugin main; + + @Override + public List complete(CommandSender sender) { + Player player = (Player) sender; + return new ArrayList<>(main.getWorld(player.getWorld()).getConfig().getStructureRegistry().keys()); + } +} diff --git a/common/src/main/java/com/dfsek/terra/registry/OpenRegistry.java b/common/src/main/java/com/dfsek/terra/registry/OpenRegistry.java index 5838a158c..1cd0b81f2 100644 --- a/common/src/main/java/com/dfsek/terra/registry/OpenRegistry.java +++ b/common/src/main/java/com/dfsek/terra/registry/OpenRegistry.java @@ -78,6 +78,11 @@ public class OpenRegistry implements Registry { return new HashSet<>(objects.values()); } + @Override + public Set keys() { + return objects.keySet(); + } + /** * Clears all entries from the registry. */