From 3b3c0249d25c35411cba0b56285151b501513692 Mon Sep 17 00:00:00 2001 From: Frank Date: Thu, 28 Jul 2022 18:29:33 +0200 Subject: [PATCH] [Feature] AlloyingRecipe --- .../interfaces/AlloyingRecipeWorkstation.java | 23 ++ .../betterx/bclib/recipes/AlloyingRecipe.java | 300 ++++++++++++++++++ 2 files changed, 323 insertions(+) create mode 100644 src/main/java/org/betterx/bclib/interfaces/AlloyingRecipeWorkstation.java create mode 100644 src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java diff --git a/src/main/java/org/betterx/bclib/interfaces/AlloyingRecipeWorkstation.java b/src/main/java/org/betterx/bclib/interfaces/AlloyingRecipeWorkstation.java new file mode 100644 index 00000000..44766e63 --- /dev/null +++ b/src/main/java/org/betterx/bclib/interfaces/AlloyingRecipeWorkstation.java @@ -0,0 +1,23 @@ +package org.betterx.bclib.interfaces; + +import net.minecraft.core.Registry; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.level.block.Block; +import net.minecraft.world.level.block.Blocks; + +import java.util.List; + +public interface AlloyingRecipeWorkstation { + static List getWorkstations() { + return Registry.BLOCK + .stream() + .filter(b -> b instanceof AlloyingRecipeWorkstation) + .toList(); + } + + static ItemStack getWorkstationIcon() { + var workstations = AlloyingRecipeWorkstation.getWorkstations(); + if (workstations.isEmpty()) return new ItemStack(Blocks.BARRIER); + return new ItemStack(workstations.get(0)); + } +} diff --git a/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java b/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java new file mode 100644 index 00000000..afda4629 --- /dev/null +++ b/src/main/java/org/betterx/bclib/recipes/AlloyingRecipe.java @@ -0,0 +1,300 @@ +package org.betterx.bclib.recipes; + +import org.betterx.bclib.BCLib; +import org.betterx.bclib.config.PathConfig; +import org.betterx.bclib.interfaces.AlloyingRecipeWorkstation; +import org.betterx.bclib.interfaces.UnknownReceipBookCategory; +import org.betterx.bclib.util.ItemUtil; +import org.betterx.bclib.util.RecipeHelper; + +import net.minecraft.core.NonNullList; +import net.minecraft.network.FriendlyByteBuf; +import net.minecraft.resources.ResourceLocation; +import net.minecraft.tags.TagKey; +import net.minecraft.util.GsonHelper; +import net.minecraft.world.Container; +import net.minecraft.world.item.Item; +import net.minecraft.world.item.ItemStack; +import net.minecraft.world.item.crafting.Ingredient; +import net.minecraft.world.item.crafting.Recipe; +import net.minecraft.world.item.crafting.RecipeSerializer; +import net.minecraft.world.item.crafting.RecipeType; +import net.minecraft.world.level.ItemLike; +import net.minecraft.world.level.Level; + +import net.fabricmc.api.EnvType; +import net.fabricmc.api.Environment; + +import com.google.gson.JsonArray; +import com.google.gson.JsonObject; + +public class AlloyingRecipe implements Recipe, UnknownReceipBookCategory { + public final static String GROUP = "alloying"; + public final static RecipeType TYPE = BCLRecipeManager.registerType(BCLib.MOD_ID, GROUP); + public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer( + BCLib.MOD_ID, + GROUP, + new Serializer() + ); + + protected final RecipeType type; + protected final ResourceLocation id; + protected final Ingredient primaryInput; + protected final Ingredient secondaryInput; + protected final ItemStack output; + protected final String group; + protected final float experience; + protected final int smeltTime; + + public AlloyingRecipe( + ResourceLocation id, + String group, + Ingredient primaryInput, + Ingredient secondaryInput, + ItemStack output, + float experience, + int smeltTime + ) { + this.group = group; + this.id = id; + this.primaryInput = primaryInput; + this.secondaryInput = secondaryInput; + this.output = output; + this.experience = experience; + this.smeltTime = smeltTime; + this.type = TYPE; + } + + public float getExperience() { + return this.experience; + } + + public int getSmeltTime() { + return this.smeltTime; + } + + @Override + public NonNullList getIngredients() { + NonNullList defaultedList = NonNullList.create(); + defaultedList.add(primaryInput); + defaultedList.add(secondaryInput); + + return defaultedList; + } + + @Override + public boolean matches(Container inv, Level world) { + return this.primaryInput.test(inv.getItem(0)) && this.secondaryInput.test(inv.getItem(1)) || this.primaryInput.test( + inv.getItem(1)) && this.secondaryInput.test(inv.getItem(0)); + } + + @Override + public ItemStack assemble(Container inv) { + return this.output.copy(); + } + + @Override + public boolean canCraftInDimensions(int width, int height) { + return true; + } + + @Override + public ItemStack getResultItem() { + return this.output; + } + + @Override + public ResourceLocation getId() { + return this.id; + } + + @Override + public RecipeSerializer getSerializer() { + return SERIALIZER; + } + + @Override + public RecipeType getType() { + return this.type; + } + + @Override + @Environment(EnvType.CLIENT) + public String getGroup() { + return this.group; + } + + @Environment(EnvType.CLIENT) + public ItemStack getToastSymbol() { + return AlloyingRecipeWorkstation.getWorkstationIcon(); + } + + public static class Builder { + private final static Builder INSTANCE = new Builder(); + private static boolean exist; + + protected static Builder create(ResourceLocation id, PathConfig config) { + INSTANCE.id = id; + INSTANCE.group = String.format("%s_%s", GROUP, id); + INSTANCE.primaryInput = null; + INSTANCE.secondaryInput = null; + INSTANCE.output = null; + INSTANCE.experience = 0.0F; + INSTANCE.smeltTime = 350; + exist = config.getBoolean("alloying", id.getPath(), true); + + return INSTANCE; + } + + protected static Builder create(String modID, String id, PathConfig config) { + return create(new ResourceLocation(modID, id), config); + } + + private ResourceLocation id; + private Ingredient primaryInput; + private Ingredient secondaryInput; + private ItemStack output; + private String group; + private float experience; + private int smeltTime; + private boolean alright = true; + + protected Builder() { + } + + public Builder setGroup(String group) { + this.group = group; + return this; + } + + public Builder setPrimaryInput(ItemLike... inputs) { + for (ItemLike item : inputs) { + this.alright &= RecipeHelper.exists(item); + } + this.primaryInput = Ingredient.of(inputs); + return this; + } + + public Builder setSecondaryInput(ItemLike... inputs) { + for (ItemLike item : inputs) { + this.alright &= RecipeHelper.exists(item); + } + this.secondaryInput = Ingredient.of(inputs); + return this; + } + + public Builder setPrimaryInput(TagKey input) { + this.primaryInput = Ingredient.of(input); + return this; + } + + public Builder setSecondaryInput(TagKey input) { + this.secondaryInput = Ingredient.of(input); + return this; + } + + public Builder setInput(ItemLike primaryInput, ItemLike secondaryInput) { + this.setPrimaryInput(primaryInput); + this.setSecondaryInput(secondaryInput); + return this; + } + + public Builder setInput(TagKey primaryInput, TagKey secondaryInput) { + this.setPrimaryInput(primaryInput); + this.setSecondaryInput(secondaryInput); + return this; + } + + public Builder setOutput(ItemLike output, int amount) { + this.alright &= RecipeHelper.exists(output); + this.output = new ItemStack(output, amount); + return this; + } + + public Builder setExpiriense(float amount) { + this.experience = amount; + return this; + } + + public Builder setSmeltTime(int time) { + this.smeltTime = time; + return this; + } + + public void build() { + if (exist) { + if (primaryInput == null) { + BCLib.LOGGER.warning( + "Primary input for Alloying recipe can't be 'null', recipe {} will be ignored!", + id + ); + return; + } + if (secondaryInput == null) { + BCLib.LOGGER.warning( + "Secondary input for Alloying can't be 'null', recipe {} will be ignored!", + id + ); + return; + } + if (output == null) { + BCLib.LOGGER.warning("Output for Alloying can't be 'null', recipe {} will be ignored!", id); + return; + } + if (BCLRecipeManager.getRecipe(TYPE, id) != null) { + BCLib.LOGGER.warning("Can't add Alloying recipe! Id {} already exists!", id); + return; + } + if (!alright) { + BCLib.LOGGER.debug("Can't add Alloying recipe {}! Ingeredient or output not exists.", id); + return; + } + BCLRecipeManager.addRecipe( + TYPE, + new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime) + ); + } + } + } + + public static class Serializer implements RecipeSerializer { + @Override + public AlloyingRecipe fromJson(ResourceLocation id, JsonObject json) { + JsonArray ingredients = GsonHelper.getAsJsonArray(json, "ingredients"); + Ingredient primaryInput = Ingredient.fromJson(ingredients.get(0)); + Ingredient secondaryInput = Ingredient.fromJson(ingredients.get(1)); + String group = GsonHelper.getAsString(json, "group", ""); + JsonObject result = GsonHelper.getAsJsonObject(json, "result"); + ItemStack output = ItemUtil.fromJsonRecipe(result); + if (output == null) { + throw new IllegalStateException("Output item does not exists!"); + } + float experience = GsonHelper.getAsFloat(json, "experience", 0.0F); + int smeltTime = GsonHelper.getAsInt(json, "smelttime", 350); + + return new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime); + } + + @Override + public AlloyingRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) { + String group = packetBuffer.readUtf(32767); + Ingredient primary = Ingredient.fromNetwork(packetBuffer); + Ingredient secondary = Ingredient.fromNetwork(packetBuffer); + ItemStack output = packetBuffer.readItem(); + float experience = packetBuffer.readFloat(); + int smeltTime = packetBuffer.readVarInt(); + + return new AlloyingRecipe(id, group, primary, secondary, output, experience, smeltTime); + } + + @Override + public void toNetwork(FriendlyByteBuf packetBuffer, AlloyingRecipe recipe) { + packetBuffer.writeUtf(recipe.group); + recipe.primaryInput.toNetwork(packetBuffer); + recipe.secondaryInput.toNetwork(packetBuffer); + packetBuffer.writeItem(recipe.output); + packetBuffer.writeFloat(recipe.experience); + packetBuffer.writeVarInt(recipe.smeltTime); + } + } +}