Skip to content

Developer API

Oribuin edited this page Feb 15, 2025 · 5 revisions

Developer API

This is the technical documentation for the Developer API, Here we will explain the following:

It is recommended that you have a good understanding of Java and Paper API before attempting to create custom content, you may join our Discord for help.

Getting Started

The most important first step is to import the API into your project, it is recommended to use Gradle or Maven to manage your dependencies.

Replace ${version} with the latest version of the API, you can find the latest version on the releases page

Gradle (build.gradle.kts)

repositories {
    // Other repositories... 
    maven("https://repo.rosewooddev.io/repository/public/")
}

dependencies {
    // Other dependencies... 
    compileOnly("dev.oribuin:fishing:${version}")
}

Maven (pom.xml)

<repositories>
    <!-- Other repositories... -->
    <repository>
        <id>rosewooddev</id>
        <url>https://repo.rosewooddev.io/repository/public/</url>
    </repository>
</repositories>

<dependencies>
<!-- Other dependencies... -->
<dependency>
    <groupId>dev.oribuin</groupId>
    <artifactId>fishing</artifactId>
    <version>${version}</version>
    <scope>provided</scope>
</dependency>
</dependencies>

In your plugin.yml file, you must add the following line to your plugin's dependencies:

softdepend: [ Fishing ]

Custom Augments

Augments are custom enchantments that can be applied to fishing rods, they can be created by extending the Augment class and implementing the required methods.

Existing implementations of augments can be found here.

In this example, we will create a custom augment that restores health when the player catches a fish.

import dev.oribuin.fishing.api.event.impl.FishCatchEvent;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;

public class AugmentExample extends Augment {

    private static final Double HEALTH_RESTORED = 2.0;

    /**
     * Create a new type of augment with a name and description.
     * <p>
     * Augment names must be unique and should be in snake_case, this will be used to identify the augment in the plugin, once implemented it should not be changed.
     */
    public AugmentExample() {
        super("api-example", "Restores health when you catch a fish.");

        // Register all the events that this augment will listen to.
        // The default events are available in the {@link Augment} class, but they must be registered here to be used.
        this.register(FishCatchEvent.class, this::onFishCatch);
    }

    /**
     * The method that will be called when the player catches a fish.
     *
     * @param event The event that was called when the fish was caught
     * @param level The level of the ability that was used, if applicable (0 if not)
     */
    @Override
    public void onFishCatch(FishCatchEvent event, int level) {
        AttributeInstance health = event.getPlayer().getAttribute(Attribute.MAX_HEALTH);
        if (health == null) return;

        if (event.getPlayer().getHealth() >= health.getValue()) return;

        event.getPlayer().setHealth(Math.min(health.getValue(), event.getPlayer().getHealth() + HEALTH_RESTORED));
        event.getPlayer().sendMessage("You have restored " + HEALTH_RESTORED + " health.");
    }

}

Registering the Augment

To register the augment, In your main class, You must register the augment using the AugmentRegistry#register(Supplier<Augment>) method. Here is an example of how to register the augment:

public class MyPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        // Check if the Fishing plugin is enabled, not neccessary if the fishing plugin is a hard-dependency.
        if (Bukkit.getPluginManager().isPluginEnabled()) {
            AugmentRegistry.register(AugmentExample::new);
        }
    }
}

Registering Augment Events

Found that the event you want to listen to is not being called? You must listen to the event yourself call the FishEventshandler#callEvents(Map<T extends FishEventsHandler, Integer>, Event) method.

Here is an example of how to use this method:

import com.destroystokyo.paper.event.player.PlayerJumpEvent;
import dev.oribuin.fishing.model.augment.Augment;
import dev.oribuin.fishing.model.augment.AugmentRegistry;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.inventory.ItemStack;

import java.util.Map;

public class PluginListeners implements Listener {

