Skip to content
This repository has been archived by the owner on May 27, 2024. It is now read-only.

Commit

Permalink
Prevent LootyItems in vanilla recipes (#49)
Browse files Browse the repository at this point in the history
* prevent LootyItems from being used in vanilla recipes

* changes

* Refactor so each system class is in its own file

* Slightly clean up indentation

* Don't check for SetItem component now that we explicitly deny using a component

* Only prevent usage in vanilla recipes

---------

Co-authored-by: Danielle Voznyy <[email protected]>
  • Loading branch information
Boy0000 and 0ffz authored Jul 1, 2023
1 parent d393452 commit 344b5ba
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 22 deletions.
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
group=com.mineinabyss
version=0.10
idofrontVersion=0.18.11
idofrontVersion=0.18.14
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
@@ -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
Expand All @@ -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<SetRecipes>()
private val TargetScope.recipes by get<SetRecipes>()
private val TargetScope.prefabKey by get<PrefabKey>()

fun TargetScope.registerRecipes(): Set<NamespacedKey> {
val discoveredRecipes = mutableSetOf<NamespacedKey>()
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<NamespacedKey>
): Listener {
@EventHandler
fun PlayerJoinEvent.showRecipesOnJoin() {
player.discoverRecipes(discoveredRecipes)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,10 @@ interface ItemRecipes {
flatMap { it.registerRecipes() }
}

gearyPaper.plugin.listeners(RecipeDiscoverySystem(autoDiscoveredRecipes))
gearyPaper.plugin.listeners(
RecipeDiscoverySystem(autoDiscoveredRecipes),
RecipeCraftingSystem(),
)
}
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<DenyInVanillaRecipes>() == true
}) {
inventory.result = null
}
}
}
Original file line number Diff line number Diff line change
@@ -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<NamespacedKey>
) : Listener {
@EventHandler
fun PlayerJoinEvent.showRecipesOnJoin() {
player.discoverRecipes(discoveredRecipes)
}
}

0 comments on commit 344b5ba

Please sign in to comment.