How to Add Vault Rewards to Minecraft Advancements using Java

How to Add Vault Rewards to Minecraft Advancements using Java

Let me explain how I added currency rewards, using Vault, for every Minecraft advancement in a Spigot server with a custom Java plugin.

Initial Setup and Enviroment

My server runs on the latest version of Paper which is an extension of Spigot. This method will work on both variations. I also installed the latest version of Vault and a bunch of other plugins that don’t influence what we’re doing here.

For the full Minecraft server setup, check out this article.

I have already programmed a custom plugin for my server. I will not go through those steps right now. If you want to learn the basics, there’s this official Spigot plugin documentation.

Basically all you need is this:

  • a Spigot server (Paper works as well)
  • the latest version of Vault
  • an economy plugin that hooks into vault (there are plenty on the Spigot website, I coded mine from scratch)
  • a basic custom plugin (this is where we write the Java code)

Let’s Code!

I know myself and I don’t read all the mumbo jumbo in programming articles. So here’s the whole script:

// put these at the top of your class
import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerAdvancementDoneEvent;

// other code here

@EventHandler
public void onPlayerAdvancementDoneEvent(PlayerAdvancementDoneEvent event) {
    Player p = event.getPlayer();
    if (!event.getAdvancement().getKey().toString().contains("recipes/")) {
        plugin.provider.depositPlayer(p, 20);
        p.sendTitle("", "§6+20 §bsouls§f", 10, 70, 10);
    }
}

Put this in your custom plugin. I added it in the listener class. Check out my GitHub code for reference.

Now let me explain it step by step.

import org.bukkit.entity.Player;
import org.bukkit.event.player.PlayerAdvancementDoneEvent;

Import every function you use. Otherwise your class will not know how to read your code. These 2 lines load up methods that we use below.

In most cases your IDE (Eclipse in my case) will autocomplete these lines.

@EventHandler
public void onPlayerAdvancementDoneEvent(PlayerAdvancementDoneEvent event)

With this line we create a function that is executed every time an event is triggered. In our case that’s PlayerAdvancementDoneEvent. For every other event check out this list.

Player p = event.getPlayer();

This is pretty straight forward. I create a new variable “p” in which I save the player that triggered my event.

if (!event.getAdvancement().getKey().toString().contains("recipes/"))

Here’s the tricky part. Minecraft consideres discovering a new recipe as an advancement. I didn’t want to give rewards for every little element. If you want to do that, remove the if.

Luckily, the advancement name has some distinguishable elements that help me filter out the recipes. They added “recipes/” or “story/” at the beginning of the name.

  • event.getAdvancement() – gets the advancement object
  • .getKey().toString() – gets the name and converts it to String
  • .contains(“recipes/”) – checks if the string contains “recipes/”
  • and the “!” in front negates my statement; returns true only when the code does NOT contain recipes
plugin.provider.depositPlayer(p, 20);

This line rewards the player we saved earlier in our variable “p” with 20 currency.

If you use external plugins from the Spigot website, this line may vary. Make sure your economy plugin accepts this kind of API calls.

In my case, plugin.provider is the Vault economy interface and the depositPlayer method adds to the user balance. For reference this is how I created the variable in the plugin class:

public static Economy provider;
public PluginManager pluginManager;

// ... other code here

public void onLoad() {
    pluginManager = getServer().getPluginManager();
 
    hookVault();
}

// ... other code here

public void hookVault() {
    if (pluginManager.getPlugin("Vault") == null) {
        System.out.println("[amongdemons.com] Vault isn't installed - this somehow got past the compatibility check - hook task aborted.");
    } else {
        provider = new myeconomy();
        Bukkit.getServicesManager().register(Economy.class, provider, this, ServicePriority.Highest);
        System.out.println("[amongdemons.com] Hooked to Vault successfuly.");
    }
}

You can find everything else on my GitHub.

p.sendTitle("", "§6+20 §bsouls§f", 10, 70, 10);

This just sends a notification the the player p. You can put anything here. Send him a message in chat or broadcast to all players. Does not matter. It’s up to you.

Final Thoughts

I made this quick guide to help other server owners. I couldn’t easily find this information on Google. That’s why I wrote it down.

The most important part is the if statement. I feel like Spigot’s documentation lacks in differentiating advancements from recipes.

If you have any questions or feedback please let me know in the comments section down below.

Thanks for checking out my mini tutorial.