    @EventHandler(ignoreCancelled = true)
    public void onJump(PlayerJumpEvent event) {
        ItemStack rod = event.getPlayer().getInventory().getItemInMainHand();
        Map<Augment, Integer> augments = AugmentRegistry.from(rod);
        AugmentRegistry.callEvent(augments, event);
    }

}

Custom Currency

Have a custom currency you want to use for the plugin? You can create a custom currency by implementing the Currency<T> interface.

The type is the type of the currency, this can be a Double, Integer, Long, or any other type that you want to use.

Existing implementations of currencies can be found here.

In this example, we will create a custom currency that uses Double as the type.

import dev.oribuin.fishing.model.economy.Currency;
import org.bukkit.OfflinePlayer;
import org.jetbrains.annotations.NotNull;

import java.util.UUID;

public class BankCurrency implements Currency<Double> {

    @Override
    public String name() {
        return "bank_balance";
    }

    @Override
    public @NotNull Number amount(@NotNull OfflinePlayer player, @NotNull Double content) {
        return new BankAccount(player.getUniqueId()).getBalance();
    }

    @Override
    public boolean has(@NotNull OfflinePlayer player, @NotNull Double content) {
        return this.amount(player, content).doubleValue() >= content;
    }

    @Override
    public void give(@NotNull OfflinePlayer player, @NotNull Double content) {
        BankAccount account = new BankAccount(player.getUniqueId());
        account.setBalance(account.getBalance() + content);
    }

    @Override
    public void take(@NotNull OfflinePlayer player, @NotNull Double content) {
        BankAccount account = new BankAccount(player.getUniqueId());
        account.setBalance(account.getBalance() - content);
    }

    /**
     * Example class to represent a bank balance for a player, you would use your own implementation
     */
    public static class BankAccount {
        private final UUID owner;
        private double balance;

        public BankAccount(UUID owner) {
            this.owner = owner;
            this.balance = 0.0;
        }

        public BankAccount(UUID owner, Double balance) {
            this.owner = owner;
            this.balance = balance;
        }


        public UUID getOwner() {
            return this.owner;
        }

        public double getBalance() {
            return balance;
        }

        public void setBalance(double balance) {
            this.balance = balance;
        }

    }

}

Registering the Currency

To register the currency, In your main class, You must register the currency using the CurrencyRegistry#register(Supplier<Currency>) method.

Here is an example of how to register the currency:

public class MyPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        // Check if the Fishing plugin is enabled, not neccessary if the fishing plugin is a hard-dependency.
        if (Bukkit.getPluginManager().isPluginEnabled()) {
            CurrencyRegistry.register(BankCurrency::new);
        }
    }
}

Custom Conditions

Conditions are custom checks that can be applied to the player when they are fishing, they can be created by extending the Condition class and implementing the required methods.

Existing implementations of conditions can be found here.

In this example, we will create a custom condition that checks if the player has a specified statistic

public class StatisticCondition extends CatchCondition {

    private Statistic statistic; // The statistic the player needs to have
    private int amount; // The amount of the statistic the player needs to have

    @Override
    public boolean shouldRun(Fish fish) {
        return this.statistic != null;
    }

    @Override
    public boolean check(Fish fish, Player player, ItemStack rod, FishHook hook) {
        return player.getStatistic(this.statistic) >= this.amount;
    }

    @Override
    public void loadSettings(@NotNull CommentedConfigurationSection config) {
        this.statistic = Statistic.valueOf(config.getString("statistic", "FISH_CAUGHT")); // FishUtils#getEnum is preferred
        this.amount = config.getInt("amount", 1);
    }

}

Registering the Condition

To register the condition, In your main class, You must register the condition using the ConditionRegistry#register(Supplier<Condition>) method.

Here is an example of how to register the condition:

public class MyPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        // Check if the Fishing plugin is enabled, not neccessary if the fishing plugin is a hard-dependency.
        if (Bukkit.getPluginManager().isPluginEnabled()) {
            ConditionRegistry.register(StatisticCondition::new);
        }
    }
}