Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public void onEnable() {
instance = this;

getServer().getPluginManager().registerEvents(new ItemsManager(), this);
getServer().getPluginManager().registerEvents(new RecipesManager(), this);

getLifecycleManager().registerEventHandler(LifecycleEvents.COMMANDS, commands ->
commands.registrar().register(Commands.literal("contentapi")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.github.kiber2009.plugin.contentapi;

import io.github.kiber2009.plugin.contentapi.api.recipe.CustomCraftingRecipe;
import io.github.kiber2009.plugin.contentapi.registry.recipe.RecipeGlobalRegistry;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.inventory.PrepareItemCraftEvent;

final class RecipesManager implements Listener {
@EventHandler
private static void onPrepareItemCraft(final PrepareItemCraftEvent event) {
if (event.isRepair())
return;

final CustomCraftingRecipe recipe = RecipeGlobalRegistry.CRAFTING.get(event.getInventory().getMatrix());
if (recipe != null)
event.getInventory().setResult(recipe.getResult());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package io.github.kiber2009.plugin.contentapi.api.recipe;

import org.bukkit.inventory.ItemStack;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.function.Predicate;

public interface CustomCraftingRecipe extends CustomRecipe, Predicate<@Nullable ItemStack @NonNull []> {}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
package io.github.kiber2009.plugin.contentapi.api.recipe;

import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NonNull;

public interface CustomRecipe {
@Contract(pure = true)
@NonNull ItemStack getResult();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package io.github.kiber2009.plugin.contentapi.api.recipe.choice;

import io.github.kiber2009.plugin.contentapi.api.item.CustomItem;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.function.Predicate;

public class CustomItemRecipeChoice implements Predicate<@Nullable ItemStack> {
private final CustomItem item;

public CustomItemRecipeChoice(final @NonNull CustomItem item) {
this.item = item;
}

@Override
@Contract(value = "null -> false", pure = true)
public boolean test(final @Nullable ItemStack stack) {
return item.match(stack);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package io.github.kiber2009.plugin.contentapi.api.recipe.crafting;

import io.github.kiber2009.plugin.contentapi.api.recipe.CustomCraftingRecipe;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.function.Predicate;

public class CustomShapedCraftingRecipe implements CustomCraftingRecipe {
private static final byte[][] OFFSETS = {{0, 0}, {0, 1}, {1, 0}, {1, 1}};

private final ItemStack result;
private final Predicate<ItemStack>[] matrix;

public CustomShapedCraftingRecipe(final @NonNull Predicate<@Nullable ItemStack> @NonNull [] matrix,
final @NonNull ItemStack result) {
if (matrix.length != 4 && matrix.length != 9)
throw new IllegalArgumentException("Invalid matrix size");
this.matrix = matrix;
this.result = result;
}

@Override
@Contract(pure = true)
public @NonNull ItemStack getResult() {
return result.clone();
}

@Override
@Contract(pure = true)
public boolean test(final @Nullable ItemStack @NonNull [] matrix) {
if (matrix.length == 4 && this.matrix.length == 9)
return false;

if (matrix.length == this.matrix.length) {
for (int i = 0; i < matrix.length; i++)
if (!this.matrix[i].test(matrix[i]))
return false;
return true;
}

for (final byte[] off : OFFSETS) {
boolean fits = true;

for (int i = 0; i < 2 && fits; i++)
for (int j = 0; j < 2; j++)
if (!this.matrix[(off[0] + i) * 3 + off[1] + j].test(matrix[i * 2 + j])) {
fits = false;
break;
}

if (fits)
return true;
}
return false;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package io.github.kiber2009.plugin.contentapi.api.recipe.crafting;

import io.github.kiber2009.plugin.contentapi.api.recipe.CustomCraftingRecipe;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

import java.util.function.Predicate;

public class CustomShapelessCraftingRecipe implements CustomCraftingRecipe {
private final ItemStack result;
private final Predicate<ItemStack>[] ingredients;

@SafeVarargs
public CustomShapelessCraftingRecipe(final @NonNull ItemStack result,
final @NonNull Predicate<@NonNull ItemStack> @NonNull ... ingredients) {
if (ingredients.length > 9)
throw new IllegalArgumentException("Too many ingredients");
this.result = result;
this.ingredients = ingredients;
}

@Override
@Contract(pure = true)
public @NonNull ItemStack getResult() {
return result.clone();
}

@Override
@Contract(pure = true)
public boolean test(final @Nullable ItemStack @NonNull [] matrix) {
if (matrix.length < ingredients.length)
return false;

final boolean[] used = new boolean[ingredients.length];
int usedCount = 0;

for (final ItemStack elem : matrix) {
if (elem == null)
continue;

boolean found = false;
for (int i = 0; i < ingredients.length; i++)
if (!used[i] && ingredients[i].test(elem)) {
used[i] = true;
usedCount++;
found = true;
break;
}

if (!found)
return false;
}

return usedCount == ingredients.length;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,19 @@
import java.util.Objects;
import java.util.Set;

public sealed class GlobalRegistry<T> permits ItemGlobalRegistry {
public class GlobalRegistry<T> {
@SuppressWarnings("StaticInitializerReferencesSubClass")
public static final ItemGlobalRegistry ITEMS = new ItemGlobalRegistry();

private final Map<NamespacedKey, T> map = new HashMap<>();
protected final Map<NamespacedKey, T> map = new HashMap<>();

protected void registerItem(final @NonNull NamespacedKey key, final @NonNull T value) {
if (map.containsKey(key))
throw new IllegalStateException("Duplicate key " + key);
map.put(key, value);
}

public void register(final @NonNull LocalRegistry<T> registry) {
public void register(final @NonNull LocalRegistry<? extends T> registry) {
for (final NamespacedKey key : registry.keySet())
registerItem(key, Objects.requireNonNull(registry.get(key)));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package io.github.kiber2009.plugin.contentapi.registry.recipe;

import io.github.kiber2009.plugin.contentapi.api.recipe.CustomCraftingRecipe;
import org.bukkit.inventory.ItemStack;
import org.jetbrains.annotations.Contract;
import org.jspecify.annotations.NonNull;
import org.jspecify.annotations.Nullable;

public final class CraftingRecipeGlobalRegistry extends RecipeGlobalRegistry<CustomCraftingRecipe> {
CraftingRecipeGlobalRegistry() {
}

@Contract(pure = true)
public @Nullable CustomCraftingRecipe get(final @Nullable ItemStack @NonNull [] matrix) {
for (final CustomCraftingRecipe recipe : map.values())
if (recipe.test(matrix))
return recipe;
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package io.github.kiber2009.plugin.contentapi.registry.recipe;

import io.github.kiber2009.plugin.contentapi.api.recipe.CustomRecipe;
import io.github.kiber2009.plugin.contentapi.registry.GlobalRegistry;

public sealed class RecipeGlobalRegistry<T extends CustomRecipe> extends GlobalRegistry<T>
permits CraftingRecipeGlobalRegistry {
@SuppressWarnings("StaticInitializerReferencesSubClass")
public static final CraftingRecipeGlobalRegistry CRAFTING = new CraftingRecipeGlobalRegistry();

RecipeGlobalRegistry() {
}
}
Loading