Skip to content
Fragmer2 edited this page Apr 8, 2026 · 4 revisions

Developer API

Hooking Into the Plugin

import com.myplugin.SpawnChestPlugin;
import org.bukkit.plugin.Plugin;

public class YourPlugin extends JavaPlugin {

    private SpawnChestPlugin spawnChestPlugin;

    @Override
    public void onEnable() {
        Plugin plugin = getServer().getPluginManager().getPlugin("SpawnChestPlugin");

        if (plugin instanceof SpawnChestPlugin) {
            spawnChestPlugin = (SpawnChestPlugin) plugin;
            getLogger().info("SpawnChestPlugin hooked.");
        } else {
            getLogger().severe("SpawnChestPlugin not found — disabling.");
            getServer().getPluginManager().disablePlugin(this);
        }
    }
}

Add SpawnChestPlugin as a depend or softdepend in your plugin.yml:

softdepend:
  - SpawnChestPlugin

Events

ChestSpawnEvent

Fired before a chest spawns. Cancellable.

@EventHandler
public void onChestSpawn(ChestSpawnEvent event) {
    String tier     = event.getTier();       // "common" | "rare" | "legendary"
    Location loc    = event.getLocation();
    Block block     = event.getChestBlock();

    // Relocate
    event.setLocation(loc.clone().add(0, 1, 0));

    // Cancel
    if (someCondition) {
        event.setCancelled(true);
        event.setCancelReason("Disabled for this event.");
    }
}

ChestOpenEvent

Fired when a player opens a spawned chest. Cancellable.

@EventHandler
public void onChestOpen(ChestOpenEvent event) {
    Player    player    = event.getPlayer();
    String    tier      = event.getTier();
    Inventory inventory = event.getInventory();

    // Add custom loot
    inventory.addItem(new ItemStack(Material.DIAMOND, 3));

    // Block opening
    if (!player.hasPermission("myserver.chest.open." + tier)) {
        event.setCancelled(true);
        player.sendMessage("§cYou cannot open this tier.");
    }
}

GuardianSpawnEvent

Fired when guardian mobs are about to spawn. Cancellable.

@EventHandler
public void onGuardianSpawn(GuardianSpawnEvent event) {
    String       tier     = event.getTier();
    List<Entity> mobs     = event.getGuardians();

    // Modify mobs before they appear
    for (Entity entity : mobs) {
        if (entity instanceof LivingEntity mob) {
            mob.getEquipment().setHelmet(new ItemStack(Material.IRON_HELMET));
        }
    }

    if (tier.equals("common")) {
        event.setCancelled(true);   // No guardians for common chests
    }
}

LegendaryItemUseEvent

Fired when a legendary item ability activates. Cancellable.

@EventHandler
public void onLegendaryUse(LegendaryItemUseEvent event) {
    Player    player = event.getPlayer();
    String    itemId = event.getItemId();   // e.g. "dragon-slayer-sword"
    ItemStack item   = event.getItem();

    // Change cooldown
    event.setCooldownMillis(10_000);

    // Cancel ability (normal hit still lands)
    if (player.getHealth() < 5.0) {
        event.setCancelled(true);
    }
}

AchievementUnlockEvent

Fired when a player unlocks an achievement. Cancellable.

@EventHandler
public void onAchievement(AchievementUnlockEvent event) {
    Player player        = event.getPlayer();
    String achievementId = event.getAchievementId();
    int    xp            = event.getXpReward();

    // Custom reward
    if (achievementId.equals("chest-master")) {
        player.getInventory().addItem(new ItemStack(Material.EMERALD, 10));
    }

    // Double XP
    event.setXpReward(xp * 2);

    // Suppress server broadcast
    event.setBroadcast(false);
}

Managers

SpawnManager

SpawnManager spawnManager = spawnChestPlugin.getSpawnManager();

// Spawn chest at specific location
spawnManager.spawnChest(location, "legendary");

// Spawn batch (respects chest-count-per-interval)
spawnManager.spawnChestBatch();

// Timer control
long nextSpawnMs       = spawnManager.getNextSpawnTime();
spawnManager.setSpawnInterval(600);
spawnManager.resetTimer();

