Fixed crafting, deprecated now-unneeded API
This commit is contained in:
@@ -106,15 +106,13 @@ import com.willfp.eco.internal.spigot.integrations.mcmmo.McmmoIntegrationImpl
|
||||
import com.willfp.eco.internal.spigot.integrations.multiverseinventories.MultiverseInventoriesIntegration
|
||||
import com.willfp.eco.internal.spigot.integrations.shop.ShopShopGuiPlus
|
||||
import com.willfp.eco.internal.spigot.math.evaluateExpression
|
||||
import com.willfp.eco.internal.spigot.proxy.BlockBreakProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.FastItemStackFactoryProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.SkullProxy
|
||||
import com.willfp.eco.internal.spigot.proxy.TPSProxy
|
||||
import com.willfp.eco.internal.spigot.recipes.ShapedRecipeListener
|
||||
import com.willfp.eco.internal.spigot.recipes.StackedRecipeListener
|
||||
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInComplex
|
||||
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInEco
|
||||
import com.willfp.eco.internal.spigot.recipes.listeners.ComplexInVanilla
|
||||
import com.willfp.eco.util.BlockUtils
|
||||
import com.willfp.eco.util.NumberUtils
|
||||
import com.willfp.eco.util.ServerUtils
|
||||
import com.willfp.eco.util.SkullUtils
|
||||
@@ -158,7 +156,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
Entities.registerArgParser(EntityArgParserEquipment())
|
||||
|
||||
ShapedRecipeListener.registerListener(ComplexInComplex())
|
||||
ShapedRecipeListener.registerListener(ComplexInEco())
|
||||
ShapedRecipeListener.registerListener(ComplexInVanilla())
|
||||
|
||||
SegmentParserGroup().register()
|
||||
@@ -170,9 +167,6 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
{ meta -> skullProxy.getSkullTexture(meta) }
|
||||
)
|
||||
|
||||
val blockBreakProxy = getProxy(BlockBreakProxy::class.java)
|
||||
BlockUtils.initialize { player, block -> blockBreakProxy.breakBlock(player, block) }
|
||||
|
||||
val tpsProxy = getProxy(TPSProxy::class.java)
|
||||
ServerUtils.initialize { tpsProxy.getTPS() }
|
||||
|
||||
@@ -322,6 +316,7 @@ abstract class EcoSpigotPlugin : EcoPlugin() {
|
||||
ArmorListener(),
|
||||
EntityDeathByEntityListeners(this),
|
||||
ShapedRecipeListener(),
|
||||
StackedRecipeListener(this),
|
||||
GUIListener(this),
|
||||
ArrowDataListener(this),
|
||||
ArmorChangeEventListeners(this),
|
||||
|
||||
@@ -2,95 +2,14 @@ package com.willfp.eco.internal.spigot.recipes
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.recipe.Recipes
|
||||
import com.willfp.eco.core.recipe.parts.TestableStack
|
||||
import org.bukkit.Keyed
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.CraftItemEvent
|
||||
import org.bukkit.event.inventory.PrepareItemCraftEvent
|
||||
import org.bukkit.event.player.PlayerRecipeDiscoverEvent
|
||||
import org.bukkit.inventory.ShapedRecipe
|
||||
|
||||
class ShapedRecipeListener : Listener {
|
||||
@EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true)
|
||||
fun stackedRecipeListener(event: CraftItemEvent) {
|
||||
val recipe = event.recipe as? ShapedRecipe ?: return
|
||||
|
||||
if (!EcoPlugin.getPluginNames().contains(recipe.key.namespace)) {
|
||||
return
|
||||
}
|
||||
|
||||
val matrix = event.inventory.matrix
|
||||
|
||||
val wrapped = WrappedCraftItemEvent(event)
|
||||
|
||||
if (validators.any { it.validate(wrapped) }) {
|
||||
return
|
||||
}
|
||||
|
||||
val matched = Recipes.getMatch(matrix)
|
||||
|
||||
if (matched == null) {
|
||||
wrapped.deny()
|
||||
return
|
||||
}
|
||||
|
||||
var isStackedRecipe = false
|
||||
var upperBound = 64
|
||||
for (i in 0..8) {
|
||||
val inMatrix = event.inventory.matrix.getOrNull(i)
|
||||
val inRecipe = matched.parts[i]
|
||||
|
||||
if (inRecipe is TestableStack) {
|
||||
val max = Math.floorDiv(inMatrix!!.amount, inRecipe.amount)
|
||||
if (max < upperBound) {
|
||||
upperBound = max
|
||||
}
|
||||
isStackedRecipe = true
|
||||
} else if (inMatrix != null) {
|
||||
val max = inMatrix.amount
|
||||
if (max < upperBound) {
|
||||
upperBound = max
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!isStackedRecipe) {
|
||||
return
|
||||
}
|
||||
|
||||
val toGivePerRecipe = event.recipe.result.amount
|
||||
val maxStackSize = event.recipe.result.maxStackSize
|
||||
while (toGivePerRecipe * upperBound > maxStackSize) {
|
||||
upperBound--
|
||||
}
|
||||
|
||||
for (i in 0..8) {
|
||||
val inMatrix = event.inventory.matrix[i]
|
||||
val inRecipe = matched.parts[i]
|
||||
|
||||
if (inRecipe is TestableStack) {
|
||||
if (event.isShiftClick) {
|
||||
var amount = inMatrix.amount + 1
|
||||
for (j in 0..upperBound) {
|
||||
amount -= inRecipe.amount
|
||||
}
|
||||
inMatrix.amount = amount
|
||||
} else {
|
||||
inMatrix.amount = inMatrix.amount - (inRecipe.amount - 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (event.isShiftClick) {
|
||||
val result = event.inventory.result ?: return
|
||||
|
||||
result.amount = result.amount * upperBound
|
||||
event.inventory.result = result
|
||||
}
|
||||
}
|
||||
|
||||
@EventHandler
|
||||
fun preventLearningDisplayedRecipes(event: PlayerRecipeDiscoverEvent) {
|
||||
if (!EcoPlugin.getPluginNames().contains(event.recipe.namespace)) {
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.willfp.eco.internal.spigot.recipes
|
||||
|
||||
import com.willfp.eco.core.EcoPlugin
|
||||
import com.willfp.eco.core.recipe.Recipes
|
||||
import com.willfp.eco.core.recipe.parts.GroupedTestableItems
|
||||
import com.willfp.eco.core.recipe.parts.TestableStack
|
||||
import org.bukkit.Bukkit
|
||||
import org.bukkit.Material
|
||||
import org.bukkit.event.EventHandler
|
||||
import org.bukkit.event.EventPriority
|
||||
import org.bukkit.event.Listener
|
||||
import org.bukkit.event.inventory.InventoryClickEvent
|
||||
import org.bukkit.inventory.CraftingInventory
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
|
||||
class StackedRecipeListener(
|
||||
private val plugin: EcoPlugin
|
||||
) : Listener {
|
||||
@EventHandler(priority = EventPriority.HIGH, ignoreCancelled = true)
|
||||
fun handleStacks(event: InventoryClickEvent) {
|
||||
val inventory = event.clickedInventory as? CraftingInventory ?: return
|
||||
if (event.slot != 0) {
|
||||
return
|
||||
}
|
||||
|
||||
val matrix = inventory.matrix
|
||||
|
||||
val recipe = Recipes.getMatch(matrix) ?: return
|
||||
|
||||
var isStackedRecipe = false
|
||||
var maxCraftable = Int.MAX_VALUE
|
||||
|
||||
// Start by calculating the maximum number of items to craft
|
||||
for (i in 0..8) {
|
||||
val item = inventory.matrix.getOrNull(i) ?: continue
|
||||
val part = recipe.parts[i].let {
|
||||
if (it is GroupedTestableItems) {
|
||||
it.getMatchingChild(item)
|
||||
} else it
|
||||
} ?: continue
|
||||
|
||||
if (part is TestableStack) {
|
||||
isStackedRecipe = true
|
||||
}
|
||||
|
||||
maxCraftable = min(maxCraftable, Math.floorDiv(item.amount, part.item.amount))
|
||||
}
|
||||
|
||||
if (!isStackedRecipe) {
|
||||
return
|
||||
}
|
||||
|
||||
// Don't allow crafting above the max stack size of the output
|
||||
maxCraftable = min(maxCraftable, Math.floorDiv(recipe.output.maxStackSize, recipe.output.amount))
|
||||
|
||||
Bukkit.getLogger().info("Amount to craft: $maxCraftable")
|
||||
|
||||
// Deduct the correct number of items from the inventory
|
||||
for (i in 0..8) {
|
||||
val item = inventory.matrix.getOrNull(i) ?: continue
|
||||
val part = recipe.parts[i].let {
|
||||
if (it is GroupedTestableItems) {
|
||||
it.getMatchingChild(item)
|
||||
} else it
|
||||
} ?: continue
|
||||
|
||||
val amount = max(
|
||||
if (event.isShiftClick) {
|
||||
item.amount - (part.item.amount * maxCraftable)
|
||||
} else {
|
||||
item.amount - part.item.amount
|
||||
}, 0
|
||||
)
|
||||
|
||||
println("Setting amount of ${item.type} to $amount")
|
||||
|
||||
// Anti-Underflow
|
||||
if (amount == 0) {
|
||||
item.type = Material.AIR
|
||||
}
|
||||
item.amount = amount
|
||||
|
||||
val newItem = item.clone()
|
||||
|
||||
// Do it twice because spigot hates me
|
||||
// Everything has to be cloned because the inventory changes the item
|
||||
inventory.matrix[i] = item // Use un-cloned version first
|
||||
plugin.scheduler.run {
|
||||
println("Setting ${inventory.matrix[i]} to $newItem")
|
||||
inventory.matrix[i] = newItem
|
||||
inventory.setItem(i + 1, newItem)
|
||||
// Just to be safe, modify the instance (safe check) Using ?. causes a warning.
|
||||
if (inventory.matrix[i] != null) {
|
||||
inventory.matrix[i].amount = amount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Multiply the result by the amount to craft if shift-clicking
|
||||
if (event.isShiftClick) {
|
||||
val result = inventory.result ?: return
|
||||
|
||||
result.amount *= maxCraftable
|
||||
inventory.result = result
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,68 +0,0 @@
|
||||
package com.willfp.eco.internal.spigot.recipes.listeners
|
||||
|
||||
import com.willfp.eco.core.items.Items
|
||||
import com.willfp.eco.core.items.TestableItem
|
||||
import com.willfp.eco.core.recipe.Recipes
|
||||
import com.willfp.eco.core.recipe.parts.GroupedTestableItems
|
||||
import com.willfp.eco.core.recipe.parts.MaterialTestableItem
|
||||
import com.willfp.eco.core.recipe.parts.ModifiedTestableItem
|
||||
import com.willfp.eco.core.recipe.parts.TestableStack
|
||||
import com.willfp.eco.core.recipe.recipes.ShapedCraftingRecipe
|
||||
import com.willfp.eco.internal.spigot.recipes.GenericCraftEvent
|
||||
import com.willfp.eco.internal.spigot.recipes.RecipeListener
|
||||
import com.willfp.eco.internal.spigot.recipes.ShapedRecipeListener
|
||||
import org.bukkit.inventory.ItemStack
|
||||
|
||||
class ComplexInEco : RecipeListener {
|
||||
override fun handle(event: GenericCraftEvent) {
|
||||
val craftingRecipe = Recipes.getRecipe(event.recipe.key)
|
||||
|
||||
if (craftingRecipe !is ShapedCraftingRecipe) {
|
||||
return
|
||||
}
|
||||
|
||||
if (ShapedRecipeListener.validators.any { it.validate(event) }) {
|
||||
return
|
||||
}
|
||||
|
||||
for (i in 0..8) {
|
||||
val itemStack = event.inventory.matrix[i] ?: continue
|
||||
val part = craftingRecipe.parts[i]
|
||||
if (part.isCustomWhenShouldNotBe(itemStack)) {
|
||||
event.deny()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun TestableItem.isCustomWhenShouldNotBe(itemStack: ItemStack): Boolean {
|
||||
when (this) {
|
||||
is MaterialTestableItem -> {
|
||||
if (Items.isCustomItem(itemStack)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
is ModifiedTestableItem -> {
|
||||
if (this.handle is MaterialTestableItem) {
|
||||
if (Items.isCustomItem(itemStack)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
is TestableStack -> {
|
||||
if (this.handle is MaterialTestableItem) {
|
||||
if (Items.isCustomItem(itemStack)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
is GroupedTestableItems -> {
|
||||
// This will fail if and only if there is a complex item grouped with a simple item of the same type
|
||||
if (this.children.any { it.isCustomWhenShouldNotBe(itemStack) && it.matches(itemStack) }) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user