diff --git a/build.gradle b/build.gradle index 6d406b5d..cb72795b 100644 --- a/build.gradle +++ b/build.gradle @@ -12,6 +12,8 @@ repositories { // Loom adds the essential maven repositories to download Minecraft and libraries from automatically. // See https://docs.gradle.org/current/userguide/declaring_repositories.html // for more information about repositories. + + maven { url 'https://jitpack.io' } } dependencies { @@ -22,6 +24,9 @@ dependencies { // Fabric API. This is technically optional, but you probably want it anyway. modImplementation "net.fabricmc.fabric-api:fabric-api:${project.fabric_version}" + + modImplementation "com.github.Chocohead:Fabric-ASM:v2.3" + include "com.github.Chocohead:Fabric-ASM:v2.3" } processResources { diff --git a/gradle.properties b/gradle.properties index 6863d751..562c3517 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,7 @@ org.gradle.jvmargs=-Xmx1G loader_version=0.18.4 # Mod Properties - mod_version = 0.4.1+1.21.1 + mod_version = 0.5.0+1.21.1 maven_group = net.errorcraft archives_base_name = itematic diff --git a/src/client/java/net/errorcraft/itematic/client/gui/screen/ingame/BrewingStandScreenDelegate.java b/src/client/java/net/errorcraft/itematic/client/gui/screen/ingame/BrewingStandScreenDelegate.java new file mode 100644 index 00000000..61b657cf --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/client/gui/screen/ingame/BrewingStandScreenDelegate.java @@ -0,0 +1,112 @@ +package net.errorcraft.itematic.client.gui.screen.ingame; + +import net.errorcraft.itematic.client.gui.screen.recipebook.BrewingRecipeBookWidget; +import net.errorcraft.itematic.mixin.client.gui.screen.ingame.BrewingStandScreenAccessor; +import net.errorcraft.itematic.mixin.client.gui.screen.ingame.HandledScreenAccessor; +import net.errorcraft.itematic.screen.BrewingStandMenuDelegate; +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.BrewingStandScreen; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.client.gui.widget.TexturedButtonWidget; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.text.Text; + +public class BrewingStandScreenDelegate extends HandledScreen implements RecipeBookProvider { + private final BrewingStandScreen delegate; + private final RecipeBookWidget recipeBook = new BrewingRecipeBookWidget(); + private boolean narrow; + + public BrewingStandScreenDelegate(BrewingStandMenuDelegate handler, PlayerInventory inventory, Text title, BrewingStandScreen delegate) { + super(handler, inventory, title); + this.delegate = delegate; + } + + @Override + @SuppressWarnings("DataFlowIssue") + protected void init() { + this.delegate.init(this.client, this.width, this.height); + super.init(); + this.narrow = this.width < 379; + this.recipeBook.initialize(this.width, this.height, this.client, this.narrow, this.handler); + this.x = this.recipeBook.findLeftEdge(this.width, this.backgroundWidth); + ((HandledScreenAccessor) this.delegate).itematic$setX(this.x); + this.addDrawableChild(new TexturedButtonWidget(this.x + 15, this.y + 50, 20, 18, RecipeBookWidget.BUTTON_TEXTURES, button -> { + this.recipeBook.toggleOpen(); + this.x = this.recipeBook.findLeftEdge(this.width, this.backgroundWidth); + ((HandledScreenAccessor) this.delegate).itematic$setX(this.x); + button.setPosition(this.x + 15, this.y + 50); + })); + this.titleX = (this.backgroundWidth - this.textRenderer.getWidth(this.title)) / 2; + } + + @Override + protected void handledScreenTick() { + super.handledScreenTick(); + this.recipeBook.update(); + } + + @Override + public void render(DrawContext context, int mouseX, int mouseY, float delta) { + if (this.recipeBook.isOpen() && this.narrow) { + this.renderBackground(context, mouseX, mouseY, delta); + this.recipeBook.render(context, mouseX, mouseY, delta); + } else { + super.render(context, mouseX, mouseY, delta); + this.recipeBook.render(context, mouseX, mouseY, delta); + this.recipeBook.drawGhostSlots(context, this.x, this.y, false, delta); + } + + this.drawMouseoverTooltip(context, mouseX, mouseY); + this.recipeBook.drawTooltip(context, this.x, this.y, mouseX, mouseY); + } + + @Override + protected void drawBackground(DrawContext context, float delta, int mouseX, int mouseY) { + ((BrewingStandScreenAccessor) this.delegate).itematic$drawBackground(context, delta, mouseX, mouseY); + } + + @Override + public boolean mouseClicked(double mouseX, double mouseY, int button) { + if (this.recipeBook.mouseClicked(mouseX, mouseY, button)) { + return true; + } + + return this.narrow && this.recipeBook.isOpen() || super.mouseClicked(mouseX, mouseY, button); + } + + @Override + protected void onMouseClick(Slot slot, int slotId, int button, SlotActionType actionType) { + super.onMouseClick(slot, slotId, button, actionType); + this.recipeBook.slotClicked(slot); + } + + @Override + public boolean keyPressed(int keyCode, int scanCode, int modifiers) { + return this.recipeBook.keyPressed(keyCode, scanCode, modifiers) || super.keyPressed(keyCode, scanCode, modifiers); + } + + @Override + protected boolean isClickOutsideBounds(double mouseX, double mouseY, int left, int top, int button) { + boolean clickedOutside = mouseX < left || mouseY < top || mouseX >= left + this.backgroundWidth || mouseY >= top + this.backgroundHeight; + return this.recipeBook.isClickOutsideBounds(mouseX, mouseY, this.x, this.y, this.backgroundWidth, this.backgroundHeight, button) && clickedOutside; + } + + @Override + public boolean charTyped(char chr, int modifiers) { + return this.recipeBook.charTyped(chr, modifiers) || super.charTyped(chr, modifiers); + } + + @Override + public void refreshRecipeBook() { + this.recipeBook.refresh(); + } + + @Override + public RecipeBookWidget getRecipeBookWidget() { + return this.recipeBook; + } +} diff --git a/src/client/java/net/errorcraft/itematic/client/gui/screen/recipebook/BrewingRecipeBookWidget.java b/src/client/java/net/errorcraft/itematic/client/gui/screen/recipebook/BrewingRecipeBookWidget.java new file mode 100644 index 00000000..69c22c2e --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/client/gui/screen/recipebook/BrewingRecipeBookWidget.java @@ -0,0 +1,51 @@ +package net.errorcraft.itematic.client.gui.screen.recipebook; + +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.errorcraft.itematic.screen.BrewingStandMenuDelegate; +import net.minecraft.client.gui.screen.ButtonTextures; +import net.minecraft.client.gui.screen.recipebook.RecipeBookWidget; +import net.minecraft.item.Item; +import net.minecraft.recipe.RecipeEntry; +import net.minecraft.registry.DynamicRegistryManager; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.screen.slot.Slot; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; + +import java.util.List; + +public class BrewingRecipeBookWidget extends RecipeBookWidget { + private static final ButtonTextures TEXTURES = new ButtonTextures( + Identifier.ofVanilla("recipe_book/brewing_stand_filter_enabled"), + Identifier.ofVanilla("recipe_book/brewing_stand_filter_disabled"), + Identifier.ofVanilla("recipe_book/brewing_stand_filter_enabled_highlighted"), + Identifier.ofVanilla("recipe_book/brewing_stand_filter_disabled_highlighted") + ); + private static final Text TOGGLE_BREWABLE_TEXT = Text.translatable("gui.recipebook.toggleRecipes.brewable"); + + @Override + protected void setBookButtonTexture() { + this.toggleCraftableButton.setTextures(TEXTURES); + } + + @Override + protected Text getToggleCraftableButtonText() { + return TOGGLE_BREWABLE_TEXT; + } + + @Override + @SuppressWarnings("DataFlowIssue") + public void showGhostRecipe(RecipeEntry recipe, List slots) { + this.ghostSlots.setRecipe(recipe); + DynamicRegistryManager registryManager = this.client.world.getRegistryManager(); + RegistryWrapper.Impl items = registryManager.getWrapperOrThrow(RegistryKeys.ITEM); + if (recipe.value() instanceof BrewingRecipe brewingRecipe) { + Slot firstInputSlot = this.craftingScreenHandler.getSlot(BrewingStandMenuDelegate.FIRST_INPUT_SLOT); + this.ghostSlots.addSlot(brewingRecipe.inputIngredient(items), firstInputSlot.x, firstInputSlot.y); + + Slot ingredientSlot = this.craftingScreenHandler.getSlot(BrewingStandMenuDelegate.INGREDIENT_SLOT); + this.ghostSlots.addSlot(brewingRecipe.reagent(), ingredientSlot.x, ingredientSlot.y); + } + } +} diff --git a/src/client/java/net/errorcraft/itematic/client/recipebook/ItematicRecipeBookGroups.java b/src/client/java/net/errorcraft/itematic/client/recipebook/ItematicRecipeBookGroups.java new file mode 100644 index 00000000..43195b01 --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/client/recipebook/ItematicRecipeBookGroups.java @@ -0,0 +1,19 @@ +package net.errorcraft.itematic.client.recipebook; + +import com.chocohead.mm.api.ClassTinkerers; +import com.google.common.collect.ImmutableList; +import net.minecraft.client.recipebook.RecipeBookGroup; + +import java.util.List; + +public class ItematicRecipeBookGroups { + public static final RecipeBookGroup BREWING_SEARCH = ClassTinkerers.getEnum(RecipeBookGroup.class, "ITEMATIC$BREWING_SEARCH"); + public static final RecipeBookGroup BREWING_MODIFY = ClassTinkerers.getEnum(RecipeBookGroup.class, "ITEMATIC$BREWING_MODIFY"); + public static final RecipeBookGroup BREWING_AMPLIFY = ClassTinkerers.getEnum(RecipeBookGroup.class, "ITEMATIC$BREWING_AMPLIFY"); + + public static final List BREWING = ImmutableList.of( + BREWING_SEARCH, + BREWING_MODIFY, + BREWING_AMPLIFY + ); +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/BrewingStandScreenAccessor.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/BrewingStandScreenAccessor.java new file mode 100644 index 00000000..f3ac8dc5 --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/BrewingStandScreenAccessor.java @@ -0,0 +1,12 @@ +package net.errorcraft.itematic.mixin.client.gui.screen.ingame; + +import net.minecraft.client.gui.DrawContext; +import net.minecraft.client.gui.screen.ingame.BrewingStandScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(BrewingStandScreen.class) +public interface BrewingStandScreenAccessor { + @Invoker("drawBackground") + void itematic$drawBackground(DrawContext context, float delta, int mouseX, int mouseY); +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/BrewingStandScreenExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/BrewingStandScreenExtender.java new file mode 100644 index 00000000..11c2e9a3 --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/BrewingStandScreenExtender.java @@ -0,0 +1,40 @@ +package net.errorcraft.itematic.mixin.client.gui.screen.ingame; + +import net.errorcraft.itematic.access.screen.BrewingStandScreenHandlerAccess; +import net.errorcraft.itematic.screen.BrewingStandMenuDelegate; +import net.minecraft.client.gui.screen.ingame.BrewingStandScreen; +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import net.minecraft.client.gui.screen.recipebook.RecipeBookProvider; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.text.Text; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Constant; +import org.spongepowered.asm.mixin.injection.ModifyConstant; +import org.spongepowered.asm.mixin.injection.ModifyVariable; + +@Mixin(BrewingStandScreen.class) +public abstract class BrewingStandScreenExtender extends HandledScreen implements RecipeBookProvider { + public BrewingStandScreenExtender(BrewingStandMenuDelegate handler, PlayerInventory inventory, Text title) { + super(handler, inventory, title); + } + + @ModifyVariable( + method = "drawBackground", + ordinal = 2, + at = @At("STORE:FIRST") + ) + private int useDirectXPosition(int original) { + return this.x; + } + + @ModifyConstant( + method = "drawBackground", + constant = @Constant( + floatValue = 400.0f + ) + ) + private float useRecipeForBrewingTime(float original) { + return ((BrewingStandScreenHandlerAccess) this.handler).itematic$maxBrewingTime(); + } +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/HandledScreenAccessor.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/HandledScreenAccessor.java new file mode 100644 index 00000000..7cf532b4 --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/HandledScreenAccessor.java @@ -0,0 +1,11 @@ +package net.errorcraft.itematic.mixin.client.gui.screen.ingame; + +import net.minecraft.client.gui.screen.ingame.HandledScreen; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(HandledScreen.class) +public interface HandledScreenAccessor { + @Accessor("x") + void itematic$setX(int x); +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/HandledScreensExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/HandledScreensExtender.java new file mode 100644 index 00000000..a82b6130 --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/ingame/HandledScreensExtender.java @@ -0,0 +1,34 @@ +package net.errorcraft.itematic.mixin.client.gui.screen.ingame; + +import net.errorcraft.itematic.client.gui.screen.ingame.BrewingStandScreenDelegate; +import net.errorcraft.itematic.screen.BrewingStandMenuDelegate; +import net.minecraft.client.gui.screen.ingame.BrewingStandScreen; +import net.minecraft.client.gui.screen.ingame.HandledScreens; +import net.minecraft.screen.BrewingStandScreenHandler; +import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; +import org.spongepowered.asm.mixin.injection.Slice; + +@Mixin(HandledScreens.class) +public class HandledScreensExtender { + @ModifyArg( + method = "", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/screen/ingame/HandledScreens;register(Lnet/minecraft/screen/ScreenHandlerType;Lnet/minecraft/client/gui/screen/ingame/HandledScreens$Provider;)V", + ordinal = 0 + ), + slice = @Slice( + from = @At( + value = "FIELD", + target = "Lnet/minecraft/screen/ScreenHandlerType;BREWING_STAND:Lnet/minecraft/screen/ScreenHandlerType;", + opcode = Opcodes.GETSTATIC + ) + ) + ) + private static HandledScreens.Provider useDelegate(HandledScreens.Provider provider) { + return (handler, inventory, title) -> new BrewingStandScreenDelegate(handler, inventory, title, provider.create(handler.delegate(), inventory, title)); + } +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/recipebook/RecipeAlternativesWidgetAccessor.java b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/recipebook/RecipeAlternativesWidgetAccessor.java index 5cf6acc1..8ae8e0cc 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/recipebook/RecipeAlternativesWidgetAccessor.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/gui/screen/recipebook/RecipeAlternativesWidgetAccessor.java @@ -1,42 +1,169 @@ package net.errorcraft.itematic.mixin.client.gui.screen.recipebook; +import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; +import net.errorcraft.itematic.access.recipe.RecipeAccess; +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; import net.minecraft.client.MinecraftClient; import net.minecraft.client.gui.screen.recipebook.RecipeAlternativesWidget; +import net.minecraft.client.gui.widget.ClickableWidget; import net.minecraft.client.world.ClientWorld; import net.minecraft.item.ItemStack; import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeEntry; +import net.minecraft.registry.DynamicRegistryManager; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.text.Text; +import net.minecraft.util.Identifier; +import net.minecraft.util.collection.DefaultedList; import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.gen.Accessor; +import org.spongepowered.asm.mixin.gen.Invoker; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; + +import java.util.Iterator; +import java.util.List; @Mixin(RecipeAlternativesWidget.class) public interface RecipeAlternativesWidgetAccessor { @Accessor("client") - MinecraftClient client(); + MinecraftClient itematic$client(); - @Mixin(targets = "net.minecraft.client.gui.screen.recipebook.RecipeAlternativesWidget$AlternativeButtonWidget") - class AlternativeButtonWidgetExtender { + @Mixin(RecipeAlternativesWidget.AlternativeButtonWidget.class) + abstract class AlternativeButtonWidgetExtender extends ClickableWidget { @Shadow @Final RecipeAlternativesWidget field_3113; + @Shadow + @Final + private boolean craftable; + + @Shadow + @Final + protected List slots; + + @Unique + private static final Identifier BREWING_TEXTURE_ENABLED = Identifier.ofVanilla("recipe_book/brewing_stand_overlay"); + @Unique + private static final Identifier BREWING_TEXTURE_ENABLED_HIGHLIGHTED = Identifier.ofVanilla("recipe_book/brewing_stand_overlay_highlighted"); + @Unique + private static final Identifier BREWING_TEXTURE_DISABLED = Identifier.ofVanilla("recipe_book/brewing_stand_overlay_disabled"); + @Unique + private static final Identifier BREWING_TEXTURE_DISABLED_HIGHLIGHTED = Identifier.ofVanilla("recipe_book/brewing_stand_overlay_disabled_highlighted"); + + @Unique + private boolean isBrewingRecipe; + + public AlternativeButtonWidgetExtender(int x, int y, int width, int height, Text message) { + super(x, y, width, height, message); + } + + @Inject( + method = "", + at = @At("TAIL") + ) + private void setBrewingRecipe(RecipeAlternativesWidget parent, int x, int y, RecipeEntry recipe, boolean craftable, CallbackInfo info) { + this.isBrewingRecipe = recipe.value() instanceof BrewingRecipe; + } + + @WrapWithCondition( + method = "alignRecipe", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/screen/recipebook/RecipeAlternativesWidget$AlternativeButtonWidget;alignRecipeToGrid(IIILnet/minecraft/recipe/RecipeEntry;Ljava/util/Iterator;I)V" + ) + ) + private boolean checkBrewingRecipe(RecipeAlternativesWidget.AlternativeButtonWidget instance, int gridWidth, int gridHeight, int gridOutputSlot, RecipeEntry recipe, Iterator inputs, int amount) { + if (!(recipe.value() instanceof BrewingRecipe brewingRecipe)) { + return true; + } + + ClientWorld world = ((RecipeAlternativesWidgetAccessor) this.field_3113).itematic$client().world; + if (world == null) { + return false; + } + + DynamicRegistryManager registries = world.getRegistryManager(); + ItemStack[] bases = brewingRecipe.inputIngredient(registries.getWrapperOrThrow(RegistryKeys.ITEM)) + .itematic$getMatchingStacks(registries); + if (bases.length > 0) { + this.slots.add(InputSlotAccessor.create(instance, 3, 17, bases)); + } + + ItemStack[] reagents = brewingRecipe.reagent().itematic$getMatchingStacks(registries); + if (reagents.length > 0) { + this.slots.add(InputSlotAccessor.create(instance, 10, 3, reagents)); + } + + return false; + } + @Redirect( - method = "acceptAlignedInput", + method = "alignRecipe", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/recipe/Recipe;getIngredients()Lnet/minecraft/util/collection/DefaultedList;" + ) + ) + @SuppressWarnings("DataFlowIssue") + private DefaultedList passItemLookup(Recipe instance) { + return ((RecipeAccess) instance).itematic$ingredients( + ((RecipeAlternativesWidgetAccessor) this.field_3113).itematic$client().world + .getRegistryManager() + .getWrapperOrThrow(RegistryKeys.ITEM) + ); + } + + @Redirect( + method = "acceptAlignedInput(Lnet/minecraft/recipe/Ingredient;IIII)V", at = @At( value = "INVOKE", target = "Lnet/minecraft/recipe/Ingredient;getMatchingStacks()[Lnet/minecraft/item/ItemStack;" ) ) private ItemStack[] getMatchingStacksUseDynamicRegistry(Ingredient instance) { - ClientWorld world = ((RecipeAlternativesWidgetAccessor) this.field_3113).client().world; + ClientWorld world = ((RecipeAlternativesWidgetAccessor) this.field_3113).itematic$client().world; if (world == null) { return new ItemStack[0]; } + return instance.itematic$getMatchingStacks(world.getRegistryManager()); } + + @ModifyArg( + method = "renderWidget", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/client/gui/DrawContext;drawGuiTexture(Lnet/minecraft/util/Identifier;IIII)V" + ) + ) + private Identifier getBrewingStandOverlayTexture(Identifier texture) { + if (!this.isBrewingRecipe) { + return texture; + } + + if (this.craftable) { + return this.isSelected() ? BREWING_TEXTURE_ENABLED_HIGHLIGHTED : BREWING_TEXTURE_ENABLED; + } + + return this.isSelected() ? BREWING_TEXTURE_DISABLED_HIGHLIGHTED : BREWING_TEXTURE_DISABLED; + } + + @Mixin(RecipeAlternativesWidget.AlternativeButtonWidget.InputSlot.class) + interface InputSlotAccessor { + @Invoker("") + static RecipeAlternativesWidget.AlternativeButtonWidget.InputSlot create(RecipeAlternativesWidget.AlternativeButtonWidget widget, final int y, final int x, final ItemStack[] stacks) { + throw new AssertionError(); + } + } } @Mixin(targets = "net.minecraft.client.gui.screen.recipebook.RecipeAlternativesWidget$FurnaceAlternativeButtonWidget") @@ -53,6 +180,7 @@ private ItemStack[] getMatchingStacksUseDynamicRegistry(Ingredient instance) { if (world == null) { return new ItemStack[0]; } + return instance.itematic$getMatchingStacks(world.getRegistryManager()); } } diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayNetworkHandlerExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayNetworkHandlerExtender.java index ab028ced..e94133c6 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayNetworkHandlerExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/network/ClientPlayNetworkHandlerExtender.java @@ -2,7 +2,7 @@ import net.errorcraft.itematic.access.network.listener.ClientPlayPacketListenerAccess; import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.network.packet.s2c.play.TwirlS2CPacket; import net.errorcraft.itematic.world.action.actions.TwirlPlayerAction; import net.minecraft.client.MinecraftClient; @@ -36,8 +36,8 @@ protected ClientPlayNetworkHandlerExtender(MinecraftClient client, ClientConnect target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" ) ) - private static boolean isOfForTotemOfUndyingUseItemComponentCheck(ItemStack instance, Item item) { - return instance.itematic$hasComponent(ItemComponentTypes.LIFE_SAVING); + private static boolean isOfForTotemOfUndyingUseEventListenerCheck(ItemStack instance, Item item) { + return instance.itematic$hasEventListener(ItemEvents.BEFORE_DEATH_HOLDER); } @Redirect( diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/ClientRecipeBookExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/ClientRecipeBookExtender.java new file mode 100644 index 00000000..6ac76802 --- /dev/null +++ b/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/ClientRecipeBookExtender.java @@ -0,0 +1,33 @@ +package net.errorcraft.itematic.mixin.client.recipebook; + +import net.errorcraft.itematic.client.recipebook.ItematicRecipeBookGroups; +import net.errorcraft.itematic.recipe.brewing.AmplifyBrewingRecipe; +import net.errorcraft.itematic.recipe.brewing.ModifyBrewingRecipe; +import net.minecraft.client.recipebook.ClientRecipeBook; +import net.minecraft.client.recipebook.RecipeBookGroup; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeEntry; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +@Mixin(ClientRecipeBook.class) +public class ClientRecipeBookExtender { + @Inject( + method = "getGroupForRecipe", + at = @At("HEAD"), + cancellable = true + ) + private static void checkBrewingRecipes(RecipeEntry recipe, CallbackInfoReturnable info) { + Recipe actualRecipe = recipe.value(); + if (actualRecipe instanceof ModifyBrewingRecipe) { + info.setReturnValue(ItematicRecipeBookGroups.BREWING_MODIFY); + return; + } + + if (actualRecipe instanceof AmplifyBrewingRecipe) { + info.setReturnValue(ItematicRecipeBookGroups.BREWING_AMPLIFY); + } + } +} diff --git a/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/RecipeBookGroupExtender.java b/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/RecipeBookGroupExtender.java index e6e822bd..6afd5d23 100644 --- a/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/RecipeBookGroupExtender.java +++ b/src/client/java/net/errorcraft/itematic/mixin/client/recipebook/RecipeBookGroupExtender.java @@ -1,11 +1,17 @@ package net.errorcraft.itematic.mixin.client.recipebook; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import net.errorcraft.itematic.access.client.recipebook.RecipeBookGroupAccess; +import net.errorcraft.itematic.client.recipebook.ItematicRecipeBookGroups; import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.recipe.book.ItematicRecipeBookCategories; import net.minecraft.client.recipebook.RecipeBookGroup; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; +import net.minecraft.recipe.book.RecipeBookCategory; import net.minecraft.registry.Registry; import net.minecraft.registry.RegistryKey; import org.spongepowered.asm.mixin.Final; @@ -13,12 +19,15 @@ import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; import java.util.ArrayList; import java.util.List; @Mixin(RecipeBookGroup.class) +@SuppressWarnings("DataFlowIssue") public class RecipeBookGroupExtender implements RecipeBookGroupAccess { @Shadow @Final @@ -114,6 +123,9 @@ public class RecipeBookGroupExtender implements RecipeBookGroupAccess { ((RecipeBookGroupExtender)(Object) SMITHING).iconKeys = List.of(ItemKeys.NETHERITE_CHESTPLATE); ((RecipeBookGroupExtender)(Object) CAMPFIRE).iconKeys = List.of(ItemKeys.PORKCHOP); ((RecipeBookGroupExtender)(Object) UNKNOWN).iconKeys = List.of(ItemKeys.BARRIER); + ((RecipeBookGroupExtender)(Object) ItematicRecipeBookGroups.BREWING_SEARCH).iconKeys = List.of(ItemKeys.COMPASS); + ((RecipeBookGroupExtender)(Object) ItematicRecipeBookGroups.BREWING_MODIFY).iconKeys = List.of(ItemKeys.NETHER_WART, ItemKeys.MAGMA_CREAM); + ((RecipeBookGroupExtender)(Object) ItematicRecipeBookGroups.BREWING_AMPLIFY).iconKeys = List.of(ItemKeys.SPLASH_POTION, ItemKeys.LINGERING_POTION); } @Redirect( @@ -127,6 +139,35 @@ private static ItemStack newItemStackReturnEmptyStack(ItemConvertible item) { return ItemStack.EMPTY; } + @ModifyExpressionValue( + method = "", + at = @At( + value = "INVOKE", + target = "Lcom/google/common/collect/ImmutableMap;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableMap;", + remap = false + ) + ) + private static ImmutableMap> addCustomEntries(ImmutableMap> original) { + return ImmutableMap.>builder() + .putAll(original) + .put( + ItematicRecipeBookGroups.BREWING_SEARCH, + ImmutableList.of(ItematicRecipeBookGroups.BREWING_MODIFY, ItematicRecipeBookGroups.BREWING_AMPLIFY) + ) + .build(); + } + + @Inject( + method = "getGroups", + at = @At("HEAD"), + cancellable = true + ) + private static void checkForCustomEntries(RecipeBookCategory category, CallbackInfoReturnable> info) { + if (category == ItematicRecipeBookCategories.BREWING) { + info.setReturnValue(ItematicRecipeBookGroups.BREWING); + } + } + @Override public List itematic$icons(Registry registry) { List stacks = new ArrayList<>(); @@ -135,6 +176,7 @@ private static ItemStack newItemStackReturnEmptyStack(ItemConvertible item) { .map(ItemStack::new) .ifPresent(stacks::add); } + return stacks; } } diff --git a/src/client/resources/itematic.client.mixins.json b/src/client/resources/itematic.client.mixins.json index d4a3394c..ee37b78b 100644 --- a/src/client/resources/itematic.client.mixins.json +++ b/src/client/resources/itematic.client.mixins.json @@ -21,13 +21,18 @@ "gui.screen.StatsScreenExtender$ItemStatsListWidgetExtender$EntryExtender", "gui.screen.StatsScreenExtender$ItemStatsListWidgetExtender$ItemComparatorExtender", "gui.screen.ingame.BeaconScreenExtender", + "gui.screen.ingame.BrewingStandScreenAccessor", + "gui.screen.ingame.BrewingStandScreenExtender", "gui.screen.ingame.CartographyTableScreenExtender", "gui.screen.ingame.CreativeInventoryScreenExtender", + "gui.screen.ingame.HandledScreenAccessor", + "gui.screen.ingame.HandledScreensExtender", "gui.screen.ingame.LoomScreenExtender", "gui.screen.ingame.SmithingScreenExtender", "gui.screen.recipebook.AbstractFurnaceRecipeBookScreenExtender", "gui.screen.recipebook.RecipeAlternativesWidgetAccessor", "gui.screen.recipebook.RecipeAlternativesWidgetAccessor$AlternativeButtonWidgetExtender", + "gui.screen.recipebook.RecipeAlternativesWidgetAccessor$AlternativeButtonWidgetExtender$InputSlotAccessor", "gui.screen.recipebook.RecipeAlternativesWidgetAccessor$FurnaceAlternativeButtonWidgetExtender", "gui.screen.recipebook.RecipeBookGhostSlotsExtender$GhostInputSlotExtender", "gui.screen.recipebook.RecipeBookWidgetExtender", @@ -44,6 +49,7 @@ "option.HotbarStorageEntryExtender", "particle.CrackParticleExtender$SlimeballFactoryExtender", "particle.CrackParticleExtender$SnowballFactoryExtender", + "recipebook.ClientRecipeBookExtender", "recipebook.RecipeBookGroupExtender", "render.WorldRendererExtender", "render.block.BlockRenderManagerExtender", diff --git a/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java b/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java index fff195ba..fd053f10 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java +++ b/src/datagen/java/net/errorcraft/itematic/data/ItematicData.java @@ -2,7 +2,8 @@ import net.errorcraft.itematic.data.client.AtlasProvider; import net.errorcraft.itematic.data.client.ItemBarStyleProvider; -import net.errorcraft.itematic.data.server.RecipeProvider; +import net.errorcraft.itematic.data.server.ItematicRecipeProvider; +import net.errorcraft.itematic.data.server.ModifiedRecipeProvider; import net.errorcraft.itematic.data.server.registry.*; import net.errorcraft.itematic.data.server.tag.*; import net.fabricmc.fabric.api.datagen.v1.DataGeneratorEntrypoint; @@ -32,10 +33,11 @@ public void onInitializeDataGenerator(FabricDataGenerator fabricDataGenerator) { pack.addProvider(ActionProvider::new); pack.addProvider(ActionTagProvider::new); pack.addProvider(SmithingTemplateProvider::new); - pack.addProvider(RecipeProvider::new); + pack.addProvider(ModifiedRecipeProvider::new); pack.addProvider(PotionTagProvider::new); pack.addProvider(DispenseBehaviorProvider::new); pack.addProvider(EntityTypeTagProvider::new); pack.addProvider(ItemBarStyleProvider::new); + pack.addProvider(ItematicRecipeProvider::new); } } diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/ItematicRecipeProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/ItematicRecipeProvider.java new file mode 100644 index 00000000..30a09832 --- /dev/null +++ b/src/datagen/java/net/errorcraft/itematic/data/server/ItematicRecipeProvider.java @@ -0,0 +1,222 @@ +package net.errorcraft.itematic.data.server; + +import net.errorcraft.itematic.access.data.server.recipe.RecipeProviderAccess; +import net.errorcraft.itematic.data.server.recipe.brewing.AmplifyBrewingRecipeBuilder; +import net.errorcraft.itematic.data.server.recipe.brewing.ModifyBrewingRecipeBuilder; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.item.ItematicItemTags; +import net.errorcraft.itematic.potion.PotionKeys; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potion; +import net.minecraft.recipe.Ingredient; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.registry.tag.TagKey; +import net.minecraft.util.Identifier; + +import java.util.concurrent.CompletableFuture; + +public class ItematicRecipeProvider extends RecipeProvider implements RecipeProviderAccess { + public ItematicRecipeProvider(FabricDataOutput output, CompletableFuture registriesFuture) { + super(output, registriesFuture); + } + + @Override + public void generate(RecipeExporter recipeExporter) {} + + @Override + public void itematic$generate(RegistryWrapper.WrapperLookup wrapperLookup, RecipeExporter exporter) { + new Generator(wrapperLookup, exporter).generate(); + } + + public static class Generator { + private final RecipeExporter exporter; + private final RegistryEntryLookup items; + private final RegistryEntryLookup potions; + + protected Generator(RegistryWrapper.WrapperLookup registries, RecipeExporter exporter) { + this.exporter = exporter; + this.items = registries.getWrapperOrThrow(RegistryKeys.ITEM); + this.potions = registries.getWrapperOrThrow(RegistryKeys.POTION); + } + + public void generate() { + this.amplify(ItemKeys.POTION, ItemKeys.GUNPOWDER, ItemKeys.SPLASH_POTION) + .save(this.exporter); + this.amplify(ItemKeys.SPLASH_POTION, ItemKeys.DRAGON_BREATH, ItemKeys.LINGERING_POTION) + .remainder(this.items.getOrThrow(ItemKeys.GLASS_BOTTLE)) + .save(this.exporter); + + this.modify(PotionKeys.WATER, ItemKeys.FERMENTED_SPIDER_EYE, PotionKeys.WEAKNESS) + .save(this.exporter); + this.modify(PotionKeys.WATER, ItemKeys.GLOWSTONE_DUST, PotionKeys.THICK) + .save(this.exporter); + this.modify(PotionKeys.WATER, ItematicItemTags.MUNDANE_POTION_REAGENTS, PotionKeys.MUNDANE) + .save(this.exporter); + this.modify(PotionKeys.WATER, ItemKeys.NETHER_WART, PotionKeys.AWKWARD) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.BLAZE_POWDER, PotionKeys.STRENGTH) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.BREEZE_ROD, PotionKeys.WIND_CHARGED) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.COBWEB, PotionKeys.WEAVING) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.GHAST_TEAR, PotionKeys.REGENERATION) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.GLISTERING_MELON_SLICE, PotionKeys.HEALING) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.GOLDEN_CARROT, PotionKeys.NIGHT_VISION) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.MAGMA_CREAM, PotionKeys.FIRE_RESISTANCE) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.PHANTOM_MEMBRANE, PotionKeys.SLOW_FALLING) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.PUFFERFISH, PotionKeys.WATER_BREATHING) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.RABBIT_FOOT, PotionKeys.LEAPING) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.SLIME_BLOCK, PotionKeys.OOZING) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.SPIDER_EYE, PotionKeys.POISON) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.STONE, PotionKeys.INFESTED) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.SUGAR, PotionKeys.SWIFTNESS) + .save(this.exporter); + this.modify(PotionKeys.AWKWARD, ItemKeys.TURTLE_HELMET, PotionKeys.TURTLE_MASTER) + .save(this.exporter); + + this.lengthen(PotionKeys.FIRE_RESISTANCE, PotionKeys.LONG_FIRE_RESISTANCE) + .save(this.exporter); + this.lengthen(PotionKeys.INVISIBILITY, PotionKeys.LONG_INVISIBILITY) + .save(this.exporter); + this.lengthen(PotionKeys.LEAPING, PotionKeys.LONG_LEAPING) + .save(this.exporter); + this.lengthen(PotionKeys.NIGHT_VISION, PotionKeys.LONG_NIGHT_VISION) + .save(this.exporter); + this.lengthen(PotionKeys.POISON, PotionKeys.LONG_POISON) + .save(this.exporter); + this.lengthen(PotionKeys.REGENERATION, PotionKeys.LONG_REGENERATION) + .save(this.exporter); + this.lengthen(PotionKeys.SLOW_FALLING, PotionKeys.LONG_SLOW_FALLING) + .save(this.exporter); + this.lengthen(PotionKeys.SLOWNESS, PotionKeys.LONG_SLOWNESS) + .save(this.exporter); + this.lengthen(PotionKeys.STRENGTH, PotionKeys.LONG_STRENGTH) + .save(this.exporter); + this.lengthen(PotionKeys.SWIFTNESS, PotionKeys.LONG_SWIFTNESS) + .save(this.exporter); + this.lengthen(PotionKeys.TURTLE_MASTER, PotionKeys.LONG_TURTLE_MASTER) + .save(this.exporter); + this.lengthen(PotionKeys.WATER_BREATHING, PotionKeys.LONG_WATER_BREATHING) + .save(this.exporter); + this.lengthen(PotionKeys.WEAKNESS, PotionKeys.LONG_WEAKNESS) + .save(this.exporter); + + this.strengthen(PotionKeys.HARMING, PotionKeys.STRONG_HARMING) + .save(this.exporter); + this.strengthen(PotionKeys.HEALING, PotionKeys.STRONG_HEALING) + .save(this.exporter); + this.strengthen(PotionKeys.LEAPING, PotionKeys.STRONG_LEAPING) + .save(this.exporter); + this.strengthen(PotionKeys.POISON, PotionKeys.STRONG_POISON) + .save(this.exporter); + this.strengthen(PotionKeys.REGENERATION, PotionKeys.STRONG_REGENERATION) + .save(this.exporter); + this.strengthen(PotionKeys.SLOWNESS, PotionKeys.STRONG_SLOWNESS) + .save(this.exporter); + this.strengthen(PotionKeys.STRENGTH, PotionKeys.STRONG_STRENGTH) + .save(this.exporter); + this.strengthen(PotionKeys.SWIFTNESS, PotionKeys.STRONG_SWIFTNESS) + .save(this.exporter); + this.strengthen(PotionKeys.TURTLE_MASTER, PotionKeys.STRONG_TURTLE_MASTER) + .save(this.exporter); + + this.negate(PotionKeys.HEALING, PotionKeys.HARMING) + .save(this.exporter); + this.negate(PotionKeys.LEAPING, PotionKeys.SLOWNESS) + .save(this.exporter); + this.negate(PotionKeys.LONG_LEAPING, PotionKeys.LONG_SLOWNESS) + .save(this.exporter); + this.negate(PotionKeys.LONG_NIGHT_VISION, PotionKeys.LONG_INVISIBILITY) + .save(this.exporter); + this.negate(PotionKeys.LONG_POISON, PotionKeys.HARMING) + .save(this.exporter); + this.negate(PotionKeys.LONG_SWIFTNESS, PotionKeys.LONG_SLOWNESS) + .save(this.exporter); + this.negate(PotionKeys.NIGHT_VISION, PotionKeys.INVISIBILITY) + .save(this.exporter); + this.negate(PotionKeys.POISON, PotionKeys.HARMING) + .save(this.exporter); + this.negate(PotionKeys.STRONG_HEALING, PotionKeys.STRONG_HARMING) + .save(this.exporter); + this.negate(PotionKeys.STRONG_POISON, PotionKeys.STRONG_HARMING) + .save(this.exporter); + this.negate(PotionKeys.SWIFTNESS, PotionKeys.SLOWNESS) + .save(this.exporter); + } + + private AmplifyBrewingRecipeBuilder amplify(RegistryKey base, RegistryKey reagent, RegistryKey result) { + RegistryEntry item = this.items.getOrThrow(reagent); + return new AmplifyBrewingRecipeBuilder( + this.items.getOrThrow(base), + Ingredient.ofStacks(new ItemStack(item)), + this.items.getOrThrow(result), + RegistryEntryList.of(item), + result.getValue() + ); + } + + private ModifyBrewingRecipeBuilder modify(RegistryKey base, RegistryKey reagent, RegistryKey result) { + RegistryEntry item = this.items.getOrThrow(reagent); + return this.modify(base, Ingredient.ofStacks(new ItemStack(item)), RegistryEntryList.of(item), result, potionName(result)); + } + + private ModifyBrewingRecipeBuilder modify(RegistryKey base, TagKey reagent, RegistryKey result) { + return this.modify(base, Ingredient.fromTag(reagent), this.items.getOrThrow(reagent), result, potionName(result)); + } + + private ModifyBrewingRecipeBuilder modify(RegistryKey base, RegistryKey reagent, RegistryKey result, String name) { + RegistryEntry item = this.items.getOrThrow(reagent); + return this.modify(base, Ingredient.ofStacks(new ItemStack(item)), RegistryEntryList.of(item), result, name); + } + + private ModifyBrewingRecipeBuilder modify(RegistryKey base, Ingredient reagent, RegistryEntryList conditionItems, RegistryKey result, String name) { + return new ModifyBrewingRecipeBuilder( + this.potions.getOrThrow(base), + reagent, + this.potions.getOrThrow(result), + conditionItems, + Identifier.ofVanilla(name) + ); + } + + private ModifyBrewingRecipeBuilder lengthen(RegistryKey from, RegistryKey to) { + return this.modify(from, ItemKeys.REDSTONE, to, potionName(from, to)); + } + + private ModifyBrewingRecipeBuilder strengthen(RegistryKey from, RegistryKey to) { + return this.modify(from, ItemKeys.GLOWSTONE_DUST, to, potionName(from, to)); + } + + private ModifyBrewingRecipeBuilder negate(RegistryKey from, RegistryKey to) { + return this.modify(from, ItemKeys.FERMENTED_SPIDER_EYE, to, potionName(from, to)); + } + + private static String potionName(RegistryKey potion) { + return potion.getValue().getPath() + "_potion"; + } + + private static String potionName(RegistryKey from, RegistryKey to) { + return potionName(to) + "_from_" + potionName(from); + } + } +} diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java new file mode 100644 index 00000000..44962fdd --- /dev/null +++ b/src/datagen/java/net/errorcraft/itematic/data/server/ModifiedRecipeProvider.java @@ -0,0 +1,229 @@ +package net.errorcraft.itematic.data.server; + +import it.unimi.dsi.fastutil.chars.Char2ObjectMap; +import it.unimi.dsi.fastutil.chars.Char2ObjectOpenHashMap; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.item.ItematicItemTags; +import net.errorcraft.itematic.recipe.ItemColoringRecipe; +import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; +import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider; +import net.minecraft.data.DataOutput; +import net.minecraft.data.server.recipe.CraftingRecipeJsonBuilder; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.*; +import net.minecraft.recipe.book.CraftingRecipeCategory; +import net.minecraft.recipe.book.RecipeCategory; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.DyeColor; +import net.minecraft.util.Identifier; +import net.minecraft.util.collection.DefaultedList; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import java.util.concurrent.CompletableFuture; +import java.util.function.BiConsumer; + +@SuppressWarnings("SameParameterValue") +public class ModifiedRecipeProvider extends FabricCodecDataProvider> { + public ModifiedRecipeProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { + super(dataOutput, registriesFuture, DataOutput.OutputType.DATA_PACK, "recipe", Recipe.CODEC); + } + + @Override + protected void configure(BiConsumer> provider, RegistryWrapper.WrapperLookup lookup) { + RegistryWrapper.Impl items = lookup.getWrapperOrThrow(RegistryKeys.ITEM); + provider.accept( + Identifier.ofVanilla("honey_block"), + shapedRecipe(RecipeCategory.FOOD, items.getOrThrow(ItemKeys.HONEY_BLOCK)) + .input('#', items.getOrThrow(ItemKeys.HONEY_BOTTLE), items.getOrThrow(ItemKeys.GLASS_BOTTLE)) + .pattern("##") + .pattern("##") + .build() + ); + provider.accept( + Identifier.ofVanilla("sugar_from_honey_bottle"), + shapelessRecipe(RecipeCategory.MISC, items.getOrThrow(ItemKeys.SUGAR), 3) + .input(items.getOrThrow(ItemKeys.HONEY_BOTTLE), 1, items.getOrThrow(ItemKeys.GLASS_BOTTLE)) + .build() + ); + provider.accept( + Identifier.ofVanilla("cake"), + shapedRecipe(RecipeCategory.FOOD, items.getOrThrow(ItemKeys.CAKE)) + .input('A', items.getOrThrow(ItemKeys.MILK_BUCKET), items.getOrThrow(ItemKeys.BUCKET)) + .input('B', items.getOrThrow(ItemKeys.SUGAR)) + .input('C', items.getOrThrow(ItemKeys.WHEAT)) + .input('E', items.getOrThrow(ItemKeys.EGG)) + .pattern("AAA") + .pattern("BEB") + .pattern("CCC") + .build() + ); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_black"), colorShulkerBox( + DyeColor.BLACK, + items.getOrThrow(ItemKeys.BLACK_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_blue"), colorShulkerBox( + DyeColor.BLUE, + items.getOrThrow(ItemKeys.BLUE_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_brown"), colorShulkerBox( + DyeColor.BROWN, + items.getOrThrow(ItemKeys.BROWN_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_cyan"), colorShulkerBox( + DyeColor.CYAN, + items.getOrThrow(ItemKeys.CYAN_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_gray"), colorShulkerBox( + DyeColor.GRAY, + items.getOrThrow(ItemKeys.GRAY_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_green"), colorShulkerBox( + DyeColor.GREEN, + items.getOrThrow(ItemKeys.GREEN_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_light_blue"), colorShulkerBox( + DyeColor.LIGHT_BLUE, + items.getOrThrow(ItemKeys.LIGHT_BLUE_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_light_gray"), colorShulkerBox( + DyeColor.LIGHT_GRAY, + items.getOrThrow(ItemKeys.LIGHT_GRAY_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_lime"), colorShulkerBox( + DyeColor.LIME, + items.getOrThrow(ItemKeys.LIME_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_magenta"), colorShulkerBox( + DyeColor.MAGENTA, + items.getOrThrow(ItemKeys.MAGENTA_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_orange"), colorShulkerBox( + DyeColor.ORANGE, + items.getOrThrow(ItemKeys.ORANGE_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_pink"), colorShulkerBox( + DyeColor.PINK, + items.getOrThrow(ItemKeys.PINK_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_purple"), colorShulkerBox( + DyeColor.PURPLE, + items.getOrThrow(ItemKeys.PURPLE_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_red"), colorShulkerBox( + DyeColor.RED, + items.getOrThrow(ItemKeys.RED_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_white"), colorShulkerBox( + DyeColor.WHITE, + items.getOrThrow(ItemKeys.WHITE_SHULKER_BOX) + )); + provider.accept(Identifier.ofVanilla("shulker_box_coloring_yellow"), colorShulkerBox( + DyeColor.YELLOW, + items.getOrThrow(ItemKeys.YELLOW_SHULKER_BOX) + )); + } + + @Override + public String getName() { + return "Modified Recipes"; + } + + private static ItemColoringRecipe colorShulkerBox(DyeColor color, RegistryEntry result) { + return new ItemColoringRecipe(CraftingRecipeCategory.MISC, Ingredient.fromTag(ItematicItemTags.SHULKER_BOXES), color, new ItemStack(result)); + } + + private static ShapelessRecipeBuilder shapelessRecipe(RecipeCategory category, RegistryEntry result, int count) { + return new ShapelessRecipeBuilder(new ItemStack(result, count), category); + } + + private static ShapedRecipeBuilder shapedRecipe(RecipeCategory category, RegistryEntry result) { + return new ShapedRecipeBuilder(new ItemStack(result), category); + } + + private static class ShapelessRecipeBuilder { + private final ItemStack result; + private final RecipeCategory category; + private final DefaultedList inputs = DefaultedList.of(); + + private ShapelessRecipeBuilder(ItemStack result, RecipeCategory category) { + this.result = result; + this.category = category; + } + + public ShapelessRecipe build() { + return new ShapelessRecipe( + "", + CraftingRecipeJsonBuilder.toCraftingCategory(this.category), + this.result, + this.inputs + ); + } + + public ShapelessRecipeBuilder input(RegistryEntry input) { + this.inputs.add(Ingredient.ofStacks(new ItemStack(input))); + return this; + } + + public ShapelessRecipeBuilder input(RegistryEntry input, int count) { + for (int i = 0; i < count; i++) { + this.inputs.add(Ingredient.ofStacks(new ItemStack(input))); + } + + return this; + } + + public ShapelessRecipeBuilder input(RegistryEntry input, int count, RegistryEntry remainder) { + for (int i = 0; i < count; i++) { + Ingredient ingredient = Ingredient.ofStacks(new ItemStack(input)); + ingredient.itematic$setRemainder(Optional.of(new ItemStack(remainder))); + this.inputs.add(ingredient); + } + + return this; + } + } + + private static class ShapedRecipeBuilder { + private final ItemStack result; + private final RecipeCategory category; + private final Char2ObjectMap inputs = new Char2ObjectOpenHashMap<>(); + private final List pattern = new ArrayList<>(); + + private ShapedRecipeBuilder(ItemStack result, RecipeCategory category) { + this.result = result; + this.category = category; + } + + public ShapedRecipe build() { + return new ShapedRecipe( + "", + CraftingRecipeJsonBuilder.toCraftingCategory(this.category), + RawShapedRecipe.create(this.inputs, this.pattern), + this.result, + true + ); + } + + public ShapedRecipeBuilder input(char key, RegistryEntry input) { + this.inputs.put(key, Ingredient.ofStacks(new ItemStack(input))); + return this; + } + + public ShapedRecipeBuilder input(char key, RegistryEntry input, RegistryEntry remainder) { + Ingredient ingredient = Ingredient.ofStacks(new ItemStack(input)); + ingredient.itematic$setRemainder(Optional.of(new ItemStack(remainder))); + this.inputs.put(key, ingredient); + return this; + } + + public ShapedRecipeBuilder pattern(String pattern) { + this.pattern.add(pattern); + return this; + } + } +} diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java deleted file mode 100644 index a7c35f37..00000000 --- a/src/datagen/java/net/errorcraft/itematic/data/server/RecipeProvider.java +++ /dev/null @@ -1,105 +0,0 @@ -package net.errorcraft.itematic.data.server; - -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.ItematicItemTags; -import net.errorcraft.itematic.recipe.ItemColoringRecipe; -import net.fabricmc.fabric.api.datagen.v1.FabricDataOutput; -import net.fabricmc.fabric.api.datagen.v1.provider.FabricCodecDataProvider; -import net.minecraft.data.DataOutput; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.recipe.Ingredient; -import net.minecraft.recipe.Recipe; -import net.minecraft.recipe.book.CraftingRecipeCategory; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.RegistryWrapper; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.util.DyeColor; -import net.minecraft.util.Identifier; - -import java.util.concurrent.CompletableFuture; -import java.util.function.BiConsumer; - -public class RecipeProvider extends FabricCodecDataProvider> { - public RecipeProvider(FabricDataOutput dataOutput, CompletableFuture registriesFuture) { - super(dataOutput, registriesFuture, DataOutput.OutputType.DATA_PACK, "recipes", Recipe.CODEC); - } - - @Override - protected void configure(BiConsumer> provider, RegistryWrapper.WrapperLookup lookup) { - RegistryWrapper.Impl items = lookup.getWrapperOrThrow(RegistryKeys.ITEM); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_black"), colorShulkerBox( - DyeColor.BLACK, - items.getOrThrow(ItemKeys.BLACK_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_blue"), colorShulkerBox( - DyeColor.BLUE, - items.getOrThrow(ItemKeys.BLUE_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_brown"), colorShulkerBox( - DyeColor.BROWN, - items.getOrThrow(ItemKeys.BROWN_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_cyan"), colorShulkerBox( - DyeColor.CYAN, - items.getOrThrow(ItemKeys.CYAN_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_gray"), colorShulkerBox( - DyeColor.GRAY, - items.getOrThrow(ItemKeys.GRAY_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_green"), colorShulkerBox( - DyeColor.GREEN, - items.getOrThrow(ItemKeys.GREEN_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_light_blue"), colorShulkerBox( - DyeColor.LIGHT_BLUE, - items.getOrThrow(ItemKeys.LIGHT_BLUE_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_light_gray"), colorShulkerBox( - DyeColor.LIGHT_GRAY, - items.getOrThrow(ItemKeys.LIGHT_GRAY_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_lime"), colorShulkerBox( - DyeColor.LIME, - items.getOrThrow(ItemKeys.LIME_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_magenta"), colorShulkerBox( - DyeColor.MAGENTA, - items.getOrThrow(ItemKeys.MAGENTA_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_orange"), colorShulkerBox( - DyeColor.ORANGE, - items.getOrThrow(ItemKeys.ORANGE_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_pink"), colorShulkerBox( - DyeColor.PINK, - items.getOrThrow(ItemKeys.PINK_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_purple"), colorShulkerBox( - DyeColor.PURPLE, - items.getOrThrow(ItemKeys.PURPLE_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_red"), colorShulkerBox( - DyeColor.RED, - items.getOrThrow(ItemKeys.RED_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_white"), colorShulkerBox( - DyeColor.WHITE, - items.getOrThrow(ItemKeys.WHITE_SHULKER_BOX) - )); - provider.accept(Identifier.ofVanilla("shulker_box_coloring_yellow"), colorShulkerBox( - DyeColor.YELLOW, - items.getOrThrow(ItemKeys.YELLOW_SHULKER_BOX) - )); - } - - @Override - public String getName() { - return "Recipes"; - } - - private static ItemColoringRecipe colorShulkerBox(DyeColor color, RegistryEntry result) { - return new ItemColoringRecipe(CraftingRecipeCategory.MISC, Ingredient.fromTag(ItematicItemTags.SHULKER_BOXES), color, new ItemStack(result)); - } -} diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/AmplifyBrewingRecipeBuilder.java b/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/AmplifyBrewingRecipeBuilder.java new file mode 100644 index 00000000..eda92ab1 --- /dev/null +++ b/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/AmplifyBrewingRecipeBuilder.java @@ -0,0 +1,24 @@ +package net.errorcraft.itematic.data.server.recipe.brewing; + +import net.errorcraft.itematic.recipe.brewing.AmplifyBrewingRecipe; +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.minecraft.item.Item; +import net.minecraft.recipe.Ingredient; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.Identifier; + +public class AmplifyBrewingRecipeBuilder extends BrewingRecipeBuilder { + public AmplifyBrewingRecipeBuilder(RegistryEntry base, Ingredient reagent, RegistryEntry result, RegistryEntryList conditionItems, Identifier name) { + super(base, reagent, result, conditionItems, name); + } + + @Override + protected BrewingRecipe createRecipe() { + return new AmplifyBrewingRecipe( + this.base, + this.reagent, + this.result + ); + } +} diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/BrewingRecipeBuilder.java b/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/BrewingRecipeBuilder.java new file mode 100644 index 00000000..f731f503 --- /dev/null +++ b/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/BrewingRecipeBuilder.java @@ -0,0 +1,58 @@ +package net.errorcraft.itematic.data.server.recipe.brewing; + +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.minecraft.advancement.Advancement; +import net.minecraft.advancement.AdvancementRequirements; +import net.minecraft.advancement.AdvancementRewards; +import net.minecraft.advancement.criterion.InventoryChangedCriterion; +import net.minecraft.advancement.criterion.RecipeUnlockedCriterion; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.predicate.item.ItemPredicate; +import net.minecraft.recipe.Ingredient; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.Identifier; + +import java.util.Optional; + +public abstract class BrewingRecipeBuilder { + protected final RegistryEntry base; + protected final Ingredient reagent; + protected final RegistryEntry result; + private final RegistryEntryList conditionItems; + private final Identifier name; + + protected BrewingRecipeBuilder(RegistryEntry base, Ingredient reagent, RegistryEntry result, RegistryEntryList conditionItems, Identifier name) { + this.base = base; + this.reagent = reagent; + this.result = result; + this.conditionItems = conditionItems; + this.name = name; + } + + public BrewingRecipeBuilder remainder(RegistryEntry remainder) { + this.reagent.itematic$setRemainder(Optional.of(new ItemStack(remainder))); + return this; + } + + public void save(RecipeExporter exporter) { + Advancement.Builder advancementBuilder = exporter.getAdvancementBuilder() + .criterion("has_the_recipe", RecipeUnlockedCriterion.create(this.name)) + .criterion("has_reagent", InventoryChangedCriterion.Conditions.items( + ItemPredicate.Builder.create() + .itematic$items(this.conditionItems) + )) + .criteriaMerger(AdvancementRequirements.CriterionMerger.OR) + .rewards(AdvancementRewards.Builder.recipe(this.name)); + BrewingRecipe recipe = this.createRecipe(); + exporter.accept( + this.name, + recipe, + advancementBuilder.build(this.name.withPrefixedPath("recipes/brewing/")) + ); + } + + protected abstract BrewingRecipe createRecipe(); +} diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/ModifyBrewingRecipeBuilder.java b/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/ModifyBrewingRecipeBuilder.java new file mode 100644 index 00000000..88400c60 --- /dev/null +++ b/src/datagen/java/net/errorcraft/itematic/data/server/recipe/brewing/ModifyBrewingRecipeBuilder.java @@ -0,0 +1,25 @@ +package net.errorcraft.itematic.data.server.recipe.brewing; + +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.errorcraft.itematic.recipe.brewing.ModifyBrewingRecipe; +import net.minecraft.item.Item; +import net.minecraft.potion.Potion; +import net.minecraft.recipe.Ingredient; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.Identifier; + +public class ModifyBrewingRecipeBuilder extends BrewingRecipeBuilder { + public ModifyBrewingRecipeBuilder(RegistryEntry base, Ingredient reagent, RegistryEntry result, RegistryEntryList conditionItems, Identifier name) { + super(base, reagent, result, conditionItems, name); + } + + @Override + protected BrewingRecipe createRecipe() { + return new ModifyBrewingRecipe( + this.base, + this.reagent, + this.result + ); + } +} diff --git a/src/datagen/java/net/errorcraft/itematic/data/server/tag/ItemTagProvider.java b/src/datagen/java/net/errorcraft/itematic/data/server/tag/ItemTagProvider.java index ff998a9e..e5c5e093 100644 --- a/src/datagen/java/net/errorcraft/itematic/data/server/tag/ItemTagProvider.java +++ b/src/datagen/java/net/errorcraft/itematic/data/server/tag/ItemTagProvider.java @@ -1394,5 +1394,22 @@ protected void configure(RegistryWrapper.WrapperLookup arg) { .add(ItemKeys.TORCHFLOWER) .add(ItemKeys.RED_MUSHROOM) .add(ItemKeys.BROWN_MUSHROOM); + this.getOrCreateTagBuilder(ItematicItemTags.BREWING_INPUTS) + .add(ItemKeys.POTION) + .add(ItemKeys.SPLASH_POTION) + .add(ItemKeys.LINGERING_POTION); + this.getOrCreateTagBuilder(ItematicItemTags.MUNDANE_POTION_REAGENTS) + .add(ItemKeys.REDSTONE) + .add(ItemKeys.MAGMA_CREAM) + .add(ItemKeys.GLISTERING_MELON_SLICE) + .add(ItemKeys.STONE) + .add(ItemKeys.RABBIT_FOOT) + .add(ItemKeys.SLIME_BLOCK) + .add(ItemKeys.SPIDER_EYE) + .add(ItemKeys.GHAST_TEAR) + .add(ItemKeys.BLAZE_POWDER) + .add(ItemKeys.SUGAR) + .add(ItemKeys.COBWEB) + .add(ItemKeys.BREEZE_ROD); } } diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java new file mode 100644 index 00000000..ab6e181c --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/gametest/block/BrewingStandBlockTestSuite.java @@ -0,0 +1,221 @@ +package net.errorcraft.itematic.gametest.block; + +import net.errorcraft.itematic.component.PotionContentsComponentUtil; +import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.gametest.TestUtil; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.screen.BrewingStandMenuDelegate; +import net.errorcraft.itematic.screen.ItematicScreenHandlerTypes; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.potion.Potions; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.test.GameTest; +import net.minecraft.test.TestContext; +import net.minecraft.util.math.BlockPos; +import net.minecraft.world.GameMode; + +public class BrewingStandBlockTestSuite { + private static final BlockPos BLOCK_POSITION = new BlockPos(1, 2, 1); + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingWaterBottleWithNetherWartTurnsItIntoAwkwardPotion(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.WATER)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.NETHER_WART)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(resultPotion, Potions.AWKWARD); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingAwkwardPotionWithSugarTurnsItIntoSwiftnessPotion(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.AWKWARD)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.SUGAR)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(resultPotion, Potions.SWIFTNESS); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingSwiftnessPotionWithGlowstoneDustTurnsItIntoStrongSwiftnessPotion(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.SWIFTNESS)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.GLOWSTONE_DUST)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(resultPotion, Potions.STRONG_SWIFTNESS); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingSwiftnessPotionWithRedstoneTurnsItIntoLongSwiftnessPotion(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.SWIFTNESS)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.REDSTONE)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(resultPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(resultPotion, Potions.LONG_SWIFTNESS); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingSwiftnessPotionWithGunpowderTurnsItIntoSwiftnessSplashPotion(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.SWIFTNESS)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.GUNPOWDER)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(resultPotion, ItemKeys.SPLASH_POTION); + Assert.itemStackHasPotion(resultPotion, Potions.SWIFTNESS); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingSwiftnessSplashPotionWithDragonBreathTurnsItIntoSwiftnessLingeringPotionAndLeavesGlassBottle(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.SPLASH_POTION), Potions.SWIFTNESS)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.DRAGON_BREATH)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack resultPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(resultPotion, ItemKeys.LINGERING_POTION); + Assert.itemStackHasPotion(resultPotion, Potions.SWIFTNESS); + ItemStack ingredientRemainder = brewingStandMenu.getSlot(3).getStack(); + Assert.itemStackIsOf(ingredientRemainder, ItemKeys.GLASS_BOTTLE); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingDifferentPotionsOnlyModifiesCorrectTargets(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.SWIFTNESS)); + brewingStandMenu.getSlot(1) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.WATER)); + brewingStandMenu.getSlot(2) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.LEAPING)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.NETHER_WART)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack firstPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(firstPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(firstPotion, Potions.SWIFTNESS); + ItemStack secondPotion = brewingStandMenu.getSlot(1).getStack(); + Assert.itemStackIsOf(secondPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(secondPotion, Potions.AWKWARD); + ItemStack thirdPotion = brewingStandMenu.getSlot(2).getStack(); + Assert.itemStackIsOf(thirdPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(thirdPotion, Potions.LEAPING); + } + ) + .completeIfSuccessful(); + } + + @GameTest(templateName = "itematic:block.brewing_stand", tickLimit = 401) + public void brewingPotionsTargetingMultipleValidRecipesModifiesBoth(TestContext context) { + ServerWorld world = context.getWorld(); + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + BrewingStandMenuDelegate brewingStandMenu = TestUtil.getMenuFromBlock(context, BLOCK_POSITION, player, ItematicScreenHandlerTypes.BREWING_STAND); + brewingStandMenu.getSlot(0) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.WATER)); + brewingStandMenu.getSlot(1) + .setStack(PotionContentsComponentUtil.setPotion(world.itematic$createStack(ItemKeys.POTION), Potions.AWKWARD)); + brewingStandMenu.getSlot(3) + .setStack(world.itematic$createStack(ItemKeys.SUGAR)); + brewingStandMenu.getSlot(4) + .setStack(world.itematic$createStack(ItemKeys.BLAZE_POWDER)); + context.createTimedTaskRunner() + .expectMinDurationAndRun( + 401, + () -> { + ItemStack firstPotion = brewingStandMenu.getSlot(0).getStack(); + Assert.itemStackIsOf(firstPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(firstPotion, Potions.MUNDANE); + ItemStack secondPotion = brewingStandMenu.getSlot(1).getStack(); + Assert.itemStackIsOf(secondPotion, ItemKeys.POTION); + Assert.itemStackHasPotion(secondPotion, Potions.SWIFTNESS); + } + ) + .completeIfSuccessful(); + } +} \ No newline at end of file diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java new file mode 100644 index 00000000..239498bd --- /dev/null +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/TotemOfUndyingTestSuite.java @@ -0,0 +1,31 @@ +package net.errorcraft.itematic.gametest.item; + +import net.errorcraft.itematic.gametest.Assert; +import net.errorcraft.itematic.item.ItemKeys; +import net.fabricmc.fabric.api.gametest.v1.FabricGameTest; +import net.minecraft.entity.effect.StatusEffects; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.test.GameTest; +import net.minecraft.test.TestContext; +import net.minecraft.util.Hand; +import net.minecraft.world.GameMode; + +public class TotemOfUndyingTestSuite { + @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) + public void holdingTotemOfUndyingSavesHolderFromDeath(TestContext context) { + PlayerEntity player = context.createMockPlayer(GameMode.SURVIVAL); + ServerWorld world = context.getWorld(); + ItemStack stack = world.itematic$createStack(ItemKeys.TOTEM_OF_UNDYING); + player.setStackInHand(Hand.MAIN_HAND, stack); + player.damage(world.getDamageSources().fall(), Float.MAX_VALUE); + context.addInstantFinalTask(() -> { + Assert.areFloatsEqual(player.getHealth(), 1.0f, (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead"); + context.expectEntityHasEffect(player, StatusEffects.REGENERATION, 1); + context.expectEntityHasEffect(player, StatusEffects.ABSORPTION, 1); + context.expectEntityHasEffect(player, StatusEffects.FIRE_RESISTANCE, 0); + Assert.itemStackIsEmpty(player.getStackInHand(Hand.MAIN_HAND)); + }); + } +} diff --git a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/WeaponItemComponentTestSuite.java b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/WeaponItemComponentTestSuite.java index 70ec90a4..72132393 100644 --- a/src/gametest/java/net/errorcraft/itematic/gametest/item/component/WeaponItemComponentTestSuite.java +++ b/src/gametest/java/net/errorcraft/itematic/gametest/item/component/WeaponItemComponentTestSuite.java @@ -38,7 +38,7 @@ public void zombieAttackingUnarmedDealsDamageFromTrueBaseValueAttackDamageAttrib } @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) - public void zombieAttackingWithIronSwordDealsDamageFromIronSword(TestContext context) { + public void zombieAttackingWithIronSwordDealsCorrectDamage(TestContext context) { ServerWorld world = context.getWorld(); ItemStack stack = world.itematic$createStack(ItemKeys.IRON_SWORD); ZombieEntity zombie = TestUtil.createEntity(context, EntityType.ZOMBIE, entity -> entity.setStackInHand(Hand.MAIN_HAND, stack)); @@ -48,14 +48,14 @@ public void zombieAttackingWithIronSwordDealsDamageFromIronSword(TestContext con context.assertTrue(zombie.tryAttack(victim), "Expected attack to be successful"); Assert.areDoublesEqual( victim.getHealth(), - MAX_HEALTH_VICTIM - TestUtil.getItemComponent(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), + MAX_HEALTH_VICTIM - zombie.getAttributeBaseValue(EntityAttributes.GENERIC_ATTACK_DAMAGE) - TestUtil.getItemComponent(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" ); }).completeIfSuccessful(); } @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) - public void piglinAttackingWithIronSwordDealsDamageFromIronSword(TestContext context) { + public void piglinAttackingWithIronSwordDealsCorrectDamage(TestContext context) { ServerWorld world = context.getWorld(); ItemStack stack = world.itematic$createStack(ItemKeys.IRON_SWORD); PiglinEntity piglin = TestUtil.createEntity(context, EntityType.PIGLIN, entity -> entity.setStackInHand(Hand.MAIN_HAND, stack)); @@ -65,14 +65,14 @@ public void piglinAttackingWithIronSwordDealsDamageFromIronSword(TestContext con context.assertTrue(piglin.tryAttack(victim), "Expected attack to be successful"); Assert.areDoublesEqual( victim.getHealth(), - MAX_HEALTH_VICTIM - TestUtil.getItemComponent(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), + MAX_HEALTH_VICTIM - piglin.getAttributeBaseValue(EntityAttributes.GENERIC_ATTACK_DAMAGE) - TestUtil.getItemComponent(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" ); }).completeIfSuccessful(); } @GameTest(templateName = FabricGameTest.EMPTY_STRUCTURE) - public void piglinAttackingWithGoldenSwordDealsDamageFromTrueBaseValueAttackDamageAttributeAndGoldenSword(TestContext context) { + public void piglinAttackingWithGoldenSwordDealsCorrectDamage(TestContext context) { ServerWorld world = context.getWorld(); ItemStack stack = world.itematic$createStack(ItemKeys.GOLDEN_SWORD); PiglinEntity piglin = TestUtil.createEntity(context, EntityType.PIGLIN, entity -> entity.setStackInHand(Hand.MAIN_HAND, stack)); @@ -82,7 +82,7 @@ public void piglinAttackingWithGoldenSwordDealsDamageFromTrueBaseValueAttackDama context.assertTrue(piglin.tryAttack(victim), "Expected attack to be successful"); Assert.areDoublesEqual( victim.getHealth(), - MAX_HEALTH_VICTIM - piglin.getAttributeBaseValue(EntityAttributes.GENERIC_ATTACK_DAMAGE) - TestUtil.getItemComponent(stack, ItemComponentTypes.WEAPON).attackDamage().rules().getFirst().damage().orElseThrow(), + MAX_HEALTH_VICTIM - piglin.getAttributeBaseValue(EntityAttributes.GENERIC_ATTACK_DAMAGE) - TestUtil.getItemComponent(stack, ItemComponentTypes.WEAPON).attackDamage().defaultDamage(), (value, expected) -> "Expected health to be " + expected + ", got " + value + " instead" ); }).completeIfSuccessful(); diff --git a/src/gametest/resources/data/itematic/gametest/structure/block.brewing_stand.snbt b/src/gametest/resources/data/itematic/gametest/structure/block.brewing_stand.snbt new file mode 100644 index 00000000..bf3b9963 --- /dev/null +++ b/src/gametest/resources/data/itematic/gametest/structure/block.brewing_stand.snbt @@ -0,0 +1,39 @@ +{ + DataVersion: 3955, + size: [3, 3, 3], + data: [ + {pos: [0, 0, 0], state: "minecraft:bedrock"}, + {pos: [0, 0, 1], state: "minecraft:bedrock"}, + {pos: [0, 0, 2], state: "minecraft:bedrock"}, + {pos: [1, 0, 0], state: "minecraft:bedrock"}, + {pos: [1, 0, 1], state: "minecraft:bedrock"}, + {pos: [1, 0, 2], state: "minecraft:bedrock"}, + {pos: [2, 0, 0], state: "minecraft:bedrock"}, + {pos: [2, 0, 1], state: "minecraft:bedrock"}, + {pos: [2, 0, 2], state: "minecraft:bedrock"}, + {pos: [0, 1, 0], state: "minecraft:air"}, + {pos: [0, 1, 1], state: "minecraft:air"}, + {pos: [0, 1, 2], state: "minecraft:air"}, + {pos: [1, 1, 0], state: "minecraft:air"}, + {pos: [1, 1, 1], state: "minecraft:brewing_stand{has_bottle_0:false,has_bottle_1:false,has_bottle_2:false}", nbt: {BrewTime: 0s, Fuel: 0b, Items: [], id: "minecraft:brewing_stand"}}, + {pos: [1, 1, 2], state: "minecraft:air"}, + {pos: [2, 1, 0], state: "minecraft:air"}, + {pos: [2, 1, 1], state: "minecraft:air"}, + {pos: [2, 1, 2], state: "minecraft:air"}, + {pos: [0, 2, 0], state: "minecraft:air"}, + {pos: [0, 2, 1], state: "minecraft:air"}, + {pos: [0, 2, 2], state: "minecraft:air"}, + {pos: [1, 2, 0], state: "minecraft:air"}, + {pos: [1, 2, 1], state: "minecraft:air"}, + {pos: [1, 2, 2], state: "minecraft:air"}, + {pos: [2, 2, 0], state: "minecraft:air"}, + {pos: [2, 2, 1], state: "minecraft:air"}, + {pos: [2, 2, 2], state: "minecraft:air"} + ], + entities: [], + palette: [ + "minecraft:bedrock", + "minecraft:air", + "minecraft:brewing_stand{has_bottle_0:false,has_bottle_1:false,has_bottle_2:false}" + ] +} diff --git a/src/gametest/resources/fabric.mod.json b/src/gametest/resources/fabric.mod.json index 40887825..22c20bef 100644 --- a/src/gametest/resources/fabric.mod.json +++ b/src/gametest/resources/fabric.mod.json @@ -9,6 +9,7 @@ "fabric-gametest": [ "net.errorcraft.itematic.gametest.block.AnvilBlockTestSuite", "net.errorcraft.itematic.gametest.block.BeehiveBlockTestSuite", + "net.errorcraft.itematic.gametest.block.BrewingStandBlockTestSuite", "net.errorcraft.itematic.gametest.block.CandleBlockTestSuite", "net.errorcraft.itematic.gametest.block.ComposterBlockTestSuite", "net.errorcraft.itematic.gametest.block.DispenserBehaviorTestSuite", @@ -37,6 +38,7 @@ "net.errorcraft.itematic.gametest.item.HoneyBottleTestSuite", "net.errorcraft.itematic.gametest.item.LeadTestSuite", "net.errorcraft.itematic.gametest.item.SignTestSuite", + "net.errorcraft.itematic.gametest.item.TotemOfUndyingTestSuite", "net.errorcraft.itematic.gametest.item.component.BlockItemComponentTestSuite", "net.errorcraft.itematic.gametest.item.component.ConsumableItemComponentTestSuite", "net.errorcraft.itematic.gametest.item.component.EquipmentItemComponentTestSuite", diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/awkward_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/awkward_potion.json new file mode 100644 index 00000000..0dfedafd --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/awkward_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:nether_wart" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:awkward_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:awkward_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/fire_resistance_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/fire_resistance_potion.json new file mode 100644 index 00000000..8bd8653d --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/fire_resistance_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:magma_cream" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:fire_resistance_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:fire_resistance_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_healing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_healing_potion.json new file mode 100644 index 00000000..6e317b33 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_healing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:harming_potion_from_healing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:harming_potion_from_healing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_long_poison_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_long_poison_potion.json new file mode 100644 index 00000000..70718998 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_long_poison_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:harming_potion_from_long_poison_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:harming_potion_from_long_poison_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_poison_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_poison_potion.json new file mode 100644 index 00000000..0223b81f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/harming_potion_from_poison_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:harming_potion_from_poison_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:harming_potion_from_poison_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/healing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/healing_potion.json new file mode 100644 index 00000000..c0ff438e --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/healing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glistering_melon_slice" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:healing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:healing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/infested_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/infested_potion.json new file mode 100644 index 00000000..5865fe29 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/infested_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:stone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:infested_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:infested_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/invisibility_potion_from_night_vision_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/invisibility_potion_from_night_vision_potion.json new file mode 100644 index 00000000..a028eb51 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/invisibility_potion_from_night_vision_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:invisibility_potion_from_night_vision_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:invisibility_potion_from_night_vision_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/leaping_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/leaping_potion.json new file mode 100644 index 00000000..ca1dbdfc --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/leaping_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:rabbit_foot" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:leaping_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:leaping_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/lingering_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/lingering_potion.json new file mode 100644 index 00000000..e3e72f46 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/lingering_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:dragon_breath" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:lingering_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:lingering_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_fire_resistance_potion_from_fire_resistance_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_fire_resistance_potion_from_fire_resistance_potion.json new file mode 100644 index 00000000..944ada4f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_fire_resistance_potion_from_fire_resistance_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_fire_resistance_potion_from_fire_resistance_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_fire_resistance_potion_from_fire_resistance_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_invisibility_potion_from_invisibility_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_invisibility_potion_from_invisibility_potion.json new file mode 100644 index 00000000..82058cf6 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_invisibility_potion_from_invisibility_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_invisibility_potion_from_invisibility_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_invisibility_potion_from_invisibility_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_invisibility_potion_from_long_night_vision_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_invisibility_potion_from_long_night_vision_potion.json new file mode 100644 index 00000000..b41b6e48 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_invisibility_potion_from_long_night_vision_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_invisibility_potion_from_long_night_vision_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_invisibility_potion_from_long_night_vision_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_leaping_potion_from_leaping_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_leaping_potion_from_leaping_potion.json new file mode 100644 index 00000000..6f0f0c4e --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_leaping_potion_from_leaping_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_leaping_potion_from_leaping_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_leaping_potion_from_leaping_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_night_vision_potion_from_night_vision_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_night_vision_potion_from_night_vision_potion.json new file mode 100644 index 00000000..fcd4388c --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_night_vision_potion_from_night_vision_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_night_vision_potion_from_night_vision_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_night_vision_potion_from_night_vision_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_poison_potion_from_poison_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_poison_potion_from_poison_potion.json new file mode 100644 index 00000000..cc153376 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_poison_potion_from_poison_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_poison_potion_from_poison_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_poison_potion_from_poison_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_regeneration_potion_from_regeneration_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_regeneration_potion_from_regeneration_potion.json new file mode 100644 index 00000000..070dddf4 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_regeneration_potion_from_regeneration_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_regeneration_potion_from_regeneration_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_regeneration_potion_from_regeneration_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slow_falling_potion_from_slow_falling_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slow_falling_potion_from_slow_falling_potion.json new file mode 100644 index 00000000..06552673 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slow_falling_potion_from_slow_falling_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_slow_falling_potion_from_slow_falling_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_slow_falling_potion_from_slow_falling_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_long_leaping_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_long_leaping_potion.json new file mode 100644 index 00000000..d971bc8b --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_long_leaping_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_slowness_potion_from_long_leaping_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_slowness_potion_from_long_leaping_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_long_swiftness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_long_swiftness_potion.json new file mode 100644 index 00000000..41fa8cf8 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_long_swiftness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_slowness_potion_from_long_swiftness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_slowness_potion_from_long_swiftness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_slowness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_slowness_potion.json new file mode 100644 index 00000000..2383ad03 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_slowness_potion_from_slowness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_slowness_potion_from_slowness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_slowness_potion_from_slowness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_strength_potion_from_strength_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_strength_potion_from_strength_potion.json new file mode 100644 index 00000000..6d6f6112 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_strength_potion_from_strength_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_strength_potion_from_strength_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_strength_potion_from_strength_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_swiftness_potion_from_swiftness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_swiftness_potion_from_swiftness_potion.json new file mode 100644 index 00000000..5c44e41a --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_swiftness_potion_from_swiftness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_swiftness_potion_from_swiftness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_swiftness_potion_from_swiftness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_turtle_master_potion_from_turtle_master_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_turtle_master_potion_from_turtle_master_potion.json new file mode 100644 index 00000000..6f294d28 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_turtle_master_potion_from_turtle_master_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_turtle_master_potion_from_turtle_master_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_turtle_master_potion_from_turtle_master_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_water_breathing_potion_from_water_breathing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_water_breathing_potion_from_water_breathing_potion.json new file mode 100644 index 00000000..05f08400 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_water_breathing_potion_from_water_breathing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_water_breathing_potion_from_water_breathing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_water_breathing_potion_from_water_breathing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/long_weakness_potion_from_weakness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_weakness_potion_from_weakness_potion.json new file mode 100644 index 00000000..f5219685 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/long_weakness_potion_from_weakness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:redstone" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:long_weakness_potion_from_weakness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:long_weakness_potion_from_weakness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/mundane_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/mundane_potion.json new file mode 100644 index 00000000..5787d38f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/mundane_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "#minecraft:mundane_potion_reagents" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:mundane_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:mundane_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/night_vision_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/night_vision_potion.json new file mode 100644 index 00000000..75783b93 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/night_vision_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:golden_carrot" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:night_vision_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:night_vision_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/oozing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/oozing_potion.json new file mode 100644 index 00000000..60121448 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/oozing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:slime_block" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:oozing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:oozing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/poison_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/poison_potion.json new file mode 100644 index 00000000..f9ebc9b1 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/poison_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:poison_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:poison_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/regeneration_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/regeneration_potion.json new file mode 100644 index 00000000..4c40da0a --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/regeneration_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:ghast_tear" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:regeneration_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:regeneration_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/slow_falling_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/slow_falling_potion.json new file mode 100644 index 00000000..cf45e674 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/slow_falling_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:phantom_membrane" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:slow_falling_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:slow_falling_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/slowness_potion_from_leaping_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/slowness_potion_from_leaping_potion.json new file mode 100644 index 00000000..6f487eb7 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/slowness_potion_from_leaping_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:slowness_potion_from_leaping_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:slowness_potion_from_leaping_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/slowness_potion_from_swiftness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/slowness_potion_from_swiftness_potion.json new file mode 100644 index 00000000..92d574fc --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/slowness_potion_from_swiftness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:slowness_potion_from_swiftness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:slowness_potion_from_swiftness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/splash_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/splash_potion.json new file mode 100644 index 00000000..9b41e97f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/splash_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:gunpowder" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:splash_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:splash_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strength_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strength_potion.json new file mode 100644 index 00000000..eed6033f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strength_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:blaze_powder" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strength_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strength_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_harming_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_harming_potion.json new file mode 100644 index 00000000..6e8e5831 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_harming_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_harming_potion_from_harming_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_harming_potion_from_harming_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_strong_healing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_strong_healing_potion.json new file mode 100644 index 00000000..b9e0fb9f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_strong_healing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_harming_potion_from_strong_healing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_harming_potion_from_strong_healing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_strong_poison_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_strong_poison_potion.json new file mode 100644 index 00000000..97ff412a --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_harming_potion_from_strong_poison_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_harming_potion_from_strong_poison_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_harming_potion_from_strong_poison_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_healing_potion_from_healing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_healing_potion_from_healing_potion.json new file mode 100644 index 00000000..6d1478c5 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_healing_potion_from_healing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_healing_potion_from_healing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_healing_potion_from_healing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_leaping_potion_from_leaping_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_leaping_potion_from_leaping_potion.json new file mode 100644 index 00000000..eeae4c04 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_leaping_potion_from_leaping_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_leaping_potion_from_leaping_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_leaping_potion_from_leaping_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_poison_potion_from_poison_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_poison_potion_from_poison_potion.json new file mode 100644 index 00000000..5dd41c4d --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_poison_potion_from_poison_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_poison_potion_from_poison_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_poison_potion_from_poison_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_regeneration_potion_from_regeneration_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_regeneration_potion_from_regeneration_potion.json new file mode 100644 index 00000000..e40e563f --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_regeneration_potion_from_regeneration_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_regeneration_potion_from_regeneration_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_regeneration_potion_from_regeneration_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_slowness_potion_from_slowness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_slowness_potion_from_slowness_potion.json new file mode 100644 index 00000000..b3862d25 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_slowness_potion_from_slowness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_slowness_potion_from_slowness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_slowness_potion_from_slowness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_strength_potion_from_strength_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_strength_potion_from_strength_potion.json new file mode 100644 index 00000000..7b2462bf --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_strength_potion_from_strength_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_strength_potion_from_strength_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_strength_potion_from_strength_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_swiftness_potion_from_swiftness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_swiftness_potion_from_swiftness_potion.json new file mode 100644 index 00000000..c9208825 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_swiftness_potion_from_swiftness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_swiftness_potion_from_swiftness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_swiftness_potion_from_swiftness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_turtle_master_potion_from_turtle_master_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_turtle_master_potion_from_turtle_master_potion.json new file mode 100644 index 00000000..11e40254 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/strong_turtle_master_potion_from_turtle_master_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:strong_turtle_master_potion_from_turtle_master_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:strong_turtle_master_potion_from_turtle_master_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/swiftness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/swiftness_potion.json new file mode 100644 index 00000000..b62718c9 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/swiftness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:sugar" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:swiftness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:swiftness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/thick_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/thick_potion.json new file mode 100644 index 00000000..cebec4f6 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/thick_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:glowstone_dust" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:thick_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:thick_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/turtle_master_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/turtle_master_potion.json new file mode 100644 index 00000000..5cbbe809 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/turtle_master_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:turtle_helmet" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:turtle_master_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:turtle_master_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/water_breathing_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/water_breathing_potion.json new file mode 100644 index 00000000..ce80e7bc --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/water_breathing_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:pufferfish" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:water_breathing_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:water_breathing_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/weakness_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/weakness_potion.json new file mode 100644 index 00000000..b2f71209 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/weakness_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:fermented_spider_eye" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:weakness_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:weakness_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/weaving_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/weaving_potion.json new file mode 100644 index 00000000..e2cc6ccd --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/weaving_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:cobweb" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:weaving_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:weaving_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/advancement/recipes/brewing/wind_charged_potion.json b/src/main/generated/data/minecraft/advancement/recipes/brewing/wind_charged_potion.json new file mode 100644 index 00000000..74491448 --- /dev/null +++ b/src/main/generated/data/minecraft/advancement/recipes/brewing/wind_charged_potion.json @@ -0,0 +1,32 @@ +{ + "parent": "minecraft:recipes/root", + "criteria": { + "has_reagent": { + "conditions": { + "items": [ + { + "items": "minecraft:breeze_rod" + } + ] + }, + "trigger": "minecraft:inventory_changed" + }, + "has_the_recipe": { + "conditions": { + "recipe": "minecraft:wind_charged_potion" + }, + "trigger": "minecraft:recipe_unlocked" + } + }, + "requirements": [ + [ + "has_the_recipe", + "has_reagent" + ] + ], + "rewards": { + "recipes": [ + "minecraft:wind_charged_potion" + ] + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/allay_spawn_egg.json b/src/main/generated/data/minecraft/item/allay_spawn_egg.json index b3453567..5038da96 100644 --- a/src/main/generated/data/minecraft/item/allay_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/allay_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:allay" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 44543 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/armadillo_spawn_egg.json b/src/main/generated/data/minecraft/item/armadillo_spawn_egg.json index 73a6405e..3fcc8b0e 100644 --- a/src/main/generated/data/minecraft/item/armadillo_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/armadillo_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:armadillo" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 8538184 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/axolotl_spawn_egg.json b/src/main/generated/data/minecraft/item/axolotl_spawn_egg.json index 777419d2..e3acddcd 100644 --- a/src/main/generated/data/minecraft/item/axolotl_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/axolotl_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:axolotl" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 10890612 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/bat_spawn_egg.json b/src/main/generated/data/minecraft/item/bat_spawn_egg.json index 89cfc5f8..e8b2cf7b 100644 --- a/src/main/generated/data/minecraft/item/bat_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/bat_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:bat" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 986895 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/bee_spawn_egg.json b/src/main/generated/data/minecraft/item/bee_spawn_egg.json index d47eb346..580436c2 100644 --- a/src/main/generated/data/minecraft/item/bee_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/bee_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:bee" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 4400155 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/beetroot_soup.json b/src/main/generated/data/minecraft/item/beetroot_soup.json index 096d3761..2f8adb23 100644 --- a/src/main/generated/data/minecraft/item/beetroot_soup.json +++ b/src/main/generated/data/minecraft/item/beetroot_soup.json @@ -3,9 +3,7 @@ "translation_key": "item.minecraft.beetroot_soup" }, "components": { - "minecraft:consumable": { - "result_item": "minecraft:bowl" - }, + "minecraft:consumable": {}, "minecraft:food": { "nutrition": 6, "saturation": 7.2000003 @@ -13,6 +11,10 @@ "minecraft:stackable": 1, "minecraft:useable": { "animation": "eat", + "remainder": { + "id": "minecraft:bowl", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 32 diff --git a/src/main/generated/data/minecraft/item/blaze_spawn_egg.json b/src/main/generated/data/minecraft/item/blaze_spawn_egg.json index 7e6df0d4..7d20e06e 100644 --- a/src/main/generated/data/minecraft/item/blaze_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/blaze_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:blaze" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16775294 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/bogged_spawn_egg.json b/src/main/generated/data/minecraft/item/bogged_spawn_egg.json index 03d6d1ea..cbe240c8 100644 --- a/src/main/generated/data/minecraft/item/bogged_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/bogged_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:bogged" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 3231003 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/breeze_spawn_egg.json b/src/main/generated/data/minecraft/item/breeze_spawn_egg.json index ca624de9..4aeec6a5 100644 --- a/src/main/generated/data/minecraft/item/breeze_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/breeze_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:breeze" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 9529055 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/camel_spawn_egg.json b/src/main/generated/data/minecraft/item/camel_spawn_egg.json index 986f1ad8..40701bd9 100644 --- a/src/main/generated/data/minecraft/item/camel_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/camel_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:camel" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 13341495 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/cat_spawn_egg.json b/src/main/generated/data/minecraft/item/cat_spawn_egg.json index c1fd6965..d6ef32a8 100644 --- a/src/main/generated/data/minecraft/item/cat_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cat_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:cat" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 9794134 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/cave_spider_spawn_egg.json b/src/main/generated/data/minecraft/item/cave_spider_spawn_egg.json index 23b818e6..265a3377 100644 --- a/src/main/generated/data/minecraft/item/cave_spider_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cave_spider_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:cave_spider" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 11013646 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/chicken.json b/src/main/generated/data/minecraft/item/chicken.json index 28f7872c..fa58bd30 100644 --- a/src/main/generated/data/minecraft/item/chicken.json +++ b/src/main/generated/data/minecraft/item/chicken.json @@ -5,16 +5,6 @@ "components": { "minecraft:consumable": {}, "minecraft:food": { - "effects": [ - { - "effect": { - "id": "minecraft:hunger", - "duration": 600, - "show_icon": true - }, - "probability": 0.3 - } - ], "nutrition": 2, "saturation": 1.2 }, @@ -26,5 +16,30 @@ "amount": 32 } } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { + "id": "minecraft:poison", + "duration": 600, + "show_icon": true + } + ], + "entity": "this" + }, + "requirements": { + "conditions": { + "chance": 0.3, + "condition": "minecraft:random_chance" + }, + "context": { + "entity": "this", + "position": "this" + } + } + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/chicken_spawn_egg.json b/src/main/generated/data/minecraft/item/chicken_spawn_egg.json index 6395345b..a9c28e0d 100644 --- a/src/main/generated/data/minecraft/item/chicken_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/chicken_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:chicken" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16711680 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/cod_spawn_egg.json b/src/main/generated/data/minecraft/item/cod_spawn_egg.json index c98903a7..fb08ca9d 100644 --- a/src/main/generated/data/minecraft/item/cod_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cod_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:cod" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15058059 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/cow_spawn_egg.json b/src/main/generated/data/minecraft/item/cow_spawn_egg.json index 64b3cb49..fc45214a 100644 --- a/src/main/generated/data/minecraft/item/cow_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/cow_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:cow" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 10592673 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/creeper_spawn_egg.json b/src/main/generated/data/minecraft/item/creeper_spawn_egg.json index 1effb8f0..be2e1f76 100644 --- a/src/main/generated/data/minecraft/item/creeper_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/creeper_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:creeper" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 0 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/dolphin_spawn_egg.json b/src/main/generated/data/minecraft/item/dolphin_spawn_egg.json index c1380b75..4adb1377 100644 --- a/src/main/generated/data/minecraft/item/dolphin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/dolphin_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:dolphin" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16382457 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/donkey_spawn_egg.json b/src/main/generated/data/minecraft/item/donkey_spawn_egg.json index f01275a6..14eec093 100644 --- a/src/main/generated/data/minecraft/item/donkey_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/donkey_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:donkey" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 8811878 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/dragon_breath.json b/src/main/generated/data/minecraft/item/dragon_breath.json index cbaf8f85..ae6070e5 100644 --- a/src/main/generated/data/minecraft/item/dragon_breath.json +++ b/src/main/generated/data/minecraft/item/dragon_breath.json @@ -4,9 +4,6 @@ "translation_key": "item.minecraft.dragon_breath" }, "components": { - "minecraft:recipe_remainder": { - "item": "minecraft:glass_bottle" - }, "minecraft:stackable": 64 } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/drowned_spawn_egg.json b/src/main/generated/data/minecraft/item/drowned_spawn_egg.json index 9cadc700..8cc24ed2 100644 --- a/src/main/generated/data/minecraft/item/drowned_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/drowned_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:drowned" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7969893 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/elder_guardian_spawn_egg.json b/src/main/generated/data/minecraft/item/elder_guardian_spawn_egg.json index 6b99f9bd..723e4e43 100644 --- a/src/main/generated/data/minecraft/item/elder_guardian_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/elder_guardian_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:elder_guardian" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7632531 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/enchanted_golden_apple.json b/src/main/generated/data/minecraft/item/enchanted_golden_apple.json index 130d8173..fd9a1bcb 100644 --- a/src/main/generated/data/minecraft/item/enchanted_golden_apple.json +++ b/src/main/generated/data/minecraft/item/enchanted_golden_apple.json @@ -8,47 +8,46 @@ "minecraft:consumable": {}, "minecraft:food": { "always_edible": true, - "effects": [ - { - "effect": { + "nutrition": 4, + "saturation": 9.6 + }, + "minecraft:stackable": 64, + "minecraft:useable": { + "animation": "eat", + "ticks": { + "type": "minecraft:constant", + "amount": 32 + } + } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { "id": "minecraft:regeneration", "amplifier": 1, "duration": 400, "show_icon": true - } - }, - { - "effect": { + }, + { "id": "minecraft:resistance", "duration": 6000, "show_icon": true - } - }, - { - "effect": { + }, + { "id": "minecraft:fire_resistance", "duration": 6000, "show_icon": true - } - }, - { - "effect": { + }, + { "id": "minecraft:absorption", - "amplifier": 3, "duration": 2400, "show_icon": true } - } - ], - "nutrition": 4, - "saturation": 9.6 - }, - "minecraft:stackable": 64, - "minecraft:useable": { - "animation": "eat", - "ticks": { - "type": "minecraft:constant", - "amount": 32 + ], + "entity": "this" } } } diff --git a/src/main/generated/data/minecraft/item/ender_dragon_spawn_egg.json b/src/main/generated/data/minecraft/item/ender_dragon_spawn_egg.json index c9ffc3f3..98c24408 100644 --- a/src/main/generated/data/minecraft/item/ender_dragon_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ender_dragon_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:ender_dragon" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 14711290 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/enderman_spawn_egg.json b/src/main/generated/data/minecraft/item/enderman_spawn_egg.json index 597ac26b..b17ef2a3 100644 --- a/src/main/generated/data/minecraft/item/enderman_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/enderman_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:enderman" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 0 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/endermite_spawn_egg.json b/src/main/generated/data/minecraft/item/endermite_spawn_egg.json index 7fc794a2..233816c7 100644 --- a/src/main/generated/data/minecraft/item/endermite_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/endermite_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:endermite" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7237230 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/evoker_spawn_egg.json b/src/main/generated/data/minecraft/item/evoker_spawn_egg.json index db495197..624ce2cf 100644 --- a/src/main/generated/data/minecraft/item/evoker_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/evoker_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:evoker" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 1973274 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/fox_spawn_egg.json b/src/main/generated/data/minecraft/item/fox_spawn_egg.json index d4efdb7b..186ca6af 100644 --- a/src/main/generated/data/minecraft/item/fox_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/fox_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:fox" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 13396256 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/frog_spawn_egg.json b/src/main/generated/data/minecraft/item/frog_spawn_egg.json index f292ee9d..ebe0c664 100644 --- a/src/main/generated/data/minecraft/item/frog_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/frog_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:frog" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16762748 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/ghast_spawn_egg.json b/src/main/generated/data/minecraft/item/ghast_spawn_egg.json index 9f9f78bf..f8c3e9f4 100644 --- a/src/main/generated/data/minecraft/item/ghast_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ghast_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:ghast" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 12369084 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/glow_squid_spawn_egg.json b/src/main/generated/data/minecraft/item/glow_squid_spawn_egg.json index 0ee47e47..734801d3 100644 --- a/src/main/generated/data/minecraft/item/glow_squid_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/glow_squid_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:glow_squid" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 8778172 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/goat_spawn_egg.json b/src/main/generated/data/minecraft/item/goat_spawn_egg.json index 92927fe6..e321a601 100644 --- a/src/main/generated/data/minecraft/item/goat_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/goat_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:goat" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5589310 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/golden_apple.json b/src/main/generated/data/minecraft/item/golden_apple.json index 07e03992..eb580510 100644 --- a/src/main/generated/data/minecraft/item/golden_apple.json +++ b/src/main/generated/data/minecraft/item/golden_apple.json @@ -7,23 +7,6 @@ "minecraft:consumable": {}, "minecraft:food": { "always_edible": true, - "effects": [ - { - "effect": { - "id": "minecraft:regeneration", - "amplifier": 1, - "duration": 100, - "show_icon": true - } - }, - { - "effect": { - "id": "minecraft:absorption", - "duration": 2400, - "show_icon": true - } - } - ], "nutrition": 4, "saturation": 9.6 }, @@ -35,5 +18,26 @@ "amount": 32 } } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { + "id": "minecraft:regeneration", + "amplifier": 1, + "duration": 100, + "show_icon": true + }, + { + "id": "minecraft:absorption", + "duration": 2400, + "show_icon": true + } + ], + "entity": "this" + } + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/golden_axe.json b/src/main/generated/data/minecraft/item/golden_axe.json index 438b2948..1e1409b8 100644 --- a/src/main/generated/data/minecraft/item/golden_axe.json +++ b/src/main/generated/data/minecraft/item/golden_axe.json @@ -29,13 +29,7 @@ "minecraft:weapon": { "attack_damage": { "default_damage": 7.0, - "rules": [ - { - "add_base": true, - "damage": 6.0, - "entities": "#minecraft:proficient_with_golden_weapons" - } - ] + "rules": [] }, "attack_speed": 0.25, "damage_per_hit": 2 diff --git a/src/main/generated/data/minecraft/item/golden_hoe.json b/src/main/generated/data/minecraft/item/golden_hoe.json index e83b1fe5..6ed0a82a 100644 --- a/src/main/generated/data/minecraft/item/golden_hoe.json +++ b/src/main/generated/data/minecraft/item/golden_hoe.json @@ -29,13 +29,7 @@ "minecraft:weapon": { "attack_damage": { "default_damage": 1.0, - "rules": [ - { - "add_base": true, - "damage": 0.0, - "entities": "#minecraft:proficient_with_golden_weapons" - } - ] + "rules": [] }, "attack_speed": 0.25, "damage_per_hit": 2 diff --git a/src/main/generated/data/minecraft/item/golden_pickaxe.json b/src/main/generated/data/minecraft/item/golden_pickaxe.json index fb351533..384f3ac0 100644 --- a/src/main/generated/data/minecraft/item/golden_pickaxe.json +++ b/src/main/generated/data/minecraft/item/golden_pickaxe.json @@ -29,13 +29,7 @@ "minecraft:weapon": { "attack_damage": { "default_damage": 2.0, - "rules": [ - { - "add_base": true, - "damage": 1.0, - "entities": "#minecraft:proficient_with_golden_weapons" - } - ] + "rules": [] }, "attack_speed": 0.3, "damage_per_hit": 2 diff --git a/src/main/generated/data/minecraft/item/golden_shovel.json b/src/main/generated/data/minecraft/item/golden_shovel.json index 924a52a1..3250849c 100644 --- a/src/main/generated/data/minecraft/item/golden_shovel.json +++ b/src/main/generated/data/minecraft/item/golden_shovel.json @@ -29,13 +29,7 @@ "minecraft:weapon": { "attack_damage": { "default_damage": 2.5, - "rules": [ - { - "add_base": true, - "damage": 1.5, - "entities": "#minecraft:proficient_with_golden_weapons" - } - ] + "rules": [] }, "attack_speed": 0.25, "damage_per_hit": 2 diff --git a/src/main/generated/data/minecraft/item/golden_sword.json b/src/main/generated/data/minecraft/item/golden_sword.json index 14454b67..26598c9c 100644 --- a/src/main/generated/data/minecraft/item/golden_sword.json +++ b/src/main/generated/data/minecraft/item/golden_sword.json @@ -30,13 +30,7 @@ "minecraft:weapon": { "attack_damage": { "default_damage": 4.0, - "rules": [ - { - "add_base": true, - "damage": 3.0, - "entities": "#minecraft:proficient_with_golden_weapons" - } - ] + "rules": [] }, "attack_speed": 0.4 } diff --git a/src/main/generated/data/minecraft/item/guardian_spawn_egg.json b/src/main/generated/data/minecraft/item/guardian_spawn_egg.json index 80e8465b..040848d3 100644 --- a/src/main/generated/data/minecraft/item/guardian_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/guardian_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:guardian" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15826224 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/hoglin_spawn_egg.json b/src/main/generated/data/minecraft/item/hoglin_spawn_egg.json index ae666c09..5fcfeb7f 100644 --- a/src/main/generated/data/minecraft/item/hoglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/hoglin_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:hoglin" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 6251620 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/honey_bottle.json b/src/main/generated/data/minecraft/item/honey_bottle.json index 93f7a440..241a0875 100644 --- a/src/main/generated/data/minecraft/item/honey_bottle.json +++ b/src/main/generated/data/minecraft/item/honey_bottle.json @@ -5,19 +5,19 @@ "components": { "minecraft:consumable": { "has_consume_particles": false, - "result_item": "minecraft:glass_bottle", "sound": "minecraft:item.honey_bottle.drink" }, "minecraft:food": { "nutrition": 6, "saturation": 1.2 }, - "minecraft:recipe_remainder": { - "item": "minecraft:glass_bottle" - }, "minecraft:stackable": 16, "minecraft:useable": { "animation": "drink", + "remainder": { + "id": "minecraft:glass_bottle", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 40 diff --git a/src/main/generated/data/minecraft/item/horse_spawn_egg.json b/src/main/generated/data/minecraft/item/horse_spawn_egg.json index 74a715bf..de1055ba 100644 --- a/src/main/generated/data/minecraft/item/horse_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/horse_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:horse" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15656192 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/husk_spawn_egg.json b/src/main/generated/data/minecraft/item/husk_spawn_egg.json index 93bf5def..d4b4c0ea 100644 --- a/src/main/generated/data/minecraft/item/husk_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/husk_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:husk" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15125652 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/iron_golem_spawn_egg.json b/src/main/generated/data/minecraft/item/iron_golem_spawn_egg.json index fa473ac5..7068257b 100644 --- a/src/main/generated/data/minecraft/item/iron_golem_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/iron_golem_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:iron_golem" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7643954 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/lava_bucket.json b/src/main/generated/data/minecraft/item/lava_bucket.json index 9ffb2ca7..93c4de58 100644 --- a/src/main/generated/data/minecraft/item/lava_bucket.json +++ b/src/main/generated/data/minecraft/item/lava_bucket.json @@ -12,11 +12,12 @@ "behavior": "minecraft:use_bucket" }, "minecraft:fuel": { + "remainder": { + "id": "minecraft:bucket", + "count": 1 + }, "ticks": 20000 }, - "minecraft:recipe_remainder": { - "item": "minecraft:bucket" - }, "minecraft:stackable": 1 } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/llama_spawn_egg.json b/src/main/generated/data/minecraft/item/llama_spawn_egg.json index b624b4df..f54207d5 100644 --- a/src/main/generated/data/minecraft/item/llama_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/llama_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:llama" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 10051392 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/magma_cube_spawn_egg.json b/src/main/generated/data/minecraft/item/magma_cube_spawn_egg.json index f549ba95..5451f91e 100644 --- a/src/main/generated/data/minecraft/item/magma_cube_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/magma_cube_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:magma_cube" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16579584 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/milk_bucket.json b/src/main/generated/data/minecraft/item/milk_bucket.json index 8c3a57f9..a644b23d 100644 --- a/src/main/generated/data/minecraft/item/milk_bucket.json +++ b/src/main/generated/data/minecraft/item/milk_bucket.json @@ -5,15 +5,15 @@ "components": { "minecraft:consumable": { "has_consume_particles": false, - "result_item": "minecraft:bucket", "sound": "minecraft:entity.generic.drink" }, - "minecraft:recipe_remainder": { - "item": "minecraft:bucket" - }, "minecraft:stackable": 1, "minecraft:useable": { "animation": "drink", + "remainder": { + "id": "minecraft:bucket", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 32 diff --git a/src/main/generated/data/minecraft/item/mooshroom_spawn_egg.json b/src/main/generated/data/minecraft/item/mooshroom_spawn_egg.json index 38d1d3bf..d1dd3bd9 100644 --- a/src/main/generated/data/minecraft/item/mooshroom_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/mooshroom_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:mooshroom" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 12040119 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/mule_spawn_egg.json b/src/main/generated/data/minecraft/item/mule_spawn_egg.json index bce47c59..dcbbe93d 100644 --- a/src/main/generated/data/minecraft/item/mule_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/mule_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:mule" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5321501 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/mushroom_stew.json b/src/main/generated/data/minecraft/item/mushroom_stew.json index 6773cea3..ccdff293 100644 --- a/src/main/generated/data/minecraft/item/mushroom_stew.json +++ b/src/main/generated/data/minecraft/item/mushroom_stew.json @@ -3,9 +3,7 @@ "translation_key": "item.minecraft.mushroom_stew" }, "components": { - "minecraft:consumable": { - "result_item": "minecraft:bowl" - }, + "minecraft:consumable": {}, "minecraft:food": { "nutrition": 6, "saturation": 7.2000003 @@ -13,6 +11,10 @@ "minecraft:stackable": 1, "minecraft:useable": { "animation": "eat", + "remainder": { + "id": "minecraft:bowl", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 32 diff --git a/src/main/generated/data/minecraft/item/ocelot_spawn_egg.json b/src/main/generated/data/minecraft/item/ocelot_spawn_egg.json index f453d1dd..fb9629a0 100644 --- a/src/main/generated/data/minecraft/item/ocelot_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ocelot_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:ocelot" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5653556 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/panda_spawn_egg.json b/src/main/generated/data/minecraft/item/panda_spawn_egg.json index f1e6fcf6..74dd3705 100644 --- a/src/main/generated/data/minecraft/item/panda_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/panda_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:panda" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 1776418 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/parrot_spawn_egg.json b/src/main/generated/data/minecraft/item/parrot_spawn_egg.json index 43f971ed..a0f3aa30 100644 --- a/src/main/generated/data/minecraft/item/parrot_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/parrot_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:parrot" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16711680 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/phantom_spawn_egg.json b/src/main/generated/data/minecraft/item/phantom_spawn_egg.json index b61a7d14..e6494186 100644 --- a/src/main/generated/data/minecraft/item/phantom_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/phantom_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:phantom" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 8978176 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pig_spawn_egg.json b/src/main/generated/data/minecraft/item/pig_spawn_egg.json index 8ab03f29..960b126d 100644 --- a/src/main/generated/data/minecraft/item/pig_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/pig_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:pig" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 14377823 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/piglin_brute_spawn_egg.json b/src/main/generated/data/minecraft/item/piglin_brute_spawn_egg.json index d6291a94..c7ff6c73 100644 --- a/src/main/generated/data/minecraft/item/piglin_brute_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/piglin_brute_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:piglin_brute" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16380836 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/piglin_spawn_egg.json b/src/main/generated/data/minecraft/item/piglin_spawn_egg.json index 754224e4..f74a1f76 100644 --- a/src/main/generated/data/minecraft/item/piglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/piglin_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:piglin" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16380836 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/pillager_spawn_egg.json b/src/main/generated/data/minecraft/item/pillager_spawn_egg.json index e2fd25ea..73d0a224 100644 --- a/src/main/generated/data/minecraft/item/pillager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/pillager_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:pillager" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 9804699 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/poisonous_potato.json b/src/main/generated/data/minecraft/item/poisonous_potato.json index e535b2e1..96751e5c 100644 --- a/src/main/generated/data/minecraft/item/poisonous_potato.json +++ b/src/main/generated/data/minecraft/item/poisonous_potato.json @@ -5,16 +5,6 @@ "components": { "minecraft:consumable": {}, "minecraft:food": { - "effects": [ - { - "effect": { - "id": "minecraft:poison", - "duration": 100, - "show_icon": true - }, - "probability": 0.6 - } - ], "nutrition": 2, "saturation": 1.2 }, @@ -26,5 +16,30 @@ "amount": 32 } } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { + "id": "minecraft:poison", + "duration": 100, + "show_icon": true + } + ], + "entity": "this" + }, + "requirements": { + "conditions": { + "chance": 0.6, + "condition": "minecraft:random_chance" + }, + "context": { + "entity": "this", + "position": "this" + } + } + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/polar_bear_spawn_egg.json b/src/main/generated/data/minecraft/item/polar_bear_spawn_egg.json index 0ddabc3c..5bbc5110 100644 --- a/src/main/generated/data/minecraft/item/polar_bear_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/polar_bear_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:polar_bear" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 14014157 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/potion.json b/src/main/generated/data/minecraft/item/potion.json index 00b2ee63..19fb7895 100644 --- a/src/main/generated/data/minecraft/item/potion.json +++ b/src/main/generated/data/minecraft/item/potion.json @@ -5,7 +5,6 @@ "components": { "minecraft:consumable": { "has_consume_particles": false, - "result_item": "minecraft:glass_bottle", "sound": "minecraft:entity.generic.drink" }, "minecraft:dispensable": { @@ -23,6 +22,10 @@ }, "minecraft:useable": { "animation": "drink", + "remainder": { + "id": "minecraft:glass_bottle", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 32 diff --git a/src/main/generated/data/minecraft/item/pufferfish.json b/src/main/generated/data/minecraft/item/pufferfish.json index 1f3452cd..fd62bc51 100644 --- a/src/main/generated/data/minecraft/item/pufferfish.json +++ b/src/main/generated/data/minecraft/item/pufferfish.json @@ -5,40 +5,42 @@ "components": { "minecraft:consumable": {}, "minecraft:food": { - "effects": [ - { - "effect": { + "nutrition": 1, + "saturation": 0.2 + }, + "minecraft:stackable": 64, + "minecraft:useable": { + "animation": "eat", + "ticks": { + "type": "minecraft:constant", + "amount": 32 + } + } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { "id": "minecraft:poison", "amplifier": 1, "duration": 1200, "show_icon": true - } - }, - { - "effect": { + }, + { "id": "minecraft:hunger", "amplifier": 2, "duration": 300, "show_icon": true - } - }, - { - "effect": { + }, + { "id": "minecraft:nausea", "duration": 300, "show_icon": true } - } - ], - "nutrition": 1, - "saturation": 0.2 - }, - "minecraft:stackable": 64, - "minecraft:useable": { - "animation": "eat", - "ticks": { - "type": "minecraft:constant", - "amount": 32 + ], + "entity": "this" } } } diff --git a/src/main/generated/data/minecraft/item/pufferfish_spawn_egg.json b/src/main/generated/data/minecraft/item/pufferfish_spawn_egg.json index 1f4bb78c..9182ef47 100644 --- a/src/main/generated/data/minecraft/item/pufferfish_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/pufferfish_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:pufferfish" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 3654642 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/rabbit_spawn_egg.json b/src/main/generated/data/minecraft/item/rabbit_spawn_egg.json index 48947d1f..a42f5ea0 100644 --- a/src/main/generated/data/minecraft/item/rabbit_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/rabbit_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:rabbit" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7555121 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/rabbit_stew.json b/src/main/generated/data/minecraft/item/rabbit_stew.json index f43ca5b1..aea402ee 100644 --- a/src/main/generated/data/minecraft/item/rabbit_stew.json +++ b/src/main/generated/data/minecraft/item/rabbit_stew.json @@ -3,9 +3,7 @@ "translation_key": "item.minecraft.rabbit_stew" }, "components": { - "minecraft:consumable": { - "result_item": "minecraft:bowl" - }, + "minecraft:consumable": {}, "minecraft:food": { "nutrition": 10, "saturation": 12.0 @@ -13,6 +11,10 @@ "minecraft:stackable": 1, "minecraft:useable": { "animation": "eat", + "remainder": { + "id": "minecraft:bowl", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 32 diff --git a/src/main/generated/data/minecraft/item/ravager_spawn_egg.json b/src/main/generated/data/minecraft/item/ravager_spawn_egg.json index bce202f7..d3e75881 100644 --- a/src/main/generated/data/minecraft/item/ravager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/ravager_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:ravager" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5984329 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/rotten_flesh.json b/src/main/generated/data/minecraft/item/rotten_flesh.json index c4e0a533..e15eee55 100644 --- a/src/main/generated/data/minecraft/item/rotten_flesh.json +++ b/src/main/generated/data/minecraft/item/rotten_flesh.json @@ -5,16 +5,6 @@ "components": { "minecraft:consumable": {}, "minecraft:food": { - "effects": [ - { - "effect": { - "id": "minecraft:hunger", - "duration": 600, - "show_icon": true - }, - "probability": 0.8 - } - ], "nutrition": 4, "saturation": 0.8 }, @@ -26,5 +16,30 @@ "amount": 32 } } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { + "id": "minecraft:hunger", + "duration": 600, + "show_icon": true + } + ], + "entity": "this" + }, + "requirements": { + "conditions": { + "chance": 0.8, + "condition": "minecraft:random_chance" + }, + "context": { + "entity": "this", + "position": "this" + } + } + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/salmon_spawn_egg.json b/src/main/generated/data/minecraft/item/salmon_spawn_egg.json index 98de7e68..62b99676 100644 --- a/src/main/generated/data/minecraft/item/salmon_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/salmon_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:salmon" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 951412 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/sheep_spawn_egg.json b/src/main/generated/data/minecraft/item/sheep_spawn_egg.json index 23a9292c..5ca28200 100644 --- a/src/main/generated/data/minecraft/item/sheep_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/sheep_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:sheep" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16758197 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/shield.json b/src/main/generated/data/minecraft/item/shield.json index 6db391ee..0df6a2d2 100644 --- a/src/main/generated/data/minecraft/item/shield.json +++ b/src/main/generated/data/minecraft/item/shield.json @@ -19,7 +19,10 @@ }, "minecraft:stackable": 1, "minecraft:useable": { - "animation": "block" + "animation": "block", + "ticks": { + "type": "minecraft:indefinite" + } } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/shulker_spawn_egg.json b/src/main/generated/data/minecraft/item/shulker_spawn_egg.json index 30b453af..aa92968b 100644 --- a/src/main/generated/data/minecraft/item/shulker_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/shulker_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:shulker" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5060690 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/silverfish_spawn_egg.json b/src/main/generated/data/minecraft/item/silverfish_spawn_egg.json index 8e798313..c434f1a2 100644 --- a/src/main/generated/data/minecraft/item/silverfish_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/silverfish_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:silverfish" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 3158064 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/skeleton_horse_spawn_egg.json b/src/main/generated/data/minecraft/item/skeleton_horse_spawn_egg.json index 3e0bc420..e57c6636 100644 --- a/src/main/generated/data/minecraft/item/skeleton_horse_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/skeleton_horse_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:skeleton_horse" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15066584 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/skeleton_spawn_egg.json b/src/main/generated/data/minecraft/item/skeleton_spawn_egg.json index b5f8545d..3ac113f7 100644 --- a/src/main/generated/data/minecraft/item/skeleton_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/skeleton_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:skeleton" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 4802889 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/slime_spawn_egg.json b/src/main/generated/data/minecraft/item/slime_spawn_egg.json index fc661e76..e8b88014 100644 --- a/src/main/generated/data/minecraft/item/slime_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/slime_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:slime" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 8306542 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/sniffer_spawn_egg.json b/src/main/generated/data/minecraft/item/sniffer_spawn_egg.json index 11130e7f..58aab764 100644 --- a/src/main/generated/data/minecraft/item/sniffer_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/sniffer_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:sniffer" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 2468720 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/snow_golem_spawn_egg.json b/src/main/generated/data/minecraft/item/snow_golem_spawn_egg.json index 15f1626d..4f9c541a 100644 --- a/src/main/generated/data/minecraft/item/snow_golem_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/snow_golem_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:snow_golem" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 8496292 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/spider_eye.json b/src/main/generated/data/minecraft/item/spider_eye.json index cf3e8806..8e14e2c6 100644 --- a/src/main/generated/data/minecraft/item/spider_eye.json +++ b/src/main/generated/data/minecraft/item/spider_eye.json @@ -5,15 +5,6 @@ "components": { "minecraft:consumable": {}, "minecraft:food": { - "effects": [ - { - "effect": { - "id": "minecraft:poison", - "duration": 100, - "show_icon": true - } - } - ], "nutrition": 2, "saturation": 3.2 }, @@ -25,5 +16,20 @@ "amount": 32 } } + }, + "events": { + "minecraft:consume_item": { + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { + "id": "minecraft:poison", + "duration": 100, + "show_icon": true + } + ], + "entity": "this" + } + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/spider_spawn_egg.json b/src/main/generated/data/minecraft/item/spider_spawn_egg.json index 5bd71b1e..106bcfca 100644 --- a/src/main/generated/data/minecraft/item/spider_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/spider_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:spider" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 11013646 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/squid_spawn_egg.json b/src/main/generated/data/minecraft/item/squid_spawn_egg.json index b1b688b8..9d2ca3d3 100644 --- a/src/main/generated/data/minecraft/item/squid_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/squid_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:squid" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7375001 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/stray_spawn_egg.json b/src/main/generated/data/minecraft/item/stray_spawn_egg.json index c25ea4bc..18773366 100644 --- a/src/main/generated/data/minecraft/item/stray_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/stray_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:stray" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 14543594 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/strider_spawn_egg.json b/src/main/generated/data/minecraft/item/strider_spawn_egg.json index baa88a61..2af53c57 100644 --- a/src/main/generated/data/minecraft/item/strider_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/strider_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:strider" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5065037 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/suspicious_stew.json b/src/main/generated/data/minecraft/item/suspicious_stew.json index 6c702e45..10605cf8 100644 --- a/src/main/generated/data/minecraft/item/suspicious_stew.json +++ b/src/main/generated/data/minecraft/item/suspicious_stew.json @@ -3,9 +3,7 @@ "translation_key": "item.minecraft.suspicious_stew" }, "components": { - "minecraft:consumable": { - "result_item": "minecraft:bowl" - }, + "minecraft:consumable": {}, "minecraft:food": { "always_edible": true, "nutrition": 6, @@ -14,6 +12,10 @@ "minecraft:stackable": 1, "minecraft:useable": { "animation": "eat", + "remainder": { + "id": "minecraft:bowl", + "count": 1 + }, "ticks": { "type": "minecraft:constant", "amount": 32 diff --git a/src/main/generated/data/minecraft/item/tadpole_spawn_egg.json b/src/main/generated/data/minecraft/item/tadpole_spawn_egg.json index e36db0ee..ec238103 100644 --- a/src/main/generated/data/minecraft/item/tadpole_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/tadpole_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:tadpole" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 1444352 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/totem_of_undying.json b/src/main/generated/data/minecraft/item/totem_of_undying.json index 65a51aa2..3edfcd72 100644 --- a/src/main/generated/data/minecraft/item/totem_of_undying.json +++ b/src/main/generated/data/minecraft/item/totem_of_undying.json @@ -4,27 +4,43 @@ "translation_key": "item.minecraft.totem_of_undying" }, "components": { - "minecraft:life_saving": { - "effects": [ - { - "id": "minecraft:regeneration", - "amplifier": 1, - "duration": 900, - "show_icon": true - }, + "minecraft:stackable": 1 + }, + "events": { + "minecraft:before_death_holder": { + "action": [ { - "id": "minecraft:absorption", - "amplifier": 1, - "duration": 100, - "show_icon": true + "action": { + "type": "minecraft:clear_status_effects", + "entity": "this" + } }, { - "id": "minecraft:fire_resistance", - "duration": 800, - "show_icon": true + "action": { + "type": "minecraft:add_status_effects", + "effects": [ + { + "id": "minecraft:regeneration", + "amplifier": 1, + "duration": 900, + "show_icon": true + }, + { + "id": "minecraft:absorption", + "amplifier": 1, + "duration": 100, + "show_icon": true + }, + { + "id": "minecraft:fire_resistance", + "duration": 800, + "show_icon": true + } + ], + "entity": "this" + } } ] - }, - "minecraft:stackable": 1 + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/trader_llama_spawn_egg.json b/src/main/generated/data/minecraft/item/trader_llama_spawn_egg.json index 7b110f17..b9b0d454 100644 --- a/src/main/generated/data/minecraft/item/trader_llama_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/trader_llama_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:trader_llama" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 4547222 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/tropical_fish_spawn_egg.json b/src/main/generated/data/minecraft/item/tropical_fish_spawn_egg.json index c9204991..afa394e2 100644 --- a/src/main/generated/data/minecraft/item/tropical_fish_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/tropical_fish_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:tropical_fish" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 16775663 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/turtle_spawn_egg.json b/src/main/generated/data/minecraft/item/turtle_spawn_egg.json index db11c88d..0545648c 100644 --- a/src/main/generated/data/minecraft/item/turtle_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/turtle_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:turtle" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 44975 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/vex_spawn_egg.json b/src/main/generated/data/minecraft/item/vex_spawn_egg.json index 8ab06401..7e0b7c95 100644 --- a/src/main/generated/data/minecraft/item/vex_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/vex_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:vex" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15265265 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/villager_spawn_egg.json b/src/main/generated/data/minecraft/item/villager_spawn_egg.json index 1cd9be26..44aad272 100644 --- a/src/main/generated/data/minecraft/item/villager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/villager_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:villager" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 12422002 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/vindicator_spawn_egg.json b/src/main/generated/data/minecraft/item/vindicator_spawn_egg.json index 82f0c83e..bbf61f3e 100644 --- a/src/main/generated/data/minecraft/item/vindicator_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/vindicator_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:vindicator" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 2580065 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/wandering_trader_spawn_egg.json b/src/main/generated/data/minecraft/item/wandering_trader_spawn_egg.json index d44e55bb..3152f291 100644 --- a/src/main/generated/data/minecraft/item/wandering_trader_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/wandering_trader_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:wandering_trader" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15377456 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/warden_spawn_egg.json b/src/main/generated/data/minecraft/item/warden_spawn_egg.json index 957046a9..5a5f2ca3 100644 --- a/src/main/generated/data/minecraft/item/warden_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/warden_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:warden" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 3790560 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/water_bucket.json b/src/main/generated/data/minecraft/item/water_bucket.json index 35e66c95..3fffa7b5 100644 --- a/src/main/generated/data/minecraft/item/water_bucket.json +++ b/src/main/generated/data/minecraft/item/water_bucket.json @@ -11,9 +11,6 @@ "minecraft:dispensable": { "behavior": "minecraft:use_bucket" }, - "minecraft:recipe_remainder": { - "item": "minecraft:bucket" - }, "minecraft:stackable": 1 } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/witch_spawn_egg.json b/src/main/generated/data/minecraft/item/witch_spawn_egg.json index 42742b47..041da8f0 100644 --- a/src/main/generated/data/minecraft/item/witch_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/witch_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:witch" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5349438 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/wither_skeleton_spawn_egg.json b/src/main/generated/data/minecraft/item/wither_skeleton_spawn_egg.json index 3a149eee..ee6f12f6 100644 --- a/src/main/generated/data/minecraft/item/wither_skeleton_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/wither_skeleton_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:wither_skeleton" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 4672845 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/wither_spawn_egg.json b/src/main/generated/data/minecraft/item/wither_spawn_egg.json index 64f4f9cd..221e66e0 100644 --- a/src/main/generated/data/minecraft/item/wither_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/wither_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:wither" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5075616 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/wolf_spawn_egg.json b/src/main/generated/data/minecraft/item/wolf_spawn_egg.json index f4f365a6..984ef7cc 100644 --- a/src/main/generated/data/minecraft/item/wolf_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/wolf_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:wolf" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 13545366 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/zoglin_spawn_egg.json b/src/main/generated/data/minecraft/item/zoglin_spawn_egg.json index dca9ffdc..1bc8a024 100644 --- a/src/main/generated/data/minecraft/item/zoglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zoglin_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:zoglin" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 15132390 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/zombie_horse_spawn_egg.json b/src/main/generated/data/minecraft/item/zombie_horse_spawn_egg.json index 68c31783..aa33d097 100644 --- a/src/main/generated/data/minecraft/item/zombie_horse_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zombie_horse_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:zombie_horse" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 9945732 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/zombie_spawn_egg.json b/src/main/generated/data/minecraft/item/zombie_spawn_egg.json index 905a5476..bcd84d12 100644 --- a/src/main/generated/data/minecraft/item/zombie_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zombie_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:zombie" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7969893 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/zombie_villager_spawn_egg.json b/src/main/generated/data/minecraft/item/zombie_villager_spawn_egg.json index 9b9765d5..cbedfeab 100644 --- a/src/main/generated/data/minecraft/item/zombie_villager_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zombie_villager_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:zombie_villager" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 7969893 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/item/zombified_piglin_spawn_egg.json b/src/main/generated/data/minecraft/item/zombified_piglin_spawn_egg.json index d105257b..7b09fdad 100644 --- a/src/main/generated/data/minecraft/item/zombified_piglin_spawn_egg.json +++ b/src/main/generated/data/minecraft/item/zombified_piglin_spawn_egg.json @@ -10,7 +10,11 @@ "allow_item_data": true, "entity": { "type": "minecraft:zombified_piglin" - } + }, + "passes": [ + "block", + "fluid" + ] }, "minecraft:spawn_egg": {}, "minecraft:stackable": 64, @@ -22,7 +26,6 @@ 5009705 ] } - }, - "minecraft:useable_on_fluid": {} + } } } \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/awkward_potion.json b/src/main/generated/data/minecraft/recipe/awkward_potion.json new file mode 100644 index 00000000..e054c307 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/awkward_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:water", + "reagent": { + "item": "minecraft:nether_wart" + }, + "result": "minecraft:awkward" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/cake.json b/src/main/generated/data/minecraft/recipe/cake.json new file mode 100644 index 00000000..e5e7a773 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/cake.json @@ -0,0 +1,33 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "A": { + "items": { + "item": "minecraft:milk_bucket" + }, + "remainder": { + "id": "minecraft:bucket", + "count": 1 + } + }, + "B": { + "item": "minecraft:sugar" + }, + "C": { + "item": "minecraft:wheat" + }, + "E": { + "item": "minecraft:egg" + } + }, + "pattern": [ + "AAA", + "BEB", + "CCC" + ], + "result": { + "id": "minecraft:cake", + "count": 1 + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/fire_resistance_potion.json b/src/main/generated/data/minecraft/recipe/fire_resistance_potion.json new file mode 100644 index 00000000..fd7f4471 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/fire_resistance_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:magma_cream" + }, + "result": "minecraft:fire_resistance" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/harming_potion_from_healing_potion.json b/src/main/generated/data/minecraft/recipe/harming_potion_from_healing_potion.json new file mode 100644 index 00000000..b5ff6c9e --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/harming_potion_from_healing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:healing", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:harming" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/harming_potion_from_long_poison_potion.json b/src/main/generated/data/minecraft/recipe/harming_potion_from_long_poison_potion.json new file mode 100644 index 00000000..6d3311ec --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/harming_potion_from_long_poison_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:long_poison", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:harming" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/harming_potion_from_poison_potion.json b/src/main/generated/data/minecraft/recipe/harming_potion_from_poison_potion.json new file mode 100644 index 00000000..7fe62698 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/harming_potion_from_poison_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:poison", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:harming" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/healing_potion.json b/src/main/generated/data/minecraft/recipe/healing_potion.json new file mode 100644 index 00000000..4606ca3b --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/healing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:glistering_melon_slice" + }, + "result": "minecraft:healing" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/honey_block.json b/src/main/generated/data/minecraft/recipe/honey_block.json new file mode 100644 index 00000000..7069cdaa --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/honey_block.json @@ -0,0 +1,23 @@ +{ + "type": "minecraft:crafting_shaped", + "category": "misc", + "key": { + "#": { + "items": { + "item": "minecraft:honey_bottle" + }, + "remainder": { + "id": "minecraft:glass_bottle", + "count": 1 + } + } + }, + "pattern": [ + "##", + "##" + ], + "result": { + "id": "minecraft:honey_block", + "count": 1 + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/infested_potion.json b/src/main/generated/data/minecraft/recipe/infested_potion.json new file mode 100644 index 00000000..07aefa25 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/infested_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:stone" + }, + "result": "minecraft:infested" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/invisibility_potion_from_night_vision_potion.json b/src/main/generated/data/minecraft/recipe/invisibility_potion_from_night_vision_potion.json new file mode 100644 index 00000000..3f7de77a --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/invisibility_potion_from_night_vision_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:night_vision", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:invisibility" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/leaping_potion.json b/src/main/generated/data/minecraft/recipe/leaping_potion.json new file mode 100644 index 00000000..7b1c892c --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/leaping_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:rabbit_foot" + }, + "result": "minecraft:leaping" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/lingering_potion.json b/src/main/generated/data/minecraft/recipe/lingering_potion.json new file mode 100644 index 00000000..41d44de0 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/lingering_potion.json @@ -0,0 +1,14 @@ +{ + "type": "minecraft:brewing_amplify", + "base": "minecraft:splash_potion", + "reagent": { + "items": { + "item": "minecraft:dragon_breath" + }, + "remainder": { + "id": "minecraft:glass_bottle", + "count": 1 + } + }, + "result": "minecraft:lingering_potion" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_fire_resistance_potion_from_fire_resistance_potion.json b/src/main/generated/data/minecraft/recipe/long_fire_resistance_potion_from_fire_resistance_potion.json new file mode 100644 index 00000000..fac682eb --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_fire_resistance_potion_from_fire_resistance_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:fire_resistance", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_fire_resistance" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_invisibility_potion_from_invisibility_potion.json b/src/main/generated/data/minecraft/recipe/long_invisibility_potion_from_invisibility_potion.json new file mode 100644 index 00000000..33842f2e --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_invisibility_potion_from_invisibility_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:invisibility", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_invisibility" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_invisibility_potion_from_long_night_vision_potion.json b/src/main/generated/data/minecraft/recipe/long_invisibility_potion_from_long_night_vision_potion.json new file mode 100644 index 00000000..0f98edbb --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_invisibility_potion_from_long_night_vision_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:long_night_vision", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:long_invisibility" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_leaping_potion_from_leaping_potion.json b/src/main/generated/data/minecraft/recipe/long_leaping_potion_from_leaping_potion.json new file mode 100644 index 00000000..ef7db774 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_leaping_potion_from_leaping_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:leaping", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_leaping" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_night_vision_potion_from_night_vision_potion.json b/src/main/generated/data/minecraft/recipe/long_night_vision_potion_from_night_vision_potion.json new file mode 100644 index 00000000..df28f01f --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_night_vision_potion_from_night_vision_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:night_vision", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_night_vision" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_poison_potion_from_poison_potion.json b/src/main/generated/data/minecraft/recipe/long_poison_potion_from_poison_potion.json new file mode 100644 index 00000000..c41513be --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_poison_potion_from_poison_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:poison", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_poison" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_regeneration_potion_from_regeneration_potion.json b/src/main/generated/data/minecraft/recipe/long_regeneration_potion_from_regeneration_potion.json new file mode 100644 index 00000000..1fed63c0 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_regeneration_potion_from_regeneration_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:regeneration", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_regeneration" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_slow_falling_potion_from_slow_falling_potion.json b/src/main/generated/data/minecraft/recipe/long_slow_falling_potion_from_slow_falling_potion.json new file mode 100644 index 00000000..dbe3745c --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_slow_falling_potion_from_slow_falling_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:slow_falling", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_slow_falling" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_long_leaping_potion.json b/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_long_leaping_potion.json new file mode 100644 index 00000000..b5ff7832 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_long_leaping_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:long_leaping", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:long_slowness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_long_swiftness_potion.json b/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_long_swiftness_potion.json new file mode 100644 index 00000000..327b2f5e --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_long_swiftness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:long_swiftness", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:long_slowness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_slowness_potion.json b/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_slowness_potion.json new file mode 100644 index 00000000..a21742b7 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_slowness_potion_from_slowness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:slowness", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_slowness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_strength_potion_from_strength_potion.json b/src/main/generated/data/minecraft/recipe/long_strength_potion_from_strength_potion.json new file mode 100644 index 00000000..acbfcc25 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_strength_potion_from_strength_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:strength", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_strength" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_swiftness_potion_from_swiftness_potion.json b/src/main/generated/data/minecraft/recipe/long_swiftness_potion_from_swiftness_potion.json new file mode 100644 index 00000000..3d1d1608 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_swiftness_potion_from_swiftness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:swiftness", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_swiftness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_turtle_master_potion_from_turtle_master_potion.json b/src/main/generated/data/minecraft/recipe/long_turtle_master_potion_from_turtle_master_potion.json new file mode 100644 index 00000000..4b7d2aa0 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_turtle_master_potion_from_turtle_master_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:turtle_master", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_turtle_master" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_water_breathing_potion_from_water_breathing_potion.json b/src/main/generated/data/minecraft/recipe/long_water_breathing_potion_from_water_breathing_potion.json new file mode 100644 index 00000000..f636cca7 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_water_breathing_potion_from_water_breathing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:water_breathing", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_water_breathing" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/long_weakness_potion_from_weakness_potion.json b/src/main/generated/data/minecraft/recipe/long_weakness_potion_from_weakness_potion.json new file mode 100644 index 00000000..68588a8f --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/long_weakness_potion_from_weakness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:weakness", + "reagent": { + "item": "minecraft:redstone" + }, + "result": "minecraft:long_weakness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/mundane_potion.json b/src/main/generated/data/minecraft/recipe/mundane_potion.json new file mode 100644 index 00000000..2c79a9ed --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/mundane_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:water", + "reagent": { + "tag": "minecraft:mundane_potion_reagents" + }, + "result": "minecraft:mundane" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/night_vision_potion.json b/src/main/generated/data/minecraft/recipe/night_vision_potion.json new file mode 100644 index 00000000..d1e21340 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/night_vision_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:golden_carrot" + }, + "result": "minecraft:night_vision" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/oozing_potion.json b/src/main/generated/data/minecraft/recipe/oozing_potion.json new file mode 100644 index 00000000..3b3982c3 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/oozing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:slime_block" + }, + "result": "minecraft:oozing" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/poison_potion.json b/src/main/generated/data/minecraft/recipe/poison_potion.json new file mode 100644 index 00000000..04948c38 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/poison_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:spider_eye" + }, + "result": "minecraft:poison" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/regeneration_potion.json b/src/main/generated/data/minecraft/recipe/regeneration_potion.json new file mode 100644 index 00000000..66185f48 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/regeneration_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:ghast_tear" + }, + "result": "minecraft:regeneration" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_black.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_black.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_black.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_black.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_blue.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_blue.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_blue.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_blue.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_brown.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_brown.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_brown.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_brown.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_cyan.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_cyan.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_cyan.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_cyan.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_gray.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_gray.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_gray.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_gray.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_green.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_green.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_green.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_green.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_light_blue.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_light_blue.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_light_blue.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_light_blue.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_light_gray.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_light_gray.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_light_gray.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_light_gray.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_lime.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_lime.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_lime.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_lime.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_magenta.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_magenta.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_magenta.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_magenta.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_orange.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_orange.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_orange.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_orange.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_pink.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_pink.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_pink.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_pink.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_purple.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_purple.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_purple.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_purple.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_red.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_red.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_red.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_red.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_white.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_white.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_white.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_white.json diff --git a/src/main/generated/data/minecraft/recipes/shulker_box_coloring_yellow.json b/src/main/generated/data/minecraft/recipe/shulker_box_coloring_yellow.json similarity index 100% rename from src/main/generated/data/minecraft/recipes/shulker_box_coloring_yellow.json rename to src/main/generated/data/minecraft/recipe/shulker_box_coloring_yellow.json diff --git a/src/main/generated/data/minecraft/recipe/slow_falling_potion.json b/src/main/generated/data/minecraft/recipe/slow_falling_potion.json new file mode 100644 index 00000000..adb07bc4 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/slow_falling_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:phantom_membrane" + }, + "result": "minecraft:slow_falling" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/slowness_potion_from_leaping_potion.json b/src/main/generated/data/minecraft/recipe/slowness_potion_from_leaping_potion.json new file mode 100644 index 00000000..9546df15 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/slowness_potion_from_leaping_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:leaping", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:slowness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/slowness_potion_from_swiftness_potion.json b/src/main/generated/data/minecraft/recipe/slowness_potion_from_swiftness_potion.json new file mode 100644 index 00000000..b6c3d946 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/slowness_potion_from_swiftness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:swiftness", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:slowness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/splash_potion.json b/src/main/generated/data/minecraft/recipe/splash_potion.json new file mode 100644 index 00000000..c9fcbbb5 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/splash_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_amplify", + "base": "minecraft:potion", + "reagent": { + "item": "minecraft:gunpowder" + }, + "result": "minecraft:splash_potion" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strength_potion.json b/src/main/generated/data/minecraft/recipe/strength_potion.json new file mode 100644 index 00000000..14cb78ec --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strength_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:blaze_powder" + }, + "result": "minecraft:strength" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_harming_potion.json b/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_harming_potion.json new file mode 100644 index 00000000..9956a438 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_harming_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:harming", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_harming" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_strong_healing_potion.json b/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_strong_healing_potion.json new file mode 100644 index 00000000..1f874124 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_strong_healing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:strong_healing", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:strong_harming" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_strong_poison_potion.json b/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_strong_poison_potion.json new file mode 100644 index 00000000..6ab77129 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_harming_potion_from_strong_poison_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:strong_poison", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:strong_harming" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_healing_potion_from_healing_potion.json b/src/main/generated/data/minecraft/recipe/strong_healing_potion_from_healing_potion.json new file mode 100644 index 00000000..d8c419be --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_healing_potion_from_healing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:healing", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_healing" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_leaping_potion_from_leaping_potion.json b/src/main/generated/data/minecraft/recipe/strong_leaping_potion_from_leaping_potion.json new file mode 100644 index 00000000..b9e0dd55 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_leaping_potion_from_leaping_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:leaping", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_leaping" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_poison_potion_from_poison_potion.json b/src/main/generated/data/minecraft/recipe/strong_poison_potion_from_poison_potion.json new file mode 100644 index 00000000..b3d8cac8 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_poison_potion_from_poison_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:poison", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_poison" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_regeneration_potion_from_regeneration_potion.json b/src/main/generated/data/minecraft/recipe/strong_regeneration_potion_from_regeneration_potion.json new file mode 100644 index 00000000..694f68d0 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_regeneration_potion_from_regeneration_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:regeneration", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_regeneration" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_slowness_potion_from_slowness_potion.json b/src/main/generated/data/minecraft/recipe/strong_slowness_potion_from_slowness_potion.json new file mode 100644 index 00000000..a1a59d2f --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_slowness_potion_from_slowness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:slowness", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_slowness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_strength_potion_from_strength_potion.json b/src/main/generated/data/minecraft/recipe/strong_strength_potion_from_strength_potion.json new file mode 100644 index 00000000..0c8e2172 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_strength_potion_from_strength_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:strength", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_strength" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_swiftness_potion_from_swiftness_potion.json b/src/main/generated/data/minecraft/recipe/strong_swiftness_potion_from_swiftness_potion.json new file mode 100644 index 00000000..9c2522b6 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_swiftness_potion_from_swiftness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:swiftness", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_swiftness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/strong_turtle_master_potion_from_turtle_master_potion.json b/src/main/generated/data/minecraft/recipe/strong_turtle_master_potion_from_turtle_master_potion.json new file mode 100644 index 00000000..c97ba37e --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/strong_turtle_master_potion_from_turtle_master_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:turtle_master", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:strong_turtle_master" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/sugar_from_honey_bottle.json b/src/main/generated/data/minecraft/recipe/sugar_from_honey_bottle.json new file mode 100644 index 00000000..cc09f813 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/sugar_from_honey_bottle.json @@ -0,0 +1,19 @@ +{ + "type": "minecraft:crafting_shapeless", + "category": "misc", + "ingredients": [ + { + "items": { + "item": "minecraft:honey_bottle" + }, + "remainder": { + "id": "minecraft:glass_bottle", + "count": 1 + } + } + ], + "result": { + "id": "minecraft:sugar", + "count": 3 + } +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/swiftness_potion.json b/src/main/generated/data/minecraft/recipe/swiftness_potion.json new file mode 100644 index 00000000..dc489e22 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/swiftness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:sugar" + }, + "result": "minecraft:swiftness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/thick_potion.json b/src/main/generated/data/minecraft/recipe/thick_potion.json new file mode 100644 index 00000000..d01143d4 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/thick_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:water", + "reagent": { + "item": "minecraft:glowstone_dust" + }, + "result": "minecraft:thick" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/turtle_master_potion.json b/src/main/generated/data/minecraft/recipe/turtle_master_potion.json new file mode 100644 index 00000000..b39c79e1 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/turtle_master_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:turtle_helmet" + }, + "result": "minecraft:turtle_master" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/water_breathing_potion.json b/src/main/generated/data/minecraft/recipe/water_breathing_potion.json new file mode 100644 index 00000000..2e6b2839 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/water_breathing_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:pufferfish" + }, + "result": "minecraft:water_breathing" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/weakness_potion.json b/src/main/generated/data/minecraft/recipe/weakness_potion.json new file mode 100644 index 00000000..12de4e65 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/weakness_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:water", + "reagent": { + "item": "minecraft:fermented_spider_eye" + }, + "result": "minecraft:weakness" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/weaving_potion.json b/src/main/generated/data/minecraft/recipe/weaving_potion.json new file mode 100644 index 00000000..f9405ef4 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/weaving_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:cobweb" + }, + "result": "minecraft:weaving" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/recipe/wind_charged_potion.json b/src/main/generated/data/minecraft/recipe/wind_charged_potion.json new file mode 100644 index 00000000..af0f6d82 --- /dev/null +++ b/src/main/generated/data/minecraft/recipe/wind_charged_potion.json @@ -0,0 +1,8 @@ +{ + "type": "minecraft:brewing_modify", + "base": "minecraft:awkward", + "reagent": { + "item": "minecraft:breeze_rod" + }, + "result": "minecraft:wind_charged" +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/brewing_inputs.json b/src/main/generated/data/minecraft/tags/item/brewing_inputs.json new file mode 100644 index 00000000..592e0eb9 --- /dev/null +++ b/src/main/generated/data/minecraft/tags/item/brewing_inputs.json @@ -0,0 +1,7 @@ +{ + "values": [ + "minecraft:potion", + "minecraft:splash_potion", + "minecraft:lingering_potion" + ] +} \ No newline at end of file diff --git a/src/main/generated/data/minecraft/tags/item/mundane_potion_reagents.json b/src/main/generated/data/minecraft/tags/item/mundane_potion_reagents.json new file mode 100644 index 00000000..e7d2369d --- /dev/null +++ b/src/main/generated/data/minecraft/tags/item/mundane_potion_reagents.json @@ -0,0 +1,16 @@ +{ + "values": [ + "minecraft:redstone", + "minecraft:magma_cream", + "minecraft:glistering_melon_slice", + "minecraft:stone", + "minecraft:rabbit_foot", + "minecraft:slime_block", + "minecraft:spider_eye", + "minecraft:ghast_tear", + "minecraft:blaze_powder", + "minecraft:sugar", + "minecraft:cobweb", + "minecraft:breeze_rod" + ] +} \ No newline at end of file diff --git a/src/main/java/net/errorcraft/itematic/Itematic.java b/src/main/java/net/errorcraft/itematic/Itematic.java index ba889cbd..6f82e723 100644 --- a/src/main/java/net/errorcraft/itematic/Itematic.java +++ b/src/main/java/net/errorcraft/itematic/Itematic.java @@ -16,6 +16,8 @@ import net.errorcraft.itematic.loot.function.ItematicItemModifierTypes; import net.errorcraft.itematic.loot.predicate.ItematicPredicateTypes; import net.errorcraft.itematic.recipe.ItematicRecipeSerializers; +import net.errorcraft.itematic.recipe.ItematicRecipeTypes; +import net.errorcraft.itematic.screen.ItematicScreenHandlerTypes; import net.errorcraft.itematic.village.trade.modifier.TradeModifierTypes; import net.errorcraft.itematic.world.action.ActionTypes; import net.errorcraft.itematic.world.action.sequence.handler.SequenceHandlerTypes; @@ -43,5 +45,7 @@ public void onInitialize() { IntegerProviderTypes.init(); ItemHolderRuleTypes.init(); ShooterMethodTypes.init(); + ItematicRecipeTypes.init(); + ItematicScreenHandlerTypes.init(); } } diff --git a/src/main/java/net/errorcraft/itematic/access/block/entity/BrewingStandBlockEntityAccess.java b/src/main/java/net/errorcraft/itematic/access/block/entity/BrewingStandBlockEntityAccess.java new file mode 100644 index 00000000..b6cb6f80 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/block/entity/BrewingStandBlockEntityAccess.java @@ -0,0 +1,6 @@ +package net.errorcraft.itematic.access.block.entity; + +public interface BrewingStandBlockEntityAccess { + int itematic$maxBrewingTime(); + void itematic$setMaxBrewingTime(int maxBrewingTime); +} diff --git a/src/main/java/net/errorcraft/itematic/access/data/server/recipe/RecipeProviderAccess.java b/src/main/java/net/errorcraft/itematic/access/data/server/recipe/RecipeProviderAccess.java new file mode 100644 index 00000000..4779aaa7 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/data/server/recipe/RecipeProviderAccess.java @@ -0,0 +1,8 @@ +package net.errorcraft.itematic.access.data.server.recipe; + +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.registry.RegistryWrapper; + +public interface RecipeProviderAccess { + void itematic$generate(RegistryWrapper.WrapperLookup wrapperLookup, RecipeExporter exporter); +} diff --git a/src/main/java/net/errorcraft/itematic/access/entity/LivingEntityAccess.java b/src/main/java/net/errorcraft/itematic/access/entity/LivingEntityAccess.java index f880d8a9..5f105786 100644 --- a/src/main/java/net/errorcraft/itematic/access/entity/LivingEntityAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/entity/LivingEntityAccess.java @@ -23,4 +23,5 @@ public interface LivingEntityAccess { default double itematic$getAttackDamage() { return 0.0d; } + default void itematic$addOrDropStack(ItemStack stack) {} } diff --git a/src/main/java/net/errorcraft/itematic/access/item/ItemAccess.java b/src/main/java/net/errorcraft/itematic/access/item/ItemAccess.java index 979d561b..dc00963c 100644 --- a/src/main/java/net/errorcraft/itematic/access/item/ItemAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/item/ItemAccess.java @@ -7,6 +7,7 @@ import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.item.event.ItemEventMap; import net.errorcraft.itematic.world.action.context.ActionContext; +import net.minecraft.component.type.AttributeModifiersComponent; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.ItemStack; import net.minecraft.util.Hand; @@ -19,6 +20,10 @@ public interface ItemAccess { return null; } default void itematic$setItemBase(ItemBase base) {} + default AttributeModifiersComponent itematic$attributeModifiers() { + return null; + } + default void itematic$setAttributeModifiers(AttributeModifiersComponent attributeModifiers) {} default ItemComponentSet itematic$components() { return null; } @@ -36,6 +41,9 @@ public interface ItemAccess { default boolean itematic$invokeEvent(ItemEvent event, ActionContext context) { return false; } + default boolean itematic$hasEventListener(ItemEvent event) { + return false; + } default boolean itematic$mayStartUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { return true; } diff --git a/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java b/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java index 5243381b..28f8f100 100644 --- a/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/item/ItemStackAccess.java @@ -6,6 +6,7 @@ import net.errorcraft.itematic.world.action.context.ActionContext; import net.minecraft.block.BlockState; import net.minecraft.component.ComponentMapImpl; +import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -39,6 +40,9 @@ public interface ItemStackAccess { return false; } default void itematic$damage(int amount, ActionContext context) {} + default ItemStack itematic$applyUseEffects(LivingEntity user, ItemStack stackBeforeUse) { + return ItemStack.EMPTY; + } default > boolean itematic$hasComponent(ItemComponentType type) { return false; } @@ -48,6 +52,9 @@ public interface ItemStackAccess { default boolean itematic$invokeEvent(ItemEvent event, ActionContext context) { return false; } + default boolean itematic$hasEventListener(ItemEvent beforeDeathHolder) { + return false; + } default boolean itematic$canMine(BlockState state, World world, BlockPos pos, PlayerEntity miner) { return false; } diff --git a/src/main/java/net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryAccess.java b/src/main/java/net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryAccess.java deleted file mode 100644 index f9b3148d..00000000 --- a/src/main/java/net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryAccess.java +++ /dev/null @@ -1,19 +0,0 @@ -package net.errorcraft.itematic.access.recipe; - -import net.errorcraft.itematic.recipe.BrewingRecipe; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.world.World; - -import java.util.List; - -public interface BrewingRecipeRegistryAccess { - default void itematic$setItemRecipes(List>> itemRecipes) {} - default void itematic$setPotionRecipes(List>> potionRecipes) {} - default ItemStack itematic$craft(ItemStack ingredient, ItemStack input, World world) { - return ItemStack.EMPTY; - } -} diff --git a/src/main/java/net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryBuilderAccess.java b/src/main/java/net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryBuilderAccess.java deleted file mode 100644 index e8ade6ac..00000000 --- a/src/main/java/net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryBuilderAccess.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.errorcraft.itematic.access.recipe; - -import net.minecraft.item.Item; -import net.minecraft.potion.Potion; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.entry.RegistryEntry; - -public interface BrewingRecipeRegistryBuilderAccess { - default void itematic$registerItemRecipe(RegistryKey from, RegistryKey ingredient, RegistryKey to) {} - default void itematic$registerWaterPotionRecipe(RegistryKey key, RegistryEntry output) {} - default void itematic$registerAwkwardPotionRecipe(RegistryKey key, RegistryEntry output) {} - default void itematic$registerLongPotionRecipe(RegistryEntry input, RegistryEntry output) {} - default void itematic$registerStrongPotionRecipe(RegistryEntry input, RegistryEntry output) {} - default void itematic$registerNegatingPotionRecipe(RegistryEntry input, RegistryEntry output) {} -} diff --git a/src/main/java/net/errorcraft/itematic/access/recipe/IngredientAccess.java b/src/main/java/net/errorcraft/itematic/access/recipe/IngredientAccess.java index ce1ab3fe..34a4f941 100644 --- a/src/main/java/net/errorcraft/itematic/access/recipe/IngredientAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/recipe/IngredientAccess.java @@ -3,8 +3,14 @@ import net.minecraft.item.ItemStack; import net.minecraft.registry.RegistryWrapper; +import java.util.Optional; + public interface IngredientAccess { default ItemStack[] itematic$getMatchingStacks(RegistryWrapper.WrapperLookup lookup) { return new ItemStack[0]; } + default Optional itematic$remainder() { + return Optional.empty(); + } + default void itematic$setRemainder(Optional remainder) {} } diff --git a/src/main/java/net/errorcraft/itematic/access/recipe/RawShapedRecipeAccess.java b/src/main/java/net/errorcraft/itematic/access/recipe/RawShapedRecipeAccess.java new file mode 100644 index 00000000..5e775a13 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/recipe/RawShapedRecipeAccess.java @@ -0,0 +1,9 @@ +package net.errorcraft.itematic.access.recipe; + +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.input.CraftingRecipeInput; +import net.minecraft.util.collection.DefaultedList; + +public interface RawShapedRecipeAccess { + DefaultedList itematic$remainder(CraftingRecipeInput input); +} diff --git a/src/main/java/net/errorcraft/itematic/access/recipe/RecipeAccess.java b/src/main/java/net/errorcraft/itematic/access/recipe/RecipeAccess.java index ba4a26b8..115a1dbe 100644 --- a/src/main/java/net/errorcraft/itematic/access/recipe/RecipeAccess.java +++ b/src/main/java/net/errorcraft/itematic/access/recipe/RecipeAccess.java @@ -3,10 +3,15 @@ import net.errorcraft.itematic.item.ItemKeys; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.recipe.Ingredient; import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.util.collection.DefaultedList; public interface RecipeAccess { default ItemStack itematic$createIcon(RegistryEntryLookup items) { return new ItemStack(items.getOrThrow(ItemKeys.CRAFTING_TABLE)); } + default DefaultedList itematic$ingredients(RegistryEntryLookup items) { + return null; + } } diff --git a/src/main/java/net/errorcraft/itematic/access/screen/BrewingStandScreenHandlerAccess.java b/src/main/java/net/errorcraft/itematic/access/screen/BrewingStandScreenHandlerAccess.java new file mode 100644 index 00000000..6dfd50c8 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/access/screen/BrewingStandScreenHandlerAccess.java @@ -0,0 +1,5 @@ +package net.errorcraft.itematic.access.screen; + +public interface BrewingStandScreenHandlerAccess { + int itematic$maxBrewingTime(); +} diff --git a/src/main/java/net/errorcraft/itematic/component/AttributeModifiersComponentUtil.java b/src/main/java/net/errorcraft/itematic/component/AttributeModifiersComponentUtil.java new file mode 100644 index 00000000..8018d632 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/component/AttributeModifiersComponentUtil.java @@ -0,0 +1,13 @@ +package net.errorcraft.itematic.component; + +import com.mojang.serialization.Codec; +import net.minecraft.component.type.AttributeModifiersComponent; + +public class AttributeModifiersComponentUtil { + public static final Codec LIST_CODEC = AttributeModifiersComponent.Entry.CODEC.listOf().xmap( + entries -> new AttributeModifiersComponent(entries, true), + AttributeModifiersComponent::modifiers + ); + + private AttributeModifiersComponentUtil() {} +} diff --git a/src/main/java/net/errorcraft/itematic/component/ItematicDataComponentTypes.java b/src/main/java/net/errorcraft/itematic/component/ItematicDataComponentTypes.java index 6b51a92a..d4db9e29 100644 --- a/src/main/java/net/errorcraft/itematic/component/ItematicDataComponentTypes.java +++ b/src/main/java/net/errorcraft/itematic/component/ItematicDataComponentTypes.java @@ -34,6 +34,8 @@ public class ItematicDataComponentTypes { public static final ComponentType SHOOTER_DEFAULT_CHARGING_SOUNDS = DataComponentTypesAccessor.register("shooter_default_charging_sounds", builder -> builder.codec(CrossbowItem.LoadingSounds.CODEC).packetCodec(ChargingSoundsUtil.PACKET_CODEC).cache()); public static final ComponentType SHOOTER_CHARGED_POWER_RULES = DataComponentTypesAccessor.register("shooter_charged_power_rules", builder -> builder.codec(ChargeableShooterMethod.ChargedPowerRules.CODEC).packetCodec(ChargeableShooterMethod.ChargedPowerRules.PACKET_CODEC)); public static final ComponentType> SHOOTER_SHOOT_SOUND = DataComponentTypesAccessor.register("shooter_shoot_sound", builder -> builder.codec(SoundEvent.ENTRY_CODEC).packetCodec(SoundEvent.ENTRY_PACKET_CODEC)); + public static final ComponentType USE_REMAINDER = DataComponentTypesAccessor.register("use_remainder", builder -> builder.codec(UseRemainderDataComponent.CODEC).packetCodec(UseRemainderDataComponent.PACKET_CODEC).cache()); + public static final ComponentType USE_COOLDOWN = DataComponentTypesAccessor.register("use_cooldown", builder -> builder.codec(UseCooldownDataComponent.CODEC).packetCodec(UseCooldownDataComponent.PACKET_CODEC).cache()); private ItematicDataComponentTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/component/type/UseCooldownDataComponent.java b/src/main/java/net/errorcraft/itematic/component/type/UseCooldownDataComponent.java new file mode 100644 index 00000000..f4be4f01 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/component/type/UseCooldownDataComponent.java @@ -0,0 +1,32 @@ +package net.errorcraft.itematic.component.type; + +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import io.netty.buffer.ByteBuf; +import net.minecraft.SharedConstants; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.util.dynamic.Codecs; + +public record UseCooldownDataComponent(float seconds) { + public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( + Codecs.POSITIVE_FLOAT.fieldOf("seconds").forGetter(UseCooldownDataComponent::seconds) + ).apply(instance, UseCooldownDataComponent::new)); + public static final PacketCodec PACKET_CODEC = PacketCodecs.FLOAT.xmap( + UseCooldownDataComponent::new, + UseCooldownDataComponent::seconds + ); + + public int ticks() { + return (int)(this.seconds * SharedConstants.TICKS_PER_SECOND); + } + + public void set(ItemStack stack, LivingEntity user) { + if (user instanceof PlayerEntity player) { + player.getItemCooldownManager().set(stack.getItem(), this.ticks()); + } + } +} diff --git a/src/main/java/net/errorcraft/itematic/component/type/UseDurationDataComponent.java b/src/main/java/net/errorcraft/itematic/component/type/UseDurationDataComponent.java index 2c12373e..cedd69cc 100644 --- a/src/main/java/net/errorcraft/itematic/component/type/UseDurationDataComponent.java +++ b/src/main/java/net/errorcraft/itematic/component/type/UseDurationDataComponent.java @@ -1,8 +1,6 @@ package net.errorcraft.itematic.component.type; import com.mojang.serialization.Codec; -import com.mojang.serialization.MapCodec; -import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.item.use.provider.IntegerProvider; import net.errorcraft.itematic.item.use.provider.providers.ConstantIntegerProvider; import net.minecraft.entity.LivingEntity; @@ -11,39 +9,32 @@ import net.minecraft.item.ItemUsage; import net.minecraft.network.RegistryByteBuf; import net.minecraft.network.codec.PacketCodec; -import net.minecraft.network.codec.PacketCodecs; import net.minecraft.util.Hand; import net.minecraft.util.dynamic.Codecs; import net.minecraft.world.World; -import java.util.Optional; - -public record UseDurationDataComponent(Optional ticks) { - public static final UseDurationDataComponent INDEFINITE = new UseDurationDataComponent(Optional.empty()); - public static final MapCodec MAP_CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - IntegerProvider.CODEC.optionalFieldOf("ticks").forGetter(UseDurationDataComponent::ticks) - ).apply(instance, UseDurationDataComponent::new)); +public record UseDurationDataComponent(IntegerProvider ticks) { + private static final Codec FULL_CODEC = IntegerProvider.CODEC.xmap( + UseDurationDataComponent::new, + UseDurationDataComponent::ticks + ); public static final Codec CODEC = Codec.withAlternative( - MAP_CODEC.codec(), + FULL_CODEC, Codecs.POSITIVE_INT, UseDurationDataComponent::new ); - public static final PacketCodec PACKET_CODEC = PacketCodecs.optional(IntegerProvider.PACKET_CODEC) - .xmap(UseDurationDataComponent::new, UseDurationDataComponent::ticks); + public static final PacketCodec PACKET_CODEC = IntegerProvider.PACKET_CODEC.xmap( + UseDurationDataComponent::new, + UseDurationDataComponent::ticks + ); public static final int INDEFINITE_USE_DURATION = -1; - public UseDurationDataComponent(IntegerProvider ticks) { - this(Optional.of(ticks)); - } - private UseDurationDataComponent(int ticks) { this(new ConstantIntegerProvider(ticks)); } public int ticks(ItemStack stack, LivingEntity user) { - return this.ticks.map(useDuration -> useDuration.get(stack, user)) - .map(useDuration -> useDuration.orElse(0)) - .orElse(INDEFINITE_USE_DURATION); + return this.ticks.get(stack, user).orElse(0); } public boolean startUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { @@ -51,11 +42,13 @@ public boolean startUsing(World world, PlayerEntity user, Hand hand, ItemStack s if (ticks == 0) { return false; } + if (ticks == INDEFINITE_USE_DURATION) { ItemUsage.consumeHeldItem(world, user, hand); } else { user.itematic$startUsingHand(hand, ticks); } + return true; } } diff --git a/src/main/java/net/errorcraft/itematic/component/type/UseRemainderDataComponent.java b/src/main/java/net/errorcraft/itematic/component/type/UseRemainderDataComponent.java new file mode 100644 index 00000000..6e5d3f76 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/component/type/UseRemainderDataComponent.java @@ -0,0 +1,40 @@ +package net.errorcraft.itematic.component.type; + +import com.mojang.serialization.Codec; +import net.minecraft.item.ItemStack; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; + +public record UseRemainderDataComponent(ItemStack remainder) { + public static final Codec CODEC = ItemStack.CODEC.xmap( + UseRemainderDataComponent::new, + UseRemainderDataComponent::remainder + ); + public static final PacketCodec PACKET_CODEC = ItemStack.PACKET_CODEC.xmap( + UseRemainderDataComponent::new, + UseRemainderDataComponent::remainder + ); + + public ItemStack convert(ItemStack stack, int oldCount, boolean inCreativeMode, RemainderConsumer inserter) { + if (inCreativeMode) { + return stack; + } + + if (stack.getCount() >= oldCount) { + return stack; + } + + ItemStack remainder = this.remainder.copy(); + if (stack.isEmpty()) { + return remainder; + } + + inserter.apply(remainder); + return stack; + } + + @FunctionalInterface + public interface RemainderConsumer { + void apply(ItemStack stack); + } +} diff --git a/src/main/java/net/errorcraft/itematic/component/type/WeaponAttackDamageDataComponent.java b/src/main/java/net/errorcraft/itematic/component/type/WeaponAttackDamageDataComponent.java index 861ba041..09a2d5b4 100644 --- a/src/main/java/net/errorcraft/itematic/component/type/WeaponAttackDamageDataComponent.java +++ b/src/main/java/net/errorcraft/itematic/component/type/WeaponAttackDamageDataComponent.java @@ -11,11 +11,9 @@ import net.minecraft.network.codec.PacketCodec; import net.minecraft.network.codec.PacketCodecs; import net.minecraft.predicate.item.ItemPredicate; -import net.minecraft.registry.Registries; import net.minecraft.registry.RegistryCodecs; import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntryList; -import net.minecraft.registry.tag.TagKey; import java.util.List; import java.util.Optional; @@ -37,6 +35,7 @@ public double getDamage(ItemStack stack, Entity entity) { return rule.damage.get(); } } + return this.defaultDamage; } @@ -46,7 +45,8 @@ public boolean shouldAddBase(ItemStack stack, Entity entity) { return rule.addBase.get(); } } - return false; + + return true; } public record Rule(Optional>> entities, Optional item, Optional damage, Optional addBase) { @@ -64,20 +64,12 @@ public record Rule(Optional>> entities, Optional Rule::new ); - public static Rule addsToBase(TagKey> entityTypes, double damage) { - return new Rule( - Optional.ofNullable(Registries.ENTITY_TYPE.getOrCreateEntryList(entityTypes)), - Optional.empty(), - Optional.of(damage), - Optional.of(true) - ); - } - @SuppressWarnings("deprecation") public boolean matches(ItemStack stack, Entity entity) { if (this.entities.isPresent() && !this.entities.get().contains(entity.getType().getRegistryEntry())) { return false; } + return this.item.map(item -> item.test(stack)) .orElse(true); } diff --git a/src/main/java/net/errorcraft/itematic/entity/effect/StatusEffectKeys.java b/src/main/java/net/errorcraft/itematic/entity/effect/StatusEffectKeys.java index d0ab3050..f6799c94 100644 --- a/src/main/java/net/errorcraft/itematic/entity/effect/StatusEffectKeys.java +++ b/src/main/java/net/errorcraft/itematic/entity/effect/StatusEffectKeys.java @@ -6,16 +6,19 @@ import net.minecraft.util.Identifier; public class StatusEffectKeys { - public static final RegistryKey JUMP_BOOST = of("jump_boost"); - public static final RegistryKey REGENERATION = of("regeneration"); - public static final RegistryKey FIRE_RESISTANCE = of("fire_resistance"); + public static final RegistryKey ABSORPTION = of("absorption"); public static final RegistryKey BLINDNESS = of("blindness"); + public static final RegistryKey FIRE_RESISTANCE = of("fire_resistance"); + public static final RegistryKey HUNGER = of("hunger"); + public static final RegistryKey JUMP_BOOST = of("jump_boost"); + public static final RegistryKey NAUSEA = of("nausea"); public static final RegistryKey NIGHT_VISION = of("night_vision"); - public static final RegistryKey WEAKNESS = of("weakness"); public static final RegistryKey POISON = of("poison"); - public static final RegistryKey WITHER = of("wither"); - public static final RegistryKey ABSORPTION = of("absorption"); + public static final RegistryKey REGENERATION = of("regeneration"); + public static final RegistryKey RESISTANCE = of("resistance"); public static final RegistryKey SATURATION = of("saturation"); + public static final RegistryKey WEAKNESS = of("weakness"); + public static final RegistryKey WITHER = of("wither"); private static RegistryKey of(String id) { return RegistryKey.of(RegistryKeys.STATUS_EFFECT, Identifier.ofVanilla(id)); diff --git a/src/main/java/net/errorcraft/itematic/item/ItemUtil.java b/src/main/java/net/errorcraft/itematic/item/ItemUtil.java index 52acf641..e42ce1fd 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItemUtil.java +++ b/src/main/java/net/errorcraft/itematic/item/ItemUtil.java @@ -5,6 +5,7 @@ import net.errorcraft.itematic.block.BlockKeys; import net.errorcraft.itematic.block.ComposterBlockUtil; import net.errorcraft.itematic.block.entity.FurnaceBlockEntityUtil; +import net.errorcraft.itematic.component.AttributeModifiersComponentUtil; import net.errorcraft.itematic.component.type.ItemDamageRulesDataComponent; import net.errorcraft.itematic.entity.EntityTypeKeys; import net.errorcraft.itematic.entity.ItematicEntityTypeTags; @@ -31,6 +32,7 @@ import net.errorcraft.itematic.item.shooter.method.methods.DirectShooterMethod; import net.errorcraft.itematic.item.smithing.template.SmithingTemplate; import net.errorcraft.itematic.item.smithing.template.SmithingTemplates; +import net.errorcraft.itematic.item.use.provider.providers.IndefiniteIntegerProvider; import net.errorcraft.itematic.loot.predicate.SideCheckPredicate; import net.errorcraft.itematic.mixin.component.type.BundleContentsComponentAccessor; import net.errorcraft.itematic.mixin.item.*; @@ -100,6 +102,7 @@ public class ItemUtil { public static final int UNSTACKABLE_MAX_STACK_SIZE = 1; public static final Codec CODEC = RecordCodecBuilder.create((instance) -> instance.group( ItemBase.CODEC.fieldOf("base").forGetter(Item::itematic$itemBase), + AttributeModifiersComponentUtil.LIST_CODEC.optionalFieldOf("attribute_modifiers", AttributeModifiersComponent.DEFAULT).forGetter(Item::itematic$attributeModifiers), ItemComponentSet.CODEC.optionalFieldOf("components", ItemComponentSet.EMPTY).forGetter(Item::itematic$components), ItemEventMap.CODEC.optionalFieldOf("events", ItemEventMap.EMPTY).forGetter(Item::itematic$events) ).apply(instance, ItemUtil::create)); @@ -122,8 +125,13 @@ private static Item create(ItemBase base, ItemComponentSet components) { } private static Item create(ItemBase base, ItemComponentSet components, ItemEventMap events) { + return create(base, AttributeModifiersComponent.DEFAULT, components, events); + } + + private static Item create(ItemBase base, AttributeModifiersComponent attributeModifiers, ItemComponentSet components, ItemEventMap events) { Item item = new Item(new Item.Settings()); item.itematic$setItemBase(base); + item.itematic$setAttributeModifiers(attributeModifiers); item.itematic$setComponents(components); item.itematic$setEvents(events); return item; @@ -199,7 +207,6 @@ private void bootstrapConsumables() { .noConsumeParticles() .consumeSound(this.soundEvents.getOrThrow(SoundEventKeys.GENERIC_DRINK)) .build()) - .with(RecipeRemainderItemComponent.of(this.items.getOrThrow(ItemKeys.BUCKET))) .build(), ItemEventMap.builder() .add(ItemEvents.CONSUME_ITEM, ActionEntry.of(ClearStatusEffectsAction.of(ActionContextParameter.THIS))) @@ -421,6 +428,17 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.CHICKEN).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + ActionRequirements.of( + ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), + RandomChanceLootCondition.builder(0.3f).build() + ), + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 600) + ) + )) .build() )); this.registerable.register(ItemKeys.COOKED_CHICKEN, create( @@ -484,6 +502,15 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.PUFFERFISH).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 1200, 1), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.HUNGER), 300, 2), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.NAUSEA), 300) + ) + )) .build() )); this.registerable.register(ItemKeys.COOKED_COD, create( @@ -548,6 +575,17 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.ROTTEN_FLESH).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + ActionRequirements.of( + ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), + RandomChanceLootCondition.builder(0.8f).build() + ), + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.HUNGER), 600) + ) + )) .build() )); this.registerable.register(ItemKeys.SPIDER_EYE, create( @@ -555,6 +593,13 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.SPIDER_EYE).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 100) + ) + )) .build() )); this.registerable.register(ItemKeys.POISONOUS_POTATO, create( @@ -562,6 +607,17 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.POISONOUS_POTATO).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + ActionRequirements.of( + ActionContextParameters.of(ActionContextParameter.THIS, ActionContextParameter.THIS), + RandomChanceLootCondition.builder(0.6f).build() + ), + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.POISON), 100) + ) + )) .build() )); this.registerable.register(ItemKeys.GOLDEN_APPLE, create( @@ -571,6 +627,14 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.GOLDEN_APPLE).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.REGENERATION), 100, 1), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.ABSORPTION), 2400) + ) + )) .build() )); this.registerable.register(ItemKeys.ENCHANTED_GOLDEN_APPLE, create( @@ -581,6 +645,16 @@ private void bootstrapFood() { ItemComponentSet.builder() .with(StackableItemComponent.of(64)) .with(ConsumableItemComponent.builder(FoodComponents.ENCHANTED_GOLDEN_APPLE).build()) + .build(), + ItemEventMap.builder() + .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( + AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.REGENERATION), 400, 1), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.RESISTANCE), 6000), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.FIRE_RESISTANCE), 6000), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.ABSORPTION), 2400) + ) + )) .build() )); this.registerable.register(ItemKeys.GOLDEN_CARROT, create( @@ -609,7 +683,6 @@ private void bootstrapFood() { .noConsumeParticles() .consumeSound(this.soundEvents.getOrThrow(SoundEventKeys.HONEY_BOTTLE_DRINK)) .build()) - .with(RecipeRemainderItemComponent.of(this.items.getOrThrow(ItemKeys.GLASS_BOTTLE))) .build(), ItemEventMap.builder() .add(ItemEvents.CONSUME_ITEM, ActionEntry.of( @@ -7100,6 +7173,7 @@ private void bootstrapEquipment() { ItemComponentSet.builder() .with(StackableItemComponent.of(1)) .with(UseableItemComponent.builder() + .useFor(IndefiniteIntegerProvider.INSTANCE) .animation(UseAction.BLOCK) .build()) .with(DamageableItemComponent.of(336)) @@ -9497,15 +9571,13 @@ private void bootstrapBuckets() { ItemBase.Builder.forItem(ItemKeys.WATER_BUCKET).build(), ItemComponentSet.builder() .with(BucketItemComponent.fluid(this.fluids.getOrThrow(FluidKeys.WATER), this.soundEvents.getOrThrow(SoundEventKeys.BUCKET_EMPTY), this.items, this.dispenseBehaviors)) - .with(RecipeRemainderItemComponent.of(this.items.getOrThrow(ItemKeys.BUCKET))) .build() )); this.registerable.register(ItemKeys.LAVA_BUCKET, create( ItemBase.Builder.forItem(ItemKeys.LAVA_BUCKET).build(), ItemComponentSet.builder() .with(BucketItemComponent.fluid(this.fluids.getOrThrow(FluidKeys.LAVA), this.soundEvents.getOrThrow(SoundEventKeys.BUCKET_EMPTY_LAVA), this.items, this.dispenseBehaviors)) - .with(FuelItemComponent.of(FurnaceBlockEntityUtil.LAVA_FUEL_TIME)) - .with(RecipeRemainderItemComponent.of(this.items.getOrThrow(ItemKeys.BUCKET))) + .with(FuelItemComponent.of(FurnaceBlockEntityUtil.LAVA_FUEL_TIME, this.items.getOrThrow(ItemKeys.BUCKET))) .build() )); this.registerable.register(ItemKeys.POWDER_SNOW_BUCKET, create( @@ -10286,7 +10358,7 @@ private void bootstrapMiscellaneous() { .with(StackableItemComponent.of(1)) .with(ZoomItemComponent.of(SpyglassItem.FOV_MULTIPLIER, this.soundEvents.getOrThrow(SoundEventKeys.SPYGLASS_USE), this.soundEvents.getOrThrow(SoundEventKeys.SPYGLASS_STOP_USING))) .with(UseableItemComponent.builder() - .ticks(SpyglassItem.MAX_USE_TIME) + .useFor(SpyglassItem.MAX_USE_TIME) .animation(UseAction.SPYGLASS) .build()) .build() @@ -10530,7 +10602,6 @@ private void bootstrapMiscellaneous() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(64)) - .with(RecipeRemainderItemComponent.of(this.items.getOrThrow(ItemKeys.GLASS_BOTTLE))) .build() )); this.registerable.register(ItemKeys.TOTEM_OF_UNDYING, create( @@ -10539,10 +10610,16 @@ private void bootstrapMiscellaneous() { .build(), ItemComponentSet.builder() .with(StackableItemComponent.of(1)) - .with(LifeSavingItemComponent.of( - new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.REGENERATION), 900, 1), - new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.ABSORPTION), 100, 1), - new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.FIRE_RESISTANCE), 800, 0) + .build(), + ItemEventMap.builder() + .add(ItemEvents.BEFORE_DEATH_HOLDER, ActionEntry.of( + UncheckedSequenceHandler.builder() + .add(ClearStatusEffectsAction.of(ActionContextParameter.THIS)) + .add(AddStatusEffectsAction.of( + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.REGENERATION), 900, 1), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.ABSORPTION), 100, 1), + new StatusEffectInstance(this.statusEffects.getOrThrow(StatusEffectKeys.FIRE_RESISTANCE), 800, 0) + )) )) .build() )); diff --git a/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java b/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java index aaf2ee57..4bb82af0 100644 --- a/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java +++ b/src/main/java/net/errorcraft/itematic/item/ItematicItemTags.java @@ -160,6 +160,9 @@ public class ItematicItemTags { public static final TagKey PREVENTS_MINING_IN_CREATIVE = of("prevents_mining_in_creative"); public static final TagKey PREVENTS_TAKING_POTTED_ITEM_OUT = of("prevents_taking_potted_item_out"); + public static final TagKey BREWING_INPUTS = of("brewing_inputs"); + public static final TagKey MUNDANE_POTION_REAGENTS = of("mundane_potion_reagents"); + private ItematicItemTags() {} private static TagKey of(String id) { diff --git a/src/main/java/net/errorcraft/itematic/item/component/ItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/ItemComponent.java index c5fef10c..dc5ae68d 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/ItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/ItemComponent.java @@ -54,7 +54,9 @@ default boolean postMine(ItemStack stack, World world, BlockState state, BlockPo default void using(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks) {} - default void stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) {} + default boolean stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { + return false; + } default void finishUsing(World world, LivingEntity user, ItemStack stack, int usedTicks, ItemStackConsumer resultStackConsumer) {} diff --git a/src/main/java/net/errorcraft/itematic/item/component/ItemComponentTypes.java b/src/main/java/net/errorcraft/itematic/item/component/ItemComponentTypes.java index c86f5e83..03f4b69f 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/ItemComponentTypes.java +++ b/src/main/java/net/errorcraft/itematic/item/component/ItemComponentTypes.java @@ -25,7 +25,6 @@ public class ItemComponentTypes { public static final ItemComponentType DYE = register("dye", new ItemComponentType<>(DyeItemComponent.CODEC)); public static final ItemComponentType DYEABLE = register("dyeable", new ItemComponentType<>(DyeableItemComponent.CODEC)); public static final ItemComponentType TINTED = register("tinted", new ItemComponentType<>(TintedItemComponent.CODEC)); - public static final ItemComponentType USEABLE_ON_FLUID = register("useable_on_fluid", new ItemComponentType<>(UseableOnFluidItemComponent.CODEC)); public static final ItemComponentType SPAWN_EGG = register("spawn_egg", new ItemComponentType<>(SpawnEggItemComponent.CODEC)); public static final ItemComponentType DISPENSABLE = register("dispensable", new ItemComponentType<>(DispensableItemComponent.CODEC)); public static final ItemComponentType SHOOTER = register("shooter", new ItemComponentType<>(ShooterItemComponent.CODEC)); @@ -54,14 +53,11 @@ public class ItemComponentTypes { public static final ItemComponentType ZOOM = register("zoom", new ItemComponentType<>(ZoomItemComponent.CODEC)); public static final ItemComponentType ITEM_HOLDER = register("item_holder", new ItemComponentType<>(ItemHolderItemComponent.CODEC)); public static final ItemComponentType IMMUNE_TO_DAMAGE = register("immune_to_damage", new ItemComponentType<>(ImmuneToDamageItemComponent.CODEC)); - public static final ItemComponentType LIFE_SAVING = register("life_saving", new ItemComponentType<>(LifeSavingItemComponent.CODEC)); public static final ItemComponentType UNLOCK_RECIPES = register("unlock_recipes", new ItemComponentType<>(UnlockRecipesItemComponent.CODEC)); public static final ItemComponentType DEBUG_STICK = register("debug_stick", new ItemComponentType<>(DebugStickItemComponent.CODEC)); public static final ItemComponentType SUSPICIOUS_EFFECT_INGREDIENT = register("suspicious_effect_ingredient", new ItemComponentType<>(SuspiciousEffectIngredientItemComponent.CODEC)); - public static final ItemComponentType RECIPE_REMAINDER = register("recipe_remainder", new ItemComponentType<>(RecipeRemainderItemComponent.CODEC)); public static final ItemComponentType CASTABLE = register("castable", new ItemComponentType<>(CastableItemComponent.CODEC)); public static final ItemComponentType STACKABLE = register("stackable", new ItemComponentType<>(StackableItemComponent.CODEC)); - public static final ItemComponentType ATTRIBUTE_MODIFIERS = register("attribute_modifiers", new ItemComponentType<>(AttributeModifiersItemComponent.CODEC)); public static final ItemComponentType OMINOUS_EFFECT_PROVIDER = register("ominous_effect_provider", new ItemComponentType<>(OminousEffectProviderItemComponent.CODEC)); private ItemComponentTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/AttributeModifiersItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/AttributeModifiersItemComponent.java deleted file mode 100644 index dbe2b50e..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/AttributeModifiersItemComponent.java +++ /dev/null @@ -1,35 +0,0 @@ -package net.errorcraft.itematic.item.component.components; - -import com.mojang.serialization.Codec; -import net.errorcraft.itematic.item.component.ItemComponent; -import net.errorcraft.itematic.item.component.ItemComponentSet; -import net.errorcraft.itematic.item.component.ItemComponentType; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.component.type.AttributeModifiersComponent; - -import java.util.List; - -public record AttributeModifiersItemComponent(List modifiers) implements ItemComponent { - public static final Codec CODEC = AttributeModifiersComponent.Entry.CODEC.listOf().xmap(AttributeModifiersItemComponent::new, AttributeModifiersItemComponent::modifiers); - - public static AttributeModifiersItemComponent of(List modifiers) { - return new AttributeModifiersItemComponent(modifiers); - } - - @Override - public ItemComponentType type() { - return ItemComponentTypes.ATTRIBUTE_MODIFIERS; - } - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public void addAttributeModifiers(AttributeModifiersComponent.Builder builder, ItemComponentSet components) { - for (AttributeModifiersComponent.Entry modifier : this.modifiers) { - builder.add(modifier.attribute(), modifier.modifier(), modifier.slot()); - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/BlockItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/BlockItemComponent.java index 0e2195bd..602b5a2d 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/BlockItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/BlockItemComponent.java @@ -11,7 +11,7 @@ import net.errorcraft.itematic.item.placement.block.picker.pickers.AttachedToSideBlockPicker; import net.errorcraft.itematic.item.placement.block.picker.pickers.SimpleBlockPicker; import net.errorcraft.itematic.mixin.item.ItemAccessor; -import net.errorcraft.itematic.serialization.ItematicCodecs; +import net.errorcraft.itematic.serialization.SetCodec; import net.minecraft.block.Block; import net.minecraft.block.ShulkerBoxBlock; import net.minecraft.component.ComponentMap; @@ -42,7 +42,7 @@ public record BlockItemComponent(BlockPicker block, boolean operatorOnly, Set public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( BlockPicker.CODEC.fieldOf("block").forGetter(BlockItemComponent::block), Codec.BOOL.optionalFieldOf("operator_only", false).forGetter(BlockItemComponent::operatorOnly), - ItematicCodecs.setCodec(Pass.CODEC).optionalFieldOf("passes", Pass.DEFAULT_PASSES).forGetter(BlockItemComponent::passes) + SetCodec.forEnum(Pass.CODEC).optionalFieldOf("passes", Pass.DEFAULT_PASSES).forGetter(BlockItemComponent::passes) ).apply(instance, BlockItemComponent::new)); public static BlockItemComponent of(BlockPicker block, boolean operatorOnly, Set passes) { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/BrushItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/BrushItemComponent.java index cf420ae2..1e484c59 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/BrushItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/BrushItemComponent.java @@ -19,7 +19,7 @@ public record BrushItemComponent() implements ItemComponent public static ItemComponent[] of(int brushTicks) { return new ItemComponent[] { UseableItemComponent.builder() - .ticks(brushTicks) + .useFor(brushTicks) .animation(UseAction.BRUSH) .passes(UseableItemComponent.Pass.BLOCK) .build(), diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ConsumableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ConsumableItemComponent.java index 785adc8f..6cbbc4c8 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ConsumableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ConsumableItemComponent.java @@ -15,11 +15,8 @@ import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsage; import net.minecraft.registry.Registries; -import net.minecraft.registry.RegistryKeys; import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; import net.minecraft.server.network.ServerPlayerEntity; import net.minecraft.server.world.ServerWorld; import net.minecraft.sound.SoundEvent; @@ -31,19 +28,17 @@ import java.util.HashSet; import java.util.Objects; -import java.util.Optional; import java.util.Set; -public record ConsumableItemComponent(Optional> resultItem, boolean hasConsumeParticles, RegistryEntry sound) implements ItemComponent { +public record ConsumableItemComponent(boolean hasConsumeParticles, RegistryEntry sound) implements ItemComponent { private static final RegistryEntry DEFAULT_SOUND = Registries.SOUND_EVENT.getEntry(SoundEvents.ENTITY_GENERIC_EAT); public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.ITEM).optionalFieldOf("result_item").forGetter(ConsumableItemComponent::resultItem), Codec.BOOL.optionalFieldOf("has_consume_particles", true).forGetter(ConsumableItemComponent::hasConsumeParticles), SoundEvent.ENTRY_CODEC.optionalFieldOf("sound", DEFAULT_SOUND).forGetter(ConsumableItemComponent::sound) ).apply(instance, ConsumableItemComponent::new)); - public static ConsumableItemComponent of(RegistryEntry resultItem, boolean hasConsumeParticles, RegistryEntry sound) { - return new ConsumableItemComponent(Optional.ofNullable(resultItem), hasConsumeParticles, sound); + public static ConsumableItemComponent of(boolean hasConsumeParticles, RegistryEntry sound) { + return new ConsumableItemComponent(hasConsumeParticles, sound); } public static Builder builder(int useDuration) { @@ -77,9 +72,8 @@ public void consume(LivingEntity user, ItemStack stack, ItemStackConsumer result .build(); stack.itematic$invokeEvent(ItemEvents.CONSUME_ITEM, context); } - this.resultItem.map(ItemStack::new) - .map(resultStack -> ItemUsage.exchangeStack(stack, player, resultStack)) - .ifPresentOrElse(resultStackConsumer::set, () -> stack.decrementUnlessCreative(1, user)); + + stack.decrementUnlessCreative(1, user); if (player instanceof ServerPlayerEntity serverPlayer) { Criteria.CONSUME_ITEM.trigger(serverPlayer, stack); } @@ -102,11 +96,12 @@ private Builder(int useDuration) { public ItemComponent[] build() { Set> behavior = new HashSet<>(); behavior.add(UseableItemComponent.builder() - .ticks(this.useDuration) + .useFor(this.useDuration) .animation(this.useAnimation) + .remainder(this.resultItem) .build() ); - behavior.add(ConsumableItemComponent.of(this.resultItem, this.hasConsumeParticles, this.consumeSound)); + behavior.add(ConsumableItemComponent.of(this.hasConsumeParticles, this.consumeSound)); if (this.food != null) { behavior.add(this.food); } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/CooldownItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/CooldownItemComponent.java index ec289228..15866af8 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/CooldownItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/CooldownItemComponent.java @@ -2,22 +2,24 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.ItemStackConsumer; +import net.errorcraft.itematic.component.ItematicDataComponentTypes; +import net.errorcraft.itematic.component.type.UseCooldownDataComponent; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; +import net.minecraft.SharedConstants; +import net.minecraft.component.ComponentMap; import net.minecraft.util.dynamic.Codecs; -import net.minecraft.world.World; public record CooldownItemComponent(int ticks) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codecs.POSITIVE_INT.fieldOf("ticks").forGetter(CooldownItemComponent::ticks) ).apply(instance, CooldownItemComponent::new)); + public static CooldownItemComponent of(int ticks) { + return new CooldownItemComponent(ticks); + } + @Override public ItemComponentType type() { return ItemComponentTypes.COOLDOWN; @@ -29,12 +31,7 @@ public Codec codec() { } @Override - public ActionResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { - user.getItemCooldownManager().set(stack.getItem(), this.ticks); - return ActionResult.PASS; - } - - public static CooldownItemComponent of(int ticks) { - return new CooldownItemComponent(ticks); + public void addComponents(ComponentMap.Builder builder) { + builder.add(ItematicDataComponentTypes.USE_COOLDOWN, new UseCooldownDataComponent((float) this.ticks / SharedConstants.TICKS_PER_SECOND)); } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/DamageableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/DamageableItemComponent.java index 9b04a728..87a58345 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/DamageableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/DamageableItemComponent.java @@ -2,7 +2,6 @@ import com.mojang.serialization.Codec; import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.component.type.WeaponAttackDamageDataComponent; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; @@ -21,7 +20,6 @@ import net.minecraft.sound.SoundEvent; import net.minecraft.util.dynamic.Codecs; -import java.util.Arrays; import java.util.List; import java.util.Optional; @@ -57,10 +55,7 @@ public static ItemComponent[] sword(ToolMaterial material, TagKey repai WeaponItemComponent.of( 1, attackDamage, - 0.4d, - Arrays.stream(proficientEntityTypeTags) - .map(proficientEntityTypeTag -> WeaponAttackDamageDataComponent.Rule.addsToBase(proficientEntityTypeTag, attackDamage - 1.0d)) - .toArray(WeaponAttackDamageDataComponent.Rule[]::new) + 0.4d ), EnchantableItemComponent.of(material), RepairableItemComponent.of(repairItemsTag) @@ -102,10 +97,7 @@ private static ItemComponent[] tool(ToolMaterial material, double attackDamag WeaponItemComponent.of( 2, realAttackDamage, - attackSpeed, - Arrays.stream(proficientEntityTypeTags) - .map(proficientEntityTypeTag -> WeaponAttackDamageDataComponent.Rule.addsToBase(proficientEntityTypeTag, realAttackDamage - 1.0d)) - .toArray(WeaponAttackDamageDataComponent.Rule[]::new) + attackSpeed ), EnchantableItemComponent.of(material), RepairableItemComponent.of(repairItemsTag) diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/EntityItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/EntityItemComponent.java index b4f4195e..62ddd0d0 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/EntityItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/EntityItemComponent.java @@ -13,11 +13,14 @@ import net.errorcraft.itematic.item.dispense.behavior.DispenseBehaviors; import net.errorcraft.itematic.item.placement.EntityPlacer; import net.errorcraft.itematic.mixin.item.DecorationItemAccessor; +import net.errorcraft.itematic.mixin.item.ItemAccessor; import net.errorcraft.itematic.mixin.item.SpawnEggItemAccessor; +import net.errorcraft.itematic.serialization.SetCodec; import net.minecraft.component.DataComponentTypes; import net.minecraft.component.type.NbtComponent; import net.minecraft.entity.EntityType; import net.minecraft.entity.decoration.painting.PaintingEntity; +import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; @@ -28,18 +31,41 @@ import net.minecraft.text.Text; import net.minecraft.util.ActionResult; import net.minecraft.util.Formatting; +import net.minecraft.util.Hand; +import net.minecraft.util.StringIdentifiable; +import net.minecraft.util.hit.BlockHitResult; +import net.minecraft.util.hit.HitResult; +import net.minecraft.world.RaycastContext; +import net.minecraft.world.World; import java.util.List; import java.util.Optional; +import java.util.Set; -public record EntityItemComponent(EntityInitializer entity, boolean allowItemData) implements ItemComponent { +public record EntityItemComponent(EntityInitializer entity, boolean allowItemData, Set passes) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( EntityInitializer.CODEC.fieldOf("entity").forGetter(EntityItemComponent::entity), - Codec.BOOL.optionalFieldOf("allow_item_data", false).forGetter(EntityItemComponent::allowItemData) + Codec.BOOL.optionalFieldOf("allow_item_data", false).forGetter(EntityItemComponent::allowItemData), + SetCodec.forEnum(Pass.CODEC).optionalFieldOf("passes", Pass.DEFAULT_PASSES).forGetter(EntityItemComponent::passes) ).apply(instance, EntityItemComponent::new)); private static final MapCodec> ENTITY_TYPE_MAP_CODEC = SpawnEggItemAccessor.entityTypeMapCodec(); private static final Text RANDOM_TEXT = DecorationItemAccessor.randomText(); + public static EntityItemComponent of(EntityInitializer entity) { + return new EntityItemComponent(entity, false, Pass.DEFAULT_PASSES); + } + + public static EntityItemComponent of(EntityInitializer entity, boolean allowItemData, Pass... passes) { + return new EntityItemComponent(entity, allowItemData, Set.of(passes)); + } + + public static ItemComponent[] from(EntityInitializer entity, RegistryEntryLookup dispenseBehaviors) { + return new ItemComponent[] { + of(entity), + DispensableItemComponent.of(dispenseBehaviors.getOrThrow(DispenseBehaviors.SPAWN_ENTITY_FROM_ITEM)) + }; + } + @Override public ItemComponentType type() { return ItemComponentTypes.ENTITY; @@ -50,6 +76,38 @@ public Codec codec() { return CODEC; } + @Override + public ActionResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { + if (this.isUnuseable(Pass.FLUID)) { + return ActionResult.PASS; + } + + if (world.isClient()) { + return ActionResult.SUCCESS; + } + + BlockHitResult blockHitResult = ItemAccessor.raycast(world, user, RaycastContext.FluidHandling.SOURCE_ONLY); + if (blockHitResult.getType() != HitResult.Type.BLOCK) { + return ActionResult.PASS; + } + + ItemUsageContext itemUsageContext = new ItemUsageContext(world, user, hand, stack, blockHitResult); + return this.place(itemUsageContext, resultStackConsumer); + } + + @Override + public ActionResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + if (this.isUnuseable(Pass.BLOCK)) { + return ActionResult.PASS; + } + + if (context.getWorld().isClient()) { + return ActionResult.SUCCESS; + } + + return this.place(context, resultStackConsumer); + } + @Override public void appendTooltip(ItemStack stack, Item.TooltipContext context, List tooltip, TooltipType type) { if (this.entity.type() != EntityType.PAINTING) { @@ -81,43 +139,43 @@ public void appendTooltip(ItemStack stack, Item.TooltipContext context, List entity) { - return of(entity, false); - } - - public static EntityItemComponent of(EntityInitializer entity, boolean allowItemData) { - return new EntityItemComponent(entity, allowItemData); - } - - public static ItemComponent[] from(EntityInitializer entity, RegistryEntryLookup dispenseBehaviors) { - return from(entity, false, dispenseBehaviors); - } - - public static ItemComponent[] from(EntityInitializer entity, boolean allowItemData, RegistryEntryLookup dispenseBehaviors) { - return new ItemComponent[] { - of(entity, allowItemData), - DispensableItemComponent.of(dispenseBehaviors.getOrThrow(DispenseBehaviors.SPAWN_ENTITY_FROM_ITEM)) - }; + private boolean isUnuseable(Pass pass) { + return !this.passes.contains(pass); } - @Override - public ActionResult useOnBlock(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { - ItemStack stack = context.getStack(); - if (context.getWorld().isClient()) { - return ActionResult.SUCCESS; - } - EntityPlacer placer = EntityPlacer.spawned(context, stack, resultStackConsumer, this); - return placer.place(); + private ActionResult place(ItemUsageContext context, ItemStackConsumer resultStackConsumer) { + return EntityPlacer.spawned(context, context.getStack(), resultStackConsumer, this) + .place(); } public EntityInitializer getEntityInitializer(ItemStack stack) { if (!this.allowItemData) { return this.entity; } + NbtComponent entityData = stack.getOrDefault(DataComponentTypes.ENTITY_DATA, NbtComponent.DEFAULT); Optional> initializer = entityData.get(ENTITY_TYPE_MAP_CODEC) .result() .map(SimpleEntityInitializer::new); return initializer.orElse(this.entity); } + + public enum Pass implements StringIdentifiable { + BLOCK("block"), + FLUID("fluid"); + + public static final Set DEFAULT_PASSES = Set.of(BLOCK); + public static final Codec CODEC = StringIdentifiable.createCodec(Pass::values); + + private final String name; + + Pass(String name) { + this.name = name; + } + + @Override + public String asString() { + return this.name; + } + } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/FoodItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/FoodItemComponent.java index 72ee669d..3f348776 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/FoodItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/FoodItemComponent.java @@ -18,16 +18,15 @@ import java.util.List; import java.util.Optional; -public record FoodItemComponent(int nutrition, float saturation, boolean alwaysEdible, List effects) implements ItemComponent { +public record FoodItemComponent(int nutrition, float saturation, boolean alwaysEdible) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( Codecs.NONNEGATIVE_INT.fieldOf("nutrition").forGetter(FoodItemComponent::nutrition), Codec.FLOAT.fieldOf("saturation").forGetter(FoodItemComponent::saturation), - Codec.BOOL.optionalFieldOf("always_edible", false).forGetter(FoodItemComponent::alwaysEdible), - FoodComponent.StatusEffectEntry.CODEC.listOf().optionalFieldOf("effects", List.of()).forGetter(FoodItemComponent::effects) + Codec.BOOL.optionalFieldOf("always_edible", false).forGetter(FoodItemComponent::alwaysEdible) ).apply(instance, FoodItemComponent::new)); public static FoodItemComponent of(FoodComponent food) { - return new FoodItemComponent(food.nutrition(), food.saturation(), food.canAlwaysEat(), food.effects()); + return new FoodItemComponent(food.nutrition(), food.saturation(), food.canAlwaysEat()); } @Override @@ -50,10 +49,15 @@ public void finishUsing(World world, LivingEntity user, ItemStack stack, int use @Override public void addComponents(ComponentMap.Builder builder) { - builder.add(DataComponentTypes.FOOD, new FoodComponent(this.nutrition, this.saturation, false, 1.0f, Optional.empty(), this.effects)); + builder.add(DataComponentTypes.FOOD, new FoodComponent(this.nutrition, this.saturation, this.alwaysEdible, 1.0f, Optional.empty(), List.of())); } - public boolean mayStartUsing(PlayerEntity user) { - return user.canConsume(this.alwaysEdible); + public boolean mayStartUsing(PlayerEntity user, ItemStack stack) { + FoodComponent food = stack.get(DataComponentTypes.FOOD); + if (food == null) { + return false; + } + + return user.canConsume(food.canAlwaysEat()); } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/FuelItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/FuelItemComponent.java index f52ce833..f2f48f9a 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/FuelItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/FuelItemComponent.java @@ -5,13 +5,27 @@ import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.dynamic.Codecs; -public record FuelItemComponent(int ticks) implements ItemComponent { +import java.util.Optional; + +public record FuelItemComponent(int ticks, Optional remainder) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - Codecs.POSITIVE_INT.fieldOf("ticks").forGetter(FuelItemComponent::ticks) + Codecs.POSITIVE_INT.fieldOf("ticks").forGetter(FuelItemComponent::ticks), + ItemStack.CODEC.optionalFieldOf("remainder").forGetter(FuelItemComponent::remainder) ).apply(instance, FuelItemComponent::new)); + public static FuelItemComponent of(int ticks) { + return new FuelItemComponent(ticks, Optional.empty()); + } + + public static FuelItemComponent of(int ticks, RegistryEntry remainder) { + return new FuelItemComponent(ticks, Optional.of(new ItemStack(remainder))); + } + @Override public ItemComponentType type() { return ItemComponentTypes.FUEL; @@ -21,8 +35,4 @@ public ItemComponentType type() { public Codec codec() { return CODEC; } - - public static FuelItemComponent of(int ticks) { - return new FuelItemComponent(ticks); - } } diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/LifeSavingItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/LifeSavingItemComponent.java deleted file mode 100644 index 00f7f35c..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/LifeSavingItemComponent.java +++ /dev/null @@ -1,37 +0,0 @@ -package net.errorcraft.itematic.item.component.components; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.component.ItemComponent; -import net.errorcraft.itematic.item.component.ItemComponentType; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.entity.LivingEntity; -import net.minecraft.entity.effect.StatusEffectInstance; - -import java.util.List; - -public record LifeSavingItemComponent(List effects) implements ItemComponent { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - StatusEffectInstance.CODEC.listOf().fieldOf("effects").forGetter(LifeSavingItemComponent::effects) - ).apply(instance, LifeSavingItemComponent::new)); - - @Override - public ItemComponentType type() { - return ItemComponentTypes.LIFE_SAVING; - } - - @Override - public Codec codec() { - return CODEC; - } - - public void apply(LivingEntity target) { - for (StatusEffectInstance effect : this.effects) { - target.addStatusEffect(new StatusEffectInstance(effect)); - } - } - - public static LifeSavingItemComponent of(StatusEffectInstance... effects) { - return new LifeSavingItemComponent(List.of(effects)); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/PlayableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/PlayableItemComponent.java index 9a94c0b4..c53f9ffe 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/PlayableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/PlayableItemComponent.java @@ -37,7 +37,7 @@ public record PlayableItemComponent(TagKey instruments) implements I public static ItemComponent[] of(TagKey instruments) { return new ItemComponent[] { UseableItemComponent.builder() - .ticks(PlayableIntegerProvider.INSTANCE) + .useFor(PlayableIntegerProvider.INSTANCE) .animation(UseAction.TOOT_HORN) .build(), new PlayableItemComponent(instruments) diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/RecipeRemainderItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/RecipeRemainderItemComponent.java deleted file mode 100644 index 7d127bdf..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/RecipeRemainderItemComponent.java +++ /dev/null @@ -1,31 +0,0 @@ -package net.errorcraft.itematic.item.component.components; - -import com.mojang.serialization.Codec; -import com.mojang.serialization.codecs.RecordCodecBuilder; -import net.errorcraft.itematic.item.component.ItemComponent; -import net.errorcraft.itematic.item.component.ItemComponentType; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.minecraft.item.Item; -import net.minecraft.registry.RegistryKeys; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.registry.entry.RegistryFixedCodec; - -public record RecipeRemainderItemComponent(RegistryEntry item) implements ItemComponent { - public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - RegistryFixedCodec.of(RegistryKeys.ITEM).fieldOf("item").forGetter(RecipeRemainderItemComponent::item) - ).apply(instance, RecipeRemainderItemComponent::new)); - - @Override - public ItemComponentType type() { - return ItemComponentTypes.RECIPE_REMAINDER; - } - - @Override - public Codec codec() { - return CODEC; - } - - public static RecipeRemainderItemComponent of(RegistryEntry item) { - return new RecipeRemainderItemComponent(item); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ShooterItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ShooterItemComponent.java index 3ab04895..ce1f2f11 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ShooterItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ShooterItemComponent.java @@ -48,7 +48,7 @@ public record ShooterItemComponent(RegistryEntryList heldAmmunition, Regis public static ItemComponent[] of(UseAction animation, RegistryEntryList heldAmmunition, RegistryEntryList ammunition, int range, ShooterMethod method, ItemDamageRulesDataComponent.Rule... rules) { return new ItemComponent[] { UseableItemComponent.builder() - .ticks(ShooterIntegerProvider.INSTANCE) + .useFor(ShooterIntegerProvider.INSTANCE) .animation(animation) .build(), new ShooterItemComponent( @@ -86,8 +86,8 @@ public void using(ItemStack stack, World world, LivingEntity user, int usedTicks } @Override - public void stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { - this.method.stop(this, stack, world, user, usedTicks); + public boolean stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { + return this.method.stop(this, stack, world, user, usedTicks); } @Override diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/SpawnEggItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/SpawnEggItemComponent.java index 9e09c771..fe7293da 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/SpawnEggItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/SpawnEggItemComponent.java @@ -26,6 +26,15 @@ public record SpawnEggItemComponent() implements ItemComponent CODEC = Codec.unit(INSTANCE); + public static ItemComponent[] from(RegistryEntry> entity, int primaryColor, int secondaryColor, RegistryEntryLookup dispenseBehaviors) { + return new ItemComponent[] { + EntityItemComponent.of(SimpleEntityInitializer.of(entity.value()), true, EntityItemComponent.Pass.BLOCK, EntityItemComponent.Pass.FLUID), + INSTANCE, + TintedItemComponent.of(IndexItemColor.of(primaryColor, secondaryColor)), + DispensableItemComponent.of(dispenseBehaviors.getOrThrow(DispenseBehaviors.SPAWN_ENTITY_FROM_ITEM)) + }; + } + @Override public ItemComponentType type() { return ItemComponentTypes.SPAWN_EGG; @@ -41,36 +50,31 @@ public Optional spawnBaby(PlayerEntity user, MobEntity entity, Entity if (entityItemComponent.isEmpty()) { return Optional.empty(); } + if (entityItemComponent.get().getEntityInitializer(stack).type() != entityType) { return Optional.empty(); } + MobEntity mobEntity = this.createEntity(entity, entityType, world); if (mobEntity == null) { return Optional.empty(); } + if (!mobEntity.itematic$trySetBaby(true)) { return Optional.empty(); } + mobEntity.refreshPositionAfterTeleport(pos); Text customName = stack.get(DataComponentTypes.CUSTOM_NAME); if (customName != null) { mobEntity.setCustomName(customName); } + world.spawnEntityAndPassengers(mobEntity); stack.decrementUnlessCreative(1, user); return Optional.of(mobEntity); } - public static ItemComponent[] from(RegistryEntry> entity, int primaryColor, int secondaryColor, RegistryEntryLookup dispenseBehaviors) { - return new ItemComponent[] { - EntityItemComponent.of(SimpleEntityInitializer.of(entity.value()), true), - INSTANCE, - UseableOnFluidItemComponent.INSTANCE, - TintedItemComponent.of(IndexItemColor.of(primaryColor, secondaryColor)), - DispensableItemComponent.of(dispenseBehaviors.getOrThrow(DispenseBehaviors.SPAWN_ENTITY_FROM_ITEM)) - }; - } - private MobEntity createEntity(MobEntity entity, EntityType entityType, ServerWorld world) { if (entity instanceof PassiveEntity passiveEntity) { return passiveEntity.createChild(world, passiveEntity); diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ThrowableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ThrowableItemComponent.java index 33471d36..487a8d19 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ThrowableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ThrowableItemComponent.java @@ -46,7 +46,7 @@ public static ThrowableItemComponent of(float speed, float angleOffset) { public static ItemComponent[] trident(float speed, float angleOffset, int minDrawDuration) { return new ItemComponent[] { UseableItemComponent.builder() - .ticks(TridentIntegerProvider.INSTANCE) + .useFor(TridentIntegerProvider.INSTANCE) .animation(UseAction.SPEAR) .build(), new ThrowableItemComponent(speed, angleOffset, Optional.of(NumberRange.IntRange.atLeast(minDrawDuration))) @@ -72,13 +72,17 @@ public ActionResult use(World world, PlayerEntity user, Hand hand, ItemStack sta } @Override - public void stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { + public boolean stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { if (this.drawDuration.filter(drawDuration -> drawDuration.test(usedTicks)).isPresent()) { this.createEntity(world, user, stack, resultStackConsumer); if (user instanceof PlayerEntity player) { player.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); } + + return true; } + + return false; } private ActionResult createEntity(World world, LivingEntity user, ItemStack stack, ItemStackConsumer resultStackConsumer) { diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/UseableItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/UseableItemComponent.java index 04390989..c53aa414 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/UseableItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/UseableItemComponent.java @@ -4,32 +4,38 @@ import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.component.type.UseDurationDataComponent; +import net.errorcraft.itematic.component.type.UseRemainderDataComponent; import net.errorcraft.itematic.item.ItemStackConsumer; import net.errorcraft.itematic.item.component.ItemComponent; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.use.provider.IntegerProvider; import net.errorcraft.itematic.item.use.provider.providers.ConstantIntegerProvider; -import net.errorcraft.itematic.serialization.ItematicCodecs; +import net.errorcraft.itematic.item.use.provider.providers.IndefiniteIntegerProvider; +import net.errorcraft.itematic.serialization.SetCodec; import net.errorcraft.itematic.util.UseActionUtil; import net.minecraft.component.ComponentMap; import net.minecraft.entity.LivingEntity; import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; import net.minecraft.item.ItemStack; import net.minecraft.item.ItemUsageContext; +import net.minecraft.registry.entry.RegistryEntry; import net.minecraft.util.ActionResult; import net.minecraft.util.Hand; import net.minecraft.util.StringIdentifiable; import net.minecraft.util.UseAction; import net.minecraft.world.World; +import java.util.Optional; import java.util.Set; -public record UseableItemComponent(UseDurationDataComponent ticks, UseAction animation, Set passes) implements ItemComponent { +public record UseableItemComponent(Optional ticks, UseAction animation, Optional remainder, Set passes) implements ItemComponent { public static final Codec CODEC = RecordCodecBuilder.create(instance -> instance.group( - UseDurationDataComponent.MAP_CODEC.forGetter(UseableItemComponent::ticks), + UseDurationDataComponent.CODEC.optionalFieldOf("ticks").forGetter(UseableItemComponent::ticks), UseActionUtil.CODEC.optionalFieldOf("animation", UseAction.NONE).forGetter(UseableItemComponent::animation), - ItematicCodecs.setCodec(Pass.CODEC).optionalFieldOf("passes", Pass.DEFAULT_PASSES).forGetter(UseableItemComponent::passes) + ItemStack.CODEC.optionalFieldOf("remainder").forGetter(UseableItemComponent::remainder), + SetCodec.forEnum(Pass.CODEC).optionalFieldOf("passes", Pass.DEFAULT_PASSES).forGetter(UseableItemComponent::passes) ).apply(instance, UseableItemComponent::new)); public static Builder builder() { @@ -86,8 +92,9 @@ private static ActionResult tryStartUsing(World world, PlayerEntity user, Hand h @Override public void addComponents(ComponentMap.Builder builder) { - builder.add(ItematicDataComponentTypes.USE_DURATION, this.ticks); + this.ticks.ifPresent(ticks -> builder.add(ItematicDataComponentTypes.USE_DURATION, ticks)); builder.add(ItematicDataComponentTypes.USE_ANIMATION, this.animation); + this.remainder.ifPresent(remainder -> builder.add(ItematicDataComponentTypes.USE_REMAINDER, new UseRemainderDataComponent(remainder))); } private boolean isUnuseable(Pass pass) { @@ -97,33 +104,45 @@ private boolean isUnuseable(Pass pass) { public static class Builder { private IntegerProvider ticks; private UseAction animation = UseAction.NONE; + private RegistryEntry remainder; private Set passes = Pass.DEFAULT_PASSES; private Builder() {} public UseableItemComponent build() { return new UseableItemComponent( - this.ticks == null ? UseDurationDataComponent.INDEFINITE : new UseDurationDataComponent(this.ticks), + Optional.ofNullable(this.ticks).map(UseDurationDataComponent::new), this.animation, + Optional.ofNullable(this.remainder).map(ItemStack::new), this.passes ); } - public Builder ticks(int ticks) { + public Builder useFor(int ticks) { this.ticks = new ConstantIntegerProvider(ticks); return this; } - public Builder ticks(IntegerProvider ticks) { + public Builder useFor(IntegerProvider ticks) { this.ticks = ticks; return this; } + public Builder useIndefinitely() { + this.ticks = IndefiniteIntegerProvider.INSTANCE; + return this; + } + public Builder animation(UseAction animation) { this.animation = animation; return this; } + public Builder remainder(RegistryEntry remainder) { + this.remainder = remainder; + return this; + } + public Builder passes(Pass... passes) { this.passes = Set.of(passes); return this; diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/UseableOnFluidItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/UseableOnFluidItemComponent.java deleted file mode 100644 index 0f869028..00000000 --- a/src/main/java/net/errorcraft/itematic/item/component/components/UseableOnFluidItemComponent.java +++ /dev/null @@ -1,43 +0,0 @@ -package net.errorcraft.itematic.item.component.components; - -import com.mojang.serialization.Codec; -import net.errorcraft.itematic.item.ItemStackConsumer; -import net.errorcraft.itematic.item.component.ItemComponent; -import net.errorcraft.itematic.item.component.ItemComponentType; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.mixin.item.ItemAccessor; -import net.minecraft.entity.player.PlayerEntity; -import net.minecraft.item.ItemStack; -import net.minecraft.item.ItemUsageContext; -import net.minecraft.util.ActionResult; -import net.minecraft.util.Hand; -import net.minecraft.util.hit.BlockHitResult; -import net.minecraft.util.hit.HitResult; -import net.minecraft.world.RaycastContext; -import net.minecraft.world.World; - -public record UseableOnFluidItemComponent() implements ItemComponent { - public static final UseableOnFluidItemComponent INSTANCE = new UseableOnFluidItemComponent(); - public static final Codec CODEC = Codec.unit(INSTANCE); - - @Override - public ItemComponentType type() { - return ItemComponentTypes.USEABLE_ON_FLUID; - } - - @Override - public Codec codec() { - return CODEC; - } - - @Override - public ActionResult use(World world, PlayerEntity user, Hand hand, ItemStack stack, ItemStackConsumer resultStackConsumer) { - BlockHitResult blockHitResult = ItemAccessor.raycast(world, user, RaycastContext.FluidHandling.SOURCE_ONLY); - if (blockHitResult.getType() != HitResult.Type.BLOCK) { - return ActionResult.PASS; - } - - ItemUsageContext itemUsageContext = new ItemUsageContext(world, user, hand, stack, blockHitResult); - return stack.useOnBlock(itemUsageContext); - } -} diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/WeaponItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/WeaponItemComponent.java index 966a008e..61bf0d91 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/WeaponItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/WeaponItemComponent.java @@ -37,10 +37,10 @@ public record WeaponItemComponent(int damagePerHit, WeaponAttackDamageDataCompon ).apply(instance, WeaponItemComponent::new)); private static final MaceItem DUMMY = new MaceItem(new Item.Settings()); - public static WeaponItemComponent of(int damagePerHit, double attackDamage, double attackSpeed, WeaponAttackDamageDataComponent.Rule... rules) { + public static WeaponItemComponent of(int damagePerHit, double attackDamage, double attackSpeed) { return new WeaponItemComponent( damagePerHit, - new WeaponAttackDamageDataComponent(List.of(rules), attackDamage), + new WeaponAttackDamageDataComponent(List.of(), attackDamage), attackSpeed, false ); diff --git a/src/main/java/net/errorcraft/itematic/item/component/components/ZoomItemComponent.java b/src/main/java/net/errorcraft/itematic/item/component/components/ZoomItemComponent.java index dc19399f..668513c1 100644 --- a/src/main/java/net/errorcraft/itematic/item/component/components/ZoomItemComponent.java +++ b/src/main/java/net/errorcraft/itematic/item/component/components/ZoomItemComponent.java @@ -46,8 +46,9 @@ public ActionResult use(World world, PlayerEntity user, Hand hand, ItemStack sta } @Override - public void stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { + public boolean stopUsing(ItemStack stack, World world, LivingEntity user, int usedTicks, int remainingUseTicks, ItemStackConsumer resultStackConsumer) { this.playStopSound(user); + return true; } @Override diff --git a/src/main/java/net/errorcraft/itematic/item/event/ItemEventKeys.java b/src/main/java/net/errorcraft/itematic/item/event/ItemEventKeys.java index c28fd3e3..dd51574d 100644 --- a/src/main/java/net/errorcraft/itematic/item/event/ItemEventKeys.java +++ b/src/main/java/net/errorcraft/itematic/item/event/ItemEventKeys.java @@ -22,6 +22,7 @@ public class ItemEventKeys { public static final RegistryKey EQUIP_ITEM = of("equip_item"); public static final RegistryKey CONSUME_ITEM = of("consume_item"); public static final RegistryKey THROW_PROJECTILE = of("throw_projectile"); + public static final RegistryKey BEFORE_DEATH_HOLDER = of("before_death_holder"); private ItemEventKeys() {} diff --git a/src/main/java/net/errorcraft/itematic/item/event/ItemEventMap.java b/src/main/java/net/errorcraft/itematic/item/event/ItemEventMap.java index b3e74424..29cd7d60 100644 --- a/src/main/java/net/errorcraft/itematic/item/event/ItemEventMap.java +++ b/src/main/java/net/errorcraft/itematic/item/event/ItemEventMap.java @@ -39,6 +39,10 @@ public boolean invokeEvent(ItemEvent event, ActionContext context) { .orElse(false); } + public boolean hasListener(ItemEvent event) { + return this.events.containsKey(event); + } + public static class Builder { private final Map> events = new HashMap<>(); diff --git a/src/main/java/net/errorcraft/itematic/item/event/ItemEvents.java b/src/main/java/net/errorcraft/itematic/item/event/ItemEvents.java index 6582f5db..19d87e15 100644 --- a/src/main/java/net/errorcraft/itematic/item/event/ItemEvents.java +++ b/src/main/java/net/errorcraft/itematic/item/event/ItemEvents.java @@ -22,6 +22,7 @@ public class ItemEvents { public static final ItemEvent EQUIP_ITEM = register(ItemEventKeys.EQUIP_ITEM); public static final ItemEvent CONSUME_ITEM = register(ItemEventKeys.CONSUME_ITEM); public static final ItemEvent THROW_PROJECTILE = register(ItemEventKeys.THROW_PROJECTILE); + public static final ItemEvent BEFORE_DEATH_HOLDER = register(ItemEventKeys.BEFORE_DEATH_HOLDER); private ItemEvents() {} diff --git a/src/main/java/net/errorcraft/itematic/item/shooter/method/ShooterMethod.java b/src/main/java/net/errorcraft/itematic/item/shooter/method/ShooterMethod.java index 4e5bed3c..b833a5a4 100644 --- a/src/main/java/net/errorcraft/itematic/item/shooter/method/ShooterMethod.java +++ b/src/main/java/net/errorcraft/itematic/item/shooter/method/ShooterMethod.java @@ -21,7 +21,7 @@ public interface ShooterMethod { void addComponents(ComponentMap.Builder builder); boolean tryShoot(ShooterItemComponent component, ItemStack stack, World world, LivingEntity user, Hand hand); void hold(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks); - void stop(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks); + boolean stop(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks); default void initializeProjectile(LivingEntity user, ProjectileEntity projectile, int index, float power, float uncertainty, float angle, boolean critical, @Nullable LivingEntity target) { if (critical && projectile instanceof PersistentProjectileEntity persistentProjectile) { persistentProjectile.setCritical(true); diff --git a/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/ChargeableShooterMethod.java b/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/ChargeableShooterMethod.java index 90b75542..cac4d3f5 100644 --- a/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/ChargeableShooterMethod.java +++ b/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/ChargeableShooterMethod.java @@ -110,18 +110,19 @@ public void hold(ShooterItemComponent shooter, ItemStack stack, World world, Liv } @Override - public void stop(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks) { + public boolean stop(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks) { if (usedTicks < CrossbowItem.getPullTime(stack, user)) { - return; + return false; } if (CrossbowItem.isCharged(stack) || !chargeProjectiles(user, stack)) { - return; + return false; } CrossbowItem.LoadingSounds chargingSounds = this.chargingSounds(stack); float pitch = MathHelper.lerp(world.getRandom().nextFloat(), 0.87f, 1.2f); chargingSounds.end().ifPresent(sound -> world.playSound(null, user.getX(), user.getY(), user.getZ(), sound.value(), user.getSoundCategory(), 1.0f, pitch)); + return true; } @Override diff --git a/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/DirectShooterMethod.java b/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/DirectShooterMethod.java index 90b98098..3e4afc29 100644 --- a/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/DirectShooterMethod.java +++ b/src/main/java/net/errorcraft/itematic/item/shooter/method/methods/DirectShooterMethod.java @@ -60,15 +60,15 @@ public boolean tryShoot(ShooterItemComponent component, ItemStack stack, World w public void hold(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks) {} @Override - public void stop(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks) { + public boolean stop(ShooterItemComponent shooter, ItemStack stack, World world, LivingEntity user, int usedTicks) { ItemStack ammunition = user.itematic$getAmmunition(stack); if (ammunition.isEmpty()) { - return; + return false; } float pullProgress = this.pullProgress(usedTicks); if (pullProgress < 0.1f) { - return; + return false; } List projectiles = RangedWeaponItemAccessor.load(stack, ammunition, user); @@ -84,6 +84,8 @@ public void stop(ShooterItemComponent shooter, ItemStack stack, World world, Liv if (user instanceof PlayerEntity playerEntity) { playerEntity.incrementStat(Stats.USED.itematic$getOrCreateStat(stack.getRegistryEntry())); } + + return true; } @Override diff --git a/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypeKeys.java b/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypeKeys.java index 126335a4..6c76524e 100644 --- a/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypeKeys.java +++ b/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypeKeys.java @@ -10,6 +10,7 @@ public class IntegerProviderTypeKeys { public static final RegistryKey> SHOOTER = of("shooter"); public static final RegistryKey> TRIDENT = of("trident"); public static final RegistryKey> CONDITION = of("condition"); + public static final RegistryKey> INDEFINITE = of("indefinite"); private IntegerProviderTypeKeys() {} diff --git a/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypes.java b/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypes.java index 0258bd8c..9fc81498 100644 --- a/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypes.java +++ b/src/main/java/net/errorcraft/itematic/item/use/provider/IntegerProviderTypes.java @@ -11,6 +11,7 @@ public class IntegerProviderTypes { public static final IntegerProviderType SHOOTER = register(IntegerProviderTypeKeys.SHOOTER, new IntegerProviderType<>(ShooterIntegerProvider.CODEC, ShooterIntegerProvider.PACKET_CODEC)); public static final IntegerProviderType TRIDENT = register(IntegerProviderTypeKeys.TRIDENT, new IntegerProviderType<>(TridentIntegerProvider.CODEC, TridentIntegerProvider.PACKET_CODEC)); public static final IntegerProviderType CONDITION = register(IntegerProviderTypeKeys.CONDITION, new IntegerProviderType<>(ConditionIntegerProvider.CODEC, ConditionIntegerProvider.PACKET_CODEC)); + public static final IntegerProviderType INDEFINITE = register(IntegerProviderTypeKeys.INDEFINITE, new IntegerProviderType<>(IndefiniteIntegerProvider.CODEC, IndefiniteIntegerProvider.PACKET_CODEC)); private IntegerProviderTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/item/use/provider/providers/IndefiniteIntegerProvider.java b/src/main/java/net/errorcraft/itematic/item/use/provider/providers/IndefiniteIntegerProvider.java new file mode 100644 index 00000000..9175b949 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/item/use/provider/providers/IndefiniteIntegerProvider.java @@ -0,0 +1,31 @@ +package net.errorcraft.itematic.item.use.provider.providers; + +import com.mojang.serialization.MapCodec; +import io.netty.buffer.ByteBuf; +import net.errorcraft.itematic.component.type.UseDurationDataComponent; +import net.errorcraft.itematic.item.use.provider.IntegerProvider; +import net.errorcraft.itematic.item.use.provider.IntegerProviderType; +import net.errorcraft.itematic.item.use.provider.IntegerProviderTypes; +import net.minecraft.entity.LivingEntity; +import net.minecraft.item.ItemStack; +import net.minecraft.network.codec.PacketCodec; + +import java.util.OptionalInt; + +public class IndefiniteIntegerProvider implements IntegerProvider { + public static final IndefiniteIntegerProvider INSTANCE = new IndefiniteIntegerProvider(); + public static final MapCodec CODEC = MapCodec.unit(INSTANCE); + public static final PacketCodec PACKET_CODEC = PacketCodec.unit(INSTANCE); + + private IndefiniteIntegerProvider() {} + + @Override + public IntegerProviderType type() { + return IntegerProviderTypes.INDEFINITE; + } + + @Override + public OptionalInt get(ItemStack stack, LivingEntity user) { + return OptionalInt.of(UseDurationDataComponent.INDEFINITE_USE_DURATION); + } +} diff --git a/src/main/java/net/errorcraft/itematic/loot/predicate/SideCheckPredicate.java b/src/main/java/net/errorcraft/itematic/loot/predicate/SideCheckPredicate.java index 61267334..7bcd7432 100644 --- a/src/main/java/net/errorcraft/itematic/loot/predicate/SideCheckPredicate.java +++ b/src/main/java/net/errorcraft/itematic/loot/predicate/SideCheckPredicate.java @@ -3,7 +3,7 @@ import com.mojang.serialization.MapCodec; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.loot.context.ItematicLootContextParameters; -import net.errorcraft.itematic.serialization.ItematicCodecs; +import net.errorcraft.itematic.serialization.SetCodec; import net.minecraft.loot.condition.LootCondition; import net.minecraft.loot.condition.LootConditionType; import net.minecraft.loot.context.LootContext; @@ -13,7 +13,7 @@ public record SideCheckPredicate(Set sides) implements LootCondition { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ItematicCodecs.setCodec(Direction.CODEC).fieldOf("sides").forGetter(SideCheckPredicate::sides) + SetCodec.forEnum(Direction.CODEC).fieldOf("sides").forGetter(SideCheckPredicate::sides) ).apply(instance, SideCheckPredicate::new)); @Override diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/entity/AbstractFurnaceBlockEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/entity/AbstractFurnaceBlockEntityExtender.java index 86f91b5e..edfbe1e9 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/entity/AbstractFurnaceBlockEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/entity/AbstractFurnaceBlockEntityExtender.java @@ -4,7 +4,6 @@ import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.component.components.FuelItemComponent; -import net.errorcraft.itematic.item.component.components.RecipeRemainderItemComponent; import net.minecraft.block.entity.AbstractFurnaceBlockEntity; import net.minecraft.item.Item; import net.minecraft.item.ItemConvertible; @@ -146,9 +145,9 @@ private boolean isValidIsOfForBucketUseRegistryKeyCheck(ItemStack instance, Item ) @SuppressWarnings("unchecked") private static E setRemainderItemStackUseItemComponent(E element, @Local(ordinal = 0) Item item) { - return (E) item.itematic$getComponent(ItemComponentTypes.RECIPE_REMAINDER) - .map(RecipeRemainderItemComponent::item) - .map(ItemStack::new) + return (E) item.itematic$getComponent(ItemComponentTypes.FUEL) + .flatMap(FuelItemComponent::remainder) + .map(ItemStack::copy) .orElse(ItemStack.EMPTY); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/block/entity/BrewingStandBlockEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/block/entity/BrewingStandBlockEntityExtender.java index cf071736..d159eae1 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/block/entity/BrewingStandBlockEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/block/entity/BrewingStandBlockEntityExtender.java @@ -1,23 +1,162 @@ package net.errorcraft.itematic.mixin.block.entity; +import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.sugar.Local; +import net.errorcraft.itematic.access.block.entity.BrewingStandBlockEntityAccess; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.RecipeRemainderItemComponent; +import net.errorcraft.itematic.recipe.ItematicRecipeTypes; +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.errorcraft.itematic.recipe.input.BrewingRecipeInput; +import net.errorcraft.itematic.screen.BrewingStandMenuDelegate; +import net.minecraft.block.BlockState; +import net.minecraft.block.entity.BlockEntityType; import net.minecraft.block.entity.BrewingStandBlockEntity; +import net.minecraft.block.entity.LockableContainerBlockEntity; import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; -import net.minecraft.recipe.BrewingRecipeRegistry; +import net.minecraft.recipe.*; +import net.minecraft.screen.BrewingStandScreenHandler; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.server.world.ServerWorld; +import net.minecraft.util.ItemScatterer; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.math.BlockPos; import net.minecraft.world.World; +import net.minecraft.world.WorldEvents; import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.Slice; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.Unique; +import org.spongepowered.asm.mixin.injection.*; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; +import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; + +import java.util.Optional; @Mixin(BrewingStandBlockEntity.class) -public class BrewingStandBlockEntityExtender { +public abstract class BrewingStandBlockEntityExtender extends LockableContainerBlockEntity implements RecipeInputProvider, BrewingStandBlockEntityAccess { + @Shadow + @Final + private static int INPUT_SLOT_INDEX; + + @Shadow + private DefaultedList inventory; + + @Unique + private final RecipeManager.MatchGetter> matcher = RecipeManager.createCachedMatchGetter(ItematicRecipeTypes.BREWING); + + @Unique + private int maxBrewingTime; + + protected BrewingStandBlockEntityExtender(BlockEntityType blockEntityType, BlockPos blockPos, BlockState blockState) { + super(blockEntityType, blockPos, blockState); + } + + @Redirect( + method = "tick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/BrewingStandBlockEntity;canCraft(Lnet/minecraft/recipe/BrewingRecipeRegistry;Lnet/minecraft/util/collection/DefaultedList;)Z" + ) + ) + @SuppressWarnings("DataFlowIssue") + private static boolean useRecipe(BrewingRecipeRegistry brewingRecipeRegistry, DefaultedList slots, World world, @Local(argsOnly = true) BrewingStandBlockEntity blockEntity) { + BrewingStandBlockEntityExtender blockEntityExtender = (BrewingStandBlockEntityExtender)(Object) blockEntity; + if (!blockEntityExtender.acceptsRecipes()) { + return false; + } + + if (!(world instanceof ServerWorld serverWorld)) { + return false; + } + + ItemStack reagent = slots.get(INPUT_SLOT_INDEX); + for (int i = 0; i < 3; i++) { + ItemStack base = slots.get(i); + BrewingRecipeInput input = new BrewingRecipeInput(base, reagent); + if (blockEntityExtender.matcher.getFirstMatch(input, serverWorld).isPresent()) { + return true; + } + } + + return false; + } + + @Redirect( + method = "tick", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/block/entity/BrewingStandBlockEntity;craft(Lnet/minecraft/world/World;Lnet/minecraft/util/math/BlockPos;Lnet/minecraft/util/collection/DefaultedList;)V" + ) + ) + @SuppressWarnings("DataFlowIssue") + private static void useRecipe(World world, BlockPos pos, DefaultedList slots, @Local(argsOnly = true) BrewingStandBlockEntity blockEntity) { + if (!(world instanceof ServerWorld serverWorld)) { + return; + } + + BrewingStandBlockEntityExtender blockEntityExtender = (BrewingStandBlockEntityExtender)(Object) blockEntity; + BrewingRecipe recipe = null; + ItemStack reagent = slots.get(INPUT_SLOT_INDEX); + for (int i = 0; i < 3; i++) { + BrewingRecipeInput input = new BrewingRecipeInput(slots.get(i), reagent); + if (recipe != null && recipe.matches(input, world)) { + ItemStack result = recipe.craft(input, world.getRegistryManager()); + slots.set(i, result); + continue; + } + + Optional>> optionalRecipe = blockEntityExtender.matcher.getFirstMatch(input, serverWorld); + if (optionalRecipe.isPresent()) { + recipe = optionalRecipe.get().value(); + ItemStack result = recipe.craft(input, world.getRegistryManager()); + slots.set(i, result); + } + } + + reagent.decrement(1); + if (recipe != null) { + recipe.reagentRemainder().ifPresent(remainder -> { + if (reagent.isEmpty()) { + slots.set(INPUT_SLOT_INDEX, remainder); + } else { + ItemScatterer.spawn(world, pos.getX(), pos.getY(), pos.getZ(), remainder); + } + }); + } + + world.syncWorldEvent(WorldEvents.BREWING_STAND_BREWS, pos, 0); + } + + @ModifyConstant( + method = "tick", + constant = @Constant( + intValue = 400 + ) + ) + @SuppressWarnings("DataFlowIssue") + private static int useRecipeForBrewingTime(int original, World world, @Local(argsOnly = true) BrewingStandBlockEntity blockEntity) { + if (world instanceof ServerWorld serverWorld) { + BrewingStandBlockEntityExtender blockEntityExtender = (BrewingStandBlockEntityExtender)(Object) blockEntity; + return blockEntityExtender.maxBrewingTime = blockEntityExtender.brewTime(serverWorld); + } + + return BrewingRecipe.DEFAULT_BREWING_TIME; + } + + @Redirect( + method = "isValid", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/recipe/BrewingRecipeRegistry;isValidIngredient(Lnet/minecraft/item/ItemStack;)Z" + ) + ) + private boolean acceptAllItemsForInput(BrewingRecipeRegistry instance, ItemStack stack) { + return true; + } + @Redirect( method = "isValid", at = @At( @@ -73,7 +212,10 @@ private boolean isOfRemainingItemChecksReturnFalse(ItemStack instance, Item item } @Redirect( - method = { "isValid", "canExtract" }, + method = { + "isValid", + "canExtract" + }, at = @At( value = "INVOKE", target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z", @@ -91,17 +233,6 @@ private boolean isOfForGlassBottleUseRegistryKeyCheck(ItemStack instance, Item i return instance.itematic$isOf(ItemKeys.GLASS_BOTTLE); } - @Redirect( - method = "craft", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/recipe/BrewingRecipeRegistry;craft(Lnet/minecraft/item/ItemStack;Lnet/minecraft/item/ItemStack;)Lnet/minecraft/item/ItemStack;" - ) - ) - private static ItemStack craftUseDynamicRegistryManager(BrewingRecipeRegistry instance, ItemStack ingredient, ItemStack input, World world) { - return instance.itematic$craft(ingredient, input, world); - } - @Redirect( method = "tick", at = @At( @@ -114,17 +245,100 @@ private static boolean isOfForBlazePowderUseRegistryKeyCheckStatic(ItemStack ins return instance.itematic$isOf(ItemKeys.BLAZE_POWDER); } - @Redirect( - method = "craft", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) + @ModifyReturnValue( + method = "createScreenHandler", + at = @At("TAIL") ) - private static ItemStack newItemStackForRemainderUseItemComponent(ItemConvertible item, @Local ItemStack stack) { - return stack.itematic$getComponent(ItemComponentTypes.RECIPE_REMAINDER) - .map(RecipeRemainderItemComponent::item) - .map(ItemStack::new) - .orElse(ItemStack.EMPTY); + private ScreenHandler useDelegate(ScreenHandler original) { + return new BrewingStandMenuDelegate((BrewingStandScreenHandler) original, this.getWorld()); + } + + @Override + public void provideRecipeInputs(RecipeMatcher finder) { + finder.addInput(this.inventory.get(INPUT_SLOT_INDEX)); + for (int i = 0; i < 3; i++) { + finder.addInput(this.inventory.get(i)); + } + } + + @Override + public int itematic$maxBrewingTime() { + return this.maxBrewingTime; + } + + @Override + public void itematic$setMaxBrewingTime(int maxBrewingTime) { + this.maxBrewingTime = maxBrewingTime; + } + + @Unique + private boolean acceptsRecipes() { + ItemStack reagent = this.inventory.get(INPUT_SLOT_INDEX); + if (reagent.isEmpty()) { + return false; + } + + for (int i = 0; i < 3; i++) { + if (!this.inventory.get(i).isEmpty()) { + return true; + } + } + + return false; + } + + @Unique + private int brewTime(ServerWorld world) { + ItemStack reagent = this.inventory.get(INPUT_SLOT_INDEX); + for (int i = 0; i < 3; i++) { + BrewingRecipeInput input = new BrewingRecipeInput(this.inventory.get(i), reagent); + Optional>> optionalRecipe = this.matcher.getFirstMatch(input, world); + if (optionalRecipe.isPresent()) { + return optionalRecipe.get() + .value() + .brewingTime(); + } + } + + return BrewingRecipe.DEFAULT_BREWING_TIME; + } + + @Mixin(targets = "net/minecraft/block/entity/BrewingStandBlockEntity$1") + public static class PropertyDelegateExtender { + @Shadow + @Final + BrewingStandBlockEntity field_17382; + + @Inject( + method = "set", + at = @At("HEAD"), + cancellable = true + ) + private void setMaxFuelTimeProperty(int index, int value, CallbackInfo info) { + if (index == 2) { + ((BrewingStandBlockEntityAccess) this.field_17382).itematic$setMaxBrewingTime(value); + info.cancel(); + } + } + + @Inject( + method = "get", + at = @At("HEAD"), + cancellable = true + ) + private void getMaxFuelTimeProperty(int index, CallbackInfoReturnable info) { + if (index == 2) { + int maxBrewingTime = ((BrewingStandBlockEntityAccess) this.field_17382).itematic$maxBrewingTime(); + info.setReturnValue(maxBrewingTime); + } + } + + @ModifyReturnValue( + method = "size", + at = @At("TAIL") + ) + private int addMaxFuelTimeProperty(int original) { + return original + 1; + } } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/component/type/FoodComponentExtender.java b/src/main/java/net/errorcraft/itematic/mixin/component/type/FoodComponentExtender.java index a0515fdf..ae90bb9a 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/component/type/FoodComponentExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/component/type/FoodComponentExtender.java @@ -1,13 +1,45 @@ package net.errorcraft.itematic.mixin.component.type; +import com.mojang.datafixers.kinds.App; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.minecraft.component.type.FoodComponent; import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; +import net.minecraft.util.dynamic.Codecs; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Unique; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; +import java.util.List; +import java.util.Optional; +import java.util.function.Function; + +@Mixin(FoodComponent.class) public class FoodComponentExtender { + @ModifyArg( + method = "", + at = @At( + value = "INVOKE", + target = "Lcom/mojang/serialization/codecs/RecordCodecBuilder;create(Ljava/util/function/Function;)Lcom/mojang/serialization/Codec;", + remap = false + ) + ) + private static Function, ? extends App, FoodComponent>> removeUnusedFields(Function, ? extends App, FoodComponent>> builder) { + return instance -> instance.group( + Codecs.NONNEGATIVE_INT.fieldOf("nutrition").forGetter(FoodComponent::nutrition), + Codec.FLOAT.fieldOf("saturation").forGetter(FoodComponent::saturation), + Codec.BOOL.optionalFieldOf("can_always_eat", false).forGetter(FoodComponent::canAlwaysEat) + ).apply(instance, (FoodComponentExtender::create)); + } + + @Unique + private static FoodComponent create(int nutrition, float saturation, boolean alwaysEdible) { + return new FoodComponent(nutrition, saturation, alwaysEdible, 1.0f, Optional.empty(), List.of()); + } + @Mixin(FoodComponent.Builder.class) public static class BuilderExtender { @Redirect( diff --git a/src/main/java/net/errorcraft/itematic/mixin/data/server/recipe/RecipeProviderExtender.java b/src/main/java/net/errorcraft/itematic/mixin/data/server/recipe/RecipeProviderExtender.java new file mode 100644 index 00000000..5c059d9a --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/data/server/recipe/RecipeProviderExtender.java @@ -0,0 +1,33 @@ +package net.errorcraft.itematic.mixin.data.server.recipe; + +import com.llamalad7.mixinextras.sugar.Local; +import net.errorcraft.itematic.access.data.server.recipe.RecipeProviderAccess; +import net.minecraft.data.server.recipe.RecipeExporter; +import net.minecraft.data.server.recipe.RecipeProvider; +import net.minecraft.registry.RegistryWrapper; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; + +@Mixin(RecipeProvider.class) +public abstract class RecipeProviderExtender implements RecipeProviderAccess { + @Shadow + public abstract void generate(RecipeExporter exporter); + + @Redirect( + method = "run(Lnet/minecraft/data/DataWriter;Lnet/minecraft/registry/RegistryWrapper$WrapperLookup;)Ljava/util/concurrent/CompletableFuture;", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/data/server/recipe/RecipeProvider;generate(Lnet/minecraft/data/server/recipe/RecipeExporter;)V" + ) + ) + private void passRegistryLookup(RecipeProvider instance, RecipeExporter exporter, @Local(argsOnly = true) RegistryWrapper.WrapperLookup lookup) { + this.itematic$generate(lookup, exporter); + } + + @Override + public void itematic$generate(RegistryWrapper.WrapperLookup wrapperLookup, RecipeExporter exporter) { + this.generate(exporter); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/LivingEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/LivingEntityExtender.java index 51597db8..23ff85d8 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/LivingEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/LivingEntityExtender.java @@ -13,7 +13,6 @@ import net.errorcraft.itematic.item.ItemStackConsumer; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.component.components.ConsumableItemComponent; -import net.errorcraft.itematic.item.component.components.LifeSavingItemComponent; import net.errorcraft.itematic.item.event.ItemEvents; import net.errorcraft.itematic.world.action.context.ActionContext; import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; @@ -24,7 +23,6 @@ import net.minecraft.entity.attribute.AttributeContainer; import net.minecraft.entity.attribute.EntityAttribute; import net.minecraft.entity.attribute.EntityAttributes; -import net.minecraft.entity.damage.DamageSource; import net.minecraft.entity.data.TrackedData; import net.minecraft.entity.effect.StatusEffectInstance; import net.minecraft.item.Equipment; @@ -49,7 +47,6 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.Optional; import java.util.function.Predicate; @Mixin(LivingEntity.class) @@ -237,10 +234,8 @@ private boolean isOfForDragonHeadUseRegistryKeyCheck(ItemStack instance, Item it target = "Lnet/minecraft/item/ItemStack;isOf(Lnet/minecraft/item/Item;)Z" ) ) - private boolean isOfForTotemOfUndyingUseItemComponent(ItemStack instance, Item item, @Share("lifeSavingItemComponent") LocalRef lifeSavingItemComponent) { - Optional optionalComponent = instance.itematic$getComponent(ItemComponentTypes.LIFE_SAVING); - optionalComponent.ifPresent(lifeSavingItemComponent::set); - return optionalComponent.isPresent(); + private boolean isOfForTotemOfUndyingUseEventListenerCheck(ItemStack instance, Item item) { + return instance.itematic$hasEventListener(ItemEvents.BEFORE_DEATH_HOLDER); } @Redirect( @@ -254,16 +249,23 @@ private Stat getOrCreateStatUseRegistryEntry(StatType instance, return instance.itematic$getOrCreateStat(stack.getRegistryEntry()); } - @Inject( + @Redirect( method = "tryUseTotem", at = @At( value = "INVOKE", - target = "Lnet/minecraft/entity/LivingEntity;clearStatusEffects()Z", - shift = At.Shift.AFTER + target = "Lnet/minecraft/entity/LivingEntity;clearStatusEffects()Z" ) ) - private void addEffectsFromLifeSavingItemComponent(DamageSource source, CallbackInfoReturnable info, @Share("lifeSavingItemComponent") LocalRef lifeSavingItemComponent) { - lifeSavingItemComponent.get().apply((LivingEntity)(Object) this); + private boolean addEffectsFromLifeSavingItemComponent(LivingEntity instance, @Local(ordinal = 0) ItemStack stack) { + if (!(this.getWorld() instanceof ServerWorld serverWorld)) { + return false; + } + + ActionContext context = ActionContext.builder(serverWorld) + .entityPosition(ActionContextParameter.THIS, this) + .stack(stack) + .build(); + return stack.itematic$invokeEvent(ItemEvents.BEFORE_DEATH_HOLDER, context); } @Redirect( diff --git a/src/main/java/net/errorcraft/itematic/mixin/entity/player/ServerPlayerEntityExtender.java b/src/main/java/net/errorcraft/itematic/mixin/entity/player/ServerPlayerEntityExtender.java index 7aef5d48..b3845789 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/entity/player/ServerPlayerEntityExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/entity/player/ServerPlayerEntityExtender.java @@ -2,6 +2,7 @@ import com.llamalad7.mixinextras.sugar.Local; import com.mojang.authlib.GameProfile; +import net.errorcraft.itematic.access.entity.LivingEntityAccess; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.minecraft.entity.player.PlayerEntity; import net.minecraft.item.Item; @@ -23,7 +24,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; @Mixin(ServerPlayerEntity.class) -public abstract class ServerPlayerEntityExtender extends PlayerEntity { +public abstract class ServerPlayerEntityExtender extends PlayerEntity implements LivingEntityAccess { public ServerPlayerEntityExtender(World world, BlockPos pos, float yaw, GameProfile gameProfile) { super(world, pos, yaw, gameProfile); } @@ -111,4 +112,11 @@ private Stat getOrCreateStatUseRegistryEntry(StatType instance, .getEntry((Item) key); return instance.itematic$getOrCreateStat(itemEntry); } + + @Override + public void itematic$addOrDropStack(ItemStack stack) { + if (!this.getInventory().insertStack(stack)) { + this.dropStack(stack); + } + } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/ItemExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/ItemExtender.java index 43e116db..06b4b425 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/ItemExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/ItemExtender.java @@ -11,7 +11,10 @@ import net.errorcraft.itematic.item.component.ItemComponentSet; import net.errorcraft.itematic.item.component.ItemComponentType; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.*; +import net.errorcraft.itematic.item.component.components.BlockItemComponent; +import net.errorcraft.itematic.item.component.components.DamageableItemComponent; +import net.errorcraft.itematic.item.component.components.EnchantableItemComponent; +import net.errorcraft.itematic.item.component.components.RepairableItemComponent; import net.errorcraft.itematic.item.event.ItemEvent; import net.errorcraft.itematic.item.event.ItemEventMap; import net.errorcraft.itematic.item.event.ItemEvents; @@ -69,6 +72,8 @@ public abstract class ItemExtender implements ItemAccess, FabricItem { @Unique private ItemBase base; @Unique + private AttributeModifiersComponent attributeModifiers; + @Unique private ItemComponentSet itemComponents; @Unique private ItemEventMap events; @@ -90,7 +95,8 @@ private void checkStackableItemComponent(CallbackInfoReturnable info) { cancellable = true ) public void useUseItemComponent(World world, PlayerEntity user, Hand hand, CallbackInfoReturnable> info) { - ItemStack stack = user.getStackInHand(hand); + ItemStack stack = user.getStackInHand(hand).copy(); + ItemStack stackBeforeUsing = stack.copy(); StackReference stackReference = StackReferenceUtil.of(stack); ActionResult result = ActionResult.PASS; for (ItemComponent component : this.itemComponents) { @@ -108,6 +114,12 @@ public void useUseItemComponent(World world, PlayerEntity user, Hand hand, Callb .build(); this.itematic$invokeEvent(ItemEvents.USE, context); } + + if (stack.getMaxUseTime(user) <= 0 && result.isAccepted()) { + ItemStack remainder = stackReference.get().itematic$applyUseEffects(user, stackBeforeUsing); + stackReference.set(remainder); + } + info.setReturnValue(new TypedActionResult<>(result, stackReference.get())); } @@ -246,10 +258,12 @@ private void onItemEntityDestroyedUseItemComponent(ItemEntity entity, CallbackIn */ @Overwrite public void onStoppedUsing(ItemStack stack, World world, LivingEntity user, int remainingUseTicks) { + ItemStack stackBeforeUsing = stack.copy(); + boolean result = false; int usedTicks = user.itematic$itemUsedTicks(); StackReference stackReference = StackReferenceUtil.of(stack); for (ItemComponent component : this.itemComponents) { - component.stopUsing(stack, world, user, usedTicks, remainingUseTicks, stackReference::set); + result |= component.stopUsing(stack, world, user, usedTicks, remainingUseTicks, stackReference::set); } if (world instanceof ServerWorld serverWorld) { @@ -259,6 +273,10 @@ public void onStoppedUsing(ItemStack stack, World world, LivingEntity user, int this.itematic$invokeEvent(ItemEvents.STOPPED_USING, context); } + if (result) { + stackReference.set(stackReference.get().itematic$applyUseEffects(user, stackBeforeUsing)); + } + tryUpdateItemStack(user, Hand.MAIN_HAND, stack, stackReference); } @@ -268,6 +286,7 @@ public void onStoppedUsing(ItemStack stack, World world, LivingEntity user, int cancellable = true ) public void finishUsingUseItemComponent(ItemStack stack, World world, LivingEntity user, CallbackInfoReturnable info) { + ItemStack stackBeforeUsing = stack.copy(); int usedTicks = user.itematic$itemUsedTicks(); StackReference stackReference = StackReferenceUtil.of(stack); for (ItemComponent component : this.itemComponents) { @@ -283,6 +302,7 @@ public void finishUsingUseItemComponent(ItemStack stack, World world, LivingEnti this.itematic$getComponent(ItemComponentTypes.CONSUMABLE) .ifPresent(c -> c.consume(user, stack, stackReference::set, world, user.getActiveHand())); + stackReference.set(stackReference.get().itematic$applyUseEffects(user, stackBeforeUsing)); info.setReturnValue(stackReference.get()); } @@ -426,15 +446,6 @@ public void checkPointableItemComponent(ItemStack stack, CallbackInfoReturnable< } } - /** - * @author ErrorCraft - * @reason Uses the ItemComponent implementation for data-driven items. - */ - @Overwrite - public boolean hasRecipeRemainder() { - return this.itematic$hasComponent(ItemComponentTypes.RECIPE_REMAINDER); - } - /** * @author ErrorCraft * @reason Uses the ItemComponent implementation for data-driven items. @@ -576,6 +587,16 @@ private void checkTextHolderItemComponent(ItemStack stack, CallbackInfoReturnabl this.base = base; } + @Override + public AttributeModifiersComponent itematic$attributeModifiers() { + return this.attributeModifiers; + } + + @Override + public void itematic$setAttributeModifiers(AttributeModifiersComponent attributeModifiers) { + this.attributeModifiers = attributeModifiers; + } + @Override public ItemComponentSet itematic$components() { return this.itemComponents; @@ -592,6 +613,7 @@ private void checkTextHolderItemComponent(ItemStack stack, CallbackInfoReturnabl if (this.itemComponents == null) { return false; } + return this.itemComponents.contains(type); } @@ -600,6 +622,7 @@ private void checkTextHolderItemComponent(ItemStack stack, CallbackInfoReturnabl if (this.itemComponents == null) { return Optional.empty(); } + return this.itemComponents.get(type); } @@ -619,19 +642,15 @@ private void checkTextHolderItemComponent(ItemStack stack, CallbackInfoReturnabl } @Override - public boolean itematic$mayStartUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { - return this.itematic$getComponent(ItemComponentTypes.FOOD) - .map(c -> c.mayStartUsing(user)) - .orElse(true); + public boolean itematic$hasEventListener(ItemEvent event) { + return this.events.hasListener(event); } @Override - public ItemStack getRecipeRemainder(ItemStack stack) { - // Use the ItemComponent implementation for data-driven items, so we don't get a NullPointerException - return this.itematic$getComponent(ItemComponentTypes.RECIPE_REMAINDER) - .map(RecipeRemainderItemComponent::item) - .map(ItemStack::new) - .orElse(ItemStack.EMPTY); + public boolean itematic$mayStartUsing(World world, PlayerEntity user, Hand hand, ItemStack stack) { + return this.itematic$getComponent(ItemComponentTypes.FOOD) + .map(c -> c.mayStartUsing(user, stack)) + .orElse(true); } @Override @@ -644,10 +663,12 @@ private static void tryUpdateItemStack(LivingEntity target, Hand hand, ItemStack if (target == null) { return; } + ItemStack newStack = stackReference.get(); if (stack == newStack) { return; } + target.setStackInHand(hand, newStack); } @@ -657,14 +678,21 @@ private ComponentMap initializeComponents() { .addAll(DataComponentTypes.DEFAULT_ITEM_COMPONENTS); this.base.addComponents(componentsBuilder); AttributeModifiersComponent.Builder attributeModifiersBuilder = AttributeModifiersComponent.builder(); + this.attributeModifiers.modifiers().forEach(entry -> attributeModifiersBuilder.add( + entry.attribute(), + entry.modifier(), + entry.slot() + )); for (ItemComponent component : this.itemComponents) { component.addComponents(componentsBuilder); component.addAttributeModifiers(attributeModifiersBuilder, this.itemComponents); } + AttributeModifiersComponent attributeModifiers = attributeModifiersBuilder.build(); if (!attributeModifiers.modifiers().isEmpty()) { componentsBuilder.add(DataComponentTypes.ATTRIBUTE_MODIFIERS, attributeModifiers); } + return COMPONENT_INTERNER.intern(componentsBuilder.build()); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java b/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java index 0f596ef0..72a72f9d 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/item/ItemStackExtender.java @@ -1,5 +1,6 @@ package net.errorcraft.itematic.mixin.item; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; import com.llamalad7.mixinextras.injector.ModifyReturnValue; import com.llamalad7.mixinextras.injector.v2.WrapWithCondition; import com.llamalad7.mixinextras.sugar.Local; @@ -8,6 +9,8 @@ import net.errorcraft.itematic.access.item.ItemStackAccess; import net.errorcraft.itematic.component.ItematicDataComponentTypes; import net.errorcraft.itematic.component.type.ImmuneToDamageComponent; +import net.errorcraft.itematic.component.type.UseCooldownDataComponent; +import net.errorcraft.itematic.component.type.UseRemainderDataComponent; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.ItemUtil; import net.errorcraft.itematic.item.ItematicItemTags; @@ -157,9 +160,7 @@ private void registryEntryConstructorSetFields(RegistryEntry entry, int co at = @At("TAIL") ) private void componentChangesConstructorSetFields(RegistryEntry item, int count, ComponentChanges changes, CallbackInfo info) { - this.entry = item; - this.components = ComponentMapImpl.create(item.value().getComponents(), changes); - item.value().postProcessComponents((ItemStack)(Object) this); + this.setFields(item, changes); } @Redirect( @@ -287,6 +288,17 @@ public RegistryEntry getRegistryEntry() { return this.entry; } + @ModifyExpressionValue( + method = "getItem", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/item/ItemStack;isEmpty()Z" + ) + ) + private boolean isEmptyCheckUnboundRegistryEntry(boolean original) { + return original || !this.entry.hasKeyAndValue(); + } + @Redirect( method = "getItem", at = @At( @@ -652,6 +664,17 @@ public String toString() { return this.count + " " + this.itematic$key().getValue().toString(); } + @Inject( + method = "hashCode", + at = @At("HEAD"), + cancellable = true + ) + private static void checkEmptyStack(ItemStack stack, CallbackInfoReturnable info) { + if (stack != null && (stack.isEmpty() || !stack.getRegistryEntry().hasKeyAndValue())) { + info.setReturnValue(0); + } + } + @Override public boolean canBeEnchantedWith(RegistryEntry enchantment, EnchantingContext context) { // Use the original implementation again @@ -724,6 +747,32 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan this.context = null; } + @Override + @SuppressWarnings("DataFlowIssue") + public ItemStack itematic$applyUseEffects(LivingEntity user, ItemStack stackBeforeUsing) { + if (!stackBeforeUsing.itematic$hasComponent(ItemComponentTypes.USEABLE)) { + return (ItemStack)(Object) this; + } + + UseRemainderDataComponent useRemainder = stackBeforeUsing.get(ItematicDataComponentTypes.USE_REMAINDER); + ItemStack trueRemainder = (ItemStack)(Object) this; + if (useRemainder != null) { + trueRemainder = useRemainder.convert( + (ItemStack)(Object) this, + stackBeforeUsing.getCount(), + user.isInCreativeMode(), + user::itematic$addOrDropStack + ); + } + + UseCooldownDataComponent useCooldown = stackBeforeUsing.get(ItematicDataComponentTypes.USE_COOLDOWN); + if (useCooldown != null) { + useCooldown.set(stackBeforeUsing, user); + } + + return trueRemainder; + } + @Override public > boolean itematic$hasComponent(ItemComponentType type) { return this.entry != null && this.entry.value().itematic$hasComponent(type); @@ -754,6 +803,15 @@ public boolean canBeEnchantedWith(RegistryEntry enchantment, Enchan return result; } + @Override + public boolean itematic$hasEventListener(ItemEvent event) { + if (this.entry == null) { + return false; + } + + return this.entry.value().itematic$hasEventListener(event); + } + @Override public boolean itematic$canMine(BlockState state, World world, BlockPos pos, PlayerEntity miner) { if (this.entry == null) { @@ -805,6 +863,17 @@ private void setFields(RegistryEntry entry) { } } + @Unique + private void setFields(RegistryEntry entry, ComponentChanges changes) { + this.entry = entry; + if (entry.hasKeyAndValue()) { + this.components = ComponentMapImpl.create(entry.value().getComponents(), changes); + entry.value().postProcessComponents((ItemStack)(Object) this); + } else { + this.components = new ComponentMapImpl(ComponentMap.EMPTY); + } + } + @Unique private void onItemBroken(Item item, Entity entity, ActionContext context) { if (entity instanceof LivingEntity livingEntity) { diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/BannerDuplicateRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/BannerDuplicateRecipeExtender.java index 41da2a34..c587626e 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/BannerDuplicateRecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/BannerDuplicateRecipeExtender.java @@ -5,10 +5,8 @@ import com.llamalad7.mixinextras.sugar.ref.LocalRef; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.errorcraft.itematic.item.component.components.BannerPatternHolderItemComponent; -import net.errorcraft.itematic.item.component.components.RecipeRemainderItemComponent; import net.minecraft.item.BannerItem; import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.recipe.BannerDuplicateRecipe; import net.minecraft.util.DyeColor; @@ -52,18 +50,4 @@ private Item castToBannerItemUseNull(Item instance) { private DyeColor getColorUseItemComponent(BannerItem instance, @Share("dyeColor") LocalRef dyeColor) { return dyeColor.get(); } - - @Redirect( - method = "getRemainder(Lnet/minecraft/recipe/input/CraftingRecipeInput;)Lnet/minecraft/util/collection/DefaultedList;", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack newItemStackForRemainderUseItemComponent(ItemConvertible item, @Local ItemStack stack) { - return stack.itematic$getComponent(ItemComponentTypes.RECIPE_REMAINDER) - .map(RecipeRemainderItemComponent::item) - .map(ItemStack::new) - .orElse(ItemStack.EMPTY); - } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java index b13b5393..98076f01 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/BookCloningRecipeExtender.java @@ -3,9 +3,7 @@ import com.llamalad7.mixinextras.sugar.Local; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.RecipeRemainderItemComponent; import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; import net.minecraft.item.ItemStack; import net.minecraft.item.WrittenBookItem; import net.minecraft.recipe.BookCloningRecipe; @@ -52,20 +50,6 @@ private boolean isOfForWritableBookUseRegistryKeyCheck(ItemStack instance, Item return instance.itematic$isOf(ItemKeys.WRITABLE_BOOK); } - @Redirect( - method = "getRemainder(Lnet/minecraft/recipe/input/CraftingRecipeInput;)Lnet/minecraft/util/collection/DefaultedList;", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack newItemStackForRemainderUseItemComponent(ItemConvertible item, @Local ItemStack stack) { - return stack.itematic$getComponent(ItemComponentTypes.RECIPE_REMAINDER) - .map(RecipeRemainderItemComponent::item) - .map(ItemStack::new) - .orElse(ItemStack.EMPTY); - } - @ModifyConstant( method = "getRemainder(Lnet/minecraft/recipe/input/CraftingRecipeInput;)Lnet/minecraft/util/collection/DefaultedList;", constant = @Constant( @@ -73,6 +57,6 @@ private ItemStack newItemStackForRemainderUseItemComponent(ItemConvertible item, ) ) private boolean instanceOfWrittenBookItemUseItemComponentCheck(Object reference, Class clazz, @Local ItemStack inputStack) { - return inputStack.itematic$hasComponent(ItemComponentTypes.RECIPE_REMAINDER); + return inputStack.itematic$hasComponent(ItemComponentTypes.TEXT_HOLDER); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/BrewingRecipeRegistryExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/BrewingRecipeRegistryExtender.java deleted file mode 100644 index 19359b5b..00000000 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/BrewingRecipeRegistryExtender.java +++ /dev/null @@ -1,304 +0,0 @@ -package net.errorcraft.itematic.mixin.recipe; - -import com.llamalad7.mixinextras.expression.Definition; -import com.llamalad7.mixinextras.expression.Expression; -import com.llamalad7.mixinextras.injector.ModifyReturnValue; -import com.llamalad7.mixinextras.sugar.Local; -import net.errorcraft.itematic.access.recipe.BrewingRecipeRegistryAccess; -import net.errorcraft.itematic.access.recipe.BrewingRecipeRegistryBuilderAccess; -import net.errorcraft.itematic.component.PotionContentsComponentUtil; -import net.errorcraft.itematic.item.ItemKeys; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.recipe.BrewingRecipe; -import net.minecraft.component.DataComponentTypes; -import net.minecraft.component.type.PotionContentsComponent; -import net.minecraft.item.Item; -import net.minecraft.item.ItemStack; -import net.minecraft.potion.Potion; -import net.minecraft.potion.Potions; -import net.minecraft.recipe.BrewingRecipeRegistry; -import net.minecraft.registry.RegistryKey; -import net.minecraft.registry.entry.RegistryEntry; -import net.minecraft.world.World; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Overwrite; -import org.spongepowered.asm.mixin.Unique; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Inject; -import org.spongepowered.asm.mixin.injection.Redirect; -import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; - -import java.util.ArrayList; -import java.util.List; -import java.util.Optional; - -@Mixin(BrewingRecipeRegistry.class) -public class BrewingRecipeRegistryExtender implements BrewingRecipeRegistryAccess { - @Unique - private List>> itemRecipes; - - @Unique - private List>> potionRecipes; - - /** - * @author ErrorCraft - * @reason Uses the ItemComponent implementation for data-driven items. - */ - @Overwrite - private boolean isPotionType(ItemStack stack) { - return stack.itematic$hasComponent(ItemComponentTypes.POTION_HOLDER); - } - - /** - * @author ErrorCraft - * @reason Uses item keys instead of direct items. - */ - @Overwrite - public boolean isItemRecipeIngredient(ItemStack stack) { - for (BrewingRecipe> recipe : this.itemRecipes) { - if (stack.itematic$isOf(recipe.ingredient())) { - return true; - } - } - - return false; - } - - /** - * @author ErrorCraft - * @reason Uses item keys instead of direct items. - */ - @Overwrite - public boolean hasItemRecipe(ItemStack input, ItemStack ingredient) { - for (BrewingRecipe> recipe : this.itemRecipes) { - if (input.itematic$isOf(recipe.input()) && ingredient.itematic$isOf(recipe.ingredient())) { - return true; - } - } - - return false; - } - - /** - * @author ErrorCraft - * @reason Uses item keys instead of direct items. - */ - @Overwrite - public boolean isPotionRecipeIngredient(ItemStack stack) { - for (BrewingRecipe> recipe : this.potionRecipes) { - if (stack.itematic$isOf(recipe.ingredient())) { - return true; - } - } - - return false; - } - - @Definition( - id = "iterator", - method = "Ljava/util/List;iterator()Ljava/util/Iterator;" - ) - @Expression("? = ?.iterator()") - @Inject( - method = "hasPotionRecipe", - at = @At( - value = "MIXINEXTRAS:EXPRESSION", - shift = At.Shift.AFTER - ), - cancellable = true - ) - @SuppressWarnings("OptionalGetWithoutIsPresent") - private void hasPotionRecipeUseItemKeys(ItemStack input, ItemStack ingredient, CallbackInfoReturnable info, @Local Optional> optional) { - RegistryEntry potion = optional.get(); - for (BrewingRecipe> recipe : this.potionRecipes) { - if (recipe.input() == potion && ingredient.itematic$isOf(recipe.ingredient())) { - info.setReturnValue(true); - return; - } - } - - info.setReturnValue(false); - } - - /** - * @author ErrorCraft - * @reason Uses item keys instead of direct items. - */ - @Overwrite - public boolean isBrewable(RegistryEntry potion) { - for (BrewingRecipe> recipe : this.potionRecipes) { - if (recipe.output() == potion) { - return true; - } - } - - return false; - } - - @Redirect( - method = "create", - at = @At( - value = "INVOKE", - target = "Lnet/minecraft/recipe/BrewingRecipeRegistry;registerDefaults(Lnet/minecraft/recipe/BrewingRecipeRegistry$Builder;)V" - ) - ) - private static void registerRecipes(BrewingRecipeRegistry.Builder builder) { - builder.itematic$registerItemRecipe(ItemKeys.POTION, ItemKeys.GUNPOWDER, ItemKeys.SPLASH_POTION); - builder.itematic$registerItemRecipe(ItemKeys.SPLASH_POTION, ItemKeys.DRAGON_BREATH, ItemKeys.LINGERING_POTION); - - builder.itematic$registerWaterPotionRecipe(ItemKeys.GLISTERING_MELON_SLICE, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.GHAST_TEAR, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.RABBIT_FOOT, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.BLAZE_POWDER, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.SPIDER_EYE, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.SUGAR, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.MAGMA_CREAM, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.GLOWSTONE_DUST, Potions.THICK); - builder.itematic$registerWaterPotionRecipe(ItemKeys.REDSTONE, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.NETHER_WART, Potions.AWKWARD); - builder.itematic$registerWaterPotionRecipe(ItemKeys.BREEZE_ROD, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.SLIME_BLOCK, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.STONE, Potions.MUNDANE); - builder.itematic$registerWaterPotionRecipe(ItemKeys.COBWEB, Potions.MUNDANE); - - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.GOLDEN_CARROT, Potions.NIGHT_VISION); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.MAGMA_CREAM, Potions.FIRE_RESISTANCE); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.RABBIT_FOOT, Potions.LEAPING); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.TURTLE_HELMET, Potions.TURTLE_MASTER); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.SUGAR, Potions.SWIFTNESS); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.PUFFERFISH, Potions.WATER_BREATHING); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.GLISTERING_MELON_SLICE, Potions.HEALING); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.SPIDER_EYE, Potions.POISON); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.GHAST_TEAR, Potions.REGENERATION); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.BLAZE_POWDER, Potions.STRENGTH); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.PHANTOM_MEMBRANE, Potions.SLOW_FALLING); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.BREEZE_ROD, Potions.WIND_CHARGED); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.SLIME_BLOCK, Potions.OOZING); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.STONE, Potions.INFESTED); - builder.itematic$registerAwkwardPotionRecipe(ItemKeys.COBWEB, Potions.WEAVING); - - builder.itematic$registerLongPotionRecipe(Potions.NIGHT_VISION, Potions.LONG_NIGHT_VISION); - builder.itematic$registerLongPotionRecipe(Potions.INVISIBILITY, Potions.LONG_INVISIBILITY); - builder.itematic$registerLongPotionRecipe(Potions.FIRE_RESISTANCE, Potions.LONG_FIRE_RESISTANCE); - builder.itematic$registerLongPotionRecipe(Potions.LEAPING, Potions.LONG_LEAPING); - builder.itematic$registerLongPotionRecipe(Potions.SLOWNESS, Potions.LONG_SLOWNESS); - builder.itematic$registerLongPotionRecipe(Potions.TURTLE_MASTER, Potions.LONG_TURTLE_MASTER); - builder.itematic$registerLongPotionRecipe(Potions.SWIFTNESS, Potions.LONG_SWIFTNESS); - builder.itematic$registerLongPotionRecipe(Potions.WATER_BREATHING, Potions.LONG_WATER_BREATHING); - builder.itematic$registerLongPotionRecipe(Potions.POISON, Potions.LONG_POISON); - builder.itematic$registerLongPotionRecipe(Potions.REGENERATION, Potions.LONG_REGENERATION); - builder.itematic$registerLongPotionRecipe(Potions.STRENGTH, Potions.LONG_STRENGTH); - builder.itematic$registerLongPotionRecipe(Potions.WEAKNESS, Potions.LONG_WEAKNESS); - builder.itematic$registerLongPotionRecipe(Potions.SLOW_FALLING, Potions.LONG_SLOW_FALLING); - - builder.itematic$registerStrongPotionRecipe(Potions.LEAPING, Potions.STRONG_LEAPING); - builder.itematic$registerStrongPotionRecipe(Potions.SLOWNESS, Potions.STRONG_SLOWNESS); - builder.itematic$registerStrongPotionRecipe(Potions.TURTLE_MASTER, Potions.STRONG_TURTLE_MASTER); - builder.itematic$registerStrongPotionRecipe(Potions.SWIFTNESS, Potions.STRONG_SWIFTNESS); - builder.itematic$registerStrongPotionRecipe(Potions.HEALING, Potions.STRONG_HEALING); - builder.itematic$registerStrongPotionRecipe(Potions.HARMING, Potions.STRONG_HARMING); - builder.itematic$registerStrongPotionRecipe(Potions.POISON, Potions.STRONG_POISON); - builder.itematic$registerStrongPotionRecipe(Potions.REGENERATION, Potions.STRONG_REGENERATION); - builder.itematic$registerStrongPotionRecipe(Potions.STRENGTH, Potions.STRONG_STRENGTH); - - builder.itematic$registerNegatingPotionRecipe(Potions.NIGHT_VISION, Potions.INVISIBILITY); - builder.itematic$registerNegatingPotionRecipe(Potions.LONG_NIGHT_VISION, Potions.LONG_INVISIBILITY); - builder.itematic$registerNegatingPotionRecipe(Potions.LEAPING, Potions.SLOWNESS); - builder.itematic$registerNegatingPotionRecipe(Potions.LONG_LEAPING, Potions.LONG_SLOWNESS); - builder.itematic$registerNegatingPotionRecipe(Potions.SWIFTNESS, Potions.SLOWNESS); - builder.itematic$registerNegatingPotionRecipe(Potions.LONG_SWIFTNESS, Potions.LONG_SLOWNESS); - builder.itematic$registerNegatingPotionRecipe(Potions.HEALING, Potions.HARMING); - builder.itematic$registerNegatingPotionRecipe(Potions.STRONG_HEALING, Potions.STRONG_HARMING); - builder.itematic$registerNegatingPotionRecipe(Potions.POISON, Potions.HARMING); - builder.itematic$registerNegatingPotionRecipe(Potions.LONG_POISON, Potions.HARMING); - builder.itematic$registerNegatingPotionRecipe(Potions.STRONG_POISON, Potions.STRONG_HARMING); - builder.itematic$registerNegatingPotionRecipe(Potions.WATER, Potions.WEAKNESS); - } - - @Override - public void itematic$setItemRecipes(List>> itemRecipes) { - this.itemRecipes = itemRecipes; - } - - @Override - public void itematic$setPotionRecipes(List>> potionRecipes) { - this.potionRecipes = potionRecipes; - } - - @Override - public ItemStack itematic$craft(ItemStack ingredient, ItemStack input, World world) { - if (input.isEmpty()) { - return input; - } - - Optional> optionalPotion = input.getOrDefault(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT) - .potion(); - if (optionalPotion.isEmpty()) { - return input; - } - - RegistryEntry potion = optionalPotion.get(); - for (BrewingRecipe> recipe : this.itemRecipes) { - if (input.itematic$isOf(recipe.input()) && ingredient.itematic$isOf(recipe.ingredient())) { - return PotionContentsComponentUtil.setPotion(world.itematic$createStack(recipe.output()), potion); - } - } - - for (BrewingRecipe> recipe : this.potionRecipes) { - if (recipe.input() == potion && ingredient.itematic$isOf(recipe.ingredient())) { - return PotionContentsComponentUtil.setPotion(new ItemStack(input.getRegistryEntry()), recipe.output()); - } - } - - return input; - } - - @Mixin(BrewingRecipeRegistry.Builder.class) - public static class BuilderExtender implements BrewingRecipeRegistryBuilderAccess { - @Unique - private final List>> itemRecipes = new ArrayList<>(); - - @Unique - private final List>> potionRecipes = new ArrayList<>(); - - @ModifyReturnValue( - method = "build", - at = @At("TAIL") - ) - private BrewingRecipeRegistry setRecipes(BrewingRecipeRegistry original) { - original.itematic$setItemRecipes(List.copyOf(this.itemRecipes)); - original.itematic$setPotionRecipes(List.copyOf(this.potionRecipes)); - return original; - } - - @Override - public void itematic$registerItemRecipe(RegistryKey from, RegistryKey ingredient, RegistryKey to) { - this.itemRecipes.add(new BrewingRecipe<>(from, ingredient, to)); - } - - @Override - public void itematic$registerWaterPotionRecipe(RegistryKey key, RegistryEntry output) { - this.potionRecipes.add(new BrewingRecipe<>(Potions.WATER, key, output)); - } - - @Override - public void itematic$registerAwkwardPotionRecipe(RegistryKey key, RegistryEntry output) { - this.potionRecipes.add(new BrewingRecipe<>(Potions.AWKWARD, key, output)); - } - - @Override - public void itematic$registerLongPotionRecipe(RegistryEntry input, RegistryEntry output) { - this.potionRecipes.add(new BrewingRecipe<>(input, ItemKeys.REDSTONE, output)); - } - - @Override - public void itematic$registerStrongPotionRecipe(RegistryEntry input, RegistryEntry output) { - this.potionRecipes.add(new BrewingRecipe<>(input, ItemKeys.GLOWSTONE_DUST, output)); - } - - @Override - public void itematic$registerNegatingPotionRecipe(RegistryEntry input, RegistryEntry output) { - this.potionRecipes.add(new BrewingRecipe<>(input, ItemKeys.FERMENTED_SPIDER_EYE, output)); - } - } -} diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/IngredientExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/IngredientExtender.java index 871ba4a8..be8ec3fb 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/IngredientExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/IngredientExtender.java @@ -1,5 +1,8 @@ package net.errorcraft.itematic.mixin.recipe; +import com.mojang.datafixers.util.Either; +import com.mojang.serialization.Codec; +import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.access.recipe.IngredientAccess; import net.errorcraft.itematic.access.recipe.IngredientEntryAccess; import net.minecraft.item.Item; @@ -11,23 +14,28 @@ import net.minecraft.registry.RegistryWrapper; import net.minecraft.registry.tag.TagKey; import org.jetbrains.annotations.Nullable; -import org.spongepowered.asm.mixin.Final; -import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.Shadow; +import org.spongepowered.asm.mixin.*; import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.List; +import java.util.*; import java.util.function.Function; import java.util.stream.Stream; @Mixin(Ingredient.class) public class IngredientExtender implements IngredientAccess { + @Shadow + @Final + @Mutable + public static Codec ALLOW_EMPTY_CODEC; + + @Shadow + @Final + @Mutable + public static Codec DISALLOW_EMPTY_CODEC; + @Shadow @Final private Ingredient.Entry[] entries; @@ -36,6 +44,15 @@ public class IngredientExtender implements IngredientAccess { @Nullable private ItemStack[] matchingStacks; + @Unique + private Optional remainder = Optional.empty(); + + static { + // Modify the codec fields in a static initializer block due to Fabric API using a cancellable @Inject for their own additions, which makes @ModifyReturnValue not work + ALLOW_EMPTY_CODEC = addRemainder(ALLOW_EMPTY_CODEC); + DISALLOW_EMPTY_CODEC = addRemainder(DISALLOW_EMPTY_CODEC); + } + @Redirect( method = "", at = @At( @@ -90,6 +107,41 @@ private void testUseDirectEntries(ItemStack itemStack, CallbackInfoReturnable itematic$remainder() { + return this.remainder; + } + + @Override + public void itematic$setRemainder(Optional remainder) { + this.remainder = remainder; + } + + @Unique + private static Codec addRemainder(Codec original) { + Codec fullCodec = RecordCodecBuilder.create(instance -> instance.group( + original.fieldOf("items").forGetter(Function.identity()), + ItemStack.CODEC.optionalFieldOf("remainder").forGetter(Ingredient::itematic$remainder) + ).apply(instance, IngredientExtender::setFields)); + return Codec.either(original, fullCodec) + .xmap( + either -> either.map(Function.identity(), Function.identity()), + ingredient -> { + if (ingredient.itematic$remainder().isEmpty()) { + return Either.left(ingredient); + } + + return Either.right(ingredient); + } + ); + } + + @Unique + private static Ingredient setFields(Ingredient ingredient, Optional remainder) { + ingredient.itematic$setRemainder(remainder); + return ingredient; + } + @Mixin(Ingredient.Entry.class) public interface EntryExtender extends IngredientEntryAccess {} diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/RawShapedRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/RawShapedRecipeExtender.java new file mode 100644 index 00000000..7d8ca7ce --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/RawShapedRecipeExtender.java @@ -0,0 +1,51 @@ +package net.errorcraft.itematic.mixin.recipe; + +import net.errorcraft.itematic.access.recipe.RawShapedRecipeAccess; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.RawShapedRecipe; +import net.minecraft.recipe.input.CraftingRecipeInput; +import net.minecraft.util.collection.DefaultedList; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(RawShapedRecipe.class) +public abstract class RawShapedRecipeExtender implements RawShapedRecipeAccess { + @Shadow + @Final + private int width; + + @Shadow + @Final + private int height; + + @Shadow + @Final + private boolean symmetrical; + + @Shadow + @Final + private DefaultedList ingredients; + + @Shadow + protected abstract boolean matches(CraftingRecipeInput input, boolean mirrored); + + @Override + public DefaultedList itematic$remainder(CraftingRecipeInput input) { + boolean actuallyMirrored = !this.symmetrical && this.matches(input, true); + DefaultedList remainders = DefaultedList.ofSize(input.getSize(), ItemStack.EMPTY); + for(int y = 0; y < this.height; y++) { + for(int x = 0; x < this.width; x++) { + int index = actuallyMirrored ? + this.width - x - 1 + y * this.width : + x + y * this.width; + this.ingredients.get(index) + .itematic$remainder() + .ifPresent(remainder -> remainders.set(index, remainder.copy())); + } + } + + return remainders; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/RecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/RecipeExtender.java index ecc45404..2a852d7d 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/recipe/RecipeExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/RecipeExtender.java @@ -1,30 +1,21 @@ package net.errorcraft.itematic.mixin.recipe; -import com.llamalad7.mixinextras.sugar.Local; import net.errorcraft.itematic.access.recipe.RecipeAccess; -import net.errorcraft.itematic.item.component.ItemComponentTypes; -import net.errorcraft.itematic.item.component.components.RecipeRemainderItemComponent; import net.minecraft.item.Item; -import net.minecraft.item.ItemConvertible; -import net.minecraft.item.ItemStack; +import net.minecraft.recipe.Ingredient; import net.minecraft.recipe.Recipe; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.util.collection.DefaultedList; import org.spongepowered.asm.mixin.Mixin; -import org.spongepowered.asm.mixin.injection.At; -import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.Shadow; @Mixin(Recipe.class) public interface RecipeExtender extends RecipeAccess { - @Redirect( - method = "getRemainder", - at = @At( - value = "NEW", - target = "(Lnet/minecraft/item/ItemConvertible;)Lnet/minecraft/item/ItemStack;" - ) - ) - private ItemStack newItemStackForRemainderUseItemComponent(ItemConvertible itemConvertible, @Local Item item) { - return item.itematic$getComponent(ItemComponentTypes.RECIPE_REMAINDER) - .map(RecipeRemainderItemComponent::item) - .map(ItemStack::new) - .orElse(ItemStack.EMPTY); + @Shadow + DefaultedList getIngredients(); + + @Override + default DefaultedList itematic$ingredients(RegistryEntryLookup items) { + return this.getIngredients(); } } diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/ShapedRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/ShapedRecipeExtender.java new file mode 100644 index 00000000..ee1749a2 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/ShapedRecipeExtender.java @@ -0,0 +1,24 @@ +package net.errorcraft.itematic.mixin.recipe; + +import net.errorcraft.itematic.access.recipe.RawShapedRecipeAccess; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.CraftingRecipe; +import net.minecraft.recipe.RawShapedRecipe; +import net.minecraft.recipe.ShapedRecipe; +import net.minecraft.recipe.input.CraftingRecipeInput; +import net.minecraft.util.collection.DefaultedList; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ShapedRecipe.class) +public abstract class ShapedRecipeExtender implements CraftingRecipe { + @Shadow + @Final + RawShapedRecipe raw; + + @Override + public DefaultedList getRemainder(CraftingRecipeInput input) { + return ((RawShapedRecipeAccess)(Object) this.raw).itematic$remainder(input); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/ShapelessRecipeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/ShapelessRecipeExtender.java new file mode 100644 index 00000000..5c205db8 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/ShapelessRecipeExtender.java @@ -0,0 +1,47 @@ +package net.errorcraft.itematic.mixin.recipe; + +import it.unimi.dsi.fastutil.ints.IntOpenHashSet; +import it.unimi.dsi.fastutil.ints.IntSet; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.CraftingRecipe; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.ShapelessRecipe; +import net.minecraft.recipe.input.CraftingRecipeInput; +import net.minecraft.util.collection.DefaultedList; +import org.spongepowered.asm.mixin.Final; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; + +@Mixin(ShapelessRecipe.class) +public abstract class ShapelessRecipeExtender implements CraftingRecipe { + @Shadow + @Final + DefaultedList ingredients; + + @Override + public DefaultedList getRemainder(CraftingRecipeInput input) { + IntSet foundInputs = new IntOpenHashSet(); + DefaultedList remainders = DefaultedList.ofSize(input.getSize(), ItemStack.EMPTY); + for (Ingredient ingredient : this.ingredients) { + if (ingredient.itematic$remainder().isEmpty()) { + continue; + } + + for (int i = 0; i < input.getSize(); i++) { + if (foundInputs.contains(i)) { + continue; + } + + if (!ingredient.test(input.getStackInSlot(i))) { + continue; + } + + remainders.set(i, ingredient.itematic$remainder().get().copy()); + foundInputs.add(i); + break; + } + } + + return remainders; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/recipe/book/RecipeBookOptionsExtender.java b/src/main/java/net/errorcraft/itematic/mixin/recipe/book/RecipeBookOptionsExtender.java new file mode 100644 index 00000000..b3d1f86c --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/recipe/book/RecipeBookOptionsExtender.java @@ -0,0 +1,31 @@ +package net.errorcraft.itematic.mixin.recipe.book; + +import com.google.common.collect.ImmutableMap; +import com.llamalad7.mixinextras.injector.ModifyExpressionValue; +import com.mojang.datafixers.util.Pair; +import net.errorcraft.itematic.recipe.book.ItematicRecipeBookCategories; +import net.minecraft.recipe.book.RecipeBookCategory; +import net.minecraft.recipe.book.RecipeBookOptions; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; + +@Mixin(RecipeBookOptions.class) +public class RecipeBookOptionsExtender { + @ModifyExpressionValue( + method = "", + at = @At( + value = "INVOKE", + target = "Lcom/google/common/collect/ImmutableMap;of(Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;Ljava/lang/Object;)Lcom/google/common/collect/ImmutableMap;", + remap = false + ) + ) + private static ImmutableMap> addCustomEntries(ImmutableMap> original) { + return ImmutableMap.>builder() + .putAll(original) + .put( + ItematicRecipeBookCategories.BREWING, + Pair.of("isBrewingStandGuiOpen", "isBrewingStandFilteringCraftable") + ) + .build(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerAccessor.java new file mode 100644 index 00000000..6570bf00 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerAccessor.java @@ -0,0 +1,27 @@ +package net.errorcraft.itematic.mixin.screen; + +import net.minecraft.inventory.Inventory; +import net.minecraft.screen.BrewingStandScreenHandler; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Accessor; + +@Mixin(BrewingStandScreenHandler.class) +public interface BrewingStandScreenHandlerAccessor { + @Accessor("field_30763") + static int inputSlotStart() { + throw new AssertionError(); + } + + @Accessor("field_30764") + static int inputSlotEnd() { + throw new AssertionError(); + } + + @Accessor("INGREDIENT_SLOT_ID") + static int ingredientSlot() { + throw new AssertionError(); + } + + @Accessor("inventory") + Inventory itematic$inventory(); +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerExtender.java b/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerExtender.java index a4cfa650..aa791586 100644 --- a/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerExtender.java +++ b/src/main/java/net/errorcraft/itematic/mixin/screen/BrewingStandScreenHandlerExtender.java @@ -1,16 +1,69 @@ package net.errorcraft.itematic.mixin.screen; +import net.errorcraft.itematic.access.screen.BrewingStandScreenHandlerAccess; import net.errorcraft.itematic.item.ItemKeys; import net.errorcraft.itematic.item.component.ItemComponentTypes; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; +import net.minecraft.recipe.BrewingRecipeRegistry; +import net.minecraft.screen.BrewingStandScreenHandler; +import net.minecraft.screen.PropertyDelegate; import org.objectweb.asm.Opcodes; +import org.spongepowered.asm.mixin.Final; import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.ModifyArg; import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Slice; -public class BrewingStandScreenHandlerExtender { +@Mixin(BrewingStandScreenHandler.class) +public class BrewingStandScreenHandlerExtender implements BrewingStandScreenHandlerAccess { + @Shadow + @Final + private PropertyDelegate propertyDelegate; + + @ModifyArg( + method = "(ILnet/minecraft/entity/player/PlayerInventory;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/screen/ArrayPropertyDelegate;(I)V" + ) + ) + private static int initAddMaxFuelTimeProperty(int size) { + return size + 1; + } + + @ModifyArg( + method = "(ILnet/minecraft/entity/player/PlayerInventory;Lnet/minecraft/inventory/Inventory;Lnet/minecraft/screen/PropertyDelegate;)V", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/screen/BrewingStandScreenHandler;checkDataCount(Lnet/minecraft/screen/PropertyDelegate;I)V" + ) + ) + private static int checkDataCountAddMaxFuelTimeProperty(int expectedCount) { + return expectedCount + 1; + } + + @Override + public int itematic$maxBrewingTime() { + return this.propertyDelegate.get(2); + } + + @Mixin(targets = "net/minecraft/screen/BrewingStandScreenHandler$IngredientSlot") + public static class IngredientSlotExtender { + @Redirect( + method = "canInsert", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/recipe/BrewingRecipeRegistry;isValidIngredient(Lnet/minecraft/item/ItemStack;)Z" + ) + ) + private static boolean isAlwaysValidIngredient(BrewingRecipeRegistry instance, ItemStack stack) { + return true; + } + } + @Mixin(targets = "net/minecraft/screen/BrewingStandScreenHandler$PotionSlot") public static class PotionSlotExtender { @Redirect( diff --git a/src/main/java/net/errorcraft/itematic/mixin/screen/ScreenHandlerTypeAccessor.java b/src/main/java/net/errorcraft/itematic/mixin/screen/ScreenHandlerTypeAccessor.java new file mode 100644 index 00000000..9e57021a --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/screen/ScreenHandlerTypeAccessor.java @@ -0,0 +1,14 @@ +package net.errorcraft.itematic.mixin.screen; + +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.gen.Invoker; + +@Mixin(ScreenHandlerType.class) +public interface ScreenHandlerTypeAccessor { + @Invoker("register") + static ScreenHandlerType register(String id, ScreenHandlerType.Factory factory) { + throw new AssertionError(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mixin/screen/ScreenHandlerTypeExtender.java b/src/main/java/net/errorcraft/itematic/mixin/screen/ScreenHandlerTypeExtender.java new file mode 100644 index 00000000..bfa4a884 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mixin/screen/ScreenHandlerTypeExtender.java @@ -0,0 +1,31 @@ +package net.errorcraft.itematic.mixin.screen; + +import net.errorcraft.itematic.screen.ItematicScreenHandlerTypes; +import net.minecraft.screen.ScreenHandler; +import net.minecraft.screen.ScreenHandlerType; +import org.spongepowered.asm.mixin.Mixin; +import org.spongepowered.asm.mixin.injection.At; +import org.spongepowered.asm.mixin.injection.Redirect; +import org.spongepowered.asm.mixin.injection.Slice; + +@Mixin(ScreenHandlerType.class) +public class ScreenHandlerTypeExtender { + @Redirect( + method = "", + at = @At( + value = "INVOKE", + target = "Lnet/minecraft/screen/ScreenHandlerType;register(Ljava/lang/String;Lnet/minecraft/screen/ScreenHandlerType$Factory;)Lnet/minecraft/screen/ScreenHandlerType;", + ordinal = 0 + ), + slice = @Slice( + from = @At( + value = "CONSTANT", + args = "stringValue=brewing_stand" + ) + ) + ) + @SuppressWarnings("unchecked") + private static ScreenHandlerType useCustomGliderDataComponent(String id, ScreenHandlerType.Factory factory) { + return (ScreenHandlerType) ItematicScreenHandlerTypes.BREWING_STAND; + } +} diff --git a/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java b/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java new file mode 100644 index 00000000..b339ae83 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mm/ItematicEarlyRiser.java @@ -0,0 +1,16 @@ +package net.errorcraft.itematic.mm; + +import com.chocohead.mm.api.ClassTinkerers; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.MappingResolver; + +public class ItematicEarlyRiser implements Runnable { + @Override + public void run() { + MappingResolver remapper = FabricLoader.getInstance().getMappingResolver(); + String recipeBookCategory = remapper.mapClassName("intermediary", "net.minecraft.class_5421"); + ClassTinkerers.enumBuilder(recipeBookCategory) + .addEnum("ITEMATIC$BREWING") + .build(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/mm/client/ItematicClientEarlyRiser.java b/src/main/java/net/errorcraft/itematic/mm/client/ItematicClientEarlyRiser.java new file mode 100644 index 00000000..a552c853 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/mm/client/ItematicClientEarlyRiser.java @@ -0,0 +1,35 @@ +package net.errorcraft.itematic.mm.client; + +import com.chocohead.mm.api.ClassTinkerers; +import net.fabricmc.api.EnvType; +import net.fabricmc.loader.api.FabricLoader; +import net.fabricmc.loader.api.MappingResolver; +import net.minecraft.item.ItemStack; + +public class ItematicClientEarlyRiser implements Runnable { + @Override + public void run() { + FabricLoader loader = FabricLoader.getInstance(); + + // There is no early riser client entry point definition, so this check is done in main instead + if (loader.getEnvironmentType() != EnvType.CLIENT) { + return; + } + + MappingResolver remapper = loader.getMappingResolver(); + String recipeBookGroup = remapper.mapClassName("intermediary", "net.minecraft.class_314"); + String itemStack = 'L' + remapper.mapClassName("intermediary", "net.minecraft.class_1799") + ';'; + String itemStackArray = '[' + itemStack; + ClassTinkerers.enumBuilder(recipeBookGroup, itemStackArray) + .addEnum("ITEMATIC$BREWING_SEARCH", () -> new Object[] { + new ItemStack[0] + }) + .addEnum("ITEMATIC$BREWING_MODIFY", () -> new Object[] { + new ItemStack[0] + }) + .addEnum("ITEMATIC$BREWING_AMPLIFY", () -> new Object[] { + new ItemStack[0] + }) + .build(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/potion/PotionKeys.java b/src/main/java/net/errorcraft/itematic/potion/PotionKeys.java index ec4ab20e..d3343f2c 100644 --- a/src/main/java/net/errorcraft/itematic/potion/PotionKeys.java +++ b/src/main/java/net/errorcraft/itematic/potion/PotionKeys.java @@ -6,7 +6,51 @@ import net.minecraft.util.Identifier; public class PotionKeys { + public static final RegistryKey AWKWARD = of("awkward"); + public static final RegistryKey FIRE_RESISTANCE = of("fire_resistance"); + public static final RegistryKey HARMING = of("harming"); + public static final RegistryKey HEALING = of("healing"); + public static final RegistryKey INFESTED = of("infested"); + public static final RegistryKey INVISIBILITY = of("invisibility"); + public static final RegistryKey LEAPING = of("leaping"); + public static final RegistryKey LONG_FIRE_RESISTANCE = of("long_fire_resistance"); + public static final RegistryKey LONG_INVISIBILITY = of("long_invisibility"); + public static final RegistryKey LONG_LEAPING = of("long_leaping"); + public static final RegistryKey LONG_NIGHT_VISION = of("long_night_vision"); + public static final RegistryKey LONG_POISON = of("long_poison"); + public static final RegistryKey LONG_REGENERATION = of("long_regeneration"); + public static final RegistryKey LONG_SLOWNESS = of("long_slowness"); + public static final RegistryKey LONG_SLOW_FALLING = of("long_slow_falling"); + public static final RegistryKey LONG_STRENGTH = of("long_strength"); + public static final RegistryKey LONG_SWIFTNESS = of("long_swiftness"); + public static final RegistryKey LONG_TURTLE_MASTER = of("long_turtle_master"); + public static final RegistryKey LONG_WATER_BREATHING = of("long_water_breathing"); + public static final RegistryKey LONG_WEAKNESS = of("long_weakness"); + public static final RegistryKey MUNDANE = of("mundane"); + public static final RegistryKey NIGHT_VISION = of("night_vision"); + public static final RegistryKey OOZING = of("oozing"); + public static final RegistryKey POISON = of("poison"); + public static final RegistryKey REGENERATION = of("regeneration"); + public static final RegistryKey SLOWNESS = of("slowness"); + public static final RegistryKey SLOW_FALLING = of("slow_falling"); + public static final RegistryKey STRENGTH = of("strength"); + public static final RegistryKey STRONG_HARMING = of("strong_harming"); + public static final RegistryKey STRONG_HEALING = of("strong_healing"); + public static final RegistryKey STRONG_LEAPING = of("strong_leaping"); + public static final RegistryKey STRONG_POISON = of("strong_poison"); + public static final RegistryKey STRONG_REGENERATION = of("strong_regeneration"); + public static final RegistryKey STRONG_SLOWNESS = of("strong_slowness"); + public static final RegistryKey STRONG_STRENGTH = of("strong_strength"); + public static final RegistryKey STRONG_SWIFTNESS = of("strong_swiftness"); + public static final RegistryKey STRONG_TURTLE_MASTER = of("strong_turtle_master"); + public static final RegistryKey SWIFTNESS = of("swiftness"); + public static final RegistryKey THICK = of("thick"); + public static final RegistryKey TURTLE_MASTER = of("turtle_master"); public static final RegistryKey WATER = of("water"); + public static final RegistryKey WATER_BREATHING = of("water_breathing"); + public static final RegistryKey WEAKNESS = of("weakness"); + public static final RegistryKey WEAVING = of("weaving"); + public static final RegistryKey WIND_CHARGED = of("wind_charged"); private PotionKeys() {} diff --git a/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateExtraFields.java b/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateExtraFields.java index f68b28e4..a54d4a1e 100644 --- a/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateExtraFields.java +++ b/src/main/java/net/errorcraft/itematic/predicate/item/ItemPredicateExtraFields.java @@ -6,7 +6,7 @@ import net.errorcraft.itematic.network.codec.PacketCodecUtil; import net.errorcraft.itematic.registry.ItematicRegistries; import net.errorcraft.itematic.registry.ItematicRegistryKeys; -import net.errorcraft.itematic.serialization.ItematicCodecs; +import net.errorcraft.itematic.serialization.SetCodec; import net.minecraft.component.ComponentType; import net.minecraft.item.ItemStack; import net.minecraft.network.RegistryByteBuf; @@ -20,8 +20,8 @@ public record ItemPredicateExtraFields(Optional>> behavior, Optional>> dataComponents) { public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( - ItematicCodecs.setCodec(ItematicRegistries.ITEM_COMPONENT_TYPE.getCodec()).optionalFieldOf("behavior").forGetter(ItemPredicateExtraFields::behavior), - ItematicCodecs.setCodec(Registries.DATA_COMPONENT_TYPE.getCodec()).optionalFieldOf("data_components").forGetter(ItemPredicateExtraFields::dataComponents) + SetCodec.forRegistry(ItematicRegistries.ITEM_COMPONENT_TYPE).optionalFieldOf("behavior").forGetter(ItemPredicateExtraFields::behavior), + SetCodec.forRegistry(Registries.DATA_COMPONENT_TYPE).optionalFieldOf("data_components").forGetter(ItemPredicateExtraFields::dataComponents) ).apply(instance, ItemPredicateExtraFields::new)); public static final PacketCodec PACKET_CODEC = PacketCodec.tuple( PacketCodecs.registryValue(ItematicRegistryKeys.ITEM_COMPONENT_TYPE).collect(PacketCodecUtil::set).collect(PacketCodecs::optional), ItemPredicateExtraFields::behavior, diff --git a/src/main/java/net/errorcraft/itematic/recipe/BrewingRecipe.java b/src/main/java/net/errorcraft/itematic/recipe/BrewingRecipe.java deleted file mode 100644 index ad6f9f37..00000000 --- a/src/main/java/net/errorcraft/itematic/recipe/BrewingRecipe.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.errorcraft.itematic.recipe; - -import net.minecraft.item.Item; -import net.minecraft.registry.RegistryKey; - -public record BrewingRecipe(T input, RegistryKey ingredient, T output) { -} diff --git a/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeSerializers.java b/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeSerializers.java index fa0467e2..6ecc1c9c 100644 --- a/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeSerializers.java +++ b/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeSerializers.java @@ -1,9 +1,13 @@ package net.errorcraft.itematic.recipe; +import net.errorcraft.itematic.recipe.brewing.AmplifyBrewingRecipe; +import net.errorcraft.itematic.recipe.brewing.ModifyBrewingRecipe; import net.minecraft.recipe.RecipeSerializer; public class ItematicRecipeSerializers { public static final RecipeSerializer ITEM_COLORING = RecipeSerializer.register("item_coloring", new ItemColoringRecipe.Serializer()); + public static final RecipeSerializer BREWING_MODIFY = RecipeSerializer.register("brewing_modify", new ModifyBrewingRecipe.Serializer()); + public static final RecipeSerializer BREWING_AMPLIFY = RecipeSerializer.register("brewing_amplify", new AmplifyBrewingRecipe.Serializer()); private ItematicRecipeSerializers() {} diff --git a/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeTypes.java b/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeTypes.java new file mode 100644 index 00000000..38404f9f --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/recipe/ItematicRecipeTypes.java @@ -0,0 +1,12 @@ +package net.errorcraft.itematic.recipe; + +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.minecraft.recipe.RecipeType; + +public class ItematicRecipeTypes { + public static final RecipeType> BREWING = RecipeType.register("brewing"); + + private ItematicRecipeTypes() {} + + public static void init() {} +} diff --git a/src/main/java/net/errorcraft/itematic/recipe/book/ItematicRecipeBookCategories.java b/src/main/java/net/errorcraft/itematic/recipe/book/ItematicRecipeBookCategories.java new file mode 100644 index 00000000..38ccea11 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/recipe/book/ItematicRecipeBookCategories.java @@ -0,0 +1,10 @@ +package net.errorcraft.itematic.recipe.book; + +import com.chocohead.mm.api.ClassTinkerers; +import net.minecraft.recipe.book.RecipeBookCategory; + +public class ItematicRecipeBookCategories { + public static final RecipeBookCategory BREWING = ClassTinkerers.getEnum(RecipeBookCategory.class, "ITEMATIC$BREWING"); + + private ItematicRecipeBookCategories() {} +} diff --git a/src/main/java/net/errorcraft/itematic/recipe/brewing/AmplifyBrewingRecipe.java b/src/main/java/net/errorcraft/itematic/recipe/brewing/AmplifyBrewingRecipe.java new file mode 100644 index 00000000..63d6fc4d --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/recipe/brewing/AmplifyBrewingRecipe.java @@ -0,0 +1,95 @@ +package net.errorcraft.itematic.recipe.brewing; + +import com.mojang.serialization.MapCodec; +import net.errorcraft.itematic.component.PotionContentsComponentUtil; +import net.errorcraft.itematic.recipe.ItematicRecipeSerializers; +import net.errorcraft.itematic.recipe.input.BrewingRecipeInput; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.potion.Potions; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.util.collection.DefaultedList; + +public class AmplifyBrewingRecipe extends BrewingRecipe { + public AmplifyBrewingRecipe(String group, RegistryEntry base, Ingredient reagent, RegistryEntry result, int brewingTime) { + super(group, base, reagent, result, brewingTime); + } + + public AmplifyBrewingRecipe(RegistryEntry base, Ingredient reagent, RegistryEntry result) { + super("", base, reagent, result, DEFAULT_BREWING_TIME); + } + + @Override + public Ingredient inputIngredient(RegistryEntryLookup items) { + return this.inputIngredient(); + } + + @Override + protected boolean matches(ItemStack base) { + return base.itemMatches(this.base()); + } + + @Override + protected ItemStack craft(ItemStack base) { + return base.split(1).itematic$copyWithItem(this.result()); + } + + @Override + public ItemStack getResult(RegistryWrapper.WrapperLookup lookup) { + return PotionContentsComponentUtil.setPotion( + new ItemStack(this.result()), + Potions.WATER + ); + } + + @Override + public DefaultedList getIngredients() { + DefaultedList ingredients = DefaultedList.ofSize(2); + ingredients.add(this.reagent()); + ingredients.add(this.inputIngredient()); + return ingredients; + } + + @Override + public RecipeSerializer> getSerializer() { + return ItematicRecipeSerializers.BREWING_AMPLIFY; + } + + private Ingredient inputIngredient() { + return Ingredient.ofStacks( + PotionContentsComponentUtil.setPotion( + new ItemStack(this.base()), + Potions.WATER + ) + ); + } + + public static class Serializer implements RecipeSerializer { + private static final MapCodec CODEC = createCodec( + RegistryKeys.ITEM, + AmplifyBrewingRecipe::new + ); + private static final PacketCodec PACKET_CODEC = createPacketCodec( + RegistryKeys.ITEM, + AmplifyBrewingRecipe::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public PacketCodec packetCodec() { + return PACKET_CODEC; + } + } +} diff --git a/src/main/java/net/errorcraft/itematic/recipe/brewing/BrewingRecipe.java b/src/main/java/net/errorcraft/itematic/recipe/brewing/BrewingRecipe.java new file mode 100644 index 00000000..ac5b6311 --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/recipe/brewing/BrewingRecipe.java @@ -0,0 +1,136 @@ +package net.errorcraft.itematic.recipe.brewing; + +import com.mojang.datafixers.util.Function5; +import com.mojang.serialization.Codec; +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.access.recipe.RecipeAccess; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.recipe.ItematicRecipeTypes; +import net.errorcraft.itematic.recipe.input.BrewingRecipeInput; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.network.codec.PacketCodecs; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeType; +import net.minecraft.registry.Registry; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKey; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryFixedCodec; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.util.dynamic.Codecs; +import net.minecraft.world.World; + +import java.util.Optional; + +public abstract class BrewingRecipe implements Recipe, RecipeAccess { + public static final int DEFAULT_BREWING_TIME = 400; + private final String group; + private final RegistryEntry base; + private final Ingredient reagent; + private final RegistryEntry result; + private final int brewingTime; + + protected BrewingRecipe(String group, RegistryEntry base, Ingredient reagent, RegistryEntry result, int brewingTime) { + this.group = group; + this.base = base; + this.reagent = reagent; + this.result = result; + this.brewingTime = brewingTime; + } + + protected static > MapCodec createCodec(RegistryKey> registry, Function5, Ingredient, RegistryEntry, Integer, R> creator) { + Codec> entryCodec = RegistryFixedCodec.of(registry); + return RecordCodecBuilder.mapCodec(instance -> instance.group( + Codec.STRING.optionalFieldOf("group", "").forGetter(R::getGroup), + entryCodec.fieldOf("base").forGetter(R::base), + Ingredient.DISALLOW_EMPTY_CODEC.fieldOf("reagent").forGetter(R::reagent), + entryCodec.fieldOf("result").forGetter(R::result), + Codecs.POSITIVE_INT.optionalFieldOf("brewing_time", DEFAULT_BREWING_TIME).forGetter(R::brewingTime) + ).apply(instance, creator)); + } + + protected static > PacketCodec createPacketCodec(RegistryKey> registry, Function5, Ingredient, RegistryEntry, Integer, R> creator) { + PacketCodec> entryPacketCodec = PacketCodecs.registryEntry(registry); + return PacketCodec.tuple( + PacketCodecs.STRING, R::getGroup, + entryPacketCodec, R::base, + Ingredient.PACKET_CODEC, R::reagent, + entryPacketCodec, R::result, + PacketCodecs.VAR_INT, R::brewingTime, + creator + ); + } + + @Override + public boolean matches(BrewingRecipeInput input, World world) { + return this.reagent.test(input.reagent()) && this.matches(input.base()); + } + + @Override + public ItemStack craft(BrewingRecipeInput input, RegistryWrapper.WrapperLookup registries) { + return this.craft(input.base()); + } + + @Override + public boolean fits(int width, int height) { + return true; + } + + @Override + public String getGroup() { + return this.group; + } + + @Override + public RecipeType> getType() { + return ItematicRecipeTypes.BREWING; + } + + @Override + public boolean isEmpty() { + return this.reagent.isEmpty(); + } + + @Override + public ItemStack itematic$createIcon(RegistryEntryLookup items) { + return new ItemStack(items.getOrThrow(ItemKeys.BREWING_STAND)); + } + + @Override + public DefaultedList itematic$ingredients(RegistryEntryLookup items) { + DefaultedList ingredients = DefaultedList.ofSize(2); + ingredients.add(this.reagent()); + ingredients.add(this.inputIngredient(items)); + return ingredients; + } + + public Optional reagentRemainder() { + return this.reagent.itematic$remainder().map(ItemStack::copy); + } + + protected RegistryEntry base() { + return this.base; + } + + public Ingredient reagent() { + return this.reagent; + } + + protected RegistryEntry result() { + return this.result; + } + + public int brewingTime() { + return this.brewingTime; + } + + public abstract Ingredient inputIngredient(RegistryEntryLookup items); + protected abstract boolean matches(ItemStack base); + protected abstract ItemStack craft(ItemStack base); +} diff --git a/src/main/java/net/errorcraft/itematic/recipe/brewing/ModifyBrewingRecipe.java b/src/main/java/net/errorcraft/itematic/recipe/brewing/ModifyBrewingRecipe.java new file mode 100644 index 00000000..6043791a --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/recipe/brewing/ModifyBrewingRecipe.java @@ -0,0 +1,103 @@ +package net.errorcraft.itematic.recipe.brewing; + +import com.mojang.serialization.MapCodec; +import net.errorcraft.itematic.component.PotionContentsComponentUtil; +import net.errorcraft.itematic.item.ItemKeys; +import net.errorcraft.itematic.item.ItematicItemTags; +import net.errorcraft.itematic.recipe.ItematicRecipeSerializers; +import net.errorcraft.itematic.recipe.input.BrewingRecipeInput; +import net.minecraft.component.DataComponentTypes; +import net.minecraft.component.type.PotionContentsComponent; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.network.RegistryByteBuf; +import net.minecraft.network.codec.PacketCodec; +import net.minecraft.potion.Potion; +import net.minecraft.recipe.Ingredient; +import net.minecraft.recipe.Recipe; +import net.minecraft.recipe.RecipeSerializer; +import net.minecraft.registry.RegistryEntryLookup; +import net.minecraft.registry.RegistryKeys; +import net.minecraft.registry.RegistryWrapper; +import net.minecraft.registry.entry.RegistryEntry; +import net.minecraft.registry.entry.RegistryEntryList; +import net.minecraft.util.collection.DefaultedList; + +import java.util.stream.Stream; + +public class ModifyBrewingRecipe extends BrewingRecipe { + public ModifyBrewingRecipe(String group, RegistryEntry base, Ingredient reagent, RegistryEntry result, int brewingTime) { + super(group, base, reagent, result, brewingTime); + } + + public ModifyBrewingRecipe(RegistryEntry base, Ingredient reagent, RegistryEntry result) { + super("", base, reagent, result, DEFAULT_BREWING_TIME); + } + + @Override + public Ingredient inputIngredient(RegistryEntryLookup items) { + return Ingredient.ofStacks(this.getInputStacks(items)); + } + + @Override + protected boolean matches(ItemStack base) { + return base.getOrDefault(DataComponentTypes.POTION_CONTENTS, PotionContentsComponent.DEFAULT) + .matches(this.base()); + } + + @Override + protected ItemStack craft(ItemStack base) { + return PotionContentsComponentUtil.setPotion(base.copyWithCount(1), this.result()); + } + + @Override + public ItemStack getResult(RegistryWrapper.WrapperLookup lookup) { + return lookup.getWrapperOrThrow(RegistryKeys.ITEM) + .getOptional(ItemKeys.POTION) + .map(ItemStack::new) + .map(stack -> PotionContentsComponentUtil.setPotion(stack, this.result())) + .orElse(ItemStack.EMPTY); + } + + @Override + public DefaultedList getIngredients() { + DefaultedList ingredients = DefaultedList.ofSize(2); + ingredients.add(this.reagent()); + ingredients.add(Ingredient.fromTag(ItematicItemTags.BREWING_INPUTS)); + return ingredients; + } + + @Override + public RecipeSerializer> getSerializer() { + return ItematicRecipeSerializers.BREWING_MODIFY; + } + + private Stream getInputStacks(RegistryEntryLookup items) { + return items.getOptional(ItematicItemTags.BREWING_INPUTS) + .stream() + .flatMap(RegistryEntryList.ListBacked::stream) + .map(ItemStack::new) + .map(stack -> PotionContentsComponentUtil.setPotion(stack, this.base())); + } + + public static class Serializer implements RecipeSerializer { + private static final MapCodec CODEC = createCodec( + RegistryKeys.POTION, + ModifyBrewingRecipe::new + ); + private static final PacketCodec PACKET_CODEC = createPacketCodec( + RegistryKeys.POTION, + ModifyBrewingRecipe::new + ); + + @Override + public MapCodec codec() { + return CODEC; + } + + @Override + public PacketCodec packetCodec() { + return PACKET_CODEC; + } + } +} diff --git a/src/main/java/net/errorcraft/itematic/recipe/input/BrewingRecipeInput.java b/src/main/java/net/errorcraft/itematic/recipe/input/BrewingRecipeInput.java new file mode 100644 index 00000000..2ebe5b8a --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/recipe/input/BrewingRecipeInput.java @@ -0,0 +1,20 @@ +package net.errorcraft.itematic.recipe.input; + +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.input.RecipeInput; + +public record BrewingRecipeInput(ItemStack base, ItemStack reagent) implements RecipeInput { + @Override + public ItemStack getStackInSlot(int slot) { + return switch (slot) { + case 0 -> this.base; + case 1 -> this.reagent; + default -> throw new IllegalArgumentException("Recipe does not contain slot " + slot); + }; + } + + @Override + public int getSize() { + return 2; + } +} diff --git a/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java b/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java new file mode 100644 index 00000000..fc87623e --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/screen/BrewingStandMenuDelegate.java @@ -0,0 +1,243 @@ +package net.errorcraft.itematic.screen; + +import net.errorcraft.itematic.mixin.screen.BrewingStandScreenHandlerAccessor; +import net.errorcraft.itematic.recipe.book.ItematicRecipeBookCategories; +import net.errorcraft.itematic.recipe.brewing.BrewingRecipe; +import net.errorcraft.itematic.recipe.input.BrewingRecipeInput; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.entity.player.PlayerInventory; +import net.minecraft.inventory.Inventory; +import net.minecraft.item.ItemStack; +import net.minecraft.recipe.RecipeEntry; +import net.minecraft.recipe.RecipeInputProvider; +import net.minecraft.recipe.RecipeMatcher; +import net.minecraft.recipe.book.RecipeBookCategory; +import net.minecraft.screen.*; +import net.minecraft.screen.slot.Slot; +import net.minecraft.screen.slot.SlotActionType; +import net.minecraft.util.collection.DefaultedList; +import net.minecraft.world.World; + +import java.util.List; +import java.util.OptionalInt; + +public class BrewingStandMenuDelegate extends AbstractRecipeScreenHandler> { + public static final int FIRST_INPUT_SLOT = BrewingStandScreenHandlerAccessor.inputSlotStart(); + public static final int LAST_INPUT_SLOT = BrewingStandScreenHandlerAccessor.inputSlotEnd(); + public static final int INGREDIENT_SLOT = BrewingStandScreenHandlerAccessor.ingredientSlot(); + + private final BrewingStandScreenHandler delegate; + private final Inventory inventory; + private final World world; + + public BrewingStandMenuDelegate(int syncId, PlayerInventory inventory) { + this(new BrewingStandScreenHandler(syncId, inventory), inventory.player.getWorld()); + } + + public BrewingStandMenuDelegate(BrewingStandScreenHandler delegate, World world) { + super(delegate.getType(), delegate.syncId); + this.delegate = delegate; + this.inventory = ((BrewingStandScreenHandlerAccessor) delegate).itematic$inventory(); + this.world = world; + delegate.slots.forEach(this::addSlot); + } + + public BrewingStandScreenHandler delegate() { + return this.delegate; + } + + @Override + public void populateRecipeFinder(RecipeMatcher matcher) { + if (this.inventory instanceof RecipeInputProvider recipeInputProvider) { + recipeInputProvider.provideRecipeInputs(matcher); + } + } + + @Override + public void clearCraftingSlots() { + for (int i = FIRST_INPUT_SLOT; i < LAST_INPUT_SLOT; i++) { + this.slots.get(i).setStackNoCallbacks(ItemStack.EMPTY); + } + + this.slots.get(INGREDIENT_SLOT).setStackNoCallbacks(ItemStack.EMPTY); + } + + @Override + public boolean matches(RecipeEntry> recipe) { + BrewingRecipeInput input = new BrewingRecipeInput( + BrewingStandMenuDelegate.this.inventory.getStack(FIRST_INPUT_SLOT), + BrewingStandMenuDelegate.this.inventory.getStack(INGREDIENT_SLOT) + ); + return recipe.value().matches(input, this.world); + } + + @Override + public int getCraftingResultSlotIndex() { + return FIRST_INPUT_SLOT; + } + + @Override + public int getCraftingWidth() { + return 2; + } + + @Override + public int getCraftingHeight() { + return 1; + } + + @Override + public int getCraftingSlotCount() { + return 4; + } + + @Override + public RecipeBookCategory getCategory() { + return ItematicRecipeBookCategories.BREWING; + } + + @Override + public boolean canInsertIntoSlot(int index) { + return (index >= FIRST_INPUT_SLOT && index <= LAST_INPUT_SLOT) || index == INGREDIENT_SLOT; + } + + @Override + public boolean canUse(PlayerEntity player) { + return this.delegate.canUse(player); + } + + @Override + public ItemStack quickMove(PlayerEntity player, int slot) { + return this.delegate.quickMove(player, slot); + } + + @Override + public void addListener(ScreenHandlerListener listener) { + this.delegate.addListener(listener); + } + + @Override + public void updateSyncHandler(ScreenHandlerSyncHandler handler) { + this.delegate.updateSyncHandler(handler); + } + + @Override + public void syncState() { + this.delegate.syncState(); + } + + @Override + public void removeListener(ScreenHandlerListener listener) { + this.delegate.removeListener(listener); + } + + @Override + public DefaultedList getStacks() { + return this.delegate.getStacks(); + } + + @Override + public void sendContentUpdates() { + this.delegate.sendContentUpdates(); + } + + @Override + public void updateToClient() { + this.delegate.updateToClient(); + } + + @Override + public void setPreviousTrackedSlot(int slot, ItemStack stack) { + this.delegate.setPreviousTrackedSlot(slot, stack); + } + + @Override + public void setPreviousTrackedSlotMutable(int slot, ItemStack stack) { + this.delegate.setPreviousTrackedSlotMutable(slot, stack); + } + + @Override + public void setPreviousCursorStack(ItemStack stack) { + this.delegate.setPreviousCursorStack(stack); + } + + @Override + public boolean onButtonClick(PlayerEntity player, int id) { + return this.delegate.onButtonClick(player, id); + } + + @Override + public Slot getSlot(int index) { + return this.delegate.getSlot(index); + } + + @Override + public void onSlotClick(int slotIndex, int button, SlotActionType actionType, PlayerEntity player) { + this.delegate.onSlotClick(slotIndex, button, actionType, player); + } + + @Override + public void onClosed(PlayerEntity player) { + this.delegate.onClosed(player); + } + + @Override + public void onContentChanged(Inventory inventory) { + this.delegate.onContentChanged(inventory); + } + + @Override + public void setStackInSlot(int slot, int revision, ItemStack stack) { + this.delegate.setStackInSlot(slot, revision, stack); + } + + @Override + public void updateSlotStacks(int revision, List stacks, ItemStack cursorStack) { + this.delegate.updateSlotStacks(revision, stacks, cursorStack); + } + + @Override + public void setProperty(int id, int value) { + this.delegate.setProperty(id, value); + } + + @Override + public void setCursorStack(ItemStack stack) { + this.delegate.setCursorStack(stack); + } + + @Override + public ItemStack getCursorStack() { + return this.delegate.getCursorStack(); + } + + @Override + public void disableSyncing() { + this.delegate.disableSyncing(); + } + + @Override + public void enableSyncing() { + this.delegate.enableSyncing(); + } + + @Override + public void copySharedSlots(ScreenHandler handler) { + this.delegate.copySharedSlots(handler); + } + + @Override + public OptionalInt getSlotIndex(Inventory inventory, int index) { + return this.delegate.getSlotIndex(inventory, index); + } + + @Override + public int getRevision() { + return this.delegate.getRevision(); + } + + @Override + public int nextRevision() { + return this.delegate.nextRevision(); + } +} diff --git a/src/main/java/net/errorcraft/itematic/screen/ItematicScreenHandlerTypes.java b/src/main/java/net/errorcraft/itematic/screen/ItematicScreenHandlerTypes.java new file mode 100644 index 00000000..b4c9d0ae --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/screen/ItematicScreenHandlerTypes.java @@ -0,0 +1,12 @@ +package net.errorcraft.itematic.screen; + +import net.errorcraft.itematic.mixin.screen.ScreenHandlerTypeAccessor; +import net.minecraft.screen.ScreenHandlerType; + +public class ItematicScreenHandlerTypes { + public static final ScreenHandlerType BREWING_STAND = ScreenHandlerTypeAccessor.register("brewing_stand", BrewingStandMenuDelegate::new); + + private ItematicScreenHandlerTypes() {} + + public static void init() {} +} diff --git a/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java b/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java index 63af13ae..c8edb56a 100644 --- a/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java +++ b/src/main/java/net/errorcraft/itematic/serialization/ItematicCodecs.java @@ -1,20 +1,12 @@ package net.errorcraft.itematic.serialization; -import com.mojang.datafixers.util.Pair; import com.mojang.serialization.Codec; import com.mojang.serialization.DataResult; -import com.mojang.serialization.DynamicOps; import com.mojang.serialization.codecs.RecordCodecBuilder; import net.errorcraft.itematic.mixin.util.dynamic.CodecsAccessor; import net.minecraft.util.dynamic.Codecs; import org.apache.commons.lang3.math.Fraction; -import java.util.ArrayList; -import java.util.HashSet; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - public class ItematicCodecs { public static final Codec NON_NEGATIVE_FLOAT = Codec.FLOAT.validate(value -> { if (value >= 0 && value <= Float.MAX_VALUE) { @@ -48,10 +40,6 @@ public static Codec index(int size) { }); } - public static Codec> setCodec(Codec codec) { - return new SetCodec<>(codec); - } - public static Codec positiveFloat(float maxInclusive) { if (maxInclusive <= 0.0f) { throw new IllegalArgumentException("maxInclusive must be positive, got " + maxInclusive + " instead"); @@ -70,36 +58,4 @@ public static Codec positiveFraction(int maxInclusive) { return DataResult.success(fraction); }); } - - private static class SetCodec implements Codec> { - private final Codec> listCodec; - - private SetCodec(Codec codec) { - this.listCodec = codec.listOf(); - } - - @Override - public DataResult, T>> decode(DynamicOps ops, T input) { - return this.listCodec.decode(ops, input) - .flatMap(pair -> { - List elements = pair.getFirst(); - Set set = new HashSet<>(); - Set duplicates = new HashSet<>(); - for (E element : elements) { - if (!set.add(element)) { - duplicates.add(element); - } - } - if (!duplicates.isEmpty()) { - return DataResult.error(() -> "Set contained duplicate entries: " + duplicates.stream().map(E::toString).collect(Collectors.joining(", "))); - } - return DataResult.success(Pair.of(set, pair.getSecond())); - }); - } - - @Override - public DataResult encode(Set input, DynamicOps ops, T prefix) { - return this.listCodec.encode(new ArrayList<>(input), ops, prefix); - } - } } diff --git a/src/main/java/net/errorcraft/itematic/serialization/SetCodec.java b/src/main/java/net/errorcraft/itematic/serialization/SetCodec.java new file mode 100644 index 00000000..00fa4c1f --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/serialization/SetCodec.java @@ -0,0 +1,58 @@ +package net.errorcraft.itematic.serialization; + +import com.mojang.datafixers.util.Pair; +import com.mojang.serialization.Codec; +import com.mojang.serialization.DataResult; +import com.mojang.serialization.DynamicOps; +import net.minecraft.registry.Registry; + +import java.util.Comparator; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public class SetCodec implements Codec> { + private final Codec> listCodec; + private final Comparator comparator; + + private SetCodec(Codec codec, Comparator comparator) { + this.listCodec = codec.listOf(); + this.comparator = comparator; + } + + @SuppressWarnings("DataFlowIssue") + public static Codec> forRegistry(Registry registry) { + return new SetCodec<>(registry.getCodec(), Comparator.comparing(registry::getId)); + } + + public static > Codec> forEnum(Codec codec) { + return new SetCodec<>(codec, Enum::compareTo); + } + + @Override + public DataResult, T>> decode(DynamicOps ops, T input) { + return this.listCodec.decode(ops, input) + .flatMap(pair -> { + List elements = pair.getFirst(); + Set set = new HashSet<>(); + Set duplicates = new HashSet<>(); + for (E element : elements) { + if (!set.add(element)) { + duplicates.add(element); + } + } + + if (!duplicates.isEmpty()) { + return DataResult.error(() -> "Set contained duplicate entries: " + duplicates.stream().map(E::toString).collect(Collectors.joining(", "))); + } + + return DataResult.success(Pair.of(set, pair.getSecond())); + }); + } + + @Override + public DataResult encode(Set input, DynamicOps ops, T prefix) { + return this.listCodec.encode(input.stream().sorted(this.comparator).toList(), ops, prefix); + } +} diff --git a/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java b/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java index e2a3a08a..ebca8365 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionTypeKeys.java @@ -49,6 +49,7 @@ public class ActionTypeKeys { public static final RegistryKey> USE_BUCKET = of("use_bucket"); public static final RegistryKey> REMOVE_STATUS_EFFECTS = of("remove_status_effects"); public static final RegistryKey> INCREMENT_STAT = of("increment_stat"); + public static final RegistryKey> ADD_STATUS_EFFECTS = of("add_status_effects"); private ActionTypeKeys() {} diff --git a/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java b/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java index d7f5bf64..8dfc4db3 100644 --- a/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java +++ b/src/main/java/net/errorcraft/itematic/world/action/ActionTypes.java @@ -50,6 +50,7 @@ public class ActionTypes { public static final ActionType USE_BUCKET = register(ActionTypeKeys.USE_BUCKET, new ActionType<>(UseBucketAction.CODEC)); public static final ActionType REMOVE_STATUS_EFFECTS = register(ActionTypeKeys.REMOVE_STATUS_EFFECTS, new ActionType<>(RemoveStatusEffectsAction.CODEC)); public static final ActionType INCREMENT_STAT = register(ActionTypeKeys.INCREMENT_STAT, new ActionType<>(IncrementStatAction.CODEC)); + public static final ActionType ADD_STATUS_EFFECTS = register(ActionTypeKeys.ADD_STATUS_EFFECTS, new ActionType<>(AddStatusEffectsAction.CODEC)); private ActionTypes() {} diff --git a/src/main/java/net/errorcraft/itematic/world/action/actions/AddStatusEffectsAction.java b/src/main/java/net/errorcraft/itematic/world/action/actions/AddStatusEffectsAction.java new file mode 100644 index 00000000..0f75a8dd --- /dev/null +++ b/src/main/java/net/errorcraft/itematic/world/action/actions/AddStatusEffectsAction.java @@ -0,0 +1,45 @@ +package net.errorcraft.itematic.world.action.actions; + +import com.mojang.serialization.MapCodec; +import com.mojang.serialization.codecs.RecordCodecBuilder; +import net.errorcraft.itematic.world.action.Action; +import net.errorcraft.itematic.world.action.ActionType; +import net.errorcraft.itematic.world.action.ActionTypes; +import net.errorcraft.itematic.world.action.context.ActionContext; +import net.errorcraft.itematic.world.action.context.parameter.ActionContextParameter; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffectInstance; + +import java.util.List; + +public record AddStatusEffectsAction(List effects, ActionContextParameter entity) implements Action { + public static final MapCodec CODEC = RecordCodecBuilder.mapCodec(instance -> instance.group( + StatusEffectInstance.CODEC.listOf().fieldOf("effects").forGetter(AddStatusEffectsAction::effects), + ActionContextParameter.CODEC.fieldOf("entity").forGetter(AddStatusEffectsAction::entity) + ).apply(instance, AddStatusEffectsAction::new)); + + public static AddStatusEffectsAction of(StatusEffectInstance... effects) { + return new AddStatusEffectsAction(List.of(effects), ActionContextParameter.THIS); + } + + @Override + public ActionType type() { + return ActionTypes.ADD_STATUS_EFFECTS; + } + + @Override + public boolean execute(ActionContext context) { + return context.livingEntity(this.entity) + .map(this::addStatusEffects) + .orElse(false); + } + + private boolean addStatusEffects(LivingEntity target) { + boolean addedStatusEffects = false; + for (StatusEffectInstance effect : this.effects) { + addedStatusEffects |= target.addStatusEffect(effect); + } + + return addedStatusEffects; + } +} \ No newline at end of file diff --git a/src/main/resources/assets/itematic/lang/en_us.json b/src/main/resources/assets/itematic/lang/en_us.json new file mode 100644 index 00000000..2b6a73c6 --- /dev/null +++ b/src/main/resources/assets/itematic/lang/en_us.json @@ -0,0 +1,3 @@ +{ + "gui.recipebook.toggleRecipes.brewable": "Show Brewable" +} diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_disabled.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_disabled.png new file mode 100644 index 00000000..2b335574 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_disabled.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_disabled_highlighted.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_disabled_highlighted.png new file mode 100644 index 00000000..32d4cc94 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_disabled_highlighted.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_enabled.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_enabled.png new file mode 100644 index 00000000..42e864a8 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_enabled.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_enabled_highlighted.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_enabled_highlighted.png new file mode 100644 index 00000000..b1199cd5 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_filter_enabled_highlighted.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay.png new file mode 100644 index 00000000..0bffda70 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_disabled.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_disabled.png new file mode 100644 index 00000000..b13febab Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_disabled.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_disabled_highlighted.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_disabled_highlighted.png new file mode 100644 index 00000000..6d77ea38 Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_disabled_highlighted.png differ diff --git a/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_highlighted.png b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_highlighted.png new file mode 100644 index 00000000..dfd1260f Binary files /dev/null and b/src/main/resources/assets/minecraft/textures/gui/sprites/recipe_book/brewing_stand_overlay_highlighted.png differ diff --git a/src/main/resources/fabric.mod.json b/src/main/resources/fabric.mod.json index 7fd35eac..1db3ccf4 100644 --- a/src/main/resources/fabric.mod.json +++ b/src/main/resources/fabric.mod.json @@ -24,6 +24,10 @@ ], "fabric-datagen": [ "net.errorcraft.itematic.data.ItematicData" + ], + "mm:early_risers": [ + "net.errorcraft.itematic.mm.ItematicEarlyRiser", + "net.errorcraft.itematic.mm.client.ItematicClientEarlyRiser" ] }, "mixins": [ @@ -75,15 +79,6 @@ "net/minecraft/class_1839": [ "net/minecraft/util/StringIdentifiable" ], - "net/minecraft/class_1845": [ - "net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryAccess" - ], - "net/minecraft/class_1845\u0024class_9665": [ - "net/errorcraft/itematic/access/recipe/BrewingRecipeRegistryBuilderAccess" - ], - "net/minecraft/class_1856": [ - "net/errorcraft/itematic/access/recipe/IngredientAccess" - ], "net/minecraft/class_1856\u0024class_1859": [ "net/errorcraft/itematic/access/recipe/IngredientEntryAccess" ], diff --git a/src/main/resources/itematic.classtweaker b/src/main/resources/itematic.classtweaker index 98b60cb3..ea3fcd07 100644 --- a/src/main/resources/itematic.classtweaker +++ b/src/main/resources/itematic.classtweaker @@ -7,6 +7,9 @@ accessible class net/minecraft/client/gui/screen/GameModeSelectionScreen$G accessible class net/minecraft/client/gui/screen/StatsScreen$ItemStatsListWidget accessible class net/minecraft/client/gui/screen/StatsScreen$ItemStatsListWidget$Entry accessible class net/minecraft/client/gui/screen/world/CustomizeFlatLevelScreen$SuperflatLayersListWidget +accessible class net/minecraft/client/gui/screen/recipebook/RecipeAlternativesWidget$AlternativeButtonWidget +accessible class net/minecraft/client/gui/screen/recipebook/RecipeAlternativesWidget$AlternativeButtonWidget$InputSlot inject-interface net/minecraft/util/DyeColor net/errorcraft/itematic/access/util/DyeColorAccess inject-interface net/minecraft/item/tooltip/BundleTooltipData net/errorcraft/itematic/access/item/tooltip/BundleTooltipDataAccess +inject-interface net/minecraft/recipe/Ingredient net/errorcraft/itematic/access/recipe/IngredientAccess diff --git a/src/main/resources/itematic.mixins.json b/src/main/resources/itematic.mixins.json index 609acb75..7ffd89c5 100644 --- a/src/main/resources/itematic.mixins.json +++ b/src/main/resources/itematic.mixins.json @@ -72,6 +72,7 @@ "block.entity.BannerBlockEntityExtender", "block.entity.BlockEntityExtender", "block.entity.BrewingStandBlockEntityExtender", + "block.entity.BrewingStandBlockEntityExtender$PropertyDelegateExtender", "block.entity.DecoratedPotBlockEntityExtender", "block.entity.LecternBlockEntityExtender", "block.entity.SherdsAccessor", @@ -88,9 +89,11 @@ "component.type.BundleContentsComponentExtender$BuilderExtender", "component.type.ChargedProjectilesComponentExtender", "component.type.DyedColorComponentExtender", + "component.type.FoodComponentExtender", "component.type.FoodComponentExtender$BuilderExtender", "component.type.ToolComponentExtender", "component.type.ToolComponentExtender$RuleExtender", + "data.server.recipe.RecipeProviderExtender", "enchantment.EnchantmentHelperExtender", "entity.BucketableExtender", "entity.CrossbowUserExtender", @@ -315,8 +318,6 @@ "recipe.BannerDuplicateRecipeExtender", "recipe.BlastingRecipeExtender", "recipe.BookCloningRecipeExtender", - "recipe.BrewingRecipeRegistryExtender", - "recipe.BrewingRecipeRegistryExtender$BuilderExtender", "recipe.CampfireCookingRecipeExtender", "recipe.CraftingDecoratedPotRecipeExtender", "recipe.FireworkRocketRecipeExtender", @@ -329,9 +330,12 @@ "recipe.InputSlotFillerExtender", "recipe.MapCloningRecipeExtender", "recipe.MapExtendingRecipeExtender", + "recipe.RawShapedRecipeExtender", "recipe.RecipeExtender", "recipe.RecipeMatcherExtender", "recipe.RepairItemRecipeExtender", + "recipe.ShapedRecipeExtender", + "recipe.ShapelessRecipeExtender", "recipe.ShieldDecorationRecipeExtender", "recipe.SmeltingRecipeExtender", "recipe.SmithingRecipeExtender", @@ -341,6 +345,7 @@ "recipe.StonecuttingRecipeExtender", "recipe.SuspiciousStewRecipeExtender", "recipe.TippedArrowRecipeExtender", + "recipe.book.RecipeBookOptionsExtender", "registry.BuiltinRegistriesExtender", "registry.RegistriesAccessor", "registry.RegistriesExtender", @@ -354,7 +359,10 @@ "scoreboard.ScoreboardCriterionExtender", "scoreboard.ScoreboardStateExtender", "screen.AnvilScreenHandlerExtender", + "screen.BrewingStandScreenHandlerAccessor", + "screen.BrewingStandScreenHandlerExtender", "screen.BrewingStandScreenHandlerExtender$FuelSlotExtender", + "screen.BrewingStandScreenHandlerExtender$IngredientSlotExtender", "screen.BrewingStandScreenHandlerExtender$PotionSlotExtender", "screen.CartographyTableScreenHandlerExtender", "screen.CartographyTableScreenHandlerExtender$AdditionSlotExtender", @@ -368,6 +376,8 @@ "screen.LoomScreenHandlerExtender$BannerPatternSlotExtender", "screen.LoomScreenHandlerExtender$BannerSlotExtender", "screen.LoomScreenHandlerExtender$DyeSlotExtender", + "screen.ScreenHandlerTypeAccessor", + "screen.ScreenHandlerTypeExtender", "screen.slot.FurnaceFuelSlotExtender", "server.ServerPlayerInteractionManagerExtender", "server.command.ScoreboardCommandExtender",