### Create and Register MultiTasks and TaskAdvancements
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
Example of setting up an advancement tab, a root advancement, and a MultiTasks advancement with associated TaskAdvancements for Dirt and Stone breaking. This demonstrates the core structure for managing complex advancement chains.
```java
private AdvancementTab advancementTab;
private Root root;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
//if you want to the enable SqlLite
main.enableSQLite(new File(getDataFolder(), "sqlLiteDbName"));
advancementTab = UltimateAdvancementAPI.getInstance(this).createAdvancementTab("a_tab");
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS_BLOCK, "Root §c", AdvancementFrameType.TASK, false, false, 0, 0, "Your adventure start here");
root = new Root(advancementTab, "root", rootDisplay, "textures/block/stone.png");
AdvancementDisplay ad = new AdvancementDisplay(Material.ACACIA_LOG, "Dig!", AdvancementFrameType.TASK, true, true, 1, 0, "-Break 2 of Dirt", "-Break 4 of stone");
MultiTasksExample multiTasksExample = new MultiTasksExample("eg", ad, root, 6);
DirtTask dirtTask = new DirtTask("dirt", multiTasksExample, 2);
StoneTask stoneTask = new StoneTask("stone", multiTasksExample, 4);
multiTasksExample.registerTasks(dirtTask, stoneTask);
advancementTab.registerAdvancements(root, multiTasksExample);
}
@EventHandler
public void onJoin(PlayerLoadingCompletedEvent e) {
Player p = e.getPlayer();
advancementTab.showTab(p);
root.grant(p);
}
```
--------------------------------
### Root Advancement with Rewards and Notifications
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Examples
This example demonstrates creating a root advancement that provides rewards and custom announcement messages upon completion. It also includes event registration for block breaking.
```java
private AdvancementTab advancementTab;
private RootAdv root;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
//if you want to the enable SqlLite
main.enableSQLite(new File(getDataFolder(), "sqlLiteDbName"));
advancementTab = UltimateAdvancementAPI.getInstance(this).createAdvancementTab("a_tab");
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS_BLOCK, "Root §c", AdvancementFrameType.TASK, true, true, 0, 0, "Break a grass block", "you will recived a gift!");
root = new RootAdv(advancementTab, "root", rootDisplay, "textures/block/stone.png");
advancementTab.registerAdvancements(root);
}
@EventHandler
public void onJoin(PlayerLoadingCompletedEvent e) {
Player p = e.getPlayer();
advancementTab.showTab(p);
}
```
```java
public class RootAdv extends RootAdvancement {
public RootAdv(@NotNull AdvancementTab advancementTab, @NotNull String key, @NotNull AdvancementDisplay display, @NotNull String backgroundTexture) {
super(advancementTab, key, display, backgroundTexture);
registerEvent(BlockBreakEvent.class, e -> {
if (isVisible(e.getPlayer()) && e.getBlock().getType() == display.getIcon().getType()) {
incrementTeamCriteria(e.getPlayer());
}
});
}
@Override
public void giveReward(@NotNull Player player) {
player.sendMessage("You recived a diamond shovel");
player.getInventory().addItem(new ItemStack(Material.DIAMOND_SHOVEL));
}
@Override
public BaseComponent[] getAnnounceMessage(@NotNull Player player) {
ChatColor color = display.getFrame().getColor();
return new ComponentBuilder(player.getName() + " has completed the " + display.getFrame().getChatText() + ' ').color(ChatColor.WHITE).append(new ComponentBuilder("[").color(color).event(new HoverEvent(Action.SHOW_TEXT, display.getChatDescription())).append(display.getChatTitle()).append(new ComponentBuilder("]").reset().color(color).create()).create()).create()).create();
}
}
```
--------------------------------
### Example: Create, Initialize, and Update AdvancementTab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Demonstrates the full lifecycle of an AdvancementTab: creation, defining advancements, registering them to initialize the tab, and updating a player's view. Attempting to re-register advancements after initialization will result in an IllegalStateException.
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(plugin);
// Create a tab with namespace "mynamespace"
AdvancementTab tab = api.createAdvancementTab("mynamespace");
// Create two advancement to be registered in the tab
RootAdvancement root = new RootAdvancement(tab, "root", new AdvancementDisplay(/*display settings*/), "backgroundTexture");
BaseAdvancement adv = new BaseAdvancement("an-adv", new AdvancementDisplay(/*display settings*/), root);
// Initialise the tab with two advancements
tab.registerAdvancements(root, adv);
// Now methods can be called
Player aPlayer = Bukkit.getPlayer("fren_gor");
tab.updateEveryAdvancement(aPlayer); // Send the tab and its advancements to the player aPlayer
// This throws an IllegalStateException since the tab has already been initialised
tab.registerAdvancements(root, adv);
```
--------------------------------
### Get UltimateAdvancementAPI Instance
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Start-Guide
Obtain an instance of the API using the static getInstance method, passing your plugin instance. The API must be enabled on the server, otherwise an exception will be thrown.
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(yourPluginInstance);
```
--------------------------------
### Create and Display Custom Advancement Tab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Start-Guide
Example of creating a custom advancement tab with a root advancement and displaying it to players upon joining. Ensure 'UltimateAdvancementAPI' is listed in your plugin.yml dependencies.
```java
public class MainClass extends JavaPlugin implements Listener {
private AdvancementTab advancementTab;
private RootAdvancement root;
private UltimateAdvancementAPI api;
@Override
public void onEnable() {
api = UltimateAdvancementAPI.getInstance(this);
advancementTab = api.createAdvancementTab("your_tab_name");
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS_BLOCK, "Example root", AdvancementFrameType.TASK, true, true, 0, 0, "description");
root = new RootAdvancement(advancementTab, "root", rootDisplay, "textures/block/stone.png");
advancementTab.registerAdvancements(root);
Bukkit.getPluginManager().registerEvents(this, this);
}
@EventHandler
public void onJoin(PlayerLoadingCompletedEvent e) {
// Called after a player has successfully been loaded by the API
Player p = e.getPlayer();
// Here you can show tabs to players
advancementTab.showTab(p);
}
}
```
--------------------------------
### Create and Register Multiparent Advancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
This snippet demonstrates the setup of an AdvancementTab, a root advancement, two base advancements, and a multiparent advancement. It then registers all advancements and shows how to grant the root advancement and display the tab to a player upon loading.
```java
private AdvancementTab advancementTab;
private Root root;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
//if you want to the enable SqlLite
main.enableSQLite(new File(getDataFolder(), "sqlLiteDbName"));
advancementTab = UltimateAdvancementAPI.getInstance(this).createAdvancementTab("atab");
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS_BLOCK, "Root §c", AdvancementFrameType.TASK, false, false, 0, 1, "Your adventure start here");
root = new Root(advancementTab, "root", rootDisplay, "textures/block/stone.png");
AdvancementDisplay ad = new AdvancementDisplay(Material.ACACIA_LOG, "MultiParent!", AdvancementFrameType.TASK, true, true, 2, 1);
AdvancementDisplay base = new AdvancementDisplay(Material.LAVA_BUCKET, "Advancement", AdvancementFrameType.TASK, true, true, 1, 0);
AdvancementDisplay base2 = new AdvancementDisplay(Material.WATER_BUCKET, "Advancement", AdvancementFrameType.TASK, true, true, 1, 2);
Adv adv1 = new Adv( "adv1", base, root);
Adv adv2 = new Adv("adv2", base2, root);
MultiparentExample multiParentsAdvancement = new MultiparentExample( "multipare", ad, adv1, adv2);
advancementTab.registerAdvancements(root, adv1 , adv2,multiParentsAdvancement);
}
@EventHandler
public void onJoin(PlayerLoadingCompletedEvent e) {
Player p = e.getPlayer();
advancementTab.showTab(p);
root.grant(p);
}
```
--------------------------------
### Pickaxe Advancement Example
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Examples
Advancement for crafting a stone pickaxe. It increments criteria when a player crafts a stone pickaxe while the advancement is visible and not yet granted. Implements ParentGrantedVisibility.
```java
public class Pickaxe extends BaseAdvancement implements ParentGrantedVisibility {
public Pickaxe( @NotNull String key, @NotNull AdvancementDisplay display, @NotNull Advancement parent) {
super(key, display, parent);
registerEvent(CraftItemEvent.class, e -> {
Player p = (Player) e.getWhoClicked();
if (isVisible(p) && !isGranted(p) && e.getRecipe().getResult().getType() == Material.STONE_PICKAXE) {
incrementTeamCriteria(p);
}
});
}
@Override
public void giveReward(@NotNull Player player) {
//things
}
}
```
--------------------------------
### Initialize and Manage UltimateAdvancementAPI Lifecycle
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Shadeable-Version
Implement onLoad, onEnable, and onDisable methods to manage the API's lifecycle. Use onEnable to initialize the database connection, for example, with SQLite, and retrieve the API instance. Ensure disable() is called in onDisable.
```java
public class MainClass extends JavaPlugin {
private AdvancementMain main;
private UltimateAdvancementAPI api;
@Override
public void onLoad() {
main = new AdvancementMain(this);
main.load();
// Rest of your code
}
@Override
public void onEnable() {
// Enable UltimateAdvancementAPI using a file based database (SQLite)
// You can use other databases classes — like MySQL, InMemory or a custom one — instead of the next line
// DBs with built-in support can be found in the com.fren_gor.ultimateAdvancementAPI.database.impl package
main.enable(() -> new SQLite(main, new File(getDataFolder(), "database.db")));
// After the initialisation of AdvancementMain you can get an instance of the UltimateAdvancementAPI class
api = UltimateAdvancementAPI.getInstance(this);
// Rest of your code
}
@Override
public void onDisable() {
main.disable();
// Rest of your code
}
}
```
--------------------------------
### Stone Advancement Example
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Examples
Advancement for breaking stone blocks. It increments criteria when a player breaks a block matching the advancement's icon type. Requires a maximum criteria count.
```java
public class Stone extends BaseAdvancement {
public Stone( @NotNull String key, @NotNull AdvancementDisplay display, @NotNull Advancement parent, @Range(from = 1L, to = 2147483647L) int maxCriteria) {
super( key, display, parent, maxCriteria);
registerEvent(BlockBreakEvent.class, e -> {
if (isVisible(e.getPlayer()) && e.getBlock().getType() == display.getIcon().getType()) {
incrementTeamCriteria(e.getPlayer());
}
});
}
@Override
public void giveReward(@NotNull Player player) {
}
}
```
--------------------------------
### Getting a Registered AdvancementTab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Retrieves a previously registered AdvancementTab using its unique namespace. This allows access to existing tabs for further management or updates.
```APIDOC
## Getting a Registered AdvancementTab
### Description
Retrieves an AdvancementTab instance by its namespace. This method is useful for accessing tabs that have already been created and registered.
### Method Signature
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(plugin);
AdvancementTab tab = api.getAdvancementTab("namespace");
```
### Parameters
* **namespace** (String) - Required - The unique namespace of the advancement tab to retrieve.
```
--------------------------------
### Get a Registered AdvancementTab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Retrieve a previously registered AdvancementTab using its unique namespace. This allows access to existing tabs for further manipulation or updates.
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(plugin);
AdvancementTab tab = api.getAdvancementTab("namespace");
```
--------------------------------
### Create and Register Advancements
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Advancements
This snippet shows how to initialize the API, create an advancement tab, define a root advancement and a custom base advancement, and register them. It also includes an event listener to display the tab and grant the root advancement when a player finishes loading.
```java
public class MainClass extends JavaPlugin {
@Override
public void onEnable() {
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(this);
AdvancementTab tab = api.createAdvancementTab("mytab");
RootAdvancement root = new RootAdvancement(tab, "root", new AdvancementDisplay(Material.OAK_SAPLING, "Root Advancement", AdvancementFrameType.CHALLENGE, false, false, 0, 0), "textures/block/cobblestone.png");
MineAdv pickaxe = new MineAdv("pickaxe", new AdvancementDisplay(Material.STONE, "Mine Stone", AdvancementFrameType.TASK, true, true, 1.5f, 0, "Mine 10 blocks of stone."), root, 10);
tab.registerAdvancements(root, pickaxe);
// Show tab on player loading. Also grants the root
tab.getEventManager().register(tab, PlayerLoadingCompletedEvent.class, event -> {
tab.showTab(event.getPlayer());
tab.grantRootAdvancement(event.getPlayer());
});
}
public static class MineAdv extends BaseAdvancement {
public MineAdv(@NotNull String key, @NotNull AdvancementDisplay display, @NotNull Advancement parent, @Range(from = 1L, to = 2147483647L) int maxProgression) {
super(key, display, parent, maxProgression);
// Register the event via the tab's EventManager
registerEvent(BlockBreakEvent.class, e -> {
Player player = e.getPlayer();
if (isVisible(player) && e.getBlock().getType() == Material.STONE) {
incrementProgression(player);
}
});
}
@Override
public void giveReward(@NotNull Player player) {
// This code is called when the advancement is granted
player.getInventory().addItem(new ItemStack(Material.STONE_BRICKS));
}
}
}
```
--------------------------------
### Create a Root Advancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Examples
This snippet shows how to create a basic root advancement tab and register it. It includes event handling for player joins to display the advancement tab.
```java
private AdvancementTab advancementTab;
private RootAdvancement root;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
//if you want to the enable SqlLite
main.enableSQLite(new File(getDataFolder(), "sqlLiteDbName"));
advancementTab = UltimateAdvancementAPI.getInstance(this).createAdvancementTab("a_tab");
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS, "Example root", AdvancementFrameType.TASK, false, false, 0, 0, "description");
root = new RootAdvancement(advancementTab, "root", rootDisplay, "textures/block/stone.png");
advancementTab.registerAdvancements(root);
}
@EventHandler
public void onJoin(PlayerLoadingCompletedEvent e) {
Player p = e.getPlayer();
advancementTab.showTab(p);
}
```
--------------------------------
### Configure MySQL Connection Settings
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Configuration
Provides essential connection details for using MySQL as the storage type. Includes username, password, database name, host, and port.
```yaml
mysql:
username: "root"
password: ""
databaseName: "advancements"
host: "127.0.0.1"
port: 3306
```
--------------------------------
### Initializing an AdvancementTab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
An AdvancementTab is initialized by registering its root and base advancements. Once initialized, the tab can be shown to players, and its methods can be called. Attempting to re-register advancements after initialization will result in an IllegalStateException.
```APIDOC
## Initializing an AdvancementTab
### Description
Initializes the AdvancementTab by registering its advancements. This method must be called before the tab can be displayed or interacted with. After initialization, no more advancements can be added or removed.
### Method Signature
```java
tab.registerAdvancements(RootAdvancement root, BaseAdvancement... advancements);
```
### Parameters
* **root** (RootAdvancement) - Required - The root advancement for the tab.
* **advancements** (BaseAdvancement...) - Optional - A variable number of base advancements to register with the tab.
```
--------------------------------
### Create an AdvancementTab Instance
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Obtain an instance of AdvancementTab by providing a unique namespace. This tab is initially not initialized and cannot be used until registered.
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(plugin);
AdvancementTab tab = api.createAdvancementTab("tabnamespace");
```
--------------------------------
### Add Gradle Repository for UltimateAdvancementAPI
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Start-Guide
Include this repository in your Gradle build script to access the API. Ensure it's declared before JitPack if both are used.
```gradle
repositories {
maven { url 'https://nexus.frengor.com/repository/public/' }
}
```
--------------------------------
### Hierarchical Advancement Structure
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Examples
This snippet illustrates setting up a main class to manage advancements, including creating a root advancement and subsequent child advancements like 'Stone' and 'Pickaxe'. It also handles player join events to display the tab and grant the root advancement.
```java
public class MainClazz extends JavaPlugin implements Listener {
private AdvancementMain main;
@Override
public void onLoad() {
main = new AdvancementMain(this);
main.load();
}
private AdvancementTab advancementTab;
private Root root;
@Override
public void onEnable() {
Bukkit.getPluginManager().registerEvents(this, this);
//if you want to the enable SqlLite
main.enableSQLite(new File(getDataFolder(), "sqlLiteDbName"));
advancementTab = UltimateAdvancementAPI.getInstance(this).createAdvancementTab("a_tab");
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS_BLOCK, "Root §c", AdvancementFrameType.TASK, false, false, 0, 0, "Your adventure start here");
root = new Root(advancementTab, "root", rootDisplay, "textures/block/stone.png");
AdvancementDisplay stoneD = new AdvancementDisplay(Material.STONE, "Stone", AdvancementFrameType.GOAL, true, true, 1, 0, "Break 3 blocks of stone");
Stone stone = new Stone("stone", stoneD, root, 3);
AdvancementDisplay pickaxeD = new AdvancementDisplay(Material.STONE_PICKAXE, "Stone Pickaxe", AdvancementFrameType.CHALLENGE, true, true, 2, 1, "Craft a stone pickaxe");
Pickaxe pickaxe = new Pickaxe( "pickaxe", pickaxeD, stone);
advancementTab.registerAdvancements(root, stone, pickaxe);
}
@EventHandler
public void onJoin(PlayerLoadingCompletedEvent e) {
Player p = e.getPlayer();
advancementTab.showTab(p);
root.grant(p);
}
@Override
public void onDisable() {
main.disable();
main = null;
}
}
```
```java
public class Root extends RootAdvancement {
```
--------------------------------
### Maven Repository Configuration
Source: https://github.com/frengor/ultimateadvancementapi/blob/main/README.md
Add this repository to your pom.xml to access the UltimateAdvancementAPI.
```xml
fren_gor
https://nexus.frengor.com/repository/public/
```
--------------------------------
### Create Root Advancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Standard-Advancement
Instantiates a root advancement with display properties and a background texture for the advancement tab. This is the main advancement for a tab.
```java
AdvancementDisplay rootDisplay = new AdvancementDisplay(Material.GRASS, "Example root", AdvancementFrameType.TASK, false, false, 0, 0, "description");
root = new RootAdvancement(advancementTab, "root", rootDisplay, "textures/block/stone.png");
```
--------------------------------
### Configure SQLite Database File
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Configuration
Defines the filename for the SQLite database when 'storage-type' is set to 'SQLite'.
```yaml
sqlite:
file: "database.db"
```
--------------------------------
### Event Handling with Bukkit vs. EventManager
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Compares standard Bukkit event handling with EventManager. EventManager consolidates multiple handlers for the same event type into a single registration, reducing expensive reflection calls.
```java
@EventHandler
public void anEvent(PlayerJoinEvent event) {
event.setJoinMessage("Hello there!");
}
@EventHandler
public void anotherJoinEvent(PlayerJoinEvent event) {
event.getPlayer().sendTitle("Welcome", "To our server!", 30, 100, 15);
}
@EventHandler
public void aBreakEvent(BlockBreakEvent event) {
event.setCancelled(true);
}
```
```java
EventManager manager = new EventManager(plugin);
Object listener = new Object();
manager.register(listener, PlayerJoinEvent.class, event -> event.setJoinMessage("Hello there!"));
manager.register(listener, PlayerJoinEvent.class, event -> event.getPlayer().sendTitle("Welcome", "To our server!", 30, 100, 15));
manager.register(listener, BlockBreakEvent.class, event -> event.setCancelled(true));
```
--------------------------------
### Add Gradle Dependency for UltimateAdvancementAPI
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Start-Guide
Add this dependency to your Gradle build script to include the API in your project. Use 'compileOnly' as the API is expected to be present on the server.
```gradle
dependencies {
compileOnly 'com.frengor:ultimateadvancementapi:2.8.0'
}
```
--------------------------------
### Markdown Changelog Template for Modrinth/Hangar
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Publishing
This Markdown template can be used for changelogs on platforms like Modrinth and Hangar. It includes sections for general and internal changes.
```markdown
* Added support for Minecraft 1.X.X
* Updated CommandAPI to X.X.X
* Changelog here
* Changelog here (by [User](https://github.com/user))
#### Internal changes:
* Changelog here
```
--------------------------------
### Define Base Advancement with Event Handling
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Standard-Advancement
Extends BaseAdvancement to create a custom advancement that listens for specific events, like crafting an item, to grant progress. Implements ParentGrantedVisibility to control when the advancement is visible.
```java
public class Pickaxe extends BaseAdvancement implements ParentGrantedVisibility {
public Pickaxe( @NotNull String key, @NotNull AdvancementDisplay display, @NotNull Advancement parent) {
super(key, display, parent);
registerEvent(CraftItemEvent.class, e -> {
Player p = (Player) e.getWhoClicked();
if (isVisible(p) && !isGranted(p) && e.getRecipe().getResult().getType() == Material.STONE_PICKAXE) {
incrementTeamCriteria(p);
}
});
}
}
```
--------------------------------
### Maven Dependency for UltimateAdvancementAPI
Source: https://github.com/frengor/ultimateadvancementapi/blob/main/README.md
Include this dependency in your project to use the UltimateAdvancementAPI. Ensure the version matches your project's requirements.
```xml
com.frengor
ultimateadvancementapi
2.8.0
provided
```
--------------------------------
### Root Advancement Constructor
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Examples
Constructor for the Root advancement type. Requires advancement tab, key, display, and background texture.
```java
public Root(@NotNull AdvancementTab advancementTab, @NotNull String key, @NotNull AdvancementDisplay display, @NotNull String backgroundTexture) {
super(advancementTab, key, display, backgroundTexture);
}
}
```
--------------------------------
### Creating an AdvancementTab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
An AdvancementTab object represents a tab in the Minecraft advancement GUI and is used to register advancements. An instance can be obtained using the UltimateAdvancementAPI. An AdvancementTab must have a unique namespace.
```APIDOC
## Creating an AdvancementTab
### Description
Creates a new AdvancementTab with a unique namespace. This tab is initially not initialized and cannot be shown to players until advancements are registered.
### Method Signature
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(plugin);
AdvancementTab tab = api.createAdvancementTab("tabnamespace");
```
### Parameters
* **namespace** (String) - Required - A unique identifier for the advancement tab.
```
--------------------------------
### Configure Advanced MySQL Settings
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Configuration
Advanced settings for MySQL connections, including connection pool size and connection timeout. These settings should only be modified by users with a thorough understanding of database performance tuning.
```yaml
mysql:
advanced-settings:
# Set these only if you know what you're doing
poolSize: 5
connectionTimeout: 6000
```
--------------------------------
### Implement a Dirt Breaking TaskAdvancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
Defines a custom TaskAdvancement that tracks the breaking of Dirt blocks. It increments progression when a Dirt block is broken and the player has not yet been granted the advancement.
```java
public class DirtTask extends TaskAdvancement {
public DirtTask(@NotNull String key, @NotNull AbstractMultiTasksAdvancement multitask, @Range(from = 1L, to = 2147483647L) int maxCriteria) {
super(key, multitask, maxCriteria);
registerEvent(BlockBreakEvent.class, e -> {
Player p = e.getPlayer();
if (!isGranted(p) && e.getBlock().getType() == Material.DIRT) {
incrementProgression(p);
}
});
}
}
```
--------------------------------
### Configure Maven Shade Plugin for Relocation
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Shadeable-Version
Configure the maven-shade-plugin to relocate the UltimateAdvancementAPI package to prevent class conflicts. This ensures your shaded JAR contains the API without namespace collisions.
```xml
org.apache.maven.plugins
maven-shade-plugin
false
false
com.fren_gor.ultimateAdvancementAPI
*your package*.libs.com.fren_gor.ultimateAdvancementAPI
package
shade
```
--------------------------------
### Add Player to Team with Callback
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Teams
Use this method to move a player to another player's team. A callback function is provided to handle the result of the operation, including success or failure.
```java
Player playerOne = Bukkit.getPlayer("fren_gor");
Player playerTwo = Bukkit.getPlayer("EscanorTargaryen");
api.updatePlayerTeam(playerOne, playerTwo, result -> {
if (result.isSucceeded()) {
playerOne.sendMessage("You're now part of " + playerTwo.getName() + " team!");
} else {
// An error occurred
playerOne.sendMessage("Something wrong happened while moving to " + playerTwo.getName() + " team");
result.getOccurredException().printStackTrace();
}
});
```
--------------------------------
### Discord Announcement Message Template
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Publishing
Use this template to post a new version announcement in the 'announcements' channel on Discord. It includes placeholders for version numbers, download links, and changelog details.
```markdown
**X.X.X and 3.0.0-beta-X Update**
Download it from:
*Modrinth:* [X.X.X](https://modrinth.com/plugin/ultimateadvancementapi/version/X.X.X) / [3.0.0-beta-X](https://modrinth.com/plugin/ultimateadvancementapi/version/3.0.0-beta-X)
*Hangar:* [X.X.X](https://hangar.papermc.io/DevHeim/UltimateAdvancementAPI/versions/X.X.X) / [3.0.0-beta-X](https://hangar.papermc.io/DevHeim/UltimateAdvancementAPI/versions/3.0.0-beta-X)
*Spigot:*
> **Changelog:**
> * Added support for Minecraft 1.X.X
> * Updated CommandAPI to X.X.X
> * Changelog here
> * Changelog here (by @User)
> * Sublist title:
> * Changelog here
> * Changelog here (by @User)
>
> Internal changes:
> * Changelog here
||@UltimateAdvancementAPI||
```
--------------------------------
### Implement a Stone Breaking TaskAdvancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
Defines a custom TaskAdvancement that tracks the breaking of Stone blocks. It increments progression when a Stone block is broken and the player has not yet been granted the advancement.
```java
public class StoneTask extends TaskAdvancement {
public StoneTask(@NotNull String key, @NotNull AbstractMultiTasksAdvancement multitask, @Range(from = 1L, to = 2147483647L) int maxCriteria) {
super(key, multitask, maxCriteria);
registerEvent(BlockBreakEvent.class, e -> {
Player p = e.getPlayer();
if (!isGranted(p) && e.getBlock().getType() == Material.STONE) {
incrementProgression(p);
}
});
}
}
```
--------------------------------
### Update API Version with Maven
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Publishing
Use the Maven versions plugin to set the new API version across all pom.xml files. Ensure you are on the 'dev' branch before executing.
```bash
mvn org.codehaus.mojo:versions-maven-plugin:2.16.1:set -DgenerateBackupPoms=false -DprocessAllModules=true -DnewVersion=X.X.X
```
--------------------------------
### Define a Custom MultiTasksAdvancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
A basic implementation of MultiTasksAdvancement. This class serves as a template for creating custom multi-task advancements, including defining rewards upon completion.
```java
public class MultiTasksExample extends MultiTasksAdvancement {
public MultiTasksExample(@NotNull String key, @NotNull AdvancementDisplay display, @NotNull Advancement parent, @Range(from = 1L, to = 2147483647L) int maxCriteria) {
super(key, display, parent, maxCriteria);
}
@Override
public void giveReward(@NotNull Player player) {
player.sendMessage("You did it! You won nothing");
}
}
```
--------------------------------
### Define a Custom Advancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
A simple custom advancement class extending BaseAdvancement. It requires a key, display properties, and a parent advancement.
```java
public class Adv extends BaseAdvancement {
public Adv( @NotNull String key, @NotNull AdvancementDisplay display, @NotNull Advancement parent) {
super( key, display, parent);
}
//todo
}
```
--------------------------------
### BB-Code Changelog Template for SpigotMC
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Publishing
This BB-Code template is used for formatting changelogs on SpigotMC. Use [icode] for inline code.
```text
[COLOR=#808080][B]Release X.X.X:[/B][/COLOR]
[LIST]
[*]Added support for Minecraft 1.X.X
[*]Updated CommandAPI to X.X.X
[*]Changelog here
[*]Changelog here (by @User)
[/LIST]
Internal changes:
[LIST]
[*]Changelog here
[/LIST]
```
--------------------------------
### Show AdvancementTab to Player
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Make an AdvancementTab visible to a specific player. It's recommended to do this after the API has loaded player information, using events like PlayerLoadingCompletedEvent.
```java
tab.showTab(player);
```
--------------------------------
### Load Offline Player and Process TeamProgression
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Teams
Loads a player's data if they are offline, processes their team progression, and prints member UUIDs. Handles potential errors during loading and ensures the player's data is not cached indefinitely.
```java
UUID uuid = UUID.fromString("831e3f14-b54d-47fe-bd4e-06d9e6ce681b");
api.loadOfflinePlayer(uuid, CacheFreeingOption.DONT_CACHE(), result -> {
if (result.isSucceeded()) {
TeamProgression progression = result.getResult();
progression.forEachMember(memberUUID -> {
System.out.println(memberUUID);
});
} else {
// An error occurred
result.getOccurredException().printStackTrace();
}
});
```
--------------------------------
### Updating Advancements for a Player
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Sends the current state of all advancements within a specific tab to a player. This is useful for ensuring a player sees the latest advancements after the tab has been initialized and potentially updated.
```APIDOC
## Updating Advancements for a Player
### Description
Updates all advancements for a given player, ensuring they see the latest state of the advancements within this tab. This method can only be called after the tab has been initialized.
### Method Signature
```java
tab.updateEveryAdvancement(Player aPlayer);
```
### Parameters
* **player** (Player) - Required - The player whose advancements need to be updated.
```
--------------------------------
### Disable Vanilla Advancements
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Configuration
Set to 'false' to enable all vanilla advancements. Be aware that disabling advancements may cause players to lose progress and can result in console messages upon player join.
```yaml
disable-vanilla-advancements: false
```
--------------------------------
### Customize Advancement Announce Message
Source: https://github.com/frengor/ultimateadvancementapi/wiki/FAQ
Override this method to customize the announcement message for an advancement. Ensure player is not null and utilize ChatColor for formatting.
```java
@Override
public BaseComponent[] getAnnounceMessage(@NotNull Player player) {
Preconditions.checkNotNull(player, "Player is null.");
ChatColor color = display.getFrame().getColor();
return new ComponentBuilder(player.getName() + " ha completato l\'obiettivo ")
.color(ChatColor.WHITE)
.append(new ComponentBuilder("[")
.color(color)
.event(new HoverEvent(Action.SHOW_TEXT, display.getChatDescription()))
.create()
, FormatRetention.NONE)
.append(display.getChatTitle(), FormatRetention.EVENTS)
.append(new ComponentBuilder("]")
.color(color)
.create()
, FormatRetention.EVENTS)
.create();
}
```
--------------------------------
### Include Shadeable UltimateAdvancementAPI Dependency
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Shadeable-Version
Add the shadeable artifact as a compile-time dependency in your Maven project. This replaces the standard API artifact.
```xml
com.frengor
ultimateadvancementapi-shadeable
2.8.0
compile
```
--------------------------------
### Include Shadeable Mojang Mapped Legacy Dependency
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Shadeable-Version
For older Minecraft versions using Mojang mapping, include the shadeable artifact with the 'mojang-mapped-legacy' classifier.
```xml
com.frengor
ultimateadvancementapi-shadeable
2.8.0
mojang-mapped-legacy
compile
```
--------------------------------
### Disable Vanilla Recipe Advancements
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Configuration
Set to 'false' to enable vanilla recipe advancements. Disabling these may cause players to lose recipe advancement progress and can lead to console messages upon player join.
```yaml
disable-vanilla-recipe-advancements: false
```
--------------------------------
### Showing an AdvancementTab to a Player
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Makes a specific AdvancementTab visible to a player. It is recommended to call this method after the API has finished loading player information, potentially in response to PlayerLoadingCompletedEvent.
```APIDOC
## Showing an AdvancementTab to a Player
### Description
Displays the AdvancementTab to the specified player. This makes the tab and its advancements visible in the player's advancement GUI.
### Method Signature
```java
tab.showTab(Player player);
```
### Parameters
* **player** (Player) - Required - The player to whom the tab should be shown.
```
--------------------------------
### Set Database Storage Type
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Configuration
Specifies the storage mechanism for the API. Options include 'SQLite', 'MySQL', and 'InMemory'. 'InMemory' storage does not persist data between application restarts.
```yaml
storage-type: SQLite
```
--------------------------------
### Define a Multiparent Advancement
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Special-Advancement
A custom multiparent advancement class extending MultiParentsAdvancement. It requires a key, display properties, and a variable number of parent advancements.
```java
public class MultiparentExample extends MultiParentsAdvancement {
public MultiparentExample(@NotNull String key, @NotNull AdvancementDisplay display, @NotNull BaseAdvancement... parents) {
super(key, display, parents);
}
//todo
}
```
--------------------------------
### Commit Message Template for Version Update
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Publishing
Use this template for your commit message when pushing version updates to GitHub.
```text
* Updated version to X.X.X
* Updated to Minecraft 1.X.X
* Updated CommandAPI to X.X.X
* Changelog
* Changelog by @user
```
--------------------------------
### Old Discord Announcement Message Format
Source: https://github.com/frengor/ultimateadvancementapi/wiki/Publishing
This is an older format for Discord announcements, used for single version updates. It contains similar information but is structured differently.
```markdown
**X.X.X Update**
Download it from:
*Modrinth:*
*Spigot:*
*Hangar:*
> **Changelog:**
> * Added support for Minecraft 1.X.X
> * Updated CommandAPI to X.X.X
> * Changelog here
> * Changelog here (by @User)
> * Sublist title:
> * Changelog here
> * Changelog here (by @User)
>
> Internal changes:
> * Changelog here
||@UltimateAdvancementAPI||
```
--------------------------------
### Registering PlayerLoadingCompletedEvent with EventManager
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Register an event listener within an AdvancementTab's EventManager. This ensures events are automatically unregistered when the tab is disposed, making it safe for advancement-related events like showing a tab upon player completion.
```java
tab.getEventManager().register(listener, PlayerLoadingCompletedEvent.class, event -> tab.showTab(event.getPlayer()));
```
--------------------------------
### Unregistering an AdvancementTab
Source: https://github.com/frengor/ultimateadvancementapi/wiki/AdvancementTab
Removes an AdvancementTab and its associated advancements from the players and disposes of the tab's resources. The tab's data is removed from players but not from the database. Calling methods on a disposed tab will result in a DisposedException.
```APIDOC
## Unregistering an AdvancementTab
### Description
Unregisters and disposes of an AdvancementTab. This removes the tab and its advancements from players and cleans up associated resources. The tab's data persists in the database.
### Method Signature
```java
UltimateAdvancementAPI api = UltimateAdvancementAPI.getInstance(plugin);
api.unregisterAdvancementTab("namespace");
```
### Parameters
* **namespace** (String) - Required - The unique namespace of the advancement tab to unregister.
```