> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sentrystudios.org/llms.txt
> Use this file to discover all available pages before exploring further.

# SentryPremades

> Trigger, query, and register SentryStudio Premades programmatically.

SentryPremades exposes a lightweight, yet extremely capable API that allows developers to deeply integrate with the premades framework. You can trigger abilities, fetch registered premades, and even dynamically register your own abilities directly from your Java or Kotlin plugins.

## Setup

Ensure that you have SentryPremades in your plugin's `depend` or `softdepend` list in your `plugin.yml`.

```yaml plugin.yml theme={null}
depend:
  - SentryPremades
```

***

## Triggering Premades

The plugin provides a central `SentryPremadesAPI` object with static methods to execute premades seamlessly.

### Executing Abilities

To execute an ability, provide the ability's ID and the target `Entity`. You can optionally provide a specific `Location`.

<CodeGroup>
  ```java Java theme={null}
  import org.sentrystudios.sentrypremades.api.SentryPremadesAPI;
  import org.bukkit.entity.Player;
  import org.bukkit.Location;

  public void triggerMyAbility(Player player) {
      // Basic execution on the entity's current location
      SentryPremadesAPI.executeAbility("flaming-shot", player);
      
      // Execution with a specific target location offset
      Location targetLoc = player.getLocation().add(0, 5, 0);
      SentryPremadesAPI.executeAbility("flaming-shot", player, targetLoc);
  }
  ```

  ```kotlin Kotlin theme={null}
  import org.sentrystudios.sentrypremades.api.SentryPremadesAPI
  import org.bukkit.entity.Player
  import org.bukkit.Location

  fun triggerMyAbility(player: Player) {
      SentryPremadesAPI.executeAbility("flaming-shot", player)
      
      val targetLoc = player.location.add(0.0, 5.0, 0.0)
      SentryPremadesAPI.executeAbility("flaming-shot", player, targetLoc)
  }
  ```
</CodeGroup>

### Executing Events

Events operate independently of a specific entity, typically affecting the environment.

<CodeGroup>
  ```java Java theme={null}
  import org.sentrystudios.sentrypremades.api.SentryPremadesAPI;
  import org.bukkit.entity.Player;
  import org.bukkit.Location;

  public void triggerMyEvent(Location loc, Player caster) {
      // Triggering the event at the given location (no specific caster)
      SentryPremadesAPI.executeEvent("meteor-shower", loc);
      
      // Triggering the event while attributing it to a specific caster
      SentryPremadesAPI.executeEvent("meteor-shower", loc, caster);
  }
  ```

  ```kotlin Kotlin theme={null}
  import org.sentrystudios.sentrypremades.api.SentryPremadesAPI
  import org.bukkit.entity.Player
  import org.bukkit.Location

  fun triggerMyEvent(loc: Location, caster: Player) {
      SentryPremadesAPI.executeEvent("meteor-shower", loc)
      SentryPremadesAPI.executeEvent("meteor-shower", loc, caster)
  }
  ```
</CodeGroup>

<Note>
  **Important:** If you specify a preset ID (e.g., `flaming-shot:low-damage`), ensure the preset ID is included exactly as formulated when calling the API!
</Note>

***

## Programmatic Registration

While SentryPremades allows bundling addons into `.jar` files (see [Custom Addons](/products/sentry-premades/custom-addons)), you can also register abilities **directly from your own plugin's code** without writing a `premade.yml`.

To do this, interact directly with the `PremadeRegistry`!

### Registering an Ability

<CodeGroup>
  ```java Java theme={null}
  import org.sentrystudios.sentrypremades.registry.PremadeRegistry;
  import org.sentrystudios.sentrypremades.api.ability.Ability;
  import org.bukkit.entity.Entity;
  import org.bukkit.Location;

  public class MyPluginAbility extends Ability {
      public MyPluginAbility(String id) {
          super(id);
      }

      @Override
      public boolean onExecute(Entity caster, Location location) {
          caster.sendMessage("Executed purely from code!");
          return true;
      }
  }

  // In your plugin's onEnable():
  PremadeRegistry.INSTANCE.register(new MyPluginAbility("my-custom-code-ability"), "my-custom-code-ability");
  ```

  ```kotlin Kotlin theme={null}
  import org.sentrystudios.sentrypremades.registry.PremadeRegistry
  import org.sentrystudios.sentrypremades.api.ability.Ability
  import org.bukkit.entity.Entity
  import org.bukkit.Location

  class MyPluginAbility(id: String) : Ability(id) {
      override fun onExecute(caster: Entity, location: Location?): Boolean {
          caster.sendMessage("Executed purely from code!")
          return true
      }
  }

  // In your plugin's onEnable():
  PremadeRegistry.register(MyPluginAbility("my-custom-code-ability"), "my-custom-code-ability")
  ```
</CodeGroup>

### Auto-Registering Bukkit Listeners

When developing complex abilities, you'll often need to listen to Bukkit events. SentryPremades makes this incredibly simple.

If your custom `Ability` or `Event` class implements `org.bukkit.event.Listener`, the `PremadeRegistry` will **automatically register** your event handlers when the ability is loaded, and **automatically unregister** them when the plugin reloads or the ability is removed!

<CodeGroup>
  ```java Java theme={null}
  import org.bukkit.event.Listener;
  import org.bukkit.event.entity.EntityDamageEvent;
  import org.bukkit.event.EventHandler;

  public class MyListenerAbility extends Ability implements Listener {
      public MyListenerAbility(String id) {
          super(id);
      }

      @Override
      public boolean onExecute(Entity caster, Location location) {
          return true;
      }

      // This is automatically registered to Bukkit upon PremadeRegistry.register()!
      @EventHandler
      public void onDamage(EntityDamageEvent event) {
          // Handle logic...
      }
  }
  ```

  ```kotlin Kotlin theme={null}
  import org.bukkit.event.Listener
  import org.bukkit.event.entity.EntityDamageEvent
  import org.bukkit.event.EventHandler

  class MyListenerAbility(id: String) : Ability(id), Listener {
      override fun onExecute(caster: Entity, location: Location?): Boolean {
          return true
      }

      // This is automatically registered to Bukkit upon PremadeRegistry.register()!
      @EventHandler
      fun onDamage(event: EntityDamageEvent) {
          // Handle logic...
      }
  }
  ```
</CodeGroup>

***

## Querying the Registry

You can also retrieve all currently registered premades to build your own GUIs, tools, or integrations dynamically.

<CodeGroup>
  ```java Java theme={null}
  import org.sentrystudios.sentrypremades.registry.PremadeRegistry;
  import org.sentrystudios.sentrypremades.api.ability.Ability;
  import java.util.List;

  // Get a list of all loaded ability IDs
  List<String> abilityNames = PremadeRegistry.INSTANCE.getAbilityNames();

  // Get the actual Ability instance by ID
  Ability ability = PremadeRegistry.INSTANCE.getAbility("flaming-shot");

  // Unregister an ability programmatically
  PremadeRegistry.INSTANCE.unregisterAbility("flaming-shot");
  ```

  ```kotlin Kotlin theme={null}
  import org.sentrystudios.sentrypremades.registry.PremadeRegistry

  // Get a list of all loaded ability IDs
  val abilityNames = PremadeRegistry.getAbilityNames()

  // Get the actual Ability instance by ID
  val ability = PremadeRegistry.getAbility("flaming-shot")

  // Unregister an ability programmatically
  PremadeRegistry.unregisterAbility("flaming-shot")
  ```
</CodeGroup>
