aikar / commands

Java Command Dispatch Framework - (Bukkit, Spigot, Paper, Sponge, Bungee, JDA, Velocity supported, generically usable anywhere)
https://acfspigot.emc.gs
MIT License
566 stars 147 forks source link

[Question] Different argument types based on previous argument #242

Open Esophose opened 5 years ago

Esophose commented 5 years ago

I've recently started looking into this command framework for Spigot plugins and it's very nice. I've run into a bit of a design issue and am unsure if there's any way to get it to work using this framework.

Currently, I have the following commands: /rs give block <player> <blockMaterial> <amount> /rs give spawner <player> <entityType> <amount> /rs give entity <player> <entityType> <amount>

This works as I would expect it to using the following code:

@CommandAlias("rs|rosestacker|stacker")
@Description("The base RoseStacker command")
public class RoseCommand extends BaseCommand {

    @Subcommand("give")
    @Description("Gives stacked items")
    @CommandPermission("rosestacker.give")
    public class GiveCommand extends BaseCommand {

        @Subcommand("block")
        @CommandCompletion("* @stackableBlockMaterial @amount")
        public void onBlock(OnlinePlayer target, Material material, int amount) {
            // TODO
        }

        @Subcommand("spawner")
        @CommandCompletion("* @spawnableEntityType @amount")
        public void onSpawner(OnlinePlayer target, EntityType entityType, int amount) {
            // TODO
        }

        @Subcommand("entity")
        @CommandCompletion("* @spawnableEntityType @amount")
        public void onEntity(OnlinePlayer target, EntityType entityType, int amount) {
            // TODO
        }

    }

}

However, I would like to move the player argument to before the next subcommand name like so: /rs give <player> block <blockMaterial> <amount> /rs give <player> spawner <entityType> <amount> /rs give <player> entity <entityType> <amount>

I haven't been able to think of a way to do this using this command framework. Is such a thing even possible? If it is, could somebody provide some insight on how I could go about doing it? Thanks in advance!

Machine-Maker commented 4 years ago

No there is no direct way to have later argument types depend on earlier ones. You can kinda-sorta work around this if you do 3 subcommands and put block, spawner, and entity into an enum and make that an argument. Then, in a custom completion, you could look at the previous arguments and filter out what wasn't valid. Then in a custom context, you could verify that was was entered for the type matched block, spawner, or entity.