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

Add miscellaneous argument type 'World' #358

Closed
lokka30 opened this issue Oct 31, 2022 · 7 comments
Closed

Add miscellaneous argument type 'World' #358

lokka30 opened this issue Oct 31, 2022 · 7 comments
Labels
enhancement New feature or request implemented for next release This has been implemented in the current dev build for the next public release

Comments

@lokka30
Copy link

lokka30 commented Oct 31, 2022

Description

Allows us to select world names, such as:

  • /kill @e[type=creeper] my_cool_world

..where my_cool_world is a world loaded on the server.

Can also be used as a list:

  • /kill @e[type=creeper] my_cool_world world world_nether world_the_end resource_world

Expected code

No response

Extra details

No response

@lokka30 lokka30 added the enhancement New feature or request label Oct 31, 2022
@willkroboth
Copy link
Collaborator

Funnily enough, the World argument is used as an example in the documentation for making custom arguments:
https://commandapi.jorel.dev/8.5.1/customarguments.html?highlight=World,argumen#example---world-argument

// Function that returns our custom argument
public Argument<World> worldArgument(String nodeName) {
    
    // Construct our CustomArgument that takes in a String input and returns a World object
    return new CustomArgument<World, String>(new StringArgument(nodeName), info -> {
        // Parse the world from our input
        World world = Bukkit.getWorld(info.input());
    
        if(world == null) {
            throw new CustomArgumentException(new MessageBuilder("Unknown world: ").appendArgInput());
        } else {
            return world;
        }
    }).replaceSuggestions(ArgumentSuggestions.strings(info -> 
        // List of world names on the server
        Bukkit.getWorlds().stream().map(World::getName).toArray(String[]::new))
    );
}

In the meantime, that should work for your use, but I agree, an official WorldArgument might be a nice addition to the CommandAPI.

On the point of having a list of worlds, if you want to do that right now, you could create a ListArgument (see https://commandapi.jorel.dev/8.5.1/listarguments.html for how to do that).

@lokka30
Copy link
Author

lokka30 commented Oct 31, 2022

Brilliant! Thanks so much @willkroboth. This ought to be the best documented library I have come across.

In case context is useful for the addition of this feature, I am writing a 'Kill' command for LevelledMobs, /lm kill <entity target> <world list>. Unfortunately Minecraft does not have a world name attribute which can be used in the selector for the entities, e.g., @e[world=world_the_end], only dimensions (minecraft:nether).

@lokka30
Copy link
Author

lokka30 commented Nov 1, 2022

Unfortunately the current workaround doesn't seem to work on load: STARTUP plugins, nor on worlds which have been loaded after the plugin's commands were registered.
I have tried a workaround where I have replaced the suggestions with a list of worlds which are queried async, of course this hasn't resolved the issue since the list of allowed list values have not been modified.
For now, I will make it use a string list argument and parse worlds manually. 🙂

@JorelAli
Copy link
Owner

As mentioned in #365, the CommandAPI will only be accepting "custom argument implementations" that satisfy the following points:

  • The custom argument is an implementation of a Vanilla Minecraft argument type that is specified in Argument types.
  • The custom argument implementation heavily requires the use of Brigadier or NMS.

The World Argument requested in this issue can already be implemented without the use of Brigadier/NMS by using the CustomArgument class, using a base argument of a StringArgument for a single world, or a ListArgument for multiple worlds. In 8.6.0, this will be improved with the new TextArgument backed ListArgument (see #351) which would let you use such an argument anywhere in the query (instead of just at the end)


Making use of the synchronous argument suggestions should work regardless of load: STARTUP plugins and regardless of whether a world has been loaded after the plugin's commands have been registered (note the info -> in the example below):

.replaceSuggestions(ArgumentSuggestions.strings(info -> 
    // List of world names on the server
    Bukkit.getWorlds().stream().map(World::getName).toArray(String[]::new))
);

Using asynchronous world suggestions is not recommended as asynchronous queries should not be accessing the Bukkit API.

@JorelAli JorelAli closed this as not planned Won't fix, can't repro, duplicate, stale Nov 23, 2022
@lokka30
Copy link
Author

lokka30 commented Nov 23, 2022

Thanks, no worries :)

@JorelAli JorelAli reopened this Nov 24, 2022
@JorelAli
Copy link
Owner

After a quick chat with a member from the CommandAPI Discord server, I've discovered that the CommandAPI's implementation of Minecraft's DimensionArgument is terrible and doesn't do what it is supposed to!

Scheduling the implementation of a DimensionArgument for CommandAPI 8.6.0 which will do pretty much exactly what you would expect - it returns a Bukkit World object.

JorelAli added a commit that referenced this issue Nov 24, 2022
Extra thanks to @booky10 for their help with cracking this one!
@JorelAli JorelAli added the implemented for next release This has been implemented in the current dev build for the next public release label Nov 24, 2022
@JorelAli
Copy link
Owner

JorelAli commented Dec 4, 2022

Implemented in release 8.6.0.

@JorelAli JorelAli closed this as completed Dec 4, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request implemented for next release This has been implemented in the current dev build for the next public release
Projects
None yet
Development

No branches or pull requests

3 participants