コンテンツにスキップ

Working examples

Snippets that compile against mythicrod-api:2026.1.0.

VIP loot provider

import io.xcutiboo.mythicrod.api.ExternalDropProvider;
import io.xcutiboo.mythicrod.api.MythicRodAPI;
import io.xcutiboo.mythicrod.api.platform.PlatformItem;
import io.xcutiboo.mythicrod.api.platform.PlatformPlayer;
import io.xcutiboo.mythicrod.paper.api.MythicRodServices;
import org.bukkit.plugin.java.JavaPlugin;

public final class VipLootPlugin extends JavaPlugin {
    @Override
    public void onEnable() {
        MythicRodServices.find().ifPresent(api ->
            api.registerExternalDropProvider(new VipReward(api)));
    }

    @Override
    public void onDisable() {
        MythicRodServices.find().ifPresent(api ->
            api.unregisterExternalDropProvider(VipReward.KEY));
    }
}

final class VipReward implements ExternalDropProvider {
    static final String KEY = "viploot:diamond";
    private final MythicRodAPI api;
    VipReward(MythicRodAPI api) { this.api = api; }

    @Override public String getKey() { return KEY; }
    @Override public String getTier() { return "rare"; }
    @Override public String getDisplayName() { return "<gold>VIP Diamond"; }

    @Override
    public double getWeight(PlatformPlayer player) {
        return player.hasPermission("viploot.vip") ? 4.0D : 0.0D;
    }

    @Override
    public PlatformItem generateItem(PlatformPlayer player) {
        return api.createItem("DIAMOND", 1).orElse(null);
    }
}

paper-plugin.yml:

name: VipLoot
main: example.VipLootPlugin
api-version: '1.21'
dependencies:
  server:
    MythicRod: { load: AFTER, required: false }

Refresh a leaderboard sign after each catch

import io.xcutiboo.mythicrod.paper.events.MythicRodStatsUpdateEvent;
import io.xcutiboo.mythicrod.paper.api.MythicRodServices;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public final class LeaderboardListener implements Listener {
    private final SignRenderer renderer;
    public LeaderboardListener(SignRenderer renderer) { this.renderer = renderer; }

    @EventHandler
    public void onStats(MythicRodStatsUpdateEvent event) {
        MythicRodServices.find().ifPresent(api ->
            api.getTopPlayers(
                io.xcutiboo.mythicrod.api.PlayerStatSnapshot.StatType.TOTAL_CAUGHT, 10)
            .thenAccept(renderer::queueRefresh));
    }
}

renderer::queueRefresh must reschedule any Bukkit-touching work onto the correct owner thread. See Folia threading.

React to the language switch

import io.xcutiboo.mythicrod.paper.events.MythicRodReloadEvent;

@EventHandler
public void onReload(MythicRodReloadEvent event) {
    if (event.isSuccess()) {
        myCachedTranslations.invalidate();
    }
}

The reload event fires both when MythicRod-side reload succeeds and when it fails so listeners can clear stale data either way; the isSuccess() flag lets you target the success path only if that is what you need.

Probe an item's MythicRod tier

import org.bukkit.NamespacedKey;
import org.bukkit.persistence.PersistentDataType;

private static final NamespacedKey CUSTOM_ROD =
    NamespacedKey.fromString("mythicrod:custom_rod");
private static final NamespacedKey ROD_TIER =
    NamespacedKey.fromString("mythicrod:rod_tier");

public Optional<String> rodTier(ItemStack rod) {
    var pdc = rod.getItemMeta().getPersistentDataContainer();
    if (!pdc.has(CUSTOM_ROD, PersistentDataType.BYTE)) return Optional.empty();
    return Optional.ofNullable(pdc.get(ROD_TIER, PersistentDataType.STRING));
}

Minigame: "what could I catch here?" preview

previewEligibleDrops(UUID, biomeKey) returns the drop table after biome and permission filters. Use it in tutorial overlays, fishing spot UIs, or scoreboard tickers without running an actual catch.

import io.xcutiboo.mythicrod.api.MythicRodAPI;
import io.xcutiboo.mythicrod.api.platform.PlatformDrop;
import io.xcutiboo.mythicrod.paper.api.MythicRodServices;
import org.bukkit.entity.Player;

public void showPreview(Player player) {
    String biomeKey = player.getWorld()
        .getBiome(player.getLocation())
        .getKey()
        .toString();

    MythicRodServices.find().ifPresent(api -> {
        var eligible = api.previewEligibleDrops(player.getUniqueId(), biomeKey);
        int total = eligible.stream().mapToInt(PlatformDrop::getWeight).sum();
        eligible.forEach(drop -> {
            double share = total == 0 ? 0.0 : (drop.getWeight() * 100.0 / total);
            player.sendMessage("§7- " + drop.getIdentifier()
                + " §8(" + String.format("%.1f", share) + "%§8)");
        });
    });
}

Pass null as the biome to ignore biome filters. The list is an immutable snapshot; reloads do not retroactively change a returned list.

← Developer API