Skip to content

Commit

Permalink
Added support for enchantments in recipes
Browse files Browse the repository at this point in the history
  • Loading branch information
WillFP committed Jul 26, 2021
1 parent d860791 commit 625b981
Show file tree
Hide file tree
Showing 2 changed files with 121 additions and 6 deletions.
69 changes: 63 additions & 6 deletions eco-api/src/main/java/com/willfp/eco/core/items/Items.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,21 @@
package com.willfp.eco.core.items;

import com.willfp.eco.core.items.builder.ItemBuilder;
import com.willfp.eco.core.items.builder.ItemStackBuilder;
import com.willfp.eco.core.recipe.parts.EmptyTestableItem;
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.util.NamespacedKeyUtils;
import lombok.experimental.UtilityClass;
import org.bukkit.Material;
import org.bukkit.NamespacedKey;
import org.bukkit.enchantments.Enchantment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.meta.ItemMeta;
import org.jetbrains.annotations.NotNull;

import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
Expand Down Expand Up @@ -54,14 +60,21 @@ public void removeCustomItem(@NotNull final NamespacedKey key) {
* @return The found testable item, or an empty item if not found.
*/
public TestableItem lookup(@NotNull final String key) {
String[] split = key.toLowerCase().split(":");
String[] args = key.split(" ");
if (args.length == 0) {
return new EmptyTestableItem();
}

TestableItem item = null;

String[] split = args[0].toLowerCase().split(":");

if (split.length == 1) {
Material material = Material.getMaterial(key.toUpperCase());
if (material == null || material == Material.AIR) {
return new EmptyTestableItem();
}
return new MaterialTestableItem(material);
item = new MaterialTestableItem(material);
}

if (split.length == 2) {
Expand All @@ -72,18 +85,62 @@ public TestableItem lookup(@NotNull final String key) {
if (material == null || material == Material.AIR) {
return new EmptyTestableItem();
}
return new TestableStack(new MaterialTestableItem(material), Integer.parseInt(split[1]));
item = new TestableStack(new MaterialTestableItem(material), Integer.parseInt(split[1]));
} else {
return part;
item = part;
}
}

if (split.length == 3) {
CustomItem part = REGISTRY.get(NamespacedKeyUtils.create(split[0], split[1]));
return part == null ? new EmptyTestableItem() : new TestableStack(part, Integer.parseInt(split[2]));
item = part == null ? new EmptyTestableItem() : new TestableStack(part, Integer.parseInt(split[2]));
}

if (item == null || item instanceof EmptyTestableItem) {
return new EmptyTestableItem();
}

String[] enchantArgs = Arrays.copyOfRange(args, 1, args.length);

Map<Enchantment, Integer> requiredEnchantments = new HashMap<>();

for (String enchantArg : enchantArgs) {
String[] enchantArgSplit = enchantArg.split(":");

Enchantment enchantment = Enchantment.getByKey(NamespacedKey.minecraft(enchantArgSplit[0].toLowerCase()));
int level = Integer.parseInt(enchantArgSplit[1]);

requiredEnchantments.put(enchantment, level);
}

return new EmptyTestableItem();
ItemBuilder builder = new ItemStackBuilder(item.getItem());
requiredEnchantments.forEach(builder::addEnchantment);
ItemStack example = builder.build();

return new ModifiedTestableItem(
item,
itemStack -> {
if (!itemStack.hasItemMeta()) {
return false;
}

ItemMeta meta = itemStack.getItemMeta();

assert meta != null;

for (Map.Entry<Enchantment, Integer> entry : requiredEnchantments.entrySet()) {
if (!meta.hasEnchant(entry.getKey())) {
return false;
}
if (meta.getEnchantLevel(entry.getKey()) < entry.getValue()) {
return false;
}
}

return true;
},
example
);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package com.willfp.eco.core.recipe.parts;

import com.willfp.eco.core.items.TestableItem;
import lombok.Getter;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.function.Predicate;

public class ModifiedTestableItem implements TestableItem {
/**
* The item.
*/
private final TestableItem handle;

/**
* The amount.
*/
@Getter
private final Predicate<ItemStack> test;

/**
* The item for the modified test.
*/
private final ItemStack example;

/**
* Create a new modified testable item.
*
* @param item The item.
* @param test The test.
* @param example The example.
*/
public ModifiedTestableItem(@NotNull final TestableItem item,
@NotNull final Predicate<ItemStack> test,
@NotNull final ItemStack example) {
this.handle = item;
this.test = test;
this.example = example;
}

/**
* If the item matches the material.
*
* @param itemStack The item to test.
* @return If the item is of the specified material.
*/
@Override
public boolean matches(@Nullable final ItemStack itemStack) {
return itemStack != null && handle.matches(itemStack) && test.test(itemStack);
}

@Override
public ItemStack getItem() {
return example;
}
}

0 comments on commit 625b981

Please sign in to comment.