Skip to content

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.


Fired when a recipe is about to be registered via CustomCrafterAPI.registerRecipe(). Implements Cancellable; cancelling the event causes the recipe registration to fail.

PropertyTypeDescription
recipesList<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.")
}
}
}

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.

PropertyTypeDescription
recipesList<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
}
}
}

Fired when an item is crafted (i.e., a craft operation is executed). This event is not cancellable.

PropertyTypeDescription
playerPlayerThe player who performed the craft
viewCraftViewThe UI input state at the time of crafting
resultSearch.SearchResult?The search result. null indicates the craft did not succeed
shiftUsedBooleanWhether the player bulk-crafted by holding Shift (since 5.0.17)
isAsyncBooleanWhether 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.")
}
}
}

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.

PropertyTypeDescription
propertyNameStringThe name of the changed property
oldValueProperty<T>The value before the change
newValueProperty<T>The value after the change
isAsyncBooleanWhether 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_BLOCK
val value: Material? = property.getOrNull(key)

The predefined PropertyKey values are as follows:

KeyCorresponding TypeCorresponding Property
RESULT_GIVE_CANCELBooleanResultGiveCancel
BASE_BLOCKMaterialBaseBlock
USE_MULTIPLE_RESULT_CANDIDATE_FEATUREBooleanUseMultipleResultCandidateFeature
USE_CUSTOM_CRAFT_UIBooleanUseCustomCraftUI
BASE_BLOCK_SIDEIntBaseBlockSide
CRAFT_UI_DESIGNERCraftUIDesignerCraftUIDesigner
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")
}
}
}
}