1
mirror of https://github.com/StarWishsama/Slimefun4.git synced 2024-09-19 19:25:48 +00:00
This commit is contained in:
TheBusyBiscuit 2021-04-03 14:01:48 +02:00
parent 5b517ea1b1
commit 5e87df873c
3 changed files with 85 additions and 7 deletions

View File

@ -60,7 +60,7 @@
* Fixed #2650
* Fixed Slimefun items applying damage to items with an `unbreakable` tag
* Fixed #2930
* Fixed #2837
* Fixed #2926
## Release Candidate 21 (14 Mar 2021)
https://thebusybiscuit.github.io/builds/TheBusyBiscuit/Slimefun4/stable/#21

View File

@ -1,6 +1,8 @@
package io.github.thebusybiscuit.slimefun4.implementation.items.autocrafters;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Predicate;
@ -24,9 +26,9 @@ import org.bukkit.inventory.InventoryHolder;
import org.bukkit.inventory.ItemStack;
import io.github.thebusybiscuit.cscorelib2.data.PersistentDataAPI;
import io.github.thebusybiscuit.cscorelib2.inventory.ItemUtils;
import io.github.thebusybiscuit.cscorelib2.item.CustomItem;
import io.github.thebusybiscuit.cscorelib2.protection.ProtectableAction;
import io.github.thebusybiscuit.slimefun4.api.MinecraftVersion;
import io.github.thebusybiscuit.slimefun4.api.SlimefunAddon;
import io.github.thebusybiscuit.slimefun4.api.items.ItemState;
import io.github.thebusybiscuit.slimefun4.core.attributes.EnergyNetComponent;
@ -415,6 +417,7 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
// Check if we have an empty slot
if (inv.firstEmpty() != -1) {
Map<Integer, Integer> itemQuantities = new HashMap<>();
List<ItemStack> leftoverItems = new ArrayList<>();
for (Predicate<ItemStack> predicate : recipe.getIngredients()) {
// Check if any Item matches the Predicate
@ -429,19 +432,71 @@ public abstract class AbstractAutoCrafter extends SlimefunItem implements Energy
// Double-check to be extra safe
if (item != null) {
// Consume the difference
int toRemove = item.getAmount() - entry.getValue();
ItemUtils.consumeItem(item, toRemove, true);
// Handle leftovers
ItemStack leftover = getLeftoverItem(item);
if (leftover != null) {
// Account for the amount of removed items
leftover.setAmount(item.getAmount() - entry.getValue());
leftoverItems.add(leftover);
}
// Update the item amount
item.setAmount(entry.getValue());
}
}
// All Predicates have found a match
return inv.addItem(recipe.getResult().clone()).isEmpty();
boolean success = inv.addItem(recipe.getResult().clone()).isEmpty();
if (success) {
// Fixes #2926 - Push leftover items to the inventory.
for (ItemStack leftoverItem : leftoverItems) {
inv.addItem(leftoverItem);
}
}
return success;
}
return false;
}
/**
* This method returns the "leftovers" from a crafting operation.
* The method functions very similarly to {@link Material#getCraftingRemainingItem()}.
* However we cannot use this method as it is only available in the latest 1.16 snapshots
* of Spigot, not even on earlier 1.16 builds...
* But this gives us more control over the leftovers anyway!
*
* @param item
* The {@link ItemStack} that is being consumed
*
* @return The leftover item or null if the item is fully consumed
*/
@Nullable
private ItemStack getLeftoverItem(@Nonnull ItemStack item) {
Material type = item.getType();
switch (type) {
case WATER_BUCKET:
case LAVA_BUCKET:
case MILK_BUCKET:
return new ItemStack(Material.BUCKET);
case DRAGON_BREATH:
case POTION:
return new ItemStack(Material.GLASS_BOTTLE);
default:
MinecraftVersion minecraftVersion = SlimefunPlugin.getMinecraftVersion();
// Honey does not exist in 1.14
if (minecraftVersion.isAtLeast(MinecraftVersion.MINECRAFT_1_15) && type == Material.HONEY_BOTTLE) {
return new ItemStack(Material.GLASS_BOTTLE);
} else {
return null;
}
}
}
/**
* This method returns the max amount of electricity this machine can hold.
*

View File

@ -98,6 +98,29 @@ class TestAutoCrafter {
Assertions.assertFalse(inv.containsAtLeast(result, 1));
}
@Test
@DisplayName("Test resource leftovers when crafting")
void testResourceLeftovers() {
NamespacedKey key = new NamespacedKey(plugin, "resource_leftovers_test");
ItemStack result = new CustomItem(Material.DIAMOND, "&9Diamond. Nuff said.");
ShapelessRecipe recipe = new ShapelessRecipe(key, result);
recipe.addIngredient(new MaterialChoice(Material.HONEY_BOTTLE));
recipe.addIngredient(new MaterialChoice(Material.HONEY_BOTTLE));
AbstractRecipe abstractRecipe = AbstractRecipe.of(recipe);
AbstractAutoCrafter crafter = getVanillaAutoCrafter();
InventoryMock inv = new ChestInventoryMock(null, 9);
inv.addItem(new ItemStack(Material.HONEY_BOTTLE, 2));
Assertions.assertTrue(crafter.craft(inv, abstractRecipe));
Assertions.assertFalse(inv.contains(Material.HONEY_BOTTLE, 2));
Assertions.assertTrue(inv.containsAtLeast(result, 1));
// Check for leftovers
Assertions.assertTrue(inv.contains(Material.GLASS_BOTTLE, 2));
}
@Test
@DisplayName("Test crafting an invalid ShapelessRecipe")
void testInvalidShapelessRecipe() {