Removed recipe manager & recipe mixins
This commit is contained in:
parent
7d76f80d94
commit
a98133c00a
7 changed files with 318 additions and 479 deletions
|
@ -1,20 +0,0 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.gen.Accessor;
|
||||
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
public interface RecipeManagerAccessor {
|
||||
@Accessor("recipes")
|
||||
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> be_getRecipes();
|
||||
|
||||
@Accessor("recipes")
|
||||
void be_setRecipes(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes);
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package ru.betterend.mixin.common;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Overwrite;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
|
||||
import net.minecraft.Util;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.server.packs.resources.ResourceManager;
|
||||
import net.minecraft.util.profiling.ProfilerFiller;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeManager;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import net.minecraft.world.level.Level;
|
||||
import ru.betterend.recipe.EndRecipeManager;
|
||||
|
||||
@Mixin(RecipeManager.class)
|
||||
public abstract class RecipeManagerMixin {
|
||||
@Shadow
|
||||
private Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes;
|
||||
|
||||
@Inject(method = "apply", at = @At(value = "RETURN"))
|
||||
private void be_apply(Map<ResourceLocation, JsonElement> map, ResourceManager resourceManager, ProfilerFiller profiler, CallbackInfo info) {
|
||||
recipes = EndRecipeManager.getMap(recipes);
|
||||
}
|
||||
|
||||
@Shadow
|
||||
private <C extends Container, T extends Recipe<C>> Map<ResourceLocation, Recipe<C>> byType(RecipeType<T> type) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @author paulevs
|
||||
* @reason Remove conflicts with vanilla tags
|
||||
* Change recipe order to show mod recipes first, helps when block have vanilla tag
|
||||
* (example - mod stone with vanilla tags and furnace from that stone)
|
||||
*/
|
||||
@Overwrite
|
||||
public <C extends Container, T extends Recipe<C>> Optional<T> getRecipeFor(RecipeType<T> type, C inventory, Level world) {
|
||||
Collection<Recipe<C>> values = byType(type).values();
|
||||
List<Recipe<C>> list = new ArrayList<Recipe<C>>(values);
|
||||
list.sort((v1, v2) -> {
|
||||
boolean b1 = v1.getId().getNamespace().equals("minecraft");
|
||||
boolean b2 = v2.getId().getNamespace().equals("minecraft");
|
||||
return b1 ^ b2 ? (b1 ? 1 : -1) : 0;
|
||||
});
|
||||
|
||||
return list.stream().flatMap((recipe) -> {
|
||||
return Util.toStream(type.tryMatch(recipe, world, inventory));
|
||||
}).findFirst();
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
package ru.betterend.recipe;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import com.google.common.collect.Maps;
|
||||
|
||||
import net.minecraft.core.Registry;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.world.item.crafting.Recipe;
|
||||
import net.minecraft.world.item.crafting.RecipeSerializer;
|
||||
import net.minecraft.world.item.crafting.RecipeType;
|
||||
import ru.betterend.BetterEnd;
|
||||
|
||||
public class EndRecipeManager {
|
||||
private static final Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> RECIPES = Maps.newHashMap();
|
||||
|
||||
public static void addRecipe(RecipeType<?> type, Recipe<?> recipe) {
|
||||
Map<ResourceLocation, Recipe<?>> list = RECIPES.get(type);
|
||||
if (list == null) {
|
||||
list = Maps.newHashMap();
|
||||
RECIPES.put(type, list);
|
||||
}
|
||||
list.put(recipe.getId(), recipe);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T extends Recipe<?>> T getRecipe(RecipeType<T> type, ResourceLocation id) {
|
||||
if (RECIPES.containsKey(type)) {
|
||||
return (T) RECIPES.get(type).get(id);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> getMap(Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> recipes) {
|
||||
Map<RecipeType<?>, Map<ResourceLocation, Recipe<?>>> result = Maps.newHashMap();
|
||||
|
||||
for (RecipeType<?> type : recipes.keySet()) {
|
||||
Map<ResourceLocation, Recipe<?>> typeList = Maps.newHashMap();
|
||||
typeList.putAll(recipes.get(type));
|
||||
result.put(type, typeList);
|
||||
}
|
||||
|
||||
for (RecipeType<?> type : RECIPES.keySet()) {
|
||||
Map<ResourceLocation, Recipe<?>> list = RECIPES.get(type);
|
||||
if (list != null) {
|
||||
Map<ResourceLocation, Recipe<?>> typeList = result.get(type);
|
||||
if (typeList == null) {
|
||||
typeList = Maps.newHashMap();
|
||||
result.put(type, typeList);
|
||||
}
|
||||
for (Entry<ResourceLocation, Recipe<?>> entry : list.entrySet()) {
|
||||
ResourceLocation id = entry.getKey();
|
||||
if (!typeList.containsKey(id))
|
||||
typeList.put(id, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static <S extends RecipeSerializer<T>, T extends Recipe<?>> S registerSerializer(String id, S serializer) {
|
||||
return Registry.register(Registry.RECIPE_SERIALIZER, BetterEnd.getStringId(id), serializer);
|
||||
}
|
||||
|
||||
public static <T extends Recipe<?>> RecipeType<T> registerType(String type) {
|
||||
ResourceLocation recipeTypeId = BetterEnd.makeID(type);
|
||||
return Registry.register(Registry.RECIPE_TYPE, recipeTypeId, new RecipeType<T>() {
|
||||
public String toString() {
|
||||
return type;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
|
@ -19,10 +19,10 @@ 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 ru.bclib.recipes.BCLRecipeManager;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.config.Configs;
|
||||
import ru.betterend.interfaces.BetterEndRecipe;
|
||||
import ru.betterend.recipe.EndRecipeManager;
|
||||
import ru.betterend.registry.EndBlocks;
|
||||
import ru.betterend.util.ItemUtil;
|
||||
import ru.betterend.util.RecipeHelper;
|
||||
|
@ -30,8 +30,8 @@ import ru.betterend.util.RecipeHelper;
|
|||
public class AlloyingRecipe implements Recipe<Container>, BetterEndRecipe {
|
||||
|
||||
public final static String GROUP = "alloying";
|
||||
public final static RecipeType<AlloyingRecipe> TYPE = EndRecipeManager.registerType(GROUP);
|
||||
public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer(GROUP, new Serializer());
|
||||
public final static RecipeType<AlloyingRecipe> TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP);
|
||||
public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer(BetterEnd.MOD_ID, GROUP, new Serializer());
|
||||
public final static ResourceLocation ID = BetterEnd.makeID(GROUP);
|
||||
|
||||
protected final RecipeType<?> type;
|
||||
|
@ -223,7 +223,7 @@ public class AlloyingRecipe implements Recipe<Container>, BetterEndRecipe {
|
|||
BetterEnd.LOGGER.warning("Output for Alloying can't be 'null', recipe {} will be ignored!", id);
|
||||
return;
|
||||
}
|
||||
if (EndRecipeManager.getRecipe(TYPE, id) != null) {
|
||||
if (BCLRecipeManager.getRecipe(TYPE, id) != null) {
|
||||
BetterEnd.LOGGER.warning("Can't add Alloying recipe! Id {} already exists!", id);
|
||||
return;
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ public class AlloyingRecipe implements Recipe<Container>, BetterEndRecipe {
|
|||
BetterEnd.LOGGER.debug("Can't add Alloying recipe {}! Ingeredient or output not exists.", id);
|
||||
return;
|
||||
}
|
||||
EndRecipeManager.addRecipe(TYPE, new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime));
|
||||
BCLRecipeManager.addRecipe(TYPE, new AlloyingRecipe(id, group, primaryInput, secondaryInput, output, experience, smeltTime));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,309 +1,309 @@
|
|||
package ru.betterend.recipe.builders;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TieredItem;
|
||||
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 ru.betterend.BetterEnd;
|
||||
import ru.betterend.config.Configs;
|
||||
import ru.betterend.interfaces.BetterEndRecipe;
|
||||
import ru.betterend.recipe.EndRecipeManager;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.ItemUtil;
|
||||
import ru.betterend.util.RecipeHelper;
|
||||
|
||||
public class AnvilRecipe implements Recipe<Container>, BetterEndRecipe {
|
||||
|
||||
public final static String GROUP = "smithing";
|
||||
public final static RecipeType<AnvilRecipe> TYPE = EndRecipeManager.registerType(GROUP);
|
||||
public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer(GROUP, new Serializer());
|
||||
public final static ResourceLocation ID = BetterEnd.makeID(GROUP);
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Ingredient input;
|
||||
private final ItemStack output;
|
||||
private final int damage;
|
||||
private final int toolLevel;
|
||||
private final int anvilLevel;
|
||||
private final int inputCount;
|
||||
|
||||
public AnvilRecipe(ResourceLocation identifier, Ingredient input, ItemStack output, int inputCount, int toolLevel, int anvilLevel, int damage) {
|
||||
this.id = identifier;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.toolLevel = toolLevel;
|
||||
this.anvilLevel = anvilLevel;
|
||||
this.inputCount = inputCount;
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getResultItem() {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Container craftingInventory, Level world) {
|
||||
return this.matches(craftingInventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack assemble(Container craftingInventory) {
|
||||
return this.output.copy();
|
||||
}
|
||||
|
||||
public ItemStack craft(Container craftingInventory, Player player) {
|
||||
if (!player.isCreative()) {
|
||||
if (!checkHammerDurability(craftingInventory, player)) return ItemStack.EMPTY;
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
hammer.hurtAndBreak(this.damage, player, entity ->
|
||||
entity.broadcastBreakEvent((InteractionHand) null));
|
||||
}
|
||||
return this.assemble(craftingInventory);
|
||||
}
|
||||
|
||||
public boolean checkHammerDurability(Container craftingInventory, Player player) {
|
||||
if (player.isCreative()) return true;
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
int damage = hammer.getDamageValue() + this.damage;
|
||||
return damage < hammer.getMaxDamage();
|
||||
}
|
||||
|
||||
public boolean matches(Container craftingInventory) {
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
if (hammer.isEmpty() || !EndTags.HAMMERS.contains(hammer.getItem())) {
|
||||
return false;
|
||||
}
|
||||
ItemStack material = craftingInventory.getItem(0);
|
||||
int materialCount = material.getCount();
|
||||
int level = ((TieredItem) hammer.getItem()).getTier().getLevel();
|
||||
return this.input.test(craftingInventory.getItem(0)) &&
|
||||
materialCount >= this.inputCount &&
|
||||
level >= this.toolLevel;
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
return this.damage;
|
||||
}
|
||||
|
||||
public int getInputCount() {
|
||||
return this.inputCount;
|
||||
}
|
||||
|
||||
public int getAnvilLevel() {
|
||||
return this.anvilLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NonNullList<Ingredient> getIngredients() {
|
||||
NonNullList<Ingredient> defaultedList = NonNullList.create();
|
||||
defaultedList.add(Ingredient.of(EndTags.HAMMERS.getValues().stream().filter(hammer ->
|
||||
((TieredItem) hammer).getTier().getLevel() >= toolLevel).map(ItemStack::new)));
|
||||
defaultedList.add(input);
|
||||
|
||||
return defaultedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public boolean canCraftInDimensions(int width, int height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecial() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AnvilRecipe that = (AnvilRecipe) o;
|
||||
return damage == that.damage && toolLevel == that.toolLevel && id.equals(that.id) && input.equals(that.input) && output.equals(that.output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, input, output, damage, toolLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AnvilRecipe [" + id + "]";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final static Builder INSTANCE = new Builder();
|
||||
|
||||
public static Builder create(String id) {
|
||||
return create(BetterEnd.makeID(id));
|
||||
}
|
||||
|
||||
public static Builder create(ResourceLocation id) {
|
||||
INSTANCE.id = id;
|
||||
INSTANCE.input = null;
|
||||
INSTANCE.output = null;
|
||||
INSTANCE.inputCount = 1;
|
||||
INSTANCE.toolLevel = 1;
|
||||
INSTANCE.anvilLevel = 1;
|
||||
INSTANCE.damage = 1;
|
||||
INSTANCE.alright = true;
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ResourceLocation id;
|
||||
private Ingredient input;
|
||||
private ItemStack output;
|
||||
private int inputCount = 1;
|
||||
private int toolLevel = 1;
|
||||
private int anvilLevel = 1;
|
||||
private int damage = 1;
|
||||
private boolean alright;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
public Builder setInput(ItemLike... inputItems) {
|
||||
this.alright &= RecipeHelper.exists(inputItems);
|
||||
this.setInput(Ingredient.of(inputItems));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInput(Tag<Item> inputTag) {
|
||||
this.setInput(Ingredient.of(inputTag));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInput(Ingredient ingredient) {
|
||||
this.input = ingredient;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInputCount(int count) {
|
||||
this.inputCount = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setOutput(ItemLike output) {
|
||||
return this.setOutput(output, 1);
|
||||
}
|
||||
|
||||
public Builder setOutput(ItemLike output, int amount) {
|
||||
this.alright &= RecipeHelper.exists(output);
|
||||
this.output = new ItemStack(output, amount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setToolLevel(int level) {
|
||||
this.toolLevel = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAnvilLevel(int level) {
|
||||
this.anvilLevel = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDamage(int damage) {
|
||||
this.damage = damage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build() {
|
||||
if (Configs.RECIPE_CONFIG.getBoolean("anvil", id.getPath(), true)) {
|
||||
if (input == null) {
|
||||
BetterEnd.LOGGER.warning("Input for Anvil recipe can't be 'null', recipe {} will be ignored!", id);
|
||||
return;
|
||||
}
|
||||
if(output == null) {
|
||||
BetterEnd.LOGGER.warning("Output for Anvil recipe can't be 'null', recipe {} will be ignored!", id);
|
||||
return;
|
||||
}
|
||||
if (EndRecipeManager.getRecipe(TYPE, id) != null) {
|
||||
BetterEnd.LOGGER.warning("Can't add Anvil recipe! Id {} already exists!", id);
|
||||
return;
|
||||
}
|
||||
if (!alright) {
|
||||
BetterEnd.LOGGER.debug("Can't add Anvil recipe {}! Ingeredient or output not exists.", id);
|
||||
return;
|
||||
}
|
||||
EndRecipeManager.addRecipe(TYPE, new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<AnvilRecipe> {
|
||||
@Override
|
||||
public AnvilRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
Ingredient input = Ingredient.fromJson(json.get("input"));
|
||||
JsonObject result = GsonHelper.getAsJsonObject(json, "result");
|
||||
ItemStack output = ItemUtil.fromJsonRecipe(result);
|
||||
if (output == null) {
|
||||
throw new IllegalStateException("Output item does not exists!");
|
||||
}
|
||||
int inputCount = GsonHelper.getAsInt(json, "inputCount", 1);
|
||||
int toolLevel = GsonHelper.getAsInt(json, "toolLevel", 1);
|
||||
int anvilLevel = GsonHelper.getAsInt(json, "anvilLevel", 1);
|
||||
int damage = GsonHelper.getAsInt(json, "damage", 1);
|
||||
|
||||
return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnvilRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) {
|
||||
Ingredient input = Ingredient.fromNetwork(packetBuffer);
|
||||
ItemStack output = packetBuffer.readItem();
|
||||
int inputCount = packetBuffer.readVarInt();
|
||||
int toolLevel = packetBuffer.readVarInt();
|
||||
int anvilLevel = packetBuffer.readVarInt();
|
||||
int damage = packetBuffer.readVarInt();
|
||||
|
||||
return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf packetBuffer, AnvilRecipe recipe) {
|
||||
recipe.input.toNetwork(packetBuffer);
|
||||
packetBuffer.writeItem(recipe.output);
|
||||
packetBuffer.writeVarInt(recipe.inputCount);
|
||||
packetBuffer.writeVarInt(recipe.toolLevel);
|
||||
packetBuffer.writeVarInt(recipe.anvilLevel);
|
||||
packetBuffer.writeVarInt(recipe.damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
package ru.betterend.recipe.builders;
|
||||
|
||||
import java.util.Objects;
|
||||
|
||||
import com.google.gson.JsonObject;
|
||||
|
||||
import net.fabricmc.api.EnvType;
|
||||
import net.fabricmc.api.Environment;
|
||||
import net.minecraft.core.NonNullList;
|
||||
import net.minecraft.network.FriendlyByteBuf;
|
||||
import net.minecraft.resources.ResourceLocation;
|
||||
import net.minecraft.tags.Tag;
|
||||
import net.minecraft.util.GsonHelper;
|
||||
import net.minecraft.world.Container;
|
||||
import net.minecraft.world.InteractionHand;
|
||||
import net.minecraft.world.entity.player.Player;
|
||||
import net.minecraft.world.item.Item;
|
||||
import net.minecraft.world.item.ItemStack;
|
||||
import net.minecraft.world.item.TieredItem;
|
||||
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 ru.bclib.recipes.BCLRecipeManager;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.config.Configs;
|
||||
import ru.betterend.interfaces.BetterEndRecipe;
|
||||
import ru.betterend.registry.EndTags;
|
||||
import ru.betterend.util.ItemUtil;
|
||||
import ru.betterend.util.RecipeHelper;
|
||||
|
||||
public class AnvilRecipe implements Recipe<Container>, BetterEndRecipe {
|
||||
|
||||
public final static String GROUP = "smithing";
|
||||
public final static RecipeType<AnvilRecipe> TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP);
|
||||
public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer(BetterEnd.MOD_ID, GROUP, new Serializer());
|
||||
public final static ResourceLocation ID = BetterEnd.makeID(GROUP);
|
||||
|
||||
private final ResourceLocation id;
|
||||
private final Ingredient input;
|
||||
private final ItemStack output;
|
||||
private final int damage;
|
||||
private final int toolLevel;
|
||||
private final int anvilLevel;
|
||||
private final int inputCount;
|
||||
|
||||
public AnvilRecipe(ResourceLocation identifier, Ingredient input, ItemStack output, int inputCount, int toolLevel, int anvilLevel, int damage) {
|
||||
this.id = identifier;
|
||||
this.input = input;
|
||||
this.output = output;
|
||||
this.toolLevel = toolLevel;
|
||||
this.anvilLevel = anvilLevel;
|
||||
this.inputCount = inputCount;
|
||||
this.damage = damage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeSerializer<?> getSerializer() {
|
||||
return SERIALIZER;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack getResultItem() {
|
||||
return this.output;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean matches(Container craftingInventory, Level world) {
|
||||
return this.matches(craftingInventory);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ItemStack assemble(Container craftingInventory) {
|
||||
return this.output.copy();
|
||||
}
|
||||
|
||||
public ItemStack craft(Container craftingInventory, Player player) {
|
||||
if (!player.isCreative()) {
|
||||
if (!checkHammerDurability(craftingInventory, player)) return ItemStack.EMPTY;
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
hammer.hurtAndBreak(this.damage, player, entity ->
|
||||
entity.broadcastBreakEvent((InteractionHand) null));
|
||||
}
|
||||
return this.assemble(craftingInventory);
|
||||
}
|
||||
|
||||
public boolean checkHammerDurability(Container craftingInventory, Player player) {
|
||||
if (player.isCreative()) return true;
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
int damage = hammer.getDamageValue() + this.damage;
|
||||
return damage < hammer.getMaxDamage();
|
||||
}
|
||||
|
||||
public boolean matches(Container craftingInventory) {
|
||||
ItemStack hammer = craftingInventory.getItem(1);
|
||||
if (hammer.isEmpty() || !EndTags.HAMMERS.contains(hammer.getItem())) {
|
||||
return false;
|
||||
}
|
||||
ItemStack material = craftingInventory.getItem(0);
|
||||
int materialCount = material.getCount();
|
||||
int level = ((TieredItem) hammer.getItem()).getTier().getLevel();
|
||||
return this.input.test(craftingInventory.getItem(0)) &&
|
||||
materialCount >= this.inputCount &&
|
||||
level >= this.toolLevel;
|
||||
}
|
||||
|
||||
public int getDamage() {
|
||||
return this.damage;
|
||||
}
|
||||
|
||||
public int getInputCount() {
|
||||
return this.inputCount;
|
||||
}
|
||||
|
||||
public int getAnvilLevel() {
|
||||
return this.anvilLevel;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NonNullList<Ingredient> getIngredients() {
|
||||
NonNullList<Ingredient> defaultedList = NonNullList.create();
|
||||
defaultedList.add(Ingredient.of(EndTags.HAMMERS.getValues().stream().filter(hammer ->
|
||||
((TieredItem) hammer).getTier().getLevel() >= toolLevel).map(ItemStack::new)));
|
||||
defaultedList.add(input);
|
||||
|
||||
return defaultedList;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Environment(EnvType.CLIENT)
|
||||
public boolean canCraftInDimensions(int width, int height) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ResourceLocation getId() {
|
||||
return this.id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public RecipeType<?> getType() {
|
||||
return TYPE;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSpecial() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (this == o) return true;
|
||||
if (o == null || getClass() != o.getClass()) return false;
|
||||
AnvilRecipe that = (AnvilRecipe) o;
|
||||
return damage == that.damage && toolLevel == that.toolLevel && id.equals(that.id) && input.equals(that.input) && output.equals(that.output);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return Objects.hash(id, input, output, damage, toolLevel);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "AnvilRecipe [" + id + "]";
|
||||
}
|
||||
|
||||
public static class Builder {
|
||||
private final static Builder INSTANCE = new Builder();
|
||||
|
||||
public static Builder create(String id) {
|
||||
return create(BetterEnd.makeID(id));
|
||||
}
|
||||
|
||||
public static Builder create(ResourceLocation id) {
|
||||
INSTANCE.id = id;
|
||||
INSTANCE.input = null;
|
||||
INSTANCE.output = null;
|
||||
INSTANCE.inputCount = 1;
|
||||
INSTANCE.toolLevel = 1;
|
||||
INSTANCE.anvilLevel = 1;
|
||||
INSTANCE.damage = 1;
|
||||
INSTANCE.alright = true;
|
||||
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ResourceLocation id;
|
||||
private Ingredient input;
|
||||
private ItemStack output;
|
||||
private int inputCount = 1;
|
||||
private int toolLevel = 1;
|
||||
private int anvilLevel = 1;
|
||||
private int damage = 1;
|
||||
private boolean alright;
|
||||
|
||||
private Builder() {}
|
||||
|
||||
public Builder setInput(ItemLike... inputItems) {
|
||||
this.alright &= RecipeHelper.exists(inputItems);
|
||||
this.setInput(Ingredient.of(inputItems));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInput(Tag<Item> inputTag) {
|
||||
this.setInput(Ingredient.of(inputTag));
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInput(Ingredient ingredient) {
|
||||
this.input = ingredient;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setInputCount(int count) {
|
||||
this.inputCount = count;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setOutput(ItemLike output) {
|
||||
return this.setOutput(output, 1);
|
||||
}
|
||||
|
||||
public Builder setOutput(ItemLike output, int amount) {
|
||||
this.alright &= RecipeHelper.exists(output);
|
||||
this.output = new ItemStack(output, amount);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setToolLevel(int level) {
|
||||
this.toolLevel = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setAnvilLevel(int level) {
|
||||
this.anvilLevel = level;
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder setDamage(int damage) {
|
||||
this.damage = damage;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void build() {
|
||||
if (Configs.RECIPE_CONFIG.getBoolean("anvil", id.getPath(), true)) {
|
||||
if (input == null) {
|
||||
BetterEnd.LOGGER.warning("Input for Anvil recipe can't be 'null', recipe {} will be ignored!", id);
|
||||
return;
|
||||
}
|
||||
if(output == null) {
|
||||
BetterEnd.LOGGER.warning("Output for Anvil recipe can't be 'null', recipe {} will be ignored!", id);
|
||||
return;
|
||||
}
|
||||
if (BCLRecipeManager.getRecipe(TYPE, id) != null) {
|
||||
BetterEnd.LOGGER.warning("Can't add Anvil recipe! Id {} already exists!", id);
|
||||
return;
|
||||
}
|
||||
if (!alright) {
|
||||
BetterEnd.LOGGER.debug("Can't add Anvil recipe {}! Ingeredient or output not exists.", id);
|
||||
return;
|
||||
}
|
||||
BCLRecipeManager.addRecipe(TYPE, new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class Serializer implements RecipeSerializer<AnvilRecipe> {
|
||||
@Override
|
||||
public AnvilRecipe fromJson(ResourceLocation id, JsonObject json) {
|
||||
Ingredient input = Ingredient.fromJson(json.get("input"));
|
||||
JsonObject result = GsonHelper.getAsJsonObject(json, "result");
|
||||
ItemStack output = ItemUtil.fromJsonRecipe(result);
|
||||
if (output == null) {
|
||||
throw new IllegalStateException("Output item does not exists!");
|
||||
}
|
||||
int inputCount = GsonHelper.getAsInt(json, "inputCount", 1);
|
||||
int toolLevel = GsonHelper.getAsInt(json, "toolLevel", 1);
|
||||
int anvilLevel = GsonHelper.getAsInt(json, "anvilLevel", 1);
|
||||
int damage = GsonHelper.getAsInt(json, "damage", 1);
|
||||
|
||||
return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnvilRecipe fromNetwork(ResourceLocation id, FriendlyByteBuf packetBuffer) {
|
||||
Ingredient input = Ingredient.fromNetwork(packetBuffer);
|
||||
ItemStack output = packetBuffer.readItem();
|
||||
int inputCount = packetBuffer.readVarInt();
|
||||
int toolLevel = packetBuffer.readVarInt();
|
||||
int anvilLevel = packetBuffer.readVarInt();
|
||||
int damage = packetBuffer.readVarInt();
|
||||
|
||||
return new AnvilRecipe(id, input, output, inputCount, toolLevel, anvilLevel, damage);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void toNetwork(FriendlyByteBuf packetBuffer, AnvilRecipe recipe) {
|
||||
recipe.input.toNetwork(packetBuffer);
|
||||
packetBuffer.writeItem(recipe.output);
|
||||
packetBuffer.writeVarInt(recipe.inputCount);
|
||||
packetBuffer.writeVarInt(recipe.toolLevel);
|
||||
packetBuffer.writeVarInt(recipe.anvilLevel);
|
||||
packetBuffer.writeVarInt(recipe.damage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,18 +17,18 @@ 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 ru.bclib.recipes.BCLRecipeManager;
|
||||
import ru.betterend.BetterEnd;
|
||||
import ru.betterend.config.Configs;
|
||||
import ru.betterend.interfaces.BetterEndRecipe;
|
||||
import ru.betterend.recipe.EndRecipeManager;
|
||||
import ru.betterend.rituals.InfusionRitual;
|
||||
import ru.betterend.util.ItemUtil;
|
||||
|
||||
public class InfusionRecipe implements Recipe<InfusionRitual>, BetterEndRecipe {
|
||||
|
||||
public final static String GROUP = "infusion";
|
||||
public final static RecipeType<InfusionRecipe> TYPE = EndRecipeManager.registerType(GROUP);
|
||||
public final static Serializer SERIALIZER = EndRecipeManager.registerSerializer(GROUP, new Serializer());
|
||||
public final static RecipeType<InfusionRecipe> TYPE = BCLRecipeManager.registerType(BetterEnd.MOD_ID, GROUP);
|
||||
public final static Serializer SERIALIZER = BCLRecipeManager.registerSerializer(BetterEnd.MOD_ID, GROUP, new Serializer());
|
||||
public final static ResourceLocation ID = BetterEnd.makeID(GROUP);
|
||||
|
||||
private final ResourceLocation id;
|
||||
|
@ -194,7 +194,7 @@ public class InfusionRecipe implements Recipe<InfusionRitual>, BetterEndRecipe {
|
|||
BetterEnd.LOGGER.warning("At least one catalyst must be non empty, recipe {} will be ignored!", id);
|
||||
return;
|
||||
}
|
||||
EndRecipeManager.addRecipe(TYPE, recipe);
|
||||
BCLRecipeManager.addRecipe(TYPE, recipe);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,12 +15,10 @@
|
|||
"ChorusPlantBlockMixin",
|
||||
"EndPodiumFeatureMixin",
|
||||
"PotionBrewingAccessor",
|
||||
"RecipeManagerAccessor",
|
||||
"MinecraftServerMixin",
|
||||
"EndDragonFightMixin",
|
||||
"BlockBehaviourMixin",
|
||||
"DimensionTypeMixin",
|
||||
"RecipeManagerMixin",
|
||||
"CraftingMenuMixin",
|
||||
"LivingEntityMixin",
|
||||
"ServerPlayerMixin",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue