Skip to content
Fragmer2 edited this page Feb 3, 2026 · 4 revisions

Developer API Documentation

Overview

SpawnChestPlugin provides a comprehensive API for developers to integrate with the plugin, create addons, and extend functionality.


Maven Dependency

Add Repository

<repositories>
    <repository>
        <id>spawnchest-repo</id>
        <url>https://your-maven-repo.com/releases</url>
    </repository>
</repositories>

Add Dependency

<dependencies>
    <dependency>
        <groupId>com.myplugin</groupId>
        <artifactId>SpawnChestPlugin</artifactId>
        <version>4.1.5</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Gradle Dependency

repositories {
    maven {
        url 'https://your-maven-repo.com/releases'
    }
}

dependencies {
    compileOnly 'com.myplugin:SpawnChestPlugin:4.1.5'
}

Getting Plugin Instance

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().warning("SpawnChestPlugin not found!");
            getServer().getPluginManager().disablePlugin(this);
        }
    }
}

Events API

ChestSpawnEvent

Fired when a chest is about to spawn.

import com.myplugin.events.ChestSpawnEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;

public class ChestListener implements Listener {
    
    @EventHandler
    public void onChestSpawn(ChestSpawnEvent event) {
        String tier = event.getTier();
        Location location = event.getLocation();
        
        // Get chest block
        Block chestBlock = event.getChestBlock();
        
        // Modify location
        Location newLocation = location.clone().add(0, 5, 0);
        event.setLocation(newLocation);
        
        // Cancel event
        if (tier.equals("legendary")) {
            event.setCancelled(true);
            event.setCancelReason("Legendary chests disabled!");
        }
        
        // Check if cancelled
        if (event.isCancelled()) {
            String reason = event.getCancelReason();
            // Handle cancellation
        }
    }
}

Methods:

  • String getTier() - Get chest tier (common/rare/legendary)
  • Location getLocation() - Get spawn location
  • void setLocation(Location) - Change spawn location
  • Block getChestBlock() - Get chest block
  • boolean isCancelled() - Check if cancelled
  • void setCancelled(boolean) - Cancel event
  • String getCancelReason() - Get cancellation reason
  • void setCancelReason(String) - Set cancellation reason

ChestOpenEvent

Fired when a player opens a spawned chest.

import com.myplugin.events.ChestOpenEvent;

@EventHandler
public void onChestOpen(ChestOpenEvent event) {
    Player player = event.getPlayer();
    String tier = event.getTier();
    Location location = event.getLocation();
    Inventory inventory = event.getInventory();
    
    // Give reward
    player.sendMessage("You opened a " + tier + " chest!");
    
    // Add custom loot
    inventory.addItem(new ItemStack(Material.DIAMOND, 5));
    
    // Cancel event (prevent opening)
    if (!player.hasPermission("chest.open." + tier)) {
        event.setCancelled(true);
        player.sendMessage("No permission!");
    }
}

Methods:

  • Player getPlayer() - Get player opening chest
  • String getTier() - Get chest tier
  • Location getLocation() - Get chest location
  • Inventory getInventory() - Get chest inventory
  • boolean isCancelled() - Check if cancelled
  • void setCancelled(boolean) - Cancel event

GuardianSpawnEvent

Fired when guardian mobs spawn.

import com.myplugin.events.GuardianSpawnEvent;

@EventHandler
public void onGuardianSpawn(GuardianSpawnEvent event) {
    String tier = event.getTier();
    Location chestLocation = event.getChestLocation();
    List<Entity> guardians = event.getGuardians();
    
    // Modify guardians
    for (Entity entity : guardians) {
        if (entity instanceof LivingEntity) {
            LivingEntity mob = (LivingEntity) entity;
            
            // Add custom equipment
            mob.getEquipment().setHelmet(new ItemStack(Material.DIAMOND_HELMET));
            
            // Add potion effect
            mob.addPotionEffect(new PotionEffect(
                PotionEffectType.INCREASE_DAMAGE, 
                999999, 
                2
            ));
        }
    }
    
    // Cancel spawning
    if (tier.equals("common")) {
        event.setCancelled(true);
    }
}

Methods:

  • String getTier() - Get chest tier
  • Location getChestLocation() - Get chest location
  • List<Entity> getGuardians() - Get guardian entities
  • void setGuardians(List<Entity>) - Replace guardians
  • boolean isCancelled() - Check if cancelled
  • void setCancelled(boolean) - Cancel event

LegendaryItemUseEvent

Fired when legendary item ability is used.

import com.myplugin.events.LegendaryItemUseEvent;

@EventHandler
public void onLegendaryUse(LegendaryItemUseEvent event) {
    Player player = event.getPlayer();
    String itemId = event.getItemId();
    ItemStack item = event.getItem();
    
    // Check which item
    if (itemId.equals("dragon-slayer-sword")) {
        // Custom logic
        player.sendMessage("Dragon Slayer activated!");
    }
    
    // Cancel ability (but allow normal attack)
    if (player.getHealth() < 5.0) {
        event.setCancelled(true);
        player.sendMessage("Too weak to use ability!");
    }
    
    // Modify cooldown
    event.setCooldownMillis(5000); // 5 seconds
}

Methods:

  • Player getPlayer() - Get player using item
  • String getItemId() - Get item identifier
  • ItemStack getItem() - Get ItemStack
  • long getCooldownMillis() - Get cooldown
  • void setCooldownMillis(long) - Change cooldown
  • boolean isCancelled() - Check if cancelled
  • void setCancelled(boolean) - Cancel event

AchievementUnlockEvent

Fired when player unlocks achievement.

import com.myplugin.events.AchievementUnlockEvent;

@EventHandler
public void onAchievement(AchievementUnlockEvent event) {
    Player player = event.getPlayer();
    String achievementId = event.getAchievementId();
    int xpReward = event.getXpReward();
    
    // Give custom reward
    if (achievementId.equals("first-chest")) {
        player.getInventory().addItem(new ItemStack(Material.DIAMOND, 1));
    }
    
    // Modify XP reward
    event.setXpReward(xpReward * 2); // Double XP
    
    // Prevent broadcast
    event.setBroadcast(false);
}

Methods:

  • Player getPlayer() - Get player
  • String getAchievementId() - Get achievement ID
  • int getXpReward() - Get XP reward
  • void setXpReward(int) - Change XP reward
  • boolean isBroadcast() - Check if broadcasts
  • void setBroadcast(boolean) - Change broadcast
  • boolean isCancelled() - Check if cancelled
  • void setCancelled(boolean) - Cancel event

Manager APIs

SpawnManager

Manage chest spawning.

import com.myplugin.managers.SpawnManager;

SpawnManager spawnManager = spawnChestPlugin.getSpawnManager();

// Spawn chest immediately
Location location = new Location(world, 100, 64, 200);
boolean success = spawnManager.spawnChest(location, "legendary");

// Get next spawn time
long timeMillis = spawnManager.getNextSpawnTime();
long remainingSeconds = (timeMillis - System.currentTimeMillis()) / 1000;

// Set spawn interval
spawnManager.setSpawnInterval(600); // 10 minutes

// Reset timer
spawnManager.resetTimer();

// Get active chests
List<Location> activeChests = spawnManager.getActiveChests();

// Remove chest
spawnManager.removeChest(location);

LootManager

Manage loot generation.

import com.myplugin.managers.LootManager;

LootManager lootManager = spawnChestPlugin.getLootManager();

// Generate loot for tier
List<ItemStack> loot = lootManager.generateLoot("rare");

// Add custom loot item
ItemStack customItem = new ItemStack(Material.DIAMOND_SWORD);
lootManager.addCustomLoot("common", customItem);

// Get legendary items
List<ItemStack> legendaryItems = lootManager.getLegendaryItems();

// Check if item is legendary
boolean isLegendary = lootManager.isLegendaryItem(itemStack);

// Get item ID
String itemId = lootManager.getLegendaryItemId(itemStack);

StatisticsManager

Manage player statistics.

import com.myplugin.managers.StatisticsManager;

StatisticsManager statsManager = spawnChestPlugin.getStatisticsManager();

// Get player stats
UUID playerUuid = player.getUniqueId();
PlayerStats stats = statsManager.getPlayerStats(playerUuid);

// Chest stats
int totalChests = stats.getChestsOpened();
int commonChests = stats.getCommonChestsOpened();
int rareChests = stats.getRareChestsOpened();
int legendaryChests = stats.getLegendaryChestsOpened();

// Other stats
int legendaryItems = stats.getLegendaryItemsFound();
int guardiansKilled = stats.getGuardiansKilled();
int applesUsed = stats.getSummonerApplesUsed();
int xp = stats.getCurrentXP();

// Modify stats
stats.addChestOpened("legendary");
stats.addLegendaryItemFound();
stats.addGuardianKilled();
stats.addXP(500);

// Save stats
statsManager.savePlayerStats(playerUuid, stats);

// Get leaderboard
List<PlayerStats> topPlayers = statsManager.getTopPlayers(10);

AchievementManager

Manage achievements.

import com.myplugin.managers.AchievementManager;

AchievementManager achievementManager = spawnChestPlugin.getAchievementManager();

// Check if unlocked
boolean unlocked = achievementManager.hasAchievement(playerUuid, "first-chest");

// Unlock achievement
achievementManager.unlockAchievement(player, "treasure-hunter");

// Get all achievements
List<String> allAchievements = achievementManager.getAllAchievementIds();

// Get player's achievements
Set<String> playerAchievements = achievementManager.getPlayerAchievements(playerUuid);

// Get achievement progress
int progress = achievementManager.getProgress(playerUuid, "chest-master");
int required = achievementManager.getRequired("chest-master");

CustomLootManager

Manage custom loot tables.

import com.myplugin.managers.CustomLootManager;

CustomLootManager customLootManager = spawnChestPlugin.getCustomLootManager();

// Check if custom loot enabled
boolean enabled = customLootManager.isCustomLootEnabled("legendary");

// Get custom loot items
List<ItemStack> customItems = customLootManager.getCustomLoot("rare");

// Get random custom loot (with fraction applied)
List<ItemStack> randomItems = customLootManager.getRandomCustomLoot("legendary");

// Check chest size
int chestSize = customLootManager.getChestSize("rare"); // 27 or 54
boolean isDouble = customLootManager.isDoubleChest("rare");

// Get item fraction
String fraction = customLootManager.getItemFraction("legendary"); // "one-third"

Utility Classes

ChestUtils

import com.myplugin.utils.ChestUtils;

// Check if location is safe for chest
boolean isSafe = ChestUtils.isSafeLocation(location);

// Find safe location nearby
Location safeLocation = ChestUtils.findSafeLocation(location, 10);

// Get chest from location
Chest chest = ChestUtils.getChest(location);

// Check if chest is spawned by plugin
boolean isPluginChest = ChestUtils.isSpawnedChest(location);

ItemBuilder

import com.myplugin.utils.ItemBuilder;

ItemStack item = new ItemBuilder(Material.DIAMOND_SWORD)
    .setName("§6Custom Sword")
    .addLore("§7First line")
    .addLore("§7Second line")
    .addEnchantment(Enchantment.DAMAGE_ALL, 5)
    .addEnchantment(Enchantment.DURABILITY, 3)
    .setUnbreakable(true)
    .addItemFlags(ItemFlag.HIDE_ENCHANTS)
    .setCustomModelData(12345)
    .build();

LocationUtils

import com.myplugin.utils.LocationUtils;

// Serialize location to string
String serialized = LocationUtils.serialize(location);

// Deserialize location from string
Location location = LocationUtils.deserialize(serialized);

// Get distance between locations
double distance = LocationUtils.distance(loc1, loc2);

// Check if location is in spawn zone
boolean inZone = LocationUtils.isInSpawnZone(location, minDist, maxDist);

Creating Custom Legendary Items

Step 1: Create Item

public class CustomLegendaryItem {
    
    public static ItemStack createItem() {
        return new ItemBuilder(Material.DIAMOND_AXE)
            .setName("§c§lThunder Axe")
            .addLore("§7Strikes enemies with lightning")
            .addLore("§7Cooldown: 5 seconds")
            .addEnchantment(Enchantment.DAMAGE_ALL, 6)
            .addEnchantment(Enchantment.DURABILITY, 5)
            .addItemFlags(ItemFlag.HIDE_ENCHANTS)
            .build();
    }
}

Step 2: Register Item

@Override
public void onEnable() {
    // Hook SpawnChestPlugin
    spawnChestPlugin = (SpawnChestPlugin) getServer().getPluginManager()
        .getPlugin("SpawnChestPlugin");
    
    // Register custom item
    LootManager lootManager = spawnChestPlugin.getLootManager();
    lootManager.registerLegendaryItem("thunder-axe", CustomLegendaryItem.createItem());
}

Step 3: Add Ability

