diff --git a/gradle.properties b/gradle.properties index 0b95439..720ee27 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,3 +1,3 @@ group=com.mineinabyss version=0.10 -idofrontVersion=0.18.11 +idofrontVersion=0.18.14 diff --git a/src/main/kotlin/com/mineinabyss/looty/features/recipes/DenyInVanillaRecipe.kt b/src/main/kotlin/com/mineinabyss/looty/features/recipes/DenyInVanillaRecipe.kt new file mode 100644 index 0000000..d34c5ee --- /dev/null +++ b/src/main/kotlin/com/mineinabyss/looty/features/recipes/DenyInVanillaRecipe.kt @@ -0,0 +1,12 @@ +package com.mineinabyss.looty.features.recipes + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable + +/** + * A component to indicate that an ItemStack should not be allowed in vanilla crafting recipes. + * Meaning if a GearyItem has a base-material of PAPER and this component, it cannot be used to craft books. + */ +@Serializable +@SerialName("looty:deny_in_vanilla_recipes") +class DenyInVanillaRecipes diff --git a/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipeSystem.kt b/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipeQuery.kt similarity index 61% rename from src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipeSystem.kt rename to src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipeQuery.kt index 6c03d29..8a38230 100644 --- a/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipeSystem.kt +++ b/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipeQuery.kt @@ -1,6 +1,5 @@ package com.mineinabyss.looty.features.recipes -import com.mineinabyss.geary.papermc.gearyPaper import com.mineinabyss.geary.papermc.tracking.items.gearyItems import com.mineinabyss.geary.prefabs.PrefabKey import com.mineinabyss.geary.systems.accessors.TargetScope @@ -9,47 +8,37 @@ import com.mineinabyss.idofront.recipes.register import com.mineinabyss.looty.config.looty import org.bukkit.Bukkit import org.bukkit.NamespacedKey -import org.bukkit.event.EventHandler -import org.bukkit.event.Listener -import org.bukkit.event.player.PlayerJoinEvent import org.bukkit.inventory.ItemStack class ItemRecipeQuery : Query() { - private val TargetScope.setRecipes by get() + private val TargetScope.recipes by get() private val TargetScope.prefabKey by get() fun TargetScope.registerRecipes(): Set { val discoveredRecipes = mutableSetOf() - val result: ItemStack? = setRecipes.result?.toItemStackOrNull() ?: gearyItems.createItem(prefabKey) + val result: ItemStack? = recipes.result?.toItemStackOrNull() ?: gearyItems.createItem(prefabKey) if (result == null) { looty.plugin.logger.warning("Recipe ${prefabKey.key} is missing result item") return emptySet() } - setRecipes.removeRecipes.forEach { + recipes.removeRecipes.forEach { runCatching { Bukkit.removeRecipe(NamespacedKey.fromString(it)!!) }.onFailure { it.printStackTrace() } } - setRecipes.recipes.forEachIndexed { i, recipe -> + recipes.recipes.forEachIndexed { i, recipe -> runCatching { val key = NamespacedKey(prefabKey.namespace, "${prefabKey.key}$i") // Register recipe only if not present - Bukkit.getRecipe(key) ?: recipe.toRecipe(key, result, setRecipes.group).register() - if (setRecipes.discoverRecipes) discoveredRecipes += key - }.onFailure { it.printStackTrace() } + Bukkit.getRecipe(key) ?: recipe.toRecipe(key, result, recipes.group).register() + if (recipes.discoverRecipes) discoveredRecipes += key + }.onFailure { + looty.plugin.logger.warning("Failed to register recipe ${prefabKey.key} #$i, ${it.message}") + } } return discoveredRecipes } } - -class RecipeDiscoverySystem( - val discoveredRecipes: List -): Listener { - @EventHandler - fun PlayerJoinEvent.showRecipesOnJoin() { - player.discoverRecipes(discoveredRecipes) - } -} diff --git a/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipes.kt b/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipes.kt index 2183594..ddfa47d 100644 --- a/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipes.kt +++ b/src/main/kotlin/com/mineinabyss/looty/features/recipes/ItemRecipes.kt @@ -20,7 +20,10 @@ interface ItemRecipes { flatMap { it.registerRecipes() } } - gearyPaper.plugin.listeners(RecipeDiscoverySystem(autoDiscoveredRecipes)) + gearyPaper.plugin.listeners( + RecipeDiscoverySystem(autoDiscoveredRecipes), + RecipeCraftingSystem(), + ) } } } diff --git a/src/main/kotlin/com/mineinabyss/looty/features/recipes/RecipeCraftingSystem.kt b/src/main/kotlin/com/mineinabyss/looty/features/recipes/RecipeCraftingSystem.kt new file mode 100644 index 0000000..0c69200 --- /dev/null +++ b/src/main/kotlin/com/mineinabyss/looty/features/recipes/RecipeCraftingSystem.kt @@ -0,0 +1,30 @@ +package com.mineinabyss.looty.features.recipes + +import com.mineinabyss.geary.papermc.datastore.decodePrefabs +import org.bukkit.Keyed +import org.bukkit.event.EventHandler +import org.bukkit.event.EventPriority +import org.bukkit.event.Listener +import org.bukkit.event.inventory.PrepareItemCraftEvent + +class RecipeCraftingSystem : Listener { + /** + * Prevents custom items being usable in vanilla recipes based on their material, + * when they have a [DenyInVanillaRecipes] component, by setting result to null. + */ + @EventHandler(priority = EventPriority.HIGHEST) + fun PrepareItemCraftEvent.onCraftWithCustomItem() { + // Ensure this only cancels vanilla recipes + if (recipe == null || (recipe as? Keyed)?.key()?.namespace() != "minecraft") return + + if (inventory.matrix.any { + it?.itemMeta?.persistentDataContainer + ?.decodePrefabs() + ?.firstOrNull() + ?.toEntityOrNull() + ?.has() == true + }) { + inventory.result = null + } + } +} diff --git a/src/main/kotlin/com/mineinabyss/looty/features/recipes/RecipeDiscoverySystem.kt b/src/main/kotlin/com/mineinabyss/looty/features/recipes/RecipeDiscoverySystem.kt new file mode 100644 index 0000000..12bc1d0 --- /dev/null +++ b/src/main/kotlin/com/mineinabyss/looty/features/recipes/RecipeDiscoverySystem.kt @@ -0,0 +1,15 @@ +package com.mineinabyss.looty.features.recipes + +import org.bukkit.NamespacedKey +import org.bukkit.event.EventHandler +import org.bukkit.event.Listener +import org.bukkit.event.player.PlayerJoinEvent + +class RecipeDiscoverySystem( + val discoveredRecipes: List +) : Listener { + @EventHandler + fun PlayerJoinEvent.showRecipesOnJoin() { + player.discoverRecipes(discoveredRecipes) + } +}