> For the complete documentation index, see [llms.txt](https://docs.mongenscave.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.mongenscave.com/premium-products/mc-tycoonhoe/developer-api.md).

# Developer API

The **mc-TycoonHoe Developer API** allows external plugins to integrate with mc-TycoonHoe features such as player hoe statistics, essence, armor boosters, crystals, custom enchants, and plugin events.

The API is designed for Paper plugins and should be used as a `compileOnly` dependency.

***

### Available API Classes

| Class                   | Purpose                                                              |
| ----------------------- | -------------------------------------------------------------------- |
| `McTycoonHoeAPI`        | Main API for player hoe stats, prestige, essence, armor and boosters |
| `McTycoonHoeCrystalAPI` | Utility API for damaging crystals on cached hoes                     |
| `McTycoonHoeEnchantAPI` | API for registering, unregistering and reading custom enchants       |

***

### Package

```java
com.mongenscave.mctycoonhoe.api
```

***

## Installation

### Gradle Kotlin DSL

Add the MonGens Cave repository:

```kotlin
repositories {
    maven("https://repo.mongenscave.com/releases")
}
```

Add the API dependency:

```kotlin
dependencies {
    compileOnly("com.mongenscave:mc-TycoonHoeAPI:1.0.4")
}
```

### Maven

```xml
<repositories>
    <repository>
        <id>mongens-cave</id>
        <url>https://repo.mongenscave.com/releases</url>
    </repository>
</repositories>
```

```xml
<dependencies>
    <dependency>
        <groupId>com.mongenscave</groupId>
        <artifactId>mc-TycoonHoeAPI</artifactId>
        <version>1.0.4</version>
        <scope>provided</scope>
    </dependency>
</dependencies>
```

***

### Plugin Dependency

Your plugin must load after mc-TycoonHoe.

For `plugin.yml`:

```yaml
depend:
  - McTycoonHoe
```

If the installed plugin name is different in the plugin’s `plugin.yml`, use that exact name.

***

## Quick Start

### Accessing the Main API

```java
import com.mongenscave.mctycoonhoe.api.McTycoonHoeAPI;

public class ExampleService {

    private final McTycoonHoeAPI api = McTycoonHoeAPI.getInstance();

}
```

Most main API methods return `CompletableFuture`, because they may use database operations.

Do not block the server thread with `.join()` or `.get()`.

Correct usage:

```java
api.getEssence(player.getUniqueId()).thenAccept(essence -> {
    player.sendMessage("Your essence: " + essence);
});
```

If you need to run Bukkit API logic after an async callback, switch back to the server thread using your plugin scheduler.

***

## Core API

Class:

```java
McTycoonHoeAPI
```

Access:

```java
McTycoonHoeAPI api = McTycoonHoeAPI.getInstance();
```

***

### Methods

#### Get Highest Hoe Level

```java
CompletableFuture<Integer> getHighestHoeLevel(UUID owner)
```

Returns the highest hoe level owned by the player.

Example:

```java
api.getHighestHoeLevel(player.getUniqueId()).thenAccept(level -> {
    player.sendMessage("Highest hoe level: " + level);
});
```

***

#### Get Highest Prestige Level

```java
CompletableFuture<Integer> getHighestPrestigeLevel(UUID owner)
```

Returns the highest prestige level owned by the player.

Example:

```java
api.getHighestPrestigeLevel(player.getUniqueId()).thenAccept(prestige -> {
    player.sendMessage("Highest prestige: " + prestige);
});
```

***

#### Get Hoe Count

```java
CompletableFuture<Integer> getHoeCount(UUID owner)
```

Returns how many hoes the player owns.

Example:

```java
api.getHoeCount(player.getUniqueId()).thenAccept(count -> {
    player.sendMessage("You own " + count + " hoes.");
});
```

***

#### Get Essence

```java
CompletableFuture<Long> getEssence(UUID owner)
```

Returns the player’s essence amount.

If the player has no stored essence data, the API returns `0`.

Example:

```java
api.getEssence(player.getUniqueId()).thenAccept(essence -> {
    player.sendMessage("Essence: " + essence);
});
```

***

#### Give Essence

```java
CompletableFuture<Boolean> giveEssence(UUID owner, long amount)
```

Adds essence to a player.

Example:

```java
api.giveEssence(player.getUniqueId(), 500).thenAccept(success -> {
    if (success) {
        player.sendMessage("You received 500 essence.");
    }
});
```

***

#### Take Essence

```java
CompletableFuture<Boolean> takeEssence(UUID owner, long amount)
```

Attempts to remove essence from a player.

Returns `true` if the player had enough essence and the amount was removed.

Returns `false` if the player did not have enough essence.

Example:

```java
api.takeEssence(player.getUniqueId(), 250).thenAccept(success -> {
    if (success) {
        player.sendMessage("250 essence was removed.");
    } else {
        player.sendMessage("You do not have enough essence.");
    }
});
```

***

#### Get Active Armor

```java
CompletableFuture<Optional<String>> getActiveArmor(UUID player)
```

Returns the player’s active armor id, if one is equipped.

Example:

```java
api.getActiveArmor(player.getUniqueId()).thenAccept(activeArmor -> {
    activeArmor.ifPresentOrElse(
        armorId -> player.sendMessage("Active armor: " + armorId),
        () -> player.sendMessage("You do not have active armor.")
    );
});
```

***

#### Get Armor Booster

```java
double getArmorBooster(UUID player, String key)
```

Returns the current armor booster value for the player and booster key.

Example:

```java
double multiplier = api.getArmorBooster(player.getUniqueId(), "essence");
player.sendMessage("Essence booster: " + multiplier);
```

***

## Crystal API

Class:

```java
McTycoonHoeCrystalAPI
```

The Crystal API currently provides a static utility method for damaging a crystal inside a hoe.

***

### Damage Crystal

```java
McTycoonHoeCrystalAPI.damageCrystal(String hoeId, int crystalIndex, int amount);
```

Damages a crystal inside a specific hoe slot.

If the crystal reaches `0` durability, the crystal will be removed from the slot.

Example:

```java
McTycoonHoeCrystalAPI.damageCrystal(hoeId, 0, 1);
```

***

### Important Notes

This method silently does nothing if:

* the hoe is not currently cached
* the crystal slot does not exist
* the crystal slot is empty
* the crystal is already broken

Crystal indexes are slot-based. Make sure you use the correct crystal slot index from your own integration logic.

***

## Enchant API

Class:

```java
McTycoonHoeEnchantAPI
```

Access:

```java
McTycoonHoeEnchantAPI enchantApi = McTycoonHoeEnchantAPI.getInstance();
```

The Enchant API allows external plugins to register custom enchants into mc-TycoonHoe.

***

### Register Custom Enchant

```java
boolean register(CustomEnchant enchant)
```

Registers a custom enchant.

Returns:

| Value   | Meaning                                                      |
| ------- | ------------------------------------------------------------ |
| `true`  | The enchant was registered as a new enchant                  |
| `false` | An enchant with the same id already existed and was replaced |

The enchant id is case-insensitive and must be unique.

Example:

```java
McTycoonHoeEnchantAPI enchantApi = McTycoonHoeEnchantAPI.getInstance();

boolean fresh = enchantApi.register(new MyCustomEnchant());

if (fresh) {
    getLogger().info("Custom enchant registered.");
} else {
    getLogger().info("Custom enchant replaced an existing enchant.");
}
```

***

### Unregister Custom Enchant

```java
boolean unregister(String id)
```

Removes an API-registered enchant.

Built-in and config-defined enchants cannot be removed using this method.

Example:

```java
boolean removed = enchantApi.unregister("my_enchant");

if (removed) {
    getLogger().info("Custom enchant removed.");
}
```

***

### Check If Enchant Exists

```java
boolean isRegistered(String id)
```

Checks whether an enchant is currently registered.

This includes built-in, config-defined and API-registered enchants.

Example:

```java
if (enchantApi.isRegistered("fortune")) {
    player.sendMessage("Fortune enchant exists.");
}
```

***

### Get Enchant

```java
CustomEnchant get(String id)
```

Returns the registered enchant by id.

Returns `null` if no enchant exists with that id.

Example:

```java
CustomEnchant enchant = enchantApi.get("fortune");

if (enchant != null) {
    player.sendMessage("Enchant max level: " + enchant.maxLevel());
}
```

***

### Get Registered Enchant IDs

```java
Set<String> getRegisteredIds()
```

Returns an immutable snapshot of all registered enchant ids.

The returned ids are uppercase.

Example:

```java
Set<String> ids = enchantApi.getRegisteredIds();

for (String id : ids) {
    player.sendMessage("- " + id);
}
```

***

### Register Timing

Register custom enchants in your plugin’s `onEnable`.

Your plugin should depend on mc-TycoonHoe, otherwise the API may not be ready yet.

Example:

```java
@Override
public void onEnable() {
    McTycoonHoeEnchantAPI.getInstance().register(new MyCustomEnchant());
}
```

If mc-TycoonHoe is not fully enabled yet, the API can throw an `IllegalStateException`.

***

## Events

mc-TycoonHoe exposes multiple Bukkit events that can be listened to from external plugins.

Register listeners like normal Paper/Bukkit events.

Example:

```java
public final class ExampleListener implements Listener {

    @EventHandler
    public void onEssenceGain(EssenceGainEvent event) {
        // Your logic here
    }
}
```

Register the listener:

```java
Bukkit.getPluginManager().registerEvents(new ExampleListener(), this);
```

***

### General Events

Package:

```java
com.mongenscave.mctycoonhoe.api.event
```

Available events:

| Event                  | Description                                          |
| ---------------------- | ---------------------------------------------------- |
| `CropHarvestEvent`     | Called when a crop is harvested through mc-TycoonHoe |
| `EssenceGainEvent`     | Called when a player gains essence                   |
| `HoeXpGainEvent`       | Called when a hoe gains XP                           |
| `HoeLevelUpEvent`      | Called when a hoe levels up                          |
| `PrestigeLevelUpEvent` | Called when a hoe prestige level increases           |

Example:

```java
@EventHandler
public void onHoeLevelUp(HoeLevelUpEvent event) {
    // Reward, log or modify your own plugin data here
}
```

***

### Boss Events

Package:

```java
com.mongenscave.mctycoonhoe.api.event.boss
```

Available events:

| Event             | Description                         |
| ----------------- | ----------------------------------- |
| `BossStartEvent`  | Called when a boss encounter starts |
| `BossDamageEvent` | Called when a boss takes damage     |
| `BossEndEvent`    | Called when a boss encounter ends   |

Example:

```java
@EventHandler
public void onBossStart(BossStartEvent event) {
    // Custom boss start logic
}
```

***

### Condense Events

Package:

```java
com.mongenscave.mctycoonhoe.api.event.condense
```

Available events:

| Event                   | Description                                  |
| ----------------------- | -------------------------------------------- |
| `CondensePrepareEvent`  | Called before a condense action is completed |
| `CondenseCompleteEvent` | Called after a condense action is completed  |

Example:

```java
@EventHandler
public void onCondenseComplete(CondenseCompleteEvent event) {
    // Custom condense reward, logging or statistics logic
}
```

***

### Enchant Events

Package:

```java
com.mongenscave.mctycoonhoe.api.event.enchant
```

Available events:

| Event                          | Description                                    |
| ------------------------------ | ---------------------------------------------- |
| `EnchantPurchasePreEvent`      | Called before an enchant purchase is completed |
| `EnchantPurchaseCompleteEvent` | Called after an enchant purchase is completed  |

Example:

```java
@EventHandler
public void onEnchantPurchase(EnchantPurchaseCompleteEvent event) {
    // Custom logic after a player purchases an enchant
}
```

***

### Cancellable Events

Some events may implement Bukkit’s `Cancellable`.

If an event implements `Cancellable`, you can cancel it like this:

```java
@EventHandler
public void onEnchantPurchasePre(EnchantPurchasePreEvent event) {
    if (shouldBlockPurchase(event)) {
        event.setCancelled(true);
    }
}
```

Always check the event class or IDE autocomplete to see whether the event supports cancellation.

***

## Best Practices

### Do Not Block the Main Thread

Many API methods return `CompletableFuture`.

Avoid this:

```java
long essence = api.getEssence(player.getUniqueId()).join();
```

Use this instead:

```java
api.getEssence(player.getUniqueId()).thenAccept(essence -> {
    player.sendMessage("Essence: " + essence);
});
```

***

### Use `depend`, Not `softdepend`

If your plugin directly imports and uses mc-TycoonHoe API classes, use `depend`.

```yaml
depend:
  - McTycoonHoe
```

Use `softdepend` only if you check for the plugin before touching API classes.

***

### Validate Input

Always validate values before calling API methods.

Example:

```java
if (amount <= 0) {
    return;
}

api.giveEssence(player.getUniqueId(), amount);
```

***

### Register Enchants During Startup

Custom enchants should be registered during plugin startup.

Recommended:

```java
@Override
public void onEnable() {
    McTycoonHoeEnchantAPI.getInstance().register(new MyCustomEnchant());
}
```

Avoid registering enchants repeatedly during gameplay unless you intentionally want to replace an existing enchant.

***

### Handle Optional Values

Some API methods return `Optional`.

Example:

```java
api.getActiveArmor(player.getUniqueId()).thenAccept(optionalArmor -> {
    if (optionalArmor.isEmpty()) {
        player.sendMessage("No active armor.");
        return;
    }

    player.sendMessage("Active armor: " + optionalArmor.get());
});
```

***

## Full Example

```java
package com.example.myplugin;

import com.mongenscave.mctycoonhoe.api.McTycoonHoeAPI;
import com.mongenscave.mctycoonhoe.api.McTycoonHoeEnchantAPI;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;

public final class MyPlugin extends JavaPlugin {

    private McTycoonHoeAPI tycoonHoeApi;

    @Override
    public void onEnable() {
        this.tycoonHoeApi = McTycoonHoeAPI.getInstance();

        getLogger().info("mc-TycoonHoe API hooked successfully.");
    }

    public void sendPlayerStats(Player player) {
        tycoonHoeApi.getEssence(player.getUniqueId()).thenAccept(essence -> {
            player.sendMessage("Your essence: " + essence);
        });

        tycoonHoeApi.getHighestHoeLevel(player.getUniqueId()).thenAccept(level -> {
            player.sendMessage("Highest hoe level: " + level);
        });
    }
}
```

***

## Version

Current API artifact:

```txt
com.mongenscave:mc-TycoonHoeAPI:1.0.4
```

Recommended Java version:

```txt
Java 21
```

Recommended server platform:

```txt
Paper 1.21.8+
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.mongenscave.com/premium-products/mc-tycoonhoe/developer-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