// Active chests
List<Location> active = spawnManager.getActiveChests();
spawnManager.removeChest(location);

LootManager

LootManager lootManager = spawnChestPlugin.getLootManager();

List<ItemStack> loot = lootManager.generateLoot("rare");

lootManager.addCustomLoot("common", myItem);

List<ItemStack> legendaryItems = lootManager.getLegendaryItems();

boolean isLegendary = lootManager.isLegendaryItem(itemStack);
String  itemId      = lootManager.getLegendaryItemId(itemStack);

StatisticsManager

StatisticsManager statsManager = spawnChestPlugin.getStatisticsManager();

PlayerStats stats = statsManager.getPlayerStats(uuid);

int total      = stats.getChestsOpened();
int rare       = stats.getRareChestsOpened();
int legendary  = stats.getLegendaryChestsOpened();
int guardians  = stats.getGuardiansKilled();
int xp         = stats.getCurrentXP();

stats.addChestOpened("legendary");
stats.addXP(500);

statsManager.savePlayerStats(uuid, stats);

List<PlayerStats> top10 = statsManager.getTopPlayers(10);

AchievementManager

AchievementManager achManager = spawnChestPlugin.getAchievementManager();

boolean has = achManager.hasAchievement(uuid, "first-chest");

achManager.unlockAchievement(player, "treasure-hunter");

List<String> all      = achManager.getAllAchievementIds();
Set<String>  unlocked = achManager.getPlayerAchievements(uuid);

int progress = achManager.getProgress(uuid, "chest-master");
int required = achManager.getRequired("chest-master");

CustomLootManager

CustomLootManager clm = spawnChestPlugin.getCustomLootManager();

boolean enabled    = clm.isCustomLootEnabled("legendary");
List<ItemStack> items = clm.getCustomLoot("rare");
List<ItemStack> random = clm.getRandomCustomLoot("legendary");

int  size      = clm.getChestSize("rare");       // 27 or 54
boolean isDouble = clm.isDoubleChest("rare");
String fraction  = clm.getItemFraction("legendary");  // "one-third"

Example — Economy Hook

Give money when a chest is opened:

@EventHandler
public void onChestOpen(ChestOpenEvent event) {
    Player player = event.getPlayer();
    double reward = switch (event.getTier()) {
        case "common"    -> 100;
        case "rare"      -> 500;
        case "legendary" -> 2000;
        default          -> 0;
    };

    if (economy != null && reward > 0) {
        economy.depositPlayer(player, reward);
        player.sendMessage("§a+$" + (int) reward);
    }
}

Example — Chest Finder Compass

@Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
    if (!(sender instanceof Player player)) return false;

    List<Location> chests = spawnChestPlugin.getSpawnManager().getActiveChests();

    if (chests.isEmpty()) {
        player.sendMessage("§7No active chests.");
        return true;
    }

    Location nearest = chests.stream()
        .min(Comparator.comparingDouble(l -> l.distance(player.getLocation())))
        .orElse(null);

    player.setCompassTarget(nearest);
    player.sendMessage(String.format("§7Compass set. (§e%.0f §7blocks)", nearest.distance(player.getLocation())));
    return true;
}

Best Practices

Always check plugin enabled:

if (!getServer().getPluginManager().isPluginEnabled("SpawnChestPlugin")) {
    getLogger().severe("SpawnChestPlugin not found.");
    getServer().getPluginManager().disablePlugin(this);
    return;
}

Use ignoreCancelled = true when appropriate:

@EventHandler(priority = EventPriority.NORMAL, ignoreCancelled = true)
public void onChestSpawn(ChestSpawnEvent event) { ... }

Never block the main thread for heavy operations:

Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
    List<ItemStack> loot = generateHeavyLoot();
    Bukkit.getScheduler().runTask(plugin, () -> inventory.setContents(loot.toArray(new ItemStack[0])));
});

Handle nulls:

PlayerStats stats = statsManager.getPlayerStats(uuid);
if (stats == null) stats = new PlayerStats(uuid);

Support

License: MIT

Clone this wiki locally