Events
CustomCrafterAPI Events
Section titled “CustomCrafterAPI Events”CustomCrafterAPI fires several custom events that implement Bukkit’s Event.
These can be listened to and handled in the same way as ordinary Bukkit events.
RegisterCustomRecipeEvent
Section titled “RegisterCustomRecipeEvent”Fired when a recipe is about to be registered via CustomCrafterAPI.registerRecipe().
Implements Cancellable; cancelling the event causes the recipe registration to fail.
| Property | Type | Description |
|---|---|---|
recipes | List<CRecipe> | The list of recipes that are about to be registered |
class RecipeRegisterListener : Listener { @EventHandler fun onRegister(event: RegisterCustomRecipeEvent) { event.recipes.forEach { recipe -> println("Recipe registered: ${recipe.name}") }
// Example: cancel registration of recipes whose name starts with "forbidden-" if (event.recipes.any { it.name.startsWith("forbidden-") }) { event.isCancelled = true println("Registration cancelled.") } }}UnregisterCustomRecipeEvent
Section titled “UnregisterCustomRecipeEvent”Fired when a recipe is about to be unregistered via CustomCrafterAPI.unregisterRecipe() or CustomCrafterAPI.unregisterAllRecipes().
Implements Cancellable; cancelling the event causes the recipe unregistration to fail.
| Property | Type | Description |
|---|---|---|
recipes | List<CRecipe> | The list of recipes that are about to be unregistered |
class RecipeUnregisterListener : Listener { @EventHandler fun onUnregister(event: UnregisterCustomRecipeEvent) { event.recipes.forEach { recipe -> println("Recipe unregistered: ${recipe.name}") }
// Example: prevent a specific recipe from being unregistered if (event.recipes.any { it.name == "protected-recipe" }) { event.isCancelled = true } }}CreateCustomItemEvent
Section titled “CreateCustomItemEvent”Fired when an item is crafted (i.e., a craft operation is executed). This event is not cancellable.
| Property | Type | Description |
|---|---|---|
player | Player | The player who performed the craft |
view | CraftView | The UI input state at the time of crafting |
result | Search.SearchResult? | The search result. null indicates the craft did not succeed |
shiftUsed | Boolean | Whether the player bulk-crafted by holding Shift (since 5.0.17) |
isAsync | Boolean | Whether the call originated from an asynchronous thread (since 5.0.17) |
class CreateItemListener : Listener { @EventHandler fun onCreateItem(event: CreateCustomItemEvent) { val result = event.result ?: return
// Log the name of the custom recipe that was crafted result.customs().forEach { (recipe, _) -> println("${event.player.name} crafted ${recipe.name}.") }
// Example: perform additional processing when bulk-crafting if (event.shiftUsed) { println("Bulk crafting was used.") } }}CustomCrafterAPIPropertiesChangeEvent
Section titled “CustomCrafterAPIPropertiesChangeEvent”Fired when a mutable property (configuration value) of CustomCrafterAPI is changed.
Both the old and new values are included.
This event is generic and carries the type T of the changed property.
| Property | Type | Description |
|---|---|---|
propertyName | String | The name of the changed property |
oldValue | Property<T> | The value before the change |
newValue | Property<T> | The value after the change |
isAsync | Boolean | Whether the change originated from an asynchronous thread |
To extract a value from Property<T> in a type-safe manner, use PropertyKey<T>.
val key = CustomCrafterAPIPropertiesChangeEvent.PropertyKey.BASE_BLOCKval value: Material? = property.getOrNull(key)The predefined PropertyKey values are as follows:
| Key | Corresponding Type | Corresponding Property |
|---|---|---|
RESULT_GIVE_CANCEL | Boolean | ResultGiveCancel |
BASE_BLOCK | Material | BaseBlock |
USE_MULTIPLE_RESULT_CANDIDATE_FEATURE | Boolean | UseMultipleResultCandidateFeature |
USE_CUSTOM_CRAFT_UI | Boolean | UseCustomCraftUI |
BASE_BLOCK_SIDE | Int | BaseBlockSide |
CRAFT_UI_DESIGNER | CraftUIDesigner | CraftUIDesigner |
Example: Detecting a Base Block Change
Section titled “Example: Detecting a Base Block Change”class PropertiesChangeListener : Listener { @EventHandler fun <T> onPropertiesChange(event: CustomCrafterAPIPropertiesChangeEvent<T>) { val key = CustomCrafterAPIPropertiesChangeEvent.PropertyKey.BASE_BLOCK
// Filter to only the relevant event by property name if (event.propertyName != key.propertyName) return
val oldBlock: Material = event.oldValue.getOrNull(key) ?: return val newBlock: Material = event.newValue.getOrNull(key) ?: return
println("Base block changed from ${oldBlock.name} to ${newBlock.name}.") }}Example: Monitoring Multiple Properties Together
Section titled “Example: Monitoring Multiple Properties Together”class AllPropertiesChangeListener : Listener { @EventHandler fun <T> onPropertiesChange(event: CustomCrafterAPIPropertiesChangeEvent<T>) { when (event.propertyName) { CustomCrafterAPIPropertiesChangeEvent.PropertyKey.BASE_BLOCK.propertyName -> { val newValue = event.newValue.getOrNull( CustomCrafterAPIPropertiesChangeEvent.PropertyKey.BASE_BLOCK ) println("Base block changed: $newValue") } CustomCrafterAPIPropertiesChangeEvent.PropertyKey.USE_CUSTOM_CRAFT_UI.propertyName -> { val newValue = event.newValue.getOrNull( CustomCrafterAPIPropertiesChangeEvent.PropertyKey.USE_CUSTOM_CRAFT_UI ) println("Custom UI enabled: $newValue") } } }}