@EventHandler
public void onItemUse(PlayerInteractEntityEvent event) {
    Player player = event.getPlayer();
    ItemStack item = player.getInventory().getItemInMainHand();
    
    // Check if our custom item
    if (isThunderAxe(item)) {
        Entity target = event.getRightClicked();
        
        // Strike with lightning
        target.getWorld().strikeLightningEffect(target.getLocation());
        
        if (target instanceof LivingEntity) {
            ((LivingEntity) target).damage(10.0, player);
        }
        
        // Set cooldown
        player.setCooldown(Material.DIAMOND_AXE, 100); // 5 seconds
    }
}

private boolean isThunderAxe(ItemStack item) {
    if (item == null || !item.hasItemMeta()) return false;
    ItemMeta meta = item.getItemMeta();
    return meta.hasDisplayName() && 
           meta.getDisplayName().equals("§c§lThunder Axe");
}

Hooking into Economy

Example: Give Money for Opening Chest

import net.milkbowl.vault.economy.Economy;

public class EconomyHook {
    
    private Economy economy;
    
    public void setupEconomy() {
        RegisteredServiceProvider<Economy> rsp = 
            getServer().getServicesManager().getRegistration(Economy.class);
        if (rsp != null) {
            economy = rsp.getProvider();
        }
    }
    
    @EventHandler
    public void onChestOpen(ChestOpenEvent event) {
        Player player = event.getPlayer();
        String tier = event.getTier();
        
        // Give money based on tier
        double amount = 0;
        switch (tier) {
            case "common": amount = 100; break;
            case "rare": amount = 500; break;
            case "legendary": amount = 2000; break;
        }
        
        if (economy != null) {
            economy.depositPlayer(player, amount);
            player.sendMessage("§a+$" + amount);
        }
    }
}

Example Addon: Chest Finder Compass

public class ChestFinderAddon extends JavaPlugin implements Listener {
    
    private SpawnChestPlugin spawnChestPlugin;
    
    @Override
    public void onEnable() {
        // Hook main plugin
        spawnChestPlugin = (SpawnChestPlugin) getServer()
            .getPluginManager().getPlugin("SpawnChestPlugin");
        
        // Register events
        getServer().getPluginManager().registerEvents(this, this);
        
        // Register command
        getCommand("chestfinder").setExecutor(this);
    }
    
    @Override
    public boolean onCommand(CommandSender sender, Command command, 
                            String label, String[] args) {
        if (!(sender instanceof Player)) return false;
        Player player = (Player) sender;
        
        // Get active chests
        SpawnManager spawnManager = spawnChestPlugin.getSpawnManager();
        List<Location> chests = spawnManager.getActiveChests();
        
        if (chests.isEmpty()) {
            player.sendMessage("§cNo chests currently spawned!");
            return true;
        }
        
        // Find nearest chest
        Location nearest = null;
        double minDist = Double.MAX_VALUE;
        
        for (Location chest : chests) {
            double dist = chest.distance(player.getLocation());
            if (dist < minDist) {
                minDist = dist;
                nearest = chest;
            }
        }
        
        // Point compass
        player.setCompassTarget(nearest);
        player.sendMessage(String.format(
            "§aCompass pointing to nearest chest! (%.0f blocks away)", 
            minDist
        ));
        
        return true;
    }
}

Best Practices

1. Check Plugin Enabled

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

2. Handle Events Properly

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

3. Don't Block Main Thread

//  BAD - blocking
player.sendMessage("Loading...");
List<ItemStack> loot = generateComplexLoot(); // Takes 5 seconds
inventory.setContents(loot.toArray(new ItemStack[0]));

//  GOOD - async
player.sendMessage("Loading...");
Bukkit.getScheduler().runTaskAsynchronously(plugin, () -> {
    List<ItemStack> loot = generateComplexLoot();
    
    Bukkit.getScheduler().runTask(plugin, () -> {
        inventory.setContents(loot.toArray(new ItemStack[0]));
    });
});

4. Handle Nulls

PlayerStats stats = statsManager.getPlayerStats(uuid);
if (stats != null) {
    int chests = stats.getChestsOpened();
    // Use stats
} else {
    // Create new stats
    stats = new PlayerStats(uuid);
}


Support for Developers

Questions about API:

Contributing:

  • Fork repository
  • Make changes
  • Submit pull request

License: MIT (modify freely)

Clone this wiki